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