home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 15 / MA_Cover_15.iso / source / winquake / cd_amiga.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-02  |  9.1 KB  |  326 lines

  1. /*
  2. Copyright (C) 2000 Peter McGavin.
  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. #include <exec/types.h>
  21. #include <exec/memory.h>
  22. #include <dos/dos.h>
  23. #include <dos/dosextens.h>
  24. #include <dos/filehandler.h>
  25. #include <dos/rdargs.h>
  26. #include <libraries/cdplayer.h>
  27.  
  28. #if defined(__VBCC__) || (defined(__STORM__) && defined(__PPC__))
  29. #include <clib/cdplayer_protos.h>
  30. #include <clib/exec_protos.h>
  31. #include <clib/dos_protos.h>
  32. #else
  33. #include <proto/exec.h>
  34. #include <proto/dos.h>
  35. #include <proto/cdplayer.h>
  36. #ifdef __PPC__
  37. #include <ppcpragmas/cdplayer_pragmas.h>
  38. #endif
  39. #endif
  40.  
  41. #include "quakedef.h"
  42.  
  43. struct Library    *CDPlayerBase = NULL;
  44.  
  45. static struct IOStdReq *CD_Request = NULL;
  46. static struct MsgPort *CD_Port = NULL;
  47. static struct CD_TOC table;
  48. static BOOL cd_is_open = FALSE;
  49. static BOOL cd_is_playing = FALSE;
  50. static qboolean cd_is_looping = FALSE;
  51. static byte cd_track;
  52. static char scsi_device_name[36] = "";
  53. static ULONG scsi_unit;
  54. static float cdvolume;
  55.  
  56. /**********************************************************************/
  57. static BOOL get_cd_dev_and_unit (char *volumename,
  58.                                  char **devicename,
  59.                                  ULONG *unit)
  60. /* given a CD volume name, search the DosList for the associated device
  61.    handler, then extract and return the low level scsi device driver name
  62.    and unit */
  63. {
  64.   struct DosList *dl, *dl2;
  65.   int len;
  66.   struct InfoData *id;
  67.   struct FileSysStartupMsg *fssm;
  68.   static char device_name[60];
  69.  
  70.   if ((id = (struct InfoData *)AllocVec (sizeof(struct InfoData), MEMF_PUBLIC | MEMF_CLEAR)) == NULL) {
  71.     Sys_Error ("AllocMem() failed\n");
  72.     return FALSE;
  73.   }
  74.   if ((dl = LockDosList (LDF_DEVICES | LDF_READ)) == NULL) {
  75.     FreeVec (id);
  76.     Sys_Error ("LockDosList() failed\n");
  77.     return FALSE;
  78.   }
  79.   while ((dl = NextDosEntry (dl, LDF_DEVICES)) != NULL) {
  80.     if (dl->dol_Type == DLT_DEVICE &&
  81.         dl->dol_Task != NULL &&
  82.         DoPkt (dl->dol_Task, ACTION_DISK_INFO, MKBADDR(id), 0, 0, 0, 0) &&
  83.         (dl2 = (struct DosList *)BADDR(id->id_VolumeNode)) != NULL &&
  84.         dl2->dol_Type == DLT_VOLUME &&
  85.         (len = ((char *)BADDR(dl2->dol_Name))[0]) == strlen(volumename) &&
  86.         strnicmp (volumename, &((char *)BADDR(dl2->dol_Name))[1], len) == 0 &&
  87.         (fssm = (struct FileSysStartupMsg *)
  88.                          BADDR(dl->dol_misc.dol_handler.dol_Startup)) != NULL) {
  89.       len = ((char *)BADDR(fssm->fssm_Device))[0];
  90.       memcpy (device_name, &((char *)BADDR(fssm->fssm_Device))[1], len);
  91.       device_name[len] = '\0';
  92.       *devicename = device_name;
  93.       *unit = fssm->fssm_Unit;
  94.       UnLockDosList (LDF_DEVICES | LDF_READ);
  95.       FreeVec (id);
  96.       return TRUE;
  97.     }
  98.   }
  99.   UnLockDosList (LDF_DEVICES | LDF_READ);
  100.   FreeVec (id);
  101.   return FALSE;
  102. }
  103.  
  104. /**********************************************************************/
  105. static int open_cdplayer (void)
  106. {
  107.   int result;
  108.  
  109.   if (CD_Request == NULL)
  110.     return 1;
  111.   if ((CDPlayerBase = OpenLibrary ("libs/" CDPLAYERNAME, CDPLAYERVERSION)) == NULL &&
  112.       (CDPlayerBase = OpenLibrary (CDPLAYERNAME, CDPLAYERVERSION)) == NULL) {
  113.     Con_Printf ("Can't open cdplayer.library, CD audio not available\n");
  114.     return 1;
  115.   }
  116.   if ((result = OpenDevice (scsi_device_name, scsi_unit,
  117.                             (struct IORequest *)CD_Request, 0)) == 0) {
  118.     cd_is_open = TRUE;
  119.   }
  120.   return result;
  121. }
  122.  
  123. /**********************************************************************/
  124. static void close_cdplayer (void)
  125. {
  126.   if (cd_is_open) {
  127.     CloseDevice ((struct IORequest *) CD_Request);
  128.     cd_is_open = FALSE;
  129.   }
  130.   if (CDPlayerBase != NULL) {
  131.     CloseLibrary (CDPlayerBase);
  132.     CDPlayerBase = NULL;
  133.   }
  134. }
  135.  
  136. /**********************************************************************/
  137. void CDAudio_Play (byte track, qboolean looping)
  138. {
  139. //  printf ("CDAudio_Play(%d,%d)\n", track, looping);
  140.   CDAudio_Stop ();
  141.   if (open_cdplayer () == 0) {
  142.     cd_is_playing = (CDPlay (track, track, CD_Request) == 0);
  143.     cd_track = track;
  144.     cd_is_looping = looping;
  145.     close_cdplayer ();
  146.   }
  147. }
  148.  
  149.  
  150. /**********************************************************************/
  151. void CDAudio_Stop (void)
  152. {
  153. //  printf ("CDAudio_Stop()\n");
  154.   if (open_cdplayer () == 0) {
  155.     CDStop (CD_Request);
  156.     cd_is_playing = FALSE;
  157.     cd_is_looping = FALSE;
  158.     close_cdplayer ();
  159.   }
  160. }
  161.  
  162.  
  163. /**********************************************************************/
  164. void CDAudio_Pause (void)
  165. {
  166. //  printf ("CDAudio_Pause()\n");
  167.   if (open_cdplayer () == 0) {
  168.     CDResume (TRUE, CD_Request);
  169.     close_cdplayer ();
  170.   }
  171. }
  172.  
  173.  
  174. /**********************************************************************/
  175. void CDAudio_Resume (void)
  176. {
  177. //  printf ("CDAudio_Resume()\n");
  178.   if (open_cdplayer () == 0) {
  179.     CDResume (FALSE, CD_Request);
  180.     close_cdplayer ();
  181.   }
  182. }
  183.  
  184.  
  185. /**********************************************************************/
  186. /* This routine called once for every frame */
  187. void CDAudio_Update (void)
  188. {
  189.   struct CD_Volume vol;
  190.   struct CD_Time cd_time;
  191.   static UWORD count = 64;
  192.  
  193. //  printf ("CDAudio_Update()\n");
  194.   if (bgmvolume.value != cdvolume) {
  195. //    printf ("bgmvolume.value = %6.2f\n", (double)bgmvolume.value);
  196.     if (bgmvolume.value == 0.0 && cdvolume != 0.0)
  197.       CDAudio_Pause ();
  198.     else if (bgmvolume.value != 0.0 && cdvolume == 0.0)
  199.       CDAudio_Resume ();
  200.     cdvolume = bgmvolume.value;
  201.     if (open_cdplayer () == 0) {
  202.       vol.cdv_Chan0 = vol.cdv_Chan1 = (UBYTE)(cdvolume * 255.0);
  203.       vol.cdv_Chan2 = vol.cdv_Chan3 = 0;
  204.       CDSetVolume (&vol, CD_Request);
  205.       close_cdplayer ();
  206.     }
  207.   }
  208.   /* replay cd_track if cd_is_looping and we reach the end */
  209.   if (--count == 0 && cd_is_playing && cd_is_looping) {
  210.     if (open_cdplayer () == 0) {
  211.       CDTitleTime (&cd_time, CD_Request);
  212. //      printf ("%d %d %d %d %d %d\n", cd_time.cdt_TrackCurBase,
  213. //              cd_time.cdt_TrackRemainBase, cd_time.cdt_TrackCompleteBase,
  214. //              cd_time.cdt_AllCurBase, cd_time.cdt_AllRemainBase,
  215. //              cd_time.cdt_AllCompleteBase);
  216.       close_cdplayer ();
  217.       if (cd_time.cdt_TrackRemainBase < 300)
  218.         CDAudio_Play (cd_track, cd_is_looping);
  219.     }
  220.     count = 64;
  221.   }
  222. }
  223.  
  224.  
  225. /**********************************************************************/
  226. int CDAudio_Init (void)
  227. {
  228.   char *scsi_device_name2, *scsi_unit_name;
  229.  
  230. //  printf ("CDAudio_Init()\n");
  231.   if (cls.state == ca_dedicated)
  232.     return -1;
  233.  
  234.   if (COM_CheckParm("-nocdaudio"))
  235.     return -1;
  236.  
  237.   if ((CD_Port = CreateMsgPort ()) == NULL) {
  238.     Sys_Error ("CreateMsgPort() failed");
  239.     return -1;
  240.   }
  241.   if ((CD_Request = (struct IOStdReq *)CreateIORequest (CD_Port,
  242.                                            sizeof (struct IOStdReq))) == NULL) {
  243.     Sys_Error ("CreateIORequest() failed");
  244.     return -1;
  245.   }
  246.   if ((scsi_unit_name = getenv("quake/scsi_unit")) != NULL)
  247.     scsi_unit = atoi(scsi_unit_name);
  248.   if (scsi_unit_name == NULL ||
  249.       (scsi_device_name2 = getenv("quake/scsi_device")) == NULL) {
  250.     if (!get_cd_dev_and_unit ("QUAKE", &scsi_device_name2, &scsi_unit)) {
  251.       Con_Printf ("Unable to determine SCSI device & Unit for CD audio\n");
  252.       return -1;
  253.     }
  254.   }
  255.   strncpy (scsi_device_name, scsi_device_name2, sizeof(scsi_device_name));
  256.   if (open_cdplayer () != 0) {
  257.     Con_Printf ("CdInit: Failed to open scsi device\n");
  258.     return 1;
  259.   }
  260.   if (CDReadTOC (&table, CD_Request) != 0) {
  261.     Sys_Error ("CdInit: CDReadTOC() failed");
  262.     return -1;
  263.   }
  264.   close_cdplayer ();
  265.   cdvolume = 1.0;
  266.   CDAudio_Update ();
  267.   return 0;
  268. }
  269.  
  270.  
  271. /**********************************************************************/
  272. void CDAudio_Shutdown (void)
  273. {
  274. //  printf ("CDAudio_Shutdown()\n");
  275.   CDAudio_Stop ();
  276.   if (cd_is_open) {
  277.     CloseDevice ((struct IORequest *) CD_Request);
  278.     cd_is_open = FALSE;
  279.   }
  280.   if (CD_Request != NULL) {
  281.     DeleteIORequest (CD_Request);
  282.     CD_Request = NULL;
  283.   }
  284.   if (CD_Port != NULL) {
  285.     DeleteMsgPort (CD_Port);
  286.     CD_Port = NULL;
  287.   }
  288.   if (CDPlayerBase != NULL) {
  289.     CloseLibrary (CDPlayerBase);
  290.     CDPlayerBase = NULL;
  291.   }
  292. }
  293.  
  294. /**********************************************************************/
  295.  
  296. #ifdef __SASC
  297. void _STD_CDAudio_Shutdown (void)
  298. {
  299. //  printf ("_STD_CDAudio_Shutdown()\n");
  300.  
  301.   CDAudio_Shutdown ();
  302. }
  303. #endif
  304.  
  305. /**********************************************************************/
  306. #ifdef __STORM__
  307. void EXIT_9_CDAudio_Shutdown (void)
  308. {
  309. //  printf ("EXIT_9_CDAudio_Shutdown()\n");
  310.  
  311.   CDAudio_Shutdown ();
  312. }
  313. #endif
  314.  
  315. /**********************************************************************/
  316. #ifdef __VBCC__
  317. void _EXIT_9_CDAudio_Shutdown (void)
  318. {
  319. //  printf ("_EXIT_9_CDAudio_Shutdown()\n");
  320.  
  321.   CDAudio_Shutdown ();
  322. }
  323. #endif
  324.  
  325. /**********************************************************************/
  326.