mirror of https://github.com/mgba-emu/mgba.git
GBA Context: Configuration options
This commit is contained in:
parent
94ffa0d2d7
commit
c45315b96b
|
@ -56,8 +56,8 @@ bool GBAContextInit(struct GBAContext* context, const char* port) {
|
|||
.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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -5,6 +5,7 @@
|
|||
* 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 @@ void GBAGUIRunloop(struct GBAGUIRunner* runner) {
|
|||
*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 @@ void GBAGUIRunloop(struct GBAGUIRunner* 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);
|
||||
|
@ -274,6 +276,9 @@ void GBAGUIRunloop(struct GBAGUIRunner* runner) {
|
|||
case RUNNER_SCREENSHOT:
|
||||
GBATakeScreenshot(runner->context.gba, 0);
|
||||
break;
|
||||
case RUNNER_CONFIG:
|
||||
GBAGUIShowConfig(runner, runner->configExtra, runner->nConfigExtra);
|
||||
break;
|
||||
case RUNNER_CONTINUE:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,9 @@ struct GBAGUIRunner {
|
|||
struct GBAGUIBackground background;
|
||||
struct GBAGUIRunnerLux luminanceSource;
|
||||
|
||||
struct GUIMenuItem* configExtra;
|
||||
size_t nConfigExtra;
|
||||
|
||||
void (*setup)(struct GBAGUIRunner*);
|
||||
void (*teardown)(struct GBAGUIRunner*);
|
||||
void (*gameLoaded)(struct GBAGUIRunner*);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#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"
|
||||
|
@ -82,6 +83,11 @@ static void _setup(struct GBAGUIRunner* runner) {
|
|||
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 @@ static void _incrementScreenMode(struct GBAGUIRunner* runner) {
|
|||
_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 @@ int main() {
|
|||
|
||||
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,
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#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 @@ int main() {
|
|||
|
||||
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,
|
||||
|
|
|
@ -263,7 +263,13 @@ void GBAPSP2DrawScreenshot(struct GBAGUIRunner* runner, const uint32_t* pixels,
|
|||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -137,7 +137,7 @@ bool GUISelectFile(struct GUIParams* params, char* outPath, size_t outLen, bool
|
|||
_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 @@ bool GUISelectFile(struct GUIParams* params, char* outPath, size_t outLen, bool
|
|||
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);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
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 @@ enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* men
|
|||
++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 @@ enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* men
|
|||
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 @@ enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* men
|
|||
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;
|
||||
|
|
|
@ -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 @@ enum GUIMenuExitReason {
|
|||
};
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue