rosalina: refactor menu handling

This commit is contained in:
TuxSH 2020-05-17 16:42:44 +01:00
parent e99ab11c6f
commit 9097276a06
8 changed files with 66 additions and 29 deletions

View File

@ -41,9 +41,11 @@
#define CORE_SYSTEM 1 #define CORE_SYSTEM 1
typedef enum MenuItemAction { typedef enum MenuItemAction {
METHOD, MENU_END = 0,
MENU METHOD = 1,
MENU = 2,
} MenuItemAction; } MenuItemAction;
typedef struct MenuItem { typedef struct MenuItem {
const char *title; const char *title;
@ -52,12 +54,14 @@ typedef struct MenuItem {
struct Menu *menu; struct Menu *menu;
void (*method)(void); void (*method)(void);
}; };
bool (*visibility)(void);
} MenuItem; } MenuItem;
typedef struct Menu { typedef struct Menu {
const char *title; const char *title;
u32 nbItems; MenuItem items[16];
MenuItem items[0x40];
} Menu; } Menu;
extern bool isN3DS; extern bool isN3DS;
@ -73,6 +77,9 @@ u32 waitInput(void);
u32 waitComboWithTimeout(s32 msec); u32 waitComboWithTimeout(s32 msec);
u32 waitCombo(void); u32 waitCombo(void);
bool menuCheckN3ds(void);
u32 menuCountItems(const Menu *menu);
MyThread *menuCreateThread(void); MyThread *menuCreateThread(void);
void menuEnter(void); void menuEnter(void);
void menuLeave(void); void menuLeave(void);

View File

@ -144,6 +144,28 @@ static MyThread menuThread;
static u8 ALIGN(8) menuThreadStack[0x1000]; static u8 ALIGN(8) menuThreadStack[0x1000];
static u8 batteryLevel = 255; 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) MyThread *menuCreateThread(void)
{ {
if(R_FAILED(MyThread_Create(&menuThread, menuThreadMain, menuThreadStack, 0x1000, 52, CORE_SYSTEM))) if(R_FAILED(MyThread_Create(&menuThread, menuThreadMain, menuThreadStack, 0x1000, 52, CORE_SYSTEM)))
@ -155,13 +177,7 @@ u32 menuCombo;
void menuThreadMain(void) void menuThreadMain(void)
{ {
if(!isN3DS) if(isN3DS)
{
rosalinaMenu.nbItems--;
for(u32 i = 7; i <= rosalinaMenu.nbItems; i++)
rosalinaMenu.items[i] = rosalinaMenu.items[i+1];
}
else
N3DSMenu_UpdateStatus(); N3DSMenu_UpdateStatus();
while (!isServiceUsable("ac:u") || !isServiceUsable("hid:USER")) 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)); 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); 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) if (menuItemIsHidden(&menu->items[i]))
break; continue;
Draw_DrawString(30, 30 + i * SPACING_Y, COLOR_WHITE, menu->items[i].title);
Draw_DrawCharacter(10, 30 + i * SPACING_Y, COLOR_TITLE, i == selected ? '>' : ' '); 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) if(miniSocEnabled)
@ -298,6 +318,10 @@ void menuShow(Menu *root)
Menu *previousMenus[0x80]; Menu *previousMenus[0x80];
u32 previousSelectedItems[0x80]; u32 previousSelectedItems[0x80];
u32 numItems = menuCountItems(currentMenu);
if (menuItemIsHidden(&currentMenu->items[selectedItem]))
selectedItem = menuAdvanceCursor(selectedItem, numItems, 1);
Draw_Lock(); Draw_Lock();
Draw_ClearFramebuffer(); Draw_ClearFramebuffer();
Draw_FlushFramebuffer(); Draw_FlushFramebuffer();
@ -310,6 +334,7 @@ void menuShow(Menu *root)
do do
{ {
u32 pressed = waitInputWithTimeout(1000); u32 pressed = waitInputWithTimeout(1000);
numItems = menuCountItems(currentMenu);
if(!menuComboReleased && (scanHeldKeys() & menuCombo) != menuCombo) if(!menuComboReleased && (scanHeldKeys() & menuCombo) != menuCombo)
{ {
@ -338,6 +363,9 @@ void menuShow(Menu *root)
currentMenu = currentMenu->items[selectedItem].menu; currentMenu = currentMenu->items[selectedItem].menu;
selectedItem = 0; selectedItem = 0;
break; break;
default:
__builtin_trap(); // oops
break;
} }
Draw_Lock(); Draw_Lock();
@ -362,13 +390,15 @@ void menuShow(Menu *root)
} }
else if(pressed & KEY_DOWN) else if(pressed & KEY_DOWN)
{ {
if(++selectedItem >= currentMenu->nbItems) selectedItem = menuAdvanceCursor(selectedItem, numItems, 1);
selectedItem = 0; if (menuItemIsHidden(&currentMenu->items[selectedItem]))
selectedItem = menuAdvanceCursor(selectedItem, numItems, 1);
} }
else if(pressed & KEY_UP) else if(pressed & KEY_UP)
{ {
if(selectedItem-- <= 0) selectedItem = menuAdvanceCursor(selectedItem, numItems, -1);
selectedItem = currentMenu->nbItems - 1; if (menuItemIsHidden(&currentMenu->items[selectedItem]))
selectedItem = menuAdvanceCursor(selectedItem, numItems, -1);
} }
Draw_Lock(); Draw_Lock();

