[Scummvm-git-logs] scummvm master -> 04b5507e244864df7b7c13712922478e2903b7eb

criezy noreply at scummvm.org
Mon Aug 8 20:09:05 UTC 2022


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

Summary:
4133cf4b9f IOS7: Add GameController capability
f8604faf41 IOS7: Set view controller's preference to lock the pointer
6387046666 IOS7: Make iPhoneView addEvent and getMouseCoords functions public
877d1ffa67 IOS7: Add pointerPosition property to iPhoneView class
15507ebc50 IOS7: Add GameController base class
db2e15b3f1 IOS7: Factor out touch pointer handling to TouchController class
c3513a151e IOS7: Add Mouse support using GameController framework
f18305e715 IOS7: Add support for Joystick actions in GameController
8d395fd790 IOS7: Add support for Extended Gamepad controllers
d76bc708c0 IOS7: Add isConnected property to GameControllers
e7759ac0ef IOS7: Implement getHardwareInputSet to get connected devices
f9e1806b14 IOS7: Update README.md with support for external devices
04b5507e24 DOCS: Add section about Game Controller support for iOS


Commit: 4133cf4b9f1dff710f92be1c0d5dbc9bfa774563
    https://github.com/scummvm/scummvm/commit/4133cf4b9f1dff710f92be1c0d5dbc9bfa774563
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2022-08-08T21:08:56+01:00

Commit Message:
IOS7: Add GameController capability

Add the GameController framework to the project and enable support for
controller user interaction in the Info.plist file. This allows for
Game Controller compatible devices to notify the application when
connected.

Add GameController framework to configure and ports.mk if not using
Xcode to build the target.

Changed paths:
    configure
    devtools/create_project/xcode.cpp
    dists/ios7/Info.plist
    dists/ios7/Info.plist.in
    ports.mk


diff --git a/configure b/configure
index 062749346e6..a441cc5345e 100755
--- a/configure
+++ b/configure
@@ -3699,6 +3699,7 @@ case $_backend in
 		append_var LIBS "-lobjc -framework UIKit -framework CoreGraphics -framework OpenGLES"
 		append_var LIBS "-framework QuartzCore -framework CoreFoundation -framework Foundation"
 		append_var LIBS "-framework AudioToolbox -framework CoreAudio -framework SystemConfiguration "
+		append_var LIBS "-framework GameController"
 		if [ $_host_cpu = 'aarch64' ]; then
 			append_var LDFLAGS "-miphoneos-version-min=7.1 -arch arm64"
 			append_var CFLAGS "-miphoneos-version-min=7.1 -arch arm64"
