GUI: Load/save states

This commit is contained in:
Jeffrey Pfau 2015-08-30 18:23:01 -07:00
parent 933a6c4f36
commit 41452ec4e6
5 changed files with 43 additions and 25 deletions

View File

@ -14,6 +14,7 @@ bool GBAContextInit(struct GBAContext* context, const char* port) {
context->gba = anonymousMemoryMap(sizeof(struct GBA)); context->gba = anonymousMemoryMap(sizeof(struct GBA));
context->cpu = anonymousMemoryMap(sizeof(struct ARMCore)); context->cpu = anonymousMemoryMap(sizeof(struct ARMCore));
context->rom = 0; context->rom = 0;
context->fname = 0;
context->save = 0; context->save = 0;
context->renderer = 0; context->renderer = 0;
memset(context->components, 0, sizeof(context->components)); memset(context->components, 0, sizeof(context->components));
@ -61,6 +62,7 @@ bool GBAContextLoadROM(struct GBAContext* context, const char* path, bool autolo
return false; return false;
} }
context->fname = path;
if (autoloadSave) { if (autoloadSave) {
context->save = VDirOptionalOpenFile(0, path, 0, ".sav", O_RDWR | O_CREAT); context->save = VDirOptionalOpenFile(0, path, 0, ".sav", O_RDWR | O_CREAT);
} }
@ -123,7 +125,7 @@ bool GBAContextStart(struct GBAContext* context) {
GBAVideoAssociateRenderer(&context->gba->video, context->renderer); GBAVideoAssociateRenderer(&context->gba->video, context->renderer);
} }
if (!GBALoadROM(context->gba, context->rom, context->save, 0)) { if (!GBALoadROM(context->gba, context->rom, context->save, context->fname)) {
return false; return false;
} }

View File

@ -16,6 +16,7 @@ struct GBAContext {
struct ARMCore* cpu; struct ARMCore* cpu;
struct GBAVideoRenderer* renderer; struct GBAVideoRenderer* renderer;
struct VFile* rom; struct VFile* rom;
const char* fname;
struct VFile* save; struct VFile* save;
struct VFile* bios; struct VFile* bios;
struct ARMComponent* components[GBA_COMPONENT_MAX]; struct ARMComponent* components[GBA_COMPONENT_MAX];

View File

@ -5,13 +5,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gui-runner.h" #include "gui-runner.h"
#include "gba/serialize.h"
#include "util/gui/file-select.h" #include "util/gui/file-select.h"
#include "util/gui/font.h" #include "util/gui/font.h"
#include "util/gui/menu.h" #include "util/gui/menu.h"
#include "util/vfs.h"
enum { enum {
RUNNER_CONTINUE, RUNNER_CONTINUE,
RUNNER_EXIT RUNNER_EXIT,
RUNNER_SAVE_STATE,
RUNNER_LOAD_STATE,
}; };
void GBAGUIInit(struct GBAGUIRunner* runner, const char* port) { void GBAGUIInit(struct GBAGUIRunner* runner, const char* port) {
@ -36,6 +40,11 @@ void GBAGUIRunloop(struct GBAGUIRunner* runner) {
}; };
GUIMenuItemListInit(&pauseMenu.items, 0); GUIMenuItemListInit(&pauseMenu.items, 0);
*GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Unpause", .data = (void*) RUNNER_CONTINUE }; *GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Unpause", .data = (void*) RUNNER_CONTINUE };
#if !(defined(__POWERPC__) || defined(__PPC__))
// PPC doesn't have working savestates yet
*GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Save state", .data = (void*) RUNNER_SAVE_STATE };
*GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Load state", .data = (void*) RUNNER_LOAD_STATE };
#endif
*GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Exit game", .data = (void*) RUNNER_EXIT }; *GUIMenuItemListAppend(&pauseMenu.items) = (struct GUIMenuItem) { .title = "Exit game", .data = (void*) RUNNER_EXIT };
while (true) { while (true) {
@ -95,29 +104,37 @@ void GBAGUIRunloop(struct GBAGUIRunner* runner) {
runner->params.guiPrepare(); runner->params.guiPrepare();
} }
GUIInvalidateKeys(&runner->params); GUIInvalidateKeys(&runner->params);
while (true) { int keys = -1; // Huge hack to avoid an extra variable!
struct GUIMenuItem item; struct GUIMenuItem item;
enum GUIMenuExitReason reason = GUIShowMenu(&runner->params, &pauseMenu, &item); enum GUIMenuExitReason reason = GUIShowMenu(&runner->params, &pauseMenu, &item);
if (reason == GUI_MENU_EXIT_ACCEPT) { if (reason == GUI_MENU_EXIT_ACCEPT) {
if (item.data == (void*) RUNNER_EXIT) { struct VFile* vf;
running = false; switch ((int) item.data) {
break; case RUNNER_EXIT:
} running = false;
if (item.data == (void*) RUNNER_CONTINUE) { keys = 0;
int keys = -1; break;
while (keys) { case RUNNER_SAVE_STATE:
GUIPollInput(&runner->params, 0, &keys); vf = GBAGetState(runner->context.gba, 0, 1, true);
} if (vf) {
break; GBASaveStateNamed(runner->context.gba, vf, true);
} vf->close(vf);
} else {
int keys = -1;
while (keys) {
GUIPollInput(&runner->params, 0, &keys);
} }
break; break;
case RUNNER_LOAD_STATE:
vf = GBAGetState(runner->context.gba, 0, 1, false);
if (vf) {
GBALoadStateNamed(runner->context.gba, vf);
vf->close(vf);
}
break;
case RUNNER_CONTINUE:
break;
} }
} }
while (keys) {
GUIPollInput(&runner->params, 0, &keys);
}
if (runner->params.guiFinish) { if (runner->params.guiFinish) {
runner->params.guiFinish(); runner->params.guiFinish();
} }

View File

@ -187,13 +187,11 @@ bool GBADeserialize(struct GBA* gba, const struct GBASerializedState* state) {
return true; return true;
} }
#ifndef _3DS
struct VFile* GBAGetState(struct GBA* gba, struct VDir* dir, int slot, bool write) { struct VFile* GBAGetState(struct GBA* gba, struct VDir* dir, int slot, bool write) {
char suffix[5] = { '\0' }; char suffix[5] = { '\0' };
snprintf(suffix, sizeof(suffix), ".ss%d", slot); snprintf(suffix, sizeof(suffix), ".ss%d", slot);
return VDirOptionalOpenFile(dir, gba->activeFile, "savestate", suffix, write ? (O_CREAT | O_TRUNC | O_RDWR) : O_RDONLY); return VDirOptionalOpenFile(dir, gba->activeFile, "savestate", suffix, write ? (O_CREAT | O_TRUNC | O_RDWR) : O_RDONLY);
} }
#endif
#ifdef USE_PNG #ifdef USE_PNG
static bool _savePNGState(struct GBA* gba, struct VFile* vf) { static bool _savePNGState(struct GBA* gba, struct VFile* vf) {

View File

@ -26,8 +26,8 @@ extern char* fake_heap_start;
extern char* fake_heap_end; extern char* fake_heap_end;
u32 __linear_heap; u32 __linear_heap;
u32 __heapBase; u32 __heapBase;
static u32 __heap_size = 0x03000000; static u32 __heap_size = 0x02800000;
static u32 __linear_heap_size = 0x00800000; static u32 __linear_heap_size = 0x01000000;
extern void (*__system_retAddr)(void); extern void (*__system_retAddr)(void);