diff --git a/include/config.hpp b/include/config.hpp index bdb697bf..adbddd32 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -1,9 +1,12 @@ #pragma once #include +#include "renderer.hpp" + // Remember to initialize every field here to its default value otherwise bad things will happen struct EmulatorConfig { bool shaderJitEnabled = false; + RendererType rendererType = RendererType::OpenGL; void load(const std::filesystem::path& path); void save(const std::filesystem::path& path); diff --git a/include/emulator.hpp b/include/emulator.hpp index f27cd990..5df986dc 100644 --- a/include/emulator.hpp +++ b/include/emulator.hpp @@ -70,8 +70,8 @@ class Emulator { public: // Decides whether to reload or not reload the ROM when resetting. We use enum class over a plain bool for clarity. // If NoReload is selected, the emulator will not reload its selected ROM. This is useful for things like booting up the emulator, or resetting to - // change ROMs. If Reload is selected, the emulator will reload its selected ROM. This is useful for eg a "reset" button that keeps the current ROM - // and just resets the emu + // change ROMs. If Reload is selected, the emulator will reload its selected ROM. This is useful for eg a "reset" button that keeps the current + // ROM and just resets the emu enum class ReloadOption { NoReload, Reload }; Emulator(); diff --git a/include/renderer.hpp b/include/renderer.hpp index 5a2b40b4..50ed1a32 100644 --- a/include/renderer.hpp +++ b/include/renderer.hpp @@ -6,6 +6,12 @@ #include "PICA/regs.hpp" #include "helpers.hpp" +enum class RendererType : s8 { + // Todo: Auto = -1, + Null = 0, + OpenGL = 1, +}; + class GPU; class Renderer { diff --git a/src/config.cpp b/src/config.cpp index 6c9a8450..7df73dbd 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -31,6 +31,7 @@ void EmulatorConfig::load(const std::filesystem::path& path) { if (gpuResult.is_ok()) { auto gpu = gpuResult.unwrap(); + rendererType = RendererType(toml::find_or(gpu, "Renderer", int64_t(rendererType))); shaderJitEnabled = toml::find_or(gpu, "EnableShaderJIT", false); } } @@ -54,6 +55,7 @@ void EmulatorConfig::save(const std::filesystem::path& path) { printf("Saving new configuration file %s\n", path.string().c_str()); } + data["GPU"]["Renderer"] = static_cast(rendererType); data["GPU"]["EnableShaderJIT"] = shaderJitEnabled; std::ofstream file(path, std::ios::out); diff --git a/src/core/PICA/gpu.cpp b/src/core/PICA/gpu.cpp index 15c99c42..487a8743 100644 --- a/src/core/PICA/gpu.cpp +++ b/src/core/PICA/gpu.cpp @@ -7,7 +7,7 @@ #include "PICA/float_types.hpp" #include "PICA/regs.hpp" - +#include "renderer_null/renderer_null.hpp" #ifdef PANDA3DS_ENABLE_OPENGL #include "renderer_gl/renderer_gl.hpp" #endif @@ -20,10 +20,22 @@ GPU::GPU(Memory& mem, EmulatorConfig& config) : mem(mem), config(config) { vram = new u8[vramSize]; mem.setVRAM(vram); // Give the bus a pointer to our VRAM - // TODO: Configurable backend + switch (config.rendererType) { + case RendererType::Null: { + renderer.reset(new RendererNull(*this, regs)); + break; + } #ifdef PANDA3DS_ENABLE_OPENGL - renderer.reset(new RendererGL(*this, regs)); + case RendererType::OpenGL: { + renderer.reset(new RendererGL(*this, regs)); + break; + } #endif + default: { + Helpers::panic("Invalid rendering backend index: %d", static_cast(config.rendererType)); + break; + } + } } void GPU::reset() { diff --git a/src/emulator.cpp b/src/emulator.cpp index 23baa258..07ce61b5 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -26,24 +26,26 @@ Emulator::Emulator() : kernel(cpu, memory, gpu), cpu(memory, kernel), gpu(memory } #ifdef PANDA3DS_ENABLE_OPENGL - // Request OpenGL 4.1 Core (Max available on MacOS) - // MacOS gets mad if we don't explicitly demand a core profile - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); - window = SDL_CreateWindow("Alber", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL); + if (config.rendererType == RendererType::OpenGL) { + // Request OpenGL 4.1 Core (Max available on MacOS) + // MacOS gets mad if we don't explicitly demand a core profile + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); + window = SDL_CreateWindow("Alber", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL); - if (window == nullptr) { - Helpers::panic("Window creation failed: %s", SDL_GetError()); - } + if (window == nullptr) { + Helpers::panic("Window creation failed: %s", SDL_GetError()); + } - glContext = SDL_GL_CreateContext(window); - if (glContext == nullptr) { - Helpers::panic("OpenGL context creation failed: %s", SDL_GetError()); - } + glContext = SDL_GL_CreateContext(window); + if (glContext == nullptr) { + Helpers::panic("OpenGL context creation failed: %s", SDL_GetError()); + } - if (!gladLoadGL(reinterpret_cast(SDL_GL_GetProcAddress))) { - Helpers::panic("OpenGL init failed: %s", SDL_GetError()); + if (!gladLoadGL(reinterpret_cast(SDL_GL_GetProcAddress))) { + Helpers::panic("OpenGL init failed: %s", SDL_GetError()); + } } #endif @@ -56,7 +58,6 @@ Emulator::Emulator() : kernel(cpu, memory, gpu), cpu(memory, kernel), gpu(memory } } - config.load(std::filesystem::current_path() / "config.toml"); reset(ReloadOption::NoReload); } diff --git a/src/main.cpp b/src/main.cpp index 1559565a..66a04b9e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,9 +1,9 @@ #include "emulator.hpp" -int main (int argc, char *argv[]) { - Emulator emu; +int main(int argc, char *argv[]) { + Emulator emu; - emu.initGraphicsContext(); + emu.initGraphicsContext(); if (argc > 1) { auto romPath = std::filesystem::current_path() / argv[1];