From 044451d557324cd90634c91a5a3e57f58838b83a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 26 May 2024 10:32:31 +0200 Subject: [PATCH 1/2] iOS: Enable ARC on all the .mm files (oops) --- CMakeLists.txt | 5 +++++ ios/AppDelegate.mm | 3 ++- ios/ViewControllerMetal.mm | 7 ++++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 51697fed25..f0be1a6f80 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1326,14 +1326,19 @@ elseif(IOS AND NOT LIBRETRO) set(nativeExtraLibs ${nativeExtraLibs} iconv) endif() + # TODO: Enable arc globally? set_source_files_properties(ios/AppDelegate.mm PROPERTIES COMPILE_FLAGS -fobjc-arc) set_source_files_properties(ios/ViewController.mm PROPERTIES COMPILE_FLAGS -fobjc-arc) + set_source_files_properties(ios/ViewControllerMetal.mm PROPERTIES COMPILE_FLAGS -fobjc-arc) set_source_files_properties(ios/iOSCoreAudio.mm PROPERTIES COMPILE_FLAGS -fobjc-arc) set_source_files_properties(ios/PPSSPPUIApplication.mm PROPERTIES COMPILE_FLAGS -fobjc-arc) set_source_files_properties(ios/iCade/iCadeReaderView.m PROPERTIES COMPILE_FLAGS -fobjc-arc) set_source_files_properties(ios/main.mm PROPERTIES COMPILE_FLAGS -fobjc-arc) set_source_files_properties(ios/CameraHelper.mm PROPERTIES COMPILE_FLAGS -fobjc-arc) + set_source_files_properties(ios/AudioEngine.mm PROPERTIES COMPILE_FLAGS -fobjc-arc) set_source_files_properties(ios/LocationHelper.mm PROPERTIES COMPILE_FLAGS -fobjc-arc) + set_source_files_properties(ios/DisplayManager.mm PROPERTIES COMPILE_FLAGS -fobjc-arc) + set_source_files_properties(ios/Controls.mm PROPERTIES COMPILE_FLAGS -fobjc-arc) set_source_files_properties(UI/DarwinFileSystemServices.mm PROPERTIES COMPILE_FLAGS -fobjc-arc) set_source_files_properties(Common/Battery/AppleBatteryClient.m PROPERTIES COMPILE_FLAGS -fobjc-arc) diff --git a/ios/AppDelegate.mm b/ios/AppDelegate.mm index b0c478166e..ea07b02d1f 100644 --- a/ios/AppDelegate.mm +++ b/ios/AppDelegate.mm @@ -164,7 +164,8 @@ } - (void)applicationWillTerminate:(UIApplication *)application { - exit(0); + // Seems like a bad idea. + // exit(0); } @end diff --git a/ios/ViewControllerMetal.mm b/ios/ViewControllerMetal.mm index 43038c8e61..3e76471178 100644 --- a/ios/ViewControllerMetal.mm +++ b/ios/ViewControllerMetal.mm @@ -81,7 +81,7 @@ bool IOSVulkanContext::InitFromRenderThread(CAMetalLayer *layer, int desiredBack return false; } - VkResult res = g_Vulkan->InitSurface(WINDOWSYSTEM_METAL_EXT, (void *)layer, nullptr); + VkResult res = g_Vulkan->InitSurface(WINDOWSYSTEM_METAL_EXT, (__bridge void *)layer, nullptr); if (res != VK_SUCCESS) { ERROR_LOG(G3D, "g_Vulkan->InitSurface failed: '%s'", VulkanResultToString(res)); return false; @@ -231,6 +231,11 @@ static std::thread g_renderLoopThread; return self; } +- (void)appWillTerminate:(NSNotification *)notification +{ + [self shutdown]; +} + // Should be very similar to the Android one, probably mergeable. void VulkanRenderLoop(IOSVulkanContext *graphicsContext, CAMetalLayer *metalLayer) { SetCurrentThreadName("EmuThreadVulkan"); From d46a7ed2285cb40a4d23b81efa111a3b7b9244c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 26 May 2024 11:11:45 +0200 Subject: [PATCH 2/2] iOS gamepad mapping: Better mapping, better defaults. Fixes the start button problem. controller.controllerPausedHandler should not be set. --- Core/KeyMap.cpp | 2 ++ Core/KeyMapDefaults.cpp | 24 ++++++++++++++ Core/KeyMapDefaults.h | 1 + ios/Controls.mm | 72 +++++++++++++++++++++-------------------- 4 files changed, 64 insertions(+), 35 deletions(-) diff --git a/Core/KeyMap.cpp b/Core/KeyMap.cpp index d9af549746..3933252c4c 100644 --- a/Core/KeyMap.cpp +++ b/Core/KeyMap.cpp @@ -741,6 +741,8 @@ void RestoreDefault() { } else { SetDefaultKeyMap(DEFAULT_MAPPING_ANDROID_PAD, false); } +#elif PPSSPP_PLATFORM(IOS) + SetDefaultKeyMap(DEFAULT_MAPPING_IOS_PAD, false); #else SetDefaultKeyMap(DEFAULT_MAPPING_KEYBOARD, true); SetDefaultKeyMap(DEFAULT_MAPPING_PAD, false); diff --git a/Core/KeyMapDefaults.cpp b/Core/KeyMapDefaults.cpp index b0493a1c2b..e796bdfe52 100644 --- a/Core/KeyMapDefaults.cpp +++ b/Core/KeyMapDefaults.cpp @@ -275,6 +275,27 @@ static const DefMappingStruct defaultPadMap[] = { {VIRTKEY_PAUSE , NKCODE_BUTTON_L2 }, }; +static const DefMappingStruct defaultPadMapIOS[] = { + {CTRL_CROSS , NKCODE_BUTTON_2}, + {CTRL_CIRCLE , NKCODE_BUTTON_3}, + {CTRL_SQUARE , NKCODE_BUTTON_4}, + {CTRL_TRIANGLE , NKCODE_BUTTON_1}, + {CTRL_UP , NKCODE_DPAD_UP}, + {CTRL_RIGHT , NKCODE_DPAD_RIGHT}, + {CTRL_DOWN , NKCODE_DPAD_DOWN}, + {CTRL_LEFT , NKCODE_DPAD_LEFT}, + {CTRL_START , NKCODE_BUTTON_START}, + {CTRL_SELECT , NKCODE_BUTTON_SELECT}, + {CTRL_LTRIGGER , NKCODE_BUTTON_L1}, + {CTRL_RTRIGGER , NKCODE_BUTTON_R1}, + {VIRTKEY_AXIS_X_MIN, JOYSTICK_AXIS_X, -1}, + {VIRTKEY_AXIS_X_MAX, JOYSTICK_AXIS_X, +1}, + {VIRTKEY_AXIS_Y_MIN, JOYSTICK_AXIS_Y, +1}, + {VIRTKEY_AXIS_Y_MAX, JOYSTICK_AXIS_Y, -1}, + {VIRTKEY_PAUSE , NKCODE_BUTTON_THUMBL }, + {VIRTKEY_FASTFORWARD , JOYSTICK_AXIS_RTRIGGER, +1}, +}; + static const DefMappingStruct defaultOuyaMap[] = { {CTRL_CROSS , NKCODE_BUTTON_A}, {CTRL_CIRCLE , NKCODE_BUTTON_B}, @@ -382,6 +403,9 @@ void SetDefaultKeyMap(DefaultMaps dmap, bool replace) { case DEFAULT_MAPPING_ANDROID_PAD: SetDefaultKeyMap(DEVICE_ID_PAD_0, defaultPadMapAndroid, ARRAY_SIZE(defaultPadMapAndroid), replace); break; + case DEFAULT_MAPPING_IOS_PAD: + SetDefaultKeyMap(DEVICE_ID_PAD_0, defaultPadMapIOS, ARRAY_SIZE(defaultPadMapIOS), replace); + break; case DEFAULT_MAPPING_OUYA: SetDefaultKeyMap(DEVICE_ID_PAD_0, defaultOuyaMap, ARRAY_SIZE(defaultOuyaMap), replace); break; diff --git a/Core/KeyMapDefaults.h b/Core/KeyMapDefaults.h index 072649bf89..f38f7d7f07 100644 --- a/Core/KeyMapDefaults.h +++ b/Core/KeyMapDefaults.h @@ -6,6 +6,7 @@ enum DefaultMaps { DEFAULT_MAPPING_KEYBOARD, DEFAULT_MAPPING_PAD, DEFAULT_MAPPING_ANDROID_PAD, + DEFAULT_MAPPING_IOS_PAD, DEFAULT_MAPPING_XINPUT, DEFAULT_MAPPING_ANDROID_XBOX, // XBox controller or similar on Android DEFAULT_MAPPING_SHIELD, diff --git a/ios/Controls.mm b/ios/Controls.mm index 2807d9ea31..6fcbd90521 100644 --- a/ios/Controls.mm +++ b/ios/Controls.mm @@ -15,20 +15,20 @@ static void controllerButtonPressed(BOOL pressed, InputKeyCode keyCode) { NativeKey(key); } +static void analogTriggerPressed(InputAxis axis, float value) { + AxisInput axisInput; + axisInput.deviceId = DEVICE_ID_PAD_0; + axisInput.axisId = axis; + axisInput.value = value; + NativeAxis(&axisInput, 1); +} + bool SetupController(GCController *controller) { GCExtendedGamepad *extendedProfile = controller.extendedGamepad; if (extendedProfile == nil) { return false; } - controller.controllerPausedHandler = ^(GCController *controller) { - KeyInput key; - key.flags = KEY_DOWN; - key.keyCode = NKCODE_ESCAPE; - key.deviceId = DEVICE_ID_KEYBOARD; - NativeKey(key); - }; - extendedProfile.buttonA.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { controllerButtonPressed(pressed, NKCODE_BUTTON_2); // Cross }; @@ -46,11 +46,11 @@ bool SetupController(GCController *controller) { }; extendedProfile.leftShoulder.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { - controllerButtonPressed(pressed, NKCODE_BUTTON_7); // LTrigger + controllerButtonPressed(pressed, NKCODE_BUTTON_L1); // LTrigger }; extendedProfile.rightShoulder.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { - controllerButtonPressed(pressed, NKCODE_BUTTON_8); // RTrigger + controllerButtonPressed(pressed, NKCODE_BUTTON_R1); // RTrigger }; extendedProfile.dpad.up.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { @@ -70,34 +70,36 @@ bool SetupController(GCController *controller) { }; extendedProfile.leftTrigger.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { - controllerButtonPressed(pressed, NKCODE_BUTTON_9); // Select + INFO_LOG(SYSTEM, "ltrigger: %f %d", value, (int)pressed); + analogTriggerPressed(JOYSTICK_AXIS_LTRIGGER, value); }; extendedProfile.rightTrigger.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { - controllerButtonPressed(pressed, NKCODE_BUTTON_10); // Start + INFO_LOG(SYSTEM, "rtrigger: %f %d", value, (int)pressed); + analogTriggerPressed(JOYSTICK_AXIS_RTRIGGER, value); }; #if defined(__IPHONE_12_1) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_12_1 if ([extendedProfile respondsToSelector:@selector(leftThumbstickButton)] && extendedProfile.leftThumbstickButton != nil) { extendedProfile.leftThumbstickButton.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { - controllerButtonPressed(pressed, NKCODE_BUTTON_11); + controllerButtonPressed(pressed, NKCODE_BUTTON_THUMBL); }; } if ([extendedProfile respondsToSelector:@selector(rightThumbstickButton)] && extendedProfile.rightThumbstickButton != nil) { extendedProfile.rightThumbstickButton.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { - controllerButtonPressed(pressed, NKCODE_BUTTON_12); + controllerButtonPressed(pressed, NKCODE_BUTTON_THUMBR); }; } #endif #if defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0 if ([extendedProfile respondsToSelector:@selector(buttonOptions)] && extendedProfile.buttonOptions != nil) { extendedProfile.buttonOptions.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { - controllerButtonPressed(pressed, NKCODE_BUTTON_13); + controllerButtonPressed(pressed, NKCODE_BUTTON_SELECT); }; } if ([extendedProfile respondsToSelector:@selector(buttonMenu)] && extendedProfile.buttonMenu != nil) { extendedProfile.buttonMenu.valueChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { - controllerButtonPressed(pressed, NKCODE_BUTTON_14); + controllerButtonPressed(pressed, NKCODE_BUTTON_START); }; } #endif @@ -143,7 +145,7 @@ bool SetupController(GCController *controller) { NativeAxis(&axisInput, 1); }; - return true; + return true; } void TouchTracker::SendTouchEvent(float x, float y, int code, int pointerId) { @@ -203,7 +205,7 @@ void TouchTracker::Began(NSSet *touches, UIView *view) { } void TouchTracker::Moved(NSSet *touches, UIView *view) { - for (UITouch* touch in touches) { + for (UITouch* touch in touches) { CGPoint point = [touch locationInView:view]; int touchId = ToTouchID(touch, true); SendTouchEvent(point.x, point.y, 0, touchId); @@ -211,40 +213,40 @@ void TouchTracker::Moved(NSSet *touches, UIView *view) { } void TouchTracker::Ended(NSSet *touches, UIView *view) { - for (UITouch* touch in touches) { + for (UITouch* touch in touches) { CGPoint point = [touch locationInView:view]; int touchId = ToTouchID(touch, false); if (touchId >= 0) { - SendTouchEvent(point.x, point.y, 2, touchId); + SendTouchEvent(point.x, point.y, 2, touchId); touches_[touchId] = nullptr; } } } void TouchTracker::Cancelled(NSSet *touches, UIView *view) { - for (UITouch* touch in touches) { + for (UITouch* touch in touches) { CGPoint point = [touch locationInView:view]; int touchId = ToTouchID(touch, false); if (touchId >= 0) { - SendTouchEvent(point.x, point.y, 2, touchId); + SendTouchEvent(point.x, point.y, 2, touchId); touches_[touchId] = nullptr; } } } void ICadeTracker::InitKeyMap() { - iCadeToKeyMap[iCadeJoystickUp] = NKCODE_DPAD_UP; - iCadeToKeyMap[iCadeJoystickRight] = NKCODE_DPAD_RIGHT; - iCadeToKeyMap[iCadeJoystickDown] = NKCODE_DPAD_DOWN; - iCadeToKeyMap[iCadeJoystickLeft] = NKCODE_DPAD_LEFT; - iCadeToKeyMap[iCadeButtonA] = NKCODE_BUTTON_9; // Select - iCadeToKeyMap[iCadeButtonB] = NKCODE_BUTTON_7; // LTrigger - iCadeToKeyMap[iCadeButtonC] = NKCODE_BUTTON_10; // Start - iCadeToKeyMap[iCadeButtonD] = NKCODE_BUTTON_8; // RTrigger - iCadeToKeyMap[iCadeButtonE] = NKCODE_BUTTON_4; // Square - iCadeToKeyMap[iCadeButtonF] = NKCODE_BUTTON_2; // Cross - iCadeToKeyMap[iCadeButtonG] = NKCODE_BUTTON_1; // Triangle - iCadeToKeyMap[iCadeButtonH] = NKCODE_BUTTON_3; // Circle + iCadeToKeyMap[iCadeJoystickUp] = NKCODE_DPAD_UP; + iCadeToKeyMap[iCadeJoystickRight] = NKCODE_DPAD_RIGHT; + iCadeToKeyMap[iCadeJoystickDown] = NKCODE_DPAD_DOWN; + iCadeToKeyMap[iCadeJoystickLeft] = NKCODE_DPAD_LEFT; + iCadeToKeyMap[iCadeButtonA] = NKCODE_BUTTON_9; // Select + iCadeToKeyMap[iCadeButtonB] = NKCODE_BUTTON_7; // LTrigger + iCadeToKeyMap[iCadeButtonC] = NKCODE_BUTTON_10; // Start + iCadeToKeyMap[iCadeButtonD] = NKCODE_BUTTON_8; // RTrigger + iCadeToKeyMap[iCadeButtonE] = NKCODE_BUTTON_4; // Square + iCadeToKeyMap[iCadeButtonF] = NKCODE_BUTTON_2; // Cross + iCadeToKeyMap[iCadeButtonG] = NKCODE_BUTTON_1; // Triangle + iCadeToKeyMap[iCadeButtonH] = NKCODE_BUTTON_3; // Circle } void ICadeTracker::ButtonDown(iCadeState button) { @@ -290,7 +292,7 @@ void ICadeTracker::ButtonDown(iCadeState button) { } void ICadeTracker::ButtonUp(iCadeState button) { - if (!iCadeConnectNotified) { + if (!iCadeConnectNotified) { iCadeConnectNotified = true; KeyMap::NotifyPadConnected(DEVICE_ID_PAD_0, "iCade"); }