Fixes by terrencehill and me:
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 14 May 2009 09:08:13 +0000 (09:08 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 14 May 2009 09:08:13 +0000 (09:08 +0000)
- better remapping handling of mixed fake and real cdtrack remappings
- fixed bgmvolume handling with CDs
- resume CD audio before stopping (SDL requires that)
- "cd" command showing help
- "cd reset" now always stops
- "cd rescan" command (don't ask me what it's good for)
- apparently work around SDL bug with looping CD tracks after pause and resume

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@8959 d7cf8633-e32d-0410-b094-e92efae38249

cd_sdl.c
cd_shared.c

index c508fc0..66ab1b6 100644 (file)
--- a/cd_sdl.c
+++ b/cd_sdl.c
@@ -22,23 +22,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "quakedef.h"
 #include "cdaudio.h"
 #include <SDL.h>
-
-/*IMPORTANT:
-SDL 1.2.7 and older seems to have a strange bug regarding CDPause and CDResume under WIN32.
-If CDResume is called, it plays to end of the CD regardless what values for lasttrack and lastframe
-were passed to CDPlayTracks.
-*/
+#include <time.h>
 
 // If one of the functions fails, it returns -1, if not 0
 
 // SDL supports multiple cd devices - so we are going to support this, too.
 static void CDAudio_SDL_CDDrive_f( void );
 
-// we only support playing on CD at a time
+// we only support playing one CD at a time
 static SDL_CD *cd;
-static int drive;
-static double pauseoffset;
-static double endtime;
 
 static int ValidateDrive( void )
 {
@@ -59,7 +51,6 @@ void CDAudio_SysCloseDoor (void)
        //NO SDL FUNCTION
 }
 
-
 int CDAudio_SysGetAudioDiskInfo (void)
 {
        if( ValidateDrive() ) // everything > 0 is ok, 0 is trayempty and -1 is error
@@ -67,66 +58,58 @@ int CDAudio_SysGetAudioDiskInfo (void)
        return -1;
 }
 
-
 float CDAudio_SysGetVolume (void)
 {
        return -1.0f;
 }
 
-
 void CDAudio_SysSetVolume (float volume)
 {
        //NO SDL FUNCTION
 }
 
-
 int CDAudio_SysPlay (int track)
 {
-       SDL_CDStop( cd );
-       endtime = realtime + (float) cd->track[ track - 1 ].length / CD_FPS;
-       return SDL_CDPlayTracks( cd, track - 1, 0, track, 1 ); //FIXME: shall we play the whole cd or only the track?
+       return SDL_CDPlayTracks(cd, track, 0, 1, 0);
 }
 
-
 int CDAudio_SysStop (void)
 {
-       endtime = -1.0;
        return SDL_CDStop( cd );
 }
 
-
 int CDAudio_SysPause (void)
 {
-       SDL_CDStatus( cd );
-       pauseoffset = cd->cur_frame;
        return SDL_CDPause( cd );
 }
 
 int CDAudio_SysResume (void)
 {
-       SDL_CDResume( cd );
-       endtime = realtime + (cd->track[ cdPlayTrack - 1 ].length - pauseoffset) / CD_FPS;
-       return SDL_CDPlayTracks( cd, cdPlayTrack - 1, (int)pauseoffset, cdPlayTrack, 0 );
+       return SDL_CDResume( cd );
 }
 
 int CDAudio_SysUpdate (void)
 {
-       if( !cd || cd->status <= 0 ) {
-               cdValid = false;
-               return -1;
-       }
-       if( endtime > 0.0 && realtime >= endtime )
-               if( SDL_CDStatus( cd ) == CD_STOPPED ){
-                       endtime = -1.0;
+       static time_t lastchk = 0;
+
+       if (cdPlaying && lastchk < time(NULL))
+       {
+               lastchk = time(NULL) + 2; //two seconds between chks
+               if( !cd || cd->status <= 0 ) {
+                       cdValid = false;
+                       return -1;
+               }
+               if (SDL_CDStatus( cd ) == CD_STOPPED)
+               {
                        if( cdPlayLooping )
                                CDAudio_SysPlay( cdPlayTrack );
                        else
                                cdPlaying = false;
                }
+       }
        return 0;
 }
 
-
 void CDAudio_SysInit (void)
 {
        if( SDL_InitSubSystem( SDL_INIT_CDROM ) == -1 )
@@ -176,8 +159,6 @@ int CDAudio_SysStartup (void)
        if( i == numdrives && !cd )
                return -1;
 
-       drive = i;
-
        return 0;
 }
 
@@ -217,7 +198,6 @@ void CDAudio_SDL_CDDrive_f( void )
        else if( !IsAudioCD() )
                Con_Printf( "The CD in drive %i is not an audio CD.\n", i );
 
-       drive = i;
        ValidateDrive();
 }
 
index 8a47f7b..0974921 100644 (file)
@@ -157,8 +157,32 @@ void CDAudio_Play_byName (const char *trackname, qboolean looping)
        {
                track = (unsigned char) atoi(trackname);
                if(track > 0 && track < MAXTRACKS)
-                               if(*remap[track])
+                       if(*remap[track])
+                       {
+                               if(strspn(remap[track], "0123456789") == strlen(remap[track]))
+                               {
                                        trackname = remap[track];
+                               }
+                               else
+                               {
+                                       // ignore remappings to fake tracks if we're going to play a real track
+                                       switch(cdaudio.integer)
+                                       {
+                                               case 0: // we never access CD
+                                               case 1: // we have a replacement
+                                                       trackname = remap[track];
+                                                       break;
+                                               case 2: // we only use fake track replacement if CD track is invalid
+                                                       CDAudio_GetAudioDiskInfo();
+                                                       if(!cdValid || track > maxTrack)
+                                                               trackname = remap[track];
+                                                       break;
+                                               case 3: // we always play from CD - ignore this remapping then
+                                               case 4: // we randomize anyway
+                                                       break;
+                                       }
+                               }
+                       }
        }
 
        if(strspn(trackname, "0123456789") == strlen(trackname))
@@ -173,6 +197,7 @@ void CDAudio_Play_byName (const char *trackname, qboolean looping)
        else
                track = 0;
 
+       // div0: I assume this code was intentionally there. Maybe turn it into a cvar?
        if (cdPlaying && cdPlayTrack == track && faketrack == -1)
                return;
        CDAudio_Stop ();
@@ -270,7 +295,7 @@ success:
        cdPlayTrack = track;
        cdPlaying = true;
 
-       if (cdvolume == 0.0)
+       if (cdvolume == 0.0 || bgmvolume.value == 0)
                CDAudio_Pause ();
 }
 
@@ -300,6 +325,12 @@ void CDAudio_Stop (void)
        }
        else if (cdPlaying && (CDAudio_SysStop() == -1))
                return;
+       else if(wasPlaying)
+       {
+               CDAudio_Resume(); // needed by SDL - can't stop while paused there
+               if (cdPlaying && (CDAudio_SysStop() == -1))
+                       return;
+       }
 
        wasPlaying = false;
        cdPlaying = false;
@@ -338,10 +369,7 @@ static void CD_f (void)
        int ret;
        int n;
 
-       if (Cmd_Argc() < 2)
-               return;
-
-       command = Cmd_Argv (1);
+       command = (Cmd_Argc() >= 2) ? Cmd_Argv (1) : "";
 
        if (strcasecmp(command, "remap") != 0)
                Host_StartVideo();
@@ -363,14 +391,21 @@ static void CD_f (void)
        if (strcasecmp(command, "reset") == 0)
        {
                enabled = true;
-               if (cdPlaying)
-                       CDAudio_Stop();
+               CDAudio_Stop();
                for (n = 0; n < MAXTRACKS; n++)
                        *remap[n] = 0; // empty string, that is, unremapped
                CDAudio_GetAudioDiskInfo();
                return;
        }
 
+       if (strcasecmp(command, "rescan") == 0)
+       {
+               CDAudio_Stop();
+               CDAudio_Shutdown();
+               CDAudio_Startup();
+               return;
+       }
+
        if (strcasecmp(command, "remap") == 0)
        {
                ret = Cmd_Argc() - 2;
@@ -442,7 +477,10 @@ static void CD_f (void)
                        Con_Printf("Currently %s track %u\n", cdPlayLooping ? "looping" : "playing", cdPlayTrack);
                else if (wasPlaying)
                        Con_Printf("Paused %s track %u\n", cdPlayLooping ? "looping" : "playing", cdPlayTrack);
-               Con_Printf("Volume is %f\n", cdvolume);
+               if (cdvolume >= 0)
+                       Con_Printf("Volume is %f\n", cdvolume);
+               else
+                       Con_Printf("Can't get CD volume\n");
                return;
        }
 
@@ -491,8 +529,8 @@ void CDAudio_Update (void)
                return;
 
        CDAudio_SetVolume (bgmvolume.value);
-
-       if (faketrack == -1 && cdaudio.integer != 0)
+       
+       if (faketrack == -1 && cdaudio.integer != 0 && bgmvolume.value != 0)
                CDAudio_SysUpdate();
 }