• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
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 	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 
GEM_VideoInit(_THIS,SDL_PixelFormat * vformat)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 
GEM_ListModes(_THIS,SDL_PixelFormat * format,Uint32 flags)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 
GEM_FreeBuffers(_THIS)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 
GEM_ClearRect(_THIS,short * rect)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 
GEM_ClearScreen(_THIS)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 
GEM_SetNewPalette(_THIS,Uint16 newpal[256][3])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 
GEM_LockScreen(_THIS)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 
GEM_UnlockScreen(_THIS)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 
GEM_SetVideoMode(_THIS,SDL_Surface * current,int width,int height,int bpp,Uint32 flags)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 
GEM_AllocHWSurface(_THIS,SDL_Surface * surface)829 static int GEM_AllocHWSurface(_THIS, SDL_Surface *surface)
830 {
831 	return -1;
832 }
833 
GEM_FreeHWSurface(_THIS,SDL_Surface * surface)834 static void GEM_FreeHWSurface(_THIS, SDL_Surface *surface)
835 {
836 	return;
837 }
838 
GEM_LockHWSurface(_THIS,SDL_Surface * surface)839 static int GEM_LockHWSurface(_THIS, SDL_Surface *surface)
840 {
841 	return(0);
842 }
843 
GEM_UnlockHWSurface(_THIS,SDL_Surface * surface)844 static void GEM_UnlockHWSurface(_THIS, SDL_Surface *surface)
845 {
846 	return;
847 }
848 
GEM_UpdateRectsFullscreen(_THIS,int numrects,SDL_Rect * rects)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 
GEM_UpdateRectsWindowed(_THIS,int numrects,SDL_Rect * rects)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 
GEM_UpdateRects(_THIS,int numrects,SDL_Rect * rects)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 
GEM_FlipHWSurfaceFullscreen(_THIS,SDL_Surface * surface)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 
GEM_FlipHWSurfaceWindowed(_THIS,SDL_Surface * surface)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 
GEM_FlipHWSurface(_THIS,SDL_Surface * surface)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 
GEM_SetColors(_THIS,int firstcolor,int ncolors,SDL_Color * colors)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 */
GEM_VideoQuit(_THIS)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 
GEM_wind_redraw(_THIS,int winhandle,short * inside)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 
refresh_window(_THIS,int winhandle,short * rect)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 
GEM_GL_SwapBuffers(_THIS)1331 static void GEM_GL_SwapBuffers(_THIS)
1332 {
1333 	SDL_AtariGL_SwapBuffers(this);
1334 	GEM_FlipHWSurface(this, this->screen);
1335 }
1336 
1337 #endif
1338