From c32107484f9712432c6a359562e3f6f8c569e34f Mon Sep 17 00:00:00 2001 From: simonmicro Date: Fri, 5 Jan 2024 18:53:30 +0100 Subject: [PATCH] Added support for software rendering --- emulator/include/Emulator.hpp | 3 ++- emulator/src/Emulator.cpp | 5 +++-- emulator/src/main.cpp | 7 +++++-- emulator/src/tests/uiTests/UiTests_main.hpp | 2 +- emulator/src/tests/unitTests/fixtures/EmulatorFixture.hpp | 2 +- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/emulator/include/Emulator.hpp b/emulator/include/Emulator.hpp index b9c325910..145257bae 100644 --- a/emulator/include/Emulator.hpp +++ b/emulator/include/Emulator.hpp @@ -40,9 +40,10 @@ class OswEmulator { static OswEmulator* instance; // "Singleton" const bool isHeadless; + const bool isSoftwareRenderer; bool autoWakeUp = true; - OswEmulator(bool headless, std::string configPath = "config.json", std::string imguiPath = "imgui.ini"); + OswEmulator(bool softwareRenderer, bool headless, std::string configPath = "config.json", std::string imguiPath = "imgui.ini"); ~OswEmulator(); void run(); diff --git a/emulator/src/Emulator.cpp b/emulator/src/Emulator.cpp index 07f8a43fd..42522803b 100644 --- a/emulator/src/Emulator.cpp +++ b/emulator/src/Emulator.cpp @@ -35,7 +35,7 @@ static void shutdownEmulatorByInterruptSignal(int s) { called = true; } -OswEmulator::OswEmulator(bool headless, std::string configPath, std::string imguiPath): isHeadless(headless) { +OswEmulator::OswEmulator(bool softwareRenderer, bool headless, std::string configPath, std::string imguiPath): isHeadless(headless), isSoftwareRenderer(softwareRenderer) { // Initialize variables for(size_t i = 0; i < BTN_NUMBER; i++) this->buttonCheckboxes[i] = false; @@ -58,6 +58,7 @@ OswEmulator::OswEmulator(bool headless, std::string configPath, std::string imgu if(this->isHeadless) { this->mainSurface = SDL_CreateRGBSurface(0, width, height, 32, 0, 0, 0, 0); assert(this->mainSurface && "Never fail surface creation"); + assert(this->isSoftwareRenderer && "Software renderer is required in headless mode"); this->mainRenderer = SDL_CreateSoftwareRenderer(this->mainSurface); } else { // Init the SDL window and renderer @@ -70,7 +71,7 @@ OswEmulator::OswEmulator(bool headless, std::string configPath, std::string imgu SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI ); assert(this->mainWindow && "Never fail window creation"); - this->mainRenderer = SDL_CreateRenderer(this->mainWindow, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED); + this->mainRenderer = SDL_CreateRenderer(this->mainWindow, -1, this-isSoftwareRenderer ? SDL_RENDERER_SOFTWARE : (SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED)); } assert(this->mainRenderer && "Never fail renderer creation"); fakeDisplayInstance = std::make_unique(DISP_W, DISP_H, this->mainRenderer); diff --git a/emulator/src/main.cpp b/emulator/src/main.cpp index 97350284c..746a34eec 100644 --- a/emulator/src/main.cpp +++ b/emulator/src/main.cpp @@ -25,10 +25,13 @@ int main(int argc, char** argv) { const std::string argRunUnitTests = "unit_tests"; const std::string argListAllTests = "list_tests"; const std::string argUiTests = "ui_tests"; + const std::string argHeadless = "headless"; + const std::string argSoftwareRenderer = "software_renderer"; a.add(argRunUnitTests, '\0', "run the unit test framework"); a.add(argListAllTests, '\0', "list all unit and UI tests, one per line"); a.add(argUiTests, '\0', "run emulator with UI tests window"); - a.add("headless", '\0', "do not open a window; use software-rendering only"); // Warning: This parameter name is also used in the unit-tests! + a.add(argHeadless, '\0', "do not open a window; also implies --software_renderer"); // Warning: This parameter name is also used in the unit-tests! + a.add(argSoftwareRenderer, '\0', "use software-rendering only"); a.parse_check(argc, argv); // Initialize SDL @@ -60,7 +63,7 @@ int main(int argc, char** argv) { returnval = UiTests_main(); } else { // Create and run the emulator - std::unique_ptr oswEmu = std::make_unique(a.exist("headless")); + std::unique_ptr oswEmu = std::make_unique(a.exist(argSoftwareRenderer) or a.exist(argHeadless), a.exist(argHeadless)); OswEmulator::instance = oswEmu.get(); oswEmu->run(); OswEmulator::instance = nullptr; diff --git a/emulator/src/tests/uiTests/UiTests_main.hpp b/emulator/src/tests/uiTests/UiTests_main.hpp index 85311956e..b45d73795 100644 --- a/emulator/src/tests/uiTests/UiTests_main.hpp +++ b/emulator/src/tests/uiTests/UiTests_main.hpp @@ -39,7 +39,7 @@ int UiTests_main(UiTests_Mode mode = UiTests_Mode::Run) { const bool isListMode = mode == UiTests_Mode::List; // Create and run the emulator - std::unique_ptr oswEmu = std::make_unique(isListMode); + std::unique_ptr oswEmu = std::make_unique(isListMode, isListMode); OswEmulator::instance = oswEmu.get(); // Setup test engine diff --git a/emulator/src/tests/unitTests/fixtures/EmulatorFixture.hpp b/emulator/src/tests/unitTests/fixtures/EmulatorFixture.hpp index 18953cdfd..fa68fc16d 100644 --- a/emulator/src/tests/unitTests/fixtures/EmulatorFixture.hpp +++ b/emulator/src/tests/unitTests/fixtures/EmulatorFixture.hpp @@ -25,7 +25,7 @@ class EmulatorFixture { // Create and run the (headless) emulator this->configPath = "config_" + std::to_string(rand()) + ".json"; this->imguiPath = "imgui_" + std::to_string(rand()) + ".ini"; - oswEmu = std::make_unique(headless, this->configPath, this->imguiPath); + oswEmu = std::make_unique(headless, headless, this->configPath, this->imguiPath); OswEmulator::instance = oswEmu.get(); std::thread t([&]() { try {