|
|
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.