From 1107dff9fa64f9ecf830709e3910b24e3640386c Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Wed, 26 Jul 2023 19:29:34 +0300 Subject: [PATCH 1/5] Implement pause/resume --- include/emulator.hpp | 6 +++++- src/emulator.cpp | 15 ++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/include/emulator.hpp b/include/emulator.hpp index d738aef3..b6662331 100644 --- a/include/emulator.hpp +++ b/include/emulator.hpp @@ -59,7 +59,8 @@ class Emulator { static constexpr u32 width = 400; static constexpr u32 height = 240 * 2; // * 2 because 2 screens ROMType romType = ROMType::None; - bool running = true; + bool running = false; // Is the emulator running a game? + bool programRunning = false; // Is the emulator program itself running? #ifdef PANDA3DS_ENABLE_HTTP_SERVER HttpServer httpServer; @@ -89,6 +90,9 @@ class Emulator { void run(); void runFrame(); + void resume(); // Resume the emulator + void pause(); // Pause the emulator + bool loadROM(const std::filesystem::path& path); bool loadNCSD(const std::filesystem::path& path, ROMType type); bool loadELF(const std::filesystem::path& path); diff --git a/src/emulator.cpp b/src/emulator.cpp index bcca5ffa..e04f073d 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -75,6 +75,8 @@ Emulator::Emulator() } } + running = false; + programRunning = false; reset(ReloadOption::NoReload); } @@ -114,7 +116,9 @@ void Emulator::step() {} void Emulator::render() {} void Emulator::run() { - while (running) { + programRunning = true; + + while (programRunning) { runFrame(); HIDService& hid = kernel.getServiceManager().getHID(); @@ -125,7 +129,7 @@ void Emulator::run() { switch (event.type) { case SDL_QUIT: printf("Bye :(\n"); - running = false; + programRunning = false; return; case SDL_KEYDOWN: @@ -344,8 +348,12 @@ void Emulator::run() { } } +// Only resume if a ROM is properly loaded +void Emulator::resume() { running = (romType != ROMType::None); } +void Emulator::pause() { running = false; } + void Emulator::runFrame() { - if (romType != ROMType::None) { + if (running) { #ifdef PANDA3DS_ENABLE_HTTP_SERVER httpServer.processActions(); #endif @@ -408,6 +416,7 @@ bool Emulator::loadROM(const std::filesystem::path& path) { romType = ROMType::None; } + resume(); // Start the emulator return success; } From 6daa419fd6fe847531b816dfd9d7bc0b51e84443 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Wed, 26 Jul 2023 19:33:06 +0300 Subject: [PATCH 2/5] Map toggle running function to hotkey --- src/emulator.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/emulator.cpp b/src/emulator.cpp index e04f073d..c5ea26d1 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -171,6 +171,12 @@ void Emulator::run() { case SDLK_RETURN: hid.pressKey(Keys::Start); break; case SDLK_BACKSPACE: hid.pressKey(Keys::Select); break; + + // Use the play button as a hot-key to pause or resume the emulator + case SDLK_AUDIOPLAY: { + running ? pause() : resume(); + break; + } } break; From f434787b6895e7a5f58c68c03ee1504789c34dd4 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Wed, 26 Jul 2023 19:38:51 +0300 Subject: [PATCH 3/5] Fix double buffering bug --- src/emulator.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/emulator.cpp b/src/emulator.cpp index c5ea26d1..e24d617f 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -363,8 +363,8 @@ void Emulator::runFrame() { #ifdef PANDA3DS_ENABLE_HTTP_SERVER httpServer.processActions(); #endif - cpu.runFrame(); // Run 1 frame of instructions - gpu.display(); // Display graphics + cpu.runFrame(); // Run 1 frame of instructions + gpu.display(); // Display graphics // Send VBlank interrupts ServiceManager& srv = kernel.getServiceManager(); @@ -374,6 +374,10 @@ void Emulator::runFrame() { if (haveCheats) [[unlikely]] { cheats.run(); } + } else if (romType != ROMType::None) { + // If the emulator is not running and a game is loaded, we still want to display the framebuffer otherwise we will get weird + // double-buffering issues + gpu.display(); } } From 8fb3096331f96fc8080b1ced6866a5bcb2077e84 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Wed, 26 Jul 2023 19:50:49 +0300 Subject: [PATCH 4/5] Fix hotkeys --- src/emulator.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/emulator.cpp b/src/emulator.cpp index e24d617f..c88e1249 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -172,11 +172,18 @@ void Emulator::run() { case SDLK_RETURN: hid.pressKey(Keys::Start); break; case SDLK_BACKSPACE: hid.pressKey(Keys::Select); break; - // Use the play button as a hot-key to pause or resume the emulator - case SDLK_AUDIOPLAY: { + // Use the F4 button as a hot-key to pause or resume the emulator + // We can't use the audio play/pause buttons because it's annoying + case SDLK_F4: { running ? pause() : resume(); break; } + + // Use F5 as a reset button + case SDLK_F5: { + reset(ReloadOption::Reload); + break; + } } break; From fa6ce2a7f2be80e63f2138818f3491a6850ffaff Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Wed, 26 Jul 2023 20:12:36 +0300 Subject: [PATCH 5/5] Add new HTTP(anda) commands --- include/emulator.hpp | 1 + include/httpserver.hpp | 4 +++- src/emulator.cpp | 3 ++- src/httpserver.cpp | 25 +++++++++++++++++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/include/emulator.hpp b/include/emulator.hpp index b6662331..94f88ba7 100644 --- a/include/emulator.hpp +++ b/include/emulator.hpp @@ -92,6 +92,7 @@ class Emulator { void resume(); // Resume the emulator void pause(); // Pause the emulator + void togglePause(); bool loadROM(const std::filesystem::path& path); bool loadNCSD(const std::filesystem::path& path, ROMType type); diff --git a/include/httpserver.hpp b/include/httpserver.hpp index 9d3cb818..7c70be14 100644 --- a/include/httpserver.hpp +++ b/include/httpserver.hpp @@ -12,7 +12,7 @@ #include "helpers.hpp" -enum class HttpActionType { None, Screenshot, Key }; +enum class HttpActionType { None, Screenshot, Key, TogglePause, Reset }; class Emulator; namespace httplib { @@ -42,6 +42,8 @@ class HttpAction { static std::unique_ptr createScreenshotAction(DeferredResponseWrapper& response); static std::unique_ptr createKeyAction(uint32_t key, bool state); + static std::unique_ptr createTogglePauseAction(); + static std::unique_ptr createResetAction(); }; struct HttpServer { diff --git a/src/emulator.cpp b/src/emulator.cpp index c88e1249..cc9bb02f 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -175,7 +175,7 @@ void Emulator::run() { // Use the F4 button as a hot-key to pause or resume the emulator // We can't use the audio play/pause buttons because it's annoying case SDLK_F4: { - running ? pause() : resume(); + togglePause(); break; } @@ -364,6 +364,7 @@ void Emulator::run() { // Only resume if a ROM is properly loaded void Emulator::resume() { running = (romType != ROMType::None); } void Emulator::pause() { running = false; } +void Emulator::togglePause() { running ? pause() : resume(); } void Emulator::runFrame() { if (running) { diff --git a/src/httpserver.cpp b/src/httpserver.cpp index d8841807..d3dc7938 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -19,6 +19,16 @@ class HttpActionScreenshot : public HttpAction { DeferredResponseWrapper& getResponse() { return response; } }; +class HttpActionTogglePause : public HttpAction { + public: + HttpActionTogglePause() : HttpAction(HttpActionType::TogglePause) {} +}; + +class HttpActionReset : public HttpAction { + public: + HttpActionReset() : HttpAction(HttpActionType::Reset) {} +}; + class HttpActionKey : public HttpAction { u32 key; bool state; @@ -35,6 +45,8 @@ std::unique_ptr HttpAction::createScreenshotAction(DeferredResponseW } std::unique_ptr HttpAction::createKeyAction(u32 key, bool state) { return std::make_unique(key, state); } +std::unique_ptr HttpAction::createTogglePauseAction() { return std::make_unique(); } +std::unique_ptr HttpAction::createResetAction() { return std::make_unique(); } HttpServer::HttpServer(Emulator* emulator) : emulator(emulator), server(std::make_unique()), keyMap({ @@ -110,6 +122,16 @@ void HttpServer::startHttpServer() { server->Get("/status", [this](const httplib::Request&, httplib::Response& response) { response.set_content(status(), "text/plain"); }); + server->Get("/togglepause", [this](const httplib::Request&, httplib::Response& response) { + pushAction(HttpAction::createTogglePauseAction()); + response.set_content("ok", "text/plain"); + }); + + server->Get("/reset", [this](const httplib::Request&, httplib::Response& response) { + pushAction(HttpAction::createResetAction()); + response.set_content("ok", "text/plain"); + }); + // TODO: ability to specify host and port printf("Starting HTTP server on port 1234\n"); server->listen("localhost", 1234); @@ -165,6 +187,9 @@ void HttpServer::processActions() { break; } + case HttpActionType::TogglePause: emulator->togglePause(); break; + case HttpActionType::Reset: emulator->reset(Emulator::ReloadOption::Reload); break; + default: break; } }