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