From c6be39fe86375ff3bc7321fca7e56a5a8ff2caca Mon Sep 17 00:00:00 2001 From: Steven Fuller <relnev@icculus.org> Date: Mon, 19 Mar 2001 03:00:29 +0000 Subject: [PATCH] sd_oal.c: started work on adlib playback rest: cleanups, etc. --- src/Makefile | 4 +- src/TODO | 56 ++++++------ src/id_heads.h | 15 +--- src/id_vh.h | 8 +- src/misc.c | 5 ++ src/sd_comm.h | 35 +------- src/sd_null.c | 25 ------ src/sd_oal.c | 238 +++++++++++++++++++++++++++++++++++++++++-------- src/sd_oss.c | 74 ++++++++------- src/vi_null.c | 3 +- src/wl_menu.c | 2 +- 11 files changed, 288 insertions(+), 177 deletions(-) diff --git a/src/Makefile b/src/Makefile index 2ffec8f..6d7d973 100644 --- a/src/Makefile +++ b/src/Makefile @@ -22,7 +22,7 @@ OBJS += sd_null.o #OBJS += sd_oss.o fmopl.o #CFLAGS += -D_REENTRANT #LFLAGS += -lpthread -#OBJS += sd_oal.o +#OBJS += sd_oal.o fmopl.o #CFLAGS += -D_REENTRANT -I/home/relnev/cvs/oal/include/ #LFLAGS += -lpthread -ldl -L/home/relnev/cvs/oal/linux/src/ -lopenal # /home/relnev/cvs/oal/linux/src/libopenal.a @@ -31,7 +31,7 @@ OBJS += sd_null.o CFLAGS += `sdl-config --cflags` SLFLAGS = $(LFLAGS) -lvga -XLFLAGS = $(LFLAGS) -L/usr/X11R6/lib -lX11 -lXext -lXxf86vm -lXxf86dga +XLFLAGS = $(LFLAGS) -L/usr/X11R6/lib -lX11 -lXext DLFLAGS = $(LFLAGS) `sdl-config --libs` -L/usr/X11R6/lib -lX11 -lXext NASM = nasm diff --git a/src/TODO b/src/TODO index f21dd33..f8acbc5 100644 --- a/src/TODO +++ b/src/TODO @@ -4,10 +4,9 @@ P R - create a better "read direction" for menu movement P M - convert while (Keyboard[sc_Blah]) IN_CheckAck() to IN_WaitKeyDown(sc.. P I - finish changing the game movement to the new style P R - update input menus/config -P M - rewrite menu code +P M - cleanup/rewrite menu code P R - update sound menus/config P I - rewrite sound code: get rid of packed structs, clean up thread stuff -P R - openal sound P I - fix issues (speed, hacks) with variable screen size P M - BSP trees (or something similar), then OpenGL support M R - port menu code (after fixed up) @@ -20,7 +19,7 @@ B R - decide if to keep SVGA/X11 targets B M - configure scripts? B M - port to dreamcast? B M - add compression to savegames/config -B I - play through (w/ sound and music) to make sure things work +B I - play through game (w/ sound and music) to make sure things work B M - use stdint.h where appropiate B M - finish serializing reads/writes, endian issues P I - fix raycast bug where at certain points you can see through corners @@ -34,36 +33,24 @@ P I - add sound "emulation" to the necessary targets so WaitSoundDone works B R - autoconf/automake P R - change boolean SD_PlaySound to void SD_PlaySound P M - position pushwall sounds +P M - id_ca.c cache code: fix/readd/rewrite the "garbage collection" system +P M - rewrite id_ca.c: uniform memory handling system +P M - either move id_heads into wl_def or split header files apart +P R - rewrite fmopl.c to avoid licensing issues Complete: P I - fix or remove fizzle fade - Removed [nice, but very hacky effect] +P R - openal sound + - almost complete ------------------------------------------------------------------------------ -Control Menu: -* TODO - -Sound Menu: -* Digital Sound Effects: -- On [PCM] -- Off -* Sound Effects -- On [AdLib/OPL2] -- PC Speaker? -- Off -* Music: -- On [AdLib/OPL2] -- Off ------------------------------------------------------------------------------- +* what exactly is the point of all the DigiMode checks in wl_act2.c? * add ylookup? * remove farmapylookup? * would be nice if Quit() used vsnprintf, etc * actor walking through door is drawn in front of door: near end of E1M1 for example (is this reproducible?) * use static and const where appropriate -* menu code is a mess, always does things differently than the rest of the -code, it really needs to be cleaned up -* id_ca.c cache code: fix/readd/rewrite the "garbage collection" system? -* rewrite id_ca.c: uniform memory handling system * clean up header files, especially wl_def.h, where some declarations aren't in the right place * change the current parameter handling code to something like getopt @@ -75,8 +62,25 @@ PlayDemoFromFile specifically * split wl_draw into two files (draw independent, draw dependent) * when window loses focus, it should clear the keys * rename visable to visible -* create 'sound channels' with priority.. ie a door can only make one sound -at a time +------------------------------------------------------------------------------ +fix: +void ControlMovement(objtype *ob) (wl_agent.c) +void UpdateInput() / void PollControls() (wl_play.c) +------------------------------------------------------------------------------ +Control Menu: +* TODO + +Sound Menu: +* Digital Sound Effects: +- On [PCM] +- Off +* Sound Effects +- On [AdLib/OPL2] +- PC Speaker? +- Off +* Music: +- On [AdLib/OPL2] +- Off ------------------------------------------------------------------------------ Save game header: 8 bytes: WOLF3D, 0, 0 @@ -117,7 +121,3 @@ Version 0x00000000 Data: (Official) Version 0x00000001 Data: (Official) <undetermined but will be compressed> ------------------------------------------------------------------------------- -fix: -void ControlMovement(objtype *ob) (wl_agent.c) -void UpdateInput() / void PollControls() (wl_play.c) diff --git a/src/id_heads.h b/src/id_heads.h index 806807f..f7f4e71 100644 --- a/src/id_heads.h +++ b/src/id_heads.h @@ -5,12 +5,9 @@ #include <stdlib.h> #include <string.h> #include <time.h> -#include <sys/types.h> #include <stdint.h> -#include <unistd.h> #include <glob.h> #include <ctype.h> -#include <fcntl.h> #include <math.h> #ifdef __cplusplus @@ -19,10 +16,6 @@ typedef bool boolean; typedef enum { false, true } boolean; #endif -#ifndef O_BINARY -#define O_BINARY 0 -#endif - #include "version.h" /* ------------------------------------------------------------------------ */ @@ -82,8 +75,10 @@ extern const byte gamepal[]; int MS_CheckParm(char *string); void Quit(char *error); +#define TickBase 70 /* 70Hz per tick */ + #undef PI -#define PI 3.1415926535897932384626433832795028841971693993751058209749445920 +#define PI 3.1415926535897932384626433832795028841971693993751058209749445920 #define MAXTICS 10 #define DEMOTICS 4 @@ -93,8 +88,4 @@ extern int tics; #define mapwidth 64 #define mapheight 64 -extern byte fontcolor, backcolor; - -#define SETFONTCOLOR(f, b) { fontcolor = f; backcolor = b; } - #endif diff --git a/src/id_vh.h b/src/id_vh.h index 2f4f2e9..2215e03 100644 --- a/src/id_vh.h +++ b/src/id_vh.h @@ -11,9 +11,11 @@ typedef struct extern pictabletype pictable[NUMPICS]; -extern byte fontcolor; -extern int fontnumber; -extern int px,py; +extern byte fontcolor, backcolor; +extern int fontnumber; +extern int px, py; + +#define SETFONTCOLOR(f, b) { fontcolor = f; backcolor = b; } void VW_UpdateScreen(); diff --git a/src/misc.c b/src/misc.c index 64a9593..27717f2 100644 --- a/src/misc.c +++ b/src/misc.c @@ -1,9 +1,14 @@ #include <sys/stat.h> #include <sys/time.h> #include <unistd.h> +#include <fcntl.h> #include "wl_def.h" +#ifndef O_BINARY +#define O_BINARY 0 +#endif + /* TimeCount from David Haslam -- dch@sirius.demon.co.uk */ static struct timeval t0; diff --git a/src/sd_comm.h b/src/sd_comm.h index 3db6ebe..5727e78 100644 --- a/src/sd_comm.h +++ b/src/sd_comm.h @@ -1,10 +1,6 @@ #ifndef __SD_COMM_H__ #define __SD_COMM_H__ -#define PACKED __attribute__((packed)) - -#define TickBase 70 /* 70Hz per tick */ - typedef enum { sdm_Off, sdm_PC,sdm_AdLib @@ -15,30 +11,6 @@ typedef enum { typedef enum { sds_Off,sds_PC,sds_SoundBlaster } SDSMode; -typedef struct { - longword length; - word priority; -} PACKED SoundCommon; - -typedef struct { - SoundCommon common; - byte data[1]; -} PACKED PCSound; - -typedef struct { - byte mChar, cChar, mScale, cScale, mAttack, cAttack, mSus, cSus, - mWave, cWave, nConn, voice, mode, unused[3]; -} PACKED Instrument; - -typedef struct { - SoundCommon common; - Instrument inst; - byte block, data[1]; -} PACKED AdLibSound; - -typedef struct { - word length, values[1]; -} PACKED MusicGroup; extern boolean AdLibPresent, SoundBlasterPresent; @@ -46,7 +18,6 @@ extern SDMode SoundMode; extern SDSMode DigiMode; extern SMMode MusicMode; - extern void SD_Startup(); extern void SD_Shutdown(); @@ -55,11 +26,9 @@ extern void SD_StopSound(), SD_WaitSoundDone(), SD_StartMusic(int music), SD_MusicOn(), - SD_MusicOff(), - SD_FadeOutMusic(); + SD_MusicOff(); -extern boolean SD_MusicPlaying(), SD_SetSoundMode(SDMode mode), - SD_SetMusicMode(SMMode mode); +extern boolean SD_SetSoundMode(SDMode mode), SD_SetMusicMode(SMMode mode); extern word SD_SoundPlaying(); diff --git a/src/sd_null.c b/src/sd_null.c index 4639adc..6df29a1 100644 --- a/src/sd_null.c +++ b/src/sd_null.c @@ -7,8 +7,6 @@ SDSMode DigiMode; static boolean SD_Started; -static boolean sqActive; - void SD_SetDigiDevice(SDSMode mode) { @@ -109,7 +107,6 @@ void SD_WaitSoundDone() /////////////////////////////////////////////////////////////////////////// void SD_MusicOn() { - sqActive = true; } /////////////////////////////////////////////////////////////////////////// @@ -119,7 +116,6 @@ void SD_MusicOn() /////////////////////////////////////////////////////////////////////////// void SD_MusicOff() { - sqActive = false; } /////////////////////////////////////////////////////////////////////////// @@ -132,27 +128,6 @@ void SD_StartMusic(int music) SD_MusicOff(); } -/////////////////////////////////////////////////////////////////////////// -// -// SD_FadeOutMusic() - starts fading out the music. Call SD_MusicPlaying() -// to see if the fadeout is complete -// -/////////////////////////////////////////////////////////////////////////// -void SD_FadeOutMusic() -{ -} - -/////////////////////////////////////////////////////////////////////////// -// -// SD_MusicPlaying() - returns true if music is currently playing, false if -// not -// -/////////////////////////////////////////////////////////////////////////// -boolean SD_MusicPlaying() -{ - return false; -} - void PlaySoundLocGlobal(word s, int id, fixed gx,fixed gy) { SD_PlaySound(s); diff --git a/src/sd_oal.c b/src/sd_oal.c index adf29e1..7af9528 100644 --- a/src/sd_oal.c +++ b/src/sd_oal.c @@ -1,15 +1,19 @@ #include "wl_def.h" +#include <unistd.h> +#include <pthread.h> + #include <AL/al.h> #include <AL/alc.h> #include <AL/alut.h> +#include "fmopl.h" + /* old stuff */ boolean AdLibPresent, SoundBlasterPresent; SDMode SoundMode, MusicMode; SDSMode DigiMode; static boolean SD_Started; -static boolean sqActive; /* AdLib Sound: @@ -35,7 +39,8 @@ static boolean sqActive; /* new stuff */ static int NumPCM; -struct _PCMSound { +struct _PCMSound +{ byte *data; int length; int used; @@ -43,7 +48,8 @@ struct _PCMSound { ALuint handle; } static *PCMSound; -struct _SoundData { +struct _SoundData +{ int priority; /* PCM */ @@ -58,7 +64,10 @@ struct _SoundData { byte *adata; } static SoundData[LASTSOUND]; -struct _MusicData { +static ALuint AdBuf[4]; + +struct _MusicData +{ int length; word *regval; @@ -79,6 +88,156 @@ struct _SoundChan { } static SoundChan[CHANNELS]; +/* how to do streaming buffer: +queue say 4 buffers of a certain size and play +now, run your updating loop: + unqueue buffers that have finished + generate new data and fill these buffers + queue the buffers with the new data + +since "Applications can have multiple threads that share one more or contexts. +In other words, AL and ALC are threadsafe.", the streaming code can be +implemented as a second thread + +*/ + +/* threads: + main thread handles pcm channels/sounds + sound thread handles adlib channels/sounds + + sound thread sets priority to -1 if a sound is not playing + + potential thread contention with both main and sound threads + accessing channel 0's information, but: + 1. it's not done in any loops + 2. any data mismatch won't affect the game (at least I think so) +*/ + +static pthread_t hSoundThread; +static pthread_mutex_t SoundMutex; + +#define SOUND_START 0 /* play this adlib sound */ +#define SOUND_STARTD 1 /* play this pcm sound */ +#define SOUND_STOP 2 /* stop all sounds */ +#define MUSIC_START 3 /* play this song */ +#define MUSIC_STOP 4 /* stop music */ +#define MUSIC_PAUSE 5 /* pause music */ +#define MUSIC_UNPAUSE 6 /* unpause music */ +#define ST_SHUTDOWN 7 /* shutdown thread */ + +struct _SoundMessage +{ + int type; /* what is it? (see above) */ + + int item; /* what to play (if anything) */ + + struct _SoundMessage *next; +}; + +struct _SoundMessage *SoundMessage; + +static void SendSTMessage(int type, int item) +{ + struct _SoundMessage *t; + + pthread_mutex_lock(&SoundMutex); + + MM_GetPtr((memptr)&t, sizeof(struct _SoundMessage)); + + t->type = type; + t->item = item; + + t->next = SoundMessage; + SoundMessage = t; + + pthread_mutex_unlock(&SoundMutex); +} + +static boolean ReceiveSTMessage(int *type, int *item) +{ + boolean retr = false; + + pthread_mutex_lock(&SoundMutex); + + if (SoundMessage) { + struct _SoundMessage *p, *t; + + p = NULL; + t = SoundMessage; + while (t->next) { + p = t; + t = t->next; + } + + if (p) { + p->next = NULL; + } else { + SoundMessage = NULL; + } + + *type = t->type; + *item = t->item; + + MM_FreePtr((memptr)&t); + + retr = true; + } else { + retr = false; + } + + pthread_mutex_unlock(&SoundMutex); + + return retr; +} + +static void *SoundThread(void *data) +{ + FM_OPL *OPL; + byte *s; + int type, item; + int i; + + OPL = OPLCreate(OPL_TYPE_YM3812, 3579545, 44100); + OPLWrite(OPL, 0x01, 0x20); /* Set WSE=1 */ + OPLWrite(OPL, 0x08, 0x00); /* Set CSM=0 & SEL=0 */ + + MM_GetPtr((memptr)&s, 63*2*5); + alGenBuffers(4, AdBuf); + + for (i = 0; i < 4; i++) + alBufferData(AdBuf[i], AL_FORMAT_MONO16, s, 63*5, 44100); + + alSourceQueueBuffers(SoundChan[0].handle, 4, AdBuf); + + for (;;) { + while (ReceiveSTMessage(&type, &item)) { + switch (type) { + case SOUND_START: + break; + case SOUND_STOP: + break; + case MUSIC_START: + break; + case MUSIC_STOP: + break; + case MUSIC_PAUSE: + break; + case MUSIC_UNPAUSE: + break; + case ST_SHUTDOWN: + /* TODO: free the openal stuff allocated in this thread */ + OPLDestroy(OPL); + return NULL; + } + } + + /* Do Stuff */ + usleep(1); + } + + return NULL; +} + void SD_Startup() { byte *p, *s; @@ -183,7 +342,7 @@ void SD_Startup() SoundChan[0].id = -1; SoundChan[0].priority = -1; - for (i = 1; i < CHANNELS; i++) { + for (i = 0; i < CHANNELS; i++) { alGenSources(1, &(SoundChan[i].handle)); SoundChan[i].id = -1; @@ -193,10 +352,19 @@ void SD_Startup() /* alSourcef(SoundChan[i].handle, AL_ROLLOFF_FACTOR, 1.0f); */ } + alSourcei(SoundChan[0].handle, AL_SOURCE_RELATIVE, AL_TRUE); + alSourcef(SoundChan[0].handle, AL_ROLLOFF_FACTOR, 0.0f); alSourcei(SoundChan[1].handle, AL_SOURCE_RELATIVE, AL_TRUE); alSourcef(SoundChan[i].handle, AL_ROLLOFF_FACTOR, 0.0f); MusicData[0].length = 0; /* silence warnings for now */ + + SoundMessage = NULL; + + pthread_mutex_init(&SoundMutex, NULL); + if (pthread_create(&hSoundThread, NULL, SoundThread, NULL) != 0) { + perror("pthread_create"); + } SD_Started = true; } @@ -205,6 +373,10 @@ void SD_Shutdown() { if (!SD_Started) return; + + SendSTMessage(ST_SHUTDOWN, 0); + +/* TODO: deallocate everything here */ SD_Started = false; } @@ -224,13 +396,15 @@ boolean SD_PlaySound(soundnames sound) alSourceStop(SoundChan[1].handle); alSourcei(SoundChan[1].handle, AL_BUFFER, s->pcm->handle); - alSourcePlay(SoundChan[1].handle); - return false; + alSourcePlay(SoundChan[1].handle); } + return false; } } - /* Adlib */ + if (s->priority >= SoundChan[0].priority) + SendSTMessage(SOUND_START, sound); + return false; } @@ -282,7 +456,7 @@ void PlaySoundLocGlobal(word sound, int id, fixed gx, fixed gy) } } - /* AdLib */ + /* Just play the AdLib version */ SD_PlaySound(sound); } @@ -295,22 +469,21 @@ void UpdateSoundLoc(fixed x, fixed y, int angle) val[2] = (ALfloat)y / 32768.0f; alListenerfv(AL_POSITION, val); - val[0] = cos(angle * PI / 180.0f); + val[0] = -cos(angle * PI / 180.0f); val[1] = 0.0f; val[2] = -sin(angle * PI / 180.0f); val[3] = 0.0f; val[4] = 1.0f; val[5] = 0.0f; - alListenerfv(AL_ORIENTATION, val); - + alListenerfv(AL_ORIENTATION, val); } void SD_StopSound() { int i; - /* Stop AdLib */ - + SendSTMessage(SOUND_STOP, 0); + for (i = 1; i < CHANNELS; i++) { SoundChan[i].id = -1; SoundChan[i].sound = -1; @@ -323,14 +496,11 @@ void SD_StopSound() word SD_SoundPlaying() { -/* returns 0 or currently playing sound */ -/* this is only checked for GETGATLINGSND so to be pedantic */ -/* return currently playing adlib else return the first found */ -/* playing channel */ ALint val; int i; - /* Check AdLib sound status */ + if (SoundChan[0].priority != -1) + return SoundChan[0].sound; for (i = 1; i < CHANNELS; i++) { alGetSourceiv(SoundChan[i].handle, AL_SOURCE_STATE, &val); @@ -343,45 +513,35 @@ word SD_SoundPlaying() void SD_WaitSoundDone() { -/* TODO: should also "work" when sound is disabled... */ while (SD_SoundPlaying()) ; } -void SD_SetDigiDevice(SDSMode mode) -{ -} - -boolean SD_SetSoundMode(SDMode mode) -{ - return false; -} - -boolean SD_SetMusicMode(SMMode mode) -{ - return false; -} - void SD_MusicOn() { - sqActive = true; + SendSTMessage(MUSIC_UNPAUSE, 0); } void SD_MusicOff() { - sqActive = false; + SendSTMessage(MUSIC_PAUSE, 0); } void SD_StartMusic(int music) { - SD_MusicOff(); + SendSTMessage(MUSIC_START, music); +} + +void SD_SetDigiDevice(SDSMode mode) +{ } -void SD_FadeOutMusic() +boolean SD_SetSoundMode(SDMode mode) { + return false; } -boolean SD_MusicPlaying() +boolean SD_SetMusicMode(SMMode mode) { return false; } diff --git a/src/sd_oss.c b/src/sd_oss.c index e2d0282..381f960 100644 --- a/src/sd_oss.c +++ b/src/sd_oss.c @@ -1,12 +1,42 @@ #include "wl_def.h" -#include <math.h> #include <pthread.h> #include <sys/ioctl.h> #include <sys/soundcard.h> - +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + #include "fmopl.h" +#define PACKED __attribute__((packed)) + +typedef struct { + longword length; + word priority; +} PACKED SoundCommon; + +typedef struct { + SoundCommon common; + byte data[1]; +} PACKED PCSound; + +typedef struct { + byte mChar, cChar, mScale, cScale, mAttack, cAttack, mSus, cSus, + mWave, cWave, nConn, voice, mode, unused[3]; +} PACKED Instrument; + +typedef struct { + SoundCommon common; + Instrument inst; + byte block, data[1]; +} PACKED AdLibSound; + +typedef struct { + word length, values[1]; +} PACKED MusicGroup; + boolean AdLibPresent, SoundBlasterPresent; SDMode SoundMode, MusicMode; @@ -42,17 +72,17 @@ static volatile int NewMusic; static volatile int NewAdlib; static volatile int AdlibPlaying; -pthread_t hSoundThread; +static pthread_t hSoundThread; -int CurDigi; -int CurAdlib; +static int CurDigi; +static int CurAdlib; -boolean SPHack; +static boolean SPHack; -short int sndbuf[512]; -short int musbuf[256]; +static short int sndbuf[512]; +static short int musbuf[256]; -void *SoundThread(void *data) +static void *SoundThread(void *data) { int i, snd; short int samp; @@ -230,7 +260,7 @@ void *SoundThread(void *data) return NULL; } -void Blah() +static void Blah() { memptr list; word *p, pg; @@ -569,6 +599,8 @@ void SD_MusicOff() /////////////////////////////////////////////////////////////////////////// void SD_StartMusic(int music) { + music += STARTMUSIC; + CA_CacheAudioChunk(music); SD_MusicOff(); @@ -577,28 +609,6 @@ void SD_StartMusic(int music) NewMusic = 1; } -/////////////////////////////////////////////////////////////////////////// -// -// SD_FadeOutMusic() - starts fading out the music. Call SD_MusicPlaying() -// to see if the fadeout is complete -// -/////////////////////////////////////////////////////////////////////////// -void SD_FadeOutMusic() -{ - SD_MusicOff(); -} - -/////////////////////////////////////////////////////////////////////////// -// -// SD_MusicPlaying() - returns true if music is currently playing, false if -// not -// -/////////////////////////////////////////////////////////////////////////// -boolean SD_MusicPlaying() -{ - return sqActive; -} - void SD_SetDigiDevice(SDSMode mode) { } diff --git a/src/vi_null.c b/src/vi_null.c index bc82fcd..20d22ff 100644 --- a/src/vi_null.c +++ b/src/vi_null.c @@ -16,7 +16,6 @@ byte *gfxbuf = NULL; void Quit(char *error) { - /* TODO: blah blah blah */ memptr screen = NULL; if (!error || !*error) { @@ -31,7 +30,7 @@ void Quit(char *error) ShutdownId(); if (screen) { - printf("TODO: spiffy ansi screen goes here..\n"); + /* printf("spiffy ansi screen goes here..\n"); */ } if (error && *error) { diff --git a/src/wl_menu.c b/src/wl_menu.c index bcf0ca8..f90cf7f 100644 --- a/src/wl_menu.c +++ b/src/wl_menu.c @@ -3149,7 +3149,7 @@ void StartCPMusic(int song) lastmusic = song; - SD_StartMusic(STARTMUSIC + song); + SD_StartMusic(song); } void FreeMusic() -- 2.18.1