1 /*
2 	cd_sdl.c
3 
4 	CD code taken from SDLQuake and modified to work with NehQuake
5 	Robert B�uml 2001-12-25
6 	W.P. van Paassen 2002-01-06
7 
8 	This program is free software; you can redistribute it and/or
9 	modify it under the terms of the GNU General Public License
10 	as published by the Free Software Foundation; either version 2
11 	of the License, or (at your option) any later version.
12 
13 	This program is distributed in the hope that it will be useful,
14 	but WITHOUT ANY WARRANTY; without even the implied warranty of
15 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 
17 	See the GNU General Public License for more details.
18 
19 	You should have received a copy of the GNU General Public License
20 	along with this program; if not, write to:
21 
22 		Free Software Foundation, Inc.
23 		59 Temple Place - Suite 330
24 		Boston, MA  02111-1307, USA
25 
26 	$Id: cd_sdl.c,v 1.5 2002/02/16 19:03:06 relnev Exp $
27 */
28 
29 #include <stdio.h>
30 #include "SDL.h"
31 #include "quakedef.h"
32 
33 static qboolean cdValid = false;
34 static qboolean initialized = false;
35 static qboolean enabled = true;
36 static qboolean playLooping = false;
37 static SDL_CD *cd_id;
38 static float cdvolume = 1.0;
39 static int lastTrack = 0;
40 
41 cvar_t	*cd_volume;
42 cvar_t *cd_nocd;
43 cvar_t *cd_dev;
44 
45 static void CD_f();
46 
CDAudio_Eject()47 static void CDAudio_Eject()
48 {
49 	if(!cd_id || !enabled) return;
50 
51 	if(SDL_CDEject(cd_id))
52 		Con_DPrintf("Unable to eject CD-ROM tray.\n");
53 }
54 
CDAudio_Play(byte track,qboolean looping)55 void CDAudio_Play(byte track, qboolean looping)
56 {
57 	CDstatus cd_stat;
58 
59 	lastTrack = track+1;
60 
61 	if(!cd_id || !enabled) return;
62 
63 	cd_stat=SDL_CDStatus(cd_id);
64 
65 	if(!cdValid)
66 	{
67 		if(!CD_INDRIVE(cd_stat) ||(!cd_id->numtracks)) return;
68 		cdValid = true;
69 	}
70 
71 	if((track < 1) || (track >= cd_id->numtracks))
72 	{
73 		Con_DPrintf("CDAudio: Bad track number: %d\n",track);
74 		return;
75 	}
76 	track--; /* Convert track from person to SDL value */
77 	if(cd_stat == CD_PLAYING)
78 	{
79 		if(cd_id->cur_track == track) return;
80 		CDAudio_Stop();
81 	}
82 
83 	if(SDL_CDPlay(cd_id,cd_id->track[track].offset,
84 			  cd_id->track[track].length))
85 	{
86 		Con_DPrintf("CDAudio_Play: Unable to play track: %d (%s)\n",track+1, SDL_GetError());
87 		return;
88 	}
89 	playLooping = looping;
90 }
91 
CDAudio_RandomPlay(void)92 void CDAudio_RandomPlay(void)
93 {
94   int track, i = 0, free_tracks = 0;
95   float f;
96   CDstatus cd_stat;
97   byte* track_bools;
98 
99   if (!cd_id || !enabled)
100     return;
101 
102   track_bools = (byte*)malloc(cd_id->numtracks* sizeof(byte));
103 
104   if (track_bools == 0)
105     return;
106 
107   //create array of available audio tracknumbers
108 
109   for (; i < cd_id->numtracks; i++)
110     {
111       track_bools[i] = cd_id->track[i].type == SDL_AUDIO_TRACK;
112       free_tracks += track_bools[i];
113     }
114 
115   if (!free_tracks)
116     {
117       Con_DPrintf("CDAudio_RandomPlay: Unable to find and play a random audio track, insert an audio cd please");
118       goto free_end;
119     }
120 
121   //choose random audio track
122   do
123     {
124       do
125 	{
126 	  f = ((float)rand()) / ((float)RAND_MAX + 1.0);
127 	  track = (int)(cd_id->numtracks  * f);
128 	}
129       while(!track_bools[track]);
130 
131       lastTrack = track+1;
132 
133       cd_stat=SDL_CDStatus(cd_id);
134 
135       if(!cdValid)
136 	{
137 	  if(!CD_INDRIVE(cd_stat) ||(!cd_id->numtracks))
138 	    {
139 	      goto free_end;
140 	    }
141 	  cdValid = true;
142 	}
143 
144       if(cd_stat == CD_PLAYING)
145 	{
146 	  if(cd_id->cur_track == track + 1)
147 	    {
148 	      goto free_end;
149 	    }
150 	  CDAudio_Stop();
151 	}
152 
153       if (SDL_CDPlay(cd_id,cd_id->track[track].offset,
154 		     cd_id->track[track].length))
155 	{
156 	  track_bools[track] = 0;
157 	  free_tracks--;
158 	}
159       else
160 	{
161 	  playLooping = true;
162 	  break;
163 	}
164     }
165   while (free_tracks > 0);
166 
167  free_end:
168   free((void*)track_bools);
169 }
170 
CDAudio_Stop()171 void CDAudio_Stop()
172 {
173 	int cdstate;
174 	if(!cd_id || !enabled) return;
175 	cdstate = SDL_CDStatus(cd_id);
176 	if((cdstate != CD_PLAYING) && (cdstate != CD_PAUSED)) return;
177 
178 	if(SDL_CDStop(cd_id))
179 		Con_DPrintf("CDAudio_Stop: Failed to stop track.\n");
180 
181 	playLooping = 0;
182 }
183 
CDAudio_Pause()184 void CDAudio_Pause()
185 {
186 	if(!cd_id || !enabled) return;
187 	if(SDL_CDStatus(cd_id) != CD_PLAYING) return;
188 
189 	if(SDL_CDPause(cd_id))
190 		Con_DPrintf("CDAudio_Pause: Failed to pause track.\n");
191 }
192 
193 
CDAudio_Resume()194 void CDAudio_Resume()
195 {
196 	if(!cd_id || !enabled) return;
197 	if(SDL_CDStatus(cd_id) != CD_PAUSED) return;
198 
199 	if(SDL_CDResume(cd_id))
200 		Con_DPrintf("CDAudio_Resume: Failed to resume track.\n");
201 }
202 
203 
CDAudio_Update()204 void CDAudio_Update()
205 {
206 	if(!cd_id || !enabled) return;
207 	if(bgmvolume.value != cdvolume)
208 	{
209 		if(cdvolume)
210 		{
211 			Cvar_SetValue("bgmvolume",0.0);
212 			CDAudio_Pause();
213 		}
214 		else
215 		{
216 			Cvar_SetValue("bgmvolume",1.0);
217 			CDAudio_Resume();
218 		}
219 		cdvolume = bgmvolume.value;
220 		return;
221 	}
222 	if(playLooping && (SDL_CDStatus(cd_id) != CD_PLAYING)
223 		 && (SDL_CDStatus(cd_id) != CD_PAUSED))
224 		CDAudio_Play(cd_id->cur_track+1,true);
225 }
226 
CDAudio_Init()227 int CDAudio_Init()
228 {
229 
230 	if (initialized)
231 		return 0;
232 
233 	if((cls.state == ca_dedicated) || COM_CheckParm("-nocdaudio"))
234 		return -1;
235 
236 	if (SDL_WasInit(SDL_INIT_EVERYTHING) == 0) {
237 		if (SDL_Init(SDL_INIT_CDROM) < 0) {
238 			Con_Printf ("Couldn't init SDL cdrom: %s\n", SDL_GetError ());
239 			return -1;
240 		}
241 	} else if (SDL_WasInit(SDL_INIT_CDROM) == 0) {
242 		if (SDL_InitSubSystem(SDL_INIT_CDROM) < 0) {
243 			Con_Printf ("Couldn't init SDL cdrom: %s\n", SDL_GetError ());
244 			return -1;
245 		}
246 	}
247 
248 	cd_id = SDL_CDOpen(0);
249 	if(!cd_id)
250 	{
251 		Con_Printf("CDAudio_Init: Unable to open default CD-ROM drive: %s\n",
252 			SDL_GetError());
253 		return -1;
254 	}
255 
256 	initialized = true;
257 	enabled = true;
258 	cdValid = true;
259 
260 	if(!CD_INDRIVE(SDL_CDStatus(cd_id)))
261 	{
262 		Con_Printf("CDAudio_Init: No CD in drive.\n");
263 		cdValid = false;
264 	}
265 	if(!cd_id->numtracks)
266 	{
267 		Con_Printf("CDAudio_Init: CD contains no audio tracks.\n");
268 		cdValid = false;
269 	}
270 	Cmd_AddCommand("cd",CD_f);
271 	Con_Printf("CD Audio Initialized.\n");
272 	return 0;
273 }
274 
275 
CDAudio_Shutdown()276 void CDAudio_Shutdown()
277 {
278 	if(!cd_id) return;
279 	CDAudio_Stop();
280 	SDL_CDClose(cd_id);
281 	cd_id = NULL;
282 
283 	if (SDL_WasInit(SDL_INIT_EVERYTHING) == SDL_INIT_CDROM)
284 		SDL_Quit();
285 	else
286 		SDL_QuitSubSystem(SDL_INIT_CDROM);
287 
288 	initialized = false;
289 }
290 
CD_f()291 static void CD_f()
292 {
293 	char *command;
294 	int cdstate;
295 	if(Cmd_Argc() < 2) return;
296 
297 	command = Cmd_Argv(1);
298 	if(!Q_strcasecmp(command,"on"))
299 	{
300 		enabled = true;
301 	}
302 	if(!Q_strcasecmp(command,"off"))
303 	{
304 		if(!cd_id) return;
305 		cdstate = SDL_CDStatus(cd_id);
306 		if((cdstate == CD_PLAYING) || (cdstate == CD_PAUSED))
307 			CDAudio_Stop();
308 		enabled = false;
309 		return;
310 	}
311 	if(!Q_strcasecmp(command,"play"))
312 	{
313 		CDAudio_Play((byte)atoi(Cmd_Argv(2)),false);
314 		return;
315 	}
316 	if(!Q_strcasecmp(command,"loop"))
317 	{
318 		CDAudio_Play((byte)atoi(Cmd_Argv(2)),true);
319 		return;
320 	}
321 	if(!Q_strcasecmp(command,"stop"))
322 	{
323 		CDAudio_Stop();
324 		return;
325 	}
326 	if(!Q_strcasecmp(command,"pause"))
327 	{
328 		CDAudio_Pause();
329 		return;
330 	}
331 	if(!Q_strcasecmp(command,"resume"))
332 	{
333 		CDAudio_Resume();
334 		return;
335 	}
336 	if(!Q_strcasecmp(command,"eject"))
337 	{
338 		CDAudio_Eject();
339 		return;
340 	}
341 	if(!Q_strcasecmp(command,"random"))
342 	{
343 		CDAudio_RandomPlay();
344 		return;
345 	}
346 	if(!Q_strcasecmp(command,"info"))
347 	{
348 		if(!cd_id) return;
349 		cdstate = SDL_CDStatus(cd_id);
350 		Con_Printf("%d tracks\n",cd_id->numtracks);
351 		if(cdstate == CD_PLAYING)
352 			Con_Printf("Currently %s track %d\n",
353 				playLooping ? "looping" : "playing",
354 				cd_id->cur_track+1);
355 		else
356 		if(cdstate == CD_PAUSED)
357 			Con_Printf("Paused %s track %d\n",
358 				playLooping ? "looping" : "playing",
359 				cd_id->cur_track+1);
360 		return;
361 	}
362 }
363 
CDAudio_Activate(qboolean active)364 void CDAudio_Activate (qboolean active)
365 {
366 	if (active)
367 		CDAudio_Resume ();
368 	else
369 		CDAudio_Pause ();
370 }
371 
372