The Linux CD module now uses O_NONBLOCK when opening the CDROM device to avoid failur...
[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 static int cdfile = -1;
35 static char cd_dev[64] = "/dev/cdrom";
36
37
38 void CDAudio_SysEject (void)
39 {
40         if (cdfile == -1)
41                 return;
42
43         if (ioctl(cdfile, CDROMEJECT) == -1)
44                 Con_DPrint("ioctl CDROMEJECT failed\n");
45 }
46
47
48 void CDAudio_SysCloseDoor (void)
49 {
50         if (cdfile == -1)
51                 return;
52
53         if (ioctl(cdfile, CDROMCLOSETRAY) == -1)
54                 Con_DPrint("ioctl CDROMCLOSETRAY failed\n");
55 }
56
57 int CDAudio_SysGetAudioDiskInfo (void)
58 {
59         struct cdrom_tochdr tochdr;
60
61         if (cdfile == -1)
62                 return -1;
63
64         if (ioctl(cdfile, CDROMREADTOCHDR, &tochdr) == -1)
65         {
66                 Con_DPrint("ioctl CDROMREADTOCHDR failed\n");
67                 return -1;
68         }
69
70         if (tochdr.cdth_trk0 < 1)
71         {
72                 Con_DPrint("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_DPrint("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_DPrint("ioctl CDROMPLAYTRKIND failed\n");
113                 return -1;
114         }
115
116         if (ioctl(cdfile, CDROMRESUME) == -1)
117         {
118                 Con_DPrint("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_DPrint("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_DPrint("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         {
173                 lastchk = time(NULL) + 2; //two seconds between chks
174                 subchnl.cdsc_format = CDROM_MSF;
175                 if (ioctl(cdfile, CDROMSUBCHNL, &subchnl) == -1)
176                 {
177                         Con_DPrint("ioctl CDROMSUBCHNL failed\n");
178                         cdPlaying = false;
179                         return -1;
180                 }
181                 if (subchnl.cdsc_audiostatus != CDROM_AUDIO_PLAY &&
182                         subchnl.cdsc_audiostatus != CDROM_AUDIO_PAUSED)
183                 {
184                         cdPlaying = false;
185                         if (cdPlayLooping)
186                                 CDAudio_Play(cdPlayTrack, true);
187                 }
188                 else
189                         cdPlayTrack = subchnl.cdsc_trk;
190         }
191
192         return 0;
193 }
194
195 void CDAudio_SysInit (void)
196 {
197         int i;
198
199         if ((i = COM_CheckParm("-cddev")) != 0 && i < com_argc - 1)
200                 strlcpy(cd_dev, com_argv[i + 1], sizeof(cd_dev));
201 }
202
203 int CDAudio_SysStartup (void)
204 {
205         if ((cdfile = open(cd_dev, O_RDONLY | O_NONBLOCK)) == -1)
206         {
207                 Con_DPrintf("CDAudio_SysStartup: open of \"%s\" failed (%i)\n",
208                                         cd_dev, errno);
209                 cdfile = -1;
210                 return -1;
211         }
212
213         return 0;
214 }
215
216 void CDAudio_SysShutdown (void)
217 {
218         close(cdfile);
219         cdfile = -1;
220 }