symbian-qemu-0.9.1-12/libsdl-trunk/src/video/ataricommon/SDL_atarigl.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 #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 */