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