diff --git a/Source/DiabloUI/diabloui.cpp b/Source/DiabloUI/diabloui.cpp index eaaec4f27..268819573 100644 --- a/Source/DiabloUI/diabloui.cpp +++ b/Source/DiabloUI/diabloui.cpp @@ -444,7 +444,7 @@ void UiHandleEvents(SDL_Event *event) if (event->type == SDL_KEYDOWN && event->key.keysym.sym == SDLK_RETURN) { const Uint8 *state = SDLC_GetKeyState(); if (state[SDLC_KEYSTATE_LALT] != 0 || state[SDLC_KEYSTATE_RALT] != 0) { - dx_reinit(); + sgOptions.Graphics.fullscreen.SetValue(!IsFullScreen()); return; } } diff --git a/Source/diablo.cpp b/Source/diablo.cpp index 5bfb6731e..cd2417a3c 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -108,7 +108,6 @@ char gszProductName[64] = "DevilutionX vUnknown"; Keymapper keymapper; std::array quickSpellActionIndexes; -bool gbForceWindowed = false; #ifdef _DEBUG bool DebugDisableNetworkTimeout = false; std::vector DebugCmdsFromCommandLine; @@ -447,7 +446,7 @@ void PressKey(int vkey) keymapper.KeyPressed(vkey); if (vkey == DVL_VK_RETURN) { if (GetAsyncKeyState(DVL_VK_MENU)) - dx_reinit(); + sgOptions.Graphics.fullscreen.SetValue(!IsFullScreen()); else control_type_message(); } @@ -472,7 +471,7 @@ void PressKey(int vkey) } if (PauseMode == 2) { if (vkey == DVL_VK_RETURN && GetAsyncKeyState(DVL_VK_MENU)) - dx_reinit(); + sgOptions.Graphics.fullscreen.SetValue(!IsFullScreen()); return; } @@ -480,7 +479,7 @@ void PressKey(int vkey) if (vkey == DVL_VK_RETURN) { if (GetAsyncKeyState(DVL_VK_MENU)) { - dx_reinit(); + sgOptions.Graphics.fullscreen.SetValue(!IsFullScreen()); } else if (stextflag != STORE_NONE) { StoreEnter(); } else if (QuestLogIsOpen) { @@ -796,7 +795,6 @@ void RunGameLoop(interface_mode uMsg) printInConsole(" %-20s %-30s\n", /* TRANSLATORS: Commandline Option */ "--config-dir", _("Specify the location of diablo.ini")); printInConsole(" %-20s %-30s\n", /* TRANSLATORS: Commandline Option */ "-n", _("Skip startup videos")); printInConsole(" %-20s %-30s\n", /* TRANSLATORS: Commandline Option */ "-f", _("Display frames per second")); - printInConsole(" %-20s %-30s\n", /* TRANSLATORS: Commandline Option */ "-x", _("Run in windowed mode")); printInConsole(" %-20s %-30s\n", /* TRANSLATORS: Commandline Option */ "--verbose", _("Enable verbose logging")); printInConsole(" %-20s %-30s\n", /* TRANSLATORS: Commandline Option */ "--record <#>", _("Record a demo file")); printInConsole(" %-20s %-30s\n", /* TRANSLATORS: Commandline Option */ "--demo <#>", _("Play a demo file")); @@ -869,8 +867,6 @@ void DiabloParseFlags(int argc, char **argv) gbShowIntro = false; } else if (arg == "-f") { EnableFrameCount(); - } else if (arg == "-x") { - gbForceWindowed = true; } else if (arg == "--spawn") { forceSpawn = true; } else if (arg == "--diablo") { diff --git a/Source/diablo.h b/Source/diablo.h index 62061457e..3d2a5672b 100644 --- a/Source/diablo.h +++ b/Source/diablo.h @@ -103,7 +103,6 @@ void diablo_color_cyc_logic(); /* rdata */ extern Keymapper keymapper; -extern bool gbForceWindowed; #ifdef _DEBUG extern bool DebugDisableNetworkTimeout; #endif diff --git a/Source/dx.cpp b/Source/dx.cpp index 96efe7982..a3d893b5f 100644 --- a/Source/dx.cpp +++ b/Source/dx.cpp @@ -67,33 +67,6 @@ bool CanRenderDirectlyToOutputSurface() #endif } -void CreateBackBuffer() -{ - if (CanRenderDirectlyToOutputSurface()) { - Log("{}", "Will render directly to the SDL output surface"); - PalSurface = GetOutputSurface(); - RenderDirectlyToOutputSurface = true; - } else { - PinnedPalSurface = SDLWrap::CreateRGBSurfaceWithFormat( - /*flags=*/0, - /*width=*/gnScreenWidth, - /*height=*/gnScreenHeight, - /*depth=*/8, - SDL_PIXELFORMAT_INDEX8); - PalSurface = PinnedPalSurface.get(); - } - -#ifndef USE_SDL1 - // In SDL2, `PalSurface` points to the global `palette`. - if (SDL_SetSurfacePalette(PalSurface, Palette.get()) < 0) - ErrSdl(); -#else - // In SDL1, `PalSurface` owns its palette and we must update it every - // time the global `palette` is changed. No need to do anything here as - // the global `palette` doesn't have any colors set yet. -#endif -} - void LockBufPriv() { MemCrit.lock(); @@ -195,33 +168,31 @@ void dx_cleanup() SDL_DestroyWindow(ghMainWnd); } -void dx_reinit() +void CreateBackBuffer() { -#ifdef USE_SDL1 - Uint32 flags = ghMainWnd->flags ^ SDL_FULLSCREEN; - if (!IsFullScreen()) { - flags |= SDL_FULLSCREEN; + if (CanRenderDirectlyToOutputSurface()) { + Log("{}", "Will render directly to the SDL output surface"); + PalSurface = GetOutputSurface(); + RenderDirectlyToOutputSurface = true; + } else { + PinnedPalSurface = SDLWrap::CreateRGBSurfaceWithFormat( + /*flags=*/0, + /*width=*/gnScreenWidth, + /*height=*/gnScreenHeight, + /*depth=*/8, + SDL_PIXELFORMAT_INDEX8); + PalSurface = PinnedPalSurface.get(); } - ghMainWnd = SDL_SetVideoMode(0, 0, 0, flags); - if (ghMainWnd == NULL) { + +#ifndef USE_SDL1 + // In SDL2, `PalSurface` points to the global `palette`. + if (SDL_SetSurfacePalette(PalSurface, Palette.get()) < 0) ErrSdl(); - } #else - Uint32 flags = 0; - if (!IsFullScreen()) { - flags = renderer != nullptr ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN; - } - if (SDL_SetWindowFullscreen(ghMainWnd, flags) != 0) { - ErrSdl(); - } + // In SDL1, `PalSurface` owns its palette and we must update it every + // time the global `palette` is changed. No need to do anything here as + // the global `palette` doesn't have any colors set yet. #endif - force_redraw = 255; -} - -void dx_resize() -{ - CreateBackBuffer(); - force_redraw = 255; } void InitPalette() diff --git a/Source/dx.h b/Source/dx.h index 7e4d1e438..0973d9c48 100644 --- a/Source/dx.h +++ b/Source/dx.h @@ -18,8 +18,7 @@ void dx_init(); void lock_buf(int idx); void unlock_buf(int idx); void dx_cleanup(); -void dx_reinit(); -void dx_resize(); +void CreateBackBuffer(); void InitPalette(); void BltFast(SDL_Rect *srcRect, SDL_Rect *dstRect); void Blit(SDL_Surface *src, SDL_Rect *srcRect, SDL_Rect *dstRect); diff --git a/Source/options.cpp b/Source/options.cpp index 58aa259eb..a49e0228e 100644 --- a/Source/options.cpp +++ b/Source/options.cpp @@ -791,14 +791,14 @@ GraphicsOptions::GraphicsOptions() , showFPS("Show FPS", OptionEntryFlags::None, N_("Show FPS"), N_("Displays the FPS in the upper left corner of the screen."), true) { resolution.SetValueChangedCallback(ResizeWindow); - fullscreen.SetValueChangedCallback(ResizeWindow); + fullscreen.SetValueChangedCallback(SetFullscreenMode); #if !defined(USE_SDL1) || defined(__3DS__) fitToScreen.SetValueChangedCallback(ResizeWindow); #endif #ifndef USE_SDL1 upscale.SetValueChangedCallback(ResizeWindow); scaleQuality.SetValueChangedCallback(ReinitializeTexture); - integerScaling.SetValueChangedCallback(ResizeWindow); + integerScaling.SetValueChangedCallback(ReinitializeIntegerScale); vSync.SetValueChangedCallback(ReinitializeRenderer); #endif showFPS.SetValueChangedCallback(OptionShowFPSChanged); diff --git a/Source/utils/display.cpp b/Source/utils/display.cpp index 01a679f0b..9c92287b1 100644 --- a/Source/utils/display.cpp +++ b/Source/utils/display.cpp @@ -57,7 +57,7 @@ Uint16 GetViewportHeight() namespace { #ifndef USE_SDL1 -void CalculatePreferdWindowSize(int &width, int &height) +void CalculatePreferredWindowSize(int &width, int &height) { SDL_DisplayMode mode; if (SDL_GetDesktopDisplayMode(0, &mode) != 0) { @@ -104,7 +104,7 @@ Size GetPreferredWindowSize() #ifndef USE_SDL1 if (*sgOptions.Graphics.upscale && *sgOptions.Graphics.fitToScreen) { - CalculatePreferdWindowSize(windowSize.width, windowSize.height); + CalculatePreferredWindowSize(windowSize.width, windowSize.height); } #endif AdjustToScreenGeometry(windowSize); @@ -228,18 +228,18 @@ bool SpawnWindow(const char *lpWindowName) #ifdef USE_SDL1 SDL_WM_SetCaption(lpWindowName, WINDOW_ICON_NAME); - SetVideoModeToPrimary(!gbForceWindowed && *sgOptions.Graphics.fullscreen, windowSize.width, windowSize.height); + SetVideoModeToPrimary(*sgOptions.Graphics.fullscreen, windowSize.width, windowSize.height); if (*sgOptions.Gameplay.grabInput) SDL_WM_GrabInput(SDL_GRAB_ON); atexit(SDL_VideoQuit); // Without this video mode is not restored after fullscreen. #else int flags = SDL_WINDOW_ALLOW_HIGHDPI; if (*sgOptions.Graphics.upscale) { - if (!gbForceWindowed && *sgOptions.Graphics.fullscreen) { + if (*sgOptions.Graphics.fullscreen) { flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; } flags |= SDL_WINDOW_RESIZABLE; - } else if (!gbForceWindowed && *sgOptions.Graphics.fullscreen) { + } else if (*sgOptions.Graphics.fullscreen) { flags |= SDL_WINDOW_FULLSCREEN; } @@ -268,6 +268,7 @@ bool SpawnWindow(const char *lpWindowName) return ghMainWnd != nullptr; } +#ifndef USE_SDL1 void ReinitializeTexture() { if (texture) @@ -279,6 +280,19 @@ void ReinitializeTexture() texture = SDLWrap::CreateTexture(renderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_STREAMING, gnScreenWidth, gnScreenHeight); } +void ReinitializeIntegerScale() +{ + if (*sgOptions.Graphics.fitToScreen) { + ResizeWindow(); + return; + } + + if (renderer != nullptr && SDL_RenderSetIntegerScale(renderer, *sgOptions.Graphics.integerScaling ? SDL_TRUE : SDL_FALSE) < 0) { + ErrSdl(); + } +} +#endif + void ReinitializeRenderer() { if (ghMainWnd == nullptr) @@ -289,6 +303,9 @@ void ReinitializeRenderer() Size windowSize = { current.current_w, current.current_h }; AdjustToScreenGeometry(windowSize); #else + if (texture) + texture.reset(); + if (renderer != nullptr) { SDL_DestroyRenderer(renderer); renderer = nullptr; @@ -322,7 +339,7 @@ void ReinitializeRenderer() ReinitializeTexture(); - if (*sgOptions.Graphics.integerScaling && SDL_RenderSetIntegerScale(renderer, SDL_TRUE) < 0) { + if (SDL_RenderSetIntegerScale(renderer, *sgOptions.Graphics.integerScaling ? SDL_TRUE : SDL_FALSE) < 0) { ErrSdl(); } @@ -342,6 +359,34 @@ void ReinitializeRenderer() #endif } +void SetFullscreenMode() +{ +#ifdef USE_SDL1 + Uint32 flags = ghMainWnd->flags ^ SDL_FULLSCREEN; + if (*sgOptions.Graphics.fullscreen) { + flags |= SDL_FULLSCREEN; + } + ghMainWnd = SDL_SetVideoMode(0, 0, 0, flags); + if (ghMainWnd == NULL) { + ErrSdl(); + } +#else + Uint32 flags = 0; + if (*sgOptions.Graphics.fullscreen) { + flags = renderer != nullptr ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN; + } + if (SDL_SetWindowFullscreen(ghMainWnd, flags) != 0) { + ErrSdl(); + } + if (renderer != nullptr && !*sgOptions.Graphics.fullscreen) { + SDL_RestoreWindow(ghMainWnd); // Avoid window being maximized before resizing + Size windowSize = GetPreferredWindowSize(); + SDL_SetWindowSize(ghMainWnd, windowSize.width, windowSize.height); + } +#endif + force_redraw = 255; +} + void ResizeWindow() { if (ghMainWnd == nullptr) @@ -350,25 +395,19 @@ void ResizeWindow() Size windowSize = GetPreferredWindowSize(); #ifdef USE_SDL1 - SetVideoModeToPrimary(!gbForceWindowed && *sgOptions.Graphics.fullscreen, windowSize.width, windowSize.height); + SetVideoModeToPrimary(*sgOptions.Graphics.fullscreen, windowSize.width, windowSize.height); #else - int flags = 0; - if (*sgOptions.Graphics.upscale) { - if (!gbForceWindowed && *sgOptions.Graphics.fullscreen) { - flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; - } - SDL_SetWindowResizable(ghMainWnd, SDL_TRUE); - } else if (!gbForceWindowed && *sgOptions.Graphics.fullscreen) { - flags |= SDL_WINDOW_FULLSCREEN; - SDL_SetWindowResizable(ghMainWnd, SDL_FALSE); - } - SDL_SetWindowFullscreen(ghMainWnd, flags); - SDL_SetWindowSize(ghMainWnd, windowSize.width, windowSize.height); #endif ReinitializeRenderer(); - dx_resize(); + +#ifndef USE_SDL1 + SDL_SetWindowResizable(ghMainWnd, renderer != nullptr ? SDL_TRUE : SDL_FALSE); +#endif + + CreateBackBuffer(); + force_redraw = 255; } SDL_Surface *GetOutputSurface() diff --git a/Source/utils/ui_fwd.h b/Source/utils/ui_fwd.h index 6a3ba8179..1d0891324 100644 --- a/Source/utils/ui_fwd.h +++ b/Source/utils/ui_fwd.h @@ -15,8 +15,15 @@ Uint16 GetScreenHeight(); Uint16 GetViewportHeight(); float GetDpiScalingFactor(); +/** + * @brief Set the screen to fullscreen or windowe if fullsc + */ +void SetFullscreenMode(); bool SpawnWindow(const char *lpWindowName); +#ifndef USE_SDL1 void ReinitializeTexture(); +void ReinitializeIntegerScale(); +#endif void ReinitializeRenderer(); void ResizeWindow(); void UiErrorOkDialog(const char *caption, const char *text, bool error = true);