src/video/ataricommon/SDL_atarigl.c
changeset 989 475166d13b44
child 991 12b13601a544
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/video/ataricommon/SDL_atarigl.c	Thu Nov 25 15:47:49 2004 +0000
     1.3 @@ -0,0 +1,331 @@
     1.4 +/*
     1.5 +    SDL - Simple DirectMedia Layer
     1.6 +    Copyright (C) 1997-2004 Sam Lantinga
     1.7 +
     1.8 +    This library is free software; you can redistribute it and/or
     1.9 +    modify it under the terms of the GNU Library General Public
    1.10 +    License as published by the Free Software Foundation; either
    1.11 +    version 2 of the License, or (at your option) any later version.
    1.12 +
    1.13 +    This library is distributed in the hope that it will be useful,
    1.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.16 +    Library General Public License for more details.
    1.17 +
    1.18 +    You should have received a copy of the GNU Library General Public
    1.19 +    License along with this library; if not, write to the Free
    1.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    1.21 +
    1.22 +    Sam Lantinga
    1.23 +    slouken@libsdl.org
    1.24 +*/
    1.25 +
    1.26 +/* Atari OSMesa.ldg implementation of SDL OpenGL support */
    1.27 +
    1.28 +/*--- Includes ---*/
    1.29 +
    1.30 +#ifdef HAVE_OPENGL
    1.31 +#include <GL/osmesa.h>
    1.32 +#endif
    1.33 +
    1.34 +#include "SDL_video.h"
    1.35 +#include "SDL_error.h"
    1.36 +#include "SDL_endian.h"
    1.37 +#include "SDL_atarigl_c.h"
    1.38 +
    1.39 +/*--- Variables ---*/
    1.40 +
    1.41 +/*--- Functions prototypes ---*/
    1.42 +
    1.43 +static void ConvertNull(SDL_Surface *surface);
    1.44 +static void Convert565To555be(SDL_Surface *surface);
    1.45 +static void Convert565To555le(SDL_Surface *surface);
    1.46 +static void Convert565le(SDL_Surface *surface);
    1.47 +static void ConvertBGRAToABGR(SDL_Surface *surface);
    1.48 +
    1.49 +/*--- Public functions ---*/
    1.50 +
    1.51 +int SDL_AtariGL_Init(_THIS, SDL_Surface *current)
    1.52 +{
    1.53 +#ifdef HAVE_OPENGL
    1.54 +	GLenum osmesa_format;
    1.55 +	SDL_PixelFormat *pixel_format;
    1.56 +	Uint32	redmask;
    1.57 +
    1.58 +	SDL_AtariGL_Quit(this);	/* Destroy previous context if exist */
    1.59 +
    1.60 +	/* Init OpenGL context using OSMesa */
    1.61 +	gl_convert = ConvertNull;
    1.62 +
    1.63 +	pixel_format = current->format;
    1.64 +	redmask = pixel_format->Rmask;
    1.65 +	switch (pixel_format->BitsPerPixel) {
    1.66 +		case 15:
    1.67 +			/* 1555, big and little endian, unsupported */
    1.68 +			osmesa_format = OSMESA_RGB_565;
    1.69 +			if (redmask == 31<<10) {
    1.70 +				gl_convert = Convert565To555be;
    1.71 +			} else {
    1.72 +				gl_convert = Convert565To555le;
    1.73 +			}
    1.74 +			break;
    1.75 +		case 16:
    1.76 +			if (redmask == 31<<11) {
    1.77 +				osmesa_format = OSMESA_RGB_565;
    1.78 +			} else {
    1.79 +				/* 565, little endian, unsupported */
    1.80 +				osmesa_format = OSMESA_RGB_565;
    1.81 +				gl_convert = Convert565le;
    1.82 +			}
    1.83 +			break;
    1.84 +		case 24:
    1.85 +			if (redmask == 255<<16) {
    1.86 +				osmesa_format = OSMESA_RGB;
    1.87 +			} else {
    1.88 +				osmesa_format = OSMESA_BGR;
    1.89 +			}
    1.90 +			break;
    1.91 +		case 32:
    1.92 +			if (redmask == 255<<16) {
    1.93 +				osmesa_format = OSMESA_ARGB;
    1.94 +			} else if (redmask == 255<<8) {
    1.95 +				osmesa_format = OSMESA_BGRA;
    1.96 +			} else if (redmask == 255<<24) {
    1.97 +				osmesa_format = OSMESA_RGBA;
    1.98 +			} else {
    1.99 +				/* ABGR format unsupported */
   1.100 +				osmesa_format = OSMESA_BGRA;
   1.101 +				gl_convert = ConvertBGRAToABGR;
   1.102 +			}
   1.103 +			break;
   1.104 +		default:
   1.105 +			osmesa_format = OSMESA_COLOR_INDEX;
   1.106 +			break;
   1.107 +	}
   1.108 +
   1.109 +	gl_ctx = OSMesaCreateContextExt( osmesa_format, this->gl_config.depth_size,
   1.110 +		this->gl_config.stencil_size, this->gl_config.accum_red_size +
   1.111 +		this->gl_config.accum_green_size + this->gl_config.accum_blue_size +
   1.112 +		this->gl_config.accum_alpha_size, NULL );
   1.113 +
   1.114 +	gl_active = (gl_ctx != NULL);
   1.115 +	return (gl_active);
   1.116 +#else
   1.117 +	return 0;
   1.118 +#endif
   1.119 +}
   1.120 +
   1.121 +void SDL_AtariGL_Quit(_THIS)
   1.122 +{
   1.123 +#ifdef HAVE_OPENGL
   1.124 +	/* Shutdown OpenGL context */
   1.125 +	if (gl_ctx) {
   1.126 +		OSMesaDestroyContext(gl_ctx);
   1.127 +		gl_ctx = NULL;
   1.128 +	}
   1.129 +#endif
   1.130 +	gl_active = 0;
   1.131 +}
   1.132 +
   1.133 +int SDL_AtariGL_LoadLibrary(_THIS, const char *path)
   1.134 +{
   1.135 +#ifdef HAVE_OPENGL
   1.136 +	/* Library is always opened */
   1.137 +	this->gl_config.driver_loaded = 1;
   1.138 +#endif
   1.139 +	return 0;
   1.140 +}
   1.141 +
   1.142 +void *SDL_AtariGL_GetProcAddress(_THIS, const char *proc)
   1.143 +{
   1.144 +	void *func = NULL;
   1.145 +#ifdef HAVE_OPENGL
   1.146 +	if (gl_ctx != NULL) {
   1.147 +		func = OSMesaGetProcAddress(proc);
   1.148 +	}
   1.149 +#endif
   1.150 +	return func;
   1.151 +}
   1.152 +
   1.153 +int SDL_AtariGL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
   1.154 +{
   1.155 +#ifdef HAVE_OPENGL
   1.156 +	GLenum mesa_attrib;
   1.157 +	SDL_Surface *surface;
   1.158 +
   1.159 +	if (gl_ctx == NULL) {
   1.160 +		return -1;
   1.161 +	}
   1.162 +
   1.163 +	switch(attrib) {
   1.164 +		case SDL_GL_RED_SIZE:
   1.165 +			mesa_attrib = GL_RED_BITS;
   1.166 +			break;
   1.167 +		case SDL_GL_GREEN_SIZE:
   1.168 +			mesa_attrib = GL_GREEN_BITS;
   1.169 +			break;
   1.170 +		case SDL_GL_BLUE_SIZE:
   1.171 +			mesa_attrib = GL_BLUE_BITS;
   1.172 +			break;
   1.173 +		case SDL_GL_ALPHA_SIZE:
   1.174 +			mesa_attrib = GL_ALPHA_BITS;
   1.175 +			break;
   1.176 +		case SDL_GL_DOUBLEBUFFER:
   1.177 +			surface = this->screen;
   1.178 +			*value = ((surface->flags & SDL_DOUBLEBUF)==SDL_DOUBLEBUF);
   1.179 +			return 0;
   1.180 +		case SDL_GL_DEPTH_SIZE:
   1.181 +			mesa_attrib = GL_DEPTH_BITS;
   1.182 +			break;
   1.183 +		case SDL_GL_STENCIL_SIZE:
   1.184 +			mesa_attrib = GL_STENCIL_BITS;
   1.185 +			break;
   1.186 +		case SDL_GL_ACCUM_RED_SIZE:
   1.187 +			mesa_attrib = GL_ACCUM_RED_BITS;
   1.188 +			break;
   1.189 +		case SDL_GL_ACCUM_GREEN_SIZE:
   1.190 +			mesa_attrib = GL_ACCUM_GREEN_BITS;
   1.191 +			break;
   1.192 +		case SDL_GL_ACCUM_BLUE_SIZE:
   1.193 +			mesa_attrib = GL_ACCUM_BLUE_BITS;
   1.194 +			break;
   1.195 +		case SDL_GL_ACCUM_ALPHA_SIZE:
   1.196 +			mesa_attrib = GL_ACCUM_ALPHA_BITS;
   1.197 +			break;
   1.198 +		default :
   1.199 +			return -1;
   1.200 +	}
   1.201 +
   1.202 +	glGetIntegerv(mesa_attrib, value);
   1.203 +	return 0;
   1.204 +#else
   1.205 +	return -1;
   1.206 +#endif
   1.207 +}
   1.208 +
   1.209 +int SDL_AtariGL_MakeCurrent(_THIS)
   1.210 +{
   1.211 +#ifdef HAVE_OPENGL
   1.212 +	SDL_Surface *surface;
   1.213 +	GLenum type;
   1.214 +
   1.215 +	if (gl_ctx == NULL) {
   1.216 +		SDL_SetError("Invalid OpenGL context");
   1.217 +		return -1;
   1.218 +	}
   1.219 +
   1.220 +	surface = this->screen;
   1.221 +	
   1.222 +	if ((surface->format->BitsPerPixel == 15) || (surface->format->BitsPerPixel == 16)) {
   1.223 +		type = GL_UNSIGNED_SHORT_5_6_5;
   1.224 +	} else {
   1.225 +		type = GL_UNSIGNED_BYTE;
   1.226 +	}
   1.227 +
   1.228 +	if (!OSMesaMakeCurrent(gl_ctx, surface->pixels, type, surface->w, surface->h)) {
   1.229 +		SDL_SetError("Can not make OpenGL context current");
   1.230 +		return -1;
   1.231 +	}
   1.232 +
   1.233 +	/* OSMesa draws upside down */
   1.234 +	OSMesaPixelStore(OSMESA_Y_UP, 0);
   1.235 +
   1.236 +	return 0;
   1.237 +#else
   1.238 +	return -1;
   1.239 +#endif
   1.240 +}
   1.241 +
   1.242 +void SDL_AtariGL_SwapBuffers(_THIS)
   1.243 +{
   1.244 +#ifdef HAVE_OPENGL
   1.245 +	if (gl_ctx == NULL) {
   1.246 +		return;
   1.247 +	}
   1.248 +
   1.249 +	gl_convert(this->screen);
   1.250 +#endif
   1.251 +}
   1.252 +
   1.253 +/*--- Private functions ---*/
   1.254 +
   1.255 +static void ConvertNull(SDL_Surface *surface)
   1.256 +{
   1.257 +}
   1.258 +
   1.259 +static void Convert565To555be(SDL_Surface *surface)
   1.260 +{
   1.261 +	int x,y, pitch;
   1.262 +	unsigned short *line, *pixel;
   1.263 +
   1.264 +	line = surface->pixels;
   1.265 +	pitch = surface->pitch >> 1;
   1.266 +	for (y=0; y<surface->h; y++) {
   1.267 +		pixel = line;
   1.268 +		for (x=0; x<surface->w; x++) {
   1.269 +			unsigned short color = *pixel;
   1.270 +
   1.271 +			*pixel++ = (color & 0x1f)|((color>>1) & 0xffe0);
   1.272 +		}
   1.273 +
   1.274 +		line += pitch;
   1.275 +	}
   1.276 +}
   1.277 +
   1.278 +static void Convert565To555le(SDL_Surface *surface)
   1.279 +{
   1.280 +	int x,y, pitch;
   1.281 +	unsigned short *line, *pixel;
   1.282 +
   1.283 +	line = surface->pixels;
   1.284 +	pitch = surface->pitch >>1;
   1.285 +	for (y=0; y<surface->h; y++) {
   1.286 +		pixel = line;
   1.287 +		for (x=0; x<surface->w; x++) {
   1.288 +			unsigned short color = *pixel;
   1.289 +
   1.290 +			color = (color & 0x1f)|((color>>1) & 0xffe0);
   1.291 +			*pixel++ = SDL_Swap16(color);
   1.292 +		}
   1.293 +
   1.294 +		line += pitch;
   1.295 +	}
   1.296 +}
   1.297 +
   1.298 +static void Convert565le(SDL_Surface *surface)
   1.299 +{
   1.300 +	int x,y, pitch;
   1.301 +	unsigned short *line, *pixel;
   1.302 +
   1.303 +	line = surface->pixels;
   1.304 +	pitch = surface->pitch >>1;
   1.305 +	for (y=0; y<surface->h; y++) {
   1.306 +		pixel = line;
   1.307 +		for (x=0; x<surface->w; x++) {
   1.308 +			unsigned short color = *pixel;
   1.309 +
   1.310 +			*pixel++ = SDL_Swap16(color);
   1.311 +		}
   1.312 +
   1.313 +		line += pitch;
   1.314 +	}
   1.315 +}
   1.316 +
   1.317 +static void ConvertBGRAToABGR(SDL_Surface *surface)
   1.318 +{
   1.319 +	int x,y, pitch;
   1.320 +	unsigned long *line, *pixel;
   1.321 +
   1.322 +	line = surface->pixels;
   1.323 +	pitch = surface->pitch >>2;
   1.324 +	for (y=0; y<surface->h; y++) {
   1.325 +		pixel = line;
   1.326 +		for (x=0; x<surface->w; x++) {
   1.327 +			unsigned long color = *pixel;
   1.328 +
   1.329 +			*pixel++ = (color<<24)|(color>>8);
   1.330 +		}
   1.331 +
   1.332 +		line += pitch;
   1.333 +	}
   1.334 +}