*** empty log message ***
authorSam Lantinga <slouken@libsdl.org>
Tue, 26 Mar 2002 17:37:31 +0000
changeset 319 189a6a3416c7
parent 318 0910a3034576
child 320 66f815c147ed
*** empty log message ***
README.MiNT
src/video/gem/SDL_gemevents.c
src/video/gem/SDL_gemmouse.c
src/video/gem/SDL_gemmouse_c.h
src/video/gem/SDL_gemvideo.c
src/video/xbios/SDL_xbios.c
--- a/README.MiNT	Sun Mar 24 21:44:06 2002 +0000
+++ b/README.MiNT	Tue Mar 26 17:37:31 2002 +0000
@@ -45,7 +45,7 @@
 ==============================================================================
 IV.  What is supported:
 
-Keyboard (GEMDOS, BIOS, Ikbd)
+Keyboard (GEMDOS, BIOS, GEM, Ikbd)
 Mouse (XBIOS, GEM, Ikbd)
 Video (XBIOS (Fullscreen), GEM (Windowed and Fullscreen))
 Timer (VBL vector)
@@ -61,7 +61,10 @@
 xbios	ikbd	ikbd	vbl	ikbd	hardware
 xbios	gemdos	xbios	vbl	xbios	hardware
 xbios	bios	xbios	vbl	xbios	hardware
-gem	gem	gem	vbl	xbios	hardware
+gem	gem	gem(*)	vbl	xbios	hardware
+
+(*) GEM does not report relative mouse motion, so xbios mouse driver is used
+to report this type event.
 
 ==============================================================================
 V.  Environment variables:
@@ -108,6 +111,48 @@
 	Lightpen and analog paddle are 2 buttons, 2 axis controllers. The 2
 	buttons are those affected to 1 button joysticks on the same port.
 
+==============================================================================
+VI.  More informations about drivers:
+
+Xbios video:
+	Video chip is detected using the _VDO cookie.
+	Screen enhancers are not supported, but could be if you know how to
+	use them.
+
+	ST, STE, Mega ST, Mega STE:
+		320x200x4 bits, shades of grey, available only for the purpose
+		of testing SDL.
+	TT:
+		320x480x8 and 320x240x8 (software double-lined mode).
+	Falcon:
+		All modes supported by the current monitor (RVB or VGA).
+	Clones and any machine with monochrome monitor:
+		Not supported.
+
+Gem video:
+	Automatically used if xbios not available.
+
+	All machines:
+		Only the current resolution, if 8 bits or higher depth.
+
+IKBD keyboard, mouse and joystick driver:
+	Available if _MCH cookie is ST, Mega ST, STE, Mega STE, TT or Falcon.
+
+	Hades has an IKBD, but xbios is not available for video, so IKBD
+	driver is disabled.
+
+Gemdos and bios keyboard driver:
+	Available on all machines.
+
+Mouse and joystick xbios driver:
+	Available on all machines (I think).
+
+Joypad driver:
+	Available if _MCH cookie is STE or Falcon.
+
+VBL timer driver:
+	Available all machines (I think).
+
 -- 
 Patrice Mandin <pmandin@caramail.com>
 http://membres.lycos.fr/pmandin/
--- a/src/video/gem/SDL_gemevents.c	Sun Mar 24 21:44:06 2002 +0000
+++ b/src/video/gem/SDL_gemevents.c	Tue Mar 26 17:37:31 2002 +0000
@@ -43,7 +43,8 @@
 #include "SDL_events_c.h"
 #include "SDL_gemvideo.h"
 #include "SDL_gemevents_c.h"
-#include "../ataricommon/SDL_atarikeys.h"	/* for keyboard scancodes */
+#include "SDL_atarikeys.h"	/* for keyboard scancodes */
+#include "SDL_xbiosinterrupt_s.h"
 
 /* Defines */
 
@@ -55,8 +56,6 @@
 static unsigned char gem_previouskeyboard[ATARIBIOS_MAXKEYS];
 static unsigned char gem_currentascii[ATARIBIOS_MAXKEYS];
 
-static short prevmousex, prevmousey, prevmouseb;
-
 /* The translation tables from a console scancode to a SDL keysym */
 static SDLKey keymap[ATARIBIOS_MAXKEYS];
 
