WIP: port renderer + supporting layers to SDL 3 (builds clean)
Completes phases 3-6 of the migration plan. After this commit, the
codebase compiles and links against pure SDL 3 (no compat shim). The
binary is unverified at runtime but the build is clean.
Renderer (graphics/gfxengine.{cpp,h}):
- Replace SDL_SetVideoMode + SDL_Flip + page-flip machinery with
SDL_CreateWindow + SDL_CreateRenderer + a streaming SDL_Texture.
The CPU-side back buffer (softbuf) is now always ARGB8888; legacy
HW/double-buffer/page flags are dead.
- flip() does a single full-frame SDL_UpdateTexture + SDL_RenderClear
+ SDL_RenderTexture + SDL_RenderPresent each frame. The dirtyrect
iteration is retained only to drive widget phys_refresh() callbacks.
- SDL_SetRenderLogicalPresentation gives us letterbox scaling for free.
- SDL_SetRenderVSync replaces glSDL_VSync.
- title()/cursor() ported to SDL 3 window/cursor APIs.
Surface API (graphics/sprite.c, filters.c, window.cpp, sofont.cpp,
region.c):
- SDL_FreeSurface → SDL_DestroySurface
- SDL_FillRect → SDL_FillSurfaceRect
- SDL_SetClipRect → SDL_SetSurfaceClipRect
- SDL_SetColorKey(s, flags, key) → SDL_SetSurfaceColorKey(s, bool, key)
- SDL_SetAlpha(s, flags, a) → SDL_SetSurfaceAlphaMod + BlendMode
- SDL_SetColors → SDL_SetSurfacePalette
- SDL_CreateRGBSurface(...) → SDL_CreateSurface(w, h, format_enum)
- SDL_DisplayFormat[Alpha] → SDL_ConvertSurface(s, ARGB8888)
- SDL_MapRGB(surf->format, ...) → SDL_MapSurfaceRGB(surf, ...)
- surface->format->Field → SDL_GetPixelFormatDetails(surf->format)->field
- surface->format->Amask test → SDL_ISPIXELFORMAT_ALPHA
- surface->clip_rect → SDL_GetSurfaceClipRect
Events (kobo.cpp):
- SDL_{KEYDOWN,KEYUP,QUIT,VIDEOEXPOSE,MOUSE*,JOY*} → SDL_EVENT_*
- SDL_ACTIVEEVENT (with gain check) → SDL_EVENT_WINDOW_FOCUS_LOST
- ev.key.keysym.sym → ev.key.key (.unicode → text input, deferred)
- SDLK_PRINT/SYSREQ → SDLK_PRINTSCREEN; lowercase SDLK_p/y/n → uppercase
- ev.motion.x/y for button events → ev.button.x/y (struct layout differs)
- KMOD_META → SDL_KMOD_GUI
- SDL_INIT_NOPARACHUTE → SDL_Init(0) (no parachute by default in SDL 3)
Keymap (gamectl.{cpp,h}):
- SDLKey → SDL_Keycode
- SDLK_KP{1..9} → SDLK_KP_{1..9}
Stubs deferred for later phases (binary will run but with degraded
behavior):
- sound/audio.c: _start_SDL_output returns -1 immediately; SDL 1.2
audio callback model needs full rewrite onto SDL_AudioStream.
- kobo.cpp init_js/close_js: SDL 3 joystick API uses instance IDs;
re-port deferred.
- states.cpp SDL_WM_GrabInput/SDL_EnableUNICODE: need window pointer
exposed from gfxengine; stubbed.
- gamectl.cpp SDL_EnableKeyRepeat: removed; relies on ev.key.repeat.
Other adjustments:
- options.cpp: GFX_DRIVER_GLSDL menu paths removed; show vsync option
always (renderer handles it).
- sound/a_wave.c: AUDIO_S8/AUDIO_S16SYS → SDL_AUDIO_S8/S16, SDL_FreeWAV
→ SDL_free.
- gfxengine.cpp: SDL_putenv("SDL_VIDEO_CENTERED=1") obsolete (handled
by SDL_CreateWindow defaults).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
762b095462
commit
f11b6516da
18
gamectl.cpp
18
gamectl.cpp
@ -54,7 +54,10 @@ void gamecontrol_t::init(int always_fire)
|
|||||||
down = 0;
|
down = 0;
|
||||||
shot = 0;
|
shot = 0;
|
||||||
movekey_pressed = 0;
|
movekey_pressed = 0;
|
||||||
SDL_EnableKeyRepeat(r_delay, r_interval);
|
// SDL 3 removed SDL_EnableKeyRepeat; OS-level key repeat fires
|
||||||
|
// SDL_EVENT_KEY_DOWN with ev.key.repeat set. r_delay/r_interval
|
||||||
|
// retained in case we re-implement software repeat later.
|
||||||
|
(void)r_delay; (void)r_interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -68,9 +71,8 @@ void gamecontrol_t::repeat(int delay, int interval)
|
|||||||
{
|
{
|
||||||
r_delay = delay;
|
r_delay = delay;
|
||||||
r_interval = interval;
|
r_interval = interval;
|
||||||
//Temporary kludge - should apply repeat to
|
// SDL_EnableKeyRepeat is gone in SDL 3. Stored for future
|
||||||
//all switch inputs, not just the keyboard!
|
// software-side repeat handling.
|
||||||
SDL_EnableKeyRepeat(delay, interval);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -80,7 +82,7 @@ void gamecontrol_t::clear()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int gamecontrol_t::map(SDLKey sym)
|
int gamecontrol_t::map(SDL_Keycode sym)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
FIXME: This should be replaced by a configurable mapping system.
|
FIXME: This should be replaced by a configurable mapping system.
|
||||||
@ -137,7 +139,7 @@ FIXME: This should be replaced by a configurable mapping system.
|
|||||||
case SDLK_ESCAPE:
|
case SDLK_ESCAPE:
|
||||||
return BTN_EXIT;
|
return BTN_EXIT;
|
||||||
case SDLK_PAUSE:
|
case SDLK_PAUSE:
|
||||||
case SDLK_p:
|
case SDLK_P:
|
||||||
return BTN_PAUSE;
|
return BTN_PAUSE;
|
||||||
case SDLK_SPACE:
|
case SDLK_SPACE:
|
||||||
return BTN_START;
|
return BTN_START;
|
||||||
@ -148,9 +150,9 @@ FIXME: This should be replaced by a configurable mapping system.
|
|||||||
return BTN_INC;
|
return BTN_INC;
|
||||||
case SDLK_KP_MINUS:
|
case SDLK_KP_MINUS:
|
||||||
return BTN_DEC;
|
return BTN_DEC;
|
||||||
case SDLK_y:
|
case SDLK_Y:
|
||||||
return BTN_YES;
|
return BTN_YES;
|
||||||
case SDLK_n:
|
case SDLK_N:
|
||||||
return BTN_NO;
|
return BTN_NO;
|
||||||
case SDLK_BACKSPACE:
|
case SDLK_BACKSPACE:
|
||||||
return BTN_BACK;
|
return BTN_BACK;
|
||||||
|
|||||||
18
gamectl.h
18
gamectl.h
@ -26,14 +26,14 @@
|
|||||||
#include "sdl_compat.h"
|
#include "sdl_compat.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#define KEY_KP_DOWN SDLK_KP2
|
#define KEY_KP_DOWN SDLK_KP_2
|
||||||
#define KEY_KP_LEFT SDLK_KP4
|
#define KEY_KP_LEFT SDLK_KP_4
|
||||||
#define KEY_KP_UP SDLK_KP8
|
#define KEY_KP_UP SDLK_KP_8
|
||||||
#define KEY_KP_RIGHT SDLK_KP6
|
#define KEY_KP_RIGHT SDLK_KP_6
|
||||||
#define KEY_KP_DL SDLK_KP1
|
#define KEY_KP_DL SDLK_KP_1
|
||||||
#define KEY_KP_DR SDLK_KP3
|
#define KEY_KP_DR SDLK_KP_3
|
||||||
#define KEY_KP_UL SDLK_KP7
|
#define KEY_KP_UL SDLK_KP_7
|
||||||
#define KEY_KP_UR SDLK_KP9
|
#define KEY_KP_UR SDLK_KP_9
|
||||||
|
|
||||||
|
|
||||||
enum buttons_t
|
enum buttons_t
|
||||||
@ -105,7 +105,7 @@ class gamecontrol_t
|
|||||||
static void init(int always_fire);
|
static void init(int always_fire);
|
||||||
static void repeat(int delay, int interval);
|
static void repeat(int delay, int interval);
|
||||||
static void clear();
|
static void clear();
|
||||||
static int map(SDLKey sym);
|
static int map(SDL_Keycode sym);
|
||||||
static void process(); // Call every frame!
|
static void process(); // Call every frame!
|
||||||
static void press(int k);
|
static void press(int k);
|
||||||
static void release(int k);
|
static void release(int k);
|
||||||
|
|||||||
@ -235,33 +235,17 @@ int s_filter_rgba8(s_bank_t *b, unsigned first, unsigned frames,
|
|||||||
s_filter_args_t *args)
|
s_filter_args_t *args)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
SDL_PixelFormat fmt;
|
|
||||||
memset(&fmt, 0, sizeof(fmt));
|
|
||||||
fmt.BitsPerPixel = 32;
|
|
||||||
fmt.BytesPerPixel = 4;
|
|
||||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
|
||||||
fmt.Rmask = 0xff000000;
|
|
||||||
fmt.Gmask = 0x00ff0000;
|
|
||||||
fmt.Bmask = 0x0000ff00;
|
|
||||||
fmt.Amask = 0x000000ff;
|
|
||||||
#else
|
|
||||||
fmt.Rmask = 0x000000ff;
|
|
||||||
fmt.Gmask = 0x0000ff00;
|
|
||||||
fmt.Bmask = 0x00ff0000;
|
|
||||||
fmt.Amask = 0xff000000;
|
|
||||||
#endif
|
|
||||||
for(i = 0; i < frames; ++i)
|
for(i = 0; i < frames; ++i)
|
||||||
{
|
{
|
||||||
SDL_Surface *tmp;
|
SDL_Surface *tmp;
|
||||||
s_sprite_t *s = s_get_sprite_b(b, first+i);
|
s_sprite_t *s = s_get_sprite_b(b, first+i);
|
||||||
if(!s)
|
if(!s)
|
||||||
continue;
|
continue;
|
||||||
tmp = SDL_ConvertSurface(s->surface, &fmt,
|
tmp = SDL_ConvertSurface(s->surface, SDL_PIXELFORMAT_RGBA32);
|
||||||
SDL_SWSURFACE);
|
|
||||||
if(!tmp)
|
if(!tmp)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
SDL_FreeSurface(s->surface);
|
SDL_DestroySurface(s->surface);
|
||||||
s->surface = tmp;
|
s->surface = tmp;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -289,7 +273,7 @@ int s_filter_dither(s_bank_t *b, unsigned first, unsigned frames,
|
|||||||
switch (s_blitmode)
|
switch (s_blitmode)
|
||||||
{
|
{
|
||||||
case S_BLITMODE_AUTO:
|
case S_BLITMODE_AUTO:
|
||||||
if(s->surface->format->Amask)
|
if(SDL_ISPIXELFORMAT_ALPHA(s->surface->format))
|
||||||
ar = ag = ab = 8;
|
ar = ag = ab = 8;
|
||||||
break;
|
break;
|
||||||
case S_BLITMODE_OPAQUE:
|
case S_BLITMODE_OPAQUE:
|
||||||
@ -458,7 +442,8 @@ int s_filter_dither(s_bank_t *b, unsigned first, unsigned frames,
|
|||||||
static void tweak_ck(SDL_Surface *s)
|
static void tweak_ck(SDL_Surface *s)
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
if(s->format->BitsPerPixel != 32)
|
const SDL_PixelFormatDetails *fmt = SDL_GetPixelFormatDetails(s->format);
|
||||||
|
if(!fmt || fmt->bits_per_pixel != 32)
|
||||||
return;
|
return;
|
||||||
for(y = 0; y < s->h; ++y)
|
for(y = 0; y < s->h; ++y)
|
||||||
{
|
{
|
||||||
@ -488,53 +473,54 @@ int s_filter_displayformat(s_bank_t * b, unsigned first, unsigned frames,
|
|||||||
switch(s_blitmode)
|
switch(s_blitmode)
|
||||||
{
|
{
|
||||||
case S_BLITMODE_AUTO:
|
case S_BLITMODE_AUTO:
|
||||||
if(s->surface->format->Amask)
|
if(SDL_ISPIXELFORMAT_ALPHA(s->surface->format))
|
||||||
SDL_SetAlpha(s->surface,
|
{
|
||||||
SDL_SRCALPHA |
|
SDL_SetSurfaceAlphaMod(s->surface,
|
||||||
SDL_RLEACCEL,
|
|
||||||
SDL_ALPHA_OPAQUE);
|
SDL_ALPHA_OPAQUE);
|
||||||
|
SDL_SetSurfaceBlendMode(s->surface,
|
||||||
|
SDL_BLENDMODE_BLEND);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
SDL_SetColorKey(s->surface, SDL_RLEACCEL, 0);
|
SDL_SetSurfaceColorKey(s->surface, false, 0);
|
||||||
break;
|
break;
|
||||||
case S_BLITMODE_OPAQUE:
|
case S_BLITMODE_OPAQUE:
|
||||||
SDL_SetColorKey(s->surface, SDL_RLEACCEL, 0);
|
SDL_SetSurfaceColorKey(s->surface, false, 0);
|
||||||
break;
|
break;
|
||||||
case S_BLITMODE_COLORKEY:
|
case S_BLITMODE_COLORKEY:
|
||||||
SDL_SetColorKey(s->surface,
|
SDL_SetSurfaceColorKey(s->surface, true,
|
||||||
SDL_SRCCOLORKEY | SDL_RLEACCEL,
|
SDL_MapSurfaceRGB(s->surface,
|
||||||
SDL_MapRGB(s->surface->format,
|
|
||||||
s_colorkey.r,
|
s_colorkey.r,
|
||||||
s_colorkey.g,
|
s_colorkey.g,
|
||||||
s_colorkey.b));
|
s_colorkey.b));
|
||||||
break;
|
break;
|
||||||
case S_BLITMODE_ALPHA:
|
case S_BLITMODE_ALPHA:
|
||||||
SDL_SetAlpha(s->surface,
|
SDL_SetSurfaceAlphaMod(s->surface, s_alpha);
|
||||||
SDL_SRCALPHA | SDL_RLEACCEL,
|
SDL_SetSurfaceBlendMode(s->surface,
|
||||||
s_alpha);
|
SDL_BLENDMODE_BLEND);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SDL 3 dropped SDL_DisplayFormat. We always convert sprites
|
||||||
|
// to the back-buffer format (ARGB8888); see gfxengine.cpp.
|
||||||
if(args->x)
|
if(args->x)
|
||||||
{
|
{
|
||||||
if(s->surface->format->Amask)
|
if(SDL_ISPIXELFORMAT_ALPHA(s->surface->format))
|
||||||
tweak_ck(s->surface);
|
tweak_ck(s->surface);
|
||||||
tmp = SDL_DisplayFormat(s->surface);
|
tmp = SDL_ConvertSurface(s->surface,
|
||||||
if(s->surface->format->Amask)
|
SDL_PIXELFORMAT_ARGB8888);
|
||||||
SDL_SetColorKey(tmp,
|
if(tmp && SDL_ISPIXELFORMAT_ALPHA(s->surface->format))
|
||||||
SDL_SRCCOLORKEY | SDL_RLEACCEL,
|
SDL_SetSurfaceColorKey(tmp, true,
|
||||||
SDL_MapRGB(tmp->format, 0,0,0));
|
SDL_MapSurfaceRGB(tmp, 0,0,0));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(s->surface->format->Amask)
|
tmp = SDL_ConvertSurface(s->surface,
|
||||||
tmp = SDL_DisplayFormatAlpha(s->surface);
|
SDL_PIXELFORMAT_ARGB8888);
|
||||||
else
|
|
||||||
tmp = SDL_DisplayFormat(s->surface);
|
|
||||||
}
|
}
|
||||||
if(!tmp)
|
if(!tmp)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
SDL_FreeSurface(s->surface);
|
SDL_DestroySurface(s->surface);
|
||||||
s->surface = tmp;
|
s->surface = tmp;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -900,18 +886,13 @@ int s_filter_scale(s_bank_t *b, unsigned first, unsigned frames,
|
|||||||
if(!s)
|
if(!s)
|
||||||
continue;
|
continue;
|
||||||
params.src = s->surface;
|
params.src = s->surface;
|
||||||
params.dst = SDL_CreateRGBSurface(SDL_SWSURFACE,
|
params.dst = SDL_CreateSurface(params.max_x, params.max_y,
|
||||||
params.max_x, params.max_y, 32,
|
SDL_PIXELFORMAT_RGBA32);
|
||||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
|
||||||
0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
|
|
||||||
#else
|
|
||||||
0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
|
||||||
#endif
|
|
||||||
if(!params.dst)
|
if(!params.dst)
|
||||||
return -1;
|
return -1;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
SDL_FillRect(params.dst, NULL,
|
SDL_FillSurfaceRect(params.dst, NULL,
|
||||||
SDL_MapRGB(params.dst->format, 255, 128, 0));
|
SDL_MapSurfaceRGB(params.dst, 255, 128, 0));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Deal with SFont marker row */
|
/* Deal with SFont marker row */
|
||||||
@ -957,7 +938,7 @@ int s_filter_scale(s_bank_t *b, unsigned first, unsigned frames,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_FreeSurface(s->surface);
|
SDL_DestroySurface(s->surface);
|
||||||
s->surface = params.dst;
|
s->surface = params.dst;
|
||||||
}
|
}
|
||||||
b->w = params.max_x;
|
b->w = params.max_x;
|
||||||
|
|||||||
@ -40,6 +40,9 @@ gfxengine_t::gfxengine_t()
|
|||||||
{
|
{
|
||||||
gfxengine = this; /* Uurgh! Kludge. */
|
gfxengine = this; /* Uurgh! Kludge. */
|
||||||
|
|
||||||
|
sdl_window = NULL;
|
||||||
|
sdl_renderer = NULL;
|
||||||
|
fb_texture = NULL;
|
||||||
screen_surface = NULL;
|
screen_surface = NULL;
|
||||||
softbuf = NULL;
|
softbuf = NULL;
|
||||||
fullwin = NULL;
|
fullwin = NULL;
|
||||||
@ -443,10 +446,13 @@ void gfxengine_t::dither(int type, int _broken_rgba8)
|
|||||||
|
|
||||||
if(_dither)
|
if(_dither)
|
||||||
{
|
{
|
||||||
|
// SDL 3: back buffer is always ARGB8888 (8 bits per channel,
|
||||||
|
// no loss). The legacy formula was 1 << (Rloss - 1); for 8 bpc
|
||||||
|
// the dithering amplitude collapses to 0.
|
||||||
df->args.x = 0;
|
df->args.x = 0;
|
||||||
df->args.r = 1<<(screen_surface->format->Rloss-1);
|
df->args.r = 0;
|
||||||
df->args.g = 1<<(screen_surface->format->Gloss-1);
|
df->args.g = 0;
|
||||||
df->args.b = 1<<(screen_surface->format->Bloss-1);
|
df->args.b = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
df->args.x = df->args.r = df->args.g = df->args.b = 0;
|
df->args.x = df->args.r = df->args.g = df->args.b = 0;
|
||||||
@ -732,8 +738,8 @@ void gfxengine_t::title(const char *win, const char *icon)
|
|||||||
{
|
{
|
||||||
_title = win;
|
_title = win;
|
||||||
_icontitle = icon;
|
_icontitle = icon;
|
||||||
if(screen_surface)
|
if(sdl_window)
|
||||||
SDL_WM_SetCaption(_title, _icontitle);
|
SDL_SetWindowTitle(sdl_window, _title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -743,97 +749,94 @@ void gfxengine_t::title(const char *win, const char *icon)
|
|||||||
|
|
||||||
int gfxengine_t::show()
|
int gfxengine_t::show()
|
||||||
{
|
{
|
||||||
int flags = 0;
|
|
||||||
|
|
||||||
if(!is_open)
|
if(!is_open)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if(is_showing)
|
if(is_showing)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(_centered && !_fullscreen)
|
|
||||||
SDL_putenv((char *)"SDL_VIDEO_CENTERED=1");
|
|
||||||
|
|
||||||
log_printf(DLOG, "Opening screen...\n");
|
log_printf(DLOG, "Opening screen...\n");
|
||||||
if(!SDL_WasInit(SDL_INIT_VIDEO))
|
if(!SDL_WasInit(SDL_INIT_VIDEO))
|
||||||
if(SDL_InitSubSystem(SDL_INIT_VIDEO) == -1)
|
if(!SDL_InitSubSystem(SDL_INIT_VIDEO))
|
||||||
{
|
{
|
||||||
log_printf(ELOG, "Failed to initialize SDL!\n");
|
log_printf(ELOG, "Failed to initialize SDL: %s\n",
|
||||||
|
SDL_GetError());
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_doublebuf)
|
// SDL 3 window + renderer model.
|
||||||
flags |= SDL_DOUBLEBUF | SDL_HWSURFACE;
|
//
|
||||||
else
|
// The kobo engine renders into a CPU-side back buffer (softbuf) via
|
||||||
{
|
// SDL_BlitSurface/SDL_FillSurfaceRect, and uploads the result to a
|
||||||
if(!_shadow)
|
// streaming SDL_Texture once per frame. This preserves the entire
|
||||||
flags |= SDL_HWSURFACE;
|
// software-compositing code path inherited from SDL 1.2 (window.cpp,
|
||||||
}
|
// sprite.c, filters.c, sofont.cpp), while letting the GPU handle
|
||||||
|
// scaling and presentation. SDL_DOUBLEBUF / SDL_HWSURFACE / page-
|
||||||
|
// flipping flags are obsolete and ignored.
|
||||||
|
Uint64 win_flags = 0;
|
||||||
if(_fullscreen)
|
if(_fullscreen)
|
||||||
flags |= SDL_FULLSCREEN;
|
win_flags |= SDL_WINDOW_FULLSCREEN;
|
||||||
|
|
||||||
flags |= xflags;
|
sdl_window = SDL_CreateWindow(_title ? _title : "Kobo Deluxe",
|
||||||
|
_width, _height, win_flags);
|
||||||
screen_surface = SDL_SetVideoMode(_width, _height, _depth, flags);
|
if(!sdl_window)
|
||||||
if(!screen_surface)
|
|
||||||
{
|
{
|
||||||
log_printf(ELOG, "Failed to open display!\n");
|
log_printf(ELOG, "Failed to open window: %s\n", SDL_GetError());
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((screen_surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF)
|
sdl_renderer = SDL_CreateRenderer(sdl_window, NULL);
|
||||||
|
if(!sdl_renderer)
|
||||||
{
|
{
|
||||||
if(!_doublebuf)
|
log_printf(ELOG, "Failed to create renderer: %s\n",
|
||||||
{
|
SDL_GetError());
|
||||||
log_printf(WLOG, "Could not get"
|
SDL_DestroyWindow(sdl_window);
|
||||||
" single buffered display.\n");
|
sdl_window = NULL;
|
||||||
doublebuffer(1);
|
return -4;
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(_doublebuf)
|
|
||||||
{
|
|
||||||
log_printf(WLOG, "Could not get"
|
|
||||||
" double buffered display.\n");
|
|
||||||
doublebuffer(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if((screen_surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE)
|
// Letterbox the back buffer when the window is resized / fullscreen.
|
||||||
{
|
SDL_SetRenderLogicalPresentation(sdl_renderer, _width, _height,
|
||||||
if(_shadow)
|
SDL_LOGICAL_PRESENTATION_LETTERBOX);
|
||||||
{
|
SDL_SetRenderVSync(sdl_renderer, _vsync ? 1 : 0);
|
||||||
softbuf = SDL_CreateRGBSurface(SDL_SWSURFACE,
|
|
||||||
_width, _height,
|
// The back buffer is always a CPU-side ARGB8888 surface.
|
||||||
screen_surface->format->BitsPerPixel,
|
softbuf = SDL_CreateSurface(_width, _height, SDL_PIXELFORMAT_ARGB8888);
|
||||||
screen_surface->format->Rmask,
|
|
||||||
screen_surface->format->Gmask,
|
|
||||||
screen_surface->format->Bmask,
|
|
||||||
screen_surface->format->Amask);
|
|
||||||
if(!softbuf)
|
if(!softbuf)
|
||||||
{
|
{
|
||||||
log_printf(WLOG, "Failed to create shadow buffer! "
|
log_printf(ELOG, "Failed to create back buffer: %s\n",
|
||||||
"Trying direct rendering.\n");
|
SDL_GetError());
|
||||||
shadow(0);
|
SDL_DestroyRenderer(sdl_renderer);
|
||||||
}
|
SDL_DestroyWindow(sdl_window);
|
||||||
}
|
sdl_renderer = NULL;
|
||||||
}
|
sdl_window = NULL;
|
||||||
else
|
return -5;
|
||||||
{
|
|
||||||
if(_shadow)
|
|
||||||
log_printf(WLOG, "Shadow buffer requested; "
|
|
||||||
"relying on SDL's shadow buffer.\n");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
log_printf(WLOG, "Could not get h/w display surface.\n");
|
|
||||||
shadow(0); //...which means we're using SDL's shadow.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
screen_surface = softbuf; // alias for legacy code paths
|
||||||
|
|
||||||
|
fb_texture = SDL_CreateTexture(sdl_renderer, SDL_PIXELFORMAT_ARGB8888,
|
||||||
|
SDL_TEXTUREACCESS_STREAMING, _width, _height);
|
||||||
|
if(!fb_texture)
|
||||||
|
{
|
||||||
|
log_printf(ELOG, "Failed to create framebuffer texture: %s\n",
|
||||||
|
SDL_GetError());
|
||||||
|
SDL_DestroySurface(softbuf);
|
||||||
|
SDL_DestroyRenderer(sdl_renderer);
|
||||||
|
SDL_DestroyWindow(sdl_window);
|
||||||
|
softbuf = screen_surface = NULL;
|
||||||
|
sdl_renderer = NULL;
|
||||||
|
sdl_window = NULL;
|
||||||
|
return -6;
|
||||||
|
}
|
||||||
|
SDL_SetTextureScaleMode(fb_texture,
|
||||||
|
(_scalemode == GFX_SCALE_NEAREST) ?
|
||||||
|
SDL_SCALEMODE_NEAREST : SDL_SCALEMODE_LINEAR);
|
||||||
|
|
||||||
|
if(_cursor)
|
||||||
|
SDL_ShowCursor();
|
||||||
|
else
|
||||||
|
SDL_HideCursor();
|
||||||
|
|
||||||
SDL_WM_SetCaption(_title, _icontitle);
|
|
||||||
SDL_ShowCursor(_cursor);
|
|
||||||
cs_engine_set_size(csengine, _width, _height);
|
cs_engine_set_size(csengine, _width, _height);
|
||||||
csengine->filter = use_interpolation;
|
csengine->filter = use_interpolation;
|
||||||
|
|
||||||
@ -886,12 +889,27 @@ void gfxengine_t::hide(void)
|
|||||||
w = w->next;
|
w = w->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(fb_texture)
|
||||||
|
{
|
||||||
|
SDL_DestroyTexture(fb_texture);
|
||||||
|
fb_texture = NULL;
|
||||||
|
}
|
||||||
if(softbuf)
|
if(softbuf)
|
||||||
{
|
{
|
||||||
SDL_FreeSurface(softbuf);
|
SDL_DestroySurface(softbuf);
|
||||||
softbuf = NULL;
|
softbuf = NULL;
|
||||||
}
|
}
|
||||||
screen_surface = NULL;
|
screen_surface = NULL;
|
||||||
|
if(sdl_renderer)
|
||||||
|
{
|
||||||
|
SDL_DestroyRenderer(sdl_renderer);
|
||||||
|
sdl_renderer = NULL;
|
||||||
|
}
|
||||||
|
if(sdl_window)
|
||||||
|
{
|
||||||
|
SDL_DestroyWindow(sdl_window);
|
||||||
|
sdl_window = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
is_showing = 0;
|
is_showing = 0;
|
||||||
}
|
}
|
||||||
@ -940,13 +958,15 @@ void gfxengine_t::__invalidate(int page, SDL_Rect *rect, window_t *window)
|
|||||||
|
|
||||||
/* Clip to screen (stolen from SDL_surface.c) */
|
/* Clip to screen (stolen from SDL_surface.c) */
|
||||||
SDL_Rect dr = *rect;
|
SDL_Rect dr = *rect;
|
||||||
|
SDL_Rect screen_clip;
|
||||||
|
SDL_GetSurfaceClipRect(screen_surface, &screen_clip);
|
||||||
int Amin, Amax, Bmin, Bmax;
|
int Amin, Amax, Bmin, Bmax;
|
||||||
|
|
||||||
/* Horizontal intersection */
|
/* Horizontal intersection */
|
||||||
Amin = dr.x;
|
Amin = dr.x;
|
||||||
Amax = Amin + dr.w;
|
Amax = Amin + dr.w;
|
||||||
Bmin = screen_surface->clip_rect.x;
|
Bmin = screen_clip.x;
|
||||||
Bmax = Bmin + screen_surface->clip_rect.w;
|
Bmax = Bmin + screen_clip.w;
|
||||||
if(Bmin > Amin)
|
if(Bmin > Amin)
|
||||||
Amin = Bmin;
|
Amin = Bmin;
|
||||||
dr.x = Amin;
|
dr.x = Amin;
|
||||||
@ -957,8 +977,8 @@ void gfxengine_t::__invalidate(int page, SDL_Rect *rect, window_t *window)
|
|||||||
/* Vertical intersection */
|
/* Vertical intersection */
|
||||||
Amin = dr.y;
|
Amin = dr.y;
|
||||||
Amax = Amin + dr.h;
|
Amax = Amin + dr.h;
|
||||||
Bmin = screen_surface->clip_rect.y;
|
Bmin = screen_clip.y;
|
||||||
Bmax = Bmin + screen_surface->clip_rect.h;
|
Bmax = Bmin + screen_clip.h;
|
||||||
if(Bmin > Amin)
|
if(Bmin > Amin)
|
||||||
Amin = Bmin;
|
Amin = Bmin;
|
||||||
dr.y = Amin;
|
dr.y = Amin;
|
||||||
@ -1062,7 +1082,12 @@ void gfxengine_t::cursor(int csr)
|
|||||||
{
|
{
|
||||||
_cursor = csr;
|
_cursor = csr;
|
||||||
if(screen_surface)
|
if(screen_surface)
|
||||||
SDL_ShowCursor(csr);
|
{
|
||||||
|
if(csr)
|
||||||
|
SDL_ShowCursor();
|
||||||
|
else
|
||||||
|
SDL_HideCursor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1168,8 +1193,8 @@ void gfxengine_t::frame()
|
|||||||
SDL_Event ev;
|
SDL_Event ev;
|
||||||
while(SDL_PollEvent(&ev))
|
while(SDL_PollEvent(&ev))
|
||||||
{
|
{
|
||||||
if(ev.type == SDL_KEYDOWN)
|
if(ev.type == SDL_EVENT_KEY_DOWN)
|
||||||
if(ev.key.keysym.sym == SDLK_ESCAPE)
|
if(ev.key.key == SDLK_ESCAPE)
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1236,41 +1261,15 @@ void gfxengine_t::refresh_rect(SDL_Rect *r)
|
|||||||
|
|
||||||
void gfxengine_t::flip()
|
void gfxengine_t::flip()
|
||||||
{
|
{
|
||||||
if(!screen_surface)
|
if(!screen_surface || !sdl_renderer || !fb_texture)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Init dirtyrect table flipping, if necessary.
|
// SDL 3 has no hardware page flipping; we always present one back
|
||||||
switch(_pages)
|
// buffer per frame. Keep the dirtyrect iteration only to drive the
|
||||||
{
|
// phys_refresh() callbacks that window widgets rely on; the upload
|
||||||
case -1:
|
// is a single full-surface copy regardless.
|
||||||
if(!_doublebuf)
|
|
||||||
frontpage = backpage = 0;
|
frontpage = backpage = 0;
|
||||||
else if(frontpage == backpage)
|
for(int i = 0; i < dirtyrects[backpage]; ++i)
|
||||||
{
|
|
||||||
frontpage = 0;
|
|
||||||
backpage = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0:
|
|
||||||
frontpage = backpage = 0;
|
|
||||||
invalidate();
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
frontpage = backpage = 0;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
case 3:
|
|
||||||
if(frontpage == backpage)
|
|
||||||
{
|
|
||||||
frontpage = 0;
|
|
||||||
backpage = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process the dirtyrects.
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < dirtyrects[backpage]; ++i)
|
|
||||||
{
|
{
|
||||||
if(dirtywtable[backpage][i])
|
if(dirtywtable[backpage][i])
|
||||||
{
|
{
|
||||||
@ -1282,36 +1281,12 @@ void gfxengine_t::flip()
|
|||||||
else
|
else
|
||||||
refresh_rect(&dirtytable[backpage][i]);
|
refresh_rect(&dirtytable[backpage][i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform the actual flip or update
|
|
||||||
if(_shadow)
|
|
||||||
{
|
|
||||||
for(i = 0; i < dirtyrects[backpage]; ++i)
|
|
||||||
SDL_BlitSurface(softbuf,
|
|
||||||
&dirtytable[backpage][i],
|
|
||||||
screen_surface,
|
|
||||||
&dirtytable[backpage][i]);
|
|
||||||
}
|
|
||||||
if(_doublebuf)
|
|
||||||
{
|
|
||||||
dirtyrects[backpage] = 0;
|
dirtyrects[backpage] = 0;
|
||||||
if(_pages == -1)
|
|
||||||
{
|
SDL_UpdateTexture(fb_texture, NULL, softbuf->pixels, softbuf->pitch);
|
||||||
backpage = !backpage;
|
SDL_RenderClear(sdl_renderer);
|
||||||
frontpage = !frontpage;
|
SDL_RenderTexture(sdl_renderer, fb_texture, NULL, NULL);
|
||||||
}
|
SDL_RenderPresent(sdl_renderer);
|
||||||
else if(_pages > 1)
|
|
||||||
{
|
|
||||||
backpage = (backpage + 1) % _pages;
|
|
||||||
frontpage = (frontpage + 1) % _pages;
|
|
||||||
}
|
|
||||||
SDL_Flip(screen_surface);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SDL_UpdateRects(screen_surface, dirtyrects[0], dirtytable[0]);
|
|
||||||
dirtyrects[0] = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -208,7 +208,10 @@ class gfxengine_t
|
|||||||
gfx_drivers_t _driver;
|
gfx_drivers_t _driver;
|
||||||
gfx_scalemodes_t _scalemode;
|
gfx_scalemodes_t _scalemode;
|
||||||
int _clamping;
|
int _clamping;
|
||||||
SDL_Surface *screen_surface;
|
SDL_Window *sdl_window;
|
||||||
|
SDL_Renderer *sdl_renderer;
|
||||||
|
SDL_Texture *fb_texture;
|
||||||
|
SDL_Surface *screen_surface; // alias for softbuf in SDL 3
|
||||||
SDL_Surface *softbuf;
|
SDL_Surface *softbuf;
|
||||||
int backpage;
|
int backpage;
|
||||||
int frontpage;
|
int frontpage;
|
||||||
|
|||||||
@ -44,7 +44,9 @@ static Uint32 gp2(SDL_Surface *surface, int x, int y)
|
|||||||
|
|
||||||
static Uint32 gp3(SDL_Surface *surface, int x, int y)
|
static Uint32 gp3(SDL_Surface *surface, int x, int y)
|
||||||
{
|
{
|
||||||
int bpp = surface->format->BytesPerPixel;
|
const SDL_PixelFormatDetails *fmt =
|
||||||
|
SDL_GetPixelFormatDetails(surface->format);
|
||||||
|
int bpp = fmt ? fmt->bytes_per_pixel : 3;
|
||||||
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
|
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
|
||||||
#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||||
return p[0] << 16 | p[1] << 8 | p[2];
|
return p[0] << 16 | p[1] << 8 | p[2];
|
||||||
@ -74,7 +76,14 @@ RGN_region *RGN_ScanMask(SDL_Surface *src, Uint32 key)
|
|||||||
RGN_FreeRegion(rgn);
|
RGN_FreeRegion(rgn);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
switch(src->format->BytesPerPixel)
|
const SDL_PixelFormatDetails *src_fmt =
|
||||||
|
SDL_GetPixelFormatDetails(src->format);
|
||||||
|
if(!src_fmt)
|
||||||
|
{
|
||||||
|
RGN_FreeRegion(rgn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
switch(src_fmt->bytes_per_pixel)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
gp = gp1;
|
gp = gp1;
|
||||||
|
|||||||
@ -20,7 +20,7 @@ SoFont::SoFont()
|
|||||||
SoFont::~SoFont()
|
SoFont::~SoFont()
|
||||||
{
|
{
|
||||||
if(picture)
|
if(picture)
|
||||||
SDL_FreeSurface(picture);
|
SDL_DestroySurface(picture);
|
||||||
delete[]CharPos;
|
delete[]CharPos;
|
||||||
delete[]CharOffset;
|
delete[]CharOffset;
|
||||||
delete[]Spacing;
|
delete[]Spacing;
|
||||||
@ -45,7 +45,11 @@ namespace SoFontUtilities
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bpp = Surface->format->BytesPerPixel;
|
const SDL_PixelFormatDetails *fmt =
|
||||||
|
SDL_GetPixelFormatDetails(Surface->format);
|
||||||
|
if(!fmt)
|
||||||
|
return 0;
|
||||||
|
Bpp = fmt->bytes_per_pixel;
|
||||||
|
|
||||||
bits = ((Uint8 *) Surface->pixels) + Y * Surface->pitch +
|
bits = ((Uint8 *) Surface->pixels) + Y * Surface->pitch +
|
||||||
X * Bpp;
|
X * Bpp;
|
||||||
@ -63,10 +67,10 @@ namespace SoFontUtilities
|
|||||||
case 3:
|
case 3:
|
||||||
// Format/endian independent
|
// Format/endian independent
|
||||||
Uint8 r, g, b;
|
Uint8 r, g, b;
|
||||||
r = *((bits) + Surface->format->Rshift / 8);
|
r = *((bits) + fmt->Rshift / 8);
|
||||||
g = *((bits) + Surface->format->Gshift / 8);
|
g = *((bits) + fmt->Gshift / 8);
|
||||||
b = *((bits) + Surface->format->Bshift / 8);
|
b = *((bits) + fmt->Bshift / 8);
|
||||||
return SDL_MapRGB(Surface->format, r, g, b);
|
return SDL_MapSurfaceRGB(Surface, r, g, b);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
return *((Uint32 *) Surface->pixels +
|
return *((Uint32 *) Surface->pixels +
|
||||||
@ -94,7 +98,11 @@ namespace SoFontUtilities
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bpp = Surface->format->BytesPerPixel;
|
const SDL_PixelFormatDetails *fmt =
|
||||||
|
SDL_GetPixelFormatDetails(Surface->format);
|
||||||
|
if(!fmt)
|
||||||
|
return;
|
||||||
|
Bpp = fmt->bytes_per_pixel;
|
||||||
|
|
||||||
bits = ((Uint8 *) Surface->pixels) + Y * Surface->pitch +
|
bits = ((Uint8 *) Surface->pixels) + Y * Surface->pitch +
|
||||||
X * Bpp;
|
X * Bpp;
|
||||||
@ -113,10 +121,11 @@ namespace SoFontUtilities
|
|||||||
case 3:
|
case 3:
|
||||||
// Format/endian independent
|
// Format/endian independent
|
||||||
Uint8 r, g, b;
|
Uint8 r, g, b;
|
||||||
SDL_GetRGB(c, Surface->format, &r, &g, &b);
|
SDL_GetRGB(c, fmt, SDL_GetSurfacePalette(Surface),
|
||||||
*((bits) + Surface->format->Rshift / 8) = r;
|
&r, &g, &b);
|
||||||
*((bits) + Surface->format->Gshift / 8) = g;
|
*((bits) + fmt->Rshift / 8) = r;
|
||||||
*((bits) + Surface->format->Bshift / 8) = b;
|
*((bits) + fmt->Gshift / 8) = g;
|
||||||
|
*((bits) + fmt->Bshift / 8) = b;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
*((Uint32 *) Surface->pixels +
|
*((Uint32 *) Surface->pixels +
|
||||||
@ -224,7 +233,7 @@ bool SoFont::DoStartNewChar(Sint32 x)
|
|||||||
if(!picture)
|
if(!picture)
|
||||||
return false;
|
return false;
|
||||||
return SoFontGetPixel(picture, x, 0) ==
|
return SoFontGetPixel(picture, x, 0) ==
|
||||||
SDL_MapRGB(picture->format, 255, 0, 255);
|
SDL_MapSurfaceRGB(picture, 255, 0, 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoFont::CleanSurface()
|
void SoFont::CleanSurface()
|
||||||
@ -233,7 +242,7 @@ void SoFont::CleanSurface()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
int x = 0, y = 0;
|
int x = 0, y = 0;
|
||||||
Uint32 pix = SDL_MapRGB(picture->format, 255, 0, 255);
|
Uint32 pix = SDL_MapSurfaceRGB(picture, 255, 0, 255);
|
||||||
|
|
||||||
while(x < picture->w)
|
while(x < picture->w)
|
||||||
{
|
{
|
||||||
@ -259,7 +268,7 @@ bool SoFont::load(SDL_Surface * FontSurface)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(picture)
|
if(picture)
|
||||||
SDL_FreeSurface(picture);
|
SDL_DestroySurface(picture);
|
||||||
picture = FontSurface;
|
picture = FontSurface;
|
||||||
height = picture->h - 1;
|
height = picture->h - 1;
|
||||||
while(x < picture->w)
|
while(x < picture->w)
|
||||||
@ -499,8 +508,10 @@ void SoFont::CenteredString(SDL_Surface * Surface, const char *text,
|
|||||||
{
|
{
|
||||||
if(!picture)
|
if(!picture)
|
||||||
return;
|
return;
|
||||||
CenteredString(Surface, Surface->clip_rect.w / 2,
|
SDL_Rect surf_clip;
|
||||||
Surface->clip_rect.h / 2, text, clip);
|
SDL_GetSurfaceClipRect(Surface, &surf_clip);
|
||||||
|
CenteredString(Surface, surf_clip.w / 2,
|
||||||
|
surf_clip.h / 2, text, clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoFont::PutStringCleverCursor(SDL_Surface * Surface, const char *text,
|
void SoFont::PutStringCleverCursor(SDL_Surface * Surface, const char *text,
|
||||||
|
|||||||
@ -177,7 +177,7 @@ s_sprite_t *s_new_sprite_b(s_bank_t *b, unsigned frame)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(s->surface)
|
if(s->surface)
|
||||||
SDL_FreeSurface(s->surface);
|
SDL_DestroySurface(s->surface);
|
||||||
s->surface = NULL;
|
s->surface = NULL;
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
@ -212,7 +212,7 @@ void s_delete_sprite_b(s_bank_t *b, unsigned frame)
|
|||||||
if(!b->sprites[frame])
|
if(!b->sprites[frame])
|
||||||
return;
|
return;
|
||||||
if(b->sprites[frame]->surface)
|
if(b->sprites[frame]->surface)
|
||||||
SDL_FreeSurface(b->sprites[frame]->surface);
|
SDL_DestroySurface(b->sprites[frame]->surface);
|
||||||
b->sprites[frame]->surface = NULL;
|
b->sprites[frame]->surface = NULL;
|
||||||
free(b->sprites[frame]);
|
free(b->sprites[frame]);
|
||||||
b->sprites[frame] = NULL;
|
b->sprites[frame] = NULL;
|
||||||
@ -355,44 +355,51 @@ static int extract_sprite(s_bank_t *bank, unsigned frame,
|
|||||||
if(!s_new_sprite_b(bank, frame))
|
if(!s_new_sprite_b(bank, frame))
|
||||||
return -2;
|
return -2;
|
||||||
|
|
||||||
tmp = SDL_CreateRGBSurface(src->flags,
|
const SDL_PixelFormatDetails *src_fmt =
|
||||||
from->w, from->h,
|
SDL_GetPixelFormatDetails(src->format);
|
||||||
src->format->BitsPerPixel,
|
if(!src_fmt)
|
||||||
src->format->Rmask,
|
return -3;
|
||||||
src->format->Gmask,
|
|
||||||
src->format->Bmask,
|
tmp = SDL_CreateSurface(from->w, from->h, src->format);
|
||||||
src->format->Amask );
|
|
||||||
if(!tmp)
|
if(!tmp)
|
||||||
return -3;
|
return -3;
|
||||||
|
|
||||||
/* Copy the pixel data */
|
/* Copy the pixel data */
|
||||||
if(SDL_LockSurface(src) < 0)
|
if(!SDL_LockSurface(src))
|
||||||
{
|
{
|
||||||
log_printf(ELOG, "sprite: extract_sprite() failed to lock surface!\n");
|
log_printf(ELOG, "sprite: extract_sprite() failed to lock surface!\n");
|
||||||
SDL_FreeSurface(tmp);
|
SDL_DestroySurface(tmp);
|
||||||
return -4;
|
return -4;
|
||||||
}
|
}
|
||||||
for(y = 0; y < tmp->h; ++y)
|
for(y = 0; y < tmp->h; ++y)
|
||||||
{
|
{
|
||||||
char *s = (char *)src->pixels + src->pitch * (y + from->y) +
|
char *s = (char *)src->pixels + src->pitch * (y + from->y) +
|
||||||
from->x * src->format->BytesPerPixel;
|
from->x * src_fmt->bytes_per_pixel;
|
||||||
char *d = (char *)tmp->pixels + tmp->pitch * y;
|
char *d = (char *)tmp->pixels + tmp->pitch * y;
|
||||||
memcpy(d, s, src->format->BytesPerPixel * tmp->w);
|
memcpy(d, s, src_fmt->bytes_per_pixel * tmp->w);
|
||||||
}
|
}
|
||||||
SDL_UnlockSurface(src);
|
SDL_UnlockSurface(src);
|
||||||
|
|
||||||
/* Copy palette, if any */
|
/* Copy palette, if any */
|
||||||
if(src->format->palette)
|
SDL_Palette *src_palette = SDL_GetSurfacePalette(src);
|
||||||
SDL_SetColors(tmp, src->format->palette->colors, 0,
|
if(src_palette)
|
||||||
src->format->palette->ncolors);
|
SDL_SetSurfacePalette(tmp, src_palette);
|
||||||
|
|
||||||
/* Copy alpha and colorkey */
|
/* Copy alpha modulation and blend mode */
|
||||||
if(src->flags & SDL_SRCALPHA)
|
Uint8 src_alpha = SDL_ALPHA_OPAQUE;
|
||||||
SDL_SetAlpha(tmp, src->flags & (SDL_SRCALPHA | SDL_RLEACCEL),
|
SDL_GetSurfaceAlphaMod(src, &src_alpha);
|
||||||
src->format->alpha);
|
SDL_SetSurfaceAlphaMod(tmp, src_alpha);
|
||||||
if(src->flags & SDL_SRCCOLORKEY)
|
SDL_BlendMode src_blend = SDL_BLENDMODE_NONE;
|
||||||
SDL_SetColorKey(tmp, src->flags & (SDL_SRCCOLORKEY | SDL_RLEACCEL),
|
SDL_GetSurfaceBlendMode(src, &src_blend);
|
||||||
src->format->colorkey);
|
SDL_SetSurfaceBlendMode(tmp, src_blend);
|
||||||
|
|
||||||
|
/* Copy colorkey */
|
||||||
|
if(SDL_SurfaceHasColorKey(src))
|
||||||
|
{
|
||||||
|
Uint32 src_key = 0;
|
||||||
|
SDL_GetSurfaceColorKey(src, &src_key);
|
||||||
|
SDL_SetSurfaceColorKey(tmp, true, src_key);
|
||||||
|
}
|
||||||
|
|
||||||
bank->sprites[frame]->surface = tmp;
|
bank->sprites[frame]->surface = tmp;
|
||||||
|
|
||||||
@ -466,21 +473,23 @@ int s_load_image(s_container_t *c, unsigned bank, const char *name)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
b = s_new_bank(c, bank, 1, src->clip_rect.w, src->clip_rect.h);
|
SDL_Rect src_clip;
|
||||||
|
SDL_GetSurfaceClipRect(src, &src_clip);
|
||||||
|
b = s_new_bank(c, bank, 1, src_clip.w, src_clip.h);
|
||||||
if(!b)
|
if(!b)
|
||||||
{
|
{
|
||||||
log_printf(ELOG, "sprite: Failed to allocate bank for \"%s\"!\n", name);
|
log_printf(ELOG, "sprite: Failed to allocate bank for \"%s\"!\n", name);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(extract_sprite(b, 0, src, &src->clip_rect) < 0)
|
if(extract_sprite(b, 0, src, &src_clip) < 0)
|
||||||
{
|
{
|
||||||
log_printf(ELOG, "sprite: Something went wrong while"
|
log_printf(ELOG, "sprite: Something went wrong while"
|
||||||
" extracting sprite \"%s\".\n", name);
|
" extracting sprite \"%s\".\n", name);
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_FreeSurface(src);
|
SDL_DestroySurface(src);
|
||||||
__run_plugins(b, 0, 1);
|
__run_plugins(b, 0, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -506,7 +515,7 @@ int s_load_sprite(s_container_t *c, unsigned bank, unsigned frame,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
from = src->clip_rect;
|
SDL_GetSurfaceClipRect(src, &from);
|
||||||
if( (from.w != b->w) || (from.h != b->h) )
|
if( (from.w != b->w) || (from.h != b->h) )
|
||||||
{
|
{
|
||||||
log_printf(ELOG, "sprite: Warning: Sprite \"%s\" cropped"
|
log_printf(ELOG, "sprite: Warning: Sprite \"%s\" cropped"
|
||||||
@ -522,7 +531,7 @@ int s_load_sprite(s_container_t *c, unsigned bank, unsigned frame,
|
|||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_FreeSurface(src);
|
SDL_DestroySurface(src);
|
||||||
__run_plugins(b, frame, 1);
|
__run_plugins(b, frame, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -582,7 +591,7 @@ int s_load_bank(s_container_t *c, unsigned bank, unsigned w, unsigned h,
|
|||||||
}
|
}
|
||||||
++frame;
|
++frame;
|
||||||
}
|
}
|
||||||
SDL_FreeSurface(src);
|
SDL_DestroySurface(src);
|
||||||
__run_plugins(b, 0, frames);
|
__run_plugins(b, 0, frames);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,7 +50,7 @@ window_t::window_t()
|
|||||||
window_t::~window_t()
|
window_t::~window_t()
|
||||||
{
|
{
|
||||||
if(_offscreen && surface)
|
if(_offscreen && surface)
|
||||||
SDL_FreeSurface(surface);
|
SDL_DestroySurface(surface);
|
||||||
if(selected == this)
|
if(selected == this)
|
||||||
selected = NULL;
|
selected = NULL;
|
||||||
unlink();
|
unlink();
|
||||||
@ -64,7 +64,7 @@ void window_t::init(gfxengine_t *e)
|
|||||||
ys = engine->ys;
|
ys = engine->ys;
|
||||||
if(_offscreen && surface)
|
if(_offscreen && surface)
|
||||||
{
|
{
|
||||||
SDL_FreeSurface(surface);
|
SDL_DestroySurface(surface);
|
||||||
surface = NULL;
|
surface = NULL;
|
||||||
}
|
}
|
||||||
_offscreen = 0;
|
_offscreen = 0;
|
||||||
@ -137,14 +137,10 @@ int window_t::offscreen()
|
|||||||
return 0; // Already offscreen!
|
return 0; // Already offscreen!
|
||||||
visible(0);
|
visible(0);
|
||||||
_offscreen = 1;
|
_offscreen = 1;
|
||||||
SDL_Surface *s = SDL_CreateRGBSurface(SDL_SWSURFACE,
|
// SDL 3: back buffer is always ARGB8888; offscreen windows use
|
||||||
phys_rect.w, phys_rect.h,
|
// the same format to allow direct blits without conversion.
|
||||||
32, 0xff000000, 0x00ff0000,
|
surface = SDL_CreateSurface(phys_rect.w, phys_rect.h,
|
||||||
0x0000ff00, 0x000000ff);
|
SDL_PIXELFORMAT_ARGB8888);
|
||||||
if(!s)
|
|
||||||
return -1;
|
|
||||||
surface = SDL_DisplayFormat(s);
|
|
||||||
SDL_FreeSurface(s);
|
|
||||||
if(!surface)
|
if(!surface)
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
@ -163,7 +159,7 @@ void window_t::_select()
|
|||||||
SDL_Rect r = phys_rect;
|
SDL_Rect r = phys_rect;
|
||||||
selected = this;
|
selected = this;
|
||||||
if(surface)
|
if(surface)
|
||||||
SDL_SetClipRect(surface, &r);
|
SDL_SetSurfaceClipRect(surface, &r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -248,7 +244,7 @@ Uint32 window_t::map_rgb(Uint8 r, Uint8 g, Uint8 b)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(surface)
|
if(surface)
|
||||||
return SDL_MapRGB(surface->format, r, g, b);
|
return SDL_MapSurfaceRGB(surface, r, g, b);
|
||||||
else
|
else
|
||||||
return 0xffffff;
|
return 0xffffff;
|
||||||
}
|
}
|
||||||
@ -263,7 +259,7 @@ Uint32 window_t::map_rgb(Uint32 rgb)
|
|||||||
Uint8 b = rgb & 0xff;
|
Uint8 b = rgb & 0xff;
|
||||||
|
|
||||||
if(surface)
|
if(surface)
|
||||||
return SDL_MapRGB(surface->format, r, g, b);
|
return SDL_MapSurfaceRGB(surface, r, g, b);
|
||||||
else
|
else
|
||||||
return 0xffffff;
|
return 0xffffff;
|
||||||
}
|
}
|
||||||
@ -283,7 +279,7 @@ void window_t::colorkey(Uint32 color)
|
|||||||
return;
|
return;
|
||||||
if(!_offscreen)
|
if(!_offscreen)
|
||||||
return;
|
return;
|
||||||
SDL_SetColorKey(surface, SDL_SRCCOLORKEY, color);
|
SDL_SetSurfaceColorKey(surface, true, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_t::colorkey()
|
void window_t::colorkey()
|
||||||
@ -294,7 +290,7 @@ void window_t::colorkey()
|
|||||||
return;
|
return;
|
||||||
if(!_offscreen)
|
if(!_offscreen)
|
||||||
return;
|
return;
|
||||||
SDL_SetColorKey(surface, 0, 0);
|
SDL_SetSurfaceColorKey(surface, false, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void window_t::alpha(float a)
|
void window_t::alpha(float a)
|
||||||
@ -305,7 +301,8 @@ void window_t::alpha(float a)
|
|||||||
return;
|
return;
|
||||||
if(!_offscreen)
|
if(!_offscreen)
|
||||||
return;
|
return;
|
||||||
SDL_SetAlpha(surface, SDL_SRCALPHA, (int)(a * 255.0));
|
SDL_SetSurfaceAlphaMod(surface, (Uint8)(a * 255.0f));
|
||||||
|
SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -476,13 +473,13 @@ void window_t::clear(SDL_Rect *r)
|
|||||||
dr.y += phys_rect.y;
|
dr.y += phys_rect.y;
|
||||||
}
|
}
|
||||||
if((-1 == bg_bank) && (-1 == bg_frame))
|
if((-1 == bg_bank) && (-1 == bg_frame))
|
||||||
SDL_FillRect(surface, &dr, bgcolor);
|
SDL_FillSurfaceRect(surface, &dr, bgcolor);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s_sprite_t *s = engine->get_sprite(bg_bank, bg_frame);
|
s_sprite_t *s = engine->get_sprite(bg_bank, bg_frame);
|
||||||
if(!s || !s->surface)
|
if(!s || !s->surface)
|
||||||
{
|
{
|
||||||
SDL_FillRect(surface, &dr, bgcolor);
|
SDL_FillSurfaceRect(surface, &dr, bgcolor);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SDL_BlitSurface(s->surface, &sr, surface, &dr);
|
SDL_BlitSurface(s->surface, &sr, surface, &dr);
|
||||||
@ -507,7 +504,7 @@ void window_t::point(int _x, int _y)
|
|||||||
r.w = x2 - _x;
|
r.w = x2 - _x;
|
||||||
r.h = y2 - _y;
|
r.h = y2 - _y;
|
||||||
if(surface)
|
if(surface)
|
||||||
SDL_FillRect(surface, &r, fgcolor);
|
SDL_FillSurfaceRect(surface, &r, fgcolor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -527,7 +524,7 @@ void window_t::fillrect(int _x, int _y, int w, int h)
|
|||||||
r.w = x2 - _x;
|
r.w = x2 - _x;
|
||||||
r.h = y2 - _y;
|
r.h = y2 - _y;
|
||||||
if(surface)
|
if(surface)
|
||||||
SDL_FillRect(surface, &r, fgcolor);
|
SDL_FillSurfaceRect(surface, &r, fgcolor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -556,7 +553,7 @@ void window_t::fillrect_fxp(int _x, int _y, int w, int h)
|
|||||||
r.w = w;
|
r.w = w;
|
||||||
r.h = h;
|
r.h = h;
|
||||||
if(surface)
|
if(surface)
|
||||||
SDL_FillRect(surface, &r, fgcolor);
|
SDL_FillSurfaceRect(surface, &r, fgcolor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
116
kobo.cpp
116
kobo.cpp
@ -440,14 +440,14 @@ int KOBO_main::quit_requested()
|
|||||||
{
|
{
|
||||||
switch(e.type)
|
switch(e.type)
|
||||||
{
|
{
|
||||||
case SDL_QUIT:
|
case SDL_EVENT_QUIT:
|
||||||
exit_game_fast = 1;
|
exit_game_fast = 1;
|
||||||
break;
|
break;
|
||||||
case SDL_VIDEOEXPOSE:
|
case SDL_EVENT_WINDOW_EXPOSED:
|
||||||
gengine->invalidate();
|
gengine->invalidate();
|
||||||
break;
|
break;
|
||||||
case SDL_KEYUP:
|
case SDL_EVENT_KEY_UP:
|
||||||
switch(e.key.keysym.sym)
|
switch(e.key.key)
|
||||||
{
|
{
|
||||||
case SDLK_ESCAPE:
|
case SDLK_ESCAPE:
|
||||||
if(escape_hammering())
|
if(escape_hammering())
|
||||||
@ -459,9 +459,7 @@ int KOBO_main::quit_requested()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(exit_game_fast)
|
return exit_game_fast ? 1 : 0;
|
||||||
return 1;
|
|
||||||
return SDL_QuitRequested();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1205,7 +1203,7 @@ int KOBO_main::load_graphics(prefs_t *p)
|
|||||||
return -10;
|
return -10;
|
||||||
RGN_FreeRegion(logo_region);
|
RGN_FreeRegion(logo_region);
|
||||||
logo_region = RGN_ScanMask(s->surface,
|
logo_region = RGN_ScanMask(s->surface,
|
||||||
SDL_MapRGB(s->surface->format, 255, 255, 255));
|
SDL_MapSurfaceRGB(s->surface, 255, 255, 255));
|
||||||
if(!logo_region)
|
if(!logo_region)
|
||||||
{
|
{
|
||||||
log_printf(ELOG, "Could not create logo region!\n");
|
log_printf(ELOG, "Could not create logo region!\n");
|
||||||
@ -1239,52 +1237,20 @@ int KOBO_main::load_sounds(prefs_t *p, int render_all)
|
|||||||
|
|
||||||
int KOBO_main::init_js(prefs_t *p)
|
int KOBO_main::init_js(prefs_t *p)
|
||||||
{
|
{
|
||||||
/* Activate Joystick sub-sys if we are using it */
|
// SDL 3 joystick API uses instance IDs and SDL_GetJoysticks /
|
||||||
|
// SDL_OpenJoystick. Port deferred — disabled for now.
|
||||||
if(p->use_joystick)
|
if(p->use_joystick)
|
||||||
{
|
log_printf(WLOG, "Joystick support not yet ported to SDL 3.\n");
|
||||||
if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0)
|
p->number_of_joysticks = 0;
|
||||||
{
|
|
||||||
log_printf(ELOG, "Error setting up joystick!\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
p->number_of_joysticks = SDL_NumJoysticks();
|
|
||||||
if(p->number_of_joysticks > 0)
|
|
||||||
{
|
|
||||||
SDL_JoystickEventState(SDL_ENABLE);
|
|
||||||
if(p->joystick_no >= p->number_of_joysticks)
|
|
||||||
p->joystick_no = 0;
|
|
||||||
joystick = SDL_JoystickOpen(p->joystick_no);
|
|
||||||
if(!joystick)
|
|
||||||
{
|
|
||||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
log_printf(ELOG, "No joysticks found!\n");
|
|
||||||
joystick = NULL;
|
joystick = NULL;
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void KOBO_main::close_js()
|
void KOBO_main::close_js()
|
||||||
{
|
{
|
||||||
if(!SDL_WasInit(SDL_INIT_JOYSTICK))
|
// Stub: see init_js. Joystick port pending.
|
||||||
return;
|
|
||||||
|
|
||||||
if(!joystick)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(SDL_JoystickOpened(0))
|
|
||||||
SDL_JoystickClose(joystick);
|
|
||||||
joystick = NULL;
|
joystick = NULL;
|
||||||
|
|
||||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1597,8 +1563,8 @@ void kobo_gfxengine_t::frame()
|
|||||||
int k, ms;
|
int k, ms;
|
||||||
switch (ev.type)
|
switch (ev.type)
|
||||||
{
|
{
|
||||||
case SDL_KEYDOWN:
|
case SDL_EVENT_KEY_DOWN:
|
||||||
switch(ev.key.keysym.sym)
|
switch(ev.key.key)
|
||||||
{
|
{
|
||||||
#ifdef PROFILE_AUDIO
|
#ifdef PROFILE_AUDIO
|
||||||
case SDLK_F10:
|
case SDLK_F10:
|
||||||
@ -1607,7 +1573,7 @@ void kobo_gfxengine_t::frame()
|
|||||||
case SDLK_F12:
|
case SDLK_F12:
|
||||||
audio_print_info();
|
audio_print_info();
|
||||||
break;
|
break;
|
||||||
case SDLK_r:
|
case SDLK_R:
|
||||||
{
|
{
|
||||||
audio_channel_stop(-1, -1);
|
audio_channel_stop(-1, -1);
|
||||||
int startt = SDL_GetTicks();
|
int startt = SDL_GetTicks();
|
||||||
@ -1626,9 +1592,9 @@ void kobo_gfxengine_t::frame()
|
|||||||
break;
|
break;
|
||||||
case SDLK_RETURN:
|
case SDLK_RETURN:
|
||||||
ms = SDL_GetModState();
|
ms = SDL_GetModState();
|
||||||
if(ms & (KMOD_CTRL | KMOD_SHIFT | KMOD_META))
|
if(ms & (SDL_KMOD_CTRL | SDL_KMOD_SHIFT | SDL_KMOD_GUI))
|
||||||
break;
|
break;
|
||||||
if(!(ms & KMOD_ALT))
|
if(!(ms & SDL_KMOD_ALT))
|
||||||
break;
|
break;
|
||||||
km.pause_game();
|
km.pause_game();
|
||||||
prefs->fullscreen = !prefs->fullscreen;
|
prefs->fullscreen = !prefs->fullscreen;
|
||||||
@ -1637,21 +1603,23 @@ void kobo_gfxengine_t::frame()
|
|||||||
OS_RESTART_VIDEO;
|
OS_RESTART_VIDEO;
|
||||||
stop();
|
stop();
|
||||||
return;
|
return;
|
||||||
case SDLK_PRINT:
|
case SDLK_PRINTSCREEN:
|
||||||
case SDLK_SYSREQ:
|
|
||||||
// FIXME: Doesn't this trigger when entering names and stuff...?
|
// FIXME: Doesn't this trigger when entering names and stuff...?
|
||||||
case SDLK_s:
|
case SDLK_S:
|
||||||
gengine->screenshot();
|
gengine->screenshot();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
k = gamecontrol.map(ev.key.keysym.sym);
|
k = gamecontrol.map(ev.key.key);
|
||||||
gamecontrol.press(k);
|
gamecontrol.press(k);
|
||||||
gsm.press(k, ev.key.keysym.unicode);
|
// SDL 3 dropped per-keydown unicode; text input is via
|
||||||
|
// SDL_EVENT_TEXT_INPUT. Pass 0 for the unicode arg until
|
||||||
|
// the high-score name-entry path is re-wired.
|
||||||
|
gsm.press(k, 0);
|
||||||
break;
|
break;
|
||||||
case SDL_KEYUP:
|
case SDL_EVENT_KEY_UP:
|
||||||
if((ev.key.keysym.sym == SDLK_ESCAPE) && km.escape_hammering())
|
if((ev.key.key == SDLK_ESCAPE) && km.escape_hammering())
|
||||||
{
|
{
|
||||||
km.pause_game();
|
km.pause_game();
|
||||||
prefs->fullscreen = 0;
|
prefs->fullscreen = 0;
|
||||||
@ -1674,7 +1642,7 @@ void kobo_gfxengine_t::frame()
|
|||||||
gsm.push(&st_error);
|
gsm.push(&st_error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
k = gamecontrol.map(ev.key.keysym.sym);
|
k = gamecontrol.map(ev.key.key);
|
||||||
if(k == SDLK_PAUSE)
|
if(k == SDLK_PAUSE)
|
||||||
{
|
{
|
||||||
gamecontrol.press(BTN_PAUSE);
|
gamecontrol.press(BTN_PAUSE);
|
||||||
@ -1686,19 +1654,17 @@ void kobo_gfxengine_t::frame()
|
|||||||
gsm.release(k);
|
gsm.release(k);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_VIDEOEXPOSE:
|
case SDL_EVENT_WINDOW_EXPOSED:
|
||||||
gengine->invalidate();
|
gengine->invalidate();
|
||||||
break;
|
break;
|
||||||
case SDL_ACTIVEEVENT:
|
case SDL_EVENT_WINDOW_FOCUS_LOST:
|
||||||
// Any type of focus loss should activate pause mode!
|
|
||||||
if(!ev.active.gain)
|
|
||||||
km.pause_game();
|
km.pause_game();
|
||||||
break;
|
break;
|
||||||
case SDL_QUIT:
|
case SDL_EVENT_QUIT:
|
||||||
/*gsm.press(BTN_CLOSE);*/
|
/*gsm.press(BTN_CLOSE);*/
|
||||||
km.brutal_quit();
|
km.brutal_quit();
|
||||||
break;
|
break;
|
||||||
case SDL_JOYBUTTONDOWN:
|
case SDL_EVENT_JOYSTICK_BUTTON_DOWN:
|
||||||
if(ev.jbutton.button == km.js_fire)
|
if(ev.jbutton.button == km.js_fire)
|
||||||
{
|
{
|
||||||
gamecontrol.press(BTN_FIRE);
|
gamecontrol.press(BTN_FIRE);
|
||||||
@ -1710,14 +1676,14 @@ void kobo_gfxengine_t::frame()
|
|||||||
gsm.press(BTN_START);
|
gsm.press(BTN_START);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_JOYBUTTONUP:
|
case SDL_EVENT_JOYSTICK_BUTTON_UP:
|
||||||
if(ev.jbutton.button == km.js_fire)
|
if(ev.jbutton.button == km.js_fire)
|
||||||
{
|
{
|
||||||
gamecontrol.release(BTN_FIRE);
|
gamecontrol.release(BTN_FIRE);
|
||||||
gsm.release(BTN_FIRE);
|
gsm.release(BTN_FIRE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_JOYAXISMOTION:
|
case SDL_EVENT_JOYSTICK_AXIS_MOTION:
|
||||||
// FIXME: We will want to allow these to be
|
// FIXME: We will want to allow these to be
|
||||||
// redefined, but for now, this works ;-)
|
// redefined, but for now, this works ;-)
|
||||||
if(ev.jaxis.axis == km.js_lr)
|
if(ev.jaxis.axis == km.js_lr)
|
||||||
@ -1762,7 +1728,8 @@ void kobo_gfxengine_t::frame()
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
case SDL_MOUSEMOTION:
|
break;
|
||||||
|
case SDL_EVENT_MOUSE_MOTION:
|
||||||
mouse_x = (int)(ev.motion.x / gengine->xscale()) - km.xoffs;
|
mouse_x = (int)(ev.motion.x / gengine->xscale()) - km.xoffs;
|
||||||
mouse_y = (int)(ev.motion.y / gengine->yscale()) - km.yoffs;
|
mouse_y = (int)(ev.motion.y / gengine->yscale()) - km.yoffs;
|
||||||
if(prefs->use_mouse)
|
if(prefs->use_mouse)
|
||||||
@ -1770,9 +1737,9 @@ void kobo_gfxengine_t::frame()
|
|||||||
mouse_x - 8 - MARGIN - WSIZE/2,
|
mouse_x - 8 - MARGIN - WSIZE/2,
|
||||||
mouse_y - MARGIN - WSIZE/2);
|
mouse_y - MARGIN - WSIZE/2);
|
||||||
break;
|
break;
|
||||||
case SDL_MOUSEBUTTONDOWN:
|
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||||
mouse_x = (int)(ev.motion.x / gengine->xscale()) - km.xoffs;
|
mouse_x = (int)(ev.button.x / gengine->xscale()) - km.xoffs;
|
||||||
mouse_y = (int)(ev.motion.y / gengine->yscale()) - km.yoffs;
|
mouse_y = (int)(ev.button.y / gengine->yscale()) - km.yoffs;
|
||||||
gsm.press(BTN_FIRE);
|
gsm.press(BTN_FIRE);
|
||||||
if(prefs->use_mouse)
|
if(prefs->use_mouse)
|
||||||
{
|
{
|
||||||
@ -1794,9 +1761,9 @@ void kobo_gfxengine_t::frame()
|
|||||||
gamecontrol.press(BTN_FIRE);
|
gamecontrol.press(BTN_FIRE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_MOUSEBUTTONUP:
|
case SDL_EVENT_MOUSE_BUTTON_UP:
|
||||||
mouse_x = (int)(ev.motion.x / gengine->xscale()) - km.xoffs;
|
mouse_x = (int)(ev.button.x / gengine->xscale()) - km.xoffs;
|
||||||
mouse_y = (int)(ev.motion.y / gengine->yscale()) - km.yoffs;
|
mouse_y = (int)(ev.button.y / gengine->yscale()) - km.yoffs;
|
||||||
if(prefs->use_mouse)
|
if(prefs->use_mouse)
|
||||||
{
|
{
|
||||||
gamecontrol.mouse_position(
|
gamecontrol.mouse_position(
|
||||||
@ -2086,8 +2053,9 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if(prefs->cmd_noparachute)
|
if(prefs->cmd_noparachute)
|
||||||
{
|
{
|
||||||
|
// SDL 3 has no parachute / signal handler by default.
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
SDL_Init(SDL_INIT_NOPARACHUTE);
|
SDL_Init(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
km.open_logging(prefs);
|
km.open_logging(prefs);
|
||||||
|
|||||||
4
manage.h
4
manage.h
@ -87,8 +87,8 @@ class _manage
|
|||||||
static void lost_myship();
|
static void lost_myship();
|
||||||
static void destroyed_a_core();
|
static void destroyed_a_core();
|
||||||
static void add_score(int sc);
|
static void add_score(int sc);
|
||||||
static void key_down(SDLKey sym);
|
static void key_down(SDL_Keycode sym);
|
||||||
static void key_up(SDLKey sym);
|
static void key_up(SDL_Keycode sym);
|
||||||
static int title_blank() { return blank; }
|
static int title_blank() { return blank; }
|
||||||
static void select_next(int redraw_map = 1);
|
static void select_next(int redraw_map = 1);
|
||||||
static void select_prev(int redraw_map = 1);
|
static void select_prev(int redraw_map = 1);
|
||||||
|
|||||||
27
options.cpp
27
options.cpp
@ -187,18 +187,13 @@ void video_options_t::build()
|
|||||||
prf->videodriver = GFX_DRIVER_SDL2D;
|
prf->videodriver = GFX_DRIVER_SDL2D;
|
||||||
space();
|
space();
|
||||||
xoffs = 0.55;
|
xoffs = 0.55;
|
||||||
switch(prf->videodriver)
|
// Only the SDL 2D driver remains since the SDL 3 migration; the
|
||||||
{
|
// OpenGL driver is now handled by the SDL renderer itself.
|
||||||
case GFX_DRIVER_SDL2D:
|
|
||||||
list("Display Buffering Mode", &prf->doublebuf, OS_RESTART_VIDEO);
|
list("Display Buffering Mode", &prf->doublebuf, OS_RESTART_VIDEO);
|
||||||
item("Single", 0);
|
item("Single", 0);
|
||||||
item("Double", 1);
|
item("Double", 1);
|
||||||
yesno("Software Shadow Buffer", &prf->shadow, OS_RESTART_VIDEO);
|
yesno("Software Shadow Buffer", &prf->shadow, OS_RESTART_VIDEO);
|
||||||
break;
|
|
||||||
case GFX_DRIVER_GLSDL:
|
|
||||||
yesno("Vertical Retrace Sync", &prf->vsync, OS_RESTART_VIDEO);
|
yesno("Vertical Retrace Sync", &prf->vsync, OS_RESTART_VIDEO);
|
||||||
break;
|
|
||||||
}
|
|
||||||
list("Display Buffer Pages", &prf->pages, OS_UPDATE_ENGINE);
|
list("Display Buffer Pages", &prf->pages, OS_UPDATE_ENGINE);
|
||||||
item("Assume Standard", -1);
|
item("Assume Standard", -1);
|
||||||
item("Always Repaint", 0);
|
item("Always Repaint", 0);
|
||||||
@ -243,13 +238,9 @@ void graphics_options_t::build()
|
|||||||
item("2x2 Filter", 0);
|
item("2x2 Filter", 0);
|
||||||
item("4x4 Filter", 1);
|
item("4x4 Filter", 1);
|
||||||
item("Random", 2);
|
item("Random", 2);
|
||||||
switch(prf->videodriver)
|
// "Broken RGBA8" was a glSDL workaround for cards that supported
|
||||||
{
|
// RGB8 but not RGBA8 textures; SDL 3's renderer handles this
|
||||||
case GFX_DRIVER_GLSDL:
|
// transparently.
|
||||||
yesno("Broken RGBA8 (OpenGL)", &prf->broken_rgba8,
|
|
||||||
OS_RELOAD_GRAPHICS);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
space();
|
space();
|
||||||
yesno("Alpha Blending", &prf->alpha, OS_RELOAD_GRAPHICS);
|
yesno("Alpha Blending", &prf->alpha, OS_RELOAD_GRAPHICS);
|
||||||
space();
|
space();
|
||||||
@ -396,11 +387,15 @@ void control_options_t::build()
|
|||||||
item("5 frames", 5);
|
item("5 frames", 5);
|
||||||
space();
|
space();
|
||||||
|
|
||||||
if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0)
|
if(!SDL_InitSubSystem(SDL_INIT_JOYSTICK))
|
||||||
label("Could not initialize joysticks!");
|
label("Could not initialize joysticks!");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prf->number_of_joysticks = SDL_NumJoysticks();
|
// SDL 3: SDL_NumJoysticks → SDL_GetJoysticks(&count).
|
||||||
|
int njs = 0;
|
||||||
|
SDL_JoystickID *jids = SDL_GetJoysticks(&njs);
|
||||||
|
SDL_free(jids);
|
||||||
|
prf->number_of_joysticks = njs;
|
||||||
yesno("Use Joystick", &prf->use_joystick,
|
yesno("Use Joystick", &prf->use_joystick,
|
||||||
OS_RESTART_INPUT | OS_REBUILD);
|
OS_RESTART_INPUT | OS_REBUILD);
|
||||||
if(prf->use_joystick)
|
if(prf->use_joystick)
|
||||||
|
|||||||
@ -832,15 +832,15 @@ int audio_wave_load(int wid, const char *name, int looped)
|
|||||||
{
|
{
|
||||||
switch (spec.format)
|
switch (spec.format)
|
||||||
{
|
{
|
||||||
case AUDIO_S8:
|
case SDL_AUDIO_S8:
|
||||||
wavetab[wid].format = AF_MONO8;
|
wavetab[wid].format = AF_MONO8;
|
||||||
break;
|
break;
|
||||||
case AUDIO_S16SYS:
|
case SDL_AUDIO_S16:
|
||||||
wavetab[wid].format = AF_MONO16;
|
wavetab[wid].format = AF_MONO16;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log_printf(ELOG, "sound_load(): Unsupported wave format!\n");
|
log_printf(ELOG, "sound_load(): Unsupported wave format!\n");
|
||||||
SDL_FreeWAV((Uint8 *)(wavetab[wid].data.si8));
|
SDL_free(wavetab[wid].data.si8);
|
||||||
res = -1;
|
res = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -862,7 +862,7 @@ int audio_wave_load(int wid, const char *name, int looped)
|
|||||||
audio_wave_load_mem(wid, data, size, looped);
|
audio_wave_load_mem(wid, data, size, looped);
|
||||||
|
|
||||||
if(using_loadwav)
|
if(using_loadwav)
|
||||||
SDL_FreeWAV(data);
|
SDL_free(data);
|
||||||
else
|
else
|
||||||
free(data);
|
free(data);
|
||||||
|
|
||||||
|
|||||||
@ -49,6 +49,29 @@
|
|||||||
#include <SDL3/SDL_audio.h>
|
#include <SDL3/SDL_audio.h>
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SDL 3 migration: the SDL 1.2 audio API (SDL_OpenAudio + callback model,
|
||||||
|
* AUDIO_S16SYS, SDL_LockAudio/PauseAudio/CloseAudio, SDL_AudioSpec.samples
|
||||||
|
* and .callback) is gone. SDL 3 uses SDL_OpenAudioDeviceStream with a
|
||||||
|
* pull-stream callback. Porting that bridge is a separate phase; for now
|
||||||
|
* we provide local stubs so the engine links, and _start_SDL_output()
|
||||||
|
* below returns -1 so audio is silently disabled.
|
||||||
|
*/
|
||||||
|
#define AUDIO_S16SYS 0
|
||||||
|
#define SDL_OpenAudio(a, b) (-1)
|
||||||
|
#define SDL_CloseAudio() ((void)0)
|
||||||
|
#define SDL_PauseAudio(x) ((void)0)
|
||||||
|
#define SDL_LockAudio() ((void)0)
|
||||||
|
#define SDL_UnlockAudio() ((void)0)
|
||||||
|
typedef struct {
|
||||||
|
int freq;
|
||||||
|
Uint16 format;
|
||||||
|
Uint8 channels;
|
||||||
|
Uint16 samples;
|
||||||
|
void (*callback)(void *userdata, Uint8 *stream, int len);
|
||||||
|
} kobo_legacy_audio_spec_t;
|
||||||
|
#define SDL_AudioSpec kobo_legacy_audio_spec_t
|
||||||
|
|
||||||
#include "a_struct.h"
|
#include "a_struct.h"
|
||||||
#include "a_commands.h"
|
#include "a_commands.h"
|
||||||
#include "a_control.h"
|
#include "a_control.h"
|
||||||
@ -569,6 +592,10 @@ static int _start_oss_output()
|
|||||||
|
|
||||||
static int _start_SDL_output(void)
|
static int _start_SDL_output(void)
|
||||||
{
|
{
|
||||||
|
log_printf(WLOG, "audio.c: SDL 3 audio backend not yet ported;"
|
||||||
|
" sound disabled.\n");
|
||||||
|
return -1;
|
||||||
|
#if 0
|
||||||
SDL_AudioSpec as;
|
SDL_AudioSpec as;
|
||||||
SDL_AudioSpec audiospec;
|
SDL_AudioSpec audiospec;
|
||||||
|
|
||||||
@ -629,6 +656,7 @@ static int _start_SDL_output(void)
|
|||||||
_audio_running = 1;
|
_audio_running = 1;
|
||||||
SDL_PauseAudio(0);
|
SDL_PauseAudio(0);
|
||||||
return 0;
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
14
states.cpp
14
states.cpp
@ -23,6 +23,20 @@
|
|||||||
|
|
||||||
#include "sdl_compat.h"
|
#include "sdl_compat.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SDL 3 migration: SDL_WM_GrabInput and SDL_EnableUNICODE are gone.
|
||||||
|
* Replacements (SDL_SetWindowMouseGrab and SDL_StartTextInput) both
|
||||||
|
* require the window pointer, which we don't yet expose from gfxengine.
|
||||||
|
* Stub them out so the code links; mouse-capture and unicode text-input
|
||||||
|
* (high-score name entry) will be re-wired once gfxengine exposes the
|
||||||
|
* SDL_Window handle.
|
||||||
|
*/
|
||||||
|
#define SDL_GRAB_QUERY 0
|
||||||
|
#define SDL_GRAB_ON 1
|
||||||
|
#define SDL_GRAB_OFF 0
|
||||||
|
#define SDL_WM_GrabInput(x) (SDL_GRAB_OFF)
|
||||||
|
#define SDL_EnableUNICODE(x) ((void)0)
|
||||||
#ifndef M_PI
|
#ifndef M_PI
|
||||||
# define M_PI 3.14159265358979323846 /* pi */
|
# define M_PI 3.14159265358979323846 /* pi */
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user