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