Updated the Amiga OS port of SDL (thanks Gabriele)
authorSam Lantinga <slouken@lokigames.com>
Thu, 10 May 2001 20:13:29 +0000
changeset 21 75a95f82bc1f
parent 20 3dc008dc229d
child 22 48c34d68918e
Updated the Amiga OS port of SDL (thanks Gabriele)
BUGS
README.AmigaOS
configure.in
src/audio/SDL_audio.c
src/audio/SDL_sysaudio.h
src/audio/amigaos/Makefile.am
src/audio/amigaos/SDL_ahiaudio.c
src/audio/amigaos/SDL_ahiaudio.h
src/audio/amigaos/SDL_audio.c
src/audio/amigaos/SDL_lowaudio.h
src/audio/amigaos/SDL_sysaudio.h
src/joystick/amigaos/Makefile.am
src/joystick/amigaos/SDL_sysjoystick.c
src/thread/amigaos/SDL_syssem.c
src/thread/amigaos/SDL_systhread.c
src/thread/amigaos/SDL_thread.c
src/timer/amigaos/SDL_systimer.c
src/video/cybergfx/SDL_amigaevents.c
src/video/cybergfx/SDL_cgxaccel.c
src/video/cybergfx/SDL_cgximage.c
src/video/cybergfx/SDL_cgxmodes.c
src/video/cybergfx/SDL_cgxmodes_c.h
src/video/cybergfx/SDL_cgxvideo.c
src/video/cybergfx/SDL_cgxvideo.h
src/video/cybergfx/SDL_cgxyuv.c
src/video/cybergfx/SDL_cgxyuv_c.h
src/video/default_cursor.h
--- a/BUGS	Thu May 10 20:10:54 2001 +0000
+++ b/BUGS	Thu May 10 20:13:29 2001 +0000
@@ -169,9 +169,6 @@
  
 	The software surfaces could use some speed up.
  
-	Many of the test apps segment violate on exit, and I'm not sure
-	they're all working either
- 
 	It doesn't look like the OpenGL stuff is there. (did a grep for
 	PdCreateOpenGLContext, nothing found).
  
@@ -187,13 +184,4 @@
 
 	Continuous relative mouse motion is not implemented.
 
-	Audio can work, but isn't completely integrated in the CVS
-	version of SDL.
-
-	The joystick subsystem isn't implemented yet.
-
-	There's some confusion about the multi-threaded synchronization
-	primitives on AmigaOS, so mutexes and semaphores aren't correctly
-	implemented yet.
-
 	The AmigaOS port was done by Gabriele.Greco@galactica.it
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.AmigaOS	Thu May 10 20:13:29 2001 +0000
@@ -0,0 +1,50 @@
+This is the porting of 1.2.0 version of SDL (the latest stable one)
+to AmigaOS/68k.
+
+All the bugs known of the past version have been corrected. And I've
+added all the new SDL features.
+
+This version of SDL needs Cybergraphx V3 (r69+) or CyberGraphX V4
+and AHI v3+. Probably it works also with P96 or CGXAga, but it's 
+untested.
+
+This version is available as linked library for SAS/C and GCC, only 68k this 
+time, a powerup (ppcemu compatible) and a morphos version will be ready quite 
+soon (i hope).
+
+Implemented:
+
+- 8/16/24/32bit video modes, both fullscreen and windowed.
+- Hardware surfaces.
+- CGX blitting acceleration.
+- CGX colorkey blitting acceleration.
+- AHI audio (8/16 bit, with any audio format), always uses unit 0 for now.
+- Thread support (maybe not 100% compatible with other implementations)
+- Semaphores 
+- Window resizing and backdrop windows (NEW)
+- Joystick/Joypad support.
+
+To do:
+
+- CDRom audio playing support
+- OpenGL (A guy was working on it but I've lost his tracks :( )
+
+The SAS/C library is distributed with debug info attached, to strip debug info 
+simply add STRIPDEBUG argument to the linker.
+
+NOTE: SDL includes debug output using kprintf, to disable it add to your 
+project a function like this:
+
+void kprintf(char *a,...)
+{
+}
+
+Otherwise you can redirect the debug to a console window with sushi, sashimi or
+similar tools (the default output is the internal serial port). 
+
+For info, support, bugfix and other feel free to mail me:
+
+Gabriele Greco (gabriele.greco@aruba.it)
+
+You can find also a small SDL Amiga page at:
+http://ggreco.interfree.it/sdl.html
--- a/configure.in	Thu May 10 20:10:54 2001 +0000
+++ b/configure.in	Thu May 10 20:13:29 2001 +0000
@@ -1936,6 +1936,7 @@
 src/video/dummy/Makefile
 src/events/Makefile
 src/joystick/Makefile
+src/joystick/amigaos/Makefile
 src/joystick/beos/Makefile
 src/joystick/dummy/Makefile
 src/joystick/linux/Makefile
--- a/src/audio/SDL_audio.c	Thu May 10 20:10:54 2001 +0000
+++ b/src/audio/SDL_audio.c	Thu May 10 20:13:29 2001 +0000
@@ -76,6 +76,10 @@
 #ifdef _AIX
 	&Paud_bootstrap,
 #endif
+#ifdef ENABLE_AHI
+	&AHI_bootstrap,
+#endif
+
 	NULL
 };
 SDL_AudioDevice *current_audio = NULL;
@@ -84,6 +88,9 @@
 int SDL_AudioInit(const char *driver_name);
 void SDL_AudioQuit(void);
 
+#ifdef ENABLE_AHI
+static int audio_configured = 0;
+#endif
 
 /* The general mixing thread function */
 int SDL_RunAudio(void *audiop)
@@ -94,6 +101,21 @@
 	void  *udata;
 	void (*fill)(void *userdata,Uint8 *stream, int len);
 	int    silence;
+#ifdef ENABLE_AHI
+	int started = 0;
+
+/* AmigaOS NEEDS that the audio driver is opened in the thread that uses it! */
+
+	D(bug("Task audio started audio struct:<%lx>...\n",audiop));
+
+	D(bug("Before Openaudio..."));
+	if(audio->OpenAudio(audio, &audio->spec)==-1)
+	{
+		D(bug("Open audio failed...\n"));
+		return(-1);
+	}
+	D(bug("OpenAudio...OK\n"));
+#endif
 
 	/* Perform any thread setup */
 	if ( audio->ThreadInit ) {
@@ -104,6 +126,15 @@
 	/* Set up the mixing function */
 	fill  = audio->spec.callback;
 	udata = audio->spec.userdata;
+
+#ifdef ENABLE_AHI
+	audio_configured = 1;
+
+	D(bug("Audio configured... Checking for conversion\n"));
+	SDL_mutexP(audio->mixer_lock);
+	D(bug("Semaphore obtained...\n"));
+#endif
+
 	if ( audio->convert.needed ) {
 		if ( audio->convert.src_format == AUDIO_U8 ) {
 			silence = 0x80;
@@ -117,6 +148,12 @@
 	}
 	stream = audio->fake_stream;
 
+#ifdef ENABLE_AHI
+	SDL_mutexV(audio->mixer_lock);
+	D(bug("Entering audio loop...\n"));
+#endif
+
+
 	/* Loop, filling the audio buffers */
 	while ( audio->enabled ) {
 
@@ -124,12 +161,14 @@
 		if ( stream == audio->fake_stream ) {
 			SDL_Delay((audio->spec.samples*1000)/audio->spec.freq);
 		} else {
+#ifdef ENABLE_AHI
+			if ( started > 1 )
+#endif
 			audio->WaitAudio(audio);
 		}
 
 		/* Fill the current buffer with sound */
 		if ( audio->convert.needed ) {
-			/* The buffer may not be allocated yet */
 			if ( audio->convert.buf ) {
 				stream = audio->convert.buf;
 			} else {
@@ -163,12 +202,25 @@
 		/* Ready current buffer for play and change current buffer */
 		if ( stream != audio->fake_stream ) {
 			audio->PlayAudio(audio);
+#ifdef ENABLE_AHI
+/* AmigaOS don't have to wait the first time audio is played! */
+			started++;
+#endif
 		}
 	}
 	/* Wait for the audio to drain.. */
 	if ( audio->WaitDone ) {
 		audio->WaitDone(audio);
 	}
+
+#ifdef ENABLE_AHI
+	D(bug("WaitAudio...Done\n"));
+
+	audio->CloseAudio(audio);
+
+	D(bug("CloseAudio..Done, subtask exiting...\n"));
+	audio_configured = 0;
+#endif
 	return(0);
 }
 
@@ -312,11 +364,33 @@
 	audio->convert.needed = 0;
 	audio->enabled = 1;
 	audio->paused  = 1;
+
+#ifndef ENABLE_AHI
+
+/* AmigaOS opens audio inside the main loop */
 	audio->opened = audio->OpenAudio(audio, &audio->spec)+1;
+
 	if ( ! audio->opened ) {
 		SDL_CloseAudio();
 		return(-1);
 	}
+#else
+	D(bug("Locking semaphore..."));
+	SDL_mutexP(audio->mixer_lock);
+
+	audio->thread = SDL_CreateThread(SDL_RunAudio, audio);
+	D(bug("Created thread...\n"));
+
+	if ( audio->thread == NULL ) {
+		SDL_mutexV(audio->mixer_lock);
+		SDL_CloseAudio();
+		SDL_SetError("Couldn't create audio thread");
+		return(-1);
+	}
+
+	while(!audio_configured)
+		SDL_Delay(100);
+#endif
 
 	/* If the audio driver changes the buffer size, accept it */
 	if ( audio->spec.samples != desired->samples ) {
@@ -365,6 +439,7 @@
 		}
 	}
 
+#ifndef ENABLE_AHI
 	/* Start the audio thread if necessary */
 	switch (audio->opened) {
 		case  1:
@@ -381,6 +456,12 @@
 			/* The audio is now playing */
 			break;
 	}
+#else
+	SDL_mutexV(audio->mixer_lock);
+	D(bug("SDL_OpenAudio USCITA...\n"));
+
+#endif
+
 	return(0);
 }
 
@@ -457,12 +538,14 @@
 		}
 		if ( audio->convert.needed ) {
 			SDL_FreeAudioMem(audio->convert.buf);
+
 		}
+#ifndef ENABLE_AHI
 		if ( audio->opened ) {
 			audio->CloseAudio(audio);
 			audio->opened = 0;
 		}
-
+#endif
 		/* Free the driver data */
 		audio->free(audio);
 		current_audio = NULL;
--- a/src/audio/SDL_sysaudio.h	Thu May 10 20:10:54 2001 +0000
+++ b/src/audio/SDL_sysaudio.h	Thu May 10 20:13:29 2001 +0000
@@ -126,14 +126,17 @@
 #ifdef ENABLE_WINDIB
 extern AudioBootStrap WAVEOUT_bootstrap;
 #endif
+#ifdef _AIX
+extern AudioBootStrap Paud_bootstrap;
+#endif
 #ifdef __BEOS__
 extern AudioBootStrap BAUDIO_bootstrap;
 #endif
 #if defined(macintosh) || TARGET_API_MAC_CARBON
 extern AudioBootStrap SNDMGR_bootstrap;
 #endif
-#ifdef _AIX
-extern AudioBootStrap Paud_bootstrap;
+#ifdef ENABLE_AHI
+extern AudioBootStrap AHI_bootstrap;
 #endif
 
 /* This is the current audio device */
--- a/src/audio/amigaos/Makefile.am	Thu May 10 20:10:54 2001 +0000
+++ b/src/audio/amigaos/Makefile.am	Thu May 10 20:13:29 2001 +0000
@@ -3,6 +3,6 @@
 
 noinst_LTLIBRARIES = libaudio_arch.la
 
-ARCH_SRCS = SDL_ahiaudio.c SDL_audio.c SDL_lowaudio.h SDL_sysaudio.h
+ARCH_SRCS = SDL_ahiaudio.c SDL_ahiaudio.h
 
 libaudio_arch_la_SOURCES = $(ARCH_SRCS)
--- a/src/audio/amigaos/SDL_ahiaudio.c	Thu May 10 20:10:54 2001 +0000
+++ b/src/audio/amigaos/SDL_ahiaudio.c	Thu May 10 20:13:29 2001 +0000
@@ -27,13 +27,17 @@
  "@(#) $Id$";
 #endif
 
-/* Allow access to a raw mixing buffer (For IRIX 6.5 and higher) */
+/* Allow access to a raw mixing buffer (for AmigaOS) */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
 #include "SDL_endian.h"
 #include "SDL_audio.h"
 #include "SDL_audiomem.h"
 #include "SDL_audio_c.h"
-#include "SDL_lowaudio.h"
+#include "SDL_ahiaudio.h"
 
 /* Audio driver functions */
 static int AHI_OpenAudio(_THIS, SDL_AudioSpec *spec);
