146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* 246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL - Simple DirectMedia Layer 346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Copyright (C) 1997-2006 Sam Lantinga 446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner This library is free software; you can redistribute it and/or 646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner modify it under the terms of the GNU Lesser General Public 746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner License as published by the Free Software Foundation; either 846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner version 2.1 of the License, or (at your option) any later version. 946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner This library is distributed in the hope that it will be useful, 1146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner but WITHOUT ANY WARRANTY; without even the implied warranty of 1246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Lesser General Public License for more details. 1446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner You should have received a copy of the GNU Lesser General Public 1646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner License along with this library; if not, write to the Free Software 1746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 1846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 1946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner Sam Lantinga 2046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner slouken@libsdl.org 2146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner*/ 2246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_config.h" 2346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef SDL_CDROM_WIN32 2546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Functions for system-level CD-ROM audio control */ 2746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 2846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define WIN32_LEAN_AND_MEAN 2946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <windows.h> 3046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include <mmsystem.h> 3146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 3246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "SDL_cdrom.h" 3346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#include "../SDL_syscdrom.h" 3446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 3546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* This really broken?? */ 3646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define BROKEN_MCI_PAUSE /* Pausing actually stops play -- Doh! */ 3746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 3846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* The maximum number of CD-ROM drives we'll detect (Don't change!) */ 3946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#define MAX_DRIVES 26 4046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 4146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* A list of available CD-ROM drives */ 4246be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic char *SDL_cdlist[MAX_DRIVES]; 4346be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic MCIDEVICEID SDL_mciID[MAX_DRIVES]; 4446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef BROKEN_MCI_PAUSE 4546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_paused[MAX_DRIVES]; 4646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 4746be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_CD_end_position; 4846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 4946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* The system-dependent CD control functions */ 5046be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic const char *SDL_SYS_CDName(int drive); 5146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDOpen(int drive); 5246be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDGetTOC(SDL_CD *cdrom); 5346be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position); 5446be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length); 5546be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDPause(SDL_CD *cdrom); 5646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDResume(SDL_CD *cdrom); 5746be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDStop(SDL_CD *cdrom); 5846be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDEject(SDL_CD *cdrom); 5946be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void SDL_SYS_CDClose(SDL_CD *cdrom); 6046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 6146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 6246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Add a CD-ROM drive to our list of valid drives */ 6346be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void AddDrive(char *drive) 6446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 6546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int i; 6646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 6746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_numcds < MAX_DRIVES ) { 6846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Add this drive to our list */ 6946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner i = SDL_numcds; 7046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_cdlist[i] = SDL_strdup(drive); 7146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_cdlist[i] == NULL ) { 7246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_OutOfMemory(); 7346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return; 7446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 7546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner ++SDL_numcds; 7646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef CDROM_DEBUG 7746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner fprintf(stderr, "Added CD-ROM drive: %s\n", drive); 7846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 7946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 8046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 8146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 8246be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerint SDL_SYS_CDInit(void) 8346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 8446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* checklist: Drive 'A' - 'Z' */ 8546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int i; 8646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char drive[4]; 8746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 8846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Fill in our driver capabilities */ 8946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Name = SDL_SYS_CDName; 9046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Open = SDL_SYS_CDOpen; 9146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; 9246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Status = SDL_SYS_CDStatus; 9346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Play = SDL_SYS_CDPlay; 9446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Pause = SDL_SYS_CDPause; 9546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Resume = SDL_SYS_CDResume; 9646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Stop = SDL_SYS_CDStop; 9746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Eject = SDL_SYS_CDEject; 9846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CDcaps.Close = SDL_SYS_CDClose; 9946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 10046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Scan the system for CD-ROM drives */ 10146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for ( i='A'; i<='Z'; ++i ) { 10246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_snprintf(drive, SDL_arraysize(drive), "%c:\\", i); 10346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( GetDriveType(drive) == DRIVE_CDROM ) { 10446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner AddDrive(drive); 10546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 10646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 10746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_memset(SDL_mciID, 0, sizeof(SDL_mciID)); 10846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(0); 10946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 11046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 11146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* General ioctl() CD-ROM command function */ 11246be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDioctl(int id, UINT msg, DWORD flags, void *arg) 11346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 11446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MCIERROR mci_error; 11546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 11646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mci_error = mciSendCommand(SDL_mciID[id], msg, flags, (DWORD_PTR)arg); 11746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( mci_error ) { 11846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char error[256]; 11946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 12046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mciGetErrorString(mci_error, error, 256); 12146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SetError("mciSendCommand() error: %s", error); 12246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 12346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(!mci_error ? 0 : -1); 12446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 12546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 12646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic const char *SDL_SYS_CDName(int drive) 12746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 12846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(SDL_cdlist[drive]); 12946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 13046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 13146be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDOpen(int drive) 13246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 13346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MCI_OPEN_PARMS mci_open; 13446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MCI_SET_PARMS mci_set; 13546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner char device[3]; 13646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DWORD flags; 13746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 13846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Open the requested device */ 13946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mci_open.lpstrDeviceType = (LPCSTR) MCI_DEVTYPE_CD_AUDIO; 14046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner device[0] = *SDL_cdlist[drive]; 14146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner device[1] = ':'; 14246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner device[2] = '\0'; 14346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mci_open.lpstrElementName = device; 14446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner flags = 14546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner (MCI_OPEN_TYPE|MCI_OPEN_SHAREABLE|MCI_OPEN_TYPE_ID|MCI_OPEN_ELEMENT); 14646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_SYS_CDioctl(0, MCI_OPEN, flags, &mci_open) < 0 ) { 14746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner flags &= ~MCI_OPEN_SHAREABLE; 14846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_SYS_CDioctl(0, MCI_OPEN, flags, &mci_open) < 0 ) { 14946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(-1); 15046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 15146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 15246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_mciID[drive] = mci_open.wDeviceID; 15346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 15446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Set the minute-second-frame time format */ 15546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mci_set.dwTimeFormat = MCI_FORMAT_MSF; 15646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SYS_CDioctl(drive, MCI_SET, MCI_SET_TIME_FORMAT, &mci_set); 15746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 15846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef BROKEN_MCI_PAUSE 15946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_paused[drive] = 0; 16046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 16146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(drive); 16246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 16346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 16446be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDGetTOC(SDL_CD *cdrom) 16546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 16646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MCI_STATUS_PARMS mci_status; 16746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int i, okay; 16846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DWORD flags; 16946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 17046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner okay = 0; 17146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mci_status.dwItem = MCI_STATUS_NUMBER_OF_TRACKS; 17246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner flags = MCI_STATUS_ITEM | MCI_WAIT; 17346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, &mci_status) == 0 ) { 17446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->numtracks = mci_status.dwReturn; 17546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( cdrom->numtracks > SDL_MAX_TRACKS ) { 17646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->numtracks = SDL_MAX_TRACKS; 17746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 17846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Read all the track TOC entries */ 17946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner flags = MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT; 18046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for ( i=0; i<cdrom->numtracks; ++i ) { 18146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i].id = i+1; 18246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mci_status.dwTrack = cdrom->track[i].id; 18346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef MCI_CDA_STATUS_TYPE_TRACK 18446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mci_status.dwItem = MCI_CDA_STATUS_TYPE_TRACK; 18546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, 18646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner &mci_status) < 0 ) { 18746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 18846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 18946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( mci_status.dwReturn == MCI_CDA_TRACK_AUDIO ) { 19046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i].type = SDL_AUDIO_TRACK; 19146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 19246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i].type = SDL_DATA_TRACK; 19346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 19446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#else 19546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i].type = SDL_AUDIO_TRACK; 19646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 19746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mci_status.dwItem = MCI_STATUS_POSITION; 19846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, 19946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner &mci_status) < 0 ) { 20046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 20146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 20246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i].offset = MSF_TO_FRAMES( 20346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MCI_MSF_MINUTE(mci_status.dwReturn), 20446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MCI_MSF_SECOND(mci_status.dwReturn), 20546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MCI_MSF_FRAME(mci_status.dwReturn)); 20646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i].length = 0; 20746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( i > 0 ) { 20846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i-1].length = 20946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i].offset- 21046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i-1].offset; 21146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 21246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 21346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( i == cdrom->numtracks ) { 21446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mci_status.dwTrack = cdrom->track[i - 1].id; 21546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mci_status.dwItem = MCI_STATUS_LENGTH; 21646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, 21746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner &mci_status) == 0 ) { 21846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i - 1].length = MSF_TO_FRAMES( 21946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MCI_MSF_MINUTE(mci_status.dwReturn), 22046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MCI_MSF_SECOND(mci_status.dwReturn), 22146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MCI_MSF_FRAME(mci_status.dwReturn)); 22246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* compute lead-out offset */ 22346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i].offset = cdrom->track[i - 1].offset + 22446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i - 1].length; 22546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner cdrom->track[i].length = 0; 22646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner okay = 1; 22746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 22846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 22946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 23046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(okay ? 0 : -1); 23146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 23246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 23346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Get CD-ROM status */ 23446be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) 23546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 23646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner CDstatus status; 23746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MCI_STATUS_PARMS mci_status; 23846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DWORD flags; 23946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 24046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner flags = MCI_STATUS_ITEM | MCI_WAIT; 24146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mci_status.dwItem = MCI_STATUS_MODE; 24246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, &mci_status) < 0 ) { 24346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_ERROR; 24446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 24546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner switch (mci_status.dwReturn) { 24646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case MCI_MODE_NOT_READY: 24746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case MCI_MODE_OPEN: 24846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_TRAYEMPTY; 24946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 25046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case MCI_MODE_STOP: 25146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef BROKEN_MCI_PAUSE 25246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_paused[cdrom->id] ) { 25346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_PAUSED; 25446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 25546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_STOPPED; 25646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 25746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#else 25846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_STOPPED; 25946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif /* BROKEN_MCI_PAUSE */ 26046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 26146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case MCI_MODE_PLAY: 26246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef BROKEN_MCI_PAUSE 26346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_paused[cdrom->id] ) { 26446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_PAUSED; 26546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 26646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_PLAYING; 26746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 26846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#else 26946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_PLAYING; 27046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif /* BROKEN_MCI_PAUSE */ 27146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 27246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner case MCI_MODE_PAUSE: 27346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_PAUSED; 27446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 27546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner default: 27646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner status = CD_ERROR; 27746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner break; 27846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 27946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 28046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( position ) { 28146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( status == CD_PLAYING || (status == CD_PAUSED) ) { 28246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mci_status.dwItem = MCI_STATUS_POSITION; 28346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, 28446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner &mci_status) == 0 ) { 28546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner *position = MSF_TO_FRAMES( 28646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MCI_MSF_MINUTE(mci_status.dwReturn), 28746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MCI_MSF_SECOND(mci_status.dwReturn), 28846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MCI_MSF_FRAME(mci_status.dwReturn)); 28946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 29046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner *position = 0; 29146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 29246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } else { 29346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner *position = 0; 29446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 29546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 29646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(status); 29746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 29846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 29946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Start play */ 30046be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) 30146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 30246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MCI_PLAY_PARMS mci_play; 30346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int m, s, f; 30446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner DWORD flags; 30546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 30646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner flags = MCI_FROM | MCI_TO | MCI_NOTIFY; 30746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mci_play.dwCallback = 0; 30846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner FRAMES_TO_MSF(start, &m, &s, &f); 30946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mci_play.dwFrom = MCI_MAKE_MSF(m, s, f); 31046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner FRAMES_TO_MSF(start+length, &m, &s, &f); 31146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mci_play.dwTo = MCI_MAKE_MSF(m, s, f); 31246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_CD_end_position = mci_play.dwTo; 31346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(SDL_SYS_CDioctl(cdrom->id, MCI_PLAY, flags, &mci_play)); 31446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 31546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 31646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Pause play */ 31746be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDPause(SDL_CD *cdrom) 31846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 31946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef BROKEN_MCI_PAUSE 32046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_paused[cdrom->id] = 1; 32146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif 32246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(SDL_SYS_CDioctl(cdrom->id, MCI_PAUSE, MCI_WAIT, NULL)); 32346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 32446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 32546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Resume play */ 32646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDResume(SDL_CD *cdrom) 32746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 32846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#ifdef BROKEN_MCI_PAUSE 32946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MCI_STATUS_PARMS mci_status; 33046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int okay; 33146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int flags; 33246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 33346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner okay = 0; 33446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner /* Play from the current play position to the end position set earlier */ 33546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner flags = MCI_STATUS_ITEM | MCI_WAIT; 33646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mci_status.dwItem = MCI_STATUS_POSITION; 33746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, &mci_status) == 0 ) { 33846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner MCI_PLAY_PARMS mci_play; 33946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 34046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner flags = MCI_FROM | MCI_TO | MCI_NOTIFY; 34146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mci_play.dwCallback = 0; 34246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mci_play.dwFrom = mci_status.dwReturn; 34346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner mci_play.dwTo = SDL_CD_end_position; 34446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if (SDL_SYS_CDioctl(cdrom->id,MCI_PLAY,flags,&mci_play) == 0) { 34546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner okay = 1; 34646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_paused[cdrom->id] = 0; 34746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 34846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 34946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(okay ? 0 : -1); 35046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#else 35146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(SDL_SYS_CDioctl(cdrom->id, MCI_RESUME, MCI_WAIT, NULL)); 35246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif /* BROKEN_MCI_PAUSE */ 35346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 35446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 35546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Stop play */ 35646be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDStop(SDL_CD *cdrom) 35746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 35846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(SDL_SYS_CDioctl(cdrom->id, MCI_STOP, MCI_WAIT, NULL)); 35946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 36046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 36146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Eject the CD-ROM */ 36246be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic int SDL_SYS_CDEject(SDL_CD *cdrom) 36346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 36446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner return(SDL_SYS_CDioctl(cdrom->id, MCI_SET, MCI_SET_DOOR_OPEN, NULL)); 36546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 36646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 36746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner/* Close the CD-ROM handle */ 36846be48730333120a7b939116cef075e61c12c703David 'Digit' Turnerstatic void SDL_SYS_CDClose(SDL_CD *cdrom) 36946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 37046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_SYS_CDioctl(cdrom->id, MCI_CLOSE, MCI_WAIT, NULL); 37146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 37246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 37346be48730333120a7b939116cef075e61c12c703David 'Digit' Turnervoid SDL_SYS_CDQuit(void) 37446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner{ 37546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner int i; 37646be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 37746be48730333120a7b939116cef075e61c12c703David 'Digit' Turner if ( SDL_numcds > 0 ) { 37846be48730333120a7b939116cef075e61c12c703David 'Digit' Turner for ( i=0; i<SDL_numcds; ++i ) { 37946be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_free(SDL_cdlist[i]); 38046be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 38146be48730333120a7b939116cef075e61c12c703David 'Digit' Turner SDL_numcds = 0; 38246be48730333120a7b939116cef075e61c12c703David 'Digit' Turner } 38346be48730333120a7b939116cef075e61c12c703David 'Digit' Turner} 38446be48730333120a7b939116cef075e61c12c703David 'Digit' Turner 38546be48730333120a7b939116cef075e61c12c703David 'Digit' Turner#endif /* SDL_CDROM_WIN32 */ 386