comparison src/cdrom/mint/SDL_syscdrom.c @ 1895:c121d94672cb

SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author Sam Lantinga <slouken@libsdl.org>
date Mon, 10 Jul 2006 21:04:37 +0000
parents 92947e3a18db
children 99210400e8b9
comparison
equal deleted inserted replaced
1894:c69cee13dd76 1895:c121d94672cb
44 #define ERRNO_TRAYEMPTY(errno) \ 44 #define ERRNO_TRAYEMPTY(errno) \
45 ((errno == EIO) || (errno == ENOENT) || \ 45 ((errno == EIO) || (errno == ENOENT) || \
46 (errno == EINVAL) || (errno == ENOMEDIUM)) 46 (errno == EINVAL) || (errno == ENOMEDIUM))
47 47
48 /* The maximum number of CD-ROM drives we'll detect */ 48 /* The maximum number of CD-ROM drives we'll detect */
49 #define MAX_DRIVES 32 49 #define MAX_DRIVES 32
50 50
51 typedef struct { 51 typedef struct
52 unsigned char device[3]; /* Physical device letter + ':' + '\0' */ 52 {
53 metaopen_t metaopen; /* Infos on opened drive */ 53 unsigned char device[3]; /* Physical device letter + ':' + '\0' */
54 metaopen_t metaopen; /* Infos on opened drive */
54 } metados_drive_t; 55 } metados_drive_t;
55 56
56 static metados_drive_t metados_drives[MAX_DRIVES]; 57 static metados_drive_t metados_drives[MAX_DRIVES];
57 58
58 /* The system-dependent CD control functions */ 59 /* The system-dependent CD control functions */
59 static const char *SDL_SYS_CDName(int drive); 60 static const char *SDL_SYS_CDName(int drive);
60 static int SDL_SYS_CDOpen(int drive); 61 static int SDL_SYS_CDOpen(int drive);
61 static void SDL_SYS_CDClose(SDL_CD *cdrom); 62 static void SDL_SYS_CDClose(SDL_CD * cdrom);
62 static int SDL_SYS_CDioctl(int id, int command, void *arg); 63 static int SDL_SYS_CDioctl(int id, int command, void *arg);
63 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom); 64 static int SDL_SYS_CDGetTOC(SDL_CD * cdrom);
64 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position); 65 static CDstatus SDL_SYS_CDStatus(SDL_CD * cdrom, int *position);
65 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length); 66 static int SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length);
66 static int SDL_SYS_CDPause(SDL_CD *cdrom); 67 static int SDL_SYS_CDPause(SDL_CD * cdrom);
67 static int SDL_SYS_CDResume(SDL_CD *cdrom); 68 static int SDL_SYS_CDResume(SDL_CD * cdrom);
68 static int SDL_SYS_CDStop(SDL_CD *cdrom); 69 static int SDL_SYS_CDStop(SDL_CD * cdrom);
69 static int SDL_SYS_CDEject(SDL_CD *cdrom); 70 static int SDL_SYS_CDEject(SDL_CD * cdrom);
70 71
71 int SDL_SYS_CDInit(void) 72 int
72 { 73 SDL_SYS_CDInit(void)
73 metainit_t metainit={0,0,0,0}; 74 {
74 metaopen_t metaopen; 75 metainit_t metainit = { 0, 0, 0, 0 };
75 int i, handle; 76 metaopen_t metaopen;
76 struct cdrom_subchnl info; 77 int i, handle;
77 78 struct cdrom_subchnl info;
78 Metainit(&metainit); 79
79 if (metainit.version == NULL) { 80 Metainit(&metainit);
81 if (metainit.version == NULL) {
80 #ifdef DEBUG_CDROM 82 #ifdef DEBUG_CDROM
81 fprintf(stderr, "MetaDOS not installed\n"); 83 fprintf(stderr, "MetaDOS not installed\n");
82 #endif 84 #endif
83 return -1; 85 return -1;
84 } 86 }
85 87
86 if (metainit.drives_map == 0) { 88 if (metainit.drives_map == 0) {
87 #ifdef DEBUG_CDROM 89 #ifdef DEBUG_CDROM
88 fprintf(stderr, "No MetaDOS devices present\n"); 90 fprintf(stderr, "No MetaDOS devices present\n");
89 #endif 91 #endif
90 return -1; 92 return -1;
91 } 93 }
92 94
93 SDL_numcds = 0; 95 SDL_numcds = 0;
94 96
95 for (i='A'; i<='Z'; i++) { 97 for (i = 'A'; i <= 'Z'; i++) {
96 metados_drives[SDL_numcds].device[0] = 0; 98 metados_drives[SDL_numcds].device[0] = 0;
97 metados_drives[SDL_numcds].device[1] = ':'; 99 metados_drives[SDL_numcds].device[1] = ':';
98 metados_drives[SDL_numcds].device[2] = 0; 100 metados_drives[SDL_numcds].device[2] = 0;
99 101
100 if (metainit.drives_map & (1<<(i-'A'))) { 102 if (metainit.drives_map & (1 << (i - 'A'))) {
101 handle = Metaopen(i, &metaopen); 103 handle = Metaopen(i, &metaopen);
102 if (handle == 0) { 104 if (handle == 0) {
103 105
104 info.cdsc_format = CDROM_MSF; 106 info.cdsc_format = CDROM_MSF;
105 if ( (Metaioctl(i, METADOS_IOCTL_MAGIC, CDROMSUBCHNL, &info) == 0) || ERRNO_TRAYEMPTY(errno) ) { 107 if ((Metaioctl
106 metados_drives[SDL_numcds].device[0] = i; 108 (i, METADOS_IOCTL_MAGIC, CDROMSUBCHNL, &info) == 0)
107 ++SDL_numcds; 109 || ERRNO_TRAYEMPTY(errno)) {
108 } 110 metados_drives[SDL_numcds].device[0] = i;
109 111 ++SDL_numcds;
110 Metaclose(i); 112 }
111 } 113
112 } 114 Metaclose(i);
113 } 115 }
114 116 }
115 /* Fill in our driver capabilities */ 117 }
116 SDL_CDcaps.Name = SDL_SYS_CDName; 118
117 SDL_CDcaps.Open = SDL_SYS_CDOpen; 119 /* Fill in our driver capabilities */
118 SDL_CDcaps.Close = SDL_SYS_CDClose; 120 SDL_CDcaps.Name = SDL_SYS_CDName;
119 121 SDL_CDcaps.Open = SDL_SYS_CDOpen;
120 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; 122 SDL_CDcaps.Close = SDL_SYS_CDClose;
121 SDL_CDcaps.Status = SDL_SYS_CDStatus; 123
122 SDL_CDcaps.Play = SDL_SYS_CDPlay; 124 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC;
123 SDL_CDcaps.Pause = SDL_SYS_CDPause; 125 SDL_CDcaps.Status = SDL_SYS_CDStatus;
124 SDL_CDcaps.Resume = SDL_SYS_CDResume; 126 SDL_CDcaps.Play = SDL_SYS_CDPlay;
125 SDL_CDcaps.Stop = SDL_SYS_CDStop; 127 SDL_CDcaps.Pause = SDL_SYS_CDPause;
126 SDL_CDcaps.Eject = SDL_SYS_CDEject; 128 SDL_CDcaps.Resume = SDL_SYS_CDResume;
127 129 SDL_CDcaps.Stop = SDL_SYS_CDStop;
128 return 0; 130 SDL_CDcaps.Eject = SDL_SYS_CDEject;
129 } 131
130 132 return 0;
131 void SDL_SYS_CDQuit(void) 133 }
132 { 134
133 SDL_numcds = 0; 135 void
134 } 136 SDL_SYS_CDQuit(void)
135 137 {
136 static const char *SDL_SYS_CDName(int drive) 138 SDL_numcds = 0;
137 { 139 }
138 return(metados_drives[drive].device); 140
139 } 141 static const char *
140 142 SDL_SYS_CDName(int drive)
141 static int SDL_SYS_CDOpen(int drive) 143 {
142 { 144 return (metados_drives[drive].device);
143 int handle; 145 }
144 146
145 handle = Metaopen(metados_drives[drive].device[0], &(metados_drives[drive].metaopen)); 147 static int
146 if (handle == 0) { 148 SDL_SYS_CDOpen(int drive)
147 return drive; 149 {
148 } 150 int handle;
149 151
150 return -1; 152 handle =
151 } 153 Metaopen(metados_drives[drive].device[0],
152 154 &(metados_drives[drive].metaopen));
153 static void SDL_SYS_CDClose(SDL_CD *cdrom) 155 if (handle == 0) {
154 { 156 return drive;
155 Metaclose(metados_drives[cdrom->id].device[0]); 157 }
156 } 158
157 159 return -1;
158 static int SDL_SYS_CDioctl(int id, int command, void *arg) 160 }
159 { 161
160 int retval; 162 static void
161 163 SDL_SYS_CDClose(SDL_CD * cdrom)
162 retval = Metaioctl(metados_drives[id].device[0], METADOS_IOCTL_MAGIC, command, arg); 164 {
163 if ( retval < 0 ) { 165 Metaclose(metados_drives[cdrom->id].device[0]);
164 SDL_SetError("ioctl() error: %s", strerror(errno)); 166 }
165 } 167
166 return(retval); 168 static int
167 } 169 SDL_SYS_CDioctl(int id, int command, void *arg)
168 170 {
169 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) 171 int retval;
170 { 172
171 int i,okay; 173 retval =
172 struct cdrom_tochdr toc; 174 Metaioctl(metados_drives[id].device[0], METADOS_IOCTL_MAGIC, command,
173 struct cdrom_tocentry entry; 175 arg);
174 176 if (retval < 0) {
175 /* Use standard ioctl() */ 177 SDL_SetError("ioctl() error: %s", strerror(errno));
176 if (SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCHDR, &toc)<0) { 178 }
177 return -1; 179 return (retval);
178 } 180 }
179 181
180 cdrom->numtracks = toc.cdth_trk1-toc.cdth_trk0+1; 182 static int
181 if ( cdrom->numtracks > SDL_MAX_TRACKS ) { 183 SDL_SYS_CDGetTOC(SDL_CD * cdrom)
182 cdrom->numtracks = SDL_MAX_TRACKS; 184 {
183 } 185 int i, okay;
184 186 struct cdrom_tochdr toc;
185 /* Read all the track TOC entries */ 187 struct cdrom_tocentry entry;
186 okay=1; 188
187 for ( i=0; i<=cdrom->numtracks; ++i ) { 189 /* Use standard ioctl() */
188 if ( i == cdrom->numtracks ) { 190 if (SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCHDR, &toc) < 0) {
189 cdrom->track[i].id = CDROM_LEADOUT; 191 return -1;
190 } else { 192 }
191 cdrom->track[i].id = toc.cdth_trk0+i; 193
192 } 194 cdrom->numtracks = toc.cdth_trk1 - toc.cdth_trk0 + 1;
193 entry.cdte_track = cdrom->track[i].id; 195 if (cdrom->numtracks > SDL_MAX_TRACKS) {
194 entry.cdte_format = CDROM_MSF; 196 cdrom->numtracks = SDL_MAX_TRACKS;
195 if ( SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCENTRY, &entry) < 0 ) { 197 }
196 okay=0; 198
197 break; 199 /* Read all the track TOC entries */
198 } else { 200 okay = 1;
199 if ( entry.cdte_ctrl & CDROM_DATA_TRACK ) { 201 for (i = 0; i <= cdrom->numtracks; ++i) {
200 cdrom->track[i].type = SDL_DATA_TRACK; 202 if (i == cdrom->numtracks) {
201 } else { 203 cdrom->track[i].id = CDROM_LEADOUT;
202 cdrom->track[i].type = SDL_AUDIO_TRACK; 204 } else {
203 } 205 cdrom->track[i].id = toc.cdth_trk0 + i;
204 cdrom->track[i].offset = MSF_TO_FRAMES( 206 }
205 entry.cdte_addr.msf.minute, 207 entry.cdte_track = cdrom->track[i].id;
206 entry.cdte_addr.msf.second, 208 entry.cdte_format = CDROM_MSF;
207 entry.cdte_addr.msf.frame); 209 if (SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCENTRY, &entry) < 0) {
208 cdrom->track[i].length = 0; 210 okay = 0;
209 if ( i > 0 ) { 211 break;
210 cdrom->track[i-1].length = cdrom->track[i].offset-cdrom->track[i-1].offset; 212 } else {
211 } 213 if (entry.cdte_ctrl & CDROM_DATA_TRACK) {
212 } 214 cdrom->track[i].type = SDL_DATA_TRACK;
213 } 215 } else {
214 216 cdrom->track[i].type = SDL_AUDIO_TRACK;
215 return(okay ? 0 : -1); 217 }
218 cdrom->track[i].offset =
219 MSF_TO_FRAMES(entry.cdte_addr.msf.minute,
220 entry.cdte_addr.msf.second,
221 entry.cdte_addr.msf.frame);
222 cdrom->track[i].length = 0;
223 if (i > 0) {
224 cdrom->track[i - 1].length =
225 cdrom->track[i].offset - cdrom->track[i - 1].offset;
226 }
227 }
228 }
229
230 return (okay ? 0 : -1);
216 } 231 }
217 232
218 /* Get CD-ROM status */ 233 /* Get CD-ROM status */
219 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) 234 static CDstatus
220 { 235 SDL_SYS_CDStatus(SDL_CD * cdrom, int *position)
221 CDstatus status; 236 {
222 struct cdrom_tochdr toc; 237 CDstatus status;
223 struct cdrom_subchnl info; 238 struct cdrom_tochdr toc;
224 239 struct cdrom_subchnl info;
225 info.cdsc_format = CDROM_MSF; 240
226 if ( SDL_SYS_CDioctl(cdrom->id, CDROMSUBCHNL, &info) < 0 ) { 241 info.cdsc_format = CDROM_MSF;
227 if ( ERRNO_TRAYEMPTY(errno) ) { 242 if (SDL_SYS_CDioctl(cdrom->id, CDROMSUBCHNL, &info) < 0) {
228 status = CD_TRAYEMPTY; 243 if (ERRNO_TRAYEMPTY(errno)) {
229 } else { 244 status = CD_TRAYEMPTY;
230 status = CD_ERROR; 245 } else {
231 } 246 status = CD_ERROR;
232 } else { 247 }
233 switch (info.cdsc_audiostatus) { 248 } else {
234 case CDROM_AUDIO_INVALID: 249 switch (info.cdsc_audiostatus) {
235 case CDROM_AUDIO_NO_STATUS: 250 case CDROM_AUDIO_INVALID:
236 /* Try to determine if there's a CD available */ 251 case CDROM_AUDIO_NO_STATUS:
237 if (SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCHDR, &toc)==0) { 252 /* Try to determine if there's a CD available */
238 status = CD_STOPPED; 253 if (SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCHDR, &toc) == 0) {
239 } else { 254 status = CD_STOPPED;
240 status = CD_TRAYEMPTY; 255 } else {
241 } 256 status = CD_TRAYEMPTY;
242 break; 257 }
243 case CDROM_AUDIO_COMPLETED: 258 break;
244 status = CD_STOPPED; 259 case CDROM_AUDIO_COMPLETED:
245 break; 260 status = CD_STOPPED;
246 case CDROM_AUDIO_PLAY: 261 break;
247 status = CD_PLAYING; 262 case CDROM_AUDIO_PLAY:
248 break; 263 status = CD_PLAYING;
249 case CDROM_AUDIO_PAUSED: 264 break;
250 /* Workaround buggy CD-ROM drive */ 265 case CDROM_AUDIO_PAUSED:
251 if ( info.cdsc_trk == CDROM_LEADOUT ) { 266 /* Workaround buggy CD-ROM drive */
252 status = CD_STOPPED; 267 if (info.cdsc_trk == CDROM_LEADOUT) {
253 } else { 268 status = CD_STOPPED;
254 status = CD_PAUSED; 269 } else {
255 } 270 status = CD_PAUSED;
256 break; 271 }
257 default: 272 break;
258 status = CD_ERROR; 273 default:
259 break; 274 status = CD_ERROR;
260 } 275 break;
261 } 276 }
262 if ( position ) { 277 }
263 if ( status == CD_PLAYING || (status == CD_PAUSED) ) { 278 if (position) {
264 *position = MSF_TO_FRAMES( 279 if (status == CD_PLAYING || (status == CD_PAUSED)) {
265 info.cdsc_absaddr.msf.minute, 280 *position = MSF_TO_FRAMES(info.cdsc_absaddr.msf.minute,
266 info.cdsc_absaddr.msf.second, 281 info.cdsc_absaddr.msf.second,
267 info.cdsc_absaddr.msf.frame); 282 info.cdsc_absaddr.msf.frame);
268 } else { 283 } else {
269 *position = 0; 284 *position = 0;
270 } 285 }
271 } 286 }
272 return(status); 287 return (status);
273 } 288 }
274 289
275 /* Start play */ 290 /* Start play */
276 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) 291 static int
277 { 292 SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length)
278 struct cdrom_msf playtime; 293 {
279 294 struct cdrom_msf playtime;
280 FRAMES_TO_MSF(start, 295
281 &playtime.cdmsf_min0, &playtime.cdmsf_sec0, &playtime.cdmsf_frame0); 296 FRAMES_TO_MSF(start,
282 FRAMES_TO_MSF(start+length, 297 &playtime.cdmsf_min0, &playtime.cdmsf_sec0,
283 &playtime.cdmsf_min1, &playtime.cdmsf_sec1, &playtime.cdmsf_frame1); 298 &playtime.cdmsf_frame0);
299 FRAMES_TO_MSF(start + length, &playtime.cdmsf_min1, &playtime.cdmsf_sec1,
300 &playtime.cdmsf_frame1);
284 #ifdef DEBUG_CDROM 301 #ifdef DEBUG_CDROM
285 fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", 302 fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n",
286 playtime.cdmsf_min0, playtime.cdmsf_sec0, playtime.cdmsf_frame0, 303 playtime.cdmsf_min0, playtime.cdmsf_sec0, playtime.cdmsf_frame0,
287 playtime.cdmsf_min1, playtime.cdmsf_sec1, playtime.cdmsf_frame1); 304 playtime.cdmsf_min1, playtime.cdmsf_sec1, playtime.cdmsf_frame1);
288 #endif 305 #endif
289 306
290 return SDL_SYS_CDioctl(cdrom->id, CDROMPLAYMSF, &playtime); 307 return SDL_SYS_CDioctl(cdrom->id, CDROMPLAYMSF, &playtime);
291 } 308 }
292 309
293 /* Pause play */ 310 /* Pause play */
294 static int SDL_SYS_CDPause(SDL_CD *cdrom) 311 static int
295 { 312 SDL_SYS_CDPause(SDL_CD * cdrom)
296 return SDL_SYS_CDioctl(cdrom->id, CDROMPAUSE, 0); 313 {
314 return SDL_SYS_CDioctl(cdrom->id, CDROMPAUSE, 0);
297 } 315 }
298 316
299 /* Resume play */ 317 /* Resume play */
300 static int SDL_SYS_CDResume(SDL_CD *cdrom) 318 static int
301 { 319 SDL_SYS_CDResume(SDL_CD * cdrom)
302 return SDL_SYS_CDioctl(cdrom->id, CDROMRESUME, 0); 320 {
321 return SDL_SYS_CDioctl(cdrom->id, CDROMRESUME, 0);
303 } 322 }
304 323
305 /* Stop play */ 324 /* Stop play */
306 static int SDL_SYS_CDStop(SDL_CD *cdrom) 325 static int
307 { 326 SDL_SYS_CDStop(SDL_CD * cdrom)
308 return SDL_SYS_CDioctl(cdrom->id, CDROMSTOP, 0); 327 {
328 return SDL_SYS_CDioctl(cdrom->id, CDROMSTOP, 0);
309 } 329 }
310 330
311 /* Eject the CD-ROM */ 331 /* Eject the CD-ROM */
312 static int SDL_SYS_CDEject(SDL_CD *cdrom) 332 static int
313 { 333 SDL_SYS_CDEject(SDL_CD * cdrom)
314 return SDL_SYS_CDioctl(cdrom->id, CDROMEJECT, 0); 334 {
335 return SDL_SYS_CDioctl(cdrom->id, CDROMEJECT, 0);
315 } 336 }
316 337
317 #endif /* SDL_CDROM_MINT */ 338 #endif /* SDL_CDROM_MINT */
339 /* vi: set ts=4 sw=4 expandtab: */