@@ -65,7 +64,7 @@
 static SDL_keysym *TranslateKey(int scancode, int asciicode, SDL_keysym *keysym);
 static int do_messages(_THIS, short *message);
 static void do_keyboard(short kc, short ks);
-static void do_mouse(_THIS, short mx, short my, short mb);
+static void do_mouse(_THIS, short mx, short my, short mb, short ks);
 
 /* Functions */
 
@@ -124,22 +123,23 @@
 	keymap[SCANCODE_CAPSLOCK] = SDLK_CAPSLOCK;
 
 	/* Mouse init */
-	prevmousex = prevmousey = prevmouseb = 0;
 	GEM_mouse_relative = SDL_FALSE;
 }
 
 void GEM_PumpEvents(_THIS)
 {
-	short mx, my, mb, dummy;
+	short mousex, mousey, mouseb, dummy;
+	short kstate, prevkc, prevks;
 	int i;
 	SDL_keysym	keysym;
 
 	memset(gem_currentkeyboard,0,sizeof(gem_currentkeyboard));
+	prevkc = prevks = 0;
 	
 	for (;;)
 	{
 		int quit, resultat;
-		short buffer[8], kc, ks;
+		short buffer[8], kc;
 
 		quit = 0;
 
@@ -150,7 +150,7 @@
 			0,0,0,0,0,
 			buffer,
 			10,
-			&dummy,&dummy,&dummy,&ks,&kc,&dummy
+			&dummy,&dummy,&dummy,&kstate,&kc,&dummy
 		);
 
 		/* Message event ? */
@@ -158,10 +158,14 @@
 			quit = do_messages(this, buffer);
 
 		/* Keyboard event ? */
-		if (resultat & MU_KEYBD)
-			do_keyboard(kc,ks);
-		else
-			do_keyboard(0,0);
+		if (resultat & MU_KEYBD) {
+			if ((prevkc != kc) || (prevks != kstate)) {
+				do_keyboard(kc,kstate);
+			} else {
+				/* Avoid looping, if repeating same key */
+				break;
+			}
+		}
 
 		/* Timer event ? */
 		if ((resultat & MU_TIMER) || quit)
@@ -169,10 +173,10 @@
 	}
 
 	/* Update mouse */
-	graf_mkstate(&mx, &my, &mb, &dummy);
-	do_mouse(this, mx, my, mb);
+	graf_mkstate(&mousex, &mousey, &mouseb, &kstate);
+	do_mouse(this, mousex, mousey, mouseb, kstate);
 