@@ -54,11 +58,29 @@
 
 static int Audio_Available(void)
 {
-#ifndef NO_AMIGADEBUG
-	D(bug("AHI available.\n"));
-#endif
+	int ok=0;
+	struct MsgPort *p;
+	struct AHIRequest *req;
+
+	if(p=CreateMsgPort())
+	{
+		if(req=(struct AHIRequest *)CreateIORequest(p,sizeof(struct AHIRequest)))
+		{
+			req->ahir_Version=4;
 
-	return 1;
+			if(!OpenDevice(AHINAME,0,(struct IORequest *)req,NULL))
+			{
+				D(bug("AHI available.\n"));
+				ok=1;
+				CloseDevice((struct IORequest *)req);
+			}
+			DeleteIORequest((struct IORequest *)req);
+		}
+		DeleteMsgPort(p);
+	}
+
+	D(if(!ok) bug("AHI not available\n"));
+	return ok;
 }
 
 static void Audio_DeleteDevice(SDL_AudioDevice *device)
@@ -125,7 +147,7 @@
 	/* Write the audio data out */
 	audio_req[current_buffer] -> ahir_Std. io_Message.mn_Node.ln_Pri = 60;
 	audio_req[current_buffer] -> ahir_Std. io_Data                = mixbuf[current_buffer];
-	audio_req[current_buffer] -> ahir_Std. io_Length              = this->spec.samples*this->hidden->bytespersample;
+	audio_req[current_buffer] -> ahir_Std. io_Length              = this->hidden->size;
 	audio_req[current_buffer] -> ahir_Std. io_Offset              = 0;
 	audio_req[current_buffer] -> ahir_Std . io_Command            = CMD_WRITE;
 	audio_req[current_buffer] -> ahir_Frequency                   = this->hidden->freq;
@@ -149,43 +171,58 @@
 {
 	D(bug("Closing audio...\n"));
 
-	if ( mixbuf[0] != NULL ) {
-		myfree(mixbuf[0]);
-//		SDL_FreeAudioMem(mixbuf[0]);
-		mixbuf[0] = NULL;
-	}
-
-	if ( mixbuf[1] != NULL ) {
-		myfree(mixbuf[1]);
-//		SDL_FreeAudioMem(mixbuf[1]);
-		mixbuf[1] = NULL;
-	}
-
 	playing=0;
 
 	if(audio_req[0])
 	{
 		if(audio_req[1])
 		{
-			if(!CheckIO((struct IORequest *)audio_req[1]))
-			{
-				AbortIO((struct IORequest *)audio_req[1]);
-				WaitIO((struct IORequest *)audio_req[1]);
-			}
-			myfree(audio_req[1]);
+			D(bug("Break req[1]...\n"));
+
+			AbortIO((struct IORequest *)audio_req[1]);
+			WaitIO((struct IORequest *)audio_req[1]);
 		}
 
-		if(!CheckIO((struct IORequest *)audio_req[0]))
+		D(bug("Break req[0]...\n"));
+
+		AbortIO((struct IORequest *)audio_req[0]);
+		WaitIO((struct IORequest *)audio_req[0]);
+
+		if(audio_req[1])
 		{
-			AbortIO((struct IORequest *)audio_req[0]);
-			WaitIO((struct IORequest *)audio_req[0]);
+			D(bug("Break AGAIN req[1]...\n"));
+			AbortIO((struct IORequest *)audio_req[1]);
+			WaitIO((struct IORequest *)audio_req[1]);
 		}
+// Double abort to be sure to break the dbuffering process.
 
+		SDL_Delay(200);
+
+		D(bug("Reqs breaked, closing device...\n"));
 		CloseDevice((struct IORequest *)audio_req[0]);
+		D(bug("Device closed, freeing memory...\n"));
+		myfree(audio_req[1]);
+		D(bug("Memory freed, deleting IOReq...\n")); 
 		DeleteIORequest((struct IORequest *)audio_req[0]);
 		audio_req[0]=audio_req[1]=NULL;
 	}
 
+	D(bug("Freeing mixbuf[0]...\n"));
+	if ( mixbuf[0] != NULL ) {
+		myfree(mixbuf[0]);
+//		SDL_FreeAudioMem(mixbuf[0]);
+		mixbuf[0] = NULL;
+	}
+
+	D(bug("Freeing mixbuf[1]...\n"));
+	if ( mixbuf[1] != NULL ) {
+		myfree(mixbuf[1]);
+//		SDL_FreeAudioMem(mixbuf[1]);
+		mixbuf[1] = NULL;
+	}
+
+	D(bug("Freeing audio_port...\n"));
+
 	if ( audio_port != NULL ) {
 		DeleteMsgPort(audio_port);
 		audio_port = NULL;
@@ -206,8 +243,10 @@
 			D(bug("Samples a 8 bit...\n"));
 			spec->format = AUDIO_S8;
 			this->hidden->bytespersample=1;
-			this->hidden->type = AHIST_M8S;
-
+			if(spec->channels<2)
+				this->hidden->type = AHIST_M8S;
+			else
+				this->hidden->type = AHIST_S8S;
 		}
 		break;
 
@@ -215,7 +254,10 @@
 			D(bug("Samples a 16 bit...\n"));
 			spec->format = AUDIO_S16MSB;
 			this->hidden->bytespersample=2;
-			this->hidden->type = AHIST_M16S;
+			if(spec->channels<2)
+				this->hidden->type = AHIST_M16S;
+			else
+				this->hidden->type = AHIST_S16S;
 		}
 		break;
 
@@ -225,6 +267,13 @@
 		}
 	}
 
+	if(spec->channels!=1 && spec->channels!=2)
+	{
+		D(bug("Wrong channel number!\n"));
+		SDL_SetError("Channel number non supported");
+		return -1;
+	}
+
 	D(bug("Before CalculateAudioSpec\n"));
 	/* Update the fragment size as size in bytes */
 	SDL_CalculateAudioSpec(spec);
@@ -258,8 +307,9 @@
 	
 	D(bug("AFTER opendevice\n"));
 
-	/* Set output frequency */
+	/* Set output frequency and size */
 	this->hidden->freq = spec->freq;
+	this->hidden->size = spec->size;
 
 	D(bug("Before buffer allocation\n"));
 
@@ -292,7 +342,7 @@
 	current_buffer=0;
 	playing=0;
 
-	D(bug("AHI opened: freq:%ld mixbuf:%lx/%lx buflen:%ld bits:%ld\n",spec->freq,mixbuf[0],mixbuf[1],spec->size,this->hidden->bytespersample*8));
+	D(bug("AHI opened: freq:%ld mixbuf:%lx/%lx buflen:%ld bits:%ld channels:%ld\n",spec->freq,mixbuf[0],mixbuf[1],spec->size,this->hidden->bytespersample*8,spec->channels));
 
 	/* We're ready to rock and roll. :-) */
 	return(0);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audio/amigaos/SDL_ahiaudio.h	Thu May 10 20:13:29 2001 +0000
