Merge remote-tracking branch 'upstream/master' into load_rom

This commit is contained in:
wheremyfoodat 2023-07-27 12:31:41 +03:00
commit b39e32fce0
4 changed files with 64 additions and 5 deletions

View file

@ -56,7 +56,8 @@ class Emulator {
static constexpr u32 width = 400; static constexpr u32 width = 400;
static constexpr u32 height = 240 * 2; // * 2 because 2 screens static constexpr u32 height = 240 * 2; // * 2 because 2 screens
ROMType romType = ROMType::None; 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 #ifdef PANDA3DS_ENABLE_HTTP_SERVER
HttpServer httpServer; HttpServer httpServer;
@ -86,6 +87,10 @@ class Emulator {
void run(); void run();
void runFrame(); void runFrame();
void resume(); // Resume the emulator
void pause(); // Pause the emulator
void togglePause();
bool loadROM(const std::filesystem::path& path); bool loadROM(const std::filesystem::path& path);
bool loadNCSD(const std::filesystem::path& path, ROMType type); bool loadNCSD(const std::filesystem::path& path, ROMType type);
bool loadELF(const std::filesystem::path& path); bool loadELF(const std::filesystem::path& path);

View file

@ -13,7 +13,7 @@
#include "helpers.hpp" #include "helpers.hpp"
enum class HttpActionType { None, Screenshot, Key, LoadRom }; enum class HttpActionType { None, Screenshot, Key, TogglePause, Reset, LoadRom };
class Emulator; class Emulator;
namespace httplib { namespace httplib {
@ -44,6 +44,8 @@ class HttpAction {
static std::unique_ptr<HttpAction> createScreenshotAction(DeferredResponseWrapper& response); static std::unique_ptr<HttpAction> createScreenshotAction(DeferredResponseWrapper& response);
static std::unique_ptr<HttpAction> createKeyAction(uint32_t key, bool state); static std::unique_ptr<HttpAction> createKeyAction(uint32_t key, bool state);
static std::unique_ptr<HttpAction> createLoadRomAction(std::filesystem::path path, bool paused); static std::unique_ptr<HttpAction> createLoadRomAction(std::filesystem::path path, bool paused);
static std::unique_ptr<HttpAction> createTogglePauseAction();
static std::unique_ptr<HttpAction> createResetAction();
}; };
struct HttpServer { struct HttpServer {

View file

@ -75,6 +75,8 @@ Emulator::Emulator()
} }
} }
running = false;
programRunning = false;
reset(ReloadOption::NoReload); reset(ReloadOption::NoReload);
} }
@ -113,7 +115,9 @@ void Emulator::step() {}
void Emulator::render() {} void Emulator::render() {}
void Emulator::run() { void Emulator::run() {
while (running) { programRunning = true;
while (programRunning) {
#ifdef PANDA3DS_ENABLE_HTTP_SERVER #ifdef PANDA3DS_ENABLE_HTTP_SERVER
httpServer.processActions(); httpServer.processActions();
#endif #endif
@ -127,7 +131,7 @@ void Emulator::run() {
switch (event.type) { switch (event.type) {
case SDL_QUIT: case SDL_QUIT:
printf("Bye :(\n"); printf("Bye :(\n");
running = false; programRunning = false;
return; return;
case SDL_KEYDOWN: case SDL_KEYDOWN:
@ -169,6 +173,19 @@ void Emulator::run() {
case SDLK_RETURN: hid.pressKey(Keys::Start); break; case SDLK_RETURN: hid.pressKey(Keys::Start); break;
case SDLK_BACKSPACE: hid.pressKey(Keys::Select); break; case SDLK_BACKSPACE: hid.pressKey(Keys::Select); break;
// 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: {
togglePause();
break;
}
// Use F5 as a reset button
case SDLK_F5: {
reset(ReloadOption::Reload);
break;
}
} }
break; break;
@ -346,8 +363,13 @@ 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() { void Emulator::runFrame() {
if (romType != ROMType::None) { if (running) {
cpu.runFrame(); // Run 1 frame of instructions cpu.runFrame(); // Run 1 frame of instructions
gpu.display(); // Display graphics gpu.display(); // Display graphics
@ -360,6 +382,10 @@ void Emulator::runFrame() {
if (cheats.haveCheats()) [[unlikely]] { if (cheats.haveCheats()) [[unlikely]] {
cheats.run(); 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();
} }
} }
@ -408,6 +434,7 @@ bool Emulator::loadROM(const std::filesystem::path& path) {
romType = ROMType::None; romType = ROMType::None;
} }
resume(); // Start the emulator
return success; return success;
} }

View file

@ -20,6 +20,16 @@ class HttpActionScreenshot : public HttpAction {
DeferredResponseWrapper& getResponse() { return response; } 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 { class HttpActionKey : public HttpAction {
u32 key; u32 key;
bool state; bool state;
@ -47,6 +57,8 @@ std::unique_ptr<HttpAction> HttpAction::createScreenshotAction(DeferredResponseW
} }
std::unique_ptr<HttpAction> HttpAction::createKeyAction(u32 key, bool state) { return std::make_unique<HttpActionKey>(key, state); } std::unique_ptr<HttpAction> HttpAction::createKeyAction(u32 key, bool state) { return std::make_unique<HttpActionKey>(key, state); }
std::unique_ptr<HttpAction> HttpAction::createTogglePauseAction() { return std::make_unique<HttpActionTogglePause>(); }
std::unique_ptr<HttpAction> HttpAction::createResetAction() { return std::make_unique<HttpActionReset>(); }
std::unique_ptr<HttpAction> HttpAction::createLoadRomAction(std::filesystem::path path, bool paused) { std::unique_ptr<HttpAction> HttpAction::createLoadRomAction(std::filesystem::path path, bool paused) {
return std::make_unique<HttpActionLoadRom>(path, paused); return std::make_unique<HttpActionLoadRom>(path, paused);
@ -154,6 +166,16 @@ void HttpServer::startHttpServer() {
} }
pushAction(HttpAction::createLoadRomAction(romPath, paused)); pushAction(HttpAction::createLoadRomAction(romPath, paused));
response.set_content("ok", "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"); response.set_content("ok", "text/plain");
}); });
@ -219,6 +241,9 @@ void HttpServer::processActions() {
break; break;
} }
case HttpActionType::TogglePause: emulator->togglePause(); break;
case HttpActionType::Reset: emulator->reset(Emulator::ReloadOption::Reload); break;
default: break; default: break;
} }
} }