Merge branch 'sdl3': migrate from SDL 1.2 to SDL 3
Brings the rendering, audio, input, and joystick layers from SDL 1.2
era APIs to native SDL 3, removes the ~2300-line glSDL OpenGL shim
that is now obsolete, and strips all the dead SDL 1.2 video-surface
state machinery (page flipping, hardware-surface flags, depth/driver
selection).
Major changes:
- Build system: find_package(SDL3 CONFIG) + SDL3::SDL3 /
SDL3_image::SDL3_image. sdl12-compat is no longer needed.
- Renderer: SDL_CreateWindow + SDL_CreateRenderer + a streaming
SDL_Texture replaces SDL_SetVideoMode + SDL_Flip. The CPU-side
back-buffer (softbuf) is now always ARGB8888 and uploaded once per
frame. SDL_SetRenderLogicalPresentation handles letterbox scaling.
- glSDL shim deleted (graphics/glSDL.{c,h}, ~2300 lines).
- Surface API: SDL_FreeSurface→SDL_DestroySurface, SDL_FillRect→
SDL_FillSurfaceRect, SDL_DisplayFormat→SDL_ConvertSurface(ARGB8888),
SDL_CreateRGBSurface→SDL_CreateSurface, SDL_SetColorKey/SetAlpha→
SDL_SetSurfaceColorKey/AlphaMod, surface->format access via
SDL_GetPixelFormatDetails.
- Events: SDL_KEYDOWN→SDL_EVENT_KEY_DOWN etc., ev.key.keysym.sym→
ev.key.key, ev.button.x/y for mouse buttons, SDL_VIDEOEXPOSE→
SDL_EVENT_WINDOW_EXPOSED, SDL_ACTIVEEVENT→SDL_EVENT_WINDOW_FOCUS_LOST.
- Keyboard: SDLKey→SDL_Keycode, SDLK_KP1..9→SDLK_KP_1..9, lowercase
SDLK_p/y/n→uppercase, KMOD_META→SDL_KMOD_GUI.
- Mouse grab: SDL_WM_GrabInput→SDL_SetWindowMouseGrab (via new
gfxengine_t::window_handle() accessor).
- Text input: SDL_EnableUNICODE→SDL_StartTextInput/SDL_StopTextInput
with SDL_EVENT_TEXT_INPUT forwarded to gsm.press(-1, ch).
- Joystick: SDL_NumJoysticks/JoystickOpen→SDL_GetJoysticks (instance
IDs)/SDL_OpenJoystick/SDL_CloseJoystick.
- Audio: SDL_OpenAudio + push-callback model→SDL_OpenAudioDeviceStream
+ SDL_AudioStreamCallback (pull). The engine's existing
_audio_callback is kept; an adapter (sdl3_stream_callback) runs it
on a scratch buffer and pushes the result via SDL_PutAudioStreamData.
- AUDIO_S16SYS→SDL_AUDIO_S16, SDL_FreeWAV→SDL_free.
Cleanup:
- Removed gfxengine_t fields _doublebuf, _pages, _shadow, _depth,
_driver, xflags, broken_rgba8, backpage/frontpage and the per-page
dirty-rect arrays (collapsed to 1-D).
- Removed prefs fields videodriver, depth, doublebuf, shadow, pages,
broken_rgba8. Existing config files are still readable (silently
absorbed as obsolete keys).
- Removed the Display Depth / Buffering Mode / Software Shadow Buffer
/ Display Buffer Pages / Broken RGBA8 entries from the options
menu.
- Removed the doublebuffer()-guarded second pass of the loading-
animation nibble draw in dashboard.cpp.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
commit
76c0776aec
@ -35,11 +35,9 @@ check_symbol_exists(_vsnprintf stdio.h HAVE__VSNPRINTF)
|
|||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# Third-party libraries
|
# Third-party libraries
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# This codebase targets SDL 1.2 and SDL_image 1.2. CMake's bundled FindSDL
|
# Migrating to SDL 3. Homebrew: `brew install sdl3 sdl3_image`.
|
||||||
# / FindSDL_image modules locate these directly; on macOS with Homebrew,
|
find_package(SDL3 CONFIG REQUIRED)
|
||||||
# `brew install sdl12-compat sdl_image` works.
|
find_package(SDL3_image CONFIG REQUIRED)
|
||||||
find_package(SDL REQUIRED)
|
|
||||||
find_package(SDL_image REQUIRED)
|
|
||||||
|
|
||||||
if(KOBO_ENABLE_OPENGL)
|
if(KOBO_ENABLE_OPENGL)
|
||||||
find_package(OpenGL)
|
find_package(OpenGL)
|
||||||
@ -122,9 +120,8 @@ target_compile_definitions(kobo_deps INTERFACE
|
|||||||
target_include_directories(kobo_deps INTERFACE
|
target_include_directories(kobo_deps INTERFACE
|
||||||
${CMAKE_CURRENT_BINARY_DIR} # for generated aconfig.h
|
${CMAKE_CURRENT_BINARY_DIR} # for generated aconfig.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR} # for config.h
|
${CMAKE_CURRENT_SOURCE_DIR} # for config.h
|
||||||
${SDL_INCLUDE_DIR}
|
|
||||||
)
|
)
|
||||||
target_link_libraries(kobo_deps INTERFACE ${SDL_LIBRARY} ${SDL_IMAGE_LIBRARIES})
|
target_link_libraries(kobo_deps INTERFACE SDL3::SDL3 SDL3_image::SDL3_image)
|
||||||
|
|
||||||
if(HAVE_OPENGL)
|
if(HAVE_OPENGL)
|
||||||
target_compile_definitions(kobo_deps INTERFACE HAVE_OPENGL)
|
target_compile_definitions(kobo_deps INTERFACE HAVE_OPENGL)
|
||||||
|
|||||||
@ -309,8 +309,8 @@ void dashboard_window_t::nibble(int tool)
|
|||||||
}
|
}
|
||||||
gengine->invalidate();
|
gengine->invalidate();
|
||||||
gengine->flip();
|
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)
|
if(last_index >= NIBBLE_TILES)
|
||||||
@ -337,7 +337,6 @@ void dashboard_window_t::nibble(int tool)
|
|||||||
++last_index;
|
++last_index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
mode(DASHBOARD_BLACK);
|
mode(DASHBOARD_BLACK);
|
||||||
gengine->flip();
|
gengine->flip();
|
||||||
}
|
}
|
||||||
|
|||||||
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;
|
||||||
|
|||||||
20
gamectl.h
20
gamectl.h
@ -23,17 +23,17 @@
|
|||||||
#ifndef _KOBO_GAMECTL_H_
|
#ifndef _KOBO_GAMECTL_H_
|
||||||
#define _KOBO_GAMECTL_H_
|
#define _KOBO_GAMECTL_H_
|
||||||
|
|
||||||
#include "glSDL.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);
|
||||||
|
|||||||
@ -2,7 +2,6 @@ add_library(graphics STATIC
|
|||||||
cs.c
|
cs.c
|
||||||
sprite.c
|
sprite.c
|
||||||
filters.c
|
filters.c
|
||||||
glSDL.c
|
|
||||||
gfxengine.cpp
|
gfxengine.cpp
|
||||||
window.cpp
|
window.cpp
|
||||||
sofont.cpp
|
sofont.cpp
|
||||||
|
|||||||
@ -22,8 +22,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "glSDL.h"
|
#include "sdl_compat.h"
|
||||||
#include "SDL_image.h"
|
#include <SDL3_image/SDL_image.h>
|
||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
#include "filters.h"
|
#include "filters.h"
|
||||||
|
|
||||||
@ -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;
|
||||||
|
|||||||
@ -28,8 +28,8 @@
|
|||||||
|
|
||||||
#include "gfxengine.h"
|
#include "gfxengine.h"
|
||||||
#include "filters.h"
|
#include "filters.h"
|
||||||
#include "SDL_image.h"
|
#include <SDL3_image/SDL_image.h>
|
||||||
#include "glSDL.h"
|
#include "sdl_compat.h"
|
||||||
#include "sofont.h"
|
#include "sofont.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
@ -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;
|
||||||
@ -51,15 +54,10 @@ gfxengine_t::gfxengine_t()
|
|||||||
sf1 = df = dsf = acf = NULL;
|
sf1 = df = dsf = acf = NULL;
|
||||||
gfx = NULL;
|
gfx = NULL;
|
||||||
csengine = NULL;
|
csengine = NULL;
|
||||||
_driver = GFX_DRIVER_SDL2D;
|
|
||||||
_shadow = 1;
|
|
||||||
_doublebuf = 1;
|
|
||||||
_pages = -1;
|
|
||||||
_vsync = 1;
|
_vsync = 1;
|
||||||
_fullscreen = 0;
|
_fullscreen = 0;
|
||||||
_centered = 0;
|
_centered = 0;
|
||||||
use_interpolation = 1;
|
use_interpolation = 1;
|
||||||
_depth = 0;
|
|
||||||
_title = "GfxEngine v0.4";
|
_title = "GfxEngine v0.4";
|
||||||
_icontitle = "GfxEngine";
|
_icontitle = "GfxEngine";
|
||||||
_cursor = 1;
|
_cursor = 1;
|
||||||
@ -68,11 +66,9 @@ gfxengine_t::gfxengine_t()
|
|||||||
_autoinvalidate = 1;
|
_autoinvalidate = 1;
|
||||||
_scalemode = GFX_SCALE_NEAREST;
|
_scalemode = GFX_SCALE_NEAREST;
|
||||||
_clamping = 0;
|
_clamping = 0;
|
||||||
xflags = 0;
|
|
||||||
|
|
||||||
_dither = 0;
|
_dither = 0;
|
||||||
_dither_type = 0;
|
_dither_type = 0;
|
||||||
broken_rgba8 = 0;
|
|
||||||
alpha_threshold = 0;
|
alpha_threshold = 0;
|
||||||
|
|
||||||
_brightness = 1.0;
|
_brightness = 1.0;
|
||||||
@ -91,10 +87,7 @@ gfxengine_t::gfxengine_t()
|
|||||||
for(int i = 0; i < CS_LAYERS ; ++i)
|
for(int i = 0; i < CS_LAYERS ; ++i)
|
||||||
xratio[i] = yratio[i] = 0.0;
|
xratio[i] = yratio[i] = 0.0;
|
||||||
|
|
||||||
dirtyrects[0] = 0;
|
dirtyrects = 0;
|
||||||
dirtyrects[1] = 0;
|
|
||||||
frontpage = 0;
|
|
||||||
backpage = 1;
|
|
||||||
screenshot_count = 0;
|
screenshot_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,75 +150,23 @@ void gfxengine_t::scale(float x, float y)
|
|||||||
|
|
||||||
void gfxengine_t::mode(int bits, int fullscreen)
|
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;
|
int was_showing = is_showing;
|
||||||
hide();
|
hide();
|
||||||
|
|
||||||
int olddepth = _depth;
|
|
||||||
_depth = bits;
|
|
||||||
if(_depth != olddepth)
|
|
||||||
reload();
|
|
||||||
_fullscreen = fullscreen;
|
_fullscreen = fullscreen;
|
||||||
|
|
||||||
if(was_showing)
|
if(was_showing)
|
||||||
show();
|
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)
|
void gfxengine_t::vsync(int use)
|
||||||
{
|
{
|
||||||
if(_vsync == use)
|
if(_vsync == use)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int was_showing = is_showing;
|
|
||||||
hide();
|
|
||||||
|
|
||||||
_vsync = use;
|
_vsync = use;
|
||||||
|
if(sdl_renderer)
|
||||||
if(was_showing)
|
SDL_SetRenderVSync(sdl_renderer, use ? 1 : 0);
|
||||||
show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void gfxengine_t::shadow(int use)
|
|
||||||
{
|
|
||||||
if(_shadow == use)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int was_showing = is_showing;
|
|
||||||
hide();
|
|
||||||
|
|
||||||
_shadow = use;
|
|
||||||
|
|
||||||
if(was_showing)
|
|
||||||
show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfxengine_t::autoinvalidate(int use)
|
void gfxengine_t::autoinvalidate(int use)
|
||||||
@ -432,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 gfxengine_t::dither(int type, int _broken_rgba8)
|
||||||
{
|
{
|
||||||
|
(void)_broken_rgba8; // legacy OpenGL workaround; no-op in SDL 3
|
||||||
_dither = type >= 0;
|
_dither = type >= 0;
|
||||||
_dither_type = type;
|
_dither_type = type;
|
||||||
broken_rgba8 = _broken_rgba8;
|
|
||||||
|
|
||||||
if(!df)
|
if(!df)
|
||||||
return;
|
return;
|
||||||
@ -443,23 +384,13 @@ void gfxengine_t::dither(int type, int _broken_rgba8)
|
|||||||
|
|
||||||
if(_dither)
|
if(_dither)
|
||||||
{
|
{
|
||||||
if(_driver == GFX_DRIVER_GLSDL)
|
// SDL 3: back buffer is always ARGB8888 (8 bits per channel,
|
||||||
{
|
// no loss). The legacy formula was 1 << (Rloss - 1); for 8 bpc
|
||||||
//Klugde for glSDL, which doesn't give us a faked
|
// the dithering amplitude collapses to 0.
|
||||||
//screen surface - while we're interested only in
|
|
||||||
//the *texture* depth; not the display depth!
|
|
||||||
df->args.r = df->args.g = df->args.b = 0;
|
|
||||||
//Another kludge, because some cards support RGB8
|
|
||||||
//(24 bit) textures, but not RGBA8 (32 bit).
|
|
||||||
df->args.x = broken_rgba8;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
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;
|
||||||
@ -685,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)
|
if(is_open)
|
||||||
return show();
|
return show();
|
||||||
|
|
||||||
@ -745,8 +674,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -756,131 +685,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(_driver)
|
// SDL 3 window + renderer model.
|
||||||
{
|
//
|
||||||
case GFX_DRIVER_SDL2D:
|
// The kobo engine renders into a CPU-side back buffer (softbuf) via
|
||||||
break;
|
// SDL_BlitSurface/SDL_FillSurfaceRect, and uploads the result to a
|
||||||
case GFX_DRIVER_GLSDL:
|
// streaming SDL_Texture once per frame. This preserves the entire
|
||||||
if(!_doublebuf)
|
// software-compositing code path inherited from SDL 1.2 (window.cpp,
|
||||||
{
|
// sprite.c, filters.c, sofont.cpp), while letting the GPU handle
|
||||||
log_printf(WLOG, "Only double buffering is supported"
|
// scaling and presentation. SDL_DOUBLEBUF / SDL_HWSURFACE / page-
|
||||||
" with OpenGL drivers!\n");
|
// flipping flags are obsolete and ignored.
|
||||||
doublebuffer(1);
|
Uint64 win_flags = 0;
|
||||||
}
|
|
||||||
if(_shadow)
|
|
||||||
{
|
|
||||||
log_printf(WLOG, "Shadow buffer not supported"
|
|
||||||
" with OpenGL drivers!\n");
|
|
||||||
shadow(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(_driver)
|
|
||||||
{
|
|
||||||
case GFX_DRIVER_SDL2D:
|
|
||||||
/* Nothing extra */
|
|
||||||
break;
|
|
||||||
case GFX_DRIVER_GLSDL:
|
|
||||||
flags |= SDL_GLSDL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_doublebuf)
|
|
||||||
flags |= SDL_DOUBLEBUF | SDL_HWSURFACE;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(!_shadow)
|
|
||||||
flags |= SDL_HWSURFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_fullscreen)
|
if(_fullscreen)
|
||||||
flags |= SDL_FULLSCREEN;
|
win_flags |= SDL_WINDOW_FULLSCREEN;
|
||||||
|
|
||||||
glSDL_VSync(_vsync);
|
sdl_window = SDL_CreateWindow(_title ? _title : "Kobo Deluxe",
|
||||||
flags |= xflags;
|
_width, _height, win_flags);
|
||||||
|
if(!sdl_window)
|
||||||
screen_surface = SDL_SetVideoMode(_width, _height, _depth, flags);
|
|
||||||
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(_driver != GFX_DRIVER_GLSDL)
|
sdl_renderer = SDL_CreateRenderer(sdl_window, NULL);
|
||||||
|
if(!sdl_renderer)
|
||||||
{
|
{
|
||||||
if((screen_surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF)
|
log_printf(ELOG, "Failed to create renderer: %s\n",
|
||||||
{
|
SDL_GetError());
|
||||||
if(!_doublebuf)
|
SDL_DestroyWindow(sdl_window);
|
||||||
{
|
sdl_window = NULL;
|
||||||
log_printf(WLOG, "Could not get"
|
return -4;
|
||||||
" single buffered display.\n");
|
|
||||||
doublebuffer(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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;
|
||||||
|
|
||||||
@ -933,12 +825,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;
|
||||||
}
|
}
|
||||||
@ -946,54 +853,37 @@ void gfxengine_t::hide(void)
|
|||||||
|
|
||||||
void gfxengine_t::invalidate(SDL_Rect *rect, window_t *window)
|
void gfxengine_t::invalidate(SDL_Rect *rect, window_t *window)
|
||||||
{
|
{
|
||||||
switch(_pages)
|
__invalidate(rect, window);
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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)
|
if(!screen_surface)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!rect || (_pages == 0))
|
if(!rect)
|
||||||
{
|
{
|
||||||
dirtyrects[page] = 1;
|
dirtyrects = 1;
|
||||||
dirtytable[page][0].x = 0;
|
dirtytable[0].x = 0;
|
||||||
dirtytable[page][0].y = 0;
|
dirtytable[0].y = 0;
|
||||||
dirtytable[page][0].w = screen_surface->w;
|
dirtytable[0].w = screen_surface->w;
|
||||||
dirtytable[page][0].h = screen_surface->h;
|
dirtytable[0].h = screen_surface->h;
|
||||||
dirtywtable[page][0] = NULL;
|
dirtywtable[0] = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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;
|
||||||
@ -1004,8 +894,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;
|
||||||
@ -1016,19 +906,18 @@ void gfxengine_t::__invalidate(int page, SDL_Rect *rect, window_t *window)
|
|||||||
if(!dr.w || !dr.h)
|
if(!dr.w || !dr.h)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for(int i = 0; i < dirtyrects[page]; ++i)
|
for(int i = 0; i < dirtyrects; ++i)
|
||||||
if(memcmp(&dirtytable[page][i], &dr, sizeof(dr)) == 0)
|
if(memcmp(&dirtytable[i], &dr, sizeof(dr)) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(dirtyrects[page] < MAX_DIRTYRECTS - 1)
|
if(dirtyrects < MAX_DIRTYRECTS - 1)
|
||||||
{
|
{
|
||||||
dirtytable[page][dirtyrects[page]] = dr;
|
dirtytable[dirtyrects] = dr;
|
||||||
dirtywtable[page][dirtyrects[page]] = window;
|
dirtywtable[dirtyrects] = window;
|
||||||
++dirtyrects[page];
|
++dirtyrects;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
log_printf(ELOG, "gfxengine: Page %d out of dirtyrects!\n",
|
log_printf(ELOG, "gfxengine: Out of dirtyrects!\n");
|
||||||
page);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1109,7 +998,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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1215,8 +1109,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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1283,82 +1177,31 @@ 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
|
||||||
|
// is a single full-surface copy regardless.
|
||||||
|
for(int i = 0; i < dirtyrects; ++i)
|
||||||
{
|
{
|
||||||
case -1:
|
if(dirtywtable[i])
|
||||||
if(!_doublebuf)
|
|
||||||
frontpage = backpage = 0;
|
|
||||||
else if(frontpage == backpage)
|
|
||||||
{
|
{
|
||||||
frontpage = 0;
|
if(!dirtywtable[i]->visible())
|
||||||
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]->visible())
|
|
||||||
continue;
|
continue;
|
||||||
SDL_Rect dr = dirtytable[backpage][i];
|
SDL_Rect dr = dirtytable[i];
|
||||||
dirtywtable[backpage][i]->phys_refresh(&dr);
|
dirtywtable[i]->phys_refresh(&dr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
refresh_rect(&dirtytable[backpage][i]);
|
refresh_rect(&dirtytable[i]);
|
||||||
}
|
}
|
||||||
|
dirtyrects = 0;
|
||||||
|
|
||||||
// Perform the actual flip or update
|
SDL_UpdateTexture(fb_texture, NULL, softbuf->pixels, softbuf->pitch);
|
||||||
if(_shadow)
|
SDL_RenderClear(sdl_renderer);
|
||||||
{
|
SDL_RenderTexture(sdl_renderer, fb_texture, NULL, NULL);
|
||||||
for(i = 0; i < dirtyrects[backpage]; ++i)
|
SDL_RenderPresent(sdl_renderer);
|
||||||
SDL_BlitSurface(softbuf,
|
|
||||||
&dirtytable[backpage][i],
|
|
||||||
screen_surface,
|
|
||||||
&dirtytable[backpage][i]);
|
|
||||||
}
|
|
||||||
if(_doublebuf)
|
|
||||||
{
|
|
||||||
dirtyrects[backpage] = 0;
|
|
||||||
if(_pages == -1)
|
|
||||||
{
|
|
||||||
backpage = !backpage;
|
|
||||||
frontpage = !frontpage;
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -24,21 +24,14 @@
|
|||||||
|
|
||||||
#define GFX_BANKS 256
|
#define GFX_BANKS 256
|
||||||
#define MAX_DIRTYRECTS 1024
|
#define MAX_DIRTYRECTS 1024
|
||||||
#define MAX_PAGES 3
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "glSDL.h"
|
#include "sdl_compat.h"
|
||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
#include "cs.h"
|
#include "cs.h"
|
||||||
|
|
||||||
enum gfx_drivers_t
|
|
||||||
{
|
|
||||||
GFX_DRIVER_SDL2D = 0,
|
|
||||||
GFX_DRIVER_GLSDL = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
enum gfx_scalemodes_t
|
enum gfx_scalemodes_t
|
||||||
{
|
{
|
||||||
GFX_SCALE_NEAREST = 0,
|
GFX_SCALE_NEAREST = 0,
|
||||||
@ -70,25 +63,11 @@ class gfxengine_t
|
|||||||
void size(int w, int h);
|
void size(int w, int h);
|
||||||
void centered(int c);
|
void centered(int c);
|
||||||
void scale(float x, float y);
|
void scale(float x, float y);
|
||||||
void driver(gfx_drivers_t drv);
|
|
||||||
void mode(int bits, int fullscreen);
|
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
|
// 1: Enable vsync, if available
|
||||||
void vsync(int use);
|
void vsync(int use);
|
||||||
|
|
||||||
// 1: Use a software shadow back buffer, if possible
|
|
||||||
void shadow(int use);
|
|
||||||
|
|
||||||
void autoinvalidate(int use);
|
void autoinvalidate(int use);
|
||||||
|
|
||||||
void interpolation(int inter);
|
void interpolation(int inter);
|
||||||
@ -103,12 +82,10 @@ class gfxengine_t
|
|||||||
void wrap(int x, int y);
|
void wrap(int x, int y);
|
||||||
|
|
||||||
/* Info */
|
/* Info */
|
||||||
int doublebuffer() { return _doublebuf; }
|
|
||||||
int shadow() { return _shadow; }
|
|
||||||
int autoinvalidate() { return _autoinvalidate; }
|
int autoinvalidate() { return _autoinvalidate; }
|
||||||
|
|
||||||
/* Engine open/close */
|
/* Engine open/close */
|
||||||
int open(int objects = 1024, int extraflags = 0);
|
int open(int objects = 1024);
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
/* Data management (use while engine is open) */
|
/* Data management (use while engine is open) */
|
||||||
@ -172,6 +149,7 @@ class gfxengine_t
|
|||||||
|
|
||||||
/* Control */
|
/* Control */
|
||||||
cs_engine_t *cs() { return csengine; }
|
cs_engine_t *cs() { return csengine; }
|
||||||
|
SDL_Window *window_handle() { return sdl_window; }
|
||||||
SDL_Surface *surface();
|
SDL_Surface *surface();
|
||||||
void flip(); // Flip pages
|
void flip(); // Flip pages
|
||||||
void update(); // Full update, making current draw page visible
|
void update(); // Full update, making current draw page visible
|
||||||
@ -206,16 +184,16 @@ class gfxengine_t
|
|||||||
float yscale() { return ys * (1.f/256.f); }
|
float yscale() { return ys * (1.f/256.f); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
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 dirtyrects;
|
||||||
int frontpage;
|
SDL_Rect dirtytable[MAX_DIRTYRECTS];
|
||||||
int dirtyrects[MAX_PAGES];
|
window_t *dirtywtable[MAX_DIRTYRECTS];
|
||||||
SDL_Rect dirtytable[MAX_PAGES][MAX_DIRTYRECTS];
|
|
||||||
window_t *dirtywtable[MAX_PAGES][MAX_DIRTYRECTS];
|
|
||||||
window_t *fullwin;
|
window_t *fullwin;
|
||||||
window_t *window;
|
window_t *window;
|
||||||
window_t *windows; // Linked list
|
window_t *windows; // Linked list
|
||||||
@ -233,23 +211,17 @@ class gfxengine_t
|
|||||||
s_container_t *gfx;
|
s_container_t *gfx;
|
||||||
SoFont *fonts[GFX_BANKS]; // Kludge.
|
SoFont *fonts[GFX_BANKS]; // Kludge.
|
||||||
cs_engine_t *csengine;
|
cs_engine_t *csengine;
|
||||||
int xflags;
|
|
||||||
int _doublebuf;
|
|
||||||
int _pages;
|
|
||||||
int _vsync;
|
int _vsync;
|
||||||
int _shadow;
|
|
||||||
int _fullscreen;
|
int _fullscreen;
|
||||||
int _centered;
|
int _centered;
|
||||||
int _autoinvalidate;
|
int _autoinvalidate;
|
||||||
int use_interpolation;
|
int use_interpolation;
|
||||||
int _width, _height;
|
int _width, _height;
|
||||||
int _depth;
|
|
||||||
const char *_title;
|
const char *_title;
|
||||||
const char *_icontitle;
|
const char *_icontitle;
|
||||||
int _cursor;
|
int _cursor;
|
||||||
int _dither;
|
int _dither;
|
||||||
int _dither_type;
|
int _dither_type;
|
||||||
int broken_rgba8; //Klugde for OpenGL (if RGBA8 ==> RGBA4)
|
|
||||||
int alpha_threshold; //For noalpha()
|
int alpha_threshold; //For noalpha()
|
||||||
float _brightness;
|
float _brightness;
|
||||||
float _contrast;
|
float _contrast;
|
||||||
@ -264,8 +236,7 @@ class gfxengine_t
|
|||||||
|
|
||||||
int screenshot_count;
|
int screenshot_count;
|
||||||
|
|
||||||
void __invalidate(int page, SDL_Rect *rect = NULL,
|
void __invalidate(SDL_Rect *rect = NULL, window_t *window = NULL);
|
||||||
window_t *window = NULL);
|
|
||||||
void refresh_rect(SDL_Rect *r);
|
void refresh_rect(SDL_Rect *r);
|
||||||
|
|
||||||
static void on_frame(cs_engine_t *e);
|
static void on_frame(cs_engine_t *e);
|
||||||
|
|||||||
2328
graphics/glSDL.c
2328
graphics/glSDL.c
File diff suppressed because it is too large
Load Diff
399
graphics/glSDL.h
399
graphics/glSDL.h
@ -1,399 +0,0 @@
|
|||||||
/*(LGPL)
|
|
||||||
------------------------------------------------------------
|
|
||||||
glSDL 0.9 - SDL 2D API on top of OpenGL
|
|
||||||
------------------------------------------------------------
|
|
||||||
* Copyright (C) 2001-2004, 2006-2007 David Olofson
|
|
||||||
* This code is released under the terms of the GNU LGPL.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _GLSDL_H_
|
|
||||||
#define _GLSDL_H_
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If you don't use GNU autotools or similar, uncomment this to
|
|
||||||
* compile with OpenGL enabled:
|
|
||||||
#define HAVE_OPENGL
|
|
||||||
*
|
|
||||||
* NOTE:
|
|
||||||
* See README about using this glSDL wrapper with
|
|
||||||
* SDL versions that have the glSDL backend!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* We're still using SDL datatypes here - we just add some stuff. */
|
|
||||||
#include "SDL.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Ignore the flag from SDL w/ glSDL backend, since we're going
|
|
||||||
* to use glSDL/wrapper by default.
|
|
||||||
*/
|
|
||||||
#ifdef SDL_GLSDL
|
|
||||||
#undef SDL_GLSDL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef HAVE_OPENGL
|
|
||||||
|
|
||||||
/* Fakes to make glSDL code compile with SDL. */
|
|
||||||
#define SDL_GLSDL 0
|
|
||||||
#define GLSDL_FIX_SURFACE(s)
|
|
||||||
|
|
||||||
#else /* HAVE_OPENGL */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (SDL_MAJOR_VERSION <= 1) && (SDL_MINOR_VERSION <= 2) && \
|
|
||||||
(SDL_PATCHLEVEL < 5)
|
|
||||||
#warning glSDL: Using SDL version 1.2.5 or later is strongly recommended!
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*----------------------------------------------------------
|
|
||||||
SDL style API
|
|
||||||
----------------------------------------------------------*/
|
|
||||||
|
|
||||||
typedef enum glSDL_TileModes
|
|
||||||
{
|
|
||||||
GLSDL_TM_SINGLE,
|
|
||||||
GLSDL_TM_HORIZONTAL,
|
|
||||||
GLSDL_TM_VERTICAL,
|
|
||||||
GLSDL_TM_HUGE
|
|
||||||
} glSDL_TileModes;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct glSDL_TexInfo
|
|
||||||
{
|
|
||||||
int textures;
|
|
||||||
int *texture;
|
|
||||||
int texsize; /* width/height of OpenGL texture */
|
|
||||||
glSDL_TileModes tilemode;
|
|
||||||
int tilew, tileh; /* At least one must equal texsize! */
|
|
||||||
int tilespertex;
|
|
||||||
|
|
||||||
/* Area of surface to download when/after unlocking */
|
|
||||||
SDL_Rect invalid_area;
|
|
||||||
} glSDL_TexInfo;
|
|
||||||
|
|
||||||
#define GLSDL_FIX_SURFACE(s) (s)->unused1 = 0;
|
|
||||||
#define IS_GLSDL_SURFACE(s) ((s) && texinfotab && glSDL_GetTexInfo(s))
|
|
||||||
|
|
||||||
#ifdef SDL_GLSDL
|
|
||||||
#undef SDL_GLSDL /* In case SDL has the glSDL backend... */
|
|
||||||
#endif
|
|
||||||
#define SDL_GLSDL 0x00100000 /* Create an OpenGL 2D rendering context */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Wraps SDL_SetVideoMode(), and adds support for the SDL_GLSDL flag.
|
|
||||||
*
|
|
||||||
* If 'flags' contains SDL_GLSDL, glSDL_SetVideoMode() sets up a "pure"
|
|
||||||
* OpenGL rendering context for use with the glSDL_ calls.
|
|
||||||
*
|
|
||||||
* SDL can be closed as usual (using SDL_ calls), but you should call
|
|
||||||
* glSDL_Quit() (kludge) to allow glSDL to clean up it's internal stuff.
|
|
||||||
*/
|
|
||||||
SDL_Surface *glSDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);
|
|
||||||
void glSDL_Quit(void);
|
|
||||||
|
|
||||||
void glSDL_QuitSubSystem(Uint32 flags);
|
|
||||||
|
|
||||||
/* Replaces SDL_Quit() entirely, when using the override defines */
|
|
||||||
void glSDL_FullQuit(void);
|
|
||||||
|
|
||||||
SDL_Surface *glSDL_GetVideoSurface(void);
|
|
||||||
|
|
||||||
void glSDL_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects);
|
|
||||||
void glSDL_UpdateRect(SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Works like SDL_Flip(), but may also perform enqueued blits.
|
|
||||||
* (That is, it's possible that the implementation renders
|
|
||||||
* *nothing* until glSDL_Flip() is called.)
|
|
||||||
*/
|
|
||||||
int glSDL_Flip(SDL_Surface *screen);
|
|
||||||
|
|
||||||
void glSDL_FreeSurface(SDL_Surface *surface);
|
|
||||||
|
|
||||||
int glSDL_LockSurface(SDL_Surface *surface);
|
|
||||||
void glSDL_UnlockSurface(SDL_Surface *surface);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Like the respective SDL functions, although they ignore
|
|
||||||
* SDL_RLEACCEL, as it makes no sense in this context.
|
|
||||||
*/
|
|
||||||
int glSDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key);
|
|
||||||
int glSDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sets up clipping for the screen, or a SDL_Surface.
|
|
||||||
*
|
|
||||||
* Note that this function takes both SDL_Surfaces and
|
|
||||||
* glSDL_Surfaces.
|
|
||||||
*/
|
|
||||||
SDL_bool glSDL_SetClipRect(SDL_Surface *surface, SDL_Rect *rect);
|
|
||||||
|
|
||||||
int glSDL_BlitSurface(SDL_Surface *src, SDL_Rect *srcrect,
|
|
||||||
SDL_Surface *dst, SDL_Rect *dstrect);
|
|
||||||
|
|
||||||
int glSDL_FillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convert the given surface into a SDL_Surface (if it isn't
|
|
||||||
* one already), and makes sure that the underlying SDL_Surface
|
|
||||||
* is of a pixel format suitable for fast texture downloading.
|
|
||||||
*
|
|
||||||
* Note that you *only* have to use this function if you want
|
|
||||||
* fast pixel access to surfaces (ie "procedural textures").
|
|
||||||
* Any surfaces that aren't converted will be downloaded
|
|
||||||
* automatically upon the first call to glSDL_BlitSurface(),
|
|
||||||
* but if conversion is required, it will be required for
|
|
||||||
* every glSDL_UnlockSurface() call.
|
|
||||||
*
|
|
||||||
* IMPORTANT:
|
|
||||||
* You *can* pass an SDL_Surface directly to this function,
|
|
||||||
* and it will try to deal with it nicely. However, this
|
|
||||||
* requires that a temporary SDL_Surface is created, and
|
|
||||||
* this surface is cached only until the texture memory is
|
|
||||||
* needed for new surfaces.
|
|
||||||
*/
|
|
||||||
SDL_Surface *glSDL_DisplayFormat(SDL_Surface *surface);
|
|
||||||
SDL_Surface *glSDL_DisplayFormatAlpha(SDL_Surface *surface);
|
|
||||||
|
|
||||||
SDL_Surface *glSDL_ConvertSurface
|
|
||||||
(SDL_Surface *src, SDL_PixelFormat *fmt, Uint32 flags);
|
|
||||||
SDL_Surface *glSDL_CreateRGBSurface
|
|
||||||
(Uint32 flags, int width, int height, int depth,
|
|
||||||
Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
|
|
||||||
SDL_Surface *glSDL_CreateRGBSurfaceFrom(void *pixels,
|
|
||||||
int width, int height, int depth, int pitch,
|
|
||||||
Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
|
|
||||||
SDL_Surface *glSDL_LoadBMP(const char *file);
|
|
||||||
int glSDL_SaveBMP(SDL_Surface *surface, const char *file);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Some ugly "overriding"... */
|
|
||||||
#ifndef _GLSDL_NO_REDEFINES_
|
|
||||||
/*
|
|
||||||
* You *always* need to lock and unlock a glSDL surface in
|
|
||||||
* order to get glSDL to update the OpenGL texture!
|
|
||||||
*/
|
|
||||||
#undef SDL_MUSTLOCK
|
|
||||||
#define SDL_MUSTLOCK(surface) \
|
|
||||||
(surface->offset || \
|
|
||||||
((surface->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_RLEACCEL)) != 0) || \
|
|
||||||
IS_GLSDL_SURFACE(surface))
|
|
||||||
|
|
||||||
#define SDL_SetVideoMode glSDL_SetVideoMode
|
|
||||||
#define SDL_GetVideoSurface glSDL_GetVideoSurface
|
|
||||||
#define SDL_Quit glSDL_FullQuit
|
|
||||||
#define SDL_QuitSubSystem glSDL_QuitSubSystem
|
|
||||||
#define SDL_UpdateRects glSDL_UpdateRects
|
|
||||||
#define SDL_UpdateRect glSDL_UpdateRect
|
|
||||||
#define SDL_Flip glSDL_Flip
|
|
||||||
#define SDL_FreeSurface glSDL_FreeSurface
|
|
||||||
#define SDL_LockSurface glSDL_LockSurface
|
|
||||||
#define SDL_UnlockSurface glSDL_UnlockSurface
|
|
||||||
#define SDL_SetColorKey glSDL_SetColorKey
|
|
||||||
#define SDL_SetAlpha glSDL_SetAlpha
|
|
||||||
#define SDL_SetClipRect glSDL_SetClipRect
|
|
||||||
#undef SDL_BlitSurface
|
|
||||||
#define SDL_BlitSurface glSDL_BlitSurface
|
|
||||||
#define SDL_FillRect glSDL_FillRect
|
|
||||||
#define SDL_DisplayFormat glSDL_DisplayFormat
|
|
||||||
#define SDL_DisplayFormatAlpha glSDL_DisplayFormatAlpha
|
|
||||||
#define SDL_ConvertSurface glSDL_ConvertSurface
|
|
||||||
#define SDL_CreateRGBSurface glSDL_CreateRGBSurface
|
|
||||||
#define SDL_CreateRGBSurfaceFrom glSDL_CreateRGBSurfaceFrom
|
|
||||||
#undef SDL_AllocSurface
|
|
||||||
#define SDL_AllocSurface glSDL_CreateRGBSurface
|
|
||||||
#undef SDL_LoadBMP
|
|
||||||
#define SDL_LoadBMP glSDL_LoadBMP
|
|
||||||
#undef SDL_SaveBMP
|
|
||||||
#define SDL_SaveBMP glSDL_SaveBMP
|
|
||||||
#define IMG_Load(x) glSDL_IMG_Load(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* HAVE_OPENGL */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_OPENGL
|
|
||||||
|
|
||||||
/* Some extra overloading for common external lib calls... */
|
|
||||||
#include "SDL_image.h"
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
SDL_Surface *glSDL_IMG_Load(const char *file);
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* HAVE_OPENGL */
|
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------
|
|
||||||
glSDL API extensions, transparent
|
|
||||||
----------------------------------------------------------*/
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
* Invalidate part of a texture.
|
|
||||||
*
|
|
||||||
* This function can be used either between calls to
|
|
||||||
* glSDL_LockSurface() and glSDL_UnlockSurface(), or before
|
|
||||||
* calling glSDL_DownloadSurface().
|
|
||||||
*
|
|
||||||
* In either case, it causes only the specified area to be
|
|
||||||
* downloaded when unlocking the surface, or calling
|
|
||||||
* glSDL_UnlockSurface(), respectively.
|
|
||||||
*
|
|
||||||
* Note that if this function is not used, glSDL assumes that
|
|
||||||
* the entire surface has to be updated. (That is, it's safe
|
|
||||||
* to ignore this function - it's "just a performance hack.")
|
|
||||||
*
|
|
||||||
* Passing a rectangle with zero height or width cancels the
|
|
||||||
* downloading when/after unlocking the surface. Use if you
|
|
||||||
* just want to read the texture, but feel like being nice and
|
|
||||||
* obeying SDL_MUSTLOCK() - which is a good idea, as things
|
|
||||||
* may change...
|
|
||||||
*
|
|
||||||
* Passing NULL for the 'area' argument results in the entire
|
|
||||||
* surface being invalidated.
|
|
||||||
*
|
|
||||||
* NOTE: This function does NOT perform clipping! Weird or
|
|
||||||
* even Bad Things may happen if you specify areas
|
|
||||||
* that protrude outside the edges of the actual
|
|
||||||
* surface.
|
|
||||||
*/
|
|
||||||
void glSDL_Invalidate(SDL_Surface *surface, SDL_Rect *area);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Make sure that the texture of the specified surface is up
|
|
||||||
* to date in OpenGL texture memory.
|
|
||||||
*
|
|
||||||
* This can be used together with glSDL_UnloadSurface() to
|
|
||||||
* implement custom texture caching schemes.
|
|
||||||
*
|
|
||||||
* Returns 0 on success, or a negative value if something
|
|
||||||
* went wrong.
|
|
||||||
*/
|
|
||||||
int glSDL_UploadSurface(SDL_Surface *surface);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Free the texture space used by the specified surface.
|
|
||||||
*
|
|
||||||
* Normally, glSDL should download textures when needed, and
|
|
||||||
* unload the oldest (in terms of use) surfaces, if it runs out
|
|
||||||
* of texture space.
|
|
||||||
*/
|
|
||||||
void glSDL_UnloadSurface(SDL_Surface *surface);
|
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------
|
|
||||||
glSDL API extensions, OpenGL mode ONLY
|
|
||||||
----------------------------------------------------------*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enable, disable or check the state of "vsync" or
|
|
||||||
* vertical retrace synchronization. Note that enabling
|
|
||||||
* this does not *guarantee* that the driver actually
|
|
||||||
* uses vsync; it only instructs OpenGL to do so if
|
|
||||||
* possible.
|
|
||||||
* Pass 1 for 'use' to enable vsync, '0' to disable
|
|
||||||
* it, and -1 to just return the current state without
|
|
||||||
* changing it.
|
|
||||||
* Returns the vsync state *before* any change made
|
|
||||||
* by the call.
|
|
||||||
*
|
|
||||||
* NOTE: Ignored when not using OpenGL acceleration!
|
|
||||||
*/
|
|
||||||
int glSDL_VSync(int use);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set alpha multiplier. This is multiplied with any full
|
|
||||||
* surface alpha or alpha channels of surfaces.
|
|
||||||
*
|
|
||||||
* The default value is 255, which makes glSDL render like
|
|
||||||
* the standard SDL 2D backends, ie based only on the
|
|
||||||
* surface settings.
|
|
||||||
*
|
|
||||||
* This function affects the global state of glSDL.
|
|
||||||
*
|
|
||||||
* NOTE: NOT available without OpenGL acceleration!
|
|
||||||
*/
|
|
||||||
void glSDL_SetBlendAlpha(Uint8 alpha);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set color multipliers. These are multiplied with the
|
|
||||||
* respective color channers of rendered surfaces,
|
|
||||||
* modulating the brightness of the resulting output.
|
|
||||||
*
|
|
||||||
* The default values are 255, which makes glSDL render
|
|
||||||
* like the standard SDL 2D backends.
|
|
||||||
*
|
|
||||||
* This function affects the global state of glSDL.
|
|
||||||
*
|
|
||||||
* NOTE: NOT available without OpenGL acceleration!
|
|
||||||
*/
|
|
||||||
void glSDL_SetBlendColor(Uint8 r, Uint8 g, Uint8 b);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set center offset in pixels for scaling and rotation.
|
|
||||||
*
|
|
||||||
* The default is (0, 0), which makes surfaces rotate and
|
|
||||||
* scale around their centers.
|
|
||||||
*
|
|
||||||
* This function affects the global state of glSDL.
|
|
||||||
*
|
|
||||||
* NOTE: NOT available without OpenGL acceleration!
|
|
||||||
*/
|
|
||||||
void glSDL_SetCenter(float x, float y);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set rotation angle in degrees. Rotation is done around
|
|
||||||
* the center point, which is defined as
|
|
||||||
* (w/2 + cx, h/2 + cy)
|
|
||||||
* where w and h are the width and height of the source
|
|
||||||
* surface, and cx and cy are the center offsets set by
|
|
||||||
* glSDL_SetCenter().
|
|
||||||
*
|
|
||||||
* The default value is 0.0f, which makes glSDL render
|
|
||||||
* like a normal SDL 2D backend.
|
|
||||||
*
|
|
||||||
* This function affects the global state of glSDL.
|
|
||||||
*
|
|
||||||
* NOTE: NOT available without OpenGL acceleration!
|
|
||||||
*/
|
|
||||||
void glSDL_SetRotation(float angle);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set scale factor. Scaling is centered around around
|
|
||||||
* the point
|
|
||||||
* (w/2 + cx, h/2 + cy)
|
|
||||||
* where w and h are the width and height of the source
|
|
||||||
* surface, and cx and cy are the center offsets set by
|
|
||||||
* glSDL_SetCenter().
|
|
||||||
*
|
|
||||||
* The default value is 1.0f, which makes glSDL render
|
|
||||||
* like a normal SDL 2D backend.
|
|
||||||
*
|
|
||||||
* This function affects the global state of glSDL.
|
|
||||||
*
|
|
||||||
* NOTE: NOT available without OpenGL acceleration!
|
|
||||||
*/
|
|
||||||
void glSDL_SetScale(float x, float y);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Reset glSDL global state to defaults.
|
|
||||||
*/
|
|
||||||
void glSDL_ResetState(void);
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _GLSDL_H_ */
|
|
||||||
@ -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;
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
#ifndef KOBO_REGION_H
|
#ifndef KOBO_REGION_H
|
||||||
#define KOBO_REGION_H
|
#define KOBO_REGION_H
|
||||||
|
|
||||||
#include "glSDL.h"
|
#include "sdl_compat.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|||||||
16
graphics/sdl_compat.h
Normal file
16
graphics/sdl_compat.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* sdl_compat.h - umbrella SDL 3 include for Kobo Deluxe.
|
||||||
|
*
|
||||||
|
* Replaces the legacy graphics/glSDL.h shim that wrapped SDL 1.2 with
|
||||||
|
* an OpenGL backend. SDL 3's renderer makes that unnecessary.
|
||||||
|
*
|
||||||
|
* This header exists so the codebase can use #include "sdl_compat.h"
|
||||||
|
* rather than scatter <SDL3/SDL.h> across the tree (which would also
|
||||||
|
* make a later SDL 4 swap painful).
|
||||||
|
*/
|
||||||
|
#ifndef _KOBO_SDL_COMPAT_H_
|
||||||
|
#define _KOBO_SDL_COMPAT_H_
|
||||||
|
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
#endif /* _KOBO_SDL_COMPAT_H_ */
|
||||||
@ -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,
|
||||||
|
|||||||
@ -34,7 +34,7 @@
|
|||||||
* Cursor tests first check if '|' is present.
|
* Cursor tests first check if '|' is present.
|
||||||
* Shadowed variables fixed.
|
* Shadowed variables fixed.
|
||||||
* Garbage data in spacing table fixed. (Thanks to
|
* Garbage data in spacing table fixed. (Thanks to
|
||||||
Andreas Spångberg for discovering this one!)
|
Andreas Sp<EFBFBD>ngberg for discovering this one!)
|
||||||
* Added ExtraSpace(). (Scaling support hack...)
|
* Added ExtraSpace(). (Scaling support hack...)
|
||||||
* Disabled colorkeying. (Ruins some RGBA fonts!)
|
* Disabled colorkeying. (Ruins some RGBA fonts!)
|
||||||
*/
|
*/
|
||||||
@ -42,7 +42,7 @@
|
|||||||
#ifndef __SOFONT_H
|
#ifndef __SOFONT_H
|
||||||
#define __SOFONT_H
|
#define __SOFONT_H
|
||||||
|
|
||||||
#include "glSDL.h"
|
#include "sdl_compat.h"
|
||||||
|
|
||||||
class SoFont
|
class SoFont
|
||||||
{
|
{
|
||||||
|
|||||||
@ -29,8 +29,8 @@ TODO: tables as needed when loading banks.
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "glSDL.h"
|
#include "sdl_compat.h"
|
||||||
#include "SDL_image.h"
|
#include <SDL3_image/SDL_image.h>
|
||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
#include "filters.h"
|
#include "filters.h"
|
||||||
|
|
||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,7 +26,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "glSDL.h"
|
#include "sdl_compat.h"
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -186,13 +182,9 @@ void window_t::invalidate(SDL_Rect *r)
|
|||||||
rr.w = phys_rect.w;
|
rr.w = phys_rect.w;
|
||||||
rr.h = phys_rect.h;
|
rr.h = phys_rect.h;
|
||||||
phys_refresh(&rr);
|
phys_refresh(&rr);
|
||||||
glSDL_Invalidate(surface, &rr);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
phys_refresh(r);
|
phys_refresh(r);
|
||||||
glSDL_Invalidate(surface, r);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,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;
|
||||||
}
|
}
|
||||||
@ -267,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;
|
||||||
}
|
}
|
||||||
@ -287,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()
|
||||||
@ -298,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)
|
||||||
@ -309,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -480,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);
|
||||||
@ -511,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -531,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -560,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -213,7 +213,7 @@
|
|||||||
#ifndef _WINDOW_H_
|
#ifndef _WINDOW_H_
|
||||||
#define _WINDOW_H_
|
#define _WINDOW_H_
|
||||||
|
|
||||||
#include "glSDL.h"
|
#include "sdl_compat.h"
|
||||||
|
|
||||||
class gfxengine_t;
|
class gfxengine_t;
|
||||||
|
|
||||||
|
|||||||
148
kobo.cpp
148
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -637,7 +635,6 @@ int KOBO_main::init_display(prefs_t *p)
|
|||||||
int dw, dh; // Display size
|
int dw, dh; // Display size
|
||||||
int gw, gh; // Game "window" size
|
int gw, gh; // Game "window" size
|
||||||
gengine->title("Kobo Deluxe " VERSION, "kobodl");
|
gengine->title("Kobo Deluxe " VERSION, "kobodl");
|
||||||
gengine->driver((gfx_drivers_t)p->videodriver);
|
|
||||||
|
|
||||||
dw = p->width;
|
dw = p->width;
|
||||||
dh = p->height;
|
dh = p->height;
|
||||||
@ -691,10 +688,7 @@ int KOBO_main::init_display(prefs_t *p)
|
|||||||
gengine->size(dw, dh);
|
gengine->size(dw, dh);
|
||||||
|
|
||||||
gengine->mode(0, p->fullscreen);
|
gengine->mode(0, p->fullscreen);
|
||||||
gengine->doublebuffer(p->doublebuf);
|
|
||||||
gengine->pages(p->pages);
|
|
||||||
gengine->vsync(p->vsync);
|
gengine->vsync(p->vsync);
|
||||||
gengine->shadow(p->shadow);
|
|
||||||
gengine->cursor(0);
|
gengine->cursor(0);
|
||||||
|
|
||||||
gengine->period(game.speed);
|
gengine->period(game.speed);
|
||||||
@ -1088,7 +1082,7 @@ int KOBO_main::load_graphics(prefs_t *p)
|
|||||||
if(gd->flags & KOBO_NODITHER || !p->use_dither)
|
if(gd->flags & KOBO_NODITHER || !p->use_dither)
|
||||||
gengine->dither(-1);
|
gengine->dither(-1);
|
||||||
else
|
else
|
||||||
gengine->dither(p->dither_type, p->broken_rgba8);
|
gengine->dither(p->dither_type, 0);
|
||||||
|
|
||||||
// Alpha channels
|
// Alpha channels
|
||||||
if(gd->flags & KOBO_NOALPHA || !p->alpha)
|
if(gd->flags & KOBO_NOALPHA || !p->alpha)
|
||||||
@ -1205,7 +1199,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,34 +1233,40 @@ 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: SDL_GetJoysticks returns an array of instance
|
||||||
if(p->use_joystick)
|
// IDs that must be SDL_free()d. SDL_OpenJoystick takes one of those
|
||||||
|
// IDs and returns the SDL_Joystick handle.
|
||||||
|
if(!p->use_joystick)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(!SDL_InitSubSystem(SDL_INIT_JOYSTICK))
|
||||||
{
|
{
|
||||||
if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0)
|
log_printf(ELOG, "Error setting up joystick: %s\n",
|
||||||
{
|
SDL_GetError());
|
||||||
log_printf(ELOG, "Error setting up joystick!\n");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
p->number_of_joysticks = SDL_NumJoysticks();
|
|
||||||
if(p->number_of_joysticks > 0)
|
int count = 0;
|
||||||
{
|
SDL_JoystickID *ids = SDL_GetJoysticks(&count);
|
||||||
SDL_JoystickEventState(SDL_ENABLE);
|
p->number_of_joysticks = count;
|
||||||
if(p->joystick_no >= p->number_of_joysticks)
|
if(count <= 0)
|
||||||
p->joystick_no = 0;
|
|
||||||
joystick = SDL_JoystickOpen(p->joystick_no);
|
|
||||||
if(!joystick)
|
|
||||||
{
|
|
||||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
SDL_free(ids);
|
||||||
log_printf(ELOG, "No joysticks found!\n");
|
log_printf(ELOG, "No joysticks found!\n");
|
||||||
joystick = NULL;
|
joystick = NULL;
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(p->joystick_no < 0 || p->joystick_no >= count)
|
||||||
|
p->joystick_no = 0;
|
||||||
|
joystick = SDL_OpenJoystick(ids[p->joystick_no]);
|
||||||
|
SDL_free(ids);
|
||||||
|
if(!joystick)
|
||||||
|
{
|
||||||
|
log_printf(ELOG, "Failed to open joystick: %s\n",
|
||||||
|
SDL_GetError());
|
||||||
|
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||||
|
return -2;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1276,14 +1276,11 @@ void KOBO_main::close_js()
|
|||||||
{
|
{
|
||||||
if(!SDL_WasInit(SDL_INIT_JOYSTICK))
|
if(!SDL_WasInit(SDL_INIT_JOYSTICK))
|
||||||
return;
|
return;
|
||||||
|
if(joystick)
|
||||||
if(!joystick)
|
{
|
||||||
return;
|
SDL_CloseJoystick(joystick);
|
||||||
|
|
||||||
if(SDL_JoystickOpened(0))
|
|
||||||
SDL_JoystickClose(joystick);
|
|
||||||
joystick = NULL;
|
joystick = NULL;
|
||||||
|
}
|
||||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1597,8 +1594,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 +1604,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 +1623,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,32 +1634,29 @@ 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;
|
||||||
prefs->videodriver = (int)GFX_DRIVER_SDL2D;
|
|
||||||
prefs->width = 640;
|
prefs->width = 640;
|
||||||
prefs->height = 480;
|
prefs->height = 480;
|
||||||
prefs->aspect = 1000;
|
prefs->aspect = 1000;
|
||||||
prefs->depth = 0;
|
|
||||||
prefs->doublebuf = 0;
|
|
||||||
prefs->pages = -1;
|
|
||||||
prefs->shadow = 1;
|
|
||||||
prefs->scalemode = (int)GFX_SCALE_NEAREST;
|
prefs->scalemode = (int)GFX_SCALE_NEAREST;
|
||||||
prefs->brightness = 100;
|
prefs->brightness = 100;
|
||||||
prefs->contrast = 100;
|
prefs->contrast = 100;
|
||||||
@ -1674,7 +1668,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 +1680,25 @@ void kobo_gfxengine_t::frame()
|
|||||||
gsm.release(k);
|
gsm.release(k);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_VIDEOEXPOSE:
|
case SDL_EVENT_TEXT_INPUT:
|
||||||
|
// SDL 3 delivers typed characters via separate text-input
|
||||||
|
// events when SDL_StartTextInput is active. Forward each
|
||||||
|
// byte of the UTF-8 string as a unicode value to the
|
||||||
|
// current gamestate (used by the high-score name-entry).
|
||||||
|
for(const char *c = ev.text.text; *c; ++c)
|
||||||
|
gsm.press(-1, (unsigned char)*c);
|
||||||
|
break;
|
||||||
|
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 +1710,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 +1762,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 +1771,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 +1795,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 +2087,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);
|
||||||
|
|||||||
8
logger.c
8
logger.c
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "glSDL.h"
|
#include "sdl_compat.h"
|
||||||
|
|
||||||
#define LOG_BUFFER 1024
|
#define LOG_BUFFER 1024
|
||||||
|
|
||||||
@ -100,6 +100,7 @@ static inline int log_write_raw(int target, const char *text)
|
|||||||
/* We should never get here. */
|
/* We should never get here. */
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -187,8 +188,9 @@ static inline void put_timestamp(int level)
|
|||||||
{
|
{
|
||||||
if(l_targets[l_levels[level].target].flags & LOG_TIMESTAMP)
|
if(l_targets[l_levels[level].target].flags & LOG_TIMESTAMP)
|
||||||
{
|
{
|
||||||
char buf[16];
|
char buf[24];
|
||||||
snprintf(buf, sizeof(buf)-1, "[%d] ", SDL_GetTicks() - start_time);
|
snprintf(buf, sizeof(buf)-1, "[%llu] ",
|
||||||
|
(unsigned long long)(SDL_GetTicks() - start_time));
|
||||||
log_write_raw(l_levels[level].target, buf);
|
log_write_raw(l_levels[level].target, buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
6
manage.h
6
manage.h
@ -24,7 +24,7 @@
|
|||||||
#ifndef _KOBO_MANAGE_H_
|
#ifndef _KOBO_MANAGE_H_
|
||||||
#define _KOBO_MANAGE_H_
|
#define _KOBO_MANAGE_H_
|
||||||
|
|
||||||
#include "glSDL.h"
|
#include "sdl_compat.h"
|
||||||
#include "score.h"
|
#include "score.h"
|
||||||
|
|
||||||
class _manage
|
class _manage
|
||||||
@ -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);
|
||||||
|
|||||||
52
options.cpp
52
options.cpp
@ -177,41 +177,7 @@ void video_options_t::build()
|
|||||||
}
|
}
|
||||||
space();
|
space();
|
||||||
yesno("Fullscreen Display", &prf->fullscreen, OS_RESTART_VIDEO);
|
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);
|
|
||||||
#if defined(HAVE_OPENGL) && !defined(GLSDL_OFF)
|
|
||||||
list("Display Driver", &prf->videodriver, OS_RESTART_VIDEO |
|
|
||||||
OS_REBUILD);
|
|
||||||
item("SDL 2D", GFX_DRIVER_SDL2D);
|
|
||||||
item("OpenGL/glSDL", GFX_DRIVER_GLSDL);
|
|
||||||
#else
|
|
||||||
prf->videodriver = GFX_DRIVER_SDL2D;
|
|
||||||
#endif
|
|
||||||
space();
|
|
||||||
xoffs = 0.55;
|
|
||||||
switch(prf->videodriver)
|
|
||||||
{
|
|
||||||
case GFX_DRIVER_SDL2D:
|
|
||||||
list("Display Buffering Mode", &prf->doublebuf, OS_RESTART_VIDEO);
|
|
||||||
item("Single", 0);
|
|
||||||
item("Double", 1);
|
|
||||||
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);
|
|
||||||
item("Assume Standard", -1);
|
|
||||||
item("Always Repaint", 0);
|
|
||||||
item("Single", 1);
|
|
||||||
item("Double", 2);
|
|
||||||
item("Triple", 3);
|
|
||||||
big();
|
big();
|
||||||
space();
|
space();
|
||||||
xoffs = 0.5;
|
xoffs = 0.5;
|
||||||
@ -250,13 +216,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();
|
||||||
@ -403,11 +365,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)
|
||||||
|
|||||||
19
prefs.cpp
19
prefs.cpp
@ -82,25 +82,18 @@ void prefs_t::init()
|
|||||||
|
|
||||||
comment("--- Video settings -------------------------");
|
comment("--- Video settings -------------------------");
|
||||||
yesno("fullscreen", fullscreen, 0); desc("Fullscreen Display");
|
yesno("fullscreen", fullscreen, 0); desc("Fullscreen Display");
|
||||||
key("videodriver", videodriver, GFX_DRIVER_SDL2D);
|
|
||||||
desc("Display Driver");
|
|
||||||
key("width", width, 640); desc("Horizontal Resolution");
|
key("width", width, 640); desc("Horizontal Resolution");
|
||||||
key("height", height, 480); desc("Vertical Resolution");
|
key("height", height, 480); desc("Vertical Resolution");
|
||||||
key("aspect", aspect, 1000); desc("Pixel Aspect Ratio");
|
key("aspect", aspect, 1000); desc("Pixel Aspect Ratio");
|
||||||
key("depth", depth, 0); desc("Display Depth");
|
|
||||||
key("maxfps", max_fps, 100); desc("Maximum fps");
|
key("maxfps", max_fps, 100); desc("Maximum fps");
|
||||||
key("maxfpsstrict", max_fps_strict, 0); desc("Strictly Regulated 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");
|
key("videomode", videomode, 0x04330); desc("Video Mode");
|
||||||
yesno("vsync", vsync, 1); desc("Enable Vertical Sync");
|
yesno("vsync", vsync, 1); desc("Enable Vertical Sync");
|
||||||
key("videopages", pages, -1); desc("Number of Video Pages");
|
|
||||||
|
|
||||||
comment("--- Graphics settings ----------------------");
|
comment("--- Graphics settings ----------------------");
|
||||||
key("scalemode", scalemode, 1); desc("Scaling Filter Mode");
|
key("scalemode", scalemode, 1); desc("Scaling Filter Mode");
|
||||||
yesno("dither", use_dither, 1); desc("Use Dithering");
|
yesno("dither", use_dither, 1); desc("Use Dithering");
|
||||||
key("dither_type", dither_type, 0); desc("Dither Type");
|
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");
|
yesno("alpha", alpha, 1); desc("Use Alpha Blending");
|
||||||
key("brightness", brightness, 100); desc("Brightness");
|
key("brightness", brightness, 100); desc("Brightness");
|
||||||
key("contrast", contrast, 100); desc("Contrast");
|
key("contrast", contrast, 100); desc("Contrast");
|
||||||
@ -120,6 +113,14 @@ void prefs_t::init()
|
|||||||
key("release", o_release, 50, 0); desc("Limiter Speed");
|
key("release", o_release, 50, 0); desc("Limiter Speed");
|
||||||
key("internalres", o_internalres, 1, 0); desc("Texture Resolution");
|
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 --------------------");
|
comment("--- Temporary variables --------------------");
|
||||||
key("last_profile", last_profile, 0);
|
key("last_profile", last_profile, 0);
|
||||||
desc("Last used player profile");
|
desc("Last used player profile");
|
||||||
@ -170,8 +171,4 @@ void prefs_t::postload()
|
|||||||
log_printf(ELOG, "Radar sweep mode broken and disabled!\n");
|
log_printf(ELOG, "Radar sweep mode broken and disabled!\n");
|
||||||
scrollradar = 2;
|
scrollradar = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some unimplemented enums were removed in 0.4.1
|
|
||||||
if(videodriver != GFX_DRIVER_SDL2D)
|
|
||||||
videodriver = GFX_DRIVER_GLSDL;
|
|
||||||
}
|
}
|
||||||
|
|||||||
15
prefs.h
15
prefs.h
@ -73,24 +73,18 @@ class prefs_t : public config_parser_t
|
|||||||
|
|
||||||
//Video settings
|
//Video settings
|
||||||
int fullscreen; //Use fullscreen mode
|
int fullscreen; //Use fullscreen mode
|
||||||
int videodriver; //Internal video driver
|
|
||||||
int width; //Screen/window width
|
int width; //Screen/window width
|
||||||
int height; //Screen/window height
|
int height; //Screen/window height
|
||||||
int aspect; //Pixel aspect ratio * 1000
|
int aspect; //Pixel aspect ratio * 1000
|
||||||
int depth; //Bits per pixel
|
|
||||||
int max_fps; //Maximum fps
|
int max_fps; //Maximum fps
|
||||||
int max_fps_strict; //Strictly regulated fps limiter
|
int max_fps_strict; //Strictly regulated fps limiter
|
||||||
int doublebuf; //Use double buffering
|
int videomode; //Selected entry from the vidmodes table
|
||||||
int shadow; //Use software shadow buffer
|
|
||||||
int videomode; //New video mode codes
|
|
||||||
int vsync; //Vertical (retrace) sync
|
int vsync; //Vertical (retrace) sync
|
||||||
int pages; //Number of physical video pages
|
|
||||||
|
|
||||||
//Graphics settings
|
//Graphics settings
|
||||||
int scalemode; //Scaling filter mode
|
int scalemode; //Scaling filter mode
|
||||||
int use_dither;
|
int use_dither;
|
||||||
int dither_type;
|
int dither_type;
|
||||||
int broken_rgba8; //For some OpenGL setups
|
|
||||||
int alpha; //Alpha blending
|
int alpha; //Alpha blending
|
||||||
int brightness; //Graphics brightness
|
int brightness; //Graphics brightness
|
||||||
int contrast; //Graphics contrast
|
int contrast; //Graphics contrast
|
||||||
@ -108,6 +102,13 @@ class prefs_t : public config_parser_t
|
|||||||
int o_threshold; //Limiter threshold
|
int o_threshold; //Limiter threshold
|
||||||
int o_release; //Limiter release rate
|
int o_release; //Limiter release rate
|
||||||
int o_internalres; //Internal resolution for OpenGL
|
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")
|
//"Hidden" stuff ("to remember until next startup")
|
||||||
int last_profile; //Last used player profile
|
int last_profile; //Last used player profile
|
||||||
|
|||||||
2
random.h
2
random.h
@ -24,7 +24,7 @@
|
|||||||
#define _KOBO_RANDOM_H_
|
#define _KOBO_RANDOM_H_
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "glSDL.h"
|
#include "sdl_compat.h"
|
||||||
|
|
||||||
class rand_num_t
|
class rand_num_t
|
||||||
{
|
{
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
#ifndef _A_TOOLS_H_
|
#ifndef _A_TOOLS_H_
|
||||||
#define _A_TOOLS_H_
|
#define _A_TOOLS_H_
|
||||||
|
|
||||||
#include "glSDL.h"
|
#include "sdl_compat.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "kobolog.h"
|
#include "kobolog.h"
|
||||||
#include "a_types.h"
|
#include "a_types.h"
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
#ifndef _A_TYPES_H_
|
#ifndef _A_TYPES_H_
|
||||||
#define _A_TYPES_H_
|
#define _A_TYPES_H_
|
||||||
|
|
||||||
#include "glSDL.h"
|
#include "sdl_compat.h"
|
||||||
|
|
||||||
/* Builtin patch drivers */
|
/* Builtin patch drivers */
|
||||||
typedef enum
|
typedef enum
|
||||||
|
|||||||
@ -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);
|
||||||
|
|
||||||
|
|||||||
127
sound/audio.c
127
sound/audio.c
@ -45,10 +45,25 @@
|
|||||||
#include "audiodev.h"
|
#include "audiodev.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "SDL.h"
|
#include <SDL3/SDL.h>
|
||||||
#include "SDL_audio.h"
|
#include <SDL3/SDL_audio.h>
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SDL 3 audio bridge.
|
||||||
|
*
|
||||||
|
* SDL 1.2 pushed callbacks into a fixed output buffer; SDL 3 uses
|
||||||
|
* SDL_AudioStream as a pull-style queue with an "I want more data"
|
||||||
|
* callback. The engine's existing _audio_callback() still fills a
|
||||||
|
* Sint16 stereo buffer of an arbitrary requested byte length, so we
|
||||||
|
* keep it intact and add a small adapter (sdl3_stream_callback) that
|
||||||
|
* runs it on a scratch buffer and pushes the result into the stream.
|
||||||
|
*/
|
||||||
|
static SDL_AudioStream *_sdl_stream = NULL;
|
||||||
|
static SDL_AudioDeviceID _sdl_audio_dev = 0;
|
||||||
|
static Uint8 *_sdl_scratch = NULL;
|
||||||
|
static int _sdl_scratch_size = 0;
|
||||||
|
|
||||||
#include "a_struct.h"
|
#include "a_struct.h"
|
||||||
#include "a_commands.h"
|
#include "a_commands.h"
|
||||||
#include "a_control.h"
|
#include "a_control.h"
|
||||||
@ -567,50 +582,63 @@ static int _start_oss_output()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void SDLCALL _sdl3_stream_callback(void *userdata,
|
||||||
|
SDL_AudioStream *stream, int additional, int total)
|
||||||
|
{
|
||||||
|
(void)userdata; (void)total;
|
||||||
|
if(additional <= 0)
|
||||||
|
return;
|
||||||
|
if(additional > _sdl_scratch_size)
|
||||||
|
{
|
||||||
|
Uint8 *p = realloc(_sdl_scratch, additional);
|
||||||
|
if(!p)
|
||||||
|
return;
|
||||||
|
_sdl_scratch = p;
|
||||||
|
_sdl_scratch_size = additional;
|
||||||
|
}
|
||||||
|
_audio_callback(NULL, _sdl_scratch, additional);
|
||||||
|
SDL_PutAudioStreamData(stream, _sdl_scratch, additional);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int _start_SDL_output(void)
|
static int _start_SDL_output(void)
|
||||||
{
|
{
|
||||||
SDL_AudioSpec as;
|
if(!SDL_InitSubSystem(SDL_INIT_AUDIO))
|
||||||
SDL_AudioSpec audiospec;
|
{
|
||||||
|
log_printf(ELOG, "audio.c: SDL_InitSubSystem failed: %s\n",
|
||||||
if(SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
|
SDL_GetError());
|
||||||
return -2;
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
as.freq = a_settings.samplerate;
|
SDL_AudioSpec spec;
|
||||||
as.format = AUDIO_S16SYS;
|
SDL_zero(spec);
|
||||||
as.channels = 2;
|
spec.freq = a_settings.samplerate;
|
||||||
as.samples = (Uint16)a_settings.output_buffersize;
|
spec.format = SDL_AUDIO_S16;
|
||||||
as.callback = _audio_callback;
|
spec.channels = 2;
|
||||||
if(SDL_OpenAudio(&as, &audiospec) < 0)
|
|
||||||
|
_sdl_stream = SDL_OpenAudioDeviceStream(
|
||||||
|
SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK,
|
||||||
|
&spec, _sdl3_stream_callback, NULL);
|
||||||
|
if(!_sdl_stream)
|
||||||
|
{
|
||||||
|
log_printf(ELOG, "audio.c: SDL_OpenAudioDeviceStream failed: %s\n",
|
||||||
|
SDL_GetError());
|
||||||
return -3;
|
return -3;
|
||||||
|
|
||||||
if(audiospec.format != AUDIO_S16SYS)
|
|
||||||
{
|
|
||||||
log_printf(ELOG, "audio.c: ERROR: Only 16 bit output supported!\n");
|
|
||||||
SDL_CloseAudio();
|
|
||||||
return -4;
|
|
||||||
}
|
}
|
||||||
|
_sdl_audio_dev = SDL_GetAudioStreamDevice(_sdl_stream);
|
||||||
|
|
||||||
if(audiospec.channels != 2)
|
// SDL 3 may give us a different frequency than requested if the
|
||||||
|
// device only supports certain rates; query the actual format.
|
||||||
|
SDL_AudioSpec dev_spec;
|
||||||
|
int dev_frames = 0;
|
||||||
|
if(SDL_GetAudioDeviceFormat(_sdl_audio_dev, &dev_spec, &dev_frames))
|
||||||
{
|
{
|
||||||
log_printf(ELOG, "audio.c: ERROR: Only stereo output supported!\n");
|
if(dev_spec.freq != a_settings.samplerate)
|
||||||
SDL_CloseAudio();
|
{
|
||||||
return -5;
|
log_printf(WLOG, "audio.c: Requested %d Hz, got %d Hz.\n",
|
||||||
|
a_settings.samplerate, dev_spec.freq);
|
||||||
|
a_settings.samplerate = dev_spec.freq;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(a_settings.samplerate != audiospec.freq)
|
|
||||||
{
|
|
||||||
log_printf(ELOG, "audio.c: Warning: Requested fs=%d Hz, but"
|
|
||||||
"got %d Hz.\n", a_settings.samplerate,
|
|
||||||
audiospec.freq);
|
|
||||||
a_settings.samplerate = audiospec.freq;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((unsigned)audiospec.samples != a_settings.output_buffersize)
|
|
||||||
{
|
|
||||||
log_printf(ELOG, "audio.c: Warning: Requested %u sample"
|
|
||||||
"buffer, but got %u samples.\n",
|
|
||||||
a_settings.output_buffersize, audiospec.samples);
|
|
||||||
a_settings.output_buffersize = audiospec.samples;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(a_settings.output_buffersize > MAX_BUFFER_SIZE)
|
if(a_settings.output_buffersize > MAX_BUFFER_SIZE)
|
||||||
@ -622,12 +650,13 @@ static int _start_SDL_output(void)
|
|||||||
mixbuf = calloc(1, a_settings.buffersize * sizeof(int) * 2);
|
mixbuf = calloc(1, a_settings.buffersize * sizeof(int) * 2);
|
||||||
if(!mixbuf)
|
if(!mixbuf)
|
||||||
{
|
{
|
||||||
SDL_CloseAudio();
|
SDL_DestroyAudioStream(_sdl_stream);
|
||||||
|
_sdl_stream = NULL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_audio_running = 1;
|
_audio_running = 1;
|
||||||
SDL_PauseAudio(0);
|
SDL_ResumeAudioStreamDevice(_sdl_stream);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -710,7 +739,17 @@ static void _stop_output(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
SDL_CloseAudio();
|
{
|
||||||
|
if(_sdl_stream)
|
||||||
|
{
|
||||||
|
SDL_DestroyAudioStream(_sdl_stream);
|
||||||
|
_sdl_stream = NULL;
|
||||||
|
_sdl_audio_dev = 0;
|
||||||
|
}
|
||||||
|
free(_sdl_scratch);
|
||||||
|
_sdl_scratch = NULL;
|
||||||
|
_sdl_scratch_size = 0;
|
||||||
|
}
|
||||||
free(mixbuf);
|
free(mixbuf);
|
||||||
mixbuf = NULL;
|
mixbuf = NULL;
|
||||||
}
|
}
|
||||||
@ -736,8 +775,8 @@ void audio_lock(void)
|
|||||||
++_audio_mutex_locked;
|
++_audio_mutex_locked;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else if(_sdl_stream)
|
||||||
SDL_LockAudio();
|
SDL_LockAudioStream(_sdl_stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -756,8 +795,8 @@ void audio_unlock(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else if(_sdl_stream)
|
||||||
SDL_UnlockAudio();
|
SDL_UnlockAudioStream(_sdl_stream);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
28
states.cpp
28
states.cpp
@ -21,7 +21,8 @@
|
|||||||
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "glSDL.h"
|
#include "sdl_compat.h"
|
||||||
|
#include "gfxengine.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#ifndef M_PI
|
#ifndef M_PI
|
||||||
# define M_PI 3.14159265358979323846 /* pi */
|
# define M_PI 3.14159265358979323846 /* pi */
|
||||||
@ -335,16 +336,15 @@ void st_game_t::enter()
|
|||||||
"Please, check your installation.");
|
"Please, check your installation.");
|
||||||
gsm.change(&st_error);
|
gsm.change(&st_error);
|
||||||
}
|
}
|
||||||
if(prefs->mousecapture)
|
if(prefs->mousecapture && gengine->window_handle())
|
||||||
if(SDL_WM_GrabInput(SDL_GRAB_QUERY) != SDL_GRAB_ON)
|
SDL_SetWindowMouseGrab(gengine->window_handle(), true);
|
||||||
SDL_WM_GrabInput(SDL_GRAB_ON);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void st_game_t::leave()
|
void st_game_t::leave()
|
||||||
{
|
{
|
||||||
if(SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON)
|
if(gengine->window_handle())
|
||||||
SDL_WM_GrabInput(SDL_GRAB_OFF);
|
SDL_SetWindowMouseGrab(gengine->window_handle(), false);
|
||||||
st_intro_title.inext = &st_intro_instructions;
|
st_intro_title.inext = &st_intro_instructions;
|
||||||
st_intro_title.duration = INTRO_TITLE_TIME + 2000;
|
st_intro_title.duration = INTRO_TITLE_TIME + 2000;
|
||||||
st_intro_title.mode = 0;
|
st_intro_title.mode = 0;
|
||||||
@ -353,16 +353,15 @@ void st_game_t::leave()
|
|||||||
|
|
||||||
void st_game_t::yield()
|
void st_game_t::yield()
|
||||||
{
|
{
|
||||||
if(SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON)
|
if(gengine->window_handle())
|
||||||
SDL_WM_GrabInput(SDL_GRAB_OFF);
|
SDL_SetWindowMouseGrab(gengine->window_handle(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void st_game_t::reenter()
|
void st_game_t::reenter()
|
||||||
{
|
{
|
||||||
if(prefs->mousecapture)
|
if(prefs->mousecapture && gengine->window_handle())
|
||||||
if(SDL_WM_GrabInput(SDL_GRAB_QUERY) != SDL_GRAB_ON)
|
SDL_SetWindowMouseGrab(gengine->window_handle(), true);
|
||||||
SDL_WM_GrabInput(SDL_GRAB_ON);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -878,12 +877,14 @@ void new_player_t::open()
|
|||||||
currentIndex = 0;
|
currentIndex = 0;
|
||||||
editing = 1;
|
editing = 1;
|
||||||
build_all();
|
build_all();
|
||||||
SDL_EnableUNICODE(1);
|
if(gengine->window_handle())
|
||||||
|
SDL_StartTextInput(gengine->window_handle());
|
||||||
}
|
}
|
||||||
|
|
||||||
void new_player_t::close()
|
void new_player_t::close()
|
||||||
{
|
{
|
||||||
SDL_EnableUNICODE(0);
|
if(gengine->window_handle())
|
||||||
|
SDL_StopTextInput(gengine->window_handle());
|
||||||
clean();
|
clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1599,7 +1600,6 @@ void st_options_base_t::select(int tag)
|
|||||||
gengine->timefilter(prefs->timefilter * 0.01f);
|
gengine->timefilter(prefs->timefilter * 0.01f);
|
||||||
gengine->interpolation(prefs->filter);
|
gengine->interpolation(prefs->filter);
|
||||||
gengine->vsync(prefs->vsync);
|
gengine->vsync(prefs->vsync);
|
||||||
gengine->pages(prefs->pages);
|
|
||||||
}
|
}
|
||||||
cfg_form->clearstatus(OS_UPDATE);
|
cfg_form->clearstatus(OS_UPDATE);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user