]> de.git.xonotic.org Git - xonotic/darkplaces.git/blob - cd_shared.c
9cedbac1e8fae162c40914d567fbb47502f9ca3a
[xonotic/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 #include "cdaudio.h"
25 #include "snd_main.h"
26
27 #define MAXTRACKS       256
28
29 // Prototypes of the system dependent functions
30 extern void CDAudio_SysEject (void);
31 extern void CDAudio_SysCloseDoor (void);
32 extern int CDAudio_SysGetAudioDiskInfo (void);
33 extern float CDAudio_SysGetVolume (void);
34 extern void CDAudio_SysSetVolume (float volume);
35 extern int CDAudio_SysPlay (qbyte track);
36 extern int CDAudio_SysStop (void);
37 extern int CDAudio_SysPause (void);
38 extern int CDAudio_SysResume (void);
39 extern int CDAudio_SysUpdate (void);
40 extern void CDAudio_SysInit (void);
41 extern int CDAudio_SysStartup (void);
42 extern void CDAudio_SysShutdown (void);
43
44 // used by menu to ghost CD audio slider
45 cvar_t  cdaudioinitialized = {CVAR_READONLY,"cdaudioinitialized","0"};
46
47 static qboolean wasPlaying = false;
48 static qboolean initialized = false;
49 static qboolean enabled = false;
50 static float cdvolume;
51 static qbyte remap[MAXTRACKS];
52 static qbyte maxTrack;
53 static int faketrack = -1;
54
55 static float saved_vol = 1.0f;
56
57 // exported variables
58 qboolean cdValid = false;
59 qboolean cdPlaying = false;
60 qboolean cdPlayLooping = false;
61 qbyte cdPlayTrack;
62
63
64 static void CDAudio_Eject (void)
65 {
66         if (!enabled)
67                 return;
68
69         CDAudio_SysEject();
70 }
71
72
73 static void CDAudio_CloseDoor (void)
74 {
75         if (!enabled)
76                 return;
77
78         CDAudio_SysCloseDoor();
79 }
80
81 static int CDAudio_GetAudioDiskInfo (void)
82 {
83         int ret;
84
85         cdValid = false;
86
87         ret = CDAudio_SysGetAudioDiskInfo();
88         if (ret < 1)
89                 return -1;
90
91         cdValid = true;
92         maxTrack = ret;
93
94         return 0;
95 }
96
97
98 void CDAudio_Play (qbyte track, qboolean looping)
99 {
100         sfx_t* sfx;
101
102         if (!enabled)
103                 return;
104
105         track = remap[track];
106         if (track < 1)
107         {
108                 Con_DPrintf("CDAudio: Bad track number %u.\n", track);
109                 return;
110         }
111
112         if (cdPlaying && cdPlayTrack == track && faketrack == -1)
113                 return;
114         CDAudio_Stop ();
115
116         // Try playing a fake track (sound file) first
117         sfx = S_PrecacheSound (va ("cdtracks/track%02u.wav", track), false, false);
118         // FIXME: perhaps force it to be always %03u (but for compatibility?):
119         if (sfx == NULL || sfx->fetcher == NULL)
120                 sfx = S_PrecacheSound (va ("cdtracks/track%03u.wav", track), false, false);
121         if (sfx != NULL)
122         {
123                 faketrack = S_StartSound (-1, 0, sfx, vec3_origin, cdvolume, 0);
124                 if (faketrack != -1)
125                 {
126                         if (looping)
127                                 S_SetChannelFlag (faketrack, CHANNELFLAG_FORCELOOP, true);
128                         S_SetChannelFlag (faketrack, CHANNELFLAG_FULLVOLUME, true);
129                         Con_DPrintf ("Fake CD track %u playing...\n", track);
130                 }
131         }
132
133         // If we can't play a fake CD track, try the real one
134         if (faketrack == -1)
135         {
136                 if (!cdValid)
137                 {
138                         CDAudio_GetAudioDiskInfo();
139                         if (!cdValid)
140                         {
141                                 Con_Print ("No CD in player.\n");
142                                 return;
143                         }
144                 }
145
146                 if (track > maxTrack)
147                 {
148                         Con_Printf("CDAudio: Bad track number %u.\n", track);
149                         return;
150                 }
151
152                 if (CDAudio_SysPlay(track) == -1)
153                         return;
154         }
155
156         cdPlayLooping = looping;
157         cdPlayTrack = track;
158         cdPlaying = true;
159
160         if (cdvolume == 0.0)
161                 CDAudio_Pause ();
162 }
163
164
165 void CDAudio_Stop (void)
166 {
167         if (!enabled || !cdPlaying)
168                 return;
169
170         if (faketrack != -1)
171         {
172                 S_StopChannel (faketrack);
173                 faketrack = -1;
174         }
175         else if (CDAudio_SysStop() == -1)
176                 return;
177
178         wasPlaying = false;
179         cdPlaying = false;
180 }
181
182 void CDAudio_Pause (void)
183 {
184         if (!enabled || !cdPlaying)
185                 return;
186
187         if (faketrack != -1)
188                 S_SetChannelFlag (faketrack, CHANNELFLAG_PAUSED, true);
189         else if (CDAudio_SysPause() == -1)
190                 return;
191
192         wasPlaying = cdPlaying;
193         cdPlaying = false;
194 }
195
196
197 void CDAudio_Resume (void)
198 {
199         if (!enabled || cdPlaying || !wasPlaying)
200                 return;
201
202         if (faketrack != -1)
203                 S_SetChannelFlag (faketrack, CHANNELFLAG_PAUSED, false);
204         else if (CDAudio_SysResume() == -1)
205                 return;
206         cdPlaying = true;
207 }
208
209 static void CD_f (void)
210 {
211         const char *command;
212         int ret;
213         int n;
214
215         if (Cmd_Argc() < 2)
216                 return;
217
218         command = Cmd_Argv (1);
219
220         if (strcasecmp(command, "on") == 0)
221         {
222                 enabled = true;
223                 return;
224         }
225
226         if (strcasecmp(command, "off") == 0)
227         {
228                 if (cdPlaying)
229                         CDAudio_Stop();
230                 enabled = false;
231                 return;
232         }
233
234         if (strcasecmp(command, "reset") == 0)
235         {
236                 enabled = true;
237                 if (cdPlaying)
238                         CDAudio_Stop();
239                 for (n = 0; n < MAXTRACKS; n++)
240                         remap[n] = n;
241                 CDAudio_GetAudioDiskInfo();
242                 return;
243         }
244
245         if (strcasecmp(command, "remap") == 0)
246         {
247                 ret = Cmd_Argc() - 2;
248                 if (ret <= 0)
249                 {
250                         for (n = 1; n < MAXTRACKS; n++)
251                                 if (remap[n] != n)
252                                         Con_Printf("  %u -> %u\n", n, remap[n]);
253                         return;
254                 }
255                 for (n = 1; n <= ret; n++)
256                         remap[n] = atoi(Cmd_Argv (n+1));
257                 return;
258         }
259
260         if (strcasecmp(command, "close") == 0)
261         {
262                 CDAudio_CloseDoor();
263                 return;
264         }
265
266         if (strcasecmp(command, "play") == 0)
267         {
268                 CDAudio_Play((qbyte)atoi(Cmd_Argv (2)), false);
269                 return;
270         }
271
272         if (strcasecmp(command, "loop") == 0)
273         {
274                 CDAudio_Play((qbyte)atoi(Cmd_Argv (2)), true);
275                 return;
276         }
277
278         if (strcasecmp(command, "stop") == 0)
279         {
280                 CDAudio_Stop();
281                 return;
282         }
283
284         if (strcasecmp(command, "pause") == 0)
285         {
286                 CDAudio_Pause();
287                 return;
288         }
289
290         if (strcasecmp(command, "resume") == 0)
291         {
292                 CDAudio_Resume();
293                 return;
294         }
295
296         if (strcasecmp(command, "eject") == 0)
297         {
298                 if (cdPlaying && faketrack == -1)
299                         CDAudio_Stop();
300                 CDAudio_Eject();
301                 cdValid = false;
302                 return;
303         }
304
305         if (strcasecmp(command, "info") == 0)
306         {
307                 CDAudio_GetAudioDiskInfo ();
308                 if (cdValid)
309                         Con_Printf("%u tracks on CD.\n", maxTrack);
310                 else
311                         Con_Print ("No CD in player.\n");
312                 if (cdPlaying)
313                         Con_Printf("Currently %s track %u\n", cdPlayLooping ? "looping" : "playing", cdPlayTrack);
314                 else if (wasPlaying)
315                         Con_Printf("Paused %s track %u\n", cdPlayLooping ? "looping" : "playing", cdPlayTrack);
316                 Con_Printf("Volume is %f\n", cdvolume);
317                 return;
318         }
319 }
320
321 void CDAudio_SetVolume (float newvol)
322 {
323         // If the volume hasn't changed
324         if (newvol == cdvolume)
325                 return;
326
327         // If the CD has been muted
328         if (newvol == 0.0f)
329                 CDAudio_Pause ();
330         else
331         {
332                 // If the CD has been unmuted
333                 if (cdvolume == 0.0f)
334                         CDAudio_Resume ();
335
336                 if (faketrack != -1)
337                         S_SetChannelVolume (faketrack, newvol);
338                 CDAudio_SysSetVolume (newvol);
339         }
340
341         cdvolume = newvol;
342 }
343
344 void CDAudio_Update (void)
345 {
346         if (!enabled)
347                 return;
348
349         CDAudio_SetVolume (bgmvolume.value);
350
351         if (faketrack == -1)
352                 CDAudio_SysUpdate();
353 }
354
355 int CDAudio_Init (void)
356 {
357         int i;
358
359         if (cls.state == ca_dedicated)
360                 return -1;
361
362 // COMMANDLINEOPTION: Sound: -nocdaudio disables CD audio support
363         if (COM_CheckParm("-nocdaudio") || COM_CheckParm("-safe"))
364                 return -1;
365
366         CDAudio_SysInit();
367
368         for (i = 0; i < MAXTRACKS; i++)
369                 remap[i] = i;
370
371         Cvar_RegisterVariable(&cdaudioinitialized);
372         Cvar_SetValueQuick(&cdaudioinitialized, true);
373         enabled = true;
374
375         Cmd_AddCommand("cd", CD_f);
376
377         return 0;
378 }
379
380 int CDAudio_Startup (void)
381 {
382         CDAudio_SysStartup ();
383
384         if (CDAudio_GetAudioDiskInfo())
385         {
386                 Con_DPrint("CDAudio_Init: No CD in player.\n");
387                 cdValid = false;
388         }
389
390         saved_vol = CDAudio_SysGetVolume ();
391         if (saved_vol < 0.0f)
392         {
393                 Con_DPrint ("Can't get initial CD volume\n");
394                 saved_vol = 1.0f;
395         }
396         else
397                 Con_DPrintf ("Initial CD volume: %g\n", saved_vol);
398
399         initialized = true;
400
401         Con_DPrint("CD Audio Initialized\n");
402
403         return 0;
404 }
405
406 void CDAudio_Shutdown (void)
407 {
408         if (!initialized)
409                 return;
410
411         CDAudio_SysSetVolume (saved_vol);
412
413         CDAudio_Stop();
414         CDAudio_SysShutdown();
415         initialized = false;
416 }