From 1bcab407aeba865d694d127e9a5b0cc0de70ba22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Thu, 6 Nov 2008 19:31:21 +0000 Subject: [PATCH] fix cdrom ioctl raw sector reading; add mci cd audio functionality to cdrom ioctl interface; add direct audio extraction functionality to cdrom ioctl interface Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3233 --- src/dos/cdrom.h | 51 +++- src/dos/cdrom_ioctl_win32.cpp | 463 ++++++++++++++++++++++++++++------ src/dos/dos_mscdex.cpp | 22 +- src/dos/dos_programs.cpp | 34 ++- 4 files changed, 478 insertions(+), 92 deletions(-) diff --git a/src/dos/cdrom.h b/src/dos/cdrom.h index 39268232..241839be 100644 --- a/src/dos/cdrom.h +++ b/src/dos/cdrom.h @@ -23,7 +23,7 @@ #define RAW_SECTOR_SIZE 2352 #define COOKED_SECTOR_SIZE 2048 -enum { CDROM_USE_SDL, CDROM_USE_ASPI, CDROM_USE_IOCTL }; +enum { CDROM_USE_SDL, CDROM_USE_ASPI, CDROM_USE_IOCTL_DIO, CDROM_USE_IOCTL_DX, CDROM_USE_IOCTL_MCI }; typedef struct SMSF { unsigned char min; @@ -265,7 +265,10 @@ private: class CDROM_Interface_Ioctl : public CDROM_Interface { public: - CDROM_Interface_Ioctl (void); + enum cdioctl_cdatype { CDIOCTL_CDA_DIO, CDIOCTL_CDA_MCI, CDIOCTL_CDA_DX }; + cdioctl_cdatype cdioctl_cda_selected; + + CDROM_Interface_Ioctl (cdioctl_cdatype ioctl_cda); virtual ~CDROM_Interface_Ioctl(void); bool SetDevice (char* path, int forceCD); @@ -282,6 +285,7 @@ public: bool PauseAudio (bool resume); bool StopAudio (void); + bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector); bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num); bool LoadUnloadMedia (bool unload); @@ -291,10 +295,51 @@ private: bool Open (void); void Close (void); - + char pathname[32]; HANDLE hIOCTL; TMSF oldLeadOut; + + + /* track start/length data */ + bool track_start_valid; + int track_start_first,track_start_last; + int track_start[128]; + + bool GetAudioTracksAll (void); + + + /* mci audio cd interface */ + bool use_mciplay; + int mci_devid; + + bool mci_CDioctl (UINT msg, DWORD flags, void *arg); + bool mci_CDOpen (char drive); + bool mci_CDClose (void); + bool mci_CDPlay (int start, int length); + bool mci_CDPause (void); + bool mci_CDResume (void); + bool mci_CDStop (void); + int mci_CDStatus (void); + bool mci_CDPosition (int *position); + + + /* digital audio extraction cd interface */ + static void dx_CDAudioCallBack(Bitu len); + + bool use_dxplay; + static struct dxPlayer { + CDROM_Interface_Ioctl *cd; + MixerChannel *channel; + SDL_mutex *mutex; + Bit8u buffer[8192]; + int bufLen; + int currFrame; + int targetFrame; + bool isPlaying; + bool isPaused; + } player; + }; #endif /* WIN 32 */ diff --git a/src/dos/cdrom_ioctl_win32.cpp b/src/dos/cdrom_ioctl_win32.cpp index 7afdc965..299f9585 100644 --- a/src/dos/cdrom_ioctl_win32.cpp +++ b/src/dos/cdrom_ioctl_win32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * Copyright (C) 2002-2008 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: cdrom_ioctl_win32.cpp,v 1.14 2007-01-08 19:45:39 qbix79 Exp $ */ +/* $Id: cdrom_ioctl_win32.cpp,v 1.15 2008-11-06 19:31:21 c2woody Exp $ */ #if defined (WIN32) @@ -34,35 +34,173 @@ #include "ddk/ntddcdrm.h" // Ioctl stuff #endif +#include + #include "cdrom.h" -CDROM_Interface_Ioctl::CDROM_Interface_Ioctl() -{ +// for a more sophisticated implementation of the mci cdda functionality +// see the SDL sources, which the mci_ functions are based on + +/* General ioctl() CD-ROM command function */ +bool CDROM_Interface_Ioctl::mci_CDioctl(UINT msg, DWORD flags, void *arg) { + MCIERROR mci_error = mciSendCommand(mci_devid, msg, flags, (DWORD_PTR)arg); + if (mci_error!=MMSYSERR_NOERROR) { + char error[256]; + mciGetErrorString(mci_error, error, 256); + LOG_MSG("mciSendCommand() error: %s", error); + return true; + } + return false; +} + +bool CDROM_Interface_Ioctl::mci_CDOpen(char 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] = drive; + device[1] = ':'; + device[2] = '\0'; + mci_open.lpstrElementName = device; + flags = (MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID|MCI_OPEN_SHAREABLE|MCI_OPEN_ELEMENT); + if (mci_CDioctl(MCI_OPEN, flags, &mci_open)) { + flags &= ~MCI_OPEN_SHAREABLE; + if (mci_CDioctl(MCI_OPEN, flags, &mci_open)) { + return true; + } + } + mci_devid = mci_open.wDeviceID; + + /* Set the minute-second-frame time format */ + mci_set.dwTimeFormat = MCI_FORMAT_MSF; + mci_CDioctl(MCI_SET, MCI_SET_TIME_FORMAT, &mci_set); + + return false; +} + +bool CDROM_Interface_Ioctl::mci_CDClose(void) { + return mci_CDioctl(MCI_CLOSE, MCI_WAIT, NULL); +} + +bool CDROM_Interface_Ioctl::mci_CDPlay(int start, int length) { + DWORD flags = MCI_FROM | MCI_TO | MCI_NOTIFY; + MCI_PLAY_PARMS mci_play; + mci_play.dwCallback = 0; + + int m, s, f; + 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); + + return mci_CDioctl(MCI_PLAY, flags, &mci_play); +} + +bool CDROM_Interface_Ioctl::mci_CDPause(void) { + return mci_CDioctl(MCI_PAUSE, MCI_WAIT, NULL); +} + +bool CDROM_Interface_Ioctl::mci_CDResume(void) { + return mci_CDioctl(MCI_RESUME, MCI_WAIT, NULL); +} + +bool CDROM_Interface_Ioctl::mci_CDStop(void) { + return mci_CDioctl(MCI_STOP, MCI_WAIT, NULL); +} + +int CDROM_Interface_Ioctl::mci_CDStatus(void) { + int status; + MCI_STATUS_PARMS mci_status; + + DWORD flags = MCI_STATUS_ITEM | MCI_WAIT; + mci_status.dwItem = MCI_STATUS_MODE; + if (mci_CDioctl(MCI_STATUS, flags, &mci_status)) { + status = -1; + } else { + switch (mci_status.dwReturn) { + case MCI_MODE_NOT_READY: + case MCI_MODE_OPEN: + status = 0; + break; + case MCI_MODE_STOP: + status = 1; + break; + case MCI_MODE_PLAY: + status = 2; + break; + case MCI_MODE_PAUSE: + status = 3; + break; + default: + status = -1; + break; + } + } + + return status; +} + +bool CDROM_Interface_Ioctl::mci_CDPosition(int *position) { + *position = 0; + + DWORD flags = MCI_STATUS_ITEM | MCI_WAIT; + + MCI_STATUS_PARMS mci_status; + mci_status.dwItem = MCI_STATUS_MODE; + if (mci_CDioctl(MCI_STATUS, flags, &mci_status)) return true; + switch (mci_status.dwReturn) { + case MCI_MODE_NOT_READY: + case MCI_MODE_OPEN: + case MCI_MODE_STOP: + return true; // not ready/undefined status + case MCI_MODE_PLAY: + case MCI_MODE_PAUSE: + mci_status.dwItem = MCI_STATUS_POSITION; + if (!mci_CDioctl(MCI_STATUS, flags, &mci_status)) { + *position = MSF_TO_FRAMES( + MCI_MSF_MINUTE(mci_status.dwReturn), + MCI_MSF_SECOND(mci_status.dwReturn), + MCI_MSF_FRAME(mci_status.dwReturn)); + } + return false; // no error, position read + default: + break; + } + return false; +} + + +CDROM_Interface_Ioctl::dxPlayer CDROM_Interface_Ioctl::player = { + NULL, NULL, NULL, 0, 0, 0, 0, 0, false, false }; + +CDROM_Interface_Ioctl::CDROM_Interface_Ioctl(cdioctl_cdatype ioctl_cda) { pathname[0] = 0; hIOCTL = INVALID_HANDLE_VALUE; memset(&oldLeadOut,0,sizeof(oldLeadOut)); -}; + cdioctl_cda_selected = ioctl_cda; +} -CDROM_Interface_Ioctl::~CDROM_Interface_Ioctl() -{ +CDROM_Interface_Ioctl::~CDROM_Interface_Ioctl() { StopAudio(); + if (use_mciplay) mci_CDStop(); Close(); -}; + if (use_mciplay) mci_CDClose(); +} -bool CDROM_Interface_Ioctl::GetUPC(unsigned char& attr, char* upc) -{ +bool CDROM_Interface_Ioctl::GetUPC(unsigned char& attr, char* upc) { // FIXME : To Do return true; } -bool CDROM_Interface_Ioctl::GetAudioTracks(int& stTrack, int& endTrack, TMSF& leadOut) -{ -// Open(); +bool CDROM_Interface_Ioctl::GetAudioTracks(int& stTrack, int& endTrack, TMSF& leadOut) { CDROM_TOC toc; DWORD byteCount; BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), &byteCount,NULL); -// Close(); if (!bStat) return false; stTrack = toc.FirstTrack; @@ -70,17 +208,30 @@ bool CDROM_Interface_Ioctl::GetAudioTracks(int& stTrack, int& endTrack, TMSF& le leadOut.min = toc.TrackData[endTrack].Address[1]; leadOut.sec = toc.TrackData[endTrack].Address[2]; leadOut.fr = toc.TrackData[endTrack].Address[3]; - return true; -}; -bool CDROM_Interface_Ioctl::GetAudioTrackInfo(int track, TMSF& start, unsigned char& attr) -{ -// Open(); + if ((use_mciplay || use_dxplay) && (!track_start_valid)) { + Bits track_num = 0; + // get track start address of all tracks + for (Bits i=toc.FirstTrack; i<=toc.LastTrack+1; i++) { + if (((toc.TrackData[i].Control&1)==0) || (i==toc.LastTrack+1)) { + track_start[track_num] = MSF_TO_FRAMES(toc.TrackData[track_num].Address[1],toc.TrackData[track_num].Address[2],toc.TrackData[track_num].Address[3])-150; + track_start[track_num] += 150; + track_num++; + } + } + track_start_first = 0; + track_start_last = track_num-1; + track_start_valid = true; + } + + return true; +} + +bool CDROM_Interface_Ioctl::GetAudioTrackInfo(int track, TMSF& start, unsigned char& attr) { CDROM_TOC toc; DWORD byteCount; BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), &byteCount,NULL); -// Close(); if (!bStat) return false; attr = (toc.TrackData[track-1].Control << 4) & 0xEF; @@ -88,11 +239,52 @@ bool CDROM_Interface_Ioctl::GetAudioTrackInfo(int track, TMSF& start, unsigned c start.sec = toc.TrackData[track-1].Address[2]; start.fr = toc.TrackData[track-1].Address[3]; return true; -}; +} -bool CDROM_Interface_Ioctl::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) -{ -// Open(); +bool CDROM_Interface_Ioctl::GetAudioTracksAll(void) { + if (track_start_valid) return true; + + CDROM_TOC toc; + DWORD byteCount; + BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL, 0, + &toc, sizeof(toc), &byteCount,NULL); + if (!bStat) return false; + + Bits track_num = 0; + // get track start address of all tracks + for (Bits i=toc.FirstTrack; i<=toc.LastTrack+1; i++) { + if (((toc.TrackData[i].Control&1)==0) || (i==toc.LastTrack+1)) { + track_start[track_num] = MSF_TO_FRAMES(toc.TrackData[track_num].Address[1],toc.TrackData[track_num].Address[2],toc.TrackData[track_num].Address[3])-150; + track_start[track_num] += 150; + track_num++; + } + } + track_start_first = 0; + track_start_last = track_num-1; + track_start_valid = true; + return true; +} + +bool CDROM_Interface_Ioctl::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) { + if (use_dxplay) { + track = 1; + FRAMES_TO_MSF(player.currFrame + 150, &absPos.min, &absPos.sec, &absPos.fr); + FRAMES_TO_MSF(player.currFrame + 150, &relPos.min, &relPos.sec, &relPos.fr); + + if (GetAudioTracksAll()) { + // get track number from current frame + for (int i=track_start_first; i<=track_start_last; i++) { + if ((player.currFrame + 150=track_start[i])) { + // track found, calculate relative position + track = i; + FRAMES_TO_MSF(player.currFrame + 150-track_start[i],&relPos.min,&relPos.sec,&relPos.fr); + break; + } + } + } + + return true; + } CDROM_SUB_Q_DATA_FORMAT insub; SUB_Q_CHANNEL_DATA sub; @@ -102,7 +294,6 @@ bool CDROM_Interface_Ioctl::GetAudioSub(unsigned char& attr, unsigned char& trac BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub), &byteCount,NULL); -// Close(); if (!bStat) return false; attr = (sub.CurrentPosition.Control << 4) & 0xEF; @@ -114,13 +305,40 @@ bool CDROM_Interface_Ioctl::GetAudioSub(unsigned char& attr, unsigned char& trac absPos.min = sub.CurrentPosition.AbsoluteAddress[1]; absPos.sec = sub.CurrentPosition.AbsoluteAddress[2]; absPos.fr = sub.CurrentPosition.AbsoluteAddress[3]; - - return true; -}; -bool CDROM_Interface_Ioctl::GetAudioStatus(bool& playing, bool& pause) -{ -// Open(); + if (use_mciplay) { + int cur_pos; + if (!mci_CDPosition(&cur_pos)) { + // absolute position read, try to calculate the track-relative position + if (GetAudioTracksAll()) { + for (int i=track_start_first; i<=track_start_last; i++) { + if ((cur_pos=track_start[i])) { + // track found, calculate relative position + FRAMES_TO_MSF(cur_pos-track_start[i],&relPos.min,&relPos.sec,&relPos.fr); + break; + } + } + } + FRAMES_TO_MSF(cur_pos,&absPos.min,&absPos.sec,&absPos.fr); + } + } + + return true; +} + +bool CDROM_Interface_Ioctl::GetAudioStatus(bool& playing, bool& pause) { + if (use_mciplay) { + int status = mci_CDStatus(); + if (status<0) return false; + playing = (status==2); + pause = (status==3); + return true; + } + if (use_dxplay) { + playing = player.isPlaying; + pause = player.isPaused; + return true; + } CDROM_SUB_Q_DATA_FORMAT insub; SUB_Q_CHANNEL_DATA sub; @@ -130,17 +348,15 @@ bool CDROM_Interface_Ioctl::GetAudioStatus(bool& playing, bool& pause) BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub), &byteCount,NULL); -// Close(); if (!bStat) return false; playing = (sub.CurrentPosition.Header.AudioStatus == AUDIO_STATUS_IN_PROGRESS); pause = (sub.CurrentPosition.Header.AudioStatus == AUDIO_STATUS_PAUSED); return true; -}; +} -bool CDROM_Interface_Ioctl::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) -{ +bool CDROM_Interface_Ioctl::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) { // Seems not possible to get this values using ioctl... int track1,track2; TMSF leadOut; @@ -149,20 +365,41 @@ bool CDROM_Interface_Ioctl::GetMediaTrayStatus(bool& mediaPresent, bool& mediaCh trayOpen = !mediaPresent; mediaChanged = (oldLeadOut.min!=leadOut.min) || (oldLeadOut.sec!=leadOut.sec) || (oldLeadOut.fr!=leadOut.fr); if (mediaChanged) { - // Open new media - Close(); Open(); - }; + Close(); + if (use_mciplay) mci_CDClose(); + // Open new medium + Open(); + + // check this (what to do if cd is ejected): + use_mciplay = false; + if (!mci_CDOpen(pathname[4])) use_mciplay = true; + track_start_valid = false; + } // Save old values oldLeadOut.min = leadOut.min; oldLeadOut.sec = leadOut.sec; oldLeadOut.fr = leadOut.fr; // always success return true; -}; +} + +bool CDROM_Interface_Ioctl::PlayAudioSector (unsigned long start,unsigned long len) { + if (use_mciplay) { + if (!mci_CDPlay(start+150, len)) return true; + if (!mci_CDPlay(start+150, len-1)) return true; + return false; + } + if (use_dxplay) { + SDL_mutexP(player.mutex); + player.cd = this; + player.currFrame = start; + player.targetFrame = start + len; + player.isPlaying = true; + player.isPaused = false; + SDL_mutexV(player.mutex); + return true; + } -bool CDROM_Interface_Ioctl::PlayAudioSector (unsigned long start,unsigned long len) -{ -// Open(); CDROM_PLAY_AUDIO_MSF audio; DWORD byteCount; // Start @@ -178,53 +415,90 @@ bool CDROM_Interface_Ioctl::PlayAudioSector (unsigned long start,unsigned long l BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_PLAY_AUDIO_MSF, &audio, sizeof(audio), NULL, 0, &byteCount,NULL); -// Close(); return bStat>0; -}; +} + +bool CDROM_Interface_Ioctl::PauseAudio(bool resume) { + if (use_mciplay) { + if (resume) { + if (!mci_CDResume()) return true; + } else { + if (!mci_CDPause()) return true; + } + return false; + } + if (use_dxplay) { + player.isPaused = !resume; + return true; + } -bool CDROM_Interface_Ioctl::PauseAudio(bool resume) -{ -// Open(); BOOL bStat; DWORD byteCount; if (resume) bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RESUME_AUDIO, NULL, 0, NULL, 0, &byteCount,NULL); else bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_PAUSE_AUDIO, NULL, 0, NULL, 0, &byteCount,NULL); -// Close(); return bStat>0; -}; +} + +bool CDROM_Interface_Ioctl::StopAudio(void) { + if (use_mciplay) { + if (!mci_CDStop()) return true; + return false; + } + if (use_dxplay) { + player.isPlaying = false; + player.isPaused = false; + return true; + } -bool CDROM_Interface_Ioctl::StopAudio(void) -{ -// Open(); BOOL bStat; DWORD byteCount; bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_STOP_AUDIO, NULL, 0, NULL, 0, &byteCount,NULL); -// Close(); return bStat>0; -}; +} -bool CDROM_Interface_Ioctl::LoadUnloadMedia(bool unload) -{ -// Open(); +bool CDROM_Interface_Ioctl::LoadUnloadMedia(bool unload) { BOOL bStat; DWORD byteCount; if (unload) bStat = DeviceIoControl(hIOCTL,IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, &byteCount,NULL); else bStat = DeviceIoControl(hIOCTL,IOCTL_STORAGE_LOAD_MEDIA, NULL, 0, NULL, 0, &byteCount,NULL); -// Close(); + track_start_valid = false; return bStat>0; -}; +} -bool CDROM_Interface_Ioctl::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num) -{ +bool CDROM_Interface_Ioctl::ReadSector(Bit8u *buffer, bool raw, unsigned long sector) { BOOL bStat; DWORD byteCount = 0; -// Open(); + Bitu buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; + + if (!raw) { + // Cooked + int success = 0; + DWORD newPos = SetFilePointer(hIOCTL, sector*COOKED_SECTOR_SIZE, 0, FILE_BEGIN); + if (newPos != 0xFFFFFFFF) success = ReadFile(hIOCTL, buffer, buflen, &byteCount, NULL); + bStat = (success!=0); + } else { + // Raw + RAW_READ_INFO in; + in.DiskOffset.LowPart = sector*COOKED_SECTOR_SIZE; + in.DiskOffset.HighPart = 0; + in.SectorCount = 1; + in.TrackMode = CDDA; + bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RAW_READ, &in, sizeof(in), + buffer, buflen, &byteCount,NULL); + } + + return (byteCount==buflen) && (bStat>0); +} + +bool CDROM_Interface_Ioctl::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num) { + BOOL bStat; + DWORD byteCount = 0; Bitu buflen = raw ? num*RAW_SECTOR_SIZE : num*COOKED_SECTOR_SIZE; Bit8u* bufdata = new Bit8u[buflen]; @@ -238,14 +512,13 @@ bool CDROM_Interface_Ioctl::ReadSectors(PhysPt buffer, bool raw, unsigned long s } else { // Raw RAW_READ_INFO in; - in.DiskOffset.LowPart = sector; + in.DiskOffset.LowPart = sector*COOKED_SECTOR_SIZE; in.DiskOffset.HighPart = 0; in.SectorCount = num; in.TrackMode = CDDA; bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RAW_READ, &in, sizeof(in), bufdata, buflen, &byteCount,NULL); } -// Close(); MEM_BlockWrite(buffer,bufdata,buflen); delete[] bufdata; @@ -253,23 +526,68 @@ bool CDROM_Interface_Ioctl::ReadSectors(PhysPt buffer, bool raw, unsigned long s return (byteCount==buflen) && (bStat>0); } -bool CDROM_Interface_Ioctl::SetDevice(char* path, int forceCD) -{ +void CDROM_Interface_Ioctl::dx_CDAudioCallBack(Bitu len) { + len *= 4; // 16 bit, stereo + if (!len) return; + if (!player.isPlaying || player.isPaused) { + player.channel->AddSilence(); + return; + } + SDL_mutexP(player.mutex); + while (player.bufLen < (Bits)len) { + bool success; + if (player.targetFrame > player.currFrame) + success = player.cd->ReadSector(&player.buffer[player.bufLen], true, player.currFrame); + else success = false; + + if (success) { + player.currFrame++; + player.bufLen += RAW_SECTOR_SIZE; + } else { + memset(&player.buffer[player.bufLen], 0, len - player.bufLen); + player.bufLen = len; + player.isPlaying = false; + } + } + SDL_mutexV(player.mutex); + player.channel->AddSamples_s16(len/4,(Bit16s *)player.buffer); + memmove(player.buffer, &player.buffer[len], player.bufLen - len); + player.bufLen -= len; +} + +bool CDROM_Interface_Ioctl::SetDevice(char* path, int forceCD) { + mci_devid = 0; + use_mciplay = false; + use_dxplay = false; + track_start_valid = false; if (GetDriveType(path)==DRIVE_CDROM) { char letter [3] = { 0, ':', 0 }; letter[0] = path[0]; strcpy(pathname,"\\\\.\\"); strcat(pathname,letter); if (Open()) { -// Close(); + if (cdioctl_cda_selected == CDIOCTL_CDA_MCI) { + // check if MCI-interface can be used for cd audio + if (!mci_CDOpen(path[0])) use_mciplay = true; + } + if (!use_mciplay) { + if (cdioctl_cda_selected == CDIOCTL_CDA_DX) { + // use direct sector access for cd audio routines + player.mutex = SDL_CreateMutex(); + if (!player.channel) { + player.channel = MIXER_AddChannel(&dx_CDAudioCallBack, 44100, "CDAUDIO"); + } + player.channel->Enable(true); + use_dxplay = true; + } + } return true; }; } return false; } -bool CDROM_Interface_Ioctl::Open(void) -{ +bool CDROM_Interface_Ioctl::Open(void) { hIOCTL = CreateFile(pathname, // drive to open GENERIC_READ, // read access FILE_SHARE_READ | // share mode @@ -279,11 +597,10 @@ bool CDROM_Interface_Ioctl::Open(void) 0, // file attributes NULL); // do not copy file attributes return (hIOCTL!=INVALID_HANDLE_VALUE); -}; +} -void CDROM_Interface_Ioctl::Close(void) -{ +void CDROM_Interface_Ioctl::Close(void) { CloseHandle(hIOCTL); -}; +} #endif diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index cc185918..55e942ed 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_mscdex.cpp,v 1.55 2008-09-07 10:55:14 c2woody Exp $ */ +/* $Id: dos_mscdex.cpp,v 1.56 2008-11-06 19:31:21 c2woody Exp $ */ #include #include @@ -173,10 +173,6 @@ CMscdex::CMscdex(void) { }; CMscdex::~CMscdex(void) { -/* if (defaultBufSeg!=0) { - DOS_FreeMemory(defaultBufSeg); // can't free that - defaultBufSeg = 0; - } */ defaultBufSeg = 0; for (Bit16u i=0; i4)) { // only WIN NT/200/XP - if (useCdromInterface==CDROM_USE_IOCTL) { - cdrom[numDrives] = new CDROM_Interface_Ioctl(); + if (useCdromInterface==CDROM_USE_IOCTL_DIO) { + cdrom[numDrives] = new CDROM_Interface_Ioctl(CDROM_Interface_Ioctl::CDIOCTL_CDA_DIO); LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: IOCTL Interface."); break; } + if (useCdromInterface==CDROM_USE_IOCTL_DX) { + cdrom[numDrives] = new CDROM_Interface_Ioctl(CDROM_Interface_Ioctl::CDIOCTL_CDA_DX); + LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: IOCTL Interface (digital audio extraction)."); + break; + } + if (useCdromInterface==CDROM_USE_IOCTL_MCI) { + cdrom[numDrives] = new CDROM_Interface_Ioctl(CDROM_Interface_Ioctl::CDIOCTL_CDA_MCI); + LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: IOCTL Interface (media control interface)."); + break; + } } if (useCdromInterface==CDROM_USE_ASPI) { - // all Wins - ASPI + // all Wins - ASPI cdrom[numDrives] = new CDROM_Interface_Aspi(); LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: ASPI Interface."); break; diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 7c6963f1..60710464 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.88 2008-09-26 17:21:17 qbix79 Exp $ */ +/* $Id: dos_programs.cpp,v 1.89 2008-11-06 19:31:21 c2woody Exp $ */ #include "dosbox.h" #include @@ -263,12 +263,32 @@ public: int error; if (cmd->FindExist("-aspi",false)) { MSCDEX_SetCDInterface(CDROM_USE_ASPI, num); - } else if (cmd->FindExist("-ioctl",false)) { - MSCDEX_SetCDInterface(CDROM_USE_IOCTL, num); + } else if (cmd->FindExist("-ioctl_dio",false)) { + MSCDEX_SetCDInterface(CDROM_USE_IOCTL_DIO, num); + } else if (cmd->FindExist("-ioctl_dx",false)) { + MSCDEX_SetCDInterface(CDROM_USE_IOCTL_DX, num); +#if defined (WIN32) + } else if (cmd->FindExist("-ioctl_mci",false)) { + MSCDEX_SetCDInterface(CDROM_USE_IOCTL_MCI, num); +#endif } else if (cmd->FindExist("-noioctl",false)) { MSCDEX_SetCDInterface(CDROM_USE_SDL, num); } else { - MSCDEX_SetCDInterface(CDROM_USE_IOCTL, num); +#if defined (WIN32) +/* // Check OS + OSVERSIONINFO osi; + osi.dwOSVersionInfoSize = sizeof(osi); + GetVersionEx(&osi); + if ((osi.dwPlatformId==VER_PLATFORM_WIN32_NT) && (osi.dwMajorVersion>5)) { + // Vista/above + MSCDEX_SetCDInterface(CDROM_USE_IOCTL_DX, num); + } else { + MSCDEX_SetCDInterface(CDROM_USE_IOCTL_DIO, num); + } */ + MSCDEX_SetCDInterface(CDROM_USE_IOCTL_DX, num); +#else + MSCDEX_SetCDInterface(CDROM_USE_IOCTL_DIO, num); +#endif } newdrive = new cdromDrive(drive,temp_line.c_str(),sizes[0],bit8size,sizes[2],0,mediaid,error); // Check Mscdex, if it worked out... @@ -515,19 +535,17 @@ public: FILE *usefile_1=NULL; FILE *usefile_2=NULL; - Bitu i; + Bitu i=0; Bit32u floppysize; Bit32u rombytesize_1=0; Bit32u rombytesize_2=0; - Bit8u drive; + Bit8u drive = 'A'; std::string cart_cmd=""; if(!cmd->GetCount()) { printError(); return; } - i=0; - drive = 'A'; while(iGetCount()) { if(cmd->FindCommand(i+1, temp_line)) { if((temp_line == "-l") || (temp_line == "-L")) {