diff --git a/include/mgba-util/gui/menu.h b/include/mgba-util/gui/menu.h index dca1d60b3..8ac9d6846 100644 --- a/include/mgba-util/gui/menu.h +++ b/include/mgba-util/gui/menu.h @@ -17,13 +17,27 @@ CXX_GUARD_START #define GUI_V_I(I) (struct GUIVariant) { .type = GUI_VARIANT_INT, .v.i = (I) } #define GUI_V_F(F) (struct GUIVariant) { .type = GUI_VARIANT_FLOAT, .v.f = (F) } #define GUI_V_S(S) (struct GUIVariant) { .type = GUI_VARIANT_STRING, .v.s = (S) } +#define GUI_V_P(P) (struct GUIVariant) { .type = GUI_VARIANT_POINTER, .v.p = (P) } + +#define GUIVariantIs(V, T) ((V).type == GUI_VARIANT_##T) +#define GUIVariantIsVoid(V) GUIVariantIs(V, VOID) +#define GUIVariantIsUInt(V) GUIVariantIs(V, UNSIGNED) +#define GUIVariantIsInt(V) GUIVariantIs(V, INT) +#define GUIVariantIsFloat(V) GUIVariantIs(V, FLOAT) +#define GUIVariantIsString(V) GUIVariantIs(V, STRING) +#define GUIVariantIsPointer(V) GUIVariantIs(V, POINTER) + +#define GUIVariantCompareUInt(V, X) (GUIVariantIsUInt(V) && (V).v.u == (X)) +#define GUIVariantCompareInt(V, X) (GUIVariantIsInt(V) && (V).v.i == (X)) +#define GUIVariantCompareString(V, X) (GUIVariantIsString(V) && strcmp((V).v.s, (X)) == 0) enum GUIVariantType { GUI_VARIANT_VOID = 0, GUI_VARIANT_UNSIGNED, GUI_VARIANT_INT, GUI_VARIANT_FLOAT, - GUI_VARIANT_STRING + GUI_VARIANT_STRING, + GUI_VARIANT_POINTER, }; struct GUIVariant { @@ -33,13 +47,14 @@ struct GUIVariant { int i; float f; const char* s; + void* p; } v; }; struct GUIMenu; struct GUIMenuItem { const char* title; - void* data; + struct GUIVariant data; unsigned state; const char* const* validStates; const struct GUIVariant* stateMappings; diff --git a/src/feature/gui/cheats.c b/src/feature/gui/cheats.c index d69d3ddc3..1b06afa0a 100644 --- a/src/feature/gui/cheats.c +++ b/src/feature/gui/cheats.c @@ -35,19 +35,19 @@ static void mGUIShowCheatSet(struct mGUIRunner* runner, struct mCheatDevice* dev }; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Add line", - .data = (void*) CHEAT_ADD_LINE, + .data = GUI_V_U(CHEAT_ADD_LINE), }; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Rename", - .data = (void*) CHEAT_RENAME, + .data = GUI_V_U(CHEAT_RENAME), }; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Delete", - .data = (void*) CHEAT_DELETE, + .data = GUI_V_U(CHEAT_DELETE), }; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Back", - .data = 0, + .data = GUI_V_V, }; while (true) { @@ -56,11 +56,11 @@ static void mGUIShowCheatSet(struct mGUIRunner* runner, struct mCheatDevice* dev struct GUIMenuItem* item; enum GUIMenuExitReason reason = GUIShowMenu(&runner->params, &menu, &item); set->enabled = GUIMenuItemListGetPointer(&menu.items, 0)->state; - if (reason != GUI_MENU_EXIT_ACCEPT || !item->data) { + if (reason != GUI_MENU_EXIT_ACCEPT || GUIVariantIsVoid(item->data)) { break; } - enum mGUICheatAction action = (enum mGUICheatAction) item->data; + enum mGUICheatAction action = (enum mGUICheatAction) item->data.v.u; switch (action) { case CHEAT_ADD_LINE: strlcpy(keyboard.title, "Add line", sizeof(keyboard.title)); @@ -108,7 +108,7 @@ void mGUIShowCheats(struct mGUIRunner* runner) { struct mCheatSet* set = *mCheatSetsGetPointer(&device->cheats, i); *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = set->name, - .data = set, + .data = GUI_V_P(set), .state = set->enabled, .validStates = offOn, .nStates = 2 @@ -116,11 +116,11 @@ void mGUIShowCheats(struct mGUIRunner* runner) { } *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Add new cheat set", - .data = 0, + .data = GUI_V_V, }; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Back", - .data = (void*) -1, + .data = GUI_V_I(-1), }; struct GUIMenuItem* item; @@ -131,11 +131,11 @@ void mGUIShowCheats(struct mGUIRunner* runner) { set->enabled = item->state; } - if (reason != GUI_MENU_EXIT_ACCEPT || item->data == (void*) -1) { + if (reason != GUI_MENU_EXIT_ACCEPT || GUIVariantCompareInt(item->data, -1)) { break; } struct mCheatSet* set = NULL; - if (!item->data) { + if (GUIVariantIsVoid(item->data)) { struct GUIKeyboardParams keyboard; GUIKeyboardParamsInit(&keyboard); keyboard.maxLen = 50; @@ -146,7 +146,7 @@ void mGUIShowCheats(struct mGUIRunner* runner) { mCheatAddSet(device, set); } } else { - set = item->data; + set = item->data.v.p; } if (set) { mGUIShowCheatSet(runner, device, set); diff --git a/src/feature/gui/gui-config.c b/src/feature/gui/gui-config.c index cba83166b..8ab4dd7dc 100644 --- a/src/feature/gui/gui-config.c +++ b/src/feature/gui/gui-config.c @@ -22,6 +22,11 @@ #define GUI_MAX_INPUTS 7 #endif +enum { + CONFIG_REMAP, + CONFIG_SAVE, +}; + static bool _biosNamed(const char* name) { char ext[PATH_MAX + 1] = {}; separatePath(name, NULL, NULL, ext); @@ -45,7 +50,7 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t GUIMenuItemListInit(&menu.items, 0); *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Frameskip", - .data = "frameskip", + .data = GUI_V_S("frameskip"), .submenu = 0, .state = 0, .validStates = (const char*[]) { @@ -55,7 +60,7 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t }; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Show framerate", - .data = "fpsCounter", + .data = GUI_V_S("fpsCounter"), .submenu = 0, .state = false, .validStates = (const char*[]) { @@ -65,7 +70,7 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t }; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Show status OSD", - .data = "showOSD", + .data = GUI_V_S("showOSD"), .submenu = 0, .state = true, .validStates = (const char*[]) { @@ -75,7 +80,7 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t }; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Autosave state", - .data = "autosave", + .data = GUI_V_S("autosave"), .submenu = 0, .state = true, .validStates = (const char*[]) { @@ -85,7 +90,7 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t }; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Autoload state", - .data = "autoload", + .data = GUI_V_S("autoload"), .submenu = 0, .state = true, .validStates = (const char*[]) { @@ -95,7 +100,7 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t }; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Mute", - .data = "mute", + .data = GUI_V_S("mute"), .submenu = 0, .state = false, .validStates = (const char*[]) { @@ -105,7 +110,7 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t }; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Fast forward mute", - .data = "fastForwardMute", + .data = GUI_V_S("fastForwardMute"), .submenu = 0, .state = false, .validStates = (const char*[]) { @@ -115,7 +120,7 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t }; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Use BIOS if found", - .data = "useBios", + .data = GUI_V_S("useBios"), .submenu = 0, .state = true, .validStates = (const char*[]) { @@ -126,26 +131,26 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t #ifdef M_CORE_GBA *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Select GBA BIOS path", - .data = "gba.bios", + .data = GUI_V_S("gba.bios"), }; #endif #ifdef M_CORE_GB *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Select GB BIOS path", - .data = "gb.bios", + .data = GUI_V_S("gb.bios"), }; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Select GBC BIOS path", - .data = "gbc.bios", + .data = GUI_V_S("gbc.bios"), }; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Select SGB BIOS path", - .data = "sgb.bios", + .data = GUI_V_S("sgb.bios"), }; struct GUIMenuItem* palette = GUIMenuItemListAppend(&menu.items); *palette = (struct GUIMenuItem) { .title = "GB palette", - .data = "gb.pal", + .data = GUI_V_S("gb.pal"), }; const struct GBColorPreset* colorPresets; palette->nStates = GBColorPresetList(&colorPresets); @@ -157,7 +162,7 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t #endif *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Interframe blending", - .data = "interframeBlending", + .data = GUI_V_S("interframeBlending"), .submenu = 0, .state = false, .validStates = (const char*[]) { @@ -168,7 +173,7 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t #if defined(M_CORE_GBA) && (defined(GEKKO) || defined(__SWITCH__) || defined(PSP2)) *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Enable GBP features", - .data = "gba.forceGbp", + .data = GUI_V_S("gba.forceGbp"), .submenu = 0, .state = false, .validStates = (const char*[]) { @@ -180,7 +185,7 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t #ifdef M_CORE_GB *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Enable SGB features", - .data = "sgb.model", + .data = GUI_V_S("sgb.model"), .submenu = 0, .state = true, .validStates = (const char*[]) { @@ -194,7 +199,7 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t }; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Enable SGB borders", - .data = "sgb.borders", + .data = GUI_V_S("sgb.borders"), .submenu = 0, .state = true, .validStates = (const char*[]) { @@ -204,7 +209,7 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t }; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Crop SGB borders", - .data = "sgb.borderCrop", + .data = GUI_V_S("sgb.borderCrop"), .submenu = 0, .state = false, .validStates = (const char*[]) { @@ -224,7 +229,7 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t } *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Remap controls", - .data = "*REMAP", + .data = GUI_V_U(CONFIG_REMAP), .state = 0, .validStates = i ? mapNames : 0, .nStates = i @@ -235,11 +240,11 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t } *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Save", - .data = "*SAVE", + .data = GUI_V_U(CONFIG_SAVE), }; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Cancel", - .data = 0, + .data = GUI_V_V, }; enum GUIMenuExitReason reason; char gbaBiosPath[256] = ""; @@ -252,59 +257,63 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t struct GUIMenuItem* item; for (i = 0; i < GUIMenuItemListSize(&menu.items); ++i) { item = GUIMenuItemListGetPointer(&menu.items, i); - if (!item->validStates || !item->data) { + if (!item->validStates || GUIVariantIsVoid(item->data)) { continue; } - if (item->stateMappings) { - size_t j; - for (j = 0; j < item->nStates; ++j) { - const struct GUIVariant* v = &item->stateMappings[j]; - struct GUIVariant test; - switch (v->type) { - case GUI_VARIANT_VOID: - if (!mCoreConfigGetValue(&runner->config, item->data)) { - item->state = j; + if (GUIVariantIsString(item->data)) { + if (item->stateMappings) { + size_t j; + for (j = 0; j < item->nStates; ++j) { + const struct GUIVariant* v = &item->stateMappings[j]; + struct GUIVariant test; + switch (v->type) { + case GUI_VARIANT_VOID: + if (!mCoreConfigGetValue(&runner->config, item->data.v.s)) { + item->state = j; + break; + } + break; + case GUI_VARIANT_UNSIGNED: + if (mCoreConfigGetUIntValue(&runner->config, item->data.v.s, &test.v.u) && test.v.u == v->v.u) { + item->state = j; + break; + } + break; + case GUI_VARIANT_INT: + if (mCoreConfigGetIntValue(&runner->config, item->data.v.s, &test.v.i) && test.v.i == v->v.i) { + item->state = j; + break; + } + break; + case GUI_VARIANT_FLOAT: + if (mCoreConfigGetFloatValue(&runner->config, item->data.v.s, &test.v.f) && fabsf(test.v.f - v->v.f) <= 1e-3f) { + item->state = j; + break; + } + break; + case GUI_VARIANT_STRING: + test.v.s = mCoreConfigGetValue(&runner->config, item->data.v.s); + if (test.v.s && strcmp(test.v.s, v->v.s) == 0) { + item->state = j; + break; + } + break; + case GUI_VARIANT_POINTER: break; } - break; - case GUI_VARIANT_UNSIGNED: - if (mCoreConfigGetUIntValue(&runner->config, item->data, &test.v.u) && test.v.u == v->v.u) { - item->state = j; - break; - } - break; - case GUI_VARIANT_INT: - if (mCoreConfigGetIntValue(&runner->config, item->data, &test.v.i) && test.v.i == v->v.i) { - item->state = j; - break; - } - break; - case GUI_VARIANT_FLOAT: - if (mCoreConfigGetFloatValue(&runner->config, item->data, &test.v.f) && fabsf(test.v.f - v->v.f) <= 1e-3f) { - item->state = j; - break; - } - break; - case GUI_VARIANT_STRING: - test.v.s = mCoreConfigGetValue(&runner->config, item->data); - if (test.v.s && strcmp(test.v.s, v->v.s) == 0) { - item->state = j; - break; - } - break; } + } else { + mCoreConfigGetUIntValue(&runner->config, item->data.v.s, &item->state); } - } else { - mCoreConfigGetUIntValue(&runner->config, item->data, &item->state); } } while (true) { reason = GUIShowMenu(&runner->params, &menu, &item); - if (reason != GUI_MENU_EXIT_ACCEPT || !item->data) { + if (reason != GUI_MENU_EXIT_ACCEPT || GUIVariantIsVoid(item->data)) { break; } - if (!strcmp(item->data, "*SAVE")) { + if (GUIVariantCompareUInt(item->data, CONFIG_SAVE)) { if (gbaBiosPath[0]) { mCoreConfigSetValue(&runner->config, "gba.bios", gbaBiosPath); } @@ -319,30 +328,32 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t } for (i = 0; i < GUIMenuItemListSize(&menu.items); ++i) { item = GUIMenuItemListGetPointer(&menu.items, i); - if (!item->validStates || !item->data || ((const char*) item->data)[0] == '*') { + if (!item->validStates || !GUIVariantIsString(item->data)) { continue; } if (item->stateMappings) { const struct GUIVariant* v = &item->stateMappings[item->state]; switch (v->type) { case GUI_VARIANT_VOID: - mCoreConfigSetValue(&runner->config, item->data, NULL); + mCoreConfigSetValue(&runner->config, item->data.v.s, NULL); break; case GUI_VARIANT_UNSIGNED: - mCoreConfigSetUIntValue(&runner->config, item->data, v->v.u); + mCoreConfigSetUIntValue(&runner->config, item->data.v.s, v->v.u); break; case GUI_VARIANT_INT: - mCoreConfigSetUIntValue(&runner->config, item->data, v->v.i); + mCoreConfigSetUIntValue(&runner->config, item->data.v.s, v->v.i); break; case GUI_VARIANT_FLOAT: - mCoreConfigSetFloatValue(&runner->config, item->data, v->v.f); + mCoreConfigSetFloatValue(&runner->config, item->data.v.s, v->v.f); break; case GUI_VARIANT_STRING: - mCoreConfigSetValue(&runner->config, item->data, v->v.s); + mCoreConfigSetValue(&runner->config, item->data.v.s, v->v.s); + break; + case GUI_VARIANT_POINTER: break; } #ifdef M_CORE_GB - } else if (!strcmp(item->data, "gb.pal")) { + } else if (GUIVariantCompareString(item->data, "gb.pal")) { const struct GBColorPreset* preset = &colorPresets[item->state]; mCoreConfigSetUIntValue(&runner->config, "gb.pal[0]", preset->colors[0] & 0xFFFFFF); mCoreConfigSetUIntValue(&runner->config, "gb.pal[1]", preset->colors[1] & 0xFFFFFF); @@ -356,10 +367,10 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t mCoreConfigSetUIntValue(&runner->config, "gb.pal[9]", preset->colors[9] & 0xFFFFFF); mCoreConfigSetUIntValue(&runner->config, "gb.pal[10]", preset->colors[10] & 0xFFFFFF); mCoreConfigSetUIntValue(&runner->config, "gb.pal[11]", preset->colors[11] & 0xFFFFFF); - mCoreConfigSetUIntValue(&runner->config, item->data, item->state); + mCoreConfigSetUIntValue(&runner->config, "gb.pal", item->state); #endif } else { - mCoreConfigSetUIntValue(&runner->config, item->data, item->state); + mCoreConfigSetUIntValue(&runner->config, item->data.v.s, item->state); } } if (runner->keySources) { @@ -373,11 +384,11 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t mCoreLoadForeignConfig(runner->core, &runner->config); break; } - if (!strcmp(item->data, "*REMAP")) { + if (GUIVariantCompareUInt(item->data, CONFIG_REMAP)) { mGUIRemapKeys(&runner->params, &runner->core->inputMap, &runner->keySources[item->state]); continue; } - if (!strcmp(item->data, "gba.bios")) { + if (GUIVariantCompareString(item->data, "gba.bios")) { // TODO: show box if failed if (!GUISelectFile(&runner->params, gbaBiosPath, sizeof(gbaBiosPath), _biosNamed, GBAIsBIOS, NULL)) { gbaBiosPath[0] = '\0'; @@ -385,21 +396,21 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t continue; } #ifdef M_CORE_GB - if (!strcmp(item->data, "gb.bios")) { + if (GUIVariantCompareString(item->data, "gb.bios")) { // TODO: show box if failed if (!GUISelectFile(&runner->params, gbBiosPath, sizeof(gbBiosPath), _biosNamed, GBIsBIOS, NULL)) { gbBiosPath[0] = '\0'; } continue; } - if (!strcmp(item->data, "gbc.bios")) { + if (GUIVariantCompareString(item->data, "gbc.bios")) { // TODO: show box if failed if (!GUISelectFile(&runner->params, gbcBiosPath, sizeof(gbcBiosPath), _biosNamed, GBIsBIOS, NULL)) { gbcBiosPath[0] = '\0'; } continue; } - if (!strcmp(item->data, "sgb.bios")) { + if (GUIVariantCompareString(item->data, "sgb.bios")) { // TODO: show box if failed if (!GUISelectFile(&runner->params, sgbBiosPath, sizeof(sgbBiosPath), _biosNamed, GBIsBIOS, NULL)) { sgbBiosPath[0] = '\0'; diff --git a/src/feature/gui/gui-runner.c b/src/feature/gui/gui-runner.c index 6d6903778..b7bb72a1b 100644 --- a/src/feature/gui/gui-runner.c +++ b/src/feature/gui/gui-runner.c @@ -351,38 +351,38 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) { GUIMenuItemListInit(&pauseMenu.items, 0); GUIMenuItemListInit(&stateSaveMenu.items, 9); GUIMenuItemListInit(&stateLoadMenu.items, 10); - *GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Unpause", .data = (void*) RUNNER_CONTINUE }; + *GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Unpause", .data = GUI_V_U(RUNNER_CONTINUE) }; *GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Save state", .submenu = &stateSaveMenu }; *GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Load state", .submenu = &stateLoadMenu }; - *GUIMenuItemListAppend(&stateSaveMenu.items) = (struct GUIMenuItem) { .title = "State 1", .data = (void*) (RUNNER_SAVE_STATE | RUNNER_STATE(1)) }; - *GUIMenuItemListAppend(&stateSaveMenu.items) = (struct GUIMenuItem) { .title = "State 2", .data = (void*) (RUNNER_SAVE_STATE | RUNNER_STATE(2)) }; - *GUIMenuItemListAppend(&stateSaveMenu.items) = (struct GUIMenuItem) { .title = "State 3", .data = (void*) (RUNNER_SAVE_STATE | RUNNER_STATE(3)) }; - *GUIMenuItemListAppend(&stateSaveMenu.items) = (struct GUIMenuItem) { .title = "State 4", .data = (void*) (RUNNER_SAVE_STATE | RUNNER_STATE(4)) }; - *GUIMenuItemListAppend(&stateSaveMenu.items) = (struct GUIMenuItem) { .title = "State 5", .data = (void*) (RUNNER_SAVE_STATE | RUNNER_STATE(5)) }; - *GUIMenuItemListAppend(&stateSaveMenu.items) = (struct GUIMenuItem) { .title = "State 6", .data = (void*) (RUNNER_SAVE_STATE | RUNNER_STATE(6)) }; - *GUIMenuItemListAppend(&stateSaveMenu.items) = (struct GUIMenuItem) { .title = "State 7", .data = (void*) (RUNNER_SAVE_STATE | RUNNER_STATE(7)) }; - *GUIMenuItemListAppend(&stateSaveMenu.items) = (struct GUIMenuItem) { .title = "State 8", .data = (void*) (RUNNER_SAVE_STATE | RUNNER_STATE(8)) }; - *GUIMenuItemListAppend(&stateSaveMenu.items) = (struct GUIMenuItem) { .title = "State 9", .data = (void*) (RUNNER_SAVE_STATE | RUNNER_STATE(9)) }; + *GUIMenuItemListAppend(&stateSaveMenu.items) = (struct GUIMenuItem) { .title = "State 1", .data = GUI_V_U(RUNNER_SAVE_STATE | RUNNER_STATE(1)) }; + *GUIMenuItemListAppend(&stateSaveMenu.items) = (struct GUIMenuItem) { .title = "State 2", .data = GUI_V_U(RUNNER_SAVE_STATE | RUNNER_STATE(2)) }; + *GUIMenuItemListAppend(&stateSaveMenu.items) = (struct GUIMenuItem) { .title = "State 3", .data = GUI_V_U(RUNNER_SAVE_STATE | RUNNER_STATE(3)) }; + *GUIMenuItemListAppend(&stateSaveMenu.items) = (struct GUIMenuItem) { .title = "State 4", .data = GUI_V_U(RUNNER_SAVE_STATE | RUNNER_STATE(4)) }; + *GUIMenuItemListAppend(&stateSaveMenu.items) = (struct GUIMenuItem) { .title = "State 5", .data = GUI_V_U(RUNNER_SAVE_STATE | RUNNER_STATE(5)) }; + *GUIMenuItemListAppend(&stateSaveMenu.items) = (struct GUIMenuItem) { .title = "State 6", .data = GUI_V_U(RUNNER_SAVE_STATE | RUNNER_STATE(6)) }; + *GUIMenuItemListAppend(&stateSaveMenu.items) = (struct GUIMenuItem) { .title = "State 7", .data = GUI_V_U(RUNNER_SAVE_STATE | RUNNER_STATE(7)) }; + *GUIMenuItemListAppend(&stateSaveMenu.items) = (struct GUIMenuItem) { .title = "State 8", .data = GUI_V_U(RUNNER_SAVE_STATE | RUNNER_STATE(8)) }; + *GUIMenuItemListAppend(&stateSaveMenu.items) = (struct GUIMenuItem) { .title = "State 9", .data = GUI_V_U(RUNNER_SAVE_STATE | RUNNER_STATE(9)) }; - *GUIMenuItemListAppend(&stateLoadMenu.items) = (struct GUIMenuItem) { .title = "Autosave", .data = (void*) (RUNNER_LOAD_STATE | RUNNER_STATE(0)) }; - *GUIMenuItemListAppend(&stateLoadMenu.items) = (struct GUIMenuItem) { .title = "State 1", .data = (void*) (RUNNER_LOAD_STATE | RUNNER_STATE(1)) }; - *GUIMenuItemListAppend(&stateLoadMenu.items) = (struct GUIMenuItem) { .title = "State 2", .data = (void*) (RUNNER_LOAD_STATE | RUNNER_STATE(2)) }; - *GUIMenuItemListAppend(&stateLoadMenu.items) = (struct GUIMenuItem) { .title = "State 3", .data = (void*) (RUNNER_LOAD_STATE | RUNNER_STATE(3)) }; - *GUIMenuItemListAppend(&stateLoadMenu.items) = (struct GUIMenuItem) { .title = "State 4", .data = (void*) (RUNNER_LOAD_STATE | RUNNER_STATE(4)) }; - *GUIMenuItemListAppend(&stateLoadMenu.items) = (struct GUIMenuItem) { .title = "State 5", .data = (void*) (RUNNER_LOAD_STATE | RUNNER_STATE(5)) }; - *GUIMenuItemListAppend(&stateLoadMenu.items) = (struct GUIMenuItem) { .title = "State 6", .data = (void*) (RUNNER_LOAD_STATE | RUNNER_STATE(6)) }; - *GUIMenuItemListAppend(&stateLoadMenu.items) = (struct GUIMenuItem) { .title = "State 7", .data = (void*) (RUNNER_LOAD_STATE | RUNNER_STATE(7)) }; - *GUIMenuItemListAppend(&stateLoadMenu.items) = (struct GUIMenuItem) { .title = "State 8", .data = (void*) (RUNNER_LOAD_STATE | RUNNER_STATE(8)) }; - *GUIMenuItemListAppend(&stateLoadMenu.items) = (struct GUIMenuItem) { .title = "State 9", .data = (void*) (RUNNER_LOAD_STATE | RUNNER_STATE(9)) }; + *GUIMenuItemListAppend(&stateLoadMenu.items) = (struct GUIMenuItem) { .title = "Autosave", .data = GUI_V_U(RUNNER_LOAD_STATE | RUNNER_STATE(0)) }; + *GUIMenuItemListAppend(&stateLoadMenu.items) = (struct GUIMenuItem) { .title = "State 1", .data = GUI_V_U(RUNNER_LOAD_STATE | RUNNER_STATE(1)) }; + *GUIMenuItemListAppend(&stateLoadMenu.items) = (struct GUIMenuItem) { .title = "State 2", .data = GUI_V_U(RUNNER_LOAD_STATE | RUNNER_STATE(2)) }; + *GUIMenuItemListAppend(&stateLoadMenu.items) = (struct GUIMenuItem) { .title = "State 3", .data = GUI_V_U(RUNNER_LOAD_STATE | RUNNER_STATE(3)) }; + *GUIMenuItemListAppend(&stateLoadMenu.items) = (struct GUIMenuItem) { .title = "State 4", .data = GUI_V_U(RUNNER_LOAD_STATE | RUNNER_STATE(4)) }; + *GUIMenuItemListAppend(&stateLoadMenu.items) = (struct GUIMenuItem) { .title = "State 5", .data = GUI_V_U(RUNNER_LOAD_STATE | RUNNER_STATE(5)) }; + *GUIMenuItemListAppend(&stateLoadMenu.items) = (struct GUIMenuItem) { .title = "State 6", .data = GUI_V_U(RUNNER_LOAD_STATE | RUNNER_STATE(6)) }; + *GUIMenuItemListAppend(&stateLoadMenu.items) = (struct GUIMenuItem) { .title = "State 7", .data = GUI_V_U(RUNNER_LOAD_STATE | RUNNER_STATE(7)) }; + *GUIMenuItemListAppend(&stateLoadMenu.items) = (struct GUIMenuItem) { .title = "State 8", .data = GUI_V_U(RUNNER_LOAD_STATE | RUNNER_STATE(8)) }; + *GUIMenuItemListAppend(&stateLoadMenu.items) = (struct GUIMenuItem) { .title = "State 9", .data = GUI_V_U(RUNNER_LOAD_STATE | RUNNER_STATE(9)) }; - *GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Take screenshot", .data = (void*) RUNNER_SCREENSHOT }; + *GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Take screenshot", .data = GUI_V_U(RUNNER_SCREENSHOT) }; if (runner->params.getText) { - *GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Cheats", .data = (void*) RUNNER_CHEATS }; + *GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Cheats", .data = GUI_V_U(RUNNER_CHEATS) }; } - *GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Configure", .data = (void*) RUNNER_CONFIG }; - *GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Reset game", .data = (void*) RUNNER_RESET }; - *GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Exit game", .data = (void*) RUNNER_EXIT }; + *GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Configure", .data = GUI_V_U(RUNNER_CONFIG) }; + *GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Reset game", .data = GUI_V_U(RUNNER_RESET) }; + *GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Exit game", .data = GUI_V_U(RUNNER_EXIT) }; runner->params.drawStart(); if (runner->params.guiPrepare) { @@ -633,8 +633,8 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) { uint32_t keys = 0xFFFFFFFF; // Huge hack to avoid an extra variable! struct GUIMenuItem* item; enum GUIMenuExitReason reason = GUIShowMenu(&runner->params, &pauseMenu, &item); - if (reason == GUI_MENU_EXIT_ACCEPT) { - switch (((int) item->data) & RUNNER_COMMAND_MASK) { + if (reason == GUI_MENU_EXIT_ACCEPT && item->data.type == GUI_VARIANT_UNSIGNED) { + switch (item->data.v.u & RUNNER_COMMAND_MASK) { case RUNNER_EXIT: running = false; keys = 0; @@ -643,10 +643,10 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) { runner->core->reset(runner->core); break; case RUNNER_SAVE_STATE: - mCoreSaveState(runner->core, ((uint32_t) item->data) >> 16, SAVESTATE_SCREENSHOT | SAVESTATE_SAVEDATA | SAVESTATE_RTC | SAVESTATE_METADATA); + mCoreSaveState(runner->core, item->data.v.u >> 16, SAVESTATE_SCREENSHOT | SAVESTATE_SAVEDATA | SAVESTATE_RTC | SAVESTATE_METADATA); break; case RUNNER_LOAD_STATE: - mCoreLoadState(runner->core, ((uint32_t) item->data) >> 16, SAVESTATE_SCREENSHOT | SAVESTATE_RTC); + mCoreLoadState(runner->core, item->data.v.u >> 16, SAVESTATE_SCREENSHOT | SAVESTATE_RTC); break; case RUNNER_SCREENSHOT: mCoreTakeScreenshot(runner->core); diff --git a/src/feature/gui/remap.c b/src/feature/gui/remap.c index d09c0ca51..5f7da0f01 100644 --- a/src/feature/gui/remap.c +++ b/src/feature/gui/remap.c @@ -21,12 +21,12 @@ void mGUIRemapKeys(struct GUIParams* params, struct mInputMap* map, const struct size_t i; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Game keys:", - .data = 0, + .data = GUI_V_V, }; for (i = 0; i < map->info->nKeys; ++i) { *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = map->info->keyId[i], - .data = (void*) (GUI_INPUT_MAX + i + 1), + .data = GUI_V_U(GUI_INPUT_MAX + i + 1), .submenu = 0, .state = mInputQueryBinding(map, keys->id, i) + 1, .validStates = keyNames, @@ -35,7 +35,7 @@ void mGUIRemapKeys(struct GUIParams* params, struct mInputMap* map, const struct } *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Interface keys:", - .data = 0, + .data = GUI_V_V, }; for (i = 0; i < params->keyMap.info->nKeys; ++i) { if (!params->keyMap.info->keyId[i]) { @@ -43,7 +43,7 @@ void mGUIRemapKeys(struct GUIParams* params, struct mInputMap* map, const struct } *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = params->keyMap.info->keyId[i], - .data = (void*) i + 1, + .data = GUI_V_U(i + 1), .submenu = 0, .state = mInputQueryBinding(¶ms->keyMap, keys->id, i) + 1, .validStates = keyNames, @@ -52,30 +52,30 @@ void mGUIRemapKeys(struct GUIParams* params, struct mInputMap* map, const struct } *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Save", - .data = (void*) (GUI_INPUT_MAX + map->info->nKeys + 2), + .data = GUI_V_I(-2), }; *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { .title = "Cancel", - .data = 0, + .data = GUI_V_I(-1), }; struct GUIMenuItem* item; while (true) { enum GUIMenuExitReason reason; reason = GUIShowMenu(params, &menu, &item); - if (reason != GUI_MENU_EXIT_ACCEPT || !item->data) { + if (reason != GUI_MENU_EXIT_ACCEPT || GUIVariantCompareInt(item->data, -1)) { break; } - if (item->data == (void*) (GUI_INPUT_MAX + map->info->nKeys + 2)) { + if (GUIVariantCompareInt(item->data, -2)) { for (i = 0; i < GUIMenuItemListSize(&menu.items); ++i) { item = GUIMenuItemListGetPointer(&menu.items, i); - if ((uintptr_t) item->data < 1) { + if (!GUIVariantIsUInt(item->data)) { continue; } - if ((uintptr_t) item->data < GUI_INPUT_MAX + 1) { - mInputBindKey(¶ms->keyMap, keys->id, item->state - 1, (uintptr_t) item->data - 1); - } else if ((uintptr_t) item->data < GUI_INPUT_MAX + map->info->nKeys + 1) { - mInputBindKey(map, keys->id, item->state - 1, (uintptr_t) item->data - GUI_INPUT_MAX - 1); + if (item->data.v.u < GUI_INPUT_MAX + 1) { + mInputBindKey(¶ms->keyMap, keys->id, item->state - 1, item->data.v.u - 1); + } else if (item->data.v.u < GUI_INPUT_MAX + map->info->nKeys + 1) { + mInputBindKey(map, keys->id, item->state - 1, item->data.v.u - GUI_INPUT_MAX - 1); } } break; diff --git a/src/platform/3ds/main.c b/src/platform/3ds/main.c index 5e826937d..fb4152867 100644 --- a/src/platform/3ds/main.c +++ b/src/platform/3ds/main.c @@ -953,7 +953,7 @@ int main() { .configExtra = (struct GUIMenuItem[]) { { .title = "Screen mode", - .data = "screenMode", + .data = GUI_V_S("screenMode"), .submenu = 0, .state = SM_PA_TOP, .validStates = (const char*[]) { @@ -968,7 +968,7 @@ int main() { }, { .title = "Filtering", - .data = "filterMode", + .data = GUI_V_S("filterMode"), .submenu = 0, .state = FM_LINEAR_2x, .validStates = (const char*[]) { @@ -980,7 +980,7 @@ int main() { }, { .title = "Screen darkening", - .data = "darkenMode", + .data = GUI_V_S("darkenMode"), .submenu = 0, .state = DM_NATIVE, .validStates = (const char*[]) { @@ -993,7 +993,7 @@ int main() { }, { .title = "Camera", - .data = "camera", + .data = GUI_V_S("camera"), .submenu = 0, .state = 1, .validStates = (const char*[]) { diff --git a/src/platform/psp2/main.c b/src/platform/psp2/main.c index 1296baa0e..2be4dafee 100644 --- a/src/platform/psp2/main.c +++ b/src/platform/psp2/main.c @@ -160,7 +160,7 @@ int main() { .configExtra = (struct GUIMenuItem[]) { { .title = "Screen mode", - .data = "screenMode", + .data = GUI_V_S("screenMode"), .submenu = 0, .state = 0, .validStates = (const char*[]) { @@ -173,7 +173,7 @@ int main() { }, { .title = "Camera", - .data = "camera", + .data = GUI_V_S("camera"), .submenu = 0, .state = 1, .validStates = (const char*[]) { diff --git a/src/platform/switch/main.c b/src/platform/switch/main.c index 7ba497d85..d127a93fb 100644 --- a/src/platform/switch/main.c +++ b/src/platform/switch/main.c @@ -924,7 +924,7 @@ int main(int argc, char* argv[]) { .configExtra = (struct GUIMenuItem[]) { { .title = "Screen mode", - .data = "screenMode", + .data = GUI_V_S("screenMode"), .submenu = 0, .state = SM_PA, .validStates = (const char*[]) { @@ -936,7 +936,7 @@ int main(int argc, char* argv[]) { }, { .title = "Fast forward cap", - .data = "fastForwardCap", + .data = GUI_V_S("fastForwardCap"), .submenu = 0, .state = 7, .validStates = (const char*[]) { @@ -966,7 +966,7 @@ int main(int argc, char* argv[]) { }, { .title = "GPU-accelerated renderer", - .data = "hwaccelVideo", + .data = GUI_V_S("hwaccelVideo"), .submenu = 0, .state = 0, .validStates = (const char*[]) { @@ -977,7 +977,7 @@ int main(int argc, char* argv[]) { }, { .title = "Hi-res scaling (requires GPU rendering)", - .data = "videoScale", + .data = GUI_V_S("videoScale"), .submenu = 0, .state = 0, .validStates = (const char*[]) { @@ -1000,7 +1000,7 @@ int main(int argc, char* argv[]) { }, { .title = "Use built-in brightness sensor for Boktai", - .data = "useLightSensor", + .data = GUI_V_S("useLightSensor"), .submenu = 0, .state = illuminanceAvailable, .validStates = (const char*[]) { diff --git a/src/platform/wii/main.c b/src/platform/wii/main.c index 535ed8091..8149ce285 100644 --- a/src/platform/wii/main.c +++ b/src/platform/wii/main.c @@ -490,7 +490,7 @@ int main(int argc, char* argv[]) { .configExtra = (struct GUIMenuItem[]) { { .title = "Video mode", - .data = "videoMode", + .data = GUI_V_S("videoMode"), .submenu = 0, .state = 0, .validStates = (const char*[]) { @@ -503,7 +503,7 @@ int main(int argc, char* argv[]) { }, { .title = "Screen mode", - .data = "screenMode", + .data = GUI_V_S("screenMode"), .submenu = 0, .state = 0, .validStates = (const char*[]) { @@ -514,7 +514,7 @@ int main(int argc, char* argv[]) { }, { .title = "Filtering", - .data = "filter", + .data = GUI_V_S("filter"), .submenu = 0, .state = 0, .validStates = (const char*[]) { @@ -526,7 +526,7 @@ int main(int argc, char* argv[]) { }, { .title = "Horizontal stretch", - .data = "stretchWidth", + .data = GUI_V_S("stretchWidth"), .submenu = 0, .state = 7, .validStates = (const char*[]) { @@ -546,7 +546,7 @@ int main(int argc, char* argv[]) { }, { .title = "Vertical stretch", - .data = "stretchHeight", + .data = GUI_V_S("stretchHeight"), .submenu = 0, .state = 6, .validStates = (const char*[]) { diff --git a/src/util/gui/file-select.c b/src/util/gui/file-select.c index b8802d8cc..8c6b86ca8 100644 --- a/src/util/gui/file-select.c +++ b/src/util/gui/file-select.c @@ -94,7 +94,7 @@ static bool _refreshDirectory(struct GUIParams* params, const char* currentPath, } else { name = strdup(name); } - *GUIMenuItemListAppend(currentFiles) = (struct GUIMenuItem) { .title = name, .data = (void*) de->type(de) }; + *GUIMenuItemListAppend(currentFiles) = (struct GUIMenuItem) { .title = name, .data = GUI_V_U(de->type(de)) }; ++items; } qsort(GUIMenuItemListGetPointer(currentFiles, 1), GUIMenuItemListSize(currentFiles) - 1, sizeof(struct GUIMenuItem), _strpcmp); @@ -124,7 +124,7 @@ static bool _refreshDirectory(struct GUIParams* params, const char* currentPath, params->drawEnd(); } struct GUIMenuItem* testItem = GUIMenuItemListGetPointer(currentFiles, item); - if (testItem->data != (void*) VFS_FILE) { + if (!GUIVariantCompareUInt(testItem->data, VFS_FILE)) { ++item; continue; } diff --git a/src/util/gui/menu.c b/src/util/gui/menu.c index ddcc1bf22..0a51102d0 100644 --- a/src/util/gui/menu.c +++ b/src/util/gui/menu.c @@ -137,7 +137,7 @@ enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* men if (reason != GUI_MENU_EXIT_BACK) { return reason; } - } else if ((*item)->validStates && !(*item)->data) { + } else if ((*item)->validStates && !(*item)->data.v.p) { _itemNext(*item, true); } else { return GUI_MENU_EXIT_ACCEPT; @@ -152,7 +152,7 @@ enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* men params->drawStart(); if (menu->background) { - menu->background->draw(menu->background, GUIMenuItemListGetPointer(&menu->items, menu->index)->data); + menu->background->draw(menu->background, GUIMenuItemListGetPointer(&menu->items, menu->index)->data.v.p); } if (params->guiPrepare) { params->guiPrepare();