|
|
1.1 root 1: // Quake is a trademark of Id Software, Inc., (c) 1996 Id Software, Inc. All
2: // rights reserved.
3:
4: #include <stdio.h>
5: #include <unistd.h>
6: #include <stdlib.h>
7: #include <sys/ioctl.h>
8: #include <sys/file.h>
9: #include <sys/types.h>
10: #include <fcntl.h>
11: #include <string.h>
12: #include <time.h>
13: #include <errno.h>
14:
15: #include <linux/cdrom.h>
16:
17: #include "../client/client.h"
18:
19: static qboolean cdValid = false;
20: static qboolean playing = false;
21: static qboolean wasPlaying = false;
22: static qboolean initialized = false;
23: static qboolean enabled = true;
24: static qboolean playLooping = false;
25: static float cdvolume;
26: static byte remap[100];
27: static byte playTrack;
28: static byte maxTrack;
29:
30: static int cdfile = -1;
31:
32: //static char cd_dev[64] = "/dev/cdrom";
33:
34: cvar_t *cd_volume;
35: cvar_t *cd_nocd;
36: cvar_t *cd_dev;
37:
38: void CDAudio_Pause(void);
39:
40: static void CDAudio_Eject(void)
41: {
42: if (cdfile == -1 || !enabled)
43: return; // no cd init'd
44:
45: if ( ioctl(cdfile, CDROMEJECT) == -1 )
46: Com_DPrintf("ioctl cdromeject failed\n");
47: }
48:
49:
50: static void CDAudio_CloseDoor(void)
51: {
52: if (cdfile == -1 || !enabled)
53: return; // no cd init'd
54:
55: if ( ioctl(cdfile, CDROMCLOSETRAY) == -1 )
56: Com_DPrintf("ioctl cdromclosetray failed\n");
57: }
58:
59: static int CDAudio_GetAudioDiskInfo(void)
60: {
61: struct cdrom_tochdr tochdr;
62:
63: cdValid = false;
64:
65: if ( ioctl(cdfile, CDROMREADTOCHDR, &tochdr) == -1 )
66: {
67: Com_DPrintf("ioctl cdromreadtochdr failed\n");
68: return -1;
69: }
70:
71: if (tochdr.cdth_trk0 < 1)
72: {
73: Com_DPrintf("CDAudio: no music tracks\n");
74: return -1;
75: }
76:
77: cdValid = true;
78: maxTrack = tochdr.cdth_trk1;
79:
80: return 0;
81: }
82:
83:
84: void CDAudio_Play(int track, qboolean looping)
85: {
86: struct cdrom_tocentry entry;
87: struct cdrom_ti ti;
88:
89: if (cdfile == -1 || !enabled)
90: return;
91:
92: if (!cdValid)
93: {
94: CDAudio_GetAudioDiskInfo();
95: if (!cdValid)
96: return;
97: }
98:
99: track = remap[track];
100:
101: if (track < 1 || track > maxTrack)
102: {
103: Com_DPrintf("CDAudio: Bad track number %u.\n", track);
104: return;
105: }
106:
107: // don't try to play a non-audio track
108: entry.cdte_track = track;
109: entry.cdte_format = CDROM_MSF;
110: if ( ioctl(cdfile, CDROMREADTOCENTRY, &entry) == -1 )
111: {
112: Com_DPrintf("ioctl cdromreadtocentry failed\n");
113: return;
114: }
115: if (entry.cdte_ctrl == CDROM_DATA_TRACK)
116: {
117: Com_Printf("CDAudio: track %i is not audio\n", track);
118: return;
119: }
120:
121: if (playing)
122: {
123: if (playTrack == track)
124: return;
125: CDAudio_Stop();
126: }
127:
128: ti.cdti_trk0 = track;
129: ti.cdti_trk1 = track;
130: ti.cdti_ind0 = 1;
131: ti.cdti_ind1 = 99;
132:
133: if ( ioctl(cdfile, CDROMPLAYTRKIND, &ti) == -1 )
134: {
135: Com_DPrintf("ioctl cdromplaytrkind failed\n");
136: return;
137: }
138:
139: if ( ioctl(cdfile, CDROMRESUME) == -1 )
140: Com_DPrintf("ioctl cdromresume failed\n");
141:
142: playLooping = looping;
143: playTrack = track;
144: playing = true;
145:
146: if (cd_volume->value == 0.0)
147: CDAudio_Pause ();
148: }
149:
150:
151: void CDAudio_Stop(void)
152: {
153: if (cdfile == -1 || !enabled)
154: return;
155:
156: if (!playing)
157: return;
158:
159: if ( ioctl(cdfile, CDROMSTOP) == -1 )
160: Com_DPrintf("ioctl cdromstop failed (%d)\n", errno);
161:
162: wasPlaying = false;
163: playing = false;
164: }
165:
166: void CDAudio_Pause(void)
167: {
168: if (cdfile == -1 || !enabled)
169: return;
170:
171: if (!playing)
172: return;
173:
174: if ( ioctl(cdfile, CDROMPAUSE) == -1 )
175: Com_DPrintf("ioctl cdrompause failed\n");
176:
177: wasPlaying = playing;
178: playing = false;
179: }
180:
181:
182: void CDAudio_Resume(void)
183: {
184: if (cdfile == -1 || !enabled)
185: return;
186:
187: if (!cdValid)
188: return;
189:
190: if (!wasPlaying)
191: return;
192:
193: if ( ioctl(cdfile, CDROMRESUME) == -1 )
194: Com_DPrintf("ioctl cdromresume failed\n");
195: playing = true;
196: }
197:
198: static void CD_f (void)
199: {
200: char *command;
201: int ret;
202: int n;
203:
204: if (Cmd_Argc() < 2)
205: return;
206:
207: command = Cmd_Argv (1);
208:
209: if (Q_strcasecmp(command, "on") == 0)
210: {
211: enabled = true;
212: return;
213: }
214:
215: if (Q_strcasecmp(command, "off") == 0)
216: {
217: if (playing)
218: CDAudio_Stop();
219: enabled = false;
220: return;
221: }
222:
223: if (Q_strcasecmp(command, "reset") == 0)
224: {
225: enabled = true;
226: if (playing)
227: CDAudio_Stop();
228: for (n = 0; n < 100; n++)
229: remap[n] = n;
230: CDAudio_GetAudioDiskInfo();
231: return;
232: }
233:
234: if (Q_strcasecmp(command, "remap") == 0)
235: {
236: ret = Cmd_Argc() - 2;
237: if (ret <= 0)
238: {
239: for (n = 1; n < 100; n++)
240: if (remap[n] != n)
241: Com_Printf(" %u -> %u\n", n, remap[n]);
242: return;
243: }
244: for (n = 1; n <= ret; n++)
245: remap[n] = atoi(Cmd_Argv (n+1));
246: return;
247: }
248:
249: if (Q_strcasecmp(command, "close") == 0)
250: {
251: CDAudio_CloseDoor();
252: return;
253: }
254:
255: if (!cdValid)
256: {
257: CDAudio_GetAudioDiskInfo();
258: if (!cdValid)
259: {
260: Com_Printf("No CD in player.\n");
261: return;
262: }
263: }
264:
265: if (Q_strcasecmp(command, "play") == 0)
266: {
267: CDAudio_Play((byte)atoi(Cmd_Argv (2)), false);
268: return;
269: }
270:
271: if (Q_strcasecmp(command, "loop") == 0)
272: {
273: CDAudio_Play((byte)atoi(Cmd_Argv (2)), true);
274: return;
275: }
276:
277: if (Q_strcasecmp(command, "stop") == 0)
278: {
279: CDAudio_Stop();
280: return;
281: }
282:
283: if (Q_strcasecmp(command, "pause") == 0)
284: {
285: CDAudio_Pause();
286: return;
287: }
288:
289: if (Q_strcasecmp(command, "resume") == 0)
290: {
291: CDAudio_Resume();
292: return;
293: }
294:
295: if (Q_strcasecmp(command, "eject") == 0)
296: {
297: if (playing)
298: CDAudio_Stop();
299: CDAudio_Eject();
300: cdValid = false;
301: return;
302: }
303:
304: if (Q_strcasecmp(command, "info") == 0)
305: {
306: Com_Printf("%u tracks\n", maxTrack);
307: if (playing)
308: Com_Printf("Currently %s track %u\n", playLooping ? "looping" : "playing", playTrack);
309: else if (wasPlaying)
310: Com_Printf("Paused %s track %u\n", playLooping ? "looping" : "playing", playTrack);
311: Com_Printf("Volume is %f\n", cdvolume);
312: return;
313: }
314: }
315:
316: void CDAudio_Update(void)
317: {
318: struct cdrom_subchnl subchnl;
319: static time_t lastchk;
320:
321: if (cdfile == -1 || !enabled)
322: return;
323:
324: if (cd_volume && cd_volume->value != cdvolume)
325: {
326: if (cdvolume)
327: {
328: Cvar_SetValue ("cd_volume", 0.0);
329: cdvolume = cd_volume->value;
330: CDAudio_Pause ();
331: }
332: else
333: {
334: Cvar_SetValue ("cd_volume", 1.0);
335: cdvolume = cd_volume->value;
336: CDAudio_Resume ();
337: }
338: }
339:
340: if (playing && lastchk < time(NULL)) {
341: lastchk = time(NULL) + 2; //two seconds between chks
342: subchnl.cdsc_format = CDROM_MSF;
343: if (ioctl(cdfile, CDROMSUBCHNL, &subchnl) == -1 ) {
344: Com_DPrintf("ioctl cdromsubchnl failed\n");
345: playing = false;
346: return;
347: }
348: if (subchnl.cdsc_audiostatus != CDROM_AUDIO_PLAY &&
349: subchnl.cdsc_audiostatus != CDROM_AUDIO_PAUSED) {
350: playing = false;
351: if (playLooping)
352: CDAudio_Play(playTrack, true);
353: }
354: }
355: }
356:
357: int CDAudio_Init(void)
358: {
359: int i;
360: cvar_t *cv;
361: extern uid_t saved_euid;
362:
363: cv = Cvar_Get ("nocdaudio", "0", CVAR_NOSET);
364: if (cv->value)
365: return -1;
366:
367: cd_nocd = Cvar_Get ("cd_nocd", "0", CVAR_ARCHIVE );
368: if ( cd_nocd->value)
369: return -1;
370:
371: cd_volume = Cvar_Get ("cd_volume", "1", CVAR_ARCHIVE);
372:
373: cd_dev = Cvar_Get("cd_dev", "/dev/cdrom", CVAR_ARCHIVE);
374:
375: seteuid(saved_euid);
376:
377: cdfile = open(cd_dev->string, O_RDONLY);
378:
379: seteuid(getuid());
380:
381: if (cdfile == -1) {
382: Com_Printf("CDAudio_Init: open of \"%s\" failed (%i)\n", cd_dev->string, errno);
383: cdfile = -1;
384: return -1;
385: }
386:
387: for (i = 0; i < 100; i++)
388: remap[i] = i;
389: initialized = true;
390: enabled = true;
391:
392: if (CDAudio_GetAudioDiskInfo())
393: {
394: Com_Printf("CDAudio_Init: No CD in player.\n");
395: cdValid = false;
396: }
397:
398: Cmd_AddCommand ("cd", CD_f);
399:
400: Com_Printf("CD Audio Initialized\n");
401:
402: return 0;
403: }
404:
405: void CDAudio_Activate (qboolean active)
406: {
407: if (active)
408: CDAudio_Resume ();
409: else
410: CDAudio_Pause ();
411: }
412:
413: void CDAudio_Shutdown(void)
414: {
415: if (!initialized)
416: return;
417: CDAudio_Stop();
418: close(cdfile);
419: cdfile = -1;
420: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.