DOSBox-X
|
00001 /* 00002 * Copyright (C) 2002-2020 The DOSBox Team 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License along 00015 * with this program; if not, write to the Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 00020 #if defined (WIN32) && 0 00021 00022 // ***************************************************************** 00023 // Windows IOCTL functions (not suitable for 95/98/Me) 00024 // ***************************************************************** 00025 00026 #include <windows.h> 00027 #include <io.h> 00028 00029 #if (defined (_MSC_VER)) || (defined __MINGW64_VERSION_MAJOR) 00030 #include <winioctl.h> // Ioctl stuff 00031 //#include <ntddcdrm.h> // Ioctl stuff 00032 #else 00033 #include "ddk/ntddcdrm.h" // Ioctl stuff 00034 #endif 00035 00036 #include <mmsystem.h> 00037 00038 #include "cdrom.h" 00039 00040 // for a more sophisticated implementation of the mci cdda functionality 00041 // see the SDL sources, which the mci_ functions are based on 00042 00043 /* General ioctl() CD-ROM command function */ 00044 bool CDROM_Interface_Ioctl::mci_CDioctl(UINT msg, DWORD flags, void *arg) { 00045 MCIERROR mci_error = mciSendCommand(mci_devid, msg, flags, (DWORD_PTR)arg); 00046 if (mci_error!=MMSYSERR_NOERROR) { 00047 char error[256]; 00048 mciGetErrorString(mci_error, error, 256); 00049 LOG_MSG("mciSendCommand() error: %s", error); 00050 return true; 00051 } 00052 return false; 00053 } 00054 00055 bool CDROM_Interface_Ioctl::mci_CDOpen(char drive) { 00056 MCI_OPEN_PARMS mci_open; 00057 MCI_SET_PARMS mci_set; 00058 char device[3]; 00059 DWORD flags; 00060 00061 /* Open the requested device */ 00062 mci_open.lpstrDeviceType = (LPCSTR) MCI_DEVTYPE_CD_AUDIO; 00063 device[0] = drive; 00064 device[1] = ':'; 00065 device[2] = '\0'; 00066 mci_open.lpstrElementName = device; 00067 flags = (MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID|MCI_OPEN_SHAREABLE|MCI_OPEN_ELEMENT); 00068 if (mci_CDioctl(MCI_OPEN, flags, &mci_open)) { 00069 flags &= ~MCI_OPEN_SHAREABLE; 00070 if (mci_CDioctl(MCI_OPEN, flags, &mci_open)) { 00071 return true; 00072 } 00073 } 00074 mci_devid = mci_open.wDeviceID; 00075 00076 /* Set the minute-second-frame time format */ 00077 mci_set.dwTimeFormat = MCI_FORMAT_MSF; 00078 mci_CDioctl(MCI_SET, MCI_SET_TIME_FORMAT, &mci_set); 00079 00080 return false; 00081 } 00082 00083 bool CDROM_Interface_Ioctl::mci_CDClose(void) { 00084 return mci_CDioctl(MCI_CLOSE, MCI_WAIT, NULL); 00085 } 00086 00087 bool CDROM_Interface_Ioctl::mci_CDPlay(int start, int length) { 00088 DWORD flags = MCI_FROM | MCI_TO | MCI_NOTIFY; 00089 MCI_PLAY_PARMS mci_play; 00090 mci_play.dwCallback = 0; 00091 00092 int m, s, f; 00093 FRAMES_TO_MSF(start, &m, &s, &f); 00094 mci_play.dwFrom = MCI_MAKE_MSF(m, s, f); 00095 00096 FRAMES_TO_MSF(start+length, &m, &s, &f); 00097 mci_play.dwTo = MCI_MAKE_MSF(m, s, f); 00098 00099 return mci_CDioctl(MCI_PLAY, flags, &mci_play); 00100 } 00101 00102 bool CDROM_Interface_Ioctl::mci_CDPause(void) { 00103 return mci_CDioctl(MCI_PAUSE, MCI_WAIT, NULL); 00104 } 00105 00106 bool CDROM_Interface_Ioctl::mci_CDResume(void) { 00107 return mci_CDioctl(MCI_RESUME, MCI_WAIT, NULL); 00108 } 00109 00110 bool CDROM_Interface_Ioctl::mci_CDStop(void) { 00111 return mci_CDioctl(MCI_STOP, MCI_WAIT, NULL); 00112 } 00113 00114 int CDROM_Interface_Ioctl::mci_CDStatus(void) { 00115 int status; 00116 MCI_STATUS_PARMS mci_status; 00117 00118 DWORD flags = MCI_STATUS_ITEM | MCI_WAIT; 00119 mci_status.dwItem = MCI_STATUS_MODE; 00120 if (mci_CDioctl(MCI_STATUS, flags, &mci_status)) { 00121 status = -1; 00122 } else { 00123 switch (mci_status.dwReturn) { 00124 case MCI_MODE_NOT_READY: 00125 case MCI_MODE_OPEN: 00126 status = 0; 00127 break; 00128 case MCI_MODE_STOP: 00129 status = 1; 00130 break; 00131 case MCI_MODE_PLAY: 00132 status = 2; 00133 break; 00134 case MCI_MODE_PAUSE: 00135 status = 3; 00136 break; 00137 default: 00138 status = -1; 00139 break; 00140 } 00141 } 00142 00143 return status; 00144 } 00145 00146 bool CDROM_Interface_Ioctl::mci_CDPosition(int *position) { 00147 *position = 0; 00148 00149 DWORD flags = MCI_STATUS_ITEM | MCI_WAIT; 00150 00151 MCI_STATUS_PARMS mci_status; 00152 mci_status.dwItem = MCI_STATUS_MODE; 00153 if (mci_CDioctl(MCI_STATUS, flags, &mci_status)) return true; 00154 switch (mci_status.dwReturn) { 00155 case MCI_MODE_NOT_READY: 00156 case MCI_MODE_OPEN: 00157 case MCI_MODE_STOP: 00158 return true; // not ready/undefined status 00159 case MCI_MODE_PLAY: 00160 case MCI_MODE_PAUSE: 00161 mci_status.dwItem = MCI_STATUS_POSITION; 00162 if (!mci_CDioctl(MCI_STATUS, flags, &mci_status)) { 00163 *position = MSF_TO_FRAMES( 00164 MCI_MSF_MINUTE(mci_status.dwReturn), 00165 MCI_MSF_SECOND(mci_status.dwReturn), 00166 MCI_MSF_FRAME(mci_status.dwReturn)); 00167 } 00168 return false; // no error, position read 00169 default: 00170 break; 00171 } 00172 return false; 00173 } 00174 00175 00176 CDROM_Interface_Ioctl::dxPlayer CDROM_Interface_Ioctl::player = { 00177 NULL, NULL, NULL, {0}, 0, 0, 0, false, false, false, {0} }; 00178 00179 CDROM_Interface_Ioctl::CDROM_Interface_Ioctl(cdioctl_cdatype ioctl_cda) { 00180 pathname[0] = 0; 00181 hIOCTL = INVALID_HANDLE_VALUE; 00182 memset(&oldLeadOut,0,sizeof(oldLeadOut)); 00183 cdioctl_cda_selected = ioctl_cda; 00184 } 00185 00186 CDROM_Interface_Ioctl::~CDROM_Interface_Ioctl() { 00187 StopAudio(); 00188 if (use_mciplay) mci_CDStop(); 00189 Close(); 00190 if (use_mciplay) mci_CDClose(); 00191 } 00192 00193 bool CDROM_Interface_Ioctl::GetUPC(unsigned char& attr, char* upc) { 00194 // FIXME : To Do 00195 return true; 00196 } 00197 00198 bool CDROM_Interface_Ioctl::GetAudioTracks(int& stTrack, int& endTrack, TMSF& leadOut) { 00199 CDROM_TOC toc; 00200 DWORD byteCount; 00201 BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL, 0, 00202 &toc, sizeof(toc), &byteCount,NULL); 00203 if (!bStat) return false; 00204 00205 stTrack = toc.FirstTrack; 00206 endTrack = toc.LastTrack; 00207 leadOut.min = toc.TrackData[endTrack].Address[1]; 00208 leadOut.sec = toc.TrackData[endTrack].Address[2]; 00209 leadOut.fr = toc.TrackData[endTrack].Address[3]; 00210 00211 if ((use_mciplay || use_dxplay) && (!track_start_valid)) { 00212 Bits track_num = 0; 00213 // get track start address of all tracks 00214 for (Bits i=toc.FirstTrack; i<=toc.LastTrack+1; i++) { 00215 if (((toc.TrackData[i].Control&1)==0) || (i==toc.LastTrack+1)) { 00216 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; 00217 track_start[track_num] += 150; 00218 track_num++; 00219 } 00220 } 00221 track_start_first = 0; 00222 track_start_last = track_num-1; 00223 track_start_valid = true; 00224 } 00225 00226 return true; 00227 } 00228 00229 bool CDROM_Interface_Ioctl::GetAudioTrackInfo(int track, TMSF& start, unsigned char& attr) { 00230 CDROM_TOC toc; 00231 DWORD byteCount; 00232 BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL, 0, 00233 &toc, sizeof(toc), &byteCount,NULL); 00234 if (!bStat) return false; 00235 00236 attr = (toc.TrackData[track-1].Control << 4) & 0xEF; 00237 start.min = toc.TrackData[track-1].Address[1]; 00238 start.sec = toc.TrackData[track-1].Address[2]; 00239 start.fr = toc.TrackData[track-1].Address[3]; 00240 return true; 00241 } 00242 00243 bool CDROM_Interface_Ioctl::GetAudioTracksAll(void) { 00244 if (track_start_valid) return true; 00245 00246 CDROM_TOC toc; 00247 DWORD byteCount; 00248 BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL, 0, 00249 &toc, sizeof(toc), &byteCount,NULL); 00250 if (!bStat) return false; 00251 00252 Bits track_num = 0; 00253 // get track start address of all tracks 00254 for (Bits i=toc.FirstTrack; i<=toc.LastTrack+1; i++) { 00255 if (((toc.TrackData[i].Control&1)==0) || (i==toc.LastTrack+1)) { 00256 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; 00257 track_start[track_num] += 150; 00258 track_num++; 00259 } 00260 } 00261 track_start_first = 0; 00262 track_start_last = track_num-1; 00263 track_start_valid = true; 00264 return true; 00265 } 00266 00267 bool CDROM_Interface_Ioctl::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) { 00268 if (use_dxplay) { 00269 track = 1; 00270 FRAMES_TO_MSF(player.currFrame + 150, &absPos.min, &absPos.sec, &absPos.fr); 00271 FRAMES_TO_MSF(player.currFrame + 150, &relPos.min, &relPos.sec, &relPos.fr); 00272 00273 if (GetAudioTracksAll()) { 00274 // get track number from current frame 00275 for (int i=track_start_first; i<=track_start_last; i++) { 00276 if ((player.currFrame + 150<track_start[i+1]) && (player.currFrame + 150>=track_start[i])) { 00277 // track found, calculate relative position 00278 track = i; 00279 FRAMES_TO_MSF(player.currFrame + 150-track_start[i],&relPos.min,&relPos.sec,&relPos.fr); 00280 break; 00281 } 00282 } 00283 } 00284 00285 return true; 00286 } 00287 00288 CDROM_SUB_Q_DATA_FORMAT insub; 00289 SUB_Q_CHANNEL_DATA sub; 00290 DWORD byteCount; 00291 00292 insub.Format = IOCTL_CDROM_CURRENT_POSITION; 00293 00294 BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), 00295 &sub, sizeof(sub), &byteCount,NULL); 00296 if (!bStat) return false; 00297 00298 attr = (sub.CurrentPosition.Control << 4) & 0xEF; 00299 track = sub.CurrentPosition.TrackNumber; 00300 index = sub.CurrentPosition.IndexNumber; 00301 relPos.min = sub.CurrentPosition.TrackRelativeAddress[1]; 00302 relPos.sec = sub.CurrentPosition.TrackRelativeAddress[2]; 00303 relPos.fr = sub.CurrentPosition.TrackRelativeAddress[3]; 00304 absPos.min = sub.CurrentPosition.AbsoluteAddress[1]; 00305 absPos.sec = sub.CurrentPosition.AbsoluteAddress[2]; 00306 absPos.fr = sub.CurrentPosition.AbsoluteAddress[3]; 00307 00308 if (use_mciplay) { 00309 int cur_pos; 00310 if (!mci_CDPosition(&cur_pos)) { 00311 // absolute position read, try to calculate the track-relative position 00312 if (GetAudioTracksAll()) { 00313 for (int i=track_start_first; i<=track_start_last; i++) { 00314 if ((cur_pos<track_start[i+1]) && (cur_pos>=track_start[i])) { 00315 // track found, calculate relative position 00316 FRAMES_TO_MSF(cur_pos-track_start[i],&relPos.min,&relPos.sec,&relPos.fr); 00317 break; 00318 } 00319 } 00320 } 00321 FRAMES_TO_MSF(cur_pos,&absPos.min,&absPos.sec,&absPos.fr); 00322 } 00323 } 00324 00325 return true; 00326 } 00327 00328 bool CDROM_Interface_Ioctl::GetAudioStatus(bool& playing, bool& pause) { 00329 if (use_mciplay) { 00330 int status = mci_CDStatus(); 00331 if (status<0) return false; 00332 playing = (status==2); 00333 pause = (status==3); 00334 return true; 00335 } 00336 if (use_dxplay) { 00337 playing = player.isPlaying; 00338 pause = player.isPaused; 00339 return true; 00340 } 00341 00342 CDROM_SUB_Q_DATA_FORMAT insub; 00343 SUB_Q_CHANNEL_DATA sub; 00344 DWORD byteCount; 00345 00346 insub.Format = IOCTL_CDROM_CURRENT_POSITION; 00347 00348 BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), 00349 &sub, sizeof(sub), &byteCount,NULL); 00350 if (!bStat) return false; 00351 00352 playing = (sub.CurrentPosition.Header.AudioStatus == AUDIO_STATUS_IN_PROGRESS); 00353 pause = (sub.CurrentPosition.Header.AudioStatus == AUDIO_STATUS_PAUSED); 00354 00355 return true; 00356 } 00357 00358 bool CDROM_Interface_Ioctl::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) { 00359 // Seems not possible to get this values using ioctl... 00360 int track1,track2; 00361 TMSF leadOut; 00362 // If we can read, there's a media 00363 mediaPresent = GetAudioTracks(track1, track2, leadOut), 00364 trayOpen = !mediaPresent; 00365 mediaChanged = (oldLeadOut.min!=leadOut.min) || (oldLeadOut.sec!=leadOut.sec) || (oldLeadOut.fr!=leadOut.fr); 00366 if (mediaChanged) { 00367 Close(); 00368 if (use_mciplay) mci_CDClose(); 00369 // Open new medium 00370 Open(); 00371 00372 if (cdioctl_cda_selected == CDIOCTL_CDA_MCI) { 00373 // check this (what to do if cd is ejected): 00374 use_mciplay = false; 00375 if (!mci_CDOpen(pathname[4])) use_mciplay = true; 00376 } 00377 track_start_valid = false; 00378 } 00379 // Save old values 00380 oldLeadOut.min = leadOut.min; 00381 oldLeadOut.sec = leadOut.sec; 00382 oldLeadOut.fr = leadOut.fr; 00383 // always success 00384 return true; 00385 } 00386 00387 bool CDROM_Interface_Ioctl::PlayAudioSector (unsigned long start,unsigned long len) { 00388 if (use_mciplay) { 00389 if (!mci_CDPlay(start+150, len)) return true; 00390 if (!mci_CDPlay(start+150, len-1)) return true; 00391 return false; 00392 } 00393 if (use_dxplay) { 00394 SDL_mutexP(player.mutex); 00395 player.cd = this; 00396 player.currFrame = start; 00397 player.targetFrame = start + len; 00398 player.isPlaying = true; 00399 player.isPaused = false; 00400 SDL_mutexV(player.mutex); 00401 return true; 00402 } 00403 00404 CDROM_PLAY_AUDIO_MSF audio; 00405 DWORD byteCount; 00406 // Start 00407 unsigned long addr = start + 150; 00408 audio.StartingF = (UCHAR)(addr%75); addr/=75; 00409 audio.StartingS = (UCHAR)(addr%60); 00410 audio.StartingM = (UCHAR)(addr/60); 00411 // End 00412 addr = start + len + 150; 00413 audio.EndingF = (UCHAR)(addr%75); addr/=75; 00414 audio.EndingS = (UCHAR)(addr%60); 00415 audio.EndingM = (UCHAR)(addr/60); 00416 00417 BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_PLAY_AUDIO_MSF, &audio, sizeof(audio), 00418 NULL, 0, &byteCount,NULL); 00419 return bStat>0; 00420 } 00421 00422 bool CDROM_Interface_Ioctl::PauseAudio(bool resume) { 00423 if (use_mciplay) { 00424 if (resume) { 00425 if (!mci_CDResume()) return true; 00426 } else { 00427 if (!mci_CDPause()) return true; 00428 } 00429 return false; 00430 } 00431 if (use_dxplay) { 00432 player.isPaused = !resume; 00433 return true; 00434 } 00435 00436 BOOL bStat; 00437 DWORD byteCount; 00438 if (resume) bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RESUME_AUDIO, NULL, 0, 00439 NULL, 0, &byteCount,NULL); 00440 else bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_PAUSE_AUDIO, NULL, 0, 00441 NULL, 0, &byteCount,NULL); 00442 return bStat>0; 00443 } 00444 00445 bool CDROM_Interface_Ioctl::StopAudio(void) { 00446 if (use_mciplay) { 00447 if (!mci_CDStop()) return true; 00448 return false; 00449 } 00450 if (use_dxplay) { 00451 player.isPlaying = false; 00452 player.isPaused = false; 00453 return true; 00454 } 00455 00456 BOOL bStat; 00457 DWORD byteCount; 00458 bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_STOP_AUDIO, NULL, 0, 00459 NULL, 0, &byteCount,NULL); 00460 return bStat>0; 00461 } 00462 00463 void CDROM_Interface_Ioctl::ChannelControl(TCtrl ctrl) 00464 { 00465 player.ctrlUsed = (ctrl.out[0]!=0 || ctrl.out[1]!=1 || ctrl.vol[0]<0xfe || ctrl.vol[1]<0xfe); 00466 player.ctrlData = ctrl; 00467 } 00468 00469 bool CDROM_Interface_Ioctl::LoadUnloadMedia(bool unload) { 00470 BOOL bStat; 00471 DWORD byteCount; 00472 if (unload) bStat = DeviceIoControl(hIOCTL,IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, 00473 NULL, 0, &byteCount,NULL); 00474 else bStat = DeviceIoControl(hIOCTL,IOCTL_STORAGE_LOAD_MEDIA, NULL, 0, 00475 NULL, 0, &byteCount,NULL); 00476 track_start_valid = false; 00477 return bStat>0; 00478 } 00479 00480 bool CDROM_Interface_Ioctl::ReadSector(Bit8u *buffer, bool raw, unsigned long sector) { 00481 BOOL bStat; 00482 DWORD byteCount = 0; 00483 00484 Bitu buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; 00485 00486 if (!raw) { 00487 // Cooked 00488 int success = 0; 00489 DWORD newPos = SetFilePointer(hIOCTL, sector*COOKED_SECTOR_SIZE, 0, FILE_BEGIN); 00490 if (newPos != 0xFFFFFFFF) success = ReadFile(hIOCTL, buffer, buflen, &byteCount, NULL); 00491 bStat = (success!=0); 00492 } else { 00493 // Raw 00494 RAW_READ_INFO in; 00495 in.DiskOffset.LowPart = sector*COOKED_SECTOR_SIZE; 00496 in.DiskOffset.HighPart = 0; 00497 in.SectorCount = 1; 00498 in.TrackMode = CDDA; 00499 bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RAW_READ, &in, sizeof(in), 00500 buffer, buflen, &byteCount,NULL); 00501 } 00502 00503 return (byteCount==buflen) && (bStat>0); 00504 } 00505 00506 bool CDROM_Interface_Ioctl::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num) { 00507 BOOL bStat; 00508 DWORD byteCount = 0; 00509 00510 Bitu buflen = raw ? num*RAW_SECTOR_SIZE : num*COOKED_SECTOR_SIZE; 00511 Bit8u* bufdata = new Bit8u[buflen]; 00512 00513 if (!raw) { 00514 // Cooked 00515 int success = 0; 00516 DWORD newPos = SetFilePointer(hIOCTL, sector*COOKED_SECTOR_SIZE, 0, FILE_BEGIN); 00517 if (newPos != 0xFFFFFFFF) success = ReadFile(hIOCTL, bufdata, buflen, &byteCount, NULL); 00518 bStat = (success!=0); 00519 } else { 00520 // Raw 00521 RAW_READ_INFO in; 00522 in.DiskOffset.LowPart = sector*COOKED_SECTOR_SIZE; 00523 in.DiskOffset.HighPart = 0; 00524 in.SectorCount = num; 00525 in.TrackMode = CDDA; 00526 bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RAW_READ, &in, sizeof(in), 00527 bufdata, buflen, &byteCount,NULL); 00528 } 00529 00530 MEM_BlockWrite(buffer,bufdata,buflen); 00531 delete[] bufdata; 00532 00533 return (byteCount==buflen) && (bStat>0); 00534 } 00535 00536 void CDROM_Interface_Ioctl::dx_CDAudioCallBack(Bitu len) { 00537 len *= 4; // 16 bit, stereo 00538 if (!len) return; 00539 if (!player.isPlaying || player.isPaused) { 00540 player.channel->AddSilence(); 00541 return; 00542 } 00543 SDL_mutexP(player.mutex); 00544 while (player.bufLen < (Bits)len) { 00545 bool success; 00546 if (player.targetFrame > player.currFrame) 00547 success = player.cd->ReadSector(&player.buffer[player.bufLen], true, player.currFrame); 00548 else success = false; 00549 00550 if (success) { 00551 player.currFrame++; 00552 player.bufLen += RAW_SECTOR_SIZE; 00553 } else { 00554 memset(&player.buffer[player.bufLen], 0, len - player.bufLen); 00555 player.bufLen = len; 00556 player.isPlaying = false; 00557 } 00558 } 00559 SDL_mutexV(player.mutex); 00560 if (player.ctrlUsed) { 00561 Bit16s sample0,sample1; 00562 Bit16s * samples=(Bit16s *)&player.buffer; 00563 for (Bitu pos=0;pos<len/4;pos++) { 00564 sample0=samples[pos*2+player.ctrlData.out[0]]; 00565 sample1=samples[pos*2+player.ctrlData.out[1]]; 00566 samples[pos*2+0]=(Bit16s)(sample0*player.ctrlData.vol[0]/255.0); 00567 samples[pos*2+1]=(Bit16s)(sample1*player.ctrlData.vol[1]/255.0); 00568 } 00569 } 00570 player.channel->AddSamples_s16(len/4,(Bit16s *)player.buffer); 00571 memmove(player.buffer, &player.buffer[len], player.bufLen - len); 00572 player.bufLen -= len; 00573 } 00574 00575 bool CDROM_Interface_Ioctl::SetDevice(char* path, int forceCD) { 00576 mci_devid = 0; 00577 use_mciplay = false; 00578 use_dxplay = false; 00579 track_start_valid = false; 00580 if (GetDriveType(path)==DRIVE_CDROM) { 00581 char letter [3] = { 0, ':', 0 }; 00582 letter[0] = path[0]; 00583 strcpy(pathname,"\\\\.\\"); 00584 strcat(pathname,letter); 00585 if (Open()) { 00586 if (cdioctl_cda_selected == CDIOCTL_CDA_MCI) { 00587 // check if MCI-interface can be used for cd audio 00588 if (!mci_CDOpen(path[0])) use_mciplay = true; 00589 } 00590 if (!use_mciplay) { 00591 if (cdioctl_cda_selected == CDIOCTL_CDA_DX) { 00592 // use direct sector access for cd audio routines 00593 player.mutex = SDL_CreateMutex(); 00594 if (!player.channel) { 00595 player.channel = MIXER_AddChannel(&dx_CDAudioCallBack, 44100, "CDAUDIO"); 00596 } 00597 player.channel->Enable(true); 00598 use_dxplay = true; 00599 } 00600 } 00601 return true; 00602 }; 00603 } 00604 return false; 00605 } 00606 00607 bool CDROM_Interface_Ioctl::Open(void) { 00608 hIOCTL = CreateFile(pathname, // drive to open 00609 GENERIC_READ, // read access 00610 FILE_SHARE_READ | // share mode 00611 FILE_SHARE_WRITE, 00612 NULL, // default security attributes 00613 OPEN_EXISTING, // disposition 00614 0, // file attributes 00615 NULL); // do not copy file attributes 00616 return (hIOCTL!=INVALID_HANDLE_VALUE); 00617 } 00618 00619 void CDROM_Interface_Ioctl::Close(void) { 00620 CloseHandle(hIOCTL); 00621 } 00622 00623 bool CDROM_Interface_Ioctl::ReadSectorsHost(void *buffer, bool raw, unsigned long sector, unsigned long num) 00624 { 00625 return false;/*TODO*/ 00626 }; 00627 00628 #endif