mGUI: Add variants

This commit is contained in:
Vicki Pfau 2018-09-29 11:09:16 -07:00
parent 927f8b0d88
commit 32c5fd6d90
4 changed files with 110 additions and 2 deletions

View File

@ -108,8 +108,10 @@ Bugfixes:
- 3DS: Fix unused screens not clearing (fixes mgba.io/i/1184)
- GBA Video: Fix caching with background toggling (fixes mgba.io/i/1118)
- Wii: Fix drawing caching regression (fixes mgba.io/i/1185)
- Switch: Fix incorrect mapping for fast forward cap
Misc:
- mGUI: Add SGB border configuration option
- mGUI: Add support for different settings types
0.7 beta 1: (2018-09-24)
- Initial beta for 0.7

View File

@ -12,12 +12,37 @@ CXX_GUARD_START
#include <mgba-util/vector.h>
#define GUI_V_V (struct GUIVariant) { .type = GUI_VARIANT_VOID }
#define GUI_V_U(U) (struct GUIVariant) { .type = GUI_VARIANT_UNSIGNED, .v.u = (U) }
#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) }
enum GUIVariantType {
GUI_VARIANT_VOID = 0,
GUI_VARIANT_UNSIGNED,
GUI_VARIANT_INT,
GUI_VARIANT_FLOAT,
GUI_VARIANT_STRING
};
struct GUIVariant {
enum GUIVariantType type;
union {
unsigned u;
int i;
float f;
const char* s;
} v;
};
struct GUIMenu;
struct GUIMenuItem {
const char* title;
void* data;
unsigned state;
const char* const* validStates;
const struct GUIVariant* stateMappings;
unsigned nStates;
struct GUIMenu* submenu;
};

View File

@ -162,8 +162,51 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t
if (!item->validStates || !item->data) {
continue;
}
if (item->stateMappings) {
item->state = 0;
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;
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, &item->state);
}
}
while (true) {
reason = GUIShowMenu(&runner->params, &menu, &item);
@ -188,8 +231,29 @@ void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t
if (!item->validStates || !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);
break;
case GUI_VARIANT_UNSIGNED:
mCoreConfigSetUIntValue(&runner->config, item->data, v->v.u);
break;
case GUI_VARIANT_INT:
mCoreConfigSetUIntValue(&runner->config, item->data, v->v.i);
break;
case GUI_VARIANT_FLOAT:
mCoreConfigSetFloatValue(&runner->config, item->data, v->v.f);
break;
case GUI_VARIANT_STRING:
mCoreConfigSetValue(&runner->config, item->data, v->v.s);
break;
}
} else {
mCoreConfigSetUIntValue(&runner->config, item->data, item->state);
}
}
if (runner->keySources) {
size_t i;
for (i = 0; runner->keySources[i].id; ++i) {

View File

@ -528,6 +528,23 @@ int main(int argc, char* argv[]) {
"10", "11", "12", "13", "14", "15",
"20", "30"
},
.stateMappings = (const struct GUIVariant[]) {
GUI_V_U(3),
GUI_V_U(4),
GUI_V_U(5),
GUI_V_U(6),
GUI_V_U(7),
GUI_V_U(8),
GUI_V_U(9),
GUI_V_U(10),
GUI_V_U(11),
GUI_V_U(12),
GUI_V_U(13),
GUI_V_U(14),
GUI_V_U(15),
GUI_V_U(20),
GUI_V_U(30),
},
.nStates = 15
},
},