Fake CD tracks support; DP now tries to play "sound/cdtracks/trackXX.wav" instead...
[divverent/darkplaces.git] / cd_shared.c
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19 */
20 // Quake is a trademark of Id Software, Inc., (c) 1996 Id Software, Inc. All
21 // rights reserved.
22
23 #include "quakedef.h"
24
25 // Prototypes of the system dependent functions
26 extern void CDAudio_SysEject (void);
27 extern void CDAudio_SysCloseDoor (void);
28 extern int CDAudio_SysGetAudioDiskInfo (void);
29 extern int CDAudio_SysPlay (qbyte track);
30 extern int CDAudio_SysStop (void);
31 extern int CDAudio_SysPause (void);
32 extern int CDAudio_SysResume (void);
33 extern int CDAudio_SysUpdate (void);
34 extern void CDAudio_SysInit (void);
35 extern int CDAudio_SysStartup (void);
36 extern void CDAudio_SysShutdown (void);
37
38 // used by menu to ghost CD audio slider
39 cvar_t  cdaudioinitialized = {CVAR_READONLY,"cdaudioinitialized","0"};
40
41 static qboolean wasPlaying = false;
42 static qboolean initialized = false;
43 static qboolean enabled = false;
44 static float cdvolume;
45 static qbyte remap[100];
46 static qbyte maxTrack;
47 static int faketrack = -1;
48
49 // exported variables
50 qboolean cdValid = false;
51 qboolean cdPlaying = false;
52 qboolean cdPlayLooping = false;
53 qbyte cdPlayTrack;
54
55
56 static void CDAudio_Eject (void)
57 {
58         if (!enabled)
59                 return;
60
61         CDAudio_SysEject();
62 }
63
64
65 static void CDAudio_CloseDoor (void)
66 {
67         if (!enabled)
68                 return;
69
70         CDAudio_SysCloseDoor();
71 }
72
73 static int CDAudio_GetAudioDiskInfo (void)
74 {
75         int ret;
76
77         cdValid = false;
78
79         ret = CDAudio_SysGetAudioDiskInfo();
80         if (ret < 1)
81                 return -1;
82
83         cdValid = true;
84         maxTrack = ret;
85
86         return 0;
87 }
88
89
90 void CDAudio_Play (qbyte track, qboolean looping)
91 {
92         sfx_t* sfx;
93
94         if (!enabled)
95                 return;
96
97         track = remap[track];
98         if (track < 1)
99         {
100                 Con_DPrintf("CDAudio: Bad track number %u.\n", track);
101                 return;
102         }
103
104         if (cdPlaying && cdPlayTrack == track)
105                 return;
106         CDAudio_Stop ();
107
108         // Try playing a fake track (sound file) first
109         sfx = S_PrecacheSound (va ("cdtracks/track%02u.wav", track), false);
110         if (sfx != NULL)
111         {
112                 faketrack = S_StartSound (-1, 0, sfx, vec3_origin, 1, 0);
113                 if (faketrack != -1)
114                 {
115                         if (looping)
116                         S_LoopChannel (faketrack, true);
117                         Con_DPrintf ("Fake CD track %u playing...\n", track);
118                 }
119         }
120
121         // If we can't play a fake CD track, try the real one
122         if (faketrack == -1)
123         {
124                 if (!cdValid)
125                 {
126                         CDAudio_GetAudioDiskInfo();
127                         if (!cdValid)
128                         {
129                                 Con_Print ("No CD in player.\n");
130                                 return;
131                         }
132                 }
133
134                 if (track > maxTrack)
135                 {
136                         Con_DPrintf("CDAudio: Bad track number %u.\n", track);
137                         return;
138                 }
139
140                 if (CDAudio_SysPlay(track) == -1)
141                         return;
142         }
143
144         cdPlayLooping = looping;
145         cdPlayTrack = track;
146         cdPlaying = true;
147
148         if (cdvolume == 0.0)
149                 CDAudio_Pause ();
150 }
151
152
153 void CDAudio_Stop (void)
154 {
155         if (!enabled || !cdPlaying)
156                 return;
157
158         if (faketrack != -1)
159         {
160                 S_StopChannel (faketrack);
161                 faketrack = -1;
162         }
163         else if (CDAudio_SysStop() == -1)
164                 return;
165
166         wasPlaying = false;
167         cdPlaying = false;
168 }
169
170 void CDAudio_Pause (void)
171 {
172         if (!enabled || !cdPlaying)
173                 return;
174
175         if (faketrack != -1)
176                 S_PauseChannel (faketrack, true);
177         else if (CDAudio_SysPause() == -1)
178                 return;
179
180         wasPlaying = cdPlaying;
181         cdPlaying = false;
182 }
183
184
185 void CDAudio_Resume (void)
186 {
187         if (!enabled || !wasPlaying)
188                 return;
189
190         if (faketrack != -1)
191                 S_PauseChannel (faketrack, false);
192         else if (CDAudio_SysResume() == -1)
193                 return;
194         cdPlaying = true;
195 }
196
197 static void CD_f (void)
198 {
199         const char *command;
200         int ret;
201         int n;
202
203         if (Cmd_Argc() < 2)
204                 return;
205
206         command = Cmd_Argv (1);
207
208         if (strcasecmp(command, "on") == 0)
209         {
210                 enabled = true;
211                 return;
212         }
213
214         if (strcasecmp(command, "off") == 0)
215         {
216                 if (cdPlaying)
217                         CDAudio_Stop();
218                 enabled = false;
219                 return;
220         }
221
222         if (strcasecmp(command, "reset") == 0)
223         {
224                 enabled = true;
225                 if (cdPlaying)
226                         CDAudio_Stop();
227                 for (n = 0; n < 100; n++)
228                         remap[n] = n;
229                 CDAudio_GetAudioDiskInfo();
230                 return;
231         }
232
233         if (strcasecmp(command, "remap") == 0)
234         {
235                 ret = Cmd_Argc() - 2;
236                 if (ret <= 0)
237                 {
238                         for (n = 1; n < 100; n++)
239                                 if (remap[n] != n)
240                                         Con_Printf("  %u -> %u\n", n, remap[n]);
241                         return;
242                 }
243                 for (n = 1; n <= ret; n++)
244                         remap[n] = atoi(Cmd_Argv (n+1));
245                 return;
246         }
247
248         if (strcasecmp(command, "close") == 0)
249         {
250                 CDAudio_CloseDoor();
251                 return;
252         }
253
254         if (strcasecmp(command, "play") == 0)
255         {
256                 CDAudio_Play((qbyte)atoi(Cmd_Argv (2)), false);
257                 return;
258         }
259
260         if (strcasecmp(command, "loop") == 0)
261         {
262                 CDAudio_Play((qbyte)atoi(Cmd_Argv (2)), true);
263                 return;
264         }
265
266         if (strcasecmp(command, "stop") == 0)
267         {
268                 CDAudio_Stop();
269                 return;
270         }
271
272         if (strcasecmp(command, "pause") == 0)
273         {
274                 CDAudio_Pause();
275                 return;
276         }
277
278         if (strcasecmp(command, "resume") == 0)
279         {
280                 CDAudio_Resume();
281                 return;
282         }
283
284         if (strcasecmp(command, "eject") == 0)
285         {
286                 if (cdPlaying && faketrack == -1)
287                         CDAudio_Stop();
288                 CDAudio_Eject();
289                 cdValid = false;
290                 return;
291         }
292
293         if (strcasecmp(command, "info") == 0)
294         {
295                 CDAudio_GetAudioDiskInfo ();
296                 if (cdValid)
297                         Con_Printf("%u tracks on CD.\n", maxTrack);
298                 else
299                         Con_Print ("No CD in player.\n");
300                 if (cdPlaying)
301                         Con_Printf("Currently %s track %u\n", cdPlayLooping ? "looping" : "playing", cdPlayTrack);
302                 else if (wasPlaying)
303                         Con_Printf("Paused %s track %u\n", cdPlayLooping ? "looping" : "playing", cdPlayTrack);
304                 Con_Printf("Volume is %f\n", cdvolume);
305                 return;
306         }
307 }
308
309 void CDAudio_Update (void)
310 {
311         if (!enabled)
312                 return;
313
314         if (bgmvolume.value != cdvolume)
315         {
316                 if (cdvolume)
317                 {
318                         Cvar_SetValueQuick (&bgmvolume, 0.0);
319                         cdvolume = bgmvolume.value;
320                         CDAudio_Pause ();
321                 }
322                 else
323                 {
324                         Cvar_SetValueQuick (&bgmvolume, 1.0);
325                         cdvolume = bgmvolume.value;
326                         CDAudio_Resume ();
327                 }
328         }
329
330         if (faketrack == -1)
331                 CDAudio_SysUpdate();
332 }
333
334 int CDAudio_Init (void)
335 {
336         int i;
337
338         if (cls.state == ca_dedicated)
339                 return -1;
340
341         if (COM_CheckParm("-nocdaudio") || COM_CheckParm("-safe"))
342                 return -1;
343
344         CDAudio_SysInit();
345
346         for (i = 0; i < 100; i++)
347                 remap[i] = i;
348
349         Cvar_RegisterVariable(&cdaudioinitialized);
350         Cvar_SetValueQuick(&cdaudioinitialized, true);
351         enabled = true;
352
353         Cmd_AddCommand("cd", CD_f);
354
355         return 0;
356 }
357
358 int CDAudio_Startup (void)
359 {
360         CDAudio_SysStartup ();
361
362         if (CDAudio_GetAudioDiskInfo())
363         {
364                 Con_DPrint("CDAudio_Init: No CD in player.\n");
365                 cdValid = false;
366         }
367
368         initialized = true;
369
370         Con_DPrint("CD Audio Initialized\n");
371
372         return 0;
373 }
374
375 void CDAudio_Shutdown (void)
376 {
377         if (!initialized)
378                 return;
379         CDAudio_Stop();
380         CDAudio_SysShutdown();
381         initialized = false;
382 }