Mercurial > sdl-ios-xcode
annotate src/cdrom/aix/SDL_syscdrom.c @ 1554:0ca607a5d173
Fixed bug #84
Date: Sun, 23 Oct 2005 16:39:03 +0200
From: "A. Schmid" <sahib@phreaker.net>
Subject: [SDL] no software surfaces with svgalib driver?
Hi,
I noticed that the SDL (1.2.9) svgalib driver only makes use of linear
addressable (framebuffer) video modes. On older systems (like one of
mine), linear addressable modes are often not available.
Especially for cards with VESA VBE < 2.0 the svgalib vesa driver is
unusable, since VESA only supports framebuffering for VBE 2.0 and later.
The changes necessary to add support for software surfaces seem to be
relatively small. I only had to hack src/video/svga/SDL_svgavideo.c (see
attached patch). The code worked fine for me, but it is no more than a
proof of concept and should be reviewed (probably has a memory leak when
switching modes). It also uses the vgagl library (included in the
svgalib package) and needs to be linked against it.
-Alex
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 19 Mar 2006 12:04:40 +0000 |
parents | d910939febfa |
children | 92947e3a18db |
rev | line source |
---|---|
0 | 1 /* |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
2 SDL - Simple DirectMedia Layer |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
3 Copyright (C) 1997-2006 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
6 modify it under the terms of the GNU Lesser General Public |
0 | 7 License as published by the Free Software Foundation; either |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
8 version 2.1 of the License, or (at your option) any later version. |
0 | 9 |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
13 Lesser General Public License for more details. |
0 | 14 |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
15 You should have received a copy of the GNU Lesser General Public |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
16 License along with this library; if not, write to the Free Software |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 18 |
19 Carsten Griwodz | |
20 griff@kom.tu-darmstadt.de | |
21 | |
22 based on linux/SDL_syscdrom.c by Sam Lantinga | |
23 */ | |
1402
d910939febfa
Use consistent identifiers for the various platforms we support.
Sam Lantinga <slouken@libsdl.org>
parents:
1379
diff
changeset
|
24 #include "SDL_config.h" |
0 | 25 |
26 /* Functions for system-level CD-ROM audio control */ | |
27 | |
1361
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1358
diff
changeset
|
28 /*#define DEBUG_CDROM 1*/ |
0 | 29 |
30 #include <sys/types.h> | |
31 #include <sys/stat.h> | |
32 #include <fcntl.h> | |
33 #include <errno.h> | |
34 #include <unistd.h> | |
35 | |
36 #include <sys/ioctl.h> | |
37 #include <sys/devinfo.h> | |
38 #include <sys/mntctl.h> | |
39 #include <sys/statfs.h> | |
40 #include <sys/vmount.h> | |
41 #include <fstab.h> | |
42 #include <sys/scdisk.h> | |
43 | |
44 #include "SDL_cdrom.h" | |
1361
19418e4422cb
New configure-based build system. Still work in progress, but much improved
Sam Lantinga <slouken@libsdl.org>
parents:
1358
diff
changeset
|
45 #include "../SDL_syscdrom.h" |
0 | 46 |
47 /* The maximum number of CD-ROM drives we'll detect */ | |
48 #define MAX_DRIVES 16 | |
49 | |
50 /* A list of available CD-ROM drives */ | |
51 static char *SDL_cdlist[MAX_DRIVES]; | |
52 static dev_t SDL_cdmode[MAX_DRIVES]; | |
53 | |
54 /* The system-dependent CD control functions */ | |
55 static const char *SDL_SYS_CDName(int drive); | |
56 static int SDL_SYS_CDOpen(int drive); | |
57 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom); | |
58 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position); | |
59 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length); | |
60 static int SDL_SYS_CDPause(SDL_CD *cdrom); | |
61 static int SDL_SYS_CDResume(SDL_CD *cdrom); | |
62 static int SDL_SYS_CDStop(SDL_CD *cdrom); | |
63 static int SDL_SYS_CDEject(SDL_CD *cdrom); | |
64 static void SDL_SYS_CDClose(SDL_CD *cdrom); | |
65 static int SDL_SYS_CDioctl(int id, int command, void *arg); | |
66 | |
67 /* Check a drive to see if it is a CD-ROM */ | |
68 static int CheckDrive(char *drive, struct stat *stbuf) | |
69 { | |
70 int is_cd; | |
71 int cdfd; | |
72 int ret; | |
73 struct devinfo info; | |
74 | |
75 /* If it doesn't exist, return -1 */ | |
76 if ( stat(drive, stbuf) < 0 ) { | |
77 return -1; | |
78 } | |
79 | |
80 /* If it does exist, verify that it's an available CD-ROM */ | |
81 is_cd = 0; | |
82 if ( S_ISCHR(stbuf->st_mode) || S_ISBLK(stbuf->st_mode) ) { | |
83 cdfd = open(drive, (O_RDONLY|O_EXCL|O_NONBLOCK), 0); | |
84 if ( cdfd >= 0 ) { | |
85 ret = SDL_SYS_CDioctl( cdfd, IOCINFO, &info ); | |
86 if ( ret < 0 ) { | |
87 /* Some kind of error */ | |
88 is_cd = 0; | |
89 } else { | |
90 if ( info.devtype == DD_CDROM ) { | |
91 is_cd = 1; | |
92 } else { | |
93 is_cd = 0; | |
94 } | |
95 } | |
96 close(cdfd); | |
97 } | |
98 #ifdef DEBUG_CDROM | |
99 else | |
100 { | |
101 fprintf(stderr, "Could not open drive %s (%s)\n", drive, strerror(errno)); | |
102 } | |
103 #endif | |
104 } | |
105 return is_cd; | |
106 } | |
107 | |
108 /* Add a CD-ROM drive to our list of valid drives */ | |
109 static void AddDrive(char *drive, struct stat *stbuf) | |
110 { | |
111 int i; | |
112 | |
113 if ( SDL_numcds < MAX_DRIVES ) { | |
114 /* Check to make sure it's not already in our list. | |
115 This can happen when we see a drive via symbolic link. | |
116 */ | |
117 for ( i=0; i<SDL_numcds; ++i ) { | |
118 if ( stbuf->st_rdev == SDL_cdmode[i] ) { | |
119 #ifdef DEBUG_CDROM | |
120 fprintf(stderr, "Duplicate drive detected: %s == %s\n", drive, SDL_cdlist[i]); | |
121 #endif | |
122 return; | |
123 } | |
124 } | |
125 | |
126 /* Add this drive to our list */ | |
127 i = SDL_numcds; | |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
128 SDL_cdlist[i] = SDL_strdup(drive); |
0 | 129 if ( SDL_cdlist[i] == NULL ) { |
130 SDL_OutOfMemory(); | |
131 return; | |
132 } | |
133 SDL_cdmode[i] = stbuf->st_rdev; | |
134 ++SDL_numcds; | |
135 #ifdef DEBUG_CDROM | |
136 fprintf(stderr, "Added CD-ROM drive: %s\n", drive); | |
137 #endif | |
138 } | |
139 } | |
140 | |
141 static void CheckMounts() | |
142 { | |
143 char* buffer; | |
144 int bufsz; | |
145 struct vmount* ptr; | |
146 int ret; | |
147 | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
148 buffer = (char*)SDL_malloc(10); |
0 | 149 bufsz = 10; |
150 if ( buffer==NULL ) | |
151 { | |
152 fprintf(stderr, "Could not allocate 10 bytes in aix/SDL_syscdrom.c:CheckMounts\n" ); | |
153 exit ( -10 ); | |
154 } | |
155 | |
156 do | |
157 { | |
158 /* mntctrl() returns an array of all mounted filesystems */ | |
159 ret = mntctl ( MCTL_QUERY, bufsz, buffer ); | |
160 if ( ret == 0 ) | |
161 { | |
162 /* Buffer was too small, realloc. */ | |
163 bufsz = *(int*)buffer; /* Required size is in first word. */ | |
164 /* (whatever a word is in AIX 4.3.3) */ | |
165 /* int seems to be OK in 32bit mode. */ | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
166 SDL_free(buffer); |
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
167 buffer = (char*)SDL_malloc(bufsz); |
0 | 168 if ( buffer==NULL ) |
169 { | |
170 fprintf(stderr, | |
171 "Could not allocate %d bytes in aix/SDL_syscdrom.c:CheckMounts\n", | |
172 bufsz ); | |
173 exit ( -10 ); | |
174 } | |
175 } | |
176 else if ( ret < 0 ) | |
177 { | |
178 #ifdef DEBUG_CDROM | |
179 fprintf(stderr, "Error reading vmount structures\n"); | |
180 #endif | |
181 return; | |
182 } | |
183 } | |
184 while ( ret == 0 ); | |
185 | |
186 #ifdef DEBUG_CDROM | |
187 fprintf ( stderr, "Read %d vmount structures\n",ret ); | |
188 #endif | |
189 ptr = (struct vmount*)buffer; | |
190 do | |
191 { | |
192 switch(ptr->vmt_gfstype) | |
193 { | |
194 case MNT_CDROM : | |
195 { | |
196 struct stat stbuf; | |
197 char* text; | |
198 | |
199 text = (char*)ptr + ptr->vmt_data[VMT_OBJECT].vmt_off; | |
200 #ifdef DEBUG_CDROM | |
201 fprintf(stderr, "Checking mount path: %s mounted on %s\n", | |
202 text, (char*)ptr + ptr->vmt_data[VMT_STUB].vmt_off ); | |
203 #endif | |
204 if ( CheckDrive( text, &stbuf) > 0) | |
205 { | |
206 AddDrive( text, &stbuf); | |
207 } | |
208 } | |
209 break; | |
210 default : | |
211 break; | |
212 } | |
213 ptr = (struct vmount*)((char*)ptr + ptr->vmt_length); | |
214 ret--; | |
215 } | |
216 while ( ret > 0 ); | |
217 | |
218 free ( buffer ); | |
219 } | |
220 | |
221 static int CheckNonmounts() | |
222 { | |
223 #ifdef _THREAD_SAFE | |
224 AFILE_t fsFile = NULL; | |
225 int passNo = 0; | |
226 int ret; | |
227 struct fstab entry; | |
228 struct stat stbuf; | |
229 | |
230 ret = setfsent_r( &fsFile, &passNo ); | |
231 if ( ret != 0 ) return -1; | |
232 do | |
233 { | |
234 ret = getfsent_r ( &entry, &fsFile, &passNo ); | |
235 if ( ret == 0 ) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
236 char* l = SDL_strrchr(entry.fs_spec,'/'); |
0 | 237 if ( l != NULL ) { |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
238 if ( !SDL_strncmp("cd",++l,2) ) { |
0 | 239 #ifdef DEBUG_CDROM |
240 fprintf(stderr, | |
241 "Found unmounted CD ROM drive with device name %s\n", | |
242 entry.fs_spec); | |
243 #endif | |
244 if ( CheckDrive( entry.fs_spec, &stbuf) > 0) | |
245 { | |
246 AddDrive( entry.fs_spec, &stbuf); | |
247 } | |
248 } | |
249 } | |
250 } | |
251 } | |
252 while ( ret == 0 ); | |
253 ret = endfsent_r ( &fsFile ); | |
254 if ( ret != 0 ) return -1; | |
255 return 0; | |
256 #else | |
257 struct fstab* entry; | |
258 struct stat stbuf; | |
259 | |
260 setfsent(); | |
261 do | |
262 { | |
263 entry = getfsent(); | |
264 if ( entry != NULL ) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
265 char* l = SDL_strrchr(entry->fs_spec,'/'); |
0 | 266 if ( l != NULL ) { |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
267 if ( !SDL_strncmp("cd",++l,2) ) { |
0 | 268 #ifdef DEBUG_CDROM |
269 fprintf(stderr,"Found unmounted CD ROM drive with device name %s", entry->fs_spec); | |
270 #endif | |
271 if ( CheckDrive( entry->fs_spec, &stbuf) > 0) | |
272 { | |
273 AddDrive( entry->fs_spec, &stbuf); | |
274 } | |
275 } | |
276 } | |
277 } | |
278 } | |
279 while ( entry != NULL ); | |
280 endfsent(); | |
281 #endif | |
282 } | |
283 | |
284 int SDL_SYS_CDInit(void) | |
285 { | |
286 char *SDLcdrom; | |
287 struct stat stbuf; | |
288 | |
289 /* Fill in our driver capabilities */ | |
290 SDL_CDcaps.Name = SDL_SYS_CDName; | |
291 SDL_CDcaps.Open = SDL_SYS_CDOpen; | |
292 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; | |
293 SDL_CDcaps.Status = SDL_SYS_CDStatus; | |
294 SDL_CDcaps.Play = SDL_SYS_CDPlay; | |
295 SDL_CDcaps.Pause = SDL_SYS_CDPause; | |
296 SDL_CDcaps.Resume = SDL_SYS_CDResume; | |
297 SDL_CDcaps.Stop = SDL_SYS_CDStop; | |
298 SDL_CDcaps.Eject = SDL_SYS_CDEject; | |
299 SDL_CDcaps.Close = SDL_SYS_CDClose; | |
300 | |
301 /* Look in the environment for our CD-ROM drive list */ | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
302 SDLcdrom = SDL_getenv("SDL_CDROM"); /* ':' separated list of devices */ |
0 | 303 if ( SDLcdrom != NULL ) { |
304 char *cdpath, *delim; | |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
305 size_t len = SDL_strlen(SDLcdrom)+1; |
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
306 cdpath = SDL_stack_alloc(char, len); |
0 | 307 if ( cdpath != NULL ) { |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
308 SDL_strlcpy(cdpath, SDLcdrom, len); |
0 | 309 SDLcdrom = cdpath; |
310 do { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
311 delim = SDL_strchr(SDLcdrom, ':'); |
0 | 312 if ( delim ) { |
313 *delim++ = '\0'; | |
314 } | |
315 #ifdef DEBUG_CDROM | |
316 fprintf(stderr, "Checking CD-ROM drive from SDL_CDROM: %s\n", SDLcdrom); | |
317 #endif | |
318 if ( CheckDrive(SDLcdrom, &stbuf) > 0 ) { | |
319 AddDrive(SDLcdrom, &stbuf); | |
320 } | |
321 if ( delim ) { | |
322 SDLcdrom = delim; | |
323 } else { | |
324 SDLcdrom = NULL; | |
325 } | |
326 } while ( SDLcdrom ); | |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
327 SDL_stack_free(cdpath); |
0 | 328 } |
329 | |
330 /* If we found our drives, there's nothing left to do */ | |
331 if ( SDL_numcds > 0 ) { | |
332 return(0); | |
333 } | |
334 } | |
335 | |
336 CheckMounts(); | |
337 CheckNonmounts(); | |
338 | |
339 return 0; | |
340 } | |
341 | |
342 /* General ioctl() CD-ROM command function */ | |
343 static int SDL_SYS_CDioctl(int id, int command, void *arg) | |
344 { | |
345 int retval; | |
346 | |
347 retval = ioctl(id, command, arg); | |
348 if ( retval < 0 ) { | |
349 SDL_SetError("ioctl() error: %s", strerror(errno)); | |
350 } | |
351 return retval; | |
352 } | |
353 | |
354 static const char *SDL_SYS_CDName(int drive) | |
355 { | |
356 return(SDL_cdlist[drive]); | |
357 } | |
358 | |
359 static int SDL_SYS_CDOpen(int drive) | |
360 { | |
361 int fd; | |
362 char* lastsl; | |
363 char* cdromname; | |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
364 size_t len; |
0 | 365 |
366 /* | |
367 * We found /dev/cd? drives and that is in our list. But we can | |
368 * open only the /dev/rcd? versions of those devices for Audio CD. | |
369 */ | |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
370 len = SDL_strlen(SDL_cdlist[drive])+2; |
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
371 cdromname = (char*)SDL_malloc(len); |
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
372 SDL_strlcpy(cdromname,SDL_cdlist[drive],len); |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
373 lastsl = SDL_strrchr(cdromname,'/'); |
0 | 374 if (lastsl) { |
375 *lastsl = 0; | |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
376 SDL_strlcat(cdromname,"/r",len); |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
377 lastsl = SDL_strrchr(SDL_cdlist[drive],'/'); |
0 | 378 if (lastsl) { |
379 lastsl++; | |
1379
c0a74f199ecf
Use only safe string functions
Sam Lantinga <slouken@libsdl.org>
parents:
1361
diff
changeset
|
380 SDL_strlcat(cdromname,lastsl,len); |
0 | 381 } |
382 } | |
383 | |
384 #ifdef DEBUG_CDROM | |
385 fprintf(stderr, "Should open drive %s, opening %s\n", SDL_cdlist[drive], cdromname); | |
386 #endif | |
387 | |
388 /* | |
389 * Use exclusive access. Don't use SC_DIAGNOSTICS as xmcd does because they | |
390 * require root priviledges, and we don't want that. SC_SINGLE provides | |
391 * exclusive access with less trouble. | |
392 */ | |
393 fd = openx(cdromname, O_RDONLY, NULL, SC_SINGLE); | |
394 if ( fd < 0 ) | |
395 { | |
396 #ifdef DEBUG_CDROM | |
397 fprintf(stderr, "Could not open drive %s (%s)\n", cdromname, strerror(errno)); | |
398 #endif | |
399 } | |
400 else | |
401 { | |
402 struct mode_form_op cdMode; | |
403 int ret; | |
404 #ifdef DEBUG_CDROM | |
405 cdMode.action = CD_GET_MODE; | |
406 ret = SDL_SYS_CDioctl(fd, DK_CD_MODE, &cdMode); | |
407 if ( ret < 0 ) { | |
408 fprintf(stderr, | |
409 "Could not get drive mode for %s (%s)\n", | |
410 cdromname, strerror(errno)); | |
411 } else { | |
412 switch(cdMode.cd_mode_form) { | |
413 case CD_MODE1 : | |
414 fprintf(stderr, | |
415 "Drive mode for %s is %s\n", | |
416 cdromname, "CD-ROM Data Mode 1"); | |
417 break; | |
418 case CD_MODE2_FORM1 : | |
419 fprintf(stderr, | |
420 "Drive mode for %s is %s\n", | |
421 cdromname, "CD-ROM XA Data Mode 2 Form 1"); | |
422 break; | |
423 case CD_MODE2_FORM2 : | |
424 fprintf(stderr, | |
425 "Drive mode for %s is %s\n", | |
426 cdromname, "CD-ROM XA Data Mode 2 Form 2"); | |
427 break; | |
428 case CD_DA : | |
429 fprintf(stderr, | |
430 "Drive mode for %s is %s\n", | |
431 cdromname, "CD-DA"); | |
432 break; | |
433 default : | |
434 fprintf(stderr, | |
435 "Drive mode for %s is %s\n", | |
436 cdromname, "unknown"); | |
437 break; | |
438 } | |
439 } | |
440 #endif | |
441 | |
442 cdMode.action = CD_CHG_MODE; | |
443 cdMode.cd_mode_form = CD_DA; | |
444 ret = SDL_SYS_CDioctl(fd, DK_CD_MODE, &cdMode); | |
445 if ( ret < 0 ) { | |
446 #ifdef DEBUG_CDROM | |
447 fprintf(stderr, | |
448 "Could not set drive mode for %s (%s)\n", | |
449 cdromname, strerror(errno)); | |
450 #endif | |
451 SDL_SetError("ioctl() error: Could not set CD drive mode, %s", | |
452 strerror(errno)); | |
453 } else { | |
454 #ifdef DEBUG_CDROM | |
455 fprintf(stderr, | |
456 "Drive mode for %s set to CD_DA\n", | |
457 cdromname); | |
458 #endif | |
459 } | |
460 } | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
461 SDL_free(cdromname); |
0 | 462 return fd; |
463 } | |
464 | |
465 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) | |
466 { | |
467 struct cd_audio_cmd cmd; | |
468 struct cd_audio_cmd entry; | |
469 int i; | |
470 int okay; | |
471 | |
472 cmd.audio_cmds = CD_TRK_INFO_AUDIO; | |
473 cmd.msf_flag = FALSE; | |
474 if ( SDL_SYS_CDioctl(cdrom->id, DKAUDIO, &cmd) < 0 ) { | |
475 return -1; | |
476 } | |
477 | |
478 okay = 0; | |
479 cdrom->numtracks = cmd.indexing.track_index.last_track | |
480 - cmd.indexing.track_index.first_track+1; | |
481 if ( cdrom->numtracks > SDL_MAX_TRACKS ) { | |
482 cdrom->numtracks = SDL_MAX_TRACKS; | |
483 } | |
484 | |
485 /* Read all the track TOC entries */ | |
486 for ( i=0; i<=cdrom->numtracks; ++i ) { | |
487 if ( i == cdrom->numtracks ) { | |
488 cdrom->track[i].id = 0xAA;; | |
489 } else { | |
490 cdrom->track[i].id = cmd.indexing.track_index.first_track+i; | |
491 } | |
492 entry.audio_cmds = CD_GET_TRK_MSF; | |
493 entry.indexing.track_msf.track = cdrom->track[i].id; | |
494 if ( SDL_SYS_CDioctl(cdrom->id, DKAUDIO, &entry) < 0 ) { | |
495 break; | |
496 } else { | |
497 cdrom->track[i].type = 0; /* don't know how to detect 0x04 data track */ | |
498 cdrom->track[i].offset = MSF_TO_FRAMES( | |
499 entry.indexing.track_msf.mins, | |
500 entry.indexing.track_msf.secs, | |
501 entry.indexing.track_msf.frames); | |
502 cdrom->track[i].length = 0; | |
503 if ( i > 0 ) { | |
504 cdrom->track[i-1].length = cdrom->track[i].offset | |
505 - cdrom->track[i-1].offset; | |
506 } | |
507 } | |
508 } | |
509 if ( i == (cdrom->numtracks+1) ) { | |
510 okay = 1; | |
511 } | |
512 return(okay ? 0 : -1); | |
513 } | |
514 | |
515 /* Get CD-ROM status */ | |
516 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) | |
517 { | |
518 CDstatus status; | |
519 struct cd_audio_cmd cmd; | |
520 cmd.audio_cmds = CD_INFO_AUDIO; | |
521 | |
522 if ( SDL_SYS_CDioctl(cdrom->id, DKAUDIO, &cmd) < 0 ) { | |
523 #ifdef DEBUG_CDROM | |
524 fprintf(stderr, "ioctl failed in SDL_SYS_CDStatus (%s)\n", SDL_GetError()); | |
525 #endif | |
526 status = CD_ERROR; | |
527 } else { | |
528 switch (cmd.status) { | |
529 case CD_NO_AUDIO: | |
530 case CD_COMPLETED: | |
531 status = CD_STOPPED; | |
532 break; | |
533 case CD_PLAY_AUDIO: | |
534 status = CD_PLAYING; | |
535 break; | |
536 case CD_PAUSE_AUDIO: | |
537 status = CD_PAUSED; | |
538 break; | |
539 case CD_NOT_VALID: | |
540 #ifdef DEBUG_CDROM | |
541 fprintf(stderr, "cdStatus failed with CD_NOT_VALID\n"); | |
542 #endif | |
543 status = CD_ERROR; | |
544 break; | |
545 case CD_STATUS_ERROR: | |
546 #ifdef DEBUG_CDROM | |
547 fprintf(stderr, "cdStatus failed with CD_STATUS_ERROR\n"); | |
548 #endif | |
549 status = CD_ERROR; | |
550 break; | |
551 default: | |
552 #ifdef DEBUG_CDROM | |
553 fprintf(stderr, "cdStatus failed with unknown error\n"); | |
554 #endif | |
555 status = CD_ERROR; | |
556 break; | |
557 } | |
558 } | |
559 if ( position ) { | |
560 if ( status == CD_PLAYING || (status == CD_PAUSED) ) { | |
561 *position = MSF_TO_FRAMES( cmd.indexing.info_audio.current_mins, | |
562 cmd.indexing.info_audio.current_secs, | |
563 cmd.indexing.info_audio.current_frames); | |
564 } else { | |
565 *position = 0; | |
566 } | |
567 } | |
568 return status; | |
569 } | |
570 | |
571 /* Start play */ | |
572 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) | |
573 { | |
574 struct cd_audio_cmd cmd; | |
575 | |
576 /* | |
577 * My CD Rom is muted by default. I think I read that this is new with | |
578 * AIX 4.3. SDL does not change the volume, so I need a kludge. Maybe | |
579 * its better to do this elsewhere? | |
580 */ | |
581 cmd.audio_cmds = CD_PLAY_AUDIO | CD_SET_VOLUME; | |
582 cmd.msf_flag = TRUE; | |
583 FRAMES_TO_MSF(start, | |
584 &cmd.indexing.msf.first_mins, | |
585 &cmd.indexing.msf.first_secs, | |
586 &cmd.indexing.msf.first_frames); | |
587 FRAMES_TO_MSF(start+length, | |
588 &cmd.indexing.msf.last_mins, | |
589 &cmd.indexing.msf.last_secs, | |
590 &cmd.indexing.msf.last_frames); | |
591 cmd.volume_type = CD_VOLUME_ALL; | |
592 cmd.all_channel_vol = 255; /* This is a uchar. What is a good value? No docu! */ | |
593 cmd.out_port_0_sel = CD_AUDIO_CHNL_0; | |
594 cmd.out_port_1_sel = CD_AUDIO_CHNL_1; | |
595 cmd.out_port_2_sel = CD_AUDIO_CHNL_2; | |
596 cmd.out_port_3_sel = CD_AUDIO_CHNL_3; | |
597 | |
598 #ifdef DEBUG_CDROM | |
599 fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", | |
600 cmd.indexing.msf.first_mins, | |
601 cmd.indexing.msf.first_secs, | |
602 cmd.indexing.msf.first_frames, | |
603 cmd.indexing.msf.last_mins, | |
604 cmd.indexing.msf.last_secs, | |
605 cmd.indexing.msf.last_frames); | |
606 #endif | |
607 return(SDL_SYS_CDioctl(cdrom->id, DKAUDIO, &cmd)); | |
608 } | |
609 | |
610 /* Pause play */ | |
611 static int SDL_SYS_CDPause(SDL_CD *cdrom) | |
612 { | |
613 struct cd_audio_cmd cmd; | |
614 cmd.audio_cmds = CD_PAUSE_AUDIO; | |
615 return(SDL_SYS_CDioctl(cdrom->id, DKAUDIO, &cmd)); | |
616 } | |
617 | |
618 /* Resume play */ | |
619 static int SDL_SYS_CDResume(SDL_CD *cdrom) | |
620 { | |
621 struct cd_audio_cmd cmd; | |
622 cmd.audio_cmds = CD_RESUME_AUDIO; | |
623 return(SDL_SYS_CDioctl(cdrom->id, DKAUDIO, &cmd)); | |
624 } | |
625 | |
626 /* Stop play */ | |
627 static int SDL_SYS_CDStop(SDL_CD *cdrom) | |
628 { | |
629 struct cd_audio_cmd cmd; | |
630 cmd.audio_cmds = CD_STOP_AUDIO; | |
631 return(SDL_SYS_CDioctl(cdrom->id, DKAUDIO, &cmd)); | |
632 } | |
633 | |
634 /* Eject the CD-ROM */ | |
635 static int SDL_SYS_CDEject(SDL_CD *cdrom) | |
636 { | |
637 return(SDL_SYS_CDioctl(cdrom->id, DKEJECT, 0)); | |
638 } | |
639 | |
640 /* Close the CD-ROM handle */ | |
641 static void SDL_SYS_CDClose(SDL_CD *cdrom) | |
642 { | |
643 close(cdrom->id); | |
644 } | |
645 | |
646 void SDL_SYS_CDQuit(void) | |
647 { | |
648 int i; | |
649 | |
650 if ( SDL_numcds > 0 ) { | |
651 for ( i=0; i<SDL_numcds; ++i ) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
652 SDL_free(SDL_cdlist[i]); |
0 | 653 } |
654 SDL_numcds = 0; | |
655 } | |
656 } | |
657 |