$NetBSD: patch-aa,v 1.6 2009/08/29 19:26:01 wiz Exp $

--- QW/client/cd_linux.c.orig	1999-12-21 18:58:58.000000000 +0000
+++ QW/client/cd_linux.c
@@ -31,7 +31,23 @@ Foundation, Inc., 59 Temple Place - Suit
 #include <time.h>
 #include <errno.h>
 
+#ifdef __linux__
 #include <linux/cdrom.h>
+#endif
+
+#if defined(__DragonFly__)
+#include <sys/cdio.h>
+#endif
+
+#if defined(__NetBSD__)
+#include <sys/cdio.h>
+
+/* resume seems to have some trouble right now.  xcdplayer also can not resume
+   the drive correctly.  It appears to play, but no audio is heard */
+
+#define PAUSE_BY_STOPPING 1
+
+#endif
 
 #include "quakedef.h"
 
@@ -46,165 +62,296 @@ static byte 	remap[100];
 static byte		playTrack;
 static byte		maxTrack;
 
+#ifdef PAUSE_BY_STOPPING
+static qboolean t_playLooping;
+static byte t_playTrack;
+#endif
+
 static int cdfile = -1;
+#ifdef __linux__
 static char cd_dev[64] = "/dev/cdrom";
+#endif
+
+#ifdef __DragonFly__
+static char cd_dev[64] = "/dev/cd0d";
+#endif
+
+#ifdef __NetBSD__
+static char cd_dev[64] = "/dev/rcd0d";
+#endif
 
 static void CDAudio_Eject(void)
 {
-	if (cdfile == -1 || !enabled)
-		return; // no cd init'd
+#if defined(__DragonFly__) || defined(__NetBSD__)
+  int arg=0;
+#endif
 
-	if ( ioctl(cdfile, CDROMEJECT) == -1 ) 
-		Con_DPrintf("ioctl cdromeject failed\n");
+  if (cdfile == -1 || !enabled)
+    return; // no cd init'd
+
+#ifdef __linux__
+  if ( ioctl(cdfile, CDROMEJECT) == -1 ) 
+    Con_DPrintf("ioctl cdromeject failed\n");
+#elif defined(__DragonFly__)
+  ioctl(cdfile, CDIOCALLOW);
+  if ( ioctl(cdfile, CDIOCEJECT) == -1 ) 
+    Con_DPrintf("ioctl cdromeject failed\n");
+#elif defined(__NetBSD__)
+  if(ioctl(cdfile, DIOCLOCK, &arg) == -1)
+    Con_DPrintf("ioctl cdromunlock failed\n");
+  arg = 1;
+  if ( ioctl(cdfile, DIOCEJECT, &arg) == -1 ) 
+    Con_DPrintf("ioctl cdromeject failed\n");
+#endif
 }
 
 
 static void CDAudio_CloseDoor(void)
 {
-	if (cdfile == -1 || !enabled)
-		return; // no cd init'd
+if (cdfile == -1 || !enabled)
+    return; // no cd init'd
 
-	if ( ioctl(cdfile, CDROMCLOSETRAY) == -1 ) 
-		Con_DPrintf("ioctl cdromclosetray failed\n");
+#ifdef __linux__
+  if ( ioctl(cdfile, CDROMCLOSETRAY) == -1 ) 
+    Con_DPrintf("ioctl cdromclosetray failed\n");
+#endif
+#if defined(__DragonFly__) || defined(__NetBSD__)
+  if(ioctl(cdfile, CDIOCCLOSE, NULL) == -1) {
+    Con_DPrintf("ioctl cdromclosetray failed\n");
+  }
+#endif
 }
 
 static int CDAudio_GetAudioDiskInfo(void)
 {
-	struct cdrom_tochdr tochdr;
+#ifdef __linux__
+struct cdrom_tochdr tochdr;
+#endif
+#if defined(__DragonFly__) || defined(__NetBSD__)
+struct ioc_toc_header tochdr;
+#endif
 
-	cdValid = false;
+cdValid = false;
 
-	if ( ioctl(cdfile, CDROMREADTOCHDR, &tochdr) == -1 ) 
-    {
-      Con_DPrintf("ioctl cdromreadtochdr failed\n");
-	  return -1;
-    }
+#ifdef __linux
+if ( ioctl(cdfile, CDROMREADTOCHDR, &tochdr) == -1 ) 
+{
+  Con_DPrintf("ioctl cdromreadtochdr failed\n");
+  return -1;
+}
+#endif
 
-	if (tochdr.cdth_trk0 < 1)
-	{
-		Con_DPrintf("CDAudio: no music tracks\n");
-		return -1;
-	}
+#if defined(__DragonFly__) || defined(__NetBSD__)
+if ( ioctl(cdfile, CDIOREADTOCHEADER, &tochdr) == -1 ) 
+{
+  Con_DPrintf("ioctl cdromreadtochdr failed\n");
+  return -1;
+}
+#endif
+
+#ifdef __linux__
+if (tochdr.cdth_trk0 < 1)
+  {
+    Con_DPrintf("CDAudio: no music tracks\n");
+    return -1;
+  }
+#endif
+#if defined(__DragonFly__) || defined(__NetBSD__)
+if (tochdr.starting_track < 1)
+  {
+    Con_DPrintf("CDAudio: no music tracks\n");
+    return -1;
+  }
+#endif
 
-	cdValid = true;
-	maxTrack = tochdr.cdth_trk1;
+cdValid = true;
+#ifdef __linux__
+maxTrack = tochdr.cdth_trk1;
+#endif
+#if defined(__DragonFly__) || defined(__NetBSD__)
+maxTrack = tochdr.ending_track;
+#endif
 
-	return 0;
+return 0;
 }
 
 
 void CDAudio_Play(byte track, qboolean looping)
 {
-	struct cdrom_tocentry entry;
-	struct cdrom_ti ti;
+#ifdef __linux__
+  struct cdrom_tocentry entry;
+  struct cdrom_ti ti;
+#endif
 
-	if (cdfile == -1 || !enabled)
-		return;
+#if defined(__DragonFly__) || defined(__NetBSD__)
+  struct ioc_read_toc_entry entry;
+  struct ioc_play_track ti;
+  int arg=1;
+#endif
+
+  if (cdfile == -1 || !enabled)
+    return;
 	
-	if (!cdValid)
-	{
-		CDAudio_GetAudioDiskInfo();
-		if (!cdValid)
-			return;
-	}
+  if (!cdValid)
+    {
+      CDAudio_GetAudioDiskInfo();
+      if (!cdValid)
+	return;
+    }
 
-	track = remap[track];
+  track = remap[track];
 
-	if (track < 1 || track > maxTrack)
-	{
-		Con_DPrintf("CDAudio: Bad track number %u.\n", track);
-		return;
-	}
+  if (track < 1 || track > maxTrack)
+    {
+      Con_DPrintf("CDAudio: Bad track number %u.\n", track);
+      return;
+    }
 
-	// don't try to play a non-audio track
-	entry.cdte_track = track;
-	entry.cdte_format = CDROM_MSF;
-    if ( ioctl(cdfile, CDROMREADTOCENTRY, &entry) == -1 )
-	{
-		Con_DPrintf("ioctl cdromreadtocentry failed\n");
-		return;
-	}
-	if (entry.cdte_ctrl == CDROM_DATA_TRACK)
-	{
-		Con_Printf("CDAudio: track %i is not audio\n", track);
-		return;
-	}
+#ifdef __linux__ /* Not sure what the equiv is for NetBSD */
+  /* don't try to play a non-audio track */
+  entry.cdte_track = track;
+  entry.cdte_format = CDROM_MSF;
+  if ( ioctl(cdfile, CDROMREADTOCENTRY, &entry) == -1 )
+    {
+      Con_DPrintf("ioctl cdromreadtocentry failed\n");
+      return;
+    }
+  if (entry.cdte_ctrl == CDROM_DATA_TRACK)
+    {
+      Con_Printf("CDAudio: track %i is not audio\n", track);
+      return;
+    }
 
-	if (playing)
-	{
-		if (playTrack == track)
-			return;
-		CDAudio_Stop();
-	}
+#endif
 
-	ti.cdti_trk0 = track;
-	ti.cdti_trk1 = track;
-	ti.cdti_ind0 = 1;
-	ti.cdti_ind1 = 99;
+  if (playing)
+    {
+      if (playTrack == track)
+	return;
+      CDAudio_Stop();
+    }
 
-	if ( ioctl(cdfile, CDROMPLAYTRKIND, &ti) == -1 ) 
+#ifdef __linux__
+  ti.cdti_trk0 = track;
+  ti.cdti_trk1 = track;
+  ti.cdti_ind0 = 1;
+  ti.cdti_ind1 = 99;
+  if ( ioctl(cdfile, CDROMPLAYTRKIND, &ti) == -1 ) 
     {
-		Con_DPrintf("ioctl cdromplaytrkind failed\n");
-		return;
+      Con_DPrintf("ioctl cdromplaytrkind failed\n");
+      return;
+    }
+
+  if ( ioctl(cdfile, CDROMRESUME) == -1 ) 
+    Con_DPrintf("ioctl cdromresume failed\n");
+#endif
+
+#if defined(__DragonFly__) || defined(__NetBSD__)
+  ti.start_track = track;
+  ti.end_track = track;
+  ti.start_index = 1;
+  ti.end_index = 99;
+  if ( ioctl(cdfile, CDIOCPLAYTRACKS, &ti) == -1 ) 
+    {
+      Con_DPrintf("ioctl cdromplaytrkind failed\n");
+      return;
     }
 
-	if ( ioctl(cdfile, CDROMRESUME) == -1 ) 
-		Con_DPrintf("ioctl cdromresume failed\n");
+  if ( ioctl(cdfile, CDIOCRESUME, &arg) == -1 ) 
+    Con_DPrintf("ioctl cdromresume failed\n");
+#endif
 
-	playLooping = looping;
-	playTrack = track;
-	playing = true;
+  playLooping = looping;
+  playTrack = track;
+  playing = true;
 
-	if (cdvolume == 0.0)
-		CDAudio_Pause ();
+  if (cdvolume == 0.0)
+    CDAudio_Pause ();
 }
 
 
 void CDAudio_Stop(void)
 {
-	if (cdfile == -1 || !enabled)
-		return;
+  if (cdfile == -1 || !enabled)
+    return;
 	
-	if (!playing)
-		return;
+  if (!playing)
+    return;
 
-	if ( ioctl(cdfile, CDROMSTOP) == -1 )
-		Con_DPrintf("ioctl cdromstop failed (%d)\n", errno);
+#ifdef __linux__
+  if ( ioctl(cdfile, CDROMSTOP) == -1 )
+    Con_DPrintf("ioctl cdromstop failed (%d)\n", errno);
+#endif
+#if defined(__DragonFly__) || defined(__NetBSD__)
+  if ( ioctl(cdfile, CDIOCSTOP) == -1 )
+    Con_DPrintf("ioctl cdromstop failed (%d)\n", errno);
+#endif
 
-	wasPlaying = false;
-	playing = false;
+  wasPlaying = false;
+  playing = false;
 }
 
 void CDAudio_Pause(void)
 {
-	if (cdfile == -1 || !enabled)
-		return;
+#ifdef PAUSE_BY_STOPPING
+  qboolean t;
+#endif
 
-	if (!playing)
-		return;
+  if (cdfile == -1 || !enabled)
+    return;
 
-	if ( ioctl(cdfile, CDROMPAUSE) == -1 ) 
-		Con_DPrintf("ioctl cdrompause failed\n");
+  if (!playing)
+    return;
 
-	wasPlaying = playing;
-	playing = false;
+#ifndef PAUSE_BY_STOPPING
+#ifdef __linux__
+  if ( ioctl(cdfile, CDROMPAUSE) == -1 ) 
+    Con_DPrintf("ioctl cdrompause failed\n");
+#endif
+
+#if defined(__DragonFly__) || defined(__NetBSD__)
+  if ( ioctl(cdfile, CDIOCPAUSE) == -1 ) 
+    Con_DPrintf("ioctl cdrompause failed\n");
+#endif
+#else
+  t_playLooping = playLooping;
+  t_playTrack=playTrack;
+  t=playing;
+  CDAudio_Stop();
+  playing=t;
+#endif
+
+  wasPlaying = playing;
+  playing = false;
 }
 
 
 void CDAudio_Resume(void)
 {
-	if (cdfile == -1 || !enabled)
-		return;
+  if (cdfile == -1 || !enabled)
+    return;
 	
-	if (!cdValid)
-		return;
+  if (!cdValid)
+    return;
 
-	if (!wasPlaying)
-		return;
+  if (!wasPlaying)
+    return;
 	
-	if ( ioctl(cdfile, CDROMRESUME) == -1 ) 
-		Con_DPrintf("ioctl cdromresume failed\n");
-	playing = true;
+#ifndef PAUSE_BY_STOPPING
+#ifdef __linux__
+  if ( ioctl(cdfile, CDROMRESUME) == -1 ) 
+    Con_DPrintf("ioctl cdromresume failed\n");
+#endif
+
+#if defined(__DragonFly__) || defined(__NetBSD__)
+  if ( ioctl(cdfile, CDIOCRESUME) == -1 ) 
+    Con_DPrintf("ioctl cdromresume failed\n");
+#endif
+#else
+  CDAudio_Play(t_playTrack, t_playLooping);
+#endif
+
+  playing = true;
 }
 
 static void CD_f (void)