@@ -0,0 +1,63 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@devolution.com
+*/
+
+#ifdef SAVE_RCSID
+static char rcsid =
+ "@(#) $Id$";
+#endif
+
+#ifndef _SDL_ahiaudio_h
+#define _SDL_ahiaudio_h
+
+#include <exec/exec.h>
+#include <dos/dos.h>
+#ifdef __SASC
+#include <proto/exec.h>
+#else
+#include <inline/exec.h>
+#endif
+
+#include <devices/ahi.h>
+#include "mydebug.h"
+#include "SDL_sysaudio.h"
+
+/* Hidden "this" pointer for the audio functions */
+#define _THIS	SDL_AudioDevice *this
+
+struct SDL_PrivateAudioData {
+	/* The handle for the audio device */
+	struct AHIRequest *audio_req[2];
+	struct MsgPort *audio_port;
+	Sint32 freq,type,bytespersample;
+	Uint8 *mixbuf[2];           /* The app mixing buffer */
+	int current_buffer;
+	Uint32 playing;
+};
+
+/* Old variable names */
+#define audio_port		(this->hidden->audio_port)
+#define audio_req		(this->hidden->audio_req)
+#define mixbuf			(this->hidden->mixbuf)
+#define current_buffer		(this->hidden->current_buffer)
+#define playing			(this->hidden->playing)
+
+#endif /* _SDL_ahiaudio_h */
--- a/src/audio/amigaos/SDL_audio.c	Thu May 10 20:10:54 2001 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,532 +0,0 @@
-/*
-    SDL - Simple DirectMedia Layer
-    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Library General Public License for more details.
-
-    You should have received a copy of the GNU Library General Public
-    License along with this library; if not, write to the Free
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-    Sam Lantinga
-    slouken@devolution.com
-*/
-
-#ifdef SAVE_RCSID
-static char rcsid =
- "@(#) $Id$";
-#endif
-
-/* Allow access to a raw mixing buffer */
-#include <stdlib.h>
-#include <stdio.h>
-#include <signal.h>
-#include <string.h>
-
-#include "SDL.h"
-#include "SDL_audio.h"
-#include "SDL_timer.h"
-#include "SDL_error.h"
-#include "SDL_audio_c.h"
-#include "SDL_audiomem.h"
-#include "SDL_sysaudio.h"
-
-
-/* Available audio drivers */
-static AudioBootStrap *bootstrap[] = {
-#ifdef unix
-	&AUDIO_bootstrap,
-#endif
-#ifdef linux
-	&DMA_bootstrap,
-#endif
-#ifdef ESD_SUPPORT
-	&ESD_bootstrap,
-#endif
-#ifdef ENABLE_DIRECTX
-	&DSOUND_bootstrap,
-#endif
-#ifdef ENABLE_WINDIB
-	&WAVEOUT_bootstrap,
-#endif
-#ifdef __BEOS__
-	&BAUDIO_bootstrap,
-#endif
-#ifdef macintosh
-	&AUDIO_bootstrap,
-#endif
-#ifdef _AIX
-	&Paud_bootstrap,
-#endif
-#ifdef ENABLE_CYBERGRAPHICS
-	&AHI_bootstrap,
-#endif
-	NULL
-};
-SDL_AudioDevice *current_audio = NULL;
-
-/* Various local functions */
-int SDL_AudioInit(const char *driver_name);
-void SDL_AudioQuit(void);
-
-struct SignalSemaphore AudioSem;
-
-/* The general mixing thread function */
-int RunAudio(void *audiop)
-{
-	SDL_AudioDevice *audio = (SDL_AudioDevice *)audiop;
-	Uint8 *stream;
-	int    stream_len;
-	void  *udata;
-	void (*fill)(void *userdata,Uint8 *stream, int len);
-	int    silence,started=0;
-
-	D(bug("Task audio started audio struct:<%lx>...\n",audiop));
-
-	D(bug("Before Openaudio..."));
-	if(audio->OpenAudio(audio, &audio->spec)==-1)
-	{
-		return(-1);
-	}
-
-	D(bug("OpenAudio...OK\n"));
-
-	/* Perform any thread setup */
-	if ( audio->ThreadInit ) {
-		audio->ThreadInit(audio);
-	}
-	audio->threadid = SDL_ThreadID();
-
-	/* Set up the mixing function */
-	fill  = audio->spec.callback;
-	udata = audio->spec.userdata;
-	if ( audio->convert.needed ) {
-		if ( audio->convert.src_format == AUDIO_U8 ) {
-			silence = 0x80;
-			D(bug("*** Silence 0x80 ***\n"));
-		} else {
-			silence = 0;
-		}
-		stream_len = audio->convert.len;
-	} else {
-		silence = audio->spec.silence;
-		stream_len = audio->spec.size;
-	}
-	stream = audio->fake_stream;
-
-	ObtainSemaphore(&AudioSem);
-	ReleaseSemaphore(&AudioSem);
-
-	D(bug("Enering audio loop...\n"));
-
-	D(if(audio->convert.needed)bug("*** Conversion needed.\n"));
-
-	/* Loop, filling the audio buffers */
-	while ( audio->enabled ) 
-	{
-		/* Wait for new current buffer to finish playing */
-
-		if ( stream == audio->fake_stream )
-			SDL_Delay((audio->spec.samples*1000)/audio->spec.freq);
-		else
-		{
-			if(started>1)
-			{
-//				D(bug("Waiting audio...\n"));
-				audio->WaitAudio(audio);
-			}
-		}
-
-		ObtainSemaphore(&AudioSem);
-
-		/* Fill the current buffer with sound */
-		if ( audio->convert.needed ) {
-			stream = audio->convert.buf;
-		} else {
-			stream = audio->GetAudioBuf(audio);
-		}
-
-		if(stream!=audio->fake_stream)
-			memset(stream, silence, stream_len);
-
-		if ( ! audio->paused ) {
-			ObtainSemaphore(&audio->mixer_lock);
-			(*fill)(udata, stream, stream_len);
-			ReleaseSemaphore(&audio->mixer_lock);
-		}
-
-		/* Convert the audio if necessary */
-		if ( audio->convert.needed ) {
-			SDL_ConvertAudio(&audio->convert);
-			stream = audio->GetAudioBuf(audio);
-			memcpy(stream, audio->convert.buf,audio->convert.len_cvt);
-		}
-
-		if(stream!=audio->fake_stream)
-		{
-//			D(bug("Playing stream at %lx\n",stream));
-
-			audio->PlayAudio(audio);
-			started++;
-		}
-		ReleaseSemaphore(&AudioSem);
-
-	}
-	D(bug("Out of subtask loop...\n"));
-
-	/* Wait for the audio to drain.. */
-	if ( audio->WaitDone ) {
-		audio->WaitDone(audio);
-	}
-
-	D(bug("WaitAudio...Done\n"));
-
-	audio->CloseAudio(audio);
-
-	D(bug("CloseAudio..Done, subtask exiting...\n"));
-
-	return(0);
-}
-
-int SDL_AudioInit(const char *driver_name)
-{
-	SDL_AudioDevice *audio;
-	int i = 0, idx;
-
-	/* Check to make sure we don't overwrite 'current_audio' */
-	if ( current_audio != NULL ) {
-		SDL_AudioQuit();
-	}
-
-	/* Select the proper audio driver */
-	audio = NULL;
-	idx = 0;
-
-	InitSemaphore(&AudioSem);
-
-	if ( audio == NULL ) {
-		if ( driver_name != NULL ) {
-			if ( strrchr(driver_name, ':') != NULL ) {
-				idx = atoi(strrchr(driver_name, ':')+1);
-			}
-			for ( i=0; bootstrap[i]; ++i ) {
-				if (strncmp(bootstrap[i]->name, driver_name,
-				            strlen(bootstrap[i]->name)) == 0) {
-					if ( bootstrap[i]->available() ) {
-						audio=bootstrap[i]->create(idx);
-						break;
-					}
-				}
-			}
-		} else {
-			for ( i=0; bootstrap[i]; ++i ) {
-				if ( bootstrap[i]->available() ) {
-					audio = bootstrap[i]->create(idx);
-					if ( audio != NULL ) {
-						break;
-					}
-				}
-			}
-		}
-		if ( audio == NULL ) {
-			SDL_SetError("No available audio device");
-#if 0 /* Don't fail SDL_Init() if audio isn't available.
-         SDL_OpenAudio() will handle it at that point.  *sigh*
-       */
-			return(-1);
-#endif
-		}
-	}
-	current_audio = audio;
-	if ( current_audio ) {
-		current_audio->name = bootstrap[i]->name;
-	}
-	return(0);
-}
-
-char *SDL_AudioDriverName(char *namebuf, int maxlen)
-{
-	if ( current_audio != NULL ) {
-		strncpy(namebuf, current_audio->name, maxlen-1);
-		namebuf[maxlen-1] = '\0';
-		return(namebuf);
-	}
-	return(NULL);
-}
-
-int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained)
-{
-	SDL_AudioDevice *audio;
-
-	/* Start up the audio driver, if necessary */
-	if ( ! current_audio ) {
-		if ( (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) ||
-		     (current_audio == NULL) ) {
-			return(-1);
-		}
-	}
-	audio = current_audio;
-
-	D(bug("Chiamata SDL_OpenAudio...\n"));
-
-	/* Verify some parameters */
-	if ( desired->callback == NULL ) {
-		SDL_SetError("SDL_OpenAudio() passed a NULL callback");
-		return(-1);
-	}
-	switch ( desired->channels ) {
-	    case 1:	/* Mono */
-	    case 2:	/* Stereo */
-		break;
-	    default:
-		SDL_SetError("1 (mono) and 2 (stereo) channels supported");
-		return(-1);
-	}
-
-	/* Create a semaphore for locking the sound buffers */
-	InitSemaphore(&audio->mixer_lock);
-
-	/* Calculate the silence and size of the audio specification */
-	SDL_CalculateAudioSpec(desired);
-
-	/* Open the audio subsystem */
-	memcpy(&audio->spec, desired, sizeof(audio->spec));
-	audio->convert.needed = 0;
-	audio->enabled = 1;
-	audio->paused  = 1;
-
-	ObtainSemaphore(&AudioSem);
-
-	audio->thread = SDL_CreateThread(RunAudio, audio);
-
-	if ( audio->thread == NULL ) {
-		ReleaseSemaphore(&AudioSem);
-		SDL_CloseAudio();
-		SDL_SetError("Couldn't create audio thread");
-		return(-1);
-	}
-
-	/* If the audio driver changes the buffer size, accept it */
-	if ( audio->spec.samples != desired->samples ) {
-		desired->samples = audio->spec.samples;
-		SDL_CalculateAudioSpec(desired);
-	}
-
-	/* Allocate a fake audio memory buffer */
-	audio->fake_stream = SDL_AllocAudioMem(audio->spec.size);
-	if ( audio->fake_stream == NULL ) {
-		ReleaseSemaphore(&AudioSem);
-		SDL_CloseAudio();
-		SDL_OutOfMemory();
-		return(-1);
-	}
-
-	/* See if we need to do any conversion */
-	if ( memcmp(desired, &audio->spec, sizeof(audio->spec)) == 0 ) {
-		/* Just copy over the desired audio specification */
-		if ( obtained != NULL ) {
-			memcpy(obtained, &audio->spec, sizeof(audio->spec));
-		}
-	} else {
-		/* Copy over the audio specification if possible */
-		if ( obtained != NULL ) {
-			memcpy(obtained, &audio->spec, sizeof(audio->spec));
-		} else {
-			/* Build an audio conversion block */
-			D(bug("Need conversion:\n desired: C:%ld F:%ld T:%lx\navailable: C:%ld F:%ld T:%lx\n",
-				desired->channels, desired->freq, desired->format,
-				audio->spec.channels,audio->spec.freq,audio->spec.format));
-
-			Forbid();
-
-// Magari poi lo sostiutisco con un semaforo.
-
-			if ( SDL_BuildAudioCVT(&audio->convert,
-				desired->format, desired->channels,
-						desired->freq,
-				audio->spec.format, audio->spec.channels,
-						audio->spec.freq) < 0 ) {
-				ReleaseSemaphore(&AudioSem);
-				SDL_CloseAudio();
-				return(-1);
-			}
-			if ( audio->convert.needed ) {
-				audio->convert.len = desired->size;
-				audio->convert.buf =(Uint8 *)SDL_AllocAudioMem(
-				   audio->convert.len*audio->convert.len_mult);
-				if ( audio->convert.buf == NULL ) {
-					ReleaseSemaphore(&AudioSem);
-					SDL_CloseAudio();
-					SDL_OutOfMemory();
-					return(-1);
-				}
-			}
-		}
-	}
-
-	ReleaseSemaphore(&AudioSem);
-
-	D(bug("SDL_OpenAudio USCITA...\n"));
-
-	return(0);
-}
-
-SDL_audiostatus SDL_GetAudioStatus(void)
-{
-	SDL_AudioDevice *audio = current_audio;
-	SDL_audiostatus status;
-
-	status = SDL_AUDIO_STOPPED;
-	if ( audio && audio->enabled ) {
-		if ( audio->paused ) {
-			status = SDL_AUDIO_PAUSED;
-		} else {
-			status = SDL_AUDIO_PLAYING;
-		}
-	}
-	return(status);
-}
-
-void SDL_PauseAudio (int pause_on)
-{
-	SDL_AudioDevice *audio = current_audio;
-
-	if ( audio ) {
-		audio->paused = pause_on;
-	}
-}
-
-void SDL_LockAudio (void)
-{
-	SDL_AudioDevice *audio = current_audio;
-
-	/* Obtain a lock on the mixing buffers */
-	if ( audio ) {
-		if ( audio->thread && (SDL_ThreadID() == audio->threadid) ) {
-			return;
-		}
-		ObtainSemaphore(&audio->mixer_lock);
-	}
-}
-
-void SDL_UnlockAudio (void)
-{
-	SDL_AudioDevice *audio = current_audio;
-
-	/* Release lock on the mixing buffers */
-	if ( audio ) {
-		if ( audio->thread && (SDL_ThreadID() == audio->threadid) ) {
-			return;
-		}
-		ReleaseSemaphore(&audio->mixer_lock);
-	}
-}
-
-void SDL_CloseAudio (void)
-{
-	SDL_AudioDevice *audio = current_audio;
-
-	if ( audio ) {
-		if(audio->enabled)
-		{
-			audio->enabled = 0;
-
-			if ( audio->thread != NULL ) {
-				D(bug("Waiting audio thread...\n"));
-				SDL_WaitThread(audio->thread, NULL);
-				D(bug("...audio replied\n"));
-			}
-		}
-
-		if ( audio->fake_stream != NULL ) {
-			SDL_FreeAudioMem(audio->fake_stream);
-			audio->fake_stream=NULL;
-		}
-		if ( audio->convert.needed && current_audio->convert.buf!=NULL) {
-			SDL_FreeAudioMem(audio->convert.buf);
-			current_audio->convert.buf=NULL;
-		}
-	}
-	SDL_QuitSubSystem(SDL_INIT_AUDIO);
-}
-
-void SDL_AudioQuit(void)
-{
-	if ( current_audio ) {
-		if(current_audio->enabled)
-		{
-			D(bug("Closing audio in AudioQuit...\n"));
-			current_audio->enabled = 0;
-
-			if ( current_audio->thread != NULL ) {
-				D(bug("Waiting audio thread...\n"));
-				SDL_WaitThread(current_audio->thread, NULL);
-				D(bug("...audio replied\n"));
-			}
-		}
-		if ( current_audio->fake_stream != NULL ) {
-			SDL_FreeAudioMem(current_audio->fake_stream);
-		}
-		if ( current_audio->convert.needed && 
-				current_audio->convert.buf) {
-			SDL_FreeAudioMem(current_audio->convert.buf);
-		}
-
-		current_audio->free(current_audio);
-		current_audio = NULL;
-	}
-}
-
-#define NUM_FORMATS	6
-static int format_idx;
-static int format_idx_sub;
-static Uint16 format_list[NUM_FORMATS][NUM_FORMATS] = {
- { AUDIO_U8, AUDIO_S8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB },
- { AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB },
- { AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8 },
- { AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8 },
- { AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U8, AUDIO_S8 },
- { AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U8, AUDIO_S8 },
-};
-
-Uint16 SDL_FirstAudioFormat(Uint16 format)
-{
-	for ( format_idx=0; format_idx < NUM_FORMATS; ++format_idx ) {
-		if ( format_list[format_idx][0] == format ) {
-			break;
-		}
-	}
-	format_idx_sub = 0;
-	return(SDL_NextAudioFormat());
-}
-
-Uint16 SDL_NextAudioFormat(void)
-{
-	if ( (format_idx == NUM_FORMATS) || (format_idx_sub == NUM_FORMATS) ) {
-		return(0);
-	}
-	return(format_list[format_idx][format_idx_sub++]);
-}
-
-void SDL_CalculateAudioSpec(SDL_AudioSpec *spec)
-{
-	switch (spec->format) {
-		case AUDIO_U8:
-			spec->silence = 0x80;
-			break;
-		default:
-			spec->silence = 0x00;
-			break;
-	}
-	spec->size = (spec->format&0xFF)/8;
-	spec->size *= spec->channels;
-	spec->size *= spec->samples;
-}
--- a/src/audio/amigaos/SDL_lowaudio.h	Thu May 10 20:10:54 2001 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*
-    SDL - Simple DirectMedia Layer
-    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Library General Public License for more details.
-
-    You should have received a copy of the GNU Library General Public
-    License along with this library; if not, write to the Free
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-    Sam Lantinga
-    slouken@devolution.com
-*/
-
-#ifdef SAVE_RCSID
-static char rcsid =
- "@(#) $Id$";
-#endif
-
-#ifndef _SDL_lowaudio_h
-#define _SDL_lowaudio_h
-
-// #include <libraries/ahi_sub.h>
-
-#include "SDL_sysaudio.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* Hidden "this" pointer for the audio functions */
-#define _THIS	SDL_AudioDevice *this
-
-struct SDL_PrivateAudioData {
-	/* The handle for the audio device */
-	struct AHIRequest *audio_req[2];
-	struct MsgPort *audio_port;
-	Sint32 freq,type,bytespersample;
-	Uint8 *mixbuf[2];           /* The app mixing buffer */
-	int current_buffer;
-	Uint32 playing;
-};
-
-/* Old variable names */
-#define audio_port		(this->hidden->audio_port)
-#define audio_req		(this->hidden->audio_req)
-#define mixbuf			(this->hidden->mixbuf)
-#define current_buffer		(this->hidden->current_buffer)
-#define playing			(this->hidden->playing)
-
-#endif /* _SDL_lowaudio_h */
--- a/src/audio/amigaos/SDL_sysaudio.h	Thu May 10 20:10:54 2001 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-/*
-    SDL - Simple DirectMedia Layer
-    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Library General Public License for more details.
-
-    You should have received a copy of the GNU Library General Public
-    License along with this library; if not, write to the Free
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-    Sam Lantinga
-    slouken@devolution.com
-*/
-
-#ifdef SAVE_RCSID
-static char rcsid =
- "@(#) $Id$";
-#endif
-
-#ifndef _SDL_sysaudio_h
-#define _SDL_sysaudio_h
-
-#include "SDL_mutex.h"
-#include "SDL_thread.h"
-
-#include <exec/exec.h>
-#include <dos/dos.h>
-#ifdef __SASC
-#include <proto/exec.h>
-#else
-#include <inline/exec.h>
-#endif
-
-#include <devices/ahi.h>
-#include "mydebug.h"
-
-/* The SDL audio driver */
-typedef struct SDL_AudioDevice SDL_AudioDevice;
-
-/* Define the SDL audio driver structure */
-#define _THIS	SDL_AudioDevice *_this
-#ifndef _STATUS
-#define _STATUS	SDL_status *status
-#endif
-struct SDL_AudioDevice {
-	/* * * */
-	/* The name of this audio driver */
-	const char *name;
-
-	/* * * */
-	/* Public driver functions */
-	int  (*OpenAudio)(_THIS, SDL_AudioSpec *spec);
-	void (*ThreadInit)(_THIS);	/* Called by audio thread at start */
-	void (*WaitAudio)(_THIS);
-	void (*PlayAudio)(_THIS);
-	Uint8 *(*GetAudioBuf)(_THIS);
-	void (*WaitDone)(_THIS);
-	void (*CloseAudio)(_THIS);
-
-	/* * * */
-	/* Data common to all devices */
-
-	/* The current audio specification (shared with audio thread) */
-	SDL_AudioSpec spec;
-
-	/* An audio conversion block for audio format emulation */
-	SDL_AudioCVT convert;
-
-	/* Current state flags */
-	int enabled;
-	int paused;
-
-	/* Fake audio buffer for when the audio hardware is busy */
-	Uint8 *fake_stream;
-
-	/* A semaphore for locking the mixing buffers */
-	struct SignalSemaphore mixer_lock;
-
-	/* A thread to feed the audio device */
-	SDL_Thread *thread;
-	Uint32 threadid;
-
-	/* * * */
-	/* Data private to this driver */
-	struct SDL_PrivateAudioData *hidden;
-
-	/* * * */
-	/* The function used to dispose of this structure */
-	void (*free)(_THIS);
-};
-#undef _THIS
-
-typedef struct AudioBootStrap {
-	const char *name;
-	int (*available)(void);
-	SDL_AudioDevice *(*create)(int devindex);
-} AudioBootStrap;
-
-#ifdef ESD_SUPPORT
-extern AudioBootStrap ESD_bootstrap;
-#endif
-#ifdef linux
-extern AudioBootStrap DMA_bootstrap;
-#endif
-#ifdef unix
-extern AudioBootStrap AUDIO_bootstrap;
-#endif
-#ifdef ENABLE_WINDIB
-extern AudioBootStrap WAVEOUT_bootstrap;
-#endif
-#ifdef ENABLE_DIRECTX
-extern AudioBootStrap DSOUND_bootstrap;
-#endif
-#ifdef __BEOS__
-extern AudioBootStrap BAUDIO_bootstrap;
-#endif
-#ifdef macintosh
-extern AudioBootStrap AUDIO_bootstrap;
-#endif
-#ifdef _AIX
-extern AudioBootStrap Paud_bootstrap;
-#endif
-#ifdef ENABLE_CYBERGRAPHICS
-extern AudioBootStrap AHI_bootstrap;
-#endif
-
-/* This is the current audio device */
-extern SDL_AudioDevice *current_audio;
-
-#ifndef __SASC
-extern struct ExecBase *SysBase;
-#endif
-
-#endif /* _SDL_sysaudio_h */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/joystick/amigaos/Makefile.am	Thu May 10 20:13:29 2001 +0000
@@ -0,0 +1,8 @@
+
+## Makefile.am for the AmigaOS joystick driver for SDL
+
+noinst_LTLIBRARIES = libjoystick_amiga.la
+libjoystick_amiga_la_SOURCES = $(SRCS)
+
+# The SDL joystick driver sources
+SRCS =  SDL_sysjoystick.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/joystick/amigaos/SDL_sysjoystick.c	Thu May 10 20:13:29 2001 +0000
@@ -0,0 +1,240 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@devolution.com
+*/
+
+
+#ifdef SAVE_RCSID
+static char rcsid =
+ "@(#) $Id$";
+#endif
+
+/* This is the system specific header for the SDL joystick API */
+
+#include <stdio.h>		/* For the definition of NULL */
+
+#include <libraries/lowlevel.h>
+#ifdef __SASC
+#include <proto/exec.h>
+#include <proto/lowlevel.h>
+#include <proto/graphics.h>
+#else
+#include <inline/exec.h>
+#include <inline/lowlevel.h>
+#include <inline/graphics.h>
+#endif
+#include "mydebug.h"
+
+extern struct ExecBase *SysBase;
+extern struct GfxBase *GfxBase;
+#include <stdlib.h>
+
+#include "SDL_error.h"
+#include "SDL_joystick.h"
+#include "SDL_sysjoystick.h"
+#include "SDL_joystick_c.h"
+
+/* Function to scan the system for joysticks.
+ * This function should set SDL_numjoysticks to the number of available
+ * joysticks.  Joystick 0 should be the system default joystick.
+ * It should return 0, or -1 on an unrecoverable fatal error.
+ */
+
+
+/* Amiga specific datas */
+struct Library *LowLevelBase=NULL;
+
+ULONG joybut[]=
+{
+	JPF_BUTTON_RED,
+	JPF_BUTTON_BLUE,
+	JPF_BUTTON_PLAY,
+	JPF_BUTTON_YELLOW,
+	JPF_BUTTON_GREEN,
+	JPF_BUTTON_FORWARD,
+	JPF_BUTTON_REVERSE,
+};
+
+struct joystick_hwdata 
+{
+	ULONG joystate;
+};
+
+int SDL_SYS_JoystickInit(void)
+{
+	if(!LowLevelBase)
+	{
+		if(LowLevelBase=OpenLibrary("lowlevel.library",37))
+			return 2;
+	}
+	else
+		return 2;
+
+	D(bug("%ld joysticks available.\n",SDL_numjoysticks));
+
+	return 0;
+}
+
+/* Function to get the device-dependent name of a joystick */
+const char *SDL_SYS_JoystickName(int index)
+{
+	if(index<2&&LowLevelBase)
+	{
+		switch(index)
+		{
+			case 0:
+				return "Port 1 Amiga Joystick/Joypad";
+			case 1:
+				return "Port 2 Amiga Joystick/Joypad";
+		}
+	}
+
+	SDL_SetError("No joystick available with that index");
+	return(NULL);
+}
+
+/* Function to open a joystick for use.
+   The joystick to open is specified by the index field of the joystick.
+   This should fill the nbuttons and naxes fields of the joystick structure.
+   It returns 0, or -1 if there is an error.
+ */
+
+int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)
+{
+	ULONG temp,i;
+	D(bug("Opening joystick %ld\n",joystick->index));
+
+	if(!(joystick->hwdata=malloc(sizeof(struct joystick_hwdata))))
+		return -1;
+
+/* This loop is to check if the controller is a joypad */
+
+	for(i=0;i<20;i++)
+	{
+		temp=ReadJoyPort(joystick->index);
+		WaitTOF();
+	}
+
+	if((temp&JP_TYPE_MASK)==JP_TYPE_GAMECTLR)
+		joystick->nbuttons=7;
+	else
+		joystick->nbuttons=3;
+
+	joystick->nhats=0;
+	joystick->nballs=0;
+	joystick->naxes=2;
+	joystick->hwdata->joystate=0L;
+
+	return 0;
+}
+
+/* Function to update the state of a joystick - called as a device poll.
+ * This function shouldn't update the joystick structure directly,
+ * but instead should call SDL_PrivateJoystick*() to deliver events
+ * and update joystick device state.
+ */
+void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
+{
+	ULONG data;	
+	int i;
+
+	if(joystick->index<2)
+	{
+		data=ReadJoyPort(joystick->index);
+
+		if(data&JP_DIRECTION_MASK)
+		{
+			if(data&JPF_JOY_DOWN)
+			{
+				if(!(joystick->hwdata->joystate&JPF_JOY_DOWN))
+					SDL_PrivateJoystickAxis(joystick,0,127);
+			}
+			else if(data&JPF_JOY_UP)
+			{
+				if(!(joystick->hwdata->joystate&JPF_JOY_UP))
+					SDL_PrivateJoystickAxis(joystick,0,-127);
+			}
+			else if(joystick->hwdata->joystate&(JPF_JOY_UP|JPF_JOY_DOWN))
+				SDL_PrivateJoystickAxis(joystick,0,0);
+
+			if(data&JPF_JOY_LEFT)
+			{
+				if(!(joystick->hwdata->joystate&JPF_JOY_LEFT))
+					SDL_PrivateJoystickAxis(joystick,1,-127);
+			}
+			else if(data&JPF_JOY_RIGHT)
+			{
+				if(!(joystick->hwdata->joystate&JPF_JOY_RIGHT))
+					SDL_PrivateJoystickAxis(joystick,1,127);
+			}
+			else if(joystick->hwdata->joystate&(JPF_JOY_LEFT|JPF_JOY_RIGHT))
+				SDL_PrivateJoystickAxis(joystick,1,0);
+		}
+		else if(joystick->hwdata->joystate&(JPF_JOY_LEFT|JPF_JOY_RIGHT))
+		{
+				SDL_PrivateJoystickAxis(joystick,1,0);
+		}
+		else if(joystick->hwdata->joystate&(JPF_JOY_UP|JPF_JOY_DOWN))
+		{
+				SDL_PrivateJoystickAxis(joystick,0,0);
+		}
+
+		for(i=0;i<joystick->nbuttons;i++)
+		{
+			if( (data&joybut[i]) )
+			{
+				if(i==1)
+					data&=(~(joybut[2]));
+
+				if(!(joystick->hwdata->joystate&joybut[i]))
+					SDL_PrivateJoystickButton(joystick,i,SDL_PRESSED);
+			}
+			else if(joystick->hwdata->joystate&joybut[i])
+				SDL_PrivateJoystickButton(joystick,i,SDL_RELEASED);
+		}
+
+		joystick->hwdata->joystate=data;
+	}
+
+	return;
+}
+
+/* Function to close a joystick after use */
+void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
+{
+	if(joystick->hwdata)
+		free(joystick->hwdata);
+	return;
+}
+
+/* Function to perform any system-specific joystick related cleanup */
+
+void SDL_SYS_JoystickQuit(void)
+{
+	if(LowLevelBase)
+	{
+		CloseLibrary(LowLevelBase);
+		LowLevelBase=NULL;
+		SDL_numjoysticks=0;
+	}
+
+	return;
+}
+
--- a/src/thread/amigaos/SDL_syssem.c	Thu May 10 20:10:54 2001 +0000
+++ b/src/thread/amigaos/SDL_syssem.c	Thu May 10 20:13:29 2001 +0000
@@ -25,7 +25,7 @@
  "@(#) $Id$";
 #endif
 
