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}