diff --git a/devtools/create_project/xcode.cpp b/devtools/create_project/xcode.cpp
index b1dfaa880bd..ae63756d14c 100644
--- a/devtools/create_project/xcode.cpp
+++ b/devtools/create_project/xcode.cpp
@@ -444,6 +444,7 @@ void XcodeProvider::setupFrameworksBuildPhase(const BuildSetup &setup) {
 	DEF_SYSFRAMEWORK("CoreGraphics");
 	DEF_SYSFRAMEWORK("CoreFoundation");
 	DEF_SYSFRAMEWORK("Foundation");
+	DEF_SYSFRAMEWORK("GameController");
 	DEF_SYSFRAMEWORK("IOKit");
 	DEF_SYSFRAMEWORK("OpenGL");
 	DEF_SYSFRAMEWORK("OpenGLES");
@@ -555,6 +556,7 @@ void XcodeProvider::setupFrameworksBuildPhase(const BuildSetup &setup) {
 	frameworks_iOS.push_back("CoreGraphics.framework");
 	frameworks_iOS.push_back("CoreFoundation.framework");
 	frameworks_iOS.push_back("Foundation.framework");
+	frameworks_iOS.push_back("GameController.framework");
 	frameworks_iOS.push_back("UIKit.framework");
 	frameworks_iOS.push_back("SystemConfiguration.framework");
 	frameworks_iOS.push_back("AudioToolbox.framework");
diff --git a/dists/ios7/Info.plist b/dists/ios7/Info.plist
index a593b700247..27fd40ce870 100644
--- a/dists/ios7/Info.plist
+++ b/dists/ios7/Info.plist
@@ -24,6 +24,8 @@
 	<string>????</string>
 	<key>CFBundleVersion</key>
 	<string>2.7.0git</string>
+	<key>GCSupportsControllerUserInteraction</key>
+	<true/>
 	<key>LSSupportsOpeningDocumentsInPlace</key>
 	<true/>
 	<key>UIApplicationExitsOnSuspend</key>
diff --git a/dists/ios7/Info.plist.in b/dists/ios7/Info.plist.in
index 68d8a506df4..d192fc8530a 100644
--- a/dists/ios7/Info.plist.in
+++ b/dists/ios7/Info.plist.in
@@ -24,6 +24,8 @@
 	<string>????</string>
 	<key>CFBundleVersion</key>
 	<string>@VERSION@</string>
+	<key>GCSupportsControllerUserInteraction</key>
+	<true/>
 	<key>LSSupportsOpeningDocumentsInPlace</key>
 	<true/>
 	<key>UIApplicationExitsOnSuspend</key>
diff --git a/ports.mk b/ports.mk
index 6418cfdefab..a518a9ae4e8 100644
--- a/ports.mk
+++ b/ports.mk
@@ -499,7 +499,7 @@ scummvm-static: $(DETECT_OBJS) $(OBJS)
 iphone: $(DETECT_OBJS) $(OBJS)
 	+$(LD) $(LDFLAGS) -o scummvm $(DETECT_OBJS) $(OBJS) \
 		$(OSX_STATIC_LIBS) \
-		-framework UIKit -framework CoreGraphics -framework OpenGLES \
+		-framework UIKit -framework CoreGraphics -framework OpenGLES -framework GameController \
 		-framework CoreFoundation -framework QuartzCore -framework Foundation \
 		-framework AudioToolbox -framework CoreAudio -framework SystemConfiguration -lobjc -lz
 


Commit: f8604faf41909addf5ed7cea90ed9d147ae8a748
    https://github.com/scummvm/scummvm/commit/f8604faf41909addf5ed7cea90ed9d147ae8a748
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2022-08-08T21:08:56+01:00

Commit Message:
IOS7: Set view controller's preference to lock the pointer

Setting this property to true indicates the view controller’s preference
to lock the pointer, although the system may not honor the request.

For the system to consider locking the pointer:
The scene must be full screen, not in Split View or Slide Over, with no
other apps in Slide Over.
The scene must be in the UISceneActivationStateForegroundActive state.

The ScummVM iOS7 client fulfills the above so the pointer is locked.
Locking the pointer hides the OS cursor (the dot), however that's wanted
since the ScummVM engine draws its own pointer.

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


diff --git a/backends/platform/ios7/ios7_scummvm_view_controller.mm b/backends/platform/ios7/ios7_scummvm_view_controller.mm
index 483f656cf4b..0072f909b78 100644
--- a/backends/platform/ios7/ios7_scummvm_view_controller.mm
+++ b/backends/platform/ios7/ios7_scummvm_view_controller.mm
@@ -32,4 +32,9 @@
 	return YES;
 }
 
+- (BOOL)prefersPointerLocked {
+	/* This hides the OS cursor so ScummVM has to draw one */
+	return YES;
+}
+
 @end


Commit: 63870466665c812dd6f906ac4aa6f98013d4d211
    https://github.com/scummvm/scummvm/commit/63870466665c812dd6f906ac4aa6f98013d4d211
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2022-08-08T21:08:56+01:00

Commit Message:
IOS7: Make iPhoneView addEvent and getMouseCoords functions public

Squash with the one above

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


diff --git a/backends/platform/ios7/ios7_video.h b/backends/platform/ios7/ios7_video.h
index ddfde9777eb..54b6ce42862 100644
--- a/backends/platform/ios7/ios7_video.h
+++ b/backends/platform/ios7/ios7_video.h
@@ -128,8 +128,11 @@ typedef struct {
 - (void) beginBackgroundSaveStateTask;
 - (void) endBackgroundSaveStateTask;
 
+- (void)addEvent:(InternalEvent)event;
 - (bool)fetchEvent:(InternalEvent *)event;
 
+- (bool)getMouseCoords:(CGPoint)point eventX:(int *)x eventY:(int *)y;
+
 @end
 
 #endif


Commit: 877d1ffa6717718d341a8244a6ecf161aba93de0
    https://github.com/scummvm/scummvm/commit/877d1ffa6717718d341a8244a6ecf161aba93de0
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2022-08-08T21:08:56+01:00

Commit Message:
IOS7: Add pointerPosition property to iPhoneView class

Let the view keep the current pointer position as a property, allowing
it to be modified by controllers.

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


diff --git a/backends/platform/ios7/ios7_video.h b/backends/platform/ios7/ios7_video.h
index 54b6ce42862..0bbc5c70b3d 100644
--- a/backends/platform/ios7/ios7_video.h
+++ b/backends/platform/ios7/ios7_video.h
@@ -92,6 +92,8 @@ typedef struct {
 	UITouch *_secondTouch;
 }
 
+ at property (nonatomic, assign) CGPoint pointerPosition;
+
 - (id)initWithFrame:(struct CGRect)frame;
 
 - (VideoContext *)getVideoContext;
diff --git a/backends/platform/ios7/ios7_video.mm b/backends/platform/ios7/ios7_video.mm
index dda9dc6b707..5c8427fbce6 100644
--- a/backends/platform/ios7/ios7_video.mm
+++ b/backends/platform/ios7/ios7_video.mm
@@ -96,6 +96,8 @@ uint getSizeNextPOT(uint size) {
 
 @implementation iPhoneView
 
+ at synthesize pointerPosition;
+
 + (Class)layerClass {
 	return [CAEAGLLayer class];
 }


Commit: 15507ebc50ddd0e373f2ad2af0833f1b548908c0
    https://github.com/scummvm/scummvm/commit/15507ebc50ddd0e373f2ad2af0833f1b548908c0
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2022-08-08T21:08:56+01:00

Commit Message:
IOS7: Add GameController base class

Add a GameController base class which handles user inputs from a
controller. The input is either a pointer move or a button action.
If the input is a pointer move, make sure that the move is within
valid coordinates in the game (respecting the resolution which is
most probably lower than the view resolution).

Changed paths:
  A backends/platform/ios7/ios7_game_controller.h
  A backends/platform/ios7/ios7_game_controller.mm
    backends/platform/ios7/module.mk


diff --git a/backends/platform/ios7/ios7_game_controller.h b/backends/platform/ios7/ios7_game_controller.h
new file mode 100644
index 00000000000..480282e475a
--- /dev/null
+++ b/backends/platform/ios7/ios7_game_controller.h
@@ -0,0 +1,46 @@
+/* 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/>.
+ *
+ */
+
+#ifndef BACKENDS_PLATFORM_IOS7_IOS7_GAME_CONTROLLER_H
+#define BACKENDS_PLATFORM_IOS7_IOS7_GAME_CONTROLLER_H
+
+#include <UIKit/UIKit.h>
+
+ at class iPhoneView;
+
+ at interface GameController : NSObject
+
+typedef enum {
+	kGameControllerMouseButtonLeft = 0,
+	kGameControllerMouseButtonRight,
+	kGameControllerMouseButtonMiddle,
+} GameControllerMouseButton;
+
+ at property (nonatomic, readwrite, retain) iPhoneView *view;
+
+- (id)initWithView:(iPhoneView *)view;
+
+- (void)handlePointerMoveTo:(CGPoint)point;
+- (void)handleMouseButtonAction:(GameControllerMouseButton)button isPressed:(bool)pressed at:(CGPoint)point;
+
+ at end
+
+#endif /* BACKENDS_PLATFORM_IOS7_IOS7_GAME_CONTROLLER_H */
diff --git a/backends/platform/ios7/ios7_game_controller.mm b/backends/platform/ios7/ios7_game_controller.mm
new file mode 100644
index 00000000000..cd197bfebfb
--- /dev/null
+++ b/backends/platform/ios7/ios7_game_controller.mm
@@ -0,0 +1,101 @@
+/* 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/>.
+ *
+ */
+
+// Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "backends/platform/ios7/ios7_game_controller.h"
+#include "backends/platform/ios7/ios7_video.h"
+
+ at interface GameController()
+ at property (nonatomic, assign) BOOL firstButtonPressed;
+ at property (nonatomic, assign) BOOL secondButtonPressed;
+ at end
+
+ at implementation GameController
+
+ at synthesize view;
+
+- (id)initWithView:(iPhoneView *)view {
+	self = [super init];
+	if (self) {
+		[self setView:view];
+	}
+	_firstButtonPressed = _secondButtonPressed = NO;
+	return self;
+}
+
+- (void)handlePointerMoveTo:(CGPoint)point {
+	int x, y;
+
+	// Only set valid mouse coordinates in games
+	if (![view getMouseCoords:point eventX:&x eventY:&y]) {
+		return;
+	}
+
+	[view setPointerPosition:point];
+
+	if (_firstButtonPressed) {
+		[view addEvent:InternalEvent(kInputMouseDragged, x, y)];
+	} else if (_secondButtonPressed) {
+		[view addEvent:InternalEvent(kInputMouseSecondDragged, x, y)];
+	} else {
+		[view addEvent:InternalEvent(kInputMouseDragged, x, y)];
+	}
+}
+
+- (void)handleMouseButtonAction:(GameControllerMouseButton)button isPressed:(bool)pressed at:(CGPoint)point{
+	int x, y;
+
+	// Only set valid mouse coordinates in games
+	if (![view getMouseCoords:[view pointerPosition] eventX:&x eventY:&y]) {
+		return;
+	}
+
+	[view setPointerPosition:point];
+
+	switch (button) {
+	case kGameControllerMouseButtonLeft:
+		if (pressed) {
+			_firstButtonPressed = YES;
+			[view addEvent:InternalEvent(kInputMouseDown, x, y)];
+		} else {
+			_firstButtonPressed = NO;
+			[view addEvent:InternalEvent(kInputMouseUp, x, y)];
+		}
+		break;
+
+	case kGameControllerMouseButtonRight:
+		if (pressed) {
+			_secondButtonPressed = YES;
+			[view addEvent:InternalEvent(kInputMouseSecondDown, x, y)];
+		} else {
+			_secondButtonPressed = NO;
+			[view addEvent:InternalEvent(kInputMouseSecondUp, x, y)];
+		}
+		break;
+
+	default:
+		break;
+	}
+}
+
+ at end
diff --git a/backends/platform/ios7/module.mk b/backends/platform/ios7/module.mk
index 4b821fef51b..780f4b0c31d 100644
--- a/backends/platform/ios7/module.mk
+++ b/backends/platform/ios7/module.mk
@@ -10,7 +10,8 @@ MODULE_OBJS := \
 	ios7_video.o \
 	ios7_keyboard.o \
 	ios7_scummvm_view_controller.o \
-	ios7_app_delegate.o
+	ios7_app_delegate.o \
+	ios7_game_controller.o
 
 # We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
 MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS))


Commit: db2e15b3f19fa8657251ead728fee99095dc727f
    https://github.com/scummvm/scummvm/commit/db2e15b3f19fa8657251ead728fee99095dc727f
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2022-08-08T21:08:56+01:00

Commit Message:
IOS7: Factor out touch pointer handling to TouchController class

Move touch inputs to a TouchController class to move some logic from the
iPhoneView class. Only do this for touches on screen since connected
trackpads can generate touches as well. The latter ones are of type
UITouchTypeIndirectPointer while touches on screen are of type
UITouchTypeDirect. They are separated thanks to the preference key
UIApplicationSupportsIndirectInputEvents set to YES in Info.plist.
Without the preference above, there is no way to distinguish touches
from screen from a trackpad.

Changed paths:
  A backends/platform/ios7/ios7_touch_controller.h
  A backends/platform/ios7/ios7_touch_controller.mm
    backends/platform/ios7/ios7_video.h
    backends/platform/ios7/ios7_video.mm
    backends/platform/ios7/module.mk
    dists/ios7/Info.plist
    dists/ios7/Info.plist.in


diff --git a/backends/platform/ios7/ios7_touch_controller.h b/backends/platform/ios7/ios7_touch_controller.h
new file mode 100644
index 00000000000..9db4ad1f97c
--- /dev/null
+++ b/backends/platform/ios7/ios7_touch_controller.h
@@ -0,0 +1,38 @@
+/* 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/>.
+ *
+ */
+
+#ifndef BACKENDS_PLATFORM_IOS7_IOS7_TOUCH_CONTROLLER_H
+#define BACKENDS_PLATFORM_IOS7_IOS7_TOUCH_CONTROLLER_H
+
+#include "backends/platform/ios7/ios7_game_controller.h"
+
+ at interface TouchController : GameController
+
+- (id)initWithView:(iPhoneView *)view;
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
+- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
+- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
+
+ at end
+
+#endif /* BACKENDS_PLATFORM_IOS7_IOS7_TOUCH_CONTROLLER_H */
diff --git a/backends/platform/ios7/ios7_touch_controller.mm b/backends/platform/ios7/ios7_touch_controller.mm
new file mode 100644
index 00000000000..6438c6b17e5
--- /dev/null
+++ b/backends/platform/ios7/ios7_touch_controller.mm
@@ -0,0 +1,105 @@
+/* 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/>.
+ *
+ */
+
+// Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "backends/platform/ios7/ios7_touch_controller.h"
+#include "backends/platform/ios7/ios7_video.h"
+
+ at implementation TouchController {
+	UITouch *_firstTouch;
+	UITouch *_secondTouch;
+}
+
+ at dynamic view;
+
+- (id)initWithView:(iPhoneView *)view {
+	self = [super initWithView:view];
+
+	_firstTouch = NULL;
+	_secondTouch = NULL;
+
+	return self;
+}
+
+- (UITouch *)secondTouchOtherTouchThan:(UITouch *)touch in:(NSSet *)set {
+	NSArray *all = [set allObjects];
+	for (UITouch *t in all) {
+		if (t != touch) {
+			return t;
+		}
+	}
+	return nil;
+}
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
+	NSSet *allTouches = [event allTouches];
+	if (allTouches.count == 1) {
+		_firstTouch = [allTouches anyObject];
+		if (_firstTouch.type == UITouchTypeDirect) {
+			// Move the pointer to the new position
+			[self handlePointerMoveTo:[_firstTouch locationInView: [self view]]];
+			[self handleMouseButtonAction:kGameControllerMouseButtonLeft isPressed:YES at:[_firstTouch locationInView:[self view]]];
+		}
+	} else if (allTouches.count == 2) {
+		_secondTouch = [self secondTouchOtherTouchThan:_firstTouch in:allTouches];
+		if (_secondTouch && _secondTouch.type == UITouchTypeDirect) {
+			[self handleMouseButtonAction:kGameControllerMouseButtonRight isPressed:YES at:[_firstTouch locationInView:[self view]]];
+		}
+	}
+}
+
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
+	NSSet *allTouches = [event allTouches];
+	for (UITouch *touch in allTouches) {
+		if (touch == _firstTouch ||
+			touch == _secondTouch) {
+			if (touch.type == UITouchTypeDirect) {
+				[self handlePointerMoveTo:[touch locationInView: [self view]]];
+			}
+		}
+	}
+}
+
+- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
+	NSSet *allTouches = [event allTouches];
+	if (allTouches.count == 1) {
+		UITouch *touch = [allTouches anyObject];
+		if (touch.type == UITouchTypeDirect) {
+			[self handleMouseButtonAction:kGameControllerMouseButtonLeft isPressed:NO at:[touch locationInView:[self view]]];
+		}
+	} else if (allTouches.count == 2) {
+		UITouch *touch = [[allTouches allObjects] objectAtIndex:1];
+		if (touch.type == UITouchTypeDirect) {
+			[self handleMouseButtonAction:kGameControllerMouseButtonRight isPressed:NO at:[touch locationInView:[self view]]];
+		}
+	}
+	_firstTouch = nil;
+	_secondTouch = nil;
+}
+
+- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
+	_firstTouch = nil;
+	_secondTouch = nil;
+}
+
+ at end
diff --git a/backends/platform/ios7/ios7_video.h b/backends/platform/ios7/ios7_video.h
index 0bbc5c70b3d..e11b72bfcc0 100644
--- a/backends/platform/ios7/ios7_video.h
+++ b/backends/platform/ios7/ios7_video.h
@@ -32,6 +32,7 @@
 
 #include "backends/platform/ios7/ios7_keyboard.h"
 #include "backends/platform/ios7/ios7_common.h"