-/* An native implementation of semaphores on AmigaOS */
+/* An implementation of semaphores using mutexes and condition variables */
 
 #include "SDL_error.h"
 #include "SDL_thread.h"
@@ -35,9 +35,13 @@
 struct SDL_semaphore
 {
 	struct SignalSemaphore Sem;
+	Uint32 count;
+	Uint32 waiters_count;
+	SDL_mutex *count_lock;
+	SDL_cond *count_nonzero;
 };
 
-#undef D(x)
+#undef D
 
 #define D(x)
 
@@ -46,20 +50,18 @@
 	SDL_sem *sem;
 
 	sem = (SDL_sem *)malloc(sizeof(*sem));
+
 	if ( ! sem ) {
 		SDL_OutOfMemory();
 		return(0);
 	}
-	memset(sem, 0, sizeof(*sem));
 
 	D(bug("Creating semaphore %lx...\n",sem));
 
+	memset(sem,0,sizeof(*sem));
+
 	InitSemaphore(&sem->Sem);
-#if 1 // Allow multiple obtainings of the semaphore
-        while ( initial_value-- ) {
-		ReleaseSemaphore(&sem->Sem);
-	}
-#endif
+	
 	return(sem);
 }
 
@@ -75,8 +77,6 @@
 
 int SDL_SemTryWait(SDL_sem *sem)
 {
-	int retval;
-
 	if ( ! sem ) {
 		SDL_SetError("Passed a NULL semaphore");
 		return -1;
@@ -84,17 +84,17 @@
 
 	D(bug("TryWait semaphore...%lx\n",sem));
 
-	retval = SDL_MUTEX_TIMEDOUT;
-	if ( AttemptSemaphore(&sem->Sem) ) {
-		retval = 0;
-	}
-	return retval;
+	ObtainSemaphore(&sem->Sem);
+//	ReleaseSemaphore(&sem->Sem);
+
+	return 1;
 }
 
 int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
 {
 	int retval;
 
+
 	if ( ! sem ) {
 		SDL_SetError("Passed a NULL semaphore");
 		return -1;
@@ -102,16 +102,22 @@
 
 	D(bug("WaitTimeout (%ld) semaphore...%lx\n",timeout,sem));
 
-#if 1 // We need to keep trying the semaphore until the timeout expires
-	retval = SDL_MUTEX_TIMEDOUT;
-	then = SDL_GetTicks();
-	do {
-		if ( AttemptSemaphore(&sem->Sem) ) {
-			retval = 0;
-		}
-		now = SDL_GetTicks();
-	} while ( (retval == SDL_MUTEX_TIMEDOUT) && ((now-then) < timeout) );
-#else
+	/* A timeout of 0 is an easy case */
+	if ( timeout == 0 ) {
+		return SDL_SemTryWait(sem);
+	}
+/*
+	SDL_LockMutex(sem->count_lock);
+	++sem->waiters_count;
+	retval = 0;
+	while ( (sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT) ) {
+		retval = SDL_CondWaitTimeout(sem->count_nonzero,
+		                             sem->count_lock, timeout);
+	}
+	--sem->waiters_count;
+	--sem->count;
+	SDL_UnlockMutex(sem->count_lock);
+*/
 	if(!(retval=AttemptSemaphore(&sem->Sem)))
 	{
 		SDL_Delay(timeout);
@@ -123,22 +129,15 @@
 //		ReleaseSemaphore(&sem->Sem);
 		retval=1;
 	}
-#endif
+
 	return retval;
 }
 
 int SDL_SemWait(SDL_sem *sem)
 {
-	if ( ! sem ) {
-		SDL_SetError("Passed a NULL semaphore");
-		return -1;
-	}
-#if 1 // This should be an infinite wait - FIXME, what is the return value?
 	ObtainSemaphore(&sem->Sem);
-        return 0;
-#else
-	return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
-#endif
+	return 0;
+//	return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
 }
 
 Uint32 SDL_SemValue(SDL_sem *sem)
@@ -148,6 +147,7 @@
 	value = 0;
 	if ( sem ) {
 		value = sem->Sem.ss_NestCount;
+//		SDL_UnlockMutex(sem->count_lock);
 	}
 	return value;
 }
@@ -161,6 +161,14 @@
 	D(bug("SemPost semaphore...%lx\n",sem));
 
 	ReleaseSemaphore(&sem->Sem);
+#if 0
+	SDL_LockMutex(sem->count_lock);
+	if ( sem->waiters_count > 0 ) {
+		SDL_CondSignal(sem->count_nonzero);
+	}
+	++sem->count;
+	SDL_UnlockMutex(sem->count_lock);
+#endif
 	return 0;
 }
 
