[Scummvm-git-logs] scummvm branch-2-7 -> 920faab9a99bfd12772c93d26aeb1f32088a1b88

larsamannen noreply at scummvm.org
Sat May 6 14:00:58 UTC 2023


This automated email contains information about 11 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
811bb45997 CREATE_PROJECT: Set bitcode as disabled as default in Xcode
29c017634a IOS7: Implement use of Timer Dispatch Sources to drive timeHandler
f8c00b17e5 BACKENDS: IOS7: Add inital code for port-specifc options
61bbe1187b IOS: Add back new delegate methods but keep old ones
a9e44384e9 IOS7: Implement port-specifc option widget
806e7e4824 IOS7: Remove legacy gesture recognizers
560dfbf2bc IOS7: Don't disable "touchpad" mode when enabling "click-and-drag"
7c903e4a55 IOS7: Write changes to mouse modes to ConfMan
cf7e3256ee IOS7: Call correct delegate method
a7d12394b0 IOS7: Add dpad actions to gamepad controller
920faab9a9 IOS7: Implement Apple GCVirtualController


Commit: 811bb4599775a36d23b9317ea74c2ce9fac260a3
    https://github.com/scummvm/scummvm/commit/811bb4599775a36d23b9317ea74c2ce9fac260a3
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2023-05-06T10:20:45+02:00

Commit Message:
CREATE_PROJECT: Set bitcode as disabled as default in Xcode

Apple never required bitcode to be enabled and with Xcode 14
bitcode is deprecated.

Set bitcode to disabled for iOS and tvOS projects. Else it will
be default on and give a build error due to the libraries in
scummvm-ios7-libs-v3 doesn't include bitcode.

Changed paths:
    devtools/create_project/xcode.cpp


