kobodl/dashboard.cpp
Ville Lindholm 8d57d63da2
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>
2026-05-28 22:12:40 +03:00

452 lines
7.9 KiB
C++

/*(GPL)
------------------------------------------------------------
Kobo Deluxe - An enhanced SDL port of XKobo
------------------------------------------------------------
* Copyright (C) 2003, 2007 David Olofson
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "config.h"
#include "kobo.h"
#include "random.h"
#include <stdlib.h>
#include <string.h>
#define MAX_PROGRESS 1000
/*----------------------------------------------------------
Screen
----------------------------------------------------------*/
void screen_window_t::border(int top, int left, int right, int bottom)
{
_top = top;
_left = left;
_right = right;
_bottom = bottom;
}
void screen_window_t::refresh(SDL_Rect *r)
{
int x, y, w, h;
foreground(map_rgb(0x000000));
x = 0;
y = 0;
w = width();
h = _top;
fillrect(x, y, w, h);
y = height() - _bottom;
h = _bottom;
fillrect(x, y, w, h);
y = _top;
w = _left;
h = height() - _top - _bottom;
fillrect(x, y, w, h);
x = width() - _right;
w = _right;
fillrect(x, y, w, h);
}
/*----------------------------------------------------------
Dashboard
----------------------------------------------------------*/
dashboard_window_t::dashboard_window_t()
{
_mode = DASHBOARD_BLACK;
_percent = 0.0f;
_msg = NULL;
}
dashboard_window_t::~dashboard_window_t()
{
free(_msg);
}
void dashboard_window_t::mode(dashboard_modes_t m)
{
int vis;
_mode = m;
switch(_mode)
{
case DASHBOARD_GAME:
vis = 1;
break;
default:
vis = 0;
break;
}
wmain->visible(vis);
whealth->visible(vis);
wtemp->visible(vis);
wttemp->visible(vis);
wradar->visible(vis);
dhigh->visible(vis);
dscore->visible(vis);
dstage->visible(vis);
dships->visible(vis);
switch(_mode)
{
case DASHBOARD_OFF:
break;
default:
gengine->invalidate();
gengine->flip();
gengine->invalidate();
gengine->flip();
gengine->invalidate();
break;
}
}
void dashboard_window_t::doing(const char *msg)
{
free(_msg);
_msg = strdup(msg);
invalidate();
gengine->flip();
}
void dashboard_window_t::progress_init(float *progtab)
{
if(!progtab)
{
progress_table = (float *)malloc(MAX_PROGRESS * sizeof(float));
progress_bench = (progress_table != NULL);
}
else
{
progress_table = progtab;
progress_bench = 0;
}
progress_index = 0;
}
void dashboard_window_t::progress()
{
if(progress_table)
{
if(progress_bench)
{
progress_table[progress_index++] = (float)SDL_GetTicks();
_percent = 0.0f;
}
else
_percent = progress_table[progress_index++];
}
else
_percent = 50.0f;
invalidate();
gengine->flip();
}
void dashboard_window_t::progress_done()
{
if(progress_bench)
{
int i;
int total = SDL_GetTicks() - (int)progress_table[0];
printf("Progress percentages:\n");
printf("---------------------\n");
for(i = 0; i < progress_index; ++i)
printf("\t%f,\n", (progress_table[i] -
progress_table[0]) * 100.0f / total);
printf("---------------------\n");
free(progress_table);
progress_bench = 0;
}
progress_table = NULL;
}
void dashboard_window_t::render_progress()
{
SDL_Rect r;
int x, y, w, h;
x = 0;
w = (int)(_percent * 0.01f * width() + 0.5f);
if(w < 4)
w = 4;
else if(w > width())
w = width();
h = 16;
y = height() - h;
r.x = x;
r.y = y;
r.w = w;
r.h = h;
foreground(map_rgb(0x000099));
rectangle(x, y, w, h);
++x;
++y;
w -= 2;
h -= 2;
foreground(map_rgb(0x0000cc));
rectangle(x, y, w, h);
++x;
++y;
w -= 2;
h -= 2;
foreground(map_rgb(0x0000ff));
fillrect(x, y, w, h);
r.x = 0;
r.y = height() - 40;
r.w = width();
r.h = 12;
foreground(map_rgb(0x000000));
fillrect(r.x, r.y, r.w, r.h);
if(_msg)
{
font(B_NORMAL_FONT);
center(height() - 40, _msg);
}
}
#define NIBBLE_W 4
#define NIBBLE_H 4
#define NIBBLE_TILES ((SCREEN_WIDTH/NIBBLE_W+1)*(SCREEN_HEIGHT/NIBBLE_H+1))
void dashboard_window_t::nibble(int tool)
{
int i;
int x[NIBBLE_TILES];
int y[NIBBLE_TILES];
mode(DASHBOARD_OFF);
if(tool < 0)
tool = (pubrand.get(20) + SDL_GetTicks()) % 5;
/* Clear */
for(i = 0; i < NIBBLE_TILES; ++i)
x[i] = y[i] = -1;
/* Fill in */
int ind = 0;
int xx = -NIBBLE_W / 2;
int yy = -NIBBLE_H / 2;
for(i = 0; i < NIBBLE_TILES; ++i)
{
ind = pubrand.get() % NIBBLE_TILES;
if(ind >= NIBBLE_TILES)
ind = 0;
while(x[ind] != -1)
if(++ind >= NIBBLE_TILES)
ind = 0;
x[ind] = xx;
y[ind] = yy;
xx += NIBBLE_W;
if(xx >= SCREEN_WIDTH + NIBBLE_W / 2)
{
xx = -NIBBLE_W / 2;
yy += NIBBLE_H;
}
}
/* Clear 8000 tiles/second, until all are done. */
foreground(map_rgb(0x000000));
ind = 0;
int last_index;
int t = SDL_GetTicks();
while(ind < NIBBLE_TILES)
{
int nt = SDL_GetTicks();
int dt = nt - t;
t = nt;
last_index = ind; /* For double buffer mode */
for(i = 0; i < dt * 8; ++i)
{
if(ind >= NIBBLE_TILES)
break;
switch (tool)
{
case 0:
fillrect(x[ind] + NIBBLE_W / 2,
y[ind] + NIBBLE_H / 2,
NIBBLE_W, NIBBLE_H);
break;
default:
sprite(x[ind] - 8 + NIBBLE_W / 2,
y[ind] - 8 +
NIBBLE_H / 2, B_BRUSHES,
tool - 1);
break;
}
++ind;
}
gengine->invalidate();
gengine->flip();
// 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)
{
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;
}
}
mode(DASHBOARD_BLACK);
gengine->flip();
}
void dashboard_window_t::refresh(SDL_Rect *r)
{
switch(_mode)
{
case DASHBOARD_OFF:
break;
case DASHBOARD_BLACK:
background(map_rgb(0x000000));
clear();
break;
case DASHBOARD_GAME:
sprite(0, 0, B_SCREEN, 0);
break;
case DASHBOARD_LOADING:
background(map_rgb(0x000000));
clear();
sprite((width() - 250) / 2, 55, B_LOADING, 0);
render_progress();
break;
}
}
/*----------------------------------------------------------
Bar graph display
----------------------------------------------------------*/
bargraph_t::bargraph_t()
{
_value = 0.0f;
_redmax = 1;
_y = -1000;
_enabled = 1;
}
void bargraph_t::value(float val)
{
if(val < 0.0f)
_value = 0.0f;
else
_value = val;
if(!_enabled)
return;
int y = (int)((height() - 2) * _value);
if(y != _y)
invalidate();
}
void bargraph_t::enable(int ena)
{
_enabled = ena;
invalidate();
}
void bargraph_t::refresh(SDL_Rect *r)
{
if(!_enabled)
{
clear();
return;
}
float v = _value;
int red, green, blue;
if(v > 1.0f)
{
blue = 50 + (v - 1.0f) * 512;
if(_redmax)
{
red = 255;
green = blue / 2;
}
else
{
green = 255;
red = blue / 2;
}
v = 1.0f;
}
else
{
if(_redmax)
{
red = (int)(v * 300.0);
green = (int)((1.0 - v) * 400.0);
}
else
{
red = (int)((1.0 - v) * 300.0);
green = (int)(v * 400.0);
}
blue = 50;
}
if(green > 180)
green = 180;
if(red > 230)
red = 230;
if(blue > 255)
blue = 255;
_y = (int)((height() - 2) * (1.0f - v));
foreground(bgcolor);
fillrect(0, 0, width(), height());
foreground(map_rgb(red, green, blue));
fillrect(1, _y + 1, width() - 2, height() - _y - 2);
}