Mercurial > sdl-ios-xcode
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 } |