diff --git a/src/gba/gui/gui-runner.c b/src/gba/gui/gui-runner.c index 30adecb89..7d4f7eb17 100644 --- a/src/gba/gui/gui-runner.c +++ b/src/gba/gui/gui-runner.c @@ -15,6 +15,10 @@ #include "util/png-io.h" #include "util/vfs.h" +#ifdef _3DS +#include <3ds.h> +#endif + #include #define FPS_GRANULARITY 120 @@ -237,6 +241,12 @@ void GBAGUIRun(struct GBAGUIRunner* runner, const char* path) { runner->lastFpsCheck = 1000000LL * tv.tv_sec + tv.tv_usec; while (true) { +#ifdef _3DS + running = aptMainLoop(); + if (!running) { + break; + } +#endif uint32_t guiKeys; GUIPollInput(&runner->params, &guiKeys, 0); if (guiKeys & (1 << GUI_INPUT_CANCEL)) { diff --git a/src/platform/3ds/main.c b/src/platform/3ds/main.c index 1aed46f87..fe1b74b3c 100644 --- a/src/platform/3ds/main.c +++ b/src/platform/3ds/main.c @@ -54,6 +54,8 @@ static struct ctrTexture gbaOutputTexture; static int guiDrawn; static int screenCleanup; +static aptHookCookie cookie; + enum { GUI_ACTIVE = 1, GUI_THIS_FRAME = 2, @@ -70,6 +72,48 @@ enum { extern bool allocateRomBuffer(void); +static void _cleanup(void) { + if (renderer.outputBuffer) { + linearFree(renderer.outputBuffer); + } + + if (gbaOutputTexture.data) { + ctrDeinitGpu(); + vramFree(gbaOutputTexture.data); + } + + gfxExit(); + + if (hasSound) { + linearFree(audioLeft); + linearFree(audioRight); + } + + csndExit(); + ptmuExit(); +} + +static void _aptHook(APT_HookType hook, void* user) { + UNUSED(user); + switch (hook) { + case APTHOOK_ONSUSPEND: + case APTHOOK_ONSLEEP: + CSND_SetPlayState(8, 0); + CSND_SetPlayState(9, 0); + csndExecCmds(false); + break; + case APTHOOK_ONEXIT: + CSND_SetPlayState(8, 0); + CSND_SetPlayState(9, 0); + csndExecCmds(false); + _cleanup(); + exit(0); + break; + default: + break; + } +} + static void _map3DSKey(struct GBAInputMap* map, int ctrKey, enum GBAKey key) { GBAInputBindKey(map, _3DS_INPUT, __builtin_ctz(ctrKey), key); } @@ -480,6 +524,8 @@ int main() { return 1; } + aptHook(&cookie, _aptHook, 0); + ptmuInit(); hasSound = !csndInit(); @@ -492,7 +538,8 @@ int main() { if (ctrInitGpu() < 0) { gbaOutputTexture.data = 0; - goto cleanup; + _cleanup(); + return 1; } ctrTexture_Init(&gbaOutputTexture); @@ -504,7 +551,8 @@ int main() { void* outputTextureEnd = (u8*)gbaOutputTexture.data + 256 * 256 * 2; if (!gbaOutputTexture.data) { - goto cleanup; + _cleanup(); + return 1; } // Zero texture data to make sure no garbage around the border interferes with filtering @@ -523,7 +571,8 @@ int main() { struct GUIFont* font = GUIFontCreate(); if (!font) { - goto cleanup; + _cleanup(); + return 1; } struct GBAGUIRunner runner = { @@ -610,24 +659,6 @@ int main() { GBAGUIRunloop(&runner); GBAGUIDeinit(&runner); -cleanup: - if (renderer.outputBuffer) { - linearFree(renderer.outputBuffer); - } - - if (gbaOutputTexture.data) { - ctrDeinitGpu(); - vramFree(gbaOutputTexture.data); - } - - gfxExit(); - - if (hasSound) { - linearFree(audioLeft); - linearFree(audioRight); - } - - csndExit(); - ptmuExit(); + _cleanup(); return 0; } diff --git a/src/util/gui/menu.c b/src/util/gui/menu.c index b65d76052..283468542 100644 --- a/src/util/gui/menu.c +++ b/src/util/gui/menu.c @@ -8,6 +8,10 @@ #include "util/gui.h" #include "util/gui/font.h" +#ifdef _3DS +#include <3ds.h> +#endif + DEFINE_VECTOR(GUIMenuItemList, struct GUIMenuItem); enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* menu, struct GUIMenuItem** item) { @@ -23,6 +27,11 @@ enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* men GUIInvalidateKeys(params); while (true) { +#ifdef _3DS + if (!aptMainLoop()) { + return GUI_MENU_EXIT_CANCEL; + } +#endif uint32_t newInput = 0; GUIPollInput(params, &newInput, 0); unsigned cx, cy;