diff --git a/libraries/ZWidget/src/window/sdl2/sdl2displaywindow.cpp b/libraries/ZWidget/src/window/sdl2/sdl2displaywindow.cpp index a715a0cb9..fc53b7dff 100644 --- a/libraries/ZWidget/src/window/sdl2/sdl2displaywindow.cpp +++ b/libraries/ZWidget/src/window/sdl2/sdl2displaywindow.cpp @@ -18,9 +18,14 @@ public: } }; -SDL2DisplayWindow::SDL2DisplayWindow(DisplayWindowHost* windowHost) : WindowHost(windowHost) +static void CheckInitSDL() { static InitSDL initsdl; +} + +SDL2DisplayWindow::SDL2DisplayWindow(DisplayWindowHost* windowHost) : WindowHost(windowHost) +{ + CheckInitSDL(); int result = SDL_CreateWindowAndRenderer(320, 200, SDL_WINDOW_HIDDEN /*| SDL_WINDOW_ALLOW_HIGHDPI*/, &WindowHandle, &RendererHandle); if (result != 0) @@ -32,6 +37,13 @@ SDL2DisplayWindow::SDL2DisplayWindow(DisplayWindowHost* windowHost) : WindowHost SDL2DisplayWindow::~SDL2DisplayWindow() { WindowList.erase(WindowList.find(SDL_GetWindowID(WindowHandle))); + + if (BackBufferTexture) + { + SDL_DestroyTexture(BackBufferTexture); + BackBufferTexture = nullptr; + } + SDL_DestroyRenderer(RendererHandle); SDL_DestroyWindow(WindowHandle); RendererHandle = nullptr; @@ -182,6 +194,36 @@ double SDL2DisplayWindow::GetDpiScale() const void SDL2DisplayWindow::PresentBitmap(int width, int height, const uint32_t* pixels) { + if (!BackBufferTexture || BackBufferWidth != width || BackBufferHeight != height) + { + if (BackBufferTexture) + { + SDL_DestroyTexture(BackBufferTexture); + BackBufferTexture = nullptr; + } + + BackBufferTexture = SDL_CreateTexture(RendererHandle, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, width, height); + if (!BackBufferTexture) + return; + + BackBufferWidth = width; + BackBufferHeight = height; + } + + int destpitch = 0; + void* dest = nullptr; + int result = SDL_LockTexture(BackBufferTexture, nullptr, &dest, &destpitch); + if (result != 0) return; + for (int y = 0; y < height; y++) + { + const void* sline = pixels + y * width; + void* dline = (uint8_t*)dest + y * destpitch; + memcpy(dline, sline, width << 2); + } + SDL_UnlockTexture(BackBufferTexture); + + SDL_RenderCopy(RendererHandle, BackBufferTexture, nullptr, nullptr); + SDL_RenderPresent(RendererHandle); } void SDL2DisplayWindow::SetBorderColor(uint32_t bgra8) @@ -216,6 +258,8 @@ void SDL2DisplayWindow::SetClipboardText(const std::string& text) void SDL2DisplayWindow::ProcessEvents() { + CheckInitSDL(); + SDL_Event event; while (SDL_PollEvent(&event) != 0) { @@ -225,6 +269,8 @@ void SDL2DisplayWindow::ProcessEvents() void SDL2DisplayWindow::RunLoop() { + CheckInitSDL(); + while (!ExitRunLoop) { SDL_Event event; @@ -237,11 +283,15 @@ void SDL2DisplayWindow::RunLoop() void SDL2DisplayWindow::ExitLoop() { + CheckInitSDL(); + ExitRunLoop = true; } Size SDL2DisplayWindow::GetScreenSize() { + CheckInitSDL(); + SDL_Rect rect = {}; int result = SDL_GetDisplayBounds(0, &rect); if (result != 0) @@ -253,11 +303,18 @@ Size SDL2DisplayWindow::GetScreenSize() void* SDL2DisplayWindow::StartTimer(int timeoutMilliseconds, std::function onTimer) { + CheckInitSDL(); + + // To do: implement timers + return nullptr; } void SDL2DisplayWindow::StopTimer(void* timerID) { + CheckInitSDL(); + + // To do: implement timers } SDL2DisplayWindow* SDL2DisplayWindow::FindEventWindow(const SDL_Event& event) diff --git a/libraries/ZWidget/src/window/sdl2/sdl2displaywindow.h b/libraries/ZWidget/src/window/sdl2/sdl2displaywindow.h index f825303c9..484ae0a45 100644 --- a/libraries/ZWidget/src/window/sdl2/sdl2displaywindow.h +++ b/libraries/ZWidget/src/window/sdl2/sdl2displaywindow.h @@ -78,6 +78,9 @@ public: DisplayWindowHost* WindowHost = nullptr; SDL_Window* WindowHandle = nullptr; SDL_Renderer* RendererHandle = nullptr; + SDL_Texture* BackBufferTexture = nullptr; + int BackBufferWidth = 0; + int BackBufferHeight = 0; static bool ExitRunLoop; static Uint32 PaintEventNumber; diff --git a/src/common/platform/posix/sdl/i_system.cpp b/src/common/platform/posix/sdl/i_system.cpp index 58a6a2f37..5aae51ce9 100644 --- a/src/common/platform/posix/sdl/i_system.cpp +++ b/src/common/platform/posix/sdl/i_system.cpp @@ -65,7 +65,7 @@ #include "palutil.h" #include "st_start.h" #include "printf.h" - +#include "common/widgets/launcherwindow.h" #ifndef NO_GTK bool I_GtkAvailable (); @@ -299,95 +299,16 @@ void I_PrintStr(const char *cp) int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad, int& autoloadflags) { - int i; - if (!showwin) { return defaultiwad; } -#ifndef __APPLE__ - if(I_FileAvailable("kdialog")) - { - FString cmd("kdialog --title \"" GAMENAME " "); - cmd << GetVersionString() << ": Select an IWAD to use\"" - " --menu \"" GAMENAME " found more than one IWAD\n" - "Select from the list below to determine which one to use:\""; - - for(i = 0; i < numwads; ++i) - { - const char *filepart = strrchr(wads[i].Path.GetChars(), '/'); - if(filepart == NULL) - filepart = wads[i].Path.GetChars(); - else - filepart++; - // Menu entries are specified in "tag" "item" pairs, where when a - // particular item is selected (and the Okay button clicked), its - // corresponding tag is printed to stdout for identification. - cmd.AppendFormat(" \"%d\" \"%s (%s)\"", i, wads[i].Name.GetChars(), filepart); - } - - if(defaultiwad >= 0 && defaultiwad < numwads) - { - const char *filepart = strrchr(wads[defaultiwad].Path.GetChars(), '/'); - if(filepart == NULL) - filepart = wads[defaultiwad].Path.GetChars(); - else - filepart++; - cmd.AppendFormat(" --default \"%s (%s)\"", wads[defaultiwad].Name.GetChars(), filepart); - } - - FILE *f = popen(cmd.GetChars(), "r"); - if(f != NULL) - { - char gotstr[16]; - - if(fgets(gotstr, sizeof(gotstr), f) == NULL || - sscanf(gotstr, "%d", &i) != 1) - i = -1; - - // Exit status = 1 means the selection was canceled (either by - // Cancel/Esc or the X button), not that there was an error running - // the program. In that case, nothing was printed so fgets will - // have failed. Other values can indicate an error running the app, - // so fall back to whatever else can be used. - int status = pclose(f); - if(WIFEXITED(status) && (WEXITSTATUS(status) == 0 || WEXITSTATUS(status) == 1)) - return i; - } - } -#endif - -#ifndef NO_GTK - if (I_GtkAvailable()) - { - return I_PickIWad_Gtk (wads, numwads, showwin, defaultiwad, autoloadflags); - } -#endif - #ifdef __APPLE__ return I_PickIWad_Cocoa (wads, numwads, showwin, defaultiwad); +#else + return LauncherWindow::ExecModal(wads, numwads, defaultiwad, &autoloadflags); #endif - - if (!isatty(fileno(stdin))) - { - return defaultiwad; - } - - printf ("Please select a game wad (or 0 to exit):\n"); - for (i = 0; i < numwads; ++i) - { - const char *filepart = strrchr (wads[i].Path.GetChars(), '/'); - if (filepart == NULL) - filepart = wads[i].Path.GetChars(); - else - filepart++; - printf ("%d. %s (%s)\n", i+1, wads[i].Name.GetChars(), filepart); - } - printf ("Which one? "); - if (scanf ("%d", &i) != 1 || i > numwads) - return -1; - return i-1; } void I_PutInClipboard (const char *str)