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