+#include "backends/platform/ios7/ios7_game_controller.h"
 
 #include "common/list.h"
 
@@ -47,6 +48,7 @@ typedef struct {
 	NSLock *_eventLock;
 	SoftKeyboard *_keyboardView;
 	BOOL _keyboardVisible;
+	Common::List<GameController*> _controllers;
 
 	UIBackgroundTaskIdentifier _backgroundSaveStateTask;
 
@@ -87,9 +89,6 @@ typedef struct {
 
 	int _scaledShakeXOffset;
 	int _scaledShakeYOffset;
-
-	UITouch *_firstTouch;
-	UITouch *_secondTouch;
 }
 
 @property (nonatomic, assign) CGPoint pointerPosition;
diff --git a/backends/platform/ios7/ios7_video.mm b/backends/platform/ios7/ios7_video.mm
index 5c8427fbce6..2d012f22536 100644
--- a/backends/platform/ios7/ios7_video.mm
+++ b/backends/platform/ios7/ios7_video.mm
@@ -23,6 +23,7 @@
 #define FORBIDDEN_SYMBOL_ALLOW_ALL
 
 #include "backends/platform/ios7/ios7_video.h"
+#include "backends/platform/ios7/ios7_touch_controller.h"
 
 #include "backends/platform/ios7/ios7_app_delegate.h"
 
@@ -421,6 +422,8 @@ uint getSizeNextPOT(uint size) {
 
 	[self setupGestureRecognizers];
 
+	_controllers.push_back([[TouchController alloc] initWithView:self]);
+
 	[self setContentScaleFactor:[[UIScreen mainScreen] scale]];
 
 	_keyboardView = nil;
@@ -432,9 +435,6 @@ uint getSizeNextPOT(uint size) {
 	_scaledShakeXOffset = 0;
 	_scaledShakeYOffset = 0;
 
-	_firstTouch = NULL;
-	_secondTouch = NULL;
-
 	_eventLock = [[NSLock alloc] init];
 
 	memset(_gameScreenCoords, 0, sizeof(GLVertex) * 4);
@@ -837,89 +837,36 @@ uint getSizeNextPOT(uint size) {
 	return _keyboardVisible;
 }
 
-- (UITouch *)secondTouchOtherTouchThan:(UITouch *)touch in:(NSSet *)set {
-	NSArray *all = [set allObjects];
-	for (UITouch *t in all) {
-		if (t != touch) {
-			return t;
-		}
-	}
-	return nil;
-}
-
 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
-	int x, y;
-
-	NSSet *allTouches = [event allTouches];
-	if (allTouches.count == 1) {
-		_firstTouch = [allTouches anyObject];
-		CGPoint point = [_firstTouch locationInView:self];
-		if (![self getMouseCoords:point eventX:&x eventY:&y])
-			return;
-
-		[self addEvent:InternalEvent(kInputMouseDown, x, y)];
-	}
-	else if (allTouches.count == 2) {
-		_secondTouch = [self secondTouchOtherTouchThan:_firstTouch in:allTouches];
-		if (_secondTouch) {
-			CGPoint point = [_secondTouch locationInView:self];
-			if (![self getMouseCoords:point eventX:&x eventY:&y])
-				return;
-
-			[self addEvent:InternalEvent(kInputMouseSecondDown, x, y)];
+	for (GameController *c : _controllers) {
+		if ([c isKindOfClass:TouchController.class]) {
+			[(TouchController *)c touchesBegan:touches withEvent:event];
 		}
 	}
 }
 
 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
-	int x, y;
-
-	NSSet *allTouches = [event allTouches];
-	for (UITouch *touch in allTouches) {
-		if (touch == _firstTouch) {
-			CGPoint point = [touch locationInView:self];
-			if (![self getMouseCoords:point eventX:&x eventY:&y])
-				return;
-
-			[self addEvent:InternalEvent(kInputMouseDragged, x, y)];
-		} else if (touch == _secondTouch) {
-			CGPoint point = [touch locationInView:self];
-			if (![self getMouseCoords:point eventX:&x eventY:&y])
-				return;
-
-			[self addEvent:InternalEvent(kInputMouseSecondDragged, x, y)];
+	for (GameController *c : _controllers) {
+		if ([c isKindOfClass:TouchController.class]) {
+			[(TouchController *)c touchesMoved:touches withEvent:event];
 		}
 	}
 }
 
 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
-	int x, y;
-
-	NSSet *allTouches = [event allTouches];
-	if (allTouches.count == 1) {
-		UITouch *touch = [allTouches anyObject];
-		CGPoint point = [touch locationInView:self];
-		if (![self getMouseCoords:point eventX:&x eventY:&y]) {
-			return;
+	for (GameController *c : _controllers) {
+		if ([c isKindOfClass:TouchController.class]) {
+			[(TouchController *)c touchesEnded:touches withEvent:event];
 		}
-
-		[self addEvent:InternalEvent(kInputMouseUp, x, y)];
 	}
-	else if (allTouches.count == 2) {
-		UITouch *touch = [[allTouches allObjects] objectAtIndex:1];
-		CGPoint point = [touch locationInView:self];
-		if (![self getMouseCoords:point eventX:&x eventY:&y])
-			return;
-
-		[self addEvent:InternalEvent(kInputMouseSecondUp, x, y)];
-	}
-	_firstTouch = nil;
-	_secondTouch = nil;
 }
 
 - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
-	_firstTouch = nil;
-	_secondTouch = nil;
+	for (GameController *c : _controllers) {
+		if ([c isKindOfClass:TouchController.class]) {
+			[(TouchController *)c touchesEnded:touches withEvent:event];
+		}
+	}
 }
 
 - (void)keyboardPinch:(UIPinchGestureRecognizer *)recognizer {
diff --git a/backends/platform/ios7/module.mk b/backends/platform/ios7/module.mk
index 780f4b0c31d..d9a345e72c0 100644
--- a/backends/platform/ios7/module.mk
+++ b/backends/platform/ios7/module.mk
@@ -11,7 +11,8 @@ MODULE_OBJS := \
 	ios7_keyboard.o \
 	ios7_scummvm_view_controller.o \
 	ios7_app_delegate.o \
-	ios7_game_controller.o
+	ios7_game_controller.o \
+	ios7_touch_controller.o
 
 # We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
 MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS))
diff --git a/dists/ios7/Info.plist b/dists/ios7/Info.plist
index 27fd40ce870..7a12be74556 100644
--- a/dists/ios7/Info.plist
+++ b/dists/ios7/Info.plist
@@ -30,6 +30,8 @@
 	<true/>
 	<key>UIApplicationExitsOnSuspend</key>
 	<false/>
+	<key>UIApplicationSupportsIndirectInputEvents</key>
+	<true/>
 	<key>UIDeviceFamily</key>
 	<array>
 		<integer>1</integer>
diff --git a/dists/ios7/Info.plist.in b/dists/ios7/Info.plist.in
index d192fc8530a..da2459ee437 100644
--- a/dists/ios7/Info.plist.in
+++ b/dists/ios7/Info.plist.in
@@ -30,6 +30,8 @@
 	<true/>
 	<key>UIApplicationExitsOnSuspend</key>
 	<false/>
+	<key>UIApplicationSupportsIndirectInputEvents</key>
+	<true/>
 	<key>UIDeviceFamily</key>
 	<array>
 		<integer>1</integer>


Commit: c3513a151eeb35ea5be05952c93963ad7b67fd7d
    https://github.com/scummvm/scummvm/commit/c3513a151eeb35ea5be05952c93963ad7b67fd7d
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2022-08-08T21:08:56+01:00

Commit Message:
IOS7: Add Mouse support using GameController framework

Add support for mouses using the GameController framework. This requires
iOS 14 and up. The trackpad on the magic keyboard to iPads is connected
as a mouse and of course other connected mouses.

The mouse movements triggers calls to the mouseMovedHandler code
block. The calls delivers delta movements on the X and Y axis from the
last pointer position. It doesn't keep track on where the pointer is in
the view. That's where pointerPosition property in the iPhoneView comes
into place.

Changed paths:
  A backends/platform/ios7/ios7_mouse_controller.h
  A backends/platform/ios7/ios7_mouse_controller.mm
    backends/platform/ios7/ios7_video.mm
    backends/platform/ios7/module.mk


diff --git a/backends/platform/ios7/ios7_mouse_controller.h b/backends/platform/ios7/ios7_mouse_controller.h
new file mode 100644
index 00000000000..18bef5c11d6
--- /dev/null
+++ b/backends/platform/ios7/ios7_mouse_controller.h
@@ -0,0 +1,34 @@
+/* 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/>.
+ *
+ */
+
+#ifndef BACKENDS_PLATFORM_IOS7_IOS7_MOUSE_CONTROLLER_H
+#define BACKENDS_PLATFORM_IOS7_IOS7_MOUSE_CONTROLLER_H
+
+#include "backends/platform/ios7/ios7_game_controller.h"
+
+API_AVAILABLE(ios(14.0))
+ at interface MouseController : GameController
+
+- (id)initWithView:(iPhoneView *)view;
+
+ at end
+
+#endif /* BACKENDS_PLATFORM_IOS7_IOS7_MOUSE_CONTROLLER_H */
diff --git a/backends/platform/ios7/ios7_mouse_controller.mm b/backends/platform/ios7/ios7_mouse_controller.mm
new file mode 100644
index 00000000000..ece81df90bb
--- /dev/null
+++ b/backends/platform/ios7/ios7_mouse_controller.mm
@@ -0,0 +1,71 @@
+/* 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/>.
+ *
+ */
+
+// Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "backends/platform/ios7/ios7_mouse_controller.h"
+#include "backends/platform/ios7/ios7_video.h"
+#include <GameController/GameController.h>
+
+ at implementation MouseController {
+#ifdef __IPHONE_14_0
+	GCMouse *_mouse;
+#endif
+}
+
+ at dynamic view;
+
+- (id)initWithView:(iPhoneView *)view {
+	self = [super initWithView:view];
+
+	if (self) {
+		[[NSNotificationCenter defaultCenter] addObserver:self
+												 selector:@selector(mouseDidConnect:)
+													 name:@"GCMouseDidConnectNotification"
+												   object:nil];
+	}
+
+	return self;
+}
+
+- (void)mouseDidConnect:(NSNotification *)notification {
+#ifdef __IPHONE_14_0
+	_mouse = (GCMouse*)notification.object;
+
+	_mouse.mouseInput.mouseMovedHandler = ^(GCMouseInput * _Nonnull mouse, float deltaX, float deltaY) {
+		CGPoint newPosition = [[self view] pointerPosition];
+		newPosition.x += deltaX;
+		newPosition.y += 0-deltaY;
+		[self handlePointerMoveTo:newPosition];
+	};
+
+	_mouse.mouseInput.leftButton.valueChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
+		[self handleMouseButtonAction:kGameControllerMouseButtonLeft isPressed:pressed at:[[self view] pointerPosition]];
+	};
+
+	_mouse.mouseInput.rightButton.valueChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
+		[self handleMouseButtonAction:kGameControllerMouseButtonRight isPressed:pressed at:[[self view] pointerPosition]];
+	};
+#endif
+}
+
+ at end
diff --git a/backends/platform/ios7/ios7_video.mm b/backends/platform/ios7/ios7_video.mm
index 2d012f22536..c702d663ff6 100644
--- a/backends/platform/ios7/ios7_video.mm
+++ b/backends/platform/ios7/ios7_video.mm
@@ -24,6 +24,7 @@
 
 #include "backends/platform/ios7/ios7_video.h"
 #include "backends/platform/ios7/ios7_touch_controller.h"
+#include "backends/platform/ios7/ios7_mouse_controller.h"
 
 #include "backends/platform/ios7/ios7_app_delegate.h"
 
@@ -422,6 +423,9 @@ uint getSizeNextPOT(uint size) {
 
 	[self setupGestureRecognizers];
 
+	if (@available(iOS 14.0, *)) {
+		_controllers.push_back([[MouseController alloc] initWithView:self]);
+	}
 	_controllers.push_back([[TouchController alloc] initWithView:self]);
 
 	[self setContentScaleFactor:[[UIScreen mainScreen] scale]];
diff --git a/backends/platform/ios7/module.mk b/backends/platform/ios7/module.mk
index d9a345e72c0..945c8aa8234 100644
--- a/backends/platform/ios7/module.mk
+++ b/backends/platform/ios7/module.mk
@@ -12,7 +12,8 @@ MODULE_OBJS := \
 	ios7_scummvm_view_controller.o \
 	ios7_app_delegate.o \
 	ios7_game_controller.o \
-	ios7_touch_controller.o
+	ios7_touch_controller.o \
+	ios7_mouse_controller.o
 
 # We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
 MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS))


Commit: f18305e715587d7c2e6859e45499a7d3d0a7f092
    https://github.com/scummvm/scummvm/commit/f18305e715587d7c2e6859e45499a7d3d0a7f092
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2022-08-08T21:08:56+01:00

Commit Message:
IOS7: Add support for Joystick actions in GameController

Joystick actions are suitable for joysticks and gamepads where the
movements are updated by a controller stick. On gamepads that's usually
a thumbstick.

Add joystick events which can be triggered by each implemented
controller that should utilize the ScummVM Joystick events.

Changed paths:
    backends/platform/ios7/ios7_common.h
    backends/platform/ios7/ios7_game_controller.h
    backends/platform/ios7/ios7_game_controller.mm
    backends/platform/ios7/ios7_osys_events.cpp


diff --git a/backends/platform/ios7/ios7_common.h b/backends/platform/ios7/ios7_common.h
index c58cbe82c0f..47ce8ba4c99 100644
--- a/backends/platform/ios7/ios7_common.h
+++ b/backends/platform/ios7/ios7_common.h
@@ -41,7 +41,10 @@ enum InputEvent {
 	kInputApplicationRestoreState,
 	kInputSwipe,
 	kInputTap,
-	kInputMainMenu
+	kInputMainMenu,
+	kInputJoystickAxisMotion,
+	kInputJoystickButtonDown,
+	kInputJoystickButtonUp
 };
 
 enum ScreenOrientation {
diff --git a/backends/platform/ios7/ios7_game_controller.h b/backends/platform/ios7/ios7_game_controller.h
index 480282e475a..50469e20131 100644
--- a/backends/platform/ios7/ios7_game_controller.h
+++ b/backends/platform/ios7/ios7_game_controller.h
@@ -34,12 +34,20 @@ typedef enum {
 	kGameControllerMouseButtonMiddle,
 } GameControllerMouseButton;
 
+typedef enum {
+	kGameControllerJoystickLeft = 0,
+	kGameControllerJoystickRight
+} GameControllerJoystick;
+
+
 @property (nonatomic, readwrite, retain) iPhoneView *view;
 
 - (id)initWithView:(iPhoneView *)view;
 
 - (void)handlePointerMoveTo:(CGPoint)point;
 - (void)handleMouseButtonAction:(GameControllerMouseButton)button isPressed:(bool)pressed at:(CGPoint)point;
+- (void)handleJoystickAxisMotionX:(int)x andY:(int)y forJoystick:(GameControllerJoystick)joystick;
+- (void)handleJoystickButtonAction:(int)button isPressed:(bool)pressed;
 
 @end
 
diff --git a/backends/platform/ios7/ios7_game_controller.mm b/backends/platform/ios7/ios7_game_controller.mm
index cd197bfebfb..85d6a443dba 100644
--- a/backends/platform/ios7/ios7_game_controller.mm
+++ b/backends/platform/ios7/ios7_game_controller.mm
@@ -22,6 +22,7 @@
 // Disable symbol overrides so that we can use system headers.
 #define FORBIDDEN_SYMBOL_ALLOW_ALL
 
+#include "common/events.h"
 #include "backends/platform/ios7/ios7_game_controller.h"
 #include "backends/platform/ios7/ios7_video.h"
 
@@ -98,4 +99,18 @@
 	}
 }
 
