2 Commits

Author SHA1 Message Date
NyakoFox a5e353a0fa 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.
2026-04-12 09:09:27 -04:00
NyakoFox 994b3602e5 Clamp editor mouse coordinates
The editor has never clamped mouse bounds, and instead relied on SDL to
return clamped mouse coordinates. Unfortunately, in #1140, this detail
was missed, and the behavior changed, allowing the cursor to leave the
bounds of the screen.

This isn't much of a problem most of the time because anything that
uses position as array indeces has bounds checks. Unfortunately,
placing entities outside of a room's bounds leads to entities you can't
ever touch ever again without modifying the level externally. This is
the worst with checkpoints, as pressing Enter in a room will now take
you to the out-of-bounds checkpoint, causing you to immediately wrap to
another room.

This fix should be backported to 2.4, as the issue can lead to level
files which need manual editing to fix!
2026-04-12 09:08:48 -04:00
4 changed files with 17 additions and 11 deletions
+2 -3
View File
@@ -3206,8 +3206,8 @@ void editorinput(void)
ed.old_tilex = ed.tilex;
ed.old_tiley = ed.tiley;
ed.tilex = key.mousex / 8;
ed.tiley = key.mousey / 8;
ed.tilex = SDL_clamp(key.mousex, 0, SCREEN_WIDTH_PIXELS - 1) / 8;
ed.tiley = SDL_clamp(key.mousey, 0, SCREEN_HEIGHT_PIXELS - 1) / 8;
bool up_pressed = key.isDown(SDLK_UP) || key.isDown(SDL_CONTROLLER_BUTTON_DPAD_UP);
bool down_pressed = key.isDown(SDLK_DOWN) || key.isDown(SDL_CONTROLLER_BUTTON_DPAD_DOWN);
@@ -3625,7 +3625,6 @@ void editorinput(void)
if (game.currentmenuname == Menu::ed_settings)
{
ed.state = EditorState_DRAW;
gameScreen.recacheTextures();
}
else
{
-1
View File
@@ -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)
{
+4 -1
View File
@@ -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)
+11 -6
View File
@@ -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)