From 8d4c82732ea5a226e92c87cbeee1565c85163007 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 22 Nov 2025 22:48:45 -0800
Subject: [PATCH] Use a render target to enable fading and scaling control
---
game/init.cpp | 5 +--
screenlib/SDL_FrameBuf.cpp | 89 ++++++++++++++++----------------------
screenlib/SDL_FrameBuf.h | 13 ++----
3 files changed, 43 insertions(+), 64 deletions(-)
diff --git a/game/init.cpp b/game/init.cpp
index 277ed600..779fb84b 100644
--- a/game/init.cpp
+++ b/game/init.cpp
@@ -839,9 +839,8 @@ int DoInitializations(Uint32 window_flags)
/* Create the UI manager */
ui = new MaelstromUI(screen, prefs);
- if (window_flags & SDL_WINDOW_FULLSCREEN) {
- ui->SetPanelTransition(PANEL_TRANSITION_FADE);
- }
+ /* Fade transition between panels */
+ ui->SetPanelTransition(PANEL_TRANSITION_FADE);
/* -- Throw up our intro screen */
if (ui->GetPanelTransition() == PANEL_TRANSITION_FADE) {
diff --git a/screenlib/SDL_FrameBuf.cpp b/screenlib/SDL_FrameBuf.cpp
index f7ecbf4e..c52c9d9f 100644
--- a/screenlib/SDL_FrameBuf.cpp
+++ b/screenlib/SDL_FrameBuf.cpp
@@ -34,15 +34,12 @@
/* Constructors cannot fail. :-/ */
FrameBuf::FrameBuf() : ErrorBase()
{
- /* Initialize various variables to null state */
- window = NULL;
- renderer = NULL;
- faded = 0;
}
int
FrameBuf::Init(int width, int height, Uint32 window_flags, SDL_Surface *icon)
{
+ /* Create the window */
window = SDL_CreateWindow(NULL, width, height, window_flags);
if (!window) {
SetError("Couldn't create %dx%d window: %s",
@@ -50,26 +47,40 @@ FrameBuf::Init(int width, int height, Uint32 window_flags, SDL_Surface *icon)
return(-1);
}
+ /* Set the icon, if any */
+ if ( icon ) {
+ SDL_SetWindowIcon(window, icon);
+ }
+
+ /* Create the renderer */
renderer = SDL_CreateRenderer(window, NULL);
if (!renderer) {
SetError("Couldn't create renderer: %s", SDL_GetError());
return(-1);
}
- /* Set the icon, if any */
- if ( icon ) {
- SDL_SetWindowIcon(window, icon);
- }
-
/* Set the output area */
SDL_SetRenderLogicalPresentation(renderer, width, height, SDL_LOGICAL_PRESENTATION_LETTERBOX);
UpdateWindowSize(width, height);
+ /* Create the render target */
+ target = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_UNKNOWN, SDL_TEXTUREACCESS_TARGET, width, height);
+ if (!target) {
+ SetError("Couldn't create target: %s", SDL_GetError());
+ return(-1);
+ }
+ //SDL_SetTextureScaleMode(target, SDL_SCALEMODE_PIXELART);
+
+ SDL_SetRenderTarget(renderer, target);
+
return(0);
}
FrameBuf::~FrameBuf()
{
+ if (target) {
+ SDL_DestroyTexture(target);
+ }
if (renderer) {
SDL_DestroyRenderer(renderer);
}
@@ -186,7 +197,18 @@ FrameBuf::StretchBlit(const SDL_Rect *_dstrect, SDL_Texture *src, const SDL_Rect
void
FrameBuf::Update(void)
{
+ /* Make sure resize events are seen before drawing to the screen */
+ SDL_PumpEvents();
+
+ SDL_SetRenderTarget(renderer, NULL);
+
+ SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
+ SDL_RenderClear(renderer);
+
+ SDL_RenderTexture(renderer, target, NULL, NULL);
SDL_RenderPresent(renderer);
+
+ SDL_SetRenderTarget(renderer, target);
}
void
@@ -196,24 +218,16 @@ FrameBuf::Fade(void)
return;
#else
const int max = 32;
- Uint16 ramp[256];
+ Uint8 value;
- for ( int j = 1; j <= max; j++ ) {
- int v = faded ? j : max - j + 1;
- for ( int i = 0; i < 256; i++ ) {
- ramp[i] = (i * v / max) << 8;
- }
- // FIXME SDL_SetWindowGammaRamp(window, ramp, ramp, ramp);
+ for ( int i = 1; i <= max; ++i ) {
+ int v = faded ? i : max - i;
+ value = (Uint8)(255 * v / max);
+ SDL_SetTextureColorMod(target, value, value, value);
+ Update();
SDL_Delay(10);
}
faded = !faded;
-
- if ( faded ) {
- for ( int i = 0; i < 256; i++ ) {
- ramp[i] = 0;
- }
- // FIXME SDL_SetWindowGammaRamp(window, ramp, ramp, ramp);
- }
#endif
}
@@ -318,32 +332,3 @@ FrameBuf::FreeImage(SDL_Texture *image)
SDL_DestroyTexture(image);
}
-SDL_Texture *
-FrameBuf::CreateRenderTarget(int w, int h)
-{
- SDL_Texture *texture;
-
- texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_XRGB8888,
- SDL_TEXTUREACCESS_TARGET, w, h);
- if (!texture) {
- SetError("Couldn't create target texture: %s", SDL_GetError());
- return NULL;
- }
- return texture;
-}
-
-int
-FrameBuf::SetRenderTarget(SDL_Texture *texture)
-{
- if (!SDL_SetRenderTarget(renderer, texture)) {
- SetError("Couldn't set render target: %s", SDL_GetError());
- return(-1);
- }
- return 0;
-}
-
-void
-FrameBuf::FreeRenderTarget(SDL_Texture *texture)
-{
- SDL_DestroyTexture(texture);
-}
diff --git a/screenlib/SDL_FrameBuf.h b/screenlib/SDL_FrameBuf.h
index 710e56c5..d5ecab7a 100644
--- a/screenlib/SDL_FrameBuf.h
+++ b/screenlib/SDL_FrameBuf.h
@@ -181,12 +181,6 @@ class FrameBuf : public ErrorBase {
}
void FreeImage(SDL_Texture *image);
- /* Create a render target */
- SDL_Texture *CreateRenderTarget(int w, int h);
- int SetRenderTarget(SDL_Texture *texture);
- void FreeRenderTarget(SDL_Texture *texture);
-
-
/* Screen dump routines */
int ScreenDump(const char *prefix, int x, int y, int w, int h);
@@ -204,9 +198,10 @@ class FrameBuf : public ErrorBase {
private:
/* The current display */
- SDL_Window *window;
- SDL_Renderer *renderer;
- int faded;
+ SDL_Window *window = nullptr;
+ SDL_Renderer *renderer = nullptr;
+ SDL_Texture *target = nullptr;
+ bool faded = false;
SDL_Rect rect;
SDL_FRect clip;
SDL_Rect output;