+- (void)handleJoystickAxisMotionX:(int)x andY:(int)y forJoystick:(GameControllerJoystick)joystick {
+	if (joystick == kGameControllerJoystickLeft) {
+		[view addEvent:InternalEvent(kInputJoystickAxisMotion, Common::JOYSTICK_AXIS_LEFT_STICK_X, x)];
+		[view addEvent:InternalEvent(kInputJoystickAxisMotion, Common::JOYSTICK_AXIS_LEFT_STICK_Y, y)];
+	} else {
+		[view addEvent:InternalEvent(kInputJoystickAxisMotion, Common::JOYSTICK_AXIS_RIGHT_STICK_X, x)];
+		[view addEvent:InternalEvent(kInputJoystickAxisMotion, Common::JOYSTICK_AXIS_RIGHT_STICK_Y, y)];
+	}
+}
+
+- (void)handleJoystickButtonAction:(int)button isPressed:(bool)pressed {
+	[view addEvent:InternalEvent(pressed ? kInputJoystickButtonDown : kInputJoystickButtonUp, button, 0)];
+}
+
 @end
diff --git a/backends/platform/ios7/ios7_osys_events.cpp b/backends/platform/ios7/ios7_osys_events.cpp
index 29d2bb3dc24..36ce927389d 100644
--- a/backends/platform/ios7/ios7_osys_events.cpp
+++ b/backends/platform/ios7/ios7_osys_events.cpp
@@ -123,6 +123,22 @@ bool OSystem_iOS7::pollEvent(Common::Event &event) {
 			_queuedEventTime = getMillis() + kQueuedInputEventDelay;
 			break;
 
+		case kInputJoystickAxisMotion:
+			event.type = Common::EVENT_JOYAXIS_MOTION;
+			event.joystick.axis = internalEvent.value1;
+			event.joystick.position = internalEvent.value2;
+			break;
+
+		case kInputJoystickButtonDown:
+			event.type = Common::EVENT_JOYBUTTON_DOWN;
+			event.joystick.button = internalEvent.value1;
+			break;
+
+		case kInputJoystickButtonUp:
+			event.type = Common::EVENT_JOYBUTTON_UP;
+			event.joystick.button = internalEvent.value1;
+			break;
+
 		default:
 			break;
 		}


