src/video/ataricommon/SDL_atarigl.c
author Patrice Mandin
Sun, 28 Nov 2004 21:52:29 +0000
changeset 995 22fc5f45bbb7
parent 993 2662da16d668
child 1000 fbeac9312843
permissions -rw-r--r--
TinyGL does not have glFinish, only glFlush
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2004 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 
    23 /* Atari OSMesa.ldg implementation of SDL OpenGL support */
    24 
    25 /*--- Includes ---*/
    26 
    27 #include <stdio.h>
    28 #include <stdlib.h>
    29 #include <string.h>
    30 #ifdef HAVE_OPENGL
    31 #include <GL/osmesa.h>
    32 #endif
    33 
    34 #include <mint/osbind.h>
    35 
    36 #include "SDL_video.h"
    37 #include "SDL_error.h"
    38 #include "SDL_endian.h"
    39 #include "SDL_atarigl_c.h"
    40 #ifdef ENABLE_OSMESA_SHARED
    41 #include "SDL_loadso.h"
    42 #endif
    43 
    44 /*--- Defines ---*/
    45 
    46 #define PATH_OSMESA_LDG	"osmesa.ldg"
    47 #define PATH_MESAGL_LDG	"mesa_gl.ldg"
    48 #define PATH_TINYGL_LDG	"tiny_gl.ldg"
    49 
    50 /*--- Functions prototypes ---*/
    51 
    52 static void SDL_AtariGL_UnloadLibrary(_THIS);
    53 
    54 static void CopyShadowNull(_THIS, SDL_Surface *surface);
    55 static void CopyShadowDirect(_THIS, SDL_Surface *surface);
    56 static void CopyShadow8888To555(_THIS, SDL_Surface *surface);
    57 static void CopyShadow8888To565(_THIS, SDL_Surface *surface);
    58 
    59 static void ConvertNull(_THIS, SDL_Surface *surface);
    60 static void Convert565To555be(_THIS, SDL_Surface *surface);
    61 static void Convert565To555le(_THIS, SDL_Surface *surface);
    62 static void Convert565le(_THIS, SDL_Surface *surface);
    63 static void ConvertBGRAToABGR(_THIS, SDL_Surface *surface);
    64 
    65 static int InitNew(_THIS, SDL_Surface *current);
    66 static int InitOld(_THIS, SDL_Surface *current);
    67 
    68 /*--- Public functions ---*/
    69 
    70 int SDL_AtariGL_Init(_THIS, SDL_Surface *current)
    71 {
    72 #ifdef HAVE_OPENGL
    73 	if (gl_oldmesa) {
    74 		gl_active = InitOld(this, current);		
    75 	} else {
    76 		gl_active = InitNew(this, current);		
    77 	}
    78 #endif
    79 
    80 	return (gl_active);
    81 }
    82 
    83 void SDL_AtariGL_Quit(_THIS, SDL_bool unload)
    84 {
    85 #ifdef HAVE_OPENGL
    86 	if (gl_oldmesa) {
    87 		/* Old mesa implementations */
    88 		if (this->gl_data->OSMesaDestroyLDG) {
    89 			this->gl_data->OSMesaDestroyLDG();
    90 		}
    91 		if (gl_shadow) {
    92 			Mfree(gl_shadow);
    93 			gl_shadow = NULL;
    94 		}
    95 	} else {
    96 		/* New mesa implementation */
    97 		if (gl_ctx) {
    98 			if (this->gl_data->OSMesaDestroyContext) {
    99 				this->gl_data->OSMesaDestroyContext(gl_ctx);
   100 			}
   101 			gl_ctx = NULL;
   102 		}
   103 	}
   104 
   105 	if (unload) {
   106 		SDL_AtariGL_UnloadLibrary(this);
   107 	}
   108 
   109 #endif /* HAVE_OPENGL */
   110 	gl_active = 0;
   111 }
   112 
   113 int SDL_AtariGL_LoadLibrary(_THIS, const char *path)
   114 {
   115 #ifdef HAVE_OPENGL
   116 
   117 #ifdef ENABLE_OSMESA_SHARED
   118 	void *handle;
   119 	SDL_bool cancel_load;
   120 
   121 	if (gl_active) {
   122 		SDL_SetError("OpenGL context already created");
   123 		return -1;
   124 	}
   125 
   126 	/* Unload previous driver */
   127 	SDL_AtariGL_UnloadLibrary(this);
   128 
   129 	/* Load library given by path */
   130 	handle = SDL_LoadObject(path);
   131 	if (handle == NULL) {
   132 		/* Try to load another one */
   133 		path = getenv("SDL_VIDEO_GL_DRIVER");
   134 		if ( path != NULL ) {
   135 			handle = SDL_LoadObject(path);
   136 		}
   137 
   138 		/* If it does not work, try some other */
   139 		if (handle == NULL) {
   140 			path = PATH_OSMESA_LDG;
   141 			handle = SDL_LoadObject(path);
   142 		}
   143 
   144 		if (handle == NULL) {
   145 			path = PATH_MESAGL_LDG;
   146 			handle = SDL_LoadObject(path);
   147 		}
   148 
   149 		if (handle == NULL) {
   150 			path = PATH_TINYGL_LDG;
   151 			handle = SDL_LoadObject(path);
   152 		}
   153 	}
   154 
   155 	if (handle == NULL) {
   156 		SDL_SetError("Could not load OpenGL library");
   157 		return -1;
   158 	}
   159 
   160 	this->gl_data->glGetIntegerv = SDL_LoadFunction(handle, "glGetIntegerv");
   161 	this->gl_data->glFinish = SDL_LoadFunction(handle, "glFinish");
   162 	this->gl_data->glFlush = SDL_LoadFunction(handle, "glFlush");
   163 
   164 	cancel_load = SDL_FALSE;
   165 	if (this->gl_data->glGetIntegerv == NULL) {
   166 		cancel_load = SDL_TRUE;
   167 	} else {
   168 		/* We need either glFinish (OSMesa) or glFlush (TinyGL) */
   169 		if ((this->gl_data->glFinish == NULL) &&
   170 			(this->gl_data->glFlush == NULL)) {
   171 				cancel_load = SDL_TRUE;
   172 		}
   173 	}
   174 	if (cancel_load) {
   175 		SDL_SetError("Could not retrieve OpenGL functions");
   176 		SDL_UnloadObject(handle);
   177 		/* Restore pointers to static library */
   178 		SDL_AtariGL_InitPointers(this);
   179 		return -1;
   180 	}
   181 
   182 	/* Load functions pointers (osmesa.ldg) */
   183 	this->gl_data->OSMesaCreateContextExt = SDL_LoadFunction(handle, "OSMesaCreateContextExt");
   184 	this->gl_data->OSMesaDestroyContext = SDL_LoadFunction(handle, "OSMesaDestroyContext");
   185 	this->gl_data->OSMesaMakeCurrent = SDL_LoadFunction(handle, "OSMesaMakeCurrent");
   186 	this->gl_data->OSMesaPixelStore = SDL_LoadFunction(handle, "OSMesaPixelStore");
   187 	this->gl_data->OSMesaGetProcAddress = SDL_LoadFunction(handle, "OSMesaGetProcAddress");
   188 
   189 	/* Load old functions pointers (mesa_gl.ldg, tiny_gl.ldg) */
   190 	this->gl_data->OSMesaCreateLDG = SDL_LoadFunction(handle, "OSMesaCreateLDG");
   191 	this->gl_data->OSMesaDestroyLDG = SDL_LoadFunction(handle, "OSMesaDestroyLDG");
   192 
   193 	gl_oldmesa = 0;
   194 
   195 	if ( (this->gl_data->OSMesaCreateContextExt == NULL) || 
   196 	     (this->gl_data->OSMesaDestroyContext == NULL) ||
   197 	     (this->gl_data->OSMesaMakeCurrent == NULL) ||
   198 	     (this->gl_data->OSMesaPixelStore == NULL) ||
   199 	     (this->gl_data->OSMesaGetProcAddress == NULL)) {
   200 		/* Hum, maybe old library ? */
   201 		if ( (this->gl_data->OSMesaCreateLDG == NULL) || 
   202 		     (this->gl_data->OSMesaDestroyLDG == NULL)) {
   203 			SDL_SetError("Could not retrieve OSMesa functions");
   204 			SDL_UnloadObject(handle);
   205 			/* Restore pointers to static library */
   206 			SDL_AtariGL_InitPointers(this);
   207 			return -1;
   208 		} else {
   209 			gl_oldmesa = 1;
   210 		}
   211 	}
   212 
   213 	this->gl_config.dll_handle = handle;
   214 	if ( path ) {
   215 		strncpy(this->gl_config.driver_path, path,
   216 			sizeof(this->gl_config.driver_path)-1);
   217 	} else {
   218 		strcpy(this->gl_config.driver_path, "");
   219 	}
   220 
   221 #endif
   222 	this->gl_config.driver_loaded = 1;
   223 
   224 	return 0;
   225 #else
   226 	return -1;
   227 #endif
   228 }
   229 
   230 void *SDL_AtariGL_GetProcAddress(_THIS, const char *proc)
   231 {
   232 	void *func = NULL;
   233 #ifdef HAVE_OPENGL
   234 
   235 	if (this->gl_config.dll_handle) {
   236 		func = SDL_LoadFunction(this->gl_config.dll_handle, (void *)proc);
   237 	} else if (this->gl_data->OSMesaGetProcAddress) {
   238 		func = this->gl_data->OSMesaGetProcAddress(proc);
   239 	}
   240 
   241 #endif
   242 	return func;
   243 }
   244 
   245 int SDL_AtariGL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
   246 {
   247 #ifdef HAVE_OPENGL
   248 	GLenum mesa_attrib;
   249 	SDL_Surface *surface;
   250 
   251 	if (!gl_active) {
   252 		return -1;
   253 	}
   254 
   255 	switch(attrib) {
   256 		case SDL_GL_RED_SIZE:
   257 			mesa_attrib = GL_RED_BITS;
   258 			break;
   259 		case SDL_GL_GREEN_SIZE:
   260 			mesa_attrib = GL_GREEN_BITS;
   261 			break;
   262 		case SDL_GL_BLUE_SIZE:
   263 			mesa_attrib = GL_BLUE_BITS;
   264 			break;
   265 		case SDL_GL_ALPHA_SIZE:
   266 			mesa_attrib = GL_ALPHA_BITS;
   267 			break;
   268 		case SDL_GL_DOUBLEBUFFER:
   269 			surface = this->screen;
   270 			*value = ((surface->flags & SDL_DOUBLEBUF)==SDL_DOUBLEBUF);
   271 			return 0;
   272 		case SDL_GL_DEPTH_SIZE:
   273 			mesa_attrib = GL_DEPTH_BITS;
   274 			break;
   275 		case SDL_GL_STENCIL_SIZE:
   276 			mesa_attrib = GL_STENCIL_BITS;
   277 			break;
   278 		case SDL_GL_ACCUM_RED_SIZE:
   279 			mesa_attrib = GL_ACCUM_RED_BITS;
   280 			break;
   281 		case SDL_GL_ACCUM_GREEN_SIZE:
   282 			mesa_attrib = GL_ACCUM_GREEN_BITS;
   283 			break;
   284 		case SDL_GL_ACCUM_BLUE_SIZE:
   285 			mesa_attrib = GL_ACCUM_BLUE_BITS;
   286 			break;
   287 		case SDL_GL_ACCUM_ALPHA_SIZE:
   288 			mesa_attrib = GL_ACCUM_ALPHA_BITS;
   289 			break;
   290 		default :
   291 			return -1;
   292 	}
   293 
   294 	this->gl_data->glGetIntegerv(mesa_attrib, value);
   295 	return 0;
   296 #else
   297 	return -1;
   298 #endif
   299 }
   300 
   301 int SDL_AtariGL_MakeCurrent(_THIS)
   302 {
   303 #ifdef HAVE_OPENGL
   304 	SDL_Surface *surface;
   305 	GLenum type;
   306 
   307 	if (gl_oldmesa && gl_active) {
   308 		return 0;
   309 	}
   310 
   311 	if (this->gl_config.dll_handle) {
   312 		if ((this->gl_data->OSMesaMakeCurrent == NULL) ||
   313 			(this->gl_data->OSMesaPixelStore == NULL)) {
   314 			return -1;
   315 		}
   316 	}
   317 
   318 	if (!gl_active) {
   319 		SDL_SetError("Invalid OpenGL context");
   320 		return -1;
   321 	}
   322 
   323 	surface = this->screen;
   324 	
   325 	if ((surface->format->BitsPerPixel == 15) || (surface->format->BitsPerPixel == 16)) {
   326 		type = GL_UNSIGNED_SHORT_5_6_5;
   327 	} else {
   328 		type = GL_UNSIGNED_BYTE;
   329 	}
   330 
   331 	if (!(this->gl_data->OSMesaMakeCurrent(gl_ctx, surface->pixels, type, surface->w, surface->h))) {
   332 		SDL_SetError("Can not make OpenGL context current");
   333 		return -1;
   334 	}
   335 
   336 	/* OSMesa draws upside down */
   337 	this->gl_data->OSMesaPixelStore(OSMESA_Y_UP, 0);
   338 
   339 	return 0;
   340 #else
   341 	return -1;
   342 #endif
   343 }
   344 
   345 void SDL_AtariGL_SwapBuffers(_THIS)
   346 {
   347 #ifdef HAVE_OPENGL
   348 	if (gl_active) {
   349 		if (this->gl_config.dll_handle) {
   350 			if (this->gl_data->glFinish) {
   351 				this->gl_data->glFinish();
   352 			} else if (this->gl_data->glFlush) {
   353 				this->gl_data->glFlush();
   354 			}
   355 		} else {
   356 			this->gl_data->glFinish();
   357 		}
   358 		gl_copyshadow(this, this->screen);
   359 		gl_convert(this, this->screen);
   360 	}
   361 #endif
   362 }
   363 
   364 void SDL_AtariGL_InitPointers(_THIS)
   365 {
   366 #if defined(HAVE_OPENGL)
   367 	this->gl_data->OSMesaCreateContextExt = OSMesaCreateContextExt;
   368 	this->gl_data->OSMesaDestroyContext = OSMesaDestroyContext;
   369 	this->gl_data->OSMesaMakeCurrent = OSMesaMakeCurrent;
   370 	this->gl_data->OSMesaPixelStore = OSMesaPixelStore;
   371 	this->gl_data->OSMesaGetProcAddress = OSMesaGetProcAddress;
   372 
   373 	this->gl_data->glGetIntegerv = glGetIntegerv;
   374 	this->gl_data->glFinish = glFinish;
   375 	this->gl_data->glFlush = glFlush;
   376 
   377 	this->gl_data->OSMesaCreateLDG = NULL;
   378 	this->gl_data->OSMesaDestroyLDG = NULL;
   379 #endif
   380 }
   381 
   382 /*--- Private functions ---*/
   383 
   384 static void SDL_AtariGL_UnloadLibrary(_THIS)
   385 {
   386 #if defined(HAVE_OPENGL)
   387 	if (this->gl_config.dll_handle) {
   388 		SDL_UnloadObject(this->gl_config.dll_handle);
   389 		this->gl_config.dll_handle = NULL;
   390 
   391 		/* Restore pointers to static library */
   392 		SDL_AtariGL_InitPointers(this);
   393 	}
   394 #endif
   395 }
   396 
   397 /*--- Creation of an OpenGL context using new/old functions ---*/
   398 
   399 static int InitNew(_THIS, SDL_Surface *current)
   400 {
   401 	GLenum osmesa_format;
   402 	SDL_PixelFormat *pixel_format;
   403 	Uint32	redmask;
   404 	int recreatecontext;
   405 	GLint newaccumsize;
   406 
   407 	if (this->gl_config.dll_handle) {
   408 		if (this->gl_data->OSMesaCreateContextExt == NULL) {
   409 			return 0;
   410 		}
   411 	}
   412 
   413 	/* Init OpenGL context using OSMesa */
   414 	gl_convert = ConvertNull;
   415 	gl_copyshadow = CopyShadowNull;
   416 
   417 	pixel_format = current->format;
   418 	redmask = pixel_format->Rmask;
   419 	switch (pixel_format->BitsPerPixel) {
   420 		case 15:
   421 			/* 1555, big and little endian, unsupported */
   422 			gl_pixelsize = 2;
   423 			osmesa_format = OSMESA_RGB_565;
   424 			if (redmask == 31<<10) {
   425 				gl_convert = Convert565To555be;
   426 			} else {
   427 				gl_convert = Convert565To555le;
   428 			}
   429 			break;
   430 		case 16:
   431 			gl_pixelsize = 2;
   432 			if (redmask == 31<<11) {
   433 				osmesa_format = OSMESA_RGB_565;
   434 			} else {
   435 				/* 565, little endian, unsupported */
   436 				osmesa_format = OSMESA_RGB_565;
   437 				gl_convert = Convert565le;
   438 			}
   439 			break;
   440 		case 24:
   441 			gl_pixelsize = 3;
   442 			if (redmask == 255<<16) {
   443 				osmesa_format = OSMESA_RGB;
   444 			} else {
   445 				osmesa_format = OSMESA_BGR;
   446 			}
   447 			break;
   448 		case 32:
   449 			gl_pixelsize = 4;
   450 			if (redmask == 255<<16) {
   451 				osmesa_format = OSMESA_ARGB;
   452 			} else if (redmask == 255<<8) {
   453 				osmesa_format = OSMESA_BGRA;
   454 			} else if (redmask == 255<<24) {
   455 				osmesa_format = OSMESA_RGBA;
   456 			} else {
   457 				/* ABGR format unsupported */
   458 				osmesa_format = OSMESA_BGRA;
   459 				gl_convert = ConvertBGRAToABGR;
   460 			}
   461 			break;
   462 		default:
   463 			gl_pixelsize = 1;
   464 			osmesa_format = OSMESA_COLOR_INDEX;
   465 			break;
   466 	}
   467 
   468 	/* Try to keep current context if possible */
   469 	newaccumsize =
   470 		this->gl_config.accum_red_size +
   471 		this->gl_config.accum_green_size +
   472 		this->gl_config.accum_blue_size +
   473 		this->gl_config.accum_alpha_size;
   474 	recreatecontext=1;
   475 	if (gl_ctx &&
   476 		(gl_curformat == osmesa_format) &&
   477 		(gl_curdepth == this->gl_config.depth_size) &&
   478 		(gl_curstencil == this->gl_config.stencil_size) &&
   479 		(gl_curaccum == newaccumsize)) {
   480 		recreatecontext = 0;
   481 	}
   482 	if (recreatecontext) {
   483 		SDL_AtariGL_Quit(this, SDL_FALSE);
   484 
   485 		gl_ctx = this->gl_data->OSMesaCreateContextExt(
   486 			osmesa_format, this->gl_config.depth_size,
   487 			this->gl_config.stencil_size, newaccumsize, NULL );
   488 
   489 		if (gl_ctx) {
   490 			gl_curformat = osmesa_format;
   491 			gl_curdepth = this->gl_config.depth_size;
   492 			gl_curstencil = this->gl_config.stencil_size;
   493 			gl_curaccum = newaccumsize;
   494 		} else {
   495 			gl_curformat = 0;
   496 			gl_curdepth = 0;
   497 			gl_curstencil = 0;
   498 			gl_curaccum = 0;
   499 		}
   500 	}
   501 
   502 	return (gl_ctx != NULL);
   503 }
   504 
   505 static int InitOld(_THIS, SDL_Surface *current)
   506 {
   507 	GLenum osmesa_format;
   508 	SDL_PixelFormat *pixel_format;
   509 	Uint32	redmask;
   510 	int recreatecontext;
   511 
   512 	if (this->gl_config.dll_handle) {
   513 		if (this->gl_data->OSMesaCreateLDG == NULL) {
   514 			return 0;
   515 		}
   516 	}
   517 
   518 	/* Init OpenGL context using OSMesa */
   519 	gl_convert = ConvertNull;
   520 	gl_copyshadow = CopyShadowNull;
   521 
   522 	pixel_format = current->format;
   523 	redmask = pixel_format->Rmask;
   524 	switch (pixel_format->BitsPerPixel) {
   525 		case 15:
   526 			/* 15 bits unsupported */
   527 			gl_pixelsize = 2;
   528 			osmesa_format = OSMESA_ARGB;
   529 			if (redmask == 31<<10) {
   530 				gl_copyshadow = CopyShadow8888To555;
   531 			} else {
   532 				gl_copyshadow = CopyShadow8888To565;
   533 				gl_convert = Convert565To555le;
   534 			}
   535 			break;
   536 		case 16:
   537 			/* 16 bits unsupported */
   538 			gl_pixelsize = 2;
   539 			osmesa_format = OSMESA_ARGB;
   540 			gl_copyshadow = CopyShadow8888To565;
   541 			if (redmask != 31<<11) {
   542 				/* 565, little endian, unsupported */
   543 				gl_convert = Convert565le;
   544 			}
   545 			break;
   546 		case 24:
   547 			gl_pixelsize = 3;
   548 			gl_copyshadow = CopyShadowDirect;
   549 			if (redmask == 255<<16) {
   550 				osmesa_format = OSMESA_RGB;
   551 			} else {
   552 				osmesa_format = OSMESA_BGR;
   553 			}
   554 			break;
   555 		case 32:
   556 			gl_pixelsize = 4;
   557 			gl_copyshadow = CopyShadowDirect;
   558 			if (redmask == 255<<16) {
   559 				osmesa_format = OSMESA_ARGB;
   560 			} else if (redmask == 255<<8) {
   561 				osmesa_format = OSMESA_BGRA;
   562 			} else if (redmask == 255<<24) {
   563 				osmesa_format = OSMESA_RGBA;
   564 			} else {
   565 				/* ABGR format unsupported */
   566 				osmesa_format = OSMESA_BGRA;
   567 				gl_convert = ConvertBGRAToABGR;
   568 			}
   569 			break;
   570 		default:
   571 			gl_pixelsize = 1;
   572 			gl_copyshadow = CopyShadowDirect;
   573 			osmesa_format = OSMESA_COLOR_INDEX;
   574 			break;
   575 	}
   576 
   577 	/* Try to keep current context if possible */
   578 	recreatecontext=1;
   579 	if (gl_shadow &&
   580 		(gl_curformat == osmesa_format) &&
   581 		(gl_curwidth == current->w) &&
   582 		(gl_curheight == current->h)) {
   583 		recreatecontext = 0;
   584 	}
   585 	if (recreatecontext) {
   586 		SDL_AtariGL_Quit(this, SDL_FALSE);
   587 
   588 		gl_shadow = this->gl_data->OSMesaCreateLDG(
   589 			osmesa_format, GL_UNSIGNED_BYTE, current->w, current->h
   590 		);
   591 
   592 		if (gl_shadow) {
   593 			gl_curformat = osmesa_format;
   594 			gl_curwidth = current->w;
   595 			gl_curheight = current->h;
   596 		} else {
   597 			gl_curformat = 0;
   598 			gl_curwidth = 0;
   599 			gl_curheight = 0;
   600 		}
   601 	}
   602 
   603 	return (gl_shadow != NULL);
   604 }
   605 
   606 /*--- Conversions routines from shadow buffer to the screen ---*/
   607 
   608 static void CopyShadowNull(_THIS, SDL_Surface *surface)
   609 {
   610 }
   611 
   612 static void CopyShadowDirect(_THIS, SDL_Surface *surface)
   613 {
   614 	int y, srcpitch, dstpitch;
   615 	Uint8 *srcline, *dstline;
   616 
   617 	srcline = gl_shadow;
   618 	srcpitch = surface->w * gl_pixelsize;
   619 	dstline = surface->pixels;
   620 	dstpitch = surface->pitch;
   621 
   622 	for (y=0; y<surface->h; y++) {
   623 		memcpy(dstline, srcline, srcpitch);
   624 
   625 		srcline += srcpitch;
   626 		dstline += dstpitch;
   627 	}
   628 }
   629 
   630 static void CopyShadow8888To555(_THIS, SDL_Surface *surface)
   631 {
   632 	int x,y, srcpitch, dstpitch;
   633 	Uint16 *dstline, *dstcol;
   634 	Uint32 *srcline, *srccol;
   635 
   636 	srcline = (Uint32 *)gl_shadow;
   637 	srcpitch = surface->w;
   638 	dstline = surface->pixels;
   639 	dstpitch = surface->pitch >>1;
   640 
   641 	for (y=0; y<surface->h; y++) {
   642 		srccol = srcline;
   643 		dstcol = dstline;
   644 		for (x=0; x<surface->w; x++) {
   645 			Uint32 srccolor;
   646 			Uint16 dstcolor;
   647 			
   648 			srccolor = *srccol++;
   649 			dstcolor = (srccolor>>9) & (31<<10);
   650 			dstcolor |= (srccolor>>6) & (31<<5);
   651 			dstcolor |= (srccolor>>3) & 31;
   652 			*dstcol++ = dstcolor;
   653 		}
   654 
   655 		srcline += srcpitch;
   656 		dstline += dstpitch;
   657 	}
   658 }
   659 
   660 static void CopyShadow8888To565(_THIS, SDL_Surface *surface)
   661 {
   662 	int x,y, srcpitch, dstpitch;
   663 	Uint16 *dstline, *dstcol;
   664 	Uint32 *srcline, *srccol;
   665 
   666 	srcline = (Uint32 *)gl_shadow;
   667 	srcpitch = surface->w;
   668 	dstline = surface->pixels;
   669 	dstpitch = surface->pitch >>1;
   670 
   671 	for (y=0; y<surface->h; y++) {
   672 		srccol = srcline;
   673 		dstcol = dstline;
   674 
   675 		for (x=0; x<surface->w; x++) {
   676 			Uint32 srccolor;
   677 			Uint16 dstcolor;
   678 			
   679 			srccolor = *srccol++;
   680 			dstcolor = (srccolor>>8) & (31<<11);
   681 			dstcolor |= (srccolor>>5) & (63<<5);
   682 			dstcolor |= (srccolor>>3) & 31;
   683 			*dstcol++ = dstcolor;
   684 		}
   685 
   686 		srcline += srcpitch;
   687 		dstline += dstpitch;
   688 	}
   689 }
   690 
   691 /*--- Conversions routines in the screen ---*/
   692 
   693 static void ConvertNull(_THIS, SDL_Surface *surface)
   694 {
   695 }
   696 
   697 static void Convert565To555be(_THIS, SDL_Surface *surface)
   698 {
   699 	int x,y, pitch;
   700 	unsigned short *line, *pixel;
   701 
   702 	line = surface->pixels;
   703 	pitch = surface->pitch >> 1;
   704 	for (y=0; y<surface->h; y++) {
   705 		pixel = line;
   706 		for (x=0; x<surface->w; x++) {
   707 			unsigned short color = *pixel;
   708 
   709 			*pixel++ = (color & 0x1f)|((color>>1) & 0xffe0);
   710 		}
   711 
   712 		line += pitch;
   713 	}
   714 }
   715 
   716 static void Convert565To555le(_THIS, SDL_Surface *surface)
   717 {
   718 	int x,y, pitch;
   719 	unsigned short *line, *pixel;
   720 
   721 	line = surface->pixels;
   722 	pitch = surface->pitch >>1;
   723 	for (y=0; y<surface->h; y++) {
   724 		pixel = line;
   725 		for (x=0; x<surface->w; x++) {
   726 			unsigned short color = *pixel;
   727 
   728 			color = (color & 0x1f)|((color>>1) & 0xffe0);
   729 			*pixel++ = SDL_Swap16(color);
   730 		}
   731 
   732 		line += pitch;
   733 	}
   734 }
   735 
   736 static void Convert565le(_THIS, SDL_Surface *surface)
   737 {
   738 	int x,y, pitch;
   739 	unsigned short *line, *pixel;
   740 
   741 	line = surface->pixels;
   742 	pitch = surface->pitch >>1;
   743 	for (y=0; y<surface->h; y++) {
   744 		pixel = line;
   745 		for (x=0; x<surface->w; x++) {
   746 			unsigned short color = *pixel;
   747 
   748 			*pixel++ = SDL_Swap16(color);
   749 		}
   750 
   751 		line += pitch;
   752 	}
   753 }
   754 
   755 static void ConvertBGRAToABGR(_THIS, SDL_Surface *surface)
   756 {
   757 	int x,y, pitch;
   758 	unsigned long *line, *pixel;
   759 
   760 	line = surface->pixels;
   761 	pitch = surface->pitch >>2;
   762 	for (y=0; y<surface->h; y++) {
   763 		pixel = line;
   764 		for (x=0; x<surface->w; x++) {
   765 			unsigned long color = *pixel;
   766 
   767 			*pixel++ = (color<<24)|(color>>8);
   768 		}
   769 
   770 		line += pitch;
   771 	}
   772 }