diff --git a/sysmodules/rosalina/include/menu.h b/sysmodules/rosalina/include/menu.h index bcf162b..760d3b1 100644 --- a/sysmodules/rosalina/include/menu.h +++ b/sysmodules/rosalina/include/menu.h @@ -27,26 +27,15 @@ #pragma once #include <3ds/types.h> +#include <3ds/services/hid.h> #include "MyThread.h" #include "utils.h" #define HID_PAD (REG32(0x10146000) ^ 0xFFF) -#define BUTTON_A (1 << 0) -#define BUTTON_B (1 << 1) -#define BUTTON_SELECT (1 << 2) -#define BUTTON_START (1 << 3) -#define BUTTON_RIGHT (1 << 4) -#define BUTTON_LEFT (1 << 5) -#define BUTTON_UP (1 << 6) -#define BUTTON_DOWN (1 << 7) -#define BUTTON_R1 (1 << 8) -#define BUTTON_L1 (1 << 9) -#define BUTTON_X (1 << 10) -#define BUTTON_Y (1 << 11) -#define DEFAULT_MENU_COMBO (BUTTON_L1 | BUTTON_DOWN | BUTTON_SELECT) -#define DIRECTIONAL_KEYS (BUTTON_DOWN | BUTTON_UP | BUTTON_LEFT | BUTTON_RIGHT) +#define DEFAULT_MENU_COMBO (KEY_L | KEY_DDOWN | KEY_SELECT) +#define DIRECTIONAL_KEYS (KEY_DOWN | KEY_UP | KEY_LEFT | KEY_RIGHT) #define CORE_APPLICATION 0 #define CORE_SYSTEM 1 diff --git a/sysmodules/rosalina/source/main.c b/sysmodules/rosalina/source/main.c index afe17ad..0d3dc05 100644 --- a/sysmodules/rosalina/source/main.c +++ b/sysmodules/rosalina/source/main.c @@ -183,12 +183,14 @@ static void handlePreTermNotification(u32 notificationId) SysConfigMenu_UpdateStatus(true); } + Draw_Lock(); if (isHidInitialized) hidExit(); // Termination request terminationRequest = true; svcSignalEvent(terminationRequestEvent); + Draw_Unlock(); } static void handleNextApplicationDebuggedByForce(u32 notificationId) diff --git a/sysmodules/rosalina/source/menu.c b/sysmodules/rosalina/source/menu.c index 6b5e5dc..b6cfd7d 100644 --- a/sysmodules/rosalina/source/menu.c +++ b/sysmodules/rosalina/source/menu.c @@ -46,17 +46,10 @@ bool hidShouldUseIrrst(void) return false; } -static u32 convertHidKeys(u32 keys) +static inline u32 convertHidKeys(u32 keys) { - u32 buttons = keys & 0xFFF; - - // Transform Circle Pad and C-stick into directional keys - if (keys & KEY_LEFT) buttons |= BUTTON_LEFT; - if (keys & KEY_RIGHT) buttons |= BUTTON_RIGHT; - if (keys & KEY_UP) buttons |= BUTTON_UP; - if (keys & KEY_DOWN) buttons |= BUTTON_DOWN; - - return buttons; + // Nothing to do yet + return keys; } u32 waitInputWithTimeout(s32 msec) @@ -67,12 +60,19 @@ u32 waitInputWithTimeout(s32 msec) do { svcSleepThread(1 * 1000 * 1000LL); - if (!isHidInitialized || terminationRequest) break; - n += 1; + Draw_Lock(); + if (!isHidInitialized || terminationRequest) + { + keys = 0; + Draw_Unlock(); + break; + } + n++; hidScanInput(); keys = convertHidKeys(hidKeysDown()) | (convertHidKeys(hidKeysDownRepeat()) & DIRECTIONAL_KEYS); - } while (keys == 0 && !terminationRequest && isHidInitialized && n < msec); + Draw_Unlock(); + } while (keys == 0 && !terminationRequest && isHidInitialized && (msec < 0 || n < msec)); return keys; @@ -83,22 +83,54 @@ u32 waitInput(void) return waitInputWithTimeout(-1); } +static u32 scanHeldKeys(void) +{ + u32 keys; + + Draw_Lock(); + + if (!isHidInitialized || terminationRequest) + keys = 0; + else + { + hidScanInput(); + keys = convertHidKeys(hidKeysHeld()); + } + + Draw_Unlock(); + return keys; +} + u32 waitComboWithTimeout(s32 msec) { s32 n = 0; - u32 keys; + u32 keys = 0; + u32 tempKeys = 0; - hidScanInput(); - keys = convertHidKeys(hidKeysHeld()); + // Wait for nothing to be pressed + while (scanHeldKeys() != 0 && !terminationRequest && isHidInitialized && (msec < 0 || n < msec)) + { + svcSleepThread(1 * 1000 * 1000LL); + n++; + } + + if (terminationRequest || !isHidInitialized || !(msec < 0 || n < msec)) + return 0; do { svcSleepThread(1 * 1000 * 1000LL); - if (!isHidInitialized || terminationRequest) break; - n += 1; - hidScanInput(); - keys = convertHidKeys(hidKeysHeld()); - } while (keys == 0 && !terminationRequest && isHidInitialized && n < msec); + n++; + + tempKeys = scanHeldKeys(); + + for (u32 i = 0x10000; i > 0; i--) + { + if (tempKeys != scanHeldKeys()) break; + if (i == 1) keys = tempKeys; + } + } + while((keys == 0 || scanHeldKeys() != 0) && !terminationRequest && isHidInitialized && (msec < 0 || n < msec)); return keys; } @@ -137,15 +169,13 @@ void menuThreadMain(void) svcSleepThread(500 * 1000 * 1000LL); hidInit(); // assume this doesn't fail - hidSetRepeatParameters(250, 100); isHidInitialized = true; while(!terminationRequest) { - u32 keys = waitComboWithTimeout(1); Cheat_ApplyCheats(); - if((keys & menuCombo) == menuCombo) + if((scanHeldKeys() & menuCombo) == menuCombo) { menuEnter(); if(isN3DS) N3DSMenu_UpdateStatus(); @@ -268,14 +298,25 @@ void menuShow(Menu *root) Draw_Lock(); Draw_ClearFramebuffer(); Draw_FlushFramebuffer(); + hidSetRepeatParameters(0, 0); menuDraw(currentMenu, selectedItem); Draw_Unlock(); + bool menuComboReleased = false; + do { u32 pressed = waitInputWithTimeout(1000); - if(pressed & BUTTON_A) + if(!menuComboReleased && (scanHeldKeys() & menuCombo) != menuCombo) + { + menuComboReleased = true; + Draw_Lock(); + hidSetRepeatParameters(200, 100); + Draw_Unlock(); + } + + if(pressed & KEY_A) { Draw_Lock(); Draw_ClearFramebuffer(); @@ -301,7 +342,7 @@ void menuShow(Menu *root) Draw_FlushFramebuffer(); Draw_Unlock(); } - else if(pressed & BUTTON_B) + else if(pressed & KEY_B) { Draw_Lock(); Draw_ClearFramebuffer(); @@ -316,12 +357,12 @@ void menuShow(Menu *root) else break; } - else if(pressed & BUTTON_DOWN) + else if(pressed & KEY_DOWN) { if(++selectedItem >= currentMenu->nbItems) selectedItem = 0; } - else if(pressed & BUTTON_UP) + else if(pressed & KEY_UP) { if(selectedItem-- <= 0) selectedItem = currentMenu->nbItems - 1; diff --git a/sysmodules/rosalina/source/menus.c b/sysmodules/rosalina/source/menus.c index 41080b1..46522fb 100644 --- a/sysmodules/rosalina/source/menus.c +++ b/sysmodules/rosalina/source/menus.c @@ -89,7 +89,7 @@ void RosalinaMenu_ShowCredits(void) Draw_FlushFramebuffer(); Draw_Unlock(); } - while(!(waitInput() & BUTTON_B) && !terminationRequest); + while(!(waitInput() & KEY_B) && !terminationRequest); } void RosalinaMenu_Reboot(void) @@ -109,12 +109,12 @@ void RosalinaMenu_Reboot(void) u32 pressed = waitInputWithTimeout(1000); - if(pressed & BUTTON_A) + if(pressed & KEY_A) { menuLeave(); APT_HardwareResetAsync(); return; - } else if(pressed & BUTTON_B) + } else if(pressed & KEY_B) return; } while(!terminationRequest); @@ -137,13 +137,13 @@ void RosalinaMenu_PowerOff(void) // Soft shutdown. u32 pressed = waitInputWithTimeout(1000); - if(pressed & BUTTON_A) + if(pressed & KEY_A) { menuLeave(); srvPublishToSubscriber(0x203, 0); return; } - else if(pressed & BUTTON_B) + else if(pressed & KEY_B) return; } while(!terminationRequest); @@ -310,7 +310,7 @@ end: Draw_FlushFramebuffer(); Draw_Unlock(); } - while(!(waitInput() & BUTTON_B) && !terminationRequest); + while(!(waitInput() & KEY_B) && !terminationRequest); #undef TRY } diff --git a/sysmodules/rosalina/source/menus/cheats.c b/sysmodules/rosalina/source/menus/cheats.c index 0531b77..e2727e6 100644 --- a/sysmodules/rosalina/source/menus/cheats.c +++ b/sysmodules/rosalina/source/menus/cheats.c @@ -1944,7 +1944,7 @@ void RosalinaMenu_Cheats(void) Draw_FlushFramebuffer(); Draw_Unlock(); - } while (!(waitInput() & BUTTON_B) && !terminationRequest); + } while (!(waitInput() & KEY_B) && !terminationRequest); } else { @@ -1991,9 +1991,9 @@ void RosalinaMenu_Cheats(void) if (pressed != 0) break; } while (pressed == 0 && !terminationRequest); - if (pressed & BUTTON_B) + if (pressed & KEY_B) break; - else if ((pressed & BUTTON_A) && R_SUCCEEDED(r)) + else if ((pressed & KEY_A) && R_SUCCEEDED(r)) { if (cheats[selected]->active) { @@ -2004,13 +2004,13 @@ void RosalinaMenu_Cheats(void) r = Cheat_MapMemoryAndApplyCheat(pid, cheats[selected]); } } - else if (pressed & BUTTON_DOWN) + else if (pressed & KEY_DOWN) selected++; - else if (pressed & BUTTON_UP) + else if (pressed & KEY_UP) selected--; - else if (pressed & BUTTON_LEFT) + else if (pressed & KEY_LEFT) selected -= CHEATS_PER_MENU_PAGE; - else if (pressed & BUTTON_RIGHT) + else if (pressed & KEY_RIGHT) { if (selected + CHEATS_PER_MENU_PAGE < cheatCount) selected += CHEATS_PER_MENU_PAGE; diff --git a/sysmodules/rosalina/source/menus/debugger.c b/sysmodules/rosalina/source/menus/debugger.c index 016c9c7..d8e6aff 100644 --- a/sysmodules/rosalina/source/menus/debugger.c +++ b/sysmodules/rosalina/source/menus/debugger.c @@ -162,7 +162,7 @@ void DebuggerMenu_EnableDebugger(void) Draw_FlushFramebuffer(); Draw_Unlock(); } - while(!(waitInput() & BUTTON_B) && !terminationRequest); + while(!(waitInput() & KEY_B) && !terminationRequest); } void DebuggerMenu_DisableDebugger(void) @@ -183,7 +183,7 @@ void DebuggerMenu_DisableDebugger(void) Draw_FlushFramebuffer(); Draw_Unlock(); } - while(!(waitInput() & BUTTON_B) && !terminationRequest); + while(!(waitInput() & KEY_B) && !terminationRequest); } void DebuggerMenu_DebugNextApplicationByForce(void) @@ -232,7 +232,7 @@ void DebuggerMenu_DebugNextApplicationByForce(void) Draw_FlushFramebuffer(); Draw_Unlock(); } - while(!(waitInput() & BUTTON_B) && !terminationRequest); + while(!(waitInput() & KEY_B) && !terminationRequest); } void debuggerSocketThreadMain(void) diff --git a/sysmodules/rosalina/source/menus/miscellaneous.c b/sysmodules/rosalina/source/menus/miscellaneous.c index e7b5503..44cde04 100644 --- a/sysmodules/rosalina/source/menus/miscellaneous.c +++ b/sysmodules/rosalina/source/menus/miscellaneous.c @@ -95,13 +95,25 @@ void MiscellaneousMenu_SwitchBoot3dsxTargetTitle(void) Draw_FlushFramebuffer(); Draw_Unlock(); } - while(!(waitInput() & BUTTON_B) && !terminationRequest); + while(!(waitInput() & KEY_B) && !terminationRequest); } static void MiscellaneousMenu_ConvertComboToString(char *out, u32 combo) { - static const char *keys[] = { "A", "B", "Select", "Start", "Right", "Left", "Up", "Down", "R", "L", "X", "Y" }; - for(s32 i = 11; i >= 0; i--) + static const char *keys[] = { + "A", "B", "Select", "Start", "Right", "Left", "Up", "Down", "R", "L", "X", "Y", + "?", "?", + "ZL", "ZR", + "?", "?", "?", "?", + "Touch", + "?", "?", "?", + "CStick Right", "CStick Left", "CStick Up", "CStick Down", + "CPad Right", "CPad Left", "CPad Up", "CPad Down", + }; + + char *outOrig = out; + out[0] = 0; + for(s32 i = 31; i >= 0; i--) { if(combo & (1 << i)) { @@ -111,12 +123,13 @@ static void MiscellaneousMenu_ConvertComboToString(char *out, u32 combo) } } - out[-1] = 0; + if (out != outOrig) + out[-1] = 0; } void MiscellaneousMenu_ChangeMenuCombo(void) { - char comboStrOrig[64], comboStr[64]; + char comboStrOrig[128], comboStr[128]; u32 posY; Draw_Lock(); @@ -132,9 +145,6 @@ void MiscellaneousMenu_ChangeMenuCombo(void) posY = Draw_DrawFormattedString(10, 30, COLOR_WHITE, "The current menu combo is: %s", comboStrOrig); posY = Draw_DrawString(10, posY + SPACING_Y, COLOR_WHITE, "Please enter the new combo:"); - Draw_FlushFramebuffer(); - Draw_Unlock(); - menuCombo = waitCombo(); MiscellaneousMenu_ConvertComboToString(comboStr, menuCombo); @@ -151,7 +161,7 @@ void MiscellaneousMenu_ChangeMenuCombo(void) Draw_FlushFramebuffer(); Draw_Unlock(); } - while(!(waitInput() & BUTTON_B) && !terminationRequest); + while(!(waitInput() & KEY_B) && !terminationRequest); } void MiscellaneousMenu_SaveSettings(void) @@ -217,7 +227,7 @@ void MiscellaneousMenu_SaveSettings(void) Draw_FlushFramebuffer(); Draw_Unlock(); } - while(!(waitInput() & BUTTON_B) && !terminationRequest); + while(!(waitInput() & KEY_B) && !terminationRequest); } void MiscellaneousMenu_InputRedirection(void) @@ -317,7 +327,7 @@ void MiscellaneousMenu_InputRedirection(void) Draw_FlushFramebuffer(); Draw_Unlock(); } - while(!(waitInput() & BUTTON_B) && !terminationRequest); + while(!(waitInput() & KEY_B) && !terminationRequest); } void MiscellaneousMenu_SyncTimeDate(void) @@ -351,16 +361,16 @@ void MiscellaneousMenu_SyncTimeDate(void) input = waitInput(); - if(input & BUTTON_LEFT) utcOffset = (24 + utcOffset - 1) % 24; // ensure utcOffset >= 0 - if(input & BUTTON_RIGHT) utcOffset = (utcOffset + 1) % 24; - if(input & BUTTON_UP) utcOffsetMinute = (utcOffsetMinute + 1) % 60; - if(input & BUTTON_DOWN) utcOffsetMinute = (60 + utcOffsetMinute - 1) % 60; + if(input & KEY_LEFT) utcOffset = (24 + utcOffset - 1) % 24; // ensure utcOffset >= 0 + if(input & KEY_RIGHT) utcOffset = (utcOffset + 1) % 24; + if(input & KEY_UP) utcOffsetMinute = (utcOffsetMinute + 1) % 60; + if(input & KEY_DOWN) utcOffsetMinute = (60 + utcOffsetMinute - 1) % 60; Draw_FlushFramebuffer(); Draw_Unlock(); } - while(!(input & (BUTTON_A | BUTTON_B)) && !terminationRequest); + while(!(input & (KEY_A | KEY_B)) && !terminationRequest); - if (input & BUTTON_B) + if (input & KEY_B) return; utcOffset -= 12; @@ -400,6 +410,6 @@ void MiscellaneousMenu_SyncTimeDate(void) Draw_FlushFramebuffer(); Draw_Unlock(); } - while(!(input & BUTTON_B) && !terminationRequest); + while(!(input & KEY_B) && !terminationRequest); } diff --git a/sysmodules/rosalina/source/menus/process_list.c b/sysmodules/rosalina/source/menus/process_list.c index 47b0bdc..6cbd77e 100644 --- a/sysmodules/rosalina/source/menus/process_list.c +++ b/sysmodules/rosalina/source/menus/process_list.c @@ -197,7 +197,7 @@ end: Draw_FlushFramebuffer(); Draw_Unlock(); } - while(!(waitInput() & BUTTON_B) && !terminationRequest); + while(!(waitInput() & KEY_B) && !terminationRequest); #undef TRY } @@ -493,21 +493,21 @@ static void ProcessListMenu_MemoryViewer(const ProcessInfo *info) u32 pressed = waitInputWithTimeout(1000); - if(pressed & BUTTON_A) + if(pressed & KEY_A) editing = !editing; - else if(pressed & BUTTON_X) + else if(pressed & KEY_X) { if(checkMode(MENU_MODE_GOTO)) finishJumping(); else gotoAddress = __builtin_bswap32(((u32)menus[MENU_MODE_NORMAL].buf) + menus[MENU_MODE_NORMAL].selected); } - else if(pressed & BUTTON_Y) + else if(pressed & KEY_Y) { if(checkMode(MENU_MODE_SEARCH)) finishSearching(); } - else if(pressed & BUTTON_SELECT) + else if(pressed & KEY_SELECT) { clearMenu(); ProcessListMenu_DumpMemory(info->name, menus[MENU_MODE_NORMAL].buf, menus[MENU_MODE_NORMAL].max); @@ -517,35 +517,35 @@ static void ProcessListMenu_MemoryViewer(const ProcessInfo *info) if(editing) { // Edit the highlighted byte - if(pressed & BUTTON_LEFT) + if(pressed & KEY_LEFT) selectedByteAdd0x10(); - else if(pressed & BUTTON_RIGHT) + else if(pressed & KEY_RIGHT) selectedByteSub0x10(); - else if(pressed & BUTTON_UP) + else if(pressed & KEY_UP) selectedByteIncrement(); - else if(pressed & BUTTON_DOWN) + else if(pressed & KEY_DOWN) selectedByteDecrement(); } else { // Move the cursor - if(pressed & BUTTON_LEFT) + if(pressed & KEY_LEFT) selectedMoveLeft(); - else if(pressed & BUTTON_RIGHT) + else if(pressed & KEY_RIGHT) selectedMoveRight(); - else if(pressed & BUTTON_UP) + else if(pressed & KEY_UP) selectedMoveUp(); - else if(pressed & BUTTON_DOWN) + else if(pressed & KEY_DOWN) selectedMoveDown(); - else if(pressed & BUTTON_L1) + else if(pressed & KEY_L) { if(menuMode == MENU_MODE_NORMAL) viewHeap(); else if(menuMode == MENU_MODE_SEARCH) searchPatternReduce(); } - else if(pressed & BUTTON_R1) + else if(pressed & KEY_R) { if(menuMode == MENU_MODE_NORMAL) viewCode(); @@ -554,7 +554,7 @@ static void ProcessListMenu_MemoryViewer(const ProcessInfo *info) } } - if(pressed & BUTTON_B) // go back to the list, or the simple viewer + if(pressed & KEY_B) // go back to the list, or the simple viewer { if(menuMode != MENU_MODE_NORMAL) { @@ -700,17 +700,17 @@ void RosalinaMenu_ProcessList(void) } while(pressed == 0 && !terminationRequest); - if(pressed & BUTTON_B) + if(pressed & KEY_B) break; - else if(pressed & BUTTON_A) + else if(pressed & KEY_A) ProcessListMenu_HandleSelected(&infos[selected]); - else if(pressed & BUTTON_DOWN) + else if(pressed & KEY_DOWN) selected++; - else if(pressed & BUTTON_UP) + else if(pressed & KEY_UP) selected--; - else if(pressed & BUTTON_LEFT) + else if(pressed & KEY_LEFT) selected -= PROCESSES_PER_MENU_PAGE; - else if(pressed & BUTTON_RIGHT) + else if(pressed & KEY_RIGHT) { if(selected + PROCESSES_PER_MENU_PAGE < processAmount) selected += PROCESSES_PER_MENU_PAGE; diff --git a/sysmodules/rosalina/source/menus/sysconfig.c b/sysmodules/rosalina/source/menus/sysconfig.c index e927398..8eab110 100644 --- a/sysmodules/rosalina/source/menus/sysconfig.c +++ b/sysmodules/rosalina/source/menus/sysconfig.c @@ -66,7 +66,7 @@ void SysConfigMenu_ToggleLEDs(void) u32 pressed = waitInputWithTimeout(1000); - if(pressed & BUTTON_A) + if(pressed & KEY_A) { mcuHwcInit(); u8 result; @@ -75,7 +75,7 @@ void SysConfigMenu_ToggleLEDs(void) MCUHWC_WriteRegister(0x28, &result, 1); mcuHwcExit(); } - else if(pressed & BUTTON_B) + else if(pressed & KEY_B) return; } while(!terminationRequest); @@ -139,13 +139,13 @@ void SysConfigMenu_ToggleWireless(void) u32 pressed = waitInputWithTimeout(1000); - if(pressed & BUTTON_A && nwmRunning) + if(pressed & KEY_A && nwmRunning) { nwmExtInit(); NWMEXT_ControlWirelessEnabled(!wireless); nwmExtExit(); } - else if(pressed & BUTTON_B) + else if(pressed & KEY_B) return; } while(!terminationRequest); @@ -224,7 +224,7 @@ static bool SysConfigMenu_ForceWifiConnection(int slot) u32 pressed = waitInputWithTimeout(1000); - if(pressed & BUTTON_B) + if(pressed & KEY_B) break; } while(!terminationRequest); @@ -259,7 +259,7 @@ void SysConfigMenu_TogglePowerButton(void) u32 pressed = waitInputWithTimeout(1000); - if(pressed & BUTTON_A) + if(pressed & KEY_A) { mcuHwcInit(); MCUHWC_ReadRegister(0x18, (u8*)&mcuIRQMask, 4); @@ -267,7 +267,7 @@ void SysConfigMenu_TogglePowerButton(void) MCUHWC_WriteRegister(0x18, (u8*)&mcuIRQMask, 4); mcuHwcExit(); } - else if(pressed & BUTTON_B) + else if(pressed & KEY_B) return; } while(!terminationRequest); @@ -296,7 +296,7 @@ void SysConfigMenu_ControlWifi(void) u32 pressed = waitInputWithTimeout(1000); - if(pressed & BUTTON_A) + if(pressed & KEY_A) { if(SysConfigMenu_ForceWifiConnection(slot)) { @@ -309,7 +309,7 @@ void SysConfigMenu_ControlWifi(void) Draw_FlushFramebuffer(); Draw_Unlock(); } - else if(pressed & BUTTON_LEFT) + else if(pressed & KEY_LEFT) { slotString[slot * 4] = ' '; slotString[(slot * 4) + 2] = ' '; @@ -319,7 +319,7 @@ void SysConfigMenu_ControlWifi(void) slotString[slot * 4] = '>'; slotString[(slot * 4) + 2] = '<'; } - else if(pressed & BUTTON_RIGHT) + else if(pressed & KEY_RIGHT) { slotString[slot * 4] = ' '; slotString[(slot * 4) + 2] = ' '; @@ -329,7 +329,7 @@ void SysConfigMenu_ControlWifi(void) slotString[slot * 4] = '>'; slotString[(slot * 4) + 2] = '<'; } - else if(pressed & BUTTON_B) + else if(pressed & KEY_B) return; } while(!terminationRequest); @@ -352,7 +352,7 @@ void SysConfigMenu_DisableForcedWifiConnection(void) Draw_DrawString(10, 30, COLOR_WHITE, "Forced connection successfully disabled.\nNote: auto-connection may remain broken."); u32 pressed = waitInputWithTimeout(1000); - if(pressed & BUTTON_B) + if(pressed & KEY_B) return; } while(!terminationRequest);