861e42fc8a92e7ad3ccc47972bd30daba14a9040
[sdl_omap.git] / src / video / ataricommon / SDL_atarigl.c
1 /*
2     SDL - Simple DirectMedia Layer
3     Copyright (C) 1997-2009 Sam Lantinga
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Library General Public
7     License as published by the Free Software Foundation; either
8     version 2 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Library General Public License for more details.
14
15     You should have received a copy of the GNU Library General Public
16     License along with this library; if not, write to the Free
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
19     Sam Lantinga
20     slouken@libsdl.org
21 */
22 #include "SDL_config.h"
23
24 /* Atari OSMesa.ldg implementation of SDL OpenGL support */
25
26 /*--- Includes ---*/
27
28 #if SDL_VIDEO_OPENGL
29 #include <GL/osmesa.h>
30 #endif
31
32 #include <mint/osbind.h>
33
34 #include "SDL_endian.h"
35 #include "SDL_video.h"
36 #include "SDL_atarigl_c.h"
37 #if SDL_VIDEO_OPENGL_OSMESA_DYNAMIC
38 #include "SDL_loadso.h"
39 #endif
40
41 /*--- Defines ---*/
42
43 #define PATH_OSMESA_LDG "osmesa.ldg"
44 #define PATH_MESAGL_LDG "mesa_gl.ldg"
45 #define PATH_TINYGL_LDG "tiny_gl.ldg"
46
47 #define VDI_RGB 0xf
48
49 /*--- Functions prototypes ---*/
50
51 static void SDL_AtariGL_UnloadLibrary(_THIS);
52
53 #if SDL_VIDEO_OPENGL
54 static void CopyShadowNull(_THIS, SDL_Surface *surface);
55 static void CopyShadowDirect(_THIS, SDL_Surface *surface);
56 static void CopyShadowRGBTo555(_THIS, SDL_Surface *surface);
57 static void CopyShadowRGBTo565(_THIS, SDL_Surface *surface);
58 static void CopyShadowRGBSwap(_THIS, SDL_Surface *surface);
59 static void CopyShadowRGBToARGB(_THIS, SDL_Surface *surface);
60 static void CopyShadowRGBToABGR(_THIS, SDL_Surface *surface);
61 static void CopyShadowRGBToBGRA(_THIS, SDL_Surface *surface);
62 static void CopyShadowRGBToRGBA(_THIS, SDL_Surface *surface);
63 static void CopyShadow8888To555(_THIS, SDL_Surface *surface);
64 static void CopyShadow8888To565(_THIS, SDL_Surface *surface);
65
66 static void ConvertNull(_THIS, SDL_Surface *surface);
67 static void Convert565To555be(_THIS, SDL_Surface *surface);
68 static void Convert565To555le(_THIS, SDL_Surface *surface);
69 static void Convert565le(_THIS, SDL_Surface *surface);
70 static void ConvertBGRAToABGR(_THIS, SDL_Surface *surface);
71
72 static int InitNew(_THIS, SDL_Surface *current);
73 static int InitOld(_THIS, SDL_Surface *current);
74 #endif
75
76 /*--- Public functions ---*/
77
78 int SDL_AtariGL_Init(_THIS, SDL_Surface *current)
79 {
80 #if SDL_VIDEO_OPENGL
81         if (gl_oldmesa) {
82                 gl_active = InitOld(this, current);             
83         } else {
84                 gl_active = InitNew(this, current);             
85         }
86 #endif
87
88         return (gl_active);
89 }
90
91 void SDL_AtariGL_Quit(_THIS, SDL_bool unload)
92 {
93 #if SDL_VIDEO_OPENGL
94         if (gl_oldmesa) {
95                 /* Old mesa implementations */
96                 if (this->gl_data->OSMesaDestroyLDG) {
97                         this->gl_data->OSMesaDestroyLDG();
98                 }
99                 if (gl_shadow) {
100                         Mfree(gl_shadow);
101                         gl_shadow = NULL;
102                 }
103         } else {
104                 /* New mesa implementation */
105                 if (gl_ctx) {
106                         if (this->gl_data->OSMesaDestroyContext) {
107                                 this->gl_data->OSMesaDestroyContext(gl_ctx);
108                         }
109                         gl_ctx = NULL;
110                 }
111         }
112
113         if (unload) {
114                 SDL_AtariGL_UnloadLibrary(this);
115         }
116
117 #endif /* SDL_VIDEO_OPENGL */
118         gl_active = 0;
119 }
120
121 int SDL_AtariGL_LoadLibrary(_THIS, const char *path)
122 {
123 #if SDL_VIDEO_OPENGL
124
125 #if SDL_VIDEO_OPENGL_OSMESA_DYNAMIC
126         void *handle;
127         SDL_bool cancel_load;
128
129         if (gl_active) {
130                 SDL_SetError("OpenGL context already created");
131                 return -1;
132         }
133
134         /* Unload previous driver */
135         SDL_AtariGL_UnloadLibrary(this);
136
137         /* Load library given by path */
138         handle = SDL_LoadObject(path);
139         if (handle == NULL) {
140                 /* Try to load another one */
141                 path = SDL_getenv("SDL_VIDEO_GL_DRIVER");
142                 if ( path != NULL ) {
143                         handle = SDL_LoadObject(path);
144                 }
145
146                 /* If it does not work, try some other */
147                 if (handle == NULL) {
148                         path = PATH_OSMESA_LDG;
149                         handle = SDL_LoadObject(path);
150                 }
151
152                 if (handle == NULL) {
153                         path = PATH_MESAGL_LDG;
154                         handle = SDL_LoadObject(path);
155                 }
156
157                 if (handle == NULL) {
158                         path = PATH_TINYGL_LDG;
159                         handle = SDL_LoadObject(path);
160                 }
161         }
162
163         if (handle == NULL) {
164                 SDL_SetError("Could not load OpenGL library");
165                 return -1;
166         }
167
168         this->gl_data->glGetIntegerv = SDL_LoadFunction(handle, "glGetIntegerv");
169         this->gl_data->glFinish = SDL_LoadFunction(handle, "glFinish");
170         this->gl_data->glFlush = SDL_LoadFunction(handle, "glFlush");
171
172         cancel_load = SDL_FALSE;
173         if (this->gl_data->glGetIntegerv == NULL) {
174                 cancel_load = SDL_TRUE;
175         } else {
176                 /* We need either glFinish (OSMesa) or glFlush (TinyGL) */
177                 if ((this->gl_data->glFinish == NULL) &&
178                         (this->gl_data->glFlush == NULL)) {
179                                 cancel_load = SDL_TRUE;
180                 }
181         }
182         if (cancel_load) {
183                 SDL_SetError("Could not retrieve OpenGL functions");
184                 SDL_UnloadObject(handle);
185                 /* Restore pointers to static library */
186                 SDL_AtariGL_InitPointers(this);
187                 return -1;
188         }
189
190         /* Load functions pointers (osmesa.ldg) */
191         this->gl_data->OSMesaCreateContextExt = SDL_LoadFunction(handle, "OSMesaCreateContextExt");
192         this->gl_data->OSMesaDestroyContext = SDL_LoadFunction(handle, "OSMesaDestroyContext");
193         this->gl_data->OSMesaMakeCurrent = SDL_LoadFunction(handle, "OSMesaMakeCurrent");
194         this->gl_data->OSMesaPixelStore = SDL_LoadFunction(handle, "OSMesaPixelStore");
195         this->gl_data->OSMesaGetProcAddress = SDL_LoadFunction(handle, "OSMesaGetProcAddress");
196
197         /* Load old functions pointers (mesa_gl.ldg, tiny_gl.ldg) */
198         this->gl_data->OSMesaCreateLDG = SDL_LoadFunction(handle, "OSMesaCreateLDG");
199         this->gl_data->OSMesaDestroyLDG = SDL_LoadFunction(handle, "OSMesaDestroyLDG");
200
201         gl_oldmesa = 0;
202
203         if ( (this->gl_data->OSMesaCreateContextExt == NULL) || 
204              (this->gl_data->OSMesaDestroyContext == NULL) ||
205              (this->gl_data->OSMesaMakeCurrent == NULL) ||
206              (this->gl_data->OSMesaPixelStore == NULL) ||
207              (this->gl_data->OSMesaGetProcAddress == NULL)) {
208                 /* Hum, maybe old library ? */
209                 if ( (this->gl_data->OSMesaCreateLDG == NULL) || 
210                      (this->gl_data->OSMesaDestroyLDG == NULL)) {
211                         SDL_SetError("Could not retrieve OSMesa functions");
212                         SDL_UnloadObject(handle);
213                         /* Restore pointers to static library */
214                         SDL_AtariGL_InitPointers(this);
215                         return -1;
216                 } else {
217                         gl_oldmesa = 1;
218                 }
219         }
220
221         this->gl_config.dll_handle = handle;
222         if ( path ) {
223                 SDL_strlcpy(this->gl_config.driver_path, path,
224                         SDL_arraysize(this->gl_config.driver_path));
225         } else {
226                 *this->gl_config.driver_path = '\0';
227         }
228
229 #endif
230         this->gl_config.driver_loaded = 1;
231
232         return 0;
233 #else
234         return -1;
235 #endif
236 }
237
238 void *SDL_AtariGL_GetProcAddress(_THIS, const char *proc)
239 {
240         void *func = NULL;
241 #if SDL_VIDEO_OPENGL
242
243         if (this->gl_config.dll_handle) {
244                 func = SDL_LoadFunction(this->gl_config.dll_handle, (void *)proc);
245         } else if (this->gl_data->OSMesaGetProcAddress) {
246                 func = this->gl_data->OSMesaGetProcAddress(proc);
247         }
248
249 #endif
250         return func;
251 }
252
253 int SDL_AtariGL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
254 {
255 #if SDL_VIDEO_OPENGL
256         GLenum mesa_attrib;
257         SDL_Surface *surface;
258
259         if (!gl_active) {
260                 return -1;
261         }
262
263         switch(attrib) {
264                 case SDL_GL_RED_SIZE:
265                         mesa_attrib = GL_RED_BITS;
266                         break;
267                 case SDL_GL_GREEN_SIZE:
268                         mesa_attrib = GL_GREEN_BITS;
269                         break;
270                 case SDL_GL_BLUE_SIZE:
271                         mesa_attrib = GL_BLUE_BITS;
272                         break;
273                 case SDL_GL_ALPHA_SIZE:
274                         mesa_attrib = GL_ALPHA_BITS;
275                         break;
276                 case SDL_GL_DOUBLEBUFFER:
277                         surface = this->screen;
278                         *value = ((surface->flags & SDL_DOUBLEBUF)==SDL_DOUBLEBUF);
279                         return 0;
280                 case SDL_GL_DEPTH_SIZE:
281                         mesa_attrib = GL_DEPTH_BITS;
282                         break;
283                 case SDL_GL_STENCIL_SIZE:
284                         mesa_attrib = GL_STENCIL_BITS;
285                         break;
286                 case SDL_GL_ACCUM_RED_SIZE:
287                         mesa_attrib = GL_ACCUM_RED_BITS;
288                         break;
289                 case SDL_GL_ACCUM_GREEN_SIZE:
290                         mesa_attrib = GL_ACCUM_GREEN_BITS;
291                         break;
292                 case SDL_GL_ACCUM_BLUE_SIZE:
293                         mesa_attrib = GL_ACCUM_BLUE_BITS;
294                         break;
295                 case SDL_GL_ACCUM_ALPHA_SIZE:
296                         mesa_attrib = GL_ACCUM_ALPHA_BITS;
297                         break;
298                 default :
299                         return -1;
300         }
301
302         this->gl_data->glGetIntegerv(mesa_attrib, value);
303         return 0;
304 #else
305         return -1;
306 #endif
307 }
308
309 int SDL_AtariGL_MakeCurrent(_THIS)
310 {
311 #if SDL_VIDEO_OPENGL
312         SDL_Surface *surface;
313         GLenum type;
314
315         if (gl_oldmesa && gl_active) {
316                 return 0;
317         }
318
319         if (this->gl_config.dll_handle) {
320                 if ((this->gl_data->OSMesaMakeCurrent == NULL) ||
321                         (this->gl_data->OSMesaPixelStore == NULL)) {
322                         return -1;
323                 }
324         }
325
326         if (!gl_active) {
327                 SDL_SetError("Invalid OpenGL context");
328                 return -1;
329         }
330
331         surface = this->screen;
332         
333         if ((surface->format->BitsPerPixel == 15) || (surface->format->BitsPerPixel == 16)) {
334                 type = GL_UNSIGNED_SHORT_5_6_5;
335         } else {
336                 type = GL_UNSIGNED_BYTE;
337         }
338
339         if (!(this->gl_data->OSMesaMakeCurrent(gl_ctx, surface->pixels, type, surface->w, surface->h))) {
340                 SDL_SetError("Can not make OpenGL context current");
341                 return -1;
342         }
343
344         /* OSMesa draws upside down */
345         this->gl_data->OSMesaPixelStore(OSMESA_Y_UP, 0);
346
347         return 0;
348 #else
349         return -1;
350 #endif
351 }
352
353 void SDL_AtariGL_SwapBuffers(_THIS)
354 {
355 #if SDL_VIDEO_OPENGL
356         if (gl_active) {
357                 if (this->gl_config.dll_handle) {
358                         if (this->gl_data->glFinish) {
359                                 this->gl_data->glFinish();
360                         } else if (this->gl_data->glFlush) {
361                                 this->gl_data->glFlush();
362                         }
363                 } else {
364                         this->gl_data->glFinish();
365                 }
366                 gl_copyshadow(this, this->screen);
367                 gl_convert(this, this->screen);
368         }
369 #endif
370 }
371
372 void SDL_AtariGL_InitPointers(_THIS)
373 {
374 #if SDL_VIDEO_OPENGL
375         this->gl_data->OSMesaCreateContextExt = OSMesaCreateContextExt;
376         this->gl_data->OSMesaDestroyContext = OSMesaDestroyContext;
377         this->gl_data->OSMesaMakeCurrent = OSMesaMakeCurrent;
378         this->gl_data->OSMesaPixelStore = OSMesaPixelStore;
379         this->gl_data->OSMesaGetProcAddress = OSMesaGetProcAddress;
380
381         this->gl_data->glGetIntegerv = glGetIntegerv;
382         this->gl_data->glFinish = glFinish;
383         this->gl_data->glFlush = glFlush;
384
385         this->gl_data->OSMesaCreateLDG = NULL;
386         this->gl_data->OSMesaDestroyLDG = NULL;
387 #endif
388 }
389
390 /*--- Private functions ---*/
391
392 static void SDL_AtariGL_UnloadLibrary(_THIS)
393 {
394 #if SDL_VIDEO_OPENGL
395         if (this->gl_config.dll_handle) {
396                 SDL_UnloadObject(this->gl_config.dll_handle);
397                 this->gl_config.dll_handle = NULL;
398
399                 /* Restore pointers to static library */
400                 SDL_AtariGL_InitPointers(this);
401         }
402 #endif
403 }
404
405 /*--- Creation of an OpenGL context using new/old functions ---*/
406
407 #if SDL_VIDEO_OPENGL
408 static int InitNew(_THIS, SDL_Surface *current)
409 {
410         GLenum osmesa_format;
411         SDL_PixelFormat *pixel_format;
412         Uint32  redmask;
413         int recreatecontext;
414         GLint newaccumsize;
415
416         if (this->gl_config.dll_handle) {
417                 if (this->gl_data->OSMesaCreateContextExt == NULL) {
418                         return 0;
419                 }
420         }
421
422         /* Init OpenGL context using OSMesa */
423         gl_convert = ConvertNull;
424         gl_copyshadow = CopyShadowNull;
425         gl_upsidedown = SDL_FALSE;
426
427         pixel_format = current->format;
428         redmask = pixel_format->Rmask;
429         switch (pixel_format->BitsPerPixel) {
430                 case 15:
431                         /* 1555, big and little endian, unsupported */
432                         gl_pixelsize = 2;
433                         osmesa_format = OSMESA_RGB_565;
434                         if (redmask == 31<<10) {
435                                 gl_convert = Convert565To555be;
436                         } else {
437                                 gl_convert = Convert565To555le;
438                         }
439                         break;
440                 case 16:
441                         gl_pixelsize = 2;
442                         if (redmask == 31<<11) {
443                                 osmesa_format = OSMESA_RGB_565;
444                         } else {
445                                 /* 565, little endian, unsupported */
446                                 osmesa_format = OSMESA_RGB_565;
447                                 gl_convert = Convert565le;
448                         }
449                         break;
450                 case 24:
451                         gl_pixelsize = 3;
452                         if (redmask == 255<<16) {
453                                 osmesa_format = OSMESA_RGB;
454                         } else {
455                                 osmesa_format = OSMESA_BGR;
456                         }
457                         break;
458                 case 32:
459                         gl_pixelsize = 4;
460                         if (redmask == 255<<16) {
461                                 osmesa_format = OSMESA_ARGB;
462                         } else if (redmask == 255<<8) {
463                                 osmesa_format = OSMESA_BGRA;
464                         } else if (redmask == 255<<24) {
465                                 osmesa_format = OSMESA_RGBA;
466                         } else {
467                                 /* ABGR format unsupported */
468                                 osmesa_format = OSMESA_BGRA;
469                                 gl_convert = ConvertBGRAToABGR;
470                         }
471                         break;
472                 default:
473                         gl_pixelsize = 1;
474                         osmesa_format = OSMESA_COLOR_INDEX;
475                         break;
476         }
477
478         /* Try to keep current context if possible */
479         newaccumsize =
480                 this->gl_config.accum_red_size +
481                 this->gl_config.accum_green_size +
482                 this->gl_config.accum_blue_size +
483                 this->gl_config.accum_alpha_size;
484         recreatecontext=1;
485         if (gl_ctx &&
486                 (gl_curformat == osmesa_format) &&
487                 (gl_curdepth == this->gl_config.depth_size) &&
488                 (gl_curstencil == this->gl_config.stencil_size) &&
489                 (gl_curaccum == newaccumsize)) {
490                 recreatecontext = 0;
491         }
492         if (recreatecontext) {
493                 SDL_AtariGL_Quit(this, SDL_FALSE);
494
495                 gl_ctx = this->gl_data->OSMesaCreateContextExt(
496                         osmesa_format, this->gl_config.depth_size,
497                         this->gl_config.stencil_size, newaccumsize, NULL );
498
499                 if (gl_ctx) {
500                         gl_curformat = osmesa_format;
501                         gl_curdepth = this->gl_config.depth_size;
502                         gl_curstencil = this->gl_config.stencil_size;
503                         gl_curaccum = newaccumsize;
504                 } else {
505                         gl_curformat = 0;
506                         gl_curdepth = 0;
507                         gl_curstencil = 0;
508                         gl_curaccum = 0;
509                 }
510         }
511
512         return (gl_ctx != NULL);
513 }
514
515
516 static int InitOld(_THIS, SDL_Surface *current)
517 {
518         GLenum osmesa_format;
519         SDL_PixelFormat *pixel_format;
520         Uint32  redmask;
521         int recreatecontext, tinygl_present;
522
523         if (this->gl_config.dll_handle) {
524                 if (this->gl_data->OSMesaCreateLDG == NULL) {
525                         return 0;
526                 }
527         }
528
529         /* TinyGL only supports VDI_RGB (OSMESA_RGB) */
530         tinygl_present=0;
531         if (this->gl_config.dll_handle) {
532                 if (this->gl_data->glFinish == NULL) {
533                         tinygl_present=1;
534                 }
535         }
536
537         /* Init OpenGL context using OSMesa */
538         gl_convert = ConvertNull;
539         gl_copyshadow = CopyShadowNull;
540         gl_upsidedown = SDL_FALSE;
541
542         pixel_format = current->format;
543         redmask = pixel_format->Rmask;
544         switch (pixel_format->BitsPerPixel) {
545                 case 15:
546                         /* 15 bits unsupported */
547                         if (tinygl_present) {
548                                 gl_pixelsize = 3;
549                                 osmesa_format = VDI_RGB;
550                                 if (redmask == 31<<10) {
551                                         gl_copyshadow = CopyShadowRGBTo555;
552                                 } else {
553                                         gl_copyshadow = CopyShadowRGBTo565;
554                                         gl_convert = Convert565To555le;
555                                 }
556                         } else {
557                                 gl_pixelsize = 4;
558                                 gl_upsidedown = SDL_TRUE;
559                                 osmesa_format = OSMESA_ARGB;
560                                 if (redmask == 31<<10) {
561                                         gl_copyshadow = CopyShadow8888To555;
562                                 } else {
563                                         gl_copyshadow = CopyShadow8888To565;
564                                         gl_convert = Convert565To555le;
565                                 }
566                         }
567                         break;
568                 case 16:
569                         /* 16 bits unsupported */
570                         if (tinygl_present) {
571                                 gl_pixelsize = 3;
572                                 osmesa_format = VDI_RGB;
573                                 gl_copyshadow = CopyShadowRGBTo565;
574                                 if (redmask != 31<<11) {
575                                         /* 565, little endian, unsupported */
576                                         gl_convert = Convert565le;
577                                 }
578                         } else {
579                                 gl_pixelsize = 4;
580                                 gl_upsidedown = SDL_TRUE;
581                                 osmesa_format = OSMESA_ARGB;
582                                 gl_copyshadow = CopyShadow8888To565;
583                                 if (redmask != 31<<11) {
584                                         /* 565, little endian, unsupported */
585                                         gl_convert = Convert565le;
586                                 }
587                         }
588                         break;
589                 case 24:
590                         gl_pixelsize = 3;
591                         if (tinygl_present) {
592                                 osmesa_format = VDI_RGB;
593                                 gl_copyshadow = CopyShadowDirect;
594                                 if (redmask != 255<<16) {
595                                         gl_copyshadow = CopyShadowRGBSwap;
596                                 }
597                         } else {
598                                 gl_copyshadow = CopyShadowDirect;
599                                 gl_upsidedown = SDL_TRUE;
600                                 if (redmask == 255<<16) {
601                                         osmesa_format = OSMESA_RGB;
602                                 } else {
603                                         osmesa_format = OSMESA_BGR;
604                                 }
605                         }
606                         break;
607                 case 32:
608                         if (tinygl_present) {
609                                 gl_pixelsize = 3;
610                                 osmesa_format = VDI_RGB;
611                                 gl_copyshadow = CopyShadowRGBToARGB;
612                                 if (redmask == 255) {
613                                         gl_convert = CopyShadowRGBToABGR;
614                                 } else if (redmask == 255<<8) {
615                                         gl_convert = CopyShadowRGBToBGRA;
616                                 } else if (redmask == 255<<24) {
617                                         gl_convert = CopyShadowRGBToRGBA;
618                                 }
619                         } else {
620                                 gl_pixelsize = 4;
621                                 gl_upsidedown = SDL_TRUE;
622                                 gl_copyshadow = CopyShadowDirect;
623                                 if (redmask == 255<<16) {
624                                         osmesa_format = OSMESA_ARGB;
625                                 } else if (redmask == 255<<8) {
626                                         osmesa_format = OSMESA_BGRA;
627                                 } else if (redmask == 255<<24) {
628                                         osmesa_format = OSMESA_RGBA;
629                                 } else {
630                                         /* ABGR format unsupported */
631                                         osmesa_format = OSMESA_BGRA;
632                                         gl_convert = ConvertBGRAToABGR;
633                                 }
634                         }
635                         break;
636                 default:
637                         if (tinygl_present) {
638                                 SDL_AtariGL_Quit(this, SDL_FALSE);
639                                 return 0;
640                         }
641                         gl_pixelsize = 1;
642                         gl_copyshadow = CopyShadowDirect;
643                         osmesa_format = OSMESA_COLOR_INDEX;
644                         break;
645         }
646
647         /* Try to keep current context if possible */
648         recreatecontext=1;
649         if (gl_shadow &&
650                 (gl_curformat == osmesa_format) &&
651                 (gl_curwidth == current->w) &&
652                 (gl_curheight == current->h)) {
653                 recreatecontext = 0;
654         }
655         if (recreatecontext) {
656                 SDL_AtariGL_Quit(this, SDL_FALSE);
657
658                 gl_shadow = this->gl_data->OSMesaCreateLDG(
659                         osmesa_format, GL_UNSIGNED_BYTE, current->w, current->h
660                 );
661
662                 if (gl_shadow) {
663                         gl_curformat = osmesa_format;
664                         gl_curwidth = current->w;
665                         gl_curheight = current->h;
666                 } else {
667                         gl_curformat = 0;
668                         gl_curwidth = 0;
669                         gl_curheight = 0;
670                 }
671         }
672
673         return (gl_shadow != NULL);
674 }
675
676 /*--- Conversions routines from shadow buffer to the screen ---*/
677
678 static void CopyShadowNull(_THIS, SDL_Surface *surface)
679 {
680 }
681
682 static void CopyShadowDirect(_THIS, SDL_Surface *surface)
683 {
684         int y, srcpitch, dstpitch;
685         Uint8 *srcline, *dstline;
686
687         srcline = gl_shadow;
688         srcpitch = surface->w * gl_pixelsize;
689         dstline = surface->pixels;
690         dstpitch = surface->pitch;
691         if (gl_upsidedown) {
692                 srcline += (surface->h-1)*srcpitch;
693                 srcpitch = -srcpitch;
694         }
695
696         for (y=0; y<surface->h; y++) {
697                 SDL_memcpy(dstline, srcline, srcpitch);
698
699                 srcline += srcpitch;
700                 dstline += dstpitch;
701         }
702 }
703
704 static void CopyShadowRGBTo555(_THIS, SDL_Surface *surface)
705 {
706         int x,y, srcpitch, dstpitch;
707         Uint16 *dstline, *dstcol;
708         Uint8 *srcline, *srccol;
709
710         srcline = (Uint8 *)gl_shadow;
711         srcpitch = surface->w * gl_pixelsize;
712         dstline = surface->pixels;
713         dstpitch = surface->pitch >>1;
714         if (gl_upsidedown) {
715                 srcline += (surface->h-1)*srcpitch;
716                 srcpitch = -srcpitch;
717         }
718
719         for (y=0; y<surface->h; y++) {
720                 srccol = srcline;
721                 dstcol = dstline;
722                 for (x=0; x<surface->w; x++) {
723                         Uint16 dstcolor;
724                         
725                         dstcolor = ((*srccol++)<<7) & (31<<10);
726                         dstcolor |= ((*srccol++)<<2) & (31<<5);
727                         dstcolor |= ((*srccol++)>>3) & 31;
728                         *dstcol++ = dstcolor;
729                 }
730
731                 srcline += srcpitch;
732                 dstline += dstpitch;
733         }
734 }
735
736 static void CopyShadowRGBTo565(_THIS, SDL_Surface *surface)
737 {
738         int x,y, srcpitch, dstpitch;
739         Uint16 *dstline, *dstcol;
740         Uint8 *srcline, *srccol;
741
742         srcline = (Uint8 *)gl_shadow;
743         srcpitch = surface->w * gl_pixelsize;
744         dstline = surface->pixels;
745         dstpitch = surface->pitch >>1;
746         if (gl_upsidedown) {
747                 srcline += (surface->h-1)*srcpitch;
748                 srcpitch = -srcpitch;
749         }
750
751         for (y=0; y<surface->h; y++) {
752                 srccol = srcline;
753                 dstcol = dstline;
754
755                 for (x=0; x<surface->w; x++) {
756                         Uint16 dstcolor;
757                         
758                         dstcolor = ((*srccol++)<<8) & (31<<11);
759                         dstcolor |= ((*srccol++)<<3) & (63<<5);
760                         dstcolor |= ((*srccol++)>>3) & 31;
761                         *dstcol++ = dstcolor;
762                 }
763
764                 srcline += srcpitch;
765                 dstline += dstpitch;
766         }
767 }
768
769 static void CopyShadowRGBSwap(_THIS, SDL_Surface *surface)
770 {
771         int x,y, srcpitch, dstpitch;
772         Uint8 *dstline, *dstcol;
773         Uint8 *srcline, *srccol;
774
775         srcline = (Uint8 *)gl_shadow;
776         srcpitch = surface->w * gl_pixelsize;
777         dstline = surface->pixels;
778         dstpitch = surface->pitch;
779         if (gl_upsidedown) {
780                 srcline += (surface->h-1)*srcpitch;
781                 srcpitch = -srcpitch;
782         }
783
784         for (y=0; y<surface->h; y++) {
785                 srccol = srcline;
786                 dstcol = dstline;
787
788                 for (x=0; x<surface->w; x++) {
789                         *dstcol++ = srccol[2];
790                         *dstcol++ = srccol[1];
791                         *dstcol++ = srccol[0];
792                         srccol += 3;
793                 }
794
795                 srcline += srcpitch;
796                 dstline += dstpitch;
797         }
798 }
799
800 static void CopyShadowRGBToARGB(_THIS, SDL_Surface *surface)
801 {
802         int x,y, srcpitch, dstpitch;
803         Uint32 *dstline, *dstcol;
804         Uint8 *srcline, *srccol;
805
806         srcline = (Uint8 *)gl_shadow;
807         srcpitch = surface->w * gl_pixelsize;
808         dstline = surface->pixels;
809         dstpitch = surface->pitch >>2;
810         if (gl_upsidedown) {
811                 srcline += (surface->h-1)*srcpitch;
812                 srcpitch = -srcpitch;
813         }
814
815         for (y=0; y<surface->h; y++) {
816                 srccol = srcline;
817                 dstcol = dstline;
818
819                 for (x=0; x<surface->w; x++) {
820                         Uint32  dstcolor;
821
822                         dstcolor = (*srccol++)<<16;
823                         dstcolor |= (*srccol++)<<8;
824                         dstcolor |= *srccol++;
825
826                         *dstcol++ = dstcolor;
827                 }
828
829                 srcline += srcpitch;
830                 dstline += dstpitch;
831         }
832 }
833
834 static void CopyShadowRGBToABGR(_THIS, SDL_Surface *surface)
835 {
836         int x,y, srcpitch, dstpitch;
837         Uint32 *dstline, *dstcol;
838         Uint8 *srcline, *srccol;
839
840         srcline = (Uint8 *)gl_shadow;
841         srcpitch = surface->w * gl_pixelsize;
842         dstline = surface->pixels;
843         dstpitch = surface->pitch >>2;
844         if (gl_upsidedown) {
845                 srcline += (surface->h-1)*srcpitch;
846                 srcpitch = -srcpitch;
847         }
848
849         for (y=0; y<surface->h; y++) {
850                 srccol = srcline;
851                 dstcol = dstline;
852
853                 for (x=0; x<surface->w; x++) {
854                         Uint32  dstcolor;
855
856                         dstcolor = *srccol++;
857                         dstcolor |= (*srccol++)<<8;
858                         dstcolor |= (*srccol++)<<16;
859
860                         *dstcol++ = dstcolor;
861                 }
862
863                 srcline += srcpitch;
864                 dstline += dstpitch;
865         }
866 }
867
868 static void CopyShadowRGBToBGRA(_THIS, SDL_Surface *surface)
869 {
870         int x,y, srcpitch, dstpitch;
871         Uint32 *dstline, *dstcol;
872         Uint8 *srcline, *srccol;
873
874         srcline = (Uint8 *)gl_shadow;
875         srcpitch = surface->w * gl_pixelsize;
876         dstline = surface->pixels;
877         dstpitch = surface->pitch >>2;
878         if (gl_upsidedown) {
879                 srcline += (surface->h-1)*srcpitch;
880                 srcpitch = -srcpitch;
881         }
882
883         for (y=0; y<surface->h; y++) {
884                 srccol = srcline;
885                 dstcol = dstline;
886
887                 for (x=0; x<surface->w; x++) {
888                         Uint32  dstcolor;
889
890                         dstcolor = (*srccol++)<<8;
891                         dstcolor |= (*srccol++)<<16;
892                         dstcolor |= (*srccol++)<<24;
893
894                         *dstcol++ = dstcolor;
895                 }
896
897                 srcline += srcpitch;
898                 dstline += dstpitch;
899         }
900 }
901
902 static void CopyShadowRGBToRGBA(_THIS, SDL_Surface *surface)
903 {
904         int x,y, srcpitch, dstpitch;
905         Uint32 *dstline, *dstcol;
906         Uint8 *srcline, *srccol;
907
908         srcline = (Uint8 *)gl_shadow;
909         srcpitch = surface->w * gl_pixelsize;
910         dstline = surface->pixels;
911         dstpitch = surface->pitch >>2;
912         if (gl_upsidedown) {
913                 srcline += (surface->h-1)*srcpitch;
914                 srcpitch = -srcpitch;
915         }
916
917         for (y=0; y<surface->h; y++) {
918                 srccol = srcline;
919                 dstcol = dstline;
920
921                 for (x=0; x<surface->w; x++) {
922                         Uint32  dstcolor;
923
924                         dstcolor = (*srccol++)<<24;
925                         dstcolor |= (*srccol++)<<16;
926                         dstcolor |= (*srccol++)<<8;
927
928                         *dstcol++ = dstcolor;
929                 }
930
931                 srcline += srcpitch;
932                 dstline += dstpitch;
933         }
934 }
935
936 static void CopyShadow8888To555(_THIS, SDL_Surface *surface)
937 {
938         int x,y, srcpitch, dstpitch;
939         Uint16 *dstline, *dstcol;
940         Uint32 *srcline, *srccol;
941
942         srcline = (Uint32 *)gl_shadow;
943         srcpitch = (surface->w * gl_pixelsize) >>2;
944         dstline = surface->pixels;
945         dstpitch = surface->pitch >>1;
946         if (gl_upsidedown) {
947                 srcline += (surface->h-1)*srcpitch;
948                 srcpitch = -srcpitch;
949         }
950
951         for (y=0; y<surface->h; y++) {
952                 srccol = srcline;
953                 dstcol = dstline;
954                 for (x=0; x<surface->w; x++) {
955                         Uint32 srccolor;
956                         Uint16 dstcolor;
957                         
958                         srccolor = *srccol++;
959                         dstcolor = (srccolor>>9) & (31<<10);
960                         dstcolor |= (srccolor>>6) & (31<<5);
961                         dstcolor |= (srccolor>>3) & 31;
962                         *dstcol++ = dstcolor;
963                 }
964
965                 srcline += srcpitch;
966                 dstline += dstpitch;
967         }
968 }
969
970 static void CopyShadow8888To565(_THIS, SDL_Surface *surface)
971 {
972         int x,y, srcpitch, dstpitch;
973         Uint16 *dstline, *dstcol;
974         Uint32 *srcline, *srccol;
975
976         srcline = (Uint32 *)gl_shadow;
977         srcpitch = (surface->w * gl_pixelsize) >> 2;
978         dstline = surface->pixels;
979         dstpitch = surface->pitch >>1;
980         if (gl_upsidedown) {
981                 srcline += (surface->h-1)*srcpitch;
982                 srcpitch = -srcpitch;
983         }
984
985         for (y=0; y<surface->h; y++) {
986                 srccol = srcline;
987                 dstcol = dstline;
988
989                 for (x=0; x<surface->w; x++) {
990                         Uint32 srccolor;
991                         Uint16 dstcolor;
992                         
993                         srccolor = *srccol++;
994                         dstcolor = (srccolor>>8) & (31<<11);
995                         dstcolor |= (srccolor>>5) & (63<<5);
996                         dstcolor |= (srccolor>>3) & 31;
997                         *dstcol++ = dstcolor;
998                 }
999
1000                 srcline += srcpitch;
1001                 dstline += dstpitch;
1002         }
1003 }
1004
1005 /*--- Conversions routines in the screen ---*/
1006
1007 static void ConvertNull(_THIS, SDL_Surface *surface)
1008 {
1009 }
1010
1011 static void Convert565To555be(_THIS, SDL_Surface *surface)
1012 {
1013         int x,y, pitch;
1014         unsigned short *line, *pixel;
1015
1016         line = surface->pixels;
1017         pitch = surface->pitch >> 1;
1018         for (y=0; y<surface->h; y++) {
1019                 pixel = line;
1020                 for (x=0; x<surface->w; x++) {
1021                         unsigned short color = *pixel;
1022
1023                         *pixel++ = (color & 0x1f)|((color>>1) & 0xffe0);
1024                 }
1025
1026                 line += pitch;
1027         }
1028 }
1029
1030 static void Convert565To555le(_THIS, SDL_Surface *surface)
1031 {
1032         int x,y, pitch;
1033         unsigned short *line, *pixel;
1034
1035         line = surface->pixels;
1036         pitch = surface->pitch >>1;
1037         for (y=0; y<surface->h; y++) {
1038                 pixel = line;
1039                 for (x=0; x<surface->w; x++) {
1040                         unsigned short color = *pixel;
1041
1042                         color = (color & 0x1f)|((color>>1) & 0xffe0);
1043                         *pixel++ = SDL_Swap16(color);
1044                 }
1045
1046                 line += pitch;
1047         }
1048 }
1049
1050 static void Convert565le(_THIS, SDL_Surface *surface)
1051 {
1052         int x,y, pitch;
1053         unsigned short *line, *pixel;
1054
1055         line = surface->pixels;
1056         pitch = surface->pitch >>1;
1057         for (y=0; y<surface->h; y++) {
1058                 pixel = line;
1059                 for (x=0; x<surface->w; x++) {
1060                         unsigned short color = *pixel;
1061
1062                         *pixel++ = SDL_Swap16(color);
1063                 }
1064
1065                 line += pitch;
1066         }
1067 }
1068
1069 static void ConvertBGRAToABGR(_THIS, SDL_Surface *surface)
1070 {
1071         int x,y, pitch;
1072         unsigned long *line, *pixel;
1073
1074         line = surface->pixels;
1075         pitch = surface->pitch >>2;
1076         for (y=0; y<surface->h; y++) {
1077                 pixel = line;
1078                 for (x=0; x<surface->w; x++) {
1079                         unsigned long color = *pixel;
1080
1081                         *pixel++ = (color<<24)|(color>>8);
1082                 }
1083
1084                 line += pitch;
1085         }
1086 }
1087
1088 #endif /* SDL_VIDEO_OPENGL */