Factorized audio CD code
[divverent/darkplaces.git] / cd_linux.c
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 <linux/cdrom.h>
24 #include <sys/ioctl.h>
25
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <time.h>
29 #include <unistd.h>
30
31 #include "quakedef.h"
32
33
34 extern qboolean cdPlaying;
35 extern qboolean cdPlayLooping;
36 extern qbyte cdPlayTrack;
37
38 static int cdfile = -1;
39 static char cd_dev[64] = "/dev/cdrom";
40
41 void CDAudio_SysEject (void)
42 {
43         if (cdfile == -1)
44                 return;
45
46         if (ioctl(cdfile, CDROMEJECT) == -1)
47                 Con_DPrintf("ioctl cdromeject failed\n");
48 }
49
50
51 void CDAudio_SysCloseDoor (void)
52 {
53         if (cdfile == -1)
54                 return;
55
56         if (ioctl(cdfile, CDROMCLOSETRAY) == -1)
57                 Con_DPrintf("ioctl cdromclosetray failed\n");
58 }
59
60 int CDAudio_SysGetAudioDiskInfo (void)
61 {
62         struct cdrom_tochdr tochdr;
63
64         if (ioctl(cdfile, CDROMREADTOCHDR, &tochdr) == -1)
65         {
66                 Con_DPrintf("ioctl cdromreadtochdr failed\n");
67                 return -1;
68         }
69
70         if (tochdr.cdth_trk0 < 1)
71         {
72                 Con_DPrintf("CDAudio: no music tracks\n");
73                 return -1;
74         }
75
76         return tochdr.cdth_trk1;
77 }
78
79
80 int CDAudio_SysPlay (qbyte track)
81 {
82         struct cdrom_tocentry entry;
83         struct cdrom_ti ti;
84
85         if (cdfile == -1)
86                 return -1;
87
88         // don't try to play a non-audio track
89         entry.cdte_track = track;
90         entry.cdte_format = CDROM_MSF;
91         if (ioctl(cdfile, CDROMREADTOCENTRY, &entry) == -1)
92         {
93                 Con_DPrintf("ioctl cdromreadtocentry failed\n");
94                 return -1;
95         }
96         if (entry.cdte_ctrl == CDROM_DATA_TRACK)
97         {
98                 Con_Printf("CDAudio: track %i is not audio\n", track);
99                 return -1;
100         }
101
102         if (cdPlaying)
103                 CDAudio_Stop();
104
105         ti.cdti_trk0 = track;
106         ti.cdti_trk1 = track;
107         ti.cdti_ind0 = 1;
108         ti.cdti_ind1 = 99;
109
110         if (ioctl(cdfile, CDROMPLAYTRKIND, &ti) == -1)
111         {
112                 Con_DPrintf("ioctl cdromplaytrkind failed\n");
113                 return -1;
114         }
115
116         if (ioctl(cdfile, CDROMRESUME) == -1)
117         {
118                 Con_DPrintf("ioctl cdromresume failed\n");
119                 return -1;
120         }
121
122         return 0;
123 }
124
125
126 int CDAudio_SysStop (void)
127 {
128         if (cdfile == -1)
129                 return -1;
130
131         if (ioctl(cdfile, CDROMSTOP) == -1)
132         {
133                 Con_DPrintf("ioctl cdromstop failed (%d)\n", errno);
134                 return -1;
135         }
136         
137         return 0;
138 }
139
140 int CDAudio_SysPause (void)
141 {
142         if (cdfile == -1)
143                 return -1;
144
145         if (ioctl(cdfile, CDROMPAUSE) == -1)
146         {
147                 Con_DPrintf("ioctl cdrompause failed\n");
148                 return -1;
149         }
150         
151         return 0;
152 }
153
154
155 int CDAudio_SysResume (void)
156 {
157         if (cdfile == -1)
158                 return -1;
159
160         if (ioctl(cdfile, CDROMRESUME) == -1)
161                 Con_DPrintf("ioctl cdromresume failed\n");
162
163         return 0;
164 }
165
166 int CDAudio_SysUpdate (void)
167 {
168         struct cdrom_subchnl subchnl;
169         static time_t lastchk = 0;
170
171         if (cdPlaying && lastchk < time(NULL)) {
172                 lastchk = time(NULL) + 2; //two seconds between chks
173                 subchnl.cdsc_format = CDROM_MSF;
174                 if (ioctl(cdfile, CDROMSUBCHNL, &subchnl) == -1 ) {
175                         Con_DPrintf("ioctl cdromsubchnl failed\n");
176                         cdPlaying = false;
177                         return -1;
178                 }
179                 if (subchnl.cdsc_audiostatus != CDROM_AUDIO_PLAY &&
180                         subchnl.cdsc_audiostatus != CDROM_AUDIO_PAUSED) {
181                         cdPlaying = false;
182                         if (cdPlayLooping)
183                                 CDAudio_Play(cdPlayTrack, true);
184                 }
185         }
186         
187         return 0;
188 }
189
190 void CDAudio_SysInit (void)
191 {
192         int i;
193
194         if ((i = COM_CheckParm("-cddev")) != 0 && i < com_argc - 1)
195                 strlcpy (cd_dev, com_argv[i + 1], sizeof (cd_dev));
196 }
197
198 int CDAudio_SysStartup (void)
199 {
200         if ((cdfile = open(cd_dev, O_RDONLY)) == -1)
201         {
202                 Con_DPrintf("CDAudio_SysStartup: open of \"%s\" failed (%i)\n", cd_dev, errno);
203                 cdfile = -1;
204                 return -1;
205         }
206
207         return 0;
208 }
209
210 void CDAudio_SysShutdown (void)
211 {
212         close(cdfile);
213         cdfile = -1;
214 }