• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     SDL - Simple DirectMedia Layer
3     Copyright (C) 1997-2004 Sam Lantinga
4 
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Library General Public
7     License as published by the Free Software Foundation; either
8     version 2 of the License, or (at your option) any later version.
9 
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Library General Public License for more details.
14 
15     You should have received a copy of the GNU Library General Public
16     License along with this library; if not, write to the Free
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 
19     Sam Lantinga
20     slouken@libsdl.org
21 */
22 #include "SDL_config.h"
23 
24 /* Atari OSMesa.ldg implementation of SDL OpenGL support */
25 
26 /*--- Includes ---*/
27 
28 #if SDL_VIDEO_OPENGL
29 #include <GL/osmesa.h>
30 #endif
31 
32 #include <mint/osbind.h>
33 
34 #include "SDL_endian.h"
35 #include "SDL_video.h"
36 #include "SDL_atarigl_c.h"
37 #if SDL_VIDEO_OPENGL_OSMESA_DYNAMIC
38 #include "SDL_loadso.h"
39 #endif
40 
41 /*--- Defines ---*/
42 
43 #define PATH_OSMESA_LDG	"osmesa.ldg"
44 #define PATH_MESAGL_LDG	"mesa_gl.ldg"
45 #define PATH_TINYGL_LDG	"tiny_gl.ldg"
46 
47 #define VDI_RGB	0xf
48 
49 /*--- Functions prototypes ---*/
50 
51 static void SDL_AtariGL_UnloadLibrary(_THIS);
52 
53 #if SDL_VIDEO_OPENGL
54 static void CopyShadowNull(_THIS, SDL_Surface *surface);
55 static void CopyShadowDirect(_THIS, SDL_Surface *surface);
56 static void CopyShadowRGBTo555(_THIS, SDL_Surface *surface);
57 static void CopyShadowRGBTo565(_THIS, SDL_Surface *surface);
58 static void CopyShadowRGBSwap(_THIS, SDL_Surface *surface);
59 static void CopyShadowRGBToARGB(_THIS, SDL_Surface *surface);
60 static void CopyShadowRGBToABGR(_THIS, SDL_Surface *surface);
61 static void CopyShadowRGBToBGRA(_THIS, SDL_Surface *surface);
62 static void CopyShadowRGBToRGBA(_THIS, SDL_Surface *surface);
63 static void CopyShadow8888To555(_THIS, SDL_Surface *surface);
64 static void CopyShadow8888To565(_THIS, SDL_Surface *surface);
65 
66 static void ConvertNull(_THIS, SDL_Surface *surface);
67 static void Convert565To555be(_THIS, SDL_Surface *surface);
68 static void Convert565To555le(_THIS, SDL_Surface *surface);
69 static void Convert565le(_THIS, SDL_Surface *surface);
70 static void ConvertBGRAToABGR(_THIS, SDL_Surface *surface);
71 
72 static int InitNew(_THIS, SDL_Surface *current);
73 static int InitOld(_THIS, SDL_Surface *current);
74 #endif
75 
76 /*--- Public functions ---*/
77 
SDL_AtariGL_Init(_THIS,SDL_Surface * current)78 int SDL_AtariGL_Init(_THIS, SDL_Surface *current)
79 {
80 #if SDL_VIDEO_OPENGL
81 	if (gl_oldmesa) {
82 		gl_active = InitOld(this, current);
83 	} else {
84 		gl_active = InitNew(this, current);
85 	}
86 #endif
87 
88 	return (gl_active);
89 }
90 
SDL_AtariGL_Quit(_THIS,SDL_bool unload)91 void SDL_AtariGL_Quit(_THIS, SDL_bool unload)
92 {
93 #if SDL_VIDEO_OPENGL
94 	if (gl_oldmesa) {
95 		/* Old mesa implementations */
96 		if (this->gl_data->OSMesaDestroyLDG) {
97 			this->gl_data->OSMesaDestroyLDG();
98 		}
99 		if (gl_shadow) {
100 			Mfree(gl_shadow);
101 			gl_shadow = NULL;
102 		}
103 	} else {
104 		/* New mesa implementation */
105 		if (gl_ctx) {
106 			if (this->gl_data->OSMesaDestroyContext) {
107 				this->gl_data->OSMesaDestroyContext(gl_ctx);
108 			}
109 			gl_ctx = NULL;
110 		}
111 	}
112 
113 	if (unload) {
114 		SDL_AtariGL_UnloadLibrary(this);
115 	}
116 
117 #endif /* SDL_VIDEO_OPENGL */
118 	gl_active = 0;
119 }
120 
SDL_AtariGL_LoadLibrary(_THIS,const char * path)121 int SDL_AtariGL_LoadLibrary(_THIS, const char *path)
122 {
123 #if SDL_VIDEO_OPENGL
124 
125 #if SDL_VIDEO_OPENGL_OSMESA_DYNAMIC
126 	void *handle;
127 	SDL_bool cancel_load;
128 
129 	if (gl_active) {
130 		SDL_SetError("OpenGL context already created");
131 		return -1;
132 	}
133 
134 	/* Unload previous driver */
135 	SDL_AtariGL_UnloadLibrary(this);
136 
137 	/* Load library given by path */
138 	handle = SDL_LoadObject(path);
139 	if (handle == NULL) {
140 		/* Try to load another one */
141 		path = SDL_getenv("SDL_VIDEO_GL_DRIVER");
142 		if ( path != NULL ) {
143 			handle = SDL_LoadObject(path);
144 		}
145 
146 		/* If it does not work, try some other */
147 		if (handle == NULL) {
148 			path = PATH_OSMESA_LDG;
149 			handle = SDL_LoadObject(path);
150 		}
151 
152 		if (handle == NULL) {
153 			path = PATH_MESAGL_LDG;
154 			handle = SDL_LoadObject(path);
155 		}
156 
157 		if (handle == NULL) {
158 			path = PATH_TINYGL_LDG;
159 			handle = SDL_LoadObject(path);
160 		}
161 	}
162 
163 	if (handle == NULL) {
164 		SDL_SetError("Could not load OpenGL library");
165 		return -1;
166 	}
167 
168 	this->gl_data->glGetIntegerv = SDL_LoadFunction(handle, "glGetIntegerv");
169 	this->gl_data->glFinish = SDL_LoadFunction(handle, "glFinish");
170 	this->gl_data->glFlush = SDL_LoadFunction(handle, "glFlush");
171 
172 	cancel_load = SDL_FALSE;
173 	if (this->gl_data->glGetIntegerv == NULL) {
174 		cancel_load = SDL_TRUE;
175 	} else {
176 		/* We need either glFinish (OSMesa) or glFlush (TinyGL) */
177 		if ((this->gl_data->glFinish == NULL) &&
178 			(this->gl_data->glFlush == NULL)) {
179 				cancel_load = SDL_TRUE;
180 		}
181 	}
182 	if (cancel_load) {
183 		SDL_SetError("Could not retrieve OpenGL functions");
184 		SDL_UnloadObject(handle);
185 		/* Restore pointers to static library */
186 		SDL_AtariGL_InitPointers(this);
187 		return -1;
188 	}
189 
190 	/* Load functions pointers (osmesa.ldg) */
191 	this->gl_data->OSMesaCreateContextExt = SDL_LoadFunction(handle, "OSMesaCreateContextExt");
192 	this->gl_data->OSMesaDestroyContext = SDL_LoadFunction(handle, "OSMesaDestroyContext");
193 	this->gl_data->OSMesaMakeCurrent = SDL_LoadFunction(handle, "OSMesaMakeCurrent");
194 	this->gl_data->OSMesaPixelStore = SDL_LoadFunction(handle, "OSMesaPixelStore");
195 	this->gl_data->OSMesaGetProcAddress = SDL_LoadFunction(handle, "OSMesaGetProcAddress");
196 
197 	/* Load old functions pointers (mesa_gl.ldg, tiny_gl.ldg) */
198 	this->gl_data->OSMesaCreateLDG = SDL_LoadFunction(handle, "OSMesaCreateLDG");
199 	this->gl_data->OSMesaDestroyLDG = SDL_LoadFunction(handle, "OSMesaDestroyLDG");
200 
201 	gl_oldmesa = 0;
202 
203 	if ( (this->gl_data->OSMesaCreateContextExt == NULL) ||
204 	     (this->gl_data->OSMesaDestroyContext == NULL) ||
205 	     (this->gl_data->OSMesaMakeCurrent == NULL) ||
206 	     (this->gl_data->OSMesaPixelStore == NULL) ||
207 	     (this->gl_data->OSMesaGetProcAddress == NULL)) {
208 		/* Hum, maybe old library ? */
209 		if ( (this->gl_data->OSMesaCreateLDG == NULL) ||
210 		     (this->gl_data->OSMesaDestroyLDG == NULL)) {
211 			SDL_SetError("Could not retrieve OSMesa functions");
212 			SDL_UnloadObject(handle);
213 			/* Restore pointers to static library */
214 			SDL_AtariGL_InitPointers(this);
215 			return -1;
216 		} else {
217 			gl_oldmesa = 1;
218 		}
219 	}
220 
221 	this->gl_config.dll_handle = handle;
222 	if ( path ) {
223 		SDL_strlcpy(this->gl_config.driver_path, path,
224 			SDL_arraysize(this->gl_config.driver_path));
225 	} else {
226 		*this->gl_config.driver_path = '\0';
227 	}
228 
229 #endif
230 	this->gl_config.driver_loaded = 1;
231 
232 	return 0;
233 #else
234 	return -1;
235 #endif
236 }
237 
SDL_AtariGL_GetProcAddress(_THIS,const char * proc)238 void *SDL_AtariGL_GetProcAddress(_THIS, const char *proc)
239 {
240 	void *func = NULL;
241 #if SDL_VIDEO_OPENGL
242 
243 	if (this->gl_config.dll_handle) {
244 		func = SDL_LoadFunction(this->gl_config.dll_handle, (void *)proc);
245 	} else if (this->gl_data->OSMesaGetProcAddress) {
246 		func = this->gl_data->OSMesaGetProcAddress(proc);
247 	}
248 
249 #endif
250 	return func;
251 }
252 
SDL_AtariGL_GetAttribute(_THIS,SDL_GLattr attrib,int * value)253 int SDL_AtariGL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
254 {
255 #if SDL_VIDEO_OPENGL
256 	GLenum mesa_attrib;
257 	SDL_Surface *surface;
258 
259 	if (!gl_active) {
260 		return -1;
261 	}
262 
263 	switch(attrib) {
264 		case SDL_GL_RED_SIZE:
265 			mesa_attrib = GL_RED_BITS;
266 			break;
267 		case SDL_GL_GREEN_SIZE:
268 			mesa_attrib = GL_GREEN_BITS;
269 			break;
270 		case SDL_GL_BLUE_SIZE:
271 			mesa_attrib = GL_BLUE_BITS;
272 			break;
273 		case SDL_GL_ALPHA_SIZE:
274 			mesa_attrib = GL_ALPHA_BITS;
275 			break;
276 		case SDL_GL_DOUBLEBUFFER:
277 			surface = this->screen;
278 			*value = ((surface->flags & SDL_DOUBLEBUF)==SDL_DOUBLEBUF);
279 			return 0;
280 		case SDL_GL_DEPTH_SIZE:
281 			mesa_attrib = GL_DEPTH_BITS;
282 			break;
283 		case SDL_GL_STENCIL_SIZE:
284 			mesa_attrib = GL_STENCIL_BITS;
285 			break;
286 		case SDL_GL_ACCUM_RED_SIZE:
287 			mesa_attrib = GL_ACCUM_RED_BITS;
288 			break;
289 		case SDL_GL_ACCUM_GREEN_SIZE:
290 			mesa_attrib = GL_ACCUM_GREEN_BITS;
291 			break;
292 		case SDL_GL_ACCUM_BLUE_SIZE:
293 			mesa_attrib = GL_ACCUM_BLUE_BITS;
294 			break;
295 		case SDL_GL_ACCUM_ALPHA_SIZE:
296 			mesa_attrib = GL_ACCUM_ALPHA_BITS;
297 			break;
298 		default :
299 			return -1;
300 	}
301 
302 	this->gl_data->glGetIntegerv(mesa_attrib, value);
303 	return 0;
304 #else
305 	return -1;
306 #endif
307 }
308 
SDL_AtariGL_MakeCurrent(_THIS)309 int SDL_AtariGL_MakeCurrent(_THIS)
310 {
311 #if SDL_VIDEO_OPENGL
312 	SDL_Surface *surface;
313 	GLenum type;
314 
315 	if (gl_oldmesa && gl_active) {
316 		return 0;
317 	}
318 
319 	if (this->gl_config.dll_handle) {
320 		if ((this->gl_data->OSMesaMakeCurrent == NULL) ||
321 			(this->gl_data->OSMesaPixelStore == NULL)) {
322 			return -1;
323 		}
324 	}
325 
326 	if (!gl_active) {
327 		SDL_SetError("Invalid OpenGL context");
328 		return -1;
329 	}
330 
331 	surface = this->screen;
332 
333 	if ((surface->format->BitsPerPixel == 15) || (surface->format->BitsPerPixel == 16)) {
334 		type = GL_UNSIGNED_SHORT_5_6_5;
335 	} else {
336 		type = GL_UNSIGNED_BYTE;
337 	}
338 
339 	if (!(this->gl_data->OSMesaMakeCurrent(gl_ctx, surface->pixels, type, surface->w, surface->h))) {
340 		SDL_SetError("Can not make OpenGL context current");
341 		return -1;
342 	}
343 
344 	/* OSMesa draws upside down */
345 	this->gl_data->OSMesaPixelStore(OSMESA_Y_UP, 0);
346 
347 	return 0;
348 #else
349 	return -1;
350 #endif
351 }
352 
SDL_AtariGL_SwapBuffers(_THIS)353 void SDL_AtariGL_SwapBuffers(_THIS)
354 {
355 #if SDL_VIDEO_OPENGL
356 	if (gl_active) {
357 		if (this->gl_config.dll_handle) {
358 			if (this->gl_data->glFinish) {
359 				this->gl_data->glFinish();
360 			} else if (this->gl_data->glFlush) {
361 				this->gl_data->glFlush();
362 			}
363 		} else {
364 			this->gl_data->glFinish();
365 		}
366 		gl_copyshadow(this, this->screen);
367 		gl_convert(this, this->screen);
368 	}
369 #endif
370 }
371 
SDL_AtariGL_InitPointers(_THIS)372 void SDL_AtariGL_InitPointers(_THIS)
373 {
374 #if SDL_VIDEO_OPENGL
375 	this->gl_data->OSMesaCreateContextExt = OSMesaCreateContextExt;
376 	this->gl_data->OSMesaDestroyContext = OSMesaDestroyContext;
377 	this->gl_data->OSMesaMakeCurrent = OSMesaMakeCurrent;
378 	this->gl_data->OSMesaPixelStore = OSMesaPixelStore;
379 	this->gl_data->OSMesaGetProcAddress = OSMesaGetProcAddress;
380 
381 	this->gl_data->glGetIntegerv = glGetIntegerv;
382 	this->gl_data->glFinish = glFinish;
383 	this->gl_data->glFlush = glFlush;
384 
385 	this->gl_data->OSMesaCreateLDG = NULL;
386 	this->gl_data->OSMesaDestroyLDG = NULL;
387 #endif
388 }
389 
390 /*--- Private functions ---*/
391 
SDL_AtariGL_UnloadLibrary(_THIS)392 static void SDL_AtariGL_UnloadLibrary(_THIS)
393 {
394 #if SDL_VIDEO_OPENGL
395 	if (this->gl_config.dll_handle) {
396 		SDL_UnloadObject(this->gl_config.dll_handle);
397 		this->gl_config.dll_handle = NULL;
398 
399 		/* Restore pointers to static library */
400 		SDL_AtariGL_InitPointers(this);
401 	}
402 #endif
403 }
404 
405 /*--- Creation of an OpenGL context using new/old functions ---*/
406 
407 #if SDL_VIDEO_OPENGL
InitNew(_THIS,SDL_Surface * current)408 static int InitNew(_THIS, SDL_Surface *current)
409 {
410 	GLenum osmesa_format;
411 	SDL_PixelFormat *pixel_format;
412 	Uint32	redmask;
413 	int recreatecontext;
414 	GLint newaccumsize;
415 
416 	if (this->gl_config.dll_handle) {
417 		if (this->gl_data->OSMesaCreateContextExt == NULL) {
418 			return 0;
419 		}
420 	}
421 
422 	/* Init OpenGL context using OSMesa */
423 	gl_convert = ConvertNull;
424 	gl_copyshadow = CopyShadowNull;
425 	gl_upsidedown = SDL_FALSE;
426 
427 	pixel_format = current->format;
428 	redmask = pixel_format->Rmask;
429 	switch (pixel_format->BitsPerPixel) {
430 		case 15:
431 			/* 1555, big and little endian, unsupported */
432 			gl_pixelsize = 2;
433 			osmesa_format = OSMESA_RGB_565;
434 			if (redmask == 31<<10) {
435 				gl_convert = Convert565To555be;
436 			} else {
437 				gl_convert = Convert565To555le;
438 			}
439 			break;
440 		case 16:
441 			gl_pixelsize = 2;
442 			if (redmask == 31<<11) {
443 				osmesa_format = OSMESA_RGB_565;
444 			} else {
445 				/* 565, little endian, unsupported */
446 				osmesa_format = OSMESA_RGB_565;
447 				gl_convert = Convert565le;
448 			}
449 			break;
450 		case 24:
451 			gl_pixelsize = 3;
452 			if (redmask == 255<<16) {
453 				osmesa_format = OSMESA_RGB;
454 			} else {
455 				osmesa_format = OSMESA_BGR;
456 			}
457 			break;
458 		case 32:
459 			gl_pixelsize = 4;
460 			if (redmask == 255<<16) {
461 				osmesa_format = OSMESA_ARGB;
462 			} else if (redmask == 255<<8) {
463 				osmesa_format = OSMESA_BGRA;
464 			} else if (redmask == 255<<24) {
465 				osmesa_format = OSMESA_RGBA;
466 			} else {
467 				/* ABGR format unsupported */
468 				osmesa_format = OSMESA_BGRA;
469 				gl_convert = ConvertBGRAToABGR;
470 			}
471 			break;
472 		default:
473 			gl_pixelsize = 1;
474 			osmesa_format = OSMESA_COLOR_INDEX;
475 			break;
476 	}
477 
478 	/* Try to keep current context if possible */
479 	newaccumsize =
480 		this->gl_config.accum_red_size +
481 		this->gl_config.accum_green_size +
482 		this->gl_config.accum_blue_size +
483 		this->gl_config.accum_alpha_size;
484 	recreatecontext=1;
485 	if (gl_ctx &&
486 		(gl_curformat == osmesa_format) &&
487 		(gl_curdepth == this->gl_config.depth_size) &&
488 		(gl_curstencil == this->gl_config.stencil_size) &&
489 		(gl_curaccum == newaccumsize)) {
490 		recreatecontext = 0;
491 	}
492 	if (recreatecontext) {
493 		SDL_AtariGL_Quit(this, SDL_FALSE);
494 
495 		gl_ctx = this->gl_data->OSMesaCreateContextExt(
496 			osmesa_format, this->gl_config.depth_size,
497 			this->gl_config.stencil_size, newaccumsize, NULL );
498 
499 		if (gl_ctx) {
500 			gl_curformat = osmesa_format;
501 			gl_curdepth = this->gl_config.depth_size;
502 			gl_curstencil = this->gl_config.stencil_size;
503 			gl_curaccum = newaccumsize;
504 		} else {
505 			gl_curformat = 0;
506 			gl_curdepth = 0;
507 			gl_curstencil = 0;
508 			gl_curaccum = 0;
509 		}
510 	}
511 
512 	return (gl_ctx != NULL);
513 }
514 
515 
InitOld(_THIS,SDL_Surface * current)516 static int InitOld(_THIS, SDL_Surface *current)
517 {
518 	GLenum osmesa_format;
519 	SDL_PixelFormat *pixel_format;
520 	Uint32	redmask;
521 	int recreatecontext, tinygl_present;
522 
523 	if (this->gl_config.dll_handle) {
524 		if (this->gl_data->OSMesaCreateLDG == NULL) {
525 			return 0;
526 		}
527 	}
528 
529 	/* TinyGL only supports VDI_RGB (OSMESA_RGB) */
530 	tinygl_present=0;
531 	if (this->gl_config.dll_handle) {
532 		if (this->gl_data->glFinish == NULL) {
533 			tinygl_present=1;
534 		}
535 	}
536 
537 	/* Init OpenGL context using OSMesa */
538 	gl_convert = ConvertNull;
539 	gl_copyshadow = CopyShadowNull;
540 	gl_upsidedown = SDL_FALSE;
541 
542 	pixel_format = current->format;
543 	redmask = pixel_format->Rmask;
544 	switch (pixel_format->BitsPerPixel) {
545 		case 15:
546 			/* 15 bits unsupported */
547 			if (tinygl_present) {
548 				gl_pixelsize = 3;
549 				osmesa_format = VDI_RGB;
550 				if (redmask == 31<<10) {
551 					gl_copyshadow = CopyShadowRGBTo555;
552 				} else {
553 					gl_copyshadow = CopyShadowRGBTo565;
554 					gl_convert = Convert565To555le;
555 				}
556 			} else {
557 				gl_pixelsize = 4;
558 				gl_upsidedown = SDL_TRUE;
559 				osmesa_format = OSMESA_ARGB;
560 				if (redmask == 31<<10) {
561 					gl_copyshadow = CopyShadow8888To555;
562 				} else {
563 					gl_copyshadow = CopyShadow8888To565;
564 					gl_convert = Convert565To555le;
565 				}
566 			}
567 			break;
568 		case 16:
569 			/* 16 bits unsupported */
570 			if (tinygl_present) {
571 				gl_pixelsize = 3;
572 				osmesa_format = VDI_RGB;
573 				gl_copyshadow = CopyShadowRGBTo565;
574 				if (redmask != 31<<11) {
575 					/* 565, little endian, unsupported */
576 					gl_convert = Convert565le;
577 				}
578 			} else {
579 				gl_pixelsize = 4;
580 				gl_upsidedown = SDL_TRUE;
581 				osmesa_format = OSMESA_ARGB;
582 				gl_copyshadow = CopyShadow8888To565;
583 				if (redmask != 31<<11) {
584 					/* 565, little endian, unsupported */
585 					gl_convert = Convert565le;
586 				}
587 			}
588 			break;
589 		case 24:
590 			gl_pixelsize = 3;
591 			if (tinygl_present) {
592 				osmesa_format = VDI_RGB;
593 				gl_copyshadow = CopyShadowDirect;
594 				if (redmask != 255<<16) {
595 					gl_copyshadow = CopyShadowRGBSwap;
596 				}
597 			} else {
598 				gl_copyshadow = CopyShadowDirect;
599 				gl_upsidedown = SDL_TRUE;
600 				if (redmask == 255<<16) {
601 					osmesa_format = OSMESA_RGB;
602 				} else {
603 					osmesa_format = OSMESA_BGR;
604 				}
605 			}
606 			break;
607 		case 32:
608 			if (tinygl_present) {
609 				gl_pixelsize = 3;
610 				osmesa_format = VDI_RGB;
611 				gl_copyshadow = CopyShadowRGBToARGB;
612 				if (redmask == 255) {
613 					gl_convert = CopyShadowRGBToABGR;
614 				} else if (redmask == 255<<8) {
615 					gl_convert = CopyShadowRGBToBGRA;
616 				} else if (redmask == 255<<24) {
617 					gl_convert = CopyShadowRGBToRGBA;
618 				}
619 			} else {
620 				gl_pixelsize = 4;
621 				gl_upsidedown = SDL_TRUE;
622 				gl_copyshadow = CopyShadowDirect;
623 				if (redmask == 255<<16) {
624 					osmesa_format = OSMESA_ARGB;
625 				} else if (redmask == 255<<8) {
626 					osmesa_format = OSMESA_BGRA;
627 				} else if (redmask == 255<<24) {
628 					osmesa_format = OSMESA_RGBA;
629 				} else {
630 					/* ABGR format unsupported */
631 					osmesa_format = OSMESA_BGRA;
632 					gl_convert = ConvertBGRAToABGR;
633 				}
634 			}
635 			break;
636 		default:
637 			if (tinygl_present) {
638 				SDL_AtariGL_Quit(this, SDL_FALSE);
639 				return 0;
640 			}
641 			gl_pixelsize = 1;
642 			gl_copyshadow = CopyShadowDirect;
643 			osmesa_format = OSMESA_COLOR_INDEX;
644 			break;
645 	}
646 
647 	/* Try to keep current context if possible */
648 	recreatecontext=1;
649 	if (gl_shadow &&
650 		(gl_curformat == osmesa_format) &&
651 		(gl_curwidth == current->w) &&
652 		(gl_curheight == current->h)) {
653 		recreatecontext = 0;
654 	}
655 	if (recreatecontext) {
656 		SDL_AtariGL_Quit(this, SDL_FALSE);
657 
658 		gl_shadow = this->gl_data->OSMesaCreateLDG(
659 			osmesa_format, GL_UNSIGNED_BYTE, current->w, current->h
660 		);
661 
662 		if (gl_shadow) {
663 			gl_curformat = osmesa_format;
664 			gl_curwidth = current->w;
665 			gl_curheight = current->h;
666 		} else {
667 			gl_curformat = 0;
668 			gl_curwidth = 0;
669 			gl_curheight = 0;
670 		}
671 	}
672 
673 	return (gl_shadow != NULL);
674 }
675 
676 /*--- Conversions routines from shadow buffer to the screen ---*/
677 
CopyShadowNull(_THIS,SDL_Surface * surface)678 static void CopyShadowNull(_THIS, SDL_Surface *surface)
679 {
680 }
681 
CopyShadowDirect(_THIS,SDL_Surface * surface)682 static void CopyShadowDirect(_THIS, SDL_Surface *surface)
683 {
684 	int y, srcpitch, dstpitch;
685 	Uint8 *srcline, *dstline;
686 
687 	srcline = gl_shadow;
688 	srcpitch = surface->w * gl_pixelsize;
689 	dstline = surface->pixels;
690 	dstpitch = surface->pitch;
691 	if (gl_upsidedown) {
692 		srcline += (surface->h-1)*srcpitch;
693 		srcpitch = -srcpitch;
694 	}
695 
696 	for (y=0; y<surface->h; y++) {
697 		SDL_memcpy(dstline, srcline, srcpitch);
698 
699 		srcline += srcpitch;
700 		dstline += dstpitch;
701 	}
702 }
703 
CopyShadowRGBTo555(_THIS,SDL_Surface * surface)704 static void CopyShadowRGBTo555(_THIS, SDL_Surface *surface)
705 {
706 	int x,y, srcpitch, dstpitch;
707 	Uint16 *dstline, *dstcol;
708 	Uint8 *srcline, *srccol;
709 
710 	srcline = (Uint8 *)gl_shadow;
711 	srcpitch = surface->w * gl_pixelsize;
712 	dstline = surface->pixels;
713 	dstpitch = surface->pitch >>1;
714 	if (gl_upsidedown) {
715 		srcline += (surface->h-1)*srcpitch;
716 		srcpitch = -srcpitch;
717 	}
718 
719 	for (y=0; y<surface->h; y++) {
720 		srccol = srcline;
721 		dstcol = dstline;
722 		for (x=0; x<surface->w; x++) {
723 			Uint16 dstcolor;
724 
725 			dstcolor = ((*srccol++)<<7) & (31<<10);
726 			dstcolor |= ((*srccol++)<<2) & (31<<5);
727 			dstcolor |= ((*srccol++)>>3) & 31;
728 			*dstcol++ = dstcolor;
729 		}
730 
731 		srcline += srcpitch;
732 		dstline += dstpitch;
733 	}
734 }
735 
CopyShadowRGBTo565(_THIS,SDL_Surface * surface)736 static void CopyShadowRGBTo565(_THIS, SDL_Surface *surface)
737 {
738 	int x,y, srcpitch, dstpitch;
739 	Uint16 *dstline, *dstcol;
740 	Uint8 *srcline, *srccol;
741 
742 	srcline = (Uint8 *)gl_shadow;
743 	srcpitch = surface->w * gl_pixelsize;
744 	dstline = surface->pixels;
745 	dstpitch = surface->pitch >>1;
746 	if (gl_upsidedown) {
747 		srcline += (surface->h-1)*srcpitch;
748 		srcpitch = -srcpitch;
749 	}
750 
751 	for (y=0; y<surface->h; y++) {
752 		srccol = srcline;
753 		dstcol = dstline;
754 
755 		for (x=0; x<surface->w; x++) {
756 			Uint16 dstcolor;
757 
758 			dstcolor = ((*srccol++)<<8) & (31<<11);
759 			dstcolor |= ((*srccol++)<<3) & (63<<5);
760 			dstcolor |= ((*srccol++)>>3) & 31;
761 			*dstcol++ = dstcolor;
762 		}
763 
764 		srcline += srcpitch;
765 		dstline += dstpitch;
766 	}
767 }
768 
CopyShadowRGBSwap(_THIS,SDL_Surface * surface)769 static void CopyShadowRGBSwap(_THIS, SDL_Surface *surface)
770 {
771 	int x,y, srcpitch, dstpitch;
772 	Uint8 *dstline, *dstcol;
773 	Uint8 *srcline, *srccol;
774 
775 	srcline = (Uint8 *)gl_shadow;
776 	srcpitch = surface->w * gl_pixelsize;
777 	dstline = surface->pixels;
778 	dstpitch = surface->pitch;
779 	if (gl_upsidedown) {
780 		srcline += (surface->h-1)*srcpitch;
781 		srcpitch = -srcpitch;
782 	}
783 
784 	for (y=0; y<surface->h; y++) {
785 		srccol = srcline;
786 		dstcol = dstline;
787 
788 		for (x=0; x<surface->w; x++) {
789 			*dstcol++ = srccol[2];
790 			*dstcol++ = srccol[1];
791 			*dstcol++ = srccol[0];
792 			srccol += 3;
793 		}
794 
795 		srcline += srcpitch;
796 		dstline += dstpitch;
797 	}
798 }
799 
CopyShadowRGBToARGB(_THIS,SDL_Surface * surface)800 static void CopyShadowRGBToARGB(_THIS, SDL_Surface *surface)
801 {
802 	int x,y, srcpitch, dstpitch;
803 	Uint32 *dstline, *dstcol;
804 	Uint8 *srcline, *srccol;
805 
806 	srcline = (Uint8 *)gl_shadow;
807 	srcpitch = surface->w * gl_pixelsize;
808 	dstline = surface->pixels;
809 	dstpitch = surface->pitch >>2;
810 	if (gl_upsidedown) {
811 		srcline += (surface->h-1)*srcpitch;
812 		srcpitch = -srcpitch;
813 	}
814 
815 	for (y=0; y<surface->h; y++) {
816 		srccol = srcline;
817 		dstcol = dstline;
818 
819 		for (x=0; x<surface->w; x++) {
820 			Uint32	dstcolor;
821 
822 			dstcolor = (*srccol++)<<16;
823 			dstcolor |= (*srccol++)<<8;
824 			dstcolor |= *srccol++;
825 
826 			*dstcol++ = dstcolor;
827 		}
828 
829 		srcline += srcpitch;
830 		dstline += dstpitch;
831 	}
832 }
833 
CopyShadowRGBToABGR(_THIS,SDL_Surface * surface)834 static void CopyShadowRGBToABGR(_THIS, SDL_Surface *surface)
835 {
836 	int x,y, srcpitch, dstpitch;
837 	Uint32 *dstline, *dstcol;
838 	Uint8 *srcline, *srccol;
839 
840 	srcline = (Uint8 *)gl_shadow;
841 	srcpitch = surface->w * gl_pixelsize;
842 	dstline = surface->pixels;
843 	dstpitch = surface->pitch >>2;
844 	if (gl_upsidedown) {
845 		srcline += (surface->h-1)*srcpitch;
846 		srcpitch = -srcpitch;
847 	}
848 
849 	for (y=0; y<surface->h; y++) {
850 		srccol = srcline;
851 		dstcol = dstline;
852 
853 		for (x=0; x<surface->w; x++) {
854 			Uint32	dstcolor;
855 
856 			dstcolor = *srccol++;
857 			dstcolor |= (*srccol++)<<8;
858 			dstcolor |= (*srccol++)<<16;
859 
860 			*dstcol++ = dstcolor;
861 		}
862 
863 		srcline += srcpitch;
864 		dstline += dstpitch;
865 	}
866 }
867 
CopyShadowRGBToBGRA(_THIS,SDL_Surface * surface)868 static void CopyShadowRGBToBGRA(_THIS, SDL_Surface *surface)
869 {
870 	int x,y, srcpitch, dstpitch;
871 	Uint32 *dstline, *dstcol;
872 	Uint8 *srcline, *srccol;
873 
874 	srcline = (Uint8 *)gl_shadow;
875 	srcpitch = surface->w * gl_pixelsize;
876 	dstline = surface->pixels;
877 	dstpitch = surface->pitch >>2;
878 	if (gl_upsidedown) {
879 		srcline += (surface->h-1)*srcpitch;
880 		srcpitch = -srcpitch;
881 	}
882 
883 	for (y=0; y<surface->h; y++) {
884 		srccol = srcline;
885 		dstcol = dstline;
886 
887 		for (x=0; x<surface->w; x++) {
888 			Uint32	dstcolor;
889 
890 			dstcolor = (*srccol++)<<8;
891 			dstcolor |= (*srccol++)<<16;
892 			dstcolor |= (*srccol++)<<24;
893 
894 			*dstcol++ = dstcolor;
895 		}
896 
897 		srcline += srcpitch;
898 		dstline += dstpitch;
899 	}
900 }
901 
CopyShadowRGBToRGBA(_THIS,SDL_Surface * surface)902 static void CopyShadowRGBToRGBA(_THIS, SDL_Surface *surface)
903 {
904 	int x,y, srcpitch, dstpitch;
905 	Uint32 *dstline, *dstcol;
906 	Uint8 *srcline, *srccol;
907 
908 	srcline = (Uint8 *)gl_shadow;
909 	srcpitch = surface->w * gl_pixelsize;
910 	dstline = surface->pixels;
911 	dstpitch = surface->pitch >>2;
912 	if (gl_upsidedown) {
913 		srcline += (surface->h-1)*srcpitch;
914 		srcpitch = -srcpitch;
915 	}
916 
917 	for (y=0; y<surface->h; y++) {
918 		srccol = srcline;
919 		dstcol = dstline;
920 
921 		for (x=0; x<surface->w; x++) {
922 			Uint32	dstcolor;
923 
924 			dstcolor = (*srccol++)<<24;
925 			dstcolor |= (*srccol++)<<16;
926 			dstcolor |= (*srccol++)<<8;
927 
928 			*dstcol++ = dstcolor;
929 		}
930 
931 		srcline += srcpitch;
932 		dstline += dstpitch;
933 	}
934 }
935 
CopyShadow8888To555(_THIS,SDL_Surface * surface)936 static void CopyShadow8888To555(_THIS, SDL_Surface *surface)
937 {
938 	int x,y, srcpitch, dstpitch;
939 	Uint16 *dstline, *dstcol;
940 	Uint32 *srcline, *srccol;
941 
942 	srcline = (Uint32 *)gl_shadow;
943 	srcpitch = (surface->w * gl_pixelsize) >>2;
944 	dstline = surface->pixels;
945 	dstpitch = surface->pitch >>1;
946 	if (gl_upsidedown) {
947 		srcline += (surface->h-1)*srcpitch;
948 		srcpitch = -srcpitch;
949 	}
950 
951 	for (y=0; y<surface->h; y++) {
952 		srccol = srcline;
953 		dstcol = dstline;
954 		for (x=0; x<surface->w; x++) {
955 			Uint32 srccolor;
956 			Uint16 dstcolor;
957 
958 			srccolor = *srccol++;
959 			dstcolor = (srccolor>>9) & (31<<10);
960 			dstcolor |= (srccolor>>6) & (31<<5);
961 			dstcolor |= (srccolor>>3) & 31;
962 			*dstcol++ = dstcolor;
963 		}
964 
965 		srcline += srcpitch;
966 		dstline += dstpitch;
967 	}
968 }
969 
CopyShadow8888To565(_THIS,SDL_Surface * surface)970 static void CopyShadow8888To565(_THIS, SDL_Surface *surface)
971 {
972 	int x,y, srcpitch, dstpitch;
973 	Uint16 *dstline, *dstcol;
974 	Uint32 *srcline, *srccol;
975 
976 	srcline = (Uint32 *)gl_shadow;
977 	srcpitch = (surface->w * gl_pixelsize) >> 2;
978 	dstline = surface->pixels;
979 	dstpitch = surface->pitch >>1;
980 	if (gl_upsidedown) {
981 		srcline += (surface->h-1)*srcpitch;
982 		srcpitch = -srcpitch;
983 	}
984 
985 	for (y=0; y<surface->h; y++) {
986 		srccol = srcline;
987 		dstcol = dstline;
988 
989 		for (x=0; x<surface->w; x++) {
990 			Uint32 srccolor;
991 			Uint16 dstcolor;
992 
993 			srccolor = *srccol++;
994 			dstcolor = (srccolor>>8) & (31<<11);
995 			dstcolor |= (srccolor>>5) & (63<<5);
996 			dstcolor |= (srccolor>>3) & 31;
997 			*dstcol++ = dstcolor;
998 		}
999 
1000 		srcline += srcpitch;
1001 		dstline += dstpitch;
1002 	}
1003 }
1004 
1005 /*--- Conversions routines in the screen ---*/
1006 
ConvertNull(_THIS,SDL_Surface * surface)1007 static void ConvertNull(_THIS, SDL_Surface *surface)
1008 {
1009 }
1010 
Convert565To555be(_THIS,SDL_Surface * surface)1011 static void Convert565To555be(_THIS, SDL_Surface *surface)
1012 {
1013 	int x,y, pitch;
1014 	unsigned short *line, *pixel;
1015 
1016 	line = surface->pixels;
1017 	pitch = surface->pitch >> 1;
1018 	for (y=0; y<surface->h; y++) {
1019 		pixel = line;
1020 		for (x=0; x<surface->w; x++) {
1021 			unsigned short color = *pixel;
1022 
1023 			*pixel++ = (color & 0x1f)|((color>>1) & 0xffe0);
1024 		}
1025 
1026 		line += pitch;
1027 	}
1028 }
1029 
Convert565To555le(_THIS,SDL_Surface * surface)1030 static void Convert565To555le(_THIS, SDL_Surface *surface)
1031 {
1032 	int x,y, pitch;
1033 	unsigned short *line, *pixel;
1034 
1035 	line = surface->pixels;
1036 	pitch = surface->pitch >>1;
1037 	for (y=0; y<surface->h; y++) {
1038 		pixel = line;
1039 		for (x=0; x<surface->w; x++) {
1040 			unsigned short color = *pixel;
1041 
1042 			color = (color & 0x1f)|((color>>1) & 0xffe0);
1043 			*pixel++ = SDL_Swap16(color);
1044 		}
1045 
1046 		line += pitch;
1047 	}
1048 }
1049 
Convert565le(_THIS,SDL_Surface * surface)1050 static void Convert565le(_THIS, SDL_Surface *surface)
1051 {
1052 	int x,y, pitch;
1053 	unsigned short *line, *pixel;
1054 
1055 	line = surface->pixels;
1056 	pitch = surface->pitch >>1;
1057 	for (y=0; y<surface->h; y++) {
1058 		pixel = line;
1059 		for (x=0; x<surface->w; x++) {
1060 			unsigned short color = *pixel;
1061 
1062 			*pixel++ = SDL_Swap16(color);
1063 		}
1064 
1065 		line += pitch;
1066 	}
1067 }
1068 
ConvertBGRAToABGR(_THIS,SDL_Surface * surface)1069 static void ConvertBGRAToABGR(_THIS, SDL_Surface *surface)
1070 {
1071 	int x,y, pitch;
1072 	unsigned long *line, *pixel;
1073 
1074 	line = surface->pixels;
1075 	pitch = surface->pitch >>2;
1076 	for (y=0; y<surface->h; y++) {
1077 		pixel = line;
1078 		for (x=0; x<surface->w; x++) {
1079 			unsigned long color = *pixel;
1080 
1081 			*pixel++ = (color<<24)|(color>>8);
1082 		}
1083 
1084 		line += pitch;
1085 	}
1086 }
1087 
1088 #endif /* SDL_VIDEO_OPENGL */
1089