Phase 9 cleanup: rip out SDL 1.2 video knobs no SDL 3 path uses

After the SDL 3 renderer migration, the engine has exactly one back
buffer (a CPU-side ARGB8888 SDL_Surface) and one presentation path
(upload to streaming SDL_Texture, RenderPresent). All the SDL 1.2
hardware-surface / page-flipping / depth / driver knobs were dead.

Removed from gfxengine_t:
- _doublebuf, doublebuffer() setter+getter
- _pages, pages() setter
- _shadow, shadow() setter+getter
- _depth + the depth argument processing in mode()
- _driver, driver() setter, gfx_drivers_t enum, GFX_DRIVER_SDL2D
- xflags + the extraflags parameter to open()
- broken_rgba8 (the OpenGL RGBA→RGBA4 workaround field)
- MAX_PAGES + backpage/frontpage + the per-page dirtyrects[]/
  dirtytable[]/dirtywtable[] arrays. Collapsed to 1-D dirtytable.
- __invalidate(int page, ...) → __invalidate(rect, window).
- The per-page invalidate() switch on _pages.
- vsync() now hot-applies via SDL_SetRenderVSync (no hide/show cycle).
- mode() keeps the int-bits arg for API compat but ignores it.

Removed from prefs_t:
- videodriver, depth, doublebuf, shadow, pages, broken_rgba8.
  Their config-file keys are now read as obsolete fields (silently
  consumed, never re-written) so existing config files load cleanly
  without breaking on unknown keys.

Removed from the options menu:
- Display Depth, Display Buffering Mode, Software Shadow Buffer,
  Display Buffer Pages, Broken RGBA8.

Removed from the escape-hammering safe-video-mode reset path the
fields that no longer exist (doublebuf, pages, shadow, depth,
videodriver).

dashboard.cpp: dropped the doublebuffer()-guarded second pass of the
loading-animation nibble draw; SDL 3's single back buffer doesn't
need it.

Build clean, binary still runs.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ville Lindholm 2026-05-28 22:12:40 +03:00
parent acb3925bb4
commit 8d57d63da2
No known key found for this signature in database
GPG Key ID: 89AE9EAA3B6FDE7C
8 changed files with 76 additions and 229 deletions

View File

@ -309,33 +309,32 @@ void dashboard_window_t::nibble(int tool)
}
gengine->invalidate();
gengine->flip();
if(gengine->doublebuffer())
// SDL 3: one logical back buffer; previously a second pass was
// only needed when actual hardware double-buffering was in use.
for(i = 0; i < dt * 4; ++i)
{
for(i = 0; i < dt * 4; ++i)
if(last_index >= NIBBLE_TILES)
break;
switch (tool)
{
if(last_index >= NIBBLE_TILES)
break;
switch (tool)
{
case 0:
fillrect(x[last_index] +
NIBBLE_W / 2,
y[last_index] +
NIBBLE_H / 2,
NIBBLE_W,
NIBBLE_H);
break;
default:
sprite(x[last_index] - 8 +
NIBBLE_W / 2,
y[last_index] - 8 +
NIBBLE_H / 2,
B_BRUSHES,
tool - 1);
break;
}
++last_index;
case 0:
fillrect(x[last_index] +
NIBBLE_W / 2,
y[last_index] +
NIBBLE_H / 2,
NIBBLE_W,
NIBBLE_H);
break;
default:
sprite(x[last_index] - 8 +
NIBBLE_W / 2,
y[last_index] - 8 +
NIBBLE_H / 2,
B_BRUSHES,
tool - 1);
break;
}
++last_index;
}
}
mode(DASHBOARD_BLACK);

View File

