Imported Upstream version 1.2.15
[platform/upstream/SDL.git] / src / video / gem / SDL_gemvideo.c
1 /*
2     SDL - Simple DirectMedia Layer
3     Copyright (C) 1997-2012 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         GEM video driver
26
27         Patrice Mandin
28         and work from
29         Olivier Landemarre, Johan Klockars, Xavier Joubert, Claude Attard
30 */
31
32 /* Mint includes */
33 #include <gem.h>
34 #include <gemx.h>
35 #include <mint/osbind.h>
36 #include <mint/cookie.h>
37
38 #include "SDL_endian.h"
39 #include "SDL_video.h"
40 #include "SDL_mouse.h"
41 #include "../SDL_sysvideo.h"
42 #include "../SDL_pixels_c.h"
43 #include "../../events/SDL_events_c.h"
44 #include "../SDL_cursor_c.h"
45
46 #include "../ataricommon/SDL_ataric2p_s.h"
47 #include "../ataricommon/SDL_atarieddi_s.h"
48 #include "../ataricommon/SDL_atarimxalloc_c.h"
49 #include "../ataricommon/SDL_atarigl_c.h"
50
51 #include "SDL_gemvideo.h"
52 #include "SDL_gemevents_c.h"
53 #include "SDL_gemmouse_c.h"
54 #include "SDL_gemwm_c.h"
55 #include "../ataricommon/SDL_xbiosevents_c.h"
56 #include "../ataricommon/SDL_ataridevmouse_c.h"
57
58 /* Defines */
59
60 /*#define DEBUG_VIDEO_GEM       1*/
61
62 #define GEM_VID_DRIVER_NAME "gem"
63
64 #undef MIN
65 #define MIN(a,b) (((a)<(b)) ? (a) : (b))
66 #undef MAX
67 #define MAX(a,b) (((a)>(b)) ? (a) : (b))
68
69 /* Variables */
70
71 static unsigned char vdi_index[256] = {
72         0,  2,  3,  6,  4,  7,  5,   8,
73         9, 10, 11, 14, 12, 15, 13, 255
74 };
75
76 static const char empty_name[]="";
77
78 /* Initialization/Query functions */
79 static int GEM_VideoInit(_THIS, SDL_PixelFormat *vformat);
80 static SDL_Rect **GEM_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
81 static SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
82 static int GEM_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
83 static void GEM_VideoQuit(_THIS);
84
85 /* Hardware surface functions */
86 static int GEM_AllocHWSurface(_THIS, SDL_Surface *surface);
87 static int GEM_LockHWSurface(_THIS, SDL_Surface *surface);
88 static int GEM_FlipHWSurface(_THIS, SDL_Surface *surface);
89 static void GEM_UnlockHWSurface(_THIS, SDL_Surface *surface);
90 static void GEM_FreeHWSurface(_THIS, SDL_Surface *surface);
91 static void GEM_UpdateRects(_THIS, int numrects, SDL_Rect *rects);
92 #if 0
93 static int GEM_ToggleFullScreen(_THIS, int on);
94 #endif
95
96 /* Internal functions */
97 static void GEM_FreeBuffers(_THIS);
98 static void GEM_ClearScreen(_THIS);
99 static void GEM_ClearRect(_THIS, short *rect);
100 static void GEM_SetNewPalette(_THIS, Uint16 newpal[256][3]);
101 static void GEM_LockScreen(_THIS);
102 static void GEM_UnlockScreen(_THIS);
103 static void refresh_window(_THIS, int winhandle, short *rect);
104
105 #if SDL_VIDEO_OPENGL
106 /* OpenGL functions */
107 static void GEM_GL_SwapBuffers(_THIS);
108 #endif
109
110 /* GEM driver bootstrap functions */
111
112 static int GEM_Available(void)
113 {
114         /* Test if AES available */
115         if (appl_init() == -1)
116                 return 0;
117
118         appl_exit();
119         return 1;
120 }
121
122 static void GEM_DeleteDevice(SDL_VideoDevice *device)
123 {
124         SDL_free(device->hidden);
125         SDL_free(device);
126 }
127
128 static SDL_VideoDevice *GEM_CreateDevice(int devindex)
129 {
130         SDL_VideoDevice *device;
131         int vectors_mask;
132 /*      unsigned long dummy;*/
133
134         /* Initialize all variables that we clean on shutdown */
135         device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
136         if ( device ) {
137                 SDL_memset(device, 0, (sizeof *device));
138                 device->hidden = (struct SDL_PrivateVideoData *)
139                                 SDL_malloc((sizeof *device->hidden));
140                 device->gl_data = (struct SDL_PrivateGLData *)
141                                 SDL_malloc((sizeof *device->gl_data));
142         }
143         if ( (device == NULL) || (device->hidden == NULL) ) {
144                 SDL_OutOfMemory();
145                 if ( device ) {
146                         SDL_free(device);
147                 }
148                 return(0);
149         }
150         SDL_memset(device->hidden, 0, (sizeof *device->hidden));
151         SDL_memset(device->gl_data, 0, sizeof(*device->gl_data));
152
153         /* Set the function pointers */
154         device->VideoInit = GEM_VideoInit;
155         device->ListModes = GEM_ListModes;
156         device->SetVideoMode = GEM_SetVideoMode;
157         device->SetColors = GEM_SetColors;
158         device->UpdateRects = NULL /*GEM_UpdateRects*/;
159         device->VideoQuit = GEM_VideoQuit;
160         device->AllocHWSurface = GEM_AllocHWSurface;
161         device->LockHWSurface = GEM_LockHWSurface;
162         device->UnlockHWSurface = GEM_UnlockHWSurface;
163         device->FlipHWSurface = GEM_FlipHWSurface;
164         device->FreeHWSurface = GEM_FreeHWSurface;
165         device->ToggleFullScreen = NULL /*GEM_ToggleFullScreen*/;
166
167         /* Window manager */
168         device->SetCaption = GEM_SetCaption;
169         device->SetIcon = GEM_SetIcon;
170         device->IconifyWindow = GEM_IconifyWindow;
171         device->GrabInput = GEM_GrabInput;
172
173         /* Events */
174         device->InitOSKeymap = GEM_InitOSKeymap;
175         device->PumpEvents = GEM_PumpEvents;
176
177         /* Mouse */
178         device->FreeWMCursor = GEM_FreeWMCursor;
179         device->CreateWMCursor = GEM_CreateWMCursor;
180         device->ShowWMCursor = GEM_ShowWMCursor;
181         device->WarpWMCursor = NULL /*GEM_WarpWMCursor*/;
182         device->CheckMouseMode = GEM_CheckMouseMode;
183
184 #if SDL_VIDEO_OPENGL
185         /* OpenGL functions */
186         device->GL_LoadLibrary = SDL_AtariGL_LoadLibrary;
187         device->GL_GetProcAddress = SDL_AtariGL_GetProcAddress;
188         device->GL_GetAttribute = SDL_AtariGL_GetAttribute;
189         device->GL_MakeCurrent = SDL_AtariGL_MakeCurrent;
190         device->GL_SwapBuffers = GEM_GL_SwapBuffers;
191 #endif
192
193         device->hidden->use_dev_mouse =
194                 (SDL_AtariDevMouse_Open()!=0) ? SDL_TRUE : SDL_FALSE;
195
196         vectors_mask = ATARI_XBIOS_JOYSTICKEVENTS;      /* XBIOS joystick events */
197         if (!(device->hidden->use_dev_mouse)) {
198                 vectors_mask |= ATARI_XBIOS_MOUSEEVENTS;        /* XBIOS mouse events */
199         }
200 /*      if (Getcookie(C_MiNT, &dummy)==C_FOUND) {
201                 vectors_mask = 0;
202         }*/
203
204         SDL_AtariXbios_InstallVectors(vectors_mask);
205
206         device->free = GEM_DeleteDevice;
207
208         return device;
209 }
210
211 VideoBootStrap GEM_bootstrap = {
212         GEM_VID_DRIVER_NAME, "Atari GEM video driver",
213         GEM_Available, GEM_CreateDevice
214 };
215
216 static void VDI_ReadExtInfo(_THIS, short *work_out)
217 {
218         unsigned long EdDI_version;
219         long cookie_EdDI;
220         Uint16 clut_type;
221
222         /* Read EdDI informations */
223         if  (Getcookie(C_EdDI, &cookie_EdDI) == C_NOTFOUND) {
224                 return;
225         }
226         
227         EdDI_version = Atari_get_EdDI_version( (void *)cookie_EdDI);
228
229         vq_scrninfo(VDI_handle, work_out);
230
231         VDI_format = work_out[0];
232         clut_type = work_out[1];
233
234         /* With EdDI>=1.1, we can have screen pitch, address and format
235          * so we can directly write to screen without using vro_cpyfm
236          */
237         if (EdDI_version >= EDDI_11) {
238                 VDI_pitch = work_out[5];
239                 VDI_screen = (void *) *((unsigned long *) &work_out[6]);
240         }
241
242         switch(clut_type) {
243                 case VDI_CLUT_HARDWARE:
244                         {
245                                 int i;
246                                 Uint16 *tmp_p;
247
248                                 tmp_p = (Uint16 *)&work_out[16];
249
250                                 for (i=0;i<256;i++) {
251                                         vdi_index[*tmp_p++] = i;
252                                 }
253                         }
254                         break;
255                 case VDI_CLUT_SOFTWARE:
256                         {
257                                 int component; /* red, green, blue, alpha, overlay */
258                                 int num_bit;
259                                 unsigned short *tmp_p;
260
261                                 /* We can build masks with info here */
262                                 tmp_p = (unsigned short *) &work_out[16];
263                                 for (component=0;component<5;component++) {
264                                         for (num_bit=0;num_bit<16;num_bit++) {
265                                                 unsigned short valeur;
266
267                                                 valeur = *tmp_p++;
268
269                                                 if (valeur == 0xffff) {
270                                                         continue;
271                                                 }
272
273                                                 switch(component) {
274                                                         case 0:
275                                                                 VDI_redmask |= 1<< valeur;
276                                                                 break;
277                                                         case 1:
278                                                                 VDI_greenmask |= 1<< valeur;
279                                                                 break;
280                                                         case 2:
281                                                                 VDI_bluemask |= 1<< valeur;
282                                                                 break;
283                                                         case 3:
284                                                                 VDI_alphamask |= 1<< valeur;
285                                                                 break;
286                                                 }
287                                         }
288                                 }
289                         }
290
291                         /* Remove lower green bits for Intel endian screen */
292                         if ((VDI_greenmask == ((7<<13)|3)) || (VDI_greenmask == ((7<<13)|7))) {
293                                 VDI_greenmask &= ~(7<<13);
294                         }
295                         break;
296                 case VDI_CLUT_NONE:
297                         break;
298         }
299 }
300
301 int GEM_VideoInit(_THIS, SDL_PixelFormat *vformat)
302 {
303         int i, menubar_size;
304         short work_in[12], work_out[272], dummy;
305
306         /* Open AES (Application Environment Services) */
307         if (appl_init() == -1) {
308                 fprintf(stderr,"Can not open AES\n");
309                 return 1;
310         }
311
312         /* Read version and features */
313         GEM_version = aes_global[0];
314         if (GEM_version >= 0x0410) {
315                 short ap_gout[4], errorcode;
316                 
317                 GEM_wfeatures=0;
318                 errorcode=appl_getinfo(AES_WINDOW, &ap_gout[0], &ap_gout[1], &ap_gout[2], &ap_gout[3]);
319
320                 if (errorcode==0) {
321                         GEM_wfeatures=ap_gout[0];                       
322                 }
323         }       
324
325         /* Ask VDI physical workstation handle opened by AES */
326         VDI_handle = graf_handle(&dummy, &dummy, &dummy, &dummy);
327         if (VDI_handle<1) {
328                 fprintf(stderr,"Wrong VDI handle %d returned by AES\n",VDI_handle);
329                 return 1;
330         }
331
332         /* Open virtual VDI workstation */
333         work_in[0]=Getrez()+2;
334         for(i = 1; i < 10; i++)
335                 work_in[i] = 1;
336         work_in[10] = 2;
337
338         v_opnvwk(work_in, &VDI_handle, work_out);
339         if (VDI_handle == 0) {
340                 fprintf(stderr,"Can not open VDI virtual workstation\n");
341                 return 1;
342         }
343
344         /* Read fullscreen size */
345         VDI_w = work_out[0] + 1;
346         VDI_h = work_out[1] + 1;
347
348         /* Read desktop size and position */
349         if (!wind_get(DESKTOP_HANDLE, WF_WORKXYWH, &GEM_desk_x, &GEM_desk_y, &GEM_desk_w, &GEM_desk_h)) {
350                 fprintf(stderr,"Can not read desktop properties\n");
351                 return 1;
352         }
353
354         /* Read bit depth */
355         vq_extnd(VDI_handle, 1, work_out);
356         VDI_bpp = work_out[4];
357         VDI_oldnumcolors=0;
358
359         switch(VDI_bpp) {
360                 case 8:
361                         VDI_pixelsize=1;
362                         break;
363                 case 15:
364                 case 16:
365                         VDI_pixelsize=2;
366                         break;
367                 case 24:
368                         VDI_pixelsize=3;
369                         break;
370                 case 32:
371                         VDI_pixelsize=4;
372                         break;
373                 default:
374                         fprintf(stderr,"%d bits colour depth not supported\n",VDI_bpp);
375                         return 1;
376         }
377
378         /* Setup hardware -> VDI palette mapping */
379         for(i = 16; i < 255; i++) {
380                 vdi_index[i] = i;
381         }
382         vdi_index[255] = 1;
383
384         /* Save current palette */
385         if (VDI_bpp>8) {
386                 VDI_oldnumcolors=1<<8;
387         } else {
388                 VDI_oldnumcolors=1<<VDI_bpp;
389         }
390         
391         for(i = 0; i < VDI_oldnumcolors; i++) {
392                 short rgb[3];
393
394                 vq_color(VDI_handle, i, 0, rgb);
395
396                 VDI_oldpalette[i][0] = rgb[0];
397                 VDI_oldpalette[i][1] = rgb[1];
398                 VDI_oldpalette[i][2] = rgb[2];
399         }
400         VDI_setpalette = GEM_SetNewPalette;
401         SDL_memcpy(VDI_curpalette,VDI_oldpalette,sizeof(VDI_curpalette));
402
403         /* Setup screen info */
404         GEM_title_name = empty_name;
405         GEM_icon_name = empty_name;
406
407         GEM_handle = -1;
408         GEM_locked = SDL_FALSE;
409         GEM_win_fulled = SDL_FALSE;
410         GEM_fullscreen = SDL_FALSE;
411         GEM_lock_redraw = SDL_TRUE;     /* Prevent redraw till buffers are setup */
412
413         VDI_screen = NULL;
414         VDI_pitch = VDI_w * VDI_pixelsize;
415         VDI_format = ( (VDI_bpp <= 8) ? VDI_FORMAT_INTER : VDI_FORMAT_PACK);
416         VDI_redmask = VDI_greenmask = VDI_bluemask = VDI_alphamask = 0;
417         VDI_ReadExtInfo(this, work_out);
418
419 #ifdef DEBUG_VIDEO_GEM
420         printf("sdl:video:gem: screen: address=0x%08x, pitch=%d\n", VDI_screen, VDI_pitch);
421         printf("sdl:video:gem: format=%d\n", VDI_format);
422         printf("sdl:video:gem: masks: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
423                 VDI_alphamask, VDI_redmask, VDI_greenmask, VDI_bluemask
424         );
425 #endif
426
427         /* Setup destination mfdb */
428         VDI_dst_mfdb.fd_addr = NULL;
429
430         /* Determine the current screen size */
431         this->info.current_w = VDI_w;
432         this->info.current_h = VDI_h;
433
434         /* Determine the screen depth */
435         /* we change this during the SDL_SetVideoMode implementation... */
436         vformat->BitsPerPixel = VDI_bpp;
437
438         /* Set mouse cursor to arrow */
439         graf_mouse(ARROW, NULL);
440         GEM_cursor = NULL;
441
442         /* Init chunky to planar routine */
443         SDL_Atari_C2pConvert = SDL_Atari_C2pConvert8;
444
445         /* Setup VDI fill functions */
446         vsf_color(VDI_handle,0);
447         vsf_interior(VDI_handle,1);
448         vsf_perimeter(VDI_handle,0);
449
450         /* Menu bar save buffer */
451         menubar_size = GEM_desk_w * GEM_desk_y * VDI_pixelsize;
452         GEM_menubar=Atari_SysMalloc(menubar_size,MX_PREFTTRAM);
453
454         /* Fill video modes list */
455         SDL_modelist[0] = SDL_malloc(sizeof(SDL_Rect));
456         SDL_modelist[0]->x = 0;
457         SDL_modelist[0]->y = 0;
458         SDL_modelist[0]->w = VDI_w;
459         SDL_modelist[0]->h = VDI_h;
460
461         SDL_modelist[1] = NULL;
462
463 #if SDL_VIDEO_OPENGL
464         SDL_AtariGL_InitPointers(this);
465 #endif
466
467         this->info.wm_available = 1;
468
469         /* We're done! */
470         return(0);
471 }
472
473 SDL_Rect **GEM_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags)
474 {
475         if (format->BitsPerPixel != VDI_bpp) {
476                 return ((SDL_Rect **)NULL);
477         }
478
479         if (flags & SDL_FULLSCREEN) {
480                 return (SDL_modelist);
481         }
482
483         return((SDL_Rect **)-1);
484 }
485
486 static void GEM_FreeBuffers(_THIS)
487 {
488         /* Release buffer */
489         if ( GEM_buffer2 ) {
490                 Mfree( GEM_buffer2 );
491                 GEM_buffer2=NULL;
492         }
493
494         if ( GEM_buffer1 ) {
495                 Mfree( GEM_buffer1 );
496                 GEM_buffer1=NULL;
497         }
498 }
499
500 static void GEM_ClearRect(_THIS, short *rect)
501 {
502         short oldrgb[3], rgb[3]={0,0,0};
503
504         vq_color(VDI_handle, vdi_index[0], 0, oldrgb);
505         vs_color(VDI_handle, vdi_index[0], rgb);
506
507         vsf_color(VDI_handle,0);
508         vsf_interior(VDI_handle,1);
509         vsf_perimeter(VDI_handle,0);
510         v_bar(VDI_handle, rect);
511
512         vs_color(VDI_handle, vdi_index[0], oldrgb);
513 }
514
515 static void GEM_ClearScreen(_THIS)
516 {
517         short pxy[4];
518
519         v_hide_c(VDI_handle);
520
521         pxy[0] = pxy[1] = 0;
522         pxy[2] = VDI_w - 1;
523         pxy[3] = VDI_h - 1;
524         GEM_ClearRect(this, pxy);
525
526         v_show_c(VDI_handle, 1);
527 }
528
529 static void GEM_SetNewPalette(_THIS, Uint16 newpal[256][3])
530 {
531         int i;
532         short rgb[3];
533
534         if (VDI_oldnumcolors==0)
535                 return;
536
537         for(i = 0; i < VDI_oldnumcolors; i++) {
538                 rgb[0] = newpal[i][0];
539                 rgb[1] = newpal[i][1];
540                 rgb[2] = newpal[i][2];
541
542                 vs_color(VDI_handle, i, rgb);
543         }
544 }
545
546 static void GEM_LockScreen(_THIS)
547 {
548         if (!GEM_locked) {
549                 /* Lock AES */
550                 wind_update(BEG_UPDATE);
551                 wind_update(BEG_MCTRL);
552                 /* Reserve memory space, used to be sure of compatibility */
553                 form_dial( FMD_START, 0,0,0,0, 0,0,VDI_w,VDI_h);
554
555                 /* Save menu bar */
556                 if (GEM_menubar) {
557                         MFDB mfdb_src;
558                         short blitcoords[8];
559
560                         mfdb_src.fd_addr=GEM_menubar;
561                         mfdb_src.fd_w=GEM_desk_w;
562                         mfdb_src.fd_h=GEM_desk_y;
563                         mfdb_src.fd_wdwidth=GEM_desk_w>>4;
564                         mfdb_src.fd_nplanes=VDI_bpp;
565                         mfdb_src.fd_stand=
566                                 mfdb_src.fd_r1=
567                                 mfdb_src.fd_r2=
568                                 mfdb_src.fd_r3= 0;
569
570                         blitcoords[0] = blitcoords[4] = 0;
571                         blitcoords[1] = blitcoords[5] = 0;
572                         blitcoords[2] = blitcoords[6] = GEM_desk_w-1;
573                         blitcoords[3] = blitcoords[7] = GEM_desk_y-1;
574
575                         vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &VDI_dst_mfdb, &mfdb_src);
576                 }
577
578                 GEM_locked=SDL_TRUE;
579         }
580 }
581
582 static void GEM_UnlockScreen(_THIS)
583 {
584         if (GEM_locked) {
585                 /* Restore menu bar */
586                 if (GEM_menubar) {
587                         MFDB mfdb_src;
588                         short blitcoords[8];
589
590                         mfdb_src.fd_addr=GEM_menubar;
591                         mfdb_src.fd_w=GEM_desk_w;
592                         mfdb_src.fd_h=GEM_desk_y;
593                         mfdb_src.fd_wdwidth=GEM_desk_w>>4;
594                         mfdb_src.fd_nplanes=VDI_bpp;
595                         mfdb_src.fd_stand=
596                                 mfdb_src.fd_r1=
597                                 mfdb_src.fd_r2=
598                                 mfdb_src.fd_r3= 0;
599
600                         blitcoords[0] = blitcoords[4] = 0;
601                         blitcoords[1] = blitcoords[5] = 0;
602                         blitcoords[2] = blitcoords[6] = GEM_desk_w-1;
603                         blitcoords[3] = blitcoords[7] = GEM_desk_y-1;
604
605                         vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, &VDI_dst_mfdb);
606                 }
607
608                 /* Restore screen memory, and send REDRAW to all apps */
609                 form_dial( FMD_FINISH, 0,0,0,0, 0,0,VDI_w,VDI_h);
610                 /* Unlock AES */
611                 wind_update(END_MCTRL);
612                 wind_update(END_UPDATE);
613
614                 GEM_locked=SDL_FALSE;
615         }
616 }
617
618 SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface *current,
619                                 int width, int height, int bpp, Uint32 flags)
620 {
621         Uint32 modeflags, screensize;
622         SDL_bool use_shadow1, use_shadow2;
623
624         /* width must be multiple of 16, for vro_cpyfm() and c2p_convert() */
625         if ((width & 15) != 0) {
626                 width = (width | 15) +1;
627         }
628
629         /*--- Verify if asked mode can be used ---*/
630         if (VDI_bpp != bpp) {
631                 SDL_SetError("%d bpp mode not supported", bpp);
632                 return(NULL);
633         }
634
635         if (flags & SDL_FULLSCREEN) {
636                 if ((VDI_w < width) || (VDI_h < height)) {
637                         SDL_SetError("%dx%d mode is too large", width, height);
638                         return(NULL);
639                 }
640         }
641
642         /*--- Allocate the new pixel format for the screen ---*/
643         if ( ! SDL_ReallocFormat(current, VDI_bpp, VDI_redmask, VDI_greenmask, VDI_bluemask, VDI_alphamask) ) {
644                 SDL_SetError("Couldn't allocate new pixel format for requested mode");
645                 return(NULL);
646         }
647
648         screensize = width * height * VDI_pixelsize;
649
650 #ifdef DEBUG_VIDEO_GEM
651         printf("sdl:video:gem: setvideomode(): %dx%dx%d = %d\n", width, height, bpp, screensize);
652 #endif
653
654         /*--- Allocate shadow buffers if needed, and conversion operations ---*/
655         GEM_FreeBuffers(this);
656
657         GEM_bufops=0;
658         use_shadow1=use_shadow2=SDL_FALSE;
659         if (VDI_screen && (flags & SDL_FULLSCREEN)) {
660                 if (VDI_format==VDI_FORMAT_INTER) {
661                         use_shadow1=SDL_TRUE;
662                         GEM_bufops = B2S_C2P_1TOS;
663                 }
664         } else {
665                 use_shadow1=SDL_TRUE;
666                 if (VDI_format==VDI_FORMAT_PACK) {
667                         GEM_bufops = B2S_VROCPYFM_1TOS;
668                 } else {
669                         use_shadow2=SDL_TRUE;
670                         GEM_bufops = B2S_C2P_1TO2|B2S_VROCPYFM_2TOS;
671                 }
672         }
673
674         if (use_shadow1) {
675                 GEM_buffer1 = Atari_SysMalloc(screensize, MX_PREFTTRAM);
676                 if (GEM_buffer1==NULL) {
677                         SDL_SetError("Can not allocate %d KB for frame buffer", screensize>>10);
678                         return NULL;
679                 }
680                 SDL_memset(GEM_buffer1, 0, screensize);
681 #ifdef DEBUG_VIDEO_GEM
682                 printf("sdl:video:gem: setvideomode(): allocated buffer 1\n");
683 #endif
684         }
685
686         if (use_shadow2) {
687                 GEM_buffer2 = Atari_SysMalloc(screensize, MX_PREFTTRAM);
688                 if (GEM_buffer2==NULL) {
689                         SDL_SetError("Can not allocate %d KB for shadow buffer", screensize>>10);
690                         return NULL;
691                 }
692                 SDL_memset(GEM_buffer2, 0, screensize);
693 #ifdef DEBUG_VIDEO_GEM
694                 printf("sdl:video:gem: setvideomode(): allocated buffer 2\n");
695 #endif
696         }
697
698         /*--- Initialize screen ---*/
699         modeflags = SDL_PREALLOC;
700         if (VDI_bpp == 8) {
701                 modeflags |= SDL_HWPALETTE;
702         }
703
704         if (flags & SDL_FULLSCREEN) {
705                 GEM_LockScreen(this);
706
707                 GEM_ClearScreen(this);
708
709                 modeflags |= SDL_FULLSCREEN;
710                 if (VDI_screen && (VDI_format==VDI_FORMAT_PACK) && !use_shadow1) {
711                         modeflags |= SDL_HWSURFACE;
712                 } else {
713                         modeflags |= SDL_SWSURFACE;
714                 }
715
716                 GEM_fullscreen = SDL_TRUE;
717         } else {
718                 int old_win_type;
719                 short x2,y2,w2,h2;
720
721                 GEM_UnlockScreen(this);
722
723                 /* Set window gadgets */
724                 old_win_type = GEM_win_type;
725                 if (!(flags & SDL_NOFRAME)) {
726                         GEM_win_type=NAME|MOVER|CLOSER|SMALLER;
727                         if (flags & SDL_RESIZABLE) {
728                                 GEM_win_type |= FULLER|SIZER;
729                                 modeflags |= SDL_RESIZABLE;
730                         }
731                 } else {
732                         GEM_win_type=0;
733                         modeflags |= SDL_NOFRAME;
734                 }
735                 modeflags |= SDL_SWSURFACE;
736
737                 /* Recreate window ? only for different widget or non-created window */
738                 if ((old_win_type != GEM_win_type) || (GEM_handle < 0)) {
739                         /* Calculate window size */
740                         if (!wind_calc(WC_BORDER, GEM_win_type, 0,0,width,height, &x2,&y2,&w2,&h2)) {
741                                 GEM_FreeBuffers(this);
742                                 SDL_SetError("Can not calculate window attributes");
743                                 return NULL;
744                         }
745
746                         /* Center window */
747                         x2 = (GEM_desk_w-w2)>>1;
748                         y2 = (GEM_desk_h-h2)>>1;
749                         if (x2<0) {
750                                 x2 = 0;
751                         }
752                         if (y2<0) {
753                                 y2 = 0;
754                         }
755                         x2 += GEM_desk_x;
756                         y2 += GEM_desk_y;
757
758                         /* Destroy existing window */
759                         if (GEM_handle >= 0) {
760                                 wind_close(GEM_handle);
761                                 wind_delete(GEM_handle);
762                         }
763
764                         /* Create window */
765                         GEM_handle=wind_create(GEM_win_type, x2,y2,w2,h2);
766                         if (GEM_handle<0) {
767                                 GEM_FreeBuffers(this);
768                                 SDL_SetError("Can not create window");
769                                 return NULL;
770                         }
771
772 #ifdef DEBUG_VIDEO_GEM
773                         printf("sdl:video:gem: handle=%d\n", GEM_handle);
774 #endif
775
776                         /* Setup window name */
777                         wind_set(GEM_handle,WF_NAME,(short)(((unsigned long)GEM_title_name)>>16),(short)(((unsigned long)GEM_title_name) & 0xffff),0,0);
778                         GEM_refresh_name = SDL_FALSE;
779
780                         /* Open the window */
781                         wind_open(GEM_handle,x2,y2,w2,h2);
782                 } else {
783                         /* Resize window to fit asked video mode */
784                         wind_get (GEM_handle, WF_WORKXYWH, &x2,&y2,&w2,&h2);
785                         if (wind_calc(WC_BORDER, GEM_win_type, x2,y2,width,height, &x2,&y2,&w2,&h2)) {
786                                 wind_set (GEM_handle, WF_CURRXYWH, x2,y2,w2,h2);
787                         }
788                 }
789
790                 GEM_fullscreen = SDL_FALSE;
791         }
792
793         /* Set up the new mode framebuffer */
794         current->w = width;
795         current->h = height;
796         if (use_shadow1) {
797                 current->pixels = GEM_buffer1;
798                 current->pitch = width * VDI_pixelsize;
799         } else {
800                 current->pixels = VDI_screen;
801                 current->pitch = VDI_pitch;
802         }
803
804 #if SDL_VIDEO_OPENGL
805         if (flags & SDL_OPENGL) {
806                 if (!SDL_AtariGL_Init(this, current)) {
807                         GEM_FreeBuffers(this);
808                         SDL_SetError("Can not create OpenGL context");
809                         return NULL;
810                 }
811
812                 modeflags |= SDL_OPENGL;
813         }
814 #endif
815
816         current->flags = modeflags;
817
818 #ifdef DEBUG_VIDEO_GEM
819         printf("sdl:video:gem: surface: %dx%d\n", current->w, current->h);
820 #endif
821
822         this->UpdateRects = GEM_UpdateRects;
823         GEM_lock_redraw = SDL_FALSE;    /* Enable redraw */
824
825         /* We're done */
826         return(current);
827 }
828
829 static int GEM_AllocHWSurface(_THIS, SDL_Surface *surface)
830 {
831         return -1;
832 }
833
834 static void GEM_FreeHWSurface(_THIS, SDL_Surface *surface)
835 {
836         return;
837 }
838
839 static int GEM_LockHWSurface(_THIS, SDL_Surface *surface)
840 {
841         return(0);
842 }
843
844 static void GEM_UnlockHWSurface(_THIS, SDL_Surface *surface)
845 {
846         return;
847 }
848
849 static void GEM_UpdateRectsFullscreen(_THIS, int numrects, SDL_Rect *rects)
850 {
851         SDL_Surface *surface;
852         int i, surf_width;
853
854         surface = this->screen;
855         /* Need to be a multiple of 16 pixels */
856         surf_width=surface->w;
857         if ((surf_width & 15) != 0) {
858                 surf_width = (surf_width | 15) + 1;
859         }
860
861         if (GEM_bufops & (B2S_C2P_1TO2|B2S_C2P_1TOS)) {
862                 void *destscr;
863                 int destpitch;
864
865                 if (GEM_bufops & B2S_C2P_1TOS) {
866                         destscr = VDI_screen;
867                         destpitch = VDI_pitch;
868                 } else {
869                         destscr = GEM_buffer2;
870                         destpitch = surface->pitch;
871                 }
872
873                 for (i=0;i<numrects;i++) {
874                         void *source,*destination;
875                         int x1,x2;
876
877                         x1 = rects[i].x & ~15;
878                         x2 = rects[i].x+rects[i].w;
879                         if (x2 & 15) {
880                                 x2 = (x2 | 15) +1;
881                         }
882
883                         source = surface->pixels;
884                         source += surface->pitch * rects[i].y;
885                         source += x1;
886
887                         destination = destscr;
888                         destination += destpitch * rects[i].y;
889                         destination += x1;
890
891                         SDL_Atari_C2pConvert(
892                                 source, destination,
893                                 x2-x1, rects[i].h,
894                                 SDL_FALSE,
895                                 surface->pitch, destpitch
896                         );
897                 }
898         }
899
900         if (GEM_bufops & (B2S_VROCPYFM_1TOS|B2S_VROCPYFM_2TOS)) {
901                 MFDB mfdb_src;
902                 short blitcoords[8];
903
904                 mfdb_src.fd_addr=surface->pixels;
905                 mfdb_src.fd_w=surf_width;
906                 mfdb_src.fd_h=surface->h;
907                 mfdb_src.fd_wdwidth= (surface->pitch/VDI_pixelsize) >> 4;
908                 mfdb_src.fd_nplanes=surface->format->BitsPerPixel;
909                 mfdb_src.fd_stand=
910                         mfdb_src.fd_r1=
911                         mfdb_src.fd_r2=
912                         mfdb_src.fd_r3= 0;
913                 if (GEM_bufops & B2S_VROCPYFM_2TOS) {
914                         mfdb_src.fd_addr=GEM_buffer2;
915                 }
916
917                 for ( i=0; i<numrects; ++i ) {
918                         blitcoords[0] = blitcoords[4] = rects[i].x;
919                         blitcoords[1] = blitcoords[5] = rects[i].y;
920                         blitcoords[2] = blitcoords[6] = rects[i].x + rects[i].w - 1;
921                         blitcoords[3] = blitcoords[7] = rects[i].y + rects[i].h - 1;
922
923                         vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, &VDI_dst_mfdb);
924                 }
925         }
926 }
927
928 static void GEM_UpdateRectsWindowed(_THIS, int numrects, SDL_Rect *rects)
929 {
930         short pxy[4], wind_pxy[4];
931         int i;
932
933         if (wind_get(GEM_handle, WF_WORKXYWH, &wind_pxy[0], &wind_pxy[1], &wind_pxy[2], &wind_pxy[3])==0) {
934                 return;
935         }
936
937         for ( i=0; i<numrects; ++i ) {
938                 pxy[0] = wind_pxy[0] + rects[i].x;
939                 pxy[1] = wind_pxy[1] + rects[i].y;
940                 pxy[2] = rects[i].w;
941                 pxy[3] = rects[i].h;
942
943                 GEM_wind_redraw(this, GEM_handle, pxy);
944         }
945 }
946
947 static void GEM_UpdateRects(_THIS, int numrects, SDL_Rect *rects)
948 {
949         SDL_Surface *surface;
950
951         if (GEM_lock_redraw) {
952                 return;
953         }
954
955         surface = this->screen;
956
957         if (surface->flags & SDL_FULLSCREEN) {
958                 GEM_UpdateRectsFullscreen(this, numrects, rects);
959         } else {
960                 GEM_UpdateRectsWindowed(this, numrects, rects);
961         }
962 }
963
964 static int GEM_FlipHWSurfaceFullscreen(_THIS, SDL_Surface *surface)
965 {
966         int surf_width;
967
968         /* Need to be a multiple of 16 pixels */
969         surf_width=surface->w;
970         if ((surf_width & 15) != 0) {
971                 surf_width = (surf_width | 15) + 1;
972         }
973
974         if (GEM_bufops & (B2S_C2P_1TO2|B2S_C2P_1TOS)) {
975                 void *destscr;
976                 int destpitch;
977
978                 if (GEM_bufops & B2S_C2P_1TOS) {
979                         destscr = VDI_screen;
980                         destpitch = VDI_pitch;
981                 } else {
982                         destscr = GEM_buffer2;
983                         destpitch = surface->pitch;
984                 }
985
986                 SDL_Atari_C2pConvert(
987                         surface->pixels, destscr,
988                         surf_width, surface->h,
989                         SDL_FALSE,
990                         surface->pitch, destpitch
991                 );
992         }
993
994         if (GEM_bufops & (B2S_VROCPYFM_1TOS|B2S_VROCPYFM_2TOS)) {
995                 MFDB mfdb_src;
996                 short blitcoords[8];
997
998                 mfdb_src.fd_w=surf_width;
999                 mfdb_src.fd_h=surface->h;
1000                 mfdb_src.fd_wdwidth=mfdb_src.fd_w >> 4;
1001                 mfdb_src.fd_nplanes=surface->format->BitsPerPixel;
1002                 mfdb_src.fd_stand=
1003                         mfdb_src.fd_r1=
1004                         mfdb_src.fd_r2=
1005                         mfdb_src.fd_r3= 0;
1006                 if (GEM_bufops & B2S_VROCPYFM_1TOS) {
1007                         mfdb_src.fd_addr=surface->pixels;
1008                 } else {
1009                         mfdb_src.fd_addr=GEM_buffer2;
1010                 }
1011
1012                 blitcoords[0] = blitcoords[4] = 0;
1013                 blitcoords[1] = blitcoords[5] = 0;
1014                 blitcoords[2] = blitcoords[6] = surface->w - 1;
1015                 blitcoords[3] = blitcoords[7] = surface->h - 1;
1016
1017                 vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, &VDI_dst_mfdb);
1018         }
1019
1020         return(0);
1021 }
1022
1023 static int GEM_FlipHWSurfaceWindowed(_THIS, SDL_Surface *surface)
1024 {
1025         short   pxy[8];
1026
1027         /* Update the whole window */
1028         wind_get(GEM_handle, WF_WORKXYWH, &pxy[0], &pxy[1], &pxy[2], &pxy[3]);
1029
1030         GEM_wind_redraw(this, GEM_handle, pxy);
1031
1032         return(0);
1033 }
1034
1035 static int GEM_FlipHWSurface(_THIS, SDL_Surface *surface)
1036 {
1037         if (GEM_lock_redraw) {
1038                 return(0);
1039         }
1040
1041         if (surface->flags & SDL_FULLSCREEN) {
1042                 return GEM_FlipHWSurfaceFullscreen(this, surface);
1043         } else {
1044                 return GEM_FlipHWSurfaceWindowed(this, surface);
1045         }
1046 }
1047
1048 static int GEM_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
1049 {
1050         int i;
1051         SDL_Surface *surface;
1052
1053 #ifdef DEBUG_VIDEO_GEM
1054         printf("sdl:video:gem: setcolors()\n");
1055 #endif
1056
1057         /* Do not change palette in True Colour */
1058         surface = this->screen;
1059         if (surface->format->BitsPerPixel > 8) {
1060                 return 1;
1061         }
1062
1063         for(i = 0; i < ncolors; i++)
1064         {
1065                 int             r, g, b;
1066                 short   rgb[3];
1067
1068                 r = colors[i].r;
1069                 g = colors[i].g;
1070                 b = colors[i].b;
1071
1072                 rgb[0] = VDI_curpalette[i][0] = (1000 * r) / 255;
1073                 rgb[1] = VDI_curpalette[i][1] =(1000 * g) / 255;
1074                 rgb[2] = VDI_curpalette[i][2] =(1000 * b) / 255;
1075
1076                 vs_color(VDI_handle, vdi_index[firstcolor+i], rgb);
1077         }
1078
1079         return(1);
1080 }
1081
1082 #if 0
1083 static int GEM_ToggleFullScreen(_THIS, int on)
1084 {
1085         if (on) {
1086                 GEM_LockScreen(this);
1087         } else {
1088                 GEM_UnlockScreen(this);
1089         }
1090
1091         return(1);
1092 }
1093 #endif
1094
1095 /* Note:  If we are terminated, this could be called in the middle of
1096    another SDL video routine -- notably UpdateRects.
1097 */
1098 void GEM_VideoQuit(_THIS)
1099 {
1100         SDL_AtariXbios_RestoreVectors();
1101         if (GEM_usedevmouse) {
1102                 SDL_AtariDevMouse_Close();
1103         }
1104
1105         GEM_FreeBuffers(this);
1106
1107 #if SDL_VIDEO_OPENGL
1108         if (gl_active) {
1109                 SDL_AtariGL_Quit(this, SDL_TRUE);
1110         }
1111 #endif
1112
1113         /* Destroy window */
1114         if (GEM_handle>=0) {
1115                 wind_close(GEM_handle);
1116                 wind_delete(GEM_handle);
1117                 GEM_handle=-1;
1118         }
1119
1120         GEM_UnlockScreen(this);
1121         if (GEM_menubar) {
1122                 Mfree(GEM_menubar);
1123                 GEM_menubar=NULL;
1124         }
1125
1126         appl_exit();
1127
1128         GEM_SetNewPalette(this, VDI_oldpalette);
1129
1130         /* Close VDI workstation */
1131         if (VDI_handle) {
1132                 v_clsvwk(VDI_handle);
1133         }
1134
1135         /* Free mode list */
1136         if (SDL_modelist[0]) {
1137                 SDL_free(SDL_modelist[0]);
1138                 SDL_modelist[0]=NULL;
1139         }
1140
1141         this->screen->pixels = NULL;    
1142 }
1143
1144 void GEM_wind_redraw(_THIS, int winhandle, short *inside)
1145 {
1146         short todo[4];
1147
1148         /* Tell AES we are going to update */
1149         wind_update(BEG_UPDATE);
1150
1151         v_hide_c(VDI_handle);
1152
1153         /* Browse the rectangle list to redraw */
1154         if (wind_get(winhandle, WF_FIRSTXYWH, &todo[0], &todo[1], &todo[2], &todo[3])!=0) {
1155
1156                 while (todo[2] && todo[3]) {
1157
1158                         if (rc_intersect((GRECT *)inside,(GRECT *)todo)) {
1159                                 todo[2] += todo[0]-1;
1160                                 todo[3] += todo[1]-1;
1161                                 refresh_window(this, winhandle, todo);
1162                         }
1163
1164                         if (wind_get(winhandle, WF_NEXTXYWH, &todo[0], &todo[1], &todo[2], &todo[3])==0) {
1165                                 break;
1166                         }
1167                 }
1168
1169         }
1170
1171         /* Update finished */
1172         wind_update(END_UPDATE);
1173
1174         v_show_c(VDI_handle,1);
1175 }
1176
1177 static void refresh_window(_THIS, int winhandle, short *rect)
1178 {
1179         MFDB mfdb_src;
1180         short pxy[8],wind_pxy[8];
1181         SDL_Surface *surface;
1182         int iconified;
1183
1184         /* Is window iconified ? */
1185         iconified = 0;
1186 /*      if (GEM_wfeatures & (1<<WF_ICONIFY))*/ {
1187                 if (wind_get(winhandle, WF_ICONIFY, &wind_pxy[0], &wind_pxy[1], &wind_pxy[2], &wind_pxy[3])!=0) {
1188                         iconified = wind_pxy[0];
1189                 }
1190         }
1191
1192         if (wind_get(winhandle, WF_WORKXYWH, &wind_pxy[0], &wind_pxy[1], &wind_pxy[2], &wind_pxy[3])==0) {
1193                 return;
1194         }
1195
1196         if (iconified && GEM_icon) {
1197                 short icon_rect[4], dst_rect[4];
1198                 short iconx,icony;
1199                 
1200                 surface = GEM_icon;
1201
1202                 GEM_ClearRect(this, rect);
1203
1204                 /* Calculate centered icon(x,y,w,h) relative to window */
1205                 iconx = (wind_pxy[2]-surface->w)>>1;
1206                 icony = (wind_pxy[3]-surface->h)>>1;
1207
1208                 icon_rect[0] = iconx;
1209                 icon_rect[1] = icony;
1210                 icon_rect[2] = surface->w;
1211                 icon_rect[3] = surface->h;
1212
1213                 /* Calculate redraw rectangle(x,y,w,h) relative to window */
1214                 dst_rect[0] = rect[0]-wind_pxy[0];
1215                 dst_rect[1] = rect[1]-wind_pxy[1];
1216                 dst_rect[2] = rect[2]-rect[0]+1;
1217                 dst_rect[3] = rect[3]-rect[1]+1;
1218
1219                 /* Does the icon rectangle must be redrawn ? */
1220                 if (!rc_intersect((GRECT *)icon_rect, (GRECT *)dst_rect)) {
1221                         return;
1222                 }
1223
1224 #if DEBUG_VIDEO_GEM
1225                 printf("sdl:video:gem:  clip(0,0,%d,%d) to (%d,%d,%d,%d)\n",
1226                         surface->w-1,surface->h-1, dst_rect[0],dst_rect[1],dst_rect[2],dst_rect[3]);
1227                 printf("sdl:video:gem:  icon(%d,%d,%d,%d)\n",
1228                         icon_rect[0], icon_rect[1], icon_rect[2], icon_rect[3]);
1229                 printf("sdl:video:gem: refresh_window(): draw icon\n");
1230 #endif
1231
1232                 /* Calculate icon(x1,y1,x2,y2) relative to screen */
1233                 icon_rect[0] += wind_pxy[0];
1234                 icon_rect[1] += wind_pxy[1];
1235                 icon_rect[2] += icon_rect[0]-1;
1236                 icon_rect[3] += icon_rect[1]-1;
1237
1238                 /* Calculate intersection rectangle to redraw */
1239                 pxy[4]=pxy[0]=MAX(icon_rect[0],rect[0]);
1240                 pxy[5]=pxy[1]=MAX(icon_rect[1],rect[1]);
1241                 pxy[6]=pxy[2]=MIN(icon_rect[2],rect[2]);
1242                 pxy[7]=pxy[3]=MIN(icon_rect[3],rect[3]);
1243
1244                 /* Calculate icon source image pos relative to window */
1245                 pxy[0] -= wind_pxy[0]+iconx;
1246                 pxy[1] -= wind_pxy[1]+icony;
1247                 pxy[2] -= wind_pxy[0]+iconx;
1248                 pxy[3] -= wind_pxy[1]+icony;
1249
1250         } else {
1251                 surface = this->screen;
1252
1253 #if DEBUG_VIDEO_GEM
1254                 printf("sdl:video:gem: refresh_window(): draw frame buffer\n");
1255 #endif
1256
1257                 /* Redraw all window content */
1258                 pxy[0] = rect[0]-wind_pxy[0];
1259                 pxy[1] = rect[1]-wind_pxy[1];
1260                 pxy[2] = rect[2]-wind_pxy[0];   
1261                 pxy[3] = rect[3]-wind_pxy[1];  
1262
1263                 pxy[4] = rect[0];
1264                 pxy[5] = rect[1];
1265                 pxy[6] = rect[2];  
1266                 pxy[7] = rect[3];
1267         }
1268
1269         if (GEM_bufops & B2S_C2P_1TO2) {
1270                 void *src, *dest;
1271                 int x1,x2;
1272
1273                 x1 = (rect[0]-wind_pxy[0]) & ~15;
1274                 x2 = rect[2]-wind_pxy[0];
1275                 if (x2 & 15) {
1276                         x2 = (x2 | 15) +1;
1277                 }
1278
1279                 src = surface->pixels;
1280                 src += surface->pitch * (rect[1]-wind_pxy[1]);
1281                 src += x1;
1282
1283                 dest = GEM_buffer2;
1284                 dest += surface->pitch * (rect[1]-wind_pxy[1]);
1285                 dest += x1;
1286
1287                 SDL_Atari_C2pConvert(
1288                         src, dest,
1289                         x2-x1, rect[3]-rect[1]+1,
1290                         SDL_FALSE,
1291                         surface->pitch, surface->pitch
1292                 );
1293         }
1294
1295         mfdb_src.fd_addr=surface->pixels;
1296         {
1297                 int width;
1298
1299                 /* Need to be a multiple of 16 pixels */
1300                 width=surface->w;
1301                 if ((width & 15) != 0) {
1302                         width = (width | 15) + 1;
1303                 }
1304                 mfdb_src.fd_w=width;
1305         }
1306         mfdb_src.fd_h=surface->h;
1307         mfdb_src.fd_nplanes=surface->format->BitsPerPixel;
1308         mfdb_src.fd_wdwidth=mfdb_src.fd_w>>4;
1309         mfdb_src.fd_stand=
1310                 mfdb_src.fd_r1=
1311                 mfdb_src.fd_r2=
1312                 mfdb_src.fd_r3= 0;
1313
1314         if (GEM_bufops & B2S_VROCPYFM_2TOS) {
1315                 mfdb_src.fd_addr=GEM_buffer2;
1316         }
1317
1318 #if DEBUG_VIDEO_GEM
1319         printf("sdl:video:gem: redraw %dx%d: (%d,%d,%d,%d) to (%d,%d,%d,%d)\n",
1320                 surface->w, surface->h,
1321                 pxy[0],pxy[1],pxy[2],pxy[3],
1322                 pxy[4],pxy[5],pxy[6],pxy[7]
1323         );
1324 #endif
1325
1326         vro_cpyfm( VDI_handle, S_ONLY, pxy, &mfdb_src, &VDI_dst_mfdb);
1327 }
1328
1329 #if SDL_VIDEO_OPENGL
1330
1331 static void GEM_GL_SwapBuffers(_THIS)
1332 {
1333         SDL_AtariGL_SwapBuffers(this);
1334         GEM_FlipHWSurface(this, this->screen);
1335 }
1336
1337 #endif