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