all repos — mgba @ c45315b96b3322e4b29f933b27d461f2a73e7bc7

mGBA Game Boy Advance Emulator

GBA Context: Configuration options
Jeffrey Pfau jeffrey@endrift.com
Thu, 17 Sep 2015 19:53:27 -0700
commit

c45315b96b3322e4b29f933b27d461f2a73e7bc7

parent

94ffa0d2d7fbf71d1cb7f14373482a810e5785c2

M src/gba/context/context.csrc/gba/context/context.c

@@ -56,8 +56,8 @@ .useBios = true,

.idleOptimization = IDLE_LOOP_DETECT, .logLevel = GBA_LOG_WARN | GBA_LOG_ERROR | GBA_LOG_FATAL | GBA_LOG_STATUS }; - GBAConfigLoadDefaults(&context->config, &opts); GBAConfigLoad(&context->config); + GBAConfigLoadDefaults(&context->config, &opts); } context->gba->sync = 0;
A src/gba/gui/gui-config.c

@@ -0,0 +1,89 @@

+/* Copyright (c) 2013-2015 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "gui-config.h" + +#include "gba/gui/gui-runner.h" +#include "util/gui/file-select.h" +#include "util/gui/menu.h" + +void GBAGUIShowConfig(struct GBAGUIRunner* runner, struct GUIMenuItem* extra, size_t nExtra) { + struct GUIMenu menu = { + .title = "Configure", + .index = 0, + .background = &runner->background.d + }; + GUIMenuItemListInit(&menu.items, 0); + *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { + .title = "Use BIOS if found", + .data = "useBios", + .submenu = 0, + .state = true, + .validStates = (const char*[]) { + "Off", "On", 0 + } + }; + *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { + .title = "Select BIOS path", + .data = "bios", + }; + size_t i; + for (i = 0; i < nExtra; ++i) { + *GUIMenuItemListAppend(&menu.items) = extra[i]; + } + *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { + .title = "Save", + .data = "[SAVE]", + }; + *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) { + .title = "Cancel", + .data = 0, + }; + enum GUIMenuExitReason reason; + char biosPath[256] = ""; + + struct GUIMenuItem* item; + for (i = 0; i < GUIMenuItemListSize(&menu.items); ++i) { + item = GUIMenuItemListGetPointer(&menu.items, i); + if (!item->validStates || !item->data) { + continue; + } + GBAConfigGetUIntValue(&runner->context.config, item->data, &item->state); + } + + while (true) { + reason = GUIShowMenu(&runner->params, &menu, &item); + if (reason != GUI_MENU_EXIT_ACCEPT || !item->data) { + break; + } + if (!strcmp(item->data, "[SAVE]")) { + if (biosPath[0]) { + GBAConfigSetValue(&runner->context.config, "bios", biosPath); + } + for (i = 0; i < GUIMenuItemListSize(&menu.items); ++i) { + item = GUIMenuItemListGetPointer(&menu.items, i); + if (!item->validStates || !item->data) { + continue; + } + GBAConfigSetUIntValue(&runner->context.config, item->data, item->state); + } + GBAConfigSave(&runner->context.config); + break; + } + if (!strcmp(item->data, "bios")) { + // TODO: show box if failed + if (!GUISelectFile(&runner->params, biosPath, sizeof(biosPath), GBAIsBIOS)) { + biosPath[0] = '\0'; + } + continue; + } + if (item->validStates) { + ++item->state; + if (!item->validStates[item->state]) { + item->state = 0; + } + } + } +}
A src/gba/gui/gui-config.h

@@ -0,0 +1,15 @@

+/* Copyright (c) 2013-2015 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef GUI_CONFIG_H +#define GUI_CONFIG_H + +#include "util/common.h" + +struct GBAGUIRunner; +struct GUIMenuItem; +void GBAGUIShowConfig(struct GBAGUIRunner* runner, struct GUIMenuItem* extra, size_t nExtra); + +#endif
M src/gba/gui/gui-runner.csrc/gba/gui/gui-runner.c

@@ -5,6 +5,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this

* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "gui-runner.h" +#include "gba/gui/gui-config.h" #include "gba/interface.h" #include "gba/serialize.h" #include "util/gui/file-select.h"

@@ -176,6 +177,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) }; #endif *GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Take screenshot", .data = (void*) RUNNER_SCREENSHOT }; + *GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Configure", .data = (void*) RUNNER_CONFIG }; *GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Exit game", .data = (void*) RUNNER_EXIT }; while (true) {

@@ -248,24 +250,24 @@ runner->paused(runner);

} GUIInvalidateKeys(&runner->params); uint32_t keys = 0xFFFFFFFF; // Huge hack to avoid an extra variable! - struct GUIMenuItem item; + struct GUIMenuItem* item; enum GUIMenuExitReason reason = GUIShowMenu(&runner->params, &pauseMenu, &item); if (reason == GUI_MENU_EXIT_ACCEPT) { struct VFile* vf; - switch (((int) item.data) & RUNNER_COMMAND_MASK) { + switch (((int) item->data) & RUNNER_COMMAND_MASK) { case RUNNER_EXIT: running = false; keys = 0; break; case RUNNER_SAVE_STATE: - vf = GBAGetState(runner->context.gba, 0, ((int) item.data) >> 16, true); + vf = GBAGetState(runner->context.gba, 0, ((int) item->data) >> 16, true); if (vf) { GBASaveStateNamed(runner->context.gba, vf, true); vf->close(vf); } break; case RUNNER_LOAD_STATE: - vf = GBAGetState(runner->context.gba, 0, ((int) item.data) >> 16, false); + vf = GBAGetState(runner->context.gba, 0, ((int) item->data) >> 16, false); if (vf) { GBALoadStateNamed(runner->context.gba, vf); vf->close(vf);

@@ -273,6 +275,9 @@ }

break; case RUNNER_SCREENSHOT: GBATakeScreenshot(runner->context.gba, 0); + break; + case RUNNER_CONFIG: + GBAGUIShowConfig(runner, runner->configExtra, runner->nConfigExtra); break; case RUNNER_CONTINUE: break;
M src/gba/gui/gui-runner.hsrc/gba/gui/gui-runner.h

@@ -35,6 +35,9 @@

struct GBAGUIBackground background; struct GBAGUIRunnerLux luminanceSource; + struct GUIMenuItem* configExtra; + size_t nConfigExtra; + void (*setup)(struct GBAGUIRunner*); void (*teardown)(struct GBAGUIRunner*); void (*gameLoaded)(struct GBAGUIRunner*);
M src/platform/3ds/main.csrc/platform/3ds/main.c

@@ -11,6 +11,7 @@ #include "gba/video.h"

#include "util/gui.h" #include "util/gui/file-select.h" #include "util/gui/font.h" +#include "util/gui/menu.h" #include "util/memory.h" #include "3ds-vfs.h"

@@ -81,6 +82,11 @@ GBAVideoSoftwareRendererCreate(&renderer);

renderer.outputBuffer = linearMemAlign(256 * VIDEO_VERTICAL_PIXELS * 2, 0x80); renderer.outputBufferStride = 256; runner->context.renderer = &renderer.d; + + unsigned mode; + if (GBAConfigGetUIntValue(&runner->context.config, "screenMode", &mode) && mode < SM_MAX) { + screenMode = mode; + } GBAAudioResizeBuffer(&runner->context.gba->audio, AUDIO_SAMPLES); }

@@ -235,7 +241,13 @@ _drawStart();

_drawEnd(); _drawStart(); _drawEnd(); - screenMode = (screenMode + 1) % SM_MAX; + unsigned mode; + if (GBAConfigGetUIntValue(&runner->context.config, "screenMode", &mode) && mode != screenMode) { + screenMode = mode; + } else { + screenMode = (screenMode + 1) % SM_MAX; + GBAConfigSetUIntValue(&runner->context.config, "screenMode", screenMode); + } } static uint32_t _pollInput(void) {

@@ -395,6 +407,24 @@ 0, 0,

GUI_PARAMS_TRAIL }, + .configExtra = (struct GUIMenuItem[]) { + { + .title = "Screen mode", + .data = "screenMode", + .submenu = 0, + .state = SM_PA_TOP, + .validStates = (const char*[]) { + "Pixel-Accurate/Bottom", + "Aspect-Ratio Fit/Bottom", + "Stretched/Bottom", + "Pixel-Accurate/Top", + "Aspect-Ratio Fit/Top", + "Stretched/Top", + 0 + } + } + }, + .nConfigExtra = 1, .setup = _setup, .teardown = 0, .gameLoaded = _gameLoaded,
M src/platform/psp2/main.csrc/platform/psp2/main.c

@@ -10,6 +10,7 @@ #include "gba/gui/gui-runner.h"

#include "util/gui.h" #include "util/gui/font.h" #include "util/gui/file-select.h" +#include "util/gui/menu.h" #include <psp2/ctrl.h> #include <psp2/kernel/processmgr.h>

@@ -88,6 +89,21 @@ 0, 0,

GUI_PARAMS_TRAIL }, + .configExtra = (struct GUIMenuItem[]) { + { + .title = "Screen mode", + .data = "screenMode", + .submenu = 0, + .state = 0, + .validStates = (const char*[]) { + "With Background", + "Without Background", + "Stretched", + 0 + } + } + }, + .nConfigExtra = 1, .setup = GBAPSP2Setup, .teardown = GBAPSP2Teardown, .gameLoaded = GBAPSP2LoadROM,
M src/platform/psp2/psp2-context.csrc/platform/psp2/psp2-context.c

@@ -263,7 +263,13 @@ }

} void GBAPSP2IncrementScreenMode(struct GBAGUIRunner* runner) { - screenMode = (screenMode + 1) % SM_MAX; + unsigned mode; + if (GBAConfigGetUIntValue(&runner->context.config, "screenMode", &mode) && mode != screenMode) { + screenMode = mode; + } else { + screenMode = (screenMode + 1) % SM_MAX; + GBAConfigSetUIntValue(&runner->context.config, "screenMode", screenMode); + } } __attribute__((noreturn, weak)) void __assert_func(const char* file, int line, const char* func, const char* expr) {
M src/util/gui/file-select.csrc/util/gui/file-select.c

@@ -137,7 +137,7 @@ GUIMenuItemListInit(&menu.items, 0);

_refreshDirectory(params, params->currentPath, &menu.items, filter); while (true) { - struct GUIMenuItem item; + struct GUIMenuItem* item; enum GUIMenuExitReason reason = GUIShowMenu(params, &menu, &item); params->fileIndex = menu.index; if (reason == GUI_MENU_EXIT_CANCEL) {

@@ -155,7 +155,7 @@ const char* sep = PATH_SEP;

if (params->currentPath[len - 1] == *sep) { sep = ""; } - snprintf(outPath, outLen, "%s%s%s", params->currentPath, sep, item.title); + snprintf(outPath, outLen, "%s%s%s", params->currentPath, sep, item->title); struct GUIMenuItemList newFiles; GUIMenuItemListInit(&newFiles, 0);
M src/util/gui/menu.csrc/util/gui/menu.c

@@ -10,7 +10,7 @@ #include "util/gui/font.h"

DEFINE_VECTOR(GUIMenuItemList, struct GUIMenuItem); -enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* menu, struct GUIMenuItem* item) { +enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* menu, struct GUIMenuItem** item) { size_t start = 0; size_t lineHeight = GUIFontHeight(params->font); size_t pageSize = params->height / lineHeight;

@@ -35,14 +35,24 @@ if (newInput & (1 << GUI_INPUT_DOWN) && menu->index < GUIMenuItemListSize(&menu->items) - 1) {

++menu->index; } if (newInput & (1 << GUI_INPUT_LEFT)) { - if (menu->index >= pageSize) { + struct GUIMenuItem* item = GUIMenuItemListGetPointer(&menu->items, menu->index); + if (item->validStates) { + if (item->state > 0) { + --item->state; + } + } else if (menu->index >= pageSize) { menu->index -= pageSize; } else { menu->index = 0; } } if (newInput & (1 << GUI_INPUT_RIGHT)) { - if (menu->index + pageSize < GUIMenuItemListSize(&menu->items)) { + struct GUIMenuItem* item = GUIMenuItemListGetPointer(&menu->items, menu->index); + if (item->validStates) { + if (item->validStates[item->state + 1]) { + ++item->state; + } + } else if (menu->index + pageSize < GUIMenuItemListSize(&menu->items)) { menu->index += pageSize; } else { menu->index = GUIMenuItemListSize(&menu->items) - 1;

@@ -70,9 +80,9 @@ if (newInput & (1 << GUI_INPUT_CANCEL)) {

break; } if (newInput & (1 << GUI_INPUT_SELECT) || (cursorOverItem == 2 && cursor == GUI_CURSOR_CLICKED)) { - *item = *GUIMenuItemListGetPointer(&menu->items, menu->index); - if (item->submenu) { - enum GUIMenuExitReason reason = GUIShowMenu(params, item->submenu, item); + *item = GUIMenuItemListGetPointer(&menu->items, menu->index); + if ((*item)->submenu) { + enum GUIMenuExitReason reason = GUIShowMenu(params, (*item)->submenu, item); if (reason != GUI_MENU_EXIT_BACK) { return reason; }

@@ -105,7 +115,11 @@ if (i == menu->index) {

color = 0xFFFFFFFF; bullet = '>'; } - GUIFontPrintf(params->font, 0, y, GUI_TEXT_LEFT, color, "%c %s", bullet, GUIMenuItemListGetPointer(&menu->items, i)->title); + struct GUIMenuItem* item = GUIMenuItemListGetPointer(&menu->items, i); + GUIFontPrintf(params->font, 0, y, GUI_TEXT_LEFT, color, "%c %s", bullet, item->title); + if (item->validStates) { + GUIFontPrintf(params->font, params->width, y, GUI_TEXT_RIGHT, color, "%s ", item->validStates[item->state]); + } y += lineHeight; if (y + lineHeight > params->height) { break;
M src/util/gui/menu.hsrc/util/gui/menu.h

@@ -12,6 +12,8 @@ struct GUIMenu;

struct GUIMenuItem { const char* title; void* data; + unsigned state; + const char** validStates; struct GUIMenu* submenu; };

@@ -32,6 +34,6 @@ GUI_MENU_EXIT_CANCEL,

}; struct GUIParams; -enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* menu, struct GUIMenuItem* item); +enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* menu, struct GUIMenuItem** item); #endif