comparison src/video/glsdl/SDL_glsdl.c @ 1662:782fd950bd46 SDL-1.3

Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API. WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid. The code is now run through a consistent indent format: indent -i4 -nut -nsc -br -ce The headers are being converted to automatically generate doxygen documentation.
author Sam Lantinga <slouken@libsdl.org>
date Sun, 28 May 2006 13:04:16 +0000
parents e49147870aac
children 4da1ee79c9af
comparison
equal deleted inserted replaced
1661:281d3f4870e5 1662:782fd950bd46
43 #undef GLSDL_GRAPHICAL_DEBUG 43 #undef GLSDL_GRAPHICAL_DEBUG
44 44
45 /* Initialization/Query functions */ 45 /* Initialization/Query functions */
46 46
47 /* Hardware surface functions */ 47 /* Hardware surface functions */
48 static int glSDL_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); 48 static int glSDL_SetColors (_THIS, int firstcolor, int ncolors,
49 static int glSDL_AllocHWSurface(_THIS, SDL_Surface *surface); 49 SDL_Color * colors);
50 static int glSDL_LockHWSurface(_THIS, SDL_Surface *surface); 50 static int glSDL_AllocHWSurface (_THIS, SDL_Surface * surface);
51 static int glSDL_FlipHWSurface(_THIS, SDL_Surface *surface); 51 static int glSDL_LockHWSurface (_THIS, SDL_Surface * surface);
52 static void glSDL_UnlockHWSurface(_THIS, SDL_Surface *surface); 52 static int glSDL_FlipHWSurface (_THIS, SDL_Surface * surface);
53 static void glSDL_FreeHWSurface(_THIS, SDL_Surface *surface); 53 static void glSDL_UnlockHWSurface (_THIS, SDL_Surface * surface);
54 static int glSDL_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color); 54 static void glSDL_FreeHWSurface (_THIS, SDL_Surface * surface);
55 static int glSDL_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst); 55 static int glSDL_FillHWRect (_THIS, SDL_Surface * dst, SDL_Rect * rect,
56 static int glSDL_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key); 56 Uint32 color);
57 static int glSDL_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha); 57 static int glSDL_CheckHWBlit (_THIS, SDL_Surface * src, SDL_Surface * dst);
58 static int glSDL_VideoInit(_THIS, SDL_PixelFormat *vformat); 58 static int glSDL_SetHWColorKey (_THIS, SDL_Surface * surface, Uint32 key);
59 static SDL_Rect **glSDL_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); 59 static int glSDL_SetHWAlpha (_THIS, SDL_Surface * surface, Uint8 alpha);
60 static void glSDL_VideoQuit(_THIS); 60 static int glSDL_VideoInit (_THIS, SDL_PixelFormat * vformat);
61 static void glSDL_UpdateRects(_THIS, int numrects, SDL_Rect *rects); 61 static SDL_Rect **glSDL_ListModes (_THIS, SDL_PixelFormat * format,
62 static SDL_Surface* glSDL_SetVideoMode(_THIS, SDL_Surface *current,int width, int height, int bpp, Uint32 flags); 62 Uint32 flags);
63 static void glSDL_VideoQuit (_THIS);
64 static void glSDL_UpdateRects (_THIS, int numrects, SDL_Rect * rects);
65 static SDL_Surface *glSDL_SetVideoMode (_THIS, SDL_Surface * current,
66 int width, int height, int bpp,
67 Uint32 flags);
63 68
64 #define IS_GLSDL_SURFACE(s) ((s) && glSDL_GetTexInfo(s)) 69 #define IS_GLSDL_SURFACE(s) ((s) && glSDL_GetTexInfo(s))
65 70
66 #define LOGIC_W(s) ( IS_GLSDL_SURFACE(this,s) ? TEXINFO(s)->lw : (s)->w ) 71 #define LOGIC_W(s) ( IS_GLSDL_SURFACE(this,s) ? TEXINFO(s)->lw : (s)->w )
67 #define LOGIC_H(s) ( IS_GLSDL_SURFACE(this,s) ? TEXINFO(s)->lh : (s)->h ) 72 #define LOGIC_H(s) ( IS_GLSDL_SURFACE(this,s) ? TEXINFO(s)->lh : (s)->h )
71 /* 76 /*
72 * Special version for glSDL, which ignores the fake SDL_HWSURFACE 77 * Special version for glSDL, which ignores the fake SDL_HWSURFACE
73 * flags, so we don't have SDL calling us back whenever we want to 78 * flags, so we don't have SDL calling us back whenever we want to
74 * do some internal blitting... 79 * do some internal blitting...
75 */ 80 */
76 static void glSDL_SoftBlit(SDL_Surface *src, SDL_Rect *srcrect, 81 static void
77 SDL_Surface *dst, SDL_Rect *dstrect) 82 glSDL_SoftBlit (SDL_Surface * src, SDL_Rect * srcrect,
78 { 83 SDL_Surface * dst, SDL_Rect * dstrect)
79 SDL_BlitInfo info; 84 {
80 85 SDL_BlitInfo info;
81 if(srcrect) 86
82 if(!srcrect->w || !srcrect->h) 87 if (srcrect)
83 return; 88 if (!srcrect->w || !srcrect->h)
84 89 return;
85 /* Check to make sure the blit mapping is valid */ 90
86 if ( (src->map->dst != dst) || 91 /* Check to make sure the blit mapping is valid */
87 (src->map->dst->format_version != 92 if ((src->map->dst != dst) ||
88 src->map->format_version) ) 93 (src->map->dst->format_version != src->map->format_version))
89 if ( SDL_MapSurface(src, dst) < 0 ) 94 if (SDL_MapSurface (src, dst) < 0)
90 return; 95 return;
91 96
92 /* Set up the blit information */ 97 /* Set up the blit information */
93 if(srcrect) 98 if (srcrect) {
94 { 99 info.s_pixels = (Uint8 *) src->pixels +
95 info.s_pixels = (Uint8 *) src->pixels + 100 (Uint16) srcrect->y * src->pitch +
96 (Uint16) srcrect->y * src->pitch + 101 (Uint16) srcrect->x * src->format->BytesPerPixel;
97 (Uint16) srcrect->x * src->format->BytesPerPixel; 102 info.s_width = srcrect->w;
98 info.s_width = srcrect->w; 103 info.s_height = srcrect->h;
99 info.s_height = srcrect->h; 104 } else {
100 } 105 info.s_pixels = (Uint8 *) src->pixels;
101 else 106 info.s_width = src->w;
102 { 107 info.s_height = src->h;
103 info.s_pixels = (Uint8 *) src->pixels; 108 }
104 info.s_width = src->w; 109 info.s_skip = src->pitch - info.s_width * src->format->BytesPerPixel;
105 info.s_height = src->h; 110 if (dstrect) {
106 } 111 info.d_pixels = (Uint8 *) dst->pixels +
107 info.s_skip = src->pitch - info.s_width * src->format->BytesPerPixel; 112 (Uint16) dstrect->y * dst->pitch +
108 if(dstrect) 113 (Uint16) dstrect->x * dst->format->BytesPerPixel;
109 { 114 /*
110 info.d_pixels = (Uint8 *) dst->pixels + 115 * NOTE: SDL_SoftBlit() uses the 'dstrect' for this!
111 (Uint16) dstrect->y * dst->pitch + 116 * This version is more like SDL_BlitSurface().
112 (Uint16) dstrect->x * dst->format->BytesPerPixel; 117 */
113 /* 118 info.d_width = srcrect->w;
114 * NOTE: SDL_SoftBlit() uses the 'dstrect' for this! 119 info.d_height = srcrect->h;
115 * This version is more like SDL_BlitSurface(). 120 } else {
116 */ 121 info.d_pixels = (Uint8 *) dst->pixels;
117 info.d_width = srcrect->w; 122 info.d_width = dst->w;
118 info.d_height = srcrect->h; 123 info.d_height = dst->h;
119 } 124 }
120 else 125 info.d_skip = dst->pitch - info.d_width * dst->format->BytesPerPixel;
121 { 126 info.aux_data = src->map->sw_data->aux_data;
122 info.d_pixels = (Uint8 *) dst->pixels; 127 info.src = src->format;
123 info.d_width = dst->w; 128 info.table = src->map->table;
124 info.d_height = dst->h; 129 info.dst = dst->format;
125 } 130
126 info.d_skip = dst->pitch - info.d_width * dst->format->BytesPerPixel; 131 src->map->sw_data->blit (&info);
127 info.aux_data = src->map->sw_data->aux_data;
128 info.src = src->format;
129 info.table = src->map->table;
130 info.dst = dst->format;
131
132 src->map->sw_data->blit(&info);
133 } 132 }
134 133
135 134
136 /* 135 /*
137 * Another special version. Doesn't lock/unlock, and doesn't mess 136 * Another special version. Doesn't lock/unlock, and doesn't mess
138 * with flags and stuff. It just converts the surface, period. 137 * with flags and stuff. It just converts the surface, period.
139 * Does not convert into palletized formats. 138 * Does not convert into palletized formats.
140 */ 139 */
141 static SDL_Surface *glSDL_ConvertSurface (SDL_Surface *surface, 140 static SDL_Surface *
142 SDL_PixelFormat *format, Uint32 flags) 141 glSDL_ConvertSurface (SDL_Surface * surface,
143 { 142 SDL_PixelFormat * format, Uint32 flags)
144 SDL_Surface *convert; 143 {
145 Uint32 colorkey = 0; 144 SDL_Surface *convert;
146 Uint8 alpha = 0; 145 Uint32 colorkey = 0;
147 Uint32 surface_flags; 146 Uint8 alpha = 0;
148 SDL_Rect bounds; 147 Uint32 surface_flags;
149 148 SDL_Rect bounds;
150 /* Create a new surface with the desired format */ 149
151 convert = SDL_CreateRGBSurface(flags, 150 /* Create a new surface with the desired format */
152 surface->w, surface->h, format->BitsPerPixel, 151 convert = SDL_CreateRGBSurface (flags,
153 format->Rmask, format->Gmask, format->Bmask, format->Amask); 152 surface->w, surface->h,
154 if ( convert == NULL ) { 153 format->BitsPerPixel, format->Rmask,
155 return(NULL); 154 format->Gmask, format->Bmask,
156 } 155 format->Amask);
157 156 if (convert == NULL) {
158 /* Save the original surface color key and alpha */ 157 return (NULL);
159 surface_flags = surface->flags; 158 }
160 if ( (surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { 159
161 /* Convert colourkeyed surfaces to RGBA if requested */ 160 /* Save the original surface color key and alpha */
162 if((flags & SDL_SRCCOLORKEY) != SDL_SRCCOLORKEY 161 surface_flags = surface->flags;
163 && format->Amask) { 162 if ((surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
164 surface_flags &= ~SDL_SRCCOLORKEY; 163 /* Convert colourkeyed surfaces to RGBA if requested */
165 } else { 164 if ((flags & SDL_SRCCOLORKEY) != SDL_SRCCOLORKEY && format->Amask) {
166 colorkey = surface->format->colorkey; 165 surface_flags &= ~SDL_SRCCOLORKEY;
167 SDL_SetColorKey(surface, 0, 0); 166 } else {
168 } 167 colorkey = surface->format->colorkey;
169 } 168 SDL_SetColorKey (surface, 0, 0);
170 if ( (surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { 169 }
171 /* Copy over the alpha channel to RGBA if requested */ 170 }
172 if ( format->Amask ) { 171 if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
173 surface->flags &= ~SDL_SRCALPHA; 172 /* Copy over the alpha channel to RGBA if requested */
174 } else { 173 if (format->Amask) {
175 alpha = surface->format->alpha; 174 surface->flags &= ~SDL_SRCALPHA;
176 SDL_SetAlpha(surface, 0, 0); 175 } else {
177 } 176 alpha = surface->format->alpha;
178 } 177 SDL_SetAlpha (surface, 0, 0);
179 178 }
180 /* Copy over the image data */ 179 }
181 bounds.x = 0; 180
182 bounds.y = 0; 181 /* Copy over the image data */
183 bounds.w = surface->w; 182 bounds.x = 0;
184 bounds.h = surface->h; 183 bounds.y = 0;
185 glSDL_SoftBlit(surface, &bounds, convert, &bounds); 184 bounds.w = surface->w;
186 185 bounds.h = surface->h;
187 /* Clean up the original surface, and update converted surface */ 186 glSDL_SoftBlit (surface, &bounds, convert, &bounds);
188 if ( convert != NULL ) { 187
189 SDL_SetClipRect(convert, &surface->clip_rect); 188 /* Clean up the original surface, and update converted surface */
190 } 189 if (convert != NULL) {
191 if ( (surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { 190 SDL_SetClipRect (convert, &surface->clip_rect);
192 Uint32 cflags = surface_flags&(SDL_SRCCOLORKEY|SDL_RLEACCELOK); 191 }
193 if ( convert != NULL ) { 192 if ((surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) {
194 Uint8 keyR, keyG, keyB; 193 Uint32 cflags = surface_flags & (SDL_SRCCOLORKEY | SDL_RLEACCELOK);
195 194 if (convert != NULL) {
196 SDL_GetRGB(colorkey,surface->format,&keyR,&keyG,&keyB); 195 Uint8 keyR, keyG, keyB;
197 SDL_SetColorKey(convert, cflags|(flags&SDL_RLEACCELOK), 196
198 SDL_MapRGB(convert->format, keyR, keyG, keyB)); 197 SDL_GetRGB (colorkey, surface->format, &keyR, &keyG, &keyB);
199 } 198 SDL_SetColorKey (convert, cflags | (flags & SDL_RLEACCELOK),
200 SDL_SetColorKey(surface, cflags, colorkey); 199 SDL_MapRGB (convert->format, keyR, keyG, keyB));
201 } 200 }
202 if ( (surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { 201 SDL_SetColorKey (surface, cflags, colorkey);
203 Uint32 aflags = surface_flags&(SDL_SRCALPHA|SDL_RLEACCELOK); 202 }
204 if ( convert != NULL ) { 203 if ((surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA) {
205 SDL_SetAlpha(convert, aflags|(flags&SDL_RLEACCELOK), 204 Uint32 aflags = surface_flags & (SDL_SRCALPHA | SDL_RLEACCELOK);
206 alpha); 205 if (convert != NULL) {
207 } 206 SDL_SetAlpha (convert, aflags | (flags & SDL_RLEACCELOK), alpha);
208 if ( format->Amask ) { 207 }
209 surface->flags |= SDL_SRCALPHA; 208 if (format->Amask) {
210 } else { 209 surface->flags |= SDL_SRCALPHA;
211 SDL_SetAlpha(surface, aflags, alpha); 210 } else {
212 } 211 SDL_SetAlpha (surface, aflags, alpha);
213 } 212 }
214 213 }
215 /* We're ready to go! */ 214
216 return(convert); 215 /* We're ready to go! */
216 return (convert);
217 } 217 }
218 218
219 219
220 /*---------------------------------------------------------- 220 /*----------------------------------------------------------
221 Some OpenGL function wrappers 221 Some OpenGL function wrappers
222 ----------------------------------------------------------*/ 222 ----------------------------------------------------------*/
223 223
224 static struct 224 static struct
225 { 225 {
226 int do_blend; 226 int do_blend;
227 int do_texture; 227 int do_texture;
228 GLuint texture; 228 GLuint texture;
229 GLenum sfactor, dfactor; 229 GLenum sfactor, dfactor;
230 } glstate; 230 } glstate;
231 231
232 static void glSDL_reset(void) 232 static void
233 { 233 glSDL_reset (void)
234 glstate.do_blend = -1; 234 {
235 glstate.do_blend = -1; 235 glstate.do_blend = -1;
236 glstate.texture = GLSDL_NOTEX; 236 glstate.do_blend = -1;
237 glstate.sfactor = 0xffffffff; 237 glstate.texture = GLSDL_NOTEX;
238 glstate.dfactor = 0xffffffff; 238 glstate.sfactor = 0xffffffff;
239 } 239 glstate.dfactor = 0xffffffff;
240 240 }
241 static __inline__ void glSDL_do_blend(_THIS, int on) 241
242 { 242 static __inline__ void
243 if(glstate.do_blend == on) 243 glSDL_do_blend (_THIS, int on)
244 return; 244 {
245 245 if (glstate.do_blend == on)
246 if(on) 246 return;
247 this->glEnable(GL_BLEND); 247
248 else 248 if (on)
249 this->glDisable(GL_BLEND); 249 this->glEnable (GL_BLEND);
250 glstate.do_blend = on; 250 else
251 } 251 this->glDisable (GL_BLEND);
252 252 glstate.do_blend = on;
253 static __inline__ void glSDL_do_texture(_THIS, int on) 253 }
254 { 254
255 if(glstate.do_texture == on) 255 static __inline__ void
256 return; 256 glSDL_do_texture (_THIS, int on)
257 257 {
258 if(on) 258 if (glstate.do_texture == on)
259 this->glEnable(GL_TEXTURE_2D); 259 return;
260 else 260
261 this->glDisable(GL_TEXTURE_2D); 261 if (on)
262 glstate.do_texture = on; 262 this->glEnable (GL_TEXTURE_2D);
263 } 263 else
264 264 this->glDisable (GL_TEXTURE_2D);
265 static __inline__ void glSDL_blendfunc(_THIS, GLenum sfactor, GLenum dfactor) 265 glstate.do_texture = on;
266 { 266 }
267 if((sfactor == glstate.sfactor) && (dfactor == glstate.dfactor)) 267
268 return; 268 static __inline__ void
269 269 glSDL_blendfunc (_THIS, GLenum sfactor, GLenum dfactor)
270 this->glBlendFunc(sfactor, dfactor); 270 {
271 271 if ((sfactor == glstate.sfactor) && (dfactor == glstate.dfactor))
272 glstate.sfactor = sfactor; 272 return;
273 glstate.dfactor = dfactor; 273
274 } 274 this->glBlendFunc (sfactor, dfactor);
275 275
276 static __inline__ void glSDL_texture(_THIS, GLuint tx) 276 glstate.sfactor = sfactor;
277 { 277 glstate.dfactor = dfactor;
278 if(tx == glstate.texture) 278 }
279 return; 279
280 280 static __inline__ void
281 this->glBindTexture(GL_TEXTURE_2D, tx); 281 glSDL_texture (_THIS, GLuint tx)
282 glstate.texture = tx; 282 {
283 if (tx == glstate.texture)
284 return;
285
286 this->glBindTexture (GL_TEXTURE_2D, tx);
287 glstate.texture = tx;
283 } 288 }
284 289
285 290
286 291
287 292
289 glSDL specific data types 294 glSDL specific data types
290 ----------------------------------------------------------*/ 295 ----------------------------------------------------------*/
291 296
292 typedef enum 297 typedef enum
293 { 298 {
294 GLSDL_TM_SINGLE, 299 GLSDL_TM_SINGLE,
295 GLSDL_TM_HORIZONTAL, 300 GLSDL_TM_HORIZONTAL,
296 GLSDL_TM_VERTICAL, 301 GLSDL_TM_VERTICAL,
297 GLSDL_TM_HUGE 302 GLSDL_TM_HUGE
298 } GLSDL_TileModes; 303 } GLSDL_TileModes;
299 304
300 305
301 typedef struct private_hwdata 306 typedef struct private_hwdata
302 { 307 {
303 /* Size of surface in logic screen pixels */ 308 /* Size of surface in logic screen pixels */
304 int lw, lh; 309 int lw, lh;
305 310
306 int textures; 311 int textures;
307 GLuint *texture; 312 GLuint *texture;
308 int texsize; /* width/height of OpenGL texture */ 313 int texsize; /* width/height of OpenGL texture */
309 GLSDL_TileModes tilemode; 314 GLSDL_TileModes tilemode;
310 int tilew, tileh; /* At least one must equal texsize! */ 315 int tilew, tileh; /* At least one must equal texsize! */
311 int tilespertex; 316 int tilespertex;
312 SDL_Rect virt; /* Total size of assembled surface */ 317 SDL_Rect virt; /* Total size of assembled surface */
313 318
314 /* Area of surface to upload when/after unlocking */ 319 /* Area of surface to upload when/after unlocking */
315 SDL_Rect invalid_area; 320 SDL_Rect invalid_area;
316 321
317 int temporary; /* Throw away after one use. */ 322 int temporary; /* Throw away after one use. */
318 323
319 SDL_Surface* next; /* The next Surface in our linked list of hardware surfaces ; == NULL if first surface */ 324 SDL_Surface *next; /* The next Surface in our linked list of hardware surfaces ; == NULL if first surface */
320 SDL_Surface* prev; /* The prev Surface in our linked list of hardware surfaces ; == NULL if last surface */ 325 SDL_Surface *prev; /* The prev Surface in our linked list of hardware surfaces ; == NULL if last surface */
321 } private_hwdata; 326 } private_hwdata;
322 327
323 /* some function prototypes */ 328 /* some function prototypes */
324 static void glSDL_Invalidate(SDL_Surface *surface, SDL_Rect *area); 329 static void glSDL_Invalidate (SDL_Surface * surface, SDL_Rect * area);
325 static void glSDL_SetLogicSize(_THIS, SDL_Surface *surface, int w, int h); 330 static void glSDL_SetLogicSize (_THIS, SDL_Surface * surface, int w, int h);
326 static private_hwdata *glSDL_UploadSurface(_THIS, SDL_Surface *surface); 331 static private_hwdata *glSDL_UploadSurface (_THIS, SDL_Surface * surface);
327 static private_hwdata *glSDL_GetTexInfo(SDL_Surface *surface); 332 static private_hwdata *glSDL_GetTexInfo (SDL_Surface * surface);
328 static void glSDL_init_formats(_THIS); 333 static void glSDL_init_formats (_THIS);
329 static private_hwdata *glSDL_AddTexInfo(_THIS, SDL_Surface *surface); 334 static private_hwdata *glSDL_AddTexInfo (_THIS, SDL_Surface * surface);
330 static void glSDL_RemoveTexInfo(_THIS, SDL_Surface *surface); 335 static void glSDL_RemoveTexInfo (_THIS, SDL_Surface * surface);
331 static void glSDL_UnloadTexture(_THIS, private_hwdata *txi); 336 static void glSDL_UnloadTexture (_THIS, private_hwdata * txi);
332 static int glSDL_BlitGL(_THIS, SDL_Surface *src, 337 static int glSDL_BlitGL (_THIS, SDL_Surface * src,
333 SDL_Rect *srcrect, SDL_Rect *dstrect); 338 SDL_Rect * srcrect, SDL_Rect * dstrect);
334 339
335 /* some variables */ 340 /* some variables */
336 static GLint maxtexsize = -1; 341 static GLint maxtexsize = -1;
337 static SDL_PixelFormat *RGBfmt = NULL; 342 static SDL_PixelFormat *RGBfmt = NULL;
338 static SDL_PixelFormat *RGBAfmt = NULL; 343 static SDL_PixelFormat *RGBAfmt = NULL;
339 static void *mirrorbuf = NULL; 344 static void *mirrorbuf = NULL;
340 /* the raw 888 opengl surface, hidden from the application */ 345 /* the raw 888 opengl surface, hidden from the application */
341 SDL_Surface* OpenGL_Surface; 346 SDL_Surface *OpenGL_Surface;
342 347
343 /* pointer to the beggining of the list used for memory allocation */ 348 /* pointer to the beggining of the list used for memory allocation */
344 SDL_Surface* first = NULL; 349 SDL_Surface *first = NULL;
345 350
346 #ifdef DEBUG_GLSDL 351 #ifdef DEBUG_GLSDL
347 static __inline__ int GLERET(const char *txt) 352 static __inline__ int
348 { 353 GLERET (const char *txt)
349 fprintf(stderr, "glSDL ERROR: '%s'\n", txt); 354 {
350 return -1; 355 fprintf (stderr, "glSDL ERROR: '%s'\n", txt);
351 } 356 return -1;
352 static __inline__ void GLERR(const char *txt) 357 }
353 { 358 static __inline__ void
354 fprintf(stderr, "glSDL ERROR: '%s'\n", txt); 359 GLERR (const char *txt)
360 {
361 fprintf (stderr, "glSDL ERROR: '%s'\n", txt);
355 } 362 }
356 #else 363 #else
357 #define GLERET(x) (-1) 364 #define GLERET(x) (-1)
358 #define GLERR(x) 365 #define GLERR(x)
359 #endif 366 #endif
366 * The purpose of this is to make glSDL "portable" across 373 * The purpose of this is to make glSDL "portable" across
367 * all video backends that support OpenGL 374 * all video backends that support OpenGL
368 */ 375 */
369 static VideoBootStrap *opengl_bootstrap = 376 static VideoBootStrap *opengl_bootstrap =
370 #if SDL_VIDEO_DRIVER_QUARTZ 377 #if SDL_VIDEO_DRIVER_QUARTZ
371 &QZ_bootstrap; 378 &QZ_bootstrap;
372 #elif SDL_VIDEO_DRIVER_X11 379 #elif SDL_VIDEO_DRIVER_X11
373 &X11_bootstrap; 380 &X11_bootstrap;
374 #elif SDL_VIDEO_DRIVER_WINDIB 381 #elif SDL_VIDEO_DRIVER_WINDIB
375 &WINDIB_bootstrap; 382 &WINDIB_bootstrap;
376 #elif SDL_VIDEO_DRIVER_BWINDOW 383 #elif SDL_VIDEO_DRIVER_BWINDOW
377 &BWINDOW_bootstrap; 384 &BWINDOW_bootstrap;
378 #elif SDL_VIDEO_DRIVER_TOOLBOX 385 #elif SDL_VIDEO_DRIVER_TOOLBOX
379 &TOOLBOX_bootstrap; 386 &TOOLBOX_bootstrap;
380 #elif SDL_VIDEO_DRIVER_CYBERGRAPHICS 387 #elif SDL_VIDEO_DRIVER_CYBERGRAPHICS
381 &CGX_bootstrap; 388 &CGX_bootstrap;
382 #elif SDL_VIDEO_DRIVER_PHOTON 389 #elif SDL_VIDEO_DRIVER_PHOTON
383 &ph_bootstrap; 390 &ph_bootstrap;
384 #elif SDL_VIDEO_DRIVER_DC 391 #elif SDL_VIDEO_DRIVER_DC
385 &DC_bootstrap; 392 &DC_bootstrap;
386 #else 393 #else
387 NULL; 394 NULL;
388 #endif 395 #endif
389 396
390 static int glSDL_Available(void) 397 static int
398 glSDL_Available (void)
391 { 399 {
392 #ifdef DEBUG_GLSDL 400 #ifdef DEBUG_GLSDL
393 fprintf(stderr,"available\n"); 401 fprintf (stderr, "available\n");
394 #endif 402 #endif
395 if (opengl_bootstrap==NULL) 403 if (opengl_bootstrap == NULL)
396 return 0; 404 return 0;
397 return (opengl_bootstrap->available()); 405 return (opengl_bootstrap->available ());
398 } 406 }
399 407
400 static void glSDL_DeleteDevice(SDL_VideoDevice *device) 408 static void
401 { 409 glSDL_DeleteDevice (SDL_VideoDevice * device)
402 SDL_free(device->hidden); 410 {
403 SDL_free(device); 411 SDL_free (device->hidden);
412 SDL_free (device);
404 } 413 }
405 414
406 /* Create a glSDL device */ 415 /* Create a glSDL device */
407 static SDL_VideoDevice* glSDL_CreateDevice(int devindex) 416 static SDL_VideoDevice *
408 { 417 glSDL_CreateDevice (int devindex)
409 SDL_VideoDevice *device; 418 {
419 SDL_VideoDevice *device;
410 #ifdef DEBUG_GLSDL 420 #ifdef DEBUG_GLSDL
411 fprintf(stderr,"entering createdevice\n"); 421 fprintf (stderr, "entering createdevice\n");
412 #endif 422 #endif
413 423
414 /* Create the device with the underlying driver */ 424 /* Create the device with the underlying driver */
415 device = opengl_bootstrap->create(devindex); 425 device = opengl_bootstrap->create (devindex);
416 426
417 /* Save the video device contents for future use */ 427 /* Save the video device contents for future use */
418 SDL_memcpy(&underlying_device,device,sizeof(SDL_VideoDevice)); 428 SDL_memcpy (&underlying_device, device, sizeof (SDL_VideoDevice));
419 429
420 /* Hook glSDL on the video device */ 430 /* Hook glSDL on the video device */
421 device->VideoInit = glSDL_VideoInit; 431 device->VideoInit = glSDL_VideoInit;
422 device->ListModes = glSDL_ListModes; 432 device->ListModes = glSDL_ListModes;
423 device->VideoQuit = glSDL_VideoQuit; 433 device->VideoQuit = glSDL_VideoQuit;
424 device->UpdateRects = glSDL_UpdateRects; 434 device->UpdateRects = glSDL_UpdateRects;
425 device->FillHWRect = glSDL_FillHWRect; 435 device->FillHWRect = glSDL_FillHWRect;
426 device->SetHWColorKey = glSDL_SetHWColorKey; 436 device->SetHWColorKey = glSDL_SetHWColorKey;
427 device->SetHWAlpha = glSDL_SetHWAlpha; 437 device->SetHWAlpha = glSDL_SetHWAlpha;
428 device->AllocHWSurface = glSDL_AllocHWSurface; 438 device->AllocHWSurface = glSDL_AllocHWSurface;
429 device->LockHWSurface = glSDL_LockHWSurface; 439 device->LockHWSurface = glSDL_LockHWSurface;
430 device->UnlockHWSurface = glSDL_UnlockHWSurface; 440 device->UnlockHWSurface = glSDL_UnlockHWSurface;
431 device->FlipHWSurface = glSDL_FlipHWSurface; 441 device->FlipHWSurface = glSDL_FlipHWSurface;
432 device->FreeHWSurface = glSDL_FreeHWSurface; 442 device->FreeHWSurface = glSDL_FreeHWSurface;
433 device->CheckHWBlit = glSDL_CheckHWBlit; 443 device->CheckHWBlit = glSDL_CheckHWBlit;
434 device->SetColors = glSDL_SetColors; 444 device->SetColors = glSDL_SetColors;
435 device->SetVideoMode = glSDL_SetVideoMode; 445 device->SetVideoMode = glSDL_SetVideoMode;
436 device->info.hw_available=1; 446 device->info.hw_available = 1;
437 device->info.blit_hw=1; 447 device->info.blit_hw = 1;
438 device->info.blit_hw_CC=1; 448 device->info.blit_hw_CC = 1;
439 device->info.blit_hw_A=1; 449 device->info.blit_hw_A = 1;
440 device->info.blit_sw=1; 450 device->info.blit_sw = 1;
441 device->info.blit_sw_CC=1; 451 device->info.blit_sw_CC = 1;
442 device->info.blit_sw_A=1; 452 device->info.blit_sw_A = 1;
443 device->info.blit_fill=1; 453 device->info.blit_fill = 1;
444 454
445 /* These functions are not supported by glSDL, so we NULLify them */ 455 /* These functions are not supported by glSDL, so we NULLify them */
446 device->SetGamma = NULL; 456 device->SetGamma = NULL;
447 device->GetGamma = NULL; 457 device->GetGamma = NULL;
448 device->SetGammaRamp = NULL; 458 device->SetGammaRamp = NULL;
449 device->GetGammaRamp = NULL; 459 device->GetGammaRamp = NULL;
450 device->ToggleFullScreen = NULL; 460 device->ToggleFullScreen = NULL;
451 461
452 device->free = glSDL_DeleteDevice; 462 device->free = glSDL_DeleteDevice;
453 463
454 #ifdef DEBUG_GLSDL 464 #ifdef DEBUG_GLSDL
455 fprintf(stderr,"leaving createdevice\n"); 465 fprintf (stderr, "leaving createdevice\n");
456 #endif 466 #endif
457 467
458 return device; 468 return device;
459 } 469 }
460 470
461 /* Our bootstraping structure */ 471 /* Our bootstraping structure */
462 VideoBootStrap glSDL_bootstrap = { 472 VideoBootStrap glSDL_bootstrap = {
463 "glSDL", "glSDL - SDL over OpenGL", 473 "glSDL", "glSDL - SDL over OpenGL",
464 glSDL_Available, glSDL_CreateDevice 474 glSDL_Available, glSDL_CreateDevice
465 }; 475 };
466 476
467 static int glSDL_VideoInit(_THIS, SDL_PixelFormat *vformat) 477 static int
468 { 478 glSDL_VideoInit (_THIS, SDL_PixelFormat * vformat)
469 int r; 479 {
470 printf("glSDL videoinit\n"); 480 int r;
481 printf ("glSDL videoinit\n");
471 #ifdef DEBUG_GLSDL 482 #ifdef DEBUG_GLSDL
472 fprintf(stderr,"videoinit\n"); 483 fprintf (stderr, "videoinit\n");
473 #endif 484 #endif
474 r=underlying_device.VideoInit(this,vformat); 485 r = underlying_device.VideoInit (this, vformat);
475 this->info.hw_available=1; 486 this->info.hw_available = 1;
476 this->info.blit_hw=1; 487 this->info.blit_hw = 1;
477 this->info.blit_hw_CC=1; 488 this->info.blit_hw_CC = 1;
478 this->info.blit_hw_A=1; 489 this->info.blit_hw_A = 1;
479 this->info.blit_sw=1; 490 this->info.blit_sw = 1;
480 this->info.blit_sw_CC=1; 491 this->info.blit_sw_CC = 1;
481 this->info.blit_sw_A=1; 492 this->info.blit_sw_A = 1;
482 this->info.blit_fill=1; 493 this->info.blit_fill = 1;
483 494
484 return r; 495 return r;
485 } 496 }
486 497
487 SDL_Rect **glSDL_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) 498 SDL_Rect **
488 { 499 glSDL_ListModes (_THIS, SDL_PixelFormat * format, Uint32 flags)
489 return((SDL_Rect **)-1); 500 {
490 } 501 return ((SDL_Rect **) - 1);
491 502 }
492 static void glSDL_VideoQuit(_THIS) 503
493 { 504 static void
494 SDL_Surface* scr; 505 glSDL_VideoQuit (_THIS)
495 506 {
496 /* free all hwdata structures */ 507 SDL_Surface *scr;
497 while(first!=NULL) 508
498 glSDL_RemoveTexInfo(this, first); 509 /* free all hwdata structures */
499 510 while (first != NULL)
500 SDL_free(mirrorbuf); 511 glSDL_RemoveTexInfo (this, first);
501 mirrorbuf = NULL; 512
502 513 SDL_free (mirrorbuf);
503 SDL_FreeFormat(RGBfmt); 514 mirrorbuf = NULL;
504 SDL_FreeFormat(RGBAfmt); 515
505 RGBfmt = RGBAfmt = NULL; 516 SDL_FreeFormat (RGBfmt);
506 517 SDL_FreeFormat (RGBAfmt);
507 SDL_FreeFormat(this->displayformatalphapixel); 518 RGBfmt = RGBAfmt = NULL;
508 this->displayformatalphapixel = NULL; 519
509 520 SDL_FreeFormat (this->displayformatalphapixel);
510 SDL_FreeSurface(OpenGL_Surface); 521 this->displayformatalphapixel = NULL;
511 OpenGL_Surface = NULL; 522
512 523 SDL_FreeSurface (OpenGL_Surface);
513 /* restore the flags to gracefully exit from fullscreen */ 524 OpenGL_Surface = NULL;
514 this->screen->flags = old_screen_flags; 525
515 526 /* restore the flags to gracefully exit from fullscreen */
516 /* keep the screen */ 527 this->screen->flags = old_screen_flags;
517 scr=this->screen; 528
518 529 /* keep the screen */
519 /* we cleaned up our stuff, now restore the underlying video driver */ 530 scr = this->screen;
520 SDL_memcpy(this,&underlying_device,sizeof(SDL_VideoDevice)); 531
521 532 /* we cleaned up our stuff, now restore the underlying video driver */
522 this->screen=scr; 533 SDL_memcpy (this, &underlying_device, sizeof (SDL_VideoDevice));
523 534
524 /* call the underlying video driver's VideoQuit function */ 535 this->screen = scr;
525 this->VideoQuit(this); 536
526 } 537 /* call the underlying video driver's VideoQuit function */
527 538 this->VideoQuit (this);
528 static SDL_Surface* glSDL_SetVideoMode(_THIS, SDL_Surface *current,int width, int height, int bpp, Uint32 flags) 539 }
529 { 540
530 SDL_Surface* hooked_screen; 541 static SDL_Surface *
531 int i; 542 glSDL_SetVideoMode (_THIS, SDL_Surface * current, int width, int height,
532 int flag_doublebuf=0; 543 int bpp, Uint32 flags)
533 544 {
534 if (opengl_bootstrap==NULL) 545 SDL_Surface *hooked_screen;
535 { 546 int i;
536 GLERR("No bootstrap for glSDL compiled in !\n"); 547 int flag_doublebuf = 0;
537 return NULL; 548
538 } 549 if (opengl_bootstrap == NULL) {
539 550 GLERR ("No bootstrap for glSDL compiled in !\n");
540 /* we don't have OpenGL */ 551 return NULL;
541 if ((flags&SDL_INTERNALOPENGL)==SDL_INTERNALOPENGL) 552 }
542 { 553
543 GLERR("OpenGL video modes are not supported by glSDL !\n"); 554 /* we don't have OpenGL */
544 return(NULL); 555 if ((flags & SDL_INTERNALOPENGL) == SDL_INTERNALOPENGL) {
545 } 556 GLERR ("OpenGL video modes are not supported by glSDL !\n");
546 557 return (NULL);
547 /* 558 }
548 * Adjust the flags 559
549 */ 560 /*
550 flags &= ~SDL_HWPALETTE; 561 * Adjust the flags
551 flags |= SDL_INTERNALOPENGL; 562 */
552 563 flags &= ~SDL_HWPALETTE;
553 /* remember whether the user requested DOUBLEBUF */ 564 flags |= SDL_INTERNALOPENGL;
554 565
555 if (flags&SDL_DOUBLEBUF) 566 /* remember whether the user requested DOUBLEBUF */
556 { 567
557 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1); 568 if (flags & SDL_DOUBLEBUF) {
558 flag_doublebuf=1; 569 SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1);
559 } 570 flag_doublebuf = 1;
560 else 571 } else {
561 { 572 SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 0);
562 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,0); 573 flag_doublebuf = 0;
563 flag_doublebuf=0; 574 }
564 } 575
565 576 hooked_screen =
566 hooked_screen = underlying_device.SetVideoMode(this,current,width,height,0,flags); 577 underlying_device.SetVideoMode (this, current, width, height, 0,
567 578 flags);
568 if (!hooked_screen) 579
569 { 580 if (!hooked_screen) {
570 GLERR("Unable to open an OpenGL window !\n"); 581 GLERR ("Unable to open an OpenGL window !\n");
571 return(NULL); 582 return (NULL);
572 } 583 }
573 584
574 /* save the screen flags for restore time */ 585 /* save the screen flags for restore time */
575 old_screen_flags = hooked_screen->flags; 586 old_screen_flags = hooked_screen->flags;
576 587
577 #ifdef DEBUG_GLSDL 588 #ifdef DEBUG_GLSDL
578 fprintf(stderr,"got %d bpp\n",bpp); 589 fprintf (stderr, "got %d bpp\n", bpp);
579 #endif 590 #endif
580 591
581 /* setup the public surface format 592 /* setup the public surface format
582 * glSDL always returns the bpp its asked 593 * glSDL always returns the bpp its asked
583 */ 594 */
584 switch(bpp) 595 switch (bpp) {
585 { 596 case 32:
586 case 32: 597 this->is_32bit = 1;
587 this->is_32bit = 1; 598 this->screen = SDL_CreateRGBSurface (flags, width, height, bpp,
588 this->screen = SDL_CreateRGBSurface(flags, width, height, bpp,
589 #if SDL_BYTEORDER == SDL_LIL_ENDIAN 599 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
590 0x00FF0000, 600 0x00FF0000,
591 0x0000FF00, 601 0x0000FF00,
592 0x000000FF, 602 0x000000FF, 0x00000000
593 0x00000000
594 #else 603 #else
595 0x0000FF00, 604 0x0000FF00,
596 0x00FF0000, 605 0x00FF0000,
597 0xFF000000, 606 0xFF000000, 0x00000000
598 0x00000000 607 #endif
599 #endif 608 );
600 ); 609 break;
601 break; 610 case 24:
602 case 24: 611 this->is_32bit = 0;
603 this->is_32bit = 0; 612 this->screen = SDL_CreateRGBSurface (flags, width, height, bpp,
604 this->screen = SDL_CreateRGBSurface(flags, width, height, bpp,
605 #if SDL_BYTEORDER == SDL_LIL_ENDIAN 613 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
606 0x00FF0000, 614 0x00FF0000,
607 0x0000FF00, 615 0x0000FF00,
608 0x000000FF, 616 0x000000FF, 0x00000000
609 0x00000000
610 #else 617 #else
611 0x0000FF00, 618 0x0000FF00,
612 0x00FF0000, 619 0x00FF0000,
613 0xFF000000, 620 0xFF000000, 0x00000000
614 0x00000000 621 #endif
615 #endif 622 );
616 ); 623 break;
617 break; 624 case 16:
618 case 16: 625 this->is_32bit = 0;
619 this->is_32bit = 0; 626 this->screen = SDL_CreateRGBSurface (flags, width, height, bpp,
620 this->screen = SDL_CreateRGBSurface(flags, width, height, bpp,
621 #if SDL_BYTEORDER == SDL_LIL_ENDIAN 627 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
622 0x0000F800, 628 0x0000F800,
623 0x000007E0, 629 0x000007E0,
624 0x0000001F, 630 0x0000001F, 0x00000000
625 0x00000000
626 #else 631 #else
627 0x0000001F, 632 0x0000001F,
628 0x000007E0, 633 0x000007E0,
629 0x0000F800, 634 0x0000F800, 0x00000000
630 0x00000000 635 #endif
631 #endif 636 );
632 ); 637 break;
633 break; 638 case 15:
634 case 15: 639 this->is_32bit = 0;
635 this->is_32bit = 0; 640 this->screen = SDL_CreateRGBSurface (flags, width, height, bpp,
636 this->screen = SDL_CreateRGBSurface(flags, width, height, bpp,
637 #if SDL_BYTEORDER == SDL_LIL_ENDIAN 641 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
638 0x00007C00, 642 0x00007C00,
639 0x000003E0, 643 0x000003E0,
640 0x0000001F, 644 0x0000001F, 0x00000000
641 0x00000000
642 #else 645 #else
643 0x0000001F, 646 0x0000001F,
644 0x000003E0, 647 0x000003E0,
645 0x00007C00, 648 0x00007C00, 0x00000000
646 0x00000000 649 #endif
647 #endif 650 );
648 ); 651 break;
649 break; 652 case 8:
650 case 8: 653 default:
651 default: 654 this->is_32bit = 0;
652 this->is_32bit = 0; 655 this->screen =
653 this->screen = SDL_CreateRGBSurface(flags, width, height, bpp, 0, 0, 0, 0); 656 SDL_CreateRGBSurface (flags, width, height, bpp, 0, 0, 0, 0);
654 /* give it a default palette if 8 bpp 657 /* give it a default palette if 8 bpp
655 * note : SDL already takes care of the palette for 4 bits & 1 bit surfaces 658 * note : SDL already takes care of the palette for 4 bits & 1 bit surfaces
656 */ 659 */
657 /* if (bpp==8) 660 /* if (bpp==8)
658 { 661 {
659 this->screen->format->palette->ncolors=255; 662 this->screen->format->palette->ncolors=255;
660 SDL_DitherColors(this->screen->format->palette->colors,bpp); 663 SDL_DitherColors(this->screen->format->palette->colors,bpp);
661 }*/ 664 }*/
662 break; 665 break;
663 } 666 }
664 667
665 /* also, we add SDL_HWSURFACE all the time, and let SDL create a shadow surface accordingly */ 668 /* also, we add SDL_HWSURFACE all the time, and let SDL create a shadow surface accordingly */
666 this->screen->flags = hooked_screen->flags | SDL_HWSURFACE | SDL_INTERNALOPENGL; 669 this->screen->flags =
667 /* add SDL_DOUBLEBUF if it was requested */ 670 hooked_screen->flags | SDL_HWSURFACE | SDL_INTERNALOPENGL;
668 if (flag_doublebuf) 671 /* add SDL_DOUBLEBUF if it was requested */
669 this->screen->flags|=SDL_DOUBLEBUF; 672 if (flag_doublebuf)
670 673 this->screen->flags |= SDL_DOUBLEBUF;
671 /* Tell SDL the alpha pixel format we'd like to have */ 674
672 this->displayformatalphapixel = SDL_AllocFormat(32, 675 /* Tell SDL the alpha pixel format we'd like to have */
676 this->displayformatalphapixel = SDL_AllocFormat (32,
673 #if SDL_BYTEORDER == SDL_BIG_ENDIAN 677 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
674 0xFF000000, 678 0xFF000000,
675 0x00FF0000, 679 0x00FF0000,
676 0x0000FF00, 680 0x0000FF00, 0x000000FF
677 0x000000FF
678 #else 681 #else
679 0x000000FF, 682 0x000000FF,
680 0x0000FF00, 683 0x0000FF00,
681 0x00FF0000, 684 0x00FF0000, 0xFF000000
682 0xFF000000 685 #endif
683 #endif 686 );
684 ); 687
685 688 /* Now create the raw OpenGL surface */
686 /* Now create the raw OpenGL surface */ 689 OpenGL_Surface = SDL_CreateRGBSurface (flags, width, height, 24,
687 OpenGL_Surface = SDL_CreateRGBSurface(flags, width, height, 24,
688 #if SDL_BYTEORDER == SDL_LIL_ENDIAN 690 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
689 0x000000FF, 691 0x000000FF,
690 0x0000FF00, 692 0x0000FF00, 0x00FF0000, 0x00000000
691 0x00FF0000,
692 0x00000000
693 #else 693 #else
694 0xFF000000, 694 0xFF000000,
695 0x00FF0000, 695 0x00FF0000, 0x0000FF00, 0x00000000
696 0x0000FF00, 696 #endif
697 0x00000000 697 );
698 #endif 698
699 ); 699 /* Here we have to setup OpenGL funcs ourselves */
700
701 /* Here we have to setup OpenGL funcs ourselves */
702 #ifndef __QNXNTO__ 700 #ifndef __QNXNTO__
703 #define SDL_PROC(ret,func,params) \ 701 #define SDL_PROC(ret,func,params) \
704 do { \ 702 do { \
705 this->func = SDL_GL_GetProcAddress(#func); \ 703 this->func = SDL_GL_GetProcAddress(#func); \
706 if ( ! this->func ) { \ 704 if ( ! this->func ) { \
710 } while ( 0 ); 708 } while ( 0 );
711 #else 709 #else
712 #define SDL_PROC(ret,func,params) this->func=func; 710 #define SDL_PROC(ret,func,params) this->func=func;
713 #endif /* __QNXNTO__ */ 711 #endif /* __QNXNTO__ */
714 #include "../SDL_glfuncs.h" 712 #include "../SDL_glfuncs.h"
715 #undef SDL_PROC 713 #undef SDL_PROC
716 714
717 if ( this->GL_MakeCurrent(this) < 0 ) 715 if (this->GL_MakeCurrent (this) < 0)
718 return(NULL); 716 return (NULL);
719 #define SDL_PROC(ret,func,params) \ 717 #define SDL_PROC(ret,func,params) \
720 do { \ 718 do { \
721 this->func = SDL_GL_GetProcAddress(#func); \ 719 this->func = SDL_GL_GetProcAddress(#func); \
722 if ( ! this->func ) { \ 720 if ( ! this->func ) { \
723 SDL_SetError("Couldn't load GL function: %s\n", #func); \ 721 SDL_SetError("Couldn't load GL function: %s\n", #func); \
724 return(NULL); \ 722 return(NULL); \
725 } \ 723 } \
726 } while ( 0 ); 724 } while ( 0 );
727 #include "../SDL_glfuncs.h" 725 #include "../SDL_glfuncs.h"
728 #undef SDL_PROC 726 #undef SDL_PROC
729 727
730 728
731 #ifdef FAKE_MAXTEXSIZE 729 #ifdef FAKE_MAXTEXSIZE
732 maxtexsize = FAKE_MAXTEXSIZE; 730 maxtexsize = FAKE_MAXTEXSIZE;
733 #else 731 #else
734 this->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxtexsize); 732 this->glGetIntegerv (GL_MAX_TEXTURE_SIZE, &maxtexsize);
735 #endif 733 #endif
736 #ifdef DEBUG_GLSDL 734 #ifdef DEBUG_GLSDL
737 fprintf(stderr, "glSDL: Max texture size: %d\n", maxtexsize); 735 fprintf (stderr, "glSDL: Max texture size: %d\n", maxtexsize);
738 #endif 736 #endif
739 737
740 glSDL_init_formats(this); 738 glSDL_init_formats (this);
741 739
742 if (flag_doublebuf) 740 if (flag_doublebuf)
743 this->glDrawBuffer(GL_BACK); 741 this->glDrawBuffer (GL_BACK);
744 else 742 else
745 this->glDrawBuffer(GL_FRONT); 743 this->glDrawBuffer (GL_FRONT);
746 744
747 this->glDisable(GL_DITHER); 745 this->glDisable (GL_DITHER);
748 746
749 if(glSDL_AddTexInfo(this, this->screen) < 0) 747 if (glSDL_AddTexInfo (this, this->screen) < 0) {
750 { 748 GLERR ("HookDevice() failed to add info to screen surface!");
751 GLERR("HookDevice() failed to add info to screen surface!"); 749 return NULL;
752 return NULL; 750 }
753 } 751
754 752 glSDL_SetLogicSize (this, this->screen, this->screen->w, this->screen->h);
755 glSDL_SetLogicSize(this, this->screen, 753
756 this->screen->w, this->screen->h); 754 glSDL_do_texture (this, 0);
757 755 glSDL_do_blend (this, 0);
758 glSDL_do_texture(this, 0); 756
759 glSDL_do_blend(this, 0); 757 for (i = 0; i < 1 + flag_doublebuf; ++i) {
760 758 this->glBegin (GL_TRIANGLE_FAN);
761 for(i = 0; i < 1+flag_doublebuf; ++i) 759 this->glColor3ub (0, 0, 0);
762 { 760 this->glVertex2i (0, 0);
763 this->glBegin(GL_TRIANGLE_FAN); 761 this->glVertex2i (this->screen->w, 0);
764 this->glColor3ub(0, 0, 0); 762 this->glVertex2i (this->screen->w, this->screen->h);
765 this->glVertex2i(0, 0); 763 this->glVertex2i (0, this->screen->h);
766 this->glVertex2i(this->screen->w, 0); 764 this->glEnd ();
767 this->glVertex2i(this->screen->w, this->screen->h); 765 if (!i)
768 this->glVertex2i(0, this->screen->h); 766 this->GL_SwapBuffers (this);
769 this->glEnd(); 767 }
770 if(!i) 768
771 this->GL_SwapBuffers(this); 769 mirrorbuf = SDL_malloc (this->screen->h * this->screen->pitch);
772 } 770 if (!mirrorbuf) {
773 771 GLERR ("HookDevice() failed to allocate temp buffer for mirroring!");
774 mirrorbuf = SDL_malloc(this->screen->h * this->screen->pitch); 772 return NULL;
775 if(!mirrorbuf) 773 }
776 { 774
777 GLERR("HookDevice() failed to allocate temp buffer for mirroring!"); 775 return this->screen;
778 return NULL; 776 }
779 } 777
780 778 static int
781 return this->screen; 779 glSDL_SetColors (_THIS, int firstcolor, int ncolors, SDL_Color * colors)
782 } 780 {
783 781 /* We don't need to fill this one */
784 static int glSDL_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) 782 return 0;
785 {
786 /* We don't need to fill this one */
787 return 0;
788 } 783 }
789 784
790 785
791 #ifdef DEBUG_GLSDL 786 #ifdef DEBUG_GLSDL
792 static void glSDL_print_glerror(_THIS, int point) 787 static void
793 { 788 glSDL_print_glerror (_THIS, int point)
794 const char *err = "<unknown>"; 789 {
795 switch(this->glGetError()) 790 const char *err = "<unknown>";
796 { 791 switch (this->glGetError ()) {
797 case GL_NO_ERROR: 792 case GL_NO_ERROR:
798 return; 793 return;
799 case GL_INVALID_ENUM: 794 case GL_INVALID_ENUM:
800 err = "GL_INVALID_ENUM"; 795 err = "GL_INVALID_ENUM";
801 break; 796 break;
802 case GL_INVALID_VALUE: 797 case GL_INVALID_VALUE:
803 err = "GL_INVALID_VALUE"; 798 err = "GL_INVALID_VALUE";
804 break; 799 break;
805 case GL_INVALID_OPERATION: 800 case GL_INVALID_OPERATION:
806 err = "GL_INVALID_OPERATION"; 801 err = "GL_INVALID_OPERATION";
807 break; 802 break;
808 case GL_STACK_OVERFLOW: 803 case GL_STACK_OVERFLOW:
809 err = "GL_STACK_OVERFLOW"; 804 err = "GL_STACK_OVERFLOW";
810 break; 805 break;
811 case GL_STACK_UNDERFLOW: 806 case GL_STACK_UNDERFLOW:
812 err = "GL_STACK_UNDERFLOW"; 807 err = "GL_STACK_UNDERFLOW";
813 break; 808 break;
814 case GL_OUT_OF_MEMORY: 809 case GL_OUT_OF_MEMORY:
815 err = "GL_OUT_OF_MEMORY"; 810 err = "GL_OUT_OF_MEMORY";
816 default: 811 default:
817 break; 812 break;
818 } 813 }
819 fprintf(stderr,"OpenGL error \"%s\" at point %d.\n", err, point); 814 fprintf (stderr, "OpenGL error \"%s\" at point %d.\n", err, point);
820 } 815 }
821 #endif 816 #endif
822 817
823 /* Get texinfo for a surface. */ 818 /* Get texinfo for a surface. */
824 static __inline__ private_hwdata *glSDL_GetTexInfo(SDL_Surface *surface) 819 static __inline__ private_hwdata *
825 { 820 glSDL_GetTexInfo (SDL_Surface * surface)
826 if(!surface) 821 {
827 return NULL; 822 if (!surface)
828 return surface->hwdata; 823 return NULL;
824 return surface->hwdata;
829 } 825 }
830 826
831 827
832 /* Allocate a "blank" texinfo for a suface. */ 828 /* Allocate a "blank" texinfo for a suface. */
833 static private_hwdata *glSDL_AllocTexInfo(SDL_Surface *surface) 829 static private_hwdata *
834 { 830 glSDL_AllocTexInfo (SDL_Surface * surface)
835 private_hwdata *txi; 831 {
836 if(!surface) 832 private_hwdata *txi;
837 return NULL; 833 if (!surface)
838 834 return NULL;
839 txi = glSDL_GetTexInfo(surface); 835
840 if(txi) 836 txi = glSDL_GetTexInfo (surface);
841 return txi; /* There already is one! --> */ 837 if (txi)
842 838 return txi; /* There already is one! --> */
843 /* ...and hook a new texinfo struct up to it. */ 839
844 txi = (private_hwdata *)SDL_calloc(1, sizeof(private_hwdata)); 840 /* ...and hook a new texinfo struct up to it. */
845 if(!txi) 841 txi = (private_hwdata *) SDL_calloc (1, sizeof (private_hwdata));
846 { 842 if (!txi) {
847 GLERR("AllocTexInfo(): Failed allocating TexInfo struct!"); 843 GLERR ("AllocTexInfo(): Failed allocating TexInfo struct!");
848 return NULL; 844 return NULL;
849 } 845 }
850 txi->temporary = 1; 846 txi->temporary = 1;
851 #ifdef DEBUG_GLSDL
852 fprintf(stderr, "glSDL: Allocated TexInfo %p.\n", txi);
853 #endif
854 return txi;
855 }
856
857
858 static void glSDL_FreeTexInfo(_THIS, private_hwdata *txi)
859 {
860 if(!txi)
861 return;
862
863 glSDL_UnloadTexture(this, txi);
864 SDL_free(txi->texture);
865 SDL_free(txi);
866 #ifdef DEBUG_GLSDL 847 #ifdef DEBUG_GLSDL
867 fprintf(stderr, "glSDL: Freed TexInfo %p.\n", txi); 848 fprintf (stderr, "glSDL: Allocated TexInfo %p.\n", txi);
849 #endif
850 return txi;
851 }
852
853
854 static void
855 glSDL_FreeTexInfo (_THIS, private_hwdata * txi)
856 {
857 if (!txi)
858 return;
859
860 glSDL_UnloadTexture (this, txi);
861 SDL_free (txi->texture);
862 SDL_free (txi);
863 #ifdef DEBUG_GLSDL
864 fprintf (stderr, "glSDL: Freed TexInfo %p.\n", txi);
868 #endif 865 #endif
869 } 866 }
870 867
871 868
872 /* Detach and free the texinfo of a surface. */ 869 /* Detach and free the texinfo of a surface. */
873 static void glSDL_RemoveTexInfo(_THIS, SDL_Surface *surface) 870 static void
874 { 871 glSDL_RemoveTexInfo (_THIS, SDL_Surface * surface)
875 SDL_Surface *next,*prev; 872 {
876 if(!glSDL_GetTexInfo(surface)) 873 SDL_Surface *next, *prev;
877 return; 874 if (!glSDL_GetTexInfo (surface))
878 875 return;
879 /* maintain our doubly linked list */ 876
880 next=surface->hwdata->next; 877 /* maintain our doubly linked list */
881 prev=surface->hwdata->prev; 878 next = surface->hwdata->next;
882 if (prev!=NULL) 879 prev = surface->hwdata->prev;
883 { 880 if (prev != NULL) {
884 prev->hwdata->next = next; 881 prev->hwdata->next = next;
885 } 882 } else {
886 else 883 first = next;
887 { 884 }
888 first = next; 885 if (next != NULL) {
889 } 886 next->hwdata->prev = prev;
890 if (next!=NULL) 887 }
891 { 888
892 next->hwdata->prev = prev; 889 glSDL_FreeTexInfo (this, surface->hwdata);
893 } 890 surface->hwdata = NULL;
894
895 glSDL_FreeTexInfo(this, surface->hwdata);
896 surface->hwdata = NULL;
897 } 891 }
898 892
899 893
900 /* 894 /*
901 * Calculate chopping/tiling of a surface to 895 * Calculate chopping/tiling of a surface to
902 * fit it into the smallest possible OpenGL 896 * fit it into the smallest possible OpenGL
903 * texture. 897 * texture.
904 */ 898 */
905 static int glSDL_CalcChop(private_hwdata *txi) 899 static int
906 { 900 glSDL_CalcChop (private_hwdata * txi)
907 int rows, vw, vh; 901 {
908 int vertical = 0; 902 int rows, vw, vh;
909 int texsize; 903 int vertical = 0;
910 int lastw, lasth, minsize; 904 int texsize;
911 905 int lastw, lasth, minsize;
912 vw = txi->virt.w; 906
913 vh = txi->virt.h; 907 vw = txi->virt.w;
908 vh = txi->virt.h;
914 909
915 #ifdef DEBUG_GLSDL_CHOP 910 #ifdef DEBUG_GLSDL_CHOP
916 fprintf(stderr, "w=%d, h=%d ", vw, vh); 911 fprintf (stderr, "w=%d, h=%d ", vw, vh);
917 #endif 912 #endif
918 if(vh > vw) 913 if (vh > vw) {
919 { 914 int t = vw;
920 int t = vw; 915 vw = vh;
921 vw = vh; 916 vh = t;
922 vh = t; 917 vertical = 1;
923 vertical = 1;
924 #ifdef DEBUG_GLSDL_CHOP 918 #ifdef DEBUG_GLSDL_CHOP
925 fprintf(stderr, "(vertical) \t"); 919 fprintf (stderr, "(vertical) \t");
926 #endif 920 #endif
927 } 921 }
928 922
929 /* 923 /*
930 * Check whether this is a "huge" surface - at least one dimension 924 * Check whether this is a "huge" surface - at least one dimension
931 * must be <= than the maximum texture size, or we'll have to chop 925 * must be <= than the maximum texture size, or we'll have to chop
932 * in both directions. 926 * in both directions.
933 */ 927 */
934 #ifdef DEBUG_GLSDL 928 #ifdef DEBUG_GLSDL
935 if(maxtexsize < 0) 929 if (maxtexsize < 0)
936 return GLERET("glSDL_CalcChop() called before OpenGL init!"); 930 return GLERET ("glSDL_CalcChop() called before OpenGL init!");
937 #endif 931 #endif
938 if(vh > maxtexsize) 932 if (vh > maxtexsize) {
939 { 933 /*
940 /* 934 * Very simple hack for now; we just tile
941 * Very simple hack for now; we just tile 935 * both ways with maximum size textures.
942 * both ways with maximum size textures. 936 */
943 */ 937 texsize = maxtexsize;
944 texsize = maxtexsize; 938
945 939 txi->tilemode = GLSDL_TM_HUGE;
946 txi->tilemode = GLSDL_TM_HUGE; 940 txi->texsize = texsize;
947 txi->texsize = texsize; 941 txi->tilew = texsize;
948 txi->tilew = texsize; 942 txi->tileh = texsize;
949 txi->tileh = texsize; 943 txi->tilespertex = 1;
950 txi->tilespertex = 1; 944
951 945 /* Calculate number of textures needed */
952 /* Calculate number of textures needed */ 946 txi->textures = (vw + texsize - 1) / texsize;
953 txi->textures = (vw + texsize - 1) / texsize; 947 txi->textures *= (vh + texsize - 1) / texsize;
954 txi->textures *= (vh + texsize - 1) / texsize; 948 txi->texture = SDL_malloc (txi->textures * sizeof (int));
955 txi->texture = SDL_malloc(txi->textures * sizeof(int)); 949 SDL_memset (txi->texture, -1, txi->textures * sizeof (int));
956 SDL_memset(txi->texture, -1, txi->textures * sizeof(int)); 950 #ifdef DEBUG_GLSDL
957 #ifdef DEBUG_GLSDL 951 fprintf (stderr, "two-way tiling; textures=%d\n", txi->textures);
958 fprintf(stderr, "two-way tiling; textures=%d\n", txi->textures); 952 #endif
959 #endif 953 if (!txi->texture) {
960 if(!txi->texture) 954 fprintf (stderr, "glSDL: INTERNAL ERROR: Failed to allocate"
961 { 955 " texture name table!\n");
962 fprintf(stderr, "glSDL: INTERNAL ERROR: Failed to allocate" 956 return -3;
963 " texture name table!\n"); 957 }
964 return -3; 958 return 0;
965 } 959 }
966 return 0; 960
967 } 961 /* Calculate minimum size */
968 962 rows = 1;
969 /* Calculate minimum size */ 963 lastw = vw;
970 rows = 1; 964 lasth = vh;
971 lastw = vw; 965 minsize = lastw > lasth ? lastw : lasth;
972 lasth = vh; 966 while (1) {
973 minsize = lastw > lasth ? lastw : lasth; 967 int w, h, size;
974 while(1) 968 ++rows;
975 { 969 w = vw / rows;
976 int w, h, size; 970 h = rows * vh;
977 ++rows; 971 size = w > h ? w : h;
978 w = vw / rows; 972 if (size >= minsize) {
979 h = rows * vh; 973 --rows;
980 size = w > h ? w : h; 974 break;
981 if(size >= minsize) 975 }
982 { 976 lastw = w;
983 --rows; 977 lasth = h;
984 break; 978 minsize = size;
985 } 979 }
986 lastw = w; 980 if (minsize > maxtexsize) {
987 lasth = h; 981 /* Handle multiple textures for very wide/tall surfaces. */
988 minsize = size; 982 minsize = maxtexsize;
989 } 983 rows = (vw + minsize - 1) / minsize;
990 if(minsize > maxtexsize) 984 }
991 {
992 /* Handle multiple textures for very wide/tall surfaces. */
993 minsize = maxtexsize;
994 rows = (vw + minsize-1) / minsize;
995 }
996 #ifdef DEBUG_GLSDL_CHOP 985 #ifdef DEBUG_GLSDL_CHOP
997 fprintf(stderr, "==> minsize=%d ", minsize); 986 fprintf (stderr, "==> minsize=%d ", minsize);
998 fprintf(stderr, "(rows=%d) \t", rows); 987 fprintf (stderr, "(rows=%d) \t", rows);
999 #endif 988 #endif
1000 989
1001 /* Recalculate with nearest higher power-of-2 width. */ 990 /* Recalculate with nearest higher power-of-2 width. */
1002 for(texsize = 1; texsize < minsize; texsize <<= 1) 991 for (texsize = 1; texsize < minsize; texsize <<= 1);
1003 ; 992 txi->texsize = texsize;
1004 txi->texsize = texsize; 993 rows = (vw + texsize - 1) / texsize;
1005 rows = (vw + texsize-1) / texsize;
1006 #ifdef DEBUG_GLSDL_CHOP 994 #ifdef DEBUG_GLSDL_CHOP
1007 fprintf(stderr, "==> texsize=%d (rows=%d) \t", texsize, rows); 995 fprintf (stderr, "==> texsize=%d (rows=%d) \t", texsize, rows);
1008 #endif 996 #endif
1009 997
1010 /* Calculate number of tiles per texture */ 998 /* Calculate number of tiles per texture */
1011 txi->tilespertex = txi->texsize / vh; 999 txi->tilespertex = txi->texsize / vh;
1012 #ifdef DEBUG_GLSDL_CHOP 1000 #ifdef DEBUG_GLSDL_CHOP
1013 fprintf(stderr, "tilespertex=%d \t", txi->tilespertex); 1001 fprintf (stderr, "tilespertex=%d \t", txi->tilespertex);
1014 #endif 1002 #endif
1015 1003
1016 /* Calculate number of textures needed */ 1004 /* Calculate number of textures needed */
1017 txi->textures = (rows + txi->tilespertex-1) / txi->tilespertex; 1005 txi->textures = (rows + txi->tilespertex - 1) / txi->tilespertex;
1018 txi->texture = (GLuint *)SDL_malloc(txi->textures * sizeof(GLuint)); 1006 txi->texture = (GLuint *) SDL_malloc (txi->textures * sizeof (GLuint));
1019 SDL_memset(txi->texture, GLSDL_NOTEX, txi->textures * sizeof(GLuint)); 1007 SDL_memset (txi->texture, GLSDL_NOTEX, txi->textures * sizeof (GLuint));
1020 #ifdef DEBUG_GLSDL_CHOP 1008 #ifdef DEBUG_GLSDL_CHOP
1021 fprintf(stderr, "textures=%d, ", txi->textures); 1009 fprintf (stderr, "textures=%d, ", txi->textures);
1022 #endif 1010 #endif
1023 if(!txi->texture) 1011 if (!txi->texture)
1024 return GLERET("Failed to allocate texture name table!"); 1012 return GLERET ("Failed to allocate texture name table!");
1025 1013
1026 /* Set up tile size. (Only one axis supported here!) */ 1014 /* Set up tile size. (Only one axis supported here!) */
1027 if(1 == rows) 1015 if (1 == rows) {
1028 { 1016 txi->tilemode = GLSDL_TM_SINGLE;
1029 txi->tilemode = GLSDL_TM_SINGLE; 1017 if (vertical) {
1030 if(vertical) 1018 txi->tilew = vh;
1031 { 1019 txi->tileh = vw;
1032 txi->tilew = vh; 1020 } else {
1033 txi->tileh = vw; 1021 txi->tilew = vw;
1034 } 1022 txi->tileh = vh;
1035 else 1023 }
1036 { 1024 } else if (vertical) {
1037 txi->tilew = vw; 1025 txi->tilemode = GLSDL_TM_VERTICAL;
1038 txi->tileh = vh; 1026 txi->tilew = vh;
1039 } 1027 txi->tileh = texsize;
1040 } 1028 } else {
1041 else if(vertical) 1029 txi->tilemode = GLSDL_TM_HORIZONTAL;
1042 { 1030 txi->tilew = texsize;
1043 txi->tilemode = GLSDL_TM_VERTICAL; 1031 txi->tileh = vh;
1044 txi->tilew = vh; 1032 }
1045 txi->tileh = texsize;
1046 }
1047 else
1048 {
1049 txi->tilemode = GLSDL_TM_HORIZONTAL;
1050 txi->tilew = texsize;
1051 txi->tileh = vh;
1052 }
1053 1033
1054 #ifdef DEBUG_GLSDL_CHOP 1034 #ifdef DEBUG_GLSDL_CHOP
1055 fprintf(stderr, "tilew=%d, tileh=%d\n", txi->tilew, txi->tileh); 1035 fprintf (stderr, "tilew=%d, tileh=%d\n", txi->tilew, txi->tileh);
1056 #endif 1036 #endif
1057 return 0; 1037 return 0;
1058 } 1038 }
1059 1039
1060 1040
1061 /* Create a temporary TexInfo struct for an SDL_Surface */ 1041 /* Create a temporary TexInfo struct for an SDL_Surface */
1062 static private_hwdata *glSDL_CreateTempTexInfo(_THIS, SDL_Surface *surface) 1042 static private_hwdata *
1063 { 1043 glSDL_CreateTempTexInfo (_THIS, SDL_Surface * surface)
1064 private_hwdata *txi; 1044 {
1065 if(!surface) 1045 private_hwdata *txi;
1066 { 1046 if (!surface) {
1067 GLERR("CreateTempTexInfo(); no surface!"); 1047 GLERR ("CreateTempTexInfo(); no surface!");
1068 return NULL; 1048 return NULL;
1069 } 1049 }
1070 if(IS_GLSDL_SURFACE(surface)) 1050 if (IS_GLSDL_SURFACE (surface))
1071 return glSDL_GetTexInfo(surface); /* Do nothing */ 1051 return glSDL_GetTexInfo (surface); /* Do nothing */
1072 1052
1073 txi = glSDL_AllocTexInfo(surface); 1053 txi = glSDL_AllocTexInfo (surface);
1074 if(!txi) 1054 if (!txi) {
1075 { 1055 GLERR ("CreateTempTexInfo(); Could not alloc TexInfo!");
1076 GLERR("CreateTempTexInfo(); Could not alloc TexInfo!"); 1056 return NULL;
1077 return NULL; 1057 }
1078 } 1058 txi->virt.w = txi->lw = surface->w;
1079 txi->virt.w = txi->lw = surface->w; 1059 txi->virt.h = txi->lh = surface->h;
1080 txi->virt.h = txi->lh = surface->h; 1060
1081 1061 if (glSDL_CalcChop (txi) < 0) {
1082 if(glSDL_CalcChop(txi) < 0) 1062 glSDL_FreeTexInfo (this, txi);
1083 { 1063 GLERR ("CreateTempTexInfo(); CalcChop() failed!");
1084 glSDL_FreeTexInfo(this, txi); 1064 return NULL;
1085 GLERR("CreateTempTexInfo(); CalcChop() failed!"); 1065 }
1086 return NULL; 1066
1087 } 1067 return txi;
1088
1089 return txi;
1090 } 1068 }
1091 1069
1092 /* Add a glSDL_TexInfo struct to an SDL_Surface */ 1070 /* Add a glSDL_TexInfo struct to an SDL_Surface */
1093 static private_hwdata *glSDL_AddTexInfo(_THIS, SDL_Surface *surface) 1071 static private_hwdata *
1094 { 1072 glSDL_AddTexInfo (_THIS, SDL_Surface * surface)
1095 private_hwdata *txi = glSDL_CreateTempTexInfo(this, surface); 1073 {
1096 if(!txi) 1074 private_hwdata *txi = glSDL_CreateTempTexInfo (this, surface);
1097 return NULL; 1075 if (!txi)
1098 1076 return NULL;
1099 /* Connect the surface to the new TexInfo. */ 1077
1100 txi->temporary = 0; 1078 /* Connect the surface to the new TexInfo. */
1101 surface->hwdata = txi; 1079 txi->temporary = 0;
1102 1080 surface->hwdata = txi;
1103 /* add this new surface in front of the list of hw surfaces */ 1081
1104 txi->next = first; 1082 /* add this new surface in front of the list of hw surfaces */
1105 txi->prev = NULL; 1083 txi->next = first;
1106 first = surface; 1084 txi->prev = NULL;
1107 if (txi->next!=NULL) 1085 first = surface;
1108 { 1086 if (txi->next != NULL) {
1109 txi->next->hwdata->prev=surface; 1087 txi->next->hwdata->prev = surface;
1110 } 1088 }
1111 1089
1112 SDL_SetClipRect(surface, &txi->virt); 1090 SDL_SetClipRect (surface, &txi->virt);
1113 return txi; 1091 return txi;
1114 } 1092 }
1115 1093
1116 1094
1117 /* Create a surface of the prefered OpenGL RGB texture format */ 1095 /* Create a surface of the prefered OpenGL RGB texture format */
1118 /*static SDL_Surface *glSDL_CreateRGBSurface(int w, int h) 1096 /*static SDL_Surface *glSDL_CreateRGBSurface(int w, int h)
1137 return s; 1115 return s;
1138 } 1116 }
1139 */ 1117 */
1140 1118
1141 /* Create a surface of the prefered OpenGL RGBA texture format */ 1119 /* Create a surface of the prefered OpenGL RGBA texture format */
1142 static SDL_Surface *glSDL_CreateRGBASurface(int w, int h) 1120 static SDL_Surface *
1143 { 1121 glSDL_CreateRGBASurface (int w, int h)
1144 SDL_Surface *s; 1122 {
1145 Uint32 rmask, gmask, bmask, amask; 1123 SDL_Surface *s;
1146 int bits = 32; 1124 Uint32 rmask, gmask, bmask, amask;
1125 int bits = 32;
1147 #if SDL_BYTEORDER == SDL_LIL_ENDIAN 1126 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
1148 rmask = 0x000000FF; 1127 rmask = 0x000000FF;
1149 gmask = 0x0000FF00; 1128 gmask = 0x0000FF00;
1150 bmask = 0x00FF0000; 1129 bmask = 0x00FF0000;
1151 amask = 0xFF000000; 1130 amask = 0xFF000000;
1152 #else 1131 #else
1153 rmask = 0xFF000000; 1132 rmask = 0xFF000000;
1154 gmask = 0x00FF0000; 1133 gmask = 0x00FF0000;
1155 bmask = 0x0000FF00; 1134 bmask = 0x0000FF00;
1156 amask = 0x000000FF; 1135 amask = 0x000000FF;
1157 #endif 1136 #endif
1158 s = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 1137 s = SDL_CreateRGBSurface (SDL_SWSURFACE, w, h,
1159 bits, rmask, gmask, bmask, amask); 1138 bits, rmask, gmask, bmask, amask);
1160 if(s) 1139 if (s)
1161 s->flags |= SDL_HWACCEL; 1140 s->flags |= SDL_HWACCEL;
1162 1141
1163 return s; 1142 return s;
1164 } 1143 }
1165 1144
1166 1145
1167 static void glSDL_init_formats(_THIS) 1146 static void
1168 { 1147 glSDL_init_formats (_THIS)
1169 RGBfmt = SDL_AllocFormat(24, 1148 {
1149 RGBfmt = SDL_AllocFormat (24,
1170 #if SDL_BYTEORDER == SDL_LIL_ENDIAN 1150 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
1171 0x000000FF, 1151 0x000000FF, 0x0000FF00, 0x00FF0000, 0);
1172 0x0000FF00,
1173 0x00FF0000,
1174 0);
1175 #else 1152 #else
1176 0x00FF0000, 1153 0x00FF0000, 0x0000FF00, 0x000000FF, 0);
1177 0x0000FF00, 1154 #endif
1178 0x000000FF, 1155 RGBAfmt = SDL_AllocFormat (32,
1179 0);
1180 #endif
1181 RGBAfmt = SDL_AllocFormat(32,
1182 #if SDL_BYTEORDER == SDL_LIL_ENDIAN 1156 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
1183 0x000000FF, 1157 0x000000FF,
1184 0x0000FF00, 1158 0x0000FF00, 0x00FF0000, 0xFF000000);
1185 0x00FF0000,
1186 0xFF000000);
1187 #else 1159 #else
1188 0xFF000000, 1160 0xFF000000,
1189 0x00FF0000, 1161 0x00FF0000, 0x0000FF00, 0x000000FF);
1190 0x0000FF00, 1162 #endif
1191 0x000000FF); 1163 }
1192 #endif 1164
1193 } 1165
1194 1166 static int
1195 1167 glSDL_FormatIsOk (SDL_Surface * surface)
1196 static int glSDL_FormatIsOk(SDL_Surface *surface) 1168 {
1197 { 1169 SDL_PixelFormat *pf;
1198 SDL_PixelFormat *pf; 1170 if (!surface)
1199 if(!surface) 1171 return 1; /* Well, there ain't much we can do anyway... */
1200 return 1; /* Well, there ain't much we can do anyway... */ 1172
1201 1173 pf = surface->format;
1202 pf = surface->format; 1174
1203 1175 /* Colorkeying requires an alpha channel! */
1204 /* Colorkeying requires an alpha channel! */ 1176 if (surface->flags & SDL_SRCCOLORKEY)
1205 if(surface->flags & SDL_SRCCOLORKEY) 1177 if (!pf->Amask)
1206 if(!pf->Amask) 1178 return 0;
1207 return 0; 1179
1208 1180 /* We need pitch == (width * BytesPerPixel) for glTex[Sub]Image2D() */
1209 /* We need pitch == (width * BytesPerPixel) for glTex[Sub]Image2D() */ 1181 if (surface->pitch != (surface->w * pf->BytesPerPixel))
1210 if(surface->pitch != (surface->w * pf->BytesPerPixel)) 1182 return 0;
1211 return 0; 1183
1212 1184 if (pf->Amask) {
1213 if(pf->Amask) 1185 if (pf->BytesPerPixel != RGBAfmt->BytesPerPixel)
1214 { 1186 return 0;
1215 if(pf->BytesPerPixel != RGBAfmt->BytesPerPixel) 1187 if (pf->Rmask != RGBAfmt->Rmask)
1216 return 0; 1188 return 0;
1217 if(pf->Rmask != RGBAfmt->Rmask) 1189 if (pf->Gmask != RGBAfmt->Gmask)
1218 return 0; 1190 return 0;
1219 if(pf->Gmask != RGBAfmt->Gmask) 1191 if (pf->Bmask != RGBAfmt->Bmask)
1220 return 0; 1192 return 0;
1221 if(pf->Bmask != RGBAfmt->Bmask) 1193 if (pf->Amask != RGBAfmt->Amask)
1222 return 0; 1194 return 0;
1223 if(pf->Amask != RGBAfmt->Amask) 1195 } else {
1224 return 0; 1196 if (pf->BytesPerPixel != RGBfmt->BytesPerPixel)
1225 } 1197 return 0;
1226 else 1198 if (pf->Rmask != RGBfmt->Rmask)
1227 { 1199 return 0;
1228 if(pf->BytesPerPixel != RGBfmt->BytesPerPixel) 1200 if (pf->Gmask != RGBfmt->Gmask)
1229 return 0; 1201 return 0;
1230 if(pf->Rmask != RGBfmt->Rmask) 1202 if (pf->Bmask != RGBfmt->Bmask)
1231 return 0; 1203 return 0;
1232 if(pf->Gmask != RGBfmt->Gmask) 1204 }
1233 return 0; 1205 return 1;
1234 if(pf->Bmask != RGBfmt->Bmask) 1206 }
1235 return 0; 1207
1236 } 1208 static void
1237 return 1; 1209 glSDL_key2alpha (SDL_Surface * surface)
1238 } 1210 {
1239 1211 int x, y;
1240 static void glSDL_key2alpha(SDL_Surface *surface) 1212 Uint32 ckey = surface->format->colorkey;
1241 {
1242 int x, y;
1243 Uint32 ckey = surface->format->colorkey;
1244 1213
1245 #ifdef DEBUG_GLSDL 1214 #ifdef DEBUG_GLSDL
1246 fprintf(stderr,"glSDL_key2alpha()\n"); 1215 fprintf (stderr, "glSDL_key2alpha()\n");
1247 #endif 1216 #endif
1248 for(y = 0; y < surface->h; ++y) 1217 for (y = 0; y < surface->h; ++y) {
1249 { 1218 Uint32 *px =
1250 Uint32 *px = (Uint32 *)((char *)surface->pixels + y*surface->pitch); 1219 (Uint32 *) ((char *) surface->pixels + y * surface->pitch);
1251 for(x = 0; x < surface->w; ++x) 1220 for (x = 0; x < surface->w; ++x)
1252 if(px[x] == ckey) 1221 if (px[x] == ckey)
1253 px[x] = 0; 1222 px[x] = 0;
1254 } 1223 }
1255 } 1224 }
1256 1225
1257 1226
1258 1227
1259 /*---------------------------------------------------------- 1228 /*----------------------------------------------------------
1260 SDL style API 1229 SDL style API
1261 ----------------------------------------------------------*/ 1230 ----------------------------------------------------------*/
1262 1231
1263 static int glSDL_FlipHWSurface(_THIS, SDL_Surface *surface) 1232 static int
1233 glSDL_FlipHWSurface (_THIS, SDL_Surface * surface)
1264 { 1234 {
1265 #ifdef GLSDL_GRAPHICAL_DEBUG 1235 #ifdef GLSDL_GRAPHICAL_DEBUG
1266 this->glDisable(GL_TEXTURE_2D); 1236 this->glDisable (GL_TEXTURE_2D);
1267 this->glBegin(GL_LINE_LOOP); 1237 this->glBegin (GL_LINE_LOOP);
1268 this->glColor4ub(0, 0, 255, 128); 1238 this->glColor4ub (0, 0, 255, 128);
1269 this->glVertex2i(0,0); 1239 this->glVertex2i (0, 0);
1270 this->glVertex2i(surface->w,0); 1240 this->glVertex2i (surface->w, 0);
1271 this->glVertex2i(surface->w,surface->h); 1241 this->glVertex2i (surface->w, surface->h);
1272 this->glVertex2i(0,surface->h); 1242 this->glVertex2i (0, surface->h);
1273 this->glEnd(); 1243 this->glEnd ();
1274 this->glEnable(GL_TEXTURE_2D); 1244 this->glEnable (GL_TEXTURE_2D);
1275 #endif 1245 #endif
1276 if (this->screen->flags&SDL_DOUBLEBUF) 1246 if (this->screen->flags & SDL_DOUBLEBUF)
1277 this->GL_SwapBuffers(this); 1247 this->GL_SwapBuffers (this);
1278 else 1248 else
1279 this->glFinish(); 1249 this->glFinish ();
1280 return 0; 1250 return 0;
1281 } 1251 }
1282 1252
1283 1253
1284 static void glSDL_UpdateRects(_THIS, int numrects, SDL_Rect *rects) 1254 static void
1255 glSDL_UpdateRects (_THIS, int numrects, SDL_Rect * rects)
1285 { 1256 {
1286 #ifdef GLSDL_GRAPHICAL_DEBUG 1257 #ifdef GLSDL_GRAPHICAL_DEBUG
1287 int i; 1258 int i;
1288 this->glDisable(GL_TEXTURE_2D); 1259 this->glDisable (GL_TEXTURE_2D);
1289 for(i=0;i<numrects;i++) 1260 for (i = 0; i < numrects; i++) {
1290 { 1261 this->glColor4ub (255, 0, 0, 128);
1291 this->glColor4ub(255, 0, 0, 128); 1262 this->glBegin (GL_LINE_LOOP);
1292 this->glBegin(GL_LINE_LOOP); 1263 this->glVertex2i (rects[i].x, rects[i].y);
1293 this->glVertex2i(rects[i].x,rects[i].y); 1264 this->glVertex2i (rects[i].x + rects[i].w, rects[i].y);
1294 this->glVertex2i(rects[i].x+rects[i].w,rects[i].y); 1265 this->glVertex2i (rects[i].x + rects[i].w, rects[i].y + rects[i].h);
1295 this->glVertex2i(rects[i].x+rects[i].w,rects[i].y+rects[i].h); 1266 this->glVertex2i (rects[i].x, rects[i].y + rects[i].h);
1296 this->glVertex2i(rects[i].x,rects[i].y+rects[i].h); 1267 this->glEnd ();
1297 this->glEnd(); 1268 }
1298 } 1269 this->glEnable (GL_TEXTURE_2D);
1299 this->glEnable(GL_TEXTURE_2D); 1270 #endif
1300 #endif 1271 if (this->screen->flags & SDL_DOUBLEBUF)
1301 if (this->screen->flags&SDL_DOUBLEBUF) 1272 this->GL_SwapBuffers (this);
1302 this->GL_SwapBuffers(this); 1273 else
1303 else 1274 this->glFinish ();
1304 this->glFinish(); 1275 }
1305 } 1276
1306 1277
1307 1278 static int
1308 static int glSDL_AllocHWSurface(_THIS, SDL_Surface *surface) 1279 glSDL_AllocHWSurface (_THIS, SDL_Surface * surface)
1309 { 1280 {
1310 surface->flags |= (SDL_HWSURFACE|SDL_HWACCEL); 1281 surface->flags |= (SDL_HWSURFACE | SDL_HWACCEL);
1311 1282
1312 surface->pixels = SDL_malloc(surface->h*surface->pitch); 1283 surface->pixels = SDL_malloc (surface->h * surface->pitch);
1313 if ( surface->pixels == NULL ) { 1284 if (surface->pixels == NULL) {
1314 SDL_FreeSurface(surface); 1285 SDL_FreeSurface (surface);
1315 SDL_OutOfMemory(); 1286 SDL_OutOfMemory ();
1316 return(-1); 1287 return (-1);
1317 } 1288 }
1318 SDL_memset(surface->pixels, 0, surface->h*surface->pitch); 1289 SDL_memset (surface->pixels, 0, surface->h * surface->pitch);
1319 return 0; 1290 return 0;
1320 } 1291 }
1321 1292
1322 1293
1323 static void glSDL_FreeHWSurface(_THIS, SDL_Surface *surface) 1294 static void
1324 { 1295 glSDL_FreeHWSurface (_THIS, SDL_Surface * surface)
1325 if(!surface) 1296 {
1326 return; 1297 if (!surface)
1327 glSDL_RemoveTexInfo(this, surface); 1298 return;
1328 } 1299 glSDL_RemoveTexInfo (this, surface);
1329 1300 }
1330 1301
1331 static int glSDL_LockHWSurface(_THIS, SDL_Surface *surface) 1302
1332 { 1303 static int
1333 int y; 1304 glSDL_LockHWSurface (_THIS, SDL_Surface * surface)
1334 1305 {
1335 if(!surface) 1306 int y;
1336 return -1; 1307
1337 1308 if (!surface)
1338 #ifdef DEBUG_GLSDL 1309 return -1;
1339 fprintf(stderr, "glSDL: Lock Surface.\n"); 1310
1340 #endif 1311 #ifdef DEBUG_GLSDL
1341 1312 fprintf (stderr, "glSDL: Lock Surface.\n");
1342 if(SDL_VideoSurface == surface) 1313 #endif
1343 { 1314
1344 glSDL_Invalidate(surface, NULL); 1315 if (SDL_VideoSurface == surface) {
1345 this->glPixelStorei(GL_UNPACK_ROW_LENGTH, 1316 glSDL_Invalidate (surface, NULL);
1346 surface->pitch / 1317 this->glPixelStorei (GL_UNPACK_ROW_LENGTH,
1347 surface->format->BytesPerPixel); 1318 surface->pitch / surface->format->BytesPerPixel);
1348 this->glReadPixels(0, 0, OpenGL_Surface->w, OpenGL_Surface->h, 1319 this->glReadPixels (0, 0, OpenGL_Surface->w, OpenGL_Surface->h,
1349 GL_RGB, 1320 GL_RGB, GL_UNSIGNED_BYTE, OpenGL_Surface->pixels);
1350 GL_UNSIGNED_BYTE, 1321 for (y = 0; y < OpenGL_Surface->h / 2; ++y) {
1351 OpenGL_Surface->pixels); 1322 void *upper = (Uint8 *) OpenGL_Surface->pixels +
1352 for(y = 0; y < OpenGL_Surface->h / 2; ++y) 1323 OpenGL_Surface->pitch * y;
1353 { 1324 void *lower = (Uint8 *) OpenGL_Surface->pixels +
1354 void *upper = (Uint8 *)OpenGL_Surface->pixels + 1325 OpenGL_Surface->pitch * (OpenGL_Surface->h - y - 1);
1355 OpenGL_Surface->pitch * y; 1326 SDL_memcpy (mirrorbuf, upper, OpenGL_Surface->pitch);
1356 void *lower = (Uint8 *)OpenGL_Surface->pixels + 1327 SDL_memcpy (upper, lower, OpenGL_Surface->pitch);
1357 OpenGL_Surface->pitch * (OpenGL_Surface->h - y - 1); 1328 SDL_memcpy (lower, mirrorbuf, OpenGL_Surface->pitch);
1358 SDL_memcpy(mirrorbuf, upper, OpenGL_Surface->pitch); 1329 }
1359 SDL_memcpy(upper, lower, OpenGL_Surface->pitch); 1330 /* the mapping has to be invalidated on 8bpp video surfaces in case of a hw palette change.
1360 SDL_memcpy(lower, mirrorbuf, OpenGL_Surface->pitch); 1331 * Now if someone could tell me why this is not handled by SDL... */
1361 } 1332 if (SDL_VideoSurface->format->BitsPerPixel == 8)
1362 /* the mapping has to be invalidated on 8bpp video surfaces in case of a hw palette change. 1333 SDL_InvalidateMap (OpenGL_Surface->map);
1363 * Now if someone could tell me why this is not handled by SDL... */ 1334
1364 if (SDL_VideoSurface->format->BitsPerPixel==8) 1335 /* convert this raw surface to the application-requested format
1365 SDL_InvalidateMap(OpenGL_Surface->map); 1336 * FIXME this is sometimes overkill, we could use glPixelStore smartly
1366 1337 * But this would be slow anyway :) */
1367 /* convert this raw surface to the application-requested format 1338
1368 * FIXME this is sometimes overkill, we could use glPixelStore smartly 1339 glSDL_SoftBlit (OpenGL_Surface, NULL, SDL_VideoSurface, NULL);
1369 * But this would be slow anyway :) */ 1340 } else
1370 1341 glSDL_Invalidate (surface, NULL);
1371 glSDL_SoftBlit(OpenGL_Surface, NULL, SDL_VideoSurface, NULL); 1342
1372 } 1343 return 0;
1373 else 1344 }
1374 glSDL_Invalidate(surface, NULL); 1345
1375 1346
1376 return 0; 1347 static void
1377 } 1348 glSDL_UnlockHWSurface (_THIS, SDL_Surface * surface)
1378 1349 {
1379 1350 private_hwdata *txi;
1380 static void glSDL_UnlockHWSurface(_THIS, SDL_Surface *surface) 1351
1381 { 1352 if (!surface)
1382 private_hwdata *txi; 1353 return;
1383 1354
1384 if(!surface) 1355 /* upload this surface ONLY if this is a glSDL surface
1385 return; 1356 * because sometimes (during displayformating for ex.) surfaces are unlocked that aren't glSDL
1386 1357 */
1387 /* upload this surface ONLY if this is a glSDL surface 1358 if (!IS_GLSDL_SURFACE (surface))
1388 * because sometimes (during displayformating for ex.) surfaces are unlocked that aren't glSDL 1359 return;
1389 */ 1360
1390 if(!IS_GLSDL_SURFACE(surface)) 1361 #ifdef DEBUG_GLSDL
1391 return; 1362 fprintf (stderr, "glSDL: Unlock Surface.\n");
1392 1363 #endif
1393 #ifdef DEBUG_GLSDL 1364
1394 fprintf(stderr, "glSDL: Unlock Surface.\n"); 1365 txi = glSDL_UploadSurface (this, surface);
1395 #endif 1366
1396 1367 if (!txi) {
1397 txi = glSDL_UploadSurface(this, surface); 1368 GLERR ("glSDL_UnlockHWSurface() failed to upload surface!");
1398 1369 return;
1399 if(!txi) 1370 }
1400 { 1371 if (txi->temporary) {
1401 GLERR("glSDL_UnlockHWSurface() failed to upload surface!"); 1372 GLERR
1402 return; 1373 ("Weirdness... glSDL_UnlockHWSurface() got a temporary TexInfo.");
1403 } 1374 return;
1404 if(txi->temporary) 1375 }
1405 { 1376 if (surface == SDL_VideoSurface)
1406 GLERR("Weirdness... glSDL_UnlockHWSurface() got a temporary TexInfo."); 1377 glSDL_BlitGL (this, SDL_VideoSurface, NULL, NULL);
1407 return; 1378 }
1408 } 1379
1409 if(surface == SDL_VideoSurface) 1380
1410 glSDL_BlitGL(this, SDL_VideoSurface, NULL, NULL); 1381 static int
1411 } 1382 glSDL_SetHWColorKey (_THIS, SDL_Surface * surface, Uint32 key)
1412 1383 {
1413 1384 /*
1414 static int glSDL_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key) 1385 * If an application does this *after* SDL_DisplayFormat,
1415 { 1386 * we're basically screwed, unless we want to do an
1416 /* 1387 * in-place surface conversion hack here.
1417 * If an application does this *after* SDL_DisplayFormat, 1388 *
1418 * we're basically screwed, unless we want to do an 1389 * What we do is just kill the glSDL texinfo... No big
1419 * in-place surface conversion hack here. 1390 * deal in most cases, as glSDL only converts once anyway,
1420 * 1391 * *unless* you keep modifying the surface.
1421 * What we do is just kill the glSDL texinfo... No big 1392 */
1422 * deal in most cases, as glSDL only converts once anyway, 1393 if (IS_GLSDL_SURFACE (surface))
1423 * *unless* you keep modifying the surface. 1394 glSDL_RemoveTexInfo (this, surface);
1424 */ 1395 return 0;
1425 if(IS_GLSDL_SURFACE(surface)) 1396 }
1426 glSDL_RemoveTexInfo(this, surface); 1397
1427 return 0; 1398
1428 } 1399 static int
1429 1400 glSDL_SetHWAlpha (_THIS, SDL_Surface * surface, Uint8 alpha)
1430 1401 {
1431 static int glSDL_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha) 1402 /*
1432 { 1403 * If an application does this *after* SDL_DisplayFormat,
1433 /* 1404 * we're basically screwed, unless we want to do an
1434 * If an application does this *after* SDL_DisplayFormat, 1405 * in-place surface conversion hack here.
1435 * we're basically screwed, unless we want to do an 1406 *
1436 * in-place surface conversion hack here. 1407 * What we do is just kill the glSDL texinfo... No big
1437 * 1408 * deal in most cases, as glSDL only converts once anyway,
1438 * What we do is just kill the glSDL texinfo... No big 1409 * *unless* you keep modifying the surface.
1439 * deal in most cases, as glSDL only converts once anyway, 1410 */
1440 * *unless* you keep modifying the surface. 1411 if (IS_GLSDL_SURFACE (surface))
1441 */ 1412 glSDL_RemoveTexInfo (this, surface);
1442 if(IS_GLSDL_SURFACE(surface)) 1413 return 0;
1443 glSDL_RemoveTexInfo(this, surface); 1414 }
1444 return 0; 1415
1445 } 1416 static SDL_bool
1446 1417 glSDL_SetClipRect (_THIS, SDL_Surface * surface, SDL_Rect * rect)
1447 static SDL_bool glSDL_SetClipRect(_THIS, SDL_Surface *surface, SDL_Rect *rect) 1418 {
1448 { 1419 SDL_bool res;
1449 SDL_bool res; 1420 if (!surface)
1450 if(!surface) 1421 return SDL_FALSE;
1451 return SDL_FALSE; 1422
1452 1423 res = SDL_SetClipRect (surface, rect);
1453 res = SDL_SetClipRect(surface, rect); 1424 if (!res)
1454 if(!res) 1425 return SDL_FALSE;
1455 return SDL_FALSE; 1426
1456 1427 rect = &surface->clip_rect;
1457 rect = &surface->clip_rect; 1428
1458 1429 if (surface == SDL_VideoSurface) {
1459 if(surface == SDL_VideoSurface) 1430 SDL_Rect r;
1460 { 1431 float xscale, yscale;
1461 SDL_Rect r; 1432 private_hwdata *txi;
1462 float xscale, yscale; 1433
1463 private_hwdata *txi; 1434 r.x = rect->x;
1464 1435 r.y = rect->y;
1465 r.x = rect->x; 1436 r.w = rect->w;
1466 r.y = rect->y; 1437 r.h = rect->h;
1467 r.w = rect->w; 1438 SDL_SetClipRect (surface, rect);
1468 r.h = rect->h; 1439
1469 SDL_SetClipRect(surface, rect); 1440 txi = glSDL_GetTexInfo (surface);
1470 1441 if (!txi)
1471 txi = glSDL_GetTexInfo(surface); 1442 return GLERET ("SetClipRect(): Could not get TexInfo!");
1472 if(!txi) 1443
1473 return GLERET("SetClipRect(): Could not get TexInfo!"); 1444 this->glViewport (rect->x,
1474 1445 surface->h - (rect->y + rect->h), rect->w, rect->h);
1475 this->glViewport(rect->x, 1446 /*
1476 surface->h - (rect->y + rect->h), 1447 * Note that this projection is upside down in
1477 rect->w, 1448 * relation to the OpenGL coordinate system.
1478 rect->h); 1449 */
1479 /* 1450 this->glMatrixMode (GL_PROJECTION);
1480 * Note that this projection is upside down in 1451 this->glLoadIdentity ();
1481 * relation to the OpenGL coordinate system. 1452 xscale = (float) txi->lw / (float) surface->w;
1482 */ 1453 yscale = (float) txi->lh / (float) surface->h;
1483 this->glMatrixMode(GL_PROJECTION); 1454 this->glOrtho (xscale * (float) rect->x,
1484 this->glLoadIdentity(); 1455 xscale * (float) (rect->w + rect->x),
1485 xscale = (float)txi->lw / (float)surface->w; 1456 yscale * (float) (rect->h + rect->y),
1486 yscale = (float)txi->lh / (float)surface->h; 1457 yscale * (float) rect->y, -1.0, 1.0);
1487 this->glOrtho( xscale*(float)rect->x, 1458 return SDL_TRUE;
1488 xscale*(float)(rect->w+rect->x), 1459 }
1489 yscale*(float)(rect->h+rect->y), 1460 return res;
1490 yscale*(float)rect->y, 1461 }
1491 -1.0, 1.0); 1462
1492 return SDL_TRUE; 1463 static int
1493 } 1464 glSDL_BlitFromGL (_THIS, SDL_Rect * srcrect,
1494 return res; 1465 SDL_Surface * dst, SDL_Rect * dstrect)
1495 } 1466 {
1496 1467 SDL_Rect sr, dr;
1497 static int glSDL_BlitFromGL(_THIS, SDL_Rect *srcrect, 1468
1498 SDL_Surface *dst, SDL_Rect *dstrect) 1469 /* In case the destination has an OpenGL texture... */
1499 { 1470 glSDL_Invalidate (dst, dstrect);
1500 SDL_Rect sr, dr; 1471
1501 1472 /* Abuse the fake screen buffer a little. */
1502 /* In case the destination has an OpenGL texture... */ 1473 this->glPixelStorei (GL_UNPACK_ROW_LENGTH, SDL_VideoSurface->pitch /
1503 glSDL_Invalidate(dst, dstrect); 1474 SDL_VideoSurface->format->BytesPerPixel);
1504 1475 if (srcrect)
1505 /* Abuse the fake screen buffer a little. */ 1476 this->glReadPixels (srcrect->x,
1506 this->glPixelStorei(GL_UNPACK_ROW_LENGTH, SDL_VideoSurface->pitch / 1477 OpenGL_Surface->h - (srcrect->y + srcrect->h - 1),
1507 SDL_VideoSurface->format->BytesPerPixel); 1478 srcrect->w, srcrect->h, GL_RGB, GL_UNSIGNED_BYTE,
1508 if(srcrect) 1479 OpenGL_Surface->pixels);
1509 this->glReadPixels(srcrect->x, OpenGL_Surface->h - (srcrect->y + srcrect->h - 1), 1480 else
1510 srcrect->w, srcrect->h, 1481 this->glReadPixels (0, 0, OpenGL_Surface->w, OpenGL_Surface->h,
1511 GL_RGB, GL_UNSIGNED_BYTE, OpenGL_Surface->pixels); 1482 GL_RGB, GL_UNSIGNED_BYTE, OpenGL_Surface->pixels);
1512 else 1483 sr = *srcrect;
1513 this->glReadPixels(0, 0, OpenGL_Surface->w, OpenGL_Surface->h, 1484 dr = *dstrect;
1514 GL_RGB, GL_UNSIGNED_BYTE, OpenGL_Surface->pixels); 1485 glSDL_SoftBlit (OpenGL_Surface, &sr, dst, &dr);
1515 sr = *srcrect; 1486 return 0;
1516 dr = *dstrect; 1487 }
1517 glSDL_SoftBlit(OpenGL_Surface, &sr, dst, &dr); 1488
1518 return 0; 1489 static __inline__ void
1519 } 1490 glSDL_BlitGL_single (_THIS, private_hwdata * txi,
1520 1491 float sx1, float sy1, SDL_Rect * dst,
1521 static __inline__ void glSDL_BlitGL_single(_THIS, private_hwdata *txi, 1492 unsigned char alpha)
1522 float sx1, float sy1, SDL_Rect *dst, unsigned char alpha) 1493 {
1523 { 1494 float sx2, sy2, texscale;
1524 float sx2, sy2, texscale; 1495 if (!txi->textures)
1525 if(!txi->textures) 1496 return;
1526 return; 1497 if (-1 == txi->texture[0])
1527 if(-1 == txi->texture[0]) 1498 return;
1528 return; 1499 glSDL_texture (this, txi->texture[0]);
1529 glSDL_texture(this, txi->texture[0]); 1500
1530 1501 texscale = 1.0 / (float) txi->texsize;
1531 texscale = 1.0 / (float)txi->texsize; 1502 sx2 = (sx1 + (float) dst->w) * texscale;
1532 sx2 = (sx1 + (float)dst->w) * texscale; 1503 sy2 = (sy1 + (float) dst->h) * texscale;
1533 sy2 = (sy1 + (float)dst->h) * texscale; 1504 sx1 *= texscale;
1534 sx1 *= texscale; 1505 sy1 *= texscale;
1535 sy1 *= texscale;
1536 1506
1537 #ifdef GLSDL_GRAPHICAL_DEBUG 1507 #ifdef GLSDL_GRAPHICAL_DEBUG
1538 this->glDisable(GL_TEXTURE_2D); 1508 this->glDisable (GL_TEXTURE_2D);
1539 this->glBegin(GL_LINE_LOOP); 1509 this->glBegin (GL_LINE_LOOP);
1540 this->glColor4ub(0, 255, 0, 128); 1510 this->glColor4ub (0, 255, 0, 128);
1541 this->glVertex2i(dst->x, dst->y); 1511 this->glVertex2i (dst->x, dst->y);
1542 this->glVertex2i(dst->x + dst->w, dst->y); 1512 this->glVertex2i (dst->x + dst->w, dst->y);
1543 this->glVertex2i(dst->x + dst->w, dst->y + dst->h); 1513 this->glVertex2i (dst->x + dst->w, dst->y + dst->h);
1544 this->glVertex2i(dst->x, dst->y + dst->h); 1514 this->glVertex2i (dst->x, dst->y + dst->h);
1545 this->glEnd(); 1515 this->glEnd ();
1546 this->glEnable(GL_TEXTURE_2D); 1516 this->glEnable (GL_TEXTURE_2D);
1547 #endif 1517 #endif
1548 1518
1549 this->glBegin(GL_TRIANGLE_FAN); 1519 this->glBegin (GL_TRIANGLE_FAN);
1550 this->glColor4ub(255, 255, 255, alpha); 1520 this->glColor4ub (255, 255, 255, alpha);
1551 this->glTexCoord2f(sx1, sy1); 1521 this->glTexCoord2f (sx1, sy1);
1552 this->glVertex2i(dst->x, dst->y); 1522 this->glVertex2i (dst->x, dst->y);
1553 this->glTexCoord2f(sx2, sy1); 1523 this->glTexCoord2f (sx2, sy1);
1554 this->glVertex2i(dst->x + dst->w, dst->y); 1524 this->glVertex2i (dst->x + dst->w, dst->y);
1555 this->glTexCoord2f(sx2, sy2); 1525 this->glTexCoord2f (sx2, sy2);
1556 this->glVertex2i(dst->x + dst->w, dst->y + dst->h); 1526 this->glVertex2i (dst->x + dst->w, dst->y + dst->h);
1557 this->glTexCoord2f(sx1, sy2); 1527 this->glTexCoord2f (sx1, sy2);
1558 this->glVertex2i(dst->x, dst->y + dst->h); 1528 this->glVertex2i (dst->x, dst->y + dst->h);
1559 this->glEnd(); 1529 this->glEnd ();
1560 } 1530 }
1561 1531
1562 1532
1563 static void glSDL_BlitGL_htile(_THIS, private_hwdata *txi, 1533 static void
1564 float sx1, float sy1, SDL_Rect *dst, unsigned char alpha) 1534 glSDL_BlitGL_htile (_THIS, private_hwdata * txi,
1565 { 1535 float sx1, float sy1, SDL_Rect * dst, unsigned char alpha)
1566 int tex; 1536 {
1567 float tile, sx2, sy2, yo; 1537 int tex;
1568 float texscale = 1.0 / (float)txi->texsize; 1538 float tile, sx2, sy2, yo;
1569 float tileh = (float)txi->tileh * texscale; 1539 float texscale = 1.0 / (float) txi->texsize;
1570 sx2 = (sx1 + (float)dst->w) * texscale; 1540 float tileh = (float) txi->tileh * texscale;
1571 sy2 = (sy1 + (float)dst->h) * texscale; 1541 sx2 = (sx1 + (float) dst->w) * texscale;
1572 sx1 *= texscale; 1542 sy2 = (sy1 + (float) dst->h) * texscale;
1573 sy1 *= texscale; 1543 sx1 *= texscale;
1574 tile = floor(sx1); 1544 sy1 *= texscale;
1575 tex = (int)tile / txi->tilespertex; 1545 tile = floor (sx1);
1576 yo = ((int)tile % txi->tilespertex) * tileh; 1546 tex = (int) tile / txi->tilespertex;
1577 1547 yo = ((int) tile % txi->tilespertex) * tileh;
1578 if(tex >= txi->textures) 1548
1579 return; 1549 if (tex >= txi->textures)
1580 if(-1 == txi->texture[tex]) 1550 return;
1581 return; 1551 if (-1 == txi->texture[tex])
1582 glSDL_texture(this, txi->texture[tex]); 1552 return;
1583 1553 glSDL_texture (this, txi->texture[tex]);
1584 while(tile < sx2) 1554
1585 { 1555 while (tile < sx2) {
1586 int tdx1 = dst->x; 1556 int tdx1 = dst->x;
1587 int tdx2 = dst->x + dst->w; 1557 int tdx2 = dst->x + dst->w;
1588 float tsx1 = sx1 - tile; 1558 float tsx1 = sx1 - tile;
1589 float tsx2 = sx2 - tile; 1559 float tsx2 = sx2 - tile;
1590 1560
1591 /* Clip to current tile */ 1561 /* Clip to current tile */
1592 if(tsx1 < 0.0) 1562 if (tsx1 < 0.0) {
1593 { 1563 tdx1 -= tsx1 * txi->texsize;
1594 tdx1 -= tsx1 * txi->texsize; 1564 tsx1 = 0.0;
1595 tsx1 = 0.0; 1565 }
1596 } 1566 if (tsx2 > 1.0) {
1597 if(tsx2 > 1.0) 1567 tdx2 -= (tsx2 - 1.0) * txi->texsize;
1598 { 1568 tsx2 = 1.0;
1599 tdx2 -= (tsx2 - 1.0) * txi->texsize; 1569 }
1600 tsx2 = 1.0; 1570
1601 } 1571 /* Maybe select next texture? */
1602 1572 if (yo + tileh > 1.0) {
1603 /* Maybe select next texture? */ 1573 ++tex;
1604 if(yo + tileh > 1.0) 1574 if (tex >= txi->textures)
1605 { 1575 return;
1606 ++tex; 1576 if (-1 == txi->texture[tex])
1607 if(tex >= txi->textures) 1577 return;
1608 return; 1578 glSDL_texture (this, txi->texture[tex]);
1609 if(-1 == txi->texture[tex]) 1579 yo = 0.0;
1610 return; 1580 }
1611 glSDL_texture(this, txi->texture[tex]);
1612 yo = 0.0;
1613 }
1614
1615 #ifdef GLSDL_GRAPHICAL_DEBUG 1581 #ifdef GLSDL_GRAPHICAL_DEBUG
1616 this->glDisable(GL_TEXTURE_2D); 1582 this->glDisable (GL_TEXTURE_2D);
1617 this->glBegin(GL_LINE_LOOP); 1583 this->glBegin (GL_LINE_LOOP);
1618 this->glColor4ub(0, 255, 0, 128); 1584 this->glColor4ub (0, 255, 0, 128);
1619 this->glVertex2i(tdx1, dst->y); 1585 this->glVertex2i (tdx1, dst->y);
1620 this->glVertex2i(tdx2, dst->y); 1586 this->glVertex2i (tdx2, dst->y);
1621 this->glVertex2i(tdx2, dst->y + dst->h); 1587 this->glVertex2i (tdx2, dst->y + dst->h);
1622 this->glVertex2i(tdx1, dst->y + dst->h); 1588 this->glVertex2i (tdx1, dst->y + dst->h);
1623 this->glEnd(); 1589 this->glEnd ();
1624 this->glEnable(GL_TEXTURE_2D); 1590 this->glEnable (GL_TEXTURE_2D);
1625 #endif 1591 #endif
1626 1592
1627 this->glBegin(GL_TRIANGLE_FAN); 1593 this->glBegin (GL_TRIANGLE_FAN);
1628 this->glColor4ub(255, 255, 255, alpha); 1594 this->glColor4ub (255, 255, 255, alpha);
1629 this->glTexCoord2f(tsx1, yo + sy1); 1595 this->glTexCoord2f (tsx1, yo + sy1);
1630 this->glVertex2i(tdx1, dst->y); 1596 this->glVertex2i (tdx1, dst->y);
1631 this->glTexCoord2f(tsx2, yo + sy1); 1597 this->glTexCoord2f (tsx2, yo + sy1);
1632 this->glVertex2i(tdx2, dst->y); 1598 this->glVertex2i (tdx2, dst->y);
1633 this->glTexCoord2f(tsx2, yo + sy2); 1599 this->glTexCoord2f (tsx2, yo + sy2);
1634 this->glVertex2i(tdx2, dst->y + dst->h); 1600 this->glVertex2i (tdx2, dst->y + dst->h);
1635 this->glTexCoord2f(tsx1, yo + sy2); 1601 this->glTexCoord2f (tsx1, yo + sy2);
1636 this->glVertex2i(tdx1, dst->y + dst->h); 1602 this->glVertex2i (tdx1, dst->y + dst->h);
1637 this->glEnd(); 1603 this->glEnd ();
1638 tile += 1.0; 1604 tile += 1.0;
1639 yo += tileh; 1605 yo += tileh;
1640 } 1606 }
1641 } 1607 }
1642 1608
1643 1609
1644 static void glSDL_BlitGL_vtile(_THIS, private_hwdata *txi, 1610 static void
1645 float sx1, float sy1, SDL_Rect *dst, unsigned char alpha) 1611 glSDL_BlitGL_vtile (_THIS, private_hwdata * txi,
1646 { 1612 float sx1, float sy1, SDL_Rect * dst, unsigned char alpha)
1647 int tex; 1613 {
1648 float tile, sx2, sy2, xo; 1614 int tex;
1649 float texscale = 1.0 / (float)txi->texsize; 1615 float tile, sx2, sy2, xo;
1650 float tilew = (float)txi->tilew * texscale; 1616 float texscale = 1.0 / (float) txi->texsize;
1651 sx2 = (sx1 + (float)dst->w) * texscale; 1617 float tilew = (float) txi->tilew * texscale;
1652 sy2 = (sy1 + (float)dst->h) * texscale; 1618 sx2 = (sx1 + (float) dst->w) * texscale;
1653 sx1 *= texscale; 1619 sy2 = (sy1 + (float) dst->h) * texscale;
1654 sy1 *= texscale; 1620 sx1 *= texscale;
1655 tile = floor(sy1); 1621 sy1 *= texscale;
1656 tex = (int)tile / txi->tilespertex; 1622 tile = floor (sy1);
1657 xo = ((int)tile % txi->tilespertex) * tilew; 1623 tex = (int) tile / txi->tilespertex;
1658 1624 xo = ((int) tile % txi->tilespertex) * tilew;
1659 if(tex >= txi->textures) 1625
1660 return; 1626 if (tex >= txi->textures)
1661 if(-1 == txi->texture[tex]) 1627 return;
1662 return; 1628 if (-1 == txi->texture[tex])
1663 glSDL_texture(this, txi->texture[tex]); 1629 return;
1664 1630 glSDL_texture (this, txi->texture[tex]);
1665 while(tile < sy2) 1631
1666 { 1632 while (tile < sy2) {
1667 int tdy1 = dst->y; 1633 int tdy1 = dst->y;
1668 int tdy2 = dst->y + dst->h; 1634 int tdy2 = dst->y + dst->h;
1669 float tsy1 = sy1 - tile; 1635 float tsy1 = sy1 - tile;
1670 float tsy2 = sy2 - tile; 1636 float tsy2 = sy2 - tile;
1671 1637
1672 /* Clip to current tile */ 1638 /* Clip to current tile */
1673 if(tsy1 < 0.0) 1639 if (tsy1 < 0.0) {
1674 { 1640 tdy1 -= tsy1 * txi->texsize;
1675 tdy1 -= tsy1 * txi->texsize; 1641 tsy1 = 0.0;
1676 tsy1 = 0.0; 1642 }
1677 } 1643 if (tsy2 > 1.0) {
1678 if(tsy2 > 1.0) 1644 tdy2 -= (tsy2 - 1.0) * txi->texsize;
1679 { 1645 tsy2 = 1.0;
1680 tdy2 -= (tsy2 - 1.0) * txi->texsize; 1646 }
1681 tsy2 = 1.0; 1647
1682 } 1648 /* Maybe select next texture? */
1683 1649 if (xo + tilew > 1.0) {
1684 /* Maybe select next texture? */ 1650 ++tex;
1685 if(xo + tilew > 1.0) 1651 if (tex >= txi->textures)
1686 { 1652 return;
1687 ++tex; 1653 if (-1 == txi->texture[tex])
1688 if(tex >= txi->textures) 1654 return;
1689 return; 1655 glSDL_texture (this, txi->texture[tex]);
1690 if(-1 == txi->texture[tex]) 1656 xo = 0.0;
1691 return; 1657 }
1692 glSDL_texture(this, txi->texture[tex]);
1693 xo = 0.0;
1694 }
1695
1696 #ifdef GLSDL_GRAPHICAL_DEBUG 1658 #ifdef GLSDL_GRAPHICAL_DEBUG
1697 this->glDisable(GL_TEXTURE_2D); 1659 this->glDisable (GL_TEXTURE_2D);
1698 this->glBegin(GL_LINE_LOOP); 1660 this->glBegin (GL_LINE_LOOP);
1699 this->glColor4ub(0, 255, 0, 128); 1661 this->glColor4ub (0, 255, 0, 128);
1700 this->glVertex2i(dst->x, tdy1); 1662 this->glVertex2i (dst->x, tdy1);
1701 this->glVertex2i(dst->x + dst->w, tdy1); 1663 this->glVertex2i (dst->x + dst->w, tdy1);
1702 this->glVertex2i(dst->x + dst->w, tdy2); 1664 this->glVertex2i (dst->x + dst->w, tdy2);
1703 this->glVertex2i(dst->x, tdy2); 1665 this->glVertex2i (dst->x, tdy2);
1704 this->glEnd(); 1666 this->glEnd ();
1705 this->glEnable(GL_TEXTURE_2D); 1667 this->glEnable (GL_TEXTURE_2D);
1706 #endif 1668 #endif
1707 1669
1708 this->glBegin(GL_TRIANGLE_FAN); 1670 this->glBegin (GL_TRIANGLE_FAN);
1709 this->glColor4ub(255, 255, 255, alpha); 1671 this->glColor4ub (255, 255, 255, alpha);
1710 this->glTexCoord2f(xo + sx1, tsy1); 1672 this->glTexCoord2f (xo + sx1, tsy1);
1711 this->glVertex2i(dst->x, tdy1); 1673 this->glVertex2i (dst->x, tdy1);
1712 this->glTexCoord2f(xo + sx2, tsy1); 1674 this->glTexCoord2f (xo + sx2, tsy1);
1713 this->glVertex2i(dst->x + dst->w, tdy1); 1675 this->glVertex2i (dst->x + dst->w, tdy1);
1714 this->glTexCoord2f(xo + sx2, tsy2); 1676 this->glTexCoord2f (xo + sx2, tsy2);
1715 this->glVertex2i(dst->x + dst->w, tdy2); 1677 this->glVertex2i (dst->x + dst->w, tdy2);
1716 this->glTexCoord2f(xo + sx1, tsy2); 1678 this->glTexCoord2f (xo + sx1, tsy2);
1717 this->glVertex2i(dst->x, tdy2); 1679 this->glVertex2i (dst->x, tdy2);
1718 this->glEnd(); 1680 this->glEnd ();
1719 1681
1720 tile += 1.0; 1682 tile += 1.0;
1721 xo += tilew; 1683 xo += tilew;
1722 } 1684 }
1723 } 1685 }
1724 1686
1725 1687
1726 static void glSDL_BlitGL_hvtile(_THIS, SDL_Surface *src, private_hwdata *txi, 1688 static void
1727 float sx1, float sy1, SDL_Rect *dst, unsigned char alpha) 1689 glSDL_BlitGL_hvtile (_THIS, SDL_Surface * src, private_hwdata * txi,
1728 { 1690 float sx1, float sy1, SDL_Rect * dst,
1729 int x, y, last_tex, tex; 1691 unsigned char alpha)
1730 float sx2, sy2; 1692 {
1731 float texscale = 1.0 / (float)txi->texsize; 1693 int x, y, last_tex, tex;
1732 int tilesperrow = (src->w + txi->tilew - 1) / txi->tilew; 1694 float sx2, sy2;
1733 sx2 = (sx1 + (float)dst->w) * texscale; 1695 float texscale = 1.0 / (float) txi->texsize;
1734 sy2 = (sy1 + (float)dst->h) * texscale; 1696 int tilesperrow = (src->w + txi->tilew - 1) / txi->tilew;
1735 sx1 *= texscale; 1697 sx2 = (sx1 + (float) dst->w) * texscale;
1736 sy1 *= texscale; 1698 sy2 = (sy1 + (float) dst->h) * texscale;
1737 1699 sx1 *= texscale;
1738 last_tex = tex = floor(sy1) * tilesperrow + floor(sx1); 1700 sy1 *= texscale;
1739 if(tex >= txi->textures) 1701
1740 return; 1702 last_tex = tex = floor (sy1) * tilesperrow + floor (sx1);
1741 if(-1 == txi->texture[tex]) 1703 if (tex >= txi->textures)
1742 return; 1704 return;
1743 glSDL_texture(this, txi->texture[tex]); 1705 if (-1 == txi->texture[tex])
1744 1706 return;
1745 for(y = floor(sy1); y < sy2; ++y) 1707 glSDL_texture (this, txi->texture[tex]);
1746 { 1708
1747 int tdy1 = dst->y; 1709 for (y = floor (sy1); y < sy2; ++y) {
1748 int tdy2 = dst->y + dst->h; 1710 int tdy1 = dst->y;
1749 float tsy1 = sy1 - y; 1711 int tdy2 = dst->y + dst->h;
1750 float tsy2 = sy2 - y; 1712 float tsy1 = sy1 - y;
1751 1713 float tsy2 = sy2 - y;
1752 /* Clip to current tile */ 1714
1753 if(tsy1 < 0.0) 1715 /* Clip to current tile */
1754 { 1716 if (tsy1 < 0.0) {
1755 tdy1 -= tsy1 * txi->texsize; 1717 tdy1 -= tsy1 * txi->texsize;
1756 tsy1 = 0.0; 1718 tsy1 = 0.0;
1757 } 1719 }
1758 if(tsy2 > 1.0) 1720 if (tsy2 > 1.0) {
1759 { 1721 tdy2 -= (tsy2 - 1.0) * txi->texsize;
1760 tdy2 -= (tsy2 - 1.0) * txi->texsize; 1722 tsy2 = 1.0;
1761 tsy2 = 1.0; 1723 }
1762 } 1724 for (x = floor (sx1); x < sx2; ++x) {
1763 for(x = floor(sx1); x < sx2; ++x) 1725 int tdx1 = dst->x;
1764 { 1726 int tdx2 = dst->x + dst->w;
1765 int tdx1 = dst->x; 1727 float tsx1 = sx1 - x;
1766 int tdx2 = dst->x + dst->w; 1728 float tsx2 = sx2 - x;
1767 float tsx1 = sx1 - x; 1729
1768 float tsx2 = sx2 - x; 1730 /* Clip to current tile */
1769 1731 if (tsx1 < 0.0) {
1770 /* Clip to current tile */ 1732 tdx1 -= tsx1 * txi->texsize;
1771 if(tsx1 < 0.0) 1733 tsx1 = 0.0;
1772 { 1734 }
1773 tdx1 -= tsx1 * txi->texsize; 1735 if (tsx2 > 1.0) {
1774 tsx1 = 0.0; 1736 tdx2 -= (tsx2 - 1.0) * txi->texsize;
1775 } 1737 tsx2 = 1.0;
1776 if(tsx2 > 1.0) 1738 }
1777 { 1739
1778 tdx2 -= (tsx2 - 1.0) * txi->texsize; 1740 /* Select texture */
1779 tsx2 = 1.0; 1741 tex = y * tilesperrow + x;
1780 } 1742 if (tex != last_tex) {
1781 1743 if (tex >= txi->textures)
1782 /* Select texture */ 1744 return;
1783 tex = y * tilesperrow + x; 1745 if (-1 == txi->texture[tex])
1784 if(tex != last_tex) 1746 return;
1785 { 1747 glSDL_texture (this, txi->texture[tex]);
1786 if(tex >= txi->textures) 1748 last_tex = tex;
1787 return; 1749 }
1788 if(-1 == txi->texture[tex])
1789 return;
1790 glSDL_texture(this, txi->texture[tex]);
1791 last_tex = tex;
1792 }
1793
1794 #ifdef GLSDL_GRAPHICAL_DEBUG 1750 #ifdef GLSDL_GRAPHICAL_DEBUG
1795 this->glDisable(GL_TEXTURE_2D); 1751 this->glDisable (GL_TEXTURE_2D);
1796 this->glBegin(GL_LINE_LOOP); 1752 this->glBegin (GL_LINE_LOOP);
1797 this->glColor4ub(0, 255, 0, 128); 1753 this->glColor4ub (0, 255, 0, 128);
1798 this->glVertex2i(tdx1, tdy1); 1754 this->glVertex2i (tdx1, tdy1);
1799 this->glVertex2i(tdx2, tdy1); 1755 this->glVertex2i (tdx2, tdy1);
1800 this->glVertex2i(tdx2, tdy2); 1756 this->glVertex2i (tdx2, tdy2);
1801 this->glVertex2i(tdx1, tdy2); 1757 this->glVertex2i (tdx1, tdy2);
1802 this->glEnd(); 1758 this->glEnd ();
1803 this->glEnable(GL_TEXTURE_2D); 1759 this->glEnable (GL_TEXTURE_2D);
1804 #endif 1760 #endif
1805 1761
1806 this->glBegin(GL_TRIANGLE_FAN); 1762 this->glBegin (GL_TRIANGLE_FAN);
1807 this->glColor4ub(255, 255, 255, alpha); 1763 this->glColor4ub (255, 255, 255, alpha);
1808 this->glTexCoord2f(tsx1, tsy1); 1764 this->glTexCoord2f (tsx1, tsy1);
1809 this->glVertex2i(tdx1, tdy1); 1765 this->glVertex2i (tdx1, tdy1);
1810 this->glTexCoord2f(tsx2, tsy1); 1766 this->glTexCoord2f (tsx2, tsy1);
1811 this->glVertex2i(tdx2, tdy1); 1767 this->glVertex2i (tdx2, tdy1);
1812 this->glTexCoord2f(tsx2, tsy2); 1768 this->glTexCoord2f (tsx2, tsy2);
1813 this->glVertex2i(tdx2, tdy2); 1769 this->glVertex2i (tdx2, tdy2);
1814 this->glTexCoord2f(tsx1, tsy2); 1770 this->glTexCoord2f (tsx1, tsy2);
1815 this->glVertex2i(tdx1, tdy2); 1771 this->glVertex2i (tdx1, tdy2);
1816 this->glEnd(); 1772 this->glEnd ();
1817 } 1773 }
1818 } 1774 }
1819 } 1775 }
1820 1776
1821 /* 1777 /*
1822 * Calculate the actual blit rectangle and source offset 1778 * Calculate the actual blit rectangle and source offset
1823 * for a blit from a rectangle in a surface with specified 1779 * for a blit from a rectangle in a surface with specified
1831 * Out: (x, y) source top-left offset 1787 * Out: (x, y) source top-left offset
1832 * rect destination rectangle 1788 * rect destination rectangle
1833 * 1789 *
1834 * Returns 1 if the result is visible, otherwise 0. 1790 * Returns 1 if the result is visible, otherwise 0.
1835 */ 1791 */
1836 static __inline__ int blitclip(SDL_Rect *rect, int w, int h, 1792 static __inline__ int
1837 int *x, int *y, SDL_Rect *clip) 1793 blitclip (SDL_Rect * rect, int w, int h, int *x, int *y, SDL_Rect * clip)
1838 { 1794 {
1839 int sx1, sy1, sx2, sy2; 1795 int sx1, sy1, sx2, sy2;
1840 int dx1, dy1, dx2, dy2; 1796 int dx1, dy1, dx2, dy2;
1841 1797
1842 /* Get source and destination coordinates */ 1798 /* Get source and destination coordinates */
1843 sx1 = rect->x; 1799 sx1 = rect->x;
1844 sy1 = rect->y; 1800 sy1 = rect->y;
1845 sx2 = sx1 + rect->w; 1801 sx2 = sx1 + rect->w;
1846 sy2 = sy1 + rect->h; 1802 sy2 = sy1 + rect->h;
1847 dx1 = *x; 1803 dx1 = *x;
1848 dy1 = *y; 1804 dy1 = *y;
1849 1805
1850 /* Keep source rect inside source surface */ 1806 /* Keep source rect inside source surface */
1851 if(sx1 < 0) 1807 if (sx1 < 0) {
1852 { 1808 dx1 -= sx1;
1853 dx1 -= sx1; 1809 sx1 = 0;
1854 sx1 = 0; 1810 }
1855 } 1811 if (sy1 < 0) {
1856 if(sy1 < 0) 1812 dy1 -= sy1;
1857 { 1813 sy1 = 0;
1858 dy1 -= sy1; 1814 }
1859 sy1 = 0; 1815 if (sx2 > w)
1860 } 1816 sx2 = w;
1861 if(sx2 > w) 1817 if (sy2 > h)
1862 sx2 = w; 1818 sy2 = h;
1863 if(sy2 > h) 1819
1864 sy2 = h; 1820 /* Cull blits from void space */
1865 1821 if (sx1 >= sx2 || sy1 >= sy2)
1866 /* Cull blits from void space */ 1822 return 0;
1867 if(sx1 >= sx2 || sy1 >= sy2) 1823
1868 return 0; 1824 /* Calculate destination lower-right */
1869 1825 dx2 = dx1 + (sx2 - sx1);
1870 /* Calculate destination lower-right */ 1826 dy2 = dy1 + (sy2 - sy1);
1871 dx2 = dx1 + (sx2 - sx1); 1827
1872 dy2 = dy1 + (sy2 - sy1); 1828 /* Clip to destination cliprect */
1873 1829 if (dx1 < clip->x) {
1874 /* Clip to destination cliprect */ 1830 sx1 += clip->x - dx1;
1875 if(dx1 < clip->x) 1831 dx1 = clip->x;
1876 { 1832 }
1877 sx1 += clip->x - dx1; 1833 if (dy1 < clip->y) {
1878 dx1 = clip->x; 1834 sy1 += clip->y - dy1;
1879 } 1835 dy1 = clip->y;
1880 if(dy1 < clip->y) 1836 }
1881 { 1837 if (dx2 > clip->x + clip->w)
1882 sy1 += clip->y - dy1; 1838 dx2 = clip->x + clip->w;
1883 dy1 = clip->y; 1839 if (dy2 > clip->y + clip->h)
1884 } 1840 dy2 = clip->y + clip->h;
1885 if(dx2 > clip->x + clip->w) 1841
1886 dx2 = clip->x + clip->w; 1842 /* Cull nop/off-screen blits */
1887 if(dy2 > clip->y + clip->h) 1843 if (dx1 >= dx2 || dy1 >= dy2)
1888 dy2 = clip->y + clip->h; 1844 return 0;
1889 1845
1890 /* Cull nop/off-screen blits */ 1846 *x = sx1;
1891 if(dx1 >= dx2 || dy1 >= dy2) 1847 *y = sy1;
1892 return 0; 1848 rect->x = dx1;
1893 1849 rect->y = dy1;
1894 *x = sx1; 1850 rect->w = dx2 - dx1;
1895 *y = sy1; 1851 rect->h = dy2 - dy1;
1896 rect->x = dx1; 1852 return 1;
1897 rect->y = dy1; 1853 }
1898 rect->w = dx2 - dx1; 1854
1899 rect->h = dy2 - dy1; 1855 static int
1900 return 1; 1856 glSDL_BlitGL (_THIS, SDL_Surface * src,
1901 } 1857 SDL_Rect * srcrect, SDL_Rect * dstrect)
1902 1858 {
1903 static int glSDL_BlitGL(_THIS, SDL_Surface *src, 1859 private_hwdata *txi;
1904 SDL_Rect *srcrect, SDL_Rect *dstrect) 1860 float x1, y1;
1905 { 1861 unsigned char alpha;
1906 private_hwdata *txi; 1862 SDL_Rect d;
1907 float x1, y1; 1863 int x, y;
1908 unsigned char alpha; 1864 SDL_Rect r;
1909 SDL_Rect d; 1865
1910 int x, y; 1866 if (!src)
1911 SDL_Rect r; 1867 return GLERET ("BlitGL(): No src surface!");
1912 1868
1913 if(!src) 1869 /* Get source and destination coordinates */
1914 return GLERET("BlitGL(): No src surface!"); 1870 if (srcrect)
1915 1871 r = *srcrect;
1916 /* Get source and destination coordinates */ 1872 else {
1917 if(srcrect) 1873 r.x = r.y = 0;
1918 r = *srcrect; 1874 r.w = src->w;
1919 else 1875 r.h = src->h;
1920 { 1876 }
1921 r.x = r.y = 0; 1877 if (dstrect) {
1922 r.w = src->w; 1878 x = dstrect->x;
1923 r.h = src->h; 1879 y = dstrect->y;
1924 } 1880 } else
1925 if(dstrect) 1881 x = y = 0;
1926 { 1882
1927 x = dstrect->x; 1883 /* Clip! */
1928 y = dstrect->y; 1884 if (!blitclip (&r, src->w, src->h, &x, &y, &this->screen->clip_rect)) {
1929 } 1885 if (dstrect)
1930 else 1886 dstrect->w = dstrect->h = 0;
1931 x = y = 0; 1887 return 0;
1932 1888 }
1933 /* Clip! */ 1889
1934 if(!blitclip(&r, src->w, src->h, &x, &y, &this->screen->clip_rect)) 1890 /* Write back the resulting cliprect */
1935 { 1891 if (dstrect)
1936 if(dstrect) 1892 *dstrect = r;
1937 dstrect->w = dstrect->h = 0; 1893
1938 return 0; 1894 /* Make sure we have a source with a valid texture */
1939 } 1895 txi = glSDL_UploadSurface (this, src);
1940 1896 if (!txi)
1941 /* Write back the resulting cliprect */ 1897 return GLERET ("BlitGL(): Could not get a TexInfo!");
1942 if(dstrect) 1898
1943 *dstrect = r; 1899 /* Set up blending */
1944 1900 if (src->flags & (SDL_SRCALPHA | SDL_SRCCOLORKEY)) {
1945 /* Make sure we have a source with a valid texture */ 1901 glSDL_blendfunc (this, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1946 txi = glSDL_UploadSurface(this, src); 1902 glSDL_do_blend (this, 1);
1947 if(!txi) 1903 } else
1948 return GLERET("BlitGL(): Could not get a TexInfo!"); 1904 glSDL_do_blend (this, 0);
1949 1905
1950 /* Set up blending */ 1906 /* Enable texturing */
1951 if(src->flags & (SDL_SRCALPHA | SDL_SRCCOLORKEY)) 1907 glSDL_do_texture (this, 1);
1952 { 1908
1953 glSDL_blendfunc(this, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1909 /* Calculate texcoords */
1954 glSDL_do_blend(this, 1); 1910 if (!srcrect)
1955 } 1911 srcrect = &txi->virt;
1956 else 1912 x1 = (float) srcrect->x;
1957 glSDL_do_blend(this, 0); 1913 y1 = (float) srcrect->y;
1958 1914
1959 /* Enable texturing */ 1915 /* Calculate screen coords. */
1960 glSDL_do_texture(this, 1); 1916 if (dstrect) {
1961 1917 d.x = dstrect->x;
1962 /* Calculate texcoords */ 1918 d.y = dstrect->y;
1963 if(!srcrect) 1919 d.w = (int) (srcrect->w * (float) txi->lw / (float) txi->virt.w);
1964 srcrect = &txi->virt; 1920 d.h = (int) (srcrect->h * (float) txi->lh / (float) txi->virt.h);
1965 x1 = (float)srcrect->x; 1921 } else {
1966 y1 = (float)srcrect->y; 1922 d.x = 0;
1967 1923 d.y = 0;
1968 /* Calculate screen coords. */ 1924 d.w = (int) (srcrect->w * (float) txi->lw / (float) txi->virt.w);
1969 if(dstrect) 1925 d.h = (int) (srcrect->h * (float) txi->lh / (float) txi->virt.h);
1970 { 1926 }
1971 d.x = dstrect->x; 1927
1972 d.y = dstrect->y; 1928 /*
1973 d.w = (int)(srcrect->w * (float)txi->lw / (float)txi->virt.w); 1929 * Note that we actually *prevent* the use of "full surface alpha"
1974 d.h = (int)(srcrect->h * (float)txi->lh / (float)txi->virt.h); 1930 * and alpha channel in combination - to stay SDL 2D compatible.
1975 } 1931 */
1976 else 1932 if ((src->flags & SDL_SRCALPHA) && (src->format->Amask))
1977 { 1933 alpha = 255;
1978 d.x = 0; 1934 else
1979 d.y = 0; 1935 alpha = src->format->alpha;
1980 d.w = (int)(srcrect->w * (float)txi->lw / (float)txi->virt.w); 1936
1981 d.h = (int)(srcrect->h * (float)txi->lh / (float)txi->virt.h); 1937 /* Render! */
1982 } 1938 switch (txi->tilemode) {
1983 1939 case GLSDL_TM_SINGLE:
1984 /* 1940 glSDL_BlitGL_single (this, txi, x1, y1, &d, alpha);
1985 * Note that we actually *prevent* the use of "full surface alpha" 1941 break;
1986 * and alpha channel in combination - to stay SDL 2D compatible. 1942 case GLSDL_TM_HORIZONTAL:
1987 */ 1943 glSDL_BlitGL_htile (this, txi, x1, y1, &d, alpha);
1988 if ((src->flags & SDL_SRCALPHA)&&(src->format->Amask)) 1944 break;
1989 alpha = 255; 1945 case GLSDL_TM_VERTICAL:
1990 else 1946 glSDL_BlitGL_vtile (this, txi, x1, y1, &d, alpha);
1991 alpha = src->format->alpha; 1947 break;
1992 1948 case GLSDL_TM_HUGE:
1993 /* Render! */ 1949 glSDL_BlitGL_hvtile (this, src, txi, x1, y1, &d, alpha);
1994 switch(txi->tilemode) 1950 break;
1995 { 1951 }
1996 case GLSDL_TM_SINGLE: 1952
1997 glSDL_BlitGL_single(this, txi, x1, y1, 1953 if (txi->temporary)
1998 &d, 1954 glSDL_FreeTexInfo (this, txi);
1999 alpha); 1955
2000 break; 1956 return 0;
2001 case GLSDL_TM_HORIZONTAL: 1957 }
2002 glSDL_BlitGL_htile(this, txi, x1, y1, 1958
2003 &d, 1959
2004 alpha); 1960 static int
2005 break; 1961 glSDL_HWAccelBlit (SDL_Surface * src, SDL_Rect * srcrect,
2006 case GLSDL_TM_VERTICAL: 1962 SDL_Surface * dst, SDL_Rect * dstrect)
2007 glSDL_BlitGL_vtile(this, txi, x1, y1, 1963 {
2008 &d, 1964 SDL_Surface *vs;
2009 alpha); 1965
2010 break; 1966 if (!src)
2011 case GLSDL_TM_HUGE: 1967 return GLERET ("HWAccelBlit(): No src surface!");
2012 glSDL_BlitGL_hvtile(this, src, txi, x1, y1, 1968 if (!dst)
2013 &d, 1969 return GLERET ("HWAccelBlit(): No dst surface!");
2014 alpha); 1970
2015 break; 1971 /*
2016 } 1972 * Figure out what to do:
2017 1973 * screen->screen: glSDL_BlitFromGL() + glSDL_BlitGL()
2018 if(txi->temporary) 1974 * surface->screen: glSDL_BlitGL()
2019 glSDL_FreeTexInfo(this, txi); 1975 * screen->surface: glSDL_BlitFromGL()
2020 1976 * surface->surface: glSDL_SoftBlit()
2021 return 0; 1977 */
2022 } 1978 vs = SDL_VideoSurface;
2023 1979 if (src == vs) {
2024 1980 if (dst == vs) {
2025 static int glSDL_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, 1981 /*
2026 SDL_Surface *dst, SDL_Rect *dstrect) 1982 FIXME: Try glCopyPixels() instead...
2027 { 1983 */
2028 SDL_Surface *vs; 1984 glSDL_BlitFromGL (current_video, srcrect, vs, dstrect);
2029 1985 return glSDL_BlitGL (current_video, vs, srcrect, dstrect);
2030 if(!src) 1986 } else {
2031 return GLERET("HWAccelBlit(): No src surface!"); 1987 return glSDL_BlitFromGL (current_video, srcrect, dst, dstrect);
2032 if(!dst) 1988 }
2033 return GLERET("HWAccelBlit(): No dst surface!"); 1989 } else {
2034 1990 if (dst == vs) {
2035 /* 1991 return glSDL_BlitGL (current_video, src, srcrect, dstrect);
2036 * Figure out what to do: 1992 } else {
2037 * screen->screen: glSDL_BlitFromGL() + glSDL_BlitGL() 1993 glSDL_Invalidate (dst, dstrect);
2038 * surface->screen: glSDL_BlitGL() 1994 glSDL_SoftBlit (src, srcrect, dst, dstrect);
2039 * screen->surface: glSDL_BlitFromGL() 1995 return 0;
2040 * surface->surface: glSDL_SoftBlit() 1996 }
2041 */ 1997 }
2042 vs = SDL_VideoSurface; 1998 }
2043 if(src == vs) 1999
2044 { 2000
2045 if(dst == vs) 2001 static int
2046 { 2002 glSDL_FillHWRect (_THIS, SDL_Surface * dst, SDL_Rect * dstrect, Uint32 color)
2047 /* 2003 {
2048 FIXME: Try glCopyPixels() instead... 2004 SDL_Surface *vs = SDL_VideoSurface;
2049 */ 2005 int dx1, dy1, dx2, dy2;
2050 glSDL_BlitFromGL(current_video, srcrect, vs, dstrect); 2006 Uint32 r, g, b;
2051 return glSDL_BlitGL(current_video, vs, 2007 Uint8 br, bg, bb;
2052 srcrect, dstrect); 2008
2053 } 2009 /*
2054 else 2010 * Some ugly reverse conversion for compatibility...
2055 { 2011 * (We must do this before losing the dst pointer,
2056 return glSDL_BlitFromGL(current_video, srcrect, 2012 * as the pixel formats of the screen and
2057 dst, dstrect); 2013 * SDL_VideoSurface may differ!)
2058 } 2014 */
2059 } 2015
2060 else 2016 if (dst->format->palette) {
2061 { 2017 /* this a paletted color */
2062 if(dst == vs) 2018 SDL_GetRGB (color, dst->format, &br, &bg, &bb);
2063 { 2019 } else {
2064 return glSDL_BlitGL(current_video, src, 2020 /* this a RGB color */
2065 srcrect, dstrect); 2021 r = color & dst->format->Rmask;
2066 } 2022 r = r >> dst->format->Rshift;
2067 else 2023 r = r << dst->format->Rloss;
2068 { 2024 br = r;
2069 glSDL_Invalidate(dst, dstrect); 2025
2070 glSDL_SoftBlit(src, srcrect, dst, dstrect); 2026 g = color & dst->format->Gmask;
2071 return 0; 2027 g = g >> dst->format->Gshift;
2072 } 2028 g = g << dst->format->Gloss;
2073 } 2029 bg = g;
2074 } 2030
2075 2031 b = color & dst->format->Bmask;
2076 2032 b = b >> dst->format->Bshift;
2077 static int glSDL_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color) 2033 b = b << dst->format->Bloss;
2078 { 2034 bb = b;
2079 SDL_Surface *vs = SDL_VideoSurface; 2035 }
2080 int dx1, dy1, dx2, dy2; 2036
2081 Uint32 r, g, b; 2037 if (vs != dst) {
2082 Uint8 br,bg,bb; 2038 /* draw a rect offscreen */
2083 2039 glSDL_Invalidate (dst, dstrect);
2084 /* 2040 /* software-fill the surface by faking it as a SW_SURFACE */
2085 * Some ugly reverse conversion for compatibility... 2041 dst->flags &= ~SDL_HWSURFACE;
2086 * (We must do this before losing the dst pointer, 2042 SDL_FillRect (dst, dstrect, color);
2087 * as the pixel formats of the screen and 2043 dst->flags |= SDL_HWSURFACE;
2088 * SDL_VideoSurface may differ!) 2044 } else {
2089 */ 2045 /* draw a rect onscreen */
2090 2046 glSDL_do_texture (this, 0);
2091 if (dst->format->palette) 2047 glSDL_do_blend (this, 0);
2092 { 2048
2093 /* this a paletted color */ 2049 dx1 = dstrect->x;
2094 SDL_GetRGB(color,dst->format,&br,&bg,&bb); 2050 dy1 = dstrect->y;
2095 } 2051 dx2 = dx1 + dstrect->w;
2096 else 2052 dy2 = dy1 + dstrect->h;
2097 { 2053
2098 /* this a RGB color */ 2054 this->glBegin (GL_TRIANGLE_FAN);
2099 r = color & dst->format->Rmask; 2055 this->glColor3ub (br, bg, bb);
2100 r = r >> dst->format->Rshift; 2056 this->glVertex2i (dx1, dy1);
2101 r = r << dst->format->Rloss; 2057 this->glVertex2i (dx2, dy1);
2102 br = r; 2058 this->glVertex2i (dx2, dy2);
2103 2059 this->glVertex2i (dx1, dy2);
2104 g = color & dst->format->Gmask; 2060 this->glEnd ();
2105 g = g >> dst->format->Gshift; 2061 }
2106 g = g << dst->format->Gloss; 2062 return 0;
2107 bg = g; 2063 }
2108 2064
2109 b = color & dst->format->Bmask; 2065 static int
2110 b = b >> dst->format->Bshift; 2066 glSDL_CheckHWBlit (_THIS, SDL_Surface * src, SDL_Surface * dst)
2111 b = b << dst->format->Bloss; 2067 {
2112 bb = b; 2068 src->flags |= SDL_HWACCEL;
2113 } 2069 src->map->hw_blit = glSDL_HWAccelBlit;
2114 2070 return 1;
2115 if(vs != dst) 2071 }
2116 { 2072
2117 /* draw a rect offscreen */ 2073
2118 glSDL_Invalidate(dst, dstrect); 2074 static SDL_Surface *
2119 /* software-fill the surface by faking it as a SW_SURFACE */ 2075 glSDL_DisplayFormat (SDL_Surface * surface)
2120 dst->flags&=~SDL_HWSURFACE; 2076 {
2121 SDL_FillRect(dst,dstrect,color); 2077 SDL_Surface *tmp;
2122 dst->flags|=SDL_HWSURFACE; 2078 int use_rgba = (surface->flags & SDL_SRCCOLORKEY) ||
2123 } 2079 ((surface->flags & SDL_SRCALPHA) && surface->format->Amask);
2124 else
2125 {
2126 /* draw a rect onscreen */
2127 glSDL_do_texture(this, 0);
2128 glSDL_do_blend(this, 0);
2129
2130 dx1 = dstrect->x;
2131 dy1 = dstrect->y;
2132 dx2 = dx1 + dstrect->w;
2133 dy2 = dy1 + dstrect->h;
2134
2135 this->glBegin(GL_TRIANGLE_FAN);
2136 this->glColor3ub(br, bg, bb);
2137 this->glVertex2i(dx1, dy1);
2138 this->glVertex2i(dx2, dy1);
2139 this->glVertex2i(dx2, dy2);
2140 this->glVertex2i(dx1, dy2);
2141 this->glEnd();
2142 }
2143 return 0;
2144 }
2145
2146 static int glSDL_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst)
2147 {
2148 src->flags |= SDL_HWACCEL;
2149 src->map->hw_blit = glSDL_HWAccelBlit;
2150 return 1;
2151 }
2152
2153
2154 static SDL_Surface *glSDL_DisplayFormat(SDL_Surface *surface)
2155 {
2156 SDL_Surface *tmp;
2157 int use_rgba = (surface->flags & SDL_SRCCOLORKEY) ||
2158 ((surface->flags & SDL_SRCALPHA) &&
2159 surface->format->Amask);
2160 #ifdef DEBUG_GLSDL 2080 #ifdef DEBUG_GLSDL
2161 fprintf(stderr,"#### glSDL_DisplayFormat()\n"); 2081 fprintf (stderr, "#### glSDL_DisplayFormat()\n");
2162 #endif 2082 #endif
2163 if(use_rgba) 2083 if (use_rgba)
2164 tmp = glSDL_ConvertSurface(surface, RGBAfmt, SDL_SWSURFACE); 2084 tmp = glSDL_ConvertSurface (surface, RGBAfmt, SDL_SWSURFACE);
2165 else 2085 else
2166 tmp = glSDL_ConvertSurface(surface, RGBfmt, SDL_SWSURFACE); 2086 tmp = glSDL_ConvertSurface (surface, RGBfmt, SDL_SWSURFACE);
2167 if(!tmp) 2087 if (!tmp) {
2168 { 2088 GLERR ("glSDL_DisplayFormat() could not convert surface!");
2169 GLERR("glSDL_DisplayFormat() could not convert surface!"); 2089 return NULL;
2170 return NULL; 2090 }
2171 } 2091 SDL_SetAlpha (tmp, 0, 0);
2172 SDL_SetAlpha(tmp, 0, 0); 2092
2173 2093 if (surface->flags & SDL_SRCCOLORKEY) {
2174 if(surface->flags & SDL_SRCCOLORKEY) 2094 /*
2175 { 2095 * We drop colorkey data here, but we have to,
2176 /* 2096 * or we'll run into trouble when converting,
2177 * We drop colorkey data here, but we have to, 2097 * in particular from indexed color formats.
2178 * or we'll run into trouble when converting, 2098 */
2179 * in particular from indexed color formats. 2099 SDL_SetColorKey (tmp, SDL_SRCCOLORKEY, surface->format->colorkey);
2180 */ 2100 glSDL_key2alpha (tmp);
2181 SDL_SetColorKey(tmp, SDL_SRCCOLORKEY, 2101 SDL_SetColorKey (tmp, 0, 0);
2182 surface->format->colorkey); 2102 }
2183 glSDL_key2alpha(tmp); 2103
2184 SDL_SetColorKey(tmp, 0, 0); 2104 return tmp;
2185 } 2105 }
2186 2106
2187 return tmp; 2107
2188 } 2108 static SDL_Surface *
2189 2109 glSDL_DisplayFormatAlpha (SDL_Surface * surface)
2190 2110 {
2191 static SDL_Surface *glSDL_DisplayFormatAlpha(SDL_Surface *surface) 2111 SDL_Surface *s, *tmp;
2192 { 2112 tmp = glSDL_ConvertSurface (surface, RGBAfmt, SDL_SWSURFACE);
2193 SDL_Surface *s, *tmp;
2194 tmp = glSDL_ConvertSurface(surface, RGBAfmt, SDL_SWSURFACE);
2195 #ifdef DEBUG_GLSDL 2113 #ifdef DEBUG_GLSDL
2196 fprintf(stderr,"#### glSDL_DisplayFormatAlpha()\n"); 2114 fprintf (stderr, "#### glSDL_DisplayFormatAlpha()\n");
2197 #endif 2115 #endif
2198 if(!tmp) 2116 if (!tmp)
2199 return NULL; 2117 return NULL;
2200 2118
2201 SDL_SetAlpha(tmp, 0, 0); 2119 SDL_SetAlpha (tmp, 0, 0);
2202 SDL_SetColorKey(tmp, 0, 0); 2120 SDL_SetColorKey (tmp, 0, 0);
2203 s = glSDL_CreateRGBASurface(surface->w, surface->h); 2121 s = glSDL_CreateRGBASurface (surface->w, surface->h);
2204 if(!s) 2122 if (!s) {
2205 { 2123 SDL_FreeSurface (tmp);
2206 SDL_FreeSurface(tmp); 2124 return NULL;
2207 return NULL; 2125 }
2208 } 2126 glSDL_SoftBlit (tmp, NULL, s, NULL);
2209 glSDL_SoftBlit(tmp, NULL, s, NULL); 2127 SDL_FreeSurface (tmp);
2210 SDL_FreeSurface(tmp); 2128
2211 2129 if (surface->flags & SDL_SRCCOLORKEY) {
2212 if(surface->flags & SDL_SRCCOLORKEY) 2130 SDL_SetColorKey (s, SDL_SRCCOLORKEY, surface->format->colorkey);
2213 { 2131 glSDL_key2alpha (s);
2214 SDL_SetColorKey(s, SDL_SRCCOLORKEY, 2132 SDL_SetColorKey (s, 0, 0);
2215 surface->format->colorkey); 2133 }
2216 glSDL_key2alpha(s); 2134
2217 SDL_SetColorKey(s, 0, 0); 2135 if (surface->flags & SDL_SRCALPHA)
2218 } 2136 SDL_SetAlpha (s, SDL_SRCALPHA, surface->format->alpha);
2219 2137 return s;
2220 if(surface->flags & SDL_SRCALPHA)
2221 SDL_SetAlpha(s, SDL_SRCALPHA,
2222 surface->format->alpha);
2223 return s;
2224 } 2138 }
2225 2139
2226 2140
2227 /*---------------------------------------------------------- 2141 /*----------------------------------------------------------
2228 glSDL specific API extensions 2142 glSDL specific API extensions
2229 ----------------------------------------------------------*/ 2143 ----------------------------------------------------------*/
2230 2144
2231 static void glSDL_Invalidate(SDL_Surface *surface, SDL_Rect *area) 2145 static void
2232 { 2146 glSDL_Invalidate (SDL_Surface * surface, SDL_Rect * area)
2233 private_hwdata *txi; 2147 {
2234 if(!surface) 2148 private_hwdata *txi;
2235 return; 2149 if (!surface)
2236 txi = glSDL_GetTexInfo(surface); 2150 return;
2237 if(!txi) 2151 txi = glSDL_GetTexInfo (surface);
2238 return; 2152 if (!txi)
2239 if(!area) 2153 return;
2240 { 2154 if (!area) {
2241 txi->invalid_area.x = 0; 2155 txi->invalid_area.x = 0;
2242 txi->invalid_area.y = 0; 2156 txi->invalid_area.y = 0;
2243 txi->invalid_area.w = surface->w; 2157 txi->invalid_area.w = surface->w;
2244 txi->invalid_area.h = surface->h; 2158 txi->invalid_area.h = surface->h;
2245 return; 2159 return;
2246 } 2160 }
2247 txi->invalid_area = *area; 2161 txi->invalid_area = *area;
2248 } 2162 }
2249 2163
2250 2164
2251 static void glSDL_SetLogicSize(_THIS, SDL_Surface *surface, int w, int h) 2165 static void
2252 { 2166 glSDL_SetLogicSize (_THIS, SDL_Surface * surface, int w, int h)
2253 SDL_Rect r; 2167 {
2254 private_hwdata *txi; 2168 SDL_Rect r;
2255 if(!IS_GLSDL_SURFACE(surface)) 2169 private_hwdata *txi;
2256 return; 2170 if (!IS_GLSDL_SURFACE (surface))
2257 2171 return;
2258 txi = glSDL_GetTexInfo(surface); 2172
2259 2173 txi = glSDL_GetTexInfo (surface);
2260 txi->lw = w; 2174
2261 txi->lh = h; 2175 txi->lw = w;
2262 2176 txi->lh = h;
2263 if(SDL_VideoSurface != surface) 2177
2264 return; 2178 if (SDL_VideoSurface != surface)
2265 2179 return;
2266 r.x = r.y = 0; 2180
2267 r.w = w; 2181 r.x = r.y = 0;
2268 r.h = h; 2182 r.w = w;
2269 glSDL_SetClipRect(this, surface, &r); 2183 r.h = h;
2270 2184 glSDL_SetClipRect (this, surface, &r);
2271 this->glMatrixMode(GL_MODELVIEW); 2185
2272 this->glLoadIdentity(); 2186 this->glMatrixMode (GL_MODELVIEW);
2273 this->glTranslated(0.0f, 0.0f, 0.0f); 2187 this->glLoadIdentity ();
2274 2188 this->glTranslated (0.0f, 0.0f, 0.0f);
2275 this->glDisable(GL_DEPTH_TEST); 2189
2276 this->glDisable(GL_CULL_FACE); 2190 this->glDisable (GL_DEPTH_TEST);
2277 2191 this->glDisable (GL_CULL_FACE);
2278 glSDL_reset(); 2192
2279 } 2193 glSDL_reset ();
2280 2194 }
2281 static int glSDL_InitTexture(_THIS, SDL_Surface *datasurf, private_hwdata *txi, int tex) 2195
2282 { 2196 static int
2283 this->glGenTextures(1, (GLuint *)&txi->texture[tex]); 2197 glSDL_InitTexture (_THIS, SDL_Surface * datasurf, private_hwdata * txi,
2284 this->glBindTexture(GL_TEXTURE_2D, txi->texture[tex]); 2198 int tex)
2285 glstate.texture = txi->texture[tex]; 2199 {
2286 this->glPixelStorei(GL_UNPACK_ROW_LENGTH, datasurf->pitch / 2200 this->glGenTextures (1, (GLuint *) & txi->texture[tex]);
2287 datasurf->format->BytesPerPixel); 2201 this->glBindTexture (GL_TEXTURE_2D, txi->texture[tex]);
2288 this->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 2202 glstate.texture = txi->texture[tex];
2289 this->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 2203 this->glPixelStorei (GL_UNPACK_ROW_LENGTH, datasurf->pitch /
2290 this->glTexImage2D(GL_TEXTURE_2D, 0, 2204 datasurf->format->BytesPerPixel);
2291 datasurf->format->Amask ? GL_RGBA8 : GL_RGB8, 2205 this->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2292 txi->texsize, txi->texsize, 0, 2206 this->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2293 datasurf->format->Amask ? GL_RGBA : GL_RGB, 2207 this->glTexImage2D (GL_TEXTURE_2D, 0,
2294 GL_UNSIGNED_BYTE, NULL); 2208 datasurf->format->Amask ? GL_RGBA8 : GL_RGB8,
2295 #ifdef DEBUG_GLSDL 2209 txi->texsize, txi->texsize, 0,
2296 glSDL_print_glerror(this, 1); 2210 datasurf->format->Amask ? GL_RGBA : GL_RGB,
2297 #endif 2211 GL_UNSIGNED_BYTE, NULL);
2298 return 0; 2212 #ifdef DEBUG_GLSDL
2213 glSDL_print_glerror (this, 1);
2214 #endif
2215 return 0;
2299 } 2216 }
2300 2217
2301 2218
2302 /* Image tiled horizontally (wide surface), or not at all */ 2219 /* Image tiled horizontally (wide surface), or not at all */
2303 static int glSDL_UploadHoriz(_THIS, SDL_Surface *datasurf, private_hwdata *txi) 2220 static int
2304 { 2221 glSDL_UploadHoriz (_THIS, SDL_Surface * datasurf, private_hwdata * txi)
2305 int bpp = datasurf->format->BytesPerPixel; 2222 {
2306 int res; 2223 int bpp = datasurf->format->BytesPerPixel;
2307 int tex = 0; 2224 int res;
2308 int fromx = 0; 2225 int tex = 0;
2309 int toy = txi->texsize; /* To init first texture */ 2226 int fromx = 0;
2310 while(1) 2227 int toy = txi->texsize; /* To init first texture */
2311 { 2228 while (1) {
2312 int thistw = datasurf->w - fromx; 2229 int thistw = datasurf->w - fromx;
2313 if(thistw > txi->tilew) 2230 if (thistw > txi->tilew)
2314 thistw = txi->tilew; 2231 thistw = txi->tilew;
2315 else if(thistw <= 0) 2232 else if (thistw <= 0)
2316 break; 2233 break;
2317 if(toy + txi->tileh > txi->texsize) 2234 if (toy + txi->tileh > txi->texsize) {
2318 { 2235 toy = 0;
2319 toy = 0; 2236 res = glSDL_InitTexture (this, datasurf, txi, tex);
2320 res = glSDL_InitTexture(this, datasurf, txi, tex); 2237 if (res < 0)
2321 if(res < 0) 2238 return res;
2322 return res; 2239 ++tex;
2323 ++tex; 2240 }
2324 } 2241 this->glTexSubImage2D (GL_TEXTURE_2D, 0, 0, toy,
2325 this->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, toy, 2242 thistw, txi->tileh,
2326 thistw, txi->tileh, 2243 datasurf->format->Amask ? GL_RGBA : GL_RGB,
2327 datasurf->format->Amask ? GL_RGBA : GL_RGB, 2244 GL_UNSIGNED_BYTE,
2328 GL_UNSIGNED_BYTE, 2245 (char *) datasurf->pixels + bpp * fromx);
2329 (char *)datasurf->pixels + bpp * fromx); 2246 #ifdef DEBUG_GLSDL
2330 #ifdef DEBUG_GLSDL 2247 glSDL_print_glerror (this, 2);
2331 glSDL_print_glerror(this, 2); 2248 #endif
2332 #endif 2249 fromx += txi->tilew;
2333 fromx += txi->tilew; 2250 toy += txi->tileh;
2334 toy += txi->tileh; 2251 }
2335 } 2252 return 0;
2336 return 0;
2337 } 2253 }
2338 2254
2339 2255
2340 /* Image tiled vertically (tall surface) */ 2256 /* Image tiled vertically (tall surface) */
2341 static int glSDL_UploadVert(_THIS, SDL_Surface *datasurf, private_hwdata *txi) 2257 static int
2342 { 2258 glSDL_UploadVert (_THIS, SDL_Surface * datasurf, private_hwdata * txi)
2343 int res; 2259 {
2344 int tex = 0; 2260 int res;
2345 int fromy = 0; 2261 int tex = 0;
2346 int tox = txi->texsize; /* To init first texture */ 2262 int fromy = 0;
2347 while(1) 2263 int tox = txi->texsize; /* To init first texture */
2348 { 2264 while (1) {
2349 int thisth = datasurf->h - fromy; 2265 int thisth = datasurf->h - fromy;
2350 if(thisth > txi->tileh) 2266 if (thisth > txi->tileh)
2351 thisth = txi->tileh; 2267 thisth = txi->tileh;
2352 else if(thisth <= 0) 2268 else if (thisth <= 0)
2353 break; 2269 break;
2354 if(tox + txi->tilew > txi->texsize) 2270 if (tox + txi->tilew > txi->texsize) {
2355 { 2271 tox = 0;
2356 tox = 0; 2272 res = glSDL_InitTexture (this, datasurf, txi, tex);
2357 res = glSDL_InitTexture(this, datasurf, txi, tex); 2273 if (res < 0)
2358 if(res < 0) 2274 return res;
2359 return res; 2275 ++tex;
2360 ++tex; 2276 }
2361 } 2277 this->glTexSubImage2D (GL_TEXTURE_2D, 0, tox, 0,
2362 this->glTexSubImage2D(GL_TEXTURE_2D, 0, tox, 0, 2278 txi->tilew, thisth,
2363 txi->tilew, thisth, 2279 datasurf->format->Amask ? GL_RGBA : GL_RGB,
2364 datasurf->format->Amask ? GL_RGBA : GL_RGB, 2280 GL_UNSIGNED_BYTE,
2365 GL_UNSIGNED_BYTE, 2281 (char *) datasurf->pixels +
2366 (char *)datasurf->pixels + datasurf->pitch * fromy); 2282 datasurf->pitch * fromy);
2367 #ifdef DEBUG_GLSDL 2283 #ifdef DEBUG_GLSDL
2368 glSDL_print_glerror(this, 3); 2284 glSDL_print_glerror (this, 3);
2369 #endif 2285 #endif
2370 fromy += txi->tileh; 2286 fromy += txi->tileh;
2371 tox += txi->tilew; 2287 tox += txi->tilew;
2372 } 2288 }
2373 return 0; 2289 return 0;
2374 } 2290 }
2375 2291
2376 2292
2377 /* Image tiled two-way (huge surface) */ 2293 /* Image tiled two-way (huge surface) */
2378 static int glSDL_UploadHuge(_THIS, SDL_Surface *datasurf, private_hwdata *txi) 2294 static int
2379 { 2295 glSDL_UploadHuge (_THIS, SDL_Surface * datasurf, private_hwdata * txi)
2380 int bpp = datasurf->format->BytesPerPixel; 2296 {
2381 int res; 2297 int bpp = datasurf->format->BytesPerPixel;
2382 int tex = 0; 2298 int res;
2383 int y = 0; 2299 int tex = 0;
2384 while(y < datasurf->h) 2300 int y = 0;
2385 { 2301 while (y < datasurf->h) {
2386 int x; 2302 int x;
2387 int thisth = datasurf->h - y; 2303 int thisth = datasurf->h - y;
2388 if(thisth > txi->tileh) 2304 if (thisth > txi->tileh)
2389 thisth = txi->tileh; 2305 thisth = txi->tileh;
2390 x = 0; 2306 x = 0;
2391 while(x < datasurf->w) 2307 while (x < datasurf->w) {
2392 { 2308 int thistw = datasurf->w - x;
2393 int thistw = datasurf->w - x; 2309 if (thistw > txi->tilew)
2394 if(thistw > txi->tilew) 2310 thistw = txi->tilew;
2395 thistw = txi->tilew; 2311 res = glSDL_InitTexture (this, datasurf, txi, tex++);
2396 res = glSDL_InitTexture(this, datasurf, txi, tex++); 2312 if (res < 0)
2397 if(res < 0) 2313 return res;
2398 return res; 2314 this->glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0,
2399 this->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2315 thistw, thisth,
2400 thistw, thisth, 2316 datasurf->format->
2401 datasurf->format->Amask ? GL_RGBA : GL_RGB, 2317 Amask ? GL_RGBA : GL_RGB,
2402 GL_UNSIGNED_BYTE, 2318 GL_UNSIGNED_BYTE,
2403 (char *)datasurf->pixels + 2319 (char *) datasurf->pixels +
2404 datasurf->pitch * y + bpp * x); 2320 datasurf->pitch * y + bpp * x);
2405 #ifdef DEBUG_GLSDL 2321 #ifdef DEBUG_GLSDL
2406 fprintf(stderr,"glTexSubImage(x = %d, y = %d, w = %d, h = %d)\n", 2322 fprintf (stderr,
2407 x, y, thistw, thisth); 2323 "glTexSubImage(x = %d, y = %d, w = %d, h = %d)\n", x,
2408 glSDL_print_glerror(this, 4); 2324 y, thistw, thisth);
2409 #endif 2325 glSDL_print_glerror (this, 4);
2410 x += txi->tilew; 2326 #endif
2411 } 2327 x += txi->tilew;
2412 y += txi->tileh; 2328 }
2413 } 2329 y += txi->tileh;
2414 return 0; 2330 }
2331 return 0;
2415 } 2332 }
2416 2333
2417 2334
2418 /* Upload all textures for a surface. */ 2335 /* Upload all textures for a surface. */
2419 static int glSDL_UploadTextures(_THIS, SDL_Surface *datasurf, private_hwdata *txi) 2336 static int
2420 { 2337 glSDL_UploadTextures (_THIS, SDL_Surface * datasurf, private_hwdata * txi)
2421 switch(txi->tilemode) 2338 {
2422 { 2339 switch (txi->tilemode) {
2423 case GLSDL_TM_SINGLE: 2340 case GLSDL_TM_SINGLE:
2424 case GLSDL_TM_HORIZONTAL: 2341 case GLSDL_TM_HORIZONTAL:
2425 glSDL_UploadHoriz(this, datasurf, txi); 2342 glSDL_UploadHoriz (this, datasurf, txi);
2426 break; 2343 break;
2427 case GLSDL_TM_VERTICAL: 2344 case GLSDL_TM_VERTICAL:
2428 glSDL_UploadVert(this, datasurf, txi); 2345 glSDL_UploadVert (this, datasurf, txi);
2429 break; 2346 break;
2430 case GLSDL_TM_HUGE: 2347 case GLSDL_TM_HUGE:
2431 glSDL_UploadHuge(this, datasurf, txi); 2348 glSDL_UploadHuge (this, datasurf, txi);
2432 break; 2349 break;
2433 } 2350 }
2434 return 0; 2351 return 0;
2435 } 2352 }
2436 2353
2437 2354
2438 /* 2355 /*
2439 * IMPORTANT: 2356 * IMPORTANT:
2444 * (as opposed to connected to 'surface'). A temporary 2361 * (as opposed to connected to 'surface'). A temporary
2445 * TexInfo must be used only once and then thrown away, 2362 * TexInfo must be used only once and then thrown away,
2446 * since it means that glSDL cannot track changes in 2363 * since it means that glSDL cannot track changes in
2447 * the pixel data of 'texture'. 2364 * the pixel data of 'texture'.
2448 */ 2365 */
2449 static private_hwdata *glSDL_UploadSurface(_THIS, SDL_Surface *surface) 2366 static private_hwdata *
2450 { 2367 glSDL_UploadSurface (_THIS, SDL_Surface * surface)
2451 int i; 2368 {
2452 int converted = 0; 2369 int i;
2453 private_hwdata *txi = glSDL_GetTexInfo(surface); 2370 int converted = 0;
2454 2371 private_hwdata *txi = glSDL_GetTexInfo (surface);
2455 if(IS_GLSDL_SURFACE(surface)) 2372
2456 { 2373 if (IS_GLSDL_SURFACE (surface)) {
2457 /* 2374 /*
2458 * Ok, this is a glSDL surface, and it *might* be 2375 * Ok, this is a glSDL surface, and it *might* be
2459 * in texture memory already. If so, it may need 2376 * in texture memory already. If so, it may need
2460 * an update. 2377 * an update.
2461 */ 2378 */
2462 if(txi->invalid_area.w) 2379 if (txi->invalid_area.w) {
2463 { 2380 glSDL_UnloadTexture (this, txi);
2464 glSDL_UnloadTexture(this, txi); 2381 } else {
2465 } 2382 int missing = 0;
2466 else 2383 if (txi->textures) {
2467 { 2384 for (i = 0; i < txi->textures; ++i)
2468 int missing = 0; 2385 if (GLSDL_NOTEX == txi->texture[i]) {
2469 if(txi->textures) 2386 missing = 1;
2470 { 2387 break;
2471 for(i = 0; i < txi->textures; ++i) 2388 }
2472 if(GLSDL_NOTEX == txi->texture[i]) 2389 if (!missing)
2473 { 2390 return txi; /* They're already there! */
2474 missing = 1; 2391 }
2475 break; 2392 }
2476 } 2393 } else {
2477 if(!missing) 2394 /*
2478 return txi; /* They're already there! */ 2395 * Nope, this isn't (yet) a glSDL surface. Let's
2479 } 2396 * try to either make it one, or set up a temporary
2480 } 2397 * TexInfo for it, valid for only one blit.
2481 } 2398 */
2482 else 2399 if ((surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE) {
2483 { 2400 txi = glSDL_AddTexInfo (this, surface);
2484 /* 2401 if (!txi) {
2485 * Nope, this isn't (yet) a glSDL surface. Let's 2402 GLERR ("UploadSurface(): Could not add TexInfo!");
2486 * try to either make it one, or set up a temporary 2403 return NULL;
2487 * TexInfo for it, valid for only one blit. 2404 }
2488 */ 2405 surface->flags |= SDL_HWSURFACE;
2489 if( (surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) 2406 surface->flags |= SDL_HWACCEL;
2490 { 2407 } else {
2491 txi = glSDL_AddTexInfo(this, surface); 2408 /*
2492 if(!txi) 2409 * FIXME
2493 { 2410 * here if the surface is small enough, it's a good
2494 GLERR("UploadSurface(): Could not add TexInfo!"); 2411 * candidate for a blit using glDrawPixels instead
2495 return NULL; 2412 * of a texture blit
2496 } 2413 */
2497 surface->flags |= SDL_HWSURFACE; 2414 txi = glSDL_CreateTempTexInfo (this, surface);
2498 surface->flags |= SDL_HWACCEL; 2415 if (!txi) {
2499 } 2416 GLERR ("UploadSurface(): Could not create temp TexInfo!");
2500 else 2417 return NULL;
2501 { 2418 }
2502 /* 2419 }
2503 * FIXME 2420 }
2504 * here if the surface is small enough, it's a good 2421
2505 * candidate for a blit using glDrawPixels instead 2422 if (txi->texsize > maxtexsize) {
2506 * of a texture blit 2423 /* This surface wasn't tiled properly... */
2507 */ 2424 if (txi->temporary)
2508 txi = glSDL_CreateTempTexInfo(this, surface); 2425 glSDL_FreeTexInfo (this, txi);
2509 if(!txi) 2426 GLERR ("UploadSurface(): Too large texture!");
2510 { 2427 return NULL;
2511 GLERR("UploadSurface(): Could not create temp TexInfo!"); 2428 }
2512 return NULL; 2429
2513 } 2430 /*
2514 } 2431 * Kludge: Convert if not of preferred RGB or RGBA format.
2515 } 2432 *
2516 2433 * Conversion should only be done when *really* needed.
2517 if(txi->texsize > maxtexsize) 2434 * That is, it should rarely have to be done with OpenGL
2518 { 2435 * 1.2+.
2519 /* This surface wasn't tiled properly... */ 2436 *
2520 if(txi->temporary) 2437 * Besides, any surface that's been SDL_DisplayFormat()ed
2521 glSDL_FreeTexInfo(this, txi); 2438 * should already be in the best known OpenGL format -
2522 GLERR("UploadSurface(): Too large texture!"); 2439 * preferably one that makes DMA w/o conversion possible.
2523 return NULL; 2440 */
2524 } 2441 if (!glSDL_FormatIsOk (surface)) {
2525 2442 #ifdef DEBUG_GLSDL
2526 /* 2443 fprintf (stderr,
2527 * Kludge: Convert if not of preferred RGB or RGBA format. 2444 "glSDL: WARNING: On-the-fly conversion performed!\n");
2528 * 2445 #endif
2529 * Conversion should only be done when *really* needed. 2446 converted = 1;
2530 * That is, it should rarely have to be done with OpenGL 2447 /* NOTE: We forget about the original surface here. */
2531 * 1.2+. 2448 if (surface->format->Amask)
2532 * 2449 surface = glSDL_DisplayFormatAlpha (surface);
2533 * Besides, any surface that's been SDL_DisplayFormat()ed 2450 else
2534 * should already be in the best known OpenGL format - 2451 surface = glSDL_DisplayFormat (surface);
2535 * preferably one that makes DMA w/o conversion possible. 2452 if (!surface) {
2536 */ 2453 GLERR ("UploadSurface(): Could not convert surface!");
2537 if(!glSDL_FormatIsOk(surface)) 2454 if (txi->temporary)
2538 { 2455 glSDL_FreeTexInfo (this, txi);
2539 #ifdef DEBUG_GLSDL 2456 return NULL;
2540 fprintf(stderr, "glSDL: WARNING: On-the-fly conversion performed!\n"); 2457 }
2541 #endif 2458 }
2542 converted = 1; 2459
2543 /* NOTE: We forget about the original surface here. */ 2460 glSDL_UploadTextures (this, surface, txi);
2544 if(surface->format->Amask) 2461
2545 surface = glSDL_DisplayFormatAlpha(surface); 2462 if (converted)
2546 else 2463 SDL_FreeSurface (surface);
2547 surface = glSDL_DisplayFormat(surface); 2464
2548 if(!surface) 2465 return txi;
2549 { 2466 }
2550 GLERR("UploadSurface(): Could not convert surface!"); 2467
2551 if(txi->temporary) 2468
2552 glSDL_FreeTexInfo(this, txi); 2469 static void
2553 return NULL; 2470 glSDL_UnloadTexture (_THIS, private_hwdata * txi)
2554 } 2471 {
2555 } 2472 int i;
2556 2473 for (i = 0; i < txi->textures; ++i)
2557 glSDL_UploadTextures(this, surface, txi); 2474 if (txi->texture[i] != GLSDL_NOTEX)
2558 2475 this->glDeleteTextures (1, &txi->texture[i]);
2559 if(converted) 2476 SDL_memset (&txi->invalid_area, 0, sizeof (txi->invalid_area));
2560 SDL_FreeSurface(surface); 2477 }
2561 2478
2562 return txi; 2479 /* vi: set ts=4 sw=4 expandtab: */
2563 }
2564
2565
2566 static void glSDL_UnloadTexture(_THIS, private_hwdata *txi)
2567 {
2568 int i;
2569 for(i = 0; i < txi->textures; ++i)
2570 if(txi->texture[i] != GLSDL_NOTEX)
2571 this->glDeleteTextures(1, &txi->texture[i]);
2572 SDL_memset(&txi->invalid_area, 0, sizeof(txi->invalid_area));
2573 }