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.
This commit is contained in:
Lars Sundström 2023-03-14 11:39:24 +01:00 committed by Eugene Sandulenko
parent 045ddca927
commit 5817e72d0d
8 changed files with 62 additions and 0 deletions

View File

@ -28,6 +28,7 @@ API_AVAILABLE(ios(7.0))
@interface GamepadController : GameController
- (id)initWithView:(iPhoneView *)view;
- (void)virtualController:(bool)connect;
@end

View File

@ -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;

View File

@ -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");
}

View File

@ -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;
}

View File

@ -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"); }

View File

@ -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();

View File

@ -143,6 +143,7 @@ uint getSizeNextPOT(uint size);
- (BOOL)isTouchControllerConnected;
- (BOOL)isMouseControllerConnected;
- (BOOL)isGamepadControllerConnected;
- (void)virtualController:(bool)connect;
@end
#endif

View File

@ -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)];