Commit: 8d395fd790c51cf48179fd9d56cd5d71f62a783e
    https://github.com/scummvm/scummvm/commit/8d395fd790c51cf48179fd9d56cd5d71f62a783e
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2022-08-08T21:08:56+01:00

Commit Message:
IOS7: Add support for Extended Gamepad controllers

Add support for Extended Gamepad controllers. What defines extended
gamepad controllers can be found here:
https://developer.apple.com/documentation/gamecontroller/gcextendedgamepad

Support has been added for controlling the pointer position using the
left thumbstick, left clicks using the A-button and right clicks using
the B-button. Also the Main menu can be accessed using the Home/Menu
button.

The thumbstick values are received when changed, however if holding the
thumbstick in the same position the valueChangedHandler will not be
called. Therefore store the X- and Y-axis values and begin to poll
readings of the stored values for as long as the thumbstick is out of
the center position.

Changed paths:
  A backends/platform/ios7/ios7_gamepad_controller.h
  A backends/platform/ios7/ios7_gamepad_controller.mm
    backends/platform/ios7/ios7_video.mm
    backends/platform/ios7/module.mk
    dists/ios7/Info.plist
    dists/ios7/Info.plist.in


diff --git a/backends/platform/ios7/ios7_gamepad_controller.h b/backends/platform/ios7/ios7_gamepad_controller.h
new file mode 100644
index 00000000000..6e2ebd797dd
--- /dev/null
+++ b/backends/platform/ios7/ios7_gamepad_controller.h
@@ -0,0 +1,34 @@
+/* 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/>.
+ *
+ */
+
+#ifndef BACKENDS_PLATFORM_IOS7_IOS7_GAMEPAD_CONTROLLER_H
+#define BACKENDS_PLATFORM_IOS7_IOS7_GAMEPAD_CONTROLLER_H
+
+#include "backends/platform/ios7/ios7_game_controller.h"
+
+API_AVAILABLE(ios(7.0))
+ at interface GamepadController : GameController
+
+- (id)initWithView:(iPhoneView *)view;
+
+ at end
+
+#endif /* BACKENDS_PLATFORM_IOS7_IOS7_GAMEPAD_CONTROLLER_H */
diff --git a/backends/platform/ios7/ios7_gamepad_controller.mm b/backends/platform/ios7/ios7_gamepad_controller.mm
new file mode 100644
index 00000000000..67697634a27
--- /dev/null
+++ b/backends/platform/ios7/ios7_gamepad_controller.mm
@@ -0,0 +1,115 @@
+/* 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/>.
+ *
+ */
+
+// Disable symbol overrides so that we can use system headers.
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "common/events.h"
+#include "backends/platform/ios7/ios7_gamepad_controller.h"
+#include "backends/platform/ios7/ios7_video.h"
+#include <GameController/GameController.h>
+
+// This value will be multiplied with the x and y values of a thumbstick
+// value (-1, 1). Should ideally be configurable through ScummVM settings
+#define GAMEPAD_SENSITIVITY 20
+
+ at implementation GamepadController {
+	GCController *_controller;
+}
+
+ at dynamic view;
+
+- (id)initWithView:(iPhoneView *)view {
+	self = [super initWithView:view];
+
+	[[NSNotificationCenter defaultCenter] addObserver:self
+											 selector:@selector(controllerDidConnect:)
+												 name:@"GCControllerDidConnectNotification"
+											   object:nil];
+
+	return self;
+}
+
+- (void)controllerDidConnect:(NSNotification *)notification {
+	_controller = (GCController*)notification.object;
+
+	if (_controller.extendedGamepad != nil) {
+		_controller.extendedGamepad.leftThumbstick.valueChangedHandler = ^(GCControllerDirectionPad * _Nonnull dpad, float xValue, float yValue) {
+			// Convert the given axis values in float (-1 to 1) to ScummVM Joystick
+			// Axis value as integers (0 to int16_max)
+			int x = xValue * (float)Common::JOYAXIS_MAX;
+			int y = yValue * (float)Common::JOYAXIS_MAX;
+
+			// Apple's Y values are reversed from ScummVM's
+			[self handleJoystickAxisMotionX:x andY:0-y forJoystick:kGameControllerJoystickLeft];
+		};
+
+		_controller.extendedGamepad.rightThumbstick.valueChangedHandler = ^(GCControllerDirectionPad * _Nonnull dpad, float xValue, float yValue) {
+			// Convert the given axis values in float (-1 to 1) to ScummVM Joystick
+			// Axis value as integers (0 to int16_max)
+			int x = xValue * (float)Common::JOYAXIS_MAX;
+			int y = yValue * (float)Common::JOYAXIS_MAX;
+
+			// Apple's Y values are reversed from ScummVM's
+			[self handleJoystickAxisMotionX:x andY:0-y forJoystick:kGameControllerJoystickRight];
+		};
+
+		_controller.extendedGamepad.buttonA.valueChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
+			[self handleJoystickButtonAction:Common::JOYSTICK_BUTTON_A isPressed:pressed];
+		};
+
+		_controller.extendedGamepad.buttonB.valueChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
+			[self handleJoystickButtonAction:Common::JOYSTICK_BUTTON_B isPressed:pressed];
+		};
+
+		_controller.extendedGamepad.buttonX.valueChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
+			[self handleJoystickButtonAction:Common::JOYSTICK_BUTTON_X isPressed:pressed];
+		};
+
+		_controller.extendedGamepad.buttonY.valueChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
+			[self handleJoystickButtonAction:Common::JOYSTICK_BUTTON_Y isPressed:pressed];
+		};
+#ifdef __IPHONE_12_1
+		_controller.extendedGamepad.leftThumbstickButton.valueChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
+			[self handleJoystickButtonAction:Common::JOYSTICK_BUTTON_LEFT_STICK isPressed:pressed];
+		};
+
+		_controller.extendedGamepad.rightThumbstickButton.valueChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
+			[self handleJoystickButtonAction:Common::JOYSTICK_BUTTON_RIGHT_STICK isPressed:pressed];
+		};
+#endif
+		_controller.extendedGamepad.leftShoulder.valueChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
+			[self handleJoystickButtonAction:Common::JOYSTICK_BUTTON_LEFT_SHOULDER isPressed:pressed];
+		};
+
+		_controller.extendedGamepad.rightShoulder.valueChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
+			[self handleJoystickButtonAction:Common::JOYSTICK_BUTTON_RIGHT_SHOULDER isPressed:pressed];
+		};
+#ifdef __IPHONE_13_0
+		_controller.extendedGamepad.buttonMenu.valueChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
+			[[self view] addEvent:InternalEvent(kInputMainMenu, 0, 0)];
+
+		};
+#endif
+	}
+}
+
+ at end
diff --git a/backends/platform/ios7/ios7_video.mm b/backends/platform/ios7/ios7_video.mm
index c702d663ff6..7c0215396d3 100644
--- a/backends/platform/ios7/ios7_video.mm
+++ b/backends/platform/ios7/ios7_video.mm
@@ -25,6 +25,7 @@
 #include "backends/platform/ios7/ios7_video.h"
 #include "backends/platform/ios7/ios7_touch_controller.h"
 #include "backends/platform/ios7/ios7_mouse_controller.h"
