diff --git a/src/core/core.h b/src/core/core.h index cc09ad44e..d00bb837a 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -58,6 +58,9 @@ struct mCore { void (*runLoop)(struct mCore*); void (*step)(struct mCore*); + bool (*loadState)(struct mCore*, struct VFile*, int flags); + bool (*saveState)(struct mCore*, struct VFile*, int flags); + void (*setKeys)(struct mCore*, uint32_t keys); void (*addKeys)(struct mCore*, uint32_t keys); void (*clearKeys)(struct mCore*, uint32_t keys); @@ -70,7 +73,15 @@ struct mCore { }; bool mCoreLoadFile(struct mCore* core, const char* path); + +#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 bool mCoreAutoloadSave(struct mCore* core); bool mCoreAutoloadPatch(struct mCore* core); +bool mCoreSaveState(struct mCore* core, int slot, int flags); +bool mCoreLoadState(struct mCore* core, int slot, int flags); +struct VFile* mCoreGetState(struct mCore* core, int slot, bool write); +void mCoreDeleteState(struct mCore* core, int slot); +#endif + #endif diff --git a/src/core/log.c b/src/core/log.c index 42ba0ad45..f843d012a 100644 --- a/src/core/log.c +++ b/src/core/log.c @@ -34,3 +34,5 @@ const char* mLogCategoryName(int category) { } return 0; } + +mLOG_DEFINE_CATEGORY(STATUS, "Status") diff --git a/src/core/log.h b/src/core/log.h index 3dd3eb4f9..36e3e6b6c 100644 --- a/src/core/log.h +++ b/src/core/log.h @@ -53,4 +53,6 @@ static inline void _mLog(int (*category)(void), enum mLogLevel level, const char return category; \ } +mLOG_DECLARE_CATEGORY(STATUS) + #endif diff --git a/src/gb/core.c b/src/gb/core.c index 84a186ec8..a5bc3e152 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -124,6 +124,22 @@ static void _GBCoreStep(struct mCore* core) { LR35902Tick(core->cpu); } +static bool _GBCoreLoadState(struct mCore* core, struct VFile* vf, int flags) { + UNUSED(core); + UNUSED(vf); + UNUSED(flags); + // TODO + return false; +} + +static bool _GBCoreSaveState(struct mCore* core, struct VFile* vf, int flags) { + UNUSED(core); + UNUSED(vf); + UNUSED(flags); + // TODO + return false; +} + static void _GBCoreSetKeys(struct mCore* core, uint32_t keys) { struct GBCore* gbcore = (struct GBCore*) core; gbcore->keys = keys; @@ -180,6 +196,8 @@ struct mCore* GBCoreCreate(void) { core->runFrame = _GBCoreRunFrame; core->runLoop = _GBCoreRunLoop; core->step = _GBCoreStep; + core->loadState = _GBCoreLoadState; + core->saveState = _GBCoreSaveState; core->setKeys = _GBCoreSetKeys; core->addKeys = _GBCoreAddKeys; core->clearKeys = _GBCoreClearKeys; diff --git a/src/gba/core.c b/src/gba/core.c index c83e0569a..0b6682844 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -9,6 +9,7 @@ #include "core/log.h" #include "gba/gba.h" #include "gba/renderers/video-software.h" +#include "gba/serialize.h" #include "util/memory.h" struct GBACore { @@ -126,6 +127,14 @@ static void _GBACoreStep(struct mCore* core) { ARMRun(core->cpu); } +static bool _GBACoreLoadState(struct mCore* core, struct VFile* vf, int flags) { + return GBALoadStateNamed(core->board, vf, flags); +} + +static bool _GBACoreSaveState(struct mCore* core, struct VFile* vf, int flags) { + return GBASaveStateNamed(core->board, vf, flags); +} + static void _GBACoreSetKeys(struct mCore* core, uint32_t keys) { struct GBACore* gbacore = (struct GBACore*) core; gbacore->keys = keys; @@ -181,6 +190,8 @@ struct mCore* GBACoreCreate(void) { core->runFrame = _GBACoreRunFrame; core->runLoop = _GBACoreRunLoop; core->step = _GBACoreStep; + core->loadState = _GBACoreLoadState; + core->saveState = _GBACoreSaveState; core->setKeys = _GBACoreSetKeys; core->addKeys = _GBACoreAddKeys; core->clearKeys = _GBACoreClearKeys; diff --git a/src/platform/sdl/sdl-events.c b/src/platform/sdl/sdl-events.c index 8840d5b73..f8457ce94 100644 --- a/src/platform/sdl/sdl-events.c +++ b/src/platform/sdl/sdl-events.c @@ -564,7 +564,90 @@ static void _mSDLHandleKeypress(struct mCoreThread* context, struct mSDLPlayer* context->sync.audioWait = event->type != SDL_KEYDOWN; return; } - // TODO: Put back events + if (event->type == SDL_KEYDOWN) { + switch (event->keysym.sym) { + case SDLK_F11: + // TODO: Put back debugger + return; +#ifdef USE_PNG + case SDLK_F12: + // TODO: Put back screenshots + return; +#endif + case SDLK_BACKSLASH: + // TODO: Put back frame advance + return; + case SDLK_BACKQUOTE: + // TODO: Put back rewind + return; +#ifdef BUILD_PANDORA + case SDLK_ESCAPE: + mCoreThreadEnd(context); + return; +#endif + default: + if ((event->keysym.mod & GUI_MOD) && (event->keysym.mod & GUI_MOD) == event->keysym.mod) { + switch (event->keysym.sym) { +#if SDL_VERSION_ATLEAST(2, 0, 0) + case SDLK_f: + SDL_SetWindowFullscreen(sdlContext->window, sdlContext->fullscreen ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP); + sdlContext->fullscreen = !sdlContext->fullscreen; + sdlContext->windowUpdated = 1; + break; +#endif + case SDLK_p: + mCoreThreadTogglePause(context); + break; + case SDLK_n: + // TODO: Put back frame advance + break; + case SDLK_r: + mCoreThreadReset(context); + break; + default: + break; + } + } + if (event->keysym.mod & KMOD_SHIFT) { + switch (event->keysym.sym) { + case SDLK_F1: + case SDLK_F2: + case SDLK_F3: + case SDLK_F4: + case SDLK_F5: + case SDLK_F6: + case SDLK_F7: + case SDLK_F8: + case SDLK_F9: + mCoreThreadInterrupt(context); + mCoreSaveState(context->core, event->keysym.sym - SDLK_F1 + 1, SAVESTATE_SCREENSHOT); + mCoreThreadContinue(context); + break; + default: + break; + } + } else { + switch (event->keysym.sym) { + case SDLK_F1: + case SDLK_F2: + case SDLK_F3: + case SDLK_F4: + case SDLK_F5: + case SDLK_F6: + case SDLK_F7: + case SDLK_F8: + case SDLK_F9: + mCoreThreadInterrupt(context); + mCoreLoadState(context->core, event->keysym.sym - SDLK_F1 + 1, SAVESTATE_SCREENSHOT); + mCoreThreadContinue(context); + break; + default: + break; + } + } + return; + } + } } static void _mSDLHandleJoyButton(struct mCore* core, struct mSDLPlayer* sdlContext, const struct SDL_JoyButtonEvent* event) {