@ -54,15 +54,10 @@ gfxengine_t::gfxengine_t()
sf1 = df = dsf = acf = NULL;
gfx = NULL;
csengine = NULL;
_driver = GFX_DRIVER_SDL2D;
_shadow = 1;
_doublebuf = 1;
_pages = -1;
_vsync = 1;
_fullscreen = 0;
_centered = 0;
use_interpolation = 1;
_depth = 0;
_title = "GfxEngine v0.4";
_icontitle = "GfxEngine";
_cursor = 1;
@ -71,11 +66,9 @@ gfxengine_t::gfxengine_t()
_autoinvalidate = 1;
_scalemode = GFX_SCALE_NEAREST;
_clamping = 0;
xflags = 0;
_dither = 0;
_dither_type = 0;
broken_rgba8 = 0;
alpha_threshold = 0;
_brightness = 1.0;
@ -94,10 +87,7 @@ gfxengine_t::gfxengine_t()
for(int i = 0; i < CS_LAYERS ; ++i)
xratio[i] = yratio[i] = 0.0;
dirtyrects[0] = 0;
dirtyrects[1] = 0;
frontpage = 0;
backpage = 1;
dirtyrects = 0;
screenshot_count = 0;
}
@ -160,75 +150,23 @@ void gfxengine_t::scale(float x, float y)
void gfxengine_t::mode(int bits, int fullscreen)
{
// SDL 3 uses the renderer's pixel format directly; the legacy depth
// argument is accepted for API compatibility but ignored.
(void)bits;
int was_showing = is_showing;
hide();
int olddepth = _depth;
_depth = bits;
if(_depth != olddepth)
reload();
_fullscreen = fullscreen;
if(was_showing)
show();
}
void gfxengine_t::driver(gfx_drivers_t drv)
{
int was_showing = is_showing;
hide();
_driver = drv;
if(was_showing)
show();
}
void gfxengine_t::doublebuffer(int use)
{
if(_doublebuf == use)
return;
int was_showing = is_showing;
hide();
_doublebuf = use;
if(was_showing)
show();
}
void gfxengine_t::pages(int np)
{
_pages = np;
}
void gfxengine_t::vsync(int use)
{
if(_vsync == use)
return;
int was_showing = is_showing;
hide();
_vsync = use;
if(was_showing)
show();
}
void gfxengine_t::shadow(int use)
{
if(_shadow == use)
return;
int was_showing = is_showing;
hide();
_shadow = use;
if(was_showing)
show();
if(sdl_renderer)
SDL_SetRenderVSync(sdl_renderer, use ? 1 : 0);
}
void gfxengine_t::autoinvalidate(int use)
@ -435,9 +373,9 @@ void gfxengine_t::clampcolor(Uint8 r, Uint8 g, Uint8 b, Uint8 a)
void gfxengine_t::dither(int type, int _broken_rgba8)
{
(void)_broken_rgba8; // legacy OpenGL workaround; no-op in SDL 3
_dither = type >= 0;
_dither_type = type;
broken_rgba8 = _broken_rgba8;
if(!df)
return;
@ -678,10 +616,8 @@ void gfxengine_t::on_frame(cs_engine_t *e)
}
int gfxengine_t::open(int objects, int extraflags)
int gfxengine_t::open(int objects)
{
xflags = extraflags;
if(is_open)
return show();
@ -917,42 +853,23 @@ void gfxengine_t::hide(void)
void gfxengine_t::invalidate(SDL_Rect *rect, window_t *window)
{
switch(_pages)
{
case -1:
if(_doublebuf)
__invalidate(1, rect, window);
__invalidate(0, rect, window);
break;
case 0:
__invalidate(0, NULL, NULL);
break;
case 3:
__invalidate(2, rect, window);
// Fallthrough!
case 2:
__invalidate(1, rect, window);
// Fallthrough!
case 1:
__invalidate(0, rect, window);
break;
}
__invalidate(rect, window);
}
void gfxengine_t::__invalidate(int page, SDL_Rect *rect, window_t *window)
void gfxengine_t::__invalidate(SDL_Rect *rect, window_t *window)
{
if(!screen_surface)
return;
if(!rect || (_pages == 0))
if(!rect)
{
dirtyrects[page] = 1;
dirtytable[page][0].x = 0;
dirtytable[page][0].y = 0;
dirtytable[page][0].w = screen_surface->w;
dirtytable[page][0].h = screen_surface->h;
dirtywtable[page][0] = NULL;
dirtyrects = 1;
dirtytable[0].x = 0;
dirtytable[0].y = 0;
dirtytable[0].w = screen_surface->w;
dirtytable[0].h = screen_surface->h;
dirtywtable[0] = NULL;
return;
}
@ -989,19 +906,18 @@ void gfxengine_t::__invalidate(int page, SDL_Rect *rect, window_t *window)
if(!dr.w || !dr.h)
return;
for(int i = 0; i < dirtyrects[page]; ++i)
if(memcmp(&dirtytable[page][i], &dr, sizeof(dr)) == 0)
for(int i = 0; i < dirtyrects; ++i)
if(memcmp(&dirtytable[i], &dr, sizeof(dr)) == 0)
return;
if(dirtyrects[page] < MAX_DIRTYRECTS - 1)
if(dirtyrects < MAX_DIRTYRECTS - 1)
{
dirtytable[page][dirtyrects[page]] = dr;
dirtywtable[page][dirtyrects[page]] = window;
++dirtyrects[page];
dirtytable[dirtyrects] = dr;
dirtywtable[dirtyrects] = window;
++dirtyrects;
}
else
log_printf(ELOG, "gfxengine: Page %d out of dirtyrects!\n",
page);
log_printf(ELOG, "gfxengine: Out of dirtyrects!\n");
}
@ -1268,20 +1184,19 @@ void gfxengine_t::flip()
// buffer per frame. Keep the dirtyrect iteration only to drive the
// phys_refresh() callbacks that window widgets rely on; the upload
// is a single full-surface copy regardless.
frontpage = backpage = 0;
for(int i = 0; i < dirtyrects[backpage]; ++i)
for(int i = 0; i < dirtyrects; ++i)
{
if(dirtywtable[backpage][i])
if(dirtywtable[i])
{
if(!dirtywtable[backpage][i]->visible())
if(!dirtywtable[i]->visible())
continue;
SDL_Rect dr = dirtytable[backpage][i];
dirtywtable[backpage][i]->phys_refresh(&dr);
SDL_Rect dr = dirtytable[i];
dirtywtable[i]->phys_refresh(&dr);
}
else
refresh_rect(&dirtytable[backpage][i]);
refresh_rect(&dirtytable[i]);
}
dirtyrects[backpage] = 0;
dirtyrects = 0;
SDL_UpdateTexture(fb_texture, NULL, softbuf->pixels, softbuf->pitch);
SDL_RenderClear(sdl_renderer);

View File

@ -24,7 +24,6 @@
#define GFX_BANKS 256
#define MAX_DIRTYRECTS 1024
#define MAX_PAGES 3
#include <stdio.h>
#include <stdlib.h>
@ -33,11 +32,6 @@
#include "sprite.h"
#include "cs.h"
enum gfx_drivers_t
{
GFX_DRIVER_SDL2D = 0
};
enum gfx_scalemodes_t
{
GFX_SCALE_NEAREST = 0,
@ -69,25 +63,11 @@ class gfxengine_t
void size(int w, int h);
void centered(int c);
void scale(float x, float y);
void driver(gfx_drivers_t drv);
void mode(int bits, int fullscreen);
// 1: Use double buffering if possible
void doublebuffer(int use);
// -1: Use default for shadow() and doublebuffer() settings
// 0: None; assume flipping gives you a garbage buffer
// 1: Assume flipping leaves the back buffer intact
// 2: Assume two buffers that are swapped when flipping
// 3: Assume three buffers cycled when flipping
void pages(int np);
// 1: Enable vsync, if available
void vsync(int use);
// 1: Use a software shadow back buffer, if possible
void shadow(int use);
void autoinvalidate(int use);
void interpolation(int inter);
@ -102,12 +82,10 @@ class gfxengine_t
void wrap(int x, int y);
/* Info */
int doublebuffer() { return _doublebuf; }
int shadow() { return _shadow; }
int autoinvalidate() { return _autoinvalidate; }
/* Engine open/close */
int open(int objects = 1024, int extraflags = 0);
int open(int objects = 1024);
void close();
/* Data management (use while engine is open) */
@ -206,7 +184,6 @@ class gfxengine_t
float yscale() { return ys * (1.f/256.f); }
protected:
gfx_drivers_t _driver;
gfx_scalemodes_t _scalemode;
int _clamping;
SDL_Window *sdl_window;
@ -214,11 +191,9 @@ class gfxengine_t
SDL_Texture *fb_texture;
SDL_Surface *screen_surface; // alias for softbuf in SDL 3
SDL_Surface *softbuf;
int backpage;
int frontpage;
int dirtyrects[MAX_PAGES];
SDL_Rect dirtytable[MAX_PAGES][MAX_DIRTYRECTS];
window_t *dirtywtable[MAX_PAGES][MAX_DIRTYRECTS];
int dirtyrects;
SDL_Rect dirtytable[MAX_DIRTYRECTS];
window_t *dirtywtable[MAX_DIRTYRECTS];
window_t *fullwin;
window_t *window;
window_t *windows; // Linked list
@ -236,23 +211,17 @@ class gfxengine_t
s_container_t *gfx;
SoFont *fonts[GFX_BANKS]; // Kludge.
cs_engine_t *csengine;
int xflags;
int _doublebuf;
int _pages;
int _vsync;
int _shadow;
int _fullscreen;
int _centered;
int _autoinvalidate;
int use_interpolation;
int _width, _height;
int _depth;
const char *_title;
const char *_icontitle;
int _cursor;
int _dither;
int _dither_type;
int broken_rgba8; //Klugde for OpenGL (if RGBA8 ==> RGBA4)
int alpha_threshold; //For noalpha()
float _brightness;
float _contrast;
@ -267,8 +236,7 @@ class gfxengine_t
int screenshot_count;
void __invalidate(int page, SDL_Rect *rect = NULL,
window_t *window = NULL);
void __invalidate(SDL_Rect *rect = NULL, window_t *window = NULL);
void refresh_rect(SDL_Rect *r);
static void on_frame(cs_engine_t *e);

View File

@ -635,7 +635,6 @@ int KOBO_main::init_display(prefs_t *p)
int dw, dh; // Display size
int gw, gh; // Game "window" size
gengine->title("Kobo Deluxe " VERSION, "kobodl");
gengine->driver((gfx_drivers_t)p->videodriver);
dw = p->width;
dh = p->height;
@ -689,10 +688,7 @@ int KOBO_main::init_display(prefs_t *p)
gengine->size(dw, dh);
gengine->mode(0, p->fullscreen);
gengine->doublebuffer(p->doublebuf);
gengine->pages(p->pages);
gengine->vsync(p->vsync);
gengine->shadow(p->shadow);
gengine->cursor(0);
gengine->period(game.speed);
@ -1086,7 +1082,7 @@ int KOBO_main::load_graphics(prefs_t *p)
if(gd->flags & KOBO_NODITHER || !p->use_dither)
gengine->dither(-1);
else
gengine->dither(p->dither_type, p->broken_rgba8);
gengine->dither(p->dither_type, 0);
// Alpha channels
if(gd->flags & KOBO_NOALPHA || !p->alpha)
@ -1658,14 +1654,9 @@ void kobo_gfxengine_t::frame()
{
km.pause_game();
prefs->fullscreen = 0;
prefs->videodriver = (int)GFX_DRIVER_SDL2D;
prefs->width = 640;
prefs->height = 480;
prefs->aspect = 1000;
prefs->depth = 0;
prefs->doublebuf = 0;
prefs->pages = -1;
prefs->shadow = 1;
prefs->scalemode = (int)GFX_SCALE_NEAREST;
prefs->brightness = 100;
prefs->contrast = 100;

View File

@ -177,29 +177,7 @@ void video_options_t::build()
}
space();
yesno("Fullscreen Display", &prf->fullscreen, OS_RESTART_VIDEO);
list("Display Depth", &prf->depth, OS_RESTART_VIDEO);
item("Default", 0);
item("8 bits", 8);
item("15 bits", 15);
item("16 bits", 16);
item("24 bits", 24);
item("32 bits", 32);
prf->videodriver = GFX_DRIVER_SDL2D;
space();
xoffs = 0.55;
// Only the SDL 2D driver remains since the SDL 3 migration; the
// OpenGL driver is now handled by the SDL renderer itself.
list("Display Buffering Mode", &prf->doublebuf, OS_RESTART_VIDEO);
item("Single", 0);
item("Double", 1);
yesno("Software Shadow Buffer", &prf->shadow, OS_RESTART_VIDEO);
yesno("Vertical Retrace Sync", &prf->vsync, OS_RESTART_VIDEO);
list("Display Buffer Pages", &prf->pages, OS_UPDATE_ENGINE);
item("Assume Standard", -1);
item("Always Repaint", 0);
item("Single", 1);
item("Double", 2);
item("Triple", 3);
big();
space();
xoffs = 0.5;

View File

@ -82,25 +82,18 @@ void prefs_t::init()
comment("--- Video settings -------------------------");
yesno("fullscreen", fullscreen, 0); desc("Fullscreen Display");
key("videodriver", videodriver, GFX_DRIVER_SDL2D);
desc("Display Driver");
key("width", width, 640); desc("Horizontal Resolution");
key("height", height, 480); desc("Vertical Resolution");
key("aspect", aspect, 1000); desc("Pixel Aspect Ratio");
key("depth", depth, 0); desc("Display Depth");
key("maxfps", max_fps, 100); desc("Maximum fps");
key("maxfpsstrict", max_fps_strict, 0); desc("Strictly Regulated fps");
key("buffer", doublebuf, 1); desc("Display Buffer Mode");
yesno("shadow", shadow, 1); desc("Use Software Shadow Buffer");
key("videomode", videomode, 0x04330); desc("Video Mode");
yesno("vsync", vsync, 1); desc("Enable Vertical Sync");
key("videopages", pages, -1); desc("Number of Video Pages");
comment("--- Graphics settings ----------------------");
key("scalemode", scalemode, 1); desc("Scaling Filter Mode");
yesno("dither", use_dither, 1); desc("Use Dithering");
key("dither_type", dither_type, 0); desc("Dither Type");
yesno("broken_rgba8", broken_rgba8, 0); desc("Broken RGBA (OpenGL)");
yesno("alpha", alpha, 1); desc("Use Alpha Blending");
key("brightness", brightness, 100); desc("Brightness");
key("contrast", contrast, 100); desc("Contrast");
@ -120,6 +113,14 @@ void prefs_t::init()
key("release", o_release, 50, 0); desc("Limiter Speed");
key("internalres", o_internalres, 1, 0); desc("Texture Resolution");
// SDL 1.2-era video keys, ignored under SDL 3.
key("videodriver", o_videodriver, 0, 0); desc("Display Driver");
key("depth", o_depth, 0, 0); desc("Display Depth");
key("buffer", o_doublebuf, 1, 0); desc("Display Buffer Mode");
yesno("shadow", o_shadow, 1, 0); desc("Software Shadow Buffer");
key("videopages", o_pages, -1, 0); desc("Number of Video Pages");
yesno("broken_rgba8", o_broken_rgba8, 0, 0); desc("Broken RGBA (OpenGL)");
comment("--- Temporary variables --------------------");
key("last_profile", last_profile, 0);
desc("Last used player profile");
@ -170,9 +171,4 @@ void prefs_t::postload()
log_printf(ELOG, "Radar sweep mode broken and disabled!\n");
scrollradar = 2;
}
// Only the SDL 2D driver remains since the SDL 3 migration; collapse
// any legacy GLSDL setting onto it.
if(videodriver != GFX_DRIVER_SDL2D)
videodriver = GFX_DRIVER_SDL2D;
}

