all repos — mgba @ 331d92d36388ae2e2007b3be34c0889a246504a5

mGBA Game Boy Advance Emulator

src/gba/gui/gui-config.c (view raw)

  1/* Copyright (c) 2013-2016 Jeffrey Pfau
  2 *
  3 * This Source Code Form is subject to the terms of the Mozilla Public
  4 * License, v. 2.0. If a copy of the MPL was not distributed with this
  5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6#include "gui-config.h"
  7
  8#include "gba/gui/gui-runner.h"
  9#include "gba/gui/remap.h"
 10#include "util/gui/file-select.h"
 11#include "util/gui/menu.h"
 12
 13#ifndef GUI_MAX_INPUTS
 14#define GUI_MAX_INPUTS 7
 15#endif
 16
 17void GBAGUIShowConfig(struct GBAGUIRunner* runner, struct GUIMenuItem* extra, size_t nExtra) {
 18	struct GUIMenu menu = {
 19		.title = "Configure",
 20		.index = 0,
 21		.background = &runner->background.d
 22	};
 23	GUIMenuItemListInit(&menu.items, 0);
 24	*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
 25		.title = "Frameskip",
 26		.data = "frameskip",
 27		.submenu = 0,
 28		.state = 0,
 29		.validStates = (const char*[]) {
 30			"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
 31		},
 32		.nStates = 10
 33	};
 34	*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
 35		.title = "Show framerate",
 36		.data = "fpsCounter",
 37		.submenu = 0,
 38		.state = false,
 39		.validStates = (const char*[]) {
 40			"Off", "On"
 41		},
 42		.nStates = 2
 43	};
 44	*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
 45		.title = "Use BIOS if found",
 46		.data = "useBios",
 47		.submenu = 0,
 48		.state = true,
 49		.validStates = (const char*[]) {
 50			"Off", "On"
 51		},
 52		.nStates = 2
 53	};
 54	*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
 55		.title = "Select BIOS path",
 56		.data = "bios",
 57	};
 58	size_t i;
 59	const char* mapNames[GUI_MAX_INPUTS + 1];
 60	if (runner->keySources) {
 61		for (i = 0; runner->keySources[i].id && i < GUI_MAX_INPUTS; ++i) {
 62			mapNames[i] = runner->keySources[i].name;
 63		}
 64		if (i == 1) {
 65			// Don't display a name if there's only one input source
 66			i = 0;
 67		}
 68		*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
 69			.title = "Remap controls",
 70			.data = "*REMAP",
 71			.state = 0,
 72			.validStates = i ? mapNames : 0,
 73			.nStates = i
 74		};
 75	}
 76	for (i = 0; i < nExtra; ++i) {
 77		*GUIMenuItemListAppend(&menu.items) = extra[i];
 78	}
 79	*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
 80		.title = "Save",
 81		.data = "*SAVE",
 82	};
 83	*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
 84		.title = "Cancel",
 85		.data = 0,
 86	};
 87	enum GUIMenuExitReason reason;
 88	char biosPath[256] = "";
 89
 90	struct GUIMenuItem* item;
 91	for (i = 0; i < GUIMenuItemListSize(&menu.items); ++i) {
 92		item = GUIMenuItemListGetPointer(&menu.items, i);
 93		if (!item->validStates || !item->data) {
 94			continue;
 95		}
 96		GBAConfigGetUIntValue(&runner->context.config, item->data, &item->state);
 97	}
 98
 99	while (true) {
100		reason = GUIShowMenu(&runner->params, &menu, &item);
101		if (reason != GUI_MENU_EXIT_ACCEPT || !item->data) {
102			break;
103		}
104		if (!strcmp(item->data, "*SAVE")) {
105			if (biosPath[0]) {
106				GBAConfigSetValue(&runner->context.config, "bios", biosPath);
107			}
108			for (i = 0; i < GUIMenuItemListSize(&menu.items); ++i) {
109				item = GUIMenuItemListGetPointer(&menu.items, i);
110				if (!item->validStates || !item->data) {
111					continue;
112				}
113				GBAConfigSetUIntValue(&runner->context.config, item->data, item->state);
114			}
115			GBAConfigSave(&runner->context.config);
116			break;
117		}
118		if (!strcmp(item->data, "*REMAP")) {
119			GBAGUIRemapKeys(&runner->params, &runner->context.inputMap, &runner->keySources[item->state]);
120			continue;
121		}
122		if (!strcmp(item->data, "bios")) {
123			// TODO: show box if failed
124			if (!GUISelectFile(&runner->params, biosPath, sizeof(biosPath), GBAIsBIOS)) {
125				biosPath[0] = '\0';
126			}
127			continue;
128		}
129		if (item->validStates) {
130			++item->state;
131			if (item->state >= item->nStates) {
132				item->state = 0;
133			}
134		}
135	}
136}