mGUI: Initial cheat support UI

This commit is contained in:
Vicki Pfau 2021-04-23 00:22:09 -07:00
parent 4ba921ccc5
commit 990704e46b
5 changed files with 187 additions and 1 deletions

View File

@ -1,6 +1,7 @@
0.10.0: (Future)
Features:
- Tool for converting scanned pictures of e-Reader cards to raw dotcode data
- Cheat code support in homebrew ports
Misc:
- Qt: Rearrange menus some

View File

@ -5,6 +5,7 @@ set(SOURCE_FILES
video-logger.c)
set(GUI_FILES
gui/cheats.c
gui/gui-config.c
gui/gui-runner.c
gui/remap.c)

158
src/feature/gui/cheats.c Normal file
View File

@ -0,0 +1,158 @@
/* Copyright (c) 2013-2021 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 <mgba/core/cheats.h>
#include <mgba/core/core.h>
#include "feature/gui/gui-runner.h"
#include <mgba-util/gui/menu.h>
enum mGUICheatAction {
CHEAT_ADD_LINE = 1,
CHEAT_RENAME,
CHEAT_DELETE,
};
static const char* const offOn[] = { "Off", "On" };
static void mGUIShowCheatSet(struct mGUIRunner* runner, struct mCheatDevice* device, struct mCheatSet* set) {
char cheatName[64];
snprintf(cheatName, sizeof(cheatName), "Edit cheat: %s", set->name);
struct GUIMenu menu = {
.title = cheatName,
.index = 0,
.background = &runner->background.d
};
GUIMenuItemListInit(&menu.items, 0);
*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
.title = "Enable",
.state = set->enabled,
.validStates = offOn,
.nStates = 2
};
*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
.title = "Add line",
.data = (void*) CHEAT_ADD_LINE,
};
*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
.title = "Rename",
.data = (void*) CHEAT_RENAME,
};
*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
.title = "Delete",
.data = (void*) CHEAT_DELETE,
};
*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
.title = "Back",
.data = 0,
};
while (true) {
struct GUIKeyboardParams keyboard;
GUIKeyboardParamsInit(&keyboard);
struct GUIMenuItem* item;
enum GUIMenuExitReason reason = GUIShowMenu(&runner->params, &menu, &item);
set->enabled = GUIMenuItemListGetPointer(&menu.items, 0)->state;
if (reason != GUI_MENU_EXIT_ACCEPT || !item->data) {
break;
}
enum mGUICheatAction action = (enum mGUICheatAction) item->data;
switch (action) {
case CHEAT_ADD_LINE:
strlcpy(keyboard.title, "Add line", sizeof(keyboard.title));
keyboard.maxLen = 12;
if (runner->params.getText(&keyboard) == GUI_KEYBOARD_DONE) {
mCheatAddLine(set, keyboard.result, 0);
}
break;
case CHEAT_RENAME:
strlcpy(keyboard.title, "Rename cheat", sizeof(keyboard.title));
strlcpy(keyboard.result, set->name, sizeof(keyboard.result));
keyboard.maxLen = 50;
if (runner->params.getText(&keyboard) == GUI_KEYBOARD_DONE) {
mCheatSetRename(set, keyboard.result);
snprintf(cheatName, sizeof(cheatName), "Edit cheat: %s", set->name);
}
break;
case CHEAT_DELETE:
mCheatRemoveSet(device, set);
break;
}
if (action == CHEAT_DELETE) {
break;
}
}
GUIMenuItemListDeinit(&menu.items);
}
void mGUIShowCheats(struct mGUIRunner* runner) {
struct mCheatDevice* device = runner->core->cheatDevice(runner->core);
if (!device) {
return;
}
struct GUIMenu menu = {
.title = "Cheats",
.index = 0,
.background = &runner->background.d
};
GUIMenuItemListInit(&menu.items, 0);
while (true) {
size_t i;
for (i = 0; i < mCheatSetsSize(&device->cheats); ++i) {
struct mCheatSet* set = *mCheatSetsGetPointer(&device->cheats, i);
*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
.title = set->name,
.data = set,
.state = set->enabled,
.validStates = offOn,
.nStates = 2
};
}
*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
.title = "Add new cheat set",
.data = 0,
};
*GUIMenuItemListAppend(&menu.items) = (struct GUIMenuItem) {
.title = "Back",
.data = (void*) -1,
};
struct GUIMenuItem* item;
enum GUIMenuExitReason reason = GUIShowMenu(&runner->params, &menu, &item);
for (i = 0; i < mCheatSetsSize(&device->cheats); ++i) {
struct mCheatSet* set = *mCheatSetsGetPointer(&device->cheats, i);
struct GUIMenuItem* item = GUIMenuItemListGetPointer(&menu.items, i);
set->enabled = item->state;
}
if (reason != GUI_MENU_EXIT_ACCEPT || item->data == (void*) -1) {
break;
}
struct mCheatSet* set = NULL;
if (!item->data) {
struct GUIKeyboardParams keyboard;
GUIKeyboardParamsInit(&keyboard);
keyboard.maxLen = 50;
strlcpy(keyboard.title, "Cheat name", sizeof(keyboard.title));
strlcpy(keyboard.result, "New cheat", sizeof(keyboard.result));
if (runner->params.getText(&keyboard) == GUI_KEYBOARD_DONE) {
set = device->createSet(device, keyboard.result);
mCheatAddSet(device, set);
}
} else {
set = item->data;
}
if (set) {
mGUIShowCheatSet(runner, device, set);
}
GUIMenuItemListClear(&menu.items);
}
GUIMenuItemListDeinit(&menu.items);
mCheatAutosave(device);
}

18
src/feature/gui/cheats.h Normal file
View File

@ -0,0 +1,18 @@
/* Copyright (c) 2013-2021 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_CHEATS_H
#define GUI_CHEATS_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct mGUIRunner;
void mGUIShowCheats(struct mGUIRunner* runner);
CXX_GUARD_END
#endif

View File

@ -8,6 +8,7 @@
#include <mgba/core/core.h>
#include <mgba/core/serialize.h>
#include "feature/gui/gui-config.h"
#include "feature/gui/cheats.h"
#include <mgba/internal/gba/gba.h>
#include <mgba/internal/gba/input.h>
#include <mgba/gba/interface.h>
@ -35,6 +36,7 @@ enum {
RUNNER_SCREENSHOT,
RUNNER_CONFIG,
RUNNER_RESET,
RUNNER_CHEATS,
RUNNER_COMMAND_MASK = 0xFFFF
};
@ -333,7 +335,7 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) {
};
GUIMenuItemListInit(&pauseMenu.items, 0);
GUIMenuItemListInit(&stateSaveMenu.items, 9);
GUIMenuItemListInit(&stateLoadMenu.items, 9);
GUIMenuItemListInit(&stateLoadMenu.items, 10);
*GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Unpause", .data = (void*) RUNNER_CONTINUE };
*GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Save state", .submenu = &stateSaveMenu };
*GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Load state", .submenu = &stateLoadMenu };
@ -360,6 +362,9 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) {
*GUIMenuItemListAppend(&stateLoadMenu.items) = (struct GUIMenuItem) { .title = "State 9", .data = (void*) (RUNNER_LOAD_STATE | RUNNER_STATE(9)) };
*GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Take screenshot", .data = (void*) RUNNER_SCREENSHOT };
if (runner->params.getText) {
*GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Cheats", .data = (void*) RUNNER_CHEATS };
}
*GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Configure", .data = (void*) RUNNER_CONFIG };
*GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Reset game", .data = (void*) RUNNER_RESET };
*GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Exit game", .data = (void*) RUNNER_EXIT };
@ -616,6 +621,9 @@ void mGUIRun(struct mGUIRunner* runner, const char* path) {
case RUNNER_CONFIG:
mGUIShowConfig(runner, runner->configExtra, runner->nConfigExtra);
break;
case RUNNER_CHEATS:
mGUIShowCheats(runner);
break;
case RUNNER_CONTINUE:
break;
}