• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     SDL - Simple DirectMedia Layer
3     Copyright (C) 1997-2006 Sam Lantinga
4 
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 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     Lesser General Public License for more details.
14 
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 
19     Sam Lantinga
20     slouken@libsdl.org
21 */
22 #include "SDL_config.h"
23 
24 /*
25  * Xbios SDL video driver
26  *
27  * Patrice Mandin
28  */
29 
30 #include <sys/stat.h>
31 #include <unistd.h>
32 
33 /* Mint includes */
34 #include <mint/cookie.h>
35 #include <mint/osbind.h>
36 #include <mint/falcon.h>
37 
38 #include "SDL_video.h"
39 #include "SDL_mouse.h"
40 #include "../SDL_sysvideo.h"
41 #include "../SDL_pixels_c.h"
42 #include "../../events/SDL_events_c.h"
43 
44 #include "../ataricommon/SDL_ataric2p_s.h"
45 #include "../ataricommon/SDL_atarievents_c.h"
46 #include "../ataricommon/SDL_atarimxalloc_c.h"
47 #include "../ataricommon/SDL_atarigl_c.h"
48 #include "SDL_xbios.h"
49 #include "SDL_xbios_blowup.h"
50 #include "SDL_xbios_centscreen.h"
51 #include "SDL_xbios_sb3.h"
52 #include "SDL_xbios_tveille.h"
53 
54 #define XBIOS_VID_DRIVER_NAME "xbios"
55 
56 /* Debug print info */
57 #if 0
58 #define DEBUG_PRINT(what) \
59 	{ \
60 		printf what; \
61 	}
62 #define DEBUG_VIDEO_XBIOS 1
63 #else
64 #define DEBUG_PRINT(what)
65 #undef DEBUG_VIDEO_XBIOS
66 #endif
67 
68 /* Initialization/Query functions */
69 static int XBIOS_VideoInit(_THIS, SDL_PixelFormat *vformat);
70 static SDL_Rect **XBIOS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
71 static SDL_Surface *XBIOS_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
72 static int XBIOS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
73 static void XBIOS_VideoQuit(_THIS);
74 
75 /* Hardware surface functions */
76 static int XBIOS_AllocHWSurface(_THIS, SDL_Surface *surface);
77 static int XBIOS_LockHWSurface(_THIS, SDL_Surface *surface);
78 static int XBIOS_FlipHWSurface(_THIS, SDL_Surface *surface);
79 static void XBIOS_UnlockHWSurface(_THIS, SDL_Surface *surface);
80 static void XBIOS_FreeHWSurface(_THIS, SDL_Surface *surface);
81 static void XBIOS_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
82 
83 #if SDL_VIDEO_OPENGL
84 /* OpenGL functions */
85 static void XBIOS_GL_SwapBuffers(_THIS);
86 #endif
87 
88 /* To setup palette */
89 
90 static unsigned short	TT_palette[256];
91 static unsigned long	F30_palette[256];
92 
93 /* Xbios driver bootstrap functions */
94 
XBIOS_Available(void)95 static int XBIOS_Available(void)
96 {
97 	unsigned long cookie_vdo, cookie_mil, cookie_hade, cookie_scpn;
98 
99 	/* Milan/Hades Atari clones do not have an Atari video chip */
100 	if ( (Getcookie(C__MIL, &cookie_mil) == C_FOUND) ||
101 		(Getcookie(C_hade, &cookie_hade) == C_FOUND) ) {
102 		return 0;
103 	}
104 
105 	/* Cookie _VDO present ? if not, assume ST machine */
106 	if (Getcookie(C__VDO, &cookie_vdo) != C_FOUND) {
107 		cookie_vdo = VDO_ST << 16;
108 	}
109 
110 	/* Test if we have a monochrome monitor plugged in */
111 	switch( cookie_vdo >>16) {
112 		case VDO_ST:
113 		case VDO_STE:
114 			if ( Getrez() == (ST_HIGH>>8) )
115 				return 0;
116 			break;
117 		case VDO_TT:
118 			if ( (EgetShift() & ES_MODE) == TT_HIGH)
119 				return 0;
120 			break;
121 		case VDO_F30:
122 			if ( VgetMonitor() == MONITOR_MONO)
123 				return 0;
124 			if (Getcookie(C_SCPN, &cookie_scpn) == C_FOUND) {
125 				if (!SDL_XBIOS_SB3Usable((scpn_cookie_t *)cookie_scpn)) {
126 					return 0;
127 				}
128 			}
129 			break;
130 		default:
131 			return 0;
132 	}
133 
134 	return 1;
135 }
136 
XBIOS_DeleteDevice(SDL_VideoDevice * device)137 static void XBIOS_DeleteDevice(SDL_VideoDevice *device)
138 {
139 	SDL_free(device->hidden);
140 	SDL_free(device);
141 }
142 
XBIOS_CreateDevice(int devindex)143 static SDL_VideoDevice *XBIOS_CreateDevice(int devindex)
144 {
145 	SDL_VideoDevice *device;
146 
147 	/* Initialize all variables that we clean on shutdown */
148 	device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
149 	if ( device ) {
150 		SDL_memset(device, 0, (sizeof *device));
151 		device->hidden = (struct SDL_PrivateVideoData *)
152 				SDL_malloc((sizeof *device->hidden));
153 		device->gl_data = (struct SDL_PrivateGLData *)
154 				SDL_malloc((sizeof *device->gl_data));
155 	}
156 	if ( (device == NULL) || (device->hidden == NULL) ) {
157 		SDL_OutOfMemory();
158 		if ( device ) {
159 			SDL_free(device);
160 		}
161 		return(0);
162 	}
163 	SDL_memset(device->hidden, 0, (sizeof *device->hidden));
164 	SDL_memset(device->gl_data, 0, sizeof(*device->gl_data));
165 
166 	/* Video functions */
167 	device->VideoInit = XBIOS_VideoInit;
168 	device->ListModes = XBIOS_ListModes;
169 	device->SetVideoMode = XBIOS_SetVideoMode;
170 	device->SetColors = XBIOS_SetColors;
171 	device->UpdateRects = NULL;
172 	device->VideoQuit = XBIOS_VideoQuit;
173 	device->AllocHWSurface = XBIOS_AllocHWSurface;
174 	device->LockHWSurface = XBIOS_LockHWSurface;
175 	device->UnlockHWSurface = XBIOS_UnlockHWSurface;
176 	device->FlipHWSurface = XBIOS_FlipHWSurface;
177 	device->FreeHWSurface = XBIOS_FreeHWSurface;
178 
179 #if SDL_VIDEO_OPENGL
180 	/* OpenGL functions */
181 	device->GL_LoadLibrary = SDL_AtariGL_LoadLibrary;
182 	device->GL_GetProcAddress = SDL_AtariGL_GetProcAddress;
183 	device->GL_GetAttribute = SDL_AtariGL_GetAttribute;
184 	device->GL_MakeCurrent = SDL_AtariGL_MakeCurrent;
185 	device->GL_SwapBuffers = XBIOS_GL_SwapBuffers;
186 #endif
187 
188 	/* Events */
189 	device->InitOSKeymap = Atari_InitOSKeymap;
190 	device->PumpEvents = Atari_PumpEvents;
191 
192 	device->free = XBIOS_DeleteDevice;
193 
194 	return device;
195 }
196 
197 VideoBootStrap XBIOS_bootstrap = {
198 	XBIOS_VID_DRIVER_NAME, "Atari Xbios driver",
199 	XBIOS_Available, XBIOS_CreateDevice
200 };
201 
SDL_XBIOS_AddMode(_THIS,Uint16 modecode,Uint16 width,Uint16 height,Uint16 depth,SDL_bool flags)202 void SDL_XBIOS_AddMode(_THIS, Uint16 modecode, Uint16 width, Uint16 height,
203 	Uint16 depth, SDL_bool flags)
204 {
205 	int i, curpos;
206 	xbiosmode_t *current_mode;
207 
208 	/* Check if mode already exists */
209 	if (XBIOS_modelist) {
210 		current_mode = XBIOS_modelist;
211 		for (i=0;i<XBIOS_nummodes; i++, current_mode++) {
212 			if (current_mode->width != width)
213 				continue;
214 			if (current_mode->height != height)
215 				continue;
216 			if (current_mode->depth != depth)
217 				continue;
218 			return;
219 		}
220 	}
221 
222 	++XBIOS_nummodes;
223 	XBIOS_modelist = (xbiosmode_t *) SDL_realloc(XBIOS_modelist, XBIOS_nummodes * sizeof(xbiosmode_t));
224 
225 	/* Keep the list sorted: bpp, width, height */
226 	curpos=0;
227 
228 	for(i=0; i<XBIOS_nummodes-1; i++) {
229 		if (XBIOS_modelist[i].depth <= depth) {
230 			if (XBIOS_modelist[i].width < width) {
231 				break;
232 			} else if (XBIOS_modelist[i].width == width) {
233 				if (XBIOS_modelist[i].height <= height) {
234 					break;
235 				}
236 			}
237 		}
238 		curpos++;
239 	}
240 
241 	/* Push remaining modes further */
242 	for(i=XBIOS_nummodes-1; i>curpos; i--) {
243 		SDL_memcpy(&XBIOS_modelist[i], &XBIOS_modelist[i-1], sizeof(xbiosmode_t));
244 	}
245 
246 	XBIOS_modelist[curpos].number = modecode;
247 	XBIOS_modelist[curpos].width = width;
248 	XBIOS_modelist[curpos].height = height;
249 	XBIOS_modelist[curpos].depth = depth;
250 	XBIOS_modelist[curpos].doubleline = flags;
251 }
252 
XBIOS_VideoInit(_THIS,SDL_PixelFormat * vformat)253 static int XBIOS_VideoInit(_THIS, SDL_PixelFormat *vformat)
254 {
255 	int i,j8,j16;
256 	xbiosmode_t *current_mode;
257 	unsigned long cookie_blow, cookie_scpn, cookie_cnts;
258 
259 	/* Initialize all variables that we clean on shutdown */
260 	memset (SDL_modelist, 0, sizeof(SDL_modelist));
261 
262 	/* Cookie _VDO present ? if not, assume ST machine */
263 	if (Getcookie(C__VDO, &XBIOS_cvdo) != C_FOUND) {
264 		XBIOS_cvdo = VDO_ST << 16;
265 	}
266 
267 	/* Allocate memory for old palette */
268 	XBIOS_oldpalette = (void *)SDL_malloc(256*sizeof(long));
269 	if ( !XBIOS_oldpalette ) {
270 		SDL_SetError("Unable to allocate memory for old palette\n");
271 		return(-1);
272 	}
273 
274 	/* Initialize video mode list */
275 	/* and save current screen status (palette, screen address, video mode) */
276 	XBIOS_nummodes = 0;
277 	XBIOS_modelist = NULL;
278 	XBIOS_centscreen = SDL_FALSE;
279 
280 	switch (XBIOS_cvdo >>16) {
281 		case VDO_ST:
282 		case VDO_STE:
283 			{
284 				short *oldpalette;
285 
286 				SDL_XBIOS_AddMode(this, ST_LOW>>8,320,200,4,SDL_FALSE);
287 
288 				XBIOS_oldvbase=Physbase();
289 				XBIOS_oldvmode=Getrez();
290 				switch(XBIOS_oldvmode << 8) {
291 					case ST_LOW:
292 						XBIOS_oldnumcol=16;
293 						break;
294 					case ST_MED:
295 						XBIOS_oldnumcol=4;
296 						break;
297 					case ST_HIGH:
298 						XBIOS_oldnumcol=2;
299 						break;
300 					default:
301 						XBIOS_oldnumcol=0;
302 						break;
303 				}
304 
305 				oldpalette= (short *) XBIOS_oldpalette;
306 				for (i=0;i<XBIOS_oldnumcol;i++) {
307 					*oldpalette++=Setcolor(i,-1);
308 				}
309 
310 				vformat->BitsPerPixel = 8;
311 			}
312 			break;
313 		case VDO_TT:
314 
315 			SDL_XBIOS_AddMode(this, TT_LOW,320,480,8,SDL_FALSE);
316 			/* Software double-lined mode */
317 			SDL_XBIOS_AddMode(this, TT_LOW,320,240,8,SDL_TRUE);
318 
319 			XBIOS_oldvbase=Logbase();
320 			XBIOS_oldvmode=EgetShift();
321 
322 			switch(XBIOS_oldvmode & ES_MODE) {
323 				case TT_LOW:
324 					XBIOS_oldnumcol=256;
325 					break;
326 				case ST_LOW:
327 				case TT_MED:
328 					XBIOS_oldnumcol=16;
329 					break;
330 				case ST_MED:
331 					XBIOS_oldnumcol=4;
332 					break;
333 				case ST_HIGH:
334 				case TT_HIGH:
335 					XBIOS_oldnumcol=2;
336 					break;
337 				default:
338 					XBIOS_oldnumcol=0;
339 					break;
340 			}
341 			if (XBIOS_oldnumcol) {
342 				EgetPalette(0, XBIOS_oldnumcol, XBIOS_oldpalette);
343 			}
344 
345 			vformat->BitsPerPixel = 8;
346 			break;
347 		case VDO_F30:
348 			switch (VgetMonitor())
349 			{
350 				case MONITOR_MONO:
351 					/* Not usable */
352 					break;
353 				case MONITOR_RGB:
354 				case MONITOR_TV:
355 					SDL_XBIOS_AddMode(this, BPS16|COL80|OVERSCAN|VERTFLAG,768,480,16,SDL_FALSE);
356 					SDL_XBIOS_AddMode(this, BPS16|COL80|OVERSCAN,768,240,16,SDL_FALSE);
357 					SDL_XBIOS_AddMode(this, BPS16|COL80|VERTFLAG,640,400,16,SDL_FALSE);
358 					SDL_XBIOS_AddMode(this, BPS16|COL80,640,200,16,SDL_FALSE);
359 					SDL_XBIOS_AddMode(this, BPS16|OVERSCAN|VERTFLAG,384,480,16,SDL_FALSE);
360 					SDL_XBIOS_AddMode(this, BPS16|OVERSCAN,384,240,16,SDL_FALSE);
361 					SDL_XBIOS_AddMode(this, BPS16|VERTFLAG,320,400,16,SDL_FALSE);
362 					SDL_XBIOS_AddMode(this, BPS16,320,200,16,SDL_FALSE);
363 					SDL_XBIOS_AddMode(this, BPS8|COL80|OVERSCAN|VERTFLAG,768,480,8,SDL_FALSE);
364 					SDL_XBIOS_AddMode(this, BPS8|COL80|OVERSCAN,768,240,8,SDL_FALSE);
365 					SDL_XBIOS_AddMode(this, BPS8|COL80|VERTFLAG,640,400,8,SDL_FALSE);
366 					SDL_XBIOS_AddMode(this, BPS8|COL80,640,200,8,SDL_FALSE);
367 					SDL_XBIOS_AddMode(this, BPS8|OVERSCAN|VERTFLAG,384,480,8,SDL_FALSE);
368 					SDL_XBIOS_AddMode(this, BPS8|OVERSCAN,384,240,8,SDL_FALSE);
369 					SDL_XBIOS_AddMode(this, BPS8|VERTFLAG,320,400,8,SDL_FALSE);
370 					SDL_XBIOS_AddMode(this, BPS8,320,200,8,SDL_FALSE);
371 					break;
372 				case MONITOR_VGA:
373 					SDL_XBIOS_AddMode(this, BPS16,320,480,16,SDL_FALSE);
374 					SDL_XBIOS_AddMode(this, BPS16|VERTFLAG,320,240,16,SDL_FALSE);
375 					SDL_XBIOS_AddMode(this, BPS8|COL80,640,480,8,SDL_FALSE);
376 					SDL_XBIOS_AddMode(this, BPS8|COL80|VERTFLAG,640,240,8,SDL_FALSE);
377 					SDL_XBIOS_AddMode(this, BPS8,320,480,8,SDL_FALSE);
378 					SDL_XBIOS_AddMode(this, BPS8|VERTFLAG,320,240,8,SDL_FALSE);
379 					break;
380 			}
381 			XBIOS_oldvbase=Logbase();
382 			XBIOS_oldvmode=VsetMode(-1);
383 
384 			XBIOS_oldnumcol= 1<< (1 << (XBIOS_oldvmode & NUMCOLS));
385 			if (XBIOS_oldnumcol > 256) {
386 				XBIOS_oldnumcol = 0;
387 			}
388 			if (XBIOS_oldnumcol) {
389 				VgetRGB(0, XBIOS_oldnumcol, XBIOS_oldpalette);
390 			}
391 
392 			vformat->BitsPerPixel = 16;
393 
394 			/* Keep vga/rvb, and pal/ntsc bits */
395 			current_mode = XBIOS_modelist;
396 			for (i=0;i<XBIOS_nummodes;i++) {
397 				Uint16 newvmode;
398 
399 				newvmode = current_mode->number;
400 				newvmode &= ~(VGA|PAL);
401 				newvmode |= XBIOS_oldvmode & (VGA|PAL);
402 				current_mode->number = newvmode;
403 
404 				current_mode++;
405 			}
406 
407 			/* Initialize BlowUp/SB3/Centscreen stuff if present */
408 			if (Getcookie(C_BLOW, &cookie_blow) == C_FOUND) {
409 				SDL_XBIOS_BlowupInit(this, (blow_cookie_t *)cookie_blow);
410 			} else if (Getcookie(C_SCPN, &cookie_scpn) == C_FOUND) {
411 				SDL_XBIOS_SB3Init(this, (scpn_cookie_t *)cookie_scpn);
412 			} else if (Getcookie(C_CNTS, &cookie_cnts) == C_FOUND) {
413 				XBIOS_oldvmode = SDL_XBIOS_CentscreenInit(this);
414 				XBIOS_centscreen = SDL_TRUE;
415 			}
416 
417 			break;
418 	}
419 
420 	/* Determine the current screen size */
421 	if ( XBIOS_nummodes > 0 ) {
422 		/* FIXME: parse video mode list to search for current mode */
423 		this->info.current_w = XBIOS_modelist[0].width;
424 		this->info.current_h = XBIOS_modelist[0].height;
425 	}
426 
427 	current_mode = XBIOS_modelist;
428 	j8 = j16 = 0;
429 	for (i=0; i<XBIOS_nummodes; i++, current_mode++) {
430 		switch (current_mode->depth) {
431 			case 4:
432 			case 8:
433 				SDL_modelist[0][j8] = SDL_malloc(sizeof(SDL_Rect));
434 				SDL_modelist[0][j8]->x = SDL_modelist[0][j8]->y = 0;
435 				SDL_modelist[0][j8]->w = current_mode->width;
436 				SDL_modelist[0][j8]->h = current_mode->height;
437 				XBIOS_videomodes[0][j8]=current_mode;
438 				j8++;
439 				break;
440 			case 16:
441 				SDL_modelist[1][j16] = SDL_malloc(sizeof(SDL_Rect));
442 				SDL_modelist[1][j16]->x = SDL_modelist[1][j16]->y = 0;
443 				SDL_modelist[1][j16]->w = current_mode->width;
444 				SDL_modelist[1][j16]->h = current_mode->height;
445 				XBIOS_videomodes[1][j16]=current_mode;
446 				j16++;
447 				break;
448 		}
449 	}
450 	SDL_modelist[0][j8] = NULL;
451 	SDL_modelist[1][j16] = NULL;
452 
453 	XBIOS_screens[0]=NULL;
454 	XBIOS_screens[1]=NULL;
455 	XBIOS_shadowscreen=NULL;
456 
457 	/* Update hardware info */
458 	this->info.hw_available = 1;
459 	this->info.video_mem = (Uint32) Atari_SysMalloc(-1L, MX_STRAM);
460 
461 	/* Init chunky to planar routine */
462 	SDL_Atari_C2pConvert = SDL_Atari_C2pConvert8;
463 
464 #if SDL_VIDEO_OPENGL
465 	SDL_AtariGL_InitPointers(this);
466 #endif
467 
468 	/* Disable screensavers */
469 	if (SDL_XBIOS_TveillePresent(this)) {
470 		SDL_XBIOS_TveilleDisable(this);
471 	}
472 
473 	/* We're done! */
474 	return(0);
475 }
476 
XBIOS_ListModes(_THIS,SDL_PixelFormat * format,Uint32 flags)477 static SDL_Rect **XBIOS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
478 {
479 	/* 8 bits -> list 0 */
480 	/* 16 bits -> list 1 */
481 	if ((format->BitsPerPixel != 8) && (format->BitsPerPixel !=16)) {
482 		return NULL;
483 	}
484 
485 	return(SDL_modelist[(format->BitsPerPixel)>>4]);
486 }
487 
XBIOS_FreeBuffers(_THIS)488 static void XBIOS_FreeBuffers(_THIS)
489 {
490 	int i;
491 
492 	for (i=0;i<2;i++) {
493 		if (XBIOS_screensmem[i]!=NULL) {
494 			Mfree(XBIOS_screensmem[i]);
495 			XBIOS_screensmem[i]=NULL;
496 		}
497 	}
498 
499 	if (XBIOS_shadowscreen!=NULL) {
500 		Mfree(XBIOS_shadowscreen);
501 		XBIOS_shadowscreen=NULL;
502 	}
503 }
504 
XBIOS_SetVideoMode(_THIS,SDL_Surface * current,int width,int height,int bpp,Uint32 flags)505 static SDL_Surface *XBIOS_SetVideoMode(_THIS, SDL_Surface *current,
506 				int width, int height, int bpp, Uint32 flags)
507 {
508 	int mode, new_depth;
509 	int i;
510 	xbiosmode_t *new_video_mode;
511 	Uint32 new_screen_size;
512 	Uint32 modeflags;
513 
514 	/* Free current buffers */
515 	XBIOS_FreeBuffers(this);
516 
517 	/* Limit bpp */
518 	if (bpp>16) {
519 		bpp = 16;
520 	}
521 	bpp >>= 4;
522 
523 	/* Search if the mode exists (width, height, bpp) */
524 	for ( mode=0; SDL_modelist[bpp][mode]; ++mode ) {
525 		if ( (SDL_modelist[bpp][mode]->w == width) &&
526 		     (SDL_modelist[bpp][mode]->h == height) ) {
527 
528 			break;
529 		}
530 	}
531 	if ( SDL_modelist[bpp][mode] == NULL ) {
532 		SDL_SetError("Couldn't find requested mode in list");
533 		return(NULL);
534 	}
535 
536 	modeflags = SDL_FULLSCREEN | SDL_PREALLOC;
537 
538 	/* Allocate needed buffers: simple/double buffer and shadow surface */
539 	new_video_mode = XBIOS_videomodes[bpp][mode];
540 	new_depth = new_video_mode->depth;
541 	if (new_depth == 4) {
542 		SDL_Atari_C2pConvert = SDL_Atari_C2pConvert4;
543 		new_depth=8;
544 		modeflags |= SDL_SWSURFACE|SDL_HWPALETTE;
545 	} else if (new_depth == 8) {
546 		SDL_Atari_C2pConvert = SDL_Atari_C2pConvert8;
547 		modeflags |= SDL_SWSURFACE|SDL_HWPALETTE;
548 	} else {
549 		modeflags |= SDL_HWSURFACE;
550 	}
551 
552 	new_screen_size = width * height * ((new_depth)>>3);
553 	new_screen_size += 256; /* To align on a 256 byte adress */
554 
555 	if (new_depth == 8) {
556 		XBIOS_shadowscreen = Atari_SysMalloc(new_screen_size, MX_PREFTTRAM);
557 
558 		if (XBIOS_shadowscreen == NULL) {
559 			SDL_SetError("Can not allocate %d KB for shadow buffer", new_screen_size>>10);
560 			return (NULL);
561 		}
562 		SDL_memset(XBIOS_shadowscreen, 0, new_screen_size);
563 	}
564 
565 	/* Output buffer needs to be twice in size for the software double-line mode */
566 	XBIOS_doubleline = SDL_FALSE;
567 	if (new_video_mode->doubleline) {
568 		new_screen_size <<= 1;
569 		XBIOS_doubleline = SDL_TRUE;
570 	}
571 
572 	XBIOS_screensmem[0] = Atari_SysMalloc(new_screen_size, MX_STRAM);
573 
574 	if (XBIOS_screensmem[0]==NULL) {
575 		XBIOS_FreeBuffers(this);
576 		SDL_SetError("Can not allocate %d KB for frame buffer", new_screen_size>>10);
577 		return (NULL);
578 	}
579 	SDL_memset(XBIOS_screensmem[0], 0, new_screen_size);
580 
581 	XBIOS_screens[0]=(void *) (( (long) XBIOS_screensmem[0]+256) & 0xFFFFFF00UL);
582 
583 #if SDL_VIDEO_OPENGL
584 	if (flags & SDL_OPENGL) {
585 		if (this->gl_config.double_buffer) {
586 			flags |= SDL_DOUBLEBUF;
587 		}
588 	}
589 #endif
590 
591 	/* Double buffer ? */
592 	if (flags & SDL_DOUBLEBUF) {
593 		XBIOS_screensmem[1] = Atari_SysMalloc(new_screen_size, MX_STRAM);
594 
595 		if (XBIOS_screensmem[1]==NULL) {
596 			XBIOS_FreeBuffers(this);
597 			SDL_SetError("Can not allocate %d KB for double buffer", new_screen_size>>10);
598 			return (NULL);
599 		}
600 		SDL_memset(XBIOS_screensmem[1], 0, new_screen_size);
601 
602 		XBIOS_screens[1]=(void *) (( (long) XBIOS_screensmem[1]+256) & 0xFFFFFF00UL);
603 		modeflags |= SDL_DOUBLEBUF;
604 	}
605 
606 	/* Allocate the new pixel format for the screen */
607 	if ( ! SDL_ReallocFormat(current, new_depth, 0, 0, 0, 0) ) {
608 		XBIOS_FreeBuffers(this);
609 		SDL_SetError("Couldn't allocate new pixel format for requested mode");
610 		return(NULL);
611 	}
612 
613 	current->w = XBIOS_width = width;
614 	current->h = XBIOS_height = height;
615 	current->pitch = (width * new_depth)>>3;
616 
617 	/* this is for C2P conversion */
618 	XBIOS_pitch = (new_video_mode->width * new_video_mode->depth)>>3;
619 
620 	if (new_depth == 8)
621 		current->pixels = XBIOS_shadowscreen;
622 	else
623 		current->pixels = XBIOS_screens[0];
624 
625 	XBIOS_fbnum = 0;
626 
627 #if SDL_VIDEO_OPENGL
628 	if (flags & SDL_OPENGL) {
629 		if (!SDL_AtariGL_Init(this, current)) {
630 			XBIOS_FreeBuffers(this);
631 			SDL_SetError("Can not create OpenGL context");
632 			return NULL;
633 		}
634 
635 		modeflags |= SDL_OPENGL;
636 	}
637 #endif
638 
639 	current->flags = modeflags;
640 
641 	/* Now set the video mode */
642 #ifndef DEBUG_VIDEO_XBIOS
643 	Setscreen(-1,XBIOS_screens[0],-1);
644 #endif
645 
646 	switch(XBIOS_cvdo >> 16) {
647 		case VDO_ST:
648 #ifndef DEBUG_VIDEO_XBIOS
649 			Setscreen(-1,-1,new_video_mode->number);
650 #endif
651 			/* Reset palette */
652 			for (i=0;i<16;i++) {
653 				TT_palette[i]= ((i>>1)<<8) | (((i*8)/17)<<4) | (i>>1);
654 			}
655 #ifndef DEBUG_VIDEO_XBIOS
656 			Setpalette(TT_palette);
657 #endif
658 			break;
659 		case VDO_STE:
660 #ifndef DEBUG_VIDEO_XBIOS
661 			Setscreen(-1,-1,new_video_mode->number);
662 #endif
663 			/* Reset palette */
664 			for (i=0;i<16;i++)
665 			{
666 				int c;
667 
668 				c=((i&1)<<3)|((i>>1)&7);
669 				TT_palette[i]=(c<<8)|(c<<4)|c;
670 			}
671 #ifndef DEBUG_VIDEO_XBIOS
672 			Setpalette(TT_palette);
673 #endif
674 			break;
675 		case VDO_TT:
676 #ifndef DEBUG_VIDEO_XBIOS
677 			EsetShift(new_video_mode->number);
678 #endif
679 			break;
680 		case VDO_F30:
681 #ifndef DEBUG_VIDEO_XBIOS
682 			if (XBIOS_centscreen) {
683 				SDL_XBIOS_CentscreenSetmode(this, width, height, new_depth);
684 			} else {
685 				VsetMode(new_video_mode->number);
686 			}
687 #endif
688 			/* Set hardware palette to black in True Colour */
689 			if (new_depth == 16) {
690 				SDL_memset(F30_palette, 0, sizeof(F30_palette));
691 				VsetRGB(0,256,F30_palette);
692 			}
693 			break;
694 	}
695 
696 	Vsync();
697 
698 	this->UpdateRects = XBIOS_UpdateRects;
699 
700 	return (current);
701 }
702 
703 /* We don't actually allow hardware surfaces other than the main one */
XBIOS_AllocHWSurface(_THIS,SDL_Surface * surface)704 static int XBIOS_AllocHWSurface(_THIS, SDL_Surface *surface)
705 {
706 	return(-1);
707 }
708 
XBIOS_FreeHWSurface(_THIS,SDL_Surface * surface)709 static void XBIOS_FreeHWSurface(_THIS, SDL_Surface *surface)
710 {
711 	return;
712 }
713 
XBIOS_LockHWSurface(_THIS,SDL_Surface * surface)714 static int XBIOS_LockHWSurface(_THIS, SDL_Surface *surface)
715 {
716 	return(0);
717 }
718 
XBIOS_UnlockHWSurface(_THIS,SDL_Surface * surface)719 static void XBIOS_UnlockHWSurface(_THIS, SDL_Surface *surface)
720 {
721 	return;
722 }
723 
XBIOS_UpdateRects(_THIS,int numrects,SDL_Rect * rects)724 static void XBIOS_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
725 {
726 	SDL_Surface *surface;
727 
728 	surface = this->screen;
729 
730 	if ((surface->format->BitsPerPixel) == 8) {
731 		int i;
732 
733 		for (i=0;i<numrects;i++) {
734 			void *source,*destination;
735 			int x1,x2;
736 
737 			x1 = rects[i].x & ~15;
738 			x2 = rects[i].x+rects[i].w;
739 			if (x2 & 15) {
740 				x2 = (x2 | 15) +1;
741 			}
742 
743 			source = surface->pixels;
744 			source += surface->pitch * rects[i].y;
745 			source += x1;
746 
747 			destination = XBIOS_screens[XBIOS_fbnum];
748 			destination += XBIOS_pitch * rects[i].y;
749 			destination += x1;
750 
751 			/* Convert chunky to planar screen */
752 			SDL_Atari_C2pConvert(
753 				source,
754 				destination,
755 				x2-x1,
756 				rects[i].h,
757 				XBIOS_doubleline,
758 				surface->pitch,
759 				XBIOS_pitch
760 			);
761 		}
762 	}
763 
764 #ifndef DEBUG_VIDEO_XBIOS
765 	Setscreen(-1,XBIOS_screens[XBIOS_fbnum],-1);
766 #endif
767 	Vsync();
768 
769 	if ((surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) {
770 		XBIOS_fbnum ^= 1;
771 		if ((surface->format->BitsPerPixel) > 8) {
772 			surface->pixels=XBIOS_screens[XBIOS_fbnum];
773 		}
774 	}
775 }
776 
XBIOS_FlipHWSurface(_THIS,SDL_Surface * surface)777 static int XBIOS_FlipHWSurface(_THIS, SDL_Surface *surface)
778 {
779 	if ((surface->format->BitsPerPixel) == 8) {
780 		void *destscr;
781 		int destx;
782 
783 		/* Center on destination screen */
784 		destscr = XBIOS_screens[XBIOS_fbnum];
785 		destscr += XBIOS_pitch * ((XBIOS_height - surface->h) >> 1);
786 		destx = (XBIOS_width - surface->w) >> 1;
787 		destx &= ~15;
788 		destscr += destx;
789 
790 		/* Convert chunky to planar screen */
791 		SDL_Atari_C2pConvert(
792 			surface->pixels,
793 			destscr,
794 			surface->w,
795 			surface->h,
796 			XBIOS_doubleline,
797 			surface->pitch,
798 			XBIOS_pitch
799 		);
800 	}
801 
802 #ifndef DEBUG_VIDEO_XBIOS
803 	Setscreen(-1,XBIOS_screens[XBIOS_fbnum],-1);
804 #endif
805 	Vsync();
806 
807 	if ((surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) {
808 		XBIOS_fbnum ^= 1;
809 		if ((surface->format->BitsPerPixel) > 8) {
810 			surface->pixels=XBIOS_screens[XBIOS_fbnum];
811 		}
812 	}
813 
814 	return(0);
815 }
816 
XBIOS_SetColors(_THIS,int firstcolor,int ncolors,SDL_Color * colors)817 static int XBIOS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
818 {
819 	int		i;
820 	int		r,v,b;
821 
822 	switch( XBIOS_cvdo >> 16) {
823 		case VDO_ST:
824 		case VDO_STE:
825 		 	for (i=0;i<ncolors;i++)
826 			{
827 				r = colors[i].r;
828 				v = colors[i].g;
829 				b = colors[i].b;
830 
831 				TT_palette[firstcolor+i]=((r*30)+(v*59)+(b*11))/100;
832 			}
833 			SDL_Atari_C2pConvert4_pal(TT_palette); /* convert the lighting */
834 			break;
835 		case VDO_TT:
836 			for(i = 0; i < ncolors; i++)
837 			{
838 				r = colors[i].r;
839 				v = colors[i].g;
840 				b = colors[i].b;
841 
842 				TT_palette[i]=((r>>4)<<8)|((v>>4)<<4)|(b>>4);
843 			}
844 #ifndef DEBUG_VIDEO_XBIOS
845 			EsetPalette(firstcolor,ncolors,TT_palette);
846 #endif
847 			break;
848 		case VDO_F30:
849 			for(i = 0; i < ncolors; i++)
850 			{
851 				r = colors[i].r;
852 				v = colors[i].g;
853 				b = colors[i].b;
854 
855 				F30_palette[i]=(r<<16)|(v<<8)|b;
856 			}
857 #ifndef DEBUG_VIDEO_XBIOS
858 			VsetRGB(firstcolor,ncolors,F30_palette);
859 #endif
860 			break;
861 	}
862 
863 	return(1);
864 }
865 
866 /* Note:  If we are terminated, this could be called in the middle of
867    another SDL video routine -- notably UpdateRects.
868 */
XBIOS_VideoQuit(_THIS)869 static void XBIOS_VideoQuit(_THIS)
870 {
871 	int i,j;
872 
873 	Atari_ShutdownEvents();
874 
875 	/* Restore video mode and palette */
876 #ifndef DEBUG_VIDEO_XBIOS
877 	switch(XBIOS_cvdo >> 16) {
878 		case VDO_ST:
879 		case VDO_STE:
880 			Setscreen(-1,XBIOS_oldvbase,XBIOS_oldvmode);
881 			if (XBIOS_oldnumcol) {
882 				Setpalette(XBIOS_oldpalette);
883 			}
884 			break;
885 		case VDO_TT:
886 			Setscreen(-1,XBIOS_oldvbase,-1);
887 			EsetShift(XBIOS_oldvmode);
888 			if (XBIOS_oldnumcol) {
889 				EsetPalette(0, XBIOS_oldnumcol, XBIOS_oldpalette);
890 			}
891 			break;
892 		case VDO_F30:
893 			Setscreen(-1, XBIOS_oldvbase, -1);
894 			if (XBIOS_centscreen) {
895 				SDL_XBIOS_CentscreenRestore(this, XBIOS_oldvmode);
896 			} else {
897 				VsetMode(XBIOS_oldvmode);
898 			}
899 			if (XBIOS_oldnumcol) {
900 				VsetRGB(0, XBIOS_oldnumcol, XBIOS_oldpalette);
901 			}
902 			break;
903 	}
904 	Vsync();
905 #endif
906 
907 
908 #if SDL_VIDEO_OPENGL
909 	if (gl_active) {
910 		SDL_AtariGL_Quit(this, SDL_TRUE);
911 	}
912 #endif
913 
914 	if (XBIOS_oldpalette) {
915 		SDL_free(XBIOS_oldpalette);
916 		XBIOS_oldpalette=NULL;
917 	}
918 	XBIOS_FreeBuffers(this);
919 
920 	/* Free mode list */
921 	for (j=0;j<NUM_MODELISTS;j++) {
922 		for (i=0;i<SDL_NUMMODES;i++) {
923 			if (SDL_modelist[j][i]!=NULL) {
924 				SDL_free(SDL_modelist[j][i]);
925 				SDL_modelist[j][i]=NULL;
926 			}
927 		}
928 	}
929 
930 	if (XBIOS_modelist) {
931 		SDL_free(XBIOS_modelist);
932 		XBIOS_nummodes=0;
933 		XBIOS_modelist=NULL;
934 	}
935 
936 	this->screen->pixels = NULL;
937 
938 	/* Restore screensavers */
939 	if (SDL_XBIOS_TveillePresent(this)) {
940 		SDL_XBIOS_TveilleRestore(this);
941 	}
942 }
943 
944 #if SDL_VIDEO_OPENGL
945 
XBIOS_GL_SwapBuffers(_THIS)946 static void XBIOS_GL_SwapBuffers(_THIS)
947 {
948 	SDL_AtariGL_SwapBuffers(this);
949 	XBIOS_FlipHWSurface(this, this->screen);
950 	SDL_AtariGL_MakeCurrent(this);
951 }
952 
953 #endif
954