-	/* Now generates keyboard events */
+	/* Now generate keyboard events */
 	for (i=0; i<ATARIBIOS_MAXKEYS; i++) {
 		/* Key pressed ? */
 		if (gem_currentkeyboard[i] && !gem_previouskeyboard[i])
@@ -259,7 +263,6 @@
 static void do_keyboard(short kc, short ks)
 {
 	int			scancode, asciicode;
-	short		dummy;
 
 	if (kc) {
 		scancode=(kc>>8) & 127;
@@ -269,9 +272,6 @@
 		gem_currentascii[scancode]=asciicode;
 	}
 
-	if (!ks)
-		graf_mkstate(&dummy, &dummy, &dummy, &ks);
-
 	/* Read special keys */
 	if (ks & K_RSHIFT)
 		gem_currentkeyboard[SCANCODE_RIGHTSHIFT]=0xFF;
@@ -283,16 +283,15 @@
 		gem_currentkeyboard[SCANCODE_LEFTALT]=0xFF;
 }
 
-static void do_mouse(_THIS, short mx, short my, short mb)
+static void do_mouse(_THIS, short mx, short my, short mb, short ks)
 {
+	static short prevmousex=0, prevmousey=0, prevmouseb=0;
+
 	/* Mouse motion ? */
 	if ((prevmousex!=mx) || (prevmousey!=my)) {
 		if (GEM_mouse_relative) {
-			short wind_pxy[8];
-
-			wind_get(GEM_handle, WF_WORKXYWH, &wind_pxy[0], &wind_pxy[1], &wind_pxy[2], &wind_pxy[3]);
-
-			SDL_PrivateMouseMotion(0, 1, mx-wind_pxy[0], my-wind_pxy[1]);
+			SDL_PrivateMouseMotion(0, 1, SDL_AtariXbios_mousex, SDL_AtariXbios_mousey);
+			SDL_AtariXbios_mousex = SDL_AtariXbios_mousey = 0;
 		} else {
 			SDL_PrivateMouseMotion(0, 1, mx, my);
 		}
@@ -304,19 +303,29 @@
 	if (prevmouseb!=mb) {
 		int i;
 
-		for (i=0;i<3;i++) {
+		for (i=0;i<2;i++) {
 			int curbutton, prevbutton;
 		
 			curbutton = mb & (1<<i);
 			prevbutton = prevmouseb & (1<<i);
 		
-			if (curbutton & !prevbutton) {
-				SDL_PrivateMouseButton(SDL_PRESSED, i, 0, 0);
+			if (curbutton && !prevbutton) {
+				SDL_PrivateMouseButton(SDL_PRESSED, i+1, 0, 0);
 			}
-			if (!curbutton & prevbutton) {
-				SDL_PrivateMouseButton(SDL_RELEASED, i, 0, 0);
+			if (!curbutton && prevbutton) {
+				SDL_PrivateMouseButton(SDL_RELEASED, i+1, 0, 0);
 			}
 		}
 		prevmouseb = mb;
 	}
+
+	/* Read special keys */
+	if (ks & K_RSHIFT)
+		gem_currentkeyboard[SCANCODE_RIGHTSHIFT]=0xFF;
+	if (ks & K_LSHIFT)
+		gem_currentkeyboard[SCANCODE_LEFTSHIFT]=0xFF;
+	if (ks & K_CTRL)
+		gem_currentkeyboard[SCANCODE_LEFTCONTROL]=0xFF;
+	if (ks & K_ALT)
+		gem_currentkeyboard[SCANCODE_LEFTALT]=0xFF;
 }
--- a/src/video/gem/SDL_gemmouse.c	Sun Mar 24 21:44:06 2002 +0000
+++ b/src/video/gem/SDL_gemmouse.c	Tue Mar 26 17:37:31 2002 +0000
@@ -136,21 +136,26 @@
 	return 1;
 }
 
+#if 0
 void GEM_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
 {
+	/* This seems to work only on AES 3.4 (Falcon) */
+
 	EVNTREC	warpevent;
 	
 	warpevent.ap_event = APPEVNT_MOUSE; 
-	warpevent.ap_value = (y << 16) | x;
+	warpevent.ap_value = (x << 16) | y;
 
 	appl_tplay(&warpevent, 1, 1000);
 }
+#endif
 
 void GEM_CheckMouseMode(_THIS)
 {
 	/* If the mouse is hidden and input is grabbed, we use relative mode */
 	if ( !(SDL_cursorstate & CURSOR_VISIBLE) &&
-		(this->input_grab != SDL_GRAB_OFF) ) {
+		(this->input_grab != SDL_GRAB_OFF) &&
+             (SDL_GetAppState() & SDL_APPACTIVE) ) {
 		GEM_mouse_relative = SDL_TRUE;
 	} else {
 		GEM_mouse_relative = SDL_FALSE;
--- a/src/video/gem/SDL_gemmouse_c.h	Sun Mar 24 21:44:06 2002 +0000
+++ b/src/video/gem/SDL_gemmouse_c.h	Tue Mar 26 17:37:31 2002 +0000
@@ -32,6 +32,7 @@
 extern WMcursor *GEM_CreateWMCursor(_THIS,
 		Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);
 extern int GEM_ShowWMCursor(_THIS, WMcursor *cursor);
+#if 0
 extern void GEM_WarpWMCursor(_THIS, Uint16 x, Uint16 y);
-extern void GEM_CheckMouseModeNoLock(_THIS);
+#endif
 extern void GEM_CheckMouseMode(_THIS);
--- a/src/video/gem/SDL_gemvideo.c	Sun Mar 24 21:44:06 2002 +0000
+++ b/src/video/gem/SDL_gemvideo.c	Tue Mar 26 17:37:31 2002 +0000
@@ -51,6 +51,7 @@
 #include "SDL_sysvideo.h"
 #include "SDL_pixels_c.h"
 #include "SDL_events_c.h"
+#include "SDL_cursor_c.h"
 
 #include "SDL_ataric2p_s.h"
 #include "SDL_ataric2p060_c.h"
@@ -95,6 +96,9 @@
 
 /* Internal functions */
 static void GEM_FreeBuffers(_THIS);
+static void GEM_ClearScreen(_THIS);
+static void GEM_LockScreen(_THIS);
+static void GEM_UnlockScreen(_THIS);
 static void refresh_window(_THIS, int winhandle, short *rect);
 
 /* GEM driver bootstrap functions */
@@ -174,11 +178,11 @@
 	device->FreeWMCursor = GEM_FreeWMCursor;
 	device->CreateWMCursor = GEM_CreateWMCursor;
 	device->ShowWMCursor = GEM_ShowWMCursor;
-	device->WarpWMCursor = GEM_WarpWMCursor;
+	device->WarpWMCursor = NULL /*GEM_WarpWMCursor*/;
 	device->CheckMouseMode = GEM_CheckMouseMode;
 
-	/* Joystick */
-	SDL_AtariXbios_InstallVectors(ATARI_XBIOS_JOYSTICKEVENTS);
+	/* Joystick + Mouse relative motion */
+	SDL_AtariXbios_InstallVectors(ATARI_XBIOS_MOUSEEVENTS|ATARI_XBIOS_JOYSTICKEVENTS);
 
 	device->free = GEM_DeleteDevice;
 
@@ -314,7 +318,7 @@
 				tmp_p = (Uint16 *)&work_out[16];
 
 				for (i=0;i<256;i++) {
-					vdi_index[i] = *tmp_p++;
+					vdi_index[*tmp_p++] = i;
 				}
 			}
 			break;
@@ -352,11 +356,11 @@
 						}
 					}
 				}
+			}
 
-				/* Remove lower green bits for Intel endian screen */
-				if ((VDI_greenmask == ((7<<13)|3)) || (VDI_greenmask == ((7<<13)|7))) {
-					VDI_greenmask &= ~(7<<13);
-				}
+			/* Remove lower green bits for Intel endian screen */
+			if ((VDI_greenmask == ((7<<13)|3)) || (VDI_greenmask == ((7<<13)|7))) {
+				VDI_greenmask &= ~(7<<13);
 			}
 			break;
 		case VDI_CLUT_NONE:
@@ -474,7 +478,7 @@
 	VDI_screen = NULL;
 	VDI_ReadExtInfo(this, work_out);
 	if (VDI_screen == NULL) {
-		VDI_pitch = VDI_w * ((VDI_bpp)>>3);
+		VDI_pitch = VDI_w * VDI_pixelsize;
 		VDI_format = VDI_FORMAT_UNKNOWN;
 		VDI_redmask = VDI_greenmask = VDI_bluemask = VDI_alphamask = 0;
 	}
@@ -539,6 +543,56 @@
 	}
 }
 