+#include "backends/platform/ios7/ios7_gamepad_controller.h"
 
 #include "backends/platform/ios7/ios7_app_delegate.h"
 
@@ -425,6 +426,7 @@ uint getSizeNextPOT(uint size) {
 
 	if (@available(iOS 14.0, *)) {
 		_controllers.push_back([[MouseController alloc] initWithView:self]);
+		_controllers.push_back([[GamepadController alloc] initWithView:self]);
 	}
 	_controllers.push_back([[TouchController alloc] initWithView:self]);
 
diff --git a/backends/platform/ios7/module.mk b/backends/platform/ios7/module.mk
index 945c8aa8234..2075dfe6e25 100644
--- a/backends/platform/ios7/module.mk
+++ b/backends/platform/ios7/module.mk
@@ -13,7 +13,8 @@ MODULE_OBJS := \
 	ios7_app_delegate.o \
 	ios7_game_controller.o \
 	ios7_touch_controller.o \
-	ios7_mouse_controller.o
+	ios7_mouse_controller.o \
+	ios7_gamepad_controller.o
 
 # We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
 MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS))
diff --git a/dists/ios7/Info.plist b/dists/ios7/Info.plist
index 7a12be74556..5e22d5a450c 100644
--- a/dists/ios7/Info.plist
+++ b/dists/ios7/Info.plist
@@ -24,6 +24,13 @@
 	<string>????</string>
 	<key>CFBundleVersion</key>
 	<string>2.7.0git</string>
