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
This commit is contained in:
parent
c96d1f063e
commit
1bcab407ae
4 changed files with 478 additions and 92 deletions
|
@ -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 */
|
||||
|
|
|
@ -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 <mmsystem.h>
|
||||
|
||||
#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+1]) && (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+1]) && (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
|
||||
|
|
|
@ -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 <string.h>
|
||||
#include <ctype.h>
|
||||
|
@ -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; i<GetNumDrives(); i++) {
|
||||
delete (cdrom)[i];
|
||||
|
@ -266,14 +262,24 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit)
|
|||
GetVersionEx(&osi);
|
||||
if ((osi.dwPlatformId==VER_PLATFORM_WIN32_NT) && (osi.dwMajorVersion>4)) {
|
||||
// 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;
|
||||
|
|
|
@ -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 <stdlib.h>
|
||||
|
@ -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(i<cmd->GetCount()) {
|
||||
if(cmd->FindCommand(i+1, temp_line)) {
|
||||
if((temp_line == "-l") || (temp_line == "-L")) {
|
||||
|
|
Loading…
Add table
Reference in a new issue