+static void GEM_ClearScreen(_THIS)
+{
+	short rgb[3]={0,0,0};
+	short oldrgb[3];
+	short pxy[4];
+
+	v_hide_c(VDI_handle);
+
+	vq_color(VDI_handle, vdi_index[0], 0, oldrgb);
+	vs_color(VDI_handle, vdi_index[0], rgb);
+
+	pxy[0] = pxy[1] = 0;
+	pxy[2] = VDI_w - 1;
+	pxy[3] = VDI_h - 1;
+	vsf_color(VDI_handle,0);
+	vsf_interior(VDI_handle,1);
+	vsf_perimeter(VDI_handle,0);
+	v_bar(VDI_handle,pxy);
+
+	vs_color(VDI_handle, vdi_index[0], oldrgb);
+
+	v_show_c(VDI_handle, 1);
+}
+
+static void GEM_LockScreen(_THIS)
+{
+	if (!GEM_locked) {
+		/* Reserve memory space, used to be sure of compatibility */
+		form_dial( FMD_START, 0,0,0,0, 0,0,VDI_w,VDI_h);
+		/* Lock AES */
+		wind_update(BEG_UPDATE);
+		wind_update(BEG_MCTRL);
+
+		GEM_locked=SDL_TRUE;
+	}
+}
+
+static void GEM_UnlockScreen(_THIS)
+{
+	if (GEM_locked) {
+		/* Restore screen memory, and send REDRAW to all apps */
+		form_dial( FMD_FINISH, 0,0,0,0, 0,0,VDI_w,VDI_h);
+		/* Unlock AES */
+		wind_update(END_MCTRL);
+		wind_update(END_UPDATE);
+
+		GEM_locked=SDL_FALSE;
+	}
+}
+
 SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface *current,
 				int width, int height, int bpp, Uint32 flags)
 {
@@ -574,11 +628,22 @@
 	use_shadow=SDL_FALSE;
 	if (flags & SDL_FULLSCREEN) {
 		if (!VDI_screen) {
+			/* No access to real framebuffer, use shadow surface */
 			use_shadow=SDL_TRUE;
-		} else if (VDI_format==VDI_FORMAT_INTER) {
-			use_shadow=SDL_TRUE;
+		} else {
+			if (VDI_format==VDI_FORMAT_INTER) {
+				/* Real framebuffer, interleaved bitplanes,
+				  use shadow surface */
+				use_shadow=SDL_TRUE;
+			} else if (flags & SDL_DOUBLEBUF) {
+				/* Real framebuffer, double-buffered,
+				  use shadow surface */
+				use_shadow=SDL_TRUE;
+				modeflags |= SDL_DOUBLEBUF;
+			}
 		}
 	} else {
+		/* Windowed mode, always with shadow surface */
 		use_shadow=SDL_TRUE;
 	}
 
@@ -595,30 +660,12 @@
 
 	/*--- Initialize screen ---*/
 	if (flags & SDL_FULLSCREEN) {
-		short rgb[3]={0,0,0};
-		short pxy[4];
-
-		if (!GEM_locked) {
-			/* Reserve memory space, used to be sure of compatibility */
-			form_dial( FMD_START, 0,0,0,0, 0,0,VDI_w,VDI_h);
-			/* Lock AES */
-			while (!wind_update(BEG_UPDATE|BEG_MCTRL));
+		GEM_LockScreen(this);
 
-			GEM_locked=SDL_TRUE;
-		}
-
-		/* Clear screen */
-		pxy[0] = pxy[1] = 0;
-		pxy[2] = VDI_w - 1;
-		pxy[3] = VDI_h - 1;
-		vs_color(VDI_handle, vdi_index[0], rgb);
-		vsf_color(VDI_handle,0);
-		vsf_interior(VDI_handle,1);
-		vsf_perimeter(VDI_handle,0);
-		v_bar(VDI_handle,pxy);
+		GEM_ClearScreen(this);
 
 		modeflags |= SDL_FULLSCREEN;
-		if (VDI_screen && (VDI_format==VDI_FORMAT_PACK)) {
+		if (VDI_screen && (VDI_format==VDI_FORMAT_PACK) && !use_shadow) {
 			modeflags |= SDL_HWSURFACE;
 		} else {
 			modeflags |= SDL_SWSURFACE;
@@ -627,13 +674,7 @@
 		int posx,posy;
 		short x2,y2,w2,h2;
 
-		if (GEM_locked) {
-			/* Restore screen memory, and send REDRAW to all apps */
-			form_dial( FMD_FINISH, 0,0,0,0, 0,0,VDI_w,VDI_h);
-			/* Unlock AES */
-			wind_update(END_UPDATE|END_MCTRL);
-			GEM_locked=SDL_FALSE;
-		}
+		GEM_UnlockScreen(this);
 
 		/* Center our window */
 		posx = GEM_desk_x;
@@ -722,6 +763,9 @@
 static void GEM_UpdateRectsFullscreen(_THIS, int numrects, SDL_Rect *rects)
 {
 	SDL_Surface *surface;
+	MFDB mfdb_src;
+	short blitcoords[8];
+	int i;
 
 	surface = this->screen;
 
@@ -734,47 +778,69 @@
 			destscr += VDI_pitch * ((VDI_h - surface->h) >> 1);
 			destx = (VDI_w - surface->w) >> 1;
 			destx &= ~15;
-			destscr += VDI_pixelsize * destx;
+			destscr += destx;
+
+			for (i=0;i<numrects;i++) {
+				void *source,*destination;
+				int x1,x2;
+
+				x1 = rects[i].x & ~15;
+				x2 = rects[i].x+rects[i].w;
+				if (x2 & 15) {
+					x2 = (x2 | 15) +1;
+				}
 
-			/* Convert chunky to planar screen */
-			Atari_C2pConvert(
-				surface->pixels,
-				destscr,
-				surface->w,
-				surface->h,
-				SDL_FALSE,
-				surface->pitch,
-				VDI_pitch
-			);
-		}
-	} else {
-		MFDB mfdb_src;
-		short blitcoords[8];
-		int i;
+				source = surface->pixels;
+				source += surface->pitch * rects[i].y;
+				source += x1;
+
+				destination = destscr;
+				destination += VDI_pitch * rects[i].y;
+				destination += x1;
+
+				/* Convert chunky to planar screen */
+				Atari_C2pConvert(
+					source,
+					destination,
+					x2-x1,
+					rects[i].h,
+					SDL_FALSE,
+					surface->pitch,
+					VDI_pitch
+				);
 
-		mfdb_src.fd_addr=surface->pixels;
-		mfdb_src.fd_w=surface->w;
-		mfdb_src.fd_h=surface->h;
-		mfdb_src.fd_wdwidth=(surface->w) >> 4;
-		mfdb_src.fd_stand=0;
-	  	mfdb_src.fd_nplanes=surface->format->BitsPerPixel;
-		mfdb_src.fd_r1=0;
-		mfdb_src.fd_r2=0;
-		mfdb_src.fd_r3=0;
+			}
+
+			return;
+		}
+
+		if (!(surface->flags & SDL_DOUBLEBUF)) {
+			return;
+		}
+	}
 
-		for ( i=0; i<numrects; ++i ) {
-			blitcoords[0] = rects[i].x;
-			blitcoords[1] = rects[i].y;
-			blitcoords[2] = blitcoords[0] + rects[i].w - 1;
-			blitcoords[3] = blitcoords[1] + rects[i].h - 1;
+	mfdb_src.fd_addr=surface->pixels;
+	mfdb_src.fd_w=surface->w;
+	mfdb_src.fd_h=surface->h;
+	mfdb_src.fd_wdwidth=(surface->w) >> 4;
+	mfdb_src.fd_stand=0;
+	mfdb_src.fd_nplanes=surface->format->BitsPerPixel;
+	mfdb_src.fd_r1=0;
+	mfdb_src.fd_r2=0;
+	mfdb_src.fd_r3=0;
 
-			blitcoords[4] = rects[i].x + ((VDI_w - surface->w) >> 1);
-			blitcoords[5] = rects[i].y + ((VDI_h - surface->h) >> 1);
-			blitcoords[6] = blitcoords[4] + rects[i].w - 1;
-			blitcoords[7] = blitcoords[5] + rects[i].h - 1;
+	for ( i=0; i<numrects; ++i ) {
+		blitcoords[0] = rects[i].x;
+		blitcoords[1] = rects[i].y;
+		blitcoords[2] = blitcoords[0] + rects[i].w - 1;
+		blitcoords[3] = blitcoords[1] + rects[i].h - 1;
 
-			vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, &VDI_dst_mfdb);
-		}
+		blitcoords[4] = rects[i].x + ((VDI_w - surface->w) >> 1);
+		blitcoords[5] = rects[i].y + ((VDI_h - surface->h) >> 1);
+		blitcoords[6] = blitcoords[4] + rects[i].w - 1;
+		blitcoords[7] = blitcoords[5] + rects[i].h - 1;
+
+		vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, &VDI_dst_mfdb);
 	}
 }
 
