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