diff --git a/Quake/cd_sdl.c b/Quake/cd_sdl.c index dd136a9b..7c344fdd 100644 --- a/Quake/cd_sdl.c +++ b/Quake/cd_sdl.c @@ -44,6 +44,7 @@ static qboolean cdValid = false; static qboolean playing = false; +static qboolean active = false; static qboolean wasPlaying = false; static qboolean enabled = true; static qboolean playLooping = false; @@ -124,6 +125,7 @@ int CDAudio_Play(byte track, qboolean looping) playLooping = looping; playTrack = track; playing = true; + active = true; FRAMES_TO_MSF(cd_handle->track[track-1].length, &len_m, &len_s, &len_f); endOfTrack = realtime + ((double)len_m * 60.0) + (double)len_s + (double)len_f / (double)CD_FPS; @@ -141,6 +143,13 @@ int CDAudio_Play(byte track, qboolean looping) return 0; } +/* We have two types of stop + * + * On many devices, CDROMSTOP + * ioctl causes any ioctls following immediately to + * fail for a considerable time. + * So avoid dead stops if playback may be resume shortly */ + void CDAudio_Stop(void) { if (!cd_handle || !enabled) @@ -149,8 +158,9 @@ void CDAudio_Stop(void) if (!playing) return; - if (SDL_CDStop(cd_handle) == -1) - Con_Printf ("CDAudio_Stop: Unable to stop CD-ROM (%s)\n", SDL_GetError()); + + if (SDL_CDPause(cd_handle) == -1) + Con_Printf ("CDAudio_Stop: Unable to pause CD-ROM (%s)\n", SDL_GetError()); wasPlaying = false; playing = false; @@ -158,6 +168,24 @@ void CDAudio_Stop(void) endOfTrack = -1.0; } +void CDAudio_ReallyStop(void) +{ + if (!cd_handle || !enabled) + return; + + if (!active) + return; + + if (SDL_CDStop(cd_handle) == -1) + Con_Printf ("CDAudio_ReallyStop: Unable to stop CD-ROM (%s)\n", SDL_GetError()); + + wasPlaying = false; + playing = false; + active = false; + pausetime = -1.0; + endOfTrack = -1.0; +} + void CDAudio_Pause(void) { if (!cd_handle || !enabled) @@ -188,6 +216,7 @@ void CDAudio_Resume(void) if (SDL_CDResume(cd_handle) == -1) Con_Printf ("Unable to resume CD-ROM: %s\n", SDL_GetError()); playing = true; + active = true; endOfTrack += realtime - pausetime; pausetime = -1.0; } @@ -217,7 +246,7 @@ static void CD_f (void) if (q_strcasecmp(command, "off") == 0) { if (playing) - CDAudio_Stop(); + CDAudio_ReallyStop(); enabled = false; return; } @@ -226,7 +255,7 @@ static void CD_f (void) { enabled = true; if (playing) - CDAudio_Stop(); + CDAudio_ReallyStop(); for (n = 0; n < 100; n++) remap[n] = n; CDAudio_GetAudioDiskInfo(); @@ -290,8 +319,8 @@ static void CD_f (void) if (q_strcasecmp(command, "eject") == 0) { - if (playing) - CDAudio_Stop(); + if (playing || active) + CDAudio_ReallyStop(); CDAudio_Eject(); cdValid = false; return; @@ -323,6 +352,9 @@ static void CD_f (void) return; } + + Con_Printf("cd: \"%s\" unknown command.\n",command); + return; } static qboolean CD_GetVolume (void *unused) @@ -532,7 +564,7 @@ void CDAudio_Shutdown(void) { if (!cd_handle) return; - CDAudio_Stop(); + CDAudio_ReallyStop(); if (hw_vol_works) CD_SetVolume (NULL); /* no SDL support at present. */ SDL_CDClose(cd_handle);