From a5e353a0fa87ebe83841c8294d12de0db51ec43f Mon Sep 17 00:00:00 2001 From: NyakoFox Date: Mon, 23 Mar 2026 21:27:55 -0300 Subject: [PATCH] Solve render recaching issues Past solutions were just "recache the screen textures under these known circumstances" where whenever things OUTSIDE of those known circumstances happened, the issue would reoccur. I recently learned about an SDL event, `SDL_RENDER_TARGETS_RESET`, which is for this exact problem. I ripped out all of the other places `Screen::recacheTextures()` was called, and just slotted it in there, and it worked perfectly. ...well, the old behavior worked perfectly; but the old behavior was flawed as well, because it only checked for "ingame_titlemode" (if you're in the main menu during gameplay) and forgot to check for the map screen... plus, it didn't ever regenerate the minimap in custom levels, which is another "persistant" render target. Hopefully, this is the last time we'll ever have to think about this one. I'm certainly sick of it. This should 100% be backported into 2.4, as the bug occurs there as well. --- desktop_version/src/Editor.cpp | 1 - desktop_version/src/Game.cpp | 1 - desktop_version/src/KeyPoll.cpp | 5 ++++- desktop_version/src/Screen.cpp | 17 +++++++++++------ 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/desktop_version/src/Editor.cpp b/desktop_version/src/Editor.cpp index 44cb0d39..4ee808f6 100644 --- a/desktop_version/src/Editor.cpp +++ b/desktop_version/src/Editor.cpp @@ -3625,7 +3625,6 @@ void editorinput(void) if (game.currentmenuname == Menu::ed_settings) { ed.state = EditorState_DRAW; - gameScreen.recacheTextures(); } else { diff --git a/desktop_version/src/Game.cpp b/desktop_version/src/Game.cpp index d41d63c9..0cf6c6dc 100644 --- a/desktop_version/src/Game.cpp +++ b/desktop_version/src/Game.cpp @@ -7926,7 +7926,6 @@ void Game::mapmenuchange(const enum GameGamestate newgamestate, const bool user_ gamestate = newgamestate; graphics.resumegamemode = false; mapheld = true; - gameScreen.recacheTextures(); if (prevgamestate == GAMEMODE) { diff --git a/desktop_version/src/KeyPoll.cpp b/desktop_version/src/KeyPoll.cpp index 4439d470..08b05cc0 100644 --- a/desktop_version/src/KeyPoll.cpp +++ b/desktop_version/src/KeyPoll.cpp @@ -459,6 +459,10 @@ void KeyPoll::Poll(void) break; } + case SDL_RENDER_TARGETS_RESET: + gameScreen.recacheTextures(); + break; + /* Window Events */ case SDL_WINDOWEVENT: switch (evt.window.event) @@ -496,7 +500,6 @@ void KeyPoll::Poll(void) } } SDL_DisableScreenSaver(); - gameScreen.recacheTextures(); break; case SDL_WINDOWEVENT_FOCUS_LOST: if (!game.disablepause) diff --git a/desktop_version/src/Screen.cpp b/desktop_version/src/Screen.cpp index 1bc4c29a..9c382a21 100644 --- a/desktop_version/src/Screen.cpp +++ b/desktop_version/src/Screen.cpp @@ -5,6 +5,8 @@ #include "Alloc.h" #include "Constants.h" +#include "CustomLevels.h" +#include "Enums.h" #include "Exit.h" #include "FileSystemUtils.h" #include "Game.h" @@ -14,6 +16,7 @@ #include "GraphicsResources.h" #endif #include "InterimVersion.h" +#include "Map.h" #include "Render.h" #include "Vlogging.h" @@ -152,7 +155,6 @@ void Screen::ResizeScreen(int x, int y) if (!isWindowed || isForcedFullscreen()) { int result = SDL_SetWindowFullscreen(m_window, SDL_WINDOW_FULLSCREEN_DESKTOP); - recacheTextures(); if (result != 0) { vlog_error("Error: could not set the game to fullscreen mode: %s", SDL_GetError()); @@ -175,7 +177,6 @@ void Screen::ResizeScreen(int x, int y) SDL_WINDOWPOS_CENTERED_DISPLAY(windowDisplay) ); } - recacheTextures(); } } @@ -352,8 +353,6 @@ void Screen::toggleVSync(void) { vsync = !vsync; SDL_RenderSetVSync(m_renderer, (int) vsync); - - recacheTextures(); } void Screen::recacheTextures(void) @@ -366,15 +365,21 @@ void Screen::recacheTextures(void) graphics.towerbg.tdrawback = true; graphics.titlebg.tdrawback = true; - if (game.ingame_titlemode) + if (game.gamestate == MAPMODE || game.ingame_titlemode) { - // Redraw the cached gameplay texture if we're in the in-game menu. + // Redraw the cached gameplay texture if we're in the map screen. // Additionally, reset alpha so things don't jitter when re-entering gameplay. float oldAlpha = graphics.alpha; graphics.alpha = 0; gamerender(); graphics.alpha = oldAlpha; } + + if (map.custommode) + { + // If we're in a custom level, regenerate the minimap, which also got cleared. + cl.generatecustomminimap(); + } } bool Screen::isForcedFullscreen(void)