From d912026f3e7edb9dfc0687c30d031189fbb55ebf Mon Sep 17 00:00:00 2001 From: Andrea Odetti Date: Tue, 9 Feb 2021 16:02:36 +0000 Subject: [PATCH] Add options to specify SDL window size via cmd line arguments. Signed-off-by: Andrea Odetti --- source/frontends/common2/programoptions.cpp | 58 +++++++++++++++---- source/frontends/common2/programoptions.h | 1 + source/frontends/sdl/imgui/sdlimguiframe.cpp | 15 ++--- source/frontends/sdl/imgui/sdlimguiframe.h | 4 +- source/frontends/sdl/main.cpp | 10 +++- .../sdl/renderer/sdlrendererframe.cpp | 16 ++--- 6 files changed, 74 insertions(+), 30 deletions(-) diff --git a/source/frontends/common2/programoptions.cpp b/source/frontends/common2/programoptions.cpp index ee3269ad..a6519f80 100644 --- a/source/frontends/common2/programoptions.cpp +++ b/source/frontends/common2/programoptions.cpp @@ -12,43 +12,61 @@ #include "Utilities.h" #include +#include namespace po = boost::program_options; +namespace +{ + + std::pair parseSize(const std::string & s) + { + std::smatch m; + if (std::regex_match(s, m, std::regex("^(\\d+)x(\\d+)$"))) + { + const int width = std::stoi(m.str(1)); + const int height = std::stoi(m.str(2)); + return std::make_pair(width, height); + } + throw std::runtime_error("Invalid sizes: " + s); + } + +} + bool getEmulatorOptions(int argc, const char * argv [], const std::string & edition, EmulatorOptions & options) { const std::string name = "Apple Emulator for " + edition + " (based on AppleWin " + getVersion() + ")"; po::options_description desc(name); desc.add_options() ("help,h", "Print this help message") - ("multi-threaded,m", "Multi threaded") - ("loose-mutex,l", "Loose mutex") - ("sdl-driver", po::value()->default_value(options.sdlDriver), "SDL driver") - ("imgui", "Render with Dear ImGui") - ("timer-interval,i", po::value()->default_value(options.timerInterval), "Timer interval in ms"); + ; po::options_description configDesc("configuration"); configDesc.add_options() ("save-conf", "Save configuration on exit") ("config,c", po::value>(), "Registry options section.path=value") - ("qt-ini,q", "Use Qt ini file (read only)"); + ("qt-ini,q", "Use Qt ini file (read only)") + ; desc.add(configDesc); po::options_description diskDesc("Disk"); diskDesc.add_options() ("d1,1", po::value(), "Disk in 1st drive") - ("d2,2", po::value(), "Disk in 2nd drive"); + ("d2,2", po::value(), "Disk in 2nd drive") + ; desc.add(diskDesc); po::options_description snapshotDesc("Snapshot"); snapshotDesc.add_options() ("state-filename,f", po::value(), "Set snapshot filename") - ("load-state,s", po::value(), "Load snapshot from file"); + ("load-state,s", po::value(), "Load snapshot from file") + ; desc.add(snapshotDesc); po::options_description memoryDesc("Memory"); memoryDesc.add_options() - ("memclear", po::value()->default_value(options.memclear), "Memory initialization pattern [0..7]"); + ("memclear", po::value()->default_value(options.memclear), "Memory initialization pattern [0..7]") + ; desc.add(memoryDesc); po::options_description emulatorDesc("Emulator"); @@ -57,13 +75,26 @@ bool getEmulatorOptions(int argc, const char * argv [], const std::string & edit ("headless", "Headless: disable video (freewheel)") ("fixed-speed", "Fixed (non-adaptive) speed") ("ntsc,nt", "NTSC: execute NTSC code") - ("benchmark,b", "Benchmark emulator"); + ("benchmark,b", "Benchmark emulator") + ; desc.add(emulatorDesc); + po::options_description sdlDesc("SDL"); + sdlDesc.add_options() + ("multi-threaded,m", "Multi threaded") + ("timer-interval,i", po::value()->default_value(options.timerInterval), "Timer interval in ms") + ("loose-mutex,l", "Loose mutex") + ("sdl-driver", po::value()->default_value(options.sdlDriver), "SDL driver") + ("imgui", "Render with Dear ImGui") + ("size", po::value(), "WxH") + ; + desc.add(sdlDesc); + po::options_description paddleDesc("Paddle"); paddleDesc.add_options() ("no-squaring", "Gamepad range is (already) a square") - ("device-name", po::value(), "Gamepad device name"); + ("device-name", po::value(), "Gamepad device name") + ; desc.add(paddleDesc); po::variables_map vm; @@ -128,6 +159,11 @@ bool getEmulatorOptions(int argc, const char * argv [], const std::string & edit options.paddleDeviceName = vm["device-name"].as(); } + if (vm.count("size")) + { + options.size = parseSize(vm["size"].as()); + } + return true; } catch (const po::error& e) diff --git a/source/frontends/common2/programoptions.h b/source/frontends/common2/programoptions.h index fca9edd0..3eb912b7 100644 --- a/source/frontends/common2/programoptions.h +++ b/source/frontends/common2/programoptions.h @@ -37,6 +37,7 @@ struct EmulatorOptions int sdlDriver = -1; // default = -1 to let SDL choose bool imgui = false; // use imgui renderer + std::pair size; // width x height std::vector registryOptions; }; diff --git a/source/frontends/sdl/imgui/sdlimguiframe.cpp b/source/frontends/sdl/imgui/sdlimguiframe.cpp index 34c5bb59..edfd3101 100644 --- a/source/frontends/sdl/imgui/sdlimguiframe.cpp +++ b/source/frontends/sdl/imgui/sdlimguiframe.cpp @@ -3,6 +3,7 @@ #include "frontends/sdl/utils.h" #include "frontends/common2/fileregistry.h" +#include "frontends/common2/programoptions.h" #include "frontends/sdl/imgui/image.h" #include "frontends/sdl/imgui/settingshelper.h" @@ -34,13 +35,8 @@ namespace } -SDLImGuiFrame::SDLImGuiFrame() +SDLImGuiFrame::SDLImGuiFrame(const EmulatorOptions & options) { - Video & video = GetVideo(); - - myBorderlessWidth = video.GetFrameBufferBorderlessWidth(); - myBorderlessHeight = video.GetFrameBufferBorderlessHeight(); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, SDL_CONTEXT_MAJOR); // from local gles.h @@ -52,7 +48,7 @@ SDLImGuiFrame::SDLImGuiFrame() SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); SDL_WindowFlags windowFlags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); - myWindow.reset(SDL_CreateWindow(g_pAppTitle.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, myBorderlessWidth, myBorderlessHeight, windowFlags), SDL_DestroyWindow); + myWindow.reset(SDL_CreateWindow(g_pAppTitle.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, options.size.first, options.size.second, windowFlags), SDL_DestroyWindow); if (!myWindow) { throw std::runtime_error(SDL_GetError()); @@ -103,6 +99,11 @@ SDLImGuiFrame::SDLImGuiFrame() glGenTextures(1, &myTexture); + Video & video = GetVideo(); + + myBorderlessWidth = video.GetFrameBufferBorderlessWidth(); + myBorderlessHeight = video.GetFrameBufferBorderlessHeight(); + const int width = video.GetFrameBufferWidth(); const size_t borderWidth = video.GetFrameBufferBorderWidth(); const size_t borderHeight = video.GetFrameBufferBorderHeight(); diff --git a/source/frontends/sdl/imgui/sdlimguiframe.h b/source/frontends/sdl/imgui/sdlimguiframe.h index 5887a78c..77f0c1b7 100644 --- a/source/frontends/sdl/imgui/sdlimguiframe.h +++ b/source/frontends/sdl/imgui/sdlimguiframe.h @@ -3,10 +3,12 @@ #include "frontends/sdl/sdlframe.h" #include "frontends/sdl/imgui/gles.h" +class EmulatorOptions; + class SDLImGuiFrame : public SDLFrame { public: - SDLImGuiFrame(); + SDLImGuiFrame(const EmulatorOptions & options); ~SDLImGuiFrame() override; diff --git a/source/frontends/sdl/main.cpp b/source/frontends/sdl/main.cpp index 62923a1e..74bee6c3 100644 --- a/source/frontends/sdl/main.cpp +++ b/source/frontends/sdl/main.cpp @@ -78,6 +78,12 @@ void run_sdl(int argc, const char * argv []) std::cerr << std::fixed << std::setprecision(2); EmulatorOptions options; + + Video & video = GetVideo(); + const int sw = video.GetFrameBufferBorderlessWidth(); + const int sh = video.GetFrameBufferBorderlessHeight(); + + options.size = std::make_pair(sw, sh); options.memclear = g_nMemoryClearType; const bool run = getEmulatorOptions(argc, argv, "SDL2", options); @@ -89,7 +95,7 @@ void run_sdl(int argc, const char * argv []) #ifdef SA2_IMGUI if (options.imgui) { - frame.reset(new SDLImGuiFrame()); + frame.reset(new SDLImGuiFrame(options)); } else { @@ -115,8 +121,6 @@ void run_sdl(int argc, const char * argv []) Initialisation init; applyOptions(options); - Video & video = GetVideo(); - const int fps = getRefreshRate(); std::cerr << "Video refresh rate: " << fps << " Hz, " << 1000.0 / fps << " ms" << std::endl; diff --git a/source/frontends/sdl/renderer/sdlrendererframe.cpp b/source/frontends/sdl/renderer/sdlrendererframe.cpp index 7171ceaf..b6ccf324 100644 --- a/source/frontends/sdl/renderer/sdlrendererframe.cpp +++ b/source/frontends/sdl/renderer/sdlrendererframe.cpp @@ -10,14 +10,7 @@ SDLRendererFrame::SDLRendererFrame(const EmulatorOptions & options) { - Video & video = GetVideo(); - - const int width = video.GetFrameBufferWidth(); - const int height = video.GetFrameBufferHeight(); - const int sw = video.GetFrameBufferBorderlessWidth(); - const int sh = video.GetFrameBufferBorderlessHeight(); - - myWindow.reset(SDL_CreateWindow(g_pAppTitle.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, sw, sh, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE), SDL_DestroyWindow); + myWindow.reset(SDL_CreateWindow(g_pAppTitle.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, options.size.first, options.size.second, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE), SDL_DestroyWindow); if (!myWindow) { throw std::runtime_error(SDL_GetError()); @@ -34,6 +27,13 @@ SDLRendererFrame::SDLRendererFrame(const EmulatorOptions & options) const Uint32 format = SDL_PIXELFORMAT_ARGB8888; printRendererInfo(std::cerr, myRenderer, format, options.sdlDriver); + Video & video = GetVideo(); + + const int width = video.GetFrameBufferWidth(); + const int height = video.GetFrameBufferHeight(); + const int sw = video.GetFrameBufferBorderlessWidth(); + const int sh = video.GetFrameBufferBorderlessHeight(); + myTexture.reset(SDL_CreateTexture(myRenderer.get(), format, SDL_TEXTUREACCESS_STATIC, width, height), SDL_DestroyTexture); myRect.x = video.GetFrameBufferBorderWidth();