From d8c2c68237ccd58f3c58eb6bca5bc391d1252aaf Mon Sep 17 00:00:00 2001 From: Eilionoir Tunnicliff Date: Thu, 16 Mar 2023 02:47:03 -0400 Subject: [PATCH] Changes - Move controller init code to a file for the controller configurator code I'm working on locally - Add option to limit framerate to 60FPS on ProMotion-enabled displays --- Natives/LauncherPreferences.m | 2 + Natives/LauncherPreferencesViewController.m | 8 +++ Natives/customcontrols/CustomControlsUtils.h | 1 + Natives/customcontrols/CustomControlsUtils.m | 69 +++++++++++++++++++ Natives/en.lproj/Localizable.strings | 2 + Natives/input/ControllerInput.m | 65 +++++------------ Natives/main.m | 1 + Natives/resources/Assets.car | Bin 9232352 -> 9232352 bytes 8 files changed, 99 insertions(+), 49 deletions(-) diff --git a/Natives/LauncherPreferences.m b/Natives/LauncherPreferences.m index dbdad5b0..085d6a42 100644 --- a/Natives/LauncherPreferences.m +++ b/Natives/LauncherPreferences.m @@ -131,10 +131,12 @@ void loadPreferences(BOOL reset) { setDefaultValueForPref(envPrefDict, @"gyroscope_invert_x_axis", @NO); setDefaultValueForPref(envPrefDict, @"gyroscope_sensitivity", @(100)); setDefaultValueForPref(envPrefDict, @"default_ctrl", @"default.json"); + setDefaultValueForPref(envPrefDict, @"default_gamepad_ctrl", @"default.json"); setDefaultValueForPref(envPrefDict, @"game_directory", @"default"); setDefaultValueForPref(envPrefDict, @"java_args", @""); setDefaultValueForPref(envPrefDict, @"allocated_memory", [NSNumber numberWithFloat:roundf((NSProcessInfo.processInfo.physicalMemory / 1048576) * 0.25)]); setDefaultValueForPref(envPrefDict, @"jitstreamer_server", @"69.69.0.1"); + setDefaultValueForPref(envPrefDict, @"max_framerate", @YES); setDefaultValueForPref(prefDict, @"appicon", @"AppIcon-Light"); setDefaultValueForPref(prefDict, @"debug_logging", @(CONFIG_RELEASE != 1)); setDefaultValueForPref(prefDict, @"cosmetica", @YES); diff --git a/Natives/LauncherPreferencesViewController.m b/Natives/LauncherPreferencesViewController.m index 2649a935..50ec3f5d 100644 --- a/Natives/LauncherPreferencesViewController.m +++ b/Natives/LauncherPreferencesViewController.m @@ -211,6 +211,14 @@ typedef void(^CreateView)(UITableViewCell *, NSString *, NSDictionary *); @"min": @(25), @"max": @(150) }, + @{@"key": @"max_framerate", + @"hasDetail": @YES, + @"icon": @"timelapse", + @"type": self.typeSwitch, + @"enableCondition": ^BOOL(){ + return whenNotInGame() && (UIScreen.mainScreen.maximumFramesPerSecond > 60); + } + }, @{@"key": @"fullscreen_airplay", @"hasDetail": @YES, @"icon": @"airplayvideo", diff --git a/Natives/customcontrols/CustomControlsUtils.h b/Natives/customcontrols/CustomControlsUtils.h index bc7c38ee..3dcc2b66 100644 --- a/Natives/customcontrols/CustomControlsUtils.h +++ b/Natives/customcontrols/CustomControlsUtils.h @@ -11,6 +11,7 @@ int convertUIColor2ARGB(UIColor* color); int convertUIColor2RGB(UIColor* color); BOOL convertLayoutIfNecessary(NSMutableDictionary* dict); void generateAndSaveDefaultControl(); +void generateAndSaveDefaultControlForGamepad(); void loadControlObject(UIView* targetView, NSMutableDictionary* controlDictionary); void initKeycodeTable(NSMutableArray* keyCodeMap, NSMutableArray* keyValueMap); diff --git a/Natives/customcontrols/CustomControlsUtils.m b/Natives/customcontrols/CustomControlsUtils.m index 95d087fe..0154ba2e 100644 --- a/Natives/customcontrols/CustomControlsUtils.m +++ b/Natives/customcontrols/CustomControlsUtils.m @@ -23,6 +23,14 @@ NSMutableDictionary* createButton(NSString* name, int* keycodes, NSString* dynam return dict; } +NSMutableDictionary* createGamepadButton(NSString* name, int gamepad_button, int keycode) { + NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; + dict[@"name"] = name; + dict[@"gamepad_button"] = @(gamepad_button); + dict[@"keycode"] = @(keycode); + return dict; +} + UIColor* convertARGB2UIColor(int argb) { return [UIColor colorWithRed:((argb>>16)&0xFF)/255.0 @@ -302,6 +310,67 @@ void generateAndSaveDefaultControl() { */ } +void generateAndSaveDefaultControlForGamepad() { + NSString *gamepadPath = [NSString stringWithFormat:@"%s/controlmap/gamepad-default.json", getenv("POJAV_HOME")]; + if ([NSFileManager.defaultManager fileExistsAtPath:gamepadPath]) { + return; + } + + NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; + dict[@"version"] = @(1); + + dict[@"mGameMappingList"] = [[NSMutableArray alloc] init]; + + [dict[@"mGameMappingList"] addObject:createGamepadButton(@"mouse_primary", SPECIALBTN_MOUSEPRI, SPECIALBTN_MOUSEPRI)]; + [dict[@"mGameMappingList"] addObject:createGamepadButton(@"mouse_middle", SPECIALBTN_MOUSEMID, SPECIALBTN_MOUSEMID)]; + [dict[@"mGameMappingList"] addObject:createGamepadButton(@"mouse_secondary", SPECIALBTN_MOUSESEC, SPECIALBTN_MOUSESEC)]; + + [dict[@"mGameMappingList"] addObject:createGamepadButton(@"bumper_left", GLFW_GAMEPAD_BUTTON_LEFT_BUMPER, SPECIALBTN_SCROLLUP)]; + [dict[@"mGameMappingList"] addObject:createGamepadButton(@"bumper_right", GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER, SPECIALBTN_SCROLLDOWN)]; + + [dict[@"mGameMappingList"] addObject:createGamepadButton(@"trigger_left", GLFW_GAMEPAD_BUTTON_LEFT_TRIGGER, SPECIALBTN_MOUSESEC)]; + [dict[@"mGameMappingList"] addObject:createGamepadButton(@"trigger_right", GLFW_GAMEPAD_BUTTON_RIGHT_TRIGGER, SPECIALBTN_MOUSEPRI)]; + + [dict[@"mGameMappingList"] addObject:createGamepadButton(@"named_back", GLFW_GAMEPAD_BUTTON_BACK, GLFW_KEY_TAB)]; + [dict[@"mGameMappingList"] addObject:createGamepadButton(@"named_start", GLFW_GAMEPAD_BUTTON_START, GLFW_KEY_ESCAPE)]; + + [dict[@"mGameMappingList"] addObject:createGamepadButton(@"named_a", GLFW_GAMEPAD_BUTTON_A, GLFW_KEY_SPACE)]; + [dict[@"mGameMappingList"] addObject:createGamepadButton(@"named_b", GLFW_GAMEPAD_BUTTON_B, GLFW_KEY_Q)]; + [dict[@"mGameMappingList"] addObject:createGamepadButton(@"named_x", GLFW_GAMEPAD_BUTTON_X, GLFW_KEY_E)]; + [dict[@"mGameMappingList"] addObject:createGamepadButton(@"named_y", GLFW_GAMEPAD_BUTTON_Y, GLFW_KEY_F)]; + + [dict[@"mGameMappingList"] addObject:createGamepadButton(@"dpad_up", GLFW_GAMEPAD_BUTTON_DPAD_UP, GLFW_KEY_LEFT_SHIFT)]; + [dict[@"mGameMappingList"] addObject:createGamepadButton(@"dpad_down", GLFW_GAMEPAD_BUTTON_DPAD_DOWN, GLFW_KEY_O)]; + [dict[@"mGameMappingList"] addObject:createGamepadButton(@"dpad_left", GLFW_GAMEPAD_BUTTON_DPAD_LEFT, GLFW_KEY_J)]; + [dict[@"mGameMappingList"] addObject:createGamepadButton(@"dpad_right", GLFW_GAMEPAD_BUTTON_DPAD_RIGHT, GLFW_KEY_K)]; + + [dict[@"mGameMappingList"] addObject:createGamepadButton(@"thumb_left", GLFW_GAMEPAD_BUTTON_LEFT_THUMB, GLFW_KEY_LEFT_CONTROL)]; + [dict[@"mGameMappingList"] addObject:createGamepadButton(@"thumb_right", GLFW_GAMEPAD_BUTTON_RIGHT_THUMB, -GLFW_KEY_LEFT_SHIFT)]; + + dict[@"mMenuMappingList"] = [[NSMutableArray alloc] init]; + + [dict[@"mMenuMappingList"] addObject:createGamepadButton(@"mouse_primary", SPECIALBTN_MOUSEPRI, SPECIALBTN_MOUSEPRI)]; + [dict[@"mMenuMappingList"] addObject:createGamepadButton(@"mouse_middle", SPECIALBTN_MOUSEMID, SPECIALBTN_MOUSEMID)]; + [dict[@"mMenuMappingList"] addObject:createGamepadButton(@"mouse_secondary", SPECIALBTN_MOUSESEC, SPECIALBTN_MOUSESEC)]; + + [dict[@"mMenuMappingList"] addObject:createGamepadButton(@"bumper_left", GLFW_GAMEPAD_BUTTON_LEFT_BUMPER, SPECIALBTN_SCROLLUP)]; + [dict[@"mMenuMappingList"] addObject:createGamepadButton(@"bumper_right", GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER, SPECIALBTN_SCROLLDOWN)]; + + [dict[@"mMenuMappingList"] addObject:createGamepadButton(@"named_a", GLFW_GAMEPAD_BUTTON_A, SPECIALBTN_MOUSEPRI)]; + [dict[@"mMenuMappingList"] addObject:createGamepadButton(@"named_b", GLFW_GAMEPAD_BUTTON_B, GLFW_KEY_ESCAPE)]; + [dict[@"mMenuMappingList"] addObject:createGamepadButton(@"named_x", GLFW_GAMEPAD_BUTTON_X, SPECIALBTN_MOUSESEC)]; + [dict[@"mMenuMappingList"] addObject:createGamepadButton(@"named_y", GLFW_GAMEPAD_BUTTON_Y, GLFW_KEY_LEFT_SHIFT)]; + + [dict[@"mMenuMappingList"] addObject:createGamepadButton(@"dpad_down", GLFW_GAMEPAD_BUTTON_DPAD_DOWN, GLFW_KEY_O)]; + [dict[@"mMenuMappingList"] addObject:createGamepadButton(@"dpad_left", GLFW_GAMEPAD_BUTTON_DPAD_LEFT, GLFW_KEY_J)]; + [dict[@"mMenuMappingList"] addObject:createGamepadButton(@"dpad_right", GLFW_GAMEPAD_BUTTON_DPAD_RIGHT, GLFW_KEY_K)]; + + NSOutputStream *os = [[NSOutputStream alloc] initToFileAtPath:gamepadPath append:NO]; + [os open]; + [NSJSONSerialization writeJSONObject:dict toStream:os options:NSJSONWritingPrettyPrinted error:nil]; + [os close]; +} + void loadControlObject(UIView* targetView, NSMutableDictionary* controlDictionary) { NSMutableString *errorString = [[NSMutableString alloc] init]; diff --git a/Natives/en.lproj/Localizable.strings b/Natives/en.lproj/Localizable.strings index 2edea2cd..b3fd0392 100644 --- a/Natives/en.lproj/Localizable.strings +++ b/Natives/en.lproj/Localizable.strings @@ -175,6 +175,8 @@ "preference.title.resolution" = "Resolution (%)"; "preference.detail.resolution" = "Allows you to decrease the game resolution."; +"preference.title.max_framerate" = "Maximum framerate"; +"preference.detail.max_framerate" = "Allows you to limit the game framerate to 60FPS on ProMotion displays."; "preference.title.fullscreen_airplay" = "Fullscreen AirPlay"; "preference.detail.fullscreen_airplay" = "Allows presenting fullscreen game window on the external display rather than mirroring everything on screen."; diff --git a/Natives/input/ControllerInput.m b/Natives/input/ControllerInput.m index b2f2d85e..20013e99 100644 --- a/Natives/input/ControllerInput.m +++ b/Natives/input/ControllerInput.m @@ -1,4 +1,5 @@ #import "ControllerInput.h" +#import "../LauncherPreferences.h" #import "../SurfaceViewController.h" #import "../utils.h" @@ -28,61 +29,27 @@ BOOL leftShiftHeld; if (gameMap && menuMap) { return; } - - gameMap = [[NSMutableDictionary alloc] init]; - - gameMap[@(SPECIALBTN_MOUSEPRI)] = @(SPECIALBTN_MOUSEPRI); - gameMap[@(SPECIALBTN_MOUSEMID)] = @(SPECIALBTN_MOUSEMID); - gameMap[@(SPECIALBTN_MOUSESEC)] = @(SPECIALBTN_MOUSESEC); - - gameMap[@(GLFW_GAMEPAD_BUTTON_LEFT_BUMPER)] = @(SPECIALBTN_SCROLLUP); - gameMap[@(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER)] = @(SPECIALBTN_SCROLLDOWN); - - gameMap[@(GLFW_GAMEPAD_BUTTON_LEFT_TRIGGER)] = @(SPECIALBTN_MOUSESEC); - gameMap[@(GLFW_GAMEPAD_BUTTON_RIGHT_TRIGGER)] = @(SPECIALBTN_MOUSEPRI); - - gameMap[@(GLFW_GAMEPAD_BUTTON_BACK)] = @(GLFW_KEY_TAB); - gameMap[@(GLFW_GAMEPAD_BUTTON_START)] = @(GLFW_KEY_ESCAPE); - //gameMap[@(GLFW_GAMEPAD_BUTTON_GUIDE)] = @(GLFW_KEY_UNKNOWN); - - gameMap[@(GLFW_GAMEPAD_BUTTON_A)] = @(GLFW_KEY_SPACE); - gameMap[@(GLFW_GAMEPAD_BUTTON_B)] = @(GLFW_KEY_Q); - gameMap[@(GLFW_GAMEPAD_BUTTON_X)] = @(GLFW_KEY_E); - gameMap[@(GLFW_GAMEPAD_BUTTON_Y)] = @(GLFW_KEY_F); - - gameMap[@(GLFW_GAMEPAD_BUTTON_DPAD_UP)] = @(GLFW_KEY_LEFT_SHIFT); - gameMap[@(GLFW_GAMEPAD_BUTTON_DPAD_DOWN)] = @(GLFW_KEY_O); - gameMap[@(GLFW_GAMEPAD_BUTTON_DPAD_LEFT)] = @(GLFW_KEY_J); - gameMap[@(GLFW_GAMEPAD_BUTTON_DPAD_RIGHT)] = @(GLFW_KEY_K); - - gameMap[@(GLFW_GAMEPAD_BUTTON_LEFT_THUMB)] = @(GLFW_KEY_LEFT_CONTROL); - gameMap[@(GLFW_GAMEPAD_BUTTON_RIGHT_THUMB)] = @(-GLFW_KEY_LEFT_SHIFT); - - menuMap = [[NSMutableDictionary alloc] init]; - - menuMap[@(SPECIALBTN_MOUSEPRI)] = @(SPECIALBTN_MOUSEPRI); - menuMap[@(SPECIALBTN_MOUSEMID)] = @(SPECIALBTN_MOUSEMID); - menuMap[@(SPECIALBTN_MOUSESEC)] = @(SPECIALBTN_MOUSESEC); - - menuMap[@(GLFW_GAMEPAD_BUTTON_LEFT_BUMPER)] = @(SPECIALBTN_SCROLLUP); - menuMap[@(GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER)] = @(SPECIALBTN_SCROLLDOWN); - - menuMap[@(GLFW_GAMEPAD_BUTTON_A)] = @(SPECIALBTN_MOUSEPRI); - menuMap[@(GLFW_GAMEPAD_BUTTON_B)] = @(GLFW_KEY_ESCAPE); - menuMap[@(GLFW_GAMEPAD_BUTTON_X)] = @(SPECIALBTN_MOUSESEC); - menuMap[@(GLFW_GAMEPAD_BUTTON_Y)] = @(GLFW_KEY_LEFT_SHIFT); - - menuMap[@(GLFW_GAMEPAD_BUTTON_DPAD_DOWN)] = @(GLFW_KEY_O); - menuMap[@(GLFW_GAMEPAD_BUTTON_DPAD_LEFT)] = @(GLFW_KEY_J); - menuMap[@(GLFW_GAMEPAD_BUTTON_DPAD_RIGHT)] = @(GLFW_KEY_K); + + NSString *gamepadPath = [NSString stringWithFormat:@"%s/controlmap/gamepad-%@", getenv("POJAV_HOME"), getPreference(@"default_gamepad_ctrl")]; + NSMutableDictionary *gamepadJSON = parseJSONFromFile(gamepadPath); + + gameMap = gamepadJSON[@"mGameMappingList"]; + menuMap = gamepadJSON[@"mMenuMappingList"]; } + (void)sendKeyEvent:(int)controllerKeycode pressed:(BOOL)pressed { int keycode; + __block NSMutableDictionary *mapping; if (isGrabbing) { - keycode = [gameMap[@(controllerKeycode)] intValue]; + mapping = gameMap; } else { - keycode = [menuMap[@(controllerKeycode)] intValue]; + mapping = menuMap; + } + + for (NSMutableDictionary *buttonDict in mapping) { + if(controllerKeycode == [buttonDict[@"gamepad_button"] intValue]) { + keycode = [buttonDict[@"keycode"] intValue]; + } } switch (keycode) { diff --git a/Natives/main.m b/Natives/main.m index d297dc76..6b5edbb5 100644 --- a/Natives/main.m +++ b/Natives/main.m @@ -242,6 +242,7 @@ void init_setupCustomControls() { NSString *controlPath = [@(getenv("POJAV_HOME")) stringByAppendingPathComponent:@"controlmap"]; [fm createDirectoryAtPath:controlPath withIntermediateDirectories:NO attributes:nil error:nil]; generateAndSaveDefaultControl(); + generateAndSaveDefaultControlForGamepad(); } void init_setupLauncherProfiles() { diff --git a/Natives/resources/Assets.car b/Natives/resources/Assets.car index e78206d04ea4a95cc263f36275a6f9c01f471bc1..6acece54c01dad0a8d34341e8e5c347d17ee1ee2 100644 GIT binary patch delta 726 zcma*lSyPPx7{KxOB<(9vS?bL$2Zhi%vX*_R?0Y1k$P!wK5IT1?<3n_lVW!JIg5$2s z^8sA=2!6)B>Ebv4d1juQXXZ)GeoId=JzHIp9|S=jx#W<|m!Hu@`PZ6cmw~ zR-h_ab2Y^8=;wy~WZ)UlIY?53U=e{bDG1AE!WehzSuLp0LFVUBQ= zV;tuMCppDw&d^K?t(@f?=efW|E^(PFT;&?qxxr1^xW#SSxkCqc>Es^wc|aH4Jme8Q zJmv{cc}6eKdBIEi=x2aIh8X4*uNmPDZyDts@A<$OANj;*#%IEKVrsIgI0#}%@0O-1 aEz;lr=C}lfGrxW$DzoOX7oAId&-??cJk4ML delta 721 zcma*lSyPPx7{KxOBsy&>M3(A3mXMH=IIltpMajODeNBbzq%0xJxr%S$rlw}P%s0@b zJAD8bK7wE4-njV9f1a7==9zhBrpD7}7@aCF%nX7cPA)lQlQow385^sd{)g7sNECh^ zO|}n((Qp{WNMjD^%w--K#K|O!Y;wqDK6&I*zycPsh(Z>#gd&!*jODDLm=a0}NwAVt ztY!^mtYsbRDQ5!}Y-AIgsbmXPRI`;Dwo%J=c93ND)}7Q*&n|YehXxwiOB4Ip&jFfg z;UI@-rH#Y1bA+QD<2WZc$tg~AhO>0g$vMt*fs0(?GFQ0DHLi1mn{;uDZhGkDHg~v7 zANRP=10M2-$2{RF&*