symbian-qemu-0.9.1-12/libsdl-trunk/src/video/ataricommon/SDL_atarigl.c
changeset 1 2fb8b9db1c86
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/symbian-qemu-0.9.1-12/libsdl-trunk/src/video/ataricommon/SDL_atarigl.c	Fri Jul 31 15:01:17 2009 +0100
@@ -0,0 +1,1088 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2004 Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+/* Atari OSMesa.ldg implementation of SDL OpenGL support */
+
+/*--- Includes ---*/
+
+#if SDL_VIDEO_OPENGL
+#include <GL/osmesa.h>
+#endif
+
+#include <mint/osbind.h>
+
+#include "SDL_endian.h"
+#include "SDL_video.h"
+#include "SDL_atarigl_c.h"
+#if SDL_VIDEO_OPENGL_OSMESA_DYNAMIC
+#include "SDL_loadso.h"
+#endif
+
+/*--- Defines ---*/
+
+#define PATH_OSMESA_LDG	"osmesa.ldg"
+#define PATH_MESAGL_LDG	"mesa_gl.ldg"
+#define PATH_TINYGL_LDG	"tiny_gl.ldg"
+
+#define VDI_RGB	0xf
+
+/*--- Functions prototypes ---*/
+
+static void SDL_AtariGL_UnloadLibrary(_THIS);
+
+#if SDL_VIDEO_OPENGL
+static void CopyShadowNull(_THIS, SDL_Surface *surface);
+static void CopyShadowDirect(_THIS, SDL_Surface *surface);
+static void CopyShadowRGBTo555(_THIS, SDL_Surface *surface);
+static void CopyShadowRGBTo565(_THIS, SDL_Surface *surface);
+static void CopyShadowRGBSwap(_THIS, SDL_Surface *surface);
+static void CopyShadowRGBToARGB(_THIS, SDL_Surface *surface);
+static void CopyShadowRGBToABGR(_THIS, SDL_Surface *surface);
+static void CopyShadowRGBToBGRA(_THIS, SDL_Surface *surface);
+static void CopyShadowRGBToRGBA(_THIS, SDL_Surface *surface);
+static void CopyShadow8888To555(_THIS, SDL_Surface *surface);
+static void CopyShadow8888To565(_THIS, SDL_Surface *surface);
+
+static void ConvertNull(_THIS, SDL_Surface *surface);
+static void Convert565To555be(_THIS, SDL_Surface *surface);
+static void Convert565To555le(_THIS, SDL_Surface *surface);
+static void Convert565le(_THIS, SDL_Surface *surface);
+static void ConvertBGRAToABGR(_THIS, SDL_Surface *surface);
+
+static int InitNew(_THIS, SDL_Surface *current);
+static int InitOld(_THIS, SDL_Surface *current);
+#endif
+
+/*--- Public functions ---*/
+
+int SDL_AtariGL_Init(_THIS, SDL_Surface *current)
+{
+#if SDL_VIDEO_OPENGL
+	if (gl_oldmesa) {
+		gl_active = InitOld(this, current);		
+	} else {
+		gl_active = InitNew(this, current);		
+	}
+#endif
+
+	return (gl_active);
+}
+
+void SDL_AtariGL_Quit(_THIS, SDL_bool unload)
+{
+#if SDL_VIDEO_OPENGL
+	if (gl_oldmesa) {
+		/* Old mesa implementations */
+		if (this->gl_data->OSMesaDestroyLDG) {
+			this->gl_data->OSMesaDestroyLDG();
+		}
+		if (gl_shadow) {
+			Mfree(gl_shadow);
+			gl_shadow = NULL;
+		}
+	} else {
+		/* New mesa implementation */
+		if (gl_ctx) {
+			if (this->gl_data->OSMesaDestroyContext) {
+				this->gl_data->OSMesaDestroyContext(gl_ctx);
+			}
+			gl_ctx = NULL;
+		}
+	}
+
+	if (unload) {
+		SDL_AtariGL_UnloadLibrary(this);
+	}
+
+#endif /* SDL_VIDEO_OPENGL */
+	gl_active = 0;
+}
+
+int SDL_AtariGL_LoadLibrary(_THIS, const char *path)
+{
+#if SDL_VIDEO_OPENGL
+
+#if SDL_VIDEO_OPENGL_OSMESA_DYNAMIC
+	void *handle;
+	SDL_bool cancel_load;
+
+	if (gl_active) {
+		SDL_SetError("OpenGL context already created");
+		return -1;
+	}
+
+	/* Unload previous driver */
+	SDL_AtariGL_UnloadLibrary(this);
+
+	/* Load library given by path */
+	handle = SDL_LoadObject(path);
+	if (handle == NULL) {
+		/* Try to load another one */
+		path = SDL_getenv("SDL_VIDEO_GL_DRIVER");
+		if ( path != NULL ) {
+			handle = SDL_LoadObject(path);
+		}
+
+		/* If it does not work, try some other */
+		if (handle == NULL) {
+			path = PATH_OSMESA_LDG;
+			handle = SDL_LoadObject(path);
+		}
+
+		if (handle == NULL) {
+			path = PATH_MESAGL_LDG;
+			handle = SDL_LoadObject(path);
+		}
+
+		if (handle == NULL) {
+			path = PATH_TINYGL_LDG;
+			handle = SDL_LoadObject(path);
+		}
+	}
+
+	if (handle == NULL) {
+		SDL_SetError("Could not load OpenGL library");
+		return -1;
+	}
+
+	this->gl_data->glGetIntegerv = SDL_LoadFunction(handle, "glGetIntegerv");
+	this->gl_data->glFinish = SDL_LoadFunction(handle, "glFinish");
+	this->gl_data->glFlush = SDL_LoadFunction(handle, "glFlush");
+
+	cancel_load = SDL_FALSE;
+	if (this->gl_data->glGetIntegerv == NULL) {
+		cancel_load = SDL_TRUE;
+	} else {
+		/* We need either glFinish (OSMesa) or glFlush (TinyGL) */
+		if ((this->gl_data->glFinish == NULL) &&
+			(this->gl_data->glFlush == NULL)) {
+				cancel_load = SDL_TRUE;
+		}
+	}
+	if (cancel_load) {
+		SDL_SetError("Could not retrieve OpenGL functions");
+		SDL_UnloadObject(handle);
+		/* Restore pointers to static library */
+		SDL_AtariGL_InitPointers(this);
+		return -1;
+	}
+
+	/* Load functions pointers (osmesa.ldg) */
+	this->gl_data->OSMesaCreateContextExt = SDL_LoadFunction(handle, "OSMesaCreateContextExt");
+	this->gl_data->OSMesaDestroyContext = SDL_LoadFunction(handle, "OSMesaDestroyContext");
+	this->gl_data->OSMesaMakeCurrent = SDL_LoadFunction(handle, "OSMesaMakeCurrent");
+	this->gl_data->OSMesaPixelStore = SDL_LoadFunction(handle, "OSMesaPixelStore");
+	this->gl_data->OSMesaGetProcAddress = SDL_LoadFunction(handle, "OSMesaGetProcAddress");
+
+	/* Load old functions pointers (mesa_gl.ldg, tiny_gl.ldg) */
+	this->gl_data->OSMesaCreateLDG = SDL_LoadFunction(handle, "OSMesaCreateLDG");
+	this->gl_data->OSMesaDestroyLDG = SDL_LoadFunction(handle, "OSMesaDestroyLDG");
+
+	gl_oldmesa = 0;
+
+	if ( (this->gl_data->OSMesaCreateContextExt == NULL) || 
+	     (this->gl_data->OSMesaDestroyContext == NULL) ||
+	     (this->gl_data->OSMesaMakeCurrent == NULL) ||
+	     (this->gl_data->OSMesaPixelStore == NULL) ||
+	     (this->gl_data->OSMesaGetProcAddress == NULL)) {
+		/* Hum, maybe old library ? */
+		if ( (this->gl_data->OSMesaCreateLDG == NULL) || 
+		     (this->gl_data->OSMesaDestroyLDG == NULL)) {
+			SDL_SetError("Could not retrieve OSMesa functions");
+			SDL_UnloadObject(handle);
+			/* Restore pointers to static library */
+			SDL_AtariGL_InitPointers(this);
+			return -1;
+		} else {
+			gl_oldmesa = 1;
+		}
+	}
+
+	this->gl_config.dll_handle = handle;
+	if ( path ) {
+		SDL_strlcpy(this->gl_config.driver_path, path,
+			SDL_arraysize(this->gl_config.driver_path));
+	} else {
+		*this->gl_config.driver_path = '\0';
+	}
+
+#endif
+	this->gl_config.driver_loaded = 1;
+
+	return 0;
+#else
+	return -1;
+#endif
+}
+
+void *SDL_AtariGL_GetProcAddress(_THIS, const char *proc)
+{
+	void *func = NULL;
+#if SDL_VIDEO_OPENGL
+
+	if (this->gl_config.dll_handle) {
+		func = SDL_LoadFunction(this->gl_config.dll_handle, (void *)proc);
+	} else if (this->gl_data->OSMesaGetProcAddress) {
+		func = this->gl_data->OSMesaGetProcAddress(proc);
+	}
+
+#endif
+	return func;
+}
+
+int SDL_AtariGL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
+{
+#if SDL_VIDEO_OPENGL
+	GLenum mesa_attrib;
+	SDL_Surface *surface;
+
+	if (!gl_active) {
+		return -1;
+	}
+
+	switch(attrib) {
+		case SDL_GL_RED_SIZE:
+			mesa_attrib = GL_RED_BITS;
+			break;
+		case SDL_GL_GREEN_SIZE:
+			mesa_attrib = GL_GREEN_BITS;
+			break;
+		case SDL_GL_BLUE_SIZE:
+			mesa_attrib = GL_BLUE_BITS;
+			break;
+		case SDL_GL_ALPHA_SIZE:
+			mesa_attrib = GL_ALPHA_BITS;
+			break;
+		case SDL_GL_DOUBLEBUFFER:
+			surface = this->screen;
+			*value = ((surface->flags & SDL_DOUBLEBUF)==SDL_DOUBLEBUF);
+			return 0;
+		case SDL_GL_DEPTH_SIZE:
+			mesa_attrib = GL_DEPTH_BITS;
+			break;
+		case SDL_GL_STENCIL_SIZE:
+			mesa_attrib = GL_STENCIL_BITS;
+			break;
+		case SDL_GL_ACCUM_RED_SIZE:
+			mesa_attrib = GL_ACCUM_RED_BITS;
+			break;
+		case SDL_GL_ACCUM_GREEN_SIZE:
+			mesa_attrib = GL_ACCUM_GREEN_BITS;
+			break;
+		case SDL_GL_ACCUM_BLUE_SIZE:
+			mesa_attrib = GL_ACCUM_BLUE_BITS;
+			break;
+		case SDL_GL_ACCUM_ALPHA_SIZE:
+			mesa_attrib = GL_ACCUM_ALPHA_BITS;
+			break;
+		default :
+			return -1;
+	}
+
+	this->gl_data->glGetIntegerv(mesa_attrib, value);
+	return 0;
+#else
+	return -1;
+#endif
+}
+
+int SDL_AtariGL_MakeCurrent(_THIS)
+{
+#if SDL_VIDEO_OPENGL
+	SDL_Surface *surface;
+	GLenum type;
+
+	if (gl_oldmesa && gl_active) {
+		return 0;
+	}
+
+	if (this->gl_config.dll_handle) {
+		if ((this->gl_data->OSMesaMakeCurrent == NULL) ||
+			(this->gl_data->OSMesaPixelStore == NULL)) {
+			return -1;
+		}
+	}
+
+	if (!gl_active) {
+		SDL_SetError("Invalid OpenGL context");
+		return -1;
+	}
+
+	surface = this->screen;
+	
+	if ((surface->format->BitsPerPixel == 15) || (surface->format->BitsPerPixel == 16)) {
+		type = GL_UNSIGNED_SHORT_5_6_5;
+	} else {
+		type = GL_UNSIGNED_BYTE;
+	}
+
+	if (!(this->gl_data->OSMesaMakeCurrent(gl_ctx, surface->pixels, type, surface->w, surface->h))) {
+		SDL_SetError("Can not make OpenGL context current");
+		return -1;
+	}
+
+	/* OSMesa draws upside down */
+	this->gl_data->OSMesaPixelStore(OSMESA_Y_UP, 0);
+
+	return 0;
+#else
+	return -1;
+#endif
+}
+
+void SDL_AtariGL_SwapBuffers(_THIS)
+{
+#if SDL_VIDEO_OPENGL
+	if (gl_active) {
+		if (this->gl_config.dll_handle) {
+			if (this->gl_data->glFinish) {
+				this->gl_data->glFinish();
+			} else if (this->gl_data->glFlush) {
+				this->gl_data->glFlush();
+			}
+		} else {
+			this->gl_data->glFinish();
+		}
+		gl_copyshadow(this, this->screen);
+		gl_convert(this, this->screen);
+	}
+#endif
+}
+
+void SDL_AtariGL_InitPointers(_THIS)
+{
+#if SDL_VIDEO_OPENGL
+	this->gl_data->OSMesaCreateContextExt = OSMesaCreateContextExt;
+	this->gl_data->OSMesaDestroyContext = OSMesaDestroyContext;
+	this->gl_data->OSMesaMakeCurrent = OSMesaMakeCurrent;
+	this->gl_data->OSMesaPixelStore = OSMesaPixelStore;
+	this->gl_data->OSMesaGetProcAddress = OSMesaGetProcAddress;
+
+	this->gl_data->glGetIntegerv = glGetIntegerv;
+	this->gl_data->glFinish = glFinish;
+	this->gl_data->glFlush = glFlush;
+
+	this->gl_data->OSMesaCreateLDG = NULL;
+	this->gl_data->OSMesaDestroyLDG = NULL;
+#endif
+}
+
+/*--- Private functions ---*/
+
+static void SDL_AtariGL_UnloadLibrary(_THIS)
+{
+#if SDL_VIDEO_OPENGL
+	if (this->gl_config.dll_handle) {
+		SDL_UnloadObject(this->gl_config.dll_handle);
+		this->gl_config.dll_handle = NULL;
+
+		/* Restore pointers to static library */
+		SDL_AtariGL_InitPointers(this);
+	}
+#endif
+}
+
+/*--- Creation of an OpenGL context using new/old functions ---*/
+
+#if SDL_VIDEO_OPENGL
+static int InitNew(_THIS, SDL_Surface *current)
+{
+	GLenum osmesa_format;
+	SDL_PixelFormat *pixel_format;
+	Uint32	redmask;
+	int recreatecontext;
+	GLint newaccumsize;
+
+	if (this->gl_config.dll_handle) {
+		if (this->gl_data->OSMesaCreateContextExt == NULL) {
+			return 0;
+		}
+	}
+
+	/* Init OpenGL context using OSMesa */
+	gl_convert = ConvertNull;
+	gl_copyshadow = CopyShadowNull;
+	gl_upsidedown = SDL_FALSE;
+
+	pixel_format = current->format;
+	redmask = pixel_format->Rmask;
+	switch (pixel_format->BitsPerPixel) {
+		case 15:
+			/* 1555, big and little endian, unsupported */
+			gl_pixelsize = 2;
+			osmesa_format = OSMESA_RGB_565;
+			if (redmask == 31<<10) {
+				gl_convert = Convert565To555be;
+			} else {
+				gl_convert = Convert565To555le;
+			}
+			break;
+		case 16:
+			gl_pixelsize = 2;
+			if (redmask == 31<<11) {
+				osmesa_format = OSMESA_RGB_565;
+			} else {
+				/* 565, little endian, unsupported */
+				osmesa_format = OSMESA_RGB_565;
+				gl_convert = Convert565le;
+			}
+			break;
+		case 24:
+			gl_pixelsize = 3;
+			if (redmask == 255<<16) {
+				osmesa_format = OSMESA_RGB;
+			} else {
+				osmesa_format = OSMESA_BGR;
+			}
+			break;
+		case 32:
+			gl_pixelsize = 4;
+			if (redmask == 255<<16) {
+				osmesa_format = OSMESA_ARGB;
+			} else if (redmask == 255<<8) {
+				osmesa_format = OSMESA_BGRA;
+			} else if (redmask == 255<<24) {
+				osmesa_format = OSMESA_RGBA;
+			} else {
+				/* ABGR format unsupported */
+				osmesa_format = OSMESA_BGRA;
+				gl_convert = ConvertBGRAToABGR;
+			}
+			break;
+		default:
+			gl_pixelsize = 1;
+			osmesa_format = OSMESA_COLOR_INDEX;
+			break;
+	}
+
+	/* Try to keep current context if possible */
+	newaccumsize =
+		this->gl_config.accum_red_size +
+		this->gl_config.accum_green_size +
+		this->gl_config.accum_blue_size +
+		this->gl_config.accum_alpha_size;
+	recreatecontext=1;
+	if (gl_ctx &&
+		(gl_curformat == osmesa_format) &&
+		(gl_curdepth == this->gl_config.depth_size) &&
+		(gl_curstencil == this->gl_config.stencil_size) &&
+		(gl_curaccum == newaccumsize)) {
+		recreatecontext = 0;
+	}
+	if (recreatecontext) {
+		SDL_AtariGL_Quit(this, SDL_FALSE);
+
+		gl_ctx = this->gl_data->OSMesaCreateContextExt(
+			osmesa_format, this->gl_config.depth_size,
+			this->gl_config.stencil_size, newaccumsize, NULL );
+
+		if (gl_ctx) {
+			gl_curformat = osmesa_format;
+			gl_curdepth = this->gl_config.depth_size;
+			gl_curstencil = this->gl_config.stencil_size;
+			gl_curaccum = newaccumsize;
+		} else {
+			gl_curformat = 0;
+			gl_curdepth = 0;
+			gl_curstencil = 0;
+			gl_curaccum = 0;
+		}
+	}
+
+	return (gl_ctx != NULL);
+}
+
+
+static int InitOld(_THIS, SDL_Surface *current)
+{
+	GLenum osmesa_format;
+	SDL_PixelFormat *pixel_format;
+	Uint32	redmask;
+	int recreatecontext, tinygl_present;
+
+	if (this->gl_config.dll_handle) {
+		if (this->gl_data->OSMesaCreateLDG == NULL) {
+			return 0;
+		}
+	}
+
+	/* TinyGL only supports VDI_RGB (OSMESA_RGB) */
+	tinygl_present=0;
+	if (this->gl_config.dll_handle) {
+		if (this->gl_data->glFinish == NULL) {
+			tinygl_present=1;
+		}
+	}
+
+	/* Init OpenGL context using OSMesa */
+	gl_convert = ConvertNull;
+	gl_copyshadow = CopyShadowNull;
+	gl_upsidedown = SDL_FALSE;
+
+	pixel_format = current->format;
+	redmask = pixel_format->Rmask;
+	switch (pixel_format->BitsPerPixel) {
+		case 15:
+			/* 15 bits unsupported */
+			if (tinygl_present) {
+				gl_pixelsize = 3;
+				osmesa_format = VDI_RGB;
+				if (redmask == 31<<10) {
+					gl_copyshadow = CopyShadowRGBTo555;
+				} else {
+					gl_copyshadow = CopyShadowRGBTo565;
+					gl_convert = Convert565To555le;
+				}
+			} else {
+				gl_pixelsize = 4;
+				gl_upsidedown = SDL_TRUE;
+				osmesa_format = OSMESA_ARGB;
+				if (redmask == 31<<10) {
+					gl_copyshadow = CopyShadow8888To555;
+				} else {
+					gl_copyshadow = CopyShadow8888To565;
+					gl_convert = Convert565To555le;
+				}
+			}
+			break;
+		case 16:
+			/* 16 bits unsupported */
+			if (tinygl_present) {
+				gl_pixelsize = 3;
+				osmesa_format = VDI_RGB;
+				gl_copyshadow = CopyShadowRGBTo565;
+				if (redmask != 31<<11) {
+					/* 565, little endian, unsupported */
+					gl_convert = Convert565le;
+				}
+			} else {
+				gl_pixelsize = 4;
+				gl_upsidedown = SDL_TRUE;
+				osmesa_format = OSMESA_ARGB;
+				gl_copyshadow = CopyShadow8888To565;
+				if (redmask != 31<<11) {
+					/* 565, little endian, unsupported */
+					gl_convert = Convert565le;
+				}
+			}
+			break;
+		case 24:
+			gl_pixelsize = 3;
+			if (tinygl_present) {
+				osmesa_format = VDI_RGB;
+				gl_copyshadow = CopyShadowDirect;
+				if (redmask != 255<<16) {
+					gl_copyshadow = CopyShadowRGBSwap;
+				}
+			} else {
+				gl_copyshadow = CopyShadowDirect;
+				gl_upsidedown = SDL_TRUE;
+				if (redmask == 255<<16) {
+					osmesa_format = OSMESA_RGB;
+				} else {
+					osmesa_format = OSMESA_BGR;
+				}
+			}
+			break;
+		case 32:
+			if (tinygl_present) {
+				gl_pixelsize = 3;
+				osmesa_format = VDI_RGB;
+				gl_copyshadow = CopyShadowRGBToARGB;
+				if (redmask == 255) {
+					gl_convert = CopyShadowRGBToABGR;
+				} else if (redmask == 255<<8) {
+					gl_convert = CopyShadowRGBToBGRA;
+				} else if (redmask == 255<<24) {
+					gl_convert = CopyShadowRGBToRGBA;
+				}
+			} else {
+				gl_pixelsize = 4;
+				gl_upsidedown = SDL_TRUE;
+				gl_copyshadow = CopyShadowDirect;
+				if (redmask == 255<<16) {
+					osmesa_format = OSMESA_ARGB;
+				} else if (redmask == 255<<8) {
+					osmesa_format = OSMESA_BGRA;
+				} else if (redmask == 255<<24) {
+					osmesa_format = OSMESA_RGBA;
+				} else {
+					/* ABGR format unsupported */
+					osmesa_format = OSMESA_BGRA;
+					gl_convert = ConvertBGRAToABGR;
+				}
+			}
+			break;
+		default:
+			if (tinygl_present) {
+				SDL_AtariGL_Quit(this, SDL_FALSE);
+				return 0;
+			}
+			gl_pixelsize = 1;
+			gl_copyshadow = CopyShadowDirect;
+			osmesa_format = OSMESA_COLOR_INDEX;
+			break;
+	}
+
+	/* Try to keep current context if possible */
+	recreatecontext=1;
+	if (gl_shadow &&
+		(gl_curformat == osmesa_format) &&
+		(gl_curwidth == current->w) &&
+		(gl_curheight == current->h)) {
+		recreatecontext = 0;
+	}
+	if (recreatecontext) {
+		SDL_AtariGL_Quit(this, SDL_FALSE);
+
+		gl_shadow = this->gl_data->OSMesaCreateLDG(
+			osmesa_format, GL_UNSIGNED_BYTE, current->w, current->h
+		);
+
+		if (gl_shadow) {
+			gl_curformat = osmesa_format;
+			gl_curwidth = current->w;
+			gl_curheight = current->h;
+		} else {
+			gl_curformat = 0;
+			gl_curwidth = 0;
+			gl_curheight = 0;
+		}
+	}
+
+	return (gl_shadow != NULL);
+}
+
+/*--- Conversions routines from shadow buffer to the screen ---*/
+
+static void CopyShadowNull(_THIS, SDL_Surface *surface)
+{
+}
+
+static void CopyShadowDirect(_THIS, SDL_Surface *surface)
+{
+	int y, srcpitch, dstpitch;
+	Uint8 *srcline, *dstline;
+
+	srcline = gl_shadow;
+	srcpitch = surface->w * gl_pixelsize;
+	dstline = surface->pixels;
+	dstpitch = surface->pitch;
+	if (gl_upsidedown) {
+		srcline += (surface->h-1)*srcpitch;
+		srcpitch = -srcpitch;
+	}
+
+	for (y=0; y<surface->h; y++) {
+		SDL_memcpy(dstline, srcline, srcpitch);
+
+		srcline += srcpitch;
+		dstline += dstpitch;
+	}
+}
+
+static void CopyShadowRGBTo555(_THIS, SDL_Surface *surface)
+{
+	int x,y, srcpitch, dstpitch;
+	Uint16 *dstline, *dstcol;
+	Uint8 *srcline, *srccol;
+
+	srcline = (Uint8 *)gl_shadow;
+	srcpitch = surface->w * gl_pixelsize;
+	dstline = surface->pixels;
+	dstpitch = surface->pitch >>1;
+	if (gl_upsidedown) {
+		srcline += (surface->h-1)*srcpitch;
+		srcpitch = -srcpitch;
+	}
+
+	for (y=0; y<surface->h; y++) {
+		srccol = srcline;
+		dstcol = dstline;
+		for (x=0; x<surface->w; x++) {
+			Uint16 dstcolor;
+			
+			dstcolor = ((*srccol++)<<7) & (31<<10);
+			dstcolor |= ((*srccol++)<<2) & (31<<5);
+			dstcolor |= ((*srccol++)>>3) & 31;
+			*dstcol++ = dstcolor;
+		}
+
+		srcline += srcpitch;
+		dstline += dstpitch;
+	}
+}
+
+static void CopyShadowRGBTo565(_THIS, SDL_Surface *surface)
+{
+	int x,y, srcpitch, dstpitch;
+	Uint16 *dstline, *dstcol;
+	Uint8 *srcline, *srccol;
+
+	srcline = (Uint8 *)gl_shadow;
+	srcpitch = surface->w * gl_pixelsize;
+	dstline = surface->pixels;
+	dstpitch = surface->pitch >>1;
+	if (gl_upsidedown) {
+		srcline += (surface->h-1)*srcpitch;
+		srcpitch = -srcpitch;
+	}
+
+	for (y=0; y<surface->h; y++) {
+		srccol = srcline;
+		dstcol = dstline;
+
+		for (x=0; x<surface->w; x++) {
+			Uint16 dstcolor;
+			
+			dstcolor = ((*srccol++)<<8) & (31<<11);
+			dstcolor |= ((*srccol++)<<3) & (63<<5);
+			dstcolor |= ((*srccol++)>>3) & 31;
+			*dstcol++ = dstcolor;
+		}
+
+		srcline += srcpitch;
+		dstline += dstpitch;
+	}
+}
+
+static void CopyShadowRGBSwap(_THIS, SDL_Surface *surface)
+{
+	int x,y, srcpitch, dstpitch;
+	Uint8 *dstline, *dstcol;
+	Uint8 *srcline, *srccol;
+
+	srcline = (Uint8 *)gl_shadow;
+	srcpitch = surface->w * gl_pixelsize;
+	dstline = surface->pixels;
+	dstpitch = surface->pitch;
+	if (gl_upsidedown) {
+		srcline += (surface->h-1)*srcpitch;
+		srcpitch = -srcpitch;
+	}
+
+	for (y=0; y<surface->h; y++) {
+		srccol = srcline;
+		dstcol = dstline;
+
+		for (x=0; x<surface->w; x++) {
+			*dstcol++ = srccol[2];
+			*dstcol++ = srccol[1];
+			*dstcol++ = srccol[0];
+			srccol += 3;
+		}
+
+		srcline += srcpitch;
+		dstline += dstpitch;
+	}
+}
+
+static void CopyShadowRGBToARGB(_THIS, SDL_Surface *surface)
+{
+	int x,y, srcpitch, dstpitch;
+	Uint32 *dstline, *dstcol;
+	Uint8 *srcline, *srccol;
+
+	srcline = (Uint8 *)gl_shadow;
+	srcpitch = surface->w * gl_pixelsize;
+	dstline = surface->pixels;
+	dstpitch = surface->pitch >>2;
+	if (gl_upsidedown) {
+		srcline += (surface->h-1)*srcpitch;
+		srcpitch = -srcpitch;
+	}
+
+	for (y=0; y<surface->h; y++) {
+		srccol = srcline;
+		dstcol = dstline;
+
+		for (x=0; x<surface->w; x++) {
+			Uint32	dstcolor;
+
+			dstcolor = (*srccol++)<<16;
+			dstcolor |= (*srccol++)<<8;
+			dstcolor |= *srccol++;
+
+			*dstcol++ = dstcolor;
+		}
+
+		srcline += srcpitch;
+		dstline += dstpitch;
+	}
+}
+
+static void CopyShadowRGBToABGR(_THIS, SDL_Surface *surface)
+{
+	int x,y, srcpitch, dstpitch;
+	Uint32 *dstline, *dstcol;
+	Uint8 *srcline, *srccol;
+
+	srcline = (Uint8 *)gl_shadow;
+	srcpitch = surface->w * gl_pixelsize;
+	dstline = surface->pixels;
+	dstpitch = surface->pitch >>2;
+	if (gl_upsidedown) {
+		srcline += (surface->h-1)*srcpitch;
+		srcpitch = -srcpitch;
+	}
+
+	for (y=0; y<surface->h; y++) {
+		srccol = srcline;
+		dstcol = dstline;
+
+		for (x=0; x<surface->w; x++) {
+			Uint32	dstcolor;
+
+			dstcolor = *srccol++;
+			dstcolor |= (*srccol++)<<8;
+			dstcolor |= (*srccol++)<<16;
+
+			*dstcol++ = dstcolor;
+		}
+
+		srcline += srcpitch;
+		dstline += dstpitch;
+	}
+}
+
+static void CopyShadowRGBToBGRA(_THIS, SDL_Surface *surface)
+{
+	int x,y, srcpitch, dstpitch;
+	Uint32 *dstline, *dstcol;
+	Uint8 *srcline, *srccol;
+
+	srcline = (Uint8 *)gl_shadow;
+	srcpitch = surface->w * gl_pixelsize;
+	dstline = surface->pixels;
+	dstpitch = surface->pitch >>2;
+	if (gl_upsidedown) {
+		srcline += (surface->h-1)*srcpitch;
+		srcpitch = -srcpitch;
+	}
+
+	for (y=0; y<surface->h; y++) {
+		srccol = srcline;
+		dstcol = dstline;
+
+		for (x=0; x<surface->w; x++) {
+			Uint32	dstcolor;
+
+			dstcolor = (*srccol++)<<8;
+			dstcolor |= (*srccol++)<<16;
+			dstcolor |= (*srccol++)<<24;
+
+			*dstcol++ = dstcolor;
+		}
+
+		srcline += srcpitch;
+		dstline += dstpitch;
+	}
+}
+
+static void CopyShadowRGBToRGBA(_THIS, SDL_Surface *surface)
+{
+	int x,y, srcpitch, dstpitch;
+	Uint32 *dstline, *dstcol;
+	Uint8 *srcline, *srccol;
+
+	srcline = (Uint8 *)gl_shadow;
+	srcpitch = surface->w * gl_pixelsize;
+	dstline = surface->pixels;
+	dstpitch = surface->pitch >>2;
+	if (gl_upsidedown) {
+		srcline += (surface->h-1)*srcpitch;
+		srcpitch = -srcpitch;
+	}
+
+	for (y=0; y<surface->h; y++) {
+		srccol = srcline;
+		dstcol = dstline;
+
+		for (x=0; x<surface->w; x++) {
+			Uint32	dstcolor;
+
+			dstcolor = (*srccol++)<<24;
+			dstcolor |= (*srccol++)<<16;
+			dstcolor |= (*srccol++)<<8;
+
+			*dstcol++ = dstcolor;
+		}
+
+		srcline += srcpitch;
+		dstline += dstpitch;
+	}
+}
+
+static void CopyShadow8888To555(_THIS, SDL_Surface *surface)
+{
+	int x,y, srcpitch, dstpitch;
+	Uint16 *dstline, *dstcol;
+	Uint32 *srcline, *srccol;
+
+	srcline = (Uint32 *)gl_shadow;
+	srcpitch = (surface->w * gl_pixelsize) >>2;
+	dstline = surface->pixels;
+	dstpitch = surface->pitch >>1;
+	if (gl_upsidedown) {
+		srcline += (surface->h-1)*srcpitch;
+		srcpitch = -srcpitch;
+	}
+
+	for (y=0; y<surface->h; y++) {
+		srccol = srcline;
+		dstcol = dstline;
+		for (x=0; x<surface->w; x++) {
+			Uint32 srccolor;
+			Uint16 dstcolor;
+			
+			srccolor = *srccol++;
+			dstcolor = (srccolor>>9) & (31<<10);
+			dstcolor |= (srccolor>>6) & (31<<5);
+			dstcolor |= (srccolor>>3) & 31;
+			*dstcol++ = dstcolor;
+		}
+
+		srcline += srcpitch;
+		dstline += dstpitch;
+	}
+}
+
+static void CopyShadow8888To565(_THIS, SDL_Surface *surface)
+{
+	int x,y, srcpitch, dstpitch;
+	Uint16 *dstline, *dstcol;
+	Uint32 *srcline, *srccol;
+
+	srcline = (Uint32 *)gl_shadow;
+	srcpitch = (surface->w * gl_pixelsize) >> 2;
+	dstline = surface->pixels;
+	dstpitch = surface->pitch >>1;
+	if (gl_upsidedown) {
+		srcline += (surface->h-1)*srcpitch;
+		srcpitch = -srcpitch;
+	}
+
+	for (y=0; y<surface->h; y++) {
+		srccol = srcline;
+		dstcol = dstline;
+
+		for (x=0; x<surface->w; x++) {
+			Uint32 srccolor;
+			Uint16 dstcolor;
+			
+			srccolor = *srccol++;
+			dstcolor = (srccolor>>8) & (31<<11);
+			dstcolor |= (srccolor>>5) & (63<<5);
+			dstcolor |= (srccolor>>3) & 31;
+			*dstcol++ = dstcolor;
+		}
+
+		srcline += srcpitch;
+		dstline += dstpitch;
+	}
+}
+
+/*--- Conversions routines in the screen ---*/
+
+static void ConvertNull(_THIS, SDL_Surface *surface)
+{
+}
+
+static void Convert565To555be(_THIS, SDL_Surface *surface)
+{
+	int x,y, pitch;
+	unsigned short *line, *pixel;
+
+	line = surface->pixels;
+	pitch = surface->pitch >> 1;
+	for (y=0; y<surface->h; y++) {
+		pixel = line;
+		for (x=0; x<surface->w; x++) {
+			unsigned short color = *pixel;
+
+			*pixel++ = (color & 0x1f)|((color>>1) & 0xffe0);
+		}
+
+		line += pitch;
+	}
+}
+
+static void Convert565To555le(_THIS, SDL_Surface *surface)
+{
+	int x,y, pitch;
+	unsigned short *line, *pixel;
+
+	line = surface->pixels;
+	pitch = surface->pitch >>1;
+	for (y=0; y<surface->h; y++) {
+		pixel = line;
+		for (x=0; x<surface->w; x++) {
+			unsigned short color = *pixel;
+
+			color = (color & 0x1f)|((color>>1) & 0xffe0);
+			*pixel++ = SDL_Swap16(color);
+		}
+
+		line += pitch;
+	}
+}
+
+static void Convert565le(_THIS, SDL_Surface *surface)
+{
+	int x,y, pitch;
+	unsigned short *line, *pixel;
+
+	line = surface->pixels;
+	pitch = surface->pitch >>1;
+	for (y=0; y<surface->h; y++) {
+		pixel = line;
+		for (x=0; x<surface->w; x++) {
+			unsigned short color = *pixel;
+
+			*pixel++ = SDL_Swap16(color);
+		}
+
+		line += pitch;
+	}
+}
+
+static void ConvertBGRAToABGR(_THIS, SDL_Surface *surface)
+{
+	int x,y, pitch;
+	unsigned long *line, *pixel;
+
+	line = surface->pixels;
+	pitch = surface->pitch >>2;
+	for (y=0; y<surface->h; y++) {
+		pixel = line;
+		for (x=0; x<surface->w; x++) {
+			unsigned long color = *pixel;
+
+			*pixel++ = (color<<24)|(color>>8);
+		}
+
+		line += pitch;
+	}
+}
+
+#endif /* SDL_VIDEO_OPENGL */