@@ -810,6 +876,9 @@
 
 static int GEM_FlipHWSurfaceFullscreen(_THIS, SDL_Surface *surface)
 {
+	MFDB mfdb_src;
+	short blitcoords[8];
+
 	if (VDI_screen) {
 		if (VDI_format==VDI_FORMAT_INTER) {
 			void *destscr;
@@ -820,7 +889,7 @@
 			destscr += VDI_pitch * ((VDI_h - surface->h) >> 1);
 			destx = (VDI_w - surface->w) >> 1;
 			destx &= ~15;
-			destscr += VDI_pixelsize * destx;
+			destscr += destx;
 
 			/* Convert chunky to planar screen */
 			Atari_C2pConvert(
@@ -832,32 +901,35 @@
 				surface->pitch,
 				VDI_pitch
 			);
+
+			return(0);
 		}
-	} else {
-		MFDB mfdb_src;
-		short blitcoords[8];
 
-		mfdb_src.fd_addr=surface->pixels;
-		mfdb_src.fd_w=surface->w;
-		mfdb_src.fd_h=surface->h;
-		mfdb_src.fd_wdwidth=(surface->w) >> 4;
-		mfdb_src.fd_stand=0;
-	  	mfdb_src.fd_nplanes=surface->format->BitsPerPixel;
-		mfdb_src.fd_r1=0;
-		mfdb_src.fd_r2=0;
-		mfdb_src.fd_r3=0;
+		if (!(surface->flags & SDL_DOUBLEBUF)) {
+			return(0);
+		}
+	}
+	
+	mfdb_src.fd_addr=surface->pixels;
+	mfdb_src.fd_w=surface->w;
+	mfdb_src.fd_h=surface->h;
+	mfdb_src.fd_wdwidth=(surface->w) >> 4;
+	mfdb_src.fd_stand=0;
+	mfdb_src.fd_nplanes=surface->format->BitsPerPixel;
+	mfdb_src.fd_r1=0;
+	mfdb_src.fd_r2=0;
+	mfdb_src.fd_r3=0;
 
-		blitcoords[0] = 0;
-		blitcoords[1] = 0;
-		blitcoords[2] = surface->w - 1;
-		blitcoords[3] = surface->h - 1;
-		blitcoords[4] = (VDI_w - surface->w) >> 1;
-		blitcoords[5] = (VDI_h - surface->h) >> 1;
-		blitcoords[6] = blitcoords[4] + surface->w - 1;
-		blitcoords[7] = blitcoords[5] + surface->h - 1;
+	blitcoords[0] = 0;
+	blitcoords[1] = 0;
+	blitcoords[2] = surface->w - 1;
+	blitcoords[3] = surface->h - 1;
+	blitcoords[4] = (VDI_w - surface->w) >> 1;
+	blitcoords[5] = (VDI_h - surface->h) >> 1;
+	blitcoords[6] = blitcoords[4] + surface->w - 1;
+	blitcoords[7] = blitcoords[5] + surface->h - 1;
 
-		vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, &VDI_dst_mfdb);
-	}
+	vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, &VDI_dst_mfdb);
 
 	return(0);
 }
