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#include <mgba-util/gui/file-select.h>
14#include <mgba-util/gui/menu.h>
15
16#ifndef GUI_MAX_INPUTS
17#define GUI_MAX_INPUTS 7
18#endif
19
20void mGUIShowConfig(struct mGUIRunner* runner, struct GUIMenuItem* extra, size_t nExtra) {
21 struct GUIMenu menu = {
22 .title = "Configure",
23 .index = 0,
24 .background = &runner->background.d
25 };
26 GUIMenuItemListInit(&menu.items, 0);
27 *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
28 .title = "Frameskip",
29 .data = "frameskip",
30 .submenu = 0,
31 .state = 0,
32 .validStates = (const char*[]) {
33 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
34 },
35 .nStates = 10
36 };
37 *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
38 .title = "Show framerate",
39 .data = "fpsCounter",
40 .submenu = 0,
41 .state = false,
42 .validStates = (const char*[]) {
43 "Off", "On"
44 },
45 .nStates = 2
46 };
47 *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
48 .title = "Use BIOS if found",
49 .data = "useBios",
50 .submenu = 0,
51 .state = true,
52 .validStates = (const char*[]) {
53 "Off", "On"
54 },
55 .nStates = 2
56 };
57 *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
58 .title = "Select BIOS path",
59 .data = "bios",
60 };
61 size_t i;
62 const char* mapNames[GUI_MAX_INPUTS + 1];
63 if (runner->keySources) {
64 for (i = 0; runner->keySources[i].id && i < GUI_MAX_INPUTS; ++i) {
65 mapNames[i] = runner->keySources[i].name;
66 }
67 if (i == 1) {
68 // Don't display a name if there's only one input source
69 i = 0;
70 }
71 *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
72 .title = "Remap controls",
73 .data = "*REMAP",
74 .state = 0,
75 .validStates = i ? mapNames : 0,
76 .nStates = i
77 };
78 }
79 for (i = 0; i < nExtra; ++i) {
80 *GUIMenuItemListAppend(&menu.items) = extra[i];
81 }
82 *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
83 .title = "Save",
84 .data = "*SAVE",
85 };
86 *GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
87 .title = "Cancel",
88 .data = 0,
89 };
90 enum GUIMenuExitReason reason;
91 char biosPath[256] = "";
92
93 struct GUIMenuItem* item;
94 for (i = 0; i < GUIMenuItemListSize(&menu.items); ++i) {
95 item = GUIMenuItemListGetPointer(&menu.items, i);
96 if (!item->validStates || !item->data) {
97 continue;
98 }
99 mCoreConfigGetUIntValue(&runner->config, item->data, &item->state);
100 }
101
102 while (true) {
103 reason = GUIShowMenu(&runner->params, &menu, &item);
104 if (reason != GUI_MENU_EXIT_ACCEPT || !item->data) {
105 break;
106 }
107 if (!strcmp(item->data, "*SAVE")) {
108 if (biosPath[0]) {
109 mCoreConfigSetValue(&runner->config, "bios", biosPath);
110 }
111 for (i = 0; i < GUIMenuItemListSize(&menu.items); ++i) {
112 item = GUIMenuItemListGetPointer(&menu.items, i);
113 if (!item->validStates || !item->data) {
114 continue;
115 }
116 mCoreConfigSetUIntValue(&runner->config, item->data, item->state);
117 }
118 if (runner->keySources) {
119 size_t i;
120 for (i = 0; runner->keySources[i].id; ++i) {
121 mInputMapSave(&runner->core->inputMap, runner->keySources[i].id, mCoreConfigGetInput(&runner->config));
122 mInputMapSave(&runner->params.keyMap, runner->keySources[i].id, mCoreConfigGetInput(&runner->config));
123 }
124 }
125 mCoreConfigSave(&runner->config);
126 mCoreLoadForeignConfig(runner->core, &runner->config);
127 break;
128 }
129 if (!strcmp(item->data, "*REMAP")) {
130 mGUIRemapKeys(&runner->params, &runner->core->inputMap, &runner->keySources[item->state]);
131 continue;
132 }
133 if (!strcmp(item->data, "bios")) {
134 // TODO: show box if failed
135 if (!GUISelectFile(&runner->params, biosPath, sizeof(biosPath), GBAIsBIOS)) {
136 biosPath[0] = '\0';
137 }
138 continue;
139 }
140 if (item->validStates) {
141 ++item->state;
142 if (item->state >= item->nStates) {
143 item->state = 0;
144 }
145 }
146 }
147}