+	<key>GCSupportedGameControllers</key>
+	<array>
+		<dict>
+			<key>ProfileName</key>
+			<string>ExtendedGamepad</string>
+		</dict>
+	</array>
 	<key>GCSupportsControllerUserInteraction</key>
 	<true/>
 	<key>LSSupportsOpeningDocumentsInPlace</key>
diff --git a/dists/ios7/Info.plist.in b/dists/ios7/Info.plist.in
index da2459ee437..139f5cf0262 100644
--- a/dists/ios7/Info.plist.in
+++ b/dists/ios7/Info.plist.in
@@ -24,6 +24,13 @@
 	<string>????</string>
 	<key>CFBundleVersion</key>
 	<string>@VERSION@</string>
+	<key>GCSupportedGameControllers</key>
+	<array>
+		<dict>
+			<key>ProfileName</key>
+			<string>ExtendedGamepad</string>
+		</dict>
+	</array>
 	<key>GCSupportsControllerUserInteraction</key>
 	<true/>
 	<key>LSSupportsOpeningDocumentsInPlace</key>


Commit: d76bc708c068633f6d24c6799fe60de914c11ce0
    https://github.com/scummvm/scummvm/commit/d76bc708c068633f6d24c6799fe60de914c11ce0
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2022-08-08T21:08:56+01:00

Commit Message:
IOS7: Add isConnected property to GameControllers

Changed paths:
    backends/platform/ios7/ios7_game_controller.h
    backends/platform/ios7/ios7_game_controller.mm
    backends/platform/ios7/ios7_gamepad_controller.mm
    backends/platform/ios7/ios7_mouse_controller.mm
    backends/platform/ios7/ios7_touch_controller.mm


