Updated the Amiga OS port of SDL (thanks Gabriele)
--HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%4022
This commit is contained in:
parent
ac645d34ed
commit
df7866c435
26 changed files with 1381 additions and 913 deletions
12
BUGS
12
BUGS
|
@ -169,9 +169,6 @@ QNX: -= NOT YET SUPPORTED =-
|
||||||
|
|
||||||
The software surfaces could use some speed up.
|
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
|
It doesn't look like the OpenGL stuff is there. (did a grep for
|
||||||
PdCreateOpenGLContext, nothing found).
|
PdCreateOpenGLContext, nothing found).
|
||||||
|
|
||||||
|
@ -187,13 +184,4 @@ AmigaOS: -= NOT YET SUPPORTED =-
|
||||||
|
|
||||||
Continuous relative mouse motion is not implemented.
|
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
|
The AmigaOS port was done by Gabriele.Greco@galactica.it
|
||||||
|
|
50
README.AmigaOS
Normal file
50
README.AmigaOS
Normal file
|
@ -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
|
|
@ -1936,6 +1936,7 @@ src/video/photon/Makefile
|
||||||
src/video/dummy/Makefile
|
src/video/dummy/Makefile
|
||||||
src/events/Makefile
|
src/events/Makefile
|
||||||
src/joystick/Makefile
|
src/joystick/Makefile
|
||||||
|
src/joystick/amigaos/Makefile
|
||||||
src/joystick/beos/Makefile
|
src/joystick/beos/Makefile
|
||||||
src/joystick/dummy/Makefile
|
src/joystick/dummy/Makefile
|
||||||
src/joystick/linux/Makefile
|
src/joystick/linux/Makefile
|
||||||
|
|
|
@ -76,6 +76,10 @@ static AudioBootStrap *bootstrap[] = {
|
||||||
#ifdef _AIX
|
#ifdef _AIX
|
||||||
&Paud_bootstrap,
|
&Paud_bootstrap,
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ENABLE_AHI
|
||||||
|
&AHI_bootstrap,
|
||||||
|
#endif
|
||||||
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
SDL_AudioDevice *current_audio = NULL;
|
SDL_AudioDevice *current_audio = NULL;
|
||||||
|
@ -84,6 +88,9 @@ SDL_AudioDevice *current_audio = NULL;
|
||||||
int SDL_AudioInit(const char *driver_name);
|
int SDL_AudioInit(const char *driver_name);
|
||||||
void SDL_AudioQuit(void);
|
void SDL_AudioQuit(void);
|
||||||
|
|
||||||
|
#ifdef ENABLE_AHI
|
||||||
|
static int audio_configured = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The general mixing thread function */
|
/* The general mixing thread function */
|
||||||
int SDL_RunAudio(void *audiop)
|
int SDL_RunAudio(void *audiop)
|
||||||
|
@ -94,6 +101,21 @@ int SDL_RunAudio(void *audiop)
|
||||||
void *udata;
|
void *udata;
|
||||||
void (*fill)(void *userdata,Uint8 *stream, int len);
|
void (*fill)(void *userdata,Uint8 *stream, int len);
|
||||||
int silence;
|
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 */
|
/* Perform any thread setup */
|
||||||
if ( audio->ThreadInit ) {
|
if ( audio->ThreadInit ) {
|
||||||
|
@ -104,6 +126,15 @@ int SDL_RunAudio(void *audiop)
|
||||||
/* Set up the mixing function */
|
/* Set up the mixing function */
|
||||||
fill = audio->spec.callback;
|
fill = audio->spec.callback;
|
||||||
udata = audio->spec.userdata;
|
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.needed ) {
|
||||||
if ( audio->convert.src_format == AUDIO_U8 ) {
|
if ( audio->convert.src_format == AUDIO_U8 ) {
|
||||||
silence = 0x80;
|
silence = 0x80;
|
||||||
|
@ -117,6 +148,12 @@ int SDL_RunAudio(void *audiop)
|
||||||
}
|
}
|
||||||
stream = audio->fake_stream;
|
stream = audio->fake_stream;
|
||||||
|
|
||||||
|
#ifdef ENABLE_AHI
|
||||||
|
SDL_mutexV(audio->mixer_lock);
|
||||||
|
D(bug("Entering audio loop...\n"));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Loop, filling the audio buffers */
|
/* Loop, filling the audio buffers */
|
||||||
while ( audio->enabled ) {
|
while ( audio->enabled ) {
|
||||||
|
|
||||||
|
@ -124,12 +161,14 @@ int SDL_RunAudio(void *audiop)
|
||||||
if ( stream == audio->fake_stream ) {
|
if ( stream == audio->fake_stream ) {
|
||||||
SDL_Delay((audio->spec.samples*1000)/audio->spec.freq);
|
SDL_Delay((audio->spec.samples*1000)/audio->spec.freq);
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef ENABLE_AHI
|
||||||
|
if ( started > 1 )
|
||||||
|
#endif
|
||||||
audio->WaitAudio(audio);
|
audio->WaitAudio(audio);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill the current buffer with sound */
|
/* Fill the current buffer with sound */
|
||||||
if ( audio->convert.needed ) {
|
if ( audio->convert.needed ) {
|
||||||
/* The buffer may not be allocated yet */
|
|
||||||
if ( audio->convert.buf ) {
|
if ( audio->convert.buf ) {
|
||||||
stream = audio->convert.buf;
|
stream = audio->convert.buf;
|
||||||
} else {
|
} else {
|
||||||
|
@ -163,12 +202,25 @@ int SDL_RunAudio(void *audiop)
|
||||||
/* Ready current buffer for play and change current buffer */
|
/* Ready current buffer for play and change current buffer */
|
||||||
if ( stream != audio->fake_stream ) {
|
if ( stream != audio->fake_stream ) {
|
||||||
audio->PlayAudio(audio);
|
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.. */
|
/* Wait for the audio to drain.. */
|
||||||
if ( audio->WaitDone ) {
|
if ( audio->WaitDone ) {
|
||||||
audio->WaitDone(audio);
|
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);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,11 +364,33 @@ int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained)
|
||||||
audio->convert.needed = 0;
|
audio->convert.needed = 0;
|
||||||
audio->enabled = 1;
|
audio->enabled = 1;
|
||||||
audio->paused = 1;
|
audio->paused = 1;
|
||||||
|
|
||||||
|
#ifndef ENABLE_AHI
|
||||||
|
|
||||||
|
/* AmigaOS opens audio inside the main loop */
|
||||||
audio->opened = audio->OpenAudio(audio, &audio->spec)+1;
|
audio->opened = audio->OpenAudio(audio, &audio->spec)+1;
|
||||||
|
|
||||||
if ( ! audio->opened ) {
|
if ( ! audio->opened ) {
|
||||||
SDL_CloseAudio();
|
SDL_CloseAudio();
|
||||||
return(-1);
|
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 the audio driver changes the buffer size, accept it */
|
||||||
if ( audio->spec.samples != desired->samples ) {
|
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 */
|
/* Start the audio thread if necessary */
|
||||||
switch (audio->opened) {
|
switch (audio->opened) {
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -381,6 +456,12 @@ int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained)
|
||||||
/* The audio is now playing */
|
/* The audio is now playing */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
SDL_mutexV(audio->mixer_lock);
|
||||||
|
D(bug("SDL_OpenAudio USCITA...\n"));
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,12 +538,14 @@ void SDL_AudioQuit(void)
|
||||||
}
|
}
|
||||||
if ( audio->convert.needed ) {
|
if ( audio->convert.needed ) {
|
||||||
SDL_FreeAudioMem(audio->convert.buf);
|
SDL_FreeAudioMem(audio->convert.buf);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#ifndef ENABLE_AHI
|
||||||
if ( audio->opened ) {
|
if ( audio->opened ) {
|
||||||
audio->CloseAudio(audio);
|
audio->CloseAudio(audio);
|
||||||
audio->opened = 0;
|
audio->opened = 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/* Free the driver data */
|
/* Free the driver data */
|
||||||
audio->free(audio);
|
audio->free(audio);
|
||||||
current_audio = NULL;
|
current_audio = NULL;
|
||||||
|
|
|
@ -126,14 +126,17 @@ extern AudioBootStrap DSOUND_bootstrap;
|
||||||
#ifdef ENABLE_WINDIB
|
#ifdef ENABLE_WINDIB
|
||||||
extern AudioBootStrap WAVEOUT_bootstrap;
|
extern AudioBootStrap WAVEOUT_bootstrap;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef _AIX
|
||||||
|
extern AudioBootStrap Paud_bootstrap;
|
||||||
|
#endif
|
||||||
#ifdef __BEOS__
|
#ifdef __BEOS__
|
||||||
extern AudioBootStrap BAUDIO_bootstrap;
|
extern AudioBootStrap BAUDIO_bootstrap;
|
||||||
#endif
|
#endif
|
||||||
#if defined(macintosh) || TARGET_API_MAC_CARBON
|
#if defined(macintosh) || TARGET_API_MAC_CARBON
|
||||||
extern AudioBootStrap SNDMGR_bootstrap;
|
extern AudioBootStrap SNDMGR_bootstrap;
|
||||||
#endif
|
#endif
|
||||||
#ifdef _AIX
|
#ifdef ENABLE_AHI
|
||||||
extern AudioBootStrap Paud_bootstrap;
|
extern AudioBootStrap AHI_bootstrap;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This is the current audio device */
|
/* This is the current audio device */
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
|
|
||||||
noinst_LTLIBRARIES = libaudio_arch.la
|
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)
|
libaudio_arch_la_SOURCES = $(ARCH_SRCS)
|
||||||
|
|
|
@ -27,13 +27,17 @@ static char rcsid =
|
||||||
"@(#) $Id$";
|
"@(#) $Id$";
|
||||||
#endif
|
#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_endian.h"
|
||||||
#include "SDL_audio.h"
|
#include "SDL_audio.h"
|
||||||
#include "SDL_audiomem.h"
|
#include "SDL_audiomem.h"
|
||||||
#include "SDL_audio_c.h"
|
#include "SDL_audio_c.h"
|
||||||
#include "SDL_lowaudio.h"
|
#include "SDL_ahiaudio.h"
|
||||||
|
|
||||||
/* Audio driver functions */
|
/* Audio driver functions */
|
||||||
static int AHI_OpenAudio(_THIS, SDL_AudioSpec *spec);
|
static int AHI_OpenAudio(_THIS, SDL_AudioSpec *spec);
|
||||||
|
@ -54,11 +58,29 @@ static void AHI_CloseAudio(_THIS);
|
||||||
|
|
||||||
static int Audio_Available(void)
|
static int Audio_Available(void)
|
||||||
{
|
{
|
||||||
#ifndef NO_AMIGADEBUG
|
int ok=0;
|
||||||
D(bug("AHI available.\n"));
|
struct MsgPort *p;
|
||||||
#endif
|
struct AHIRequest *req;
|
||||||
|
|
||||||
return 1;
|
if(p=CreateMsgPort())
|
||||||
|
{
|
||||||
|
if(req=(struct AHIRequest *)CreateIORequest(p,sizeof(struct AHIRequest)))
|
||||||
|
{
|
||||||
|
req->ahir_Version=4;
|
||||||
|
|
||||||
|
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)
|
static void Audio_DeleteDevice(SDL_AudioDevice *device)
|
||||||
|
@ -125,7 +147,7 @@ static void AHI_PlayAudio(_THIS)
|
||||||
/* Write the audio data out */
|
/* 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_Message.mn_Node.ln_Pri = 60;
|
||||||
audio_req[current_buffer] -> ahir_Std. io_Data = mixbuf[current_buffer];
|
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_Offset = 0;
|
||||||
audio_req[current_buffer] -> ahir_Std . io_Command = CMD_WRITE;
|
audio_req[current_buffer] -> ahir_Std . io_Command = CMD_WRITE;
|
||||||
audio_req[current_buffer] -> ahir_Frequency = this->hidden->freq;
|
audio_req[current_buffer] -> ahir_Frequency = this->hidden->freq;
|
||||||
|
@ -149,43 +171,58 @@ static void AHI_CloseAudio(_THIS)
|
||||||
{
|
{
|
||||||
D(bug("Closing audio...\n"));
|
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;
|
playing=0;
|
||||||
|
|
||||||
if(audio_req[0])
|
if(audio_req[0])
|
||||||
{
|
{
|
||||||
if(audio_req[1])
|
if(audio_req[1])
|
||||||
{
|
{
|
||||||
if(!CheckIO((struct IORequest *)audio_req[1]))
|
D(bug("Break req[1]...\n"));
|
||||||
{
|
|
||||||
AbortIO((struct IORequest *)audio_req[1]);
|
AbortIO((struct IORequest *)audio_req[1]);
|
||||||
WaitIO((struct IORequest *)audio_req[1]);
|
WaitIO((struct IORequest *)audio_req[1]);
|
||||||
}
|
|
||||||
myfree(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]);
|
D(bug("Break AGAIN req[1]...\n"));
|
||||||
WaitIO((struct IORequest *)audio_req[0]);
|
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]);
|
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]);
|
DeleteIORequest((struct IORequest *)audio_req[0]);
|
||||||
audio_req[0]=audio_req[1]=NULL;
|
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 ) {
|
if ( audio_port != NULL ) {
|
||||||
DeleteMsgPort(audio_port);
|
DeleteMsgPort(audio_port);
|
||||||
audio_port = NULL;
|
audio_port = NULL;
|
||||||
|
@ -206,8 +243,10 @@ static int AHI_OpenAudio(_THIS, SDL_AudioSpec *spec)
|
||||||
D(bug("Samples a 8 bit...\n"));
|
D(bug("Samples a 8 bit...\n"));
|
||||||
spec->format = AUDIO_S8;
|
spec->format = AUDIO_S8;
|
||||||
this->hidden->bytespersample=1;
|
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;
|
break;
|
||||||
|
|
||||||
|
@ -215,7 +254,10 @@ static int AHI_OpenAudio(_THIS, SDL_AudioSpec *spec)
|
||||||
D(bug("Samples a 16 bit...\n"));
|
D(bug("Samples a 16 bit...\n"));
|
||||||
spec->format = AUDIO_S16MSB;
|
spec->format = AUDIO_S16MSB;
|
||||||
this->hidden->bytespersample=2;
|
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;
|
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"));
|
D(bug("Before CalculateAudioSpec\n"));
|
||||||
/* Update the fragment size as size in bytes */
|
/* Update the fragment size as size in bytes */
|
||||||
SDL_CalculateAudioSpec(spec);
|
SDL_CalculateAudioSpec(spec);
|
||||||
|
@ -258,8 +307,9 @@ static int AHI_OpenAudio(_THIS, SDL_AudioSpec *spec)
|
||||||
|
|
||||||
D(bug("AFTER opendevice\n"));
|
D(bug("AFTER opendevice\n"));
|
||||||
|
|
||||||
/* Set output frequency */
|
/* Set output frequency and size */
|
||||||
this->hidden->freq = spec->freq;
|
this->hidden->freq = spec->freq;
|
||||||
|
this->hidden->size = spec->size;
|
||||||
|
|
||||||
D(bug("Before buffer allocation\n"));
|
D(bug("Before buffer allocation\n"));
|
||||||
|
|
||||||
|
@ -292,7 +342,7 @@ static int AHI_OpenAudio(_THIS, SDL_AudioSpec *spec)
|
||||||
current_buffer=0;
|
current_buffer=0;
|
||||||
playing=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. :-) */
|
/* We're ready to rock and roll. :-) */
|
||||||
return(0);
|
return(0);
|
||||||
|
|
|
@ -25,15 +25,20 @@ static char rcsid =
|
||||||
"@(#) $Id$";
|
"@(#) $Id$";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _SDL_lowaudio_h
|
#ifndef _SDL_ahiaudio_h
|
||||||
#define _SDL_lowaudio_h
|
#define _SDL_ahiaudio_h
|
||||||
|
|
||||||
// #include <libraries/ahi_sub.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"
|
#include "SDL_sysaudio.h"
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* Hidden "this" pointer for the audio functions */
|
/* Hidden "this" pointer for the audio functions */
|
||||||
#define _THIS SDL_AudioDevice *this
|
#define _THIS SDL_AudioDevice *this
|
||||||
|
@ -55,4 +60,4 @@ struct SDL_PrivateAudioData {
|
||||||
#define current_buffer (this->hidden->current_buffer)
|
#define current_buffer (this->hidden->current_buffer)
|
||||||
#define playing (this->hidden->playing)
|
#define playing (this->hidden->playing)
|
||||||
|
|
||||||
#endif /* _SDL_lowaudio_h */
|
#endif /* _SDL_ahiaudio_h */
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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 */
|
|
8
src/joystick/amigaos/Makefile.am
Normal file
8
src/joystick/amigaos/Makefile.am
Normal file
|
@ -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
|
240
src/joystick/amigaos/SDL_sysjoystick.c
Normal file
240
src/joystick/amigaos/SDL_sysjoystick.c
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ static char rcsid =
|
||||||
"@(#) $Id$";
|
"@(#) $Id$";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* An native implementation of semaphores on AmigaOS */
|
/* An implementation of semaphores using mutexes and condition variables */
|
||||||
|
|
||||||
#include "SDL_error.h"
|
#include "SDL_error.h"
|
||||||
#include "SDL_thread.h"
|
#include "SDL_thread.h"
|
||||||
|
@ -35,9 +35,13 @@ static char rcsid =
|
||||||
struct SDL_semaphore
|
struct SDL_semaphore
|
||||||
{
|
{
|
||||||
struct SignalSemaphore Sem;
|
struct SignalSemaphore Sem;
|
||||||
|
Uint32 count;
|
||||||
|
Uint32 waiters_count;
|
||||||
|
SDL_mutex *count_lock;
|
||||||
|
SDL_cond *count_nonzero;
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef D(x)
|
#undef D
|
||||||
|
|
||||||
#define D(x)
|
#define D(x)
|
||||||
|
|
||||||
|
@ -46,20 +50,18 @@ SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
|
||||||
SDL_sem *sem;
|
SDL_sem *sem;
|
||||||
|
|
||||||
sem = (SDL_sem *)malloc(sizeof(*sem));
|
sem = (SDL_sem *)malloc(sizeof(*sem));
|
||||||
|
|
||||||
if ( ! sem ) {
|
if ( ! sem ) {
|
||||||
SDL_OutOfMemory();
|
SDL_OutOfMemory();
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
memset(sem, 0, sizeof(*sem));
|
|
||||||
|
|
||||||
D(bug("Creating semaphore %lx...\n",sem));
|
D(bug("Creating semaphore %lx...\n",sem));
|
||||||
|
|
||||||
|
memset(sem,0,sizeof(*sem));
|
||||||
|
|
||||||
InitSemaphore(&sem->Sem);
|
InitSemaphore(&sem->Sem);
|
||||||
#if 1 // Allow multiple obtainings of the semaphore
|
|
||||||
while ( initial_value-- ) {
|
|
||||||
ReleaseSemaphore(&sem->Sem);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return(sem);
|
return(sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,8 +77,6 @@ void SDL_DestroySemaphore(SDL_sem *sem)
|
||||||
|
|
||||||
int SDL_SemTryWait(SDL_sem *sem)
|
int SDL_SemTryWait(SDL_sem *sem)
|
||||||
{
|
{
|
||||||
int retval;
|
|
||||||
|
|
||||||
if ( ! sem ) {
|
if ( ! sem ) {
|
||||||
SDL_SetError("Passed a NULL semaphore");
|
SDL_SetError("Passed a NULL semaphore");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -84,17 +84,17 @@ int SDL_SemTryWait(SDL_sem *sem)
|
||||||
|
|
||||||
D(bug("TryWait semaphore...%lx\n",sem));
|
D(bug("TryWait semaphore...%lx\n",sem));
|
||||||
|
|
||||||
retval = SDL_MUTEX_TIMEDOUT;
|
ObtainSemaphore(&sem->Sem);
|
||||||
if ( AttemptSemaphore(&sem->Sem) ) {
|
// ReleaseSemaphore(&sem->Sem);
|
||||||
retval = 0;
|
|
||||||
}
|
return 1;
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
|
|
||||||
if ( ! sem ) {
|
if ( ! sem ) {
|
||||||
SDL_SetError("Passed a NULL semaphore");
|
SDL_SetError("Passed a NULL semaphore");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -102,16 +102,22 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||||
|
|
||||||
D(bug("WaitTimeout (%ld) semaphore...%lx\n",timeout,sem));
|
D(bug("WaitTimeout (%ld) semaphore...%lx\n",timeout,sem));
|
||||||
|
|
||||||
#if 1 // We need to keep trying the semaphore until the timeout expires
|
/* A timeout of 0 is an easy case */
|
||||||
retval = SDL_MUTEX_TIMEDOUT;
|
if ( timeout == 0 ) {
|
||||||
then = SDL_GetTicks();
|
return SDL_SemTryWait(sem);
|
||||||
do {
|
}
|
||||||
if ( AttemptSemaphore(&sem->Sem) ) {
|
/*
|
||||||
retval = 0;
|
SDL_LockMutex(sem->count_lock);
|
||||||
}
|
++sem->waiters_count;
|
||||||
now = SDL_GetTicks();
|
retval = 0;
|
||||||
} while ( (retval == SDL_MUTEX_TIMEDOUT) && ((now-then) < timeout) );
|
while ( (sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT) ) {
|
||||||
#else
|
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)))
|
if(!(retval=AttemptSemaphore(&sem->Sem)))
|
||||||
{
|
{
|
||||||
SDL_Delay(timeout);
|
SDL_Delay(timeout);
|
||||||
|
@ -123,22 +129,15 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
|
||||||
// ReleaseSemaphore(&sem->Sem);
|
// ReleaseSemaphore(&sem->Sem);
|
||||||
retval=1;
|
retval=1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_SemWait(SDL_sem *sem)
|
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);
|
ObtainSemaphore(&sem->Sem);
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
// return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
|
||||||
return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint32 SDL_SemValue(SDL_sem *sem)
|
Uint32 SDL_SemValue(SDL_sem *sem)
|
||||||
|
@ -148,6 +147,7 @@ Uint32 SDL_SemValue(SDL_sem *sem)
|
||||||
value = 0;
|
value = 0;
|
||||||
if ( sem ) {
|
if ( sem ) {
|
||||||
value = sem->Sem.ss_NestCount;
|
value = sem->Sem.ss_NestCount;
|
||||||
|
// SDL_UnlockMutex(sem->count_lock);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -161,6 +161,14 @@ int SDL_SemPost(SDL_sem *sem)
|
||||||
D(bug("SemPost semaphore...%lx\n",sem));
|
D(bug("SemPost semaphore...%lx\n",sem));
|
||||||
|
|
||||||
ReleaseSemaphore(&sem->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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ static char rcsid =
|
||||||
"@(#) $Id$";
|
"@(#) $Id$";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* AmigaOS thread management routines for SDL */
|
/* BeOS thread management routines for SDL */
|
||||||
|
|
||||||
#include "SDL_error.h"
|
#include "SDL_error.h"
|
||||||
#include "SDL_mutex.h"
|
#include "SDL_mutex.h"
|
||||||
|
@ -40,6 +40,8 @@ typedef struct {
|
||||||
struct Task *wait;
|
struct Task *wait;
|
||||||
} thread_args;
|
} thread_args;
|
||||||
|
|
||||||
|
#ifndef MORPHOS
|
||||||
|
|
||||||
#if defined(__SASC) && !defined(__PPC__)
|
#if defined(__SASC) && !defined(__PPC__)
|
||||||
__saveds __asm Uint32 RunThread(register __a0 char *args )
|
__saveds __asm Uint32 RunThread(register __a0 char *args )
|
||||||
#elif defined(__PPC__)
|
#elif defined(__PPC__)
|
||||||
|
@ -60,6 +62,34 @@ Uint32 RunThread(char *args __asm("a0") )
|
||||||
return(0);
|
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)
|
int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
|
||||||
{
|
{
|
||||||
/* Create the thread and go! */
|
/* Create the thread and go! */
|
||||||
|
@ -98,6 +128,7 @@ Uint32 SDL_ThreadID(void)
|
||||||
|
|
||||||
void SDL_SYS_WaitThread(SDL_Thread *thread)
|
void SDL_SYS_WaitThread(SDL_Thread *thread)
|
||||||
{
|
{
|
||||||
|
SetSignal(0L,SIGBREAKF_CTRL_F|SIGBREAKF_CTRL_C);
|
||||||
Wait(SIGBREAKF_CTRL_F|SIGBREAKF_CTRL_C);
|
Wait(SIGBREAKF_CTRL_F|SIGBREAKF_CTRL_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)
|
void SDL_KillThread(SDL_Thread *thread)
|
||||||
{
|
{
|
||||||
if ( thread ) {
|
if ( thread ) {
|
||||||
|
|
|
@ -26,98 +26,221 @@ static char rcsid =
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/time.h>
|
#include <time.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.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_error.h"
|
||||||
#include "SDL_timer.h"
|
#include "SDL_timer.h"
|
||||||
#include "SDL_timer_c.h"
|
#include "SDL_timer_c.h"
|
||||||
|
|
||||||
|
#if defined(DISABLE_THREADS) || defined(FORK_HACK)
|
||||||
|
#define USE_ITIMER
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The first ticks value of the application */
|
/* The first ticks value of the application */
|
||||||
static struct timeval start;
|
|
||||||
|
#ifndef __PPC__
|
||||||
|
static clock_t start;
|
||||||
|
|
||||||
void SDL_StartTicks(void)
|
void SDL_StartTicks(void)
|
||||||
{
|
{
|
||||||
/* Set first ticks value */
|
/* Set first ticks value */
|
||||||
gettimeofday(&start, NULL);
|
start=clock();
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint32 SDL_GetTicks (void)
|
Uint32 SDL_GetTicks (void)
|
||||||
{
|
{
|
||||||
struct timeval now;
|
clock_t ticks;
|
||||||
Uint32 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);
|
return(ticks);
|
||||||
|
#else
|
||||||
|
// CLOCKS_PER_SEC != 1000 !
|
||||||
|
|
||||||
|
return ticks*(1000/CLOCKS_PER_SEC);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL_Delay (Uint32 ms)
|
void SDL_Delay (Uint32 ms)
|
||||||
{
|
{
|
||||||
int was_error;
|
// Do a busy wait if time is less than 50ms
|
||||||
#ifndef linux /* Non-Linux implementations need to calculate time left */
|
|
||||||
Uint32 then, now, elapsed;
|
|
||||||
#endif
|
|
||||||
struct timeval tv;
|
|
||||||
|
|
||||||
/* Set the timeout interval - Linux only needs to do this once */
|
if(ms<50)
|
||||||
#ifdef linux
|
{
|
||||||
tv.tv_sec = ms/1000;
|
clock_t to_wait=clock();
|
||||||
tv.tv_usec = (ms%1000)*1000;
|
|
||||||
#else
|
#ifndef __SASC
|
||||||
then = SDL_GetTicks();
|
ms*=(CLOCKS_PER_SEC/1000);
|
||||||
#endif
|
#endif
|
||||||
do {
|
to_wait+=ms;
|
||||||
errno = 0;
|
|
||||||
#ifndef linux
|
while(clock()<to_wait);
|
||||||
/* Calculate the time interval left (in case of interrupt) */
|
}
|
||||||
now = SDL_GetTicks();
|
else
|
||||||
elapsed = (now-then);
|
{
|
||||||
then = now;
|
Delay(ms/20);
|
||||||
if ( elapsed >= ms ) {
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
ms -= elapsed;
|
|
||||||
tv.tv_sec = ms/1000;
|
|
||||||
tv.tv_usec = (ms%1000)*1000;
|
|
||||||
#endif
|
|
||||||
was_error = select(0, NULL, NULL, NULL, &tv);
|
|
||||||
} while ( was_error && (errno == EINTR) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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
|
||||||
|
|
||||||
#include "SDL_thread.h"
|
#include "SDL_thread.h"
|
||||||
|
|
||||||
/* Data to handle a single periodic alarm */
|
/* Data to handle a single periodic alarm */
|
||||||
static int timer_alive = 0;
|
static int timer_alive = 0;
|
||||||
static SDL_Thread *timer = NULL;
|
static SDL_Thread *timer_thread = NULL;
|
||||||
|
|
||||||
static int RunTimer(void *unused)
|
static int RunTimer(void *unused)
|
||||||
{
|
{
|
||||||
|
D(bug("SYSTimer: Entering RunTimer loop..."));
|
||||||
|
|
||||||
|
if(GfxBase==NULL)
|
||||||
|
GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37);
|
||||||
|
|
||||||
while ( timer_alive ) {
|
while ( timer_alive ) {
|
||||||
if ( SDL_timer_running ) {
|
if ( SDL_timer_running ) {
|
||||||
SDL_ThreadedTimerCheck();
|
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);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is only called if the event thread is not running */
|
/* This is only called if the event thread is not running */
|
||||||
int SDL_SYS_TimerInit(void)
|
int SDL_SYS_TimerInit(void)
|
||||||
{
|
{
|
||||||
#ifdef NO_AMIGADEBUG
|
D(bug("Creo il thread per il timer (NOITMER)...\n"));
|
||||||
fprintf(stderr,"Creo il thread per il timer (NOITMER)...\n");
|
|
||||||
#endif
|
|
||||||
timer_alive = 1;
|
timer_alive = 1;
|
||||||
timer = SDL_CreateThread(RunTimer, NULL);
|
timer_thread = SDL_CreateThread(RunTimer, NULL);
|
||||||
if ( timer == NULL )
|
if ( timer_thread == NULL )
|
||||||
{
|
{
|
||||||
#ifdef NO_AMIGADEBUG
|
D(bug("Creazione del thread fallita...\n"));
|
||||||
fprintf(stderr,"Creazione del thread fallita...\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
@ -127,15 +250,15 @@ int SDL_SYS_TimerInit(void)
|
||||||
void SDL_SYS_TimerQuit(void)
|
void SDL_SYS_TimerQuit(void)
|
||||||
{
|
{
|
||||||
timer_alive = 0;
|
timer_alive = 0;
|
||||||
if ( timer ) {
|
if ( timer_thread ) {
|
||||||
SDL_WaitThread(timer, NULL);
|
SDL_WaitThread(timer_thread, NULL);
|
||||||
timer = NULL;
|
timer_thread = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_SYS_StartTimer(void)
|
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);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -255,8 +255,8 @@ printf("MapNotify!\n");
|
||||||
|
|
||||||
/* Have we been resized? */
|
/* Have we been resized? */
|
||||||
case IDCMP_NEWSIZE:
|
case IDCMP_NEWSIZE:
|
||||||
SDL_PrivateResize(SDL_Window->Width,
|
SDL_PrivateResize(SDL_Window->Width-SDL_Window->BorderLeft-SDL_Window->BorderRight,
|
||||||
SDL_Window->Height);
|
SDL_Window->Height-SDL_Window->BorderTop-SDL_Window->BorderBottom);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Have we been requested to quit? */
|
/* Have we been requested to quit? */
|
||||||
|
|
|
@ -214,6 +214,8 @@ static int CGX_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
|
||||||
}
|
}
|
||||||
else if(dst->hwdata)
|
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);
|
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)
|
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);
|
FillPixelArray(&temprp,dstrect->x,dstrect->y,dstrect->w,dstrect->h,color);
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,7 @@ int CGX_SetupImage(_THIS, SDL_Surface *screen)
|
||||||
{
|
{
|
||||||
if(screen->flags&SDL_HWSURFACE)
|
if(screen->flags&SDL_HWSURFACE)
|
||||||
{
|
{
|
||||||
|
Uint32 pitch;
|
||||||
SDL_Ximage=NULL;
|
SDL_Ximage=NULL;
|
||||||
|
|
||||||
if(!screen->hwdata)
|
if(!screen->hwdata)
|
||||||
|
@ -66,14 +67,30 @@ int CGX_SetupImage(_THIS, SDL_Surface *screen)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
D(bug("Creating system accel struct\n"));
|
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;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,6 +100,18 @@ int CGX_SetupImage(_THIS, SDL_Surface *screen)
|
||||||
SDL_OutOfMemory();
|
SDL_OutOfMemory();
|
||||||
return(-1);
|
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;
|
SDL_Ximage=screen->pixels;
|
||||||
|
|
||||||
if ( SDL_Ximage == NULL ) {
|
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 CGX_ResizeImage(_THIS, SDL_Surface *screen, Uint32 flags)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
|
D(bug("Chiamata ResizeImage!\n"));
|
||||||
|
|
||||||
CGX_DestroyImage(this, screen);
|
CGX_DestroyImage(this, screen);
|
||||||
|
|
||||||
if ( flags & SDL_OPENGL ) { /* No image when using GL */
|
if ( flags & SDL_OPENGL ) { /* No image when using GL */
|
||||||
retval = 0;
|
retval = 0;
|
||||||
} else {
|
} else {
|
||||||
retval = CGX_SetupImage(this, screen);
|
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);
|
return(retval);
|
||||||
}
|
}
|
||||||
|
@ -135,11 +183,11 @@ int CGX_AllocHWSurface(_THIS, SDL_Surface *surface)
|
||||||
{
|
{
|
||||||
if(!(surface->hwdata=malloc(sizeof(struct private_hwdata))))
|
if(!(surface->hwdata=malloc(sizeof(struct private_hwdata))))
|
||||||
return -1;
|
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))
|
if(surface->hwdata->bmap=AllocBitMap(surface->w,surface->h,this->hidden->depth,BMF_MINPLANES,SDL_Display->RastPort.BitMap))
|
||||||
{
|
{
|
||||||
surface->flags|=SDL_HWSURFACE;
|
surface->flags|=SDL_HWSURFACE;
|
||||||
|
@ -205,7 +253,7 @@ void CGX_UnlockHWSurface(_THIS, SDL_Surface *surface)
|
||||||
{
|
{
|
||||||
UnLockBitMap(surface->hwdata->lock);
|
UnLockBitMap(surface->hwdata->lock);
|
||||||
surface->hwdata->lock=NULL;
|
surface->hwdata->lock=NULL;
|
||||||
surface->pixels=NULL;
|
// surface->pixels=NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,13 @@ static void get_real_resolution(_THIS, int* w, int* h)
|
||||||
*h = SDL_Display->Height;
|
*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)
|
static void add_visual(_THIS, int depth, int class)
|
||||||
{
|
{
|
||||||
Uint32 tID;
|
Uint32 tID;
|
||||||
|
|
|
@ -40,5 +40,10 @@ extern int CGX_GetVideoModes(_THIS);
|
||||||
extern SDL_Rect **CGX_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
|
extern SDL_Rect **CGX_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
|
||||||
extern void CGX_FreeVideoModes(_THIS);
|
extern void CGX_FreeVideoModes(_THIS);
|
||||||
extern int CGX_ResizeFullScreen(_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_EnterFullScreen(_THIS);
|
||||||
extern int CGX_LeaveFullScreen(_THIS);
|
extern int CGX_LeaveFullScreen(_THIS);
|
||||||
|
|
|
@ -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 SDL_Surface *CGX_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
|
||||||
static int CGX_ToggleFullScreen(_THIS, int on);
|
static int CGX_ToggleFullScreen(_THIS, int on);
|
||||||
static void CGX_UpdateMouse(_THIS);
|
static void CGX_UpdateMouse(_THIS);
|
||||||
static int CGX_SetColors(_THIS, int firstcolor, int ncolors,
|
static int CGX_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
|
||||||
SDL_Color *colors);
|
|
||||||
static void CGX_VideoQuit(_THIS);
|
static void CGX_VideoQuit(_THIS);
|
||||||
|
|
||||||
/* CGX driver bootstrap functions */
|
/* CGX driver bootstrap functions */
|
||||||
|
@ -110,6 +109,7 @@ static void DestroyScreen(_THIS)
|
||||||
this->hidden->dbuffer=0;
|
this->hidden->dbuffer=0;
|
||||||
}
|
}
|
||||||
CloseScreen(GFX_Display);
|
CloseScreen(GFX_Display);
|
||||||
|
currently_fullscreen=0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
UnlockPubScreen(NULL,GFX_Display);
|
UnlockPubScreen(NULL,GFX_Display);
|
||||||
|
@ -173,6 +173,9 @@ static SDL_VideoDevice *CGX_CreateDevice(int devindex)
|
||||||
device->SetVideoMode = CGX_SetVideoMode;
|
device->SetVideoMode = CGX_SetVideoMode;
|
||||||
device->ToggleFullScreen = CGX_ToggleFullScreen;
|
device->ToggleFullScreen = CGX_ToggleFullScreen;
|
||||||
device->UpdateMouse = CGX_UpdateMouse;
|
device->UpdateMouse = CGX_UpdateMouse;
|
||||||
|
#ifdef XFREE86_XV
|
||||||
|
device->CreateYUVOverlay = X11_CreateYUVOverlay;
|
||||||
|
#endif
|
||||||
device->SetColors = CGX_SetColors;
|
device->SetColors = CGX_SetColors;
|
||||||
device->UpdateRects = NULL;
|
device->UpdateRects = NULL;
|
||||||
device->VideoQuit = CGX_VideoQuit;
|
device->VideoQuit = CGX_VideoQuit;
|
||||||
|
@ -192,8 +195,8 @@ static SDL_VideoDevice *CGX_CreateDevice(int devindex)
|
||||||
device->GL_MakeCurrent = X11_GL_MakeCurrent;
|
device->GL_MakeCurrent = X11_GL_MakeCurrent;
|
||||||
device->GL_SwapBuffers = X11_GL_SwapBuffers;
|
device->GL_SwapBuffers = X11_GL_SwapBuffers;
|
||||||
#endif
|
#endif
|
||||||
device->SetCaption = CGX_SetCaption;
|
|
||||||
device->SetIcon = CGX_SetIcon;
|
device->SetIcon = CGX_SetIcon;
|
||||||
|
device->SetCaption = CGX_SetCaption;
|
||||||
device->IconifyWindow = NULL; /* CGX_IconifyWindow; */
|
device->IconifyWindow = NULL; /* CGX_IconifyWindow; */
|
||||||
device->GrabInput = NULL /* CGX_GrabInput*/;
|
device->GrabInput = NULL /* CGX_GrabInput*/;
|
||||||
device->GetWMInfo = CGX_GetWMInfo;
|
device->GetWMInfo = CGX_GetWMInfo;
|
||||||
|
@ -211,10 +214,114 @@ static SDL_VideoDevice *CGX_CreateDevice(int devindex)
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoBootStrap CGX_bootstrap = {
|
VideoBootStrap CGX_bootstrap = {
|
||||||
"CGX", "Amiga CyberGFX video",
|
"CGX", "AmigaOS CyberGraphics", CGX_Available, CGX_CreateDevice
|
||||||
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)
|
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_Visual = this->hidden->visuals[i].visual;
|
||||||
|
|
||||||
|
// SDL_XColorMap = SDL_DisplayColormap;
|
||||||
|
|
||||||
this->hidden->depth = this->hidden->visuals[i].depth;
|
this->hidden->depth = this->hidden->visuals[i].depth;
|
||||||
D(bug("Setto la profiondita' dello schermo a: %ld\n",this->hidden->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; */
|
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 the fullscreen and managed windows */
|
||||||
// create_aux_windows(this);
|
// create_aux_windows(this);
|
||||||
|
|
||||||
|
@ -517,45 +630,47 @@ static int CGX_VideoInit(_THIS, SDL_PixelFormat *vformat)
|
||||||
|
|
||||||
void CGX_DestroyWindow(_THIS, SDL_Surface *screen)
|
void CGX_DestroyWindow(_THIS, SDL_Surface *screen)
|
||||||
{
|
{
|
||||||
/* Hide the managed window */
|
if ( ! SDL_windowid ) {
|
||||||
int was_fullscreen=0;
|
/* Hide the managed window */
|
||||||
|
int was_fullscreen=0;
|
||||||
|
|
||||||
if ( screen && (screen->flags & SDL_FULLSCREEN) ) {
|
if ( screen && (screen->flags & SDL_FULLSCREEN) ) {
|
||||||
was_fullscreen=1;
|
was_fullscreen=1;
|
||||||
screen->flags &= ~SDL_FULLSCREEN;
|
screen->flags &= ~SDL_FULLSCREEN;
|
||||||
CGX_LeaveFullScreen(this);
|
// CGX_LeaveFullScreen(this); tolto x crash
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Destroy the output window */
|
/* Destroy the output window */
|
||||||
if ( SDL_Window ) {
|
if ( SDL_Window ) {
|
||||||
CloseWindow(SDL_Window);
|
CloseWindow(SDL_Window);
|
||||||
SDL_Window=NULL;
|
SDL_Window=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free the colormap entries */
|
/* Free the colormap entries */
|
||||||
if ( SDL_XPixels ) {
|
if ( SDL_XPixels ) {
|
||||||
int numcolors;
|
int numcolors;
|
||||||
unsigned long pixel;
|
unsigned long pixel;
|
||||||
|
|
||||||
if(this->screen->format&&this->hidden->depth==8&&!was_fullscreen)
|
if(this->screen->format&&this->hidden->depth==8&&!was_fullscreen)
|
||||||
{
|
|
||||||
numcolors = 1<<this->screen->format->BitsPerPixel;
|
|
||||||
|
|
||||||
if(numcolors>256)
|
|
||||||
numcolors=256;
|
|
||||||
|
|
||||||
if(!was_fullscreen&&this->hidden->depth==8)
|
|
||||||
{
|
{
|
||||||
for ( pixel=0; pixel<numcolors; pixel++ )
|
numcolors = 1<<this->screen->format->BitsPerPixel;
|
||||||
|
|
||||||
|
if(numcolors>256)
|
||||||
|
numcolors=256;
|
||||||
|
|
||||||
|
if(!was_fullscreen&&this->hidden->depth==8)
|
||||||
{
|
{
|
||||||
if(SDL_XPixels[pixel]>=0)
|
for ( pixel=0; pixel<numcolors; pixel++ )
|
||||||
ReleasePen(GFX_Display->ViewPort.ColorMap,SDL_XPixels[pixel]);
|
{
|
||||||
|
if(SDL_XPixels[pixel]>=0)
|
||||||
|
ReleasePen(GFX_Display->ViewPort.ColorMap,SDL_XPixels[pixel]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
free(SDL_XPixels);
|
||||||
free(SDL_XPixels);
|
SDL_XPixels = NULL;
|
||||||
SDL_XPixels = NULL;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CGX_SetSizeHints(_THIS, int w, int h, Uint32 flags)
|
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 ) {
|
if ( SDL_Window ) {
|
||||||
CGX_DestroyWindow(this, screen);
|
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 */
|
/* find out which visual we are going to use */
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -656,6 +777,11 @@ int CGX_CreateWindow(_THIS, SDL_Surface *screen,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the appropriate colormap */
|
/* 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 ) {
|
if ( GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_PIXFMT)==PIXFMT_LUT8 || bpp==8 ) {
|
||||||
int ncolors;
|
int ncolors;
|
||||||
D(bug("Alloco XPixels x la palette...\n"));
|
D(bug("Alloco XPixels x la palette...\n"));
|
||||||
|
@ -681,32 +807,70 @@ int CGX_CreateWindow(_THIS, SDL_Surface *screen,
|
||||||
flags |= SDL_HWPALETTE;
|
flags |= SDL_HWPALETTE;
|
||||||
|
|
||||||
if ( 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 */
|
/* resize the (possibly new) window manager window */
|
||||||
|
|
||||||
/* Create (or use) the X11 display window */
|
/* Create (or use) the X11 display window */
|
||||||
if ( flags & SDL_OPENGL ) {
|
if ( !SDL_windowid ) {
|
||||||
return(-1);
|
if ( flags & SDL_OPENGL ) {
|
||||||
} else {
|
return(-1);
|
||||||
if(flags & SDL_FULLSCREEN)
|
}
|
||||||
SDL_Window = OpenWindowTags(NULL,WA_Width,w,WA_Height,h,
|
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_Flags,WFLG_ACTIVATE|WFLG_RMBTRAP|WFLG_BORDERLESS|WFLG_BACKDROP|WFLG_REPORTMOUSE,
|
||||||
WA_IDCMP,IDCMP_RAWKEY|IDCMP_MOUSEBUTTONS|IDCMP_MOUSEMOVE,
|
WA_IDCMP,IDCMP_RAWKEY|IDCMP_MOUSEBUTTONS|IDCMP_MOUSEMOVE,
|
||||||
WA_CustomScreen,(ULONG)SDL_Display,
|
WA_CustomScreen,(ULONG)SDL_Display,
|
||||||
TAG_DONE);
|
TAG_DONE);
|
||||||
else
|
|
||||||
SDL_Window = OpenWindowTags(NULL,WA_InnerWidth,w,WA_InnerHeight,h,
|
D(bug("Apro finestra backdrop %ldx%ld su %lx!\n",w,h,SDL_Display));
|
||||||
WA_Flags,WFLG_REPORTMOUSE|WFLG_ACTIVATE|WFLG_RMBTRAP|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_DRAGBAR| ((screen->flags&SDL_RESIZABLE) ? WFLG_SIZEGADGET|WFLG_SIZEBBOTTOM : 0),
|
}
|
||||||
|
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_IDCMP,IDCMP_RAWKEY|IDCMP_CLOSEWINDOW|IDCMP_MOUSEBUTTONS|IDCMP_NEWSIZE|IDCMP_MOUSEMOVE,
|
||||||
WA_PubScreen,(ULONG)SDL_Display,
|
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);
|
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)
|
if(flags&SDL_HWSURFACE)
|
||||||
screen->flags|=SDL_HWSURFACE;
|
screen->flags|=SDL_HWSURFACE;
|
||||||
|
|
||||||
CGX_SetSizeHints(this, w, h, flags);
|
if( !SDL_windowid ) {
|
||||||
current_w = w;
|
CGX_SetSizeHints(this, w, h, flags);
|
||||||
current_h = h;
|
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 */
|
/* Map them both and go fullscreen, if requested */
|
||||||
if ( flags & SDL_FULLSCREEN ) {
|
if ( ! SDL_windowid ) {
|
||||||
screen->flags |= SDL_FULLSCREEN;
|
if ( flags & SDL_FULLSCREEN ) {
|
||||||
currently_fullscreen=1;
|
screen->flags |= SDL_FULLSCREEN;
|
||||||
// CGX_EnterFullScreen(this); Ci siamo gia'!
|
currently_fullscreen=1;
|
||||||
} else {
|
// CGX_EnterFullScreen(this); Ci siamo gia'!
|
||||||
screen->flags &= ~SDL_FULLSCREEN;
|
} else {
|
||||||
|
screen->flags &= ~SDL_FULLSCREEN;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
screen->w = w;
|
||||||
|
screen->h = h;
|
||||||
|
screen->pitch = SDL_CalculatePitch(screen);
|
||||||
|
CGX_ResizeImage(this, screen, flags);
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CGX_ResizeWindow(_THIS,
|
int CGX_ResizeWindow(_THIS,
|
||||||
SDL_Surface *screen, int w, int h, Uint32 flags)
|
SDL_Surface *screen, int w, int h, Uint32 flags)
|
||||||
{
|
{
|
||||||
/* Resize the window manager window */
|
if ( ! SDL_windowid ) {
|
||||||
CGX_SetSizeHints(this, w, h, flags);
|
/* Resize the window manager window */
|
||||||
current_w = w;
|
CGX_SetSizeHints(this, w, h, flags);
|
||||||
current_h = h;
|
current_w = w;
|
||||||
|
current_h = h;
|
||||||
|
|
||||||
ChangeWindowBox(SDL_Window,SDL_Window->LeftEdge,SDL_Window->TopEdge, w+SDL_Window->BorderLeft+SDL_Window->BorderRight,
|
ChangeWindowBox(SDL_Window,SDL_Window->LeftEdge,SDL_Window->TopEdge, w+SDL_Window->BorderLeft+SDL_Window->BorderRight,
|
||||||
h+SDL_Window->BorderTop+SDL_Window->BorderBottom);
|
h+SDL_Window->BorderTop+SDL_Window->BorderBottom);
|
||||||
|
|
||||||
/* Resize the fullscreen and display windows */
|
/* Resize the fullscreen and display windows */
|
||||||
if ( flags & SDL_FULLSCREEN ) {
|
/*
|
||||||
if ( screen->flags & SDL_FULLSCREEN ) {
|
if ( flags & SDL_FULLSCREEN ) {
|
||||||
CGX_ResizeFullScreen(this);
|
if ( screen->flags & SDL_FULLSCREEN ) {
|
||||||
|
CGX_ResizeFullScreen(this);
|
||||||
|
} else {
|
||||||
|
screen->flags |= SDL_FULLSCREEN;
|
||||||
|
CGX_EnterFullScreen(this);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
screen->flags |= SDL_FULLSCREEN;
|
if ( screen->flags & SDL_FULLSCREEN ) {
|
||||||
CGX_EnterFullScreen(this);
|
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);
|
return(0);
|
||||||
}
|
}
|
||||||
|
@ -783,24 +971,51 @@ static SDL_Surface *CGX_SetVideoMode(_THIS, SDL_Surface *current,
|
||||||
int width, int height, int bpp, Uint32 flags)
|
int width, int height, int bpp, Uint32 flags)
|
||||||
{
|
{
|
||||||
Uint32 saved_flags;
|
Uint32 saved_flags;
|
||||||
|
int needcreate=0;
|
||||||
|
|
||||||
/* Lock the event thread, in multi-threading environments */
|
/* Lock the event thread, in multi-threading environments */
|
||||||
SDL_Lock_EventThread();
|
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...
|
// Check if we need to close an already existing videomode...
|
||||||
|
|
||||||
if(current->flags&SDL_FULLSCREEN && !(flags&SDL_FULLSCREEN))
|
if(current->flags&SDL_FULLSCREEN && !(flags&SDL_FULLSCREEN))
|
||||||
{
|
{
|
||||||
|
unsigned long i;
|
||||||
CGX_DestroyImage(this,current);
|
CGX_DestroyImage(this,current);
|
||||||
CGX_DestroyWindow(this,current);
|
CGX_DestroyWindow(this,current);
|
||||||
DestroyScreen(this);
|
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 */
|
/* Check the combination of flags we were passed */
|
||||||
if ( flags & SDL_FULLSCREEN ) {
|
if ( flags & SDL_FULLSCREEN ) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Clear fullscreen flag if not supported */
|
/* 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 ||
|
if(current->w!=width ||
|
||||||
current->h!=height ||
|
current->h!=height ||
|
||||||
|
@ -930,7 +1145,7 @@ buildnewscreen:
|
||||||
saved_flags = current->flags;
|
saved_flags = current->flags;
|
||||||
|
|
||||||
if (SDL_Window && (saved_flags&SDL_OPENGL) == (flags&SDL_OPENGL)
|
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) {
|
if (CGX_ResizeWindow(this, current, width, height, flags) < 0) {
|
||||||
current = NULL;
|
current = NULL;
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -942,6 +1157,7 @@ buildnewscreen:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* Set up the new mode framebuffer */
|
/* Set up the new mode framebuffer */
|
||||||
if ( ((current->w != width) || (current->h != height)) ||
|
if ( ((current->w != width) || (current->h != height)) ||
|
||||||
((saved_flags&SDL_OPENGL) != (flags&SDL_OPENGL)) ) {
|
((saved_flags&SDL_OPENGL) != (flags&SDL_OPENGL)) ) {
|
||||||
|
@ -950,6 +1166,8 @@ buildnewscreen:
|
||||||
current->pitch = SDL_CalculatePitch(current);
|
current->pitch = SDL_CalculatePitch(current);
|
||||||
CGX_ResizeImage(this, current, flags);
|
CGX_ResizeImage(this, current, flags);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
current->flags |= (flags&SDL_RESIZABLE); // Resizable only if the user asked it
|
current->flags |= (flags&SDL_RESIZABLE); // Resizable only if the user asked it
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
@ -964,6 +1182,11 @@ static int CGX_ToggleFullScreen(_THIS, int on)
|
||||||
{
|
{
|
||||||
Uint32 event_thread;
|
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 */
|
/* Don't lock if we are the event thread */
|
||||||
event_thread = SDL_EventThreadID();
|
event_thread = SDL_EventThreadID();
|
||||||
if ( event_thread && (SDL_ThreadID() == event_thread) ) {
|
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 */
|
/* 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 */
|
/* It's easy if we have a hidden colormap */
|
||||||
if ( (this->screen->flags & SDL_HWPALETTE) && currently_fullscreen )
|
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));
|
// D(bug("Setting %ld colors on an HWPALETTE screen\n",ncolors));
|
||||||
|
|
||||||
for ( i=0; i<ncolors; i++ ) {
|
for ( i=0; i<ncolors; i++ ) {
|
||||||
xcmap[i*3+1] = colors[i].r<<24;
|
xcmap[i*3+1] = colors[i+firstcolor].r<<24;
|
||||||
xcmap[i*3+2] = colors[i].g<<24;
|
xcmap[i*3+2] = colors[i+firstcolor].g<<24;
|
||||||
xcmap[i*3+3] = colors[i].b<<24;
|
xcmap[i*3+3] = colors[i+firstcolor].b<<24;
|
||||||
}
|
}
|
||||||
xcmap[ncolors*3+1]=0;
|
xcmap[ncolors*3+1]=0;
|
||||||
LoadRGB32(&GFX_Display->ViewPort,xcmap);
|
LoadRGB32(&GFX_Display->ViewPort,xcmap);
|
||||||
|
@ -1119,7 +1339,6 @@ static int CGX_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
colors = this->screen->format->palette->colors;
|
|
||||||
if(this->hidden->depth==8)
|
if(this->hidden->depth==8)
|
||||||
{
|
{
|
||||||
// In this case I have to unalloc and realloc the full palette
|
// In this case I have to unalloc and realloc the full palette
|
||||||
|
@ -1178,6 +1397,22 @@ static void CGX_VideoQuit(_THIS)
|
||||||
SDL_VideoSurface=NULL;
|
SDL_VideoSurface=NULL;
|
||||||
CGX_FreeVideoModes(this);
|
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 */
|
/* Free that blank cursor */
|
||||||
if ( SDL_BlankCursor != NULL ) {
|
if ( SDL_BlankCursor != NULL ) {
|
||||||
FreeMem(SDL_BlankCursor,16);
|
FreeMem(SDL_BlankCursor,16);
|
||||||
|
|
|
@ -69,6 +69,8 @@ struct SDL_PrivateVideoData {
|
||||||
struct Window *SDL_Window; /* Shared by both displays (no X security?) */
|
struct Window *SDL_Window; /* Shared by both displays (no X security?) */
|
||||||
unsigned char *BlankCursor; /* The invisible cursor */
|
unsigned char *BlankCursor; /* The invisible cursor */
|
||||||
|
|
||||||
|
char *SDL_windowid; /* Flag: true if we have been passed a window */
|
||||||
|
|
||||||
/* The variables used for displaying graphics */
|
/* The variables used for displaying graphics */
|
||||||
Uint8 *Ximage; /* The X image for our window */
|
Uint8 *Ximage; /* The X image for our window */
|
||||||
int swap_pixels; /* Flag: true if display is swapped endian */
|
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 SDL_Window (this->hidden->SDL_Window)
|
||||||
#define WM_DELETE_WINDOW (this->hidden->WM_DELETE_WINDOW)
|
#define WM_DELETE_WINDOW (this->hidden->WM_DELETE_WINDOW)
|
||||||
#define SDL_BlankCursor (this->hidden->BlankCursor)
|
#define SDL_BlankCursor (this->hidden->BlankCursor)
|
||||||
|
#define SDL_windowid (this->hidden->SDL_windowid)
|
||||||
#define SDL_Ximage (this->hidden->Ximage)
|
#define SDL_Ximage (this->hidden->Ximage)
|
||||||
#define SDL_GC (this->hidden->gc)
|
#define SDL_GC (this->hidden->gc)
|
||||||
#define swap_pixels (this->hidden->swap_pixels)
|
#define swap_pixels (this->hidden->swap_pixels)
|
||||||
|
@ -152,6 +155,9 @@ struct SDL_PrivateVideoData {
|
||||||
#define SDL_XPixels (this->hidden->XPixels)
|
#define SDL_XPixels (this->hidden->XPixels)
|
||||||
#define SDL_iconcolors (this->hidden->iconcolors)
|
#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,
|
extern int CGX_CreateWindow(_THIS, SDL_Surface *screen,
|
||||||
int w, int h, int bpp, Uint32 flags);
|
int w, int h, int bpp, Uint32 flags);
|
||||||
extern int CGX_ResizeWindow(_THIS,
|
extern int CGX_ResizeWindow(_THIS,
|
||||||
|
|
191
src/video/cybergfx/SDL_cgxyuv.c
Normal file
191
src/video/cybergfx/SDL_cgxyuv.c
Normal file
|
@ -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 */
|
45
src/video/cybergfx/SDL_cgxyuv_c.h
Normal file
45
src/video/cybergfx/SDL_cgxyuv_c.h
Normal file
|
@ -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 */
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
SDL - Simple DirectMedia Layer
|
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
|
This library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Library General Public
|
modify it under the terms of the GNU Library General Public
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue