Fake CD tracks support; DP now tries to play "sound/cdtracks/trackXX.wav" instead...
authormolivier <molivier@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 5 Apr 2004 07:00:19 +0000 (07:00 +0000)
committermolivier <molivier@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 5 Apr 2004 07:00:19 +0000 (07:00 +0000)
"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

cd_bsd.c
cd_linux.c
cd_null.c
cd_shared.c
makefile.inc
snd_dma.c
snd_mix.c
snd_null.c
sound.h

index bdb6f75..41de20a 100644 (file)
--- 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");
index 6331c00..6e6525e 100644 (file)
@@ -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");
index e1a3a30..7bfe2f3 100644 (file)
--- 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)
 {
 }
index fd5ee0e..a791944 100644 (file)
@@ -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())
        {
index e790de9..3a09a9b 100644 (file)
@@ -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)
 
index ea4d6a4..dd19c69 100644 (file)
--- 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 ; i<MAX_DYNAMIC_CHANNELS ; i++)
+       ch = &channels[channel_ind];
+       if (ch->sfx != 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));
 
index e4759cf..29e319f 100644 (file)
--- 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;
                                }
                        }
index d6f1269..dec8251 100755 (executable)
@@ -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 4107320..b6a44bc 100644 (file)
--- 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);