@@ -327,43 +474,72 @@ static void CD_f (void)
 
 void CDAudio_Update(void)
 {
-	struct cdrom_subchnl subchnl;
-	static time_t lastchk;
+#ifdef __linux__
+  struct cdrom_subchnl subchnl;
+#endif
+#if defined(__DragonFly__) || defined(__NetBSD__)
+  struct ioc_read_subchannel subchnl;
+  struct cd_sub_channel_info data;
+#endif
+  static time_t lastchk;
 
-	if (!enabled)
-		return;
+  if (!enabled)
+    return;
 
-	if (bgmvolume.value != cdvolume)
+  if (bgmvolume.value != cdvolume)
+    {
+      if (cdvolume)
 	{
-		if (cdvolume)
-		{
-			Cvar_SetValue ("bgmvolume", 0.0);
-			cdvolume = bgmvolume.value;
-			CDAudio_Pause ();
-		}
-		else
-		{
-			Cvar_SetValue ("bgmvolume", 1.0);
-			cdvolume = bgmvolume.value;
-			CDAudio_Resume ();
-		}
+	  Cvar_SetValue ("bgmvolume", 0.0);
+	  cdvolume = bgmvolume.value;
+	  CDAudio_Pause ();
 	}
-
-	if (playing && lastchk < time(NULL)) {
-		lastchk = time(NULL) + 2; //two seconds between chks
-		subchnl.cdsc_format = CDROM_MSF;
-		if (ioctl(cdfile, CDROMSUBCHNL, &subchnl) == -1 ) {
-			Con_DPrintf("ioctl cdromsubchnl failed\n");
-			playing = false;
-			return;
-		}
-		if (subchnl.cdsc_audiostatus != CDROM_AUDIO_PLAY &&
-			subchnl.cdsc_audiostatus != CDROM_AUDIO_PAUSED) {
-			playing = false;
-			if (playLooping)
-				CDAudio_Play(playTrack, true);
-		}
+      else
+	{
+	  Cvar_SetValue ("bgmvolume", 1.0);
+	  cdvolume = bgmvolume.value;
+	  CDAudio_Resume ();
 	}
+    }
+
+
+  if (playing && lastchk < time(NULL)) {
+    lastchk = time(NULL) + 2;    /* two seconds between chks */
+#ifdef __linux
+    subchnl.cdsc_format = CDROM_MSF;
+    if (ioctl(cdfile, CDROMSUBCHNL, &subchnl) == -1 ) {
+      Con_DPrintf("ioctl cdromsubchnl failed\n");
+      playing = false;
+      return;
+    }
+    if (subchnl.cdsc_audiostatus != CDROM_AUDIO_PLAY &&
+	subchnl.cdsc_audiostatus != CDROM_AUDIO_PAUSED) {
+      playing = false;
+      if (playLooping)
+	CDAudio_Play(playTrack, true);
+    }
+#endif
+#if defined(__DragonFly__) || defined(__NetBSD__)
+    subchnl.address_format = CD_MSF_FORMAT;
+    subchnl.data_format = CD_CURRENT_POSITION;
+    subchnl.data_len = sizeof(data);
+    subchnl.track = playTrack;
+    subchnl.data = &data;
+
+    if (ioctl(cdfile, CDIOCREADSUBCHANNEL, &subchnl) == -1 ) {
+      Con_DPrintf("ioctl cdromsubchnl failed\n");
+      playing = false;
+      return;
+    }
+    if (subchnl.data->header.audio_status != CD_AS_PLAY_IN_PROGRESS &&
+	subchnl.data->header.audio_status != CD_AS_PLAY_PAUSED) {
+      playing = false;
+      if (playLooping)
+	CDAudio_Play(playTrack, true);
+    }
+#endif
+  }
+
 }
 
 int CDAudio_Init(void)
@@ -375,6 +551,8 @@ int CDAudio_Init(void)
 		return -1;
 #endif
 
+	fprintf(stderr,"......  cdaudio_init .......\n");
+
 	if (COM_CheckParm("-nocdaudio"))
 		return -1;
 
@@ -384,9 +562,9 @@ int CDAudio_Init(void)
 	}
 
 	if ((cdfile = open(cd_dev, O_RDONLY)) == -1) {
-		Con_Printf("CDAudio_Init: open of \"%s\" failed (%i)\n", cd_dev, errno);
-		cdfile = -1;
-		return -1;
+	  Con_Printf("CDAudio_Init: open of \"%s\" failed (%i)\n", cd_dev, errno);
+	  cdfile = -1;
+	  return -1;
 	}
 
 	for (i = 0; i < 100; i++)
