From 29b0361a47f30a0428a05091466826c770cf77a1 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 10 May 2001 20:13:29 +0000 Subject: [PATCH] Updated the Amiga OS port of SDL (thanks Gabriele) --- BUGS | 12 - README.AmigaOS | 50 ++ configure.in | 1 + src/audio/SDL_audio.c | 87 ++- src/audio/SDL_sysaudio.h | 7 +- src/audio/amigaos/Makefile.am | 2 +- src/audio/amigaos/SDL_ahiaudio.c | 116 ++-- .../{SDL_lowaudio.h => SDL_ahiaudio.h} | 21 +- src/audio/amigaos/SDL_audio.c | 532 ------------------ src/audio/amigaos/SDL_sysaudio.h | 142 ----- src/joystick/amigaos/Makefile.am | 8 + src/joystick/amigaos/SDL_sysjoystick.c | 240 ++++++++ src/thread/amigaos/SDL_syssem.c | 78 +-- src/thread/amigaos/SDL_systhread.c | 33 +- src/thread/amigaos/SDL_thread.c | 12 + src/timer/amigaos/SDL_systimer.c | 215 +++++-- src/video/cybergfx/SDL_amigaevents.c | 4 +- src/video/cybergfx/SDL_cgxaccel.c | 3 + src/video/cybergfx/SDL_cgximage.c | 68 ++- src/video/cybergfx/SDL_cgxmodes.c | 7 + src/video/cybergfx/SDL_cgxmodes_c.h | 5 + src/video/cybergfx/SDL_cgxvideo.c | 403 ++++++++++--- src/video/cybergfx/SDL_cgxvideo.h | 6 + src/video/cybergfx/SDL_cgxyuv.c | 191 +++++++ src/video/cybergfx/SDL_cgxyuv_c.h | 45 ++ src/video/default_cursor.h | 2 +- 26 files changed, 1379 insertions(+), 911 deletions(-) create mode 100644 README.AmigaOS rename src/audio/amigaos/{SDL_lowaudio.h => SDL_ahiaudio.h} (86%) delete mode 100644 src/audio/amigaos/SDL_audio.c delete mode 100644 src/audio/amigaos/SDL_sysaudio.h create mode 100644 src/joystick/amigaos/Makefile.am create mode 100644 src/joystick/amigaos/SDL_sysjoystick.c create mode 100644 src/video/cybergfx/SDL_cgxyuv.c create mode 100644 src/video/cybergfx/SDL_cgxyuv_c.h diff --git a/BUGS b/BUGS index e285b9436..c729b8677 100644 --- a/BUGS +++ b/BUGS @@ -169,9 +169,6 @@ QNX: -= NOT YET SUPPORTED =- 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 @@ AmigaOS: -= NOT YET SUPPORTED =- 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 diff --git a/README.AmigaOS b/README.AmigaOS new file mode 100644 index 000000000..dffb850d0 --- /dev/null +++ b/README.AmigaOS @@ -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 diff --git a/configure.in b/configure.in index 4f47e5024..e37ca55cc 100644 --- a/configure.in +++ b/configure.in @@ -1936,6 +1936,7 @@ src/video/photon/Makefile 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 diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 5e5cfbf17..e96f63dca 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -76,6 +76,10 @@ static AudioBootStrap *bootstrap[] = { #ifdef _AIX &Paud_bootstrap, #endif +#ifdef ENABLE_AHI + &AHI_bootstrap, +#endif + NULL }; SDL_AudioDevice *current_audio = NULL; @@ -84,6 +88,9 @@ SDL_AudioDevice *current_audio = NULL; 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 @@ int SDL_RunAudio(void *audiop) 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 @@ int SDL_RunAudio(void *audiop) /* 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 @@ int SDL_RunAudio(void *audiop) } 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 @@ int SDL_RunAudio(void *audiop) 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 @@ int SDL_RunAudio(void *audiop) /* 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 @@ int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained) 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 @@ int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained) } } +#ifndef ENABLE_AHI /* Start the audio thread if necessary */ switch (audio->opened) { case 1: @@ -381,6 +456,12 @@ int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained) /* 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 @@ void SDL_AudioQuit(void) } 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; diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h index 709f9de1f..32db77ec4 100644 --- a/src/audio/SDL_sysaudio.h +++ b/src/audio/SDL_sysaudio.h @@ -126,14 +126,17 @@ extern AudioBootStrap DSOUND_bootstrap; #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 */ diff --git a/src/audio/amigaos/Makefile.am b/src/audio/amigaos/Makefile.am index 1ee53ef16..99d95d8ac 100644 --- a/src/audio/amigaos/Makefile.am +++ b/src/audio/amigaos/Makefile.am @@ -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) diff --git a/src/audio/amigaos/SDL_ahiaudio.c b/src/audio/amigaos/SDL_ahiaudio.c index 6ff717a8c..d79fdb3d5 100644 --- a/src/audio/amigaos/SDL_ahiaudio.c +++ b/src/audio/amigaos/SDL_ahiaudio.c @@ -27,13 +27,17 @@ static char rcsid = "@(#) $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 +#include +#include #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 void AHI_CloseAudio(_THIS); 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 @@ static void AHI_PlayAudio(_THIS) /* 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 @@ static void AHI_CloseAudio(_THIS) { 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 @@ static int AHI_OpenAudio(_THIS, SDL_AudioSpec *spec) 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 @@ static int AHI_OpenAudio(_THIS, SDL_AudioSpec *spec) 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 @@ static int AHI_OpenAudio(_THIS, SDL_AudioSpec *spec) } } + 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 @@ static int AHI_OpenAudio(_THIS, SDL_AudioSpec *spec) 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 @@ static int AHI_OpenAudio(_THIS, SDL_AudioSpec *spec) 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); diff --git a/src/audio/amigaos/SDL_lowaudio.h b/src/audio/amigaos/SDL_ahiaudio.h similarity index 86% rename from src/audio/amigaos/SDL_lowaudio.h rename to src/audio/amigaos/SDL_ahiaudio.h index cea9f8379..3c73fa20c 100644 --- a/src/audio/amigaos/SDL_lowaudio.h +++ b/src/audio/amigaos/SDL_ahiaudio.h @@ -25,15 +25,20 @@ static char rcsid = "@(#) $Id$"; #endif -#ifndef _SDL_lowaudio_h -#define _SDL_lowaudio_h - -// #include +#ifndef _SDL_ahiaudio_h +#define _SDL_ahiaudio_h + +#include +#include +#ifdef __SASC +#include +#else +#include +#endif +#include +#include "mydebug.h" #include "SDL_sysaudio.h" -#include -#include -#include /* Hidden "this" pointer for the audio functions */ #define _THIS SDL_AudioDevice *this @@ -55,4 +60,4 @@ struct SDL_PrivateAudioData { #define current_buffer (this->hidden->current_buffer) #define playing (this->hidden->playing) -#endif /* _SDL_lowaudio_h */ +#endif /* _SDL_ahiaudio_h */ diff --git a/src/audio/amigaos/SDL_audio.c b/src/audio/amigaos/SDL_audio.c deleted file mode 100644 index 5a1b343db..000000000 --- a/src/audio/amigaos/SDL_audio.c +++ /dev/null @@ -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 -#include -#include -#include - -#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; -} diff --git a/src/audio/amigaos/SDL_sysaudio.h b/src/audio/amigaos/SDL_sysaudio.h deleted file mode 100644 index 2cc12b516..000000000 --- a/src/audio/amigaos/SDL_sysaudio.h +++ /dev/null @@ -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 -#include -#ifdef __SASC -#include -#else -#include -#endif - -#include -#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 */ diff --git a/src/joystick/amigaos/Makefile.am b/src/joystick/amigaos/Makefile.am new file mode 100644 index 000000000..e9e54540b --- /dev/null +++ b/src/joystick/amigaos/Makefile.am @@ -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 diff --git a/src/joystick/amigaos/SDL_sysjoystick.c b/src/joystick/amigaos/SDL_sysjoystick.c new file mode 100644 index 000000000..dc7b9ea35 --- /dev/null +++ b/src/joystick/amigaos/SDL_sysjoystick.c @@ -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 /* For the definition of NULL */ + +#include +#ifdef __SASC +#include +#include +#include +#else +#include +#include +#include +#endif +#include "mydebug.h" + +extern struct ExecBase *SysBase; +extern struct GfxBase *GfxBase; +#include + +#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;inbuttons;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; +} + diff --git a/src/thread/amigaos/SDL_syssem.c b/src/thread/amigaos/SDL_syssem.c index 8a1431adb..51fd167a5 100644 --- a/src/thread/amigaos/SDL_syssem.c +++ b/src/thread/amigaos/SDL_syssem.c @@ -25,7 +25,7 @@ static char rcsid = "@(#) $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 @@ static char rcsid = 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 *SDL_CreateSemaphore(Uint32 initial_value) 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 @@ void SDL_DestroySemaphore(SDL_sem *sem) int SDL_SemTryWait(SDL_sem *sem) { - int retval; - if ( ! sem ) { SDL_SetError("Passed a NULL semaphore"); return -1; @@ -84,17 +84,17 @@ int SDL_SemTryWait(SDL_sem *sem) 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 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) 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 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) // 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 @@ Uint32 SDL_SemValue(SDL_sem *sem) value = 0; if ( sem ) { value = sem->Sem.ss_NestCount; +// SDL_UnlockMutex(sem->count_lock); } return value; } @@ -161,6 +161,14 @@ int SDL_SemPost(SDL_sem *sem) 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; } diff --git a/src/thread/amigaos/SDL_systhread.c b/src/thread/amigaos/SDL_systhread.c index 7df32ccdb..2755728b1 100644 --- a/src/thread/amigaos/SDL_systhread.c +++ b/src/thread/amigaos/SDL_systhread.c @@ -25,7 +25,7 @@ static char rcsid = "@(#) $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 @@ typedef struct { 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 @@ Uint32 RunThread(char *args __asm("a0") ) return(0); } +#else + +#include + +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 @@ Uint32 SDL_ThreadID(void) void SDL_SYS_WaitThread(SDL_Thread *thread) { + SetSignal(0L,SIGBREAKF_CTRL_F|SIGBREAKF_CTRL_C); Wait(SIGBREAKF_CTRL_F|SIGBREAKF_CTRL_C); } diff --git a/src/thread/amigaos/SDL_thread.c b/src/thread/amigaos/SDL_thread.c index bd2b16b9e..8810ae793 100644 --- a/src/thread/amigaos/SDL_thread.c +++ b/src/thread/amigaos/SDL_thread.c @@ -265,6 +265,18 @@ void SDL_WaitThread(SDL_Thread *thread, int *status) } } +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 ) { diff --git a/src/timer/amigaos/SDL_systimer.c b/src/timer/amigaos/SDL_systimer.c index f49ce3a3a..de06a9af1 100644 --- a/src/timer/amigaos/SDL_systimer.c +++ b/src/timer/amigaos/SDL_systimer.c @@ -26,98 +26,221 @@ static char rcsid = #endif #include -#include +#include #include #include #include #include +#include +#ifdef __SASC +#include +#include +#include +#include +#include +#else +#include +#include +#include +#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; +// Do a busy wait if time is less than 50ms + + if(ms<50) + { + clock_t to_wait=clock(); + +#ifndef __SASC + ms*=(CLOCKS_PER_SEC/1000); #endif - struct timeval tv; + to_wait+=ms; + + while(clock()= ms ) { - break; + +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]>=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 + #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 @@ int SDL_SYS_TimerInit(void) 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); } diff --git a/src/video/cybergfx/SDL_amigaevents.c b/src/video/cybergfx/SDL_amigaevents.c index 3be613eb5..2b2452aa9 100644 --- a/src/video/cybergfx/SDL_amigaevents.c +++ b/src/video/cybergfx/SDL_amigaevents.c @@ -255,8 +255,8 @@ printf("MapNotify!\n"); /* 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? */ diff --git a/src/video/cybergfx/SDL_cgxaccel.c b/src/video/cybergfx/SDL_cgxaccel.c index 3bd698537..f7657c826 100644 --- a/src/video/cybergfx/SDL_cgxaccel.c +++ b/src/video/cybergfx/SDL_cgxaccel.c @@ -214,6 +214,8 @@ static int CGX_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect, } 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 @@ int CGX_FillHWRect(_THIS,SDL_Surface *dst,SDL_Rect *dstrect,Uint32 color) FillPixelArray(&temprp,dstrect->x,dstrect->y,dstrect->w,dstrect->h,color); } + return 0; } diff --git a/src/video/cybergfx/SDL_cgximage.c b/src/video/cybergfx/SDL_cgximage.c index 1ff0afa20..1c960ae94 100644 --- a/src/video/cybergfx/SDL_cgximage.c +++ b/src/video/cybergfx/SDL_cgximage.c @@ -57,6 +57,7 @@ int CGX_SetupImage(_THIS, SDL_Surface *screen) { if(screen->flags&SDL_HWSURFACE) { + Uint32 pitch; SDL_Ximage=NULL; if(!screen->hwdata) @@ -66,14 +67,30 @@ int CGX_SetupImage(_THIS, SDL_Surface *screen) 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 @@ int CGX_SetupImage(_THIS, SDL_Surface *screen) 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 @@ void CGX_DestroyImage(_THIS, SDL_Surface *screen) } } +/* 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 @@ int CGX_AllocHWSurface(_THIS, SDL_Surface *surface) { 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 @@ void CGX_UnlockHWSurface(_THIS, SDL_Surface *surface) { UnLockBitMap(surface->hwdata->lock); surface->hwdata->lock=NULL; - surface->pixels=NULL; +// surface->pixels=NULL; } } diff --git a/src/video/cybergfx/SDL_cgxmodes.c b/src/video/cybergfx/SDL_cgxmodes.c index 75c2ca3f1..162896846 100644 --- a/src/video/cybergfx/SDL_cgxmodes.c +++ b/src/video/cybergfx/SDL_cgxmodes.c @@ -76,6 +76,13 @@ static void get_real_resolution(_THIS, int* w, int* h) *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; diff --git a/src/video/cybergfx/SDL_cgxmodes_c.h b/src/video/cybergfx/SDL_cgxmodes_c.h index 68c4a382e..adee2d156 100644 --- a/src/video/cybergfx/SDL_cgxmodes_c.h +++ b/src/video/cybergfx/SDL_cgxmodes_c.h @@ -40,5 +40,10 @@ extern int CGX_GetVideoModes(_THIS); 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); diff --git a/src/video/cybergfx/SDL_cgxvideo.c b/src/video/cybergfx/SDL_cgxvideo.c index 1050fc9b3..ad8cce75a 100644 --- a/src/video/cybergfx/SDL_cgxvideo.c +++ b/src/video/cybergfx/SDL_cgxvideo.c @@ -64,8 +64,7 @@ static int CGX_VideoInit(_THIS, SDL_PixelFormat *vformat); 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 @@ static void DestroyScreen(_THIS) this->hidden->dbuffer=0; } CloseScreen(GFX_Display); + currently_fullscreen=0; } else UnlockPubScreen(NULL,GFX_Display); @@ -173,6 +173,9 @@ static SDL_VideoDevice *CGX_CreateDevice(int devindex) 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 @@ static SDL_VideoDevice *CGX_CreateDevice(int devindex) device->GL_MakeCurrent = X11_GL_MakeCurrent; device->GL_SwapBuffers = X11_GL_SwapBuffers; #endif - device->SetCaption = CGX_SetCaption; device->SetIcon = CGX_SetIcon; + device->SetCaption = CGX_SetCaption; device->IconifyWindow = NULL; /* CGX_IconifyWindow; */ device->GrabInput = NULL /* CGX_GrabInput*/; device->GetWMInfo = CGX_GetWMInfo; @@ -211,10 +214,114 @@ static SDL_VideoDevice *CGX_CreateDevice(int devindex) } 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 @@ static int CGX_VideoInit(_THIS, SDL_PixelFormat *vformat) } 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 @@ static int CGX_VideoInit(_THIS, SDL_PixelFormat *vformat) } } + /* 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 @@ static int CGX_VideoInit(_THIS, SDL_PixelFormat *vformat) 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<screen->format->BitsPerPixel; + if(this->screen->format&&this->hidden->depth==8&&!was_fullscreen) + { + numcolors = 1<screen->format->BitsPerPixel; - if(numcolors>256) - numcolors=256; + if(numcolors>256) + numcolors=256; - if(!was_fullscreen&&this->hidden->depth==8) - { - for ( pixel=0; pixelhidden->depth==8) { - if(SDL_XPixels[pixel]>=0) - ReleasePen(GFX_Display->ViewPort.ColorMap,SDL_XPixels[pixel]); + for ( pixel=0; 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 @@ int CGX_CreateWindow(_THIS, SDL_Surface *screen, 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 @@ int CGX_CreateWindow(_THIS, SDL_Surface *screen, } /* 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 @@ int CGX_CreateWindow(_THIS, SDL_Surface *screen, 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 @@ int CGX_CreateWindow(_THIS, SDL_Surface *screen, 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); - } - } else { - if ( screen->flags & SDL_FULLSCREEN ) { - screen->flags &= ~SDL_FULLSCREEN; - CGX_LeaveFullScreen(this); + 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 @@ static SDL_Surface *CGX_SetVideoMode(_THIS, SDL_Surface *current, 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 @@ static SDL_Surface *CGX_SetVideoMode(_THIS, SDL_Surface *current, 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 @@ static SDL_Surface *CGX_SetVideoMode(_THIS, SDL_Surface *current, } } +#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 @@ static SDL_Surface *CGX_SetVideoMode(_THIS, SDL_Surface *current, 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 @@ static int CGX_ToggleFullScreen(_THIS, int on) { 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 @@ static int CGX_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) /* 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 @@ static int CGX_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) // D(bug("Setting %ld colors on an HWPALETTE screen\n",ncolors)); for ( i=0; iViewPort,xcmap); @@ -1119,7 +1339,6 @@ static int CGX_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) 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 @@ static void CGX_VideoQuit(_THIS) SDL_VideoSurface=NULL; CGX_FreeVideoModes(this); +/* + if ( SDL_iconcolors ) { + unsigned long pixel; + int numcolors = + ((this->screen->format)->palette)->ncolors; + for ( pixel=0; 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); diff --git a/src/video/cybergfx/SDL_cgxvideo.h b/src/video/cybergfx/SDL_cgxvideo.h index d607bf523..e7e5ee1bd 100644 --- a/src/video/cybergfx/SDL_cgxvideo.h +++ b/src/video/cybergfx/SDL_cgxvideo.h @@ -69,6 +69,8 @@ struct SDL_PrivateVideoData { 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 @@ struct SDL_PrivateVideoData { #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 @@ struct SDL_PrivateVideoData { #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, diff --git a/src/video/cybergfx/SDL_cgxyuv.c b/src/video/cybergfx/SDL_cgxyuv.c new file mode 100644 index 000000000..373e45fa0 --- /dev/null +++ b/src/video/cybergfx/SDL_cgxyuv.c @@ -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 +#include +#include +#include +#include +#include +#include + +#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; (iformat = 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 */ diff --git a/src/video/cybergfx/SDL_cgxyuv_c.h b/src/video/cybergfx/SDL_cgxyuv_c.h new file mode 100644 index 000000000..8697f2cf0 --- /dev/null +++ b/src/video/cybergfx/SDL_cgxyuv_c.h @@ -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 */ diff --git a/src/video/default_cursor.h b/src/video/default_cursor.h index a1d32ce31..a4b2d38b9 100644 --- a/src/video/default_cursor.h +++ b/src/video/default_cursor.h @@ -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