|
|
1.1 root 1: // Quake is a trademark of Id Software, Inc., (c) 1996 Id Software, Inc. All
2: // rights reserved.
3:
4: #include <windows.h>
5: #include "../client/client.h"
6:
7: extern HWND cl_hwnd;
8:
9: static qboolean cdValid = false;
10: static qboolean playing = false;
11: static qboolean wasPlaying = false;
12: static qboolean initialized = false;
13: static qboolean enabled = false;
14: static qboolean playLooping = false;
15: static byte remap[100];
16: static byte cdrom;
17: static byte playTrack;
18: static byte maxTrack;
19:
20: cvar_t *cd_nocd;
21: cvar_t *cd_loopcount;
22: cvar_t *cd_looptrack;
23:
24: UINT wDeviceID;
25: int loopcounter;
26:
27:
28: void CDAudio_Pause(void);
29:
30: static void CDAudio_Eject(void)
31: {
32: DWORD dwReturn;
33:
34: if (dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, (DWORD)NULL))
35: Com_DPrintf("MCI_SET_DOOR_OPEN failed (%i)\n", dwReturn);
36: }
37:
38:
39: static void CDAudio_CloseDoor(void)
40: {
41: DWORD dwReturn;
42:
43: if (dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_DOOR_CLOSED, (DWORD)NULL))
44: Com_DPrintf("MCI_SET_DOOR_CLOSED failed (%i)\n", dwReturn);
45: }
46:
47:
48: static int CDAudio_GetAudioDiskInfo(void)
49: {
50: DWORD dwReturn;
51: MCI_STATUS_PARMS mciStatusParms;
52:
53:
54: cdValid = false;
55:
56: mciStatusParms.dwItem = MCI_STATUS_READY;
57: dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD) (LPVOID) &mciStatusParms);
58: if (dwReturn)
59: {
60: Com_DPrintf("CDAudio: drive ready test - get status failed\n");
61: return -1;
62: }
63: if (!mciStatusParms.dwReturn)
64: {
65: Com_DPrintf("CDAudio: drive not ready\n");
66: return -1;
67: }
68:
69: mciStatusParms.dwItem = MCI_STATUS_NUMBER_OF_TRACKS;
70: dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD) (LPVOID) &mciStatusParms);
71: if (dwReturn)
72: {
73: Com_DPrintf("CDAudio: get tracks - status failed\n");
74: return -1;
75: }
76: if (mciStatusParms.dwReturn < 1)
77: {
78: Com_DPrintf("CDAudio: no music tracks\n");
79: return -1;
80: }
81:
82: cdValid = true;
83: maxTrack = mciStatusParms.dwReturn;
84:
85: return 0;
86: }
87:
88:
89:
90: void CDAudio_Play2(int track, qboolean looping)
91: {
92: DWORD dwReturn;
93: MCI_PLAY_PARMS mciPlayParms;
94: MCI_STATUS_PARMS mciStatusParms;
95:
96: if (!enabled)
97: return;
98:
99: if (!cdValid)
100: {
101: CDAudio_GetAudioDiskInfo();
102: if (!cdValid)
103: return;
104: }
105:
106: track = remap[track];
107:
108: if (track < 1 || track > maxTrack)
109: {
110: CDAudio_Stop();
111: return;
112: }
113:
114: // don't try to play a non-audio track
115: mciStatusParms.dwItem = MCI_CDA_STATUS_TYPE_TRACK;
116: mciStatusParms.dwTrack = track;
117: dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD) (LPVOID) &mciStatusParms);
118: if (dwReturn)
119: {
120: Com_DPrintf("MCI_STATUS failed (%i)\n", dwReturn);
121: return;
122: }
123: if (mciStatusParms.dwReturn != MCI_CDA_TRACK_AUDIO)
124: {
125: Com_Printf("CDAudio: track %i is not audio\n", track);
126: return;
127: }
128:
129: // get the length of the track to be played
130: mciStatusParms.dwItem = MCI_STATUS_LENGTH;
131: mciStatusParms.dwTrack = track;
132: dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD) (LPVOID) &mciStatusParms);
133: if (dwReturn)
134: {
135: Com_DPrintf("MCI_STATUS failed (%i)\n", dwReturn);
136: return;
137: }
138:
139: if (playing)
140: {
141: if (playTrack == track)
142: return;
143: CDAudio_Stop();
144: }
145:
146: mciPlayParms.dwFrom = MCI_MAKE_TMSF(track, 0, 0, 0);
147: mciPlayParms.dwTo = (mciStatusParms.dwReturn << 8) | track;
148: mciPlayParms.dwCallback = (DWORD)cl_hwnd;
149: dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_NOTIFY | MCI_FROM | MCI_TO, (DWORD)(LPVOID) &mciPlayParms);
150: if (dwReturn)
151: {
152: Com_DPrintf("CDAudio: MCI_PLAY failed (%i)\n", dwReturn);
153: return;
154: }
155:
156: playLooping = looping;
157: playTrack = track;
158: playing = true;
159:
160: if ( Cvar_VariableValue( "cd_nocd" ) )
161: CDAudio_Pause ();
162: }
163:
164:
165: void CDAudio_Play(int track, qboolean looping)
166: {
167: // set a loop counter so that this track will change to the
168: // looptrack later
169: loopcounter = 0;
170: CDAudio_Play2(track, looping);
171: }
172:
173: void CDAudio_Stop(void)
174: {
175: DWORD dwReturn;
176:
177: if (!enabled)
178: return;
179:
180: if (!playing)
181: return;
182:
183: if (dwReturn = mciSendCommand(wDeviceID, MCI_STOP, 0, (DWORD)NULL))
184: Com_DPrintf("MCI_STOP failed (%i)", dwReturn);
185:
186: wasPlaying = false;
187: playing = false;
188: }
189:
190:
191: void CDAudio_Pause(void)
192: {
193: DWORD dwReturn;
194: MCI_GENERIC_PARMS mciGenericParms;
195:
196: if (!enabled)
197: return;
198:
199: if (!playing)
200: return;
201:
202: mciGenericParms.dwCallback = (DWORD)cl_hwnd;
203: if (dwReturn = mciSendCommand(wDeviceID, MCI_PAUSE, 0, (DWORD)(LPVOID) &mciGenericParms))
204: Com_DPrintf("MCI_PAUSE failed (%i)", dwReturn);
205:
206: wasPlaying = playing;
207: playing = false;
208: }
209:
210:
211: void CDAudio_Resume(void)
212: {
213: DWORD dwReturn;
214: MCI_PLAY_PARMS mciPlayParms;
215:
216: if (!enabled)
217: return;
218:
219: if (!cdValid)
220: return;
221:
222: if (!wasPlaying)
223: return;
224:
225: mciPlayParms.dwFrom = MCI_MAKE_TMSF(playTrack, 0, 0, 0);
226: mciPlayParms.dwTo = MCI_MAKE_TMSF(playTrack + 1, 0, 0, 0);
227: mciPlayParms.dwCallback = (DWORD)cl_hwnd;
228: dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_TO | MCI_NOTIFY, (DWORD)(LPVOID) &mciPlayParms);
229: if (dwReturn)
230: {
231: Com_DPrintf("CDAudio: MCI_PLAY failed (%i)\n", dwReturn);
232: return;
233: }
234: playing = true;
235: }
236:
237:
238: static void CD_f (void)
239: {
240: char *command;
241: int ret;
242: int n;
243:
244: if (Cmd_Argc() < 2)
245: return;
246:
247: command = Cmd_Argv (1);
248:
249: if (Q_strcasecmp(command, "on") == 0)
250: {
251: enabled = true;
252: return;
253: }
254:
255: if (Q_strcasecmp(command, "off") == 0)
256: {
257: if (playing)
258: CDAudio_Stop();
259: enabled = false;
260: return;
261: }
262:
263: if (Q_strcasecmp(command, "reset") == 0)
264: {
265: enabled = true;
266: if (playing)
267: CDAudio_Stop();
268: for (n = 0; n < 100; n++)
269: remap[n] = n;
270: CDAudio_GetAudioDiskInfo();
271: return;
272: }
273:
274: if (Q_strcasecmp(command, "remap") == 0)
275: {
276: ret = Cmd_Argc() - 2;
277: if (ret <= 0)
278: {
279: for (n = 1; n < 100; n++)
280: if (remap[n] != n)
281: Com_Printf(" %u -> %u\n", n, remap[n]);
282: return;
283: }
284: for (n = 1; n <= ret; n++)
285: remap[n] = atoi(Cmd_Argv (n+1));
286: return;
287: }
288:
289: if (Q_strcasecmp(command, "close") == 0)
290: {
291: CDAudio_CloseDoor();
292: return;
293: }
294:
295: if (!cdValid)
296: {
297: CDAudio_GetAudioDiskInfo();
298: if (!cdValid)
299: {
300: Com_Printf("No CD in player.\n");
301: return;
302: }
303: }
304:
305: if (Q_strcasecmp(command, "play") == 0)
306: {
307: CDAudio_Play(atoi(Cmd_Argv (2)), false);
308: return;
309: }
310:
311: if (Q_strcasecmp(command, "loop") == 0)
312: {
313: CDAudio_Play(atoi(Cmd_Argv (2)), true);
314: return;
315: }
316:
317: if (Q_strcasecmp(command, "stop") == 0)
318: {
319: CDAudio_Stop();
320: return;
321: }
322:
323: if (Q_strcasecmp(command, "pause") == 0)
324: {
325: CDAudio_Pause();
326: return;
327: }
328:
329: if (Q_strcasecmp(command, "resume") == 0)
330: {
331: CDAudio_Resume();
332: return;
333: }
334:
335: if (Q_strcasecmp(command, "eject") == 0)
336: {
337: if (playing)
338: CDAudio_Stop();
339: CDAudio_Eject();
340: cdValid = false;
341: return;
342: }
343:
344: if (Q_strcasecmp(command, "info") == 0)
345: {
346: Com_Printf("%u tracks\n", maxTrack);
347: if (playing)
348: Com_Printf("Currently %s track %u\n", playLooping ? "looping" : "playing", playTrack);
349: else if (wasPlaying)
350: Com_Printf("Paused %s track %u\n", playLooping ? "looping" : "playing", playTrack);
351: return;
352: }
353: }
354:
355:
356: LONG CDAudio_MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
357: {
358: if (lParam != wDeviceID)
359: return 1;
360:
361: switch (wParam)
362: {
363: case MCI_NOTIFY_SUCCESSFUL:
364: if (playing)
365: {
366: playing = false;
367: if (playLooping)
368: {
369: // if the track has played the given number of times,
370: // go to the ambient track
371: if (++loopcounter >= cd_loopcount->value)
372: CDAudio_Play2(cd_looptrack->value, true);
373: else
374: CDAudio_Play2(playTrack, true);
375: }
376: }
377: break;
378:
379: case MCI_NOTIFY_ABORTED:
380: case MCI_NOTIFY_SUPERSEDED:
381: break;
382:
383: case MCI_NOTIFY_FAILURE:
384: Com_DPrintf("MCI_NOTIFY_FAILURE\n");
385: CDAudio_Stop ();
386: cdValid = false;
387: break;
388:
389: default:
390: Com_DPrintf("Unexpected MM_MCINOTIFY type (%i)\n", wParam);
391: return 1;
392: }
393:
394: return 0;
395: }
396:
397:
398: void CDAudio_Update(void)
399: {
400: if ( cd_nocd->value != !enabled )
401: {
402: if ( cd_nocd->value )
403: {
404: CDAudio_Stop();
405: enabled = false;
406: }
407: else
408: {
409: enabled = true;
410: CDAudio_Resume ();
411: }
412: }
413: }
414:
415:
416: int CDAudio_Init(void)
417: {
418: DWORD dwReturn;
419: MCI_OPEN_PARMS mciOpenParms;
420: MCI_SET_PARMS mciSetParms;
421: int n;
422:
423: cd_nocd = Cvar_Get ("cd_nocd", "0", CVAR_ARCHIVE );
424: cd_loopcount = Cvar_Get ("cd_loopcount", "4", 0);
425: cd_looptrack = Cvar_Get ("cd_looptrack", "11", 0);
426: if ( cd_nocd->value)
427: return -1;
428:
429: mciOpenParms.lpstrDeviceType = "cdaudio";
430: if (dwReturn = mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_SHAREABLE, (DWORD) (LPVOID) &mciOpenParms))
431: {
432: Com_Printf("CDAudio_Init: MCI_OPEN failed (%i)\n", dwReturn);
433: return -1;
434: }
435: wDeviceID = mciOpenParms.wDeviceID;
436:
437: // Set the time format to track/minute/second/frame (TMSF).
438: mciSetParms.dwTimeFormat = MCI_FORMAT_TMSF;
439: if (dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD)(LPVOID) &mciSetParms))
440: {
441: Com_Printf("MCI_SET_TIME_FORMAT failed (%i)\n", dwReturn);
442: mciSendCommand(wDeviceID, MCI_CLOSE, 0, (DWORD)NULL);
443: return -1;
444: }
445:
446: for (n = 0; n < 100; n++)
447: remap[n] = n;
448: initialized = true;
449: enabled = true;
450:
451: if (CDAudio_GetAudioDiskInfo())
452: {
453: // Com_Printf("CDAudio_Init: No CD in player.\n");
454: cdValid = false;
455: enabled = false;
456: }
457:
458: Cmd_AddCommand ("cd", CD_f);
459:
460: Com_Printf("CD Audio Initialized\n");
461:
462: return 0;
463: }
464:
465:
466: void CDAudio_Shutdown(void)
467: {
468: if (!initialized)
469: return;
470: CDAudio_Stop();
471: if (mciSendCommand(wDeviceID, MCI_CLOSE, MCI_WAIT, (DWORD)NULL))
472: Com_DPrintf("CDAudio_Shutdown: MCI_CLOSE failed\n");
473: }
474:
475:
476: /*
477: ===========
478: CDAudio_Activate
479:
480: Called when the main window gains or loses focus.
481: The window have been destroyed and recreated
482: between a deactivate and an activate.
483: ===========
484: */
485: void CDAudio_Activate (qboolean active)
486: {
487: if (active)
488: CDAudio_Resume ();
489: else
490: CDAudio_Pause ();
491: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.