15
prefs.h
View File

@ -73,24 +73,18 @@ class prefs_t : public config_parser_t
//Video settings
int fullscreen; //Use fullscreen mode
int videodriver; //Internal video driver
int width; //Screen/window width
int height; //Screen/window height
int aspect; //Pixel aspect ratio * 1000
int depth; //Bits per pixel
int max_fps; //Maximum fps
int max_fps_strict; //Strictly regulated fps limiter
int doublebuf; //Use double buffering
int shadow; //Use software shadow buffer
int videomode; //New video mode codes
int videomode; //Selected entry from the vidmodes table
int vsync; //Vertical (retrace) sync
int pages; //Number of physical video pages
//Graphics settings
int scalemode; //Scaling filter mode
int use_dither;
int dither_type;
int broken_rgba8; //For some OpenGL setups
int alpha; //Alpha blending
int brightness; //Graphics brightness
int contrast; //Graphics contrast
@ -108,6 +102,13 @@ class prefs_t : public config_parser_t
int o_threshold; //Limiter threshold
int o_release; //Limiter release rate
int o_internalres; //Internal resolution for OpenGL
// SDL 1.2 video settings, read for back-compat but unused under SDL 3
int o_videodriver;
int o_depth;
int o_doublebuf;
int o_shadow;
int o_pages;
int o_broken_rgba8;
//"Hidden" stuff ("to remember until next startup")
int last_profile; //Last used player profile

View File

@ -1600,7 +1600,6 @@ void st_options_base_t::select(int tag)
gengine->timefilter(prefs->timefilter * 0.01f);
gengine->interpolation(prefs->filter);
gengine->vsync(prefs->vsync);
gengine->pages(prefs->pages);
}
cfg_form->clearstatus(OS_UPDATE);