diff options
author | Sam Lantinga <slouken@libsdl.org> | 2002-10-05 16:50:56 +0000 |
---|---|---|
committer | Sam Lantinga <slouken@libsdl.org> | 2002-10-05 16:50:56 +0000 |
commit | 3ee2de057f31ea7b7d94781e90283d984be8eb13 (patch) | |
tree | 255ee0dcf0510c2687480d9436119cbb4a14938d | |
parent | 148a1a64f4ab2ddf70b4e6b1c27f9e3cdd0836ce (diff) |
Added initial support for Dreamcast (thanks HERO!)
--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%40510
43 files changed, 2847 insertions, 4 deletions
diff --git a/Makefile.am b/Makefile.am index 1510ba81..e61a32a4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -25,6 +25,7 @@ EXTRA_DIST = \ README \ README.AmigaOS \ README.CVS \ + README.DC \ README.Epoc \ README.MacOS \ README.MacOSX \ @@ -40,6 +41,7 @@ EXTRA_DIST = \ VisualC.html \ VisualC.zip \ VisualCE.zip \ + Makefile.dc \ MPWmake.sea.bin \ CWprojects.sea.bin \ PBProjects.tar.gz \ diff --git a/Makefile.dc b/Makefile.dc new file mode 100644 index 00000000..46739132 --- /dev/null +++ b/Makefile.dc @@ -0,0 +1,105 @@ +#GL=1 + +CC = sh-elf-gcc -ml -m4-single-only +AR = sh-elf-ar +KOS_BASE=/prog/kos-1.1.7 +INCS = -I$(KOS_BASE)/libc/include -I$(KOS_BASE)/include -I$(KOS_BASE)/kernel/arch/dreamcast/include +DEFS =-DNO_SIGNAL_H -DENABLE_DC + +ifdef GL +DEFS += -DHAVE_OPENGL +TARGET = libSDL_gl.a +else +TARGET = libSDL.a +endif + +OPTFLAGS=-O2 -fomit-frame-pointer +CFLAGS=-D_arch_dreamcast $(DEFS) $(INCS) -Iinclude -Isrc -Isrc/audio -Isrc/cdrom -Isrc/endian -Isrc/events -Isrc/joystick -Isrc/thread/dc -Isrc/thread -Isrc/timer -Isrc/video $(OPTFLAGS) + +SRCS = \ + src/audio/dc/SDL_dcaudio.c \ + src/audio/dc/aica.c \ + src/audio/SDL_audio.c \ + src/audio/SDL_audiocvt.c \ + src/audio/SDL_audiodev.c \ + src/audio/SDL_audiomem.c \ + src/audio/SDL_mixer.c \ + src/audio/SDL_wave.c \ + src/cdrom/dc/SDL_syscdrom.c \ + src/cdrom/SDL_cdrom.c \ + src/endian/SDL_endian.c \ + src/events/SDL_active.c \ + src/events/SDL_events.c \ + src/events/SDL_expose.c \ + src/events/SDL_keyboard.c \ + src/events/SDL_mouse.c \ + src/events/SDL_quit.c \ + src/events/SDL_resize.c \ + src/file/SDL_rwops.c \ + src/joystick/dc/SDL_sysjoystick.c \ + src/joystick/SDL_joystick.c \ + src/SDL.c \ + src/SDL_error.c \ + src/SDL_fatal.c \ + src/SDL_getenv.c \ + src/SDL_loadso.c \ + src/thread/dc/SDL_syscond.c \ + src/thread/dc/SDL_sysmutex.c \ + src/thread/dc/SDL_syssem.c \ + src/thread/dc/SDL_systhread.c \ + src/thread/SDL_thread.c \ + src/timer/dc/SDL_systimer.c \ + src/timer/SDL_timer.c \ + src/video/dc/SDL_dcevents.c \ + src/video/dc/SDL_dcvideo.c \ + src/video/SDL_blit.c \ + src/video/SDL_blit_0.c \ + src/video/SDL_blit_1.c \ + src/video/SDL_blit_A.c \ + src/video/SDL_blit_N.c \ + src/video/SDL_bmp.c \ + src/video/SDL_cursor.c \ + src/video/SDL_gamma.c \ + src/video/SDL_pixels.c \ + src/video/SDL_RLEaccel.c \ + src/video/SDL_stretch.c \ + src/video/SDL_surface.c \ + src/video/SDL_video.c \ + src/video/SDL_yuv.c \ + src/video/SDL_yuv_sw.c \ + +OBJS = $(SRCS:.c=.o) + +TEST = \ + test/checkkeys.c \ + test/graywin.c \ + test/loopwave.c \ + test/testalpha.c \ + test/testbitmap.c \ + test/testcdrom.c \ + test/testerror.c \ + test/testgamma.c \ + test/testgl.c \ + test/testhread.c \ + test/testjoystick.c \ + test/testkeys.c \ + test/testlock.c \ + test/testoverlay.c \ + test/testpalette.c \ + test/testsem.c \ + test/testsprite.c \ + test/testtimer.c \ + test/testtypes.c \ + test/testver.c \ + test/testvidinfo.c \ + test/testwin.c \ + test/testwm.c \ + test/threadwin.c \ + test/torturethread.c \ + +clean: + rm $(OBJS) + +$(TARGET) : $(OBJS) + $(AR) rcs $(TARGET) $(OBJS) + diff --git a/README.DC b/README.DC new file mode 100644 index 00000000..c7c39b18 --- /dev/null +++ b/README.DC @@ -0,0 +1,37 @@ +SDL for Dreamcast (beta2) + + BERO + bero@geocities.co.jp + + http://www.geocities.co.jp/Playtown/2004/ + +this work with kos-newlib +http://sourceforge.net/projects/dcquake/ + +compile +- edit KOS_BASE in Makefie.dc for your enviroment +- make -f Makefile.dc + +FIXME: The KOS thread files can be found on HERO's site - not in the SDL source. +- overwrite thread/*.c to kos-1.1.7/kernel/thread +- rebuild kos + +compile with gl support +- install latest libgl from http://sourceforge.net/projects/dcquake/ +- uncomment GL=1 in Makefile.dc +- make -f Makefile.dc clean +- make -f Makefile.dc + +install +- copy include/*.h and libSDL.a or libSDL_gl.a for your enviroment + +changelog: + +beta2 +- OpenGL support +- Hardware page flip support + +beta +- thread, timer don't tested so much. +- not support OpenGL + @@ -16,6 +16,7 @@ be found at the <A HREF="http://www.libsdl.org/"> main SDL page</A>. Major changes since SDL 1.0.0: </H2> <UL> + <LI> 1.2.5: Added initial support for Dreamcast (thanks HERO!) <LI> 1.2.5: Updated Borland projects for Kylix 3 (thanks Dominique) <LI> 1.2.5: Added project files for embedded Visual C++ 4.0 <LI> 1.2.5: Added SDL_BUTTON_WHEELUP (4) and SDL_BUTTON_WHEELDOWN (5) diff --git a/src/audio/Makefile.am b/src/audio/Makefile.am index 8330d280..9b3a2afa 100644 --- a/src/audio/Makefile.am +++ b/src/audio/Makefile.am @@ -6,7 +6,7 @@ noinst_LTLIBRARIES = libaudio.la # Define which subdirectories need to be built SUBDIRS = @AUDIO_SUBDIRS@ DIST_SUBDIRS = alsa arts baudio dma dmedia dsp esd macrom nas nto openbsd \ - paudio sun ums windib windx5 disk mint + paudio sun ums windib windx5 disk mint dc DRIVERS = @AUDIO_DRIVERS@ diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 287fa26b..97d00b7f 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -89,6 +89,9 @@ static AudioBootStrap *bootstrap[] = { #ifdef DISKAUD_SUPPORT &DISKAUD_bootstrap, #endif +#ifdef ENABLE_DC + &DCAUD_bootstrap, +#endif NULL }; SDL_AudioDevice *current_audio = NULL; diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h index 55ad91f0..3d1ad9e9 100644 --- a/src/audio/SDL_sysaudio.h +++ b/src/audio/SDL_sysaudio.h @@ -153,6 +153,9 @@ extern AudioBootStrap MINTAUDIO_bootstrap; #ifdef DISKAUD_SUPPORT extern AudioBootStrap DISKAUD_bootstrap; #endif +#ifdef ENABLE_DC +extern AudioBootStrap DCAUD_bootstrap; +#endif /* This is the current audio device */ extern SDL_AudioDevice *current_audio; diff --git a/src/audio/dc/.cvsignore b/src/audio/dc/.cvsignore new file mode 100644 index 00000000..899d5355 --- /dev/null +++ b/src/audio/dc/.cvsignore @@ -0,0 +1,6 @@ +Makefile.in +Makefile +.libs +*.o +*.lo +*.la diff --git a/src/audio/dc/Makefile.am b/src/audio/dc/Makefile.am new file mode 100644 index 00000000..a5d0e1cf --- /dev/null +++ b/src/audio/dc/Makefile.am @@ -0,0 +1,11 @@ + +## Makefile.am for SDL on the Dreamcast console + +noinst_LTLIBRARIES = libaudio_dc.la +libaudio_dc_la_SOURCES = $(SRCS) + +# The SDL audio driver sources +SRCS = SDL_dcaudio.c \ + SDL_dcaudio.h \ + aica.c \ + aica.h diff --git a/src/audio/dc/SDL_dcaudio.c b/src/audio/dc/SDL_dcaudio.c new file mode 100644 index 00000000..8e84c299 --- /dev/null +++ b/src/audio/dc/SDL_dcaudio.c @@ -0,0 +1,245 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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 + + BERO <bero@geocities.co.jp> + based on SDL_diskaudio.c by Sam Lantinga <slouken@libsdl.org> + +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +/* Output dreamcast aica */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + + +#include "SDL_audio.h" +#include "SDL_error.h" +#include "SDL_audiomem.h" +#include "SDL_audio_c.h" +#include "SDL_timer.h" +#include "SDL_audiodev_c.h" +#include "SDL_dcaudio.h" + +#include "aica.h" +#include <dc/spu.h> + +/* Audio driver functions */ +static int DCAUD_OpenAudio(_THIS, SDL_AudioSpec *spec); +static void DCAUD_WaitAudio(_THIS); +static void DCAUD_PlayAudio(_THIS); +static Uint8 *DCAUD_GetAudioBuf(_THIS); +static void DCAUD_CloseAudio(_THIS); + +/* Audio driver bootstrap functions */ +static int DCAUD_Available(void) +{ + return 1; +} + +static void DCAUD_DeleteDevice(SDL_AudioDevice *device) +{ + free(device->hidden); + free(device); +} + +static SDL_AudioDevice *DCAUD_CreateDevice(int devindex) +{ + SDL_AudioDevice *this; + + /* Initialize all variables that we clean on shutdown */ + this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice)); + if ( this ) { + memset(this, 0, (sizeof *this)); + this->hidden = (struct SDL_PrivateAudioData *) + malloc((sizeof *this->hidden)); + } + if ( (this == NULL) || (this->hidden == NULL) ) { + SDL_OutOfMemory(); + if ( this ) { + free(this); + } + return(0); + } + memset(this->hidden, 0, (sizeof *this->hidden)); + + /* Set the function pointers */ + this->OpenAudio = DCAUD_OpenAudio; + this->WaitAudio = DCAUD_WaitAudio; + this->PlayAudio = DCAUD_PlayAudio; + this->GetAudioBuf = DCAUD_GetAudioBuf; + this->CloseAudio = DCAUD_CloseAudio; + + this->free = DCAUD_DeleteDevice; + + spu_init(); + + return this; +} + +AudioBootStrap DCAUD_bootstrap = { + "dcaudio", "Dreamcast AICA audio", + DCAUD_Available, DCAUD_CreateDevice +}; + +/* This function waits until it is possible to write a full sound buffer */ +static void DCAUD_WaitAudio(_THIS) +{ + if (this->hidden->playing) { + /* wait */ + while(aica_get_pos(0)/this->spec.samples == this->hidden->nextbuf) { + thd_pass(); + } + } +} + +#define SPU_RAM_BASE 0xa0800000 + +static void spu_memload_stereo8(int leftpos,int rightpos,void *src0,size_t size) +{ + uint8 *src = src0; + uint32 *left = (uint32*)(leftpos +SPU_RAM_BASE); + uint32 *right = (uint32*)(rightpos+SPU_RAM_BASE); + size = (size+7)/8; + while(size--) { + unsigned lval,rval; + lval = *src++; + rval = *src++; + lval|= (*src++)<<8; + rval|= (*src++)<<8; + lval|= (*src++)<<16; + rval|= (*src++)<<16; + lval|= (*src++)<<24; + rval|= (*src++)<<24; + g2_write_32(left++,lval); + g2_write_32(right++,rval); + g2_fifo_wait(); + } +} + +static void spu_memload_stereo16(int leftpos,int rightpos,void *src0,size_t size) +{ + uint16 *src = src0; + uint32 *left = (uint32*)(leftpos +SPU_RAM_BASE); + uint32 *right = (uint32*)(rightpos+SPU_RAM_BASE); + size = (size+7)/8; + while(size--) { + unsigned lval,rval; + lval = *src++; + rval = *src++; + lval|= (*src++)<<16; + rval|= (*src++)<<16; + g2_write_32(left++,lval); + g2_write_32(right++,rval); + g2_fifo_wait(); + } +} + +static void DCAUD_PlayAudio(_THIS) +{ + SDL_AudioSpec *spec = &this->spec; + unsigned int offset; + + if (this->hidden->playing) { + /* wait */ + while(aica_get_pos(0)/spec->samples == this->hidden->nextbuf) { + thd_pass(); + } + } + + offset = this->hidden->nextbuf*spec->size; + this->hidden->nextbuf^=1; + /* Write the audio data, checking for EAGAIN on broken audio drivers */ + if (spec->channels==1) { + spu_memload(this->hidden->leftpos+offset,this->hidden->mixbuf,this->hidden->mixlen); + } else { + offset/=2; + if ((this->spec.format&255)==8) { + spu_memload_stereo8(this->hidden->leftpos+offset,this->hidden->rightpos+offset,this->hidden->mixbuf,this->hidden->mixlen); + } else { + spu_memload_stereo16(this->hidden->leftpos+offset,this->hidden->rightpos+offset,this->hidden->mixbuf,this->hidden->mixlen); + } + } + + if (!this->hidden->playing) { + int mode; + this->hidden->playing = 1; + mode = (spec->format==AUDIO_S8)?SM_8BIT:SM_16BIT; + if (spec->channels==1) { + aica_play(0,mode,this->hidden->leftpos,0,spec->samples*2,spec->freq,255,128,1); + } else { + aica_play(0,mode,this->hidden->leftpos ,0,spec->samples*2,spec->freq,255,0,1); + aica_play(1,mode,this->hidden->rightpos,0,spec->samples*2,spec->freq,255,255,1); + } + } +} + +static Uint8 *DCAUD_GetAudioBuf(_THIS) +{ + return(this->hidden->mixbuf); +} + +static void DCAUD_CloseAudio(_THIS) +{ + aica_stop(0); + if (this->spec.channels==2) aica_stop(1); + if ( this->hidden->mixbuf != NULL ) { + SDL_FreeAudioMem(this->hidden->mixbuf); + this->hidden->mixbuf = NULL; + } +} + +static int DCAUD_OpenAudio(_THIS, SDL_AudioSpec *spec) +{ + switch(spec->format&0xff) { + case 8: spec->format = AUDIO_S8; break; + case 16: spec->format = AUDIO_S16LSB; break; + default: + SDL_SetError("Unsupported audio format"); + return(-1); + } + + /* Update the fragment size as size in bytes */ + SDL_CalculateAudioSpec(spec); + + /* Allocate mixing buffer */ + this->hidden->mixlen = spec->size; + this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen); + if ( this->hidden->mixbuf == NULL ) { + return(-1); + } + memset(this->hidden->mixbuf, spec->silence, spec->size); + this->hidden->leftpos = 0x11000; + this->hidden->rightpos = 0x11000+spec->size; + this->hidden->playing = 0; + this->hidden->nextbuf = 0; + + /* We're ready to rock and roll. :-) */ + return(0); +} diff --git a/src/audio/dc/SDL_dcaudio.h b/src/audio/dc/SDL_dcaudio.h new file mode 100644 index 00000000..8084e19a --- /dev/null +++ b/src/audio/dc/SDL_dcaudio.h @@ -0,0 +1,45 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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 + + BERO <bero@geocities.co.jp> + based on SDL_diskaudio.h by Sam Lantinga <slouken@libsdl.org> +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +#ifndef _SDL_diskaudio_h +#define _SDL_diskaudio_h + +#include "SDL_sysaudio.h" + +/* Hidden "this" pointer for the video functions */ +#define _THIS SDL_AudioDevice *this + +struct SDL_PrivateAudioData { + /* The file descriptor for the audio device */ + Uint8 *mixbuf; + Uint32 mixlen; + int playing; + int leftpos,rightpos; + int nextbuf; +}; + +#endif /* _SDL_diskaudio_h */ diff --git a/src/audio/dc/aica.c b/src/audio/dc/aica.c new file mode 100644 index 00000000..160c2857 --- /dev/null +++ b/src/audio/dc/aica.c @@ -0,0 +1,267 @@ +/* This file is part of the Dreamcast function library. + * Please see libdream.c for further details. + * + * (c)2000 Dan Potter + * modify BERO + */ +#include "aica.h" + +/* #define dc_snd_base ((volatile unsigned char *)0x00800000) */ /* arm side */ +#define dc_snd_base ((volatile unsigned char *)0xa0700000) /* dc side */ + +/* Some convienence macros */ +#define SNDREGADDR(x) (0xa0700000 + (x)) +#define CHNREGADDR(ch,x) SNDREGADDR(0x80*(ch)+(x)) + + +#define SNDREG32(x) (*(volatile unsigned long *)SNDREGADDR(x)) +#define SNDREG8(x) (*(volatile unsigned char *)SNDREGADDR(x)) +#define CHNREG32(ch, x) (*(volatile unsigned long *)CHNREGADDR(ch,x)) +#define CHNREG8(ch, x) (*(volatile unsigned long *)CHNREGADDR(ch,x)) + +#define G2_LOCK(OLD) \ + do { \ + if (!irq_inside_int()) \ + OLD = irq_disable(); \ + /* suspend any G2 DMA here... */ \ + while((*(volatile unsigned int *)0xa05f688c) & 0x20) \ + ; \ + } while(0) + +#define G2_UNLOCK(OLD) \ + do { \ + /* resume any G2 DMA here... */ \ + if (!irq_inside_int()) \ + irq_restore(OLD); \ + } while(0) + + +void aica_init() { + int i, j, old; + + /* Initialize AICA channels */ + G2_LOCK(old); + SNDREG32(0x2800) = 0x0000; + + for (i=0; i<64; i++) { + for (j=0; j<0x80; j+=4) { + if ((j&31)==0) g2_fifo_wait(); + CHNREG32(i, j) = 0; + } + g2_fifo_wait(); + CHNREG32(i,0) = 0x8000; + CHNREG32(i,20) = 0x1f; + } + + SNDREG32(0x2800) = 0x000f; + g2_fifo_wait(); + G2_UNLOCK(old); +} + +/* Translates a volume from linear form to logarithmic form (required by + the AICA chip */ +/* int logs[] = { + +0, 40, 50, 58, 63, 68, 73, 77, 80, 83, 86, 89, 92, 94, 97, 99, 101, 103, +105, 107, 109, 111, 112, 114, 116, 117, 119, 120, 122, 123, 125, 126, 127, +129, 130, 131, 133, 134, 135, 136, 137, 139, 140, 141, 142, 143, 144, 145, +146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 156, 157, 158, 159, +160, 161, 162, 162, 163, 164, 165, 166, 166, 167, 168, 169, 170, 170, 171, +172, 172, 173, 174, 175, 175, 176, 177, 177, 178, 179, 180, 180, 181, 182, +182, 183, 183, 184, 185, 185, 186, 187, 187, 188, 188, 189, 190, 190, 191, +191, 192, 193, 193, 194, 194, 195, 196, 196, 197, 197, 198, 198, 199, 199, +200, 201, 201, 202, 202, 203, 203, 204, 204, 205, 205, 206, 206, 207, 207, +208, 208, 209, 209, 210, 210, 211, 211, 212, 212, 213, 213, 214, 214, 215, +215, 216, 216, 217, 217, 217, 218, 218, 219, 219, 220, 220, 221, 221, 222, +222, 222, 223, 223, 224, 224, 225, 225, 225, 226, 226, 227, 227, 228, 228, +228, 229, 229, 230, 230, 230, 231, 231, 232, 232, 232, 233, 233, 234, 234, +234, 235, 235, 236, 236, 236, 237, 237, 238, 238, 238, 239, 239, 240, 240, +240, 241, 241, 241, 242, 242, 243, 243, 243, 244, 244, 244, 245, 245, 245, +246, 246, 247, 247, 247, 248, 248, 248, 249, 249, 249, 250, 250, 250, 251, +251, 251, 252, 252, 252, 253, 253, 253, 254, 254, 254, 255 + +}; */ + +const static unsigned char logs[] = { + 0, 15, 22, 27, 31, 35, 39, 42, 45, 47, 50, 52, 55, 57, 59, 61, + 63, 65, 67, 69, 71, 73, 74, 76, 78, 79, 81, 82, 84, 85, 87, 88, + 90, 91, 92, 94, 95, 96, 98, 99, 100, 102, 103, 104, 105, 106, + 108, 109, 110, 111, 112, 113, 114, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 156, + 157, 158, 159, 160, 160, 161, 162, 163, 164, 164, 165, 166, 167, + 167, 168, 169, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, + 177, 178, 178, 179, 180, 181, 181, 182, 183, 183, 184, 185, 185, + 186, 187, 187, 188, 189, 189, 190, 191, 191, 192, 193, 193, 194, + 195, 195, 196, 197, 197, 198, 199, 199, 200, 200, 201, 202, 202, + 203, 204, 204, 205, 205, 206, 207, 207, 208, 209, 209, 210, 210, + 211, 212, 212, 213, 213, 214, 215, 215, 216, 216, 217, 217, 218, + 219, 219, 220, 220, 221, 221, 222, 223, 223, 224, 224, 225, 225, + 226, 227, 227, 228, 228, 229, 229, 230, 230, 231, 232, 232, 233, + 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 239, 239, 240, + 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, + 247, 247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253, 254, 255 +}; + +/* For the moment this is going to have to suffice, until we really + figure out what these mean. */ +#define AICA_PAN(x) ((x)==0x80?(0):((x)<0x80?(0x1f):(0x0f))) +#define AICA_VOL(x) (0xff - logs[128 + (((x) & 0xff) / 2)]) +//#define AICA_VOL(x) (0xff - logs[x&255]) + +static inline unsigned AICA_FREQ(unsigned freq) { + unsigned long freq_lo, freq_base = 5644800; + int freq_hi = 7; + + /* Need to convert frequency to floating point format + (freq_hi is exponent, freq_lo is mantissa) + Formula is ferq = 44100*2^freq_hi*(1+freq_lo/1024) */ + while (freq < freq_base && freq_hi > -8) { + freq_base >>= 1; + --freq_hi; + } + while (freq < freq_base && freq_hi > -8) { + freq_base >>= 1; + freq_hi--; + } + freq_lo = (freq<<10) / freq_base; + return (freq_hi << 11) | (freq_lo & 1023); +} + +/* Sets up a sound channel completely. This is generally good if you want + a quick and dirty way to play notes. If you want a more comprehensive + set of routines (more like PC wavetable cards) see below. + + ch is the channel to play on (0 - 63) + smpptr is the pointer to the sound data; if you're running off the + SH4, then this ought to be (ptr - 0xa0800000); otherwise it's just + ptr. Basically, it's an offset into sound ram. + mode is one of the mode constants (16 bit, 8 bit, ADPCM) + nsamp is the number of samples to play (not number of bytes!) + freq is the sampling rate of the sound + vol is the volume, 0 to 0xff (0xff is louder) + pan is a panning constant -- 0 is left, 128 is center, 255 is right. + + This routine (and the similar ones) owe a lot to Marcus' sound example -- + I hadn't gotten quite this far into dissecting the individual regs yet. */ +void aica_play(int ch,int mode,unsigned long smpptr,int loopst,int loopend,int freq,int vol,int pan,int loopflag) { + int i; + int val; + int old; + + /* Stop the channel (if it's already playing) */ + aica_stop(ch); + /* doesn't seem to be needed, but it's here just in case */ +/* + for (i=0; i<256; i++) { + asm("nop"); + asm("nop"); + asm("nop"); + asm("nop"); + } +*/ + G2_LOCK(old); + /* Envelope setup. The first of these is the loop point, + e.g., where the sample starts over when it loops. The second + is the loop end. This is the full length of the sample when + you are not looping, or the loop end point when you are (though + storing more than that is a waste of memory if you're not doing + volume enveloping). */ + CHNREG32(ch, 8) = loopst & 0xffff; + CHNREG32(ch, 12) = loopend & 0xffff; + + /* Write resulting values */ + CHNREG32(ch, 24) = AICA_FREQ(freq); + + /* Set volume, pan, and some other things that we don't know what + they do =) */ + CHNREG32(ch, 36) = AICA_PAN(pan) | (0xf<<8); + /* Convert the incoming volume and pan into hardware values */ + /* Vol starts at zero so we can ramp */ + vol = AICA_VOL(vol); + CHNREG32(ch, 40) = 0x24 | (vol<<8); + /* Convert the incoming volume and pan into hardware values */ + /* Vol starts at zero so we can ramp */ + + /* If we supported volume envelopes (which we don't yet) then + this value would set that up. The top 4 bits determine the + envelope speed. f is the fastest, 1 is the slowest, and 0 + seems to be an invalid value and does weird things). The + default (below) sets it into normal mode (play and terminate/loop). + CHNREG32(ch, 16) = 0xf010; + */ + CHNREG32(ch, 16) = 0x1f; /* No volume envelope */ + + + /* Set sample format, buffer address, and looping control. If + 0x0200 mask is set on reg 0, the sample loops infinitely. If + it's not set, the sample plays once and terminates. We'll + also set the bits to start playback here. */ + CHNREG32(ch, 4) = smpptr & 0xffff; + val = 0xc000 | 0x0000 | (mode<<7) | (smpptr >> 16); + if (loopflag) val|=0x200; + + CHNREG32(ch, 0) = val; + + G2_UNLOCK(old); + + /* Enable playback */ + /* CHNREG32(ch, 0) |= 0xc000; */ + g2_fifo_wait(); + +#if 0 + for (i=0xff; i>=vol; i--) { + if ((i&7)==0) g2_fifo_wait(); + CHNREG32(ch, 40) = 0x24 | (i<<8);; + } + + g2_fifo_wait(); +#endif +} + +/* Stop the sound on a given channel */ +void aica_stop(int ch) { + g2_write_32(CHNREGADDR(ch, 0),(g2_read_32(CHNREGADDR(ch, 0)) & ~0x4000) | 0x8000); + g2_fifo_wait(); +} + + +/* The rest of these routines can change the channel in mid-stride so you + can do things like vibrato and panning effects. */ + +/* Set channel volume */ +void aica_vol(int ch,int vol) { +// g2_write_8(CHNREGADDR(ch, 41),AICA_VOL(vol)); + g2_write_32(CHNREGADDR(ch, 40),(g2_read_32(CHNREGADDR(ch, 40))&0xffff00ff)|(AICA_VOL(vol)<<8) ); + g2_fifo_wait(); +} + +/* Set channel pan */ +void aica_pan(int ch,int pan) { +// g2_write_8(CHNREGADDR(ch, 36),AICA_PAN(pan)); + g2_write_32(CHNREGADDR(ch, 36),(g2_read_32(CHNREGADDR(ch, 36))&0xffffff00)|(AICA_PAN(pan)) ); + g2_fifo_wait(); +} + +/* Set channel frequency */ +void aica_freq(int ch,int freq) { + g2_write_32(CHNREGADDR(ch, 24),AICA_FREQ(freq)); + g2_fifo_wait(); +} + +/* Get channel position */ +int aica_get_pos(int ch) { +#if 1 + /* Observe channel ch */ + g2_write_32(SNDREGADDR(0x280c),(g2_read_32(SNDREGADDR(0x280c))&0xffff00ff) | (ch<<8)); + g2_fifo_wait(); + /* Update position counters */ + return g2_read_32(SNDREGADDR(0x2814)) & 0xffff; +#else + /* Observe channel ch */ + g2_write_8(SNDREGADDR(0x280d),ch); + /* Update position counters */ + return g2_read_32(SNDREGADDR(0x2814)) & 0xffff; +#endif +} diff --git a/src/audio/dc/aica.h b/src/audio/dc/aica.h new file mode 100644 index 00000000..d9e7098e --- /dev/null +++ b/src/audio/dc/aica.h @@ -0,0 +1,17 @@ +#ifndef _AICA_H_ +#define _AICA_H_ + +#define AICA_MEM 0xa0800000 + +#define SM_8BIT 1 +#define SM_16BIT 0 +#define SM_ADPCM 2 + +void aica_play(int ch,int mode,unsigned long smpptr,int looptst,int loopend,int freq,int vol,int pan,int loopflag); +void aica_stop(int ch); +void aica_vol(int ch,int vol); +void aica_pan(int ch,int pan); +void aica_freq(int ch,int freq); +int aica_get_pos(int ch); + +#endif diff --git a/src/cdrom/Makefile.am b/src/cdrom/Makefile.am index 73a3551c..29b81d2b 100644 --- a/src/cdrom/Makefile.am +++ b/src/cdrom/Makefile.am @@ -5,7 +5,7 @@ noinst_LTLIBRARIES = libcdrom.la # Define which subdirectories need to be built SUBDIRS = @CDROM_SUBDIRS@ -DIST_SUBDIRS = aix beos bsdi dummy freebsd linux macos openbsd qnx win32 +DIST_SUBDIRS = aix beos bsdi dc dummy freebsd linux macos openbsd qnx win32 DRIVERS = @CDROM_DRIVERS@ diff --git a/src/cdrom/dc/.cvsignore b/src/cdrom/dc/.cvsignore new file mode 100644 index 00000000..899d5355 --- /dev/null +++ b/src/cdrom/dc/.cvsignore @@ -0,0 +1,6 @@ +Makefile.in +Makefile +.libs +*.o +*.lo +*.la diff --git a/src/cdrom/dc/Makefile.am b/src/cdrom/dc/Makefile.am new file mode 100644 index 00000000..7bf356ee --- /dev/null +++ b/src/cdrom/dc/Makefile.am @@ -0,0 +1,8 @@ + +## Makefile.am for the Dreamcast cdrom driver for SDL + +noinst_LTLIBRARIES = libcdrom_dc.la +libcdrom_dc_la_SOURCES = $(SRCS) + +# The SDL cdrom driver sources +SRCS = SDL_syscdrom.c diff --git a/src/cdrom/dc/SDL_syscdrom.c b/src/cdrom/dc/SDL_syscdrom.c new file mode 100644 index 00000000..4a1be8e7 --- /dev/null +++ b/src/cdrom/dc/SDL_syscdrom.c @@ -0,0 +1,176 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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 + + BERO + bero@geocities.co.jp + + based on win32/SDL_syscdrom.c by + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +/* Functions for system-level CD-ROM audio control */ + +#include <stdlib.h> +#include <stdio.h> +#include <dc/cdrom.h> +#include <dc/spu.h> + +#include "SDL_error.h" +#include "SDL_cdrom.h" +#include "SDL_syscdrom.h" + +/* The system-dependent CD control functions */ +static const char *SDL_SYS_CDName(int drive); +static int SDL_SYS_CDOpen(int drive); +static int SDL_SYS_CDGetTOC(SDL_CD *cdrom); +static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position); +static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length); +static int SDL_SYS_CDPause(SDL_CD *cdrom); +static int SDL_SYS_CDResume(SDL_CD *cdrom); +static int SDL_SYS_CDStop(SDL_CD *cdrom); +static int SDL_SYS_CDEject(SDL_CD *cdrom); +static void SDL_SYS_CDClose(SDL_CD *cdrom); + + +int SDL_SYS_CDInit(void) +{ + /* Fill in our driver capabilities */ + SDL_CDcaps.Name = SDL_SYS_CDName; + SDL_CDcaps.Open = SDL_SYS_CDOpen; + SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; + SDL_CDcaps.Status = SDL_SYS_CDStatus; + SDL_CDcaps.Play = SDL_SYS_CDPlay; + SDL_CDcaps.Pause = SDL_SYS_CDPause; + SDL_CDcaps.Resume = SDL_SYS_CDResume; + SDL_CDcaps.Stop = SDL_SYS_CDStop; + SDL_CDcaps.Eject = SDL_SYS_CDEject; + SDL_CDcaps.Close = SDL_SYS_CDClose; + + return(0); +} + +static const char *SDL_SYS_CDName(int drive) +{ + return "/cd"; +} + +static int SDL_SYS_CDOpen(int drive) +{ + return(drive); +} + +#define TRACK_CDDA 0 +static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) +{ + CDROM_TOC toc; + int ret,i; + + ret = cdrom_read_toc(&toc,0); + if (ret!=ERR_OK) { + return -1; + } + + cdrom->numtracks = TOC_TRACK(toc.last)-TOC_TRACK(toc.first)+1; + for(i=0;i<cdrom->numtracks;i++) { + unsigned long entry = toc.entry[i]; + cdrom->track[i].id = i+1; + cdrom->track[i].type = (TOC_CTRL(toc.entry[i])==TRACK_CDDA)?SDL_AUDIO_TRACK:SDL_DATA_TRACK; + cdrom->track[i].offset = TOC_LBA(entry)-150; + cdrom->track[i].length = TOC_LBA((i+1<toc.last)?toc.entry[i+1]:toc.dunno)-TOC_LBA(entry); + } + + return 0; +} + +/* Get CD-ROM status */ +static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) +{ + CDstatus status; + int ret,dc_status,disc_type; + + ret = cdrom_get_status(&dc_status,&disc_type); + if (ret!=ERR_OK) return CD_ERROR; + + switch(dc_status) { +// case CD_STATUS_BUSY: + case CD_STATUS_PAUSED: + return CD_PAUSED; + case CD_STATUS_STANDBY: + return CD_STOPPED; + case CD_STATUS_PLAYING: + return CD_PLAYING; +// case CD_STATUS_SEEKING: +// case CD_STATUS_SCANING: + case CD_STATUS_OPEN: + case CD_STATUS_NO_DISC: + return CD_TRAYEMPTY; + default: + return CD_ERROR; + } +} + +/* Start play */ +static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) +{ + int ret = cdrom_cdda_play(start-150,start-150+length,1,CDDA_SECTORS); + return ret==ERR_OK?0:-1; +} + +/* Pause play */ +static int SDL_SYS_CDPause(SDL_CD *cdrom) +{ + int ret=cdrom_cdda_pause(); + return ret==ERR_OK?0:-1; +} + +/* Resume play */ +static int SDL_SYS_CDResume(SDL_CD *cdrom) +{ + int ret=cdrom_cdda_resume(); + return ret==ERR_OK?0:-1; +} + +/* Stop play */ +static int SDL_SYS_CDStop(SDL_CD *cdrom) +{ + int ret=cdrom_spin_down(); + return ret==ERR_OK?0:-1; +} + +/* Eject the CD-ROM */ +static int SDL_SYS_CDEject(SDL_CD *cdrom) +{ + return -1; +} + +/* Close the CD-ROM handle */ +static void SDL_SYS_CDClose(SDL_CD *cdrom) +{ +} + +void SDL_SYS_CDQuit(void) +{ + +} diff --git a/src/joystick/Makefile.am b/src/joystick/Makefile.am index b88f107d..0e0decd6 100644 --- a/src/joystick/Makefile.am +++ b/src/joystick/Makefile.am @@ -5,7 +5,7 @@ noinst_LTLIBRARIES = libjoystick.la # Define which subdirectories need to be built SUBDIRS = @JOYSTICK_SUBDIRS@ -DIST_SUBDIRS = dummy amigaos beos bsd darwin linux macos mint win32 +DIST_SUBDIRS = dummy amigaos beos bsd darwin dc linux macos mint win32 DRIVERS = @JOYSTICK_DRIVERS@ diff --git a/src/joystick/dc/.cvsignore b/src/joystick/dc/.cvsignore new file mode 100644 index 00000000..899d5355 --- /dev/null +++ b/src/joystick/dc/.cvsignore @@ -0,0 +1,6 @@ +Makefile.in +Makefile +.libs +*.o +*.lo +*.la diff --git a/src/joystick/dc/Makefile.am b/src/joystick/dc/Makefile.am new file mode 100644 index 00000000..da51e95c --- /dev/null +++ b/src/joystick/dc/Makefile.am @@ -0,0 +1,8 @@ + +## Makefile.am for the Dreamcast joystick driver for SDL + +noinst_LTLIBRARIES = libjoystick_dc.la +libjoystick_dc_la_SOURCES = $(SRCS) + +# The SDL joystick driver sources +SRCS = SDL_sysjoystick.c diff --git a/src/joystick/dc/SDL_sysjoystick.c b/src/joystick/dc/SDL_sysjoystick.c new file mode 100644 index 00000000..ab5a4d17 --- /dev/null +++ b/src/joystick/dc/SDL_sysjoystick.c @@ -0,0 +1,203 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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 + + BERO + bero@geocities.co.jp + + based on win32/SDL_mmjoystick.c + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +/* Win32 MultiMedia Joystick driver, contributed by Andrei de A. Formiga */ + +#include <stdlib.h> +#include <stdio.h> /* For the definition of NULL */ + +#include "SDL_error.h" +#include "SDL_joystick.h" +#include "SDL_sysjoystick.h" +#include "SDL_joystick_c.h" + +#include <dc/maple.h> +#include <dc/maple/controller.h> + +#define MAX_JOYSTICKS 8 /* only 2 are supported in the multimedia API */ +#define MAX_AXES 6 /* each joystick can have up to 6 axes */ +#define MAX_BUTTONS 8 /* and 8 buttons */ +#define MAX_HATS 2 + +#define JOYNAMELEN 8 + +/* array to hold joystick ID values */ +static uint8 SYS_Joystick_addr[MAX_JOYSTICKS]; + +/* The private structure used to keep track of a joystick */ +struct joystick_hwdata +{ + cont_cond_t prev_cond; + int prev_buttons; +}; + +/* 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. + */ +int SDL_SYS_JoystickInit(void) +{ + int numdevs; + + int p,u; + + numdevs = 0; + for(p=0;p<MAPLE_PORT_COUNT;p++) { + for(u=0;u<MAPLE_UNIT_COUNT;u++) { + if (maple_device_func(p,u)&MAPLE_FUNC_CONTROLLER) { + SYS_Joystick_addr[numdevs] = maple_addr(p,u); + numdevs++; + } + } + } + + return(numdevs); +} + +/* Function to get the device-dependent name of a joystick */ +const char *SDL_SYS_JoystickName(int index) +{ + maple_device_t *dev; + if (maple_compat_resolve(SYS_Joystick_addr[index],&dev,MAPLE_FUNC_CONTROLLER)!=0) return NULL; + return dev->info.product_name; +} + +/* 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) +{ + /* allocate memory for system specific hardware data */ + joystick->hwdata = (struct joystick_hwdata *) malloc(sizeof(*joystick->hwdata)); + if (joystick->hwdata == NULL) + { + SDL_OutOfMemory(); + return(-1); + } + memset(joystick->hwdata, 0, sizeof(*joystick->hwdata)); + + /* fill nbuttons, naxes, and nhats fields */ + joystick->nbuttons = MAX_BUTTONS; + joystick->naxes = MAX_AXES; + joystick->nhats = MAX_HATS; + 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) +{ +const int sdl_buttons[] = { + CONT_C, + CONT_B, + CONT_A, + CONT_START, + CONT_Z, + CONT_Y, + CONT_X, + CONT_D +}; + + uint8 addr; + cont_cond_t cond,*prev_cond; + int buttons,prev_buttons,i,changed; + + addr = SYS_Joystick_addr[joystick->index]; + if (cont_get_cond(addr,&cond)<0) return; + + buttons = cond.buttons; + prev_buttons = joystick->hwdata->prev_buttons; + changed = buttons^prev_buttons; + + if ((changed)&(CONT_DPAD_UP|CONT_DPAD_DOWN|CONT_DPAD_LEFT|CONT_DPAD_RIGHT)) { + int hat = SDL_HAT_CENTERED; + if (buttons&CONT_DPAD_UP) hat|=SDL_HAT_UP; + if (buttons&CONT_DPAD_DOWN) hat|=SDL_HAT_DOWN; + if (buttons&CONT_DPAD_LEFT) hat|=SDL_HAT_LEFT; + if (buttons&CONT_DPAD_RIGHT) hat|=SDL_HAT_RIGHT; + SDL_PrivateJoystickHat(joystick, 0, hat); + } + if ((changed)&(CONT_DPAD2_UP|CONT_DPAD2_DOWN|CONT_DPAD2_LEFT|CONT_DPAD2_RIGHT)) { + int hat = SDL_HAT_CENTERED; + if (buttons&CONT_DPAD2_UP) hat|=SDL_HAT_UP; + if (buttons&CONT_DPAD2_DOWN) hat|=SDL_HAT_DOWN; + if (buttons&CONT_DPAD2_LEFT) hat|=SDL_HAT_LEFT; + if (buttons&CONT_DPAD2_RIGHT) hat|=SDL_HAT_RIGHT; + SDL_PrivateJoystickHat(joystick, 1, hat); + } + + for(i=0;i<sizeof(sdl_buttons)/sizeof(sdl_buttons[0]);i++) { + if (changed & sdl_buttons[i]) { + SDL_PrivateJoystickButton(joystick, i, (buttons & sdl_buttons[i])?SDL_PRESSED:SDL_RELEASED); + } + } + + prev_cond = &joystick->hwdata->prev_cond; + if (cond.joyx!=prev_cond->joyx) + SDL_PrivateJoystickAxis(joystick, 0, cond.joyx-128); + if (cond.joyy!=prev_cond->joyy) + SDL_PrivateJoystickAxis(joystick, 1, cond.joyy-128); + if (cond.rtrig!=prev_cond->rtrig) + SDL_PrivateJoystickAxis(joystick, 2, cond.rtrig); + if (cond.ltrig!=prev_cond->ltrig) + SDL_PrivateJoystickAxis(joystick, 3, cond.ltrig); + if (cond.joy2x!=prev_cond->joy2x) + SDL_PrivateJoystickAxis(joystick, 4, cond.joy2x-128); + if (cond.joy2y!=prev_cond->joy2y) + SDL_PrivateJoystickAxis(joystick, 5, cond.joy2y-128); + + joystick->hwdata->prev_buttons = buttons; + joystick->hwdata->prev_cond = cond; +} + +/* Function to close a joystick after use */ +void SDL_SYS_JoystickClose(SDL_Joystick *joystick) +{ + if (joystick->hwdata != NULL) { + /* free system specific hardware data */ + free(joystick->hwdata); + } +} + +/* Function to perform any system-specific joystick related cleanup */ +void SDL_SYS_JoystickQuit(void) +{ + return; +} diff --git a/src/thread/Makefile.am b/src/thread/Makefile.am index 98194a50..c53b2f45 100644 --- a/src/thread/Makefile.am +++ b/src/thread/Makefile.am @@ -7,6 +7,7 @@ ARCH_SUBDIRS = $(srcdir)/generic \ $(srcdir)/amigaos \ $(srcdir)/beos \ $(srcdir)/bsdi \ + $(srcdir)/dc \ $(srcdir)/epoc \ $(srcdir)/irix \ $(srcdir)/linux \ diff --git a/src/thread/dc/SDL_syscond.c b/src/thread/dc/SDL_syscond.c new file mode 100644 index 00000000..8b888d5a --- /dev/null +++ b/src/thread/dc/SDL_syscond.c @@ -0,0 +1,223 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +/* An implementation of condition variables using semaphores and mutexes */ +/* + This implementation borrows heavily from the BeOS condition variable + implementation, written by Christopher Tate and Owen Smith. Thanks! + */ + +#include <stdio.h> +#include <stdlib.h> + +#include "SDL_error.h" +#include "SDL_thread.h" + +struct SDL_cond +{ + SDL_mutex *lock; + int waiting; + int signals; + SDL_sem *wait_sem; + SDL_sem *wait_done; +}; + +/* Create a condition variable */ +SDL_cond * SDL_CreateCond(void) +{ + SDL_cond *cond; + + cond = (SDL_cond *) malloc(sizeof(SDL_cond)); + if ( cond ) { + cond->lock = SDL_CreateMutex(); + cond->wait_sem = SDL_CreateSemaphore(0); + cond->wait_done = SDL_CreateSemaphore(0); + cond->waiting = cond->signals = 0; + if ( ! cond->lock || ! cond->wait_sem || ! cond->wait_done ) { + SDL_DestroyCond(cond); + cond = NULL; + } + } else { + SDL_OutOfMemory(); + } + return(cond); +} + +/* Destroy a condition variable */ +void SDL_DestroyCond(SDL_cond *cond) +{ + if ( cond ) { + if ( cond->wait_sem ) { + SDL_DestroySemaphore(cond->wait_sem); + } + if ( cond->wait_done ) { + SDL_DestroySemaphore(cond->wait_done); + } + if ( cond->lock ) { + SDL_DestroyMutex(cond->lock); + } + free(cond); + } +} + +/* Restart one of the threads that are waiting on the condition variable */ +int SDL_CondSignal(SDL_cond *cond) +{ + if ( ! cond ) { + SDL_SetError("Passed a NULL condition variable"); + return -1; + } + + /* If there are waiting threads not already signalled, then + signal the condition and wait for the thread to respond. + */ + SDL_LockMutex(cond->lock); + if ( cond->waiting > cond->signals ) { + ++cond->signals; + SDL_SemPost(cond->wait_sem); + SDL_UnlockMutex(cond->lock); + SDL_SemWait(cond->wait_done); + } else { + SDL_UnlockMutex(cond->lock); + } + + return 0; +} + +/* Restart all threads that are waiting on the condition variable */ +int SDL_CondBroadcast(SDL_cond *cond) +{ + if ( ! cond ) { + SDL_SetError("Passed a NULL condition variable"); + return -1; + } + + /* If there are waiting threads not already signalled, then + signal the condition and wait for the thread to respond. + */ + SDL_LockMutex(cond->lock); + if ( cond->waiting > cond->signals ) { + int i, num_waiting; + + num_waiting = (cond->waiting - cond->signals); + cond->signals = cond->waiting; + for ( i=0; i<num_waiting; ++i ) { + SDL_SemPost(cond->wait_sem); + } + /* Now all released threads are blocked here, waiting for us. + Collect them all (and win fabulous prizes!) :-) + */ + SDL_UnlockMutex(cond->lock); + for ( i=0; i<num_waiting; ++i ) { + SDL_SemWait(cond->wait_done); + } + } else { + SDL_UnlockMutex(cond->lock); + } + + return 0; +} + +/* Wait on the condition variable for at most 'ms' milliseconds. + The mutex must be locked before entering this function! + The mutex is unlocked during the wait, and locked again after the wait. + +Typical use: + +Thread A: + SDL_LockMutex(lock); + while ( ! condition ) { + SDL_CondWait(cond); + } + SDL_UnlockMutex(lock); + +Thread B: + SDL_LockMutex(lock); + ... + condition = true; + ... + SDL_UnlockMutex(lock); + */ +int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms) +{ + int retval; + + if ( ! cond ) { + SDL_SetError("Passed a NULL condition variable"); + return -1; + } + + /* Obtain the protection mutex, and increment the number of waiters. + This allows the signal mechanism to only perform a signal if there + are waiting threads. + */ + SDL_LockMutex(cond->lock); + ++cond->waiting; + SDL_UnlockMutex(cond->lock); + + /* Unlock the mutex, as is required by condition variable semantics */ + SDL_UnlockMutex(mutex); + + /* Wait for a signal */ + if ( ms == SDL_MUTEX_MAXWAIT ) { + retval = SDL_SemWait(cond->wait_sem); + } else { + retval = SDL_SemWaitTimeout(cond->wait_sem, ms); + } + + /* Let the signaler know we have completed the wait, otherwise + the signaler can race ahead and get the condition semaphore + if we are stopped between the mutex unlock and semaphore wait, + giving a deadlock. See the following URL for details: + http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html + */ + SDL_LockMutex(cond->lock); + if ( cond->signals > 0 ) { + /* If we timed out, we need to eat a condition signal */ + if ( retval > 0 ) { + SDL_SemWait(cond->wait_sem); + } + /* We always notify the signal thread that we are done */ + SDL_SemPost(cond->wait_done); + + /* Signal handshake complete */ + --cond->signals; + } + --cond->waiting; + SDL_UnlockMutex(cond->lock); + + /* Lock the mutex, as is required by condition variable semantics */ + SDL_LockMutex(mutex); + + return retval; +} + +/* Wait on the condition variable forever */ +int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex) +{ + return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT); +} diff --git a/src/thread/dc/SDL_syscond_c.h b/src/thread/dc/SDL_syscond_c.h new file mode 100644 index 00000000..33585baf --- /dev/null +++ b/src/thread/dc/SDL_syscond_c.h @@ -0,0 +1,27 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + diff --git a/src/thread/dc/SDL_sysmutex.c b/src/thread/dc/SDL_sysmutex.c new file mode 100644 index 00000000..6ffec6c6 --- /dev/null +++ b/src/thread/dc/SDL_sysmutex.c @@ -0,0 +1,135 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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 + + BERO + bero@geocities.co.jp + + based on generic/SDL_sysmutex.c + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +/* An implementation of mutexes using semaphores */ + +#include <stdio.h> +#include <stdlib.h> + +#include "SDL_error.h" +#include "SDL_thread.h" +#include "SDL_systhread_c.h" + +#include <arch/spinlock.h> + +struct SDL_mutex { + int recursive; + Uint32 owner; + spinlock_t mutex; +}; + +/* Create a mutex */ +SDL_mutex *SDL_CreateMutex(void) +{ + SDL_mutex *mutex; + + /* Allocate mutex memory */ + mutex = (SDL_mutex *)malloc(sizeof(*mutex)); + if ( mutex ) { + spinlock_init(&mutex->mutex); + mutex->recursive = 0; + mutex->owner = 0; + } else { + SDL_OutOfMemory(); + } + return mutex; +} + +/* Free the mutex */ +void SDL_DestroyMutex(SDL_mutex *mutex) +{ + if ( mutex ) { + free(mutex); + } +} + +/* Lock the semaphore */ +int SDL_mutexP(SDL_mutex *mutex) +{ +#ifdef DISABLE_THREADS + return 0; +#else + Uint32 this_thread; + + if ( mutex == NULL ) { + SDL_SetError("Passed a NULL mutex"); + return -1; + } + + this_thread = SDL_ThreadID(); + if ( mutex->owner == this_thread ) { + ++mutex->recursive; + } else { + /* The order of operations is important. + We set the locking thread id after we obtain the lock + so unlocks from other threads will fail. + */ + spinlock_lock(&mutex->mutex); + mutex->owner = this_thread; + mutex->recursive = 0; + } + + return 0; +#endif /* DISABLE_THREADS */ +} + +/* Unlock the mutex */ +int SDL_mutexV(SDL_mutex *mutex) +{ +#ifdef DISABLE_THREADS + return 0; +#else + if ( mutex == NULL ) { + SDL_SetError("Passed a NULL mutex"); + return -1; + } + + /* If we don't own the mutex, we can't unlock it */ + if ( SDL_ThreadID() != mutex->owner ) { + SDL_SetError("mutex not owned by this thread"); + return -1; + } + + if ( mutex->recursive ) { + --mutex->recursive; + } else { + /* The order of operations is important. + First reset the owner so another thread doesn't lock + the mutex and set the ownership before we reset it, + then release the lock semaphore. + */ + mutex->owner = 0; + spinlock_unlock(&mutex->mutex); + } + return 0; +#endif /* DISABLE_THREADS */ +} diff --git a/src/thread/dc/SDL_sysmutex_c.h b/src/thread/dc/SDL_sysmutex_c.h new file mode 100644 index 00000000..33585baf --- /dev/null +++ b/src/thread/dc/SDL_sysmutex_c.h @@ -0,0 +1,27 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + diff --git a/src/thread/dc/SDL_syssem.c b/src/thread/dc/SDL_syssem.c new file mode 100644 index 00000000..bd9f97b1 --- /dev/null +++ b/src/thread/dc/SDL_syssem.c @@ -0,0 +1,180 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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 + + BERO + bero@geocities.co.jp + + based on generic/SDL_syssem.c + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +/* An implementation of semaphores using mutexes and condition variables */ + +#include <stdlib.h> + +#include "SDL_error.h" +#include "SDL_timer.h" +#include "SDL_thread.h" +#include "SDL_systhread_c.h" + + +#ifdef DISABLE_THREADS + +SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) +{ + SDL_SetError("SDL not configured with thread support"); + return (SDL_sem *)0; +} + +void SDL_DestroySemaphore(SDL_sem *sem) +{ + return; +} + +int SDL_SemTryWait(SDL_sem *sem) +{ + SDL_SetError("SDL not configured with thread support"); + return -1; +} + +int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) +{ + SDL_SetError("SDL not configured with thread support"); + return -1; +} + +int SDL_SemWait(SDL_sem *sem) +{ + SDL_SetError("SDL not configured with thread support"); + return -1; +} + +Uint32 SDL_SemValue(SDL_sem *sem) +{ + return 0; +} + +int SDL_SemPost(SDL_sem *sem) +{ + SDL_SetError("SDL not configured with thread support"); + return -1; +} + +#else + +#include <kos/sem.h> + +struct SDL_semaphore +{ + semaphore_t sem; +}; + +SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) +{ + return (SDL_sem *)sem_create(initial_value); +} + +/* WARNING: + You cannot call this function when another thread is using the semaphore. +*/ +void SDL_DestroySemaphore(SDL_sem *sem) +{ + if ( ! sem ) { + SDL_SetError("Passed a NULL semaphore"); + return; + } + + sem_destroy(&sem->sem); +} + +int SDL_SemTryWait(SDL_sem *sem) +{ + int retval; + + if ( ! sem ) { + SDL_SetError("Passed a NULL semaphore"); + return -1; + } + + retval = sem_trywait(&sem->sem); + if (retval==0) return 0; + else return SDL_MUTEX_TIMEDOUT; + + return retval; +} + +int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) +{ + int retval; + + if ( ! sem ) { + SDL_SetError("Passed a NULL semaphore"); + return -1; + } + + /* A timeout of 0 is an easy case */ + if ( timeout == 0 ) { + return SDL_SemTryWait(sem); + } + + retval = sem_wait_timed(&sem->sem,timeout); + if (retval==-1) retval= SDL_MUTEX_TIMEDOUT; + + return retval; +} + +int SDL_SemWait(SDL_sem *sem) +{ + if ( ! sem ) { + SDL_SetError("Passed a NULL semaphore"); + return -1; + } + + sem_wait(&sem->sem); + return 0; +} + +Uint32 SDL_SemValue(SDL_sem *sem) +{ + if ( ! sem ) { + SDL_SetError("Passed a NULL semaphore"); + return -1; + } + + return sem_count(&sem->sem); +} + +int SDL_SemPost(SDL_sem *sem) +{ + if ( ! sem ) { + SDL_SetError("Passed a NULL semaphore"); + return -1; + } + + sem_signal(&sem->sem); + return 0; +} + +#endif /* DISABLE_THREADS */ diff --git a/src/thread/dc/SDL_syssem_c.h b/src/thread/dc/SDL_syssem_c.h new file mode 100644 index 00000000..33585baf --- /dev/null +++ b/src/thread/dc/SDL_syssem_c.h @@ -0,0 +1,27 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + diff --git a/src/thread/dc/SDL_systhread.c b/src/thread/dc/SDL_systhread.c new file mode 100644 index 00000000..4395f799 --- /dev/null +++ b/src/thread/dc/SDL_systhread.c @@ -0,0 +1,98 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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 + + BERO + bero@geocities.co.jp + + based on generic/SDL_thread.c + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +/* Thread management routines for SDL */ + +#include "SDL_error.h" +#include "SDL_thread.h" +#include "SDL_systhread.h" + +#include <kos/thread.h> + +#ifdef DISABLE_THREADS +int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) +{ + SDL_SetError("Threads are not supported on this platform"); + return(-1); +} + +void SDL_SYS_SetupThread(void) +{ + return; +} + +Uint32 SDL_ThreadID(void) +{ + return(0); +} + +void SDL_SYS_WaitThread(SDL_Thread *thread) +{ + return; +} + +void SDL_SYS_KillThread(SDL_Thread *thread) +{ + return; +} + +#else +int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) +{ + thread->handle = thd_create(SDL_RunThread,args); + if (thread->handle == NULL) { + SDL_SetError("Not enough resources to create thread"); + return(-1); + } + return(0); +} + +void SDL_SYS_SetupThread(void) +{ + return; +} + +Uint32 SDL_ThreadID(void) +{ + return (Uint32)thd_get_current(); +} + +void SDL_SYS_WaitThread(SDL_Thread *thread) +{ + thd_wait(thread->handle); +} + +void SDL_SYS_KillThread(SDL_Thread *thread) +{ + thd_destroy(thread->handle); +} +#endif diff --git a/src/thread/dc/SDL_systhread_c.h b/src/thread/dc/SDL_systhread_c.h new file mode 100644 index 00000000..30576399 --- /dev/null +++ b/src/thread/dc/SDL_systhread_c.h @@ -0,0 +1,29 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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@libsdl.org +*/ + +/* Stub until we implement threads on this platform */ +typedef struct kthread* SYS_ThreadHandle; +/* +#ifndef DISABLE_THREADS +#define DISABLE_THREADS +#endif +*/ diff --git a/src/timer/Makefile.am b/src/timer/Makefile.am index 473710cb..01cab757 100644 --- a/src/timer/Makefile.am +++ b/src/timer/Makefile.am @@ -5,6 +5,7 @@ noinst_LTLIBRARIES = libtimer.la ARCH_SUBDIRS = $(srcdir)/amigaos \ $(srcdir)/beos \ + $(srcdir)/dc \ $(srcdir)/epoc \ $(srcdir)/linux \ $(srcdir)/macos \ diff --git a/src/timer/dc/SDL_systimer.c b/src/timer/dc/SDL_systimer.c new file mode 100644 index 00000000..69b3321b --- /dev/null +++ b/src/timer/dc/SDL_systimer.c @@ -0,0 +1,106 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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 + + BERO + bero@geocities.co.jp + + based on win32/SDL_systimer.c + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +#include <kos.h> + +#include "SDL_thread.h" +#include "SDL_timer.h" +#include "SDL_error.h" +#include "SDL_timer_c.h" + +static unsigned start; + +/* + jif = ms * HZ /1000 + ms = jif * 1000/HZ +*/ + +void SDL_StartTicks(void) +{ + /* Set first ticks value */ + start = jiffies; +} + +Uint32 SDL_GetTicks(void) +{ + return((jiffies-start)*1000/HZ); +} + +void SDL_Delay(Uint32 ms) +{ + thd_sleep(ms); +} + +/* Data to handle a single periodic alarm */ +static int timer_alive = 0; +static SDL_Thread *timer = NULL; + +static int RunTimer(void *unused) +{ + while ( timer_alive ) { + if ( SDL_timer_running ) { + SDL_ThreadedTimerCheck(); + } + SDL_Delay(10); + } + return(0); +} + +/* This is only called if the event thread is not running */ +int SDL_SYS_TimerInit(void) +{ + timer_alive = 1; + timer = SDL_CreateThread(RunTimer, NULL); + if ( timer == NULL ) + return(-1); + return(SDL_SetTimerThreaded(1)); +} + +void SDL_SYS_TimerQuit(void) +{ + timer_alive = 0; + if ( timer ) { + SDL_WaitThread(timer, NULL); + timer = NULL; + } +} + +int SDL_SYS_StartTimer(void) +{ + SDL_SetError("Internal logic error: DC uses threaded timer"); + return(-1); +} + +void SDL_SYS_StopTimer(void) +{ + return; +} diff --git a/src/video/Makefile.am b/src/video/Makefile.am index 72528fb2..73f3b27c 100644 --- a/src/video/Makefile.am +++ b/src/video/Makefile.am @@ -9,7 +9,7 @@ DIST_SUBDIRS = dummy x11 dga nanox fbcon directfb vgl svga ggi aalib \ wincommon windib windx5 \ maccommon macdsp macrom quartz \ bwindow ps2gs photon cybergfx epoc picogui \ - ataricommon xbios gem XFree86 + ataricommon xbios gem dc XFree86 DRIVERS = @VIDEO_DRIVERS@ diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index a325ae5d..56634161 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -406,6 +406,9 @@ extern VideoBootStrap Qtopia_bootstrap; #ifdef ENABLE_PICOGUI extern VideoBootStrap PG_bootstrap; #endif +#ifdef ENABLE_DC +extern VideoBootStrap DC_bootstrap; +#endif /* This is the current video device */ extern SDL_VideoDevice *current_video; diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index c09d84cb..5aa327e8 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -117,6 +117,9 @@ static VideoBootStrap *bootstrap[] = { #ifdef ENABLE_PICOGUI &PG_bootstrap, #endif +#ifdef ENABLE_DC + &DC_bootstrap, +#endif NULL }; diff --git a/src/video/dc/.cvsignore b/src/video/dc/.cvsignore new file mode 100644 index 00000000..899d5355 --- /dev/null +++ b/src/video/dc/.cvsignore @@ -0,0 +1,6 @@ +Makefile.in +Makefile +.libs +*.o +*.lo +*.la diff --git a/src/video/dc/Makefile.am b/src/video/dc/Makefile.am new file mode 100644 index 00000000..040a67a6 --- /dev/null +++ b/src/video/dc/Makefile.am @@ -0,0 +1,14 @@ + +## Makefile.am for SDL using the Dreamcast video driver + +noinst_LTLIBRARIES = libvideo_dc.la +libvideo_dc_la_SOURCES = $(SRCS) + +# The SDL Dreamcast video driver sources +SRCS = \ + SDL_dcevents.c \ + SDL_dcevents_c.h \ + SDL_dcmouse.c \ + SDL_dcmouse_c.h \ + SDL_dcvideo.c \ + SDL_dcvideo.h diff --git a/src/video/dc/SDL_dcevents.c b/src/video/dc/SDL_dcevents.c new file mode 100644 index 00000000..125d06e5 --- /dev/null +++ b/src/video/dc/SDL_dcevents.c @@ -0,0 +1,164 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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 + + BERO + bero@geocities.co.jp + + based on SDL_nullevents.c by + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +/* Being a null driver, there's no event stream. We just define stubs for + most of the API. */ + +#include "SDL.h" +#include "SDL_sysevents.h" +#include "SDL_events_c.h" +#include "SDL_dcvideo.h" +#include "SDL_dcevents_c.h" + +#include <dc/maple.h> +#include <dc/maple/mouse.h> +#include <dc/maple/keyboard.h> + +const static unsigned short sdl_key[]= { + /*0*/ 0, 0, 0, 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', + 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', + 'u', 'v', 'w', 'x', 'y', 'z', + /*1e*/ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', + /*28*/ SDLK_RETURN, SDLK_ESCAPE, SDLK_BACKSPACE, SDLK_TAB, SDLK_SPACE, SDLK_MINUS, SDLK_PLUS, SDLK_LEFTBRACKET, + SDLK_RIGHTBRACKET, SDLK_BACKSLASH , 0, SDLK_SEMICOLON, SDLK_QUOTE, + /*35*/ '~', SDLK_COMMA, SDLK_PERIOD, SDLK_SLASH, SDLK_CAPSLOCK, + SDLK_F1, SDLK_F2, SDLK_F3, SDLK_F4, SDLK_F5, SDLK_F6, SDLK_F7, SDLK_F8, SDLK_F9, SDLK_F10, SDLK_F11, SDLK_F12, + /*46*/ SDLK_PRINT, SDLK_SCROLLOCK, SDLK_PAUSE, SDLK_INSERT, SDLK_HOME, SDLK_PAGEUP, SDLK_DELETE, SDLK_END, SDLK_PAGEDOWN, SDLK_RIGHT, SDLK_LEFT, SDLK_DOWN, SDLK_UP, + /*53*/ SDLK_NUMLOCK, SDLK_KP_DIVIDE, SDLK_KP_MULTIPLY, SDLK_KP_MINUS, SDLK_KP_PLUS, SDLK_KP_ENTER, + SDLK_KP1, SDLK_KP2, SDLK_KP3, SDLK_KP4, SDLK_KP5, SDLK_KP6, + /*5f*/ SDLK_KP7, SDLK_KP8, SDLK_KP9, SDLK_KP0, SDLK_KP_PERIOD, 0 /* S3 */ +}; + +const static unsigned short sdl_shift[] = { + SDLK_LCTRL,SDLK_LSHIFT,SDLK_LALT,0 /* S1 */, + SDLK_RCTRL,SDLK_RSHIFT,SDLK_RALT,0 /* S2 */, +}; + +#define MOUSE_WHEELUP (1<<4) +#define MOUSE_WHEELDOWN (1<<5) + +static void mouse_update(void) +{ +const static char sdl_mousebtn[] = { + MOUSE_LEFTBUTTON, + MOUSE_RIGHTBUTTON, + MOUSE_SIDEBUTTON, + MOUSE_WHEELUP, + MOUSE_WHEELDOWN +}; + + uint8 addr; + mouse_cond_t cond; + + static int prev_buttons; + int buttons,changed; + int i; + + if ((addr = maple_first_mouse())==0 || mouse_get_cond(addr, &cond)<0) return; + + buttons = cond.buttons^0xff; + if (cond.dz<0) buttons|=MOUSE_WHEELUP; + if (cond.dz>0) buttons|=MOUSE_WHEELDOWN; + + if (cond.dx||cond.dy) SDL_PrivateMouseMotion(0,1,cond.dx,cond.dy); + + changed = buttons^prev_buttons; + for(i=0;i<sizeof(sdl_mousebtn);i++) { + if (changed & sdl_mousebtn[i]) { + SDL_PrivateMouseButton((buttons & sdl_mousebtn[i])?SDL_PRESSED:SDL_RELEASED,i,0,0); + } + } + prev_buttons = buttons; +} + +static void keyboard_update(void) +{ + static kbd_state_t old_state; + static uint8 old_addr; + + kbd_state_t *state; + uint8 addr; + int port,unit; + + int shiftkeys; + SDL_keysym keysym; + + int i; + + addr = maple_first_kb(); + + if (addr==0) return; + + if (addr!=old_addr) { + old_addr = addr; + memset(&old_state,0,sizeof(old_state)); + } + + maple_raddr(addr,&port,&unit); + + state = kbd_get_state(port,unit); + if (!state) return; + + shiftkeys = state->shift_keys ^ old_state.shift_keys; + for(i=0;i<sizeof(sdl_shift);i++) { + if ((shiftkeys>>i)&1) { + keysym.sym = sdl_shift[i]; + SDL_PrivateKeyboard(((state->shift_keys>>i)&1)?SDL_PRESSED:SDL_RELEASED,&keysym); + } + } + + for(i=0;i<sizeof(sdl_key);i++) { + if (state->matrix[i]!=old_state.matrix[i]) { + int key = sdl_key[i]; + if (key) { + keysym.sym = key; + SDL_PrivateKeyboard(state->matrix[i]?SDL_PRESSED:SDL_RELEASED,&keysym); + } + } + } + + old_state = *state; +} + +void DC_PumpEvents(_THIS) +{ + keyboard_update(); + mouse_update(); +} + +void DC_InitOSKeymap(_THIS) +{ + /* do nothing. */ +} + +/* end of SDL_dcevents.c ... */ + diff --git a/src/video/dc/SDL_dcevents_c.h b/src/video/dc/SDL_dcevents_c.h new file mode 100644 index 00000000..ea91fcb4 --- /dev/null +++ b/src/video/dc/SDL_dcevents_c.h @@ -0,0 +1,42 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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 + + BERO + bero@geocities.co.jp + + based on SDL_nullevents.h by + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +#include "SDL_dcvideo.h" + +/* Variables and functions exported by SDL_sysevents.c to other parts + of the native video subsystem (SDL_sysvideo.c) +*/ +extern void DC_InitOSKeymap(_THIS); +extern void DC_PumpEvents(_THIS); + +/* end of SDL_dcevents_c.h ... */ + diff --git a/src/video/dc/SDL_dcmouse.c b/src/video/dc/SDL_dcmouse.c new file mode 100644 index 00000000..728384a4 --- /dev/null +++ b/src/video/dc/SDL_dcmouse.c @@ -0,0 +1,45 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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 + + BERO + bero@geocities.co.jp + + based on SDL_nullvideo.h by + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +#include <stdio.h> + +#include "SDL_error.h" +#include "SDL_mouse.h" +#include "SDL_events_c.h" + +#include "SDL_dcmouse_c.h" + + +/* The implementation dependent data for the window manager cursor */ +struct WMcursor { + int unused; +}; diff --git a/src/video/dc/SDL_dcmouse_c.h b/src/video/dc/SDL_dcmouse_c.h new file mode 100644 index 00000000..72c31275 --- /dev/null +++ b/src/video/dc/SDL_dcmouse_c.h @@ -0,0 +1,35 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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 + + BERO + bero@geocities.co.jp + + based on SDL_nullmouse.h by + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +#include "SDL_dcvideo.h" + +/* Functions to be exported */ diff --git a/src/video/dc/SDL_dcvideo.c b/src/video/dc/SDL_dcvideo.c new file mode 100644 index 00000000..d26d744b --- /dev/null +++ b/src/video/dc/SDL_dcvideo.c @@ -0,0 +1,477 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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 + + BERO + bero@geocities.co.jp + + based on SDL_nullvideo.c by + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +/* Dummy SDL video driver implementation; this is just enough to make an + * SDL-based application THINK it's got a working video driver, for + * applications that call SDL_Init(SDL_INIT_VIDEO) when they don't need it, + * and also for use as a collection of stubs when porting SDL to a new + * platform for which you haven't yet written a valid video driver. + * + * This is also a great way to determine bottlenecks: if you think that SDL + * is a performance problem for a given platform, enable this driver, and + * then see if your application runs faster without video overhead. + * + * Initial work by Ryan C. Gordon (icculus@linuxgames.com). A good portion + * of this was cut-and-pasted from Stephane Peter's work in the AAlib + * SDL video driver. Renamed to "DC" by Sam Lantinga. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "SDL.h" +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_mouse.h" +#include "SDL_sysvideo.h" +#include "SDL_pixels_c.h" +#include "SDL_events_c.h" + +#include "SDL_dcvideo.h" +#include "SDL_dcevents_c.h" +#include "SDL_dcmouse_c.h" + +#include <dc/video.h> +#include <dc/pvr.h> + +#ifdef HAVE_OPENGL +#include <GL/gl.h> +#endif + + +/* Initialization/Query functions */ +static int DC_VideoInit(_THIS, SDL_PixelFormat *vformat); +static SDL_Rect **DC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); +static SDL_Surface *DC_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); +static int DC_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); +static void DC_VideoQuit(_THIS); + +/* Hardware surface functions */ +static int DC_AllocHWSurface(_THIS, SDL_Surface *surface); +static int DC_LockHWSurface(_THIS, SDL_Surface *surface); +static void DC_UnlockHWSurface(_THIS, SDL_Surface *surface); +static void DC_FreeHWSurface(_THIS, SDL_Surface *surface); +static int DC_FlipHWSurface(_THIS, SDL_Surface *surface); + +/* etc. */ +static void DC_UpdateRects(_THIS, int numrects, SDL_Rect *rects); + +/* OpenGL */ +static void *DC_GL_GetProcAddress(_THIS, const char *proc); +static int DC_GL_LoadLibrary(_THIS, const char *path); +static int DC_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value); +static void DC_GL_SwapBuffers(_THIS); + +/* DC driver bootstrap functions */ + +static int DC_Available(void) +{ + return 1; +} + +static void DC_DeleteDevice(SDL_VideoDevice *device) +{ + free(device->hidden); + free(device); +} + +static SDL_VideoDevice *DC_CreateDevice(int devindex) +{ + SDL_VideoDevice *device; + + /* Initialize all variables that we clean on shutdown */ + device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice)); + if ( device ) { + memset(device, 0, (sizeof *device)); + device->hidden = (struct SDL_PrivateVideoData *) + malloc((sizeof *device->hidden)); + } + if ( (device == NULL) || (device->hidden == NULL) ) { + SDL_OutOfMemory(); + if ( device ) { + free(device); + } + return(0); + } + memset(device->hidden, 0, (sizeof *device->hidden)); + + /* Set the function pointers */ + device->VideoInit = DC_VideoInit; + device->ListModes = DC_ListModes; + device->SetVideoMode = DC_SetVideoMode; + device->CreateYUVOverlay = NULL; + device->SetColors = DC_SetColors; + device->UpdateRects = DC_UpdateRects; + device->VideoQuit = DC_VideoQuit; + device->AllocHWSurface = DC_AllocHWSurface; + device->CheckHWBlit = NULL; + device->FillHWRect = NULL; + device->SetHWColorKey = NULL; + device->SetHWAlpha = NULL; + device->LockHWSurface = DC_LockHWSurface; + device->UnlockHWSurface = DC_UnlockHWSurface; + device->FlipHWSurface = DC_FlipHWSurface; + device->FreeHWSurface = DC_FreeHWSurface; +#ifdef HAVE_OPENGL + device->GL_LoadLibrary = DC_GL_LoadLibrary; + device->GL_GetProcAddress = DC_GL_GetProcAddress; + device->GL_GetAttribute = DC_GL_GetAttribute; + device->GL_MakeCurrent = NULL; + device->GL_SwapBuffers = DC_GL_SwapBuffers; +#endif + device->SetCaption = NULL; + device->SetIcon = NULL; + device->IconifyWindow = NULL; + device->GrabInput = NULL; + device->GetWMInfo = NULL; + device->InitOSKeymap = DC_InitOSKeymap; + device->PumpEvents = DC_PumpEvents; + + device->free = DC_DeleteDevice; + + return device; +} + +VideoBootStrap DC_bootstrap = { + "dcvideo", "Dreamcast Video", + DC_Available, DC_CreateDevice +}; + + +int DC_VideoInit(_THIS, SDL_PixelFormat *vformat) +{ + /* Determine the screen depth (use default 8-bit depth) */ + /* we change this during the SDL_SetVideoMode implementation... */ + vformat->BitsPerPixel = 16; + vformat->Rmask = 0x0000f800; + vformat->Gmask = 0x000007e0; + vformat->Bmask = 0x0000001f; + + /* We're done! */ + return(0); +} + +const static SDL_Rect + RECT_800x600 = {0,0,800,600}, + RECT_640x480 = {0,0,640,480}, + RECT_320x240 = {0,0,320,240}; +const static SDL_Rect *vid_modes[] = { + &RECT_800x600, + &RECT_640x480, + &RECT_320x240, + NULL +}; + +SDL_Rect **DC_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) +{ + switch(format->BitsPerPixel) { + case 15: + case 16: + return &vid_modes; + case 32: + if (!(flags & SDL_OPENGL)) + return &vid_modes; + default: + return NULL; + } +// return (SDL_Rect **) -1; +} + +pvr_init_params_t params = { + /* Enable opaque and translucent polygons with size 16 */ + { PVR_BINSIZE_16, PVR_BINSIZE_0, PVR_BINSIZE_16, PVR_BINSIZE_0, PVR_BINSIZE_16 }, + + /* Vertex buffer size */ + 512*1024 +}; + +#ifdef HAVE_OPENGL +static int pvr_inited; +#endif + +SDL_Surface *DC_SetVideoMode(_THIS, SDL_Surface *current, + int width, int height, int bpp, Uint32 flags) +{ + int disp_mode,pixel_mode,pitch; + Uint32 Rmask, Gmask, Bmask; + + if (width==320 && height==240) disp_mode=DM_320x240; + else if (width==640 && height==480) disp_mode=DM_640x480; + else if (width==800 && height==600) disp_mode=DM_800x608; + else { + SDL_SetError("Couldn't find requested mode in list"); + return(NULL); + } + + switch(bpp) { + case 15: pixel_mode = PM_RGB555; pitch = width*2; + /* 5-5-5 */ + Rmask = 0x00007c00; + Gmask = 0x000003e0; + Bmask = 0x0000001f; + break; + case 16: pixel_mode = PM_RGB565; pitch = width*2; + /* 5-6-5 */ + Rmask = 0x0000f800; + Gmask = 0x000007e0; + Bmask = 0x0000001f; + break; + case 24: bpp = 32; + case 32: pixel_mode = PM_RGB888; pitch = width*4; + Rmask = 0x00ff0000; + Gmask = 0x0000ff00; + Bmask = 0x000000ff; +#ifdef HAVE_OPENGL + if (!(flags & SDL_OPENGL)) +#endif + break; + default: + SDL_SetError("Couldn't find requested mode in list"); + return(NULL); + } + +// if ( bpp != current->format->BitsPerPixel ) { + if ( ! SDL_ReallocFormat(current, bpp, Rmask, Gmask, Bmask, 0) ) { + return(NULL); + } +// } + + /* Set up the new mode framebuffer */ + current->flags = (SDL_FULLSCREEN|SDL_HWSURFACE); + current->w = width; + current->h = height; + current->pitch = pitch; + +#ifdef HAVE_OPENGL + if (pvr_inited) { + pvr_inited = 0; + pvr_shutdown(); + } +#endif + + vid_set_mode(disp_mode,pixel_mode); + + current->pixels = vram_s; + +#ifdef HAVE_OPENGL + if (flags & SDL_OPENGL) { + this->gl_config.driver_loaded = 1; + current->flags = SDL_FULLSCREEN | SDL_OPENGL; + current->pixels = NULL; + pvr_inited = 1; + pvr_init(¶ms); + glKosInit(); + glKosBeginFrame(); + } else +#endif + if (flags | SDL_DOUBLEBUF) { + current->flags |= SDL_DOUBLEBUF; + current->pixels = (void*)((int)current->pixels | 0x400000); + } + + /* We're done */ + return(current); +} + +/* We don't actually allow hardware surfaces other than the main one */ +static int DC_AllocHWSurface(_THIS, SDL_Surface *surface) +{ + return(-1); +} +static void DC_FreeHWSurface(_THIS, SDL_Surface *surface) +{ + return; +} + +/* We need to wait for vertical retrace on page flipped displays */ +static int DC_LockHWSurface(_THIS, SDL_Surface *surface) +{ + return(0); +} + +static void DC_UnlockHWSurface(_THIS, SDL_Surface *surface) +{ + return; +} + +static int DC_FlipHWSurface(_THIS, SDL_Surface *surface) +{ + if (surface->flags & SDL_DOUBLEBUF) { + vid_set_start((int)surface->pixels & 0xffffff); + surface->pixels = (void*)((int)surface->pixels ^ 0x400000); + } + return(0); +} + +static void DC_UpdateRects(_THIS, int numrects, SDL_Rect *rects) +{ + /* do nothing. */ +} + +static int DC_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) +{ + /* do nothing of note. */ + return(1); +} + +/* Note: If we are terminated, this could be called in the middle of + another SDL video routine -- notably UpdateRects. +*/ +static void DC_VideoQuit(_THIS) +{ +#ifdef HAVE_OPENGL + if (pvr_inited) { + pvr_inited = 0; + pvr_shutdown(); + } +#endif +} + +#ifdef HAVE_OPENGL + +void dmyfunc(void) {} + +typedef void (*funcptr)(); +const static struct { + char *name; + funcptr addr; +} glfuncs[] = { +#define DEF(func) {#func,&func} + DEF(glBegin), + DEF(glBindTexture), + DEF(glBlendFunc), + DEF(glColor4f), +// DEF(glCopyImageID), + DEF(glDisable), + DEF(glEnable), + DEF(glEnd), + DEF(glFlush), + DEF(glGenTextures), + DEF(glGetString), + DEF(glLoadIdentity), + DEF(glMatrixMode), + DEF(glOrtho), + DEF(glPixelStorei), +// DEF(glPopAttrib), +// DEF(glPopClientAttrib), + {"glPopAttrib",&dmyfunc}, + {"glPopClientAttrib",&dmyfunc}, + DEF(glPopMatrix), +// DEF(glPushAttrib), +// DEF(glPushClientAttrib), + {"glPushAttrib",&dmyfunc}, + {"glPushClientAttrib",&dmyfunc}, + DEF(glPushMatrix), + DEF(glTexCoord2f), + DEF(glTexEnvf), + DEF(glTexImage2D), + DEF(glTexParameteri), + DEF(glTexSubImage2D), + DEF(glVertex2i), + DEF(glViewport), +#undef DEF +}; + +static void *DC_GL_GetProcAddress(_THIS, const char *proc) +{ + void *ret; + int i; + + ret = glKosGetProcAddress(proc); + if (ret) return ret; + + for(i=0;i<sizeof(glfuncs)/sizeof(glfuncs[0]);i++) { + if (strcmp(proc,glfuncs[i].name)==0) return glfuncs[i].addr; + } + + return NULL; +} + +static int DC_GL_LoadLibrary(_THIS, const char *path) +{ + this->gl_config.driver_loaded = 1; + + return 0; +} + +static int DC_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value) +{ + GLenum mesa_attrib; + int val; + + switch(attrib) { + case SDL_GL_RED_SIZE: + val = 5; + break; + case SDL_GL_GREEN_SIZE: + val = 6; + break; + case SDL_GL_BLUE_SIZE: + val = 5; + break; + case SDL_GL_ALPHA_SIZE: + val = 0; + break; + case SDL_GL_DOUBLEBUFFER: + val = 1; + break; + case SDL_GL_DEPTH_SIZE: + val = 16; /* or 32? */ + break; + case SDL_GL_STENCIL_SIZE: + val = 0; + break; + case SDL_GL_ACCUM_RED_SIZE: + val = 0; + break; + case SDL_GL_ACCUM_GREEN_SIZE: + val = 0; + case SDL_GL_ACCUM_BLUE_SIZE: + val = 0; + break; + case SDL_GL_ACCUM_ALPHA_SIZE: + val = 0; + break; + default : + return -1; + } + *value = val; + return 0; +} + +static void DC_GL_SwapBuffers(_THIS) +{ + glKosFinishFrame(); + glKosBeginFrame(); +} +#endif diff --git a/src/video/dc/SDL_dcvideo.h b/src/video/dc/SDL_dcvideo.h new file mode 100644 index 00000000..79c94092 --- /dev/null +++ b/src/video/dc/SDL_dcvideo.h @@ -0,0 +1,51 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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 + + BERO + bero@geocities.co.jp + + based on SDL_nullvideo.h by + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +#ifndef _SDL_dcvideo_h +#define _SDL_dcvideo_h + +#include "SDL_mouse.h" +#include "SDL_sysvideo.h" +#include "SDL_mutex.h" + +/* Hidden "this" pointer for the video functions */ +#define _THIS SDL_VideoDevice *this + + +/* Private display data */ + +struct SDL_PrivateVideoData { + int w, h; + void *buffer; +}; + +#endif /* _SDL_dcvideo_h */ |