diff --git a/backends/platform/ios7/ios7_game_controller.h b/backends/platform/ios7/ios7_game_controller.h
index 50469e20131..f219710cd66 100644
--- a/backends/platform/ios7/ios7_game_controller.h
+++ b/backends/platform/ios7/ios7_game_controller.h
@@ -41,6 +41,7 @@ typedef enum {
 
 
 @property (nonatomic, readwrite, retain) iPhoneView *view;
+ at property (nonatomic, assign) BOOL isConnected;
 
 - (id)initWithView:(iPhoneView *)view;
 
diff --git a/backends/platform/ios7/ios7_game_controller.mm b/backends/platform/ios7/ios7_game_controller.mm
index 85d6a443dba..741384cdb55 100644
--- a/backends/platform/ios7/ios7_game_controller.mm
+++ b/backends/platform/ios7/ios7_game_controller.mm
@@ -34,6 +34,7 @@
 @implementation GameController
 
 @synthesize view;
+ at synthesize isConnected;
 
 - (id)initWithView:(iPhoneView *)view {
 	self = [super init];
diff --git a/backends/platform/ios7/ios7_gamepad_controller.mm b/backends/platform/ios7/ios7_gamepad_controller.mm
index 67697634a27..e7b34758d1a 100644
--- a/backends/platform/ios7/ios7_gamepad_controller.mm
+++ b/backends/platform/ios7/ios7_gamepad_controller.mm
@@ -36,6 +36,7 @@
 }
 
 @dynamic view;
+ at dynamic isConnected;
 
 - (id)initWithView:(iPhoneView *)view {
 	self = [super initWithView:view];
@@ -49,6 +50,7 @@
 }
 
 - (void)controllerDidConnect:(NSNotification *)notification {
+	[self setIsConnected:YES];
 	_controller = (GCController*)notification.object;
 
 	if (_controller.extendedGamepad != nil) {
diff --git a/backends/platform/ios7/ios7_mouse_controller.mm b/backends/platform/ios7/ios7_mouse_controller.mm
index ece81df90bb..0cef9bf7d77 100644
--- a/backends/platform/ios7/ios7_mouse_controller.mm
+++ b/backends/platform/ios7/ios7_mouse_controller.mm
@@ -33,6 +33,7 @@
 }
 
 @dynamic view;
+ at dynamic isConnected;
 
 - (id)initWithView:(iPhoneView *)view {
 	self = [super initWithView:view];
@@ -49,6 +50,7 @@
 
 - (void)mouseDidConnect:(NSNotification *)notification {
 #ifdef __IPHONE_14_0
+	[self setIsConnected:YES];
 	_mouse = (GCMouse*)notification.object;
 
 	_mouse.mouseInput.mouseMovedHandler = ^(GCMouseInput * _Nonnull mouse, float deltaX, float deltaY) {
diff --git a/backends/platform/ios7/ios7_touch_controller.mm b/backends/platform/ios7/ios7_touch_controller.mm
index 6438c6b17e5..d556606bce8 100644
--- a/backends/platform/ios7/ios7_touch_controller.mm
+++ b/backends/platform/ios7/ios7_touch_controller.mm
@@ -31,6 +31,7 @@
 }
 
 @dynamic view;
+ at dynamic isConnected;
 
 - (id)initWithView:(iPhoneView *)view {
 	self = [super initWithView:view];
@@ -38,6 +39,9 @@
 	_firstTouch = NULL;
 	_secondTouch = NULL;
 
+	// Touches should always be present in iOS view
+	[self setIsConnected:YES];
+
 	return self;
 }
 


Commit: e7759ac0ef36c0e67117f2b778aaaa0bf29ae61d
    https://github.com/scummvm/scummvm/commit/e7759ac0ef36c0e67117f2b778aaaa0bf29ae61d
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2022-08-08T21:08:56+01:00

Commit Message:
IOS7: Implement getHardwareInputSet to get connected devices

Trigger EVENT_INPUT_CHANGED when devices connects to make the ScummVM
engine update the hardware input set.

Changed paths:
    backends/platform/ios7/ios7_common.h
    backends/platform/ios7/ios7_game_controller.mm
    backends/platform/ios7/ios7_osys_events.cpp
    backends/platform/ios7/ios7_osys_main.h
    backends/platform/ios7/ios7_osys_misc.mm
    backends/platform/ios7/ios7_video.h
    backends/platform/ios7/ios7_video.mm


diff --git a/backends/platform/ios7/ios7_common.h b/backends/platform/ios7/ios7_common.h
index 47ce8ba4c99..7b232650093 100644
--- a/backends/platform/ios7/ios7_common.h
+++ b/backends/platform/ios7/ios7_common.h
@@ -44,7 +44,8 @@ enum InputEvent {
 	kInputMainMenu,
 	kInputJoystickAxisMotion,
 	kInputJoystickButtonDown,
-	kInputJoystickButtonUp
+	kInputJoystickButtonUp,
+	kInputChanged
 };
 
 enum ScreenOrientation {
diff --git a/backends/platform/ios7/ios7_game_controller.mm b/backends/platform/ios7/ios7_game_controller.mm
index 741384cdb55..1c0c365ad6b 100644
--- a/backends/platform/ios7/ios7_game_controller.mm
+++ b/backends/platform/ios7/ios7_game_controller.mm
@@ -34,7 +34,6 @@
 @implementation GameController
 
 @synthesize view;
- at synthesize isConnected;
 
 - (id)initWithView:(iPhoneView *)view {
 	self = [super init];
@@ -45,6 +44,13 @@
 	return self;
 }
 
+// Override the setter method
+- (void)setIsConnected:(BOOL)isConnected {
+	// Inform that input changed
+	_isConnected = isConnected;
+	[view addEvent:InternalEvent(kInputChanged, 0, 0)];
+}
+
 - (void)handlePointerMoveTo:(CGPoint)point {
 	int x, y;
 
diff --git a/backends/platform/ios7/ios7_osys_events.cpp b/backends/platform/ios7/ios7_osys_events.cpp
index 36ce927389d..35b30ae26b6 100644
--- a/backends/platform/ios7/ios7_osys_events.cpp
+++ b/backends/platform/ios7/ios7_osys_events.cpp
@@ -137,6 +137,11 @@ bool OSystem_iOS7::pollEvent(Common::Event &event) {
 		case kInputJoystickButtonUp:
 			event.type = Common::EVENT_JOYBUTTON_UP;
 			event.joystick.button = internalEvent.value1;
+
+		case kInputChanged:
+			event.type = Common::EVENT_INPUT_CHANGED;
+			_queuedInputEvent.type = Common::EVENT_INVALID;
+			_queuedEventTime = getMillis() + kQueuedInputEventDelay;
 			break;
 
 		default:
diff --git a/backends/platform/ios7/ios7_osys_main.h b/backends/platform/ios7/ios7_osys_main.h
index 61c35715e87..f54b1d9081a 100644
--- a/backends/platform/ios7/ios7_osys_main.h
+++ b/backends/platform/ios7/ios7_osys_main.h
@@ -25,6 +25,7 @@
 #include "graphics/surface.h"
 #include "backends/platform/ios7/ios7_common.h"
 #include "backends/modular-backend.h"
+#include "backends/keymapper/hardware-input.h"
 #include "common/events.h"
 #include "common/str.h"
 #include "common/ustr.h"
@@ -193,6 +194,8 @@ public:
 	void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0) override;
 	void getTimeAndDate(TimeDate &td, bool skipRecord = false) const override;
 
+	Common::HardwareInputSet *getHardwareInputSet() override;
+
 	Audio::Mixer *getMixer() override;
 
 	void startSoundsystem();
diff --git a/backends/platform/ios7/ios7_osys_misc.mm b/backends/platform/ios7/ios7_osys_misc.mm
index e39ff954f63..4c7c9bce09d 100644
--- a/backends/platform/ios7/ios7_osys_misc.mm
+++ b/backends/platform/ios7/ios7_osys_misc.mm
@@ -124,6 +124,23 @@ bool OSystem_iOS7::isConnectionLimited() {
 	return (flags & kSCNetworkReachabilityFlagsIsWWAN);
 }
 
+Common::HardwareInputSet *OSystem_iOS7::getHardwareInputSet() {
+	using namespace Common;
+
+	CompositeHardwareInputSet *inputSet = new CompositeHardwareInputSet();
+	// Ask view about connected controllers
+	if ([[iOS7AppDelegate iPhoneView] isTouchControllerConnected] ||
+		[[iOS7AppDelegate iPhoneView] isMouseControllerConnected]) {
+		inputSet->addHardwareInputSet(new MouseHardwareInputSet(defaultMouseButtons));
+	}
+
+	if ([[iOS7AppDelegate iPhoneView] isGamepadControllerConnected]) {
+		inputSet->addHardwareInputSet(new JoystickHardwareInputSet(defaultJoystickButtons, defaultJoystickAxes));
+	}
+
+	return inputSet;
+}
+
 void OSystem_iOS7::handleEvent_applicationSaveState() {
 	[[iOS7AppDelegate iPhoneView] beginBackgroundSaveStateTask];
 	saveState();
diff --git a/backends/platform/ios7/ios7_video.h b/backends/platform/ios7/ios7_video.h
index e11b72bfcc0..2ff3f843588 100644
--- a/backends/platform/ios7/ios7_video.h
+++ b/backends/platform/ios7/ios7_video.h
@@ -133,7 +133,9 @@ typedef struct {
 - (bool)fetchEvent:(InternalEvent *)event;
 
 - (bool)getMouseCoords:(CGPoint)point eventX:(int *)x eventY:(int *)y;
-
+- (BOOL)isTouchControllerConnected;
+- (BOOL)isMouseControllerConnected;
+- (BOOL)isGamepadControllerConnected;
 @end
 
 #endif
diff --git a/backends/platform/ios7/ios7_video.mm b/backends/platform/ios7/ios7_video.mm
index 7c0215396d3..420c932aac9 100644
--- a/backends/platform/ios7/ios7_video.mm
+++ b/backends/platform/ios7/ios7_video.mm
@@ -818,6 +818,39 @@ uint getSizeNextPOT(uint size) {
 	return true;
 }
 
+- (BOOL)isControllerTypeConnected:(Class)controller {
+	for (GameController *c : _controllers) {
+		if ([c isConnected]) {
+			if ([c isKindOfClass:controller]) {
+				return YES;
+			}
+		}
+	}
+	return NO;
+}
+
+- (BOOL)isTouchControllerConnected {
+	return [self isControllerTypeConnected:TouchController.class];
+}
+
+- (BOOL)isMouseControllerConnected {
+	if (@available(iOS 14.0, *)) {
+		return [self isControllerTypeConnected:MouseController.class];
+	} else {
+		// Fallback on earlier versions
+		return NO;
+	}
+}
+
+- (BOOL)isGamepadControllerConnected {
+	if (@available(iOS 14.0, *)) {
+		return [self isControllerTypeConnected:GamepadController.class];
+	} else {
+		// Fallback on earlier versions
+		return NO;
+	}
+}
+
 - (void)deviceOrientationChanged:(UIDeviceOrientation)orientation {
 	[self addEvent:InternalEvent(kInputOrientationChanged, orientation, 0)];
 


Commit: f9e1806b14435bd5c1662f9f1947fc04a757a19d
    https://github.com/scummvm/scummvm/commit/f9e1806b14435bd5c1662f9f1947fc04a757a19d
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2022-08-08T21:08:56+01:00

Commit Message:
IOS7: Update README.md with support for external devices

Changed paths:
    backends/platform/ios7/README.md


diff --git a/backends/platform/ios7/README.md b/backends/platform/ios7/README.md
index ca1384ef54f..fdb5718d9e6 100644
--- a/backends/platform/ios7/README.md
+++ b/backends/platform/ios7/README.md
@@ -23,3 +23,5 @@ Here is a list of the in-game gestures:
 |Two fingers double-tap|Skip the cinematic / video|
 
 The iOS keyboard is visible when the device is in portrait mode, and hidden in landscape mode.
+
+External devices such as mouse, trackpad and gamepad controllers, are supported from iOS 14 and later.


Commit: 04b5507e244864df7b7c13712922478e2903b7eb
    https://github.com/scummvm/scummvm/commit/04b5507e244864df7b7c13712922478e2903b7eb
Author: Lars Sundström (l.sundstrom at gmail.com)
Date: 2022-08-08T21:08:56+01:00

Commit Message:
DOCS: Add section about Game Controller support for iOS

Changed paths:
    doc/docportal/other_platforms/ios.rst


diff --git a/doc/docportal/other_platforms/ios.rst b/doc/docportal/other_platforms/ios.rst
index 46960b78ee1..326e2aed385 100644
--- a/doc/docportal/other_platforms/ios.rst
+++ b/doc/docportal/other_platforms/ios.rst
@@ -220,6 +220,10 @@ Keyboard
 ^^^^^^^^^^^^^^^^^^^^
 If no external keyboard is connected, the pinch gesture shows and hides the onscreen keyboard. When an external keyboard is connected, the pinch gesture enables/disables inputs from the external keyboard.
 
+Game controllers
+^^^^^^^^^^^^^^^^^^^^
+If running iOS 14 and later there is support for connected mouses and gamepad controllers using the Apple Game Controller framework. Only "Extended Gamepad Controllers" are supported at the moment. For more information visit https://developer.apple.com/documentation/gamecontroller/gcextendedgamepad
+
 Paths
 =======
 




More information about the Scummvm-git-logs mailing list