Mercurial > sdl-ios-xcode
view src/cdrom/os2/SDL_syscdrom.c @ 2915:deb377097225
Fixed CPU feature detection on x86_64 platform
(registers were being corrupted, causing crashes)
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 24 Dec 2008 13:13:38 +0000 |
parents | 99210400e8b9 |
children |
line wrap: on
line source
/* 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: */