View File

@ -42,7 +42,6 @@
Menu rosalinaMenu = { Menu rosalinaMenu = {
"Rosalina menu", "Rosalina menu",
.nbItems = 12,
{ {
{ "Take screenshot", METHOD, .method = &RosalinaMenu_TakeScreenshot }, { "Take screenshot", METHOD, .method = &RosalinaMenu_TakeScreenshot },
{ "Change screen brightness", METHOD, .method = &RosalinaMenu_ChangeScreenBrightness }, { "Change screen brightness", METHOD, .method = &RosalinaMenu_ChangeScreenBrightness },
@ -51,11 +50,12 @@ Menu rosalinaMenu = {
{ "Debugger options...", MENU, .menu = &debuggerMenu }, { "Debugger options...", MENU, .menu = &debuggerMenu },
{ "System configuration...", MENU, .menu = &sysconfigMenu }, { "System configuration...", MENU, .menu = &sysconfigMenu },
{ "Screen filters...", MENU, .menu = &screenFiltersMenu }, { "Screen filters...", MENU, .menu = &screenFiltersMenu },
{ "New 3DS menu...", MENU, .menu = &N3DSMenu }, { "New 3DS menu...", MENU, .menu = &N3DSMenu, .visibility = &menuCheckN3ds },
{ "Miscellaneous options...", MENU, .menu = &miscellaneousMenu }, { "Miscellaneous options...", MENU, .menu = &miscellaneousMenu },
{ "Power off", METHOD, .method = &RosalinaMenu_PowerOff }, { "Power off", METHOD, .method = &RosalinaMenu_PowerOff },
{ "Reboot", METHOD, .method = &RosalinaMenu_Reboot }, { "Reboot", METHOD, .method = &RosalinaMenu_Reboot },
{ "Credits", METHOD, .method = &RosalinaMenu_ShowCredits } { "Credits", METHOD, .method = &RosalinaMenu_ShowCredits },
{},
} }
}; };

View File

@ -38,11 +38,11 @@
Menu debuggerMenu = { Menu debuggerMenu = {
"Debugger options menu", "Debugger options menu",
.nbItems = 3,
{ {
{ "Enable debugger", METHOD, .method = &DebuggerMenu_EnableDebugger }, { "Enable debugger", METHOD, .method = &DebuggerMenu_EnableDebugger },
{ "Disable debugger", METHOD, .method = &DebuggerMenu_DisableDebugger }, { "Disable debugger", METHOD, .method = &DebuggerMenu_DisableDebugger },
{ "Force-debug next application at launch", METHOD, .method = &DebuggerMenu_DebugNextApplicationByForce }, { "Force-debug next application at launch", METHOD, .method = &DebuggerMenu_DebugNextApplicationByForce },
{},
} }
}; };

View File

@ -39,13 +39,13 @@
Menu miscellaneousMenu = { Menu miscellaneousMenu = {
"Miscellaneous options menu", "Miscellaneous options menu",
.nbItems = 5,
{ {
{ "Switch the hb. title to the current app.", METHOD, .method = &MiscellaneousMenu_SwitchBoot3dsxTargetTitle }, { "Switch the hb. title to the current app.", METHOD, .method = &MiscellaneousMenu_SwitchBoot3dsxTargetTitle },
{ "Change the menu combo", METHOD, .method = &MiscellaneousMenu_ChangeMenuCombo }, { "Change the menu combo", METHOD, .method = &MiscellaneousMenu_ChangeMenuCombo },
{ "Start InputRedirection", METHOD, .method = &MiscellaneousMenu_InputRedirection }, { "Start InputRedirection", METHOD, .method = &MiscellaneousMenu_InputRedirection },
{ "Sync time and date via NTP", METHOD, .method = &MiscellaneousMenu_SyncTimeDate }, { "Sync time and date via NTP", METHOD, .method = &MiscellaneousMenu_SyncTimeDate },
{ "Save settings", METHOD, .method = &MiscellaneousMenu_SaveSettings }, { "Save settings", METHOD, .method = &MiscellaneousMenu_SaveSettings },
{},
} }
}; };

View File

@ -34,10 +34,10 @@ static char clkRateBuf[128 + 1];
Menu N3DSMenu = { Menu N3DSMenu = {
"New 3DS menu", "New 3DS menu",
.nbItems = 2,
{ {
{ "Enable L2 cache", METHOD, .method = &N3DSMenu_EnableDisableL2Cache }, { "Enable L2 cache", METHOD, .method = &N3DSMenu_EnableDisableL2Cache },
{ clkRateBuf, METHOD, .method = &N3DSMenu_ChangeClockRate } { clkRateBuf, METHOD, .method = &N3DSMenu_ChangeClockRate },
{},
} }
}; };

View File

@ -91,7 +91,6 @@ void applyColorSettings(color_setting_t* cs)
Menu screenFiltersMenu = { Menu screenFiltersMenu = {
"Screen filters menu", "Screen filters menu",
.nbItems = 6,
{ {
{ "Disable", METHOD, .method = &screenFiltersSetDisabled }, { "Disable", METHOD, .method = &screenFiltersSetDisabled },
{ "Reduce blue light (level 1)", METHOD, .method = &screenFiltersReduceBlueLevel1 }, { "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 3)", METHOD, .method = &screenFiltersReduceBlueLevel3 },
{ "Reduce blue light (level 4)", METHOD, .method = &screenFiltersReduceBlueLevel4 }, { "Reduce blue light (level 4)", METHOD, .method = &screenFiltersReduceBlueLevel4 },
{ "Reduce blue light (level 5)", METHOD, .method = &screenFiltersReduceBlueLevel5 }, { "Reduce blue light (level 5)", METHOD, .method = &screenFiltersReduceBlueLevel5 },
{},
} }
}; };

View File

@ -34,12 +34,12 @@
Menu sysconfigMenu = { Menu sysconfigMenu = {
"System configuration menu", "System configuration menu",
.nbItems = 4,
{ {
{ "Toggle LEDs", METHOD, .method = &SysConfigMenu_ToggleLEDs }, { "Toggle LEDs", METHOD, .method = &SysConfigMenu_ToggleLEDs },
{ "Toggle Wireless", METHOD, .method = &SysConfigMenu_ToggleWireless }, { "Toggle Wireless", METHOD, .method = &SysConfigMenu_ToggleWireless },
{ "Toggle Power Button", METHOD, .method=&SysConfigMenu_TogglePowerButton }, { "Toggle Power Button", METHOD, .method=&SysConfigMenu_TogglePowerButton },
{ "Control Wireless connection", METHOD, .method = &SysConfigMenu_ControlWifi }, { "Control Wireless connection", METHOD, .method = &SysConfigMenu_ControlWifi },
{},
} }
}; };