From 1aeddbfc9ff643c147224940c3e258743221a730 Mon Sep 17 00:00:00 2001 From: CocoSimone Date: Tue, 6 Dec 2022 20:51:37 +0100 Subject: [PATCH] Don't use virtual class for different type of cpu core --- external/parallel-rdp/CMakeLists.txt | 2 +- src/CMakeLists.txt | 2 +- src/frontend/imgui/Window.cpp | 35 ++++++++++++++++++++++++---- src/frontend/imgui/Window.hpp | 8 ++++++- src/n64/Core.cpp | 21 ++++++++--------- src/n64/Core.hpp | 30 +++++++++++++++++++++++- src/n64/core/BaseCpu.hpp | 12 ---------- src/n64/core/Dynarec.hpp | 10 ++++---- src/n64/core/Interpreter.hpp | 8 +++---- 9 files changed, 89 insertions(+), 39 deletions(-) delete mode 100644 src/n64/core/BaseCpu.hpp diff --git a/external/parallel-rdp/CMakeLists.txt b/external/parallel-rdp/CMakeLists.txt index b46ed969..6599fb44 100644 --- a/external/parallel-rdp/CMakeLists.txt +++ b/external/parallel-rdp/CMakeLists.txt @@ -63,7 +63,7 @@ target_include_directories(parallel-rdp PUBLIC ../../src/n64/core/ ../../src/n64/core/mmio ../../src/n64/core/interpreter/ - ../../src/n64/core/interpreter/registers + ../../src/n64/core/registers parallel-rdp-standalone .. ../capstone/include diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 855a9677..249d6950 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -32,7 +32,7 @@ target_include_directories(gadolinium PRIVATE n64 n64/core n64/core/interpreter/ - n64/core/interpreter/registers + n64/core/registers n64/core/mmio n64/core/rsp frontend diff --git a/src/frontend/imgui/Window.cpp b/src/frontend/imgui/Window.cpp index 4d549f8b..3cb9eac0 100644 --- a/src/frontend/imgui/Window.cpp +++ b/src/frontend/imgui/Window.cpp @@ -2,17 +2,16 @@ #include #include #include -#include #include #include VkInstance instance{}; -using json = nlohmann::json; Window::Window(n64::Core& core) { InitSDL(); + LoadSettings(core); InitParallelRDP(core.mem.GetRDRAM(), window); - InitImgui(core); + InitImgui(); NFD::Init(); } @@ -21,6 +20,34 @@ Window::Window(n64::Core& core) { && event.window.windowID == SDL_GetWindowID(window); } +void Window::LoadSettings(n64::Core &core) { + settingsFile.open("settings.json", std::fstream::in | std::fstream::out); + if(settingsFile.is_open()) { + settings = json::parse(settingsFile); + auto entryCpuType = settings["cpu_type"]; + if(!entryCpuType.empty()) { + auto cpuType = entryCpuType.get(); + if(cpuType == "dynarec") { + core.cpuType = n64::CpuType::Dynarec; + } else if(cpuType == "interpreter") { + core.cpuType = n64::CpuType::Interpreter; + } else { + util::panic("Unrecognized cpu type: {}\n", cpuType); + } + } else { + settings["cpu_type"] = "dynarec"; + settingsFile << settings; + core.cpuType = n64::CpuType::Dynarec; + } + } else { + settings["cpu_type"] = "dynarec"; + settingsFile << settings; + core.cpuType = n64::CpuType::Dynarec; + } + + settingsFile.close(); +} + void Window::InitSDL() { SDL_Init(SDL_INIT_EVERYTHING); n64::InitAudio(); @@ -47,7 +74,7 @@ static void check_vk_result(VkResult err) { } } -void Window::InitImgui(const n64::Core& core) { +void Window::InitImgui() { VkResult err; IMGUI_CHECKVERSION(); diff --git a/src/frontend/imgui/Window.hpp b/src/frontend/imgui/Window.hpp index 5378dac9..5a353f3a 100644 --- a/src/frontend/imgui/Window.hpp +++ b/src/frontend/imgui/Window.hpp @@ -6,6 +6,9 @@ #include #include #include +#include + +using namespace nlohmann; struct Window { explicit Window(n64::Core& core); @@ -18,13 +21,16 @@ struct Window { float volumeL = 0.1, volumeR = 0.1; void LoadROM(n64::Core& core, const std::string& path); private: + json settings; + std::fstream settingsFile; bool lockVolume = true; SDL_Window* window{}; std::string windowTitle; std::string shadowWindowTitle; void InitSDL(); - void InitImgui(const n64::Core& core); + void InitImgui(); void Render(n64::Core& core); + void LoadSettings(n64::Core&); VkPhysicalDevice physicalDevice{}; VkDevice device{}; diff --git a/src/n64/Core.cpp b/src/n64/Core.cpp index 8d243065..4ba393fc 100644 --- a/src/n64/Core.cpp +++ b/src/n64/Core.cpp @@ -7,12 +7,11 @@ namespace n64 { Core::Core() { - cpu = std::make_unique(); Stop(); } void Core::Stop() { - cpu->Reset(); + CpuReset(); mem.Reset(); pause = true; romLoaded = false; @@ -20,13 +19,13 @@ void Core::Stop() { CartInfo Core::LoadROM(const std::string& rom_) { rom = rom_; - cpu->Reset(); + CpuReset(); mem.Reset(); pause = false; romLoaded = true; CartInfo cartInfo = mem.LoadROM(rom); - DoPIFHLE(mem, cpu->regs, cartInfo); + DoPIFHLE(mem, CpuGetRegs(), cartInfo); return cartInfo; } @@ -42,11 +41,11 @@ void Core::Run(Window& window, float volumeL, float volumeR) { mmio.vi.current = (i << 1) + field; if ((mmio.vi.current & 0x3FE) == mmio.vi.intr) { - InterruptRaise(mmio.mi, cpu->regs, Interrupt::VI); + InterruptRaise(mmio.mi, CpuGetRegs(), Interrupt::VI); } for(;cycles <= mmio.vi.cyclesPerHalfline; cycles++, frameCycles++) { - cpu->Step(mem); + CpuStep(mem); cpuSteps++; if(mmio.rsp.spStatus.halt) { mmio.rsp.steps = 0; @@ -59,25 +58,25 @@ void Core::Run(Window& window, float volumeL, float volumeR) { while(mmio.rsp.steps > 0) { mmio.rsp.steps--; - mmio.rsp.Step(cpu->regs, mem); + mmio.rsp.Step(CpuGetRegs(), mem); } } - mmio.ai.Step(mem, cpu->regs, 1, volumeL, volumeR); - scheduler.tick(1, mem, cpu->regs); + mmio.ai.Step(mem, CpuGetRegs(), 1, volumeL, volumeR); + scheduler.tick(1, mem, CpuGetRegs()); } cycles -= mmio.vi.cyclesPerHalfline; } if ((mmio.vi.current & 0x3FE) == mmio.vi.intr) { - InterruptRaise(mmio.mi, cpu->regs, Interrupt::VI); + InterruptRaise(mmio.mi, CpuGetRegs(), Interrupt::VI); } UpdateScreenParallelRdp(*this, window, GetVI()); int missedCycles = N64_CYCLES_PER_FRAME - frameCycles; - mmio.ai.Step(mem, cpu->regs, missedCycles, volumeL, volumeR); + mmio.ai.Step(mem, CpuGetRegs(), missedCycles, volumeL, volumeR); } else if(pause && romLoaded) { UpdateScreenParallelRdp(*this, window, GetVI()); } else if(pause && !romLoaded) { diff --git a/src/n64/Core.hpp b/src/n64/Core.hpp index 390112f8..a8f9d6ae 100644 --- a/src/n64/Core.hpp +++ b/src/n64/Core.hpp @@ -3,10 +3,15 @@ #include #include #include +#include struct Window; namespace n64 { +enum class CpuType { + Dynarec, Interpreter +}; + struct Core { ~Core() { Stop(); } Core(); @@ -17,6 +22,27 @@ struct Core { void TogglePause() { pause = !pause; } VI& GetVI() { return mem.mmio.vi; } + void CpuReset() { + switch(cpuType) { + case CpuType::Dynarec: cpuDynarec.Reset(); break; + case CpuType::Interpreter: cpuInterp.Reset(); break; + } + } + + void CpuStep(Mem& mem) { + switch(cpuType) { + case CpuType::Dynarec: cpuDynarec.Step(mem); break; + case CpuType::Interpreter: cpuInterp.Step(mem); break; + } + } + + Registers& CpuGetRegs() { + switch(cpuType) { + case CpuType::Dynarec: return cpuDynarec.regs; + case CpuType::Interpreter: return cpuInterp.regs; + } + } + u32 breakpoint = 0; int cycles = 0; @@ -27,6 +53,8 @@ struct Core { bool done = false; std::string rom; Mem mem; - std::unique_ptr cpu; + CpuType cpuType = CpuType::Dynarec; + Interpreter cpuInterp; + Dynarec cpuDynarec; }; } diff --git a/src/n64/core/BaseCpu.hpp b/src/n64/core/BaseCpu.hpp deleted file mode 100644 index 2d7f38f5..00000000 --- a/src/n64/core/BaseCpu.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#pragma -#include - -namespace n64 { -struct BaseCpu { - virtual ~BaseCpu() {} - - Registers regs; - virtual void Step(Mem& mem) {} - virtual void Reset() {} -}; -} \ No newline at end of file diff --git a/src/n64/core/Dynarec.hpp b/src/n64/core/Dynarec.hpp index 64fca4f9..8ff9a2d5 100644 --- a/src/n64/core/Dynarec.hpp +++ b/src/n64/core/Dynarec.hpp @@ -1,11 +1,13 @@ #pragma once -#include #include +#include +#include namespace n64 { -struct Dynarec : BaseCpu { - void Step(Mem& mem) override; - void Reset() override; +struct Dynarec { + void Step(Mem& mem); + void Reset(); + Registers regs; private: Xbyak::CodeGenerator code; }; diff --git a/src/n64/core/Interpreter.hpp b/src/n64/core/Interpreter.hpp index c7be06c5..9b74c7f0 100644 --- a/src/n64/core/Interpreter.hpp +++ b/src/n64/core/Interpreter.hpp @@ -1,12 +1,11 @@ #pragma once -#include #include #include #include #include namespace n64 { -struct Interpreter : BaseCpu { +struct Interpreter { Interpreter() { if(cs_open(CS_ARCH_MIPS, CS_MODE_MIPS64, &handle) != CS_ERR_OK) { util::panic("Could not initialize capstone!\n"); @@ -17,8 +16,9 @@ struct Interpreter : BaseCpu { ~Interpreter() { cs_close(&handle); } - void Reset() override; - void Step(Mem&) override; + void Reset(); + void Step(Mem&); + Registers regs; private: csh handle;