mGUI: Use variants for menu data

This commit is contained in:
Vicki Pfau 2021-06-28 21:13:05 -07:00
parent e3ad33366b
commit 9a26c1a679
11 changed files with 177 additions and 151 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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';

View File

@ -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);

View File

@ -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(&params->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(&params->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(&params->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;

View File

@ -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*[]) {

View File

@ -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*[]) {

View File

@ -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*[]) {

View File

@ -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*[]) {

View File

@ -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;
}

View File

@ -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();