--- a/src/thread/amigaos/SDL_systhread.c	Thu May 10 20:10:54 2001 +0000
+++ b/src/thread/amigaos/SDL_systhread.c	Thu May 10 20:13:29 2001 +0000
@@ -25,7 +25,7 @@
  "@(#) $Id$";
 #endif
 
-/* AmigaOS thread management routines for SDL */
+/* BeOS thread management routines for SDL */
 
 #include "SDL_error.h"
 #include "SDL_mutex.h"
@@ -40,6 +40,8 @@
 	struct Task *wait;
 } thread_args;
 
+#ifndef MORPHOS
+
 #if defined(__SASC) && !defined(__PPC__) 
 __saveds __asm Uint32 RunThread(register __a0 char *args )
 #elif defined(__PPC__)
@@ -60,6 +62,34 @@
 	return(0);
 }
 
+#else
+
+#include <emul/emulinterface.h>
+
+Uint32 RunTheThread(void)
+{
+	thread_args *data=(thread_args *)atol(REG_A0);
+	struct Task *Father;
+
+	D(bug("Received data: %lx\n",data));
+	Father=data->wait;
+
+	SDL_RunThread(data);
+
+	Signal(Father,SIGBREAKF_CTRL_F);
+	return(0);
+}
+
+struct EmulLibEntry RunThread=
+{
+	TRAP_LIB,
+	0,
+	RunTheThread
+};
+
+#endif
+
+
 int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
 {
 	/* Create the thread and go! */
@@ -98,6 +128,7 @@
 
 void SDL_SYS_WaitThread(SDL_Thread *thread)
 {
+	SetSignal(0L,SIGBREAKF_CTRL_F|SIGBREAKF_CTRL_C);
 	Wait(SIGBREAKF_CTRL_F|SIGBREAKF_CTRL_C);
 }
 
--- a/src/thread/amigaos/SDL_thread.c	Thu May 10 20:10:54 2001 +0000
+++ b/src/thread/amigaos/SDL_thread.c	Thu May 10 20:13:29 2001 +0000
@@ -265,6 +265,18 @@
 	}
 }
 
+Uint32 SDL_GetThreadID(SDL_Thread *thread)
+{
+	Uint32 id;
+
+	if ( thread ) {
+		id = thread->threadid;
+	} else {
+		id = SDL_ThreadID();
+	}
+	return(id);
+}
+
 void SDL_KillThread(SDL_Thread *thread)
 {
 	if ( thread ) {
--- a/src/timer/amigaos/SDL_systimer.c	Thu May 10 20:10:54 2001 +0000
+++ b/src/timer/amigaos/SDL_systimer.c	Thu May 10 20:13:29 2001 +0000
@@ -26,98 +26,221 @@
 #endif
 
 #include <stdio.h>
-#include <sys/time.h>
+#include <time.h>
 #include <signal.h>
 #include <unistd.h>
 #include <string.h>
 #include <errno.h>
+#include <exec/types.h>
+#ifdef __SASC
+#include <proto/dos.h>
+#include <clib/graphics_protos.h>
+#include <pragmas/graphics.h>
+#include <clib/exec_protos.h>
+#include <pragmas/exec.h>
+#else
+#include <inline/dos.h>
+#include <inline/exec.h>
+#include <inline/graphics.h>
+#endif
+#include "mydebug.h"
+
+extern struct DosLibrary *DOSBase;
+extern struct ExecBase *SysBase;
+static struct GfxBase *GfxBase;
 
 #include "SDL_error.h"
 #include "SDL_timer.h"
 #include "SDL_timer_c.h"
 
+#if defined(DISABLE_THREADS) || defined(FORK_HACK)
+#define USE_ITIMER
+#endif
+
 /* The first ticks value of the application */
-static struct timeval start;
+
+#ifndef __PPC__
+static clock_t start;
 
 void SDL_StartTicks(void)
 {
 	/* Set first ticks value */
-	gettimeofday(&start, NULL);
+	start=clock();
 }
 
 Uint32 SDL_GetTicks (void)
 {
-	struct timeval now;
-	Uint32 ticks;
+	clock_t ticks;
+
+	ticks=clock()-start;
+
+#ifdef __SASC
+// CLOCKS_PER_SEC == 1000 !
 
-	gettimeofday(&now, NULL);
-	ticks=(now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000;
 	return(ticks);
+#else
+// CLOCKS_PER_SEC != 1000 !
+
+	return ticks*(1000/CLOCKS_PER_SEC);
+#endif
 }
 
 void SDL_Delay (Uint32 ms)
 {
-	int was_error;
-#ifndef linux	/* Non-Linux implementations need to calculate time left */
-	Uint32 then, now, elapsed;
-#endif
-	struct timeval tv;
+// Do a busy wait if time is less than 50ms
 
-	/* Set the timeout interval - Linux only needs to do this once */
-#ifdef linux
-	tv.tv_sec = ms/1000;
-	tv.tv_usec = (ms%1000)*1000;
-#else
-	then = SDL_GetTicks();
+	if(ms<50)
+	{
+		clock_t to_wait=clock();
+
+#ifndef __SASC
+		ms*=(CLOCKS_PER_SEC/1000);
 #endif
-	do {
-		errno = 0;
-#ifndef linux
-		/* Calculate the time interval left (in case of interrupt) */
-		now = SDL_GetTicks();
-		elapsed = (now-then);
-		then = now;
-		if ( elapsed >= ms ) {
-			break;
+		to_wait+=ms;
+
+		while(clock()<to_wait);
+	}
+	else
+	{
+		Delay(ms/20);
+	}
+}
+
+#else
+
+ULONG MY_CLOCKS_PER_SEC;
+
+void PPC_TimerInit(void);
+APTR MyTimer;
+
+ULONG start[2];
+
+void SDL_StartTicks(void)
+{
+	/* Set first ticks value */
+	if(!MyTimer)
+		PPC_TimerInit();
+	
+	PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,start);
+	start[1]>>=10;
+	start[1]|=((result[0]&0x3ff)<<22);
+	start[0]>>=10;
+}
+
+Uint32 SDL_GetTicks (void)
+{
+	ULONG result[2];
+	PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,result);
+
+//	PPCAsr64p(result,10);
+// Non va, la emulo:
+	
+	result[1]>>=10;
+	result[1]|=((result[0]&0x3ff)<<22);
+
+// Non mi interessa piu' result[0]
+
+	return result[1]*1000/MY_CLOCKS_PER_SEC;
+}
+
+void SDL_Delay (Uint32 ms)
+{
+// Do a busy wait if time is less than 50ms
+
+	if(ms<50)
+	{
+		ULONG to_wait[2],actual[2];
+		PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,result);
+		actual[1]=0;
+		to_wait[1]+=ms*1000/MY_CLOCKS_PER_SEC;
+
+		while(actual[1]<to_wait[1])
+		{
+			PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,actual);
 		}
-		ms -= elapsed;
-		tv.tv_sec = ms/1000;
-		tv.tv_usec = (ms%1000)*1000;
+	}
+	else
+	{
+		Delay(ms/50);
+	}
+}
+
+void PPC_TimerInit(void)
+{
+	struct TagItem tags[]=
+		{
+			PPCTIMERTAG_CPU,TRUE,
+			TAG_DONE,0
+		};
+
+
+	if(MyTimer=PPCCreateTimerObject(tags))
+	{
+		ULONG result[2];
+
+		PPCGetTimerObject(MyTimer,PPCTIMERTAG_TICKSPERSEC,result);
+		D(bug("Timer inizializzato, TPS: %lu - %lu\n",result[0],result[1]));
+//		PPCAsr64p(result,10);
+		result[1]>>=10;
+		result[1]|=((result[0]&0x3ff)<<22);
+		result[0]>>=10;
+
+		D(bug("Shiftato TPS: %lu - %lu\n",result[0],result[1]));
+		MY_CLOCKS_PER_SEC=result[1];
+
+		PPCGetTimerObject(MyTimer,PPCTIMERTAG_CURRENTTICKS,result);
+
+		D(bug("Current ticks: %lu - %lu\n",result[0],result[1]));
+		result[1]>>=10;
+		result[1]|=((result[0]&0x3ff)<<22);
+		result[0]>>=10;
+//		PPCAsr64p(result,10);
+		D(bug("Shiftato: %lu - %lu\n",result[0],result[1]));
+	}
+	else
+	{
+		D(bug("Errore nell'inizializzazione del timer!\n"));
+	}	
+}
+
 #endif
-		was_error = select(0, NULL, NULL, NULL, &tv);
-	} while ( was_error && (errno == EINTR) );
-}
 
 #include "SDL_thread.h"
 
 /* Data to handle a single periodic alarm */
 static int timer_alive = 0;
-static SDL_Thread *timer = NULL;
+static SDL_Thread *timer_thread = NULL;
 
 static int RunTimer(void *unused)
 {
+	D(bug("SYSTimer: Entering RunTimer loop..."));
+
+	if(GfxBase==NULL)
+		GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37);
+
 	while ( timer_alive ) {
 		if ( SDL_timer_running ) {
 			SDL_ThreadedTimerCheck();
 		}
-		SDL_Delay(1);
+		if(GfxBase)
+			WaitTOF();  // Check the timer every fifth of seconds. Was SDL_Delay(1)->BusyWait!
+		else
+			Delay(1);
 	}
+	D(bug("SYSTimer: EXITING RunTimer loop..."));
 	return(0);
 }
 
 /* This is only called if the event thread is not running */
 int SDL_SYS_TimerInit(void)
 {
-#ifdef NO_AMIGADEBUG
-	fprintf(stderr,"Creo il thread per il timer (NOITMER)...\n");
-#endif
+	D(bug("Creo il thread per il timer (NOITMER)...\n"));
+
 	timer_alive = 1;
-	timer = SDL_CreateThread(RunTimer, NULL);
-	if ( timer == NULL )
+	timer_thread = SDL_CreateThread(RunTimer, NULL);
+	if ( timer_thread == NULL )
 	{
-#ifdef NO_AMIGADEBUG
-		fprintf(stderr,"Creazione del thread fallita...\n");
-#endif
+		D(bug("Creazione del thread fallita...\n"));
 
 		return(-1);
 	}
@@ -127,15 +250,15 @@
 void SDL_SYS_TimerQuit(void)
 {
 	timer_alive = 0;
-	if ( timer ) {
-		SDL_WaitThread(timer, NULL);
-		timer = NULL;
+	if ( timer_thread ) {
+		SDL_WaitThread(timer_thread, NULL);
+		timer_thread = NULL;
 	}
 }
 
 int SDL_SYS_StartTimer(void)
 {
-	SDL_SetError("Internal logic error: Linux uses threaded timer");
+	SDL_SetError("Internal logic error: AmigaOS uses threaded timer");
 	return(-1);
 }
 
--- a/src/video/cybergfx/SDL_amigaevents.c	Thu May 10 20:10:54 2001 +0000
+++ b/src/video/cybergfx/SDL_amigaevents.c	Thu May 10 20:13:29 2001 +0000
@@ -255,8 +255,8 @@
 
 	    /* Have we been resized? */
 	    case IDCMP_NEWSIZE: 
-			SDL_PrivateResize(SDL_Window->Width,
-		                  SDL_Window->Height);
+			SDL_PrivateResize(SDL_Window->Width-SDL_Window->BorderLeft-SDL_Window->BorderRight,
+		                  SDL_Window->Height-SDL_Window->BorderTop-SDL_Window->BorderBottom);
 			break;
 
 	    /* Have we been requested to quit? */
--- a/src/video/cybergfx/SDL_cgxaccel.c	Thu May 10 20:10:54 2001 +0000
+++ b/src/video/cybergfx/SDL_cgxaccel.c	Thu May 10 20:13:29 2001 +0000
@@ -214,6 +214,8 @@
 	}
 	else if(dst->hwdata)
 		BBB(src->hwdata->bmap,srcrect->x,srcrect->y,dst->hwdata->bmap,dstrect->x,dstrect->y,srcrect->w,srcrect->h,0xc0,0xff,NULL);
+
+	return 0;
 }
 
 int CGX_FillHWRect(_THIS,SDL_Surface *dst,SDL_Rect *dstrect,Uint32 color)
