From: molivier Date: Mon, 5 Apr 2004 07:00:19 +0000 (+0000) Subject: Fake CD tracks support; DP now tries to play "sound/cdtracks/trackXX.wav" instead... X-Git-Tag: xonotic-v0.1.0preview~5935 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=commitdiff_plain;h=543e06fbc28e7930b50d08c4db9c1b45e48acbc7 Fake CD tracks support; DP now tries to play "sound/cdtracks/trackXX.wav" instead of CD track XX. If it fails, it tries "trackXX.ogg", and then the real CD track if any. CD console commands should work as expected. "cd_shared.c" is now part of the common files so it allows people to compile DP without real CD support, but with fake CD tracks support. "cd_null.c" is now a null driver, at the same level as "cd_linux.c" or "cd_win.c". Fixed the broken return value of S_StartSound and a potential memory leak in S_StopAllSounds in the process. git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@4085 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/cd_bsd.c b/cd_bsd.c index bdb6f751..41de20a1 100644 --- a/cd_bsd.c +++ b/cd_bsd.c @@ -62,6 +62,9 @@ int CDAudio_SysGetAudioDiskInfo (void) { struct ioc_toc_header tochdr; + if (cdfile == -1) + return -1; + if (ioctl(cdfile, CDIOREADTOCHEADER, &tochdr) == -1) { Con_DPrint("ioctl CDIOREADTOCHEADER failed\n"); diff --git a/cd_linux.c b/cd_linux.c index 6331c00e..6e6525eb 100644 --- a/cd_linux.c +++ b/cd_linux.c @@ -58,6 +58,9 @@ int CDAudio_SysGetAudioDiskInfo (void) { struct cdrom_tochdr tochdr; + if (cdfile == -1) + return -1; + if (ioctl(cdfile, CDROMREADTOCHDR, &tochdr) == -1) { Con_DPrint("ioctl CDROMREADTOCHDR failed\n"); diff --git a/cd_null.c b/cd_null.c index e1a3a300..7bfe2f3e 100644 --- a/cd_null.c +++ b/cd_null.c @@ -17,55 +17,63 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + #include "quakedef.h" -cvar_t cdaudioinitialized = {CVAR_READONLY,"cdaudioinitialized","0"}; -void CDAudio_Play(qbyte track, qboolean looping) +void CDAudio_SysEject (void) { } -void CDAudio_Stop(void) +void CDAudio_SysCloseDoor (void) { } -void CDAudio_Pause(void) +int CDAudio_SysGetAudioDiskInfo (void) { + return -1; } -void CDAudio_Resume(void) +int CDAudio_SysPlay (qbyte track) { + return -1; } -void CDAudio_Update(void) +int CDAudio_SysStop (void) { + return -1; } -int CDAudio_Init(void) +int CDAudio_SysPause (void) { - Cvar_RegisterVariable(&cdaudioinitialized); - return 0; + return -1; } -int CDAudio_Startup(void) +int CDAudio_SysResume (void) { - return 0; + return -1; } -void CDAudio_Shutdown(void) +int CDAudio_SysUpdate (void) { + return -1; } -void CDAudio_Open(void) +void CDAudio_SysInit (void) +{ +} + +int CDAudio_SysStartup (void) { + return -1; } -void CDAudio_Close(void) +void CDAudio_SysShutdown (void) { } diff --git a/cd_shared.c b/cd_shared.c index fd5ee0ed..a7919448 100644 --- a/cd_shared.c +++ b/cd_shared.c @@ -44,6 +44,7 @@ static qboolean enabled = false; static float cdvolume; static qbyte remap[100]; static qbyte maxTrack; +static int faketrack = -1; // exported variables qboolean cdValid = false; @@ -88,18 +89,13 @@ static int CDAudio_GetAudioDiskInfo (void) void CDAudio_Play (qbyte track, qboolean looping) { + sfx_t* sfx; + if (!enabled) return; - if (!cdValid) - { - CDAudio_GetAudioDiskInfo(); - if (!cdValid) - return; - } - track = remap[track]; - if (track < 1 || track > maxTrack) + if (track < 1) { Con_DPrintf("CDAudio: Bad track number %u.\n", track); return; @@ -107,9 +103,43 @@ void CDAudio_Play (qbyte track, qboolean looping) if (cdPlaying && cdPlayTrack == track) return; + CDAudio_Stop (); - if (CDAudio_SysPlay(track) == -1) - return; + // Try playing a fake track (sound file) first + sfx = S_PrecacheSound (va ("cdtracks/track%02u.wav", track), false); + if (sfx != NULL) + { + faketrack = S_StartSound (-1, 0, sfx, vec3_origin, 1, 0); + if (faketrack != -1) + { + if (looping) + S_LoopChannel (faketrack, true); + Con_DPrintf ("Fake CD track %u playing...\n", track); + } + } + + // If we can't play a fake CD track, try the real one + if (faketrack == -1) + { + if (!cdValid) + { + CDAudio_GetAudioDiskInfo(); + if (!cdValid) + { + Con_Print ("No CD in player.\n"); + return; + } + } + + if (track > maxTrack) + { + Con_DPrintf("CDAudio: Bad track number %u.\n", track); + return; + } + + if (CDAudio_SysPlay(track) == -1) + return; + } cdPlayLooping = looping; cdPlayTrack = track; @@ -125,7 +155,12 @@ void CDAudio_Stop (void) if (!enabled || !cdPlaying) return; - if (CDAudio_SysStop() == -1) + if (faketrack != -1) + { + S_StopChannel (faketrack); + faketrack = -1; + } + else if (CDAudio_SysStop() == -1) return; wasPlaying = false; @@ -137,7 +172,9 @@ void CDAudio_Pause (void) if (!enabled || !cdPlaying) return; - if (CDAudio_SysPause() == -1) + if (faketrack != -1) + S_PauseChannel (faketrack, true); + else if (CDAudio_SysPause() == -1) return; wasPlaying = cdPlaying; @@ -147,10 +184,12 @@ void CDAudio_Pause (void) void CDAudio_Resume (void) { - if (!enabled || !cdValid || !wasPlaying) + if (!enabled || !wasPlaying) return; - if (CDAudio_SysResume() == -1) + if (faketrack != -1) + S_PauseChannel (faketrack, false); + else if (CDAudio_SysResume() == -1) return; cdPlaying = true; } @@ -212,16 +251,6 @@ static void CD_f (void) return; } - if (!cdValid) - { - CDAudio_GetAudioDiskInfo(); - if (!cdValid) - { - Con_Print("No CD in player.\n"); - return; - } - } - if (strcasecmp(command, "play") == 0) { CDAudio_Play((qbyte)atoi(Cmd_Argv (2)), false); @@ -254,7 +283,7 @@ static void CD_f (void) if (strcasecmp(command, "eject") == 0) { - if (cdPlaying) + if (cdPlaying && faketrack == -1) CDAudio_Stop(); CDAudio_Eject(); cdValid = false; @@ -263,7 +292,11 @@ static void CD_f (void) if (strcasecmp(command, "info") == 0) { - Con_Printf("%u tracks\n", maxTrack); + CDAudio_GetAudioDiskInfo (); + if (cdValid) + Con_Printf("%u tracks on CD.\n", maxTrack); + else + Con_Print ("No CD in player.\n"); if (cdPlaying) Con_Printf("Currently %s track %u\n", cdPlayLooping ? "looping" : "playing", cdPlayTrack); else if (wasPlaying) @@ -294,7 +327,8 @@ void CDAudio_Update (void) } } - CDAudio_SysUpdate(); + if (faketrack == -1) + CDAudio_SysUpdate(); } int CDAudio_Init (void) @@ -323,8 +357,7 @@ int CDAudio_Init (void) int CDAudio_Startup (void) { - if (CDAudio_SysStartup() == -1) - return -1; + CDAudio_SysStartup (); if (CDAudio_GetAudioDiskInfo()) { diff --git a/makefile.inc b/makefile.inc index e790de9b..3a09a9b0 100644 --- a/makefile.inc +++ b/makefile.inc @@ -22,11 +22,11 @@ OBJ_COMMONSOUND=snd_dma.o snd_mem.o snd_mix.o snd_ogg.o snd_wav.o OBJ_NOSOUND=snd_null.o # CD objects -OBJ_COMMONCD=cd_shared.o OBJ_NOCD=cd_null.o # Common objects OBJ_COMMON= \ + cd_shared.o \ cgame.o \ cgamevm.o \ cl_collision.o \ @@ -158,7 +158,7 @@ LIB_LINUXSOUND= #LIB_LINUXSOUND= # If you want CD sound in Linux -OBJ_LINUXCD=$(OBJ_COMMONCD) cd_linux.o +OBJ_LINUXCD=cd_linux.o # If you want no CD audio #OBJ_LINUXCD=$(OBJ_NOCD) @@ -175,7 +175,7 @@ OBJ_BSDSOUND=$(OBJ_COMMONSOUND) snd_bsd.o LIB_BSDSOUND= #if you want CD sound in BSD -OBJ_BSDCD=$(OBJ_COMMONCD) cd_bsd.o +OBJ_BSDCD=cd_bsd.o #if you want no CD audio #OBJ_BSDCD=$(OBJ_NOCD) @@ -192,7 +192,7 @@ OBJ_WINSOUND=$(OBJ_COMMONSOUND) snd_win.o LIB_WINSOUND= #if you want CD sound in Win32 -OBJ_WINCD=$(OBJ_COMMONCD) cd_win.o +OBJ_WINCD=cd_win.o #if you want no CD audio #OBJ_WINCD=$(OBJ_NOCD) diff --git a/snd_dma.c b/snd_dma.c index ea4d6a40..dd19c690 100644 --- a/snd_dma.c +++ b/snd_dma.c @@ -591,27 +591,65 @@ int S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fv } } - return (channels - target_chan); + return (target_chan - channels); } -void S_StopSound(int entnum, int entchannel) +void S_StopChannel (unsigned int channel_ind) { - int i; + channel_t *ch; + + if (channel_ind >= total_channels) + return; - for (i=0 ; isfx != NULL) { - if (channels[i].entnum == entnum - && channels[i].entchannel == entchannel) + if (ch->sfx->fetcher != NULL) { - channels[i].end = 0; - channels[i].sfx = NULL; - return; + snd_fetcher_end_t fetcher_end = ch->sfx->fetcher->end; + if (fetcher_end != NULL) + fetcher_end (ch); } + ch->sfx = NULL; } + ch->end = 0; +} + +void S_PauseChannel (unsigned int channel_ind, qboolean toggle) +{ + if (toggle) + channels[channel_ind].flags |= CHANNELFLAG_PAUSED; + else + channels[channel_ind].flags &= ~CHANNELFLAG_PAUSED; +} + +void S_LoopChannel (unsigned int channel_ind, qboolean toggle) +{ + if (toggle) + channels[channel_ind].flags |= CHANNELFLAG_FORCELOOP; + else + channels[channel_ind].flags &= ~CHANNELFLAG_FORCELOOP; +} + +void S_StopSound(int entnum, int entchannel) +{ + unsigned int i; + + for (i = 0; i < MAX_DYNAMIC_CHANNELS; i++) + if (channels[i].entnum == entnum && channels[i].entchannel == entchannel) + { + S_StopChannel (i); + return; + } } void S_StopAllSounds(qboolean clear) { + unsigned int i; + + for (i = 0; i < total_channels; i++) + S_StopChannel (i); + total_channels = MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; // no statics memset(channels, 0, MAX_CHANNELS * sizeof(channel_t)); diff --git a/snd_mix.c b/snd_mix.c index e4759cfd..29e319f8 100644 --- a/snd_mix.c +++ b/snd_mix.c @@ -375,9 +375,7 @@ void S_PaintChannels(int endtime) if (stop_paint) { - if (ch->sfx->fetcher->end != NULL) - ch->sfx->fetcher->end (ch); - ch->sfx = NULL; + S_StopChannel (ch - channels); break; } } diff --git a/snd_null.c b/snd_null.c index d6f1269f..dec82519 100755 --- a/snd_null.c +++ b/snd_null.c @@ -77,6 +77,18 @@ int S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f return -1; } +void S_StopChannel (unsigned int channel_ind) +{ +} + +void S_PauseChannel (unsigned int channel_ind, qboolean toggle) +{ +} + +void S_LoopChannel (unsigned int channel_ind, qboolean toggle) +{ +} + void S_StopSound (int entnum, int entchannel) { } diff --git a/sound.h b/sound.h index 4107320a..b6a44bc1 100644 --- a/sound.h +++ b/sound.h @@ -101,8 +101,12 @@ struct snd_fetcher_s void S_Init (void); void S_Startup (void); void S_Shutdown (void); +// S_StartSound returns the channel index, or -1 if an error occurred int S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation); void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation); +void S_StopChannel (unsigned int channel_ind); +void S_PauseChannel (unsigned int channel_ind, qboolean toggle); +void S_LoopChannel (unsigned int channel_ind, qboolean toggle); void S_StopSound (int entnum, int entchannel); void S_StopAllSounds(qboolean clear); void S_PauseGameSounds (void);