/
SDL_gemvideo.c
1329 lines (1082 loc) · 30.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
22
23
Sam Lantinga
slouken@libsdl.org
*/
/*
24
25
26
27
28
29
GEM video driver
Patrice Mandin
and work from
Olivier Landemarre, Johan Klockars, Xavier Joubert, Claude Attard
*/
30
31
32
33
34
/* Mint includes */
#include <gem.h>
#include <gemx.h>
#include <mint/osbind.h>
35
#include <mint/cookie.h>
36
37
#include "SDL_endian.h"
38
39
#include "SDL_video.h"
#include "SDL_mouse.h"
40
41
42
43
#include "../SDL_sysvideo.h"
#include "../SDL_pixels_c.h"
#include "../../events/SDL_events_c.h"
#include "../SDL_cursor_c.h"
44
45
46
47
#include "SDL_ataric2p_s.h"
#include "SDL_atarieddi_s.h"
#include "SDL_atarimxalloc_c.h"
48
49
#include "SDL_atarigl_c.h"
50
51
52
53
#include "SDL_gemvideo.h"
#include "SDL_gemevents_c.h"
#include "SDL_gemmouse_c.h"
#include "SDL_gemwm_c.h"
54
#include "SDL_xbiosevents_c.h"
55
56
57
/* Defines */
58
/*#define DEBUG_VIDEO_GEM 1*/
59
60
61
#define GEM_VID_DRIVER_NAME "gem"
62
63
64
65
66
#undef MIN
#define MIN(a,b) (((a)<(b)) ? (a) : (b))
#undef MAX
#define MAX(a,b) (((a)>(b)) ? (a) : (b))
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/* Variables */
static unsigned char vdi_index[256] = {
0, 2, 3, 6, 4, 7, 5, 8,
9, 10, 11, 14, 12, 15, 13, 255
};
static const unsigned char empty_name[]="";
/* Initialization/Query functions */
static int GEM_VideoInit(_THIS, SDL_PixelFormat *vformat);
static SDL_Rect **GEM_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
static SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
static int GEM_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
static void GEM_VideoQuit(_THIS);
/* Hardware surface functions */
static int GEM_AllocHWSurface(_THIS, SDL_Surface *surface);
static int GEM_LockHWSurface(_THIS, SDL_Surface *surface);
static int GEM_FlipHWSurface(_THIS, SDL_Surface *surface);
static void GEM_UnlockHWSurface(_THIS, SDL_Surface *surface);
static void GEM_FreeHWSurface(_THIS, SDL_Surface *surface);
static void GEM_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
#if 0
static int GEM_ToggleFullScreen(_THIS, int on);
#endif
/* Internal functions */
static void GEM_FreeBuffers(_THIS);
96
static void GEM_ClearScreen(_THIS);
97
static void GEM_ClearRect(_THIS, short *rect);
98
static void GEM_SetNewPalette(_THIS, Uint16 newpal[256][3]);
99
100
static void GEM_LockScreen(_THIS);
static void GEM_UnlockScreen(_THIS);
101
102
static void refresh_window(_THIS, int winhandle, short *rect);
103
#if SDL_VIDEO_OPENGL
104
105
106
107
/* OpenGL functions */
static void GEM_GL_SwapBuffers(_THIS);
#endif
108
109
110
111
112
/* GEM driver bootstrap functions */
static int GEM_Available(void)
{
/* Test if AES available */
113
if (appl_init() == -1)
114
115
116
117
118
119
120
121
return 0;
appl_exit();
return 1;
}
static void GEM_DeleteDevice(SDL_VideoDevice *device)
{
122
123
SDL_free(device->hidden);
SDL_free(device);
124
125
126
127
128
}
static SDL_VideoDevice *GEM_CreateDevice(int devindex)
{
SDL_VideoDevice *device;
129
130
int vectors_mask;
unsigned long dummy;
131
132
/* Initialize all variables that we clean on shutdown */
133
device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
134
if ( device ) {
135
SDL_memset(device, 0, (sizeof *device));
136
device->hidden = (struct SDL_PrivateVideoData *)
137
SDL_malloc((sizeof *device->hidden));
138
device->gl_data = (struct SDL_PrivateGLData *)
139
SDL_malloc((sizeof *device->gl_data));
140
141
142
143
}
if ( (device == NULL) || (device->hidden == NULL) ) {
SDL_OutOfMemory();
if ( device ) {
144
SDL_free(device);
145
146
147
}
return(0);
}
148
149
SDL_memset(device->hidden, 0, (sizeof *device->hidden));
SDL_memset(device->gl_data, 0, sizeof(*device->gl_data));
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/* Set the function pointers */
device->VideoInit = GEM_VideoInit;
device->ListModes = GEM_ListModes;
device->SetVideoMode = GEM_SetVideoMode;
device->SetColors = GEM_SetColors;
device->UpdateRects = NULL /*GEM_UpdateRects*/;
device->VideoQuit = GEM_VideoQuit;
device->AllocHWSurface = GEM_AllocHWSurface;
device->LockHWSurface = GEM_LockHWSurface;
device->UnlockHWSurface = GEM_UnlockHWSurface;
device->FlipHWSurface = GEM_FlipHWSurface;
device->FreeHWSurface = GEM_FreeHWSurface;
device->ToggleFullScreen = NULL /*GEM_ToggleFullScreen*/;
/* Window manager */
device->SetCaption = GEM_SetCaption;
167
device->SetIcon = GEM_SetIcon;
168
169
170
171
172
173
174
175
176
177
178
device->IconifyWindow = GEM_IconifyWindow;
device->GrabInput = GEM_GrabInput;
/* Events */
device->InitOSKeymap = GEM_InitOSKeymap;
device->PumpEvents = GEM_PumpEvents;
/* Mouse */
device->FreeWMCursor = GEM_FreeWMCursor;
device->CreateWMCursor = GEM_CreateWMCursor;
device->ShowWMCursor = GEM_ShowWMCursor;
179
device->WarpWMCursor = NULL /*GEM_WarpWMCursor*/;
180
181
device->CheckMouseMode = GEM_CheckMouseMode;
182
#if SDL_VIDEO_OPENGL
183
/* OpenGL functions */
184
185
186
187
device->GL_LoadLibrary = SDL_AtariGL_LoadLibrary;
device->GL_GetProcAddress = SDL_AtariGL_GetProcAddress;
device->GL_GetAttribute = SDL_AtariGL_GetAttribute;
device->GL_MakeCurrent = SDL_AtariGL_MakeCurrent;
188
189
190
device->GL_SwapBuffers = GEM_GL_SwapBuffers;
#endif
191
/* Joystick + Mouse relative motion */
192
193
194
195
196
197
vectors_mask = ATARI_XBIOS_MOUSEEVENTS|ATARI_XBIOS_JOYSTICKEVENTS;
if (Getcookie(C_MiNT, &dummy)==C_FOUND) {
vectors_mask = 0;
}
SDL_AtariXbios_InstallVectors(vectors_mask);
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
device->free = GEM_DeleteDevice;
return device;
}
VideoBootStrap GEM_bootstrap = {
GEM_VID_DRIVER_NAME, "Atari GEM video driver",
GEM_Available, GEM_CreateDevice
};
static void VDI_ReadExtInfo(_THIS, short *work_out)
{
unsigned long EdDI_version;
unsigned long cookie_EdDI;
Uint32 num_colours;
Uint16 clut_type, num_bits;
/* Read EdDI informations */
if (Getcookie(C_EdDI, &cookie_EdDI) == C_NOTFOUND) {
return;
}
EdDI_version = Atari_get_EdDI_version( (void *)cookie_EdDI);
vq_scrninfo(VDI_handle, work_out);
VDI_format = work_out[0];
clut_type = work_out[1];
num_bits = work_out[2];
num_colours = *((Uint32 *) &work_out[3]);
/* With EdDI>=1.1, we can have screen pitch, address and format
* so we can directly write to screen without using vro_cpyfm
*/
if (EdDI_version >= EDDI_11) {
VDI_pitch = work_out[5];
VDI_screen = (void *) *((unsigned long *) &work_out[6]);
}
switch(clut_type) {
case VDI_CLUT_HARDWARE:
{
int i;
Uint16 *tmp_p;
tmp_p = (Uint16 *)&work_out[16];
for (i=0;i<256;i++) {
247
vdi_index[*tmp_p++] = i;
248
249
250
251
}
}
break;
case VDI_CLUT_SOFTWARE:
252
{
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
int component; /* red, green, blue, alpha, overlay */
int num_bit;
unsigned short *tmp_p;
/* We can build masks with info here */
tmp_p = (unsigned short *) &work_out[16];
for (component=0;component<5;component++) {
for (num_bit=0;num_bit<16;num_bit++) {
unsigned short valeur;
valeur = *tmp_p++;
if (valeur == 0xffff) {
continue;
}
switch(component) {
case 0:
VDI_redmask |= 1<< valeur;
break;
case 1:
VDI_greenmask |= 1<< valeur;
break;
case 2:
VDI_bluemask |= 1<< valeur;
break;
case 3:
VDI_alphamask |= 1<< valeur;
break;
}
}
}
285
}
286
287
288
289
/* Remove lower green bits for Intel endian screen */
if ((VDI_greenmask == ((7<<13)|3)) || (VDI_greenmask == ((7<<13)|7))) {
VDI_greenmask &= ~(7<<13);
290
291
292
293
294
295
296
297
298
}
break;
case VDI_CLUT_NONE:
break;
}
}
int GEM_VideoInit(_THIS, SDL_PixelFormat *vformat)
{
299
int i, menubar_size;
300
301
302
short work_in[12], work_out[272], dummy;
/* Open AES (Application Environment Services) */
303
if (appl_init() == -1) {
304
305
306
307
308
fprintf(stderr,"Can not open AES\n");
return 1;
}
/* Read version and features */
309
310
311
GEM_version = aes_global[0];
if (GEM_version >= 0x0410) {
short ap_gout[4], errorcode;
312
313
GEM_wfeatures=0;
314
315
316
errorcode=appl_getinfo(AES_WINDOW, &ap_gout[0], &ap_gout[1], &ap_gout[2], &ap_gout[3]);
if (errorcode==0) {
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
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
391
392
393
394
395
GEM_wfeatures=ap_gout[0];
}
}
/* Ask VDI physical workstation handle opened by AES */
VDI_handle = graf_handle(&dummy, &dummy, &dummy, &dummy);
if (VDI_handle<1) {
fprintf(stderr,"Wrong VDI handle %d returned by AES\n",VDI_handle);
return 1;
}
/* Open virtual VDI workstation */
work_in[0]=Getrez()+2;
for(i = 1; i < 10; i++)
work_in[i] = 1;
work_in[10] = 2;
v_opnvwk(work_in, &VDI_handle, work_out);
if (VDI_handle == 0) {
fprintf(stderr,"Can not open VDI virtual workstation\n");
return 1;
}
/* Read fullscreen size */
VDI_w = work_out[0] + 1;
VDI_h = work_out[1] + 1;
/* Read desktop size and position */
if (!wind_get(DESKTOP_HANDLE, WF_WORKXYWH, &GEM_desk_x, &GEM_desk_y, &GEM_desk_w, &GEM_desk_h)) {
fprintf(stderr,"Can not read desktop properties\n");
return 1;
}
/* Read bit depth */
vq_extnd(VDI_handle, 1, work_out);
VDI_bpp = work_out[4];
VDI_oldnumcolors=0;
switch(VDI_bpp) {
case 8:
VDI_pixelsize=1;
break;
case 15:
case 16:
VDI_pixelsize=2;
break;
case 24:
VDI_pixelsize=3;
break;
case 32:
VDI_pixelsize=4;
break;
default:
fprintf(stderr,"%d bits colour depth not supported\n",VDI_bpp);
return 1;
}
/* Setup hardware -> VDI palette mapping */
for(i = 16; i < 255; i++) {
vdi_index[i] = i;
}
vdi_index[255] = 1;
/* Save current palette */
if (VDI_bpp>8) {
VDI_oldnumcolors=1<<8;
} else {
VDI_oldnumcolors=1<<VDI_bpp;
}
for(i = 0; i < VDI_oldnumcolors; i++) {
short rgb[3];
vq_color(VDI_handle, i, 0, rgb);
VDI_oldpalette[i][0] = rgb[0];
VDI_oldpalette[i][1] = rgb[1];
VDI_oldpalette[i][2] = rgb[2];
}
396
VDI_setpalette = GEM_SetNewPalette;
397
SDL_memcpy(VDI_curpalette,VDI_oldpalette,sizeof(VDI_curpalette));
398
399
400
401
402
403
404
405
/* Setup screen info */
GEM_title_name = empty_name;
GEM_icon_name = empty_name;
GEM_handle = -1;
GEM_locked = SDL_FALSE;
GEM_win_fulled = SDL_FALSE;
406
GEM_fullscreen = SDL_FALSE;
407
GEM_lock_redraw = SDL_TRUE; /* Prevent redraw till buffers are setup */
408
409
VDI_screen = NULL;
410
411
412
413
414
415
416
417
418
419
420
421
VDI_pitch = VDI_w * VDI_pixelsize;
VDI_format = ( (VDI_bpp <= 8) ? VDI_FORMAT_INTER : VDI_FORMAT_PACK);
VDI_redmask = VDI_greenmask = VDI_bluemask = VDI_alphamask = 0;
VDI_ReadExtInfo(this, work_out);
#ifdef DEBUG_VIDEO_GEM
printf("sdl:video:gem: screen: address=0x%08x, pitch=%d\n", VDI_screen, VDI_pitch);
printf("sdl:video:gem: format=%d\n", VDI_format);
printf("sdl:video:gem: masks: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
VDI_alphamask, VDI_redmask, VDI_greenmask, VDI_bluemask
);
#endif
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
/* Setup destination mfdb */
VDI_dst_mfdb.fd_addr = NULL;
/* Update hardware info */
this->info.hw_available = 0;
this->info.video_mem = 0;
/* Determine the screen depth */
/* we change this during the SDL_SetVideoMode implementation... */
vformat->BitsPerPixel = VDI_bpp;
/* Set mouse cursor to arrow */
graf_mouse(ARROW, NULL);
/* Init chunky to planar routine */
438
439
440
441
442
443
444
SDL_Atari_C2pConvert = SDL_Atari_C2pConvert8;
/* Setup VDI fill functions */
vsf_color(VDI_handle,0);
vsf_interior(VDI_handle,1);
vsf_perimeter(VDI_handle,0);
445
446
447
448
/* Menu bar save buffer */
menubar_size = GEM_desk_w * GEM_desk_y * VDI_pixelsize;
GEM_menubar=Atari_SysMalloc(menubar_size,MX_PREFTTRAM);
449
/* Fill video modes list */
450
SDL_modelist[0] = SDL_malloc(sizeof(SDL_Rect));
451
452
453
454
455
456
457
SDL_modelist[0]->x = 0;
SDL_modelist[0]->y = 0;
SDL_modelist[0]->w = VDI_w;
SDL_modelist[0]->h = VDI_h;
SDL_modelist[1] = NULL;
458
#if SDL_VIDEO_OPENGL
459
SDL_AtariGL_InitPointers(this);
460
#endif
461
462
463
464
465
466
467
/* We're done! */
return(0);
}
SDL_Rect **GEM_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
{
468
if (format->BitsPerPixel != VDI_bpp) {
469
470
return ((SDL_Rect **)NULL);
}
471
472
473
474
475
476
if (flags & SDL_FULLSCREEN) {
return (SDL_modelist);
}
return((SDL_Rect **)-1);
477
478
479
480
481
}
static void GEM_FreeBuffers(_THIS)
{
/* Release buffer */
482
if ( GEM_buffer2 ) {
483
Mfree( GEM_buffer2 );
484
485
486
487
GEM_buffer2=NULL;
}
if ( GEM_buffer1 ) {
488
Mfree( GEM_buffer1 );
489
GEM_buffer1=NULL;
490
491
492
}
}
493
static void GEM_ClearRect(_THIS, short *rect)
494
{
495
short oldrgb[3], rgb[3]={0,0,0};
496
497
498
499
500
501
502
vq_color(VDI_handle, vdi_index[0], 0, oldrgb);
vs_color(VDI_handle, vdi_index[0], rgb);
vsf_color(VDI_handle,0);
vsf_interior(VDI_handle,1);
vsf_perimeter(VDI_handle,0);
503
v_bar(VDI_handle, rect);
504
505
vs_color(VDI_handle, vdi_index[0], oldrgb);
506
507
508
509
510
511
512
513
514
515
516
517
}
static void GEM_ClearScreen(_THIS)
{
short pxy[4];
v_hide_c(VDI_handle);
pxy[0] = pxy[1] = 0;
pxy[2] = VDI_w - 1;
pxy[3] = VDI_h - 1;
GEM_ClearRect(this, pxy);
518
519
520
521
v_show_c(VDI_handle, 1);
}
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
static void GEM_SetNewPalette(_THIS, Uint16 newpal[256][3])
{
int i;
short rgb[3];
if (VDI_oldnumcolors==0)
return;
for(i = 0; i < VDI_oldnumcolors; i++) {
rgb[0] = newpal[i][0];
rgb[1] = newpal[i][1];
rgb[2] = newpal[i][2];
vs_color(VDI_handle, i, rgb);
}
}
539
540
541
542
543
544
static void GEM_LockScreen(_THIS)
{
if (!GEM_locked) {
/* Lock AES */
wind_update(BEG_UPDATE);
wind_update(BEG_MCTRL);
545
546
/* Reserve memory space, used to be sure of compatibility */
form_dial( FMD_START, 0,0,0,0, 0,0,VDI_w,VDI_h);
547
548
549
550
551
552
553
554
555
/* Save menu bar */
if (GEM_menubar) {
MFDB mfdb_src;
short blitcoords[8];
mfdb_src.fd_addr=GEM_menubar;
mfdb_src.fd_w=GEM_desk_w;
mfdb_src.fd_h=GEM_desk_y;
556
mfdb_src.fd_wdwidth=GEM_desk_w>>4;
557
558
559
560
561
562
563
564
565
566
567
568
569
570
mfdb_src.fd_nplanes=VDI_bpp;
mfdb_src.fd_stand=
mfdb_src.fd_r1=
mfdb_src.fd_r2=
mfdb_src.fd_r3= 0;
blitcoords[0] = blitcoords[4] = 0;
blitcoords[1] = blitcoords[5] = 0;
blitcoords[2] = blitcoords[6] = GEM_desk_w-1;
blitcoords[3] = blitcoords[7] = GEM_desk_y-1;
vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &VDI_dst_mfdb, &mfdb_src);
}
571
572
573
574
575
576
577
GEM_locked=SDL_TRUE;
}
}
static void GEM_UnlockScreen(_THIS)
{
if (GEM_locked) {
578
579
580
581
582
583
584
585
/* Restore menu bar */
if (GEM_menubar) {
MFDB mfdb_src;
short blitcoords[8];
mfdb_src.fd_addr=GEM_menubar;
mfdb_src.fd_w=GEM_desk_w;
mfdb_src.fd_h=GEM_desk_y;
586
mfdb_src.fd_wdwidth=GEM_desk_w>>4;
587
588
589
590
591
592
593
594
595
596
597
598
599
600
mfdb_src.fd_nplanes=VDI_bpp;
mfdb_src.fd_stand=
mfdb_src.fd_r1=
mfdb_src.fd_r2=
mfdb_src.fd_r3= 0;
blitcoords[0] = blitcoords[4] = 0;
blitcoords[1] = blitcoords[5] = 0;
blitcoords[2] = blitcoords[6] = GEM_desk_w-1;
blitcoords[3] = blitcoords[7] = GEM_desk_y-1;
vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, &VDI_dst_mfdb);
}
601
602
603
604
605
606
607
608
609
610
/* Restore screen memory, and send REDRAW to all apps */
form_dial( FMD_FINISH, 0,0,0,0, 0,0,VDI_w,VDI_h);
/* Unlock AES */
wind_update(END_MCTRL);
wind_update(END_UPDATE);
GEM_locked=SDL_FALSE;
}
}
611
612
613
614
615
SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface *current,
int width, int height, int bpp, Uint32 flags)
{
int maxwidth, maxheight;
Uint32 modeflags, screensize;
616
SDL_bool use_shadow1, use_shadow2;
617
618
619
620
621
622
623
624
625
626
627
/*--- Verify if asked mode can be used ---*/
if (flags & SDL_FULLSCREEN) {
maxwidth=VDI_w;
maxheight=VDI_h;
} else {
/* Windowed mode */
maxwidth=GEM_desk_w;
maxheight=GEM_desk_h;
}
628
/* width must be multiple of 16, for vro_cpyfm() and c2p_convert() */
629
if ((width & 15) != 0) {
630
631
632
width = (width | 15) +1;
}
633
634
635
636
637
638
639
640
641
642
643
if ((maxwidth < width) || (maxheight < height) || (VDI_bpp != bpp)) {
SDL_SetError("Couldn't find requested mode in list");
return(NULL);
}
/*--- Allocate the new pixel format for the screen ---*/
if ( ! SDL_ReallocFormat(current, VDI_bpp, VDI_redmask, VDI_greenmask, VDI_bluemask, VDI_alphamask) ) {
SDL_SetError("Couldn't allocate new pixel format for requested mode");
return(NULL);
}
644
645
screensize = width * height * VDI_pixelsize;
646
647
648
649
#ifdef DEBUG_VIDEO_GEM
printf("sdl:video:gem: setvideomode(): %dx%dx%d = %d\n", width, height, bpp, screensize);
#endif
650
/*--- Allocate shadow buffers if needed, and conversion operations ---*/
651
652
GEM_FreeBuffers(this);
653
654
655
656
657
658
GEM_bufops=0;
use_shadow1=use_shadow2=SDL_FALSE;
if (VDI_screen && (flags & SDL_FULLSCREEN)) {
if (VDI_format==VDI_FORMAT_INTER) {
use_shadow1=SDL_TRUE;
GEM_bufops = B2S_C2P_1TOS;
659
660
}
} else {
661
662
663
664
665
666
667
use_shadow1=SDL_TRUE;
if (VDI_format==VDI_FORMAT_PACK) {
GEM_bufops = B2S_VROCPYFM_1TOS;
} else {
use_shadow2=SDL_TRUE;
GEM_bufops = B2S_C2P_1TO2|B2S_VROCPYFM_2TOS;
}
668
669
}
670
671
672
if (use_shadow1) {
GEM_buffer1 = Atari_SysMalloc(screensize, MX_PREFTTRAM);
if (GEM_buffer1==NULL) {
673
SDL_SetError("Can not allocate %d KB for frame buffer", screensize>>10);
674
675
return NULL;
}
676
SDL_memset(GEM_buffer1, 0, screensize);
677
678
679
680
#ifdef DEBUG_VIDEO_GEM
printf("sdl:video:gem: setvideomode(): allocated buffer 1\n");
#endif
}
681
682
683
684
if (use_shadow2) {
GEM_buffer2 = Atari_SysMalloc(screensize, MX_PREFTTRAM);
if (GEM_buffer2==NULL) {
685
SDL_SetError("Can not allocate %d KB for shadow buffer", screensize>>10);
686
687
return NULL;
}
688
SDL_memset(GEM_buffer2, 0, screensize);
689
690
691
#ifdef DEBUG_VIDEO_GEM
printf("sdl:video:gem: setvideomode(): allocated buffer 2\n");
#endif
692
693
694
}
/*--- Initialize screen ---*/
695
modeflags = SDL_PREALLOC;
696
697
698
699
if (VDI_bpp == 8) {
modeflags |= SDL_HWPALETTE;
}
700
if (flags & SDL_FULLSCREEN) {
701
GEM_LockScreen(this);
702
703
GEM_ClearScreen(this);
704
705
modeflags |= SDL_FULLSCREEN;
706
if (VDI_screen && (VDI_format==VDI_FORMAT_PACK) && !use_shadow1) {
707
708
709
710
modeflags |= SDL_HWSURFACE;
} else {
modeflags |= SDL_SWSURFACE;
}
711
712
GEM_fullscreen = SDL_TRUE;
713
} else {
714
int old_win_type;
715
716
short x2,y2,w2,h2;
717
GEM_UnlockScreen(this);
718
719
/* Set window gadgets */
720
old_win_type = GEM_win_type;
721
722
723
724
725
726
727
728
729
730
if (!(flags & SDL_NOFRAME)) {
GEM_win_type=NAME|MOVER|CLOSER|SMALLER;
if (flags & SDL_RESIZABLE) {
GEM_win_type |= FULLER|SIZER;
modeflags |= SDL_RESIZABLE;
}
} else {
GEM_win_type=0;
modeflags |= SDL_NOFRAME;
}
731
modeflags |= SDL_SWSURFACE;
732
733
/* Recreate window ? only for different widget or non-created window */
734
if ((old_win_type != GEM_win_type) || (GEM_handle < 0)) {
735
736
737
738
739
740
/* Calculate window size */
if (!wind_calc(WC_BORDER, GEM_win_type, 0,0,width,height, &x2,&y2,&w2,&h2)) {
GEM_FreeBuffers(this);
SDL_SetError("Can not calculate window attributes");
return NULL;
}
741
742
743
744
/* Center window */
x2 = GEM_desk_x+((GEM_desk_w-w2)>>1);
y2 = GEM_desk_y+((GEM_desk_h-h2)>>1);
745
746
747
748
749
750
751
752
753
754
755
756
757
758
/* Destroy existing window */
if (GEM_handle >= 0) {
wind_close(GEM_handle);
wind_delete(GEM_handle);
}
/* Create window */
GEM_handle=wind_create(GEM_win_type, x2,y2,w2,h2);
if (GEM_handle<0) {
GEM_FreeBuffers(this);
SDL_SetError("Can not create window");
return NULL;
}
759
760
#ifdef DEBUG_VIDEO_GEM
761
printf("sdl:video:gem: handle=%d\n", GEM_handle);
762
763
#endif
764
765
766
/* Setup window name */
wind_set(GEM_handle,WF_NAME,(short)(((unsigned long)GEM_title_name)>>16),(short)(((unsigned long)GEM_title_name) & 0xffff),0,0);
GEM_refresh_name = SDL_FALSE;
767
768
769
/* Open the window */
wind_open(GEM_handle,x2,y2,w2,h2);
770
771
772
773
774
775
776
777
778
779
780
781
782
} else {
/* Resize window if needed, to fit asked video mode */
if (modeflags & SDL_RESIZABLE) {
wind_get (GEM_handle, WF_WORKXYWH, &x2,&y2,&w2,&h2);
if ((w2&15)!=0) {
w2=(w2|15)+1;
}
if ((w2!=width) || (h2!=height)) {
if (wind_calc(WC_BORDER, GEM_win_type, x2,y2,width,height, &x2,&y2,&w2,&h2)) {
wind_set (GEM_handle, WF_CURRXYWH, x2,y2,w2,h2);
}
}
}
783
}
784
785
GEM_fullscreen = SDL_FALSE;
786
787
788
789
790
}
/* Set up the new mode framebuffer */
current->w = width;
current->h = height;
791
792
if (use_shadow1) {
current->pixels = GEM_buffer1;
793
current->pitch = width * VDI_pixelsize;
794
795
796
797
798
} else {
current->pixels = VDI_screen;
current->pitch = VDI_pitch;
}
799
#if SDL_VIDEO_OPENGL
800
if (flags & SDL_OPENGL) {
801
if (!SDL_AtariGL_Init(this, current)) {
802
GEM_FreeBuffers(this);
803
804
SDL_SetError("Can not create OpenGL context");
return NULL;
805
806
807
808
809
810
811
812
}
modeflags |= SDL_OPENGL;
}
#endif
current->flags = modeflags;
813
814
815
816
#ifdef DEBUG_VIDEO_GEM
printf("sdl:video:gem: surface: %dx%d\n", current->w, current->h);
#endif
817
this->UpdateRects = GEM_UpdateRects;
818
GEM_lock_redraw = SDL_FALSE; /* Enable redraw */
819
820
821
822
823
824
825
826
827
/* We're done */
return(current);
}
static int GEM_AllocHWSurface(_THIS, SDL_Surface *surface)
{
return -1;
}
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
static void GEM_FreeHWSurface(_THIS, SDL_Surface *surface)
{
return;
}
static int GEM_LockHWSurface(_THIS, SDL_Surface *surface)
{
return(0);
}
static void GEM_UnlockHWSurface(_THIS, SDL_Surface *surface)
{
return;
}
static void GEM_UpdateRectsFullscreen(_THIS, int numrects, SDL_Rect *rects)
{
SDL_Surface *surface;
847
int i, surf_width;
848
849
surface = this->screen;
850
851
/* Need to be a multiple of 16 pixels */
surf_width=surface->w;
852
if ((surf_width & 15) != 0) {
853
854
surf_width = (surf_width | 15) + 1;
}
855
856
857
858
859
860
if (GEM_bufops & (B2S_C2P_1TO2|B2S_C2P_1TOS)) {
void *destscr;
int destpitch;
if (GEM_bufops & B2S_C2P_1TOS) {
861
destscr = VDI_screen;
862
863
864
865
866
destpitch = VDI_pitch;
} else {
destscr = GEM_buffer2;
destpitch = surface->pitch;
}
867
868
869
870
for (i=0;i<numrects;i++) {
void *source,*destination;
int x1,x2;
871
872
873
874
875
x1 = rects[i].x & ~15;
x2 = rects[i].x+rects[i].w;
if (x2 & 15) {
x2 = (x2 | 15) +1;
876
877
}
878
879
880
source = surface->pixels;
source += surface->pitch * rects[i].y;
source += x1;
881
882
883
884
885
886
887
888
889
890
891
destination = destscr;
destination += destpitch * rects[i].y;
destination += x1;
SDL_Atari_C2pConvert(
source, destination,
x2-x1, rects[i].h,
SDL_FALSE,
surface->pitch, destpitch
);
892
893
}
}
894
895
896
897
if (GEM_bufops & (B2S_VROCPYFM_1TOS|B2S_VROCPYFM_2TOS)) {
MFDB mfdb_src;
short blitcoords[8];
898
899
mfdb_src.fd_addr=surface->pixels;
900
mfdb_src.fd_w=surf_width;
901
mfdb_src.fd_h=surface->h;
902
mfdb_src.fd_wdwidth= (surface->pitch/VDI_pixelsize) >> 4;
903
904
905
906
907
908
909
910
mfdb_src.fd_nplanes=surface->format->BitsPerPixel;
mfdb_src.fd_stand=
mfdb_src.fd_r1=
mfdb_src.fd_r2=
mfdb_src.fd_r3= 0;
if (GEM_bufops & B2S_VROCPYFM_2TOS) {
mfdb_src.fd_addr=GEM_buffer2;
}
911
912
for ( i=0; i<numrects; ++i ) {
913
914
915
916
blitcoords[0] = blitcoords[4] = rects[i].x;
blitcoords[1] = blitcoords[5] = rects[i].y;
blitcoords[2] = blitcoords[6] = rects[i].x + rects[i].w - 1;
blitcoords[3] = blitcoords[7] = rects[i].y + rects[i].h - 1;
917
918
919
vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, &VDI_dst_mfdb);
}
920
}
921
922
923
924
}
static void GEM_UpdateRectsWindowed(_THIS, int numrects, SDL_Rect *rects)
{
925
short pxy[4], wind_pxy[4];
926
927
int i;
928
929
930
if (wind_get(GEM_handle, WF_WORKXYWH, &wind_pxy[0], &wind_pxy[1], &wind_pxy[2], &wind_pxy[3])==0) {
return;
}
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
for ( i=0; i<numrects; ++i ) {
pxy[0] = wind_pxy[0] + rects[i].x;
pxy[1] = wind_pxy[1] + rects[i].y;
pxy[2] = rects[i].w;
pxy[3] = rects[i].h;
GEM_wind_redraw(this, GEM_handle, pxy);
}
}
static void GEM_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
{
SDL_Surface *surface;
946
947
948
949
if (GEM_lock_redraw) {
return;
}
950
951
952
953
954
955
956
957
958
959
960
surface = this->screen;
if (surface->flags & SDL_FULLSCREEN) {
GEM_UpdateRectsFullscreen(this, numrects, rects);
} else {
GEM_UpdateRectsWindowed(this, numrects, rects);
}
}
static int GEM_FlipHWSurfaceFullscreen(_THIS, SDL_Surface *surface)
{
961
962
963
964
int surf_width;
/* Need to be a multiple of 16 pixels */
surf_width=surface->w;
965
if ((surf_width & 15) != 0) {
966
967
968
surf_width = (surf_width | 15) + 1;
}
969
970
971
if (GEM_bufops & (B2S_C2P_1TO2|B2S_C2P_1TOS)) {
void *destscr;
int destpitch;
972
973
if (GEM_bufops & B2S_C2P_1TOS) {
974
destscr = VDI_screen;
975
976
977
978
979
destpitch = VDI_pitch;
} else {
destscr = GEM_buffer2;
destpitch = surface->pitch;
}
980
981
982
SDL_Atari_C2pConvert(
surface->pixels, destscr,
983
surf_width, surface->h,
984
985
986
987
SDL_FALSE,
surface->pitch, destpitch
);
}
988
989
990
991
if (GEM_bufops & (B2S_VROCPYFM_1TOS|B2S_VROCPYFM_2TOS)) {
MFDB mfdb_src;
short blitcoords[8];
992
993
mfdb_src.fd_w=surf_width;
994
mfdb_src.fd_h=surface->h;
995
mfdb_src.fd_wdwidth=mfdb_src.fd_w >> 4;
996
997
998
999
1000
mfdb_src.fd_nplanes=surface->format->BitsPerPixel;
mfdb_src.fd_stand=
mfdb_src.fd_r1=
mfdb_src.fd_r2=
mfdb_src.fd_r3= 0;