Mercurial > sdl-ios-xcode
changeset 3243:5db962a9a991
CD-ROM support is so passé :)
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 05 Sep 2009 09:11:03 +0000 |
parents | af4a5af3cd2b |
children | 7c73d5b5a0d6 |
files | TODO configure.in include/SDL.h include/SDL_cdrom.h include/SDL_config.h.in include/SDL_config_dreamcast.h include/SDL_config_iphoneos.h include/SDL_config_macosx.h include/SDL_config_minimal.h include/SDL_config_nintendods.h include/SDL_config_os2.h include/SDL_config_pandora.h include/SDL_config_win32.h src/SDL.c src/cdrom/SDL_cdrom.c src/cdrom/SDL_syscdrom.h src/cdrom/aix/SDL_syscdrom.c src/cdrom/beos/SDL_syscdrom.cc src/cdrom/bsdi/SDL_syscdrom.c src/cdrom/dc/SDL_syscdrom.c src/cdrom/dummy/SDL_syscdrom.c src/cdrom/freebsd/SDL_syscdrom.c src/cdrom/linux/SDL_syscdrom.c src/cdrom/macosx/AudioFilePlayer.c src/cdrom/macosx/AudioFilePlayer.h src/cdrom/macosx/AudioFileReaderThread.c src/cdrom/macosx/CDPlayer.c src/cdrom/macosx/CDPlayer.h src/cdrom/macosx/SDLOSXCAGuard.c src/cdrom/macosx/SDLOSXCAGuard.h src/cdrom/macosx/SDL_syscdrom.c src/cdrom/macosx/SDL_syscdrom_c.h src/cdrom/mint/SDL_syscdrom.c src/cdrom/openbsd/SDL_syscdrom.c src/cdrom/os2/SDL_syscdrom.c src/cdrom/osf/SDL_syscdrom.c src/cdrom/qnx/SDL_syscdrom.c src/cdrom/win32/SDL_syscdrom.c test/Makefile.in test/testcdrom.c |
diffstat | 40 files changed, 3 insertions(+), 9394 deletions(-) [+] |
line wrap: on
line diff
--- a/TODO Sat Sep 05 09:03:35 2009 +0000 +++ b/TODO Sat Sep 05 09:11:03 2009 +0000 @@ -50,4 +50,4 @@ compatibility in this way. Requests: - * PCM and CDROM volume control (deprecated, but possible) + * PCM volume control (deprecated, but possible)
--- a/configure.in Sat Sep 05 09:03:35 2009 +0000 +++ b/configure.in Sat Sep 05 09:11:03 2009 +0000 @@ -206,7 +206,6 @@ # Standard C sources SOURCES="$SOURCES $srcdir/src/*.c" SOURCES="$SOURCES $srcdir/src/audio/*.c" -SOURCES="$SOURCES $srcdir/src/cdrom/*.c" SOURCES="$SOURCES $srcdir/src/cpuinfo/*.c" SOURCES="$SOURCES $srcdir/src/events/*.c" SOURCES="$SOURCES $srcdir/src/file/*.c" @@ -265,12 +264,6 @@ else SOURCES="$SOURCES $srcdir/src/power/*.c" fi -AC_ARG_ENABLE(cdrom, -AC_HELP_STRING([--enable-cdrom], [Enable the cdrom subsystem [[default=yes]]]), - , enable_cdrom=yes) -if test x$enable_cdrom != xyes; then - AC_DEFINE(SDL_CDROM_DISABLED) -fi AC_ARG_ENABLE(threads, AC_HELP_STRING([--enable-threads], [Enable the threading subsystem [[default=yes]]]), , enable_threads=yes) @@ -2481,41 +2474,6 @@ ;; esac fi - # Set up files for the cdrom library - if test x$enable_cdrom = xyes; then - case $ARCH in - linux|solaris) - AC_DEFINE(SDL_CDROM_LINUX) - SOURCES="$SOURCES $srcdir/src/cdrom/linux/*.c" - have_cdrom=yes - ;; - *freebsd*) - AC_DEFINE(SDL_CDROM_FREEBSD) - SOURCES="$SOURCES $srcdir/src/cdrom/freebsd/*.c" - have_cdrom=yes - ;; - *openbsd*|*netbsd*) - AC_DEFINE(SDL_CDROM_OPENBSD) - SOURCES="$SOURCES $srcdir/src/cdrom/openbsd/*.c" - have_cdrom=yes - ;; - bsdi) - AC_DEFINE(SDL_CDROM_BSDI) - SOURCES="$SOURCES $srcdir/src/cdrom/bsdi/*.c" - have_cdrom=yes - ;; - aix) - AC_DEFINE(SDL_CDROM_AIX) - SOURCES="$SOURCES $srcdir/src/cdrom/aix/*.c" - have_cdrom=yes - ;; - osf) - AC_DEFINE(SDL_CDROM_OSF) - SOURCES="$SOURCES $srcdir/src/cdrom/osf/*.c" - have_cdrom=yes - ;; - esac - fi # Set up files for the thread library if test x$enable_threads = xyes -a x$use_pthreads != xyes -a x$use_pth != xyes -a x$ARCH = xirix; then AC_DEFINE(SDL_THREAD_SPROC) @@ -2560,12 +2518,6 @@ EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lasound" have_audio=yes fi - # Set up files for the cdrom library - if test x$enable_cdrom = xyes; then - AC_DEFINE(SDL_CDROM_QNX) - SOURCES="$SOURCES $srcdir/src/cdrom/qnx/*.c" - have_cdrom=yes - fi # Set up files for the timer library if test x$enable_timers = xyes; then AC_DEFINE(SDL_TIMER_UNIX) @@ -2743,12 +2695,6 @@ SOURCES="$SOURCES $srcdir/src/power/windows/SDL_syspower.c" have_power=yes fi - # Set up files for the cdrom library - if test x$enable_cdrom = xyes; then - AC_DEFINE(SDL_CDROM_WIN32) - SOURCES="$SOURCES $srcdir/src/cdrom/win32/*.c" - have_cdrom=yes - fi # Set up files for the thread library if test x$enable_threads = xyes; then AC_DEFINE(SDL_THREAD_WIN32) @@ -2801,12 +2747,6 @@ SOURCES="$SOURCES $srcdir/src/joystick/beos/*.cc" have_joystick=yes fi - # Set up files for the cdrom library - if test x$enable_cdrom = xyes; then - AC_DEFINE(SDL_CDROM_BEOS) - SOURCES="$SOURCES $srcdir/src/cdrom/beos/*.cc" - have_cdrom=yes - fi # Set up files for the thread library if test x$enable_threads = xyes; then AC_DEFINE(SDL_THREAD_BEOS) @@ -2910,12 +2850,6 @@ SOURCES="$SOURCES $srcdir/src/power/macosx/*.c" have_power=yes fi - # Set up files for the cdrom library - if test x$enable_cdrom = xyes; then - AC_DEFINE(SDL_CDROM_MACOSX) - SOURCES="$SOURCES $srcdir/src/cdrom/macosx/*.c" - have_cdrom=yes - fi # Set up files for the timer library if test x$enable_timers = xyes; then AC_DEFINE(SDL_TIMER_UNIX) @@ -2929,7 +2863,7 @@ EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Carbon" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,IOKit" # If either the audio or CD driver is used, add the AudioUnit framework - if test x$enable_audio = xyes -o x$enable_cdrom = xyes; then + if test x$enable_audio = xyes; then EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit" fi ;; @@ -2959,12 +2893,6 @@ SOURCES="$SOURCES $srcdir/src/joystick/mint/*.c" have_joystick=yes fi - # Set up files for the cdrom library - if test x$enable_cdrom = xyes; then - AC_DEFINE(SDL_CDROM_MINT) - SOURCES="$SOURCES $srcdir/src/cdrom/mint/*.c" - have_cdrom=yes - fi # Set up files for the timer library if test x$enable_timers = xyes; then if test x$enable_threads = xyes -a x$enable_pth = xyes; then @@ -3025,12 +2953,6 @@ fi SOURCES="$SOURCES $srcdir/src/haptic/dummy/*.c" fi -if test x$have_cdrom != xyes; then - if test x$enable_cdrom = xyes; then - AC_DEFINE(SDL_CDROM_DISABLED) - fi - SOURCES="$SOURCES $srcdir/src/cdrom/dummy/*.c" -fi if test x$have_threads != xyes; then if test x$enable_threads = xyes; then AC_DEFINE(SDL_THREADS_DISABLED)
--- a/include/SDL.h Sat Sep 05 09:03:35 2009 +0000 +++ b/include/SDL.h Sat Sep 05 09:11:03 2009 +0000 @@ -78,7 +78,6 @@ #include "SDL_stdinc.h" #include "SDL_atomic.h" #include "SDL_audio.h" -#include "SDL_cdrom.h" #include "SDL_cpuinfo.h" #include "SDL_endian.h" #include "SDL_error.h" @@ -109,7 +108,6 @@ #define SDL_INIT_TIMER 0x00000001 #define SDL_INIT_AUDIO 0x00000010 #define SDL_INIT_VIDEO 0x00000020 -#define SDL_INIT_CDROM 0x00000100 #define SDL_INIT_JOYSTICK 0x00000200 #define SDL_INIT_HAPTIC 0x00001000 #define SDL_INIT_NOPARACHUTE 0x00100000 /* Don't catch fatal signals */
--- a/include/SDL_cdrom.h Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,186 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ - -/** - * \file SDL_cdrom.h - * - * This is the CD-audio control API for Simple DirectMedia Layer - */ - -#ifndef _SDL_cdrom_h -#define _SDL_cdrom_h - -#include "SDL_stdinc.h" -#include "SDL_error.h" - -#include "begin_code.h" -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -/* *INDENT-OFF* */ -extern "C" { -/* *INDENT-ON* */ -#endif - -/* In order to use these functions, SDL_Init() must have been called - with the SDL_INIT_CDROM flag. This causes SDL to scan the system - for CD-ROM drives, and load appropriate drivers. -*/ - -/* The maximum number of CD-ROM tracks on a disk */ -#define SDL_MAX_TRACKS 99 - -/* The types of CD-ROM track possible */ -#define SDL_AUDIO_TRACK 0x00 -#define SDL_DATA_TRACK 0x04 - -/* The possible states which a CD-ROM drive can be in. */ -typedef enum -{ - CD_TRAYEMPTY, - CD_STOPPED, - CD_PLAYING, - CD_PAUSED, - CD_ERROR = -1 -} CDstatus; - -/* Given a status, returns true if there's a disk in the drive */ -#define CD_INDRIVE(status) ((int)(status) > 0) - -typedef struct SDL_CDtrack -{ - Uint8 id; /* Track number */ - Uint8 type; /* Data or audio track */ - Uint16 unused; - Uint32 length; /* Length, in frames, of this track */ - Uint32 offset; /* Offset, in frames, from start of disk */ -} SDL_CDtrack; - -/* This structure is only current as of the last call to SDL_CDStatus() */ -typedef struct SDL_CD -{ - int id; /* Private drive identifier */ - CDstatus status; /* Current drive status */ - - /* The rest of this structure is only valid if there's a CD in drive */ - int numtracks; /* Number of tracks on disk */ - int cur_track; /* Current track position */ - int cur_frame; /* Current frame offset within current track */ - SDL_CDtrack track[SDL_MAX_TRACKS + 1]; -} SDL_CD; - -/* Conversion functions from frames to Minute/Second/Frames and vice versa */ -#define CD_FPS 75 -#define FRAMES_TO_MSF(f, M,S,F) { \ - int value = f; \ - *(F) = value%CD_FPS; \ - value /= CD_FPS; \ - *(S) = value%60; \ - value /= 60; \ - *(M) = value; \ -} -#define MSF_TO_FRAMES(M, S, F) ((M)*60*CD_FPS+(S)*CD_FPS+(F)) - -/* CD-audio API functions: */ - -/* Returns the number of CD-ROM drives on the system, or -1 if - SDL_Init() has not been called with the SDL_INIT_CDROM flag. - */ -extern DECLSPEC int SDLCALL SDL_CDNumDrives(void); - -/* Returns a human-readable, system-dependent identifier for the CD-ROM. - Example: - "/dev/cdrom" - "E:" - "/dev/disk/ide/1/master" -*/ -extern DECLSPEC const char *SDLCALL SDL_CDName(int drive); - -/* Opens a CD-ROM drive for access. It returns a drive handle on success, - or NULL if the drive was invalid or busy. This newly opened CD-ROM - becomes the default CD used when other CD functions are passed a NULL - CD-ROM handle. - Drives are numbered starting with 0. Drive 0 is the system default CD-ROM. -*/ -extern DECLSPEC SDL_CD *SDLCALL SDL_CDOpen(int drive); - -/* This function returns the current status of the given drive. - If the drive has a CD in it, the table of contents of the CD and current - play position of the CD will be stored in the SDL_CD structure. -*/ -extern DECLSPEC CDstatus SDLCALL SDL_CDStatus(SDL_CD * cdrom); - -/* Play the given CD starting at 'start_track' and 'start_frame' for 'ntracks' - tracks and 'nframes' frames. If both 'ntrack' and 'nframe' are 0, play - until the end of the CD. This function will skip data tracks. - This function should only be called after calling SDL_CDStatus() to - get track information about the CD. - For example: - // Play entire CD: - if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) - SDL_CDPlayTracks(cdrom, 0, 0, 0, 0); - // Play last track: - if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) { - SDL_CDPlayTracks(cdrom, cdrom->numtracks-1, 0, 0, 0); - } - // Play first and second track and 10 seconds of third track: - if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) - SDL_CDPlayTracks(cdrom, 0, 0, 2, 10); - - This function returns 0, or -1 if there was an error. -*/ -extern DECLSPEC int SDLCALL SDL_CDPlayTracks(SDL_CD * cdrom, - int start_track, - int start_frame, int ntracks, - int nframes); - -/* Play the given CD starting at 'start' frame for 'length' frames. - It returns 0, or -1 if there was an error. -*/ -extern DECLSPEC int SDLCALL SDL_CDPlay(SDL_CD * cdrom, int start, int length); - -/* Pause play -- returns 0, or -1 on error */ -extern DECLSPEC int SDLCALL SDL_CDPause(SDL_CD * cdrom); - -/* Resume play -- returns 0, or -1 on error */ -extern DECLSPEC int SDLCALL SDL_CDResume(SDL_CD * cdrom); - -/* Stop play -- returns 0, or -1 on error */ -extern DECLSPEC int SDLCALL SDL_CDStop(SDL_CD * cdrom); - -/* Eject CD-ROM -- returns 0, or -1 on error */ -extern DECLSPEC int SDLCALL SDL_CDEject(SDL_CD * cdrom); - -/* Closes the handle for the CD-ROM drive */ -extern DECLSPEC void SDLCALL SDL_CDClose(SDL_CD * cdrom); - - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -/* *INDENT-OFF* */ -} -/* *INDENT-ON* */ -#endif -#include "close_code.h" - -#endif /* _SDL_video_h */ - -/* vi: set ts=4 sw=4 expandtab: */
--- a/include/SDL_config.h.in Sat Sep 05 09:03:35 2009 +0000 +++ b/include/SDL_config.h.in Sat Sep 05 09:11:03 2009 +0000 @@ -160,7 +160,6 @@ /* Allow disabling of core subsystems */ #undef SDL_AUDIO_DISABLED -#undef SDL_CDROM_DISABLED #undef SDL_CPUINFO_DISABLED #undef SDL_EVENTS_DISABLED #undef SDL_FILE_DISABLED @@ -204,22 +203,6 @@ #undef SDL_AUDIO_DRIVER_FUSIONSOUND #undef SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC -/* Enable various cdrom drivers */ -#undef SDL_CDROM_AIX -#undef SDL_CDROM_BEOS -#undef SDL_CDROM_BSDI -#undef SDL_CDROM_DC -#undef SDL_CDROM_DUMMY -#undef SDL_CDROM_FREEBSD -#undef SDL_CDROM_LINUX -#undef SDL_CDROM_MACOSX -#undef SDL_CDROM_MINT -#undef SDL_CDROM_OPENBSD -#undef SDL_CDROM_OS2 -#undef SDL_CDROM_OSF -#undef SDL_CDROM_QNX -#undef SDL_CDROM_WIN32 - /* Enable various input drivers */ #undef SDL_INPUT_LINUXEV #undef SDL_INPUT_TSLIB
--- a/include/SDL_config_dreamcast.h Sat Sep 05 09:03:35 2009 +0000 +++ b/include/SDL_config_dreamcast.h Sat Sep 05 09:11:03 2009 +0000 @@ -88,9 +88,6 @@ #define SDL_AUDIO_DRIVER_DISK 1 #define SDL_AUDIO_DRIVER_DUMMY 1 -/* Enable various cdrom drivers */ -#define SDL_CDROM_DC 1 - /* Enable various input drivers */ #define SDL_JOYSTICK_DC 1 #define SDL_HAPTIC_DUMMY 1
--- a/include/SDL_config_iphoneos.h Sat Sep 05 09:03:35 2009 +0000 +++ b/include/SDL_config_iphoneos.h Sat Sep 05 09:11:03 2009 +0000 @@ -106,9 +106,6 @@ /* Enable the dummy audio driver (src/audio/dummy/\*.c) */ #define SDL_AUDIO_DRIVER_DUMMY 1 -/* Enable the stub cdrom driver (src/cdrom/dummy/\*.c) */ -#define SDL_CDROM_DISABLED 1 - /* Enable the stub haptic driver (src/haptic/dummy/\*.c) */ #define SDL_HAPTIC_DISABLED 1
--- a/include/SDL_config_macosx.h Sat Sep 05 09:03:35 2009 +0000 +++ b/include/SDL_config_macosx.h Sat Sep 05 09:11:03 2009 +0000 @@ -106,9 +106,6 @@ #define SDL_AUDIO_DRIVER_DISK 1 #define SDL_AUDIO_DRIVER_DUMMY 1 -/* Enable various cdrom drivers */ -#define SDL_CDROM_MACOSX 1 - /* Enable various input drivers */ #define SDL_JOYSTICK_IOKIT 1 #define SDL_HAPTIC_IOKIT 1
--- a/include/SDL_config_minimal.h Sat Sep 05 09:03:35 2009 +0000 +++ b/include/SDL_config_minimal.h Sat Sep 05 09:11:03 2009 +0000 @@ -43,9 +43,6 @@ /* Enable the dummy audio driver (src/audio/dummy/\*.c) */ #define SDL_AUDIO_DRIVER_DUMMY 1 -/* Enable the stub cdrom driver (src/cdrom/dummy/\*.c) */ -#define SDL_CDROM_DISABLED 1 - /* Enable the stub joystick driver (src/joystick/dummy/\*.c) */ #define SDL_JOYSTICK_DISABLED 1
--- a/include/SDL_config_nintendods.h Sat Sep 05 09:03:35 2009 +0000 +++ b/include/SDL_config_nintendods.h Sat Sep 05 09:11:03 2009 +0000 @@ -96,9 +96,6 @@ #define SDL_AUDIO_DRIVER_NDS 1 /*#define SDL_AUDIO_DRIVER_DUMMY 1 TODO: uncomment this later*/ -/* DS doesn't have optical media */ -#define SDL_CDROM_DISABLED 1 - /* Enable various input drivers */ #define SDL_JOYSTICK_NDS 1 /*#define SDL_JOYSTICK_DUMMY 1 TODO: uncomment this later*/
--- a/include/SDL_config_os2.h Sat Sep 05 09:03:35 2009 +0000 +++ b/include/SDL_config_os2.h Sat Sep 05 09:11:03 2009 +0000 @@ -116,9 +116,6 @@ #define SDL_AUDIO_DRIVER_DISK 1 #define SDL_AUDIO_DRIVER_DUMMY 1 -/* Enable various cdrom drivers */ -#define SDL_CDROM_OS2 1 - /* Enable various input drivers */ #define SDL_JOYSTICK_OS2 1 #define SDL_HAPTIC_DUMMY 1
--- a/include/SDL_config_pandora.h Sat Sep 05 09:03:35 2009 +0000 +++ b/include/SDL_config_pandora.h Sat Sep 05 09:11:03 2009 +0000 @@ -95,7 +95,6 @@ #define HAVE_SETJMP 1 #define HAVE_NANOSLEEP 1 -#define SDL_CDROM_DISABLED 1 #define SDL_AUDIO_DRIVER_DUMMY 1 #define SDL_AUDIO_DRIVER_OSS 1
--- a/include/SDL_config_win32.h Sat Sep 05 09:03:35 2009 +0000 +++ b/include/SDL_config_win32.h Sat Sep 05 09:11:03 2009 +0000 @@ -150,13 +150,6 @@ #define SDL_AUDIO_DRIVER_DISK 1 #define SDL_AUDIO_DRIVER_DUMMY 1 -/* Enable various cdrom drivers */ -#ifdef _WIN32_WCE -#define SDL_CDROM_DISABLED 1 -#else -#define SDL_CDROM_WIN32 1 -#endif - /* Enable various input drivers */ #ifdef _WIN32_WCE #define SDL_JOYSTICK_DISABLED 1
--- a/src/SDL.c Sat Sep 05 09:03:35 2009 +0000 +++ b/src/SDL.c Sat Sep 05 09:11:03 2009 +0000 @@ -42,10 +42,6 @@ extern int SDL_HapticInit(void); extern int SDL_HapticQuit(void); #endif -#if !SDL_CDROM_DISABLED -extern int SDL_CDROMInit(void); -extern void SDL_CDROMQuit(void); -#endif #if !SDL_TIMERS_DISABLED extern void SDL_StartTicks(void); extern int SDL_TimerInit(void); @@ -145,22 +141,6 @@ return (-1); } #endif - - -#if !SDL_CDROM_DISABLED - /* Initialize the CD-ROM subsystem */ - if ((flags & SDL_INIT_CDROM) && !(SDL_initialized & SDL_INIT_CDROM)) { - if (SDL_CDROMInit() < 0) { - return (-1); - } - SDL_initialized |= SDL_INIT_CDROM; - } -#else - if (flags & SDL_INIT_CDROM) { - SDL_SetError("SDL not built with cdrom support"); - return (-1); - } -#endif return (0); } @@ -198,12 +178,6 @@ SDL_QuitSubSystem(Uint32 flags) { /* Shut down requested initialized subsystems */ -#if !SDL_CDROM_DISABLED - if ((flags & SDL_initialized & SDL_INIT_CDROM)) { - SDL_CDROMQuit(); - SDL_initialized &= ~SDL_INIT_CDROM; - } -#endif #if !SDL_JOYSTICK_DISABLED if ((flags & SDL_initialized & SDL_INIT_JOYSTICK)) { SDL_JoystickQuit();
--- a/src/cdrom/SDL_cdrom.c Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,357 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* This is the CD-audio control API for Simple DirectMedia Layer */ - -#include "SDL_cdrom.h" -#include "SDL_syscdrom.h" - -#define CLIP_FRAMES 10 /* Some CD-ROMs won't go all the way */ - -static int SDL_cdinitted = 0; -static SDL_CD *default_cdrom; - -/* The system level CD-ROM control functions */ -struct CDcaps SDL_CDcaps = { - NULL, /* Name */ - NULL, /* Open */ - NULL, /* GetTOC */ - NULL, /* Status */ - NULL, /* Play */ - NULL, /* Pause */ - NULL, /* Resume */ - NULL, /* Stop */ - NULL, /* Eject */ - NULL, /* Close */ -}; - -int SDL_numcds; - -int -SDL_CDROMInit(void) -{ - int retval; - - SDL_numcds = 0; - retval = SDL_SYS_CDInit(); - if (retval == 0) { - SDL_cdinitted = 1; - } - default_cdrom = NULL; - return (retval); -} - -/* Check to see if the CD-ROM subsystem has been initialized */ -static int -CheckInit(int check_cdrom, SDL_CD ** cdrom) -{ - int okay; - - okay = SDL_cdinitted; - if (check_cdrom && (*cdrom == NULL)) { - *cdrom = default_cdrom; - if (*cdrom == NULL) { - SDL_SetError("CD-ROM not opened"); - okay = 0; - } - } - if (!SDL_cdinitted) { - SDL_SetError("CD-ROM subsystem not initialized"); - } - return (okay); -} - -int -SDL_CDNumDrives(void) -{ - if (!CheckInit(0, NULL)) { - return (-1); - } - return (SDL_numcds); -} - -const char * -SDL_CDName(int drive) -{ - if (!CheckInit(0, NULL)) { - return (NULL); - } - if (drive >= SDL_numcds) { - SDL_SetError("Invalid CD-ROM drive index"); - return (NULL); - } - if (SDL_CDcaps.Name) { - return (SDL_CDcaps.Name(drive)); - } else { - return (""); - } -} - -SDL_CD * -SDL_CDOpen(int drive) -{ - struct SDL_CD *cdrom; - - if (!CheckInit(0, NULL)) { - return (NULL); - } - if (drive >= SDL_numcds) { - SDL_SetError("Invalid CD-ROM drive index"); - return (NULL); - } - cdrom = (SDL_CD *) SDL_malloc(sizeof(*cdrom)); - if (cdrom == NULL) { - SDL_OutOfMemory(); - return (NULL); - } - SDL_memset(cdrom, 0, sizeof(*cdrom)); - cdrom->id = SDL_CDcaps.Open(drive); - if (cdrom->id < 0) { - SDL_free(cdrom); - return (NULL); - } - default_cdrom = cdrom; - return (cdrom); -} - -CDstatus -SDL_CDStatus(SDL_CD * cdrom) -{ - CDstatus status; - int i; - Uint32 position; - - /* Check if the CD-ROM subsystem has been initialized */ - if (!CheckInit(1, &cdrom)) { - return (CD_ERROR); - } - - /* Get the current status of the drive */ - cdrom->numtracks = 0; - cdrom->cur_track = 0; - cdrom->cur_frame = 0; - status = SDL_CDcaps.Status(cdrom, &i); - position = (Uint32) i; - cdrom->status = status; - - /* Get the table of contents, if there's a CD available */ - if (CD_INDRIVE(status)) { - if (SDL_CDcaps.GetTOC(cdrom) < 0) { - status = CD_ERROR; - } - /* If the drive is playing, get current play position */ - if ((status == CD_PLAYING) || (status == CD_PAUSED)) { - for (i = 1; cdrom->track[i].offset <= position; ++i) { - /* Keep looking */ ; - } -#ifdef DEBUG_CDROM - fprintf(stderr, - "Current position: %d, track = %d (offset is %d)\n", - position, i - 1, cdrom->track[i - 1].offset); -#endif - cdrom->cur_track = i - 1; - position -= cdrom->track[cdrom->cur_track].offset; - cdrom->cur_frame = position; - } - } - return (status); -} - -int -SDL_CDPlayTracks(SDL_CD * cdrom, - int strack, int sframe, int ntracks, int nframes) -{ - int etrack, eframe; - int start, length; - - /* Check if the CD-ROM subsystem has been initialized */ - if (!CheckInit(1, &cdrom)) { - return (CD_ERROR); - } - - /* Determine the starting and ending tracks */ - if ((strack < 0) || (strack >= cdrom->numtracks)) { - SDL_SetError("Invalid starting track"); - return (CD_ERROR); - } - if (!ntracks && !nframes) { - etrack = cdrom->numtracks; - eframe = 0; - } else { - etrack = strack + ntracks; - if (etrack == strack) { - eframe = sframe + nframes; - } else { - eframe = nframes; - } - } - if (etrack > cdrom->numtracks) { - SDL_SetError("Invalid play length"); - return (CD_ERROR); - } - - /* Skip data tracks and verify frame offsets */ - while ((strack <= etrack) && - (cdrom->track[strack].type == SDL_DATA_TRACK)) { - ++strack; - } - if (sframe >= (int) cdrom->track[strack].length) { - SDL_SetError("Invalid starting frame for track %d", strack); - return (CD_ERROR); - } - while ((etrack > strack) && - (cdrom->track[etrack - 1].type == SDL_DATA_TRACK)) { - --etrack; - } - if (eframe > (int) cdrom->track[etrack].length) { - SDL_SetError("Invalid ending frame for track %d", etrack); - return (CD_ERROR); - } - - /* Determine start frame and play length */ - start = (cdrom->track[strack].offset + sframe); - length = (cdrom->track[etrack].offset + eframe) - start; -#ifdef CLIP_FRAMES - /* I've never seen this necessary, but xmcd does it.. */ - length -= CLIP_FRAMES; /* CLIP_FRAMES == 10 */ -#endif - if (length < 0) { - return (0); - } - - /* Play! */ -#ifdef DEBUG_CDROM - fprintf(stderr, "Playing %d frames at offset %d\n", length, start); -#endif - return (SDL_CDcaps.Play(cdrom, start, length)); -} - -int -SDL_CDPlay(SDL_CD * cdrom, int sframe, int length) -{ - /* Check if the CD-ROM subsystem has been initialized */ - if (!CheckInit(1, &cdrom)) { - return (CD_ERROR); - } - - return (SDL_CDcaps.Play(cdrom, sframe, length)); -} - -int -SDL_CDPause(SDL_CD * cdrom) -{ - CDstatus status; - int retval; - - /* Check if the CD-ROM subsystem has been initialized */ - if (!CheckInit(1, &cdrom)) { - return (CD_ERROR); - } - - status = SDL_CDcaps.Status(cdrom, NULL); - switch (status) { - case CD_PLAYING: - retval = SDL_CDcaps.Pause(cdrom); - break; - default: - retval = 0; - break; - } - return (retval); -} - -int -SDL_CDResume(SDL_CD * cdrom) -{ - CDstatus status; - int retval; - - /* Check if the CD-ROM subsystem has been initialized */ - if (!CheckInit(1, &cdrom)) { - return (CD_ERROR); - } - - status = SDL_CDcaps.Status(cdrom, NULL); - switch (status) { - case CD_PAUSED: - retval = SDL_CDcaps.Resume(cdrom); - default: - retval = 0; - break; - } - return (retval); -} - -int -SDL_CDStop(SDL_CD * cdrom) -{ - CDstatus status; - int retval; - - /* Check if the CD-ROM subsystem has been initialized */ - if (!CheckInit(1, &cdrom)) { - return (CD_ERROR); - } - - status = SDL_CDcaps.Status(cdrom, NULL); - switch (status) { - case CD_PLAYING: - case CD_PAUSED: - retval = SDL_CDcaps.Stop(cdrom); - default: - retval = 0; - break; - } - return (retval); -} - -int -SDL_CDEject(SDL_CD * cdrom) -{ - /* Check if the CD-ROM subsystem has been initialized */ - if (!CheckInit(1, &cdrom)) { - return (CD_ERROR); - } - return (SDL_CDcaps.Eject(cdrom)); -} - -void -SDL_CDClose(SDL_CD * cdrom) -{ - /* Check if the CD-ROM subsystem has been initialized */ - if (!CheckInit(1, &cdrom)) { - return; - } - SDL_CDcaps.Close(cdrom); - SDL_free(cdrom); - default_cdrom = NULL; -} - -void -SDL_CDROMQuit(void) -{ - SDL_SYS_CDQuit(); - SDL_cdinitted = 0; -} - -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/cdrom/SDL_syscdrom.h Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is SDL_free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* This is the system specific header for the SDL CD-ROM API */ - -/* Structure of CD audio control functions */ -extern struct CDcaps -{ - /* Get the name of the specified drive */ - const char *(*Name) (int drive); - - /* Open the specified drive, returning a drive id, or -1 on error */ - int (*Open) (int drive); - - /* Get table-of-contents (number of tracks + track info) for disk. - The TOC information should be stored in the cdrom structure. - This function should return 0 on success, or -1 on error. - */ - int (*GetTOC) (SDL_CD * cdrom); - - /* Return the current status and play position, in frames, of the - drive. 'position' may be NULL, and if so, should be ignored. - */ - CDstatus(*Status) (SDL_CD * cdrom, int *position); - - /* Play from frame 'start' to 'start+len' */ - int (*Play) (SDL_CD * cdrom, int start, int len); - - /* Pause play */ - int (*Pause) (SDL_CD * cdrom); - - /* Resume play */ - int (*Resume) (SDL_CD * cdrom); - - /* Stop play */ - int (*Stop) (SDL_CD * cdrom); - - /* Eject the current disk */ - int (*Eject) (SDL_CD * cdrom); - - /* Close the specified drive */ - void (*Close) (SDL_CD * cdrom); -} SDL_CDcaps; - -/* The number of available CD-ROM drives on the system */ -extern int SDL_numcds; - -/* Function to scan the system for CD-ROM drives and fill SDL_CDcaps. - * This function should set SDL_numcds to the number of available CD - * drives. Drive 0 should be the system default CD-ROM. - * It should return 0, or -1 on an unrecoverable fatal error. -*/ -extern int SDL_SYS_CDInit(void); - -/* Function to perform any system-specific CD-ROM related cleanup */ -extern void SDL_SYS_CDQuit(void); - -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/cdrom/aix/SDL_syscdrom.c Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,665 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Carsten Griwodz - griff@kom.tu-darmstadt.de - - based on linux/SDL_syscdrom.c by Sam Lantinga -*/ -#include "SDL_config.h" - -#ifdef SDL_CDROM_AIX - -/* Functions for system-level CD-ROM audio control */ - -/*#define DEBUG_CDROM 1*/ - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> -#include <unistd.h> - -#include <sys/ioctl.h> -#include <sys/devinfo.h> -#include <sys/mntctl.h> -#include <sys/statfs.h> -#include <sys/vmount.h> -#include <fstab.h> -#include <sys/scdisk.h> - -#include "SDL_cdrom.h" -#include "../SDL_syscdrom.h" - -/* The maximum number of CD-ROM drives we'll detect */ -#define MAX_DRIVES 16 - -/* A list of available CD-ROM drives */ -static char *SDL_cdlist[MAX_DRIVES]; -static dev_t SDL_cdmode[MAX_DRIVES]; - -/* The system-dependent CD control functions */ -static const char *SDL_SYS_CDName(int drive); -static int SDL_SYS_CDOpen(int drive); -static int SDL_SYS_CDGetTOC(SDL_CD * cdrom); -static CDstatus SDL_SYS_CDStatus(SDL_CD * cdrom, int *position); -static int SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length); -static int SDL_SYS_CDPause(SDL_CD * cdrom); -static int SDL_SYS_CDResume(SDL_CD * cdrom); -static int SDL_SYS_CDStop(SDL_CD * cdrom); -static int SDL_SYS_CDEject(SDL_CD * cdrom); -static void SDL_SYS_CDClose(SDL_CD * cdrom); -static int SDL_SYS_CDioctl(int id, int command, void *arg); - -/* Check a drive to see if it is a CD-ROM */ -static int -CheckDrive(char *drive, struct stat *stbuf) -{ - int is_cd; - int cdfd; - int ret; - struct devinfo info; - - /* If it doesn't exist, return -1 */ - if (stat(drive, stbuf) < 0) { - return -1; - } - - /* If it does exist, verify that it's an available CD-ROM */ - is_cd = 0; - if (S_ISCHR(stbuf->st_mode) || S_ISBLK(stbuf->st_mode)) { - cdfd = open(drive, (O_RDONLY | O_EXCL | O_NONBLOCK), 0); - if (cdfd >= 0) { - ret = SDL_SYS_CDioctl(cdfd, IOCINFO, &info); - if (ret < 0) { - /* Some kind of error */ - is_cd = 0; - } else { - if (info.devtype == DD_CDROM) { - is_cd = 1; - } else { - is_cd = 0; - } - } - close(cdfd); - } -#ifdef DEBUG_CDROM - else { - fprintf(stderr, "Could not open drive %s (%s)\n", drive, - strerror(errno)); - } -#endif - } - return is_cd; -} - -/* Add a CD-ROM drive to our list of valid drives */ -static void -AddDrive(char *drive, struct stat *stbuf) -{ - int i; - - if (SDL_numcds < MAX_DRIVES) { - /* Check to make sure it's not already in our list. - This can happen when we see a drive via symbolic link. - */ - for (i = 0; i < SDL_numcds; ++i) { - if (stbuf->st_rdev == SDL_cdmode[i]) { -#ifdef DEBUG_CDROM - fprintf(stderr, "Duplicate drive detected: %s == %s\n", - drive, SDL_cdlist[i]); -#endif - return; - } - } - - /* Add this drive to our list */ - i = SDL_numcds; - SDL_cdlist[i] = SDL_strdup(drive); - if (SDL_cdlist[i] == NULL) { - SDL_OutOfMemory(); - return; - } - SDL_cdmode[i] = stbuf->st_rdev; - ++SDL_numcds; -#ifdef DEBUG_CDROM - fprintf(stderr, "Added CD-ROM drive: %s\n", drive); -#endif - } -} - -static void -CheckMounts() -{ - char *buffer; - int bufsz; - struct vmount *ptr; - int ret; - - buffer = (char *) SDL_malloc(10); - bufsz = 10; - if (buffer == NULL) { - fprintf(stderr, - "Could not allocate 10 bytes in aix/SDL_syscdrom.c:CheckMounts\n"); - exit(-10); - } - - do { - /* mntctrl() returns an array of all mounted filesystems */ - ret = mntctl(MCTL_QUERY, bufsz, buffer); - if (ret == 0) { - /* Buffer was too small, realloc. */ - bufsz = *(int *) buffer; /* Required size is in first word. */ - /* (whatever a word is in AIX 4.3.3) */ - /* int seems to be OK in 32bit mode. */ - SDL_free(buffer); - buffer = (char *) SDL_malloc(bufsz); - if (buffer == NULL) { - fprintf(stderr, - "Could not allocate %d bytes in aix/SDL_syscdrom.c:CheckMounts\n", - bufsz); - exit(-10); - } - } else if (ret < 0) { -#ifdef DEBUG_CDROM - fprintf(stderr, "Error reading vmount structures\n"); -#endif - return; - } - } while (ret == 0); - -#ifdef DEBUG_CDROM - fprintf(stderr, "Read %d vmount structures\n", ret); -#endif - ptr = (struct vmount *) buffer; - do { - switch (ptr->vmt_gfstype) { - case MNT_CDROM: - { - struct stat stbuf; - char *text; - - text = (char *) ptr + ptr->vmt_data[VMT_OBJECT].vmt_off; -#ifdef DEBUG_CDROM - fprintf(stderr, - "Checking mount path: %s mounted on %s\n", text, - (char *) ptr + ptr->vmt_data[VMT_STUB].vmt_off); -#endif - if (CheckDrive(text, &stbuf) > 0) { - AddDrive(text, &stbuf); - } - } - break; - default: - break; - } - ptr = (struct vmount *) ((char *) ptr + ptr->vmt_length); - ret--; - } while (ret > 0); - - free(buffer); -} - -static int -CheckNonmounts() -{ -#ifdef _THREAD_SAFE - AFILE_t fsFile = NULL; - int passNo = 0; - int ret; - struct fstab entry; - struct stat stbuf; - - ret = setfsent_r(&fsFile, &passNo); - if (ret != 0) - return -1; - do { - ret = getfsent_r(&entry, &fsFile, &passNo); - if (ret == 0) { - char *l = SDL_strrchr(entry.fs_spec, '/'); - if (l != NULL) { - if (!SDL_strncmp("cd", ++l, 2)) { -#ifdef DEBUG_CDROM - fprintf(stderr, - "Found unmounted CD ROM drive with device name %s\n", - entry.fs_spec); -#endif - if (CheckDrive(entry.fs_spec, &stbuf) > 0) { - AddDrive(entry.fs_spec, &stbuf); - } - } - } - } - } while (ret == 0); - ret = endfsent_r(&fsFile); - if (ret != 0) - return -1; - return 0; -#else - struct fstab *entry; - struct stat stbuf; - - setfsent(); - do { - entry = getfsent(); - if (entry != NULL) { - char *l = SDL_strrchr(entry->fs_spec, '/'); - if (l != NULL) { - if (!SDL_strncmp("cd", ++l, 2)) { -#ifdef DEBUG_CDROM - fprintf(stderr, - "Found unmounted CD ROM drive with device name %s", - entry->fs_spec); -#endif - if (CheckDrive(entry->fs_spec, &stbuf) > 0) { - AddDrive(entry->fs_spec, &stbuf); - } - } - } - } - } while (entry != NULL); - endfsent(); -#endif -} - -int -SDL_SYS_CDInit(void) -{ - char *SDLcdrom; - struct stat stbuf; - - /* Fill in our driver capabilities */ - SDL_CDcaps.Name = SDL_SYS_CDName; - SDL_CDcaps.Open = SDL_SYS_CDOpen; - SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; - SDL_CDcaps.Status = SDL_SYS_CDStatus; - SDL_CDcaps.Play = SDL_SYS_CDPlay; - SDL_CDcaps.Pause = SDL_SYS_CDPause; - SDL_CDcaps.Resume = SDL_SYS_CDResume; - SDL_CDcaps.Stop = SDL_SYS_CDStop; - SDL_CDcaps.Eject = SDL_SYS_CDEject; - SDL_CDcaps.Close = SDL_SYS_CDClose; - - /* Look in the environment for our CD-ROM drive list */ - SDLcdrom = SDL_getenv("SDL_CDROM"); /* ':' separated list of devices */ - if (SDLcdrom != NULL) { - char *cdpath, *delim; - size_t len = SDL_strlen(SDLcdrom) + 1; - cdpath = SDL_stack_alloc(char, len); - if (cdpath != NULL) { - SDL_strlcpy(cdpath, SDLcdrom, len); - SDLcdrom = cdpath; - do { - delim = SDL_strchr(SDLcdrom, ':'); - if (delim) { - *delim++ = '\0'; - } -#ifdef DEBUG_CDROM - fprintf(stderr, - "Checking CD-ROM drive from SDL_CDROM: %s\n", - SDLcdrom); -#endif - if (CheckDrive(SDLcdrom, &stbuf) > 0) { - AddDrive(SDLcdrom, &stbuf); - } - if (delim) { - SDLcdrom = delim; - } else { - SDLcdrom = NULL; - } - } while (SDLcdrom); - SDL_stack_free(cdpath); - } - - /* If we found our drives, there's nothing left to do */ - if (SDL_numcds > 0) { - return (0); - } - } - - CheckMounts(); - CheckNonmounts(); - - return 0; -} - -/* General ioctl() CD-ROM command function */ -static int -SDL_SYS_CDioctl(int id, int command, void *arg) -{ - int retval; - - retval = ioctl(id, command, arg); - if (retval < 0) { - SDL_SetError("ioctl() error: %s", strerror(errno)); - } - return retval; -} - -static const char * -SDL_SYS_CDName(int drive) -{ - return (SDL_cdlist[drive]); -} - -static int -SDL_SYS_CDOpen(int drive) -{ - int fd; - char *lastsl; - char *cdromname; - size_t len; - - /* - * We found /dev/cd? drives and that is in our list. But we can - * open only the /dev/rcd? versions of those devices for Audio CD. - */ - len = SDL_strlen(SDL_cdlist[drive]) + 2; - cdromname = (char *) SDL_malloc(len); - SDL_strlcpy(cdromname, SDL_cdlist[drive], len); - lastsl = SDL_strrchr(cdromname, '/'); - if (lastsl) { - *lastsl = 0; - SDL_strlcat(cdromname, "/r", len); - lastsl = SDL_strrchr(SDL_cdlist[drive], '/'); - if (lastsl) { - lastsl++; - SDL_strlcat(cdromname, lastsl, len); - } - } -#ifdef DEBUG_CDROM - fprintf(stderr, "Should open drive %s, opening %s\n", SDL_cdlist[drive], - cdromname); -#endif - - /* - * Use exclusive access. Don't use SC_DIAGNOSTICS as xmcd does because they - * require root priviledges, and we don't want that. SC_SINGLE provides - * exclusive access with less trouble. - */ - fd = openx(cdromname, O_RDONLY, NULL, SC_SINGLE); - if (fd < 0) { -#ifdef DEBUG_CDROM - fprintf(stderr, "Could not open drive %s (%s)\n", cdromname, - strerror(errno)); -#endif - } else { - struct mode_form_op cdMode; - int ret; -#ifdef DEBUG_CDROM - cdMode.action = CD_GET_MODE; - ret = SDL_SYS_CDioctl(fd, DK_CD_MODE, &cdMode); - if (ret < 0) { - fprintf(stderr, - "Could not get drive mode for %s (%s)\n", - cdromname, strerror(errno)); - } else { - switch (cdMode.cd_mode_form) { - case CD_MODE1: - fprintf(stderr, - "Drive mode for %s is %s\n", - cdromname, "CD-ROM Data Mode 1"); - break; - case CD_MODE2_FORM1: - fprintf(stderr, - "Drive mode for %s is %s\n", - cdromname, "CD-ROM XA Data Mode 2 Form 1"); - break; - case CD_MODE2_FORM2: - fprintf(stderr, - "Drive mode for %s is %s\n", - cdromname, "CD-ROM XA Data Mode 2 Form 2"); - break; - case CD_DA: - fprintf(stderr, - "Drive mode for %s is %s\n", cdromname, "CD-DA"); - break; - default: - fprintf(stderr, - "Drive mode for %s is %s\n", cdromname, "unknown"); - break; - } - } -#endif - - cdMode.action = CD_CHG_MODE; - cdMode.cd_mode_form = CD_DA; - ret = SDL_SYS_CDioctl(fd, DK_CD_MODE, &cdMode); - if (ret < 0) { -#ifdef DEBUG_CDROM - fprintf(stderr, - "Could not set drive mode for %s (%s)\n", - cdromname, strerror(errno)); -#endif - SDL_SetError - ("ioctl() error: Could not set CD drive mode, %s", - strerror(errno)); - } else { -#ifdef DEBUG_CDROM - fprintf(stderr, "Drive mode for %s set to CD_DA\n", cdromname); -#endif - } - } - SDL_free(cdromname); - return fd; -} - -static int -SDL_SYS_CDGetTOC(SDL_CD * cdrom) -{ - struct cd_audio_cmd cmd; - struct cd_audio_cmd entry; - int i; - int okay; - - cmd.audio_cmds = CD_TRK_INFO_AUDIO; - cmd.msf_flag = FALSE; - if (SDL_SYS_CDioctl(cdrom->id, DKAUDIO, &cmd) < 0) { - return -1; - } - - okay = 0; - cdrom->numtracks = cmd.indexing.track_index.last_track - - cmd.indexing.track_index.first_track + 1; - if (cdrom->numtracks > SDL_MAX_TRACKS) { - cdrom->numtracks = SDL_MAX_TRACKS; - } - - /* Read all the track TOC entries */ - for (i = 0; i <= cdrom->numtracks; ++i) { - if (i == cdrom->numtracks) { - cdrom->track[i].id = 0xAA;; - } else { - cdrom->track[i].id = cmd.indexing.track_index.first_track + i; - } - entry.audio_cmds = CD_GET_TRK_MSF; - entry.indexing.track_msf.track = cdrom->track[i].id; - if (SDL_SYS_CDioctl(cdrom->id, DKAUDIO, &entry) < 0) { - break; - } else { - cdrom->track[i].type = 0; /* don't know how to detect 0x04 data track */ - cdrom->track[i].offset = - MSF_TO_FRAMES(entry.indexing.track_msf.mins, - entry.indexing.track_msf.secs, - entry.indexing.track_msf.frames); - cdrom->track[i].length = 0; - if (i > 0) { - cdrom->track[i - 1].length = cdrom->track[i].offset - - cdrom->track[i - 1].offset; - } - } - } - if (i == (cdrom->numtracks + 1)) { - okay = 1; - } - return (okay ? 0 : -1); -} - -/* Get CD-ROM status */ -static CDstatus -SDL_SYS_CDStatus(SDL_CD * cdrom, int *position) -{ - CDstatus status; - struct cd_audio_cmd cmd; - cmd.audio_cmds = CD_INFO_AUDIO; - - if (SDL_SYS_CDioctl(cdrom->id, DKAUDIO, &cmd) < 0) { -#ifdef DEBUG_CDROM - fprintf(stderr, "ioctl failed in SDL_SYS_CDStatus (%s)\n", - SDL_GetError()); -#endif - status = CD_ERROR; - } else { - switch (cmd.status) { - case CD_NO_AUDIO: - case CD_COMPLETED: - status = CD_STOPPED; - break; - case CD_PLAY_AUDIO: - status = CD_PLAYING; - break; - case CD_PAUSE_AUDIO: - status = CD_PAUSED; - break; - case CD_NOT_VALID: -#ifdef DEBUG_CDROM - fprintf(stderr, "cdStatus failed with CD_NOT_VALID\n"); -#endif - status = CD_ERROR; - break; - case CD_STATUS_ERROR: -#ifdef DEBUG_CDROM - fprintf(stderr, "cdStatus failed with CD_STATUS_ERROR\n"); -#endif - status = CD_ERROR; - break; - default: -#ifdef DEBUG_CDROM - fprintf(stderr, "cdStatus failed with unknown error\n"); -#endif - status = CD_ERROR; - break; - } - } - if (position) { - if (status == CD_PLAYING || (status == CD_PAUSED)) { - *position = - MSF_TO_FRAMES(cmd.indexing.info_audio.current_mins, - cmd.indexing.info_audio.current_secs, - cmd.indexing.info_audio.current_frames); - } else { - *position = 0; - } - } - return status; -} - -/* Start play */ -static int -SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length) -{ - struct cd_audio_cmd cmd; - - /* - * My CD Rom is muted by default. I think I read that this is new with - * AIX 4.3. SDL does not change the volume, so I need a kludge. Maybe - * its better to do this elsewhere? - */ - cmd.audio_cmds = CD_PLAY_AUDIO | CD_SET_VOLUME; - cmd.msf_flag = TRUE; - FRAMES_TO_MSF(start, - &cmd.indexing.msf.first_mins, - &cmd.indexing.msf.first_secs, - &cmd.indexing.msf.first_frames); - FRAMES_TO_MSF(start + length, - &cmd.indexing.msf.last_mins, - &cmd.indexing.msf.last_secs, &cmd.indexing.msf.last_frames); - cmd.volume_type = CD_VOLUME_ALL; - cmd.all_channel_vol = 255; /* This is a uchar. What is a good value? No docu! */ - cmd.out_port_0_sel = CD_AUDIO_CHNL_0; - cmd.out_port_1_sel = CD_AUDIO_CHNL_1; - cmd.out_port_2_sel = CD_AUDIO_CHNL_2; - cmd.out_port_3_sel = CD_AUDIO_CHNL_3; - -#ifdef DEBUG_CDROM - fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", - cmd.indexing.msf.first_mins, - cmd.indexing.msf.first_secs, - cmd.indexing.msf.first_frames, - cmd.indexing.msf.last_mins, - cmd.indexing.msf.last_secs, cmd.indexing.msf.last_frames); -#endif - return (SDL_SYS_CDioctl(cdrom->id, DKAUDIO, &cmd)); -} - -/* Pause play */ -static int -SDL_SYS_CDPause(SDL_CD * cdrom) -{ - struct cd_audio_cmd cmd; - cmd.audio_cmds = CD_PAUSE_AUDIO; - return (SDL_SYS_CDioctl(cdrom->id, DKAUDIO, &cmd)); -} - -/* Resume play */ -static int -SDL_SYS_CDResume(SDL_CD * cdrom) -{ - struct cd_audio_cmd cmd; - cmd.audio_cmds = CD_RESUME_AUDIO; - return (SDL_SYS_CDioctl(cdrom->id, DKAUDIO, &cmd)); -} - -/* Stop play */ -static int -SDL_SYS_CDStop(SDL_CD * cdrom) -{ - struct cd_audio_cmd cmd; - cmd.audio_cmds = CD_STOP_AUDIO; - return (SDL_SYS_CDioctl(cdrom->id, DKAUDIO, &cmd)); -} - -/* Eject the CD-ROM */ -static int -SDL_SYS_CDEject(SDL_CD * cdrom) -{ - return (SDL_SYS_CDioctl(cdrom->id, DKEJECT, 0)); -} - -/* Close the CD-ROM handle */ -static void -SDL_SYS_CDClose(SDL_CD * cdrom) -{ - close(cdrom->id); -} - -void -SDL_SYS_CDQuit(void) -{ - int i; - - if (SDL_numcds > 0) { - for (i = 0; i < SDL_numcds; ++i) { - SDL_free(SDL_cdlist[i]); - } - SDL_numcds = 0; - } -} - -#endif /* SDL_CDROM_AIX */ -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/cdrom/beos/SDL_syscdrom.cc Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,427 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifdef SDL_CDROM_BEOS - -/* Functions for system-level CD-ROM audio control on BeOS - (not completely implemented yet) - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -#include <scsi.h> -#include <Directory.h> -#include <Entry.h> -#include <Path.h> - -#include "SDL_cdrom.h" -extern "C" -{ -#include "../SDL_syscdrom.h" -} - -/* Constants to help us get at the SCSI table-of-contents info */ -#define CD_NUMTRACKS(toc) toc.toc_data[3] -#define CD_TRACK(toc, track) (&toc.toc_data[6+(track)*8]) -#define CD_TRACK_N(toc, track) CD_TRACK(toc, track)[0] -#define CD_TRACK_M(toc, track) CD_TRACK(toc, track)[3] -#define CD_TRACK_S(toc, track) CD_TRACK(toc, track)[4] -#define CD_TRACK_F(toc, track) CD_TRACK(toc, track)[5] - -/* Constants to help us get at the SCSI position info */ -#define POS_TRACK(pos) pos.position[6] -#define POS_ABS_M(pos) pos.position[9] -#define POS_ABS_S(pos) pos.position[10] -#define POS_ABS_F(pos) pos.position[11] -#define POS_REL_M(pos) pos.position[13] -#define POS_REL_S(pos) pos.position[14] -#define POS_REL_F(pos) pos.position[15] - -/* The maximum number of CD-ROM drives we'll detect */ -#define MAX_DRIVES 16 - -/* A list of available CD-ROM drives */ -static char *SDL_cdlist[MAX_DRIVES]; - -/* The system-dependent CD control functions */ -static const char *SDL_SYS_CDName(int drive); -static int SDL_SYS_CDOpen(int drive); -static int SDL_SYS_CDGetTOC(SDL_CD * cdrom); -static CDstatus SDL_SYS_CDStatus(SDL_CD * cdrom, int *position); -static int SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length); -static int SDL_SYS_CDPause(SDL_CD * cdrom); -static int SDL_SYS_CDResume(SDL_CD * cdrom); -static int SDL_SYS_CDStop(SDL_CD * cdrom); -static int SDL_SYS_CDEject(SDL_CD * cdrom); -static void SDL_SYS_CDClose(SDL_CD * cdrom); -int try_dir(const char *directory); - - -/* Check a drive to see if it is a CD-ROM */ -static int -CheckDrive(char *drive) -{ - struct stat stbuf; - int is_cd, cdfd; - device_geometry info; - - /* If it doesn't exist, return -1 */ - if (stat(drive, &stbuf) < 0) { - return (-1); - } - - /* If it does exist, verify that it's an available CD-ROM */ - is_cd = 0; - cdfd = open(drive, 0); - if (cdfd >= 0) { - if (ioctl(cdfd, B_GET_GEOMETRY, &info) == B_NO_ERROR) { - if (info.device_type == B_CD) { - is_cd = 1; - } - } - close(cdfd); - } else { - /* This can happen when the drive is open .. (?) */ ; - is_cd = 1; - } - return (is_cd); -} - -/* Add a CD-ROM drive to our list of valid drives */ -static void -AddDrive(char *drive) -{ - int i; - size_t len; - - if (SDL_numcds < MAX_DRIVES) { - /* Add this drive to our list */ - i = SDL_numcds; - len = SDL_strlen(drive) + 1; - SDL_cdlist[i] = (char *) SDL_malloc(len); - if (SDL_cdlist[i] == NULL) { - SDL_OutOfMemory(); - return; - } - SDL_strlcpy(SDL_cdlist[i], drive, len); - ++SDL_numcds; -#ifdef CDROM_DEBUG - fprintf(stderr, "Added CD-ROM drive: %s\n", drive); -#endif - } -} - -/* IDE bus scanning magic */ -enum -{ - IDE_GET_DEVICES_INFO = B_DEVICE_OP_CODES_END + 50, -}; -struct ide_ctrl_info -{ - bool ide_0_present; - bool ide_0_master_present; - bool ide_0_slave_present; - int ide_0_master_type; - int ide_0_slave_type; - bool ide_1_present; - bool ide_1_master_present; - bool ide_1_slave_present; - int ide_1_master_type; - int ide_1_slave_type; -}; - -int -SDL_SYS_CDInit(void) -{ - char *SDLcdrom; - int raw_fd; - struct ide_ctrl_info info; - - /* Fill in our driver capabilities */ - SDL_CDcaps.Name = SDL_SYS_CDName; - SDL_CDcaps.Open = SDL_SYS_CDOpen; - SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; - SDL_CDcaps.Status = SDL_SYS_CDStatus; - SDL_CDcaps.Play = SDL_SYS_CDPlay; - SDL_CDcaps.Pause = SDL_SYS_CDPause; - SDL_CDcaps.Resume = SDL_SYS_CDResume; - SDL_CDcaps.Stop = SDL_SYS_CDStop; - SDL_CDcaps.Eject = SDL_SYS_CDEject; - SDL_CDcaps.Close = SDL_SYS_CDClose; - - /* Look in the environment for our CD-ROM drive list */ - SDLcdrom = SDL_getenv("SDL_CDROM"); /* ':' separated list of devices */ - if (SDLcdrom != NULL) { - char *cdpath, *delim; - size_t len = SDL_strlen(SDLcdrom) + 1; - cdpath = SDL_stack_alloc(char, len); - if (cdpath != NULL) { - SDL_strlcpy(cdpath, SDLcdrom, len); - SDLcdrom = cdpath; - do { - delim = SDL_strchr(SDLcdrom, ':'); - if (delim) { - *delim++ = '\0'; - } - if (CheckDrive(SDLcdrom) > 0) { - AddDrive(SDLcdrom); - } - if (delim) { - SDLcdrom = delim; - } else { - SDLcdrom = NULL; - } - } while (SDLcdrom); - SDL_stack_free(cdpath); - } - - /* If we found our drives, there's nothing left to do */ - if (SDL_numcds > 0) { - return (0); - } - } - - /* Scan the system for CD-ROM drives */ - try_dir("/dev/disk"); - return 0; -} - - -int -try_dir(const char *directory) -{ - BDirectory dir; - dir.SetTo(directory); - if (dir.InitCheck() != B_NO_ERROR) { - return false; - } - dir.Rewind(); - BEntry entry; - while (dir.GetNextEntry(&entry) >= 0) { - BPath path; - const char *name; - entry_ref e; - - if (entry.GetPath(&path) != B_NO_ERROR) - continue; - name = path.Path(); - - if (entry.GetRef(&e) != B_NO_ERROR) - continue; - - if (entry.IsDirectory()) { - if (SDL_strcmp(e.name, "floppy") == 0) - continue; /* ignore floppy (it is not silent) */ - int devfd = try_dir(name); - if (devfd >= 0) - return devfd; - } else { - int devfd; - device_geometry g; - - if (SDL_strcmp(e.name, "raw") != 0) - continue; /* ignore partitions */ - - devfd = open(name, O_RDONLY); - if (devfd < 0) - continue; - - if (ioctl(devfd, B_GET_GEOMETRY, &g, sizeof(g)) >= 0) { - if (g.device_type == B_CD) { - AddDrive(strdup(name)); - } - } - close(devfd); - } - } - return B_ERROR; -} - - -/* General ioctl() CD-ROM command function */ -static int -SDL_SYS_CDioctl(int index, int command, void *arg) -{ - int okay; - int fd; - - okay = 0; - fd = open(SDL_cdlist[index], 0); - if (fd >= 0) { - if (ioctl(fd, command, arg) == B_NO_ERROR) { - okay = 1; - } - close(fd); - } - return (okay ? 0 : -1); -} - -static const char * -SDL_SYS_CDName(int drive) -{ - return (SDL_cdlist[drive]); -} - -static int -SDL_SYS_CDOpen(int drive) -{ - return (drive); -} - -static int -SDL_SYS_CDGetTOC(SDL_CD * cdrom) -{ - int i; - scsi_toc toc; - - if (SDL_SYS_CDioctl(cdrom->id, B_SCSI_GET_TOC, &toc) == 0) { - cdrom->numtracks = CD_NUMTRACKS(toc); - if (cdrom->numtracks > SDL_MAX_TRACKS) { - cdrom->numtracks = SDL_MAX_TRACKS; - } - for (i = 0; i <= cdrom->numtracks; ++i) { - cdrom->track[i].id = CD_TRACK_N(toc, i); - /* FIXME: How do we tell on BeOS? */ - cdrom->track[i].type = SDL_AUDIO_TRACK; - cdrom->track[i].offset = MSF_TO_FRAMES(CD_TRACK_M(toc, i), - CD_TRACK_S(toc, i), - CD_TRACK_F(toc, i)); - cdrom->track[i].length = 0; - if (i > 0) { - cdrom->track[i - 1].length = - cdrom->track[i].offset - cdrom->track[i - 1].offset; - } - } - return (0); - } else { - return (-1); - } -} - -/* Get CD-ROM status */ -static CDstatus -SDL_SYS_CDStatus(SDL_CD * cdrom, int *position) -{ - CDstatus status; - int fd; - int cur_frame; - scsi_position pos; - - fd = open(SDL_cdlist[cdrom->id], 0); - cur_frame = 0; - if (fd >= 0) { - if (ioctl(fd, B_SCSI_GET_POSITION, &pos) == B_NO_ERROR) { - cur_frame = - MSF_TO_FRAMES(POS_ABS_M(pos), POS_ABS_S(pos), POS_ABS_F(pos)); - } - if (!pos.position[1] || (pos.position[1] >= 0x13) || - ((pos.position[1] == 0x12) && (!pos.position[6]))) { - status = CD_STOPPED; - } else if (pos.position[1] == 0x11) { - status = CD_PLAYING; - } else { - status = CD_PAUSED; - } - close(fd); - } else { - status = CD_TRAYEMPTY; - } - if (position) { - *position = cur_frame; - } - return (status); -} - -/* Start play */ -static int -SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length) -{ - int okay; - int fd; - scsi_play_position pos; - - okay = 0; - fd = open(SDL_cdlist[cdrom->id], 0); - if (fd >= 0) { - FRAMES_TO_MSF(start, &pos.start_m, &pos.start_s, &pos.start_f); - FRAMES_TO_MSF(start + length, &pos.end_m, &pos.end_s, &pos.end_f); - if (ioctl(fd, B_SCSI_PLAY_POSITION, &pos) == B_NO_ERROR) { - okay = 1; - } - close(fd); - } - return (okay ? 0 : -1); -} - -/* Pause play */ -static int -SDL_SYS_CDPause(SDL_CD * cdrom) -{ - return (SDL_SYS_CDioctl(cdrom->id, B_SCSI_PAUSE_AUDIO, 0)); -} - -/* Resume play */ -static int -SDL_SYS_CDResume(SDL_CD * cdrom) -{ - return (SDL_SYS_CDioctl(cdrom->id, B_SCSI_RESUME_AUDIO, 0)); -} - -/* Stop play */ -static int -SDL_SYS_CDStop(SDL_CD * cdrom) -{ - return (SDL_SYS_CDioctl(cdrom->id, B_SCSI_STOP_AUDIO, 0)); -} - -/* Eject the CD-ROM */ -static int -SDL_SYS_CDEject(SDL_CD * cdrom) -{ - return (SDL_SYS_CDioctl(cdrom->id, B_SCSI_EJECT, 0)); -} - -/* Close the CD-ROM handle */ -static void -SDL_SYS_CDClose(SDL_CD * cdrom) -{ - close(cdrom->id); -} - -void -SDL_SYS_CDQuit(void) -{ - int i; - - if (SDL_numcds > 0) { - for (i = 0; i < SDL_numcds; ++i) { - SDL_free(SDL_cdlist[i]); - } - SDL_numcds = 0; - } -} - -#endif /* SDL_CDROM_BEOS */ -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/cdrom/bsdi/SDL_syscdrom.c Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,550 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifdef SDL_CDROM_BSDI - -/* - * Functions for system-level CD-ROM audio control for BSD/OS 4.x - * This started life out as a copy of the freebsd/SDL_cdrom.c file but was - * heavily modified. Works for standard (MMC) SCSI and ATAPI CDrom drives. - * - * Steven Schultz - sms@to.gd-es.com -*/ - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <err.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include </sys/dev/scsi/scsi.h> -#include </sys/dev/scsi/scsi_ioctl.h> - -#include "SDL_cdrom.h" -#include "../SDL_syscdrom.h" - -/* - * The msf_to_frame and frame_to_msf were yanked from libcdrom and inlined - * here so that -lcdrom doesn't have to be dragged in for something so simple. -*/ - -#define FRAMES_PER_SECOND 75 -#define FRAMES_PER_MINUTE (FRAMES_PER_SECOND * 60) - -int -msf_to_frame(int minute, int second, int frame) -{ - return (minute * FRAMES_PER_MINUTE + second * FRAMES_PER_SECOND + frame); -} - -void -frame_to_msf(int frame, int *minp, int *secp, int *framep) -{ - *minp = frame / FRAMES_PER_MINUTE; - *secp = (frame % FRAMES_PER_MINUTE) / FRAMES_PER_SECOND; - *framep = frame % FRAMES_PER_SECOND; -} - -/* The maximum number of CD-ROM drives we'll detect */ -#define MAX_DRIVES 16 - -/* A list of available CD-ROM drives */ -static char *SDL_cdlist[MAX_DRIVES]; -static dev_t SDL_cdmode[MAX_DRIVES]; - -/* The system-dependent CD control functions */ -static const char *SDL_SYS_CDName(int drive); -static int SDL_SYS_CDOpen(int drive); -static int SDL_SYS_CDGetTOC(SDL_CD * cdrom); -static CDstatus SDL_SYS_CDStatus(SDL_CD * cdrom, int *position); -static int SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length); -static int SDL_SYS_CDPause(SDL_CD * cdrom); -static int SDL_SYS_CDResume(SDL_CD * cdrom); -static int SDL_SYS_CDStop(SDL_CD * cdrom); -static int SDL_SYS_CDEject(SDL_CD * cdrom); -static void SDL_SYS_CDClose(SDL_CD * cdrom); - -typedef struct scsi_cdb cdb_t; - -static int -scsi_cmd(int fd, - struct scsi_cdb *cdb, - int cdblen, - int rw, caddr_t data, int datalen, struct scsi_user_cdb *sus) -{ - int scsistatus; - unsigned char *cp; - struct scsi_user_cdb suc; - - /* safety checks */ - if (!cdb) - return (-1); - if (rw != SUC_READ && rw != SUC_WRITE) - return (-1); - - suc.suc_flags = rw; - suc.suc_cdblen = cdblen; - bcopy(cdb, suc.suc_cdb, cdblen); - suc.suc_datalen = datalen; - suc.suc_data = data; - suc.suc_timeout = 10; /* 10 secs max for TUR or SENSE */ - if (ioctl(fd, SCSIRAWCDB, &suc) == -1) - return (-11); - scsistatus = suc.suc_sus.sus_status; - cp = suc.suc_sus.sus_sense; - -/* - * If a place to copy the sense data back to has been provided then the - * caller is responsible for checking the errors and printing any information - * out if the status was not successful. -*/ - if (scsistatus != 0 && !sus) { - fprintf(stderr, "scsistatus = %x cmd = %x\n", scsistatus, cdb[0]); - fprintf(stderr, - "sense %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n", - cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7], - cp[8], cp[9], cp[10], cp[11], cp[12], cp[13], cp[14], cp[15]); - return (1); - } - if (sus) - bcopy(&suc, sus, sizeof(struct scsi_user_cdb)); - if (scsistatus) - return (1); /* Return non-zero for unsuccessful status */ - return (0); -} - -/* request vendor brand and model */ -unsigned char * -Inquiry(int fd) -{ - static struct scsi_cdb6 cdb = { - 0x12, - 0, 0, 0, - 56, - 0 - }; - static unsigned char Inqbuffer[56]; - - if (scsi_cmd(fd, (cdb_t *) & cdb, 6, SUC_READ, Inqbuffer, - sizeof(Inqbuffer), 0)) - return ("\377"); - return (Inqbuffer); -} - -#define ADD_SENSECODE 12 -#define ADD_SC_QUALIFIER 13 - -int -TestForMedium(int fd) -{ - int sts, asc, ascq; - struct scsi_user_cdb sus; - static struct scsi_cdb6 cdb = { - CMD_TEST_UNIT_READY, /* command */ - 0, /* reserved */ - 0, /* reserved */ - 0, /* reserved */ - 0, /* reserved */ - 0 /* reserved */ - }; - - again:sts = scsi_cmd(fd, (cdb_t *) & cdb, 6, SUC_READ, 0, 0, &sus); - asc = sus.suc_sus.sus_sense[ADD_SENSECODE]; - ascq = sus.suc_sus.sus_sense[ADD_SC_QUALIFIER]; - if (asc == 0x3a && ascq == 0x0) /* no medium */ - return (0); - if (asc == 0x28 && ascq == 0x0) /* medium changed */ - goto again; - if (asc == 0x4 && ascq == 0x1) { /* coming ready */ - sleep(2); - goto again; - } - return (1); -} - -/* Check a drive to see if it is a CD-ROM */ -static int -CheckDrive(char *drive, struct stat *stbuf) -{ - int is_cd = 0, cdfd; - char *p; - - /* If it doesn't exist, return -1 */ - if (stat(drive, stbuf) < 0) { - return (-1); - } - - /* If it does exist, verify that it's an available CD-ROM */ - cdfd = open(drive, (O_RDONLY | O_EXCL | O_NONBLOCK), 0); - if (cdfd >= 0) { - p = Inquiry(cdfd); - if (*p == TYPE_ROM) - is_cd = 1; - close(cdfd); - } - return (is_cd); -} - -/* Add a CD-ROM drive to our list of valid drives */ -static void -AddDrive(char *drive, struct stat *stbuf) -{ - int i; - - if (SDL_numcds < MAX_DRIVES) { - /* Check to make sure it's not already in our list. - This can happen when we see a drive via symbolic link. - */ - for (i = 0; i < SDL_numcds; ++i) { - if (stbuf->st_rdev == SDL_cdmode[i]) { -#ifdef DEBUG_CDROM - fprintf(stderr, "Duplicate drive detected: %s == %s\n", - drive, SDL_cdlist[i]); -#endif - return; - } - } - - /* Add this drive to our list */ - i = SDL_numcds; - SDL_cdlist[i] = SDL_strdup(drive); - if (SDL_cdlist[i] == NULL) { - SDL_OutOfMemory(); - return; - } - SDL_cdmode[i] = stbuf->st_rdev; - ++SDL_numcds; -#ifdef DEBUG_CDROM - fprintf(stderr, "Added CD-ROM drive: %s\n", drive); -#endif - } -} - -int -SDL_SYS_CDInit(void) -{ - /* checklist: /dev/rsr?c */ - static char *checklist[] = { - "?0 rsr?", NULL - }; - char *SDLcdrom; - int i, j, exists; - char drive[32]; - struct stat stbuf; - - /* Fill in our driver capabilities */ - SDL_CDcaps.Name = SDL_SYS_CDName; - SDL_CDcaps.Open = SDL_SYS_CDOpen; - SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; - SDL_CDcaps.Status = SDL_SYS_CDStatus; - SDL_CDcaps.Play = SDL_SYS_CDPlay; - SDL_CDcaps.Pause = SDL_SYS_CDPause; - SDL_CDcaps.Resume = SDL_SYS_CDResume; - SDL_CDcaps.Stop = SDL_SYS_CDStop; - SDL_CDcaps.Eject = SDL_SYS_CDEject; - SDL_CDcaps.Close = SDL_SYS_CDClose; - - /* Look in the environment for our CD-ROM drive list */ - SDLcdrom = SDL_getenv("SDL_CDROM"); /* ':' separated list of devices */ - if (SDLcdrom != NULL) { - char *cdpath, *delim; - size_t len = SDL_strlen(SDLcdrom) + 1; - cdpath = SDL_stack_alloc(char, len); - if (cdpath != NULL) { - SDL_strlcpy(cdpath, SDLcdrom, len); - SDLcdrom = cdpath; - do { - delim = SDL_strchr(SDLcdrom, ':'); - if (delim) { - *delim++ = '\0'; - } - if (CheckDrive(SDLcdrom, &stbuf) > 0) { - AddDrive(SDLcdrom, &stbuf); - } - if (delim) { - SDLcdrom = delim; - } else { - SDLcdrom = NULL; - } - } while (SDLcdrom); - SDL_stack_free(cdpath); - } - - /* If we found our drives, there's nothing left to do */ - if (SDL_numcds > 0) { - return (0); - } - } - - /* Scan the system for CD-ROM drives */ - for (i = 0; checklist[i]; ++i) { - if (checklist[i][0] == '?') { - char *insert; - exists = 1; - for (j = checklist[i][1]; exists; ++j) { - SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%sc", - &checklist[i][3]); - insert = SDL_strchr(drive, '?'); - if (insert != NULL) { - *insert = j; - } - switch (CheckDrive(drive, &stbuf)) { - /* Drive exists and is a CD-ROM */ - case 1: - AddDrive(drive, &stbuf); - break; - /* Drive exists, but isn't a CD-ROM */ - case 0: - break; - /* Drive doesn't exist */ - case -1: - exists = 0; - break; - } - } - } else { - SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%s", - checklist[i]); - if (CheckDrive(drive, &stbuf) > 0) { - AddDrive(drive, &stbuf); - } - } - } - return (0); -} - -static const char * -SDL_SYS_CDName(int drive) -{ - return (SDL_cdlist[drive]); -} - -static int -SDL_SYS_CDOpen(int drive) -{ - return (open(SDL_cdlist[drive], O_RDONLY | O_NONBLOCK | O_EXCL, 0)); -} - -static int -SDL_SYS_CDGetTOC(SDL_CD * cdrom) -{ - u_char cdb[10], buf[4], *p, *toc; - struct scsi_user_cdb sus; - int i, sts, first_track, last_track, ntracks, toc_size; - - bzero(cdb, sizeof(cdb)); - cdb[0] = 0x43; /* Read TOC */ - cdb[1] = 0x2; /* MSF */ - cdb[8] = 4; /* size TOC header */ - sts = scsi_cmd(cdrom->id, (cdb_t *) cdb, 10, SUC_READ, buf, 4, &sus); - if (sts < 0) - return (-1); - first_track = buf[2]; - last_track = buf[3]; - ntracks = last_track - first_track + 1; - cdrom->numtracks = ntracks; - toc_size = 4 + (ntracks + 1) * 8; - toc = (u_char *) SDL_malloc(toc_size); - if (toc == NULL) - return (-1); - bzero(cdb, sizeof(cdb)); - cdb[0] = 0x43; - cdb[1] = 0x2; - cdb[6] = first_track; - cdb[7] = toc_size >> 8; - cdb[8] = toc_size & 0xff; - sts = scsi_cmd(cdrom->id, (cdb_t *) cdb, 10, SUC_READ, toc, toc_size, - &sus); - if (sts < 0) { - SDL_free(toc); - return (-1); - } - - for (i = 0, p = toc + 4; i <= ntracks; i++, p += 8) { - if (i == ntracks) - cdrom->track[i].id = 0xAA; /* Leadout */ - else - cdrom->track[i].id = first_track + i; - if (p[1] & 0x20) - cdrom->track[i].type = SDL_DATA_TRACK; - else - cdrom->track[i].type = SDL_AUDIO_TRACK; - cdrom->track[i].offset = msf_to_frame(p[5], p[6], p[7]); - cdrom->track[i].length = 0; - if (i > 0) - cdrom->track[i - 1].length = cdrom->track[i].offset - - cdrom->track[i - 1].offset; - } - SDL_free(toc); - return (0); -} - -/* Get CD-ROM status */ -static CDstatus -SDL_SYS_CDStatus(SDL_CD * cdrom, int *position) -{ - CDstatus status; - u_char cdb[10], buf[16]; - int sts; - struct scsi_user_cdb sus; - - bzero(cdb, sizeof(cdb)); - cdb[0] = 0x42; /* read subq */ - cdb[1] = 0x2; /* MSF */ - cdb[2] = 0x40; /* q channel */ - cdb[3] = 1; /* current pos */ - cdb[7] = sizeof(buf) >> 8; - cdb[8] = sizeof(buf) & 0xff; - sts = scsi_cmd(cdrom->id, (cdb_t *) cdb, 10, SUC_READ, buf, sizeof(buf), - &sus); - if (sts < 0) - return (-1); - if (sts) { - if (TestForMedium(cdrom->id) == 0) - status = CD_TRAYEMPTY; - else - status = CD_ERROR; - } else { - switch (buf[1]) { - case 0x11: - status = CD_PLAYING; - break; - case 0x12: - status = CD_PAUSED; - break; - case 0x13: - case 0x14: - case 0x15: - status = CD_STOPPED; - break; - default: - status = CD_ERROR; - break; - } - } - if (position) { - if (status == CD_PLAYING || (status == CD_PAUSED)) - *position = msf_to_frame(buf[9], buf[10], buf[11]); - else - *position = 0; - } - return (status); -} - -/* Start play */ -static int -SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length) -{ - u_char cdb[10]; - int sts, minute, second, frame, eminute, esecond, eframe; - struct scsi_user_cdb sus; - - bzero(cdb, sizeof(cdb)); - cdb[0] = 0x47; /* Play */ - frame_to_msf(start, &minute, &second, &frame); - frame_to_msf(start + length, &eminute, &esecond, &eframe); - cdb[3] = minute; - cdb[4] = second; - cdb[5] = frame; - cdb[6] = eminute; - cdb[7] = esecond; - cdb[8] = eframe; - sts = scsi_cmd(cdrom->id, (cdb_t *) cdb, 10, SUC_READ, 0, 0, &sus); - return (sts); -} - -static int -pauseresume(SDL_CD * cdrom, int flag) -{ - u_char cdb[10]; - struct scsi_user_cdb sus; - - bzero(cdb, sizeof(cdb)); - cdb[0] = 0x4b; - cdb[8] = flag & 0x1; - return (scsi_cmd(cdrom->id, (cdb_t *) cdb, 10, SUC_READ, 0, 0, &sus)); -} - -/* Pause play */ -static int -SDL_SYS_CDPause(SDL_CD * cdrom) -{ - return (pauseresume(cdrom, 0)); -} - -/* Resume play */ -static int -SDL_SYS_CDResume(SDL_CD * cdrom) -{ - return (pauseresume(cdrom, 1)); -} - -/* Stop play */ -static int -SDL_SYS_CDStop(SDL_CD * cdrom) -{ - u_char cdb[6]; - struct scsi_user_cdb sus; - - bzero(cdb, sizeof(cdb)); - cdb[0] = 0x1b; /* stop */ - cdb[1] = 1; /* immediate */ - return (scsi_cmd(cdrom->id, (cdb_t *) cdb, 6, SUC_READ, 0, 0, &sus)); -} - -/* Eject the CD-ROM */ -static int -SDL_SYS_CDEject(SDL_CD * cdrom) -{ - u_char cdb[6]; - struct scsi_user_cdb sus; - - bzero(cdb, sizeof(cdb)); - cdb[0] = 0x1b; /* stop */ - cdb[1] = 1; /* immediate */ - cdb[4] = 2; /* eject */ - return (scsi_cmd(cdrom->id, (cdb_t *) cdb, 6, SUC_READ, 0, 0, &sus)); -} - -/* Close the CD-ROM handle */ -static void -SDL_SYS_CDClose(SDL_CD * cdrom) -{ - close(cdrom->id); -} - -void -SDL_SYS_CDQuit(void) -{ - int i; - - if (SDL_numcds > 0) { - for (i = 0; i < SDL_numcds; ++i) { - SDL_free(SDL_cdlist[i]); - } - } - SDL_numcds = 0; -} - -#endif /* SDL_CDROM_BSDI */ -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/cdrom/dc/SDL_syscdrom.c Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,187 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifdef SDL_CDROM_DC - -/* Functions for system-level CD-ROM audio control */ - -#include <dc/cdrom.h> -#include <dc/spu.h> - -#include "SDL_cdrom.h" -#include "../SDL_syscdrom.h" - -/* The system-dependent CD control functions */ -static const char *SDL_SYS_CDName(int drive); -static int SDL_SYS_CDOpen(int drive); -static int SDL_SYS_CDGetTOC(SDL_CD * cdrom); -static CDstatus SDL_SYS_CDStatus(SDL_CD * cdrom, int *position); -static int SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length); -static int SDL_SYS_CDPause(SDL_CD * cdrom); -static int SDL_SYS_CDResume(SDL_CD * cdrom); -static int SDL_SYS_CDStop(SDL_CD * cdrom); -static int SDL_SYS_CDEject(SDL_CD * cdrom); -static void SDL_SYS_CDClose(SDL_CD * cdrom); - - -int -SDL_SYS_CDInit(void) -{ - /* Fill in our driver capabilities */ - SDL_CDcaps.Name = SDL_SYS_CDName; - SDL_CDcaps.Open = SDL_SYS_CDOpen; - SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; - SDL_CDcaps.Status = SDL_SYS_CDStatus; - SDL_CDcaps.Play = SDL_SYS_CDPlay; - SDL_CDcaps.Pause = SDL_SYS_CDPause; - SDL_CDcaps.Resume = SDL_SYS_CDResume; - SDL_CDcaps.Stop = SDL_SYS_CDStop; - SDL_CDcaps.Eject = SDL_SYS_CDEject; - SDL_CDcaps.Close = SDL_SYS_CDClose; - - return (0); -} - -static const char * -SDL_SYS_CDName(int drive) -{ - return "/cd"; -} - -static int -SDL_SYS_CDOpen(int drive) -{ - return (drive); -} - -#define TRACK_CDDA 0 -static int -SDL_SYS_CDGetTOC(SDL_CD * cdrom) -{ - CDROM_TOC toc; - int ret, i; - - ret = cdrom_read_toc(&toc, 0); - if (ret != ERR_OK) { - return -1; - } - - cdrom->numtracks = TOC_TRACK(toc.last) - TOC_TRACK(toc.first) + 1; - for (i = 0; i < cdrom->numtracks; i++) { - unsigned long entry = toc.entry[i]; - cdrom->track[i].id = i + 1; - cdrom->track[i].type = - (TOC_CTRL(toc.entry[i]) == - TRACK_CDDA) ? SDL_AUDIO_TRACK : SDL_DATA_TRACK; - cdrom->track[i].offset = TOC_LBA(entry) - 150; - cdrom->track[i].length = - TOC_LBA((i + 1 < - toc.last) ? toc.entry[i + 1] : toc.leadout_sector) - - TOC_LBA(entry); - } - - return 0; -} - -/* Get CD-ROM status */ -static CDstatus -SDL_SYS_CDStatus(SDL_CD * cdrom, int *position) -{ - int ret, dc_status, disc_type; - - ret = cdrom_get_status(&dc_status, &disc_type); - if (ret != ERR_OK) - return CD_ERROR; - - switch (dc_status) { -// case CD_STATUS_BUSY: - case CD_STATUS_PAUSED: - return CD_PAUSED; - case CD_STATUS_STANDBY: - return CD_STOPPED; - case CD_STATUS_PLAYING: - return CD_PLAYING; -// case CD_STATUS_SEEKING: -// case CD_STATUS_SCANING: - case CD_STATUS_OPEN: - case CD_STATUS_NO_DISC: - return CD_TRAYEMPTY; - default: - return CD_ERROR; - } -} - -/* Start play */ -static int -SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length) -{ - int ret = - cdrom_cdda_play(start - 150, start - 150 + length, 1, CDDA_SECTORS); - return ret == ERR_OK ? 0 : -1; -} - -/* Pause play */ -static int -SDL_SYS_CDPause(SDL_CD * cdrom) -{ - int ret = cdrom_cdda_pause(); - return ret == ERR_OK ? 0 : -1; -} - -/* Resume play */ -static int -SDL_SYS_CDResume(SDL_CD * cdrom) -{ - int ret = cdrom_cdda_resume(); - return ret == ERR_OK ? 0 : -1; -} - -/* Stop play */ -static int -SDL_SYS_CDStop(SDL_CD * cdrom) -{ - int ret = cdrom_spin_down(); - return ret == ERR_OK ? 0 : -1; -} - -/* Eject the CD-ROM */ -static int -SDL_SYS_CDEject(SDL_CD * cdrom) -{ - return -1; -} - -/* Close the CD-ROM handle */ -static void -SDL_SYS_CDClose(SDL_CD * cdrom) -{ -} - -void -SDL_SYS_CDQuit(void) -{ - -} - -#endif /* SDL_CDROM_DC */ -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/cdrom/dummy/SDL_syscdrom.c Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#if defined(SDL_CDROM_DUMMY) || defined(SDL_CDROM_DISABLED) - -/* Stub functions for system-level CD-ROM audio control */ - -#include "SDL_cdrom.h" -#include "../SDL_syscdrom.h" - -int -SDL_SYS_CDInit(void) -{ - return (0); -} - -void -SDL_SYS_CDQuit(void) -{ - return; -} - -#endif /* SDL_CDROM_DUMMY || SDL_CDROM_DISABLED */ -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/cdrom/freebsd/SDL_syscdrom.c Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,422 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifdef SDL_CDROM_FREEBSD - -/* Functions for system-level CD-ROM audio control */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> -#include <unistd.h> -#include <sys/cdio.h> - -#include "SDL_cdrom.h" -#include "../SDL_syscdrom.h" - - -/* The maximum number of CD-ROM drives we'll detect */ -#define MAX_DRIVES 16 - -/* A list of available CD-ROM drives */ -static char *SDL_cdlist[MAX_DRIVES]; -static dev_t SDL_cdmode[MAX_DRIVES]; - -/* The system-dependent CD control functions */ -static const char *SDL_SYS_CDName(int drive); -static int SDL_SYS_CDOpen(int drive); -static int SDL_SYS_CDGetTOC(SDL_CD * cdrom); -static CDstatus SDL_SYS_CDStatus(SDL_CD * cdrom, int *position); -static int SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length); -static int SDL_SYS_CDPause(SDL_CD * cdrom); -static int SDL_SYS_CDResume(SDL_CD * cdrom); -static int SDL_SYS_CDStop(SDL_CD * cdrom); -static int SDL_SYS_CDEject(SDL_CD * cdrom); -static void SDL_SYS_CDClose(SDL_CD * cdrom); - -/* Some ioctl() errno values which occur when the tray is empty */ -#define ERRNO_TRAYEMPTY(errno) \ - ((errno == EIO) || (errno == ENOENT) || (errno == EINVAL)) - -/* Check a drive to see if it is a CD-ROM */ -static int -CheckDrive(char *drive, struct stat *stbuf) -{ - int is_cd, cdfd; - struct ioc_read_subchannel info; - - /* If it doesn't exist, return -1 */ - if (stat(drive, stbuf) < 0) { - return (-1); - } - - /* If it does exist, verify that it's an available CD-ROM */ - is_cd = 0; - if (S_ISCHR(stbuf->st_mode) || S_ISBLK(stbuf->st_mode)) { - cdfd = open(drive, (O_RDONLY | O_EXCL | O_NONBLOCK), 0); - if (cdfd >= 0) { - info.address_format = CD_MSF_FORMAT; - info.data_format = CD_CURRENT_POSITION; - info.data_len = 0; - info.data = NULL; - /* Under Linux, EIO occurs when a disk is not present. - This isn't 100% reliable, so we use the USE_MNTENT - code above instead. - */ - if ((ioctl(cdfd, CDIOCREADSUBCHANNEL, &info) == 0) || - ERRNO_TRAYEMPTY(errno)) { - is_cd = 1; - } - close(cdfd); - } - } - return (is_cd); -} - -/* Add a CD-ROM drive to our list of valid drives */ -static void -AddDrive(char *drive, struct stat *stbuf) -{ - int i; - - if (SDL_numcds < MAX_DRIVES) { - /* Check to make sure it's not already in our list. - This can happen when we see a drive via symbolic link. - */ - for (i = 0; i < SDL_numcds; ++i) { - if (stbuf->st_rdev == SDL_cdmode[i]) { -#ifdef DEBUG_CDROM - fprintf(stderr, "Duplicate drive detected: %s == %s\n", - drive, SDL_cdlist[i]); -#endif - return; - } - } - - /* Add this drive to our list */ - i = SDL_numcds; - SDL_cdlist[i] = SDL_strdup(drive); - if (SDL_cdlist[i] == NULL) { - SDL_OutOfMemory(); - return; - } - SDL_cdmode[i] = stbuf->st_rdev; - ++SDL_numcds; -#ifdef DEBUG_CDROM - fprintf(stderr, "Added CD-ROM drive: %s\n", drive); -#endif - } -} - -int -SDL_SYS_CDInit(void) -{ - /* checklist: /dev/cdrom,/dev/cd?c /dev/acd?c - /dev/matcd?c /dev/mcd?c /dev/scd?c */ - static char *checklist[] = { - "cdrom", "?0 cd?", "?0 acd?", "?0 matcd?", "?0 mcd?", "?0 scd?", NULL - }; - char *SDLcdrom; - int i, j, exists; - char drive[32]; - struct stat stbuf; - - /* Fill in our driver capabilities */ - SDL_CDcaps.Name = SDL_SYS_CDName; - SDL_CDcaps.Open = SDL_SYS_CDOpen; - SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; - SDL_CDcaps.Status = SDL_SYS_CDStatus; - SDL_CDcaps.Play = SDL_SYS_CDPlay; - SDL_CDcaps.Pause = SDL_SYS_CDPause; - SDL_CDcaps.Resume = SDL_SYS_CDResume; - SDL_CDcaps.Stop = SDL_SYS_CDStop; - SDL_CDcaps.Eject = SDL_SYS_CDEject; - SDL_CDcaps.Close = SDL_SYS_CDClose; - - /* Look in the environment for our CD-ROM drive list */ - SDLcdrom = SDL_getenv("SDL_CDROM"); /* ':' separated list of devices */ - if (SDLcdrom != NULL) { - char *cdpath, *delim; - size_t len = SDL_strlen(SDLcdrom) + 1; - cdpath = SDL_stack_alloc(char, len); - if (cdpath != NULL) { - SDL_strlcpy(cdpath, SDLcdrom, len); - SDLcdrom = cdpath; - do { - delim = SDL_strchr(SDLcdrom, ':'); - if (delim) { - *delim++ = '\0'; - } - if (CheckDrive(SDLcdrom, &stbuf) > 0) { - AddDrive(SDLcdrom, &stbuf); - } - if (delim) { - SDLcdrom = delim; - } else { - SDLcdrom = NULL; - } - } while (SDLcdrom); - SDL_stack_free(cdpath); - } - - /* If we found our drives, there's nothing left to do */ - if (SDL_numcds > 0) { - return (0); - } - } - - /* Scan the system for CD-ROM drives */ - for (i = 0; checklist[i]; ++i) { - if (checklist[i][0] == '?') { - char *insert; - exists = 1; - for (j = checklist[i][1]; exists; ++j) { - SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%sc", - &checklist[i][3]); - insert = SDL_strchr(drive, '?'); - if (insert != NULL) { - *insert = j; - } - switch (CheckDrive(drive, &stbuf)) { - /* Drive exists and is a CD-ROM */ - case 1: - AddDrive(drive, &stbuf); - break; - /* Drive exists, but isn't a CD-ROM */ - case 0: - break; - /* Drive doesn't exist */ - case -1: - exists = 0; - break; - } - } - } else { - SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%s", - checklist[i]); - if (CheckDrive(drive, &stbuf) > 0) { - AddDrive(drive, &stbuf); - } - } - } - return (0); -} - -/* General ioctl() CD-ROM command function */ -static int -SDL_SYS_CDioctl(int id, int command, void *arg) -{ - int retval; - - retval = ioctl(id, command, arg); - if (retval < 0) { - SDL_SetError("ioctl() error: %s", strerror(errno)); - } - return (retval); -} - -static const char * -SDL_SYS_CDName(int drive) -{ - return (SDL_cdlist[drive]); -} - -static int -SDL_SYS_CDOpen(int drive) -{ - return (open(SDL_cdlist[drive], (O_RDONLY | O_EXCL | O_NONBLOCK), 0)); -} - -static int -SDL_SYS_CDGetTOC(SDL_CD * cdrom) -{ - struct ioc_toc_header toc; - int i, okay; - struct ioc_read_toc_entry entry; - struct cd_toc_entry data; - - okay = 0; - if (SDL_SYS_CDioctl(cdrom->id, CDIOREADTOCHEADER, &toc) == 0) { - cdrom->numtracks = toc.ending_track - toc.starting_track + 1; - if (cdrom->numtracks > SDL_MAX_TRACKS) { - cdrom->numtracks = SDL_MAX_TRACKS; - } - /* Read all the track TOC entries */ - for (i = 0; i <= cdrom->numtracks; ++i) { - if (i == cdrom->numtracks) { - cdrom->track[i].id = 0xAA; /* CDROM_LEADOUT */ - } else { - cdrom->track[i].id = toc.starting_track + i; - } - entry.starting_track = cdrom->track[i].id; - entry.address_format = CD_MSF_FORMAT; - entry.data_len = sizeof(data); - entry.data = &data; - if (SDL_SYS_CDioctl(cdrom->id, CDIOREADTOCENTRYS, &entry) < 0) { - break; - } else { - cdrom->track[i].type = data.control; - cdrom->track[i].offset = - MSF_TO_FRAMES(data.addr.msf.minute, - data.addr.msf.second, data.addr.msf.frame); - cdrom->track[i].length = 0; - if (i > 0) { - cdrom->track[i - 1].length = - cdrom->track[i].offset - cdrom->track[i - 1].offset; - } - } - } - if (i == (cdrom->numtracks + 1)) { - okay = 1; - } - } - return (okay ? 0 : -1); -} - -/* Get CD-ROM status */ -static CDstatus -SDL_SYS_CDStatus(SDL_CD * cdrom, int *position) -{ - CDstatus status; - struct ioc_toc_header toc; - struct ioc_read_subchannel info; - struct cd_sub_channel_info data; - - info.address_format = CD_MSF_FORMAT; - info.data_format = CD_CURRENT_POSITION; - info.track = 0; - info.data_len = sizeof(data); - info.data = &data; - if (ioctl(cdrom->id, CDIOCREADSUBCHANNEL, &info) < 0) { - if (ERRNO_TRAYEMPTY(errno)) { - status = CD_TRAYEMPTY; - } else { - status = CD_ERROR; - } - } else { - switch (data.header.audio_status) { - case CD_AS_AUDIO_INVALID: - case CD_AS_NO_STATUS: - /* Try to determine if there's a CD available */ - if (ioctl(cdrom->id, CDIOREADTOCHEADER, &toc) == 0) - status = CD_STOPPED; - else - status = CD_TRAYEMPTY; - break; - case CD_AS_PLAY_COMPLETED: - status = CD_STOPPED; - break; - case CD_AS_PLAY_IN_PROGRESS: - status = CD_PLAYING; - break; - case CD_AS_PLAY_PAUSED: - status = CD_PAUSED; - break; - default: - status = CD_ERROR; - break; - } - } - if (position) { - if (status == CD_PLAYING || (status == CD_PAUSED)) { - *position = - MSF_TO_FRAMES(data.what.position.absaddr.msf.minute, - data.what.position.absaddr.msf.second, - data.what.position.absaddr.msf.frame); - } else { - *position = 0; - } - } - return (status); -} - -/* Start play */ -static int -SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length) -{ - struct ioc_play_msf playtime; - - FRAMES_TO_MSF(start, - &playtime.start_m, &playtime.start_s, &playtime.start_f); - FRAMES_TO_MSF(start + length, - &playtime.end_m, &playtime.end_s, &playtime.end_f); -#ifdef DEBUG_CDROM - fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", - playtime.cdmsf_min0, playtime.cdmsf_sec0, playtime.cdmsf_frame0, - playtime.cdmsf_min1, playtime.cdmsf_sec1, playtime.cdmsf_frame1); -#endif - ioctl(cdrom->id, CDIOCSTART, 0); - return (SDL_SYS_CDioctl(cdrom->id, CDIOCPLAYMSF, &playtime)); -} - -/* Pause play */ -static int -SDL_SYS_CDPause(SDL_CD * cdrom) -{ - return (SDL_SYS_CDioctl(cdrom->id, CDIOCPAUSE, 0)); -} - -/* Resume play */ -static int -SDL_SYS_CDResume(SDL_CD * cdrom) -{ - return (SDL_SYS_CDioctl(cdrom->id, CDIOCRESUME, 0)); -} - -/* Stop play */ -static int -SDL_SYS_CDStop(SDL_CD * cdrom) -{ - return (SDL_SYS_CDioctl(cdrom->id, CDIOCSTOP, 0)); -} - -/* Eject the CD-ROM */ -static int -SDL_SYS_CDEject(SDL_CD * cdrom) -{ - return (SDL_SYS_CDioctl(cdrom->id, CDIOCEJECT, 0)); -} - -/* Close the CD-ROM handle */ -static void -SDL_SYS_CDClose(SDL_CD * cdrom) -{ - close(cdrom->id); -} - -void -SDL_SYS_CDQuit(void) -{ - int i; - - if (SDL_numcds > 0) { - for (i = 0; i < SDL_numcds; ++i) { - SDL_free(SDL_cdlist[i]); - } - SDL_numcds = 0; - } -} - -#endif /* SDL_CDROM_FREEBSD */ -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/cdrom/linux/SDL_syscdrom.c Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,585 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifdef SDL_CDROM_LINUX - -/* Functions for system-level CD-ROM audio control */ - -#include <string.h> /* For strerror() */ -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <fcntl.h> -#include <errno.h> -#include <unistd.h> -#ifdef __LINUX__ -#ifdef HAVE_LINUX_VERSION_H -/* linux 2.6.9 workaround */ -#include <linux/version.h> -#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,9) -#include <asm/types.h> -#define __le64 __u64 -#define __le32 __u32 -#define __le16 __u16 -#define __be64 __u64 -#define __be32 __u32 -#define __be16 __u16 -#endif /* linux 2.6.9 workaround */ -#endif /* HAVE_LINUX_VERSION_H */ -#include <linux/cdrom.h> -#endif -#ifdef __SVR4 -#include <sys/cdio.h> -#endif - -/* Define this to use the alternative getmntent() code */ -#ifndef __SVR4 -#define USE_MNTENT -#endif - -#ifdef USE_MNTENT -#if defined(__USLC__) -#include <sys/mntent.h> -#else -#include <mntent.h> -#endif - -#ifndef _PATH_MNTTAB -#ifdef MNTTAB -#define _PATH_MNTTAB MNTTAB -#else -#define _PATH_MNTTAB "/etc/fstab" -#endif -#endif /* !_PATH_MNTTAB */ - -#ifndef _PATH_MOUNTED -#define _PATH_MOUNTED "/etc/mtab" -#endif /* !_PATH_MOUNTED */ - -#ifndef MNTTYPE_CDROM -#define MNTTYPE_CDROM "iso9660" -#endif -#ifndef MNTTYPE_SUPER -#define MNTTYPE_SUPER "supermount" -#endif -#endif /* USE_MNTENT */ - -#include "SDL_cdrom.h" -#include "../SDL_syscdrom.h" - - -/* The maximum number of CD-ROM drives we'll detect */ -#define MAX_DRIVES 16 - -/* A list of available CD-ROM drives */ -static char *SDL_cdlist[MAX_DRIVES]; -static dev_t SDL_cdmode[MAX_DRIVES]; - -/* The system-dependent CD control functions */ -static const char *SDL_SYS_CDName(int drive); -static int SDL_SYS_CDOpen(int drive); -static int SDL_SYS_CDGetTOC(SDL_CD * cdrom); -static CDstatus SDL_SYS_CDStatus(SDL_CD * cdrom, int *position); -static int SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length); -static int SDL_SYS_CDPause(SDL_CD * cdrom); -static int SDL_SYS_CDResume(SDL_CD * cdrom); -static int SDL_SYS_CDStop(SDL_CD * cdrom); -static int SDL_SYS_CDEject(SDL_CD * cdrom); -static void SDL_SYS_CDClose(SDL_CD * cdrom); - -/* Some ioctl() errno values which occur when the tray is empty */ -#ifndef ENOMEDIUM -#define ENOMEDIUM ENOENT -#endif -#define ERRNO_TRAYEMPTY(errno) \ - ((errno == EIO) || (errno == ENOENT) || \ - (errno == EINVAL) || (errno == ENOMEDIUM)) - -/* Check a drive to see if it is a CD-ROM */ -static int -CheckDrive(char *drive, char *mnttype, struct stat *stbuf) -{ - int is_cd, cdfd; - struct cdrom_subchnl info; - - /* If it doesn't exist, return -1 */ - if (stat(drive, stbuf) < 0) { - return (-1); - } - - /* If it does exist, verify that it's an available CD-ROM */ - is_cd = 0; - if (S_ISCHR(stbuf->st_mode) || S_ISBLK(stbuf->st_mode)) { - cdfd = open(drive, (O_RDONLY | O_NONBLOCK), 0); - if (cdfd >= 0) { - info.cdsc_format = CDROM_MSF; - /* Under Linux, EIO occurs when a disk is not present. - */ - if ((ioctl(cdfd, CDROMSUBCHNL, &info) == 0) || - ERRNO_TRAYEMPTY(errno)) { - is_cd = 1; - } - close(cdfd); - } -#ifdef USE_MNTENT - /* Even if we can't read it, it might be mounted */ - else if (mnttype && (SDL_strcmp(mnttype, MNTTYPE_CDROM) == 0)) { - is_cd = 1; - } -#endif - } - return (is_cd); -} - -/* Add a CD-ROM drive to our list of valid drives */ -static void -AddDrive(char *drive, struct stat *stbuf) -{ - int i; - - if (SDL_numcds < MAX_DRIVES) { - /* Check to make sure it's not already in our list. - This can happen when we see a drive via symbolic link. - */ - for (i = 0; i < SDL_numcds; ++i) { - if (stbuf->st_rdev == SDL_cdmode[i]) { -#ifdef DEBUG_CDROM - fprintf(stderr, "Duplicate drive detected: %s == %s\n", - drive, SDL_cdlist[i]); -#endif - return; - } - } - - /* Add this drive to our list */ - i = SDL_numcds; - SDL_cdlist[i] = SDL_strdup(drive); - if (SDL_cdlist[i] == NULL) { - SDL_OutOfMemory(); - return; - } - SDL_cdmode[i] = stbuf->st_rdev; - ++SDL_numcds; -#ifdef DEBUG_CDROM - fprintf(stderr, "Added CD-ROM drive: %s\n", drive); -#endif - } -} - -#ifdef USE_MNTENT -static void -CheckMounts(const char *mtab) -{ - FILE *mntfp; - struct mntent *mntent; - struct stat stbuf; - - mntfp = setmntent(mtab, "r"); - if (mntfp != NULL) { - char *tmp; - char *mnt_type; - size_t mnt_type_len; - char *mnt_dev; - size_t mnt_dev_len; - - while ((mntent = getmntent(mntfp)) != NULL) { - mnt_type_len = SDL_strlen(mntent->mnt_type) + 1; - mnt_type = SDL_stack_alloc(char, mnt_type_len); - if (mnt_type == NULL) - continue; /* maybe you'll get lucky next time. */ - - mnt_dev_len = SDL_strlen(mntent->mnt_fsname) + 1; - mnt_dev = SDL_stack_alloc(char, mnt_dev_len); - if (mnt_dev == NULL) { - SDL_stack_free(mnt_type); - continue; - } - - SDL_strlcpy(mnt_type, mntent->mnt_type, mnt_type_len); - SDL_strlcpy(mnt_dev, mntent->mnt_fsname, mnt_dev_len); - - /* Handle "supermount" filesystem mounts */ - if (SDL_strcmp(mnt_type, MNTTYPE_SUPER) == 0) { - tmp = SDL_strstr(mntent->mnt_opts, "fs="); - if (tmp) { - SDL_stack_free(mnt_type); - mnt_type = SDL_strdup(tmp + SDL_strlen("fs=")); - if (mnt_type) { - tmp = SDL_strchr(mnt_type, ','); - if (tmp) { - *tmp = '\0'; - } - } - } - tmp = SDL_strstr(mntent->mnt_opts, "dev="); - if (tmp) { - SDL_stack_free(mnt_dev); - mnt_dev = SDL_strdup(tmp + SDL_strlen("dev=")); - if (mnt_dev) { - tmp = SDL_strchr(mnt_dev, ','); - if (tmp) { - *tmp = '\0'; - } - } - } - } - if (SDL_strcmp(mnt_type, MNTTYPE_CDROM) == 0) { -#ifdef DEBUG_CDROM - fprintf(stderr, - "Checking mount path from %s: %s mounted on %s of %s\n", - mtab, mnt_dev, mntent->mnt_dir, mnt_type); -#endif - if (CheckDrive(mnt_dev, mnt_type, &stbuf) > 0) { - AddDrive(mnt_dev, &stbuf); - } - } - SDL_stack_free(mnt_dev); - SDL_stack_free(mnt_type); - } - endmntent(mntfp); - } -} -#endif /* USE_MNTENT */ - -int -SDL_SYS_CDInit(void) -{ - /* checklist: /dev/cdrom, /dev/hd?, /dev/scd? /dev/sr? */ - static char *checklist[] = { - "cdrom", "?a hd?", "?0 scd?", "?0 sr?", NULL - }; - char *SDLcdrom; - int i, j, exists; - char drive[32]; - struct stat stbuf; - - /* Fill in our driver capabilities */ - SDL_CDcaps.Name = SDL_SYS_CDName; - SDL_CDcaps.Open = SDL_SYS_CDOpen; - SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; - SDL_CDcaps.Status = SDL_SYS_CDStatus; - SDL_CDcaps.Play = SDL_SYS_CDPlay; - SDL_CDcaps.Pause = SDL_SYS_CDPause; - SDL_CDcaps.Resume = SDL_SYS_CDResume; - SDL_CDcaps.Stop = SDL_SYS_CDStop; - SDL_CDcaps.Eject = SDL_SYS_CDEject; - SDL_CDcaps.Close = SDL_SYS_CDClose; - - /* Look in the environment for our CD-ROM drive list */ - SDLcdrom = SDL_getenv("SDL_CDROM"); /* ':' separated list of devices */ - if (SDLcdrom != NULL) { - char *cdpath, *delim; - size_t len = SDL_strlen(SDLcdrom) + 1; - cdpath = SDL_stack_alloc(char, len); - if (cdpath != NULL) { - SDL_strlcpy(cdpath, SDLcdrom, len); - SDLcdrom = cdpath; - do { - delim = SDL_strchr(SDLcdrom, ':'); - if (delim) { - *delim++ = '\0'; - } -#ifdef DEBUG_CDROM - fprintf(stderr, - "Checking CD-ROM drive from SDL_CDROM: %s\n", - SDLcdrom); -#endif - if (CheckDrive(SDLcdrom, NULL, &stbuf) > 0) { - AddDrive(SDLcdrom, &stbuf); - } - if (delim) { - SDLcdrom = delim; - } else { - SDLcdrom = NULL; - } - } while (SDLcdrom); - SDL_stack_free(cdpath); - } - - /* If we found our drives, there's nothing left to do */ - if (SDL_numcds > 0) { - return (0); - } - } -#ifdef USE_MNTENT - /* Check /dev/cdrom first :-) */ - if (CheckDrive("/dev/cdrom", NULL, &stbuf) > 0) { - AddDrive("/dev/cdrom", &stbuf); - } - - /* Now check the currently mounted CD drives */ - CheckMounts(_PATH_MOUNTED); - - /* Finally check possible mountable drives in /etc/fstab */ - CheckMounts(_PATH_MNTTAB); - - /* If we found our drives, there's nothing left to do */ - if (SDL_numcds > 0) { - return (0); - } -#endif /* USE_MNTENT */ - - /* Scan the system for CD-ROM drives. - Not always 100% reliable, so use the USE_MNTENT code above first. - */ - for (i = 0; checklist[i]; ++i) { - if (checklist[i][0] == '?') { - char *insert; - exists = 1; - for (j = checklist[i][1]; exists; ++j) { - SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%s", - &checklist[i][3]); - insert = SDL_strchr(drive, '?'); - if (insert != NULL) { - *insert = j; - } -#ifdef DEBUG_CDROM - fprintf(stderr, "Checking possible CD-ROM drive: %s\n", - drive); -#endif - switch (CheckDrive(drive, NULL, &stbuf)) { - /* Drive exists and is a CD-ROM */ - case 1: - AddDrive(drive, &stbuf); - break; - /* Drive exists, but isn't a CD-ROM */ - case 0: - break; - /* Drive doesn't exist */ - case -1: - exists = 0; - break; - } - } - } else { - SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%s", - checklist[i]); -#ifdef DEBUG_CDROM - fprintf(stderr, "Checking possible CD-ROM drive: %s\n", drive); -#endif - if (CheckDrive(drive, NULL, &stbuf) > 0) { - AddDrive(drive, &stbuf); - } - } - } - return (0); -} - -/* General ioctl() CD-ROM command function */ -static int -SDL_SYS_CDioctl(int id, int command, void *arg) -{ - int retval; - - retval = ioctl(id, command, arg); - if (retval < 0) { - SDL_SetError("ioctl() error: %s", strerror(errno)); - } - return (retval); -} - -static const char * -SDL_SYS_CDName(int drive) -{ - return (SDL_cdlist[drive]); -} - -static int -SDL_SYS_CDOpen(int drive) -{ - return (open(SDL_cdlist[drive], (O_RDONLY | O_NONBLOCK), 0)); -} - -static int -SDL_SYS_CDGetTOC(SDL_CD * cdrom) -{ - struct cdrom_tochdr toc; - int i, okay; - struct cdrom_tocentry entry; - - okay = 0; - if (SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCHDR, &toc) == 0) { - cdrom->numtracks = toc.cdth_trk1 - toc.cdth_trk0 + 1; - if (cdrom->numtracks > SDL_MAX_TRACKS) { - cdrom->numtracks = SDL_MAX_TRACKS; - } - /* Read all the track TOC entries */ - for (i = 0; i <= cdrom->numtracks; ++i) { - if (i == cdrom->numtracks) { - cdrom->track[i].id = CDROM_LEADOUT; - } else { - cdrom->track[i].id = toc.cdth_trk0 + i; - } - entry.cdte_track = cdrom->track[i].id; - entry.cdte_format = CDROM_MSF; - if (SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCENTRY, &entry) < 0) { - break; - } else { - if (entry.cdte_ctrl & CDROM_DATA_TRACK) { - cdrom->track[i].type = SDL_DATA_TRACK; - } else { - cdrom->track[i].type = SDL_AUDIO_TRACK; - } - cdrom->track[i].offset = - MSF_TO_FRAMES(entry.cdte_addr.msf.minute, - entry.cdte_addr.msf.second, - entry.cdte_addr.msf.frame); - cdrom->track[i].length = 0; - if (i > 0) { - cdrom->track[i - 1].length = - cdrom->track[i].offset - cdrom->track[i - 1].offset; - } - } - } - if (i == (cdrom->numtracks + 1)) { - okay = 1; - } - } - return (okay ? 0 : -1); -} - -/* Get CD-ROM status */ -static CDstatus -SDL_SYS_CDStatus(SDL_CD * cdrom, int *position) -{ - CDstatus status; - struct cdrom_tochdr toc; - struct cdrom_subchnl info; - - info.cdsc_format = CDROM_MSF; - if (ioctl(cdrom->id, CDROMSUBCHNL, &info) < 0) { - if (ERRNO_TRAYEMPTY(errno)) { - status = CD_TRAYEMPTY; - } else { - status = CD_ERROR; - } - } else { - switch (info.cdsc_audiostatus) { - case CDROM_AUDIO_INVALID: - case CDROM_AUDIO_NO_STATUS: - /* Try to determine if there's a CD available */ - if (ioctl(cdrom->id, CDROMREADTOCHDR, &toc) == 0) - status = CD_STOPPED; - else - status = CD_TRAYEMPTY; - break; - case CDROM_AUDIO_COMPLETED: - status = CD_STOPPED; - break; - case CDROM_AUDIO_PLAY: - status = CD_PLAYING; - break; - case CDROM_AUDIO_PAUSED: - /* Workaround buggy CD-ROM drive */ - if (info.cdsc_trk == CDROM_LEADOUT) { - status = CD_STOPPED; - } else { - status = CD_PAUSED; - } - break; - default: - status = CD_ERROR; - break; - } - } - if (position) { - if (status == CD_PLAYING || (status == CD_PAUSED)) { - *position = MSF_TO_FRAMES(info.cdsc_absaddr.msf.minute, - info.cdsc_absaddr.msf.second, - info.cdsc_absaddr.msf.frame); - } else { - *position = 0; - } - } - return (status); -} - -/* Start play */ -static int -SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length) -{ - struct cdrom_msf playtime; - - FRAMES_TO_MSF(start, - &playtime.cdmsf_min0, &playtime.cdmsf_sec0, - &playtime.cdmsf_frame0); - FRAMES_TO_MSF(start + length, &playtime.cdmsf_min1, &playtime.cdmsf_sec1, - &playtime.cdmsf_frame1); -#ifdef DEBUG_CDROM - fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", - playtime.cdmsf_min0, playtime.cdmsf_sec0, playtime.cdmsf_frame0, - playtime.cdmsf_min1, playtime.cdmsf_sec1, playtime.cdmsf_frame1); -#endif - return (SDL_SYS_CDioctl(cdrom->id, CDROMPLAYMSF, &playtime)); -} - -/* Pause play */ -static int -SDL_SYS_CDPause(SDL_CD * cdrom) -{ - return (SDL_SYS_CDioctl(cdrom->id, CDROMPAUSE, 0)); -} - -/* Resume play */ -static int -SDL_SYS_CDResume(SDL_CD * cdrom) -{ - return (SDL_SYS_CDioctl(cdrom->id, CDROMRESUME, 0)); -} - -/* Stop play */ -static int -SDL_SYS_CDStop(SDL_CD * cdrom) -{ - return (SDL_SYS_CDioctl(cdrom->id, CDROMSTOP, 0)); -} - -/* Eject the CD-ROM */ -static int -SDL_SYS_CDEject(SDL_CD * cdrom) -{ - return (SDL_SYS_CDioctl(cdrom->id, CDROMEJECT, 0)); -} - -/* Close the CD-ROM handle */ -static void -SDL_SYS_CDClose(SDL_CD * cdrom) -{ - close(cdrom->id); -} - -void -SDL_SYS_CDQuit(void) -{ - int i; - - if (SDL_numcds > 0) { - for (i = 0; i < SDL_numcds; ++i) { - SDL_free(SDL_cdlist[i]); - } - SDL_numcds = 0; - } -} - -#endif /* SDL_CDROM_LINUX */ -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/cdrom/macosx/AudioFilePlayer.c Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,397 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Sam Lantinga - slouken@libsdl.org - - This file based on Apple sample code. We haven't changed the file name, - so if you want to see the original search for it on apple.com/developer -*/ -#include "SDL_config.h" - -/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - AudioFilePlayer.cpp -*/ -#include "AudioFilePlayer.h" - -/* -void ThrowResult (OSStatus result, const char* str) -{ - SDL_SetError ("Error: %s %d", str, result); - throw result; -} -*/ - -#if DEBUG -static void -PrintStreamDesc(AudioStreamBasicDescription * inDesc) -{ - if (!inDesc) { - printf("Can't print a NULL desc!\n"); - return; - } - - printf("- - - - - - - - - - - - - - - - - - - -\n"); - printf(" Sample Rate:%f\n", inDesc->mSampleRate); - printf(" Format ID:%s\n", (char *) &inDesc->mFormatID); - printf(" Format Flags:%lX\n", inDesc->mFormatFlags); - printf(" Bytes per Packet:%ld\n", inDesc->mBytesPerPacket); - printf(" Frames per Packet:%ld\n", inDesc->mFramesPerPacket); - printf(" Bytes per Frame:%ld\n", inDesc->mBytesPerFrame); - printf(" Channels per Frame:%ld\n", inDesc->mChannelsPerFrame); - printf(" Bits per Channel:%ld\n", inDesc->mBitsPerChannel); - printf("- - - - - - - - - - - - - - - - - - - -\n"); -} -#endif - - -static int -AudioFilePlayer_SetDestination(AudioFilePlayer * afp, AudioUnit * inDestUnit) -{ - /*if (afp->mConnected) throw static_cast<OSStatus>(-1); *//* can't set dest if already engaged */ - if (afp->mConnected) - return 0; - - SDL_memcpy(&afp->mPlayUnit, inDestUnit, sizeof(afp->mPlayUnit)); - - OSStatus result = noErr; - - - /* we can "down" cast a component instance to a component */ - ComponentDescription desc; - result = GetComponentInfo((Component) * inDestUnit, &desc, 0, 0, 0); - if (result) - return 0; /*THROW_RESULT("GetComponentInfo") */ - - /* we're going to use this to know which convert routine to call - a v1 audio unit will have a type of 'aunt' - a v2 audio unit will have one of several different types. */ - if (desc.componentType != kAudioUnitComponentType) { - result = badComponentInstance; - /*THROW_RESULT("BAD COMPONENT") */ - if (result) - return 0; - } - - /* Set the input format of the audio unit. */ - result = AudioUnitSetProperty(*inDestUnit, - kAudioUnitProperty_StreamFormat, - kAudioUnitScope_Input, - 0, - &afp->mFileDescription, - sizeof(afp->mFileDescription)); - /*THROW_RESULT("AudioUnitSetProperty") */ - if (result) - return 0; - return 1; -} - -static void -AudioFilePlayer_SetNotifier(AudioFilePlayer * afp, - AudioFilePlayNotifier inNotifier, void *inRefCon) -{ - afp->mNotifier = inNotifier; - afp->mRefCon = inRefCon; -} - -static int -AudioFilePlayer_IsConnected(AudioFilePlayer * afp) -{ - return afp->mConnected; -} - -static AudioUnit -AudioFilePlayer_GetDestUnit(AudioFilePlayer * afp) -{ - return afp->mPlayUnit; -} - -static void -AudioFilePlayer_Print(AudioFilePlayer * afp) -{ -#if DEBUG - printf("Is Connected:%s\n", (IsConnected()? "true" : "false")); - printf("- - - - - - - - - - - - - - \n"); -#endif -} - -static void -AudioFilePlayer_SetStartFrame(AudioFilePlayer * afp, int frame) -{ - SInt64 position = frame * 2352; - - afp->mStartFrame = frame; - afp->mAudioFileManager->SetPosition(afp->mAudioFileManager, position); -} - - -static int -AudioFilePlayer_GetCurrentFrame(AudioFilePlayer * afp) -{ - return afp->mStartFrame + - (afp->mAudioFileManager->GetByteCounter(afp->mAudioFileManager) / - 2352); -} - -static void -AudioFilePlayer_SetStopFrame(AudioFilePlayer * afp, int frame) -{ - SInt64 position = frame * 2352; - - afp->mAudioFileManager->SetEndOfFile(afp->mAudioFileManager, position); -} - -void -delete_AudioFilePlayer(AudioFilePlayer * afp) -{ - if (afp != NULL) { - afp->Disconnect(afp); - - if (afp->mAudioFileManager) { - delete_AudioFileManager(afp->mAudioFileManager); - afp->mAudioFileManager = 0; - } - - if (afp->mForkRefNum) { - FSCloseFork(afp->mForkRefNum); - afp->mForkRefNum = 0; - } - SDL_free(afp); - } -} - -static int -AudioFilePlayer_Connect(AudioFilePlayer * afp) -{ -#if DEBUG - printf("Connect:%x, engaged=%d\n", (int) afp->mPlayUnit, - (afp->mConnected ? 1 : 0)); -#endif - if (!afp->mConnected) { - if (!afp->mAudioFileManager->DoConnect(afp->mAudioFileManager)) - return 0; - - /* set the render callback for the file data to be supplied to the sound converter AU */ - afp->mInputCallback.inputProc = afp->mAudioFileManager->FileInputProc; - afp->mInputCallback.inputProcRefCon = afp->mAudioFileManager; - - OSStatus result = AudioUnitSetProperty(afp->mPlayUnit, - kAudioUnitProperty_SetInputCallback, - kAudioUnitScope_Input, - 0, - &afp->mInputCallback, - sizeof(afp->mInputCallback)); - if (result) - return 0; /*THROW_RESULT("AudioUnitSetProperty") */ - afp->mConnected = 1; - } - - return 1; -} - -/* warning noted, now please go away ;-) */ -/* #warning This should redirect the calling of notification code to some other thread */ -static void -AudioFilePlayer_DoNotification(AudioFilePlayer * afp, OSStatus inStatus) -{ - if (afp->mNotifier) { - (*afp->mNotifier) (afp->mRefCon, inStatus); - } else { - SDL_SetError("Notification posted with no notifier in place"); - - if (inStatus == kAudioFilePlay_FileIsFinished) - afp->Disconnect(afp); - else if (inStatus != kAudioFilePlayErr_FilePlayUnderrun) - afp->Disconnect(afp); - } -} - -static void -AudioFilePlayer_Disconnect(AudioFilePlayer * afp) -{ -#if DEBUG - printf("Disconnect:%x,%ld, engaged=%d\n", (int) afp->mPlayUnit, 0, - (afp->mConnected ? 1 : 0)); -#endif - if (afp->mConnected) { - afp->mConnected = 0; - - afp->mInputCallback.inputProc = 0; - afp->mInputCallback.inputProcRefCon = 0; - OSStatus result = AudioUnitSetProperty(afp->mPlayUnit, - kAudioUnitProperty_SetInputCallback, - kAudioUnitScope_Input, - 0, - &afp->mInputCallback, - sizeof(afp->mInputCallback)); - if (result) - SDL_SetError("AudioUnitSetProperty:RemoveInputCallback:%ld", - result); - - afp->mAudioFileManager->Disconnect(afp->mAudioFileManager); - } -} - -typedef struct -{ - UInt32 offset; - UInt32 blockSize; -} SSNDData; - -static int -AudioFilePlayer_OpenFile(AudioFilePlayer * afp, const FSRef * inRef, - SInt64 * outFileDataSize) -{ - ContainerChunk chunkHeader; - ChunkHeader chunk; - SSNDData ssndData; - - OSErr result; - HFSUniStr255 dfName; - ByteCount actual; - SInt64 offset; - - /* Open the data fork of the input file */ - result = FSGetDataForkName(&dfName); - if (result) - return 0; /*THROW_RESULT("AudioFilePlayer::OpenFile(): FSGetDataForkName") */ - - result = - FSOpenFork(inRef, dfName.length, dfName.unicode, fsRdPerm, - &afp->mForkRefNum); - if (result) - return 0; /*THROW_RESULT("AudioFilePlayer::OpenFile(): FSOpenFork") */ - - /* Read the file header, and check if it's indeed an AIFC file */ - result = - FSReadFork(afp->mForkRefNum, fsAtMark, 0, sizeof(chunkHeader), - &chunkHeader, &actual); - if (result) - return 0; /*THROW_RESULT("AudioFilePlayer::OpenFile(): FSReadFork") */ - - if (chunkHeader.ckID != 'FORM') { - result = -1; - if (result) - return 0; /*THROW_RESULT("AudioFilePlayer::OpenFile(): chunk id is not 'FORM'"); */ - } - - if (chunkHeader.formType != 'AIFC') { - result = -1; - if (result) - return 0; /*THROW_RESULT("AudioFilePlayer::OpenFile(): file format is not 'AIFC'"); */ - } - - /* Search for the SSND chunk. We ignore all compression etc. information - in other chunks. Of course that is kind of evil, but for now we are lazy - and rely on the cdfs to always give us the same fixed format. - TODO: Parse the COMM chunk we currently skip to fill in mFileDescription. - */ - offset = 0; - do { - result = - FSReadFork(afp->mForkRefNum, fsFromMark, offset, - sizeof(chunk), &chunk, &actual); - if (result) - return 0; /*THROW_RESULT("AudioFilePlayer::OpenFile(): FSReadFork") */ - - /* Skip the chunk data */ - offset = chunk.ckSize; - } while (chunk.ckID != 'SSND'); - - /* Read the header of the SSND chunk. After this, we are positioned right - at the start of the audio data. */ - result = - FSReadFork(afp->mForkRefNum, fsAtMark, 0, sizeof(ssndData), - &ssndData, &actual); - if (result) - return 0; /*THROW_RESULT("AudioFilePlayer::OpenFile(): FSReadFork") */ - - result = FSSetForkPosition(afp->mForkRefNum, fsFromMark, ssndData.offset); - if (result) - return 0; /*THROW_RESULT("AudioFilePlayer::OpenFile(): FSSetForkPosition") */ - - /* Data size */ - *outFileDataSize = chunk.ckSize - ssndData.offset - 8; - - /* File format */ - afp->mFileDescription.mSampleRate = 44100; - afp->mFileDescription.mFormatID = kAudioFormatLinearPCM; - afp->mFileDescription.mFormatFlags = - kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger; - afp->mFileDescription.mBytesPerPacket = 4; - afp->mFileDescription.mFramesPerPacket = 1; - afp->mFileDescription.mBytesPerFrame = 4; - afp->mFileDescription.mChannelsPerFrame = 2; - afp->mFileDescription.mBitsPerChannel = 16; - - return 1; -} - -AudioFilePlayer * -new_AudioFilePlayer(const FSRef * inFileRef) -{ - SInt64 fileDataSize = 0; - - AudioFilePlayer *afp = - (AudioFilePlayer *) SDL_malloc(sizeof(AudioFilePlayer)); - if (afp == NULL) - return NULL; - SDL_memset(afp, '\0', sizeof(*afp)); - -#define SET_AUDIOFILEPLAYER_METHOD(m) afp->m = AudioFilePlayer_##m - SET_AUDIOFILEPLAYER_METHOD(SetDestination); - SET_AUDIOFILEPLAYER_METHOD(SetNotifier); - SET_AUDIOFILEPLAYER_METHOD(SetStartFrame); - SET_AUDIOFILEPLAYER_METHOD(GetCurrentFrame); - SET_AUDIOFILEPLAYER_METHOD(SetStopFrame); - SET_AUDIOFILEPLAYER_METHOD(Connect); - SET_AUDIOFILEPLAYER_METHOD(Disconnect); - SET_AUDIOFILEPLAYER_METHOD(DoNotification); - SET_AUDIOFILEPLAYER_METHOD(IsConnected); - SET_AUDIOFILEPLAYER_METHOD(GetDestUnit); - SET_AUDIOFILEPLAYER_METHOD(Print); - SET_AUDIOFILEPLAYER_METHOD(OpenFile); -#undef SET_AUDIOFILEPLAYER_METHOD - - if (!afp->OpenFile(afp, inFileRef, &fileDataSize)) { - SDL_free(afp); - return NULL; - } - - /* we want about 4 seconds worth of data for the buffer */ - int bytesPerSecond = - (UInt32) (4 * afp->mFileDescription.mSampleRate * - afp->mFileDescription.mBytesPerFrame); - -#if DEBUG - printf("File format:\n"); - PrintStreamDesc(&afp->mFileDescription); -#endif - - afp->mAudioFileManager = new_AudioFileManager(afp, afp->mForkRefNum, - fileDataSize, - bytesPerSecond); - if (afp->mAudioFileManager == NULL) { - delete_AudioFilePlayer(afp); - return NULL; - } - - return afp; -} - -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/cdrom/macosx/AudioFilePlayer.h Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,178 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Sam Lantinga - slouken@libsdl.org - - This file based on Apple sample code. We haven't changed the file name, - so if you want to see the original search for it on apple.com/developer -*/ -#include "SDL_config.h" - -/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - AudioFilePlayer.h -*/ -#ifndef __AudioFilePlayer_H__ -#define __AudioFilePlayer_H__ - -#include <CoreServices/CoreServices.h> - -#include <AudioUnit/AudioUnit.h> -#ifdef AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER -#include <AudioUnit/AUNTComponent.h> -#endif - -#include "SDL_error.h" - -const char *AudioFilePlayerErrorStr(OSStatus error); - -/* -void ThrowResult (OSStatus result, const char *str); - -#define THROW_RESULT(str) \ - if (result) { \ - ThrowResult (result, str); \ - } -*/ - -typedef void (*AudioFilePlayNotifier) (void *inRefCon, OSStatus inStatus); - -enum -{ - kAudioFilePlayErr_FilePlayUnderrun = -10000, - kAudioFilePlay_FileIsFinished = -10001, - kAudioFilePlay_PlayerIsUninitialized = -10002 -}; - - -struct S_AudioFileManager; - -#pragma mark __________ AudioFilePlayer -typedef struct S_AudioFilePlayer -{ -/*public:*/ - int (*SetDestination) (struct S_AudioFilePlayer * afp, - AudioUnit * inDestUnit); - void (*SetNotifier) (struct S_AudioFilePlayer * afp, - AudioFilePlayNotifier inNotifier, void *inRefCon); - void (*SetStartFrame) (struct S_AudioFilePlayer * afp, int frame); /* seek in the file */ - int (*GetCurrentFrame) (struct S_AudioFilePlayer * afp); /* get the current frame position */ - void (*SetStopFrame) (struct S_AudioFilePlayer * afp, int frame); /* set limit in the file */ - int (*Connect) (struct S_AudioFilePlayer * afp); - void (*Disconnect) (struct S_AudioFilePlayer * afp); - void (*DoNotification) (struct S_AudioFilePlayer * afp, OSStatus inError); - int (*IsConnected) (struct S_AudioFilePlayer * afp); - AudioUnit(*GetDestUnit) (struct S_AudioFilePlayer * afp); - void (*Print) (struct S_AudioFilePlayer * afp); - -/*private:*/ - AudioUnit mPlayUnit; - SInt16 mForkRefNum; - - AudioUnitInputCallback mInputCallback; - - AudioStreamBasicDescription mFileDescription; - - int mConnected; - - struct S_AudioFileManager *mAudioFileManager; - - AudioFilePlayNotifier mNotifier; - void *mRefCon; - - int mStartFrame; - -#pragma mark __________ Private_Methods - - int (*OpenFile) (struct S_AudioFilePlayer * afp, const FSRef * inRef, - SInt64 * outFileSize); -} AudioFilePlayer; - - -AudioFilePlayer *new_AudioFilePlayer(const FSRef * inFileRef); -void delete_AudioFilePlayer(AudioFilePlayer * afp); - - - -#pragma mark __________ AudioFileManager -typedef struct S_AudioFileManager -{ -/*public:*/ - /* this method should NOT be called by an object of this class - as it is called by the parent's Disconnect() method */ - void (*Disconnect) (struct S_AudioFileManager * afm); - int (*DoConnect) (struct S_AudioFileManager * afm); - OSStatus(*Read) (struct S_AudioFileManager * afm, char *buffer, - UInt32 * len); - const char *(*GetFileBuffer) (struct S_AudioFileManager * afm); - const AudioFilePlayer *(*GetParent) (struct S_AudioFileManager * afm); - void (*SetPosition) (struct S_AudioFileManager * afm, SInt64 pos); /* seek/rewind in the file */ - int (*GetByteCounter) (struct S_AudioFileManager * afm); /* return actual bytes streamed to audio hardware */ - void (*SetEndOfFile) (struct S_AudioFileManager * afm, SInt64 pos); /* set the "EOF" (will behave just like it reached eof) */ - -/*protected:*/ - AudioFilePlayer *mParent; - SInt16 mForkRefNum; - SInt64 mAudioDataOffset; - - char *mFileBuffer; - - int mByteCounter; - - int mReadFromFirstBuffer; - int mLockUnsuccessful; - int mIsEngaged; - - int mNumTimesAskedSinceFinished; - - - void *mTmpBuffer; - UInt32 mBufferSize; - UInt32 mBufferOffset; -/*public:*/ - UInt32 mChunkSize; - SInt64 mFileLength; - SInt64 mReadFilePosition; - int mWriteToFirstBuffer; - int mFinishedReadingData; - -/*protected:*/ - OSStatus(*Render) (struct S_AudioFileManager * afm, - AudioBuffer * ioData); - OSStatus(*GetFileData) (struct S_AudioFileManager * afm, - void **inOutData, UInt32 * inOutDataSize); - void (*AfterRender) (struct S_AudioFileManager * afm); - -/*public:*/ - /*static */ - OSStatus(*FileInputProc) (void *inRefCon, - AudioUnitRenderActionFlags inActionFlags, - const AudioTimeStamp * inTimeStamp, - UInt32 inBusNumber, AudioBuffer * ioData); -} AudioFileManager; - - -AudioFileManager *new_AudioFileManager(AudioFilePlayer * inParent, - SInt16 inForkRefNum, - SInt64 inFileLength, - UInt32 inChunkSize); - -void delete_AudioFileManager(AudioFileManager * afm); - -#endif -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/cdrom/macosx/AudioFileReaderThread.c Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,657 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Sam Lantinga - slouken@libsdl.org - - This file based on Apple sample code. We haven't changed the file name, - so if you want to see the original search for it on apple.com/developer -*/ -#include "SDL_config.h" - -/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - AudioFileManager.cpp -*/ -#include "AudioFilePlayer.h" -#include <mach/mach.h> /* used for setting policy of thread */ -#include "SDLOSXCAGuard.h" -#include <pthread.h> - -/*#include <list>*/ - -/*typedef void *FileData;*/ -typedef struct S_FileData -{ - AudioFileManager *obj; - struct S_FileData *next; -} FileData; - - -typedef struct S_FileReaderThread -{ -/*public:*/ - SDLOSXCAGuard *(*GetGuard) (struct S_FileReaderThread * frt); - void (*AddReader) (struct S_FileReaderThread * frt); - void (*RemoveReader) (struct S_FileReaderThread * frt, - AudioFileManager * inItem); - int (*TryNextRead) (struct S_FileReaderThread * frt, - AudioFileManager * inItem); - - int mThreadShouldDie; - -/*private:*/ - /*typedef std::list<AudioFileManager*> FileData; */ - - SDLOSXCAGuard *mGuard; - UInt32 mThreadPriority; - - int mNumReaders; - FileData *mFileData; - - - void (*ReadNextChunk) (struct S_FileReaderThread * frt); - int (*StartFixedPriorityThread) (struct S_FileReaderThread * frt); - /*static */ - UInt32(*GetThreadBasePriority) (pthread_t inThread); - /*static */ - void *(*DiskReaderEntry) (void *inRefCon); -} FileReaderThread; - - -static SDLOSXCAGuard * -FileReaderThread_GetGuard(FileReaderThread * frt) -{ - return frt->mGuard; -} - -/* returns 1 if succeeded */ -static int -FileReaderThread_TryNextRead(FileReaderThread * frt, - AudioFileManager * inItem) -{ - int didLock = 0; - int succeeded = 0; - if (frt->mGuard->Try(frt->mGuard, &didLock)) { - /*frt->mFileData.push_back (inItem); */ - /* !!! FIXME: this could be faster with a "tail" member. --ryan. */ - FileData *i = frt->mFileData; - FileData *prev = NULL; - - FileData *newfd = (FileData *) SDL_malloc(sizeof(FileData)); - newfd->obj = inItem; - newfd->next = NULL; - - while (i != NULL) { - prev = i; - i = i->next; - } - if (prev == NULL) - frt->mFileData = newfd; - else - prev->next = newfd; - - frt->mGuard->Notify(frt->mGuard); - succeeded = 1; - - if (didLock) - frt->mGuard->Unlock(frt->mGuard); - } - - return succeeded; -} - -static void -FileReaderThread_AddReader(FileReaderThread * frt) -{ - if (frt->mNumReaders == 0) { - frt->mThreadShouldDie = 0; - frt->StartFixedPriorityThread(frt); - } - frt->mNumReaders++; -} - -static void -FileReaderThread_RemoveReader(FileReaderThread * frt, - AudioFileManager * inItem) -{ - if (frt->mNumReaders > 0) { - int bNeedsRelease = frt->mGuard->Lock(frt->mGuard); - - /*frt->mFileData.remove (inItem); */ - FileData *i = frt->mFileData; - FileData *prev = NULL; - while (i != NULL) { - FileData *next = i->next; - if (i->obj != inItem) - prev = i; - else { - if (prev == NULL) - frt->mFileData = next; - else - prev->next = next; - SDL_free(i); - } - i = next; - } - - if (--frt->mNumReaders == 0) { - frt->mThreadShouldDie = 1; - frt->mGuard->Notify(frt->mGuard); /* wake up thread so it will quit */ - frt->mGuard->Wait(frt->mGuard); /* wait for thread to die */ - } - - if (bNeedsRelease) - frt->mGuard->Unlock(frt->mGuard); - } -} - -static int -FileReaderThread_StartFixedPriorityThread(FileReaderThread * frt) -{ - pthread_attr_t theThreadAttrs; - pthread_t pThread; - - OSStatus result = pthread_attr_init(&theThreadAttrs); - if (result) - return 0; /*THROW_RESULT("pthread_attr_init - Thread attributes could not be created.") */ - - result = - pthread_attr_setdetachstate(&theThreadAttrs, PTHREAD_CREATE_DETACHED); - if (result) - return 0; /*THROW_RESULT("pthread_attr_setdetachstate - Thread attributes could not be detached.") */ - - result = - pthread_create(&pThread, &theThreadAttrs, frt->DiskReaderEntry, frt); - if (result) - return 0; /*THROW_RESULT("pthread_create - Create and start the thread.") */ - - pthread_attr_destroy(&theThreadAttrs); - - /* we've now created the thread and started it - we'll now set the priority of the thread to the nominated priority - and we'll also make the thread fixed */ - thread_extended_policy_data_t theFixedPolicy; - thread_precedence_policy_data_t thePrecedencePolicy; - SInt32 relativePriority; - - /* make thread fixed */ - theFixedPolicy.timeshare = 0; /* set to 1 for a non-fixed thread */ - result = - thread_policy_set(pthread_mach_thread_np(pThread), - THREAD_EXTENDED_POLICY, - (thread_policy_t) & theFixedPolicy, - THREAD_EXTENDED_POLICY_COUNT); - if (result) - return 0; /*THROW_RESULT("thread_policy - Couldn't set thread as fixed priority.") */ - /* set priority */ - /* precedency policy's "importance" value is relative to spawning thread's priority */ - relativePriority = - frt->mThreadPriority - frt->GetThreadBasePriority(pthread_self()); - - thePrecedencePolicy.importance = relativePriority; - result = - thread_policy_set(pthread_mach_thread_np(pThread), - THREAD_PRECEDENCE_POLICY, - (thread_policy_t) & thePrecedencePolicy, - THREAD_PRECEDENCE_POLICY_COUNT); - if (result) - return 0; /*THROW_RESULT("thread_policy - Couldn't set thread priority.") */ - - return 1; -} - -static UInt32 -FileReaderThread_GetThreadBasePriority(pthread_t inThread) -{ - thread_basic_info_data_t threadInfo; - policy_info_data_t thePolicyInfo; - unsigned int count; - - /* get basic info */ - count = THREAD_BASIC_INFO_COUNT; - thread_info(pthread_mach_thread_np(inThread), THREAD_BASIC_INFO, - (integer_t *) & threadInfo, &count); - - switch (threadInfo.policy) { - case POLICY_TIMESHARE: - count = POLICY_TIMESHARE_INFO_COUNT; - thread_info(pthread_mach_thread_np(inThread), - THREAD_SCHED_TIMESHARE_INFO, - (integer_t *) & (thePolicyInfo.ts), &count); - return thePolicyInfo.ts.base_priority; - break; - - case POLICY_FIFO: - count = POLICY_FIFO_INFO_COUNT; - thread_info(pthread_mach_thread_np(inThread), - THREAD_SCHED_FIFO_INFO, - (integer_t *) & (thePolicyInfo.fifo), &count); - if (thePolicyInfo.fifo.depressed) { - return thePolicyInfo.fifo.depress_priority; - } else { - return thePolicyInfo.fifo.base_priority; - } - break; - - case POLICY_RR: - count = POLICY_RR_INFO_COUNT; - thread_info(pthread_mach_thread_np(inThread), - THREAD_SCHED_RR_INFO, - (integer_t *) & (thePolicyInfo.rr), &count); - if (thePolicyInfo.rr.depressed) { - return thePolicyInfo.rr.depress_priority; - } else { - return thePolicyInfo.rr.base_priority; - } - break; - } - - return 0; -} - -static void * -FileReaderThread_DiskReaderEntry(void *inRefCon) -{ - FileReaderThread *frt = (FileReaderThread *) inRefCon; - frt->ReadNextChunk(frt); -#if DEBUG - printf("finished with reading file\n"); -#endif - - return 0; -} - -static void -FileReaderThread_ReadNextChunk(FileReaderThread * frt) -{ - OSStatus result; - UInt32 dataChunkSize; - AudioFileManager *theItem = 0; - - for (;;) { - { /* this is a scoped based lock */ - int bNeedsRelease = frt->mGuard->Lock(frt->mGuard); - - if (frt->mThreadShouldDie) { - frt->mGuard->Notify(frt->mGuard); - if (bNeedsRelease) - frt->mGuard->Unlock(frt->mGuard); - return; - } - - /*if (frt->mFileData.empty()) */ - if (frt->mFileData == NULL) { - frt->mGuard->Wait(frt->mGuard); - } - - /* kill thread */ - if (frt->mThreadShouldDie) { - - frt->mGuard->Notify(frt->mGuard); - if (bNeedsRelease) - frt->mGuard->Unlock(frt->mGuard); - return; - } - - /*theItem = frt->mFileData.front(); */ - /*frt->mFileData.pop_front(); */ - theItem = NULL; - if (frt->mFileData != NULL) { - FileData *next = frt->mFileData->next; - theItem = frt->mFileData->obj; - SDL_free(frt->mFileData); - frt->mFileData = next; - } - - if (bNeedsRelease) - frt->mGuard->Unlock(frt->mGuard); - } - - if ((theItem->mFileLength - theItem->mReadFilePosition) < - theItem->mChunkSize) - dataChunkSize = theItem->mFileLength - theItem->mReadFilePosition; - else - dataChunkSize = theItem->mChunkSize; - - /* this is the exit condition for the thread */ - if (dataChunkSize <= 0) { - theItem->mFinishedReadingData = 1; - continue; - } - /* construct pointer */ - char *writePtr = (char *) (theItem->GetFileBuffer(theItem) + - (theItem->mWriteToFirstBuffer ? 0 : - theItem->mChunkSize)); - - /* read data */ - result = theItem->Read(theItem, writePtr, &dataChunkSize); - if (result != noErr && result != eofErr) { - AudioFilePlayer *afp = - (AudioFilePlayer *) theItem->GetParent(theItem); - afp->DoNotification(afp, result); - continue; - } - - if (dataChunkSize != theItem->mChunkSize) { - writePtr += dataChunkSize; - - /* can't exit yet.. we still have to pass the partial buffer back */ - SDL_memset(writePtr, 0, (theItem->mChunkSize - dataChunkSize)); - } - - theItem->mWriteToFirstBuffer = !theItem->mWriteToFirstBuffer; /* switch buffers */ - - if (result == eofErr) - theItem->mReadFilePosition = theItem->mFileLength; - else - theItem->mReadFilePosition += dataChunkSize; /* increment count */ - } -} - -void -delete_FileReaderThread(FileReaderThread * frt) -{ - if (frt != NULL) { - delete_SDLOSXCAGuard(frt->mGuard); - SDL_free(frt); - } -} - -FileReaderThread * -new_FileReaderThread() -{ - FileReaderThread *frt = - (FileReaderThread *) SDL_malloc(sizeof(FileReaderThread)); - if (frt == NULL) - return NULL; - SDL_memset(frt, '\0', sizeof(*frt)); - - frt->mGuard = new_SDLOSXCAGuard(); - if (frt->mGuard == NULL) { - SDL_free(frt); - return NULL; - } -#define SET_FILEREADERTHREAD_METHOD(m) frt->m = FileReaderThread_##m - SET_FILEREADERTHREAD_METHOD(GetGuard); - SET_FILEREADERTHREAD_METHOD(AddReader); - SET_FILEREADERTHREAD_METHOD(RemoveReader); - SET_FILEREADERTHREAD_METHOD(TryNextRead); - SET_FILEREADERTHREAD_METHOD(ReadNextChunk); - SET_FILEREADERTHREAD_METHOD(StartFixedPriorityThread); - SET_FILEREADERTHREAD_METHOD(GetThreadBasePriority); - SET_FILEREADERTHREAD_METHOD(DiskReaderEntry); -#undef SET_FILEREADERTHREAD_METHOD - - frt->mThreadPriority = 62; - return frt; -} - - -static FileReaderThread *sReaderThread; - - -static int -AudioFileManager_DoConnect(AudioFileManager * afm) -{ - if (!afm->mIsEngaged) { - OSStatus result; - - /*afm->mReadFilePosition = 0; */ - afm->mFinishedReadingData = 0; - - afm->mNumTimesAskedSinceFinished = 0; - afm->mLockUnsuccessful = 0; - - UInt32 dataChunkSize; - - if ((afm->mFileLength - afm->mReadFilePosition) < afm->mChunkSize) - dataChunkSize = afm->mFileLength - afm->mReadFilePosition; - else - dataChunkSize = afm->mChunkSize; - - result = afm->Read(afm, afm->mFileBuffer, &dataChunkSize); - if (result) - return 0; /*THROW_RESULT("AudioFileManager::DoConnect(): Read") */ - - afm->mReadFilePosition += dataChunkSize; - - afm->mWriteToFirstBuffer = 0; - afm->mReadFromFirstBuffer = 1; - - sReaderThread->AddReader(sReaderThread); - - afm->mIsEngaged = 1; - } - /* - else - throw static_cast<OSStatus>(-1); *//* thread has already been started */ - - return 1; -} - -static void -AudioFileManager_Disconnect(AudioFileManager * afm) -{ - if (afm->mIsEngaged) { - sReaderThread->RemoveReader(sReaderThread, afm); - afm->mIsEngaged = 0; - } -} - -static OSStatus -AudioFileManager_Read(AudioFileManager * afm, char *buffer, UInt32 * len) -{ - return FSReadFork(afm->mForkRefNum, - fsFromStart, - afm->mReadFilePosition + afm->mAudioDataOffset, - *len, buffer, len); -} - -static OSStatus -AudioFileManager_GetFileData(AudioFileManager * afm, void **inOutData, - UInt32 * inOutDataSize) -{ - if (afm->mFinishedReadingData) { - ++afm->mNumTimesAskedSinceFinished; - *inOutDataSize = 0; - *inOutData = 0; - return noErr; - } - - if (afm->mReadFromFirstBuffer == afm->mWriteToFirstBuffer) { -#if DEBUG - printf("* * * * * * * Can't keep up with reading file\n"); -#endif - - afm->mParent->DoNotification(afm->mParent, - kAudioFilePlayErr_FilePlayUnderrun); - *inOutDataSize = 0; - *inOutData = 0; - } else { - *inOutDataSize = afm->mChunkSize; - *inOutData = - afm->mReadFromFirstBuffer ? afm->mFileBuffer : (afm->mFileBuffer + - afm->mChunkSize); - } - - afm->mLockUnsuccessful = !sReaderThread->TryNextRead(sReaderThread, afm); - - afm->mReadFromFirstBuffer = !afm->mReadFromFirstBuffer; - - return noErr; -} - -static void -AudioFileManager_AfterRender(AudioFileManager * afm) -{ - if (afm->mNumTimesAskedSinceFinished > 0) { - int didLock = 0; - SDLOSXCAGuard *guard = sReaderThread->GetGuard(sReaderThread); - if (guard->Try(guard, &didLock)) { - afm->mParent->DoNotification(afm->mParent, - kAudioFilePlay_FileIsFinished); - if (didLock) - guard->Unlock(guard); - } - } - - if (afm->mLockUnsuccessful) - afm->mLockUnsuccessful = - !sReaderThread->TryNextRead(sReaderThread, afm); -} - -static void -AudioFileManager_SetPosition(AudioFileManager * afm, SInt64 pos) -{ - if (pos < 0 || pos >= afm->mFileLength) { - SDL_SetError - ("AudioFileManager::SetPosition - position invalid: %d filelen=%d\n", - (unsigned int) pos, (unsigned int) afm->mFileLength); - pos = 0; - } - - afm->mReadFilePosition = pos; -} - -static void -AudioFileManager_SetEndOfFile(AudioFileManager * afm, SInt64 pos) -{ - if (pos <= 0 || pos > afm->mFileLength) { - SDL_SetError - ("AudioFileManager::SetEndOfFile - position beyond actual eof\n"); - pos = afm->mFileLength; - } - - afm->mFileLength = pos; -} - -static const char * -AudioFileManager_GetFileBuffer(AudioFileManager * afm) -{ - return afm->mFileBuffer; -} - -const AudioFilePlayer * -AudioFileManager_GetParent(AudioFileManager * afm) -{ - return afm->mParent; -} - -static int -AudioFileManager_GetByteCounter(AudioFileManager * afm) -{ - return afm->mByteCounter; -} - - -static OSStatus -AudioFileManager_FileInputProc(void *inRefCon, - AudioUnitRenderActionFlags inActionFlags, - const AudioTimeStamp * inTimeStamp, - UInt32 inBusNumber, AudioBuffer * ioData) -{ - AudioFileManager *afm = (AudioFileManager *) inRefCon; - return afm->Render(afm, ioData); -} - -static OSStatus -AudioFileManager_Render(AudioFileManager * afm, AudioBuffer * ioData) -{ - OSStatus result = noErr; - - if (afm->mBufferOffset >= afm->mBufferSize) { - result = afm->GetFileData(afm, &afm->mTmpBuffer, &afm->mBufferSize); - if (result) { - SDL_SetError("AudioConverterFillBuffer:%ld\n", result); - afm->mParent->DoNotification(afm->mParent, result); - return result; - } - - afm->mBufferOffset = 0; - } - - if (ioData->mDataByteSize > afm->mBufferSize - afm->mBufferOffset) - ioData->mDataByteSize = afm->mBufferSize - afm->mBufferOffset; - ioData->mData = (char *) afm->mTmpBuffer + afm->mBufferOffset; - afm->mBufferOffset += ioData->mDataByteSize; - - afm->mByteCounter += ioData->mDataByteSize; - afm->AfterRender(afm); - return result; -} - - -void -delete_AudioFileManager(AudioFileManager * afm) -{ - if (afm != NULL) { - if (afm->mFileBuffer) { - free(afm->mFileBuffer); - } - - SDL_free(afm); - } -} - - -AudioFileManager * -new_AudioFileManager(AudioFilePlayer * inParent, - SInt16 inForkRefNum, - SInt64 inFileLength, UInt32 inChunkSize) -{ - AudioFileManager *afm; - - if (sReaderThread == NULL) { - sReaderThread = new_FileReaderThread(); - if (sReaderThread == NULL) - return NULL; - } - - afm = (AudioFileManager *) SDL_malloc(sizeof(AudioFileManager)); - if (afm == NULL) - return NULL; - SDL_memset(afm, '\0', sizeof(*afm)); - -#define SET_AUDIOFILEMANAGER_METHOD(m) afm->m = AudioFileManager_##m - SET_AUDIOFILEMANAGER_METHOD(Disconnect); - SET_AUDIOFILEMANAGER_METHOD(DoConnect); - SET_AUDIOFILEMANAGER_METHOD(Read); - SET_AUDIOFILEMANAGER_METHOD(GetFileBuffer); - SET_AUDIOFILEMANAGER_METHOD(GetParent); - SET_AUDIOFILEMANAGER_METHOD(SetPosition); - SET_AUDIOFILEMANAGER_METHOD(GetByteCounter); - SET_AUDIOFILEMANAGER_METHOD(SetEndOfFile); - SET_AUDIOFILEMANAGER_METHOD(Render); - SET_AUDIOFILEMANAGER_METHOD(GetFileData); - SET_AUDIOFILEMANAGER_METHOD(AfterRender); - SET_AUDIOFILEMANAGER_METHOD(FileInputProc); -#undef SET_AUDIOFILEMANAGER_METHOD - - afm->mParent = inParent; - afm->mForkRefNum = inForkRefNum; - afm->mBufferSize = inChunkSize; - afm->mBufferOffset = inChunkSize; - afm->mChunkSize = inChunkSize; - afm->mFileLength = inFileLength; - afm->mFileBuffer = (char *) SDL_malloc(afm->mChunkSize * 2); - FSGetForkPosition(afm->mForkRefNum, &afm->mAudioDataOffset); - assert(afm->mFileBuffer != NULL); - return afm; -} - -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/cdrom/macosx/CDPlayer.c Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,669 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#include "CDPlayer.h" -#include "AudioFilePlayer.h" -#include "SDLOSXCAGuard.h" - -/* we're exporting these functions into C land for SDL_syscdrom.c */ -/*extern "C" {*/ - -/*/////////////////////////////////////////////////////////////////////////// - Constants - //////////////////////////////////////////////////////////////////////////*/ - -#define kAudioCDFilesystemID (UInt16)(('J' << 8) | 'H') /* 'JH'; this avoids compiler warning */ - -/* XML PList keys */ -#define kRawTOCDataString "Format 0x02 TOC Data" -#define kSessionsString "Sessions" -#define kSessionTypeString "Session Type" -#define kTrackArrayString "Track Array" -#define kFirstTrackInSessionString "First Track" -#define kLastTrackInSessionString "Last Track" -#define kLeadoutBlockString "Leadout Block" -#define kDataKeyString "Data" -#define kPointKeyString "Point" -#define kSessionNumberKeyString "Session Number" -#define kStartBlockKeyString "Start Block" - -/*/////////////////////////////////////////////////////////////////////////// - Globals - //////////////////////////////////////////////////////////////////////////*/ - -#pragma mark -- Globals -- - -static int playBackWasInit = 0; -static AudioUnit theUnit; -static AudioFilePlayer *thePlayer = NULL; -static CDPlayerCompletionProc completionProc = NULL; -static SDL_mutex *apiMutex = NULL; -static SDL_sem *callbackSem; -static SDL_CD *theCDROM; - -/*/////////////////////////////////////////////////////////////////////////// - Prototypes - //////////////////////////////////////////////////////////////////////////*/ - -#pragma mark -- Prototypes -- - -static OSStatus CheckInit(); - -static void FilePlayNotificationHandler(void *inRefCon, OSStatus inStatus); - -static int RunCallBackThread(void *inRefCon); - - -#pragma mark -- Public Functions -- - -void -Lock() -{ - if (!apiMutex) { - apiMutex = SDL_CreateMutex(); - } - SDL_mutexP(apiMutex); -} - -void -Unlock() -{ - SDL_mutexV(apiMutex); -} - -int -DetectAudioCDVolumes(FSVolumeRefNum * volumes, int numVolumes) -{ - int volumeIndex; - int cdVolumeCount = 0; - OSStatus result = noErr; - - for (volumeIndex = 1; result == noErr || result != nsvErr; volumeIndex++) { - FSVolumeRefNum actualVolume; - FSVolumeInfo volumeInfo; - - memset(&volumeInfo, 0, sizeof(volumeInfo)); - - result = FSGetVolumeInfo(kFSInvalidVolumeRefNum, - volumeIndex, - &actualVolume, - kFSVolInfoFSInfo, &volumeInfo, NULL, NULL); - - if (result == noErr) { - if (volumeInfo.filesystemID == kAudioCDFilesystemID) { /* It's an audio CD */ - if (volumes != NULL && cdVolumeCount < numVolumes) - volumes[cdVolumeCount] = actualVolume; - - cdVolumeCount++; - } - } else { - /* I'm commenting this out because it seems to be harmless */ - /*SDL_SetError ("DetectAudioCDVolumes: FSGetVolumeInfo returned %d", result); */ - } - } - - return cdVolumeCount; -} - -int -ReadTOCData(FSVolumeRefNum theVolume, SDL_CD * theCD) -{ - HFSUniStr255 dataForkName; - OSStatus theErr; - SInt16 forkRefNum; - SInt64 forkSize; - Ptr forkData = 0; - ByteCount actualRead; - CFDataRef dataRef = 0; - CFPropertyListRef propertyListRef = 0; - - FSRefParam fsRefPB; - FSRef tocPlistFSRef; - - const char *error = "Unspecified Error"; - - /* get stuff from .TOC.plist */ - fsRefPB.ioCompletion = NULL; - fsRefPB.ioNamePtr = "\p.TOC.plist"; - fsRefPB.ioVRefNum = theVolume; - fsRefPB.ioDirID = 0; - fsRefPB.newRef = &tocPlistFSRef; - - theErr = PBMakeFSRefSync(&fsRefPB); - if (theErr != noErr) { - error = "PBMakeFSRefSync"; - goto bail; - } - - /* Load and parse the TOC XML data */ - - theErr = FSGetDataForkName(&dataForkName); - if (theErr != noErr) { - error = "FSGetDataForkName"; - goto bail; - } - - theErr = - FSOpenFork(&tocPlistFSRef, dataForkName.length, dataForkName.unicode, - fsRdPerm, &forkRefNum); - if (theErr != noErr) { - error = "FSOpenFork"; - goto bail; - } - - theErr = FSGetForkSize(forkRefNum, &forkSize); - if (theErr != noErr) { - error = "FSGetForkSize"; - goto bail; - } - - /* Allocate some memory for the XML data */ - forkData = NewPtr(forkSize); - if (forkData == NULL) { - error = "NewPtr"; - goto bail; - } - - theErr = FSReadFork(forkRefNum, fsFromStart, 0 /* offset location */ , - forkSize, forkData, &actualRead); - if (theErr != noErr) { - error = "FSReadFork"; - goto bail; - } - - dataRef = CFDataCreate(kCFAllocatorDefault, (UInt8 *) forkData, forkSize); - if (dataRef == 0) { - error = "CFDataCreate"; - goto bail; - } - - propertyListRef = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, - dataRef, - kCFPropertyListImmutable, - NULL); - if (propertyListRef == NULL) { - error = "CFPropertyListCreateFromXMLData"; - goto bail; - } - - /* Now we got the Property List in memory. Parse it. */ - - /* First, make sure the root item is a CFDictionary. If not, release and bail. */ - if (CFGetTypeID(propertyListRef) == CFDictionaryGetTypeID()) { - CFDictionaryRef dictRef = (CFDictionaryRef) propertyListRef; - - CFDataRef theRawTOCDataRef; - CFArrayRef theSessionArrayRef; - CFIndex numSessions; - CFIndex index; - - /* This is how we get the Raw TOC Data */ - theRawTOCDataRef = - (CFDataRef) CFDictionaryGetValue(dictRef, - CFSTR(kRawTOCDataString)); - - /* Get the session array info. */ - theSessionArrayRef = - (CFArrayRef) CFDictionaryGetValue(dictRef, - CFSTR(kSessionsString)); - - /* Find out how many sessions there are. */ - numSessions = CFArrayGetCount(theSessionArrayRef); - - /* Initialize the total number of tracks to 0 */ - theCD->numtracks = 0; - - /* Iterate over all sessions, collecting the track data */ - for (index = 0; index < numSessions; index++) { - CFDictionaryRef theSessionDict; - CFNumberRef leadoutBlock; - CFArrayRef trackArray; - CFIndex numTracks; - CFIndex trackIndex; - UInt32 value = 0; - - theSessionDict = (CFDictionaryRef) - CFArrayGetValueAtIndex(theSessionArrayRef, index); - leadoutBlock = - (CFNumberRef) CFDictionaryGetValue(theSessionDict, - CFSTR - (kLeadoutBlockString)); - - trackArray = - (CFArrayRef) CFDictionaryGetValue(theSessionDict, - CFSTR(kTrackArrayString)); - - numTracks = CFArrayGetCount(trackArray); - - for (trackIndex = 0; trackIndex < numTracks; trackIndex++) { - - CFDictionaryRef theTrackDict; - CFNumberRef trackNumber; - CFNumberRef sessionNumber; - CFNumberRef startBlock; - CFBooleanRef isDataTrack; - UInt32 value; - - theTrackDict = (CFDictionaryRef) - CFArrayGetValueAtIndex(trackArray, trackIndex); - - trackNumber = - (CFNumberRef) CFDictionaryGetValue(theTrackDict, - CFSTR - (kPointKeyString)); - sessionNumber = - (CFNumberRef) CFDictionaryGetValue(theTrackDict, - CFSTR - (kSessionNumberKeyString)); - startBlock = - (CFNumberRef) CFDictionaryGetValue(theTrackDict, - CFSTR - (kStartBlockKeyString)); - isDataTrack = - (CFBooleanRef) CFDictionaryGetValue(theTrackDict, - CFSTR - (kDataKeyString)); - - /* Fill in the SDL_CD struct */ - int idx = theCD->numtracks++; - - CFNumberGetValue(trackNumber, kCFNumberSInt32Type, &value); - theCD->track[idx].id = value; - - CFNumberGetValue(startBlock, kCFNumberSInt32Type, &value); - theCD->track[idx].offset = value; - - theCD->track[idx].type = - (isDataTrack == - kCFBooleanTrue) ? SDL_DATA_TRACK : SDL_AUDIO_TRACK; - - /* Since the track lengths are not stored in .TOC.plist we compute them. */ - if (trackIndex > 0) { - theCD->track[idx - 1].length = - theCD->track[idx].offset - theCD->track[idx - - 1].offset; - } - } - - /* Compute the length of the last track */ - CFNumberGetValue(leadoutBlock, kCFNumberSInt32Type, &value); - - theCD->track[theCD->numtracks - 1].length = - value - theCD->track[theCD->numtracks - 1].offset; - - /* Set offset to leadout track */ - theCD->track[theCD->numtracks].offset = value; - } - - } - - theErr = 0; - goto cleanup; - bail: - SDL_SetError("ReadTOCData: %s returned %d", error, theErr); - theErr = -1; - cleanup: - - if (propertyListRef != NULL) - CFRelease(propertyListRef); - if (dataRef != NULL) - CFRelease(dataRef); - if (forkData != NULL) - DisposePtr(forkData); - - FSCloseFork(forkRefNum); - - return theErr; -} - -int -ListTrackFiles(FSVolumeRefNum theVolume, FSRef * trackFiles, int numTracks) -{ - OSStatus result = -1; - FSIterator iterator; - ItemCount actualObjects; - FSRef rootDirectory; - FSRef ref; - HFSUniStr255 nameStr; - - result = FSGetVolumeInfo(theVolume, - 0, - NULL, - kFSVolInfoFSInfo, NULL, NULL, &rootDirectory); - - if (result != noErr) { - SDL_SetError("ListTrackFiles: FSGetVolumeInfo returned %d", result); - return result; - } - - result = FSOpenIterator(&rootDirectory, kFSIterateFlat, &iterator); - if (result == noErr) { - do { - result = FSGetCatalogInfoBulk(iterator, 1, &actualObjects, - NULL, kFSCatInfoNone, NULL, - &ref, NULL, &nameStr); - if (result == noErr) { - - CFStringRef name; - name = - CFStringCreateWithCharacters(NULL, nameStr.unicode, - nameStr.length); - - /* Look for .aiff extension */ - if (CFStringHasSuffix(name, CFSTR(".aiff")) || - CFStringHasSuffix(name, CFSTR(".cdda"))) { - - /* Extract the track id from the filename */ - int trackID = 0, i = 0; - while (i < nameStr.length && !isdigit(nameStr.unicode[i])) { - ++i; - } - while (i < nameStr.length && isdigit(nameStr.unicode[i])) { - trackID = 10 * trackID + (nameStr.unicode[i] - '0'); - ++i; - } - -#if DEBUG_CDROM - printf("Found AIFF for track %d: '%s'\n", - trackID, CFStringGetCStringPtr(name, - CFStringGetSystemEncoding - ())); -#endif - - /* Track ID's start at 1, but we want to start at 0 */ - trackID--; - - assert(0 <= trackID && trackID <= SDL_MAX_TRACKS); - - if (trackID < numTracks) - memcpy(&trackFiles[trackID], &ref, sizeof(FSRef)); - } - CFRelease(name); - } - } while (noErr == result); - FSCloseIterator(iterator); - } - - return 0; -} - -int -LoadFile(const FSRef * ref, int startFrame, int stopFrame) -{ - int error = -1; - - if (CheckInit() < 0) - goto bail; - - /* release any currently playing file */ - if (ReleaseFile() < 0) - goto bail; - -#if DEBUG_CDROM - printf("LoadFile: %d %d\n", startFrame, stopFrame); -#endif - - /*try { */ - - /* create a new player, and attach to the audio unit */ - - thePlayer = new_AudioFilePlayer(ref); - if (thePlayer == NULL) { - SDL_SetError("LoadFile: Could not create player"); - return -3; /*throw (-3); */ - } - - if (!thePlayer->SetDestination(thePlayer, &theUnit)) - goto bail; - - if (startFrame >= 0) - thePlayer->SetStartFrame(thePlayer, startFrame); - - if (stopFrame >= 0 && stopFrame > startFrame) - thePlayer->SetStopFrame(thePlayer, stopFrame); - - /* we set the notifier later */ - /*thePlayer->SetNotifier(thePlayer, FilePlayNotificationHandler, NULL); */ - - if (!thePlayer->Connect(thePlayer)) - goto bail; - -#if DEBUG_CDROM - thePlayer->Print(thePlayer); - fflush(stdout); -#endif - /*} - catch (...) - { - goto bail; - } */ - - error = 0; - - bail: - return error; -} - -int -ReleaseFile() -{ - int error = -1; - - /* (Don't see any way that the original C++ code could throw here.) --ryan. */ - /*try { */ - if (thePlayer != NULL) { - - thePlayer->Disconnect(thePlayer); - - delete_AudioFilePlayer(thePlayer); - - thePlayer = NULL; - } - /*} - catch (...) - { - goto bail; - } */ - - error = 0; - -/* bail: */ - return error; -} - -int -PlayFile() -{ - OSStatus result = -1; - - if (CheckInit() < 0) - goto bail; - - /*try { */ - - // start processing of the audio unit - result = AudioOutputUnitStart(theUnit); - if (result) - goto bail; //THROW_RESULT("PlayFile: AudioOutputUnitStart") - - /*} - catch (...) - { - goto bail; - } */ - - result = 0; - - bail: - return result; -} - -int -PauseFile() -{ - OSStatus result = -1; - - if (CheckInit() < 0) - goto bail; - - /*try { */ - - /* stop processing the audio unit */ - result = AudioOutputUnitStop(theUnit); - if (result) - goto bail; /*THROW_RESULT("PauseFile: AudioOutputUnitStop") */ - /*} - catch (...) - { - goto bail; - } */ - - result = 0; - bail: - return result; -} - -void -SetCompletionProc(CDPlayerCompletionProc proc, SDL_CD * cdrom) -{ - assert(thePlayer != NULL); - - theCDROM = cdrom; - completionProc = proc; - thePlayer->SetNotifier(thePlayer, FilePlayNotificationHandler, cdrom); -} - -int -GetCurrentFrame() -{ - int frame; - - if (thePlayer == NULL) - frame = 0; - else - frame = thePlayer->GetCurrentFrame(thePlayer); - - return frame; -} - - -#pragma mark -- Private Functions -- - -static OSStatus -CheckInit() -{ - if (playBackWasInit) - return 0; - - OSStatus result = noErr; - - /* Create the callback semaphore */ - callbackSem = SDL_CreateSemaphore(0); - - /* Start callback thread */ - SDL_CreateThread(RunCallBackThread, NULL); - - { /*try { */ - ComponentDescription desc; - - desc.componentType = kAudioUnitComponentType; - desc.componentSubType = kAudioUnitSubType_Output; - desc.componentManufacturer = kAudioUnitID_DefaultOutput; - desc.componentFlags = 0; - desc.componentFlagsMask = 0; - - Component comp = FindNextComponent(NULL, &desc); - if (comp == NULL) { - SDL_SetError("CheckInit: FindNextComponent returned NULL"); - if (result) - return -1; //throw(internalComponentErr); - } - - result = OpenAComponent(comp, &theUnit); - if (result) - return -1; //THROW_RESULT("CheckInit: OpenAComponent") - - // you need to initialize the output unit before you set it as a destination - result = AudioUnitInitialize(theUnit); - if (result) - return -1; //THROW_RESULT("CheckInit: AudioUnitInitialize") - - - playBackWasInit = true; - } - /*catch (...) - { - return -1; - } */ - - return 0; -} - -static void -FilePlayNotificationHandler(void *inRefCon, OSStatus inStatus) -{ - if (inStatus == kAudioFilePlay_FileIsFinished) { - - /* notify non-CA thread to perform the callback */ - SDL_SemPost(callbackSem); - - } else if (inStatus == kAudioFilePlayErr_FilePlayUnderrun) { - - SDL_SetError("CDPlayer Notification: buffer underrun"); - } else if (inStatus == kAudioFilePlay_PlayerIsUninitialized) { - - SDL_SetError("CDPlayer Notification: player is uninitialized"); - } else { - - SDL_SetError("CDPlayer Notification: unknown error %ld", inStatus); - } -} - -static int -RunCallBackThread(void *param) -{ - for (;;) { - - SDL_SemWait(callbackSem); - - if (completionProc && theCDROM) { -#if DEBUG_CDROM - printf("callback!\n"); -#endif - (*completionProc) (theCDROM); - } else { -#if DEBUG_CDROM - printf("callback?\n"); -#endif - } - } - -#if DEBUG_CDROM - printf("thread dying now...\n"); -#endif - - return 0; -} - -/*}; // extern "C" */ -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/cdrom/macosx/CDPlayer.h Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifndef __CDPlayer__H__ -#define __CDPlayer__H__ 1 - -#include <string.h> - -#include <Carbon/Carbon.h> -#include <CoreFoundation/CoreFoundation.h> -#include <AudioUnit/AudioUnit.h> - -#include "SDL_cdrom.h" -#include "SDL_thread.h" -#include "SDL_mutex.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - - typedef void (*CDPlayerCompletionProc) (SDL_CD * cdrom); - - void Lock(); - - void Unlock(); - - int LoadFile(const FSRef * ref, int startFrame, int endFrame); /* pass -1 to do nothing */ - - int ReleaseFile(); - - int PlayFile(); - - int PauseFile(); - - void SetCompletionProc(CDPlayerCompletionProc proc, SDL_CD * cdrom); - - int ReadTOCData(FSVolumeRefNum theVolume, SDL_CD * theCD); - - int ListTrackFiles(FSVolumeRefNum theVolume, FSRef * trackFiles, - int numTracks); - - int DetectAudioCDVolumes(FSVolumeRefNum * volumes, int numVolumes); - - int GetCurrentFrame(); - -#ifdef __cplusplus -}; -#endif - -#endif /* __CD_Player__H__ */ -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/cdrom/macosx/SDLOSXCAGuard.c Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,205 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* - Note: This file hasn't been modified so technically we have to keep the disclaimer :-( - - Copyright: © Copyright 2002 Apple Computer, Inc. All rights reserved. - - Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. - ("Apple") in consideration of your agreement to the following terms, and your - use, installation, modification or redistribution of this Apple software - constitutes acceptance of these terms. If you do not agree with these terms, - please do not use, install, modify or redistribute this Apple software. - - In consideration of your agreement to abide by the following terms, and subject - to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs - copyrights in this original Apple software (the "Apple Software"), to use, - reproduce, modify and redistribute the Apple Software, with or without - modifications, in source and/or binary forms; provided that if you redistribute - the Apple Software in its entirety and without modifications, you must retain - this notice and the following text and disclaimers in all such redistributions of - the Apple Software. Neither the name, trademarks, service marks or logos of - Apple Computer, Inc. may be used to endorse or promote products derived from the - Apple Software without specific prior written permission from Apple. Except as - expressly stated in this notice, no other rights or licenses, express or implied, - are granted by Apple herein, including but not limited to any patent rights that - may be infringed by your derivative works or by other works in which the Apple - Software may be incorporated. - - The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO - WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED - WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN - COMBINATION WITH YOUR PRODUCTS. - - IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION - OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT - (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -/*============================================================================= - CAGuard.cp - -=============================================================================*/ - -/*============================================================================= - Includes - =============================================================================*/ - -/* -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -*/ -#include "SDL_stdinc.h" - -/*#define NDEBUG 1*/ -/* -#include <assert.h> -*/ -#define assert(X) - - -#include "SDLOSXCAGuard.h" - -/*#warning Need a try-based Locker too*/ -/*============================================================================= - SDLOSXCAGuard - =============================================================================*/ - -static int -SDLOSXCAGuard_Lock(SDLOSXCAGuard * cag) -{ - int theAnswer = 0; - - if (pthread_self() != cag->mOwner) { - OSStatus theError = pthread_mutex_lock(&cag->mMutex); - (void) theError; - assert(theError == 0); - cag->mOwner = pthread_self(); - theAnswer = 1; - } - - return theAnswer; -} - -static void -SDLOSXCAGuard_Unlock(SDLOSXCAGuard * cag) -{ - OSStatus theError; - assert(pthread_self() == cag->mOwner); - - cag->mOwner = 0; - theError = pthread_mutex_unlock(&cag->mMutex); - (void) theError; - assert(theError == 0); -} - -static int -SDLOSXCAGuard_Try(SDLOSXCAGuard * cag, int *outWasLocked) -{ - int theAnswer = 0; - *outWasLocked = 0; - - if (pthread_self() == cag->mOwner) { - theAnswer = 1; - *outWasLocked = 0; - } else { - OSStatus theError = pthread_mutex_trylock(&cag->mMutex); - if (theError == 0) { - cag->mOwner = pthread_self(); - theAnswer = 1; - *outWasLocked = 1; - } - } - - return theAnswer; -} - -static void -SDLOSXCAGuard_Wait(SDLOSXCAGuard * cag) -{ - OSStatus theError; - assert(pthread_self() == cag->mOwner); - - cag->mOwner = 0; - - theError = pthread_cond_wait(&cag->mCondVar, &cag->mMutex); - (void) theError; - assert(theError == 0); - cag->mOwner = pthread_self(); -} - -static void -SDLOSXCAGuard_Notify(SDLOSXCAGuard * cag) -{ - OSStatus theError = pthread_cond_signal(&cag->mCondVar); - (void) theError; - assert(theError == 0); -} - - -SDLOSXCAGuard * -new_SDLOSXCAGuard(void) -{ - OSStatus theError; - SDLOSXCAGuard *cag = (SDLOSXCAGuard *) SDL_malloc(sizeof(SDLOSXCAGuard)); - if (cag == NULL) - return NULL; - SDL_memset(cag, '\0', sizeof(*cag)); - -#define SET_SDLOSXCAGUARD_METHOD(m) cag->m = SDLOSXCAGuard_##m - SET_SDLOSXCAGUARD_METHOD(Lock); - SET_SDLOSXCAGUARD_METHOD(Unlock); - SET_SDLOSXCAGUARD_METHOD(Try); - SET_SDLOSXCAGUARD_METHOD(Wait); - SET_SDLOSXCAGUARD_METHOD(Notify); -#undef SET_SDLOSXCAGUARD_METHOD - - theError = pthread_mutex_init(&cag->mMutex, NULL); - (void) theError; - assert(theError == 0); - - theError = pthread_cond_init(&cag->mCondVar, NULL); - (void) theError; - assert(theError == 0); - - cag->mOwner = 0; - return cag; -} - -void -delete_SDLOSXCAGuard(SDLOSXCAGuard * cag) -{ - if (cag != NULL) { - pthread_mutex_destroy(&cag->mMutex); - pthread_cond_destroy(&cag->mCondVar); - SDL_free(cag); - } -} - -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/cdrom/macosx/SDLOSXCAGuard.h Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,116 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* - Note: This file hasn't been modified so technically we have to keep the disclaimer :-( - - - Copyright: © Copyright 2002 Apple Computer, Inc. All rights reserved. - - Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. - ("Apple") in consideration of your agreement to the following terms, and your - use, installation, modification or redistribution of this Apple software - constitutes acceptance of these terms. If you do not agree with these terms, - please do not use, install, modify or redistribute this Apple software. - - In consideration of your agreement to abide by the following terms, and subject - to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs - copyrights in this original Apple software (the "Apple Software"), to use, - reproduce, modify and redistribute the Apple Software, with or without - modifications, in source and/or binary forms; provided that if you redistribute - the Apple Software in its entirety and without modifications, you must retain - this notice and the following text and disclaimers in all such redistributions of - the Apple Software. Neither the name, trademarks, service marks or logos of - Apple Computer, Inc. may be used to endorse or promote products derived from the - Apple Software without specific prior written permission from Apple. Except as - expressly stated in this notice, no other rights or licenses, express or implied, - are granted by Apple herein, including but not limited to any patent rights that - may be infringed by your derivative works or by other works in which the Apple - Software may be incorporated. - - The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO - WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED - WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN - COMBINATION WITH YOUR PRODUCTS. - - IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION - OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT - (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -/*============================================================================= - CAGuard.h - -=============================================================================*/ -#if !defined(__CAGuard_h__) -#define __CAGuard_h__ - -/*============================================================================= - Includes - =============================================================================*/ - -#include <CoreAudio/CoreAudioTypes.h> -#include <pthread.h> - - -/*============================================================================= - CAGuard - - This is your typical mutex with signalling implemented via pthreads. - Lock() will return true if and only if the guard is locked on that call. - A thread that already has the guard will receive 'false' if it locks it - again. Use of the stack-based CAGuard::Locker class is highly recommended - to properly manage the recursive nesting. The Wait calls with timeouts - will return true if and only if the timeout period expired. They will - return false if they receive notification any other way. - =============================================================================*/ - -typedef struct S_SDLOSXCAGuard -{ - -/* Construction/Destruction */ -/*public:*/ -/* Actions */ -/*public:*/ - int (*Lock) (struct S_SDLOSXCAGuard * cag); - void (*Unlock) (struct S_SDLOSXCAGuard * cag); - int (*Try) (struct S_SDLOSXCAGuard * cag, int *outWasLocked); /* returns true if lock is free, false if not */ - void (*Wait) (struct S_SDLOSXCAGuard * cag); - void (*Notify) (struct S_SDLOSXCAGuard * cag); - -/* Implementation */ -/*protected:*/ - pthread_mutex_t mMutex; - pthread_cond_t mCondVar; - pthread_t mOwner; -} SDLOSXCAGuard; - -SDLOSXCAGuard *new_SDLOSXCAGuard(void); -void delete_SDLOSXCAGuard(SDLOSXCAGuard * cag); - -#endif -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/cdrom/macosx/SDL_syscdrom.c Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,523 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifdef SDL_CDROM_MACOSX - -#include "SDL_syscdrom_c.h" - -#pragma mark -- Globals -- - -static FSRef **tracks; -static FSVolumeRefNum *volumes; -static CDstatus status; -static int nextTrackFrame; -static int nextTrackFramesRemaining; -static int fakeCD; -static int currentTrack; -static int didReadTOC; -static int cacheTOCNumTracks; -static int currentDrive; /* Only allow 1 drive in use at a time */ - -#pragma mark -- Prototypes -- - -static const char *SDL_SYS_CDName(int drive); -static int SDL_SYS_CDOpen(int drive); -static int SDL_SYS_CDGetTOC(SDL_CD * cdrom); -static CDstatus SDL_SYS_CDStatus(SDL_CD * cdrom, int *position); -static int SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length); -static int SDL_SYS_CDPause(SDL_CD * cdrom); -static int SDL_SYS_CDResume(SDL_CD * cdrom); -static int SDL_SYS_CDStop(SDL_CD * cdrom); -static int SDL_SYS_CDEject(SDL_CD * cdrom); -static void SDL_SYS_CDClose(SDL_CD * cdrom); - -#pragma mark -- Helper Functions -- - -/* Read a list of tracks from the volume */ -static int -LoadTracks(SDL_CD * cdrom) -{ - /* Check if tracks are already loaded */ - if (tracks[cdrom->id] != NULL) - return 0; - - /* Allocate memory for tracks */ - tracks[cdrom->id] = - (FSRef *) SDL_calloc(1, sizeof(**tracks) * cdrom->numtracks); - if (tracks[cdrom->id] == NULL) { - SDL_OutOfMemory(); - return -1; - } - - /* Load tracks */ - if (ListTrackFiles - (volumes[cdrom->id], tracks[cdrom->id], cdrom->numtracks) < 0) - return -1; - - return 0; -} - -/* Find a file for a given start frame and length */ -static FSRef * -GetFileForOffset(SDL_CD * cdrom, int start, int length, int *outStartFrame, - int *outStopFrame) -{ - int i; - - for (i = 0; i < cdrom->numtracks; i++) { - - if (cdrom->track[i].offset <= start && - start < (cdrom->track[i].offset + cdrom->track[i].length)) - break; - } - - if (i == cdrom->numtracks) - return NULL; - - currentTrack = i; - - *outStartFrame = start - cdrom->track[i].offset; - - if ((*outStartFrame + length) < cdrom->track[i].length) { - *outStopFrame = *outStartFrame + length; - length = 0; - nextTrackFrame = -1; - nextTrackFramesRemaining = -1; - } else { - *outStopFrame = -1; - length -= cdrom->track[i].length - *outStartFrame; - nextTrackFrame = cdrom->track[i + 1].offset; - nextTrackFramesRemaining = length; - } - - return &tracks[cdrom->id][i]; -} - -/* Setup another file for playback, or stop playback (called from another thread) */ -static void -CompletionProc(SDL_CD * cdrom) -{ - - Lock(); - - if (nextTrackFrame > 0 && nextTrackFramesRemaining > 0) { - - /* Load the next file to play */ - int startFrame, stopFrame; - FSRef *file; - - PauseFile(); - ReleaseFile(); - - file = GetFileForOffset(cdrom, nextTrackFrame, - nextTrackFramesRemaining, &startFrame, - &stopFrame); - - if (file == NULL) { - status = CD_STOPPED; - Unlock(); - return; - } - - LoadFile(file, startFrame, stopFrame); - - SetCompletionProc(CompletionProc, cdrom); - - PlayFile(); - } else { - - /* Release the current file */ - PauseFile(); - ReleaseFile(); - status = CD_STOPPED; - } - - Unlock(); -} - - -#pragma mark -- Driver Functions -- - -/* Initialize */ -int -SDL_SYS_CDInit(void) -{ - /* Initialize globals */ - volumes = NULL; - tracks = NULL; - status = CD_STOPPED; - nextTrackFrame = -1; - nextTrackFramesRemaining = -1; - fakeCD = SDL_FALSE; - currentTrack = -1; - didReadTOC = SDL_FALSE; - cacheTOCNumTracks = -1; - currentDrive = -1; - - /* Fill in function pointers */ - SDL_CDcaps.Name = SDL_SYS_CDName; - SDL_CDcaps.Open = SDL_SYS_CDOpen; - SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; - SDL_CDcaps.Status = SDL_SYS_CDStatus; - SDL_CDcaps.Play = SDL_SYS_CDPlay; - SDL_CDcaps.Pause = SDL_SYS_CDPause; - SDL_CDcaps.Resume = SDL_SYS_CDResume; - SDL_CDcaps.Stop = SDL_SYS_CDStop; - SDL_CDcaps.Eject = SDL_SYS_CDEject; - SDL_CDcaps.Close = SDL_SYS_CDClose; - - /* - Read the list of "drives" - - This is currently a hack that infers drives from - mounted audio CD volumes, rather than - actual CD-ROM devices - which means it may not - act as expected sometimes. - */ - - /* Find out how many cd volumes are mounted */ - SDL_numcds = DetectAudioCDVolumes(NULL, 0); - - /* - If there are no volumes, fake a cd device - so tray empty can be reported. - */ - if (SDL_numcds == 0) { - - fakeCD = SDL_TRUE; - SDL_numcds = 1; - status = CD_TRAYEMPTY; - - return 0; - } - - /* Allocate space for volumes */ - volumes = (FSVolumeRefNum *) SDL_calloc(1, sizeof(*volumes) * SDL_numcds); - if (volumes == NULL) { - SDL_OutOfMemory(); - return -1; - } - - /* Allocate space for tracks */ - tracks = (FSRef **) SDL_calloc(1, sizeof(*tracks) * (SDL_numcds + 1)); - if (tracks == NULL) { - SDL_OutOfMemory(); - return -1; - } - - /* Mark the end of the tracks array */ - tracks[SDL_numcds] = (FSRef *) - 1; - - /* - Redetect, now save all volumes for later - Update SDL_numcds just in case it changed - */ - { - int numVolumes = SDL_numcds; - - SDL_numcds = DetectAudioCDVolumes(volumes, numVolumes); - - /* If more cds suddenly show up, ignore them */ - if (SDL_numcds > numVolumes) { - SDL_SetError("Some CD's were added but they will be ignored"); - SDL_numcds = numVolumes; - } - } - - return 0; -} - -/* Shutdown and cleanup */ -void -SDL_SYS_CDQuit(void) -{ - ReleaseFile(); - - if (volumes != NULL) - free(volumes); - - if (tracks != NULL) { - - FSRef **ptr; - for (ptr = tracks; *ptr != (FSRef *) - 1; ptr++) - if (*ptr != NULL) - free(*ptr); - - free(tracks); - } -} - -/* Get the Unix disk name of the volume */ -static const char * -SDL_SYS_CDName(int drive) -{ - OSStatus err = noErr; - HParamBlockRec pb; - GetVolParmsInfoBuffer volParmsInfo; - - if (fakeCD) - return "Fake CD-ROM Device"; - - pb.ioParam.ioNamePtr = NULL; - pb.ioParam.ioVRefNum = volumes[drive]; - pb.ioParam.ioBuffer = (Ptr) & volParmsInfo; - pb.ioParam.ioReqCount = (SInt32) sizeof(volParmsInfo); - err = PBHGetVolParmsSync(&pb); - - if (err != noErr) { - SDL_SetError("PBHGetVolParmsSync returned %d", err); - return NULL; - } - - return volParmsInfo.vMDeviceID; -} - -/* Open the "device" */ -static int -SDL_SYS_CDOpen(int drive) -{ - /* Only allow 1 device to be open */ - if (currentDrive >= 0) { - SDL_SetError("Only one cdrom is supported"); - return -1; - } else - currentDrive = drive; - - return drive; -} - -/* Get the table of contents */ -static int -SDL_SYS_CDGetTOC(SDL_CD * cdrom) -{ - if (fakeCD) { - SDL_SetError(kErrorFakeDevice); - return -1; - } - - if (didReadTOC) { - cdrom->numtracks = cacheTOCNumTracks; - return 0; - } - - - ReadTOCData(volumes[cdrom->id], cdrom); - didReadTOC = SDL_TRUE; - cacheTOCNumTracks = cdrom->numtracks; - - return 0; -} - -/* Get CD-ROM status */ -static CDstatus -SDL_SYS_CDStatus(SDL_CD * cdrom, int *position) -{ - if (position) { - int trackFrame; - - Lock(); - trackFrame = GetCurrentFrame(); - Unlock(); - - *position = cdrom->track[currentTrack].offset + trackFrame; - } - - return status; -} - -/* Start playback */ -static int -SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length) -{ - int startFrame, stopFrame; - FSRef *ref; - - if (fakeCD) { - SDL_SetError(kErrorFakeDevice); - return -1; - } - - Lock(); - - if (LoadTracks(cdrom) < 0) - return -2; - - if (PauseFile() < 0) - return -3; - - if (ReleaseFile() < 0) - return -4; - - ref = GetFileForOffset(cdrom, start, length, &startFrame, &stopFrame); - if (ref == NULL) { - SDL_SetError("SDL_SYS_CDPlay: No file for start=%d, length=%d", - start, length); - return -5; - } - - if (LoadFile(ref, startFrame, stopFrame) < 0) - return -6; - - SetCompletionProc(CompletionProc, cdrom); - - if (PlayFile() < 0) - return -7; - - status = CD_PLAYING; - - Unlock(); - - return 0; -} - -/* Pause playback */ -static int -SDL_SYS_CDPause(SDL_CD * cdrom) -{ - if (fakeCD) { - SDL_SetError(kErrorFakeDevice); - return -1; - } - - Lock(); - - if (PauseFile() < 0) { - Unlock(); - return -2; - } - - status = CD_PAUSED; - - Unlock(); - - return 0; -} - -/* Resume playback */ -static int -SDL_SYS_CDResume(SDL_CD * cdrom) -{ - if (fakeCD) { - SDL_SetError(kErrorFakeDevice); - return -1; - } - - Lock(); - - if (PlayFile() < 0) { - Unlock(); - return -2; - } - - status = CD_PLAYING; - - Unlock(); - - return 0; -} - -/* Stop playback */ -static int -SDL_SYS_CDStop(SDL_CD * cdrom) -{ - if (fakeCD) { - SDL_SetError(kErrorFakeDevice); - return -1; - } - - Lock(); - - if (PauseFile() < 0) { - Unlock(); - return -2; - } - - if (ReleaseFile() < 0) { - Unlock(); - return -3; - } - - status = CD_STOPPED; - - Unlock(); - - return 0; -} - -/* Eject the CD-ROM (Unmount the volume) */ -static int -SDL_SYS_CDEject(SDL_CD * cdrom) -{ - OSStatus err; - pid_t dissenter; - - if (fakeCD) { - SDL_SetError(kErrorFakeDevice); - return -1; - } - - Lock(); - - if (PauseFile() < 0) { - Unlock(); - return -2; - } - - if (ReleaseFile() < 0) { - Unlock(); - return -3; - } - - status = CD_STOPPED; - - /* Eject the volume */ - err = FSEjectVolumeSync(volumes[cdrom->id], kNilOptions, &dissenter); - - if (err != noErr) { - Unlock(); - SDL_SetError("PBUnmountVol returned %d", err); - return -4; - } - - status = CD_TRAYEMPTY; - - /* Invalidate volume and track info */ - volumes[cdrom->id] = 0; - free(tracks[cdrom->id]); - tracks[cdrom->id] = NULL; - - Unlock(); - - return 0; -} - -/* Close the CD-ROM */ -static void -SDL_SYS_CDClose(SDL_CD * cdrom) -{ - currentDrive = -1; - return; -} - -#endif /* SDL_CDROM_MACOSX */ -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/cdrom/macosx/SDL_syscdrom_c.h Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,136 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* This is the Mac OS X / CoreAudio specific header for the SDL CD-ROM API - Contributed by Darrell Walisser and Max Horn - */ - -/*********************************************************************************** - Implementation Notes - ********************* - - This code has several limitations currently (all of which are proabaly fixable): - - 1. A CD-ROM device is inferred from a mounted cdfs volume, so device 0 is - not necessarily the first CD-ROM device on the system. (Somewhat easy to fix - by useing the device name from the volume id's to reorder the volumes) - - 2. You can only open and control 1 CD-ROM device at a time. (Challenging to fix, - due to extensive code restructuring) - - 3. The status reported by SDL_CDStatus only changes to from CD_PLAYING to CD_STOPPED in - 1-second intervals (because the audio is buffered in 1-second chunks) If - the audio data is less than 1 second, the remainder is filled with silence. - - If you need to play sequences back-to-back that are less that 1 second long, - use the frame position to determine when to play the next sequence, instead - of SDL_CDStatus. - - This may be possible to fix with a clever usage of the AudioUnit API. - - 4. When new volumes are inserted, our volume information is not updated. The only way - to refresh this information is to reinit the CD-ROM subsystem of SDL. To fix this, - one would probably have to fix point 1 above first, then figure out how to register - for a notification when new media is mounted in order to perform an automatic - rescan for cdfs volumes. - - - - So, here comes a description of how this all works. - - < Initializing > - - To get things rolling, we have to locate mounted volumes that contain - audio (since nearly all Macs don't have analog audio-in on the sound card). - That's easy, since these volumes have a flag that indicates this special - filesystem. See DetectAudioCDVolumes() in CDPlayer.cpp for this code. - - Next, we parse the invisible .TOC.plist in the root of the volume, which gets us - the track information (number, offset, length, leadout, etc). See ReadTOCData() in - CDPlayer.cpp for the skinny on this. - - - < The Playback Loop > - - Now come the tricky parts. Let's start with basic audio playback. When a frame - range to play is requested, we must first find the .aiff files on the volume, - hopefully in the right order. Since these files all begin with a number "1 Audio Track", - etc, this is used to determine the correct track order. - - Once all files are determined, we have to find what file corresponds to the start - and length parameter to SDL_SYS_CDPlay(). Again, this is quite simple by walking the - cdrom's track list. At this point, we also save the offset to the next track and frames - remaining, if we're going to have to play another file after the first one. See - GetFileForOffset() for this code. - - At this point we have all info needed to start playback, so we hand off to the LoadFile() - function, which proceeds to do its magic and plays back the file. - - When the file is finished playing, CompletionProc() is invoked, at which time we can - play the next file if the previously saved next track and frames remaining - indicates that we should. - - - < Magic > - - OK, so it's not really magic, but since I don't fully understand all the hidden details it - seems like it to me ;-) The API's involved are the AudioUnit and AudioFile API's. These - appear to be an extension of CoreAudio for creating modular playback and f/x entities. - The important thing is that CPU usage is very low and reliability is very high. You'd - be hard-pressed to find a way to stutter the playback with other CPU-intensive tasks. - - One part of this magic is that it uses multiple threads, which carries the usual potential - for disaster if not handled carefully. Playback currently requires 4 additional threads: - 1. The coreaudio runloop thread - 2. The coreaudio device i/o thread - 3. The file streaming thread - 4. The notification/callback thread - - The first 2 threads are necessary evil - CoreAudio creates this no matter what the situation - is (even the SDL sound implementation creates theses suckers). The last two are are created - by us. - - The file is streamed from disk using a threaded double-buffer approach. - This way, the high latency operation of reading from disk can be performed without interrupting - the real-time device thread (which amounts to avoiding dropouts). The device thread grabs the - buffer that isn't being read and sends it to the CoreAudio mixer where it eventually gets - to the sound card. - - The device thread posts a notification when the file streaming thread is out of data. This - notification must be handled in a separate thread to avoid potential deadlock in the - device thread. That's where the notification thread comes in. This thread is signaled - whenever a notification needs to be processed, so another file can be played back if need be. - - The API in CDPlayer.cpp contains synchronization because otherwise both the notification thread - and main thread (or another other thread using the SDL CD api) can potentially call it at the same time. - -************************************************************************************/ - - -#include "SDL_cdrom.h" -#include "../SDL_syscdrom.h" - -#include "CDPlayer.h" - -#define kErrorFakeDevice "Error: Cannot proceed since we're faking a CD-ROM device. Reinit the CD-ROM subsystem to scan for new volumes." -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/cdrom/mint/SDL_syscdrom.c Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,339 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifdef SDL_CDROM_MINT - -/* - Atari MetaDOS CD-ROM functions - - Patrice Mandin -*/ - -#include <errno.h> - -#include <cdromio.h> -#include <metados.h> - -#include "SDL_cdrom.h" -#include "../SDL_syscdrom.h" - -/* Some ioctl() errno values which occur when the tray is empty */ -#ifndef ENOMEDIUM -#define ENOMEDIUM ENOENT -#endif -#define ERRNO_TRAYEMPTY(errno) \ - ((errno == EIO) || (errno == ENOENT) || \ - (errno == EINVAL) || (errno == ENOMEDIUM)) - -/* The maximum number of CD-ROM drives we'll detect */ -#define MAX_DRIVES 32 - -typedef struct -{ - unsigned char device[3]; /* Physical device letter + ':' + '\0' */ - metaopen_t metaopen; /* Infos on opened drive */ -} metados_drive_t; - -static metados_drive_t metados_drives[MAX_DRIVES]; - -/* The system-dependent CD control functions */ -static const char *SDL_SYS_CDName(int drive); -static int SDL_SYS_CDOpen(int drive); -static void SDL_SYS_CDClose(SDL_CD * cdrom); -static int SDL_SYS_CDioctl(int id, int command, void *arg); -static int SDL_SYS_CDGetTOC(SDL_CD * cdrom); -static CDstatus SDL_SYS_CDStatus(SDL_CD * cdrom, int *position); -static int SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length); -static int SDL_SYS_CDPause(SDL_CD * cdrom); -static int SDL_SYS_CDResume(SDL_CD * cdrom); -static int SDL_SYS_CDStop(SDL_CD * cdrom); -static int SDL_SYS_CDEject(SDL_CD * cdrom); - -int -SDL_SYS_CDInit(void) -{ - metainit_t metainit = { 0, 0, 0, 0 }; - metaopen_t metaopen; - int i, handle; - struct cdrom_subchnl info; - - Metainit(&metainit); - if (metainit.version == NULL) { -#ifdef DEBUG_CDROM - fprintf(stderr, "MetaDOS not installed\n"); -#endif - return -1; - } - - if (metainit.drives_map == 0) { -#ifdef DEBUG_CDROM - fprintf(stderr, "No MetaDOS devices present\n"); -#endif - return -1; - } - - SDL_numcds = 0; - - for (i = 'A'; i <= 'Z'; i++) { - metados_drives[SDL_numcds].device[0] = 0; - metados_drives[SDL_numcds].device[1] = ':'; - metados_drives[SDL_numcds].device[2] = 0; - - if (metainit.drives_map & (1 << (i - 'A'))) { - handle = Metaopen(i, &metaopen); - if (handle == 0) { - - info.cdsc_format = CDROM_MSF; - if ((Metaioctl - (i, METADOS_IOCTL_MAGIC, CDROMSUBCHNL, &info) == 0) - || ERRNO_TRAYEMPTY(errno)) { - metados_drives[SDL_numcds].device[0] = i; - ++SDL_numcds; - } - - Metaclose(i); - } - } - } - - /* Fill in our driver capabilities */ - SDL_CDcaps.Name = SDL_SYS_CDName; - SDL_CDcaps.Open = SDL_SYS_CDOpen; - SDL_CDcaps.Close = SDL_SYS_CDClose; - - SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; - SDL_CDcaps.Status = SDL_SYS_CDStatus; - SDL_CDcaps.Play = SDL_SYS_CDPlay; - SDL_CDcaps.Pause = SDL_SYS_CDPause; - SDL_CDcaps.Resume = SDL_SYS_CDResume; - SDL_CDcaps.Stop = SDL_SYS_CDStop; - SDL_CDcaps.Eject = SDL_SYS_CDEject; - - return 0; -} - -void -SDL_SYS_CDQuit(void) -{ - SDL_numcds = 0; -} - -static const char * -SDL_SYS_CDName(int drive) -{ - return (metados_drives[drive].device); -} - -static int -SDL_SYS_CDOpen(int drive) -{ - int handle; - - handle = - Metaopen(metados_drives[drive].device[0], - &(metados_drives[drive].metaopen)); - if (handle == 0) { - return drive; - } - - return -1; -} - -static void -SDL_SYS_CDClose(SDL_CD * cdrom) -{ - Metaclose(metados_drives[cdrom->id].device[0]); -} - -static int -SDL_SYS_CDioctl(int id, int command, void *arg) -{ - int retval; - - retval = - Metaioctl(metados_drives[id].device[0], METADOS_IOCTL_MAGIC, command, - arg); - if (retval < 0) { - SDL_SetError("ioctl() error: %s", strerror(errno)); - } - return (retval); -} - -static int -SDL_SYS_CDGetTOC(SDL_CD * cdrom) -{ - int i, okay; - struct cdrom_tochdr toc; - struct cdrom_tocentry entry; - - /* Use standard ioctl() */ - if (SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCHDR, &toc) < 0) { - return -1; - } - - cdrom->numtracks = toc.cdth_trk1 - toc.cdth_trk0 + 1; - if (cdrom->numtracks > SDL_MAX_TRACKS) { - cdrom->numtracks = SDL_MAX_TRACKS; - } - - /* Read all the track TOC entries */ - okay = 1; - for (i = 0; i <= cdrom->numtracks; ++i) { - if (i == cdrom->numtracks) { - cdrom->track[i].id = CDROM_LEADOUT; - } else { - cdrom->track[i].id = toc.cdth_trk0 + i; - } - entry.cdte_track = cdrom->track[i].id; - entry.cdte_format = CDROM_MSF; - if (SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCENTRY, &entry) < 0) { - okay = 0; - break; - } else { - if (entry.cdte_ctrl & CDROM_DATA_TRACK) { - cdrom->track[i].type = SDL_DATA_TRACK; - } else { - cdrom->track[i].type = SDL_AUDIO_TRACK; - } - cdrom->track[i].offset = - MSF_TO_FRAMES(entry.cdte_addr.msf.minute, - entry.cdte_addr.msf.second, - entry.cdte_addr.msf.frame); - cdrom->track[i].length = 0; - if (i > 0) { - cdrom->track[i - 1].length = - cdrom->track[i].offset - cdrom->track[i - 1].offset; - } - } - } - - return (okay ? 0 : -1); -} - -/* Get CD-ROM status */ -static CDstatus -SDL_SYS_CDStatus(SDL_CD * cdrom, int *position) -{ - CDstatus status; - struct cdrom_tochdr toc; - struct cdrom_subchnl info; - - info.cdsc_format = CDROM_MSF; - if (SDL_SYS_CDioctl(cdrom->id, CDROMSUBCHNL, &info) < 0) { - if (ERRNO_TRAYEMPTY(errno)) { - status = CD_TRAYEMPTY; - } else { - status = CD_ERROR; - } - } else { - switch (info.cdsc_audiostatus) { - case CDROM_AUDIO_INVALID: - case CDROM_AUDIO_NO_STATUS: - /* Try to determine if there's a CD available */ - if (SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCHDR, &toc) == 0) { - status = CD_STOPPED; - } else { - status = CD_TRAYEMPTY; - } - break; - case CDROM_AUDIO_COMPLETED: - status = CD_STOPPED; - break; - case CDROM_AUDIO_PLAY: - status = CD_PLAYING; - break; - case CDROM_AUDIO_PAUSED: - /* Workaround buggy CD-ROM drive */ - if (info.cdsc_trk == CDROM_LEADOUT) { - status = CD_STOPPED; - } else { - status = CD_PAUSED; - } - break; - default: - status = CD_ERROR; - break; - } - } - if (position) { - if (status == CD_PLAYING || (status == CD_PAUSED)) { - *position = MSF_TO_FRAMES(info.cdsc_absaddr.msf.minute, - info.cdsc_absaddr.msf.second, - info.cdsc_absaddr.msf.frame); - } else { - *position = 0; - } - } - return (status); -} - -/* Start play */ -static int -SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length) -{ - struct cdrom_msf playtime; - - FRAMES_TO_MSF(start, - &playtime.cdmsf_min0, &playtime.cdmsf_sec0, - &playtime.cdmsf_frame0); - FRAMES_TO_MSF(start + length, &playtime.cdmsf_min1, &playtime.cdmsf_sec1, - &playtime.cdmsf_frame1); -#ifdef DEBUG_CDROM - fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", - playtime.cdmsf_min0, playtime.cdmsf_sec0, playtime.cdmsf_frame0, - playtime.cdmsf_min1, playtime.cdmsf_sec1, playtime.cdmsf_frame1); -#endif - - return SDL_SYS_CDioctl(cdrom->id, CDROMPLAYMSF, &playtime); -} - -/* Pause play */ -static int -SDL_SYS_CDPause(SDL_CD * cdrom) -{ - return SDL_SYS_CDioctl(cdrom->id, CDROMPAUSE, 0); -} - -/* Resume play */ -static int -SDL_SYS_CDResume(SDL_CD * cdrom) -{ - return SDL_SYS_CDioctl(cdrom->id, CDROMRESUME, 0); -} - -/* Stop play */ -static int -SDL_SYS_CDStop(SDL_CD * cdrom) -{ - return SDL_SYS_CDioctl(cdrom->id, CDROMSTOP, 0); -} - -/* Eject the CD-ROM */ -static int -SDL_SYS_CDEject(SDL_CD * cdrom) -{ - return SDL_SYS_CDioctl(cdrom->id, CDROMEJECT, 0); -} - -#endif /* SDL_CDROM_MINT */ -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/cdrom/openbsd/SDL_syscdrom.c Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,430 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifdef SDL_CDROM_OPENBSD - -/* Functions for system-level CD-ROM audio control */ - -#include <sys/types.h> -#include <sys/ioctl.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <sys/cdio.h> - -#include "SDL_cdrom.h" -#include "../SDL_syscdrom.h" - - -/* The maximum number of CD-ROM drives we'll detect */ -#define MAX_DRIVES 16 - -/* A list of available CD-ROM drives */ -static char *SDL_cdlist[MAX_DRIVES]; -static dev_t SDL_cdmode[MAX_DRIVES]; - -/* The system-dependent CD control functions */ -static const char *SDL_SYS_CDName(int drive); -static int SDL_SYS_CDOpen(int drive); -static int SDL_SYS_CDGetTOC(SDL_CD * cdrom); -static CDstatus SDL_SYS_CDStatus(SDL_CD * cdrom, int *position); -static int SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length); -static int SDL_SYS_CDPause(SDL_CD * cdrom); -static int SDL_SYS_CDResume(SDL_CD * cdrom); -static int SDL_SYS_CDStop(SDL_CD * cdrom); -static int SDL_SYS_CDEject(SDL_CD * cdrom); -static void SDL_SYS_CDClose(SDL_CD * cdrom); - -/* Some ioctl() errno values which occur when the tray is empty */ -#define ERRNO_TRAYEMPTY(errno) \ - ((errno == EIO) || (errno == ENOENT) || (errno == EINVAL) || \ - (errno == ENODEV)) - -/* Check a drive to see if it is a CD-ROM */ -static int -CheckDrive(char *drive, struct stat *stbuf) -{ - int is_cd, cdfd; - struct ioc_read_subchannel info; - - /* If it doesn't exist, return -1 */ - if (stat(drive, stbuf) < 0) { - return (-1); - } - - /* If it does exist, verify that it's an available CD-ROM */ - is_cd = 0; - if (S_ISCHR(stbuf->st_mode) || S_ISBLK(stbuf->st_mode)) { - cdfd = open(drive, (O_RDONLY | O_EXCL | O_NONBLOCK), 0); - if (cdfd >= 0) { - info.address_format = CD_MSF_FORMAT; - info.data_format = CD_CURRENT_POSITION; - info.data_len = 0; - info.data = NULL; - /* Under Linux, EIO occurs when a disk is not present. - This isn't 100% reliable, so we use the USE_MNTENT - code above instead. - */ - if ((ioctl(cdfd, CDIOCREADSUBCHANNEL, &info) == 0) || - ERRNO_TRAYEMPTY(errno)) { - is_cd = 1; - } - close(cdfd); - } else if (ERRNO_TRAYEMPTY(errno)) - is_cd = 1; - } - return (is_cd); -} - -/* Add a CD-ROM drive to our list of valid drives */ -static void -AddDrive(char *drive, struct stat *stbuf) -{ - int i; - - if (SDL_numcds < MAX_DRIVES) { - /* Check to make sure it's not already in our list. - This can happen when we see a drive via symbolic link. - */ - for (i = 0; i < SDL_numcds; ++i) { - if (stbuf->st_rdev == SDL_cdmode[i]) { -#ifdef DEBUG_CDROM - fprintf(stderr, "Duplicate drive detected: %s == %s\n", - drive, SDL_cdlist[i]); -#endif - return; - } - } - - /* Add this drive to our list */ - i = SDL_numcds; - SDL_cdlist[i] = SDL_strdup(drive); - if (SDL_cdlist[i] == NULL) { - SDL_OutOfMemory(); - return; - } - SDL_cdmode[i] = stbuf->st_rdev; - ++SDL_numcds; -#ifdef DEBUG_CDROM - fprintf(stderr, "Added CD-ROM drive: %s\n", drive); -#endif - } -} - -int -SDL_SYS_CDInit(void) -{ - static char *checklist[] = { -#if defined(__OPENBSD__) - "?0 cd?c", "cdrom", NULL -#elif defined(__NETBSD__) - "?0 cd?d", "?0 cd?c", "cdrom", NULL -#else - "?0 cd?c", "?0 acd?c", "cdrom", NULL -#endif - }; - char *SDLcdrom; - int i, j, exists; - char drive[32]; - struct stat stbuf; - - /* Fill in our driver capabilities */ - SDL_CDcaps.Name = SDL_SYS_CDName; - SDL_CDcaps.Open = SDL_SYS_CDOpen; - SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; - SDL_CDcaps.Status = SDL_SYS_CDStatus; - SDL_CDcaps.Play = SDL_SYS_CDPlay; - SDL_CDcaps.Pause = SDL_SYS_CDPause; - SDL_CDcaps.Resume = SDL_SYS_CDResume; - SDL_CDcaps.Stop = SDL_SYS_CDStop; - SDL_CDcaps.Eject = SDL_SYS_CDEject; - SDL_CDcaps.Close = SDL_SYS_CDClose; - - /* Look in the environment for our CD-ROM drive list */ - SDLcdrom = SDL_getenv("SDL_CDROM"); /* ':' separated list of devices */ - if (SDLcdrom != NULL) { - char *cdpath, *delim; - size_t len = SDL_strlen(SDLcdrom) + 1; - cdpath = SDL_stack_alloc(char, len); - if (cdpath != NULL) { - SDL_strlcpy(cdpath, SDLcdrom, len); - SDLcdrom = cdpath; - do { - delim = SDL_strchr(SDLcdrom, ':'); - if (delim) { - *delim++ = '\0'; - } - if (CheckDrive(SDLcdrom, &stbuf) > 0) { - AddDrive(SDLcdrom, &stbuf); - } - if (delim) { - SDLcdrom = delim; - } else { - SDLcdrom = NULL; - } - } while (SDLcdrom); - SDL_stack_free(cdpath); - } - - /* If we found our drives, there's nothing left to do */ - if (SDL_numcds > 0) { - return (0); - } - } - - /* Scan the system for CD-ROM drives */ - for (i = 0; checklist[i]; ++i) { - if (checklist[i][0] == '?') { - char *insert; - exists = 1; - for (j = checklist[i][1]; exists; ++j) { - SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%s", - &checklist[i][3]); - insert = SDL_strchr(drive, '?'); - if (insert != NULL) { - *insert = j; - } - switch (CheckDrive(drive, &stbuf)) { - /* Drive exists and is a CD-ROM */ - case 1: - AddDrive(drive, &stbuf); - break; - /* Drive exists, but isn't a CD-ROM */ - case 0: - break; - /* Drive doesn't exist */ - case -1: - exists = 0; - break; - } - } - } else { - SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%s", - checklist[i]); - if (CheckDrive(drive, &stbuf) > 0) { - AddDrive(drive, &stbuf); - } - } - } - return (0); -} - -/* General ioctl() CD-ROM command function */ -static int -SDL_SYS_CDioctl(int id, int command, void *arg) -{ - int retval; - - retval = ioctl(id, command, arg); - if (retval < 0) { - SDL_SetError("ioctl() error: %s", strerror(errno)); - } - return (retval); -} - -static const char * -SDL_SYS_CDName(int drive) -{ - return (SDL_cdlist[drive]); -} - -static int -SDL_SYS_CDOpen(int drive) -{ - return (open(SDL_cdlist[drive], (O_RDONLY | O_EXCL | O_NONBLOCK), 0)); -} - -static int -SDL_SYS_CDGetTOC(SDL_CD * cdrom) -{ - struct ioc_toc_header toc; - int i, okay; - struct ioc_read_toc_entry entry; - struct cd_toc_entry data; - - okay = 0; - if (SDL_SYS_CDioctl(cdrom->id, CDIOREADTOCHEADER, &toc) == 0) { - cdrom->numtracks = toc.ending_track - toc.starting_track + 1; - if (cdrom->numtracks > SDL_MAX_TRACKS) { - cdrom->numtracks = SDL_MAX_TRACKS; - } - /* Read all the track TOC entries */ - for (i = 0; i <= cdrom->numtracks; ++i) { - if (i == cdrom->numtracks) { - cdrom->track[i].id = 0xAA; /* CDROM_LEADOUT */ - } else { - cdrom->track[i].id = toc.starting_track + i; - } - entry.starting_track = cdrom->track[i].id; - entry.address_format = CD_MSF_FORMAT; - entry.data_len = sizeof(data); - entry.data = &data; - if (SDL_SYS_CDioctl(cdrom->id, CDIOREADTOCENTRYS, &entry) < 0) { - break; - } else { - cdrom->track[i].type = data.control; - cdrom->track[i].offset = - MSF_TO_FRAMES(data.addr.msf.minute, - data.addr.msf.second, data.addr.msf.frame); - cdrom->track[i].length = 0; - if (i > 0) { - cdrom->track[i - 1].length = - cdrom->track[i].offset - cdrom->track[i - 1].offset; - } - } - } - if (i == (cdrom->numtracks + 1)) { - okay = 1; - } - } - return (okay ? 0 : -1); -} - -/* Get CD-ROM status */ -static CDstatus -SDL_SYS_CDStatus(SDL_CD * cdrom, int *position) -{ - CDstatus status; - struct ioc_toc_header toc; - struct ioc_read_subchannel info; - struct cd_sub_channel_info data; - - info.address_format = CD_MSF_FORMAT; - info.data_format = CD_CURRENT_POSITION; - info.track = 0; - info.data_len = sizeof(data); - info.data = &data; - if (ioctl(cdrom->id, CDIOCREADSUBCHANNEL, &info) < 0) { - if (ERRNO_TRAYEMPTY(errno)) { - status = CD_TRAYEMPTY; - } else { - status = CD_ERROR; - } - } else { - switch (data.header.audio_status) { - case CD_AS_AUDIO_INVALID: - case CD_AS_NO_STATUS: - /* Try to determine if there's a CD available */ - if (ioctl(cdrom->id, CDIOREADTOCHEADER, &toc) == 0) - status = CD_STOPPED; - else - status = CD_TRAYEMPTY; - break; - case CD_AS_PLAY_COMPLETED: - status = CD_STOPPED; - break; - case CD_AS_PLAY_IN_PROGRESS: - status = CD_PLAYING; - break; - case CD_AS_PLAY_PAUSED: - status = CD_PAUSED; - break; - default: - status = CD_ERROR; - break; - } - } - if (position) { - if (status == CD_PLAYING || (status == CD_PAUSED)) { - *position = - MSF_TO_FRAMES(data.what.position.absaddr.msf.minute, - data.what.position.absaddr.msf.second, - data.what.position.absaddr.msf.frame); - } else { - *position = 0; - } - } - return (status); -} - -/* Start play */ -static int -SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length) -{ - struct ioc_play_msf playtime; - - FRAMES_TO_MSF(start, - &playtime.start_m, &playtime.start_s, &playtime.start_f); - FRAMES_TO_MSF(start + length, - &playtime.end_m, &playtime.end_s, &playtime.end_f); -#ifdef DEBUG_CDROM - fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", - playtime.start_m, playtime.start_s, playtime.start_f, - playtime.end_m, playtime.end_s, playtime.end_f); -#endif - ioctl(cdrom->id, CDIOCSTART, 0); - return (SDL_SYS_CDioctl(cdrom->id, CDIOCPLAYMSF, &playtime)); -} - -/* Pause play */ -static int -SDL_SYS_CDPause(SDL_CD * cdrom) -{ - return (SDL_SYS_CDioctl(cdrom->id, CDIOCPAUSE, 0)); -} - -/* Resume play */ -static int -SDL_SYS_CDResume(SDL_CD * cdrom) -{ - return (SDL_SYS_CDioctl(cdrom->id, CDIOCRESUME, 0)); -} - -/* Stop play */ -static int -SDL_SYS_CDStop(SDL_CD * cdrom) -{ - return (SDL_SYS_CDioctl(cdrom->id, CDIOCSTOP, 0)); -} - -/* Eject the CD-ROM */ -static int -SDL_SYS_CDEject(SDL_CD * cdrom) -{ - return (SDL_SYS_CDioctl(cdrom->id, CDIOCEJECT, 0)); -} - -/* Close the CD-ROM handle */ -static void -SDL_SYS_CDClose(SDL_CD * cdrom) -{ - close(cdrom->id); -} - -void -SDL_SYS_CDQuit(void) -{ - int i; - - if (SDL_numcds > 0) { - for (i = 0; i < SDL_numcds; ++i) { - SDL_free(SDL_cdlist[i]); - } - SDL_numcds = 0; - } -} - -#endif /* SDL_CDROM_OPENBSD */ -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/cdrom/os2/SDL_syscdrom.c Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,442 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifdef SDL_CDROM_OS2 - -/* Functions for system-level CD-ROM audio control */ - -#define INCL_MCIOS2 -#include <os2.h> -#include <os2me.h> - -#include "SDL_cdrom.h" -#include "../SDL_syscdrom.h" - -/* Size of MCI result buffer (in bytes) */ -#define MCI_CMDRETBUFSIZE 128 - -/* The maximum number of CD-ROM drives we'll detect */ -#define MAX_DRIVES 16 - -/* A list of available CD-ROM drives */ -static char *SDL_cdlist[MAX_DRIVES]; -//static dev_t SDL_cdmode[MAX_DRIVES]; - -/* The system-dependent CD control functions */ -static const char *SDL_SYS_CDName(int drive); -static int SDL_SYS_CDOpen(int drive); -static int SDL_SYS_CDGetTOC(SDL_CD * cdrom); -static CDstatus SDL_SYS_CDStatus(SDL_CD * cdrom, int *position); -static int SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length); -static int SDL_SYS_CDPause(SDL_CD * cdrom); -static int SDL_SYS_CDResume(SDL_CD * cdrom); -static int SDL_SYS_CDStop(SDL_CD * cdrom); -static int SDL_SYS_CDEject(SDL_CD * cdrom); -static void SDL_SYS_CDClose(SDL_CD * cdrom); - -/* MCI Timing Functions */ -#define MCI_MMTIMEPERSECOND 3000 -#define FRAMESFROMMM(mmtime) (((mmtime)*CD_FPS)/MCI_MMTIMEPERSECOND) - - -/* Ready for MCI CDAudio Devices */ -int -SDL_SYS_CDInit(void) -{ - int i; /* generig counter */ - MCI_SYSINFO_PARMS msp; /* Structure to MCI SysInfo parameters */ - CHAR SysInfoRet[MCI_CMDRETBUFSIZE]; /* Buffer for MCI Command result */ - -/* Fill in our driver capabilities */ - SDL_CDcaps.Name = SDL_SYS_CDName; - SDL_CDcaps.Open = SDL_SYS_CDOpen; - SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; - SDL_CDcaps.Status = SDL_SYS_CDStatus; - SDL_CDcaps.Play = SDL_SYS_CDPlay; - SDL_CDcaps.Pause = SDL_SYS_CDPause; - SDL_CDcaps.Resume = SDL_SYS_CDResume; - SDL_CDcaps.Stop = SDL_SYS_CDStop; - SDL_CDcaps.Eject = SDL_SYS_CDEject; - SDL_CDcaps.Close = SDL_SYS_CDClose; - -/* Get the number of CD ROMs in the System */ -/* Clean SysInfo structure */ - SDL_memset(&msp, 0x00, sizeof(MCI_SYSINFO_PARMS)); -/* Prepare structure to Ask Numer of Audio CDs */ - msp.usDeviceType = MCI_DEVTYPE_CD_AUDIO; /* CD Audio Type */ - msp.pszReturn = (PSZ) & SysInfoRet; /* Return Structure */ - msp.ulRetSize = MCI_CMDRETBUFSIZE; /* Size of ret struct */ - if (LOUSHORT - (mciSendCommand - (0, MCI_SYSINFO, MCI_SYSINFO_QUANTITY | MCI_WAIT, (PVOID) & msp, - 0)) != MCIERR_SUCCESS) - return (CD_ERROR); - SDL_numcds = atoi(SysInfoRet); - if (SDL_numcds > MAX_DRIVES) - SDL_numcds = MAX_DRIVES; /* Limit maximum CD number */ - -/* Get and Add their system name to the SDL_cdlist */ - msp.pszReturn = (PSZ) & SysInfoRet; /* Return Structure */ - msp.ulRetSize = MCI_CMDRETBUFSIZE; /* Size of ret struct */ - msp.usDeviceType = MCI_DEVTYPE_CD_AUDIO; /* CD Audio Type */ - for (i = 0; i < SDL_numcds; i++) { - msp.ulNumber = i + 1; - mciSendCommand(0, MCI_SYSINFO, MCI_SYSINFO_NAME | MCI_WAIT, &msp, 0); - SDL_cdlist[i] = SDL_strdup(SysInfoRet); - if (SDL_cdlist[i] == NULL) { - SDL_OutOfMemory(); - return (-1); - } - } - return (0); -} - -/* Return CDAudio System Dependent Device Name - Ready for MCI*/ -static const char * -SDL_SYS_CDName(int drive) -{ - return (SDL_cdlist[drive]); -} - -/* Open CDAudio Device - Ready for MCI */ -static int -SDL_SYS_CDOpen(int drive) -{ - MCI_OPEN_PARMS mop; - MCI_SET_PARMS msp; - MCI_GENERIC_PARMS mgp; - -/* Open the device */ - mop.hwndCallback = (HWND) NULL; // None - mop.usDeviceID = (USHORT) NULL; // Will be returned. - mop.pszDeviceType = (PSZ) SDL_cdlist[drive]; // CDAudio Device - if (LOUSHORT(mciSendCommand(0, MCI_OPEN, MCI_WAIT, &mop, 0)) != - MCIERR_SUCCESS) - return (CD_ERROR); -/* Set time format */ - msp.hwndCallback = (HWND) NULL; // None - msp.ulTimeFormat = MCI_FORMAT_MSF; // Minute : Second : Frame structure - msp.ulSpeedFormat = (ULONG) NULL; // No change - msp.ulAudio = (ULONG) NULL; // No Channel - msp.ulLevel = (ULONG) NULL; // No Volume - msp.ulOver = (ULONG) NULL; // No Delay - msp.ulItem = (ULONG) NULL; // No item - msp.ulValue = (ULONG) NULL; // No value for item flag - if (LOUSHORT - (mciSendCommand - (mop.usDeviceID, MCI_SET, MCI_WAIT | MCI_SET_TIME_FORMAT, &msp, - 0)) == MCIERR_SUCCESS) - return (mop.usDeviceID); -/* Error setting time format? - Close opened device */ - mgp.hwndCallback = (HWND) NULL; // None - mciSendCommand(mop.usDeviceID, MCI_CLOSE, MCI_WAIT, &mgp, 0); - return (CD_ERROR); -} - -/* Get CD Table Of Contents - Ready for MCI */ -static int -SDL_SYS_CDGetTOC(SDL_CD * cdrom) -{ - MCI_TOC_PARMS mtp; - MCI_STATUS_PARMS msp; - MCI_TOC_REC *mtr; - INT i; - -/* Correction because MCI cannot read TOC while CD is playing (it'll stop!) */ - if (cdrom->status == CD_PLAYING || cdrom->status == CD_PAUSED) - return 0; - -/* Get Number of Tracks */ - msp.hwndCallback = (HWND) NULL; /* None */ - msp.ulReturn = (ULONG) NULL; /* We want this information */ - msp.ulItem = MCI_STATUS_NUMBER_OF_TRACKS; - msp.ulValue = (ULONG) NULL; /* No additional information */ - if (LOUSHORT - (mciSendCommand - (cdrom->id, MCI_STATUS, MCI_WAIT | MCI_STATUS_ITEM, &msp, - 0)) != MCIERR_SUCCESS) - return (CD_ERROR); - cdrom->numtracks = msp.ulReturn; - if (cdrom->numtracks > SDL_MAX_TRACKS) { - cdrom->numtracks = SDL_MAX_TRACKS; - } -/* Alocate space for TOC data */ - mtr = (MCI_TOC_REC *) SDL_malloc(cdrom->numtracks * sizeof(MCI_TOC_REC)); - if (mtr == NULL) { - SDL_OutOfMemory(); - return (-1); - } -/* Get TOC from CD */ - mtp.pBuf = mtr; - mtp.ulBufSize = cdrom->numtracks * sizeof(MCI_TOC_REC); - if (LOUSHORT(mciSendCommand(cdrom->id, MCI_GETTOC, MCI_WAIT, &mtp, 0)) - != MCIERR_SUCCESS) { - SDL_OutOfMemory(); - SDL_free(mtr); - return (CD_ERROR); - } -/* Fill SDL Tracks Structure */ - for (i = 0; i < cdrom->numtracks; i++) { - /* Set Track ID */ - cdrom->track[i].id = (mtr + i)->TrackNum; - /* Set Track Type */ - msp.hwndCallback = (HWND) NULL; /* None */ - msp.ulReturn = (ULONG) NULL; /* We want this information */ - msp.ulItem = MCI_CD_STATUS_TRACK_TYPE; - msp.ulValue = (ULONG) ((mtr + i)->TrackNum); /* Track Number? */ - if (LOUSHORT - (mciSendCommand - (cdrom->id, MCI_STATUS, MCI_WAIT | MCI_TRACK | MCI_STATUS_ITEM, - &msp, 0)) != MCIERR_SUCCESS) { - SDL_free(mtr); - return (CD_ERROR); - } - if (msp.ulReturn == MCI_CD_TRACK_AUDIO) - cdrom->track[i].type = SDL_AUDIO_TRACK; - else - cdrom->track[i].type = SDL_DATA_TRACK; - /* Set Track Length - values from MCI are in MMTIMEs - 3000 MMTIME = 1 second */ - cdrom->track[i].length = - FRAMESFROMMM((mtr + i)->ulEndAddr - (mtr + i)->ulStartAddr); - /* Set Track Offset */ - cdrom->track[i].offset = FRAMESFROMMM((mtr + i)->ulStartAddr); - } - SDL_free(mtr); - return (0); -} - - -/* Get CD-ROM status - Ready for MCI */ -static CDstatus -SDL_SYS_CDStatus(SDL_CD * cdrom, int *position) -{ - CDstatus status; - MCI_STATUS_PARMS msp; - -/* Get Status from MCI */ - msp.hwndCallback = (HWND) NULL; /* None */ - msp.ulReturn = (ULONG) NULL; /* We want this information */ - msp.ulItem = MCI_STATUS_MODE; - msp.ulValue = (ULONG) NULL; /* No additional information */ - if (LOUSHORT - (mciSendCommand - (cdrom->id, MCI_STATUS, MCI_WAIT | MCI_STATUS_ITEM, &msp, - 0)) != MCIERR_SUCCESS) - status = CD_ERROR; - else { - switch (msp.ulReturn) { - case MCI_MODE_NOT_READY: - status = CD_TRAYEMPTY; - break; - case MCI_MODE_PAUSE: - status = CD_PAUSED; - break; - case MCI_MODE_PLAY: - status = CD_PLAYING; - break; - case MCI_MODE_STOP: - status = CD_STOPPED; - break; - /* These cases should not occour */ - case MCI_MODE_RECORD: - case MCI_MODE_SEEK: - default: - status = CD_ERROR; - break; - } - } - -/* Determine position */ - if (position != NULL) { /* The SDL $&$&%# CDROM call sends NULL pointer here! */ - if ((status == CD_PLAYING) || (status == CD_PAUSED)) { - /* Get Position */ - msp.hwndCallback = (HWND) NULL; /* None */ - msp.ulReturn = (ULONG) NULL; /* We want this information */ - msp.ulItem = MCI_STATUS_POSITION; - msp.ulValue = (ULONG) NULL; /* No additiona info */ - if (LOUSHORT - (mciSendCommand - (cdrom->id, MCI_STATUS, MCI_WAIT | MCI_STATUS_ITEM, &msp, - 0)) != MCIERR_SUCCESS) - return (CD_ERROR); - /* Convert from MSF (format selected in the Open process) to Frames (format that will be returned) */ - *position = - MSF_TO_FRAMES(MSF_MINUTE(msp.ulReturn), - MSF_SECOND(msp.ulReturn), - MSF_FRAME(msp.ulReturn)); - } else - *position = 0; - } - return (status); -} - -/* Start play - Ready for MCI */ -static int -SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length) -{ - MCI_GENERIC_PARMS mgp; - MCI_STATUS_PARMS msp; - MCI_PLAY_PARMS mpp; - ULONG min, sec, frm; - -/* Start MSF */ - FRAMES_TO_MSF(start, &min, &sec, &frm); - MSF_MINUTE(mpp.ulFrom) = min; - MSF_SECOND(mpp.ulFrom) = sec; - MSF_FRAME(mpp.ulFrom) = frm; -/* End MSF */ - FRAMES_TO_MSF(start + length, &min, &sec, &frm); - MSF_MINUTE(mpp.ulTo) = min; - MSF_SECOND(mpp.ulTo) = sec; - MSF_FRAME(mpp.ulTo) = frm; -#ifdef DEBUG_CDROM - fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", - playtime.cdmsf_min0, playtime.cdmsf_sec0, playtime.cdmsf_frame0, - playtime.cdmsf_min1, playtime.cdmsf_sec1, playtime.cdmsf_frame1); -#endif -/* Verifies if it is paused first... and if it is, unpause before stopping it. */ - msp.hwndCallback = (HWND) NULL; /* None */ - msp.ulReturn = (ULONG) NULL; /* We want this information */ - msp.ulItem = MCI_STATUS_MODE; - msp.ulValue = (ULONG) NULL; /* No additional information */ - if (LOUSHORT - (mciSendCommand - (cdrom->id, MCI_STATUS, MCI_WAIT | MCI_STATUS_ITEM, &msp, - 0)) == MCIERR_SUCCESS) { - if (msp.ulReturn == MCI_MODE_PAUSE) { - mgp.hwndCallback = (HWND) NULL; // None - mciSendCommand(cdrom->id, MCI_RESUME, 0, &mgp, 0); - } - } -/* Now play it. */ - mpp.hwndCallback = (HWND) NULL; // We do not want the info. temp - if (LOUSHORT - (mciSendCommand(cdrom->id, MCI_PLAY, MCI_FROM | MCI_TO, &mpp, 0)) == - MCIERR_SUCCESS) - return 0; - return (CD_ERROR); -} - -/* Pause play - Ready for MCI */ -static int -SDL_SYS_CDPause(SDL_CD * cdrom) -{ - MCI_GENERIC_PARMS mgp; - - mgp.hwndCallback = (HWND) NULL; // None - if (LOUSHORT(mciSendCommand(cdrom->id, MCI_PAUSE, MCI_WAIT, &mgp, 0)) == - MCIERR_SUCCESS) - return 0; - return (CD_ERROR); -} - -/* Resume play - Ready for MCI */ -static int -SDL_SYS_CDResume(SDL_CD * cdrom) -{ - MCI_GENERIC_PARMS mgp; - - mgp.hwndCallback = (HWND) NULL; // None - if (LOUSHORT(mciSendCommand(cdrom->id, MCI_RESUME, MCI_WAIT, &mgp, 0)) - == MCIERR_SUCCESS) - return 0; - return (CD_ERROR); -} - -/* Stop play - Ready for MCI */ -static int -SDL_SYS_CDStop(SDL_CD * cdrom) -{ - MCI_GENERIC_PARMS mgp; - MCI_STATUS_PARMS msp; - -/* Verifies if it is paused first... and if it is, unpause before stopping it. */ - msp.hwndCallback = (HWND) NULL; /* None */ - msp.ulReturn = (ULONG) NULL; /* We want this information */ - msp.ulItem = MCI_STATUS_MODE; - msp.ulValue = (ULONG) NULL; /* No additional information */ - if (LOUSHORT - (mciSendCommand - (cdrom->id, MCI_STATUS, MCI_WAIT | MCI_STATUS_ITEM, &msp, - 0)) == MCIERR_SUCCESS) { - if (msp.ulReturn == MCI_MODE_PAUSE) { - mgp.hwndCallback = (HWND) NULL; // None - mciSendCommand(cdrom->id, MCI_RESUME, 0, &mgp, 0); - } - } -/* Now stops the media */ - mgp.hwndCallback = (HWND) NULL; // None - if (LOUSHORT(mciSendCommand(cdrom->id, MCI_STOP, MCI_WAIT, &mgp, 0)) == - MCIERR_SUCCESS) - return 0; - return (CD_ERROR); -} - -/* Eject the CD-ROM - Ready for MCI */ -static int -SDL_SYS_CDEject(SDL_CD * cdrom) -{ - MCI_SET_PARMS msp; - - msp.hwndCallback = (HWND) NULL; // None - msp.ulTimeFormat = (ULONG) NULL; // No change - msp.ulSpeedFormat = (ULONG) NULL; // No change - msp.ulAudio = (ULONG) NULL; // No Channel - msp.ulLevel = (ULONG) NULL; // No Volume - msp.ulOver = (ULONG) NULL; // No Delay - msp.ulItem = (ULONG) NULL; // No item - msp.ulValue = (ULONG) NULL; // No value for item flag - if (LOUSHORT - (mciSendCommand - (cdrom->id, MCI_SET, MCI_WAIT | MCI_SET_DOOR_OPEN, &msp, - 0)) == MCIERR_SUCCESS) - return 0; - return (CD_ERROR); -} - -/* Close the CD-ROM handle - Ready for MCI */ -static void -SDL_SYS_CDClose(SDL_CD * cdrom) -{ - MCI_GENERIC_PARMS mgp; - - mgp.hwndCallback = (HWND) NULL; // None - mciSendCommand(cdrom->id, MCI_CLOSE, MCI_WAIT, &mgp, 0); -} - -/* Finalize CDROM Subsystem - Ready for MCI */ -void -SDL_SYS_CDQuit(void) -{ - int i; - - if (SDL_numcds > 0) { - for (i = 0; i < SDL_numcds; ++i) { - SDL_free(SDL_cdlist[i]); - } - SDL_numcds = 0; - } -} - -#endif /* SDL_CDROM_OS2 */ -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/cdrom/osf/SDL_syscdrom.c Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,464 +0,0 @@ -/* - Tru64 audio module for SDL (Simple DirectMedia Layer) - Copyright (C) 2003 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -*/ -#include "SDL_config.h" - -#ifdef SDL_CDROM_OSF - -/* Functions for system-level CD-ROM audio control */ - -/* #define DEBUG_CDROM 1 */ - -#include <sys/types.h> -#include <dirent.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <io/cam/cdrom.h> -#include <io/cam/rzdisk.h> -#include <io/common/devgetinfo.h> - -#include "SDL_cdrom.h" -#include "../SDL_syscdrom.h" - -/* The maximum number of CD-ROM drives we'll detect */ -#define MAX_DRIVES 16 - -/* A list of available CD-ROM drives */ -static char *SDL_cdlist[MAX_DRIVES]; -static dev_t SDL_cdmode[MAX_DRIVES]; - -/* The system-dependent CD control functions */ -static const char *SDL_SYS_CDName(int drive); -static int SDL_SYS_CDOpen(int drive); -static int SDL_SYS_CDGetTOC(SDL_CD * cdrom); -static CDstatus SDL_SYS_CDStatus(SDL_CD * cdrom, int *position); -static int SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length); -static int SDL_SYS_CDPause(SDL_CD * cdrom); -static int SDL_SYS_CDResume(SDL_CD * cdrom); -static int SDL_SYS_CDStop(SDL_CD * cdrom); -static int SDL_SYS_CDEject(SDL_CD * cdrom); -static void SDL_SYS_CDClose(SDL_CD * cdrom); - -/* Check a drive to see if it is a CD-ROM */ -/* Caution!! Not tested. */ -static int -CheckDrive(char *drive, struct stat *stbuf) -{ - int cdfd, is_cd = 0; - struct mode_sel_sns_params msp; - struct inquiry_info inq; - -#ifdef DEBUG_CDROM - char *devtype[] = { "Disk", "Tape", "Printer", "Processor", "WORM", - "CD-ROM", "Scanner", "Optical", "Changer", "Comm", "Unknown" - }; -#endif - - bzero(&msp, sizeof(msp)); - bzero(&inq, sizeof(inq)); - - /* If it doesn't exist, return -1 */ - if (stat(drive, stbuf) < 0) { - return (-1); - } - - if ((cdfd = open(drive, (O_RDWR | O_NDELAY), 0)) >= 0) { - msp.msp_addr = (caddr_t) & inq; - msp.msp_pgcode = 0; - msp.msp_pgctrl = 0; - msp.msp_length = sizeof(inq); - msp.msp_setps = 0; - - if (ioctl(cdfd, SCSI_GET_INQUIRY_DATA, &msp)) - return (0); - -#ifdef DEBUG_CDROM - fprintf(stderr, "Device Type: %s\n", devtype[inq.perfdt]); - fprintf(stderr, "Vendor: %.8s\n", inq.vndrid); - fprintf(stderr, "Product: %.8s\n", inq.prodid); - fprintf(stderr, "Revision: %.8s\n", inq.revlvl); -#endif - if (inq.perfdt == DTYPE_RODIRECT) - is_cd = 1; - } - - return (is_cd); -} - -/* Add a CD-ROM drive to our list of valid drives */ -static void -AddDrive(char *drive, struct stat *stbuf) -{ - int i; - - if (SDL_numcds < MAX_DRIVES) { - /* Check to make sure it's not already in our list. - * This can happen when we see a drive via symbolic link. - * - */ - for (i = 0; i < SDL_numcds; ++i) { - if (stbuf->st_rdev == SDL_cdmode[i]) { -#ifdef DEBUG_CDROM - fprintf(stderr, "Duplicate drive detected: %s == %s\n", - drive, SDL_cdlist[i]); -#endif - return; - } - } - - /* Add this drive to our list */ - i = SDL_numcds; - SDL_cdlist[i] = SDL_strdup(drive); - if (SDL_cdlist[i] == NULL) { - SDL_OutOfMemory(); - return; - } - SDL_cdmode[i] = stbuf->st_rdev; - ++SDL_numcds; -#ifdef DEBUG_CDROM - fprintf(stderr, "Added CD-ROM drive: %s\n", drive); -#endif - } -} - -int -SDL_SYS_CDInit(void) -{ - /* checklist: - * - * Tru64 5.X (/dev/rdisk/cdrom?c) - * dir: /dev/rdisk, name: cdrom - * - * Digital UNIX 4.0X (/dev/rrz?c) - * dir: /dev, name: rrz - * - */ - struct - { - char *dir; - char *name; - } checklist[] = { - { - "/dev/rdisk", "cdrom"}, { - "/dev", "rrz"}, { - NULL, NULL}}; - char drive[32]; - char *SDLcdrom; - int i, j, exists; - struct stat stbuf; - - /* Fill in our driver capabilities */ - SDL_CDcaps.Name = SDL_SYS_CDName; - SDL_CDcaps.Open = SDL_SYS_CDOpen; - SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; - SDL_CDcaps.Status = SDL_SYS_CDStatus; - SDL_CDcaps.Play = SDL_SYS_CDPlay; - SDL_CDcaps.Pause = SDL_SYS_CDPause; - SDL_CDcaps.Resume = SDL_SYS_CDResume; - SDL_CDcaps.Stop = SDL_SYS_CDStop; - SDL_CDcaps.Eject = SDL_SYS_CDEject; - SDL_CDcaps.Close = SDL_SYS_CDClose; - - - /* Look in the environment for our CD-ROM drive list */ - SDLcdrom = SDL_getenv("SDL_CDROM"); /* ':' separated list of devices */ - if (SDLcdrom != NULL) { - char *cdpath, *delim; - size_t len = SDL_strlen(SDLcdrom) + 1; - cdpath = SDL_stack_alloc(char, len); - if (cdpath != NULL) { - SDL_strlcpy(cdpath, SDLcdrom, len); - SDLcdrom = cdpath; - do { - delim = SDL_strchr(SDLcdrom, ':'); - if (delim) { - *delim++ = '\0'; - } - if (CheckDrive(SDLcdrom, &stbuf) > 0) { - AddDrive(SDLcdrom, &stbuf); - } - if (delim) { - SDLcdrom = delim; - } else { - SDLcdrom = NULL; - } - } while (SDLcdrom); - SDL_stack_free(cdpath); - } - - /* If we found our drives, there's nothing left to do */ - if (SDL_numcds > 0) { - return (0); - } - } - /* Scan the system for CD-ROM drives */ - for (i = 0; checklist[i].dir; ++i) { - DIR *devdir; - struct dirent *devent; - int name_len; - - devdir = opendir(checklist[i].dir); - if (devdir) { - name_len = SDL_strlen(checklist[i].name); - while (devent = readdir(devdir)) - if (SDL_memcmp - (checklist[i].name, devent->d_name, name_len) == 0) - if (devent->d_name[devent->d_namlen - 1] == 'c') { - SDL_snprintf(drive, SDL_arraysize(drive), - "%s/%s", checklist[i].dir, - devent->d_name); -#ifdef DEBUG_CDROM - fprintf(stderr, "Try to add drive: %s\n", drive); -#endif - if (CheckDrive(drive, &stbuf) > 0) - AddDrive(drive, &stbuf); - } - closedir(devdir); - } else { -#ifdef DEBUG_CDROM - fprintf(stderr, "cannot open dir: %s\n", checklist[i].dir); -#endif - } - } - return (0); -} - -static const char * -SDL_SYS_CDName(int drive) -{ - return (SDL_cdlist[drive]); -} - -static int -SDL_SYS_CDOpen(int drive) -{ - /* O_RDWR: To use ioctl(fd, SCSI_STOP_UNIT) */ - return (open(SDL_cdlist[drive], (O_RDWR | O_NDELAY), 0)); -} - -static int -SDL_SYS_CDGetTOC(SDL_CD * cdrom) -{ - struct cd_toc toc; - struct cd_toc_header hdr; - struct cd_toc_entry *cdte; - int i; - int okay = 0; - if (ioctl(cdrom->id, CDROM_TOC_HEADER, &hdr)) { - fprintf(stderr, "ioctl error CDROM_TOC_HEADER\n"); - return -1; - } - cdrom->numtracks = hdr.th_ending_track - hdr.th_starting_track + 1; - if (cdrom->numtracks > SDL_MAX_TRACKS) { - cdrom->numtracks = SDL_MAX_TRACKS; - } -#ifdef DEBUG_CDROM - fprintf(stderr, "hdr.th_data_len1 = %d\n", hdr.th_data_len1); - fprintf(stderr, "hdr.th_data_len0 = %d\n", hdr.th_data_len0); - fprintf(stderr, "hdr.th_starting_track = %d\n", hdr.th_starting_track); - fprintf(stderr, "hdr.th_ending_track = %d\n", hdr.th_ending_track); - fprintf(stderr, "cdrom->numtracks = %d\n", cdrom->numtracks); -#endif - toc.toc_address_format = CDROM_LBA_FORMAT; - toc.toc_starting_track = 0; - toc.toc_alloc_length = (hdr.th_data_len1 << 8) + - hdr.th_data_len0 + sizeof(hdr); - if ((toc.toc_buffer = alloca(toc.toc_alloc_length)) == NULL) { - fprintf(stderr, "cannot allocate toc.toc_buffer\n"); - return -1; - } - - bzero(toc.toc_buffer, toc.toc_alloc_length); - if (ioctl(cdrom->id, CDROM_TOC_ENTRYS, &toc)) { - fprintf(stderr, "ioctl error CDROM_TOC_ENTRYS\n"); - return -1; - } - - cdte = (struct cd_toc_entry *) ((char *) toc.toc_buffer + sizeof(hdr)); - for (i = 0; i <= cdrom->numtracks; ++i) { - if (i == cdrom->numtracks) { - cdrom->track[i].id = 0xAA;; - } else { - cdrom->track[i].id = hdr.th_starting_track + i; - } - - cdrom->track[i].type = cdte[i].te_control & CDROM_DATA_TRACK; - cdrom->track[i].offset = - cdte[i].te_absaddr.lba.addr3 << 24 | - cdte[i].te_absaddr.lba.addr2 << 16 | - cdte[i].te_absaddr.lba.addr1 << 8 | cdte[i].te_absaddr.lba.addr0; - cdrom->track[i].length = 0; - if (i > 0) { - cdrom->track[i - 1].length = - cdrom->track[i].offset - cdrom->track[i - 1].offset; - } - } -#ifdef DEBUG_CDROM - for (i = 0; i <= cdrom->numtracks; i++) { - fprintf(stderr, "toc_entry[%d].te_track_number = %d\n", - i, cdte[i].te_track_number); - fprintf(stderr, "cdrom->track[%d].id = %d\n", i, cdrom->track[i].id); - fprintf(stderr, "cdrom->track[%d].type = %x\n", i, - cdrom->track[i].type); - fprintf(stderr, "cdrom->track[%d].offset = %d\n", i, - cdrom->track[i].offset); - fprintf(stderr, "cdrom->track[%d].length = %d\n", i, - cdrom->track[i].length); - } -#endif - if (i == (cdrom->numtracks + 1)) { - okay = 1; - } - - return (okay ? 0 : -1); -} - -/* Get CD-ROM status */ -static CDstatus -SDL_SYS_CDStatus(SDL_CD * cdrom, int *position) -{ - CDstatus status; - struct cd_sub_channel sc; - struct cd_subc_channel_data scd; - - sc.sch_address_format = CDROM_LBA_FORMAT; - sc.sch_data_format = CDROM_CURRENT_POSITION; - sc.sch_track_number = 0; - sc.sch_alloc_length = sizeof(scd); - sc.sch_buffer = (caddr_t) & scd; - if (ioctl(cdrom->id, CDROM_READ_SUBCHANNEL, &sc)) { - status = CD_ERROR; - fprintf(stderr, "ioctl error CDROM_READ_SUBCHANNEL \n"); - } else { - switch (scd.scd_header.sh_audio_status) { - case AS_AUDIO_INVALID: - status = CD_STOPPED; - break; - case AS_PLAY_IN_PROGRESS: - status = CD_PLAYING; - break; - case AS_PLAY_PAUSED: - status = CD_PAUSED; - break; - case AS_PLAY_COMPLETED: - status = CD_STOPPED; - break; - case AS_PLAY_ERROR: - status = CD_ERROR; - break; - case AS_NO_STATUS: - status = CD_STOPPED; - break; - default: - status = CD_ERROR; - break; - } -#ifdef DEBUG_CDROM - fprintf(stderr, "scd.scd_header.sh_audio_status = %x\n", - scd.scd_header.sh_audio_status); -#endif - } - if (position) { - if (status == CD_PLAYING || (status == CD_PAUSED)) { - *position = - scd.scd_position_data.scp_absaddr.lba.addr3 << 24 | - scd.scd_position_data.scp_absaddr.lba.addr2 << 16 | - scd.scd_position_data.scp_absaddr.lba.addr1 << 8 | - scd.scd_position_data.scp_absaddr.lba.addr0; - } else { - *position = 0; - } - } - - return status; -} - -/* Start play */ -static int -SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length) -{ -/* - * Play MSF - */ - struct cd_play_audio_msf msf; - int end; - - bzero(&msf, sizeof(msf)); - end = start + length; - FRAMES_TO_MSF(start + 150, /* LBA = 4500*M + 75*S + F - 150 */ - &msf.msf_starting_M_unit, - &msf.msf_starting_S_unit, &msf.msf_starting_F_unit); - FRAMES_TO_MSF(end + 150, /* LBA = 4500*M + 75*S + F - 150 */ - &msf.msf_ending_M_unit, - &msf.msf_ending_S_unit, &msf.msf_ending_F_unit); - - return (ioctl(cdrom->id, CDROM_PLAY_AUDIO_MSF, &msf)); -} - -/* Pause play */ -static int -SDL_SYS_CDPause(SDL_CD * cdrom) -{ - return (ioctl(cdrom->id, CDROM_PAUSE_PLAY)); -} - -/* Resume play */ -static int -SDL_SYS_CDResume(SDL_CD * cdrom) -{ - return (ioctl(cdrom->id, CDROM_RESUME_PLAY)); -} - -/* Stop play */ -static int -SDL_SYS_CDStop(SDL_CD * cdrom) -{ - return (ioctl(cdrom->id, SCSI_STOP_UNIT)); -} - -/* Eject the CD-ROM */ -static int -SDL_SYS_CDEject(SDL_CD * cdrom) -{ - return (ioctl(cdrom->id, CDROM_EJECT_CADDY)); -} - -/* Close the CD-ROM handle */ -static void -SDL_SYS_CDClose(SDL_CD * cdrom) -{ - close(cdrom->id); -} - -void -SDL_SYS_CDQuit(void) -{ - int i; - - if (SDL_numcds > 0) { - for (i = 0; i < SDL_numcds; ++i) { - SDL_free(SDL_cdlist[i]); - } - SDL_numcds = 0; - } -} - -#endif /* SDL_CDROM_OSF */ -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/cdrom/qnx/SDL_syscdrom.c Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,507 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifdef SDL_CDROM_QNX - -/* Functions for system-level CD-ROM audio control */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <fcntl.h> -#include <errno.h> -#include <unistd.h> -#include <sys/cdrom.h> -#include <sys/dcmd_cam.h> - -#include "SDL_timer.h" -#include "SDL_cdrom.h" -#include "../SDL_syscdrom.h" - -/* The maximum number of CD-ROM drives we'll detect */ -#define MAX_DRIVES 16 - -#define QNX_CD_OPENMODE O_RDONLY | O_EXCL - -/* A list of available CD-ROM drives */ -static char *SDL_cdlist[MAX_DRIVES]; -static dev_t SDL_cdmode[MAX_DRIVES]; -static int SDL_cdopen[MAX_DRIVES]; - -/* The system-dependent CD control functions */ -static const char *SDL_SYS_CDName(int drive); -static int SDL_SYS_CDOpen(int drive); -static int SDL_SYS_CDGetTOC(SDL_CD * cdrom); -static CDstatus SDL_SYS_CDStatus(SDL_CD * cdrom, int *position); -static int SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length); -static int SDL_SYS_CDPause(SDL_CD * cdrom); -static int SDL_SYS_CDResume(SDL_CD * cdrom); -static int SDL_SYS_CDStop(SDL_CD * cdrom); -static int SDL_SYS_CDEject(SDL_CD * cdrom); -static void SDL_SYS_CDClose(SDL_CD * cdrom); - -/* Check a drive to see if it is a CD-ROM */ -static int -CheckDrive(char *drive, struct stat *stbuf) -{ - int is_cd, cdfd; - cam_devinfo_t dinfo; - int devctlret = 0; - - int atapi; - int removable; - int cdb10; - - /* If it doesn't exist, return -1 */ - if (stat(drive, stbuf) < 0) { - return (-1); - } - - /* If it does exist, verify that it's an available CD-ROM */ - is_cd = 0; - - if (S_ISCHR(stbuf->st_mode) || S_ISBLK(stbuf->st_mode)) { - cdfd = open(drive, QNX_CD_OPENMODE); - if (cdfd >= 0) { - devctlret = - devctl(cdfd, DCMD_CAM_DEVINFO, &dinfo, - sizeof(cam_devinfo_t), NULL); - - if (devctlret == EOK) { - atapi = dinfo.flags & DEV_ATAPI; - removable = dinfo.flags & DEV_REMOVABLE; - cdb10 = dinfo.flags & DEV_CDB_10; /* I'm not sure about that flag */ - - /* in the near future need to add more checks for splitting cdroms from other devices */ - if ((atapi) && (removable)) { - is_cd = 1; - } - } - - close(cdfd); - } - } - return (is_cd); -} - -/* Add a CD-ROM drive to our list of valid drives */ -static void -AddDrive(char *drive, struct stat *stbuf) -{ - int i; - - if (SDL_numcds < MAX_DRIVES) { - /* Check to make sure it's not already in our list. - This can happen when we see a drive via symbolic link. */ - - for (i = 0; i < SDL_numcds; ++i) { - if (stbuf->st_rdev == SDL_cdmode[i]) { - return; - } - } - - /* Add this drive to our list */ - - i = SDL_numcds; - SDL_cdlist[i] = SDL_strdup(drive); - if (SDL_cdlist[i] == NULL) { - SDL_OutOfMemory(); - return; - } - SDL_cdmode[i] = stbuf->st_rdev; - ++SDL_numcds; - } -} - -int -SDL_SYS_CDInit(void) -{ - /* checklist: /dev/cdrom, /dev/cd?, /dev/scd? */ - static char *checklist[] = - { "cdrom", "?0 cd?", "?1 cd?", "?0 scd?", NULL }; - - char *SDLcdrom; - int i, j, exists; - char drive[32]; - struct stat stbuf; - - /* Fill in our driver capabilities */ - SDL_CDcaps.Name = SDL_SYS_CDName; - SDL_CDcaps.Open = SDL_SYS_CDOpen; - SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; - SDL_CDcaps.Status = SDL_SYS_CDStatus; - SDL_CDcaps.Play = SDL_SYS_CDPlay; - SDL_CDcaps.Pause = SDL_SYS_CDPause; - SDL_CDcaps.Resume = SDL_SYS_CDResume; - SDL_CDcaps.Stop = SDL_SYS_CDStop; - SDL_CDcaps.Eject = SDL_SYS_CDEject; - SDL_CDcaps.Close = SDL_SYS_CDClose; - - /* clearing device open status */ - for (i = 0; i < MAX_DRIVES; i++) { - SDL_cdopen[i] = 0; - } - - /* Look in the environment for our CD-ROM drive list */ - SDLcdrom = SDL_getenv("SDL_CDROM"); /* ':' separated list of devices */ - if (SDLcdrom != NULL) { - char *cdpath, *delim; - size_t len = SDL_strlen(SDLcdrom) + 1; - cdpath = SDL_stack_alloc(char, len); - if (cdpath != NULL) { - SDL_strlcpy(cdpath, SDLcdrom, len); - SDLcdrom = cdpath; - do { - delim = SDL_strchr(SDLcdrom, ':'); - if (delim) { - *delim++ = '\0'; - } - if (CheckDrive(SDLcdrom, &stbuf) > 0) { - AddDrive(SDLcdrom, &stbuf); - } - if (delim) { - SDLcdrom = delim; - } else { - SDLcdrom = NULL; - } - } while (SDLcdrom); - SDL_stack_free(cdpath); - } - - /* If we found our drives, there's nothing left to do */ - if (SDL_numcds > 0) { - return (0); - } - } - - /* Scan the system for CD-ROM drives */ - for (i = 0; checklist[i]; ++i) { - if (checklist[i][0] == '?') { - char *insert; - exists = 1; - - for (j = checklist[i][1]; exists; ++j) { - SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%s", - &checklist[i][3]); - insert = SDL_strchr(drive, '?'); - if (insert != NULL) { - *insert = j; - } - switch (CheckDrive(drive, &stbuf)) { - /* Drive exists and is a CD-ROM */ - case 1: - AddDrive(drive, &stbuf); - break; - /* Drive exists, but isn't a CD-ROM */ - case 0: - break; - /* Drive doesn't exist */ - case -1: - exists = 0; - break; - } - } - } else { - SDL_snprintf(drive, SDL_arraysize(drive), "/dev/%s", - checklist[i]); - if (CheckDrive(drive, &stbuf) > 0) { - AddDrive(drive, &stbuf); - } - } - } - return (0); -} - -static const char * -SDL_SYS_CDName(int drive) -{ - return (SDL_cdlist[drive]); -} - -static int -SDL_SYS_CDOpen(int drive) -{ - int handle; - - handle = open(SDL_cdlist[drive], QNX_CD_OPENMODE); - - if (handle > 0) { - SDL_cdopen[drive] = handle; - } - - return (handle); -} - -static int -SDL_SYS_CDGetTOC(SDL_CD * cdrom) -{ - cdrom_read_toc_t toc; - int i, okay; - - okay = 0; - if (devctl(cdrom->id, DCMD_CAM_CDROMREADTOC, &toc, sizeof(toc), NULL) == - 0) { - cdrom->numtracks = toc.last_track - toc.first_track + 1; - if (cdrom->numtracks > SDL_MAX_TRACKS) { - cdrom->numtracks = SDL_MAX_TRACKS; - } - /* Read all the track TOC entries */ - for (i = 0; i <= cdrom->numtracks; ++i) { - if (i == cdrom->numtracks) { - cdrom->track[i].id = CDROM_LEADOUT; - } else { - cdrom->track[i].id = toc.first_track + i; - } - - cdrom->track[i].type = toc.toc_entry[i].control_adr & 0x0F; - cdrom->track[i].offset = toc.toc_entry[i].addr.lba; - cdrom->track[i].length = 0; - - if (i > 0) { - cdrom->track[i - 1].length = - cdrom->track[i].offset - cdrom->track[i - 1].offset; - } - } - if (i == (cdrom->numtracks + 1)) { - okay = 1; - } - } - return (okay ? 0 : -1); -} - -/* Get CD-ROM status */ -static CDstatus -SDL_SYS_CDStatus(SDL_CD * cdrom, int *position) -{ - CDstatus status; - - cdrom_read_toc_t toc; - cdrom_subch_data_t info; - cam_devinfo_t dinfo; - - int devctlret = 0; - int drive = -1; - int i; - int eagaincnt = 0; - - /* check media presence before read subchannel call, some cdroms can lockups */ - /* if no media, while calling read subchannel functions. */ - devctlret = - devctl(cdrom->id, DCMD_CAM_DEVINFO, &dinfo, sizeof(cam_devinfo_t), - NULL); - - if (devctlret == EOK) { - if ((dinfo.flags & DEV_NO_MEDIA) != 0) { - status = CD_TRAYEMPTY; - if (position) { - *position = 0; - } - return (status); - } - } - - /* if media exists, then do other stuff */ - - SDL_memset(&info, 0x00, sizeof(info)); - info.subch_command.data_format = CDROM_SUBCH_CURRENT_POSITION; - - do { - devctlret = - devctl(cdrom->id, DCMD_CAM_CDROMSUBCHNL, &info, sizeof(info), - NULL); - if (devctlret == EIO) { - /* big workaround for media change, handle is unusable after that, - that bug was found in QNX 6.2, 6.2.1 is not released yet. */ - - for (i = 0; i < MAX_DRIVES; i++) { - if (SDL_cdopen[i] == cdrom->id) { - drive = i; - break; - } - } - if (drive == -1) { - /* that cannot happen, but ... */ - break; - } - close(cdrom->id); - cdrom->id = open(SDL_cdlist[drive], QNX_CD_OPENMODE); - devctlret = EAGAIN; - } - if (devctlret == EAGAIN) { - eagaincnt++; - } - if (eagaincnt == 2) { - /* workaround for broken cdroms, which can return always EAGAIN when its not ready, */ - /* that mean errornous media or just no media avail */ - devctlret = ENXIO; - break; - } - } while ((devctlret == EAGAIN) || (devctlret == ESTALE)); - - if (devctlret != 0) { - if (devctlret == ENXIO) { - status = CD_TRAYEMPTY; - } else { - status = CD_ERROR; - } - } else { - switch (info.current_position.header.audio_status) { - case CDROM_AUDIO_INVALID: - case CDROM_AUDIO_NO_STATUS: - /* Try to determine if there's a CD available */ - if (devctl - (cdrom->id, DCMD_CAM_CDROMREADTOC, &toc, sizeof(toc), - NULL) == 0) - status = CD_STOPPED; - else - status = CD_TRAYEMPTY; - break; - case CDROM_AUDIO_COMPLETED: - status = CD_STOPPED; - break; - case CDROM_AUDIO_PLAY: - status = CD_PLAYING; - break; - case CDROM_AUDIO_PAUSED: - /* Workaround buggy CD-ROM drive */ - if (info.current_position.data_format == CDROM_LEADOUT) { - status = CD_STOPPED; - } else { - status = CD_PAUSED; - } - break; - default: - status = CD_ERROR; - break; - } - } - - if (position) { - if (status == CD_PLAYING || (status == CD_PAUSED)) { - *position = - MSF_TO_FRAMES(info.current_position.addr.msf.minute, - info.current_position.addr.msf.second, - info.current_position.addr.msf.frame); - } else { - *position = 0; - } - } - - return (status); -} - -/* Start play */ -static int -SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length) -{ - cdrom_playmsf_t playtime; - - FRAMES_TO_MSF(start, &playtime.start_minute, &playtime.start_second, - &playtime.start_frame); - FRAMES_TO_MSF(start + length, &playtime.end_minute, &playtime.end_second, - &playtime.end_frame); - - if (devctl - (cdrom->id, DCMD_CAM_CDROMPLAYMSF, &playtime, sizeof(playtime), - NULL) != 0) { - return -1; - } else { - return 0; - } -} - -/* Pause play */ -static int -SDL_SYS_CDPause(SDL_CD * cdrom) -{ - if (devctl(cdrom->id, DCMD_CAM_CDROMPAUSE, NULL, 0, NULL) != 0) { - return -1; - } else { - return 0; - } -} - -/* Resume play */ -static int -SDL_SYS_CDResume(SDL_CD * cdrom) -{ - if (devctl(cdrom->id, DCMD_CAM_CDROMRESUME, NULL, 0, NULL) != 0) { - return -1; - } else { - return 0; - } -} - -/* Stop play */ -static int -SDL_SYS_CDStop(SDL_CD * cdrom) -{ - if (devctl(cdrom->id, DCMD_CAM_CDROMSTOP, NULL, 0, NULL) != 0) { - return -1; - } else { - return 0; - } -} - -/* Eject the CD-ROM */ -static int -SDL_SYS_CDEject(SDL_CD * cdrom) -{ - if (devctl(cdrom->id, DCMD_CAM_EJECT_MEDIA, NULL, 0, NULL) != 0) { - return -1; - } else { - return 0; - } -} - -/* Close the CD-ROM handle */ -static void -SDL_SYS_CDClose(SDL_CD * cdrom) -{ - int i; - - for (i = 0; i < MAX_DRIVES; i++) { - if (SDL_cdopen[i] == cdrom->id) { - SDL_cdopen[i] = 0; - break; - } - } - - close(cdrom->id); -} - -void -SDL_SYS_CDQuit(void) -{ - int i; - - if (SDL_numcds > 0) { - for (i = 0; i < SDL_numcds; ++i) { - SDL_free(SDL_cdlist[i]); - } - SDL_numcds = 0; - } -} - -#endif /* SDL_CDROM_QNX */ -/* vi: set ts=4 sw=4 expandtab: */
--- a/src/cdrom/win32/SDL_syscdrom.c Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,400 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2009 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifdef SDL_CDROM_WIN32 - -/* Functions for system-level CD-ROM audio control */ - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#include <mmsystem.h> - -#include "SDL_cdrom.h" -#include "../SDL_syscdrom.h" - -/* This really broken?? */ -#define BROKEN_MCI_PAUSE /* Pausing actually stops play -- Doh! */ - -/* The maximum number of CD-ROM drives we'll detect (Don't change!) */ -#define MAX_DRIVES 26 - -/* A list of available CD-ROM drives */ -static char *SDL_cdlist[MAX_DRIVES]; -static MCIDEVICEID SDL_mciID[MAX_DRIVES]; -#ifdef BROKEN_MCI_PAUSE -static int SDL_paused[MAX_DRIVES]; -#endif -static int SDL_CD_end_position; - -/* The system-dependent CD control functions */ -static const char *SDL_SYS_CDName(int drive); -static int SDL_SYS_CDOpen(int drive); -static int SDL_SYS_CDGetTOC(SDL_CD * cdrom); -static CDstatus SDL_SYS_CDStatus(SDL_CD * cdrom, int *position); -static int SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length); -static int SDL_SYS_CDPause(SDL_CD * cdrom); -static int SDL_SYS_CDResume(SDL_CD * cdrom); -static int SDL_SYS_CDStop(SDL_CD * cdrom); -static int SDL_SYS_CDEject(SDL_CD * cdrom); -static void SDL_SYS_CDClose(SDL_CD * cdrom); - - -/* Add a CD-ROM drive to our list of valid drives */ -static void -AddDrive(char *drive) -{ - int i; - - if (SDL_numcds < MAX_DRIVES) { - /* Add this drive to our list */ - i = SDL_numcds; - SDL_cdlist[i] = SDL_strdup(drive); - if (SDL_cdlist[i] == NULL) { - SDL_OutOfMemory(); - return; - } - ++SDL_numcds; -#ifdef CDROM_DEBUG - fprintf(stderr, "Added CD-ROM drive: %s\n", drive); -#endif - } -} - -int -SDL_SYS_CDInit(void) -{ - /* checklist: Drive 'A' - 'Z' */ - int i; - char drive[4]; - - /* Fill in our driver capabilities */ - SDL_CDcaps.Name = SDL_SYS_CDName; - SDL_CDcaps.Open = SDL_SYS_CDOpen; - SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; - SDL_CDcaps.Status = SDL_SYS_CDStatus; - SDL_CDcaps.Play = SDL_SYS_CDPlay; - SDL_CDcaps.Pause = SDL_SYS_CDPause; - SDL_CDcaps.Resume = SDL_SYS_CDResume; - SDL_CDcaps.Stop = SDL_SYS_CDStop; - SDL_CDcaps.Eject = SDL_SYS_CDEject; - SDL_CDcaps.Close = SDL_SYS_CDClose; - - /* Scan the system for CD-ROM drives */ - for (i = 'A'; i <= 'Z'; ++i) { - SDL_snprintf(drive, SDL_arraysize(drive), "%c:\\", i); - if (GetDriveType(drive) == DRIVE_CDROM) { - AddDrive(drive); - } - } - SDL_memset(SDL_mciID, 0, sizeof(SDL_mciID)); - return (0); -} - -/* General ioctl() CD-ROM command function */ -static int -SDL_SYS_CDioctl(int id, UINT msg, DWORD flags, void *arg) -{ - MCIERROR mci_error; - - mci_error = mciSendCommand(SDL_mciID[id], msg, flags, (DWORD_PTR) arg); - if (mci_error) { - char error[256]; - - mciGetErrorString(mci_error, error, 256); - SDL_SetError("mciSendCommand() error: %s", error); - } - return (!mci_error ? 0 : -1); -} - -static const char * -SDL_SYS_CDName(int drive) -{ - return (SDL_cdlist[drive]); -} - -static int -SDL_SYS_CDOpen(int drive) -{ - MCI_OPEN_PARMS mci_open; - MCI_SET_PARMS mci_set; - char device[3]; - DWORD flags; - - /* Open the requested device */ - mci_open.lpstrDeviceType = (LPCSTR) MCI_DEVTYPE_CD_AUDIO; - device[0] = *SDL_cdlist[drive]; - device[1] = ':'; - device[2] = '\0'; - mci_open.lpstrElementName = device; - flags = - (MCI_OPEN_TYPE | MCI_OPEN_SHAREABLE | MCI_OPEN_TYPE_ID | - MCI_OPEN_ELEMENT); - if (SDL_SYS_CDioctl(0, MCI_OPEN, flags, &mci_open) < 0) { - flags &= ~MCI_OPEN_SHAREABLE; - if (SDL_SYS_CDioctl(0, MCI_OPEN, flags, &mci_open) < 0) { - return (-1); - } - } - SDL_mciID[drive] = mci_open.wDeviceID; - - /* Set the minute-second-frame time format */ - mci_set.dwTimeFormat = MCI_FORMAT_MSF; - SDL_SYS_CDioctl(drive, MCI_SET, MCI_SET_TIME_FORMAT, &mci_set); - -#ifdef BROKEN_MCI_PAUSE - SDL_paused[drive] = 0; -#endif - return (drive); -} - -static int -SDL_SYS_CDGetTOC(SDL_CD * cdrom) -{ - MCI_STATUS_PARMS mci_status; - int i, okay; - DWORD flags; - - okay = 0; - mci_status.dwItem = MCI_STATUS_NUMBER_OF_TRACKS; - flags = MCI_STATUS_ITEM | MCI_WAIT; - if (SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, &mci_status) == 0) { - cdrom->numtracks = mci_status.dwReturn; - if (cdrom->numtracks > SDL_MAX_TRACKS) { - cdrom->numtracks = SDL_MAX_TRACKS; - } - /* Read all the track TOC entries */ - flags = MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT; - for (i = 0; i < cdrom->numtracks; ++i) { - cdrom->track[i].id = i + 1; - mci_status.dwTrack = cdrom->track[i].id; -#ifdef MCI_CDA_STATUS_TYPE_TRACK - mci_status.dwItem = MCI_CDA_STATUS_TYPE_TRACK; - if (SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, - &mci_status) < 0) { - break; - } - if (mci_status.dwReturn == MCI_CDA_TRACK_AUDIO) { - cdrom->track[i].type = SDL_AUDIO_TRACK; - } else { - cdrom->track[i].type = SDL_DATA_TRACK; - } -#else - cdrom->track[i].type = SDL_AUDIO_TRACK; -#endif - mci_status.dwItem = MCI_STATUS_POSITION; - if (SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, - &mci_status) < 0) { - break; - } - cdrom->track[i].offset = - MSF_TO_FRAMES(MCI_MSF_MINUTE(mci_status.dwReturn), - MCI_MSF_SECOND(mci_status.dwReturn), - MCI_MSF_FRAME(mci_status.dwReturn)); - cdrom->track[i].length = 0; - if (i > 0) { - cdrom->track[i - 1].length = - cdrom->track[i].offset - cdrom->track[i - 1].offset; - } - } - if (i == cdrom->numtracks) { - mci_status.dwTrack = cdrom->track[i - 1].id; - mci_status.dwItem = MCI_STATUS_LENGTH; - if (SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, - &mci_status) == 0) { - cdrom->track[i - 1].length = - MSF_TO_FRAMES(MCI_MSF_MINUTE(mci_status.dwReturn), - MCI_MSF_SECOND(mci_status.dwReturn), - MCI_MSF_FRAME(mci_status.dwReturn)); - /* compute lead-out offset */ - cdrom->track[i].offset = cdrom->track[i - 1].offset + - cdrom->track[i - 1].length; - cdrom->track[i].length = 0; - okay = 1; - } - } - } - return (okay ? 0 : -1); -} - -/* Get CD-ROM status */ -static CDstatus -SDL_SYS_CDStatus(SDL_CD * cdrom, int *position) -{ - CDstatus status; - MCI_STATUS_PARMS mci_status; - DWORD flags; - - flags = MCI_STATUS_ITEM | MCI_WAIT; - mci_status.dwItem = MCI_STATUS_MODE; - if (SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, &mci_status) < 0) { - status = CD_ERROR; - } else { - switch (mci_status.dwReturn) { - case MCI_MODE_NOT_READY: - case MCI_MODE_OPEN: - status = CD_TRAYEMPTY; - break; - case MCI_MODE_STOP: -#ifdef BROKEN_MCI_PAUSE - if (SDL_paused[cdrom->id]) { - status = CD_PAUSED; - } else { - status = CD_STOPPED; - } -#else - status = CD_STOPPED; -#endif /* BROKEN_MCI_PAUSE */ - break; - case MCI_MODE_PLAY: -#ifdef BROKEN_MCI_PAUSE - if (SDL_paused[cdrom->id]) { - status = CD_PAUSED; - } else { - status = CD_PLAYING; - } -#else - status = CD_PLAYING; -#endif /* BROKEN_MCI_PAUSE */ - break; - case MCI_MODE_PAUSE: - status = CD_PAUSED; - break; - default: - status = CD_ERROR; - break; - } - } - if (position) { - if (status == CD_PLAYING || (status == CD_PAUSED)) { - mci_status.dwItem = MCI_STATUS_POSITION; - if (SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, - &mci_status) == 0) { - *position = - MSF_TO_FRAMES(MCI_MSF_MINUTE(mci_status.dwReturn), - MCI_MSF_SECOND(mci_status.dwReturn), - MCI_MSF_FRAME(mci_status.dwReturn)); - } else { - *position = 0; - } - } else { - *position = 0; - } - } - return (status); -} - -/* Start play */ -static int -SDL_SYS_CDPlay(SDL_CD * cdrom, int start, int length) -{ - MCI_PLAY_PARMS mci_play; - int m, s, f; - DWORD flags; - - flags = MCI_FROM | MCI_TO | MCI_NOTIFY; - mci_play.dwCallback = 0; - FRAMES_TO_MSF(start, &m, &s, &f); - mci_play.dwFrom = MCI_MAKE_MSF(m, s, f); - FRAMES_TO_MSF(start + length, &m, &s, &f); - mci_play.dwTo = MCI_MAKE_MSF(m, s, f); - SDL_CD_end_position = mci_play.dwTo; - return (SDL_SYS_CDioctl(cdrom->id, MCI_PLAY, flags, &mci_play)); -} - -/* Pause play */ -static int -SDL_SYS_CDPause(SDL_CD * cdrom) -{ -#ifdef BROKEN_MCI_PAUSE - SDL_paused[cdrom->id] = 1; -#endif - return (SDL_SYS_CDioctl(cdrom->id, MCI_PAUSE, MCI_WAIT, NULL)); -} - -/* Resume play */ -static int -SDL_SYS_CDResume(SDL_CD * cdrom) -{ -#ifdef BROKEN_MCI_PAUSE - MCI_STATUS_PARMS mci_status; - int okay; - int flags; - - okay = 0; - /* Play from the current play position to the end position set earlier */ - flags = MCI_STATUS_ITEM | MCI_WAIT; - mci_status.dwItem = MCI_STATUS_POSITION; - if (SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, &mci_status) == 0) { - MCI_PLAY_PARMS mci_play; - - flags = MCI_FROM | MCI_TO | MCI_NOTIFY; - mci_play.dwCallback = 0; - mci_play.dwFrom = mci_status.dwReturn; - mci_play.dwTo = SDL_CD_end_position; - if (SDL_SYS_CDioctl(cdrom->id, MCI_PLAY, flags, &mci_play) == 0) { - okay = 1; - SDL_paused[cdrom->id] = 0; - } - } - return (okay ? 0 : -1); -#else - return (SDL_SYS_CDioctl(cdrom->id, MCI_RESUME, MCI_WAIT, NULL)); -#endif /* BROKEN_MCI_PAUSE */ -} - -/* Stop play */ -static int -SDL_SYS_CDStop(SDL_CD * cdrom) -{ - return (SDL_SYS_CDioctl(cdrom->id, MCI_STOP, MCI_WAIT, NULL)); -} - -/* Eject the CD-ROM */ -static int -SDL_SYS_CDEject(SDL_CD * cdrom) -{ - return (SDL_SYS_CDioctl(cdrom->id, MCI_SET, MCI_SET_DOOR_OPEN, NULL)); -} - -/* Close the CD-ROM handle */ -static void -SDL_SYS_CDClose(SDL_CD * cdrom) -{ - SDL_SYS_CDioctl(cdrom->id, MCI_CLOSE, MCI_WAIT, NULL); -} - -void -SDL_SYS_CDQuit(void) -{ - int i; - - if (SDL_numcds > 0) { - for (i = 0; i < SDL_numcds; ++i) { - SDL_free(SDL_cdlist[i]); - } - SDL_numcds = 0; - } -} - -#endif /* SDL_CDROM_WIN32 */ -/* vi: set ts=4 sw=4 expandtab: */
--- a/test/Makefile.in Sat Sep 05 09:03:35 2009 +0000 +++ b/test/Makefile.in Sat Sep 05 09:11:03 2009 +0000 @@ -7,7 +7,7 @@ CFLAGS = @CFLAGS@ LIBS = @LIBS@ -TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testresample$(EXE) testaudioinfo$(EXE) testmultiaudio$(EXE) testpower$(EXE) testalpha$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcdrom$(EXE) testcursor$(EXE) testintersections$(EXE) testdraw2$(EXE) testdyngl$(EXE) testdyngles$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl$(EXE) testgl2$(EXE) testgles$(EXE) testhread$(EXE) testiconv$(EXE) testjoystick$(EXE) testkeys$(EXE) testlock$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testsem$(EXE) testsprite$(EXE) testsprite2$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm$(EXE) testwm2$(EXE) threadwin$(EXE) torturethread$(EXE) testloadso$(EXE) testhaptic$(EXE) testmmousetablet$(EXE) testatomic$(EXE) +TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testresample$(EXE) testaudioinfo$(EXE) testmultiaudio$(EXE) testpower$(EXE) testalpha$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcursor$(EXE) testintersections$(EXE) testdraw2$(EXE) testdyngl$(EXE) testdyngles$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl$(EXE) testgl2$(EXE) testgles$(EXE) testhread$(EXE) testiconv$(EXE) testjoystick$(EXE) testkeys$(EXE) testlock$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testsem$(EXE) testsprite$(EXE) testsprite2$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm$(EXE) testwm2$(EXE) threadwin$(EXE) torturethread$(EXE) testloadso$(EXE) testhaptic$(EXE) testmmousetablet$(EXE) testatomic$(EXE) all: Makefile $(TARGETS) @@ -44,9 +44,6 @@ testblitspeed$(EXE): $(srcdir)/testblitspeed.c $(CC) -o $@ $? $(CFLAGS) $(LIBS) -testcdrom$(EXE): $(srcdir)/testcdrom.c - $(CC) -o $@ $? $(CFLAGS) $(LIBS) - testcursor$(EXE): $(srcdir)/testcursor.c $(CC) -o $@ $? $(CFLAGS) $(LIBS)
--- a/test/testcdrom.c Sat Sep 05 09:03:35 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,203 +0,0 @@ - -/* Test the SDL CD-ROM audio functions */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <ctype.h> - -#include "SDL.h" - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - SDL_Quit(); - exit(rc); -} - -static void -PrintStatus(int driveindex, SDL_CD * cdrom) -{ - CDstatus status; - char *status_str; - - status = SDL_CDStatus(cdrom); - switch (status) { - case CD_TRAYEMPTY: - status_str = "tray empty"; - break; - case CD_STOPPED: - status_str = "stopped"; - break; - case CD_PLAYING: - status_str = "playing"; - break; - case CD_PAUSED: - status_str = "paused"; - break; - case CD_ERROR: - status_str = "error state"; - break; - } - printf("Drive %d status: %s\n", driveindex, status_str); - if (status >= CD_PLAYING) { - int m, s, f; - FRAMES_TO_MSF(cdrom->cur_frame, &m, &s, &f); - printf("Currently playing track %d, %d:%2.2d\n", - cdrom->track[cdrom->cur_track].id, m, s); - } -} - -static void -ListTracks(SDL_CD * cdrom) -{ - int i; - int m, s, f; - char *trtype; - - SDL_CDStatus(cdrom); - printf("Drive tracks: %d\n", cdrom->numtracks); - for (i = 0; i < cdrom->numtracks; ++i) { - FRAMES_TO_MSF(cdrom->track[i].length, &m, &s, &f); - if (f > 0) - ++s; - switch (cdrom->track[i].type) { - case SDL_AUDIO_TRACK: - trtype = "audio"; - break; - case SDL_DATA_TRACK: - trtype = "data"; - break; - default: - trtype = "unknown"; - break; - } - printf("\tTrack (index %d) %d: %d:%2.2d / %d [%s track]\n", i, - cdrom->track[i].id, m, s, cdrom->track[i].length, trtype); - } -} - -static void -PrintUsage(char *argv0) -{ - fprintf(stderr, "Usage: %s [drive#] [command] [command] ...\n", argv0); - fprintf(stderr, "Where 'command' is one of:\n"); - fprintf(stderr, " -status\n"); - fprintf(stderr, " -list\n"); - fprintf(stderr, - " -play [first_track] [first_frame] [num_tracks] [num_frames]\n"); - fprintf(stderr, " -pause\n"); - fprintf(stderr, " -resume\n"); - fprintf(stderr, " -stop\n"); - fprintf(stderr, " -eject\n"); - fprintf(stderr, " -sleep <milliseconds>\n"); -} - -int -main(int argc, char *argv[]) -{ - int drive; - int i; - SDL_CD *cdrom; - - /* Initialize SDL first */ - if (SDL_Init(SDL_INIT_CDROM) < 0) { - fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); - return (1); - } - - /* Find out how many CD-ROM drives are connected to the system */ - if (SDL_CDNumDrives() == 0) { - printf("No CD-ROM devices detected\n"); - quit(0); - } - printf("Drives available: %d\n", SDL_CDNumDrives()); - for (i = 0; i < SDL_CDNumDrives(); ++i) { - printf("Drive %d: \"%s\"\n", i, SDL_CDName(i)); - } - - /* Open the CD-ROM */ - drive = 0; - i = 1; - if (argv[i] && isdigit(argv[i][0])) { - drive = atoi(argv[i++]); - } - cdrom = SDL_CDOpen(drive); - if (cdrom == NULL) { - fprintf(stderr, "Couldn't open drive %d: %s\n", drive, - SDL_GetError()); - quit(2); - } -#ifdef TEST_NULLCD - cdrom = NULL; -#endif - - /* Find out which function to perform */ - for (; argv[i]; ++i) { - if (strcmp(argv[i], "-status") == 0) { - /* PrintStatus(drive, cdrom); */ - } else if (strcmp(argv[i], "-list") == 0) { - ListTracks(cdrom); - } else if (strcmp(argv[i], "-play") == 0) { - int strack, sframe; - int ntrack, nframe; - - strack = 0; - if (argv[i + 1] && isdigit(argv[i + 1][0])) { - strack = atoi(argv[++i]); - } - sframe = 0; - if (argv[i + 1] && isdigit(argv[i + 1][0])) { - sframe = atoi(argv[++i]); - } - ntrack = 0; - if (argv[i + 1] && isdigit(argv[i + 1][0])) { - ntrack = atoi(argv[++i]); - } - nframe = 0; - if (argv[i + 1] && isdigit(argv[i + 1][0])) { - nframe = atoi(argv[++i]); - } - if (CD_INDRIVE(SDL_CDStatus(cdrom))) { - if (SDL_CDPlayTracks(cdrom, strack, sframe, - ntrack, nframe) < 0) { - fprintf(stderr, - "Couldn't play tracks %d/%d for %d/%d: %s\n", - strack, sframe, ntrack, nframe, SDL_GetError()); - } - } else { - fprintf(stderr, "No CD in drive!\n"); - } - } else if (strcmp(argv[i], "-pause") == 0) { - if (SDL_CDPause(cdrom) < 0) { - fprintf(stderr, "Couldn't pause CD: %s\n", SDL_GetError()); - } - } else if (strcmp(argv[i], "-resume") == 0) { - if (SDL_CDResume(cdrom) < 0) { - fprintf(stderr, "Couldn't resume CD: %s\n", SDL_GetError()); - } - } else if (strcmp(argv[i], "-stop") == 0) { - if (SDL_CDStop(cdrom) < 0) { - fprintf(stderr, "Couldn't eject CD: %s\n", SDL_GetError()); - } - } else if (strcmp(argv[i], "-eject") == 0) { - if (SDL_CDEject(cdrom) < 0) { - fprintf(stderr, "Couldn't eject CD: %s\n", SDL_GetError()); - } - } else if ((strcmp(argv[i], "-sleep") == 0) && - (argv[i + 1] && isdigit(argv[i + 1][0]))) { - SDL_Delay(atoi(argv[++i])); - printf("Delayed %d milliseconds\n", atoi(argv[i])); - } else { - PrintUsage(argv[0]); - SDL_CDClose(cdrom); - quit(1); - } - } - PrintStatus(drive, cdrom); - SDL_CDClose(cdrom); - SDL_Quit(); - - return (0); -}