diff --git a/devtools/create_project/xcode.cpp b/devtools/create_project/xcode.cpp
index 560ffc4e376..82a99370d1f 100644
--- a/devtools/create_project/xcode.cpp
+++ b/devtools/create_project/xcode.cpp
@@ -1314,6 +1314,7 @@ void XcodeProvider::setupBuildConfiguration(const BuildSetup &setup) {
 	ADD_SETTING_QUOTE_VAR(iPhone_Debug, "CODE_SIGN_IDENTITY[sdk=iphoneos*]", "iPhone Developer");
 	ADD_SETTING(iPhone_Debug, "COPY_PHASE_STRIP", "NO");
 	ADD_SETTING_QUOTE(iPhone_Debug, "DEBUG_INFORMATION_FORMAT", "dwarf");
+	ADD_SETTING(iPhone_Debug, "ENABLE_BITCODE", "NO");
 	ValueList iPhone_FrameworkSearchPaths;
 	iPhone_FrameworkSearchPaths.push_back("$(inherited)");
 	iPhone_FrameworkSearchPaths.push_back("\"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"");
@@ -1472,6 +1473,7 @@ void XcodeProvider::setupBuildConfiguration(const BuildSetup &setup) {
 	ADD_SETTING_QUOTE_VAR(tvOS_Debug, "CODE_SIGN_IDENTITY[sdk=appletvos*]", "iPhone Developer");
 	ADD_SETTING(tvOS_Debug, "COPY_PHASE_STRIP", "NO");
 	ADD_SETTING_QUOTE(tvOS_Debug, "DEBUG_INFORMATION_FORMAT", "dwarf");
+	ADD_SETTING(tvOS_Debug, "ENABLE_BITCODE", "NO");
 	ValueList tvOS_FrameworkSearchPaths;
 	tvOS_FrameworkSearchPaths.push_back("$(inherited)");
 	tvOS_FrameworkSearchPaths.push_back("\"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"");


Commit: 29c017634adb29c701f605b494ba6ebc65e835b9
    https://github.com/scummvm/scummvm/commit/29c017634adb29c701f605b494ba6ebc65e835b9
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2023-05-06T10:20:52+02:00

Commit Message:
IOS7: Implement use of Timer Dispatch Sources to drive timeHandler

The timeHandler was driven by calls to the pollEvent callback function.
Each time pollEvent was called the timeHandler called the TimeManager
handle function to advance in time and make sure scheduled tasks were
triggered.

This worked good for most game engines but some, e.g. the Hypno engine
was using the TimeManager to schedule tasks without calling pollEvent
since it was expecting nor handling events at the specific point in
time.

Since iOS have threads the timerHandler can be called from a separate
thread and not rely on pollEvent.
Implement timerHandler to use a Timer Dispatch Source which and make
it operate on a background thread rather than the main thread.
Read more on Dispatch Sources here:
https://developer.apple.com/library/archive/documentation/General/
Conceptual/ConcurrencyProgrammingGuide/GCDWorkQueues/GCDWorkQueues.html

Changed paths:
    backends/platform/ios7/ios7_osys_events.cpp
    backends/platform/ios7/ios7_osys_main.cpp
    backends/platform/ios7/ios7_osys_main.h


diff --git a/backends/platform/ios7/ios7_osys_events.cpp b/backends/platform/ios7/ios7_osys_events.cpp
index 290a84b63e7..9880ade53ab 100644
--- a/backends/platform/ios7/ios7_osys_events.cpp
+++ b/backends/platform/ios7/ios7_osys_events.cpp
@@ -34,11 +34,6 @@ bool OSystem_iOS7::pollEvent(Common::Event &event) {
 
 	long curTime = getMillis();
 
-	if (_timerCallback && (curTime >= _timerCallbackNext)) {
-		_timerCallback(_timerCallbackTimer);
-		_timerCallbackNext = curTime + _timerCallbackTimer;
-	}
-
 	if (_queuedInputEvent.type != Common::EVENT_INVALID && curTime >= _queuedEventTime) {
 		event = _queuedInputEvent;
 		_queuedInputEvent.type = Common::EVENT_INVALID;
diff --git a/backends/platform/ios7/ios7_osys_main.cpp b/backends/platform/ios7/ios7_osys_main.cpp
index 3511ed83b16..d769cb4b325 100644
--- a/backends/platform/ios7/ios7_osys_main.cpp
+++ b/backends/platform/ios7/ios7_osys_main.cpp
@@ -303,13 +303,15 @@ void OSystem_iOS7::delayMillis(uint msecs) {
 
 void OSystem_iOS7::setTimerCallback(TimerProc callback, int interval) {
 	//printf("setTimerCallback()\n");
-
-	if (callback != NULL) {
-		_timerCallbackTimer = interval;
-		_timerCallbackNext = getMillis() + interval;
-		_timerCallback = callback;
-	} else
-		_timerCallback = NULL;
+	dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+	dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
+
+	if (timer)
+	{
+		dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), interval * NSEC_PER_MSEC, interval * NSEC_PER_MSEC / 10);
+		dispatch_source_set_event_handler(timer, ^{ callback(interval); });
+		dispatch_resume(timer);
+	}
 }
 
 Common::MutexInternal *OSystem_iOS7::createMutex() {
diff --git a/backends/platform/ios7/ios7_osys_main.h b/backends/platform/ios7/ios7_osys_main.h
index 825cf47bb49..6ce8f6bd71e 100644
--- a/backends/platform/ios7/ios7_osys_main.h
+++ b/backends/platform/ios7/ios7_osys_main.h
@@ -95,10 +95,6 @@ protected:
 	int _lastDragPosX;
 	int _lastDragPosY;
 
-	int _timerCallbackNext;
-	int _timerCallbackTimer;
-	TimerProc _timerCallback;
-
 	Common::Array<Common::Rect> _dirtyRects;
 	Common::Array<Common::Rect> _dirtyOverlayRects;
 	ScreenOrientation _screenOrientation;


Commit: f8c00b17e5498e58051c1fa043b5dff6c09fb515
    https://github.com/scummvm/scummvm/commit/f8c00b17e5498e58051c1fa043b5dff6c09fb515
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-05-06T10:21:00+02:00

Commit Message:
BACKENDS: IOS7: Add inital code for port-specifc options

Changed paths:
  A backends/platform/ios7/ios7_options.cpp


diff --git a/backends/platform/ios7/ios7_options.cpp b/backends/platform/ios7/ios7_options.cpp
new file mode 100644
index 00000000000..feeaa6c439e
--- /dev/null
+++ b/backends/platform/ios7/ios7_options.cpp
@@ -0,0 +1,157 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include "gui/gui-manager.h"
+#include "gui/ThemeEval.h"
+#include "gui/widget.h"
+
+#include "common/translation.h"
+
+enum {
+	kHelpCmd = 'Help',
+};
+
+class IOS7OptionsWidget final : public GUI::OptionsContainerWidget {
+public:
+	explicit IOS7OptionsWidget(GuiObject *boss, const Common::String &name, const Common::String &domain);
+	~IOS7OptionsWidget() override;
+
+	// OptionsContainerWidget API
+	void load() override;
+	bool save() override;
+	bool hasKeys() override;
+	void setEnabled(bool e) override;
+
+private:
+	// OptionsContainerWidget API
+	void defineLayout(GUI::ThemeEval &layouts, const Common::String &layoutName, const Common::String &overlayedLayout) const override;
+	void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) override;
+
+	GUI::CheckboxWidget *_onscreenCheckbox;
+	GUI::CheckboxWidget *_touchpadCheckbox;
+	GUI::CheckboxWidget *_clickAndDragdCheckbox;
+
+	bool _enabled;
+
+	uint32 loadTouchMode(const Common::String &setting, bool acceptDefault, uint32 defaultValue);
+	void saveTouchMode(const Common::String &setting, uint32 touchMode);
+};
+
+IOS7OptionsWidget::IOS7OptionsWidget(GuiObject *boss, const Common::String &name, const Common::String &domain) :
+		OptionsContainerWidget(boss, name, "IOS7OptionsDialog", false, domain), _enabled(true) {
+
+	const bool inAppDomain = domain.equalsIgnoreCase(Common::ConfigManager::kApplicationDomain);
+
+	_onscreenCheckbox = new GUI::CheckboxWidget(widgetsBoss(), "IOS7OptionsDialog.OnScreenControl", _("Show On-screen control"));
+	_touchpadCheckbox = new GUI::CheckboxWidget(widgetsBoss(), "IOS7OptionsDialog.TouchpadMouseMode", _("Touchpad mouse mode"));
+	_clickAndDragdCheckbox = new GUI::CheckboxWidget(widgetsBoss(), "IOS7OptionsDialog.ClickAndDragMode", _("Mouse-click-and-drag mode"));
+
+	new GUI::ButtonWidget(widgetsBoss(), "IOS7OptionsDialog.ControlsHelp", _("Controls Help"), Common::U32String(), kHelpCmd);
+}
+
+IOS7OptionsWidget::~IOS7OptionsWidget() {
+}
+
+void IOS7OptionsWidget::defineLayout(GUI::ThemeEval &layouts, const Common::String &layoutName, const Common::String &overlayedLayout) const {
+	const bool inAppDomain = _domain.equalsIgnoreCase(Common::ConfigManager::kApplicationDomain);;
+
+	layouts.addDialog(layoutName, overlayedLayout)
+	        .addLayout(GUI::ThemeLayout::kLayoutVertical)
+	            .addPadding(0, 0, 0, 0)
+	            .addWidget("OnScreenControl", "Checkbox")
+	            .addWidget("TouchpadMouseMode", "Checkbox")
+	            .addWidget("ClickAndDragMode", "Checkbox")
+	            .addPadding(0, 0, 0, 0)
+	            .addWidget("ControlsHelp", "WideButton");
+
+	layouts.closeLayout()
+	    .closeDialog();
+}
+
+void IOS7OptionsWidget::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) {
+	switch (cmd) {
+	case kHelpCmd: {
+		GUI::MessageDialog help(_(
+"Gestures and controls:
+
+One finger tap: Left mouse click
+Two finger tap: Right mouse click
+Two finger double tap: ESC
+Two finger swipe (bottom to top): Toggles Click and drag mode
+Two finger swipe (left to right): Toggles between touch direct mode and touchpad mode
+Two finger swipe (top to bottom): Global Main Menu
+Three finger swipe: Arrow keys
+Pinch gesture: Enables/disables keyboard
+Keyboard spacebar: Pause"));
+
+		help.runModal();
+		break;
+	}
+	default:
+		GUI::OptionsContainerWidget::handleCommand(sender, cmd, data);
+	}
+}
+
+void IOS7OptionsWidget::load() {
+	_onscreenCheckbox->setState(ConfMan.getBool("onscreen_control", _domain));
+	_touchpadCheckbox->setState(ConfMan.getBool("touchpad_mode", _domain));
+	_clickAndDragdCheckbox->setState(ConfMan.getBool("clickanddrag_mode", _domain));
+}
+
+bool IOS7OptionsWidget::save() {
+	if (_enabled) {
+		ConfMan.setBool("onscreen_control", _onscreenCheckbox->getState(), _domain);
+		ConfMan.setBool("touchpad_mode", _touchpadCheckbox->getState(), _domain);
+		ConfMan.setBool("clickanddrag_mode", _clickAndDragdCheckbox->getState(), _domain);
+	} else {
+		ConfMan.removeKey("onscreen_control", _domain);
+		ConfMan.removeKey("touchpad_mode", _domain);
+		ConfMan.removeKey("clickanddrag_mode", _domain);
+	}
+
+	return true;
+}
+
+bool IOS7OptionsWidget::hasKeys() {
+	return ConfMan.hasKey("onscreen_control", _domain) ||
+	       ConfMan.hasKey("touchpad_mode", _domain) ||
+	       ConfMan.hasKey("clickanddrag_mode", _domain));
+}
+
+void IOS7OptionsWidget::setEnabled(bool e) {
+	_enabled = e;
+
+	_onscreenCheckbox->setEnabled(e);
+	_touchpadCheckbox->setEnabled(e);
+	_clickAndDragdCheckbox->setEnabled(e);
+}
+
+
+GUI::OptionsContainerWidget *OSystem_iOS7::buildBackendOptionsWidget(GUI::GuiObject *boss, const Common::String &name, const Common::String &target) const {
+	return new IOS7OptionsWidget(boss, name, target);
+}
+
+void OSystem_iOS7::registerDefaultSettings(const Common::String &target) const {
+	ConfMan.registerDefault("onscreen_control", true);
+	ConfMan.registerDefault("touchpad_mode", true);
+	ConfMan.registerDefault("clickanddrag_mode", false);
+}


Commit: 61bbe1187bf2bb568b261f20db3c833aca191cab
    https://github.com/scummvm/scummvm/commit/61bbe1187bf2bb568b261f20db3c833aca191cab
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2023-05-06T10:21:08+02:00

Commit Message:
IOS: Add back new delegate methods but keep old ones

On iOS 12 and below, the one delegate methods are called. On iOS13.2
and above if both sets are implemented only the new delegate methods
are called, which prevent getting the deprecation warning.

Changed paths:
    backends/platform/ios7/ios7_app_delegate.mm


diff --git a/backends/platform/ios7/ios7_app_delegate.mm b/backends/platform/ios7/ios7_app_delegate.mm
index 517e509e96c..45f9207cb2c 100644
--- a/backends/platform/ios7/ios7_app_delegate.mm
+++ b/backends/platform/ios7/ios7_app_delegate.mm
@@ -118,6 +118,16 @@
 	return YES;
 }
 
+#ifdef __IPHONE_13_2
+- (BOOL)application:(UIApplication *)application shouldSaveSecureApplicationState:(NSCoder *)coder {
+	return YES;
+}
+
+- (BOOL)application:(UIApplication *)application shouldRestoreSecureApplicationState:(NSCoder *)coder {
+	return YES;
+}
+#endif
+
 - (void)application:(UIApplication *)application didDecodeRestorableStateWithCoder:(NSCoder *)coder {
 	_restoreState = YES;
 }


Commit: a9e44384e93bfe03e691ae5d24f69909e9175bff
    https://github.com/scummvm/scummvm/commit/a9e44384e93bfe03e691ae5d24f69909e9175bff
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2023-05-06T10:21:17+02:00

Commit Message:
IOS7: Implement port-specifc option widget

Include the newly added ios7_options implementation to the project.
Change the file type to .mm which is Objective C++ to be able to use
the @availble mechanism.

Implement virtual functions and fix build errors in initial code.
Also add help section for the tvOS port when building for tvOS.

Add ios7_options to POTFILES to get automatic translation on the
help section.

Changed paths:
  A backends/platform/ios7/ios7_options.mm
  R backends/platform/ios7/ios7_options.cpp
    backends/platform/ios7/ios7_osys_main.cpp
    backends/platform/ios7/ios7_osys_main.h
    backends/platform/ios7/module.mk
    po/POTFILES


diff --git a/backends/platform/ios7/ios7_options.cpp b/backends/platform/ios7/ios7_options.mm
similarity index 66%
rename from backends/platform/ios7/ios7_options.cpp
rename to backends/platform/ios7/ios7_options.mm
index feeaa6c439e..5c87211a1c5 100644
--- a/backends/platform/ios7/ios7_options.cpp
+++ b/backends/platform/ios7/ios7_options.mm
@@ -19,12 +19,18 @@
  *
  */
 
+// Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
 
 #include "gui/gui-manager.h"
+#include "gui/message.h"
 #include "gui/ThemeEval.h"
 #include "gui/widget.h"
 
 #include "common/translation.h"
+#include "backends/platform/ios7/ios7_osys_main.h"
+
+#include <TargetConditionals.h>
 
 enum {
 	kHelpCmd = 'Help',
@@ -51,9 +57,6 @@ private:
 	GUI::CheckboxWidget *_clickAndDragdCheckbox;
 
 	bool _enabled;
-
-	uint32 loadTouchMode(const Common::String &setting, bool acceptDefault, uint32 defaultValue);
-	void saveTouchMode(const Common::String &setting, uint32 touchMode);
 };
 
 IOS7OptionsWidget::IOS7OptionsWidget(GuiObject *boss, const Common::String &name, const Common::String &domain) :
@@ -61,11 +64,15 @@ IOS7OptionsWidget::IOS7OptionsWidget(GuiObject *boss, const Common::String &name
 
 	const bool inAppDomain = domain.equalsIgnoreCase(Common::ConfigManager::kApplicationDomain);
 
-	_onscreenCheckbox = new GUI::CheckboxWidget(widgetsBoss(), "IOS7OptionsDialog.OnScreenControl", _("Show On-screen control"));
+	_onscreenCheckbox = new GUI::CheckboxWidget(widgetsBoss(), "IOS7OptionsDialog.OnScreenControl", _("Show On-screen control (iOS 15 and later)"));
 	_touchpadCheckbox = new GUI::CheckboxWidget(widgetsBoss(), "IOS7OptionsDialog.TouchpadMouseMode", _("Touchpad mouse mode"));
 	_clickAndDragdCheckbox = new GUI::CheckboxWidget(widgetsBoss(), "IOS7OptionsDialog.ClickAndDragMode", _("Mouse-click-and-drag mode"));
 
 	new GUI::ButtonWidget(widgetsBoss(), "IOS7OptionsDialog.ControlsHelp", _("Controls Help"), Common::U32String(), kHelpCmd);
+
+	// setEnabled is normally only called from the EditGameDialog, but some options (OnScreenControl)
+	// should be disabled in all domains if system is running a lower version of iOS than 15.0.
+	setEnabled(_enabled);
 }
 
 IOS7OptionsWidget::~IOS7OptionsWidget() {
@@ -90,18 +97,35 @@ void IOS7OptionsWidget::defineLayout(GUI::ThemeEval &layouts, const Common::Stri
 void IOS7OptionsWidget::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) {
 	switch (cmd) {
 	case kHelpCmd: {
-		GUI::MessageDialog help(_(
-"Gestures and controls:
-
-One finger tap: Left mouse click
-Two finger tap: Right mouse click
-Two finger double tap: ESC
-Two finger swipe (bottom to top): Toggles Click and drag mode
-Two finger swipe (left to right): Toggles between touch direct mode and touchpad mode
-Two finger swipe (top to bottom): Global Main Menu
-Three finger swipe: Arrow keys
-Pinch gesture: Enables/disables keyboard
-Keyboard spacebar: Pause"));
+		GUI::MessageDialog help(
+#if TARGET_OS_IOS
+			_("Gestures and controls:\n"
+			  "\n"
+			  "One finger tap: Left mouse click\n"
+			  "Two finger tap: Right mouse click\n"
+			  "Two finger double tap: ESC\n"
+			  "Two finger swipe (bottom to top): Toggles Click and drag mode\n"
+			  "Two finger swipe (left to right): Toggles between touch direct mode and touchpad mode\n"
+			  "Two finger swipe (right to left): Shows/hides on-screen controls\n"
+			  "Two finger swipe (top to bottom): Global Main Menu\n"
+			  "Three finger swipe: Arrow keys\n"
+			  "Pinch gesture: Enables/disables keyboard\n"
+			  "Keyboard spacebar: Pause"),
+#else // TVOS
+			_("Using the Apple TV remote control:\n"
+			  "\n"
+			  "Press Touch area: Left mouse click\n"
+			  "Press Play/Pause button: Right mouse click\n"
+			  "Press Back/Menu button in game: Global Main menu\n"
+			  "Press Back/Menu button in launcher: Apple TV Home\n"
+			  "Press and hold Play/Pause button: Show keyboard with extra keys\n"
+			  "Touch (not press) on top of Touch area: Up arrow key\n"
+			  "Touch (not press) on left of Touch area: Left arrow key\n"
+			  "Touch (not press) on right of Touch area: Right arrow key\n"
+			  "Touch (not press) on bottom of Touch area: Down arrow key\n"
+			  "Keyboard spacebar: Pause"),
+#endif
+			Common::U32String(_("Close")), Common::U32String(), Graphics::kTextAlignLeft);
 
 		help.runModal();
 		break;
@@ -134,24 +158,37 @@ bool IOS7OptionsWidget::save() {
 bool IOS7OptionsWidget::hasKeys() {
 	return ConfMan.hasKey("onscreen_control", _domain) ||
 	       ConfMan.hasKey("touchpad_mode", _domain) ||
-	       ConfMan.hasKey("clickanddrag_mode", _domain));
+	       ConfMan.hasKey("clickanddrag_mode", _domain);
 }
 
 void IOS7OptionsWidget::setEnabled(bool e) {
 	_enabled = e;
 
-	_onscreenCheckbox->setEnabled(e);
+#if TARGET_OS_IOS && defined (__IPHONE_15_0)
+	// On-screen controls (virtual controller is supported in iOS 15 and later)
+	if (@available(iOS 15.0, *)) {
+		_onscreenCheckbox->setEnabled(e);
+	} else {
+		_onscreenCheckbox->setEnabled(false);
+	}
+#else
+	_onscreenCheckbox->setEnabled(false);
+#endif
 	_touchpadCheckbox->setEnabled(e);
 	_clickAndDragdCheckbox->setEnabled(e);
 }
 
-
 GUI::OptionsContainerWidget *OSystem_iOS7::buildBackendOptionsWidget(GUI::GuiObject *boss, const Common::String &name, const Common::String &target) const {
 	return new IOS7OptionsWidget(boss, name, target);
 }
 
 void OSystem_iOS7::registerDefaultSettings(const Common::String &target) const {
-	ConfMan.registerDefault("onscreen_control", true);
-	ConfMan.registerDefault("touchpad_mode", true);
+	ConfMan.registerDefault("onscreen_control", false);
+	ConfMan.registerDefault("touchpad_mode", !iOS7_isBigDevice());
 	ConfMan.registerDefault("clickanddrag_mode", false);
 }
+
+void OSystem_iOS7::applyBackendSettings() {
+	_touchpadModeEnabled = ConfMan.getBool("touchpad_mode");
+	_mouseClickAndDragEnabled = ConfMan.getBool("clickanddrag_mode");
+}
diff --git a/backends/platform/ios7/ios7_osys_main.cpp b/backends/platform/ios7/ios7_osys_main.cpp
index d769cb4b325..abb274a23e3 100644
--- a/backends/platform/ios7/ios7_osys_main.cpp
+++ b/backends/platform/ios7/ios7_osys_main.cpp
@@ -87,12 +87,13 @@ public:
 OSystem_iOS7::OSystem_iOS7() :
 	_mixer(NULL), _lastMouseTap(0), _queuedEventTime(0),
 	_mouseNeedTextureUpdate(false), _secondaryTapped(false), _lastSecondaryTap(0),
-	_screenOrientation(kScreenOrientationFlippedLandscape), _mouseClickAndDragEnabled(false),
+	_screenOrientation(kScreenOrientationFlippedLandscape),
 	_gestureStartX(-1), _gestureStartY(-1), _fullScreenIsDirty(false), _fullScreenOverlayIsDirty(false),
 	_mouseDirty(false), _timeSuspended(0), _lastDragPosX(-1), _lastDragPosY(-1), _screenChangeCount(0),
 	_mouseCursorPaletteEnabled(false), _gfxTransactionError(kTransactionSuccess) {
 	_queuedInputEvent.type = Common::EVENT_INVALID;
-	_touchpadModeEnabled = !iOS7_isBigDevice();
+	_touchpadModeEnabled = ConfMan.getBool("touchpad_mode");
+	_mouseClickAndDragEnabled = ConfMan.getBool("clickanddrag_mode");
 
 	_chrootBasePath = iOS7_getDocumentsDir();
 	ChRootFilesystemFactory *chFsFactory = new ChRootFilesystemFactory(_chrootBasePath);
@@ -300,7 +301,6 @@ void OSystem_iOS7::delayMillis(uint msecs) {
 	usleep(msecs * 1000);
 }
 
-
 void OSystem_iOS7::setTimerCallback(TimerProc callback, int interval) {
 	//printf("setTimerCallback()\n");
 	dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
diff --git a/backends/platform/ios7/ios7_osys_main.h b/backends/platform/ios7/ios7_osys_main.h
index 6ce8f6bd71e..1bb3d815926 100644
--- a/backends/platform/ios7/ios7_osys_main.h
+++ b/backends/platform/ios7/ios7_osys_main.h
@@ -211,6 +211,10 @@ public:
 
 	virtual Common::String getDefaultLogFileName() override { return Common::String("/scummvm.log"); }
 
+	virtual GUI::OptionsContainerWidget* buildBackendOptionsWidget(GUI::GuiObject *boss, const Common::String &name, const Common::String &target) const override;
+	virtual void applyBackendSettings() override;
+	virtual void registerDefaultSettings(const Common::String &target) const override;
+
 protected:
 	void initVideoContext();
 	void updateOutputSurface();
diff --git a/backends/platform/ios7/module.mk b/backends/platform/ios7/module.mk
index ddda4a6f5ed..cd50f30a8cb 100644
--- a/backends/platform/ios7/module.mk
+++ b/backends/platform/ios7/module.mk
@@ -8,6 +8,7 @@ MODULE_OBJS := \
 	ios7_osys_misc.o \
 	ios7_misc.o \
 	ios7_main.o \
+	ios7_options.o \
 	ios7_video.o \
 	ios7_keyboard.o \
 	ios7_scummvm_view_controller.o \
diff --git a/po/POTFILES b/po/POTFILES
index 8d877da3faf..53b9faa7722 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -97,6 +97,7 @@ backends/platform/3ds/osystem-events.cpp
 backends/platform/android/options.cpp
 backends/platform/ds/ds-graphics.cpp
 backends/platform/ds/osystem_ds.cpp
+backends/platform/ios7/ios7_options.mm
 backends/platform/ios7/ios7_osys_events.cpp
 backends/platform/ios7/ios7_osys_main.cpp
 backends/platform/iphone/osys_events.cpp


Commit: 806e7e48244fdc8fd0ad9a39d5001d101035c9a5
    https://github.com/scummvm/scummvm/commit/806e7e48244fdc8fd0ad9a39d5001d101035c9a5
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2023-05-06T10:21:38+02:00

Commit Message:
IOS7: Remove legacy gesture recognizers

These gesture recognizers were inherited from the iphone port. The
ios7 port use the UIGestureRecognizers to accomplish the same.

Changed paths:
    backends/platform/ios7/ios7_osys_events.cpp
    backends/platform/ios7/ios7_osys_main.cpp
    backends/platform/ios7/ios7_osys_main.h


diff --git a/backends/platform/ios7/ios7_osys_events.cpp b/backends/platform/ios7/ios7_osys_events.cpp
index 9880ade53ab..14cf8f0072f 100644
--- a/backends/platform/ios7/ios7_osys_events.cpp
+++ b/backends/platform/ios7/ios7_osys_events.cpp
@@ -204,8 +204,6 @@ bool OSystem_iOS7::handleEvent_mouseUp(Common::Event &event, int x, int y) {
 
 bool OSystem_iOS7::handleEvent_secondMouseDown(Common::Event &event, int x, int y) {
 	_lastSecondaryDown = getMillis();
-	_gestureStartX = x;
-	_gestureStartY = y;
 
 	if (_mouseClickAndDragEnabled) {
 		event.type = Common::EVENT_LBUTTONUP;
@@ -306,68 +304,6 @@ bool OSystem_iOS7::handleEvent_mouseDragged(Common::Event &event, int x, int y)
 }
 
 bool OSystem_iOS7::handleEvent_mouseSecondDragged(Common::Event &event, int x, int y) {
-	if (_gestureStartX == -1 || _gestureStartY == -1) {
-		return false;
-	}
-
-	static const int kNeededLength = 100;
-	static const int kMaxDeviation = 20;
-
-	int vecX = (x - _gestureStartX);
-	int vecY = (y - _gestureStartY);
-
-	int absX = abs(vecX);
-	int absY = abs(vecY);
-
-	//printf("(%d, %d)\n", vecX, vecY);
-
-	if (absX >= kNeededLength || absY >= kNeededLength) { // Long enough gesture to react upon.
-		_gestureStartX = -1;
-		_gestureStartY = -1;
-
-		if (absX < kMaxDeviation && vecY >= kNeededLength) {
-			// Swipe down
-			event.type = Common::EVENT_MAINMENU;
-			_queuedInputEvent.type = Common::EVENT_INVALID;
-
-			_queuedEventTime = getMillis() + kQueuedInputEventDelay;
-			return true;
-		}
-
-		if (absX < kMaxDeviation && -vecY >= kNeededLength) {
-			// Swipe up
-			_mouseClickAndDragEnabled = !_mouseClickAndDragEnabled;
-			Common::U32String dialogMsg;
-			if (_mouseClickAndDragEnabled) {
-				_touchpadModeEnabled = false;
-				dialogMsg = _("Mouse-click-and-drag mode enabled.");
-			} else
-				dialogMsg = _("Mouse-click-and-drag mode disabled.");
-			GUI::TimedMessageDialog dialog(dialogMsg, 1500);
-			dialog.runModal();
-			return false;
-		}
-
-		if (absY < kMaxDeviation && vecX >= kNeededLength) {
-			// Swipe right
-			_touchpadModeEnabled = !_touchpadModeEnabled;
-			Common::U32String dialogMsg;
-			if (_touchpadModeEnabled)
-				dialogMsg = _("Touchpad mode enabled.");
-			else
-				dialogMsg = _("Touchpad mode disabled.");
-			GUI::TimedMessageDialog dialog(dialogMsg, 1500);
-			dialog.runModal();
-			return false;
-
-		}
-
-		if (absY < kMaxDeviation && -vecX >= kNeededLength) {
-			// Swipe left
-			return false;
-		}
-	}
-
 	return false;
 }
 
diff --git a/backends/platform/ios7/ios7_osys_main.cpp b/backends/platform/ios7/ios7_osys_main.cpp
index abb274a23e3..5378f81ed31 100644
--- a/backends/platform/ios7/ios7_osys_main.cpp
+++ b/backends/platform/ios7/ios7_osys_main.cpp
@@ -88,7 +88,7 @@ OSystem_iOS7::OSystem_iOS7() :
 	_mixer(NULL), _lastMouseTap(0), _queuedEventTime(0),
 	_mouseNeedTextureUpdate(false), _secondaryTapped(false), _lastSecondaryTap(0),
 	_screenOrientation(kScreenOrientationFlippedLandscape),
-	_gestureStartX(-1), _gestureStartY(-1), _fullScreenIsDirty(false), _fullScreenOverlayIsDirty(false),
+	_fullScreenIsDirty(false), _fullScreenOverlayIsDirty(false),
 	_mouseDirty(false), _timeSuspended(0), _lastDragPosX(-1), _lastDragPosY(-1), _screenChangeCount(0),
 	_mouseCursorPaletteEnabled(false), _gfxTransactionError(kTransactionSuccess) {
 	_queuedInputEvent.type = Common::EVENT_INVALID;
diff --git a/backends/platform/ios7/ios7_osys_main.h b/backends/platform/ios7/ios7_osys_main.h
index 1bb3d815926..361a3ac1ef2 100644
--- a/backends/platform/ios7/ios7_osys_main.h
+++ b/backends/platform/ios7/ios7_osys_main.h
@@ -87,7 +87,6 @@ protected:
 	bool _secondaryTapped;
 	long _lastSecondaryDown;
 	long _lastSecondaryTap;
-	int _gestureStartX, _gestureStartY;
 	bool _mouseClickAndDragEnabled;
 	bool _touchpadModeEnabled;
 	int _lastPadX;


Commit: 560dfbf2bcb6c876fe44b8c631bb0589569b8362
    https://github.com/scummvm/scummvm/commit/560dfbf2bcb6c876fe44b8c631bb0589569b8362
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2023-05-06T10:21:47+02:00

Commit Message:
IOS7: Don't disable "touchpad" mode when enabling "click-and-drag"

The "touchpad" mode and "click-and-drag" mode was mutual exclusive
when enabling "click-and-drag" using swipe gesture.

The difference between "touchpad" mode and "click-and-drag" mode
is how the button down/up events are sent. In touchpad mode the
button down and button up events are sent on touches ended, while
in click-and-drag the button down event is sent on touches began
and button up on touches ended.

Changed paths:
    backends/platform/ios7/ios7_osys_events.cpp


diff --git a/backends/platform/ios7/ios7_osys_events.cpp b/backends/platform/ios7/ios7_osys_events.cpp
index 14cf8f0072f..17f6b9b49ca 100644
--- a/backends/platform/ios7/ios7_osys_events.cpp
+++ b/backends/platform/ios7/ios7_osys_events.cpp
@@ -406,7 +406,6 @@ bool OSystem_iOS7::handleEvent_swipe(Common::Event &event, int direction, int to
 			_mouseClickAndDragEnabled = !_mouseClickAndDragEnabled;
 			Common::U32String dialogMsg;
 			if (_mouseClickAndDragEnabled) {
-				_touchpadModeEnabled = false;
 				dialogMsg = _("Mouse-click-and-drag mode enabled.");
 			} else
 				dialogMsg = _("Mouse-click-and-drag mode disabled.");


Commit: 7c903e4a55b684899d7921a46c9f3d90b493c973
    https://github.com/scummvm/scummvm/commit/7c903e4a55b684899d7921a46c9f3d90b493c973
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2023-05-06T10:21:54+02:00

Commit Message:
IOS7: Write changes to mouse modes to ConfMan

When changing "Touchpad mode" or "Mouse-click-and-drag mode" by
swipe gestures, these changes must be stored in ConfMan.

Changed paths:
    backends/platform/ios7/ios7_osys_events.cpp


diff --git a/backends/platform/ios7/ios7_osys_events.cpp b/backends/platform/ios7/ios7_osys_events.cpp
index 17f6b9b49ca..4d357a80828 100644
--- a/backends/platform/ios7/ios7_osys_events.cpp
+++ b/backends/platform/ios7/ios7_osys_events.cpp
@@ -24,6 +24,7 @@
 
 #include "gui/message.h"
 #include "common/translation.h"
+#include "common/config-manager.h"
 
 #include "backends/platform/ios7/ios7_osys_main.h"
 
@@ -404,6 +405,8 @@ bool OSystem_iOS7::handleEvent_swipe(Common::Event &event, int direction, int to
 		switch ((UIViewSwipeDirection)direction) {
 		case kUIViewSwipeUp: {
 			_mouseClickAndDragEnabled = !_mouseClickAndDragEnabled;
+			ConfMan.setBool("clickanddrag_mode", _mouseClickAndDragEnabled);
+			ConfMan.flushToDisk();
 			Common::U32String dialogMsg;
 			if (_mouseClickAndDragEnabled) {
 				dialogMsg = _("Mouse-click-and-drag mode enabled.");
@@ -425,6 +428,8 @@ bool OSystem_iOS7::handleEvent_swipe(Common::Event &event, int direction, int to
 		case kUIViewSwipeRight: {
 			// Swipe right
 			_touchpadModeEnabled = !_touchpadModeEnabled;
+			ConfMan.setBool("touchpad_mode", _touchpadModeEnabled);
+			ConfMan.flushToDisk();
 			Common::U32String dialogMsg;
 			if (_touchpadModeEnabled)
 				dialogMsg = _("Touchpad mode enabled.");


Commit: cf7e3256eec37ffb83a0652d3c618997ee78cdc6
    https://github.com/scummvm/scummvm/commit/cf7e3256eec37ffb83a0652d3c618997ee78cdc6
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2023-05-06T10:22:01+02:00

Commit Message:
IOS7: Call correct delegate method

The wrong delegate method was called for touchesCancelled. This
led to button presses ended too early if moving the fingers.

Changed paths:
    backends/platform/ios7/ios7_video.mm


diff --git a/backends/platform/ios7/ios7_video.mm b/backends/platform/ios7/ios7_video.mm
index 25f97c15eda..7f3412739b5 100644
--- a/backends/platform/ios7/ios7_video.mm
+++ b/backends/platform/ios7/ios7_video.mm
@@ -981,7 +981,7 @@ uint getSizeNextPOT(uint size) {
 - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
 	for (GameController *c : _controllers) {
 		if ([c isKindOfClass:TouchController.class]) {
-			[(TouchController *)c touchesEnded:touches withEvent:event];
+			[(TouchController *)c touchesCancelled:touches withEvent:event];
 		}
 	}
 }


Commit: a7d12394b094ce9a1b2d0b6b98e9af900ad76052
    https://github.com/scummvm/scummvm/commit/a7d12394b094ce9a1b2d0b6b98e9af900ad76052
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2023-05-06T10:22:09+02:00

Commit Message:
IOS7: Add dpad actions to gamepad controller

Some game engines requires the dpad to control a character. The GRIM
engine is an example of this where the user steer the character by
the arrow keys or dpad controller.

Changed paths:
    backends/platform/ios7/ios7_gamepad_controller.mm


diff --git a/backends/platform/ios7/ios7_gamepad_controller.mm b/backends/platform/ios7/ios7_gamepad_controller.mm
index 07af27f7d34..f8953768503 100644
--- a/backends/platform/ios7/ios7_gamepad_controller.mm
+++ b/backends/platform/ios7/ios7_gamepad_controller.mm
@@ -91,6 +91,14 @@
 			[self handleJoystickAxisMotionX:x andY:0-y forJoystick:kGameControllerJoystickRight];
 		};
 
+		_controller.extendedGamepad.dpad.valueChangedHandler = ^(GCControllerDirectionPad * _Nonnull dpad, float xValue, float yValue) {
+			// Negative values are left/down, positive are right/up, 0 is no press
+			[self handleJoystickButtonAction:Common::JOYSTICK_BUTTON_DPAD_LEFT isPressed:(xValue < 0)];
+			[self handleJoystickButtonAction:Common::JOYSTICK_BUTTON_DPAD_RIGHT isPressed:(xValue > 0)];
+			[self handleJoystickButtonAction:Common::JOYSTICK_BUTTON_DPAD_UP isPressed:(yValue > 0)];
+			[self handleJoystickButtonAction:Common::JOYSTICK_BUTTON_DPAD_DOWN isPressed:(yValue < 0)];
+		};
+
 		_controller.extendedGamepad.buttonA.valueChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
 			[self handleJoystickButtonAction:Common::JOYSTICK_BUTTON_A isPressed:pressed];
 		};


Commit: 920faab9a99bfd12772c93d26aeb1f32088a1b88
    https://github.com/scummvm/scummvm/commit/920faab9a99bfd12772c93d26aeb1f32088a1b88
Author: Lars Sundström (lars.sundstrom at audiodo.com)
Date: 2023-05-06T10:22:20+02:00

Commit Message:
IOS7: Implement Apple GCVirtualController

Apple introduced the GCVirtualController in iOS 15 which is a
software emulation of a real controller. The virtual controllers
can be configurable with different inputs. See more info at:
https://developer.apple.com/documentation/gamecontroller/gcvirtualcontroller

A simple gamepad configuration with a dPad and A and B buttons
is added. The user can enable/disable the virtual game controller
swiping two fingers right to left, or through the port-specific
option dialog.

Changed paths:
    backends/platform/ios7/ios7_gamepad_controller.h
    backends/platform/ios7/ios7_gamepad_controller.mm
    backends/platform/ios7/ios7_options.mm
    backends/platform/ios7/ios7_osys_events.cpp
    backends/platform/ios7/ios7_osys_main.h
    backends/platform/ios7/ios7_osys_video.mm
    backends/platform/ios7/ios7_video.h
    backends/platform/ios7/ios7_video.mm


diff --git a/backends/platform/ios7/ios7_gamepad_controller.h b/backends/platform/ios7/ios7_gamepad_controller.h
index 6e2ebd797dd..600dc441d8c 100644
--- a/backends/platform/ios7/ios7_gamepad_controller.h
+++ b/backends/platform/ios7/ios7_gamepad_controller.h
@@ -28,6 +28,7 @@ API_AVAILABLE(ios(7.0))
 @interface GamepadController : GameController
 
 - (id)initWithView:(iPhoneView *)view;
+- (void)virtualController:(bool)connect;
 
 @end
 
diff --git a/backends/platform/ios7/ios7_gamepad_controller.mm b/backends/platform/ios7/ios7_gamepad_controller.mm
index f8953768503..f64410d89fd 100644
--- a/backends/platform/ios7/ios7_gamepad_controller.mm
+++ b/backends/platform/ios7/ios7_gamepad_controller.mm
@@ -29,6 +29,14 @@
 
 @implementation GamepadController {
 	GCController *_controller;
+#if TARGET_OS_IOS
+#ifdef __IPHONE_15_0
+	API_AVAILABLE(ios(15.0))
+	GCVirtualController *_virtualController;
+	API_AVAILABLE(ios(15.0))
+	GCVirtualControllerConfiguration *_config;
+#endif
+#endif
 }
 
 @dynamic view;
@@ -42,9 +50,34 @@
 												 name:@"GCControllerDidConnectNotification"
 											   object:nil];
 
+#if TARGET_OS_IOS
+#ifdef __IPHONE_15_0
+	if (@available(iOS 15.0, *)) {
+		// Configure a simple game controller with dPad and A and B buttons
+		_config = [[GCVirtualControllerConfiguration alloc] init];
+		_config.elements = [[NSSet alloc] initWithObjects:GCInputDirectionPad, GCInputButtonA, GCInputButtonB, nil];
+		_virtualController = [[GCVirtualController alloc] initWithConfiguration:_config];
+	}
+#endif
+#endif
 	return self;
 }
 
+- (void)virtualController:(bool)connect {
+#if TARGET_OS_IOS
+#ifdef __IPHONE_15_0
+	if (@available(iOS 15.0, *)) {
+		if (connect && ![self isConnected]) {
+			[_virtualController connectWithReplyHandler:^(NSError * _Nullable error) { }];		}
+		else if (!connect && [self isConnected]) {
+			[_virtualController disconnect];
+			[self setIsConnected:NO];
+		}
+	}
+#endif
+#endif
+}
+
 - (void)controllerDidConnect:(NSNotification *)notification {
 	_controller = (GCController*)notification.object;
 
diff --git a/backends/platform/ios7/ios7_options.mm b/backends/platform/ios7/ios7_options.mm
index 5c87211a1c5..77c86fff7ee 100644
--- a/backends/platform/ios7/ios7_options.mm
+++ b/backends/platform/ios7/ios7_options.mm
@@ -189,6 +189,7 @@ void OSystem_iOS7::registerDefaultSettings(const Common::String &target) const {
 }
 
 void OSystem_iOS7::applyBackendSettings() {
+	virtualController(ConfMan.getBool("onscreen_control"));
 	_touchpadModeEnabled = ConfMan.getBool("touchpad_mode");
 	_mouseClickAndDragEnabled = ConfMan.getBool("clickanddrag_mode");
 }
diff --git a/backends/platform/ios7/ios7_osys_events.cpp b/backends/platform/ios7/ios7_osys_events.cpp
index 4d357a80828..f0542fde8d6 100644
--- a/backends/platform/ios7/ios7_osys_events.cpp
+++ b/backends/platform/ios7/ios7_osys_events.cpp
@@ -440,6 +440,15 @@ bool OSystem_iOS7::handleEvent_swipe(Common::Event &event, int direction, int to
 			return false;
 		}
 
+		case kUIViewSwipeLeft: {
+			// Swipe left
+			bool connect = !ConfMan.getBool("onscreen_control");
+			ConfMan.setBool("onscreen_control", connect);
+			ConfMan.flushToDisk();
+			virtualController(connect);
+			return false;
+		}
+
 		default:
 			break;
 		}
diff --git a/backends/platform/ios7/ios7_osys_main.h b/backends/platform/ios7/ios7_osys_main.h
index 361a3ac1ef2..0ecb7104e54 100644
--- a/backends/platform/ios7/ios7_osys_main.h
+++ b/backends/platform/ios7/ios7_osys_main.h
@@ -207,6 +207,7 @@ public:
 	Common::String getSystemLanguage() const override;
 
 	bool isConnectionLimited() override;
+	void virtualController(bool connect);
 
 	virtual Common::String getDefaultLogFileName() override { return Common::String("/scummvm.log"); }
 
diff --git a/backends/platform/ios7/ios7_osys_video.mm b/backends/platform/ios7/ios7_osys_video.mm
index e4a3e5b0ce5..a98432f8803 100644
--- a/backends/platform/ios7/ios7_osys_video.mm
+++ b/backends/platform/ios7/ios7_osys_video.mm
@@ -486,6 +486,12 @@ void OSystem_iOS7::warpMouse(int x, int y) {
 	_mouseDirty = true;
 }
 
+void OSystem_iOS7::virtualController(bool connect) {
+	execute_on_main_thread(^ {
+		[[iOS7AppDelegate iPhoneView] virtualController:connect];
+	});
+}
+
 void OSystem_iOS7::dirtyFullScreen() {
 	if (!_fullScreenIsDirty) {
 		_dirtyRects.clear();
diff --git a/backends/platform/ios7/ios7_video.h b/backends/platform/ios7/ios7_video.h
index e4dccf2fa3d..55e8e100eb6 100644
--- a/backends/platform/ios7/ios7_video.h
+++ b/backends/platform/ios7/ios7_video.h
@@ -143,6 +143,7 @@ uint getSizeNextPOT(uint size);
 - (BOOL)isTouchControllerConnected;
 - (BOOL)isMouseControllerConnected;
 - (BOOL)isGamepadControllerConnected;
+- (void)virtualController:(bool)connect;
 @end
 
 #endif
diff --git a/backends/platform/ios7/ios7_video.mm b/backends/platform/ios7/ios7_video.mm
index 7f3412739b5..4153e305d2d 100644
--- a/backends/platform/ios7/ios7_video.mm
+++ b/backends/platform/ios7/ios7_video.mm
@@ -931,6 +931,16 @@ uint getSizeNextPOT(uint size) {
 	}
 }
 
+- (void)virtualController:(bool)connect {
+	if (@available(iOS 15.0, *)) {
+		for (GameController *c : _controllers) {
+			if ([c isKindOfClass:GamepadController.class]) {
+				[(GamepadController*)c virtualController:connect];
+			}
+		}
+	}
+}
+
 #if TARGET_OS_IOS
 - (void)interfaceOrientationChanged:(UIInterfaceOrientation)orientation {
 	[self addEvent:InternalEvent(kInputOrientationChanged, orientation, 0)];




More information about the Scummvm-git-logs mailing list