From 4a12e59c2f9cf64df27ed3678b7a9ed39bf9adb2 Mon Sep 17 00:00:00 2001 From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> Date: Fri, 7 Jul 2023 13:39:35 +0300 Subject: [PATCH] Slightly more robust ROM management --- include/emulator.hpp | 5 ++++- src/emulator.cpp | 30 ++++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/include/emulator.hpp b/include/emulator.hpp index 73929f26..309b5db6 100644 --- a/include/emulator.hpp +++ b/include/emulator.hpp @@ -5,6 +5,7 @@ #include #include +#include #include "PICA/gpu.hpp" #include "cpu.hpp" @@ -25,7 +26,7 @@ class Emulator { GLStateManager gl; SDL_Window* window; SDL_GLContext glContext; - SDL_GameController* gameController; + SDL_GameController* gameController = nullptr; int gameControllerID; // Variables to keep track of whether the user is controlling the 3DS analog stick with their keyboard @@ -44,6 +45,8 @@ class Emulator { std::ifstream loadedELF; NCSD loadedNCSD; + std::optional romPath = std::nullopt; + public: Emulator(); diff --git a/src/emulator.cpp b/src/emulator.cpp index 45ff0b7c..24dfc0b5 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -63,8 +63,16 @@ void Emulator::reset() { // Reloading r13 and r15 needs to happen after everything has been reset // Otherwise resetting the kernel or cpu might nuke them cpu.setReg(13, VirtualAddrs::StackTop); // Set initial SP - if (romType == ROMType::ELF) { // Reload ELF if we're using one - loadELF(loadedELF); + + // If a ROM is active and we reset, reload it. This is necessary to set up stack, executable memory, .data/.rodata/.bss all over again + if (romType != ROMType::None && romPath.has_value()) { + bool success = loadROM(romPath.value()); + if (!success) { + romType = ROMType::None; + romPath = std::nullopt; + + Helpers::panic("Failed to reload ROM. This should pause the emulator in the future GUI"); + } } } @@ -284,17 +292,27 @@ bool Emulator::loadROM(const std::filesystem::path& path) { kernel.initializeFS(); auto extension = path.extension(); + bool success; // Tracks if we loaded the ROM successfully if (extension == ".elf" || extension == ".axf") - return loadELF(path); + success = loadELF(path); else if (extension == ".3ds") - return loadNCSD(path, ROMType::NCSD); + success = loadNCSD(path, ROMType::NCSD); else if (extension == ".cxi" || extension == ".app") - return loadNCSD(path, ROMType::CXI); + success = loadNCSD(path, ROMType::CXI); else { printf("Unknown file type\n"); - return false; + success = false; } + + if (success) { + romPath = path; + } else { + romPath = std::nullopt; + romType = ROMType::None; + } + + return success; } // Used for loading both CXI and NCSD files since they are both so similar and use the same interface