all repos — mgba @ cfc90a3b67d42d6019ddd44742068af6df3f54c8

mGBA Game Boy Advance Emulator

src/feature/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 <mgba/core/config.h>
  9#include <mgba/core/core.h>
 10#include "feature/gui/gui-runner.h"
 11#include "feature/gui/remap.h"
 12#include <mgba/internal/gba/gba.h>
 13#ifdef M_CORE_GB
 14#include <mgba/internal/gb/gb.h>
 15#endif
 16#include <mgba-util/gui/file-select.h>
 17#include <mgba-util/gui/menu.h>
 18
 19#ifndef GUI_MAX_INPUTS
 20#define GUI_MAX_INPUTS 7
 21#endif
 22
 23void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t nExtra) {
 24	struct GUIMenu menu = {
 25		.title = "Configure",
 26		.index = 0,
 27		.background = &runner->background.d
 28	};
 29	GUIMenuItemListInit(&menu.items, 0);
 30	*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
 31		.title = "Frameskip",
 32		.data = "frameskip",
 33		.submenu = 0,
 34		.state = 0,
 35		.validStates = (const char*[]) {
 36			"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
 37		},
 38		.nStates = 10
 39	};
 40	*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
 41		.title = "Show framerate",
 42		.data = "fpsCounter",
 43		.submenu = 0,
 44		.state = false,
 45		.validStates = (const char*[]) {
 46			"Off", "On"
 47		},
 48		.nStates = 2
 49	};
 50	*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
 51		.title = "Autosave state",
 52		.data = "autosave",
 53		.submenu = 0,
 54		.state = true,
 55		.validStates = (const char*[]) {
 56			"Off", "On"
 57		},
 58		.nStates = 2
 59	};
 60	*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
 61		.title = "Autoload state",
 62		.data = "autoload",
 63		.submenu = 0,
 64		.state = true,
 65		.validStates = (const char*[]) {
 66			"Off", "On"
 67		},
 68		.nStates = 2
 69	};
 70	*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
 71		.title = "Use BIOS if found",
 72		.data = "useBios",
 73		.submenu = 0,
 74		.state = true,
 75		.validStates = (const char*[]) {
 76			"Off", "On"
 77		},
 78		.nStates = 2
 79	};
 80	*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
 81		.title = "Select GBA BIOS path",
 82		.data = "gba.bios",
 83	};
 84#ifdef M_CORE_GB
 85	*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
 86		.title = "Select GB BIOS path",
 87		.data = "gb.bios",
 88	};
 89	*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
 90		.title = "Select GBC BIOS path",
 91		.data = "gbc.bios",
 92	};
 93	*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
 94		.title = "Select SGB BIOS path",
 95		.data = "sgb.bios",
 96	};
 97#endif
 98	size_t i;
 99	const char* mapNames[GUI_MAX_INPUTS + 1];
100	if (runner->keySources) {
101		for (i = 0; runner->keySources[i].id && i < GUI_MAX_INPUTS; ++i) {
102			mapNames[i] = runner->keySources[i].name;
103		}
104		if (i == 1) {
105			// Don't display a name if there's only one input source
106			i = 0;
107		}
108		*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
109			.title = "Remap controls",
110			.data = "*REMAP",
111			.state = 0,
112			.validStates = i ? mapNames : 0,
113			.nStates = i
114		};
115	}
116	for (i = 0; i < nExtra; ++i) {
117		*GUIMenuItemListAppend(&menu.items) = extra[i];
118	}
119	*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
120		.title = "Save",
121		.data = "*SAVE",
122	};
123	*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
124		.title = "Cancel",
125		.data = 0,
126	};
127	enum GUIMenuExitReason reason;
128	char gbaBiosPath[256] = "";
129#ifdef M_CORE_GB
130	char gbBiosPath[256] = "";
131	char gbcBiosPath[256] = "";
132	char sgbBiosPath[256] = "";
133#endif
134
135	struct GUIMenuItem* item;
136	for (i = 0; i < GUIMenuItemListSize(&menu.items); ++i) {
137		item = GUIMenuItemListGetPointer(&menu.items, i);
138		if (!item->validStates || !item->data) {
139			continue;
140		}
141		mCoreConfigGetUIntValue(&runner->config, item->data, &item->state);
142	}
143
144	while (true) {
145		reason = GUIShowMenu(&runner->params, &menu, &item);
146		if (reason != GUI_MENU_EXIT_ACCEPT || !item->data) {
147			break;
148		}
149		if (!strcmp(item->data, "*SAVE")) {
150			if (gbaBiosPath[0]) {
151				mCoreConfigSetValue(&runner->config, "gba.bios", gbaBiosPath);
152			}
153			if (gbBiosPath[0]) {
154				mCoreConfigSetValue(&runner->config, "gb.bios", gbBiosPath);
155			}
156			if (gbcBiosPath[0]) {
157				mCoreConfigSetValue(&runner->config, "gbc.bios", gbcBiosPath);
158			}
159			if (sgbBiosPath[0]) {
160				mCoreConfigSetValue(&runner->config, "sgb.bios", sgbBiosPath);
161			}
162			for (i = 0; i < GUIMenuItemListSize(&menu.items); ++i) {
163				item = GUIMenuItemListGetPointer(&menu.items, i);
164				if (!item->validStates || !item->data) {
165					continue;
166				}
167				mCoreConfigSetUIntValue(&runner->config, item->data, item->state);
168			}
169			if (runner->keySources) {
170				size_t i;
171				for (i = 0; runner->keySources[i].id; ++i) {
172					mInputMapSave(&runner->core->inputMap, runner->keySources[i].id, mCoreConfigGetInput(&runner->config));
173					mInputMapSave(&runner->params.keyMap, runner->keySources[i].id, mCoreConfigGetInput(&runner->config));
174				}
175			}
176			mCoreConfigSave(&runner->config);
177			mCoreLoadForeignConfig(runner->core, &runner->config);
178			break;
179		}
180		if (!strcmp(item->data, "*REMAP")) {
181			mGUIRemapKeys(&runner->params, &runner->core->inputMap, &runner->keySources[item->state]);
182			continue;
183		}
184		if (!strcmp(item->data, "gba.bios")) {
185			// TODO: show box if failed
186			if (!GUISelectFile(&runner->params, gbaBiosPath, sizeof(gbaBiosPath), GBAIsBIOS)) {
187				gbaBiosPath[0] = '\0';
188			}
189			continue;
190		}
191#ifdef M_CORE_GB
192		if (!strcmp(item->data, "gb.bios")) {
193			// TODO: show box if failed
194			if (!GUISelectFile(&runner->params, gbBiosPath, sizeof(gbBiosPath), GBIsBIOS)) {
195				gbBiosPath[0] = '\0';
196			}
197			continue;
198		}
199		if (!strcmp(item->data, "gbc.bios")) {
200			// TODO: show box if failed
201			if (!GUISelectFile(&runner->params, gbcBiosPath, sizeof(gbcBiosPath), GBIsBIOS)) {
202				gbcBiosPath[0] = '\0';
203			}
204			continue;
205		}
206		if (!strcmp(item->data, "sgb.bios")) {
207			// TODO: show box if failed
208			if (!GUISelectFile(&runner->params, sgbBiosPath, sizeof(sgbBiosPath), GBIsBIOS)) {
209				sgbBiosPath[0] = '\0';
210			}
211			continue;
212		}
213#endif
214		if (item->validStates) {
215			++item->state;
216			if (item->state >= item->nStates) {
217				item->state = 0;
218			}
219		}
220	}
221}