home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quake_src / cd_linux.c < prev    next >
C/C++ Source or Header  |  2000-06-17  |  8KB  |  417 lines

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