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