@@ -894,7 +966,6 @@
 		return 1;
 	}
 
-
 	for(i = 0; i < ncolors; i++)
 	{
 		int		r, g, b;
@@ -918,18 +989,9 @@
 static int GEM_ToggleFullScreen(_THIS, int on)
 {
 	if (on) {
-		if (!GEM_locked) {
-			/* Lock AES */
-			while (!wind_update(BEG_UPDATE|BEG_MCTRL));
-			GEM_locked=SDL_TRUE;
-		}
+		GEM_LockScreen(this);
 	} else {
-		if (GEM_locked) {
-			/* Unlock AES */
-			wind_update(END_UPDATE|END_MCTRL);
-			GEM_locked=SDL_FALSE;
-		}
-		/* Redraw all screen */
+		GEM_UnlockScreen(this);
 	}
 
 	return(1);
@@ -945,15 +1007,8 @@
 
 	GEM_FreeBuffers(this);
 
-	if (GEM_locked) {
-		/* Restore screen memory, and send REDRAW to all apps */
-		form_dial( FMD_FINISH, 0,0,0,0, 0,0,VDI_w,VDI_h);
-		/* Unlock AES */
-		wind_update(END_UPDATE|END_MCTRL);
-		GEM_locked=SDL_FALSE;
-	}
+	GEM_UnlockScreen(this);
 
-	/* Close AES application */
 	appl_exit();
 
 	/* Restore palette */
@@ -990,7 +1045,7 @@
 	short todo[4];
 
 	/* Tell AES we are going to update */
-	while (!wind_update(BEG_UPDATE));
+	wind_update(BEG_UPDATE);
 
 	v_hide_c(VDI_handle);
 
--- a/src/video/xbios/SDL_xbios.c	Sun Mar 24 21:44:06 2002 +0000
+++ b/src/video/xbios/SDL_xbios.c	Tue Mar 26 17:37:31 2002 +0000
@@ -639,7 +639,10 @@
 			int x1,x2;
 
 			x1 = rects[i].x & ~15;
-			x2 = ((rects[i].x+rects[i].w) | 15) +1;
+			x2 = rects[i].x+rects[i].w;
+			if (x2 & 15) {
+				x2 = (x2 | 15) +1;
+			}
 
 			source = surface->pixels;
 			source += surface->pitch * rects[i].y;