From 762b0954627e1339b65c2de469289db7f9d7ad81 Mon Sep 17 00:00:00 2001 From: Ville Lindholm Date: Thu, 28 May 2026 21:37:01 +0300 Subject: [PATCH] WIP: delete glSDL shim, replace with sdl_compat.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Step 1+2 of the SDL 3 migration. The 2300-line graphics/glSDL.{c,h} OpenGL-on-top-of-SDL-1.2 shim is obsolete under SDL 3 (SDL_Renderer does what glSDL did natively), and its #define overrides of SDL surface APIs collided directly with SDL 3's SDL_oldnames.h. - Add graphics/sdl_compat.h: a one-line umbrella that just pulls in . - Replace every #include "glSDL.h" with #include "sdl_compat.h" (15 files across the tree). - Delete graphics/glSDL.c, graphics/glSDL.h. - Drop glSDL.c from graphics/CMakeLists.txt. - Remove GFX_DRIVER_GLSDL from the gfx_drivers_t enum and from all switches/conditions in gfxengine.cpp. - Drop the glSDL_VSync() call site (will be re-introduced as SDL_SetRenderVSync once gfxengine is ported to SDL_Renderer). - Drop the two glSDL_Invalidate() calls in window.cpp (texture re-upload hints with no equivalent in a pure-surface compositor). - options.cpp: remove the now-empty "OpenGL/glSDL" menu item; force videodriver to GFX_DRIVER_SDL2D. - prefs.cpp: collapse legacy GLSDL setting onto SDL2D on load. After this commit the macro-collision wall is gone (renamed_-token errors drop from many to zero). The build still fails on the next layer of work: SDL 1.2 surface APIs that no longer exist (SDL_FreeSurface, SDL_SetAlpha, SDL_CreateRGBSurface, SDL_DisplayFormat, SDL_PixelFormat struct member access, SDL audio callback API, etc.). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- gamectl.h | 2 +- graphics/CMakeLists.txt | 1 - graphics/filters.c | 2 +- graphics/gfxengine.cpp | 81 +- graphics/gfxengine.h | 5 +- graphics/glSDL.c | 2328 --------------------------------------- graphics/glSDL.h | 399 ------- graphics/region.h | 2 +- graphics/sdl_compat.h | 16 + graphics/sofont.h | 4 +- graphics/sprite.c | 2 +- graphics/sprite.h | 2 +- graphics/window.cpp | 4 - graphics/window.h | 2 +- logger.c | 2 +- manage.h | 2 +- options.cpp | 7 - prefs.cpp | 5 +- random.h | 2 +- sound/a_tools.h | 2 +- sound/a_types.h | 2 +- states.cpp | 2 +- 22 files changed, 52 insertions(+), 2822 deletions(-) delete mode 100644 graphics/glSDL.c delete mode 100644 graphics/glSDL.h create mode 100644 graphics/sdl_compat.h diff --git a/gamectl.h b/gamectl.h index dfdebf2..640e945 100644 --- a/gamectl.h +++ b/gamectl.h @@ -23,7 +23,7 @@ #ifndef _KOBO_GAMECTL_H_ #define _KOBO_GAMECTL_H_ -#include "glSDL.h" +#include "sdl_compat.h" #include "config.h" #define KEY_KP_DOWN SDLK_KP2 diff --git a/graphics/CMakeLists.txt b/graphics/CMakeLists.txt index 081aec0..f149d72 100644 --- a/graphics/CMakeLists.txt +++ b/graphics/CMakeLists.txt @@ -2,7 +2,6 @@ add_library(graphics STATIC cs.c sprite.c filters.c - glSDL.c gfxengine.cpp window.cpp sofont.cpp diff --git a/graphics/filters.c b/graphics/filters.c index f1ae9ff..37d8d22 100644 --- a/graphics/filters.c +++ b/graphics/filters.c @@ -22,7 +22,7 @@ #include #include #include "logger.h" -#include "glSDL.h" +#include "sdl_compat.h" #include #include "sprite.h" #include "filters.h" diff --git a/graphics/gfxengine.cpp b/graphics/gfxengine.cpp index 4016d8e..a8a3b32 100644 --- a/graphics/gfxengine.cpp +++ b/graphics/gfxengine.cpp @@ -29,7 +29,7 @@ #include "gfxengine.h" #include "filters.h" #include -#include "glSDL.h" +#include "sdl_compat.h" #include "sofont.h" #include "window.h" @@ -443,23 +443,10 @@ void gfxengine_t::dither(int type, int _broken_rgba8) if(_dither) { - if(_driver == GFX_DRIVER_GLSDL) - { - //Klugde for glSDL, which doesn't give us a faked - //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.r = 1<<(screen_surface->format->Rloss-1); - df->args.g = 1<<(screen_surface->format->Gloss-1); - df->args.b = 1<<(screen_surface->format->Bloss-1); - } + df->args.x = 0; + df->args.r = 1<<(screen_surface->format->Rloss-1); + df->args.g = 1<<(screen_surface->format->Gloss-1); + df->args.b = 1<<(screen_surface->format->Bloss-1); } else df->args.x = df->args.r = df->args.g = df->args.b = 0; @@ -775,36 +762,6 @@ int gfxengine_t::show() return -2; } - switch(_driver) - { - case GFX_DRIVER_SDL2D: - break; - case GFX_DRIVER_GLSDL: - if(!_doublebuf) - { - log_printf(WLOG, "Only double buffering is supported" - " with OpenGL drivers!\n"); - doublebuffer(1); - } - 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 @@ -816,7 +773,6 @@ int gfxengine_t::show() if(_fullscreen) flags |= SDL_FULLSCREEN; - glSDL_VSync(_vsync); flags |= xflags; screen_surface = SDL_SetVideoMode(_width, _height, _depth, flags); @@ -826,25 +782,22 @@ int gfxengine_t::show() return -3; } - if(_driver != GFX_DRIVER_GLSDL) + if((screen_surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) { - if((screen_surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) + if(!_doublebuf) { - if(!_doublebuf) - { - log_printf(WLOG, "Could not get" - " single buffered display.\n"); - doublebuffer(1); - } + log_printf(WLOG, "Could not get" + " single buffered display.\n"); + doublebuffer(1); } - else + } + else + { + if(_doublebuf) { - if(_doublebuf) - { - log_printf(WLOG, "Could not get" - " double buffered display.\n"); - doublebuffer(0); - } + log_printf(WLOG, "Could not get" + " double buffered display.\n"); + doublebuffer(0); } } diff --git a/graphics/gfxengine.h b/graphics/gfxengine.h index b473247..d937d01 100644 --- a/graphics/gfxengine.h +++ b/graphics/gfxengine.h @@ -29,14 +29,13 @@ #include #include #include -#include "glSDL.h" +#include "sdl_compat.h" #include "sprite.h" #include "cs.h" enum gfx_drivers_t { - GFX_DRIVER_SDL2D = 0, - GFX_DRIVER_GLSDL = 1 + GFX_DRIVER_SDL2D = 0 }; enum gfx_scalemodes_t diff --git a/graphics/glSDL.c b/graphics/glSDL.c deleted file mode 100644 index b43e90b..0000000 --- a/graphics/glSDL.c +++ /dev/null @@ -1,2328 +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. - */ - -#define _GLSDL_NO_REDEFINES_ -#include "glSDL.h" - -#ifdef HAVE_OPENGL - -#define LEAK_TRACKING - -#define DBG(x) /*error messages, warnings*/ -#define DBG2(x) /*texture allocation*/ -#define DBG3(x) /*chopping/tiling*/ -#define DBG4(x) /*texture uploading*/ -#define DBG5(x) /*two-way chopping/tiling*/ -#define DBG6(x) /*OpenGL lib loading*/ - -#undef CKSTATS /*colorkey statistics*/ - -/* Keep this on for now! Makes large surfaces faster. */ -#define FAKE_MAXTEXSIZE 256 - -#include -#include -#include - -#if HAS_SDL_OPENGL_H -#include -#else -#ifdef WIN32 -#include -#endif -#if defined(__APPLE__) && defined(__MACH__) -#include -#include -#else -#include -#include -#endif -#endif - -#if defined(_WIN32) && !defined(APIENTRY) && \ - !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) -#include -#endif -#ifndef APIENTRY -#define APIENTRY -#endif - - -static inline void clip_rect(SDL_Rect *r, SDL_Rect *to) -{ - int dx1 = r->x; - int dy1 = r->y; - int dx2 = dx1 + r->w; - int dy2 = dy1 + r->h; - if(dx1 < to->x) - dx1 = to->x; - if(dy1 < to->y) - dy1 = to->y; - if(dx2 > to->x + to->w) - dx2 = to->x + to->w; - if(dy2 > to->y + to->h) - dy2 = to->y + to->h; - if(dx2 < dx1 || dy2 < dy1) - { - r->x = r->y = 0; - r->w = r->h = 0; - } - else - { - r->x = dx1; - r->y = dy1; - r->w = dx2 - dx1; - r->h = dy2 - dy1; - } -} - - -/*---------------------------------------------------------- - OpenGL interface -----------------------------------------------------------*/ - -static struct -{ - void (APIENTRY *Begin)(GLenum); - void (APIENTRY *BindTexture)(GLenum, GLuint); - void (APIENTRY *BlendFunc)(GLenum, GLenum); - void (APIENTRY *Color4ub)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); - void (APIENTRY *DeleteTextures)(GLsizei n, const GLuint *textures); - void (APIENTRY *Disable)(GLenum cap); - void (APIENTRY *Enable)(GLenum cap); - void (APIENTRY *End)(void); - void (APIENTRY *Flush)(void); - void (APIENTRY *GenTextures)(GLsizei n, GLuint *textures); - GLenum (APIENTRY *GetError)(void); - void (APIENTRY *GetIntegerv)(GLenum pname, GLint *params); - void (APIENTRY *LoadIdentity)(void); - void (APIENTRY *MatrixMode)(GLenum mode); - void (APIENTRY *Ortho)(GLdouble left, GLdouble right, GLdouble bottom, - GLdouble top, GLdouble zNear, GLdouble zFar); - void (APIENTRY *PixelStorei)(GLenum pname, GLint param); - void (APIENTRY *ReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, GLvoid *pixels); - void (APIENTRY *TexCoord2f)(GLfloat s, GLfloat t); - void (APIENTRY *TexImage2D)(GLenum target, GLint level, GLint internalformat, - GLsizei width, GLsizei height, GLint border, - GLenum format, GLenum type, const GLvoid *pixels); - void (APIENTRY *TexParameteri)(GLenum target, GLenum pname, GLint param); - void (APIENTRY *TexSubImage2D)(GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - GLenum format, GLenum type, const GLvoid *pixels); - void (APIENTRY *Translatef)(GLfloat x, GLfloat y, GLfloat z); - void (APIENTRY *Vertex2i)(GLint x, GLint y); - void (APIENTRY *Viewport)(GLint x, GLint y, GLsizei width, GLsizei height); - void (APIENTRY *Rotated)(GLdouble, GLdouble, GLdouble, GLdouble); - void (APIENTRY *Scalef)(GLfloat, GLfloat, GLfloat); - void (APIENTRY *PushMatrix)(void); - void (APIENTRY *PopMatrix)(void); -} gl; - - -static int GetGL(void) -{ - int i; - struct - { - const char *name; - void **fn; - } glfuncs[] = { - {"glBegin", (void *)&gl.Begin }, - {"glBindTexture", (void *)&gl.BindTexture }, - {"glBlendFunc", (void *)&gl.BlendFunc }, - {"glColor4ub", (void *)&gl.Color4ub }, - {"glDeleteTextures", (void *)&gl.DeleteTextures }, - {"glDisable", (void *)&gl.Disable }, - {"glEnable", (void *)&gl.Enable }, - {"glEnd", (void *)&gl.End }, - {"glFlush", (void *)&gl.Flush }, - {"glGenTextures", (void *)&gl.GenTextures }, - {"glGetError", (void *)&gl.GetError }, - {"glGetIntegerv", (void *)&gl.GetIntegerv }, - {"glLoadIdentity", (void *)&gl.LoadIdentity }, - {"glMatrixMode", (void *)&gl.MatrixMode }, - {"glOrtho", (void *)&gl.Ortho }, - {"glPixelStorei", (void *)&gl.PixelStorei }, - {"glReadPixels", (void *)&gl.ReadPixels }, - {"glTexCoord2f", (void *)&gl.TexCoord2f }, - {"glTexImage2D", (void *)&gl.TexImage2D }, - {"glTexParameteri", (void *)&gl.TexParameteri }, - {"glTexSubImage2D", (void *)&gl.TexSubImage2D }, - {"glTranslatef", (void *)&gl.Translatef }, - {"glVertex2i", (void *)&gl.Vertex2i }, - {"glViewport", (void *)&gl.Viewport }, - {"glRotated", (void *)&gl.Rotated }, - {"glScalef", (void *)&gl.Scalef }, - {"glPushMatrix", (void *)&gl.PushMatrix }, - {"glPopMatrix", (void *)&gl.PopMatrix }, - {NULL, NULL } - }; - for(i = 0; glfuncs[i].name; ++i) - { - *glfuncs[i].fn = SDL_GL_GetProcAddress(glfuncs[i].name); - if(!*glfuncs[i].fn) - { - DBG6(fprintf(stderr,"glSDL/wrapper ERROR: Could not get " - "OpenGL function '%s'!\n", - glfuncs[i].name);) - return -1; - } - DBG6(printf("Got OpenGL function '%s'.\n", glfuncs[i].name);) - } - return 0; -} - - -static int LoadGL(void) -{ - if(GetGL() < 0) - { - DBG6(printf("Couldn't get GL funcs! Trying to load lib...\n");) - SDL_GL_LoadLibrary(NULL); - if(GetGL() < 0) - { - DBG6(printf("Still couldn't get GL funcs!\n");) - return -1; - } - } - return 0; -} - - -static void UnloadGL(void) -{ -} - - -static void print_glerror(int point) -{ -#if (DBG(1)+0 == 1) - const char *err = ""; - switch(gl.GetError()) - { - case GL_NO_ERROR: - return; - case GL_INVALID_ENUM: - err = "GL_INVALID_ENUM"; - break; - case GL_INVALID_VALUE: - err = "GL_INVALID_VALUE"; - break; - case GL_INVALID_OPERATION: - err = "GL_INVALID_OPERATION"; - break; - case GL_STACK_OVERFLOW: - err = "GL_STACK_OVERFLOW"; - break; - case GL_STACK_UNDERFLOW: - err = "GL_STACK_UNDERFLOW"; - break; - case GL_OUT_OF_MEMORY: - err = "GL_OUT_OF_MEMORY"; - break; - default: - err = ""; - break; - } - fprintf(stderr,"OpenGL error \"%s\" at point %d.\n", err, point); -#endif -} - - -/*---------------------------------------------------------- - OpenGL state wrapper -----------------------------------------------------------*/ - -static struct -{ - int do_blend; - int do_texture; - GLint texture; - GLenum sfactor, dfactor; -} glstate; - -static void gl_reset(void) -{ - glstate.do_blend = -1; - glstate.do_blend = -1; - glstate.texture = -1; - glstate.sfactor = 0xffffffff; - glstate.dfactor = 0xffffffff; -} - -static __inline__ void gl_do_blend(int on) -{ - if(glstate.do_blend == on) - return; - - if(on) - gl.Enable(GL_BLEND); - else - gl.Disable(GL_BLEND); - glstate.do_blend = on; -} - -static __inline__ void gl_do_texture(int on) -{ - if(glstate.do_texture == on) - return; - - if(on) - gl.Enable(GL_TEXTURE_2D); - else - gl.Disable(GL_TEXTURE_2D); - glstate.do_texture = on; -} - -static __inline__ void gl_blendfunc(GLenum sfactor, GLenum dfactor) -{ - if((sfactor == glstate.sfactor) && (dfactor == glstate.dfactor)) - return; - - gl.BlendFunc(sfactor, dfactor); - - glstate.sfactor = sfactor; - glstate.dfactor = dfactor; -} - -static __inline__ void gl_texture(GLuint tx) -{ - if(tx == (unsigned)glstate.texture) - return; - - gl.BindTexture(GL_TEXTURE_2D, tx); - glstate.texture = tx; -} - - -/*---------------------------------------------------------- - Global stuff -----------------------------------------------------------*/ - -static int initialized = 0; - -static int using_glsdl = 0; -#define USING_GLSDL (0 != using_glsdl) - -#define MAX_TEXINFOS 16384 - -static glSDL_TexInfo **texinfotab = NULL; -static GLint maxtexsize = 256; -static SDL_PixelFormat RGBfmt, RGBAfmt; - -static void UnloadTexture(glSDL_TexInfo *txi); - -static int scale = 1; -static int vsync = 1; - -static SDL_Surface *fake_screen = NULL; - - -static int glSDL_BlitGL(SDL_Surface *src, SDL_Rect *srcrect, - SDL_Surface *dst, SDL_Rect *dstrect); - - -/*---------------------------------------------------------- - glSDL Global State -----------------------------------------------------------*/ - -static struct -{ - Uint8 alpha; /* Alpha */ - Uint8 r, g, b; /* Color modulation */ - float cx, cy; /* Transform center offset */ - float sx, sy; /* Scale */ - float rot; /* Rotation */ -} state; - - -void glSDL_SetBlendAlpha(Uint8 alpha) -{ - state.alpha = alpha; -} - - -void glSDL_SetBlendColor(Uint8 r, Uint8 g, Uint8 b) -{ - state.r = r; - state.g = g; - state.b = b; -} - - -void glSDL_SetCenter(float x, float y) -{ - state.cx = x; - state.cy = y; -} - - -void glSDL_SetRotation(float angle) -{ - state.rot = angle; -} - - -void glSDL_SetScale(float x, float y) -{ - state.sx = x; - state.sy = y; -} - - -void glSDL_ResetState(void) -{ - glSDL_SetBlendAlpha(255); - glSDL_SetBlendColor(255, 255, 255); - glSDL_SetCenter(0.0f, 0.0f); - glSDL_SetRotation(0.0f); - glSDL_SetScale(1.0f, 1.0f); -} - - -/*---------------------------------------------------------- - Code -----------------------------------------------------------*/ - -/* Get texinfo for a surface. */ -static __inline__ glSDL_TexInfo *glSDL_GetTexInfo(SDL_Surface *surface) -{ - if(texinfotab) - return texinfotab[surface->unused1]; - else - return NULL; -} - - -/* Allocate a "blank" texinfo for a suface. */ -glSDL_TexInfo *glSDL_AllocTexInfo(SDL_Surface *surface) -{ - int handle, i = 0; - glSDL_TexInfo *txi; - if(!surface) - return NULL; - - txi = glSDL_GetTexInfo(surface); - if(txi) - return txi; /* There already is one! --> */ - - /* Find a free handle... */ - handle = -1; - for(i = 1; i < MAX_TEXINFOS + 1; ++i) - if(NULL == texinfotab[i]) - { - handle = i; - break; - } - - if(handle < 0) - { - DBG(fprintf(stderr, "glSDL/wrapper: Out of handles!\n")); - return NULL; - } - - /* ...and hook a new texinfo struct up to it. */ - texinfotab[handle] = (glSDL_TexInfo*)calloc(1, sizeof(glSDL_TexInfo)); - if(!texinfotab[handle]) - return NULL; - - /* Connect the surface to the new TexInfo. */ - surface->unused1 = (Uint32)handle; - - DBG2(fprintf(stderr, "glSDL/wrapper: Allocated TexInfo %d.\n", handle)); - - return texinfotab[handle]; -} - - -static void FreeTexInfo(Uint32 handle) -{ - if(handle >= MAX_TEXINFOS) - return; - if(!texinfotab[handle]) - return; - - UnloadTexture(texinfotab[handle]); - texinfotab[handle]->textures = 0; - free(texinfotab[handle]->texture); - texinfotab[handle]->texture = NULL; - free(texinfotab[handle]); - texinfotab[handle] = NULL; - DBG2(fprintf(stderr, "glSDL/wrapper: Freed TexInfo %d.\n", handle)); -} - - -/* Detach and free the texinfo of a surface. */ -void glSDL_FreeTexInfo(SDL_Surface *surface) -{ - if(!texinfotab) - return; - - if(!surface) - return; - - if(!glSDL_GetTexInfo(surface)) - return; - - FreeTexInfo(surface->unused1); - GLSDL_FIX_SURFACE(surface); -} - - -/* - * Calculate chopping/tiling of a surface to - * fit it into the smallest possible OpenGL - * texture. - */ -static int CalcChop(SDL_Surface *s, glSDL_TexInfo *txi) -{ - int rows, vw, vh; - int vertical = 0; - int texsize; - int lastw, lasth, minsize; - - vw = s->w; - vh = s->h; - - DBG3(fprintf(stderr, "w=%d, h=%d ", vw, vh)); - if(vh > vw) - { - int t = vw; - vw = vh; - vh = t; - vertical = 1; - DBG3(fprintf(stderr, "(vertical) \t")); - } - - /* - * Check whether this is a "huge" surface - at least one dimension - * must be <= than the maximum texture size, or we'll have to chop - * in both directions. - */ - if(vh > maxtexsize) - { - /* - * Very simple hack for now; we just tile - * both ways with maximum size textures. - */ - texsize = maxtexsize; - - txi->tilemode = GLSDL_TM_HUGE; - txi->texsize = texsize; - txi->tilew = texsize; - txi->tileh = texsize; - txi->tilespertex = 1; - - /* Calculate number of textures needed */ - txi->textures = (vw + texsize - 1) / texsize; - txi->textures *= (vh + texsize - 1) / texsize; - txi->texture = (int*)malloc(txi->textures * sizeof(int)); - memset(txi->texture, -1, txi->textures * sizeof(int)); - DBG5(fprintf(stderr, "two-way tiling; textures=%d\n", txi->textures)); - if(!txi->texture) - { - fprintf(stderr, "glSDL/wrapper: INTERNAL ERROR: Failed to allocate" - " texture name table!\n"); - return -3; - } - return 0; - } - - /* Calculate minimum size */ - rows = 1; - lastw = vw; - lasth = vh; - minsize = lastw > lasth ? lastw : lasth; - while(1) - { - int w, h, size; - ++rows; - w = vw / rows; - h = rows * vh; - size = w > h ? w : h; - if(size >= minsize) - { - --rows; - break; - } - lastw = w; - lasth = h; - minsize = size; - } - if(minsize > maxtexsize) - { - /* Handle multiple textures for very wide/tall surfaces. */ - minsize = maxtexsize; - rows = (vw + minsize-1) / minsize; - } - DBG3(fprintf(stderr, "==> minsize=%d ", minsize)); - DBG3(fprintf(stderr, "(rows=%d) \t", rows)); - - /* Recalculate with nearest higher power-of-2 width. */ - for(texsize = 1; texsize < minsize; texsize <<= 1) - ; - txi->texsize = texsize; - rows = (vw + texsize-1) / texsize; - DBG3(fprintf(stderr, "==> texsize=%d (rows=%d) \t", texsize, rows)); - - /* Calculate number of tiles per texture */ - txi->tilespertex = txi->texsize / vh; - DBG3(fprintf(stderr, "tilespertex=%d \t", txi->tilespertex)); - - /* Calculate number of textures needed */ - txi->textures = (rows + txi->tilespertex-1) / txi->tilespertex; - txi->texture = (int*)malloc(txi->textures * sizeof(int)); - memset(txi->texture, -1, txi->textures * sizeof(int)); - DBG3(fprintf(stderr, "textures=%d, ", txi->textures)); - if(!txi->texture) - { - fprintf(stderr, "glSDL/wrapper: INTERNAL ERROR: Failed to allocate" - " texture name table!\n"); - return -2; - } - - /* Set up tile size. (Only one axis supported here!) */ - if(1 == rows) - { - txi->tilemode = GLSDL_TM_SINGLE; - if(vertical) - { - txi->tilew = vh; - txi->tileh = vw; - } - else - { - txi->tilew = vw; - txi->tileh = vh; - } - } - else if(vertical) - { - txi->tilemode = GLSDL_TM_VERTICAL; - txi->tilew = vh; - txi->tileh = texsize; - } - else - { - txi->tilemode = GLSDL_TM_HORIZONTAL; - txi->tilew = texsize; - txi->tileh = vh; - } - - DBG3(fprintf(stderr, "tilew=%d, tileh=%d\n", txi->tilew, txi->tileh)); - return 0; -} - - -/* Add a glSDL_TexInfo struct to an SDL_Surface */ -static int glSDL_AddTexInfo(SDL_Surface *surface) -{ - glSDL_TexInfo *txi; - - if(!surface) - return -1; - if(IS_GLSDL_SURFACE(surface)) - return 0; /* Do nothing */ - - glSDL_AllocTexInfo(surface); - txi = glSDL_GetTexInfo(surface); - if(!txi) - return -2; /* Oops! Didn't get a texinfo... --> */ - - if(CalcChop(surface, txi) < 0) - return -3; - - SDL_SetClipRect(surface, NULL); - - return 0; -} - - -/* Create a surface of the prefered OpenGL RGB texture format */ -static SDL_Surface *CreateRGBSurface(int w, int h) -{ - SDL_Surface *s; - Uint32 rmask, gmask, bmask; - int bits = 24; -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - rmask = 0x00ff0000; - gmask = 0x0000ff00; - bmask = 0x000000ff; -#else - rmask = 0x000000ff; - gmask = 0x0000ff00; - bmask = 0x00ff0000; -#endif - s = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, - bits, rmask, gmask, bmask, 0); - if(s) - GLSDL_FIX_SURFACE(s); - - glSDL_AddTexInfo(s); - return s; -} - - -/* Create a surface of the prefered OpenGL RGBA texture format */ -static SDL_Surface *CreateRGBASurface(int w, int h) -{ - SDL_Surface *s; - Uint32 rmask, gmask, bmask, amask; - int bits = 32; -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - rmask = 0xff000000; - gmask = 0x00ff0000; - bmask = 0x0000ff00; - amask = 0x000000ff; -#else - rmask = 0x000000ff; - gmask = 0x0000ff00; - bmask = 0x00ff0000; - amask = 0xff000000; -#endif - s = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, - bits, rmask, gmask, bmask, amask); - if(s) - GLSDL_FIX_SURFACE(s); - - glSDL_AddTexInfo(s); - return s; -} - - -static void init_formats(void) -{ - SDL_Surface *s = CreateRGBSurface(1, 1); - if(!s) - return; - RGBfmt = *(s->format); - glSDL_FreeSurface(s); - - s = CreateRGBASurface(1, 1); - if(!s) - return; - RGBAfmt = *(s->format); - glSDL_FreeSurface(s); -} - - -static int FormatIsOk(SDL_Surface *surface) -{ - SDL_PixelFormat *pf; - if(!surface) - return 1; /* Well, there ain't much we can do anyway... */ - - pf = surface->format; - - /* Colorkeying always requires conversion! */ - if(surface->flags & SDL_SRCCOLORKEY) - return 0; - - /* We need pitch == (width * BytesPerPixel) for glTex[Sub]Image2D() */ - if(surface->pitch != (surface->w * pf->BytesPerPixel)) - return 0; - - if(pf->Amask) - { - if(pf->BytesPerPixel != RGBAfmt.BytesPerPixel) - return 0; - if(pf->Rmask != RGBAfmt.Rmask) - return 0; - if(pf->Gmask != RGBAfmt.Gmask) - return 0; - if(pf->Bmask != RGBAfmt.Bmask) - return 0; - if(pf->Amask != RGBAfmt.Amask) - return 0; - } - else - { - if(pf->BytesPerPixel != RGBfmt.BytesPerPixel) - return 0; - if(pf->Rmask != RGBfmt.Rmask) - return 0; - if(pf->Gmask != RGBfmt.Gmask) - return 0; - if(pf->Bmask != RGBfmt.Bmask) - return 0; - } - return 1; -} - - - -static void key2alpha(SDL_Surface *surface) -{ - int x, y; -#ifdef CKSTATS - int transp = 0; -#endif - Uint32 rgbmask = surface->format->Rmask | - surface->format->Gmask | - surface->format->Bmask; - Uint32 ckey = surface->format->colorkey & rgbmask; - if(SDL_LockSurface(surface) < 0) - return; - - for(y = 0; y < surface->h; ++y) - { - Uint32 *px = (Uint32 *)((char *)surface->pixels + y*surface->pitch); - for(x = 0; x < surface->w; ++x) - if((px[x] & rgbmask) == ckey) - { - px[x] = 0; -#ifdef CKSTATS - ++transp; -#endif - } - } -#ifdef CKSTATS - printf("glSDL/wrapper: key2alpha(); %dx%d surface, %d opaque pixels.\n", - surface->w, surface->h, - surface->w * surface->h - transp); -#endif - SDL_UnlockSurface(surface); -} - - - -/*---------------------------------------------------------- - SDL style API -----------------------------------------------------------*/ - -static void KillAllTextures(void) -{ - if(texinfotab) - { - unsigned i; -#ifdef LEAK_TRACKING - int leaked = 0; - for(i = 3; i < MAX_TEXINFOS + 1; ++i) - if(texinfotab[i]) - { - ++leaked; - fprintf(stderr, "glSDL/wrapper: Leaked TexInfo" - " %d! (%d %dx%d textures)\n", - i, - texinfotab[i]->textures, - texinfotab[i]->texsize, - texinfotab[i]->texsize - ); - } - if(leaked) - fprintf(stderr, "glSDL/wrapper: Leaked %d TexInfos!\n", leaked); -#endif - for(i = 1; i < MAX_TEXINFOS + 1; ++i) - FreeTexInfo(i); - free(texinfotab); - texinfotab = NULL; - } -} - -void glSDL_Quit(void) -{ - if(SDL_WasInit(SDL_INIT_VIDEO)) - { - glSDL_FreeTexInfo(SDL_GetVideoSurface()); - if(fake_screen) - { - glSDL_FreeTexInfo(fake_screen); - SDL_FreeSurface(fake_screen); - fake_screen = NULL; - } - UnloadGL(); - SDL_QuitSubSystem(SDL_INIT_VIDEO); - } -#ifndef LEAK_TRACKING - KillAllTextures(); -#endif -} - - -void glSDL_FullQuit(void) -{ -#ifdef LEAK_TRACKING - KillAllTextures(); -#endif - glSDL_Quit(); - SDL_Quit(); -} - - -void glSDL_QuitSubSystem(Uint32 flags) -{ - if(flags & SDL_INIT_VIDEO) - glSDL_Quit(); - SDL_QuitSubSystem(flags); -} - - -SDL_Surface *glSDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) -{ - SDL_Surface *screen; - GLint gl_doublebuf; - - if(!initialized) - { - glSDL_ResetState(); - initialized = 1; - } - - if(USING_GLSDL) - { - glSDL_FreeTexInfo(SDL_GetVideoSurface()); - if(fake_screen) - { - glSDL_FreeTexInfo(fake_screen); - SDL_FreeSurface(fake_screen); - fake_screen = NULL; - } - UnloadGL(); - using_glsdl = 0; - } - - if(!(flags & SDL_GLSDL)) - { - screen = SDL_SetVideoMode(width, height, bpp, flags); - if(screen) - GLSDL_FIX_SURFACE(screen); - return screen; - } - - if((SDL_Linked_Version()->major <= 1) && - (SDL_Linked_Version()->minor <= 2) && - (SDL_Linked_Version()->patch < 5)) - fprintf(stderr, "glSDL/wrapper WARNING: Using SDL version" - " 1.2.5 or later is strongly" - " recommended!\n"); - - if(LoadGL() < 0) - { - fprintf(stderr, "glSDL/wrapper ERROR: Could not load OpenGL library!\n"); - return NULL; - } - -/* - * FIXME: Here's the place to insert proper handling of this call being - * used for resizing the window... For now, just make sure we - * don't end up with invalid texinfos and stuff no matter what. - */ - KillAllTextures(); - - texinfotab = (glSDL_TexInfo**)calloc(MAX_TEXINFOS + 1, sizeof(glSDL_TexInfo *)); - if(!texinfotab) - return NULL; - - /* Remove flag to avoid confusion inside SDL - just in case! */ - flags &= ~SDL_GLSDL; - - flags |= SDL_OPENGL; - if(bpp == 15) - { - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); - } - else if(bpp == 16) - { - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); - } - else if(bpp >= 24) - { - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); - } - gl_doublebuf = (flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF; - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, gl_doublebuf); - SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, vsync); - scale = 1; - - screen = SDL_SetVideoMode(width*scale, height*scale, bpp, flags); - if(!screen) - { - KillAllTextures(); - return NULL; - } - - GLSDL_FIX_SURFACE(screen); - -#ifdef FAKE_MAXTEXSIZE - maxtexsize = FAKE_MAXTEXSIZE; -#else - gl.GetIntegerv(GL_MAX_TEXTURE_SIZE, &maxtexsize); -#endif - DBG(fprintf(stderr, "glSDL/wrapper: Max texture size: %d\n", maxtexsize)); - - init_formats(); - gl_reset(); - - if(glSDL_AddTexInfo(screen) < 0) - { - DBG(fprintf(stderr, "glSDL/wrapper: Failed to add info to screen surface!\n")); - SDL_QuitSubSystem(SDL_INIT_VIDEO); - return NULL; - } - - glSDL_SetClipRect(screen, &screen->clip_rect); - - gl.Viewport(0, 0, screen->w * scale, screen->h * scale); - /* - * Note that this projection is upside down in - * relation to the OpenGL coordinate system. - */ - gl.MatrixMode(GL_PROJECTION); - gl.LoadIdentity(); - gl.Ortho(0, scale * (float)screen->w, scale * (float)screen->h, 0, - -1.0, 1.0); - - gl.MatrixMode(GL_MODELVIEW); - gl.LoadIdentity(); - gl.Translatef(0.0f, 0.0f, 0.0f); - - gl.Disable(GL_DEPTH_TEST); - gl.Disable(GL_CULL_FACE); - - /* - * Create a software shadow buffer of the requested size. - * This is used for blit-from-screen and simulation of - * direct software rendering. (Dog slow crap. It's only - * legitimate use is probably screen shots.) - */ - fake_screen = CreateRGBSurface(screen->w / scale, - screen->h / scale); - using_glsdl = 1; - return fake_screen; -} - - -SDL_Surface *glSDL_GetVideoSurface(void) -{ - if(fake_screen) - return fake_screen; - else - return SDL_GetVideoSurface(); -} - - -void glSDL_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects) -{ - if(IS_GLSDL_SURFACE(screen)) - glSDL_Flip(screen); - else - SDL_UpdateRects(screen, numrects, rects); -} - - -void glSDL_UpdateRect(SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h) -{ - SDL_Rect r; - r.x = x; - r.y = y; - r.w = w; - r.h = h; - glSDL_UpdateRects(screen, 1, &r); -} - - -int glSDL_Flip(SDL_Surface *screen) -{ - if(!IS_GLSDL_SURFACE(screen)) - return SDL_Flip(screen); - - SDL_GL_SwapBuffers(); - return 0; -} - - -void glSDL_FreeSurface(SDL_Surface *surface) -{ - if(!surface) - return; - glSDL_FreeTexInfo(surface); - SDL_FreeSurface(surface); -} - - -int glSDL_LockSurface(SDL_Surface *surface) -{ - if(!surface) - return 0; - - if(IS_GLSDL_SURFACE(surface)) - { - if((surface == fake_screen) || - (SDL_GetVideoSurface() == surface)) - { - if(scale > 1) - return -1; - - glSDL_Invalidate(fake_screen, NULL); - - gl.PixelStorei(GL_UNPACK_ROW_LENGTH, - fake_screen->pitch / - fake_screen->format->BytesPerPixel); - - gl.ReadPixels(0, 0, fake_screen->w, fake_screen->h, - GL_RGB, GL_UNSIGNED_BYTE, - fake_screen->pixels); - return 0; - } - else - { - glSDL_Invalidate(surface, NULL); - return SDL_LockSurface(surface); - } - } - else - return SDL_LockSurface(surface); -} - - -void glSDL_UnlockSurface(SDL_Surface *surface) -{ - if(!surface) - return; - - if(IS_GLSDL_SURFACE(surface)) - { - glSDL_UploadSurface(surface); - if((surface == fake_screen) || - (SDL_GetVideoSurface() == surface)) - glSDL_BlitGL(fake_screen, NULL, - SDL_GetVideoSurface(), NULL); - } - else - SDL_UnlockSurface(surface); -} - - -int glSDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key) -{ - int res = SDL_SetColorKey(surface, flag, key); - if(res < 0) - return res; - /* - * If an application does this *after* SDL_DisplayFormat, - * we're basically screwed, unless we want to do an - * in-place surface conversion hack here. - * - * What we do is just kill the glSDL texinfo... No big - * deal in most cases, as glSDL only converts once anyway, - * *unless* you keep modifying the surface. - */ - if(IS_GLSDL_SURFACE(surface)) - glSDL_FreeTexInfo(surface); - return res; -} - - -int glSDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha) -{ - /* - * This is just parameters to OpenGL, so the actual - * "work" is done in glSDL_BlitSurface(). - */ - return SDL_SetAlpha(surface, flag, alpha); -} - - -SDL_bool glSDL_SetClipRect(SDL_Surface *surface, SDL_Rect *rect) -{ - SDL_bool res; - SDL_Surface *screen; - SDL_Rect fsr; - if(!surface) - return SDL_FALSE; - - screen = SDL_GetVideoSurface(); - - res = SDL_SetClipRect(surface, rect); - if(!res) - return SDL_FALSE; - - if(!rect) - { - fsr.x = 0; - fsr.y = 0; - fsr.w = screen->w; - fsr.h = screen->h; - rect = &fsr; - } - if(surface == fake_screen) - { - SDL_Rect r; - r.x = rect->x; - r.y = rect->y; - r.w = rect->w; - r.h = rect->h; - surface = screen; - SDL_SetClipRect(surface, rect); - return SDL_TRUE; - } - return res; -} - - -static int glSDL_BlitFromGL(SDL_Rect *srcrect, - SDL_Surface *dst, SDL_Rect *dstrect) -{ - int i, sy0, dy0; - SDL_Rect sr, dr; - - if(scale > 1) - return -1; - - /* In case the destination has an OpenGL texture... */ - glSDL_Invalidate(dst, dstrect); - - /* Abuse the fake screen buffer a little. */ - gl.PixelStorei(GL_UNPACK_ROW_LENGTH, fake_screen->pitch / - fake_screen->format->BytesPerPixel); - if(srcrect) - { - sr = *srcrect; - dr.x = dr.y = 0; - dr.w = fake_screen->w; - dr.h = fake_screen->h; - clip_rect(&sr, &dr); - gl.ReadPixels(sr.x, sr.y, sr.w, sr.h, GL_RGB, GL_UNSIGNED_BYTE, - fake_screen->pixels); - } - else - { - sr.x = sr.y = 0; - sr.w = dst->w; - srcrect = &sr; - gl.ReadPixels(0, 0, fake_screen->w, fake_screen->h, - GL_RGB, GL_UNSIGNED_BYTE, fake_screen->pixels); - } - - /* Blit to the actual target! (Vert. flip... Uuurgh!) */ - if(dstrect) - dr = *dstrect; - else - { - dr.x = dr.y = 0; - dstrect = &dr; - } - - i = srcrect->h; - sy0 = srcrect->y; - dy0 = dstrect->y + dstrect->h - 1; - while(i--) - { - sr.y = sy0 + i; - dr.y = dy0 - i; - sr.h = 1; - if(SDL_BlitSurface(fake_screen, &sr, dst, &dr) < 0) - return -1; - } - return 0; -} - - -static __inline__ void BlitGL_single(glSDL_TexInfo *txi, - float sx1, float sy1, SDL_Rect *dst, unsigned char alpha) -{ - float sx2, sy2, texscale; - if(!txi->textures) - return; - if(-1 == txi->texture[0]) - return; - gl_texture(txi->texture[0]); - - texscale = 1.0 / (float)txi->texsize; - sx2 = (sx1 + (float)dst->w) * texscale; - sy2 = (sy1 + (float)dst->h) * texscale; - sx1 *= texscale; - sy1 *= texscale; - - gl.Begin(GL_QUADS); - gl.Color4ub(state.r, state.g, state.b, alpha); - gl.TexCoord2f(sx1, sy1); - gl.Vertex2i(dst->x, dst->y); - gl.TexCoord2f(sx2, sy1); - gl.Vertex2i(dst->x + dst->w, dst->y); - gl.TexCoord2f(sx2, sy2); - gl.Vertex2i(dst->x + dst->w, dst->y + dst->h); - gl.TexCoord2f(sx1, sy2); - gl.Vertex2i(dst->x, dst->y + dst->h); - gl.End(); -} - - -static void BlitGL_htile(glSDL_TexInfo *txi, - float sx1, float sy1, SDL_Rect *dst, unsigned char alpha) -{ - int tex; - float tile, sx2, sy2, yo; - float texscale = 1.0 / (float)txi->texsize; - float tileh = (float)txi->tileh * texscale; - sx2 = (sx1 + (float)dst->w) * texscale; - sy2 = (sy1 + (float)dst->h) * texscale; - sx1 *= texscale; - sy1 *= texscale; - tile = floor(sx1); - tex = (int)tile / txi->tilespertex; - yo = ((int)tile % txi->tilespertex) * tileh; - - if(tex >= txi->textures) - return; - if(-1 == txi->texture[tex]) - return; - gl_texture(txi->texture[tex]); - - gl.Begin(GL_QUADS); - while(tile < sx2) - { - int tdx1 = dst->x; - int tdx2 = dst->x + dst->w; - float tsx1 = sx1 - tile; - float tsx2 = sx2 - tile; - - /* Clip to current tile */ - if(tsx1 < 0.0) - { - tdx1 -= (int)(tsx1 * txi->texsize); - tsx1 = 0.0; - } - if(tsx2 > 1.0) - { - tdx2 -= (int)((tsx2 - 1.0) * txi->texsize); - tsx2 = 1.0; - } - - /* Maybe select next texture? */ - if(yo + tileh > 1.0) - { - ++tex; - gl.End(); - if(tex >= txi->textures) - return; - if(-1 == txi->texture[tex]) - return; - gl_texture(txi->texture[tex]); - yo = 0.0; - gl.Begin(GL_QUADS); - } - - gl.Color4ub(state.r, state.g, state.b, alpha); - gl.TexCoord2f(tsx1, yo + sy1); - gl.Vertex2i(tdx1, dst->y); - gl.TexCoord2f(tsx2, yo + sy1); - gl.Vertex2i(tdx2, dst->y); - gl.TexCoord2f(tsx2, yo + sy2); - gl.Vertex2i(tdx2, dst->y + dst->h); - gl.TexCoord2f(tsx1, yo + sy2); - gl.Vertex2i(tdx1, dst->y + dst->h); - - tile += 1.0; - yo += tileh; - } - gl.End(); -} - - -static void BlitGL_vtile(glSDL_TexInfo *txi, - float sx1, float sy1, SDL_Rect *dst, unsigned char alpha) -{ - int tex; - float tile, sx2, sy2, xo; - float texscale = 1.0 / (float)txi->texsize; - float tilew = (float)txi->tilew * texscale; - sx2 = (sx1 + (float)dst->w) * texscale; - sy2 = (sy1 + (float)dst->h) * texscale; - sx1 *= texscale; - sy1 *= texscale; - tile = floor(sy1); - tex = (int)tile / txi->tilespertex; - xo = ((int)tile % txi->tilespertex) * tilew; - - if(tex >= txi->textures) - return; - if(-1 == txi->texture[tex]) - return; - gl_texture(txi->texture[tex]); - - gl.Begin(GL_QUADS); - while(tile < sy2) - { - int tdy1 = dst->y; - int tdy2 = dst->y + dst->h; - float tsy1 = sy1 - tile; - float tsy2 = sy2 - tile; - - /* Clip to current tile */ - if(tsy1 < 0.0) - { - tdy1 -= (int)(tsy1 * txi->texsize); - tsy1 = 0.0; - } - if(tsy2 > 1.0) - { - tdy2 -= (int)((tsy2 - 1.0) * txi->texsize); - tsy2 = 1.0; - } - - /* Maybe select next texture? */ - if(xo + tilew > 1.0) - { - ++tex; - gl.End(); - if(tex >= txi->textures) - return; - if(-1 == txi->texture[tex]) - return; - gl_texture(txi->texture[tex]); - xo = 0.0; - gl.Begin(GL_QUADS); - } - - gl.Color4ub(state.r, state.g, state.b, alpha); - gl.TexCoord2f(xo + sx1, tsy1); - gl.Vertex2i(dst->x, tdy1); - gl.TexCoord2f(xo + sx2, tsy1); - gl.Vertex2i(dst->x + dst->w, tdy1); - gl.TexCoord2f(xo + sx2, tsy2); - gl.Vertex2i(dst->x + dst->w, tdy2); - gl.TexCoord2f(xo + sx1, tsy2); - gl.Vertex2i(dst->x, tdy2); - - tile += 1.0; - xo += tilew; - } - gl.End(); -} - - -static void BlitGL_hvtile(SDL_Surface *src, glSDL_TexInfo *txi, - float sx1, float sy1, SDL_Rect *dst, unsigned char alpha) -{ - int x, y, last_tex, tex; - float sx2, sy2; - float texscale = 1.0 / (float)txi->texsize; - int tilesperrow = (src->w + txi->tilew - 1) / txi->tilew; - sx2 = (sx1 + (float)dst->w) * texscale; - sy2 = (sy1 + (float)dst->h) * texscale; - sx1 *= texscale; - sy1 *= texscale; - - last_tex = tex = (int)(floor(sy1) * tilesperrow + floor(sx1)); - if(tex >= txi->textures) - return; - if(-1 == txi->texture[tex]) - return; - gl_texture(txi->texture[tex]); - - gl.Begin(GL_QUADS); - for(y = (int)floor(sy1); y < sy2; ++y) - { - int tdy1 = dst->y; - int tdy2 = dst->y + dst->h; - float tsy1 = sy1 - y; - float tsy2 = sy2 - y; - - /* Clip to current tile */ - if(tsy1 < 0.0) - { - tdy1 -= (int)(tsy1 * txi->texsize); - tsy1 = 0.0; - } - if(tsy2 > 1.0) - { - tdy2 -= (int)((tsy2 - 1.0) * txi->texsize); - tsy2 = 1.0; - } - for(x = (int)floor(sx1); x < sx2; ++x) - { - int tdx1 = dst->x; - int tdx2 = dst->x + dst->w; - float tsx1 = sx1 - x; - float tsx2 = sx2 - x; - - /* Clip to current tile */ - if(tsx1 < 0.0) - { - tdx1 -= (int)(tsx1 * txi->texsize); - tsx1 = 0.0; - } - if(tsx2 > 1.0) - { - tdx2 -= (int)((tsx2 - 1.0) * txi->texsize); - tsx2 = 1.0; - } - - /* Select texture */ - tex = y * tilesperrow + x; - if(tex != last_tex) - { - gl.End(); - if(tex >= txi->textures) - return; - if(-1 == txi->texture[tex]) - return; - gl_texture(txi->texture[tex]); - last_tex = tex; - gl.Begin(GL_QUADS); - } - - gl.Color4ub(state.r, state.g, state.b, alpha); - gl.TexCoord2f(tsx1, tsy1); - gl.Vertex2i(tdx1, tdy1); - gl.TexCoord2f(tsx2, tsy1); - gl.Vertex2i(tdx2, tdy1); - gl.TexCoord2f(tsx2, tsy2); - gl.Vertex2i(tdx2, tdy2); - gl.TexCoord2f(tsx1, tsy2); - gl.Vertex2i(tdx1, tdy2); - } - } - gl.End(); -} - - -/* - * Calculate the actual blit rectangle and source offset - * for a blit from a rectangle in a surface with specified - * size to a surface with a cliprect. - * - * In: rect source rectangle - * w, h source surface size - * (x, y) destination coordinate - * clip destination clip rectangle - * - * Out: (x, y) source top-left offset - * rect destination rectangle - * - * Returns 1 if the result is visible, otherwise 0. - */ -static __inline__ int blitclip(SDL_Rect *rect, int w, int h, - int *x, int *y, SDL_Rect *clip) -{ - int sx1, sy1, sx2, sy2; - int dx1, dy1, dx2, dy2; - - /* Get source and destination coordinates */ - sx1 = rect->x; - sy1 = rect->y; - sx2 = sx1 + rect->w; - sy2 = sy1 + rect->h; - dx1 = *x; - dy1 = *y; - - /* Keep source rect inside source surface */ - if(sx1 < 0) - { - dx1 -= sx1; - sx1 = 0; - } - if(sy1 < 0) - { - dy1 -= sy1; - sy1 = 0; - } - if(sx2 > w) - sx2 = w; - if(sy2 > h) - sy2 = h; - - /* Cull blits from void space */ - if(sx1 >= sx2 || sy1 >= sy2) - return 0; - - /* Calculate destination lower-right */ - dx2 = dx1 + (sx2 - sx1); - dy2 = dy1 + (sy2 - sy1); - - if(clip) - { - /* Clip to destination cliprect */ - if(dx1 < clip->x) - { - sx1 += clip->x - dx1; - dx1 = clip->x; - } - if(dy1 < clip->y) - { - sy1 += clip->y - dy1; - dy1 = clip->y; - } - if(dx2 > clip->x + clip->w) - dx2 = clip->x + clip->w; - if(dy2 > clip->y + clip->h) - dy2 = clip->y + clip->h; - } - - /* Cull nop/off-screen blits */ - if(dx1 >= dx2 || dy1 >= dy2) - return 0; - - *x = sx1; - *y = sy1; - rect->x = dx1; - rect->y = dy1; - rect->w = dx2 - dx1; - rect->h = dy2 - dy1; - return 1; -} - - -static int glSDL_BlitGL(SDL_Surface *src, SDL_Rect *srcrect, - SDL_Surface *dst, SDL_Rect *dstrect) -{ - glSDL_TexInfo *txi; - SDL_Rect r; - int x, y; - unsigned char alpha; - int plain = (state.rot == 0.0f) && - (state.sx == 1.0f) && - (state.sy == 1.0f); - if(!src || !dst) - return -1; - - /* Get source and destination coordinates */ - if(srcrect) - r = *srcrect; - else - { - r.x = r.y = 0; - r.w = src->w; - r.h = src->h; - } - if(dstrect) - { - x = dstrect->x; - y = dstrect->y; - } - else - x = y = 0; - - /* Clip! */ - if(!blitclip(&r, src->w, src->h, &x, &y, - plain ? &dst->clip_rect : NULL)) - { - if(dstrect) - dstrect->w = dstrect->h = 0; - return 0; - } - - /* Write back the resulting cliprect */ - if(dstrect) - *dstrect = r; - - /* Make sure we have a source with a valid texture */ - glSDL_UploadSurface(src); - txi = glSDL_GetTexInfo(src); - if(!txi) - return -1; - - /* Set up blending */ - if(src->flags & (SDL_SRCALPHA | SDL_SRCCOLORKEY) || - (state.alpha != 255)) - { - gl_blendfunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl_do_blend(1); - } - else - gl_do_blend(0); - - /* Enable texturing */ - gl_do_texture(1); - - /* - * Note that we actually *prevent* the use of "full surface alpha" - * and alpha channel in combination - to stay SDL 2D compatible. - */ - if((src->flags & SDL_SRCALPHA) && - (!src->format->Amask || (src->flags & SDL_SRCCOLORKEY))) - alpha = src->format->alpha; - else - alpha = 255; - - /* ...however, the GL only global state alpha is always applied! */ - alpha = (Uint32)alpha * state.alpha * 258 >> 16; - - /* Render! */ - if(!plain) - { - int rcx = (r.w >> 1) + state.cx; - int rcy = (r.h >> 1) + state.cy; - gl.PushMatrix(); - gl.Translatef(r.x + rcx, r.y + rcy, 0.0f); - if(state.rot) - gl.Rotated(state.rot, 0.0f, 0.0f, 1.0f); - if(state.sx || state.sy) - gl.Scalef(state.sx, state.sy, 1.0f); - r.x = -rcx; - r.y = -rcy; - } - switch(txi->tilemode) - { - case GLSDL_TM_SINGLE: - BlitGL_single(txi, x, y, &r, alpha); - break; - case GLSDL_TM_HORIZONTAL: - BlitGL_htile(txi, x, y, &r, alpha); - break; - case GLSDL_TM_VERTICAL: - BlitGL_vtile(txi, x, y, &r, alpha); - break; - case GLSDL_TM_HUGE: - BlitGL_hvtile(src, txi, x, y, &r, alpha); - break; - } - if(!plain) - gl.PopMatrix(); - return 0; -} - - -int glSDL_BlitSurface(SDL_Surface *src, SDL_Rect *srcrect, - SDL_Surface *dst, SDL_Rect *dstrect) -{ - SDL_Surface *vs; - if(!src || !dst) - return -1; - - /* - * Figure out what to do: - * Not using glSDL: SDL_BlitSurface() - * screen->screen: _glSDL_BlitFromGL() + _glSDL_BlitGL() - * surface->screen: _glSDL_BlitGL() - * screen->surface: _glSDL_BlitFromGL() - * surface->surface: SDL_BlitSurface() - */ - if(!USING_GLSDL) - return SDL_BlitSurface(src, srcrect, dst, dstrect); - - vs = SDL_GetVideoSurface(); - if(src == fake_screen) - src = vs; - if(dst == fake_screen) - dst = vs; - if(src == vs) - { - if(dst == vs) - { - glSDL_BlitFromGL(srcrect, fake_screen, dstrect); - return glSDL_BlitGL(fake_screen, srcrect, - dst, dstrect); - } - else - { - return glSDL_BlitFromGL(srcrect, dst, dstrect); - } - } - else - { - if(dst == vs) - { - return glSDL_BlitGL(src, srcrect, - dst, dstrect); - } - else - { - glSDL_Invalidate(dst, dstrect); - return SDL_BlitSurface(src, srcrect, dst, dstrect); - } - } -} - - -int glSDL_FillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color) -{ - SDL_Surface *vs = SDL_GetVideoSurface(); - SDL_PixelFormat *pf = dst->format; - int dx1, dy1, dx2, dy2; - Uint32 r, g, b; - - if(dst == fake_screen) - dst = vs; - if(vs != dst) - glSDL_Invalidate(dst, dstrect); - if((vs != dst) || !USING_GLSDL) - return SDL_FillRect(dst, dstrect, color); - - if(dstrect) - { - dx1 = dstrect->x; - dy1 = dstrect->y; - dx2 = dx1 + dstrect->w; - dy2 = dy1 + dstrect->h; - if(dx1 < dst->clip_rect.x) - dx1 = dst->clip_rect.x; - if(dy1 < dst->clip_rect.y) - dy1 = dst->clip_rect.y; - if(dx2 > dst->clip_rect.x + dst->clip_rect.w) - dx2 = dst->clip_rect.x + dst->clip_rect.w; - if(dy2 > dst->clip_rect.y + dst->clip_rect.h) - dy2 = dst->clip_rect.y + dst->clip_rect.h; - dstrect->x = dx1; - dstrect->y = dy1; - dstrect->w = dx2 - dx1; - dstrect->h = dy2 - dy1; - if(!dstrect->w || !dstrect->h) - return 0; - } - else - { - dx1 = dst->clip_rect.x; - dy1 = dst->clip_rect.y; - dx2 = dx1 + dst->clip_rect.w; - dy2 = dy1 + dst->clip_rect.h; - } - - r = color & pf->Rmask; - r = r >> pf->Rshift; - r = r << pf->Rloss; - g = color & pf->Gmask; - g = g >> pf->Gshift; - g = g << pf->Gloss; - b = color & pf->Bmask; - b = b >> pf->Bshift; - b = b << pf->Bloss; - - r = r * state.r * 258 >> 16; - g = g * state.g * 258 >> 16; - b = b * state.b * 258 >> 16; - - gl_do_texture(0); - if(state.alpha != 255) - { - gl_blendfunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl_do_blend(1); - } - else - gl_do_blend(0); - - gl.Begin(GL_QUADS); - gl.Color4ub(r, g, b, state.alpha); - gl.Vertex2i(dx1, dy1); - gl.Vertex2i(dx2, dy1); - gl.Vertex2i(dx2, dy2); - gl.Vertex2i(dx1, dy2); - gl.End(); - return 0; -} - - -SDL_Surface *glSDL_DisplayFormat(SDL_Surface *surface) -{ - SDL_Surface *s, *tmp; - if(USING_GLSDL) - { - int use_rgba = (surface->flags & SDL_SRCCOLORKEY) || - ((surface->flags & SDL_SRCALPHA) && - surface->format->Amask); - if(use_rgba) - tmp = SDL_ConvertSurface(surface, &RGBAfmt, SDL_SWSURFACE); - else - tmp = SDL_ConvertSurface(surface, &RGBfmt, SDL_SWSURFACE); - if(!tmp) - return NULL; - GLSDL_FIX_SURFACE(tmp); - SDL_SetAlpha(tmp, 0, 0); - - if(surface->flags & SDL_SRCCOLORKEY) - { - /* - * We drop colorkey data here, but we have to, - * or we'll run into trouble when converting, - * in particular from indexed color formats. - */ - SDL_SetColorKey(tmp, SDL_SRCCOLORKEY, - surface->format->colorkey); - key2alpha(tmp); - } - SDL_SetColorKey(tmp, 0, 0); - - if(use_rgba) - s = CreateRGBASurface(surface->w, surface->h); - else - s = CreateRGBSurface(surface->w, surface->h); - if(!s) - { - glSDL_FreeSurface(tmp); - return NULL; - } - SDL_BlitSurface(tmp, NULL, s, NULL); - glSDL_FreeSurface(tmp); - - if(surface->flags & SDL_SRCALPHA) - SDL_SetAlpha(s, SDL_SRCALPHA, - surface->format->alpha); - return s; - } - else - { - s = SDL_DisplayFormat(surface); - if(s) - GLSDL_FIX_SURFACE(s); - return s; - } -} - - -SDL_Surface *glSDL_DisplayFormatAlpha(SDL_Surface *surface) -{ - SDL_Surface *s, *tmp; - if(USING_GLSDL) - { - tmp = SDL_ConvertSurface(surface, &RGBAfmt, SDL_SWSURFACE); - if(!tmp) - return NULL; - GLSDL_FIX_SURFACE(tmp); - - SDL_SetAlpha(tmp, 0, 0); - SDL_SetColorKey(tmp, 0, 0); - s = CreateRGBASurface(surface->w, surface->h); - if(!s) - { - glSDL_FreeSurface(tmp); - return NULL; - } - SDL_BlitSurface(tmp, NULL, s, NULL); - glSDL_FreeSurface(tmp); - - if(surface->flags & SDL_SRCCOLORKEY) - { - SDL_SetColorKey(s, SDL_SRCCOLORKEY, - surface->format->colorkey); - key2alpha(s); - } - if(surface->flags & SDL_SRCALPHA) - SDL_SetAlpha(s, SDL_SRCALPHA, - surface->format->alpha); - return s; - } - else - { - s = SDL_DisplayFormatAlpha(surface); - if(s) - GLSDL_FIX_SURFACE(s); - return s; - } -} - - -SDL_Surface *glSDL_ConvertSurface - (SDL_Surface *src, SDL_PixelFormat *fmt, Uint32 flags) -{ - SDL_Surface *s = SDL_ConvertSurface(src, fmt, flags); - if(s) - GLSDL_FIX_SURFACE(s); - return s; -} - - -SDL_Surface *glSDL_CreateRGBSurface - (Uint32 flags, int width, int height, int depth, - Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) -{ - SDL_Surface *s = SDL_CreateRGBSurface(flags, width, height, depth, - Rmask, Gmask, Bmask, Amask); - if(s) - GLSDL_FIX_SURFACE(s); - return s; -} - - -SDL_Surface *glSDL_CreateRGBSurfaceFrom(void *pixels, - int width, int height, int depth, int pitch, - Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) -{ - SDL_Surface *s = SDL_CreateRGBSurfaceFrom(pixels, - width, height, depth, pitch, - Rmask, Gmask, Bmask, Amask); - if(s) - GLSDL_FIX_SURFACE(s); - return s; -} - - -SDL_Surface *glSDL_LoadBMP(const char *file) -{ - SDL_Surface *s = SDL_LoadBMP(file); - if(s) - GLSDL_FIX_SURFACE(s); - return s; -} - - -int glSDL_SaveBMP(SDL_Surface *surface, const char *file) -{ - SDL_Rect r; - SDL_Surface *buf; - SDL_Surface *screen = SDL_GetVideoSurface(); - - if(!USING_GLSDL) - return SDL_SaveBMP(surface, file); - - if((surface != screen) && (surface != fake_screen)) - return SDL_SaveBMP(surface, file); - - buf = CreateRGBSurface(fake_screen->w, fake_screen->h); - - r.x = 0; - r.y = 0; - r.w = fake_screen->w; - r.h = fake_screen->h; - if(glSDL_BlitFromGL(&r, buf, &r) < 0) - return -1; - - return SDL_SaveBMP(buf, file); - - glSDL_FreeSurface(buf); -} - - - - -static int InitTexture(SDL_Surface *datasurf, glSDL_TexInfo *txi, int tex) -{ - gl.GenTextures(1, (unsigned int *)&txi->texture[tex]); - gl.BindTexture(GL_TEXTURE_2D, txi->texture[tex]); - gl.PixelStorei(GL_UNPACK_ROW_LENGTH, datasurf->pitch / - datasurf->format->BytesPerPixel); - gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - gl.TexImage2D(GL_TEXTURE_2D, 0, - datasurf->format->Amask ? GL_RGBA8 : GL_RGB8, - txi->texsize, txi->texsize, 0, - datasurf->format->Amask ? GL_RGBA : GL_RGB, - GL_UNSIGNED_BYTE, NULL); - print_glerror(1); - return 0; -} - - -/* Image tiled horizontally (wide surface), or not at all */ -static int UploadHoriz(SDL_Surface *datasurf, glSDL_TexInfo *txi) -{ - int bpp = datasurf->format->BytesPerPixel; - int res; - int tex = 0; - int fromx = 0; - int toy = txi->texsize; /* To init first texture */ - while(1) - { - int thistw = datasurf->w - fromx; - if(thistw > txi->tilew) - thistw = txi->tilew; - else if(thistw <= 0) - break; - if(toy + txi->tileh > txi->texsize) - { - toy = 0; - res = InitTexture(datasurf, txi, tex); - if(res < 0) - return res; - ++tex; - } - gl.TexSubImage2D(GL_TEXTURE_2D, 0, 0, toy, - thistw, txi->tileh, - datasurf->format->Amask ? GL_RGBA : GL_RGB, - GL_UNSIGNED_BYTE, - (char *)datasurf->pixels + bpp * fromx); - print_glerror(2); - fromx += txi->tilew; - toy += txi->tileh; - gl.Flush(); - } - return 0; -} - - -/* Image tiled vertically (tall surface) */ -static int UploadVert(SDL_Surface *datasurf, glSDL_TexInfo *txi) -{ - int res; - int tex = 0; - int fromy = 0; - int tox = txi->texsize; /* To init first texture */ - while(1) - { - int thisth = datasurf->h - fromy; - if(thisth > txi->tileh) - thisth = txi->tileh; - else if(thisth <= 0) - break; - if(tox + txi->tilew > txi->texsize) - { - tox = 0; - res = InitTexture(datasurf, txi, tex); - if(res < 0) - return res; - ++tex; - } - gl.TexSubImage2D(GL_TEXTURE_2D, 0, tox, 0, - txi->tilew, thisth, - datasurf->format->Amask ? GL_RGBA : GL_RGB, - GL_UNSIGNED_BYTE, - (char *)datasurf->pixels + datasurf->pitch * fromy); - print_glerror(3); - fromy += txi->tileh; - tox += txi->tilew; - gl.Flush(); - } - return 0; -} - - -/* Image tiled two-way (huge surface) */ -static int UploadHuge(SDL_Surface *datasurf, glSDL_TexInfo *txi) -{ - int bpp = datasurf->format->BytesPerPixel; - int res; - int tex = 0; - int y = 0; - while(y < datasurf->h) - { - int x; - int thisth = datasurf->h - y; - if(thisth > txi->tileh) - thisth = txi->tileh; - x = 0; - while(x < datasurf->w) - { - int thistw = datasurf->w - x; - if(thistw > txi->tilew) - thistw = txi->tilew; - res = InitTexture(datasurf, txi, tex++); - if(res < 0) - return res; - gl.TexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, - thistw, thisth, - datasurf->format->Amask ? GL_RGBA : GL_RGB, - GL_UNSIGNED_BYTE, - (char *)datasurf->pixels + - datasurf->pitch * y + bpp * x); - print_glerror(4); - x += txi->tilew; - gl.Flush(); - } - y += txi->tileh; - } - return 0; -} - - -/* Upload all textures for a surface. */ -static int UploadTextures(SDL_Surface *datasurf, glSDL_TexInfo *txi) -{ - switch(txi->tilemode) - { - case GLSDL_TM_SINGLE: - case GLSDL_TM_HORIZONTAL: - UploadHoriz(datasurf, txi); - break; - case GLSDL_TM_VERTICAL: - UploadVert(datasurf, txi); - break; - case GLSDL_TM_HUGE: - UploadHuge(datasurf, txi); - break; - } - return 0; -} - - -SDL_Surface *glSDL_IMG_Load(const char *file) -{ - SDL_Surface *s; - s = IMG_Load(file); - if(s) - GLSDL_FIX_SURFACE(s); - return s; -} - - -/*---------------------------------------------------------- - glSDL specific API extensions -----------------------------------------------------------*/ - -int glSDL_VSync(int use) -{ - int old = vsync; - if(use >= 0) - vsync = use; - return old; -} - - -void glSDL_Invalidate(SDL_Surface *surface, SDL_Rect *area) -{ - glSDL_TexInfo *txi; - if(!surface) - return; - txi = glSDL_GetTexInfo(surface); - if(!txi) - return; - if(!area) - { - txi->invalid_area.x = 0; - txi->invalid_area.y = 0; - txi->invalid_area.w = surface->w; - txi->invalid_area.h = surface->h; - return; - } - txi->invalid_area = *area; -} - - -int glSDL_UploadSurface(SDL_Surface *surface) -{ - SDL_Surface *datasurf = surface; - glSDL_TexInfo *txi; - int i; - /* - * For now, we just assume that *every* texture needs - * conversion before uploading. - */ - - /* If there's no TexInfo, add one. */ - if(!IS_GLSDL_SURFACE(surface)) - glSDL_AddTexInfo(surface); - - txi = glSDL_GetTexInfo(surface); - if(!txi) - return -1; - - /* No partial updates implemented yet... */ - if(txi->invalid_area.w) - glSDL_UnloadSurface(surface); - else - { - int missing = 0; - if(txi->textures) - { - for(i = 0; i < txi->textures; ++i) - if(-1 == txi->texture[i]) - { - missing = 1; - break; - } - if(!missing) - return 0; /* They're already there! */ - } - } - - if(txi->texsize > maxtexsize) - { - fprintf(stderr, "glSDL/wrapper: INTERNAL ERROR: Too large texture!\n"); - return -1; /* This surface wasn't tiled properly... */ - } - - /* - * Kludge: Convert if not of preferred RGB or RGBA format. - * - * Conversion should only be done when *really* needed. - * That is, it should rarely have to be done with OpenGL - * 1.2+. - * - * Besides, any surface that's been SDL_DisplayFormat()ed - * should already be in the best known OpenGL format - - * preferably one that makes DMA w/o conversion possible. - */ - if(FormatIsOk(surface)) - datasurf = surface; - else - { - DBG(fprintf(stderr, "glSDL/wrapper: WARNING: On-the-fly conversion performed!\n")); - if(surface->format->Amask) - datasurf = glSDL_DisplayFormatAlpha(surface); - else - datasurf = glSDL_DisplayFormat(surface); - if(!datasurf) - return -2; - } - - if(UploadTextures(datasurf, txi) < 0) - return -3; - - if(datasurf != surface) - glSDL_FreeSurface(datasurf); - return 0; -} - - -static void UnloadTexture(glSDL_TexInfo *txi) -{ - int i; - if(SDL_WasInit(SDL_INIT_VIDEO)) - for(i = 0; i < txi->textures; ++i) - gl.DeleteTextures(1, (unsigned int *)&txi->texture[i]); - memset(&txi->invalid_area, 0, sizeof(txi->invalid_area)); -} - - -void glSDL_UnloadSurface(SDL_Surface *surface) -{ - glSDL_TexInfo *txi; - if(!IS_GLSDL_SURFACE(surface)) - return; - - txi = glSDL_GetTexInfo(surface); - if(txi) - UnloadTexture(txi); -} - - -#else /* HAVE_OPENGL */ - -/*---------------------------------------------------------- - Dummies for glSDL extensions that require OpenGL -----------------------------------------------------------*/ - -void glSDL_Invalidate(SDL_Surface *surface, SDL_Rect *area) -{ -} - -int glSDL_UploadSurface(SDL_Surface *surface) -{ - return 0; -} - -void glSDL_UnloadSurface(SDL_Surface *surface) -{ -} - -int glSDL_VSync(int use) -{ - return 0; -} - -void glSDL_SetBlendAlpha(Uint8 alpha) -{ -} - -void glSDL_SetBlendColor(Uint8 r, Uint8 g, Uint8 b) -{ -} - -void glSDL_SetCenter(float x, float y) -{ -} - -void glSDL_SetRotation(float angle) -{ -} - -void glSDL_SetScale(float x, float y) -{ -} - -void glSDL_ResetState(void) -{ -} - -#endif /* HAVE_OPENGL */ diff --git a/graphics/glSDL.h b/graphics/glSDL.h deleted file mode 100644 index f0bbf4a..0000000 --- a/graphics/glSDL.h +++ /dev/null @@ -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 - -/* - * 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_ */ diff --git a/graphics/region.h b/graphics/region.h index cb88e62..806f8c4 100644 --- a/graphics/region.h +++ b/graphics/region.h @@ -22,7 +22,7 @@ #ifndef KOBO_REGION_H #define KOBO_REGION_H -#include "glSDL.h" +#include "sdl_compat.h" #ifdef __cplusplus extern "C" { diff --git a/graphics/sdl_compat.h b/graphics/sdl_compat.h new file mode 100644 index 0000000..9c74f44 --- /dev/null +++ b/graphics/sdl_compat.h @@ -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 across the tree (which would also + * make a later SDL 4 swap painful). + */ +#ifndef _KOBO_SDL_COMPAT_H_ +#define _KOBO_SDL_COMPAT_H_ + +#include + +#endif /* _KOBO_SDL_COMPAT_H_ */ diff --git a/graphics/sofont.h b/graphics/sofont.h index 4cf62e1..fa6e0aa 100644 --- a/graphics/sofont.h +++ b/graphics/sofont.h @@ -34,7 +34,7 @@ * Cursor tests first check if '|' is present. * Shadowed variables fixed. * Garbage data in spacing table fixed. (Thanks to - Andreas Spångberg for discovering this one!) + Andreas Sp�ngberg for discovering this one!) * Added ExtraSpace(). (Scaling support hack...) * Disabled colorkeying. (Ruins some RGBA fonts!) */ @@ -42,7 +42,7 @@ #ifndef __SOFONT_H #define __SOFONT_H -#include "glSDL.h" +#include "sdl_compat.h" class SoFont { diff --git a/graphics/sprite.c b/graphics/sprite.c index b1b9eb9..31c6ee1 100644 --- a/graphics/sprite.c +++ b/graphics/sprite.c @@ -29,7 +29,7 @@ TODO: tables as needed when loading banks. #include #include #include "logger.h" -#include "glSDL.h" +#include "sdl_compat.h" #include #include "sprite.h" #include "filters.h" diff --git a/graphics/sprite.h b/graphics/sprite.h index 6897cdc..4f3a664 100644 --- a/graphics/sprite.h +++ b/graphics/sprite.h @@ -26,7 +26,7 @@ extern "C" { #endif -#include "glSDL.h" +#include "sdl_compat.h" typedef enum { diff --git a/graphics/window.cpp b/graphics/window.cpp index 6198c39..29c4332 100644 --- a/graphics/window.cpp +++ b/graphics/window.cpp @@ -186,13 +186,9 @@ void window_t::invalidate(SDL_Rect *r) rr.w = phys_rect.w; rr.h = phys_rect.h; phys_refresh(&rr); - glSDL_Invalidate(surface, &rr); } else - { phys_refresh(r); - glSDL_Invalidate(surface, r); - } return; } diff --git a/graphics/window.h b/graphics/window.h index 702ec1d..fcf5143 100644 --- a/graphics/window.h +++ b/graphics/window.h @@ -213,7 +213,7 @@ #ifndef _WINDOW_H_ #define _WINDOW_H_ -#include "glSDL.h" +#include "sdl_compat.h" class gfxengine_t; diff --git a/logger.c b/logger.c index f315c2b..5420c27 100644 --- a/logger.c +++ b/logger.c @@ -25,7 +25,7 @@ #include "config.h" #include "logger.h" -#include "glSDL.h" +#include "sdl_compat.h" #define LOG_BUFFER 1024 diff --git a/manage.h b/manage.h index 24cd294..6f90932 100644 --- a/manage.h +++ b/manage.h @@ -24,7 +24,7 @@ #ifndef _KOBO_MANAGE_H_ #define _KOBO_MANAGE_H_ -#include "glSDL.h" +#include "sdl_compat.h" #include "score.h" class _manage diff --git a/options.cpp b/options.cpp index 2161c6c..97b5ac5 100644 --- a/options.cpp +++ b/options.cpp @@ -184,14 +184,7 @@ void video_options_t::build() 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) diff --git a/prefs.cpp b/prefs.cpp index b87bad7..99136d1 100644 --- a/prefs.cpp +++ b/prefs.cpp @@ -171,7 +171,8 @@ void prefs_t::postload() scrollradar = 2; } - // Some unimplemented enums were removed in 0.4.1 + // Only the SDL 2D driver remains since the SDL 3 migration; collapse + // any legacy GLSDL setting onto it. if(videodriver != GFX_DRIVER_SDL2D) - videodriver = GFX_DRIVER_GLSDL; + videodriver = GFX_DRIVER_SDL2D; } diff --git a/random.h b/random.h index 97c69c7..d1756ee 100644 --- a/random.h +++ b/random.h @@ -24,7 +24,7 @@ #define _KOBO_RANDOM_H_ #include -#include "glSDL.h" +#include "sdl_compat.h" class rand_num_t { diff --git a/sound/a_tools.h b/sound/a_tools.h index f37466e..43f314f 100644 --- a/sound/a_tools.h +++ b/sound/a_tools.h @@ -22,7 +22,7 @@ #ifndef _A_TOOLS_H_ #define _A_TOOLS_H_ -#include "glSDL.h" +#include "sdl_compat.h" #include #include "kobolog.h" #include "a_types.h" diff --git a/sound/a_types.h b/sound/a_types.h index 5b18e08..ec519c3 100644 --- a/sound/a_types.h +++ b/sound/a_types.h @@ -22,7 +22,7 @@ #ifndef _A_TYPES_H_ #define _A_TYPES_H_ -#include "glSDL.h" +#include "sdl_compat.h" /* Builtin patch drivers */ typedef enum diff --git a/states.cpp b/states.cpp index 6c1c3a9..efe78cf 100644 --- a/states.cpp +++ b/states.cpp @@ -21,7 +21,7 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "glSDL.h" +#include "sdl_compat.h" #include #ifndef M_PI # define M_PI 3.14159265358979323846 /* pi */