@@ -234,4 +236,5 @@
 
 		FillPixelArray(&temprp,dstrect->x,dstrect->y,dstrect->w,dstrect->h,color);
 	}
+	return 0;
 }
--- a/src/video/cybergfx/SDL_cgximage.c	Thu May 10 20:10:54 2001 +0000
+++ b/src/video/cybergfx/SDL_cgximage.c	Thu May 10 20:13:29 2001 +0000
@@ -57,6 +57,7 @@
 {
 	if(screen->flags&SDL_HWSURFACE)
 	{
+		Uint32 pitch;
 		SDL_Ximage=NULL;
 
 		if(!screen->hwdata)
@@ -66,14 +67,30 @@
 				return -1;
 			}
 			D(bug("Creating system accel struct\n"));
-			screen->hwdata->lock=0;
-			screen->hwdata->bmap=SDL_RastPort->BitMap;
-			screen->hwdata->videodata=this;
 		}
+		screen->hwdata->lock=0;
+		screen->hwdata->bmap=SDL_RastPort->BitMap;
+		screen->hwdata->videodata=this;
+
+		if(!(screen->hwdata->lock=LockBitMapTags(screen->hwdata->bmap,
+				LBMI_BASEADDRESS,(ULONG)&screen->pixels,
+				LBMI_BYTESPERROW,(ULONG)&pitch,TAG_DONE)))
+		{
+			free(screen->hwdata);
+			screen->hwdata=NULL;
+			return -1;
+		}
+		else
+		{
+			UnLockBitMap(screen->hwdata->lock);
+			screen->hwdata->lock=NULL;
+		}
+
+		screen->pitch=pitch;
 
 		this->UpdateRects = CGX_FakeUpdate;
 
-		D(bug("Accel video image configured.\n"));
+		D(bug("Accel video image configured (%lx, pitch %ld).\n",screen->pixels,screen->pitch));
 		return 0;
 	}
 
@@ -83,6 +100,18 @@
 		SDL_OutOfMemory();
 		return(-1);
 	}
+
+/*
+	{
+ 	        int bpp = screen->format->BytesPerPixel;
+			SDL_Ximage = XCreateImage(SDL_Display, SDL_Visual,
+					  this->hidden->depth, ZPixmap, 0,
+					  (char *)screen->pixels, 
+					  screen->w, screen->h,
+					  (bpp == 3) ? 32 : bpp * 8,
+					  0);
+	}
+*/
 	SDL_Ximage=screen->pixels;
 
 	if ( SDL_Ximage == NULL ) {
@@ -106,16 +135,35 @@
 	}
 }
 
+/* This is a hack to see whether this system has more than 1 CPU */
+static int num_CPU(void)
+{
+	return 1;
+}
+
 int CGX_ResizeImage(_THIS, SDL_Surface *screen, Uint32 flags)
 {
 	int retval;
 
+	D(bug("Chiamata ResizeImage!\n"));
+
 	CGX_DestroyImage(this, screen);
 
-	if ( flags & SDL_OPENGL ) {  /* No image when using GL */
+    if ( flags & SDL_OPENGL ) {  /* No image when using GL */
         	retval = 0;
-	} else {
+    } else {
 		retval = CGX_SetupImage(this, screen);
+		/* We support asynchronous blitting on the display */
+		if ( flags & SDL_ASYNCBLIT ) {
+			/* This is actually slower on single-CPU systems,
+			   probably because of CPU contention between the
+			   X server and the application.
+			   Note: Is this still true with XFree86 4.0?
+			*/
+			if ( num_CPU() > 1 ) {
+				screen->flags |= SDL_ASYNCBLIT;
+			}
+		}
 	}
 	return(retval);
 }
@@ -135,11 +183,11 @@
 	{
 		if(!(surface->hwdata=malloc(sizeof(struct private_hwdata))))
 			return -1;
-		
-		surface->hwdata->lock=NULL;
-		surface->hwdata->videodata=this;
 	}
 
+	surface->hwdata->lock=NULL;
+	surface->hwdata->videodata=this;
+
 	if(surface->hwdata->bmap=AllocBitMap(surface->w,surface->h,this->hidden->depth,BMF_MINPLANES,SDL_Display->RastPort.BitMap))
 	{
 		surface->flags|=SDL_HWSURFACE;
@@ -205,7 +253,7 @@
 	{
 		UnLockBitMap(surface->hwdata->lock);
 		surface->hwdata->lock=NULL;
-		surface->pixels=NULL;
+//		surface->pixels=NULL;
 	}
 }
 
--- a/src/video/cybergfx/SDL_cgxmodes.c	Thu May 10 20:10:54 2001 +0000
+++ b/src/video/cybergfx/SDL_cgxmodes.c	Thu May 10 20:13:29 2001 +0000
@@ -76,6 +76,13 @@
     *h = SDL_Display->Height;
 }
 
+static void move_cursor_to(_THIS, int x, int y)
+{
+/*    XWarpPointer(SDL_Display, None, SDL_Root, 0, 0, 0, 0, x, y); */
+
+/* DA FARE! */
+}
+
 static void add_visual(_THIS, int depth, int class)
 {
 	Uint32 tID;
--- a/src/video/cybergfx/SDL_cgxmodes_c.h	Thu May 10 20:10:54 2001 +0000
+++ b/src/video/cybergfx/SDL_cgxmodes_c.h	Thu May 10 20:13:29 2001 +0000
@@ -40,5 +40,10 @@
 extern SDL_Rect **CGX_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
 extern void CGX_FreeVideoModes(_THIS);
 extern int CGX_ResizeFullScreen(_THIS);
+/*
+extern void CGX_WaitMapped(_THIS, Window win);
+extern void CGX_WaitUnmapped(_THIS, Window win);
+extern void CGX_QueueEnterFullScreen(_THIS);
+*/
 extern int CGX_EnterFullScreen(_THIS);
 extern int CGX_LeaveFullScreen(_THIS);
--- a/src/video/cybergfx/SDL_cgxvideo.c	Thu May 10 20:10:54 2001 +0000
+++ b/src/video/cybergfx/SDL_cgxvideo.c	Thu May 10 20:13:29 2001 +0000
@@ -64,8 +64,7 @@
 static SDL_Surface *CGX_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
 static int CGX_ToggleFullScreen(_THIS, int on);
 static void CGX_UpdateMouse(_THIS);
-static int CGX_SetColors(_THIS, int firstcolor, int ncolors,
-			 SDL_Color *colors);
+static int CGX_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
 static void CGX_VideoQuit(_THIS);
 
 /* CGX driver bootstrap functions */
@@ -110,6 +109,7 @@
 			this->hidden->dbuffer=0;
 		}
 		CloseScreen(GFX_Display);
+		currently_fullscreen=0;
 	}
 	else
 		UnlockPubScreen(NULL,GFX_Display);
@@ -173,6 +173,9 @@
 	device->SetVideoMode = CGX_SetVideoMode;
 	device->ToggleFullScreen = CGX_ToggleFullScreen;
 	device->UpdateMouse = CGX_UpdateMouse;
+#ifdef XFREE86_XV
+	device->CreateYUVOverlay = X11_CreateYUVOverlay;
+#endif
 	device->SetColors = CGX_SetColors;
 	device->UpdateRects = NULL;
 	device->VideoQuit = CGX_VideoQuit;
@@ -192,8 +195,8 @@
 	device->GL_MakeCurrent = X11_GL_MakeCurrent;
 	device->GL_SwapBuffers = X11_GL_SwapBuffers;
 #endif
+	device->SetIcon = CGX_SetIcon;
 	device->SetCaption = CGX_SetCaption;
-	device->SetIcon = CGX_SetIcon;
 	device->IconifyWindow = NULL; /* CGX_IconifyWindow; */
 	device->GrabInput = NULL /* CGX_GrabInput*/; 
 	device->GetWMInfo = CGX_GetWMInfo;
@@ -211,10 +214,114 @@
 }
 
 VideoBootStrap CGX_bootstrap = {
-	"CGX", "Amiga CyberGFX video",
-	CGX_Available, CGX_CreateDevice
+	"CGX", "AmigaOS CyberGraphics", CGX_Available, CGX_CreateDevice
 };
 
+#if 0
+
+/* Create auxiliary (toplevel) windows with the current visual */
+static void create_aux_windows(_THIS)
+{
+    XSetWindowAttributes xattr;
+    XWMHints *hints;
+    XTextProperty titleprop, iconprop;
+    int def_vis = (SDL_Visual == DefaultVisual(SDL_Display, SDL_Screen));
+
+    /* Don't create any extra windows if we are being managed */
+    if ( SDL_windowid ) {
+	FSwindow = 0;
+	WMwindow = strtol(SDL_windowid, NULL, 0);
+        return;
+    }
+
+    if(FSwindow)
+	XDestroyWindow(SDL_Display, FSwindow);
+
+    xattr.override_redirect = True;
+    xattr.background_pixel = def_vis ? BlackPixel(SDL_Display, SDL_Screen) : 0;
+    xattr.border_pixel = 0;
+    xattr.colormap = SDL_XColorMap;
+
+    FSwindow = XCreateWindow(SDL_Display, SDL_Root, 0, 0, 32, 32, 0,
+			     this->hidden->depth, InputOutput, SDL_Visual,
+			     CWOverrideRedirect | CWBackPixel | CWBorderPixel
+			     | CWColormap,
+			     &xattr);
+
+    XSelectInput(SDL_Display, FSwindow, StructureNotifyMask);
+
+    /* Tell KDE to keep the fullscreen window on top */
+    {
+	XEvent ev;
+	long mask;
+
+	memset(&ev, 0, sizeof(ev));
+	ev.xclient.type = ClientMessage;
+	ev.xclient.window = SDL_Root;
+	ev.xclient.message_type = XInternAtom(SDL_Display,
+					      "KWM_KEEP_ON_TOP", False);
+	ev.xclient.format = 32;
+	ev.xclient.data.l[0] = FSwindow;
+	ev.xclient.data.l[1] = CurrentTime;
+	mask = SubstructureRedirectMask;
+	XSendEvent(SDL_Display, SDL_Root, False, mask, &ev);
+    }
+
+    hints = NULL;
+    titleprop.value = iconprop.value = NULL;
+    if(WMwindow) {
+	/* All window attributes must survive the recreation */
+	hints = XGetWMHints(SDL_Display, WMwindow);
+	XGetWMName(SDL_Display, WMwindow, &titleprop);
+	XGetWMIconName(SDL_Display, WMwindow, &iconprop);
+	XDestroyWindow(SDL_Display, WMwindow);
+    }
+
+    /* Create the window for windowed management */
+    /* (reusing the xattr structure above) */
+    WMwindow = XCreateWindow(SDL_Display, SDL_Root, 0, 0, 32, 32, 0,
+			     this->hidden->depth, InputOutput, SDL_Visual,
+			     CWBackPixel | CWBorderPixel | CWColormap,
+			     &xattr);
+
+    /* Set the input hints so we get keyboard input */
+    if(!hints) {
+	hints = XAllocWMHints();
+	hints->input = True;
+	hints->flags = InputHint;
+    }
+    XSetWMHints(SDL_Display, WMwindow, hints);
+    XFree(hints);
+    if(titleprop.value) {
+	XSetWMName(SDL_Display, WMwindow, &titleprop);
+	XFree(titleprop.value);
+    }
+    if(iconprop.value) {
+	XSetWMIconName(SDL_Display, WMwindow, &iconprop);
+	XFree(iconprop.value);
+    }
+
+    XSelectInput(SDL_Display, WMwindow,
+		 FocusChangeMask | KeyPressMask | KeyReleaseMask
+		 | PropertyChangeMask | StructureNotifyMask);
+
+    /* Set the class hints so we can get an icon (AfterStep) */
+    {
+	XClassHint *classhints;
+	classhints = XAllocClassHint();
+	if(classhints != NULL) {
+	    classhints->res_name = "SDL_App";
+	    classhints->res_class = "SDL_App";
+	    XSetClassHint(SDL_Display, WMwindow, classhints);
+	    XFree(classhints);
+	}
+    }
+
+    /* Allow the window to be deleted by the window manager */
+    WM_DELETE_WINDOW = XInternAtom(SDL_Display, "WM_DELETE_WINDOW", False);
+    XSetWMProtocols(SDL_Display, WMwindow, &WM_DELETE_WINDOW, 1);
+}
+#endif
 
 Uint32 MakeBitMask(_THIS,int type,int format,int *bpp)
 {
@@ -468,6 +575,8 @@
 	}
 	SDL_Visual = this->hidden->visuals[i].visual;
 
