diff --git a/sysmodules/rosalina/include/menu.h b/sysmodules/rosalina/include/menu.h index d012027..98080b6 100644 --- a/sysmodules/rosalina/include/menu.h +++ b/sysmodules/rosalina/include/menu.h @@ -41,9 +41,11 @@ #define CORE_SYSTEM 1 typedef enum MenuItemAction { - METHOD, - MENU + MENU_END = 0, + METHOD = 1, + MENU = 2, } MenuItemAction; + typedef struct MenuItem { const char *title; @@ -52,12 +54,14 @@ typedef struct MenuItem { struct Menu *menu; void (*method)(void); }; + + bool (*visibility)(void); } MenuItem; + typedef struct Menu { const char *title; - u32 nbItems; - MenuItem items[0x40]; + MenuItem items[16]; } Menu; extern bool isN3DS; @@ -73,6 +77,9 @@ u32 waitInput(void); u32 waitComboWithTimeout(s32 msec); u32 waitCombo(void); +bool menuCheckN3ds(void); +u32 menuCountItems(const Menu *menu); + MyThread *menuCreateThread(void); void menuEnter(void); void menuLeave(void); diff --git a/sysmodules/rosalina/source/menu.c b/sysmodules/rosalina/source/menu.c index b383f4b..e117908 100644 --- a/sysmodules/rosalina/source/menu.c +++ b/sysmodules/rosalina/source/menu.c @@ -144,6 +144,28 @@ static MyThread menuThread; static u8 ALIGN(8) menuThreadStack[0x1000]; static u8 batteryLevel = 255; +static inline u32 menuAdvanceCursor(u32 pos, u32 numItems, s32 displ) +{ + return (pos + numItems + displ) % numItems; +} + +static inline bool menuItemIsHidden(const MenuItem *item) +{ + return item->visibility != NULL && !item->visibility(); +} + +bool menuCheckN3ds(void) +{ + return isN3DS; +} + +u32 menuCountItems(const Menu *menu) +{ + u32 n; + for (n = 0; menu->items[n].action_type != MENU_END; n++); + return n; +} + MyThread *menuCreateThread(void) { if(R_FAILED(MyThread_Create(&menuThread, menuThreadMain, menuThreadStack, 0x1000, 52, CORE_SYSTEM))) @@ -155,13 +177,7 @@ u32 menuCombo; void menuThreadMain(void) { - if(!isN3DS) - { - rosalinaMenu.nbItems--; - for(u32 i = 7; i <= rosalinaMenu.nbItems; i++) - rosalinaMenu.items[i] = rosalinaMenu.items[i+1]; - } - else + if(isN3DS) N3DSMenu_UpdateStatus(); while (!isServiceUsable("ac:u") || !isServiceUsable("hid:USER")) @@ -257,13 +273,17 @@ static void menuDraw(Menu *menu, u32 selected) sprintf(versionString, "v%lu.%lu.%lu", GET_VERSION_MAJOR(version), GET_VERSION_MINOR(version), GET_VERSION_REVISION(version)); Draw_DrawString(10, 10, COLOR_TITLE, menu->title); + u32 numItems = menuCountItems(menu); + u32 dispY = 0; - for(u32 i = 0; i < 15; i++) + for(u32 i = 0; i < numItems; i++) { - if(i >= menu->nbItems) - break; - Draw_DrawString(30, 30 + i * SPACING_Y, COLOR_WHITE, menu->items[i].title); - Draw_DrawCharacter(10, 30 + i * SPACING_Y, COLOR_TITLE, i == selected ? '>' : ' '); + if (menuItemIsHidden(&menu->items[i])) + continue; + + Draw_DrawString(30, 30 + dispY, COLOR_WHITE, menu->items[i].title); + Draw_DrawCharacter(10, 30 + dispY, COLOR_TITLE, i == selected ? '>' : ' '); + dispY += SPACING_Y; } if(miniSocEnabled) @@ -298,6 +318,10 @@ void menuShow(Menu *root) Menu *previousMenus[0x80]; u32 previousSelectedItems[0x80]; + u32 numItems = menuCountItems(currentMenu); + if (menuItemIsHidden(¤tMenu->items[selectedItem])) + selectedItem = menuAdvanceCursor(selectedItem, numItems, 1); + Draw_Lock(); Draw_ClearFramebuffer(); Draw_FlushFramebuffer(); @@ -310,6 +334,7 @@ void menuShow(Menu *root) do { u32 pressed = waitInputWithTimeout(1000); + numItems = menuCountItems(currentMenu); if(!menuComboReleased && (scanHeldKeys() & menuCombo) != menuCombo) { @@ -338,6 +363,9 @@ void menuShow(Menu *root) currentMenu = currentMenu->items[selectedItem].menu; selectedItem = 0; break; + default: + __builtin_trap(); // oops + break; } Draw_Lock(); @@ -362,13 +390,15 @@ void menuShow(Menu *root) } else if(pressed & KEY_DOWN) { - if(++selectedItem >= currentMenu->nbItems) - selectedItem = 0; + selectedItem = menuAdvanceCursor(selectedItem, numItems, 1); + if (menuItemIsHidden(¤tMenu->items[selectedItem])) + selectedItem = menuAdvanceCursor(selectedItem, numItems, 1); } else if(pressed & KEY_UP) { - if(selectedItem-- <= 0) - selectedItem = currentMenu->nbItems - 1; + selectedItem = menuAdvanceCursor(selectedItem, numItems, -1); + if (menuItemIsHidden(¤tMenu->items[selectedItem])) + selectedItem = menuAdvanceCursor(selectedItem, numItems, -1); } Draw_Lock(); diff --git a/sysmodules/rosalina/source/menus.c b/sysmodules/rosalina/source/menus.c index 8826692..57c4584 100644 --- a/sysmodules/rosalina/source/menus.c +++ b/sysmodules/rosalina/source/menus.c @@ -42,7 +42,6 @@ Menu rosalinaMenu = { "Rosalina menu", - .nbItems = 12, { { "Take screenshot", METHOD, .method = &RosalinaMenu_TakeScreenshot }, { "Change screen brightness", METHOD, .method = &RosalinaMenu_ChangeScreenBrightness }, @@ -51,11 +50,12 @@ Menu rosalinaMenu = { { "Debugger options...", MENU, .menu = &debuggerMenu }, { "System configuration...", MENU, .menu = &sysconfigMenu }, { "Screen filters...", MENU, .menu = &screenFiltersMenu }, - { "New 3DS menu...", MENU, .menu = &N3DSMenu }, + { "New 3DS menu...", MENU, .menu = &N3DSMenu, .visibility = &menuCheckN3ds }, { "Miscellaneous options...", MENU, .menu = &miscellaneousMenu }, { "Power off", METHOD, .method = &RosalinaMenu_PowerOff }, { "Reboot", METHOD, .method = &RosalinaMenu_Reboot }, - { "Credits", METHOD, .method = &RosalinaMenu_ShowCredits } + { "Credits", METHOD, .method = &RosalinaMenu_ShowCredits }, + {}, } }; diff --git a/sysmodules/rosalina/source/menus/debugger.c b/sysmodules/rosalina/source/menus/debugger.c index 82a514e..70bf67a 100644 --- a/sysmodules/rosalina/source/menus/debugger.c +++ b/sysmodules/rosalina/source/menus/debugger.c @@ -38,11 +38,11 @@ Menu debuggerMenu = { "Debugger options menu", - .nbItems = 3, { { "Enable debugger", METHOD, .method = &DebuggerMenu_EnableDebugger }, { "Disable debugger", METHOD, .method = &DebuggerMenu_DisableDebugger }, { "Force-debug next application at launch", METHOD, .method = &DebuggerMenu_DebugNextApplicationByForce }, + {}, } }; diff --git a/sysmodules/rosalina/source/menus/miscellaneous.c b/sysmodules/rosalina/source/menus/miscellaneous.c index 515c09b..20f03a3 100644 --- a/sysmodules/rosalina/source/menus/miscellaneous.c +++ b/sysmodules/rosalina/source/menus/miscellaneous.c @@ -39,13 +39,13 @@ Menu miscellaneousMenu = { "Miscellaneous options menu", - .nbItems = 5, { { "Switch the hb. title to the current app.", METHOD, .method = &MiscellaneousMenu_SwitchBoot3dsxTargetTitle }, { "Change the menu combo", METHOD, .method = &MiscellaneousMenu_ChangeMenuCombo }, { "Start InputRedirection", METHOD, .method = &MiscellaneousMenu_InputRedirection }, { "Sync time and date via NTP", METHOD, .method = &MiscellaneousMenu_SyncTimeDate }, { "Save settings", METHOD, .method = &MiscellaneousMenu_SaveSettings }, + {}, } }; diff --git a/sysmodules/rosalina/source/menus/n3ds.c b/sysmodules/rosalina/source/menus/n3ds.c index db85889..9f90034 100644 --- a/sysmodules/rosalina/source/menus/n3ds.c +++ b/sysmodules/rosalina/source/menus/n3ds.c @@ -34,10 +34,10 @@ static char clkRateBuf[128 + 1]; Menu N3DSMenu = { "New 3DS menu", - .nbItems = 2, { { "Enable L2 cache", METHOD, .method = &N3DSMenu_EnableDisableL2Cache }, - { clkRateBuf, METHOD, .method = &N3DSMenu_ChangeClockRate } + { clkRateBuf, METHOD, .method = &N3DSMenu_ChangeClockRate }, + {}, } }; diff --git a/sysmodules/rosalina/source/menus/screen_filters.c b/sysmodules/rosalina/source/menus/screen_filters.c index 481e343..fc37285 100644 --- a/sysmodules/rosalina/source/menus/screen_filters.c +++ b/sysmodules/rosalina/source/menus/screen_filters.c @@ -91,7 +91,6 @@ void applyColorSettings(color_setting_t* cs) Menu screenFiltersMenu = { "Screen filters menu", - .nbItems = 6, { { "Disable", METHOD, .method = &screenFiltersSetDisabled }, { "Reduce blue light (level 1)", METHOD, .method = &screenFiltersReduceBlueLevel1 }, @@ -99,6 +98,7 @@ Menu screenFiltersMenu = { { "Reduce blue light (level 3)", METHOD, .method = &screenFiltersReduceBlueLevel3 }, { "Reduce blue light (level 4)", METHOD, .method = &screenFiltersReduceBlueLevel4 }, { "Reduce blue light (level 5)", METHOD, .method = &screenFiltersReduceBlueLevel5 }, + {}, } }; diff --git a/sysmodules/rosalina/source/menus/sysconfig.c b/sysmodules/rosalina/source/menus/sysconfig.c index 674577a..4a357dd 100644 --- a/sysmodules/rosalina/source/menus/sysconfig.c +++ b/sysmodules/rosalina/source/menus/sysconfig.c @@ -34,12 +34,12 @@ Menu sysconfigMenu = { "System configuration menu", - .nbItems = 4, { { "Toggle LEDs", METHOD, .method = &SysConfigMenu_ToggleLEDs }, { "Toggle Wireless", METHOD, .method = &SysConfigMenu_ToggleWireless }, { "Toggle Power Button", METHOD, .method=&SysConfigMenu_TogglePowerButton }, { "Control Wireless connection", METHOD, .method = &SysConfigMenu_ControlWifi }, + {}, } };