|
|
1.1.1.2 ! root 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: */ 1.1 root 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: 39: cvar_t *cd_nocd; 40: cvar_t *cd_loopcount; 41: cvar_t *cd_looptrack; 42: 43: UINT wDeviceID; 44: int loopcounter; 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)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)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) (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) (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: void 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; 117: 118: if (!cdValid) 119: { 120: CDAudio_GetAudioDiskInfo(); 121: if (!cdValid) 122: return; 123: } 124: 125: track = remap[track]; 126: 127: if (track < 1 || track > maxTrack) 128: { 129: CDAudio_Stop(); 130: return; 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) (LPVOID) &mciStatusParms); 137: if (dwReturn) 138: { 139: Com_DPrintf("MCI_STATUS failed (%i)\n", dwReturn); 140: return; 141: } 142: if (mciStatusParms.dwReturn != MCI_CDA_TRACK_AUDIO) 143: { 144: Com_Printf("CDAudio: track %i is not audio\n", track); 145: return; 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) (LPVOID) &mciStatusParms); 152: if (dwReturn) 153: { 154: Com_DPrintf("MCI_STATUS failed (%i)\n", dwReturn); 155: return; 156: } 157: 158: if (playing) 159: { 160: if (playTrack == track) 161: return; 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)cl_hwnd; 168: dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_NOTIFY | MCI_FROM | MCI_TO, (DWORD)(LPVOID) &mciPlayParms); 169: if (dwReturn) 170: { 171: Com_DPrintf("CDAudio: MCI_PLAY failed (%i)\n", dwReturn); 172: return; 173: } 174: 175: playLooping = looping; 176: playTrack = track; 177: playing = true; 178: 179: if ( Cvar_VariableValue( "cd_nocd" ) ) 180: CDAudio_Pause (); 181: } 182: 183: 184: void CDAudio_Play(int track, qboolean looping) 185: { 186: // set a loop counter so that this track will change to the 187: // looptrack later 188: loopcounter = 0; 189: CDAudio_Play2(track, looping); 190: } 191: 192: void CDAudio_Stop(void) 193: { 194: DWORD dwReturn; 195: 196: if (!enabled) 197: return; 198: 199: if (!playing) 200: return; 201: 202: if (dwReturn = mciSendCommand(wDeviceID, MCI_STOP, 0, (DWORD)NULL)) 203: Com_DPrintf("MCI_STOP failed (%i)", dwReturn); 204: 205: wasPlaying = false; 206: playing = false; 207: } 208: 209: 210: void CDAudio_Pause(void) 211: { 212: DWORD dwReturn; 213: MCI_GENERIC_PARMS mciGenericParms; 214: 215: if (!enabled) 216: return; 217: 218: if (!playing) 219: return; 220: 221: mciGenericParms.dwCallback = (DWORD)cl_hwnd; 222: if (dwReturn = mciSendCommand(wDeviceID, MCI_PAUSE, 0, (DWORD)(LPVOID) &mciGenericParms)) 223: Com_DPrintf("MCI_PAUSE failed (%i)", dwReturn); 224: 225: wasPlaying = playing; 226: playing = false; 227: } 228: 229: 230: void CDAudio_Resume(void) 231: { 232: DWORD dwReturn; 233: MCI_PLAY_PARMS mciPlayParms; 234: 235: if (!enabled) 236: return; 237: 238: if (!cdValid) 239: return; 240: 241: if (!wasPlaying) 242: return; 243: 244: mciPlayParms.dwFrom = MCI_MAKE_TMSF(playTrack, 0, 0, 0); 245: mciPlayParms.dwTo = MCI_MAKE_TMSF(playTrack + 1, 0, 0, 0); 246: mciPlayParms.dwCallback = (DWORD)cl_hwnd; 247: dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_TO | MCI_NOTIFY, (DWORD)(LPVOID) &mciPlayParms); 248: if (dwReturn) 249: { 250: Com_DPrintf("CDAudio: MCI_PLAY failed (%i)\n", dwReturn); 251: return; 252: } 253: playing = true; 254: } 255: 256: 257: static void CD_f (void) 258: { 259: char *command; 260: int ret; 261: int n; 262: 263: if (Cmd_Argc() < 2) 264: return; 265: 266: command = Cmd_Argv (1); 267: 268: if (Q_strcasecmp(command, "on") == 0) 269: { 270: enabled = true; 271: return; 272: } 273: 274: if (Q_strcasecmp(command, "off") == 0) 275: { 276: if (playing) 277: CDAudio_Stop(); 278: enabled = false; 279: return; 280: } 281: 282: if (Q_strcasecmp(command, "reset") == 0) 283: { 284: enabled = true; 285: if (playing) 286: CDAudio_Stop(); 287: for (n = 0; n < 100; n++) 288: remap[n] = n; 289: CDAudio_GetAudioDiskInfo(); 290: return; 291: } 292: 293: if (Q_strcasecmp(command, "remap") == 0) 294: { 295: ret = Cmd_Argc() - 2; 296: if (ret <= 0) 297: { 298: for (n = 1; n < 100; n++) 299: if (remap[n] != n) 300: Com_Printf(" %u -> %u\n", n, remap[n]); 301: return; 302: } 303: for (n = 1; n <= ret; n++) 304: remap[n] = atoi(Cmd_Argv (n+1)); 305: return; 306: } 307: 308: if (Q_strcasecmp(command, "close") == 0) 309: { 310: CDAudio_CloseDoor(); 311: return; 312: } 313: 314: if (!cdValid) 315: { 316: CDAudio_GetAudioDiskInfo(); 317: if (!cdValid) 318: { 319: Com_Printf("No CD in player.\n"); 320: return; 321: } 322: } 323: 324: if (Q_strcasecmp(command, "play") == 0) 325: { 326: CDAudio_Play(atoi(Cmd_Argv (2)), false); 327: return; 328: } 329: 330: if (Q_strcasecmp(command, "loop") == 0) 331: { 332: CDAudio_Play(atoi(Cmd_Argv (2)), true); 333: return; 334: } 335: 336: if (Q_strcasecmp(command, "stop") == 0) 337: { 338: CDAudio_Stop(); 339: return; 340: } 341: 342: if (Q_strcasecmp(command, "pause") == 0) 343: { 344: CDAudio_Pause(); 345: return; 346: } 347: 348: if (Q_strcasecmp(command, "resume") == 0) 349: { 350: CDAudio_Resume(); 351: return; 352: } 353: 354: if (Q_strcasecmp(command, "eject") == 0) 355: { 356: if (playing) 357: CDAudio_Stop(); 358: CDAudio_Eject(); 359: cdValid = false; 360: return; 361: } 362: 363: if (Q_strcasecmp(command, "info") == 0) 364: { 365: Com_Printf("%u tracks\n", maxTrack); 366: if (playing) 367: Com_Printf("Currently %s track %u\n", playLooping ? "looping" : "playing", playTrack); 368: else if (wasPlaying) 369: Com_Printf("Paused %s track %u\n", playLooping ? "looping" : "playing", playTrack); 370: return; 371: } 372: } 373: 374: 375: LONG CDAudio_MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 376: { 377: if (lParam != wDeviceID) 378: return 1; 379: 380: switch (wParam) 381: { 382: case MCI_NOTIFY_SUCCESSFUL: 383: if (playing) 384: { 385: playing = false; 386: if (playLooping) 387: { 388: // if the track has played the given number of times, 389: // go to the ambient track 390: if (++loopcounter >= cd_loopcount->value) 391: CDAudio_Play2(cd_looptrack->value, true); 392: else 393: CDAudio_Play2(playTrack, true); 394: } 395: } 396: break; 397: 398: case MCI_NOTIFY_ABORTED: 399: case MCI_NOTIFY_SUPERSEDED: 400: break; 401: 402: case MCI_NOTIFY_FAILURE: 403: Com_DPrintf("MCI_NOTIFY_FAILURE\n"); 404: CDAudio_Stop (); 405: cdValid = false; 406: break; 407: 408: default: 409: Com_DPrintf("Unexpected MM_MCINOTIFY type (%i)\n", wParam); 410: return 1; 411: } 412: 413: return 0; 414: } 415: 416: 417: void CDAudio_Update(void) 418: { 419: if ( cd_nocd->value != !enabled ) 420: { 421: if ( cd_nocd->value ) 422: { 423: CDAudio_Stop(); 424: enabled = false; 425: } 426: else 427: { 428: enabled = true; 429: CDAudio_Resume (); 430: } 431: } 432: } 433: 434: 435: int CDAudio_Init(void) 436: { 437: DWORD dwReturn; 438: MCI_OPEN_PARMS mciOpenParms; 439: MCI_SET_PARMS mciSetParms; 440: int n; 441: 442: cd_nocd = Cvar_Get ("cd_nocd", "0", CVAR_ARCHIVE ); 443: cd_loopcount = Cvar_Get ("cd_loopcount", "4", 0); 444: cd_looptrack = Cvar_Get ("cd_looptrack", "11", 0); 445: if ( cd_nocd->value) 446: return -1; 447: 448: mciOpenParms.lpstrDeviceType = "cdaudio"; 449: if (dwReturn = mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_SHAREABLE, (DWORD) (LPVOID) &mciOpenParms)) 450: { 451: Com_Printf("CDAudio_Init: MCI_OPEN failed (%i)\n", dwReturn); 452: return -1; 453: } 454: wDeviceID = mciOpenParms.wDeviceID; 455: 456: // Set the time format to track/minute/second/frame (TMSF). 457: mciSetParms.dwTimeFormat = MCI_FORMAT_TMSF; 458: if (dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD)(LPVOID) &mciSetParms)) 459: { 460: Com_Printf("MCI_SET_TIME_FORMAT failed (%i)\n", dwReturn); 461: mciSendCommand(wDeviceID, MCI_CLOSE, 0, (DWORD)NULL); 462: return -1; 463: } 464: 465: for (n = 0; n < 100; n++) 466: remap[n] = n; 467: initialized = true; 468: enabled = true; 469: 470: if (CDAudio_GetAudioDiskInfo()) 471: { 472: // Com_Printf("CDAudio_Init: No CD in player.\n"); 473: cdValid = false; 474: enabled = false; 475: } 476: 477: Cmd_AddCommand ("cd", CD_f); 478: 479: Com_Printf("CD Audio Initialized\n"); 480: 481: return 0; 482: } 483: 484: 485: void CDAudio_Shutdown(void) 486: { 487: if (!initialized) 488: return; 489: CDAudio_Stop(); 490: if (mciSendCommand(wDeviceID, MCI_CLOSE, MCI_WAIT, (DWORD)NULL)) 491: Com_DPrintf("CDAudio_Shutdown: MCI_CLOSE failed\n"); 492: } 493: 494: 495: /* 496: =========== 497: CDAudio_Activate 498: 499: Called when the main window gains or loses focus. 500: The window have been destroyed and recreated 501: between a deactivate and an activate. 502: =========== 503: */ 504: void CDAudio_Activate (qboolean active) 505: { 506: if (active) 507: CDAudio_Resume (); 508: else 509: CDAudio_Pause (); 510: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.