From 29ea9139d1692910898f9f7180c834e77d9fefeb Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Fri, 4 Aug 2023 20:11:14 +1000 Subject: [PATCH] Consoles: Allow rebinding mappings 3DS: Also fixes that clicking on bottom screen would always mass delete blocks --- readme.md | 4 ++ src/Input.c | 23 ++++++++++-- src/Window_3DS.c | 29 +++++++-------- src/Window_GCWii.c | 91 +++++++++++++++++++--------------------------- src/Window_PSP.c | 67 ++++++++++++++++++++-------------- 5 files changed, 113 insertions(+), 101 deletions(-) diff --git a/readme.md b/readme.md index 873b56496..287c82f60 100644 --- a/readme.md +++ b/readme.md @@ -273,6 +273,10 @@ Further information (e.g. style) for ClassiCube's source code can be found in th * [libctru](https://github.com/devkitPro/libctru) - Backend for 3DS * [citro3D](https://github.com/devkitPro/citro3d) - Rendering backend for 3DS * [pspsdk](https://github.com/pspdev/pspsdk) - Backend for PSP +* [libfat](https://github.com/devkitPro/libfat) - Filesystem backend for Wii/GC +* [Citra](https://github.com/citra-emu/citra) - Emulator used to test 3DS port +* [Dolphin](https://github.com/dolphin-emu/dolphin) - Emulator used to test Wii/GC port +* [PPSSPP](https://github.com/hrydgard/ppsspp) - Emulator used to test 3DS port ## Sound Credits ClassiCube uses sounds from [Freesound.org](https://freesound.org)
diff --git a/src/Input.c b/src/Input.c index f48b0db84..51b3ed3f4 100644 --- a/src/Input.c +++ b/src/Input.c @@ -322,6 +322,18 @@ void Pointer_SetPosition(int idx, int x, int y) { *---------------------------------------------------------Keybinds--------------------------------------------------------* *#########################################################################################################################*/ cc_uint8 KeyBinds[KEYBIND_COUNT]; +/* TODO find a better way than this. maybe alternative keybinds? */ +#if defined CC_BUILD_3DS || defined CC_BUILD_PSP || defined CC_BUILD_GCWII +const cc_uint8 KeyBind_Defaults[KEYBIND_COUNT] = { + CCPAD_UP, CCPAD_DOWN, CCPAD_LEFT, CCPAD_RIGHT, /* Movement */ + CCPAD_A, 0, CCPAD_START, CCPAD_Y, /* Jump, SetSpawn, OpenChat */ + CCPAD_X, 0, CCPAD_START, 0, /* Inventory, EnterChat */ + CCKEY_LSHIFT, 'X', 'Z', 'Q', 'E', + 0, 0, 0, 0, + CCKEY_F5, 0, 0, 0, + 0, CCPAD_L, 0, CCPAD_R, +}; +#else const cc_uint8 KeyBind_Defaults[KEYBIND_COUNT] = { 'W', 'S', 'A', 'D', CCKEY_SPACE, 'R', CCKEY_ENTER, 'T', @@ -335,6 +347,7 @@ const cc_uint8 KeyBind_Defaults[KEYBIND_COUNT] = { 0, 0, 0, 0, '1','2','3', '4','5','6', '7','8','9' }; +#endif static const char* const keybindNames[KEYBIND_COUNT] = { "Forward", "Back", "Left", "Right", "Jump", "Respawn", "SetSpawn", "Chat", "Inventory", @@ -359,7 +372,8 @@ static void KeyBind_Load(void) { int i; String_InitArray_NT(name, nameBuffer); - for (i = 0; i < KEYBIND_COUNT; i++) { + for (i = 0; i < KEYBIND_COUNT; i++) + { name.length = 0; String_Format1(&name, "key-%c", keybindNames[i]); name.buffer[name.length] = '\0'; @@ -383,7 +397,8 @@ void KeyBind_Set(KeyBind binding, int key) { /* Initialises and loads key bindings from options */ static void KeyBind_Init(void) { int i; - for (i = 0; i < KEYBIND_COUNT; i++) { + for (i = 0; i < KEYBIND_COUNT; i++) + { KeyBinds[i] = KeyBind_Defaults[i]; } KeyBind_Load(); @@ -1057,7 +1072,7 @@ static void OnInputDown(void* obj, int key, cc_bool was) { int i; #ifndef CC_BUILD_WEB - if (key == CCKEY_ESCAPE && (s = Gui_GetClosable())) { + if (Input_IsEscapeButton(key) && (s = Gui_GetClosable())) { /* Don't want holding down escape to go in and out of pause menu */ if (!was) Gui_Remove(s); return; @@ -1077,7 +1092,7 @@ static void OnInputDown(void* obj, int key, cc_bool was) { if (s->VTABLE->HandlesInputDown(s, key)) return; } - if ((key == CCKEY_ESCAPE || key == CCKEY_PAUSE) && !Gui.InputGrab) { + if ((Input_IsEscapeButton(key) || key == CCKEY_PAUSE) && !Gui.InputGrab) { #ifdef CC_BUILD_WEB /* Can't do this in KeyUp, because pressing escape without having */ /* explicitly disabled mouse lock means a KeyUp event isn't sent. */ diff --git a/src/Window_3DS.c b/src/Window_3DS.c index 67e1a111f..41aa9adff 100644 --- a/src/Window_3DS.c +++ b/src/Window_3DS.c @@ -76,25 +76,21 @@ void Window_Close(void) { *----------------------------------------------------Input processing-----------------------------------------------------* *#########################################################################################################################*/ static void HandleButtons_Game(u32 mods) { - Input_SetNonRepeatable(KeyBinds[KEYBIND_PLACE_BLOCK], mods & KEY_L); - Input_SetNonRepeatable(KeyBinds[KEYBIND_DELETE_BLOCK], mods & KEY_R); + Input_SetNonRepeatable(CCPAD_L, mods & KEY_L); + Input_SetNonRepeatable(CCPAD_R, mods & KEY_R); - Input_SetNonRepeatable(KeyBinds[KEYBIND_JUMP], mods & KEY_A); - Input_SetNonRepeatable(KeyBinds[KEYBIND_INVENTORY], mods & KEY_X); - Input_SetNonRepeatable(KeyBinds[KEYBIND_CHAT], mods & KEY_Y); + Input_SetNonRepeatable(CCPAD_A, mods & KEY_A); + Input_SetNonRepeatable(CCPAD_B, mods & KEY_B); + Input_SetNonRepeatable(CCPAD_X, mods & KEY_X); + Input_SetNonRepeatable(CCPAD_Y, mods & KEY_Y); - Input_SetNonRepeatable(CCKEY_ENTER, mods & KEY_START); - Input_SetNonRepeatable(CCKEY_ESCAPE, mods & KEY_SELECT); + Input_SetNonRepeatable(CCPAD_START, mods & KEY_START); + Input_SetNonRepeatable(CCPAD_SELECT, mods & KEY_SELECT); - Input_SetNonRepeatable(KeyBinds[KEYBIND_LEFT], mods & KEY_DLEFT); - Input_SetNonRepeatable(CCPAD_LEFT, mods & KEY_DLEFT); - Input_SetNonRepeatable(KeyBinds[KEYBIND_RIGHT], mods & KEY_DRIGHT); - Input_SetNonRepeatable(CCPAD_RIGHT, mods & KEY_DRIGHT); - - Input_SetNonRepeatable(KeyBinds[KEYBIND_FORWARD], mods & KEY_DUP); - Input_SetNonRepeatable(CCPAD_UP, mods & KEY_DUP); - Input_SetNonRepeatable(KeyBinds[KEYBIND_BACK], mods & KEY_DDOWN); - Input_SetNonRepeatable(CCPAD_DOWN, mods & KEY_DDOWN); + Input_SetNonRepeatable(CCPAD_LEFT, mods & KEY_DLEFT); + Input_SetNonRepeatable(CCPAD_RIGHT, mods & KEY_DRIGHT); + Input_SetNonRepeatable(CCPAD_UP, mods & KEY_DUP); + Input_SetNonRepeatable(CCPAD_DOWN, mods & KEY_DDOWN); } static void HandleButtons_Launcher(u32 mods) { @@ -108,6 +104,7 @@ static void HandleButtons_Launcher(u32 mods) { Input_SetNonRepeatable(CCPAD_UP, mods & KEY_DUP); Input_SetNonRepeatable(CCPAD_DOWN, mods & KEY_DDOWN); } + static void ProcessJoystickInput(circlePosition* pos) { // May not be exactly 0 on actual hardware if (Math_AbsI(pos->dx) <= 4) pos->dx = 0; diff --git a/src/Window_GCWii.c b/src/Window_GCWii.c index 0f51d72b9..31794415d 100644 --- a/src/Window_GCWii.c +++ b/src/Window_GCWii.c @@ -165,47 +165,42 @@ static void ProcessWPAD_Launcher(int mods) { Input_SetNonRepeatable(CCKEY_ENTER, mods & WPAD_BUTTON_A); Input_SetNonRepeatable(CCKEY_ESCAPE, mods & WPAD_BUTTON_B); - Input_SetNonRepeatable(CCPAD_LEFT, mods & WPAD_BUTTON_LEFT); - Input_SetNonRepeatable(CCPAD_RIGHT, mods & WPAD_BUTTON_RIGHT); - Input_SetNonRepeatable(CCPAD_UP, mods & WPAD_BUTTON_UP); - Input_SetNonRepeatable(CCPAD_DOWN, mods & WPAD_BUTTON_DOWN); + Input_SetNonRepeatable(CCPAD_LEFT, mods & WPAD_BUTTON_LEFT); + Input_SetNonRepeatable(CCPAD_RIGHT, mods & WPAD_BUTTON_RIGHT); + Input_SetNonRepeatable(CCPAD_UP, mods & WPAD_BUTTON_UP); + Input_SetNonRepeatable(CCPAD_DOWN, mods & WPAD_BUTTON_DOWN); } static void ProcessWPAD_Game(int mods) { - Input_SetNonRepeatable(KeyBinds[KEYBIND_PLACE_BLOCK], mods & WPAD_BUTTON_1); - Input_SetNonRepeatable(KeyBinds[KEYBIND_DELETE_BLOCK], mods & WPAD_BUTTON_2); + Input_SetNonRepeatable(CCPAD_L, mods & WPAD_BUTTON_1); + Input_SetNonRepeatable(CCPAD_R, mods & WPAD_BUTTON_2); - Input_SetNonRepeatable(KeyBinds[KEYBIND_JUMP], mods & WPAD_BUTTON_A); - Input_SetNonRepeatable(KeyBinds[KEYBIND_INVENTORY], mods & WPAD_BUTTON_PLUS); - // TODO: WPAD_BUTTON_B + Input_SetNonRepeatable(CCPAD_A, mods & WPAD_BUTTON_A); + Input_SetNonRepeatable(CCPAD_B, mods & WPAD_BUTTON_B); + Input_SetNonRepeatable(CCPAD_X, mods & WPAD_BUTTON_PLUS); - Input_SetNonRepeatable(CCKEY_ENTER, mods & WPAD_BUTTON_HOME); - Input_SetNonRepeatable(CCKEY_ESCAPE, mods & WPAD_BUTTON_MINUS); + Input_SetNonRepeatable(CCPAD_START, mods & WPAD_BUTTON_HOME); + Input_SetNonRepeatable(CCPAD_SELECT, mods & WPAD_BUTTON_MINUS); - Input_SetNonRepeatable(KeyBinds[KEYBIND_LEFT], mods & WPAD_BUTTON_LEFT); - Input_SetNonRepeatable(CCPAD_LEFT, mods & WPAD_BUTTON_LEFT); - Input_SetNonRepeatable(KeyBinds[KEYBIND_RIGHT], mods & WPAD_BUTTON_RIGHT); - Input_SetNonRepeatable(CCPAD_RIGHT, mods & WPAD_BUTTON_RIGHT); - - Input_SetNonRepeatable(KeyBinds[KEYBIND_FORWARD], mods & WPAD_BUTTON_UP); - Input_SetNonRepeatable(CCPAD_UP, mods & WPAD_BUTTON_UP); - Input_SetNonRepeatable(KeyBinds[KEYBIND_BACK], mods & WPAD_BUTTON_DOWN); - Input_SetNonRepeatable(CCPAD_DOWN, mods & WPAD_BUTTON_DOWN); + Input_SetNonRepeatable(CCPAD_LEFT, mods & WPAD_BUTTON_LEFT); + Input_SetNonRepeatable(CCPAD_RIGHT, mods & WPAD_BUTTON_RIGHT); + Input_SetNonRepeatable(CCPAD_UP, mods & WPAD_BUTTON_UP); + Input_SetNonRepeatable(CCPAD_DOWN, mods & WPAD_BUTTON_DOWN); } static void ProcessNunchuck_Game(int mods, double delta) { WPADData* wd = WPAD_Data(0); joystick_t analog = wd->exp.nunchuk.js; - Input_SetNonRepeatable(KeyBinds[KEYBIND_PLACE_BLOCK], mods & WPAD_NUNCHUK_BUTTON_C); - Input_SetNonRepeatable(KeyBinds[KEYBIND_DELETE_BLOCK], mods & WPAD_NUNCHUK_BUTTON_Z); + Input_SetNonRepeatable(CCPAD_L, mods & WPAD_NUNCHUK_BUTTON_C); + Input_SetNonRepeatable(CCPAD_R, mods & WPAD_NUNCHUK_BUTTON_Z); - Input_SetNonRepeatable(KeyBinds[KEYBIND_JUMP], mods & WPAD_BUTTON_A); - Input_SetNonRepeatable(KeyBinds[KEYBIND_CHAT], mods & WPAD_BUTTON_1); - Input_SetNonRepeatable(KeyBinds[KEYBIND_INVENTORY], mods & WPAD_BUTTON_2); + Input_SetNonRepeatable(CCPAD_A, mods & WPAD_BUTTON_A); + Input_SetNonRepeatable(CCPAD_Y, mods & WPAD_BUTTON_1); + Input_SetNonRepeatable(CCPAD_X, mods & WPAD_BUTTON_2); - Input_SetNonRepeatable(CCKEY_ENTER, mods & WPAD_BUTTON_HOME); - Input_SetNonRepeatable(CCKEY_ESCAPE, mods & WPAD_BUTTON_MINUS); + Input_SetNonRepeatable(CCPAD_START, mods & WPAD_BUTTON_HOME); + Input_SetNonRepeatable(CCPAD_SELECT, mods & WPAD_BUTTON_MINUS); Input_SetNonRepeatable(KeyBinds[KEYBIND_FLY], mods & WPAD_BUTTON_LEFT); @@ -222,15 +217,10 @@ static void ProcessNunchuck_Game(int mods, double delta) { bool nunchuckLeft = (analog.ang > -90-ANGLE_DELTA) && (analog.ang < -90+ANGLE_DELTA) && (analog.mag > 0.5); bool nunchuckRight = (analog.ang > 90-ANGLE_DELTA) && (analog.ang < 90+ANGLE_DELTA) && (analog.mag > 0.5); - Input_SetNonRepeatable(KeyBinds[KEYBIND_LEFT], nunchuckLeft); - Input_SetNonRepeatable(CCPAD_LEFT, nunchuckLeft); - Input_SetNonRepeatable(KeyBinds[KEYBIND_RIGHT], nunchuckRight); - Input_SetNonRepeatable(CCPAD_RIGHT, nunchuckRight); - - Input_SetNonRepeatable(KeyBinds[KEYBIND_FORWARD], nunchuckUp); - Input_SetNonRepeatable(CCPAD_UP, nunchuckUp); - Input_SetNonRepeatable(KeyBinds[KEYBIND_BACK], nunchuckDown); - Input_SetNonRepeatable(CCPAD_DOWN, nunchuckDown); + Input_SetNonRepeatable(CCPAD_LEFT, nunchuckLeft); + Input_SetNonRepeatable(CCPAD_RIGHT, nunchuckRight); + Input_SetNonRepeatable(CCPAD_UP, nunchuckUp); + Input_SetNonRepeatable(CCPAD_DOWN, nunchuckDown); } static void ProcessClassic_Joystick(struct joystick_t* js) { @@ -249,26 +239,21 @@ static void ProcessClassic_Game(void) { classic_ctrl_t ctrls = wd->exp.classic; int mods = ctrls.btns | ctrls.btns_held; - Input_SetNonRepeatable(KeyBinds[KEYBIND_PLACE_BLOCK], mods & CLASSIC_CTRL_BUTTON_FULL_L); - Input_SetNonRepeatable(KeyBinds[KEYBIND_DELETE_BLOCK], mods & CLASSIC_CTRL_BUTTON_FULL_R); + Input_SetNonRepeatable(CCPAD_L, mods & CLASSIC_CTRL_BUTTON_FULL_L); + Input_SetNonRepeatable(CCPAD_R, mods & CLASSIC_CTRL_BUTTON_FULL_R); - Input_SetNonRepeatable(KeyBinds[KEYBIND_JUMP], mods & CLASSIC_CTRL_BUTTON_A); - Input_SetNonRepeatable(KeyBinds[KEYBIND_INVENTORY], mods & CLASSIC_CTRL_BUTTON_X); - Input_SetNonRepeatable(KeyBinds[KEYBIND_CHAT], mods & CLASSIC_CTRL_BUTTON_Y); - // TODO: CLASSIC_CTRL_BUTTON_B + Input_SetNonRepeatable(CCPAD_A, mods & CLASSIC_CTRL_BUTTON_A); + Input_SetNonRepeatable(CCPAD_B, mods & CLASSIC_CTRL_BUTTON_B); + Input_SetNonRepeatable(CCPAD_X, mods & CLASSIC_CTRL_BUTTON_X); + Input_SetNonRepeatable(CCPAD_Y, mods & CLASSIC_CTRL_BUTTON_Y); - Input_SetNonRepeatable(CCKEY_ENTER, mods & CLASSIC_CTRL_BUTTON_PLUS); - Input_SetNonRepeatable(CCKEY_ESCAPE, mods & CLASSIC_CTRL_BUTTON_MINUS); + Input_SetNonRepeatable(CCPAD_START, mods & CLASSIC_CTRL_BUTTON_PLUS); + Input_SetNonRepeatable(CCPAD_SELECT, mods & CLASSIC_CTRL_BUTTON_MINUS); - Input_SetNonRepeatable(KeyBinds[KEYBIND_LEFT], mods & CLASSIC_CTRL_BUTTON_LEFT); - Input_SetNonRepeatable(CCPAD_LEFT, mods & CLASSIC_CTRL_BUTTON_LEFT); - Input_SetNonRepeatable(KeyBinds[KEYBIND_RIGHT], mods & CLASSIC_CTRL_BUTTON_RIGHT); - Input_SetNonRepeatable(CCPAD_RIGHT, mods & CLASSIC_CTRL_BUTTON_RIGHT); - - Input_SetNonRepeatable(KeyBinds[KEYBIND_FORWARD], mods & CLASSIC_CTRL_BUTTON_UP); - Input_SetNonRepeatable(CCPAD_UP, mods & CLASSIC_CTRL_BUTTON_UP); - Input_SetNonRepeatable(KeyBinds[KEYBIND_BACK], mods & CLASSIC_CTRL_BUTTON_DOWN); - Input_SetNonRepeatable(CCPAD_DOWN, mods & CLASSIC_CTRL_BUTTON_DOWN); + Input_SetNonRepeatable(CCPAD_LEFT, mods & CLASSIC_CTRL_BUTTON_LEFT); + Input_SetNonRepeatable(CCPAD_RIGHT, mods & CLASSIC_CTRL_BUTTON_RIGHT); + Input_SetNonRepeatable(CCPAD_UP, mods & CLASSIC_CTRL_BUTTON_UP); + Input_SetNonRepeatable(CCPAD_DOWN, mods & CLASSIC_CTRL_BUTTON_DOWN); if (Input.RawMode) { ProcessClassic_Joystick(&ctrls.ljs); diff --git a/src/Window_PSP.c b/src/Window_PSP.c index 110df0a55..0778abd1a 100644 --- a/src/Window_PSP.c +++ b/src/Window_PSP.c @@ -14,6 +14,7 @@ #define BUFFER_WIDTH 512 #define SCREEN_WIDTH 480 #define SCREEN_HEIGHT 272 +static cc_bool launcherMode; void Window_Init(void) { DisplayInfo.Width = SCREEN_WIDTH; @@ -31,10 +32,8 @@ void Window_Init(void) { sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); } -static void DoCreateWindow(int _3d) { -} -void Window_Create2D(int width, int height) { DoCreateWindow(0); } -void Window_Create3D(int width, int height) { DoCreateWindow(1); } +void Window_Create2D(int width, int height) { launcherMode = true; } +void Window_Create3D(int width, int height) { launcherMode = false; } void Window_SetTitle(const cc_string* title) { } void Clipboard_GetText(cc_string* value) { } @@ -52,6 +51,36 @@ void Window_Close(void) { /* TODO implement */ } +static void HandleButtons_Launcher(int mods) { + Input_SetNonRepeatable(CCKEY_ENTER, mods & PSP_CTRL_TRIANGLE); + Input_SetNonRepeatable(CCKEY_ESCAPE, mods & PSP_CTRL_SQUARE); + // fake tab with PSP_CTRL_SQUARE for Launcher too + //Input_SetNonRepeatable(CCKEY_TAB, mods & PSP_CTRL_SQUARE); + + Input_SetNonRepeatable(CCPAD_LEFT, mods & PSP_CTRL_LEFT); + Input_SetNonRepeatable(CCPAD_RIGHT, mods & PSP_CTRL_RIGHT); + Input_SetNonRepeatable(CCPAD_UP, mods & PSP_CTRL_UP); + Input_SetNonRepeatable(CCPAD_DOWN, mods & PSP_CTRL_DOWN); +} + +static void HandleButtons_Game(int mods) { + Input_SetNonRepeatable(CCPAD_L, mods & PSP_CTRL_LTRIGGER); + Input_SetNonRepeatable(CCPAD_R, mods & PSP_CTRL_RTRIGGER); + + Input_SetNonRepeatable(CCPAD_A, mods & PSP_CTRL_TRIANGLE); + Input_SetNonRepeatable(CCPAD_B, mods & PSP_CTRL_SQUARE); + Input_SetNonRepeatable(CCPAD_X, mods & PSP_CTRL_CROSS); + Input_SetNonRepeatable(CCPAD_Y, mods & PSP_CTRL_CIRCLE); + + Input_SetNonRepeatable(CCPAD_START, mods & PSP_CTRL_START); + Input_SetNonRepeatable(CCPAD_SELECT, mods & PSP_CTRL_SELECT); + + Input_SetNonRepeatable(CCPAD_LEFT, mods & PSP_CTRL_LEFT); + Input_SetNonRepeatable(CCPAD_RIGHT, mods & PSP_CTRL_RIGHT); + Input_SetNonRepeatable(CCPAD_UP, mods & PSP_CTRL_UP); + Input_SetNonRepeatable(CCPAD_DOWN, mods & PSP_CTRL_DOWN); +} + void Window_ProcessEvents(double delta) { SceCtrlData pad; /* TODO implement */ @@ -63,31 +92,13 @@ void Window_ProcessEvents(double delta) { if (Input.RawMode && (Math_AbsI(dx) > 1 || Math_AbsI(dy) > 1)) { //Platform_Log2("RAW: %i, %i", &dx, &dy); Event_RaiseRawMove(&PointerEvents.RawMoved, dx / 32.0f, dy / 32.0f); + } + + if (launcherMode) { + HandleButtons_Launcher(mods); + } else { + HandleButtons_Game(mods); } - - - Input_SetNonRepeatable(KeyBinds[KEYBIND_PLACE_BLOCK], mods & PSP_CTRL_LTRIGGER); - Input_SetNonRepeatable(KeyBinds[KEYBIND_DELETE_BLOCK], mods & PSP_CTRL_RTRIGGER); - - Input_SetNonRepeatable(KeyBinds[KEYBIND_JUMP], mods & PSP_CTRL_TRIANGLE); - Input_SetNonRepeatable(KeyBinds[KEYBIND_CHAT], mods & PSP_CTRL_CIRCLE); - Input_SetNonRepeatable(KeyBinds[KEYBIND_INVENTORY], mods & PSP_CTRL_CROSS); - // PSP_CTRL_SQUARE - - Input_SetNonRepeatable(CCKEY_ENTER, mods & PSP_CTRL_START); - Input_SetNonRepeatable(CCKEY_ESCAPE, mods & PSP_CTRL_SELECT); - // fake tab with PSP_CTRL_SQUARE for Launcher too - Input_SetNonRepeatable(CCKEY_TAB, mods & PSP_CTRL_SQUARE); - - Input_SetNonRepeatable(KeyBinds[KEYBIND_LEFT], mods & PSP_CTRL_LEFT); - Input_SetNonRepeatable(CCPAD_LEFT, mods & PSP_CTRL_LEFT); - Input_SetNonRepeatable(KeyBinds[KEYBIND_RIGHT], mods & PSP_CTRL_RIGHT); - Input_SetNonRepeatable(CCPAD_RIGHT, mods & PSP_CTRL_RIGHT); - - Input_SetNonRepeatable(KeyBinds[KEYBIND_FORWARD], mods & PSP_CTRL_UP); - Input_SetNonRepeatable(CCPAD_UP, mods & PSP_CTRL_UP); - Input_SetNonRepeatable(KeyBinds[KEYBIND_BACK], mods & PSP_CTRL_DOWN); - Input_SetNonRepeatable(CCPAD_DOWN, mods & PSP_CTRL_DOWN); } static void Cursor_GetRawPos(int* x, int* y) {