+//	SDL_XColorMap = SDL_DisplayColormap;
+
 	this->hidden->depth = this->hidden->visuals[i].depth;
 	D(bug("Setto la profiondita' dello schermo a: %ld\n",this->hidden->depth));
 	vformat->BitsPerPixel = this->hidden->visuals[i].depth; /* this->hidden->visuals[i].bpp; */
@@ -495,6 +604,10 @@
 		}
 	}
 
+	/* See if we have been passed a window to use */
+/*	SDL_windowid = getenv("SDL_WINDOWID"); */
+	SDL_windowid=NULL;
+
 	/* Create the fullscreen and managed windows */
 //	create_aux_windows(this);
 
@@ -517,45 +630,47 @@
 
 void CGX_DestroyWindow(_THIS, SDL_Surface *screen)
 {
-	/* Hide the managed window */
-	int was_fullscreen=0;
+	if ( ! SDL_windowid ) {
+		/* Hide the managed window */
+		int was_fullscreen=0;
 
-	if ( screen && (screen->flags & SDL_FULLSCREEN) ) {	
-		was_fullscreen=1;
-		screen->flags &= ~SDL_FULLSCREEN;
-		CGX_LeaveFullScreen(this);
-	}
+		if ( screen && (screen->flags & SDL_FULLSCREEN) ) {	
+			was_fullscreen=1;
+			screen->flags &= ~SDL_FULLSCREEN;
+//			CGX_LeaveFullScreen(this); tolto x crash
+		}
 
-	/* Destroy the output window */
-	if ( SDL_Window ) {
-		CloseWindow(SDL_Window);
-		SDL_Window=NULL;
-	}
+		/* Destroy the output window */
+		if ( SDL_Window ) {
+			CloseWindow(SDL_Window);
+			SDL_Window=NULL;
+		}
 
-	/* Free the colormap entries */
-	if ( SDL_XPixels ) {
-		int numcolors;
-		unsigned long pixel;
+		/* Free the colormap entries */
+		if ( SDL_XPixels ) {
+			int numcolors;
+			unsigned long pixel;
 
-		if(this->screen->format&&this->hidden->depth==8&&!was_fullscreen)
-		{
-			numcolors = 1<<this->screen->format->BitsPerPixel;
+			if(this->screen->format&&this->hidden->depth==8&&!was_fullscreen)
+			{
+				numcolors = 1<<this->screen->format->BitsPerPixel;
 
-			if(numcolors>256)
-				numcolors=256;
+				if(numcolors>256)
+					numcolors=256;
 
-			if(!was_fullscreen&&this->hidden->depth==8)
-			{
-				for ( pixel=0; pixel<numcolors; pixel++ ) 
+				if(!was_fullscreen&&this->hidden->depth==8)
 				{
-					if(SDL_XPixels[pixel]>=0)
-						ReleasePen(GFX_Display->ViewPort.ColorMap,SDL_XPixels[pixel]);
+					for ( pixel=0; pixel<numcolors; pixel++ ) 
+					{
+						if(SDL_XPixels[pixel]>=0)
+							ReleasePen(GFX_Display->ViewPort.ColorMap,SDL_XPixels[pixel]);
+					}
 				}
 			}
-		}
-		free(SDL_XPixels);
-		SDL_XPixels = NULL;
-	} 
+			free(SDL_XPixels);
+			SDL_XPixels = NULL;
+		} 
+	}
 }
 
 static void CGX_SetSizeHints(_THIS, int w, int h, Uint32 flags)
@@ -590,7 +705,13 @@
 	if ( SDL_Window ) {
 		CGX_DestroyWindow(this, screen);
 	}
-	SDL_Window = 0;
+
+	/* See if we have been given a window id */
+	if ( SDL_windowid ) {
+		SDL_Window = (struct Window *)atol(SDL_windowid);
+	} else {
+		SDL_Window = 0;
+	}
 
 	/* find out which visual we are going to use */
 #if 0
@@ -656,6 +777,11 @@
 	}
 
 	/* Create the appropriate colormap */
+/*
+	if ( SDL_XColorMap != SDL_DisplayColormap ) {
+		XFreeColormap(SDL_Display, SDL_XColorMap);
+	}
+*/
 	if ( GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_PIXFMT)==PIXFMT_LUT8 || bpp==8 ) {
 	    int ncolors;
 	    D(bug("Alloco XPixels x la palette...\n"));
@@ -681,32 +807,70 @@
 		flags |= SDL_HWPALETTE;
 
 	    if ( flags & SDL_HWPALETTE ) {
-		screen->flags |= SDL_HWPALETTE;
+			screen->flags |= SDL_HWPALETTE;
+/*
+			SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root,
+		                                SDL_Visual, AllocAll);
+*/
+	    } else {
+/*
+			SDL_XColorMap = SDL_DisplayColormap;
+*/
 	    }
+	} else {
+/*
+	    SDL_XColorMap = XCreateColormap(SDL_Display, SDL_Root,
+	                                    SDL_Visual, AllocNone);
+*/
 	}
 
+	/* Recreate the auxiliary windows, if needed (required for GL) */
+/*
+	if ( vis_change )
+	    create_aux_windows(this);
+*/
+
 	/* resize the (possibly new) window manager window */
 
 	/* Create (or use) the X11 display window */
