/* snd_sdl.c CD code taken from SDLQuake and modified to work with Quake2 Robert Bäuml 2001-12-25 W.P. van Paassen 2002-01-06 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to: Free Software Foundation, Inc. 59 Temple Place - Suite 330 Boston, MA 02111-1307, USA $Id$ */ #include #include "SDL.h" #include "../client/client.h" static qboolean cdValid = false; static qboolean initialized = false; static qboolean enabled = true; static qboolean playLooping = false; static SDL_CD *cd_id; static float cdvolume = 1.0; static int lastTrack = 0; cvar_t *cd_volume; cvar_t *cd_nocd; cvar_t *cd_dev; static void CD_f(); static void CDAudio_Eject() { if(!cd_id || !enabled) return; if(SDL_CDEject(cd_id)) Com_DPrintf("Unable to eject CD-ROM tray.\n"); } void CDAudio_Play(int track, qboolean looping) { CDstatus cd_stat; lastTrack = track + 1; if(!cd_id || !enabled) return; cd_stat = SDL_CDStatus(cd_id); if(!cdValid) { if(!CD_INDRIVE(cd_stat) ||(!cd_id->numtracks)) return; cdValid = true; } if((track < 1) || (track >= cd_id->numtracks)) { Com_DPrintf("CDAudio: Bad track number: %d\n",track); return; } track--; /* Convert track from person to SDL value */ if(cd_stat == CD_PLAYING) { if(cd_id->cur_track == track) return; CDAudio_Stop(); } if(SDL_CDPlay(cd_id,cd_id->track[track].offset, cd_id->track[track].length)) { Com_DPrintf("CDAudio_Play: Unable to play track: %d (%s)\n", track+1, SDL_GetError()); return; } playLooping = looping; } void CDAudio_RandomPlay(void) { int track, i = 0, free_tracks = 0; float f; CDstatus cd_stat; unsigned char track_bools[100]; if (!cd_id || !enabled) return; //create array of available audio tracknumbers for (; i < cd_id->numtracks; i++) { track_bools[i] = cd_id->track[i].type == SDL_AUDIO_TRACK; free_tracks += track_bools[i]; } if (!free_tracks) { Com_DPrintf("CDAudio_RandomPlay: Unable to find and play a random audio track, insert an audio cd please"); return; } //choose random audio track do { do { f = ((float)rand()) / ((float)RAND_MAX + 1.0); track = (int)(cd_id->numtracks * f); } while(!track_bools[track]); lastTrack = track+1; cd_stat=SDL_CDStatus(cd_id); if(!cdValid) { if(!CD_INDRIVE(cd_stat) ||(!cd_id->numtracks)) return; cdValid = true; } if(cd_stat == CD_PLAYING) { if(cd_id->cur_track == track + 1) return; CDAudio_Stop(); } if (SDL_CDPlay(cd_id,cd_id->track[track].offset, cd_id->track[track].length)) { track_bools[track] = 0; free_tracks--; } else { playLooping = true; return; } } while (free_tracks > 0); } void CDAudio_Stop() { int cdstate; if(!cd_id || !enabled) return; cdstate = SDL_CDStatus(cd_id); if((cdstate != CD_PLAYING) && (cdstate != CD_PAUSED)) return; if(SDL_CDStop(cd_id)) Com_DPrintf("CDAudio_Stop: Failed to stop track.\n"); playLooping = 0; } void CDAudio_Pause() { if(!cd_id || !enabled) return; if(SDL_CDStatus(cd_id) != CD_PLAYING) return; if(SDL_CDPause(cd_id)) Com_DPrintf("CDAudio_Pause: Failed to pause track.\n"); } void CDAudio_Resume() { if(!cd_id || !enabled) return; if(SDL_CDStatus(cd_id) != CD_PAUSED) return; if(SDL_CDResume(cd_id)) Com_DPrintf("CDAudio_Resume: Failed to resume track.\n"); } void CDAudio_Update() { if(!cd_id || !enabled) return; if(cd_volume && cd_volume->value != cdvolume) { if(cdvolume) { Cvar_SetValue("cd_volume",0.0); CDAudio_Pause(); } else { Cvar_SetValue("cd_volume",1.0); CDAudio_Resume(); } cdvolume = cd_volume->value; return; } if(cd_nocd->value) { CDAudio_Stop(); return; } if(playLooping && (SDL_CDStatus(cd_id) != CD_PLAYING) && (SDL_CDStatus(cd_id) != CD_PAUSED)) { CDAudio_Play(lastTrack, true); } } int CDAudio_Init() { cvar_t *cv; if (initialized) return 0; cv = Cvar_Get ("nocdaudio", "0", CVAR_NOSET); if (cv->value) return -1; cd_nocd = Cvar_Get ("cd_nocd", "0", CVAR_ARCHIVE ); if ( cd_nocd->value) return -1; cd_volume = Cvar_Get ("cd_volume", "1", CVAR_ARCHIVE); if (SDL_WasInit(SDL_INIT_EVERYTHING) == 0) { if (SDL_Init(SDL_INIT_CDROM) < 0) { Com_Printf ("Couldn't init SDL cdrom: %s\n", SDL_GetError ()); return -1; } } else if (SDL_WasInit(SDL_INIT_CDROM) == 0) { if (SDL_InitSubSystem(SDL_INIT_CDROM) < 0) { Com_Printf ("Couldn't init SDL cdrom: %s\n", SDL_GetError ()); return -1; } } cd_id = SDL_CDOpen(0); if(!cd_id) { Com_Printf("CDAudio_Init: Unable to open default CD-ROM drive: %s\n", SDL_GetError()); return -1; } initialized = true; enabled = true; cdValid = true; if(!CD_INDRIVE(SDL_CDStatus(cd_id))) { Com_Printf("CDAudio_Init: No CD in drive.\n"); cdValid = false; } if(!cd_id->numtracks) { Com_Printf("CDAudio_Init: CD contains no audio tracks.\n"); cdValid = false; } Cmd_AddCommand("cd",CD_f); Com_Printf("CD Audio Initialized.\n"); return 0; } void CDAudio_Shutdown() { if(!cd_id) return; CDAudio_Stop(); SDL_CDClose(cd_id); cd_id = NULL; if (SDL_WasInit(SDL_INIT_EVERYTHING) == SDL_INIT_CDROM) SDL_Quit(); else SDL_QuitSubSystem(SDL_INIT_CDROM); initialized = false; } static void CD_f() { char *command; int cdstate; if(Cmd_Argc() < 2) return; command = Cmd_Argv(1); if(!Q_strcasecmp(command,"on")) { enabled = true; } if(!Q_strcasecmp(command,"off")) { if(!cd_id) return; cdstate = SDL_CDStatus(cd_id); if((cdstate == CD_PLAYING) || (cdstate == CD_PAUSED)) CDAudio_Stop(); enabled = false; return; } if(!Q_strcasecmp(command,"play")) { CDAudio_Play((byte)atoi(Cmd_Argv(2)),false); return; } if(!Q_strcasecmp(command,"loop")) { CDAudio_Play((byte)atoi(Cmd_Argv(2)),true); return; } if(!Q_strcasecmp(command,"stop")) { CDAudio_Stop(); return; } if(!Q_strcasecmp(command,"pause")) { CDAudio_Pause(); return; } if(!Q_strcasecmp(command,"resume")) { CDAudio_Resume(); return; } if(!Q_strcasecmp(command,"eject")) { CDAudio_Eject(); return; } if(!Q_strcasecmp(command,"info")) { if(!cd_id) return; cdstate = SDL_CDStatus(cd_id); Com_Printf("%d tracks\n",cd_id->numtracks); if(cdstate == CD_PLAYING) Com_Printf("Currently %s track %d\n", playLooping ? "looping" : "playing", cd_id->cur_track+1); else if(cdstate == CD_PAUSED) Com_Printf("Paused %s track %d\n", playLooping ? "looping" : "playing", cd_id->cur_track+1); return; } } void CDAudio_Activate (qboolean active) { if (active) CDAudio_Resume (); else CDAudio_Pause (); }