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