-	if ( flags & SDL_OPENGL ) {
-		return(-1);
-	} else {
-		if(flags & SDL_FULLSCREEN)
-			SDL_Window = OpenWindowTags(NULL,WA_Width,w,WA_Height,h,
+	if ( !SDL_windowid ) {
+		if ( flags & SDL_OPENGL ) {
+			return(-1);
+		} 
+		else 
+		{
+			if(flags & SDL_FULLSCREEN)
+			{
+				SDL_Window = OpenWindowTags(NULL,WA_Width,w,WA_Height,h,
 											WA_Flags,WFLG_ACTIVATE|WFLG_RMBTRAP|WFLG_BORDERLESS|WFLG_BACKDROP|WFLG_REPORTMOUSE,
 											WA_IDCMP,IDCMP_RAWKEY|IDCMP_MOUSEBUTTONS|IDCMP_MOUSEMOVE,
 											WA_CustomScreen,(ULONG)SDL_Display,
 											TAG_DONE);
-		else
-			SDL_Window = OpenWindowTags(NULL,WA_InnerWidth,w,WA_InnerHeight,h,
-											WA_Flags,WFLG_REPORTMOUSE|WFLG_ACTIVATE|WFLG_RMBTRAP|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_DRAGBAR| ((screen->flags&SDL_RESIZABLE) ? WFLG_SIZEGADGET|WFLG_SIZEBBOTTOM : 0),
+
+				D(bug("Apro finestra backdrop %ldx%ld su %lx!\n",w,h,SDL_Display));
+			}
+			else
+			{
+				SDL_Window = OpenWindowTags(NULL,WA_InnerWidth,w,WA_InnerHeight,h,
+											WA_Flags,WFLG_REPORTMOUSE|WFLG_ACTIVATE|WFLG_RMBTRAP | ((flags&SDL_NOFRAME) ? 0 : (WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_DRAGBAR | ((flags&SDL_RESIZABLE) ? WFLG_SIZEGADGET|WFLG_SIZEBBOTTOM : 0))),
 											WA_IDCMP,IDCMP_RAWKEY|IDCMP_CLOSEWINDOW|IDCMP_MOUSEBUTTONS|IDCMP_NEWSIZE|IDCMP_MOUSEMOVE,
 											WA_PubScreen,(ULONG)SDL_Display,
-											TAG_DONE);
+														TAG_DONE);
+				D(bug("Apro finestra %ldx%ld sul wb!\n",w,h));
+			}
+
+		}
+		/* Only manage our input if we own the window */
+/*
+		XSelectInput(SDL_Display, SDL_Window,
+					( EnterWindowMask | LeaveWindowMask
+					| ButtonPressMask | ButtonReleaseMask
+					| PointerMotionMask | ExposureMask ));
+*/
+
+		if(!SDL_Window)
+			return -1;
 	}
-	/* Only manage our input if we own the window */
-	if(!SDL_Window)
-		return -1;
 
 	this->hidden->BytesPerPixel=GetCyberMapAttr(SDL_Window->RPort->BitMap,CYBRMATTR_BPPIX);
 
@@ -736,45 +900,69 @@
 	if(flags&SDL_HWSURFACE)
 		screen->flags|=SDL_HWSURFACE;
 
-	CGX_SetSizeHints(this, w, h, flags);
-	current_w = w;
-	current_h = h;
+	if( !SDL_windowid ) {
+	    CGX_SetSizeHints(this, w, h, flags);
+		current_w = w;
+		current_h = h;
+	}
+
+	/* Set our colormaps when not setting a GL mode */
+/*
+	if ( ! (flags & SDL_OPENGL) ) {
+		XSetWindowColormap(SDL_Display, SDL_Window, SDL_XColorMap);
+	}
+*/
 
 	/* Map them both and go fullscreen, if requested */
-	if ( flags & SDL_FULLSCREEN ) {
-		screen->flags |= SDL_FULLSCREEN;
-		currently_fullscreen=1;
-//		CGX_EnterFullScreen(this); Ci siamo gia'!
-	} else {
-		screen->flags &= ~SDL_FULLSCREEN;
+	if ( ! SDL_windowid ) {
+		if ( flags & SDL_FULLSCREEN ) {
+			screen->flags |= SDL_FULLSCREEN;
+			currently_fullscreen=1;
+//			CGX_EnterFullScreen(this); Ci siamo gia'!
+		} else {
+			screen->flags &= ~SDL_FULLSCREEN;
+		}
 	}
+	screen->w = w;
+	screen->h = h;
+	screen->pitch = SDL_CalculatePitch(screen);
+	CGX_ResizeImage(this, screen, flags);
+
 	return(0);
 }
 
 int CGX_ResizeWindow(_THIS,
 			SDL_Surface *screen, int w, int h, Uint32 flags)
 {
-	/* Resize the window manager window */
-	CGX_SetSizeHints(this, w, h, flags);
-	current_w = w;
-	current_h = h;
+	if ( ! SDL_windowid ) {
+		/* Resize the window manager window */
+		CGX_SetSizeHints(this, w, h, flags);
+		current_w = w;
+		current_h = h;
 
-	ChangeWindowBox(SDL_Window,SDL_Window->LeftEdge,SDL_Window->TopEdge, w+SDL_Window->BorderLeft+SDL_Window->BorderRight,
-				h+SDL_Window->BorderTop+SDL_Window->BorderBottom);
+		ChangeWindowBox(SDL_Window,SDL_Window->LeftEdge,SDL_Window->TopEdge, w+SDL_Window->BorderLeft+SDL_Window->BorderRight,
+					h+SDL_Window->BorderTop+SDL_Window->BorderBottom);
 
-	/* Resize the fullscreen and display windows */
-	if ( flags & SDL_FULLSCREEN ) {
-		if ( screen->flags & SDL_FULLSCREEN ) {
-			CGX_ResizeFullScreen(this);
+		/* Resize the fullscreen and display windows */
+/*
+		if ( flags & SDL_FULLSCREEN ) {
+			if ( screen->flags & SDL_FULLSCREEN ) {
+				CGX_ResizeFullScreen(this);
+			} else {
+				screen->flags |= SDL_FULLSCREEN;
+				CGX_EnterFullScreen(this);
+			}
 		} else {
-			screen->flags |= SDL_FULLSCREEN;
-			CGX_EnterFullScreen(this);
+			if ( screen->flags & SDL_FULLSCREEN ) {
+				screen->flags &= ~SDL_FULLSCREEN;
+				CGX_LeaveFullScreen(this);
+			}
 		}
-	} else {
-		if ( screen->flags & SDL_FULLSCREEN ) {
-			screen->flags &= ~SDL_FULLSCREEN;
-			CGX_LeaveFullScreen(this);
-		}
+*/
+		screen->w = w;
+		screen->h = h;
+		screen->pitch = SDL_CalculatePitch(screen);
+		CGX_ResizeImage(this, screen, flags);
 	}
 	return(0);
 }
@@ -783,24 +971,51 @@
 				int width, int height, int bpp, Uint32 flags)
 {
 	Uint32 saved_flags;
+	int needcreate=0;
 
 	/* Lock the event thread, in multi-threading environments */
 	SDL_Lock_EventThread();
 
+// Check if the window needs to be closed or can be resized
+
+	if( (flags&SDL_FULLSCREEN) || (current->flags&SDL_FULLSCREEN && !(flags&SDL_FULLSCREEN)))
+		needcreate=1;
+
 // Check if we need to close an already existing videomode... 
 
 	if(current->flags&SDL_FULLSCREEN && !(flags&SDL_FULLSCREEN))
 	{
+		unsigned long i;
 		CGX_DestroyImage(this,current);
 		CGX_DestroyWindow(this,current);
 		DestroyScreen(this);
+		D(bug("Distrutte immagine, finestra e schermo!\n"));
+		GFX_Display=SDL_Display=LockPubScreen(NULL);
+
+		bpp=this->hidden->depth=GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH);
+
+		for ( i = 0; i < this->hidden->nvisuals; i++ ) {
+			if ( this->hidden->visuals[i].depth == bpp ) /* era .depth */
+				break;
+		}
+		if ( i == this->hidden->nvisuals ) {
+			SDL_SetError("No matching visual for requested depth");
+			return NULL;	/* should never happen */
+		}
+		SDL_Visual = this->hidden->visuals[i].visual;
+
+		D(bug("Setto la profiondita' dello schermo a: %ld\n",this->hidden->depth));
+		
 	}
 	/* Check the combination of flags we were passed */
 	if ( flags & SDL_FULLSCREEN ) {
 		int i;
 	
 		/* Clear fullscreen flag if not supported */
-		if(current->flags&SDL_FULLSCREEN )
+		if ( SDL_windowid ) {
+			flags &= ~SDL_FULLSCREEN;
+		}
+		else if(current->flags&SDL_FULLSCREEN )
 		{
 			if(current->w!=width ||
 				current->h!=height ||
@@ -930,7 +1145,7 @@
 	saved_flags = current->flags;
 
 	if (SDL_Window && (saved_flags&SDL_OPENGL) == (flags&SDL_OPENGL)
-	    && bpp == current->format->BitsPerPixel) {
+	    && bpp == current->format->BitsPerPixel && !needcreate) {
 		if (CGX_ResizeWindow(this, current, width, height, flags) < 0) {
 			current = NULL;
 			goto done;
@@ -942,6 +1157,7 @@
 		}
 	}
 
+#if 0
 	/* Set up the new mode framebuffer */
 	if ( ((current->w != width) || (current->h != height)) ||
              ((saved_flags&SDL_OPENGL) != (flags&SDL_OPENGL)) ) {
@@ -950,6 +1166,8 @@
 		current->pitch = SDL_CalculatePitch(current);
 		CGX_ResizeImage(this, current, flags);
 	}
+#endif
+
 	current->flags |= (flags&SDL_RESIZABLE); // Resizable only if the user asked it
 
   done:
@@ -964,6 +1182,11 @@
 {
 	Uint32 event_thread;
 
+	/* Don't switch if we don't own the window */
+	if ( SDL_windowid ) {
+		return(0);
+	}
+
 	/* Don't lock if we are the event thread */
 	event_thread = SDL_EventThreadID();
 	if ( event_thread && (SDL_ThreadID() == event_thread) ) {
@@ -1090,9 +1313,6 @@
 
 	/* Check to make sure we have a colormap allocated */
 
-// It's not needed to reload the whole palette each time on Amiga!
-//	ncolors = this->screen->format->palette->ncolors;
-
 	/* It's easy if we have a hidden colormap */
 	if ( (this->screen->flags & SDL_HWPALETTE) && currently_fullscreen ) 
 	{
@@ -1104,9 +1324,9 @@
 //		D(bug("Setting %ld colors on an HWPALETTE screen\n",ncolors));
 
 		for ( i=0; i<ncolors; i++ ) {
-			xcmap[i*3+1] = colors[i].r<<24;
-			xcmap[i*3+2] = colors[i].g<<24;
-			xcmap[i*3+3] = colors[i].b<<24;
+			xcmap[i*3+1] = colors[i+firstcolor].r<<24;
+			xcmap[i*3+2] = colors[i+firstcolor].g<<24;
+			xcmap[i*3+3] = colors[i+firstcolor].b<<24;
 		}
 		xcmap[ncolors*3+1]=0;
 		LoadRGB32(&GFX_Display->ViewPort,xcmap);
@@ -1119,7 +1339,6 @@
 			return(0);
 		}
 
-		colors = this->screen->format->palette->colors;
 		if(this->hidden->depth==8)
 		{
 // In this case I have to unalloc and realloc the full palette
@@ -1178,6 +1397,22 @@
 		SDL_VideoSurface=NULL;
 		CGX_FreeVideoModes(this);
 
+/*
+		if ( SDL_iconcolors ) {
+			unsigned long pixel;
+			int numcolors =
+				((this->screen->format)->palette)->ncolors;
+			for ( pixel=0; pixel<numcolors; ++pixel ) {
+				while ( SDL_iconcolors[pixel] > 0 ) {
+					XFreeColors(SDL_Display,
+						SDL_DisplayColormap,&pixel,1,0);
+					--SDL_iconcolors[pixel];
+				}
+			}
+			free(SDL_iconcolors);
+			SDL_iconcolors = NULL;
+		} 
+*/
 		/* Free that blank cursor */
 		if ( SDL_BlankCursor != NULL ) {
 			FreeMem(SDL_BlankCursor,16);
--- a/src/video/cybergfx/SDL_cgxvideo.h	Thu May 10 20:10:54 2001 +0000
+++ b/src/video/cybergfx/SDL_cgxvideo.h	Thu May 10 20:13:29 2001 +0000
@@ -69,6 +69,8 @@
     struct Window *SDL_Window;	/* Shared by both displays (no X security?) */
     unsigned char *BlankCursor;	/* The invisible cursor */
 
+    char *SDL_windowid;		/* Flag: true if we have been passed a window */
+
     /* The variables used for displaying graphics */
     Uint8 *Ximage;		/* The X image for our window */
     int swap_pixels;		/* Flag: true if display is swapped endian */
@@ -134,6 +136,7 @@
 #define SDL_Window		(this->hidden->SDL_Window)
 #define WM_DELETE_WINDOW	(this->hidden->WM_DELETE_WINDOW)
 #define SDL_BlankCursor		(this->hidden->BlankCursor)
+#define SDL_windowid		(this->hidden->SDL_windowid)
 #define SDL_Ximage		(this->hidden->Ximage)
 #define SDL_GC			(this->hidden->gc)
 #define swap_pixels		(this->hidden->swap_pixels)
@@ -152,6 +155,9 @@
 #define SDL_XPixels		(this->hidden->XPixels)
 #define SDL_iconcolors		(this->hidden->iconcolors)
 
+/* Used to get the X cursor from a window-manager specific cursor */
+// extern Cursor SDL_GetWMXCursor(WMcursor *cursor);
+
 extern int CGX_CreateWindow(_THIS, SDL_Surface *screen,
 			    int w, int h, int bpp, Uint32 flags);
 extern int CGX_ResizeWindow(_THIS,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/cybergfx/SDL_cgxyuv.c	Thu May 10 20:13:29 2001 +0000
@@ -0,0 +1,191 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@devolution.com
+*/
+
+#ifdef SAVE_RCSID
+static char rcsid =
+ "@(#) $Id$";
+#endif
+
+/* This is the XFree86 Xv extension implementation of YUV video overlays */
+
+#ifdef XFREE86_XV
+
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <X11/extensions/XShm.h>
+#include <X11/extensions/Xvlib.h>
+
+#include "SDL_error.h"
+#include "SDL_video.h"
+#include "SDL_x11yuv_c.h"
+#include "SDL_yuvfuncs.h"
+
+/* The functions used to manipulate software video overlays */
+static struct private_yuvhwfuncs x11_yuvfuncs = {
+	X11_LockYUVOverlay,
+	X11_UnlockYUVOverlay,
+	X11_DisplayYUVOverlay,
+	X11_FreeYUVOverlay
+};
+
+struct private_yuvhwdata {
+	int port;
+	XShmSegmentInfo yuvshm;
+	XvImage *image;
+};
+
+
+SDL_Overlay *X11_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display)
+{
+	SDL_Overlay *overlay;
+	struct private_yuvhwdata *hwdata;
+	int xv_port;
+	int i, j;
+	int adaptors;
+	XvAdaptorInfo *ainfo;
+	XShmSegmentInfo *yuvshm;
+
+	xv_port = -1;
+	if ( (Success == XvQueryExtension(GFX_Display, &j, &j, &j, &j, &j)) &&
+	     (Success == XvQueryAdaptors(GFX_Display,
+	                                 RootWindow(GFX_Display, SDL_Screen),
+	                                 &adaptors, &ainfo)) ) {
+		for ( i=0; (i<adaptors) && (xv_port == -1); ++i ) {
+			if ( (ainfo[i].type & XvInputMask) &&
+			     (ainfo[i].type & XvImageMask) ) {
+				int num_formats;
+				XvImageFormatValues *formats;
+				formats = XvListImageFormats(GFX_Display,
+				              ainfo[i].base_id, &num_formats);
+				for ( j=0; j<num_formats; ++j ) {
+					if ( (Uint32)formats[j].id == format ) {
+						xv_port = ainfo[i].base_id;
+						break;
+					}
+				}
+			}
+		}
+	}
+	if ( xv_port == -1 ) {
+		SDL_SetError("No available video ports for requested format");
+		return(NULL);
+	}
+
+	/* Create the overlay structure */
+	overlay = (SDL_Overlay *)malloc(sizeof *overlay);
+	if ( overlay == NULL ) {
+		SDL_OutOfMemory();
+		return(NULL);
+	}
+	memset(overlay, 0, (sizeof *overlay));
+
+	/* Fill in the basic members */
+	overlay->format = format;
+	overlay->w = width;
+	overlay->h = height;
+
+	/* Set up the YUV surface function structure */
+	overlay->hwfuncs = &x11_yuvfuncs;
+
+	/* Create the pixel data and lookup tables */
+	hwdata = (struct private_yuvhwdata *)malloc(sizeof *hwdata);
+	overlay->hwdata = hwdata;
+	if ( hwdata == NULL ) {
+		SDL_OutOfMemory();
+		SDL_FreeYUVOverlay(overlay);
+		return(NULL);
+	}
+	yuvshm = &hwdata->yuvshm;
+	memset(yuvshm, 0, sizeof(*yuvshm));
+	hwdata->port = xv_port;
+	hwdata->image = XvShmCreateImage(GFX_Display, xv_port, format,
+	                                 0, width, height, yuvshm);
+	if ( hwdata->image == NULL ) {
+		SDL_OutOfMemory();
+		SDL_FreeYUVOverlay(overlay);
+		return(NULL);
+	}
+	yuvshm->shmid = shmget(IPC_PRIVATE, hwdata->image->data_size,
+	                       IPC_CREAT | 0777);
+	if ( yuvshm->shmid < 0 ) {
+		SDL_SetError("Unable to get %d bytes shared memory",
+		             hwdata->image->data_size);
+		SDL_FreeYUVOverlay(overlay);
+		return(NULL);
+	}
+	yuvshm->shmaddr  = (caddr_t) shmat(yuvshm->shmid, 0, 0);
+	yuvshm->readOnly = False;
+	hwdata->image->data = yuvshm->shmaddr;
+
+	XShmAttach(GFX_Display, yuvshm);
+	XSync(GFX_Display, False);
+	shmctl(yuvshm->shmid, IPC_RMID, 0);
+
+	/* We're all done.. */
+	return(overlay);
+}
+
+int X11_LockYUVOverlay(_THIS, SDL_Overlay *overlay)
+{
+	overlay->pixels = overlay->hwdata->image->data;
+	/* What should the pitch be set to? */
+	return(0);
+}
+
+void X11_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay)
+{
+	overlay->pixels = NULL;
+}
+
+int X11_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect)
+{
+	struct private_yuvhwdata *hwdata;
+
+	hwdata = overlay->hwdata;
+	XvShmPutImage(GFX_Display, hwdata->port, SDL_Window, SDL_GC,
+	              hwdata->image, 0, 0, overlay->w, overlay->h,
+	              dstrect->x, dstrect->y, dstrect->w, dstrect->h, False);
+	XSync(GFX_Display, False);
+	return(0);
+}
+
+void X11_FreeYUVOverlay(_THIS, SDL_Overlay *overlay)
+{
+	struct private_yuvhwdata *hwdata;
+
+	hwdata = overlay->hwdata;
+	if ( hwdata ) {
+		if ( hwdata->yuvshm.shmaddr ) {
+			XShmDetach(GFX_Display, &hwdata->yuvshm);
+			shmdt(hwdata->yuvshm.shmaddr);
+		}
+		if ( hwdata->image ) {
+			XFree(hwdata->image);
+		}
+		free(hwdata);
+	}
+}
+
+#endif /* XFREE86_XV */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/cybergfx/SDL_cgxyuv_c.h	Thu May 10 20:13:29 2001 +0000
@@ -0,0 +1,45 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@devolution.com
+*/
+
+#ifdef SAVE_RCSID
+static char rcsid =
+ "@(#) $Id$";
+#endif
+
+/* This is the XFree86 Xv extension implementation of YUV video overlays */
+
+#include "SDL_video.h"
+#include "SDL_cgxvideo.h"
+
+#ifdef XFREE86_XV
+
+extern SDL_Overlay *X11_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display);
+
+extern int X11_LockYUVOverlay(_THIS, SDL_Overlay *overlay);
+
+extern void X11_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay);
+
+extern int X11_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect);
+
+extern void X11_FreeYUVOverlay(_THIS, SDL_Overlay *overlay);
+
+#endif /* XFREE86_XV */
--- a/src/video/default_cursor.h	Thu May 10 20:10:54 2001 +0000
+++ b/src/video/default_cursor.h	Thu May 10 20:13:29 2001 +0000
@@ -1,6 +1,6 @@
 /*
     SDL - Simple DirectMedia Layer
-    Copyright (C) 1997, 1998, 1999, 2000  Sam Lantinga
+    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
 
     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Library General Public