diff options
author | Simon Howard | 2008-09-09 18:16:51 +0000 |
---|---|---|
committer | Simon Howard | 2008-09-09 18:16:51 +0000 |
commit | 580372cddbb04538da69a3936f670f7128765c4b (patch) | |
tree | d0c766cade0863a5dbe792f1f941e55d5364492f /src/hexen/i_cdmus.c | |
parent | 3a41ade9fab0556d0d025c0b0e81834436a4f2e8 (diff) | |
download | chocolate-doom-580372cddbb04538da69a3936f670f7128765c4b.tar.gz chocolate-doom-580372cddbb04538da69a3936f670f7128765c4b.tar.bz2 chocolate-doom-580372cddbb04538da69a3936f670f7128765c4b.zip |
Replace Hexen CD music API with SDL-based equivalent (as yet untested).
Subversion-branch: /branches/raven-branch
Subversion-revision: 1217
Diffstat (limited to 'src/hexen/i_cdmus.c')
-rw-r--r-- | src/hexen/i_cdmus.c | 1040 |
1 files changed, 0 insertions, 1040 deletions
diff --git a/src/hexen/i_cdmus.c b/src/hexen/i_cdmus.c deleted file mode 100644 index b6182d91..00000000 --- a/src/hexen/i_cdmus.c +++ /dev/null @@ -1,1040 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// Copyright(C) 1993-1996 Id Software, Inc. -// Copyright(C) 1993-2008 Raven Software -// -// 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 the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -// 02111-1307, USA. -// -//----------------------------------------------------------------------------- - - -// HEADER FILES ------------------------------------------------------------ - -#include <stdio.h> -#include <stdlib.h> -#include <dos.h> -#include <stddef.h> -#include <string.h> -#include "h2def.h" -#include "i_sound.h" - -// MACROS ------------------------------------------------------------------ - -#define MAX_AUDIO_TRACKS 25 -#define MULTIPLEX_INT 0x2f -#define CDROM_GETDRIVECOUNT 0x1500 -#define CDROM_SENDDEVICEREQ 0x1510 -#define CDROM_GETVERSION 0x150c -#define HSG_MODE 0 -#define RED_MODE 1 -#define DRC_IOCTLINPUT 0x03 -#define DRC_IOCTLOUTPUT 0x0c -#define DRC_PLAYAUDIO 0x84 -#define DRC_STOPAUDIO 0x85 -#define DRC_RESUMEAUDIO 0x88 - -#define DPMI_INT 0x31 -#define DPMI_ALLOCREALMEM 0x0100 -#define DPMI_FREEREALMEM 0x0101 -#define DPMI_SIMREALINT 0x0300 - -// IOCTL input commands - -#define ADRDEVHEAD 0 // Return Address of Device Header -#define HEADLOCATION 1 // Location of Head -#define RESERVED 2 // Reserved -#define ERRSTATISTICS 3 // Error Statistics -#define AUDIOCHANINFO 4 // Audio Channel Info -#define READDRVBYTES 5 // Read Drive Bytes -#define DEVICESTATUS 6 // Device Status -#define GETSECTORSIZE 7 // Return Sector Size -#define GETVOLSIZE 8 // Return Volume Size -#define MEDIACHANGED 9 // Media Changed -#define AUDIODISKINFO 10 // Audio Disk Info -#define AUDIOTRACKINFO 11 // Audio Track Info -#define AUDIOQCHANINFO 12 // Audio Q-Channel Info -#define AUDIOSUBINFO 13 // Audio Sub-Channel Info -#define UPCCODE 14 // UPC Code -#define AUDIOSTATUSINFO 15 // Audio Status Info - -// IOCTL output commands - -#define EJECTDISK 0 // Eject Disk -#define DOORLOCK 1 // Lock/Unlock Door -#define RESETDRIVE 2 // Reset Drive -#define AUDIOCHANCONTROL 3 // Audio Channel Control -#define WRITEDEVCONTROL 4 // Write Device Control String -#define CLOSETRAY 5 // Close Tray - -// TYPES ------------------------------------------------------------------- - -typedef signed char S_BYTE; -typedef unsigned char U_BYTE; -typedef signed short S_WORD; -typedef unsigned short U_WORD; -typedef signed int S_LONG; -typedef unsigned int U_LONG; - -typedef struct -{ - U_LONG size; - void **address; - U_WORD *segment; - U_WORD *selector; -} DOSChunk_t; - -typedef struct -{ - U_LONG edi; - U_LONG esi; - U_LONG ebp; - U_LONG reserved; - U_LONG ebx; - U_LONG edx; - U_LONG ecx; - U_LONG eax; - U_WORD flags; - U_WORD es; - U_WORD ds; - U_WORD fs; - U_WORD gs; - U_WORD ip; - U_WORD cs; - U_WORD sp; - U_WORD ss; -} RegBlock_t; - -typedef struct -{ - short lengthMin; - short lengthSec; - int redStart; - int sectorStart; - int sectorLength; -} AudioTrack_t; - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -static U_WORD InputIOCTL(S_WORD request, U_LONG pctrlblk); -static U_WORD OutputIOCTL(S_WORD request, U_LONG pctrlblk); -static U_LONG RedToSectors(U_LONG red); -static int AllocIOCTLBuffers(void); -static void DPMI_SimRealInt(U_LONG intr, RegBlock_t * rBlock); -static void *DPMI_AllocRealMem(U_LONG size, U_WORD * segment, - U_WORD * selector); -static void DPMI_FreeRealMem(U_WORD selector); - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -int cd_Error; - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -static int cd_DriveCount; -static int cd_FirstDrive; -static int cd_CurDrive; -static U_WORD cd_Version; -static int cd_FirstTrack; -static int cd_LastTrack; -static int cd_TrackCount; -static U_WORD cd_LeadOutMin; -static U_WORD cd_LeadOutSec; -static U_LONG cd_LeadOutRed; -static U_LONG cd_LeadOutSector; -static U_LONG cd_IOCTLBufferTotal; -static AudioTrack_t cd_AudioTracks[MAX_AUDIO_TRACKS]; - -static int OkInit = 0; - -static RegBlock_t RegBlock; - -static struct PlayReq_s -{ // CD-ROM Play Audio Device Request Struct - U_BYTE headerSize; - U_BYTE subUnitCode; - U_BYTE command; // = DRC_PLAYAUDIO - U_WORD status; - U_BYTE reserved[8]; - U_BYTE addressMode; - U_LONG startSector; - U_LONG numberToRead; -} *cd_PlayReq; -static U_WORD cd_PlayReqSeg; -static U_WORD cd_PlayReqSel; - -static struct StopReq_s -{ // CD-ROM Stop Audio Device Request Struct - U_BYTE headerSize; - U_BYTE subUnitCode; - U_BYTE command; // = DRC_STOPAUDIO - U_WORD status; - U_BYTE reserved[8]; -} *cd_StopReq; -static U_WORD cd_StopReqSeg; -static U_WORD cd_StopReqSel; - -static struct ResumeReq_s -{ // CD-ROM Resume Audio Device Request Struct - U_BYTE headerSize; - U_BYTE subUnitCode; - U_BYTE command; // = DRC_RESUMEAUDIO - U_WORD status; - U_BYTE reserved[8]; -} *cd_ResumeReq; -static U_WORD cd_ResumeReqSeg; -static U_WORD cd_ResumeReqSel; - -// IOCTL Input command data buffer structures - -static struct IOCTLIn_s -{ // IOCTL Input Struct - U_BYTE headerSize; - U_BYTE subUnitCode; - U_BYTE command; // = DRC_IOCTLINPUT - U_WORD status; - U_BYTE reserved[8]; - U_BYTE mediaDescriptor; - U_LONG ctrlBlkAddr; - U_WORD tranSize; - U_WORD startSector; - U_LONG volPtr; -} *cd_IOCTLIn; -static U_WORD cd_IOCTLInSeg; -static U_WORD cd_IOCTLInSel; - -static struct RAddrDevHead_s -{ - U_BYTE code; // ADRDEVHEAD - U_LONG devHdrAddr; // Address of device header -} *cd_RAddrDevHead; -static U_WORD cd_RAddrDevHeadSeg; -static U_WORD cd_RAddrDevHeadSel; - -static struct LocHead_s -{ - U_BYTE code; // HEADLOCATION - U_BYTE addrMode; // Addressing mode - U_LONG headLocation; // Location of drive head -} *cd_LocHead; -static U_WORD cd_LocHeadSeg; -static U_WORD cd_LocHeadSel; - -static struct ErrStat_s -{ - U_BYTE code; // ERRSTATISTICS - U_BYTE errVal; // Error statistics -} *cd_ErrStat; -static U_WORD cd_ErrStatSeg; -static U_WORD cd_ErrStatSel; - -static struct AudChanInfo_s -{ - U_BYTE code; // AUDIOCHANINFO - U_BYTE inChanOut0; // Input chan(0,1,2,or 3) for output chan 0 - U_BYTE volumeOut0; // Volume control (0-0xff) for output chan 0 - U_BYTE inChanOut1; // Input chan(0,1,2,or 3) for output chan 1 - U_BYTE volumeOut1; // Volume control (0-0xff) for output chan 1 - U_BYTE inChanOut2; // Input chan(0,1,2,or 3) for output chan 2 - U_BYTE volumeOut2; // Volume control (0-0xff) for output chan 2 - U_BYTE inChanOut3; // Input chan(0,1,2,or 3) for output chan 3 - U_BYTE volumeOut3; // Volume control (0-0xff) for output chan 3 -} *cd_AudChanInfo; -static U_WORD cd_AudChanInfoSeg; -static U_WORD cd_AudChanInfoSel; - -static struct RDrvBytes_s -{ - U_BYTE code; // READDRVBYTES - U_BYTE numBytes; // Number of bytes to read - U_BYTE rBuffer[128]; // Read buffer -} *cd_RDrvBytes; -static U_WORD cd_RDrvBytesSeg; -static U_WORD cd_RDrvBytesSel; - -static struct DevStat_s -{ - U_BYTE code; // DEVICESTATUS - U_LONG devParams; // Device parameters -} *cd_DevStat; -static U_WORD cd_DevStatSeg; -static U_WORD cd_DevStatSel; - -static struct SectSize_s -{ - U_BYTE code; // GETSECTORSIZE - U_BYTE readMode; // Read mode - U_WORD sectorSize; // Sector size -} *cd_SectSize; -static U_WORD cd_SectSizeSeg; -static U_WORD cd_SectSizeSel; - -static struct VolSize_s -{ - U_BYTE code; // GETVOLSIZE - U_LONG volumeSize; // Volume size -} *cd_VolSize; -static U_WORD cd_VolSizeSeg; -static U_WORD cd_VolSizeSel; - -static struct MedChng_s -{ - U_BYTE code; // MEDIACHANGED - U_BYTE changed; // Media byte -} *cd_MedChng; -static U_WORD cd_MedChngSeg; -static U_WORD cd_MedChngSel; - -static struct DiskInfo_s -{ - U_BYTE code; // AUDIODISKINFO - U_BYTE lowTrack; // Lowest track number - U_BYTE highTrack; // Highest track number - U_LONG startLeadOut; // Starting point of the lead-out track -} *cd_DiskInfo; -static U_WORD cd_DiskInfoSeg; -static U_WORD cd_DiskInfoSel; - -static struct TrackInfo_s -{ - U_BYTE code; // AUDIOTRACKINFO - U_BYTE track; // Track number - U_LONG start; // Starting point of the track - U_BYTE ctrlInfo; // Track control information -} *cd_TrackInfo; -static U_WORD cd_TrackInfoSeg; -static U_WORD cd_TrackInfoSel; - -static struct QInfo_s -{ - U_BYTE code; // AUDIOQCHANINFO - U_BYTE control; // CONTROL and ADR byte - U_BYTE tno; // Track number (TNO) - U_BYTE index; // (POINT) or Index(X) - U_BYTE min; // (MIN) Running time within a track - U_BYTE sec; // (SEC) " " " " " - U_BYTE frame; // (FRAME) " " " " " - U_BYTE zero; // (ZERO) " " " " " - U_BYTE aMin; // (AMIN) or (PMIN) Running time on disk - U_BYTE aSec; // (ASEC) or (PSEC) " " " " - U_BYTE aFrame; // (AFRAME) or (PFRAME)" " " " -} *cd_QInfo; -static U_WORD cd_QInfoSeg; -static U_WORD cd_QInfoSel; - -static struct SubChanInfo_s -{ - U_BYTE code; // AUDIOSUBINFO - U_LONG startSectAddr; // Starting sector address - U_LONG transAddr; // Transfer address - U_LONG numSects; // Number of sectors to read -} *cd_SubChanInfo; -static U_WORD cd_SubChanInfoSeg; -static U_WORD cd_SubChanInfoSel; - -static struct UPCCode_s -{ - U_BYTE code; // UPCCODE - U_BYTE control; // CONTROL and ADR byte - U_BYTE upc[7]; // UPC/EAN code - U_BYTE zero; // Zero - U_BYTE aFrame; // Aframe -} *cd_UPCCode; -static U_WORD cd_UPCCodeSeg; -static U_WORD cd_UPCCodeSel; - -static struct AudStat_s -{ - U_BYTE code; // AUDIOSTATUSINFO - U_WORD status; // Audio status bits - U_LONG startPlay; // Starting location of last Play/Resume - U_LONG endPlay; // Ending location for last Play/Resume -} *cd_AudStat; -static U_WORD cd_AudStatSeg; -static U_WORD cd_AudStatSel; - -// IOCTL Output command data buffer structures - -static struct IOCTLOut_s -{ // IOCTL Output struct - U_BYTE headerSize; - U_BYTE subUnitCode; - U_BYTE command; // = DRC_IOCTLOUTPUT - U_WORD status; - U_BYTE reserved[8]; - U_BYTE mediaDescriptor; - U_LONG ctrlBlkAddr; - U_WORD tranSize; - U_WORD startSector; - U_LONG volPtr; -} *cd_IOCTLOut; -static U_WORD cd_IOCTLOutSeg; -static U_WORD cd_IOCTLOutSel; - -static struct Eject_s -{ - U_BYTE code; // EJECTDISK -} *cd_Eject; -static U_WORD cd_EjectSeg; -static U_WORD cd_EjectSel; - -static struct LockDoor_s -{ - U_BYTE code; // DOORLOCK - U_BYTE lock; // Lock function : 0 = unlock, 1 = lock -} *cd_LockDoor; -static U_WORD cd_LockDoorSeg; -static U_WORD cd_LockDoorSel; - -static struct ResetDrv_s -{ - U_BYTE code; // RESETDRIVE -} *cd_ResetDrv; -static U_WORD cd_ResetDrvSeg; -static U_WORD cd_ResetDrvSel; - -static struct AudInfo_s -{ - U_BYTE code; // AUDIOCHANCONTROL - U_BYTE inChanOut0; // Input chan(0,1,2,or 3) for output chan 0 - U_BYTE volumeOut0; // Volume control (0-0xff) for output chan 0 - U_BYTE inChanOut1; // Input chan(0,1,2,or 3) for output chan 1 - U_BYTE volumeOut1; // Volume control (0-0xff) for output chan 1 - U_BYTE inChanOut2; // Input chan(0,1,2,or 3) for output chan 2 - U_BYTE volumeOut2; // Volume control (0-0xff) for output chan 2 - U_BYTE inChanOut3; // Input chan(0,1,2,or 3) for output chan 3 - U_BYTE volumeOut3; // Volume control (0-0xff) for output chan 3 -} *cd_AudInfo; -static U_WORD cd_AudInfoSeg; -static U_WORD cd_AudInfoSel; - -static struct WDrvBytes_s -{ - U_BYTE code; // WRITEDEVCONTROL - U_BYTE buf[5]; // Write buffer - size ?? -} *cd_WDrvBytes; -static U_WORD cd_WDrvBytesSeg; -static U_WORD cd_WDrvBytesSel; - -static struct CloseTray_s -{ - U_BYTE code; // CLOSETRAY -} *cd_CloseTray; -static U_WORD cd_CloseTraySeg; -static U_WORD cd_CloseTraySel; - -static U_WORD InCtrlBlkSize[16] = { - 0x05, 0x06, 0x00, 0x00, - 0x09, 0x82, 0x05, 0x04, - 0x05, 0x02, 0x07, 0x07, - 0x0b, 0x0d, 0x0b, 0x0b -}; - -static U_WORD OutCtrlBlkSize[6] = { - 0x01, 0x02, - 0x01, 0x09, - 0x06, 0x01 -}; - -// Structures for allocating conventional memory - -static DOSChunk_t DOSChunks[] = { - { - sizeof(struct PlayReq_s), - &cd_PlayReq, &cd_PlayReqSeg, &cd_PlayReqSel}, - { - sizeof(struct StopReq_s), - &cd_StopReq, &cd_StopReqSeg, &cd_StopReqSel}, - { - sizeof(struct ResumeReq_s), - &cd_ResumeReq, &cd_ResumeReqSeg, &cd_ResumeReqSel}, - { - sizeof(struct IOCTLOut_s), - &cd_IOCTLOut, &cd_IOCTLOutSeg, &cd_IOCTLOutSel}, - { - sizeof(struct Eject_s), - &cd_Eject, &cd_EjectSeg, &cd_EjectSel}, - { - sizeof(struct LockDoor_s), - &cd_LockDoor, &cd_LockDoorSeg, &cd_LockDoorSel}, - { - sizeof(struct ResetDrv_s), - &cd_ResetDrv, &cd_ResetDrvSeg, &cd_ResetDrvSel}, - { - sizeof(struct AudInfo_s), - &cd_AudInfo, &cd_AudInfoSeg, &cd_AudInfoSel}, - { - sizeof(struct WDrvBytes_s), - &cd_WDrvBytes, &cd_WDrvBytesSeg, &cd_WDrvBytesSel}, - { - sizeof(struct CloseTray_s), - &cd_CloseTray, &cd_CloseTraySeg, &cd_CloseTraySel}, - { - sizeof(struct IOCTLIn_s), - &cd_IOCTLIn, &cd_IOCTLInSeg, &cd_IOCTLInSel}, - { - sizeof(struct RAddrDevHead_s), - &cd_RAddrDevHead, &cd_RAddrDevHeadSeg, &cd_RAddrDevHeadSel}, - { - sizeof(struct LocHead_s), - &cd_LocHead, &cd_LocHeadSeg, &cd_LocHeadSel}, - { - sizeof(struct ErrStat_s), - &cd_ErrStat, &cd_ErrStatSeg, &cd_ErrStatSel}, - { - sizeof(struct AudChanInfo_s), - &cd_AudChanInfo, &cd_AudChanInfoSeg, &cd_AudChanInfoSel}, - { - sizeof(struct RDrvBytes_s), - &cd_RDrvBytes, &cd_RDrvBytesSeg, &cd_RDrvBytesSel}, - { - sizeof(struct DevStat_s), - &cd_DevStat, &cd_DevStatSeg, &cd_DevStatSel}, - { - sizeof(struct SectSize_s), - &cd_SectSize, &cd_SectSizeSeg, &cd_SectSizeSel}, - { - sizeof(struct VolSize_s), - &cd_VolSize, &cd_VolSizeSeg, &cd_VolSizeSel}, - { - sizeof(struct MedChng_s), - &cd_MedChng, &cd_MedChngSeg, &cd_MedChngSel}, - { - sizeof(struct DiskInfo_s), - &cd_DiskInfo, &cd_DiskInfoSeg, &cd_DiskInfoSel}, - { - sizeof(struct TrackInfo_s), - &cd_TrackInfo, &cd_TrackInfoSeg, &cd_TrackInfoSel}, - { - sizeof(struct QInfo_s), - &cd_QInfo, &cd_QInfoSeg, &cd_QInfoSel}, - { - sizeof(struct SubChanInfo_s), - &cd_SubChanInfo, &cd_SubChanInfoSeg, &cd_SubChanInfoSel}, - { - sizeof(struct UPCCode_s), - &cd_UPCCode, &cd_UPCCodeSeg, &cd_UPCCodeSel}, - { - sizeof(struct AudStat_s), - &cd_AudStat, &cd_AudStatSeg, &cd_AudStatSel}, - { - 0, NULL, NULL, NULL} -}; - -// CODE -------------------------------------------------------------------- - -//========================================================================== -// -// I_CDMusInit -// -// Initializes the CD audio system. Must be called before using any -// other I_CDMus functions. -// -// Returns: 0 (ok) or -1 (error, in cd_Error). -// -//========================================================================== - -int I_CDMusInit(void) -{ - int i; - int sect; - int maxTrack; - S_BYTE startMin1 = 0; - S_BYTE startSec1 = 0; - S_BYTE startMin2 = 0; - S_BYTE startSec2 = 0; - S_BYTE lengthMin = 0; - S_BYTE lengthSec = 0; - - if (OkInit != 1) - { // Only execute if uninitialized - - // Get number of CD-ROM drives and first drive - memset(&RegBlock, 0, sizeof(RegBlock)); - RegBlock.eax = CDROM_GETDRIVECOUNT; - RegBlock.ebx = 0; - DPMI_SimRealInt(MULTIPLEX_INT, &RegBlock); - cd_DriveCount = RegBlock.ebx; - - // MSCDEX not installed if number of drives = 0 - if (cd_DriveCount == 0) - { - cd_Error = CDERR_NOTINSTALLED; - return -1; - } - cd_FirstDrive = RegBlock.ecx; - cd_CurDrive = cd_FirstDrive; - - // Allocate the IOCTL buffers - if (AllocIOCTLBuffers() == -1) - { - cd_Error = CDERR_IOCTLBUFFMEM; - return -1; - } - - // Get MSCDEX version - // Major version in upper byte, minor version in lower byte - memset(&RegBlock, 0, sizeof(RegBlock)); - RegBlock.eax = CDROM_GETVERSION; - DPMI_SimRealInt(MULTIPLEX_INT, &RegBlock); - cd_Version = RegBlock.ebx; - - // Check device status to make sure we can read Audio CD's - InputIOCTL(DEVICESTATUS, cd_DevStatSeg); - if ((cd_DevStat->devParams & 0x0010) == 0) - { - cd_Error = CDERR_NOAUDIOSUPPORT; - return -1; - } - } - - // Force audio to stop playing - I_CDMusStop(); - - // Make sure we have the current TOC - InputIOCTL(MEDIACHANGED, cd_MedChngSeg); - - // Set track variables - InputIOCTL(AUDIODISKINFO, cd_DiskInfoSeg); - cd_FirstTrack = cd_DiskInfo->lowTrack; - cd_LastTrack = cd_DiskInfo->highTrack; - if (cd_FirstTrack == 0 && cd_FirstTrack == cd_LastTrack) - { - cd_Error = CDERR_NOAUDIOTRACKS; - return -1; - } - cd_TrackCount = cd_LastTrack - cd_FirstTrack + 1; - cd_LeadOutMin = cd_DiskInfo->startLeadOut >> 16 & 0xFF; - cd_LeadOutSec = cd_DiskInfo->startLeadOut >> 8 & 0xFF; - cd_LeadOutRed = cd_DiskInfo->startLeadOut; - cd_LeadOutSector = RedToSectors(cd_DiskInfo->startLeadOut); - - // Create Red Book start, sector start, and sector length - // for all tracks - sect = cd_LeadOutSector; - for (i = cd_LastTrack; i >= cd_FirstTrack; i--) - { - cd_TrackInfo->track = i; - InputIOCTL(AUDIOTRACKINFO, cd_TrackInfoSeg); - if (i < MAX_AUDIO_TRACKS) - { - cd_AudioTracks[i].redStart = cd_TrackInfo->start; - cd_AudioTracks[i].sectorStart = RedToSectors(cd_TrackInfo->start); - cd_AudioTracks[i].sectorLength = - sect - RedToSectors(cd_TrackInfo->start); - } - sect = RedToSectors(cd_TrackInfo->start); - } - - // Create track lengths in minutes and seconds - if (cd_LastTrack >= MAX_AUDIO_TRACKS) - { - maxTrack = MAX_AUDIO_TRACKS - 1; - } - else - { - maxTrack = cd_LastTrack; - } - cd_TrackInfo->track = cd_FirstTrack; - InputIOCTL(AUDIOTRACKINFO, cd_TrackInfoSeg); - startMin1 = (cd_TrackInfo->start >> 16); - startSec1 = (cd_TrackInfo->start >> 8); - for (i = cd_FirstTrack; i <= maxTrack; i++) - { - cd_TrackInfo->track = i + 1; - if (i < cd_LastTrack) - { - InputIOCTL(AUDIOTRACKINFO, cd_TrackInfoSeg); - startMin2 = (cd_TrackInfo->start >> 16); - startSec2 = (cd_TrackInfo->start >> 8); - } - else - { - startMin2 = cd_LeadOutRed >> 16; - startSec2 = cd_LeadOutRed >> 8; - } - lengthSec = startSec2 - startSec1; - lengthMin = startMin2 - startMin1; - if (lengthSec < 0) - { - lengthSec += 60; - lengthMin--; - } - cd_AudioTracks[i].lengthMin = lengthMin; - cd_AudioTracks[i].lengthSec = lengthSec; - startMin1 = startMin2; - startSec1 = startSec2; - } - - // Clip high tracks - cd_LastTrack = maxTrack; - - OkInit = 1; - return 0; -} - -//========================================================================== -// -// I_CDMusPlay -// -// Play an audio CD track. -// -// Returns: 0 (ok) or -1 (error, in cd_Error). -// -//========================================================================== - -int I_CDMusPlay(int track) -{ - int start; - int len; - - if (track < cd_FirstTrack || track > cd_LastTrack) - { - cd_Error = CDERR_BADTRACK; - return (-1); - } - I_CDMusStop(); - start = cd_AudioTracks[track].redStart; - len = cd_AudioTracks[track].sectorLength; - cd_PlayReq->addressMode = RED_MODE; - cd_PlayReq->startSector = start; - cd_PlayReq->numberToRead = len; - memset(&RegBlock, 0, sizeof(RegBlock)); - RegBlock.eax = CDROM_SENDDEVICEREQ; - RegBlock.ecx = cd_CurDrive; - RegBlock.ebx = 0; - RegBlock.es = cd_PlayReqSeg; - DPMI_SimRealInt(MULTIPLEX_INT, &RegBlock); - if (cd_PlayReq->status & 0x8000) - { - cd_Error = CDERR_DEVREQBASE + (cd_PlayReq->status) & 0x00ff; - return (-1); - } - return (0); -} - -//========================================================================== -// -// I_CDMusStop -// -// Stops the playing of an audio CD. -// -// Returns: 0 (ok) or -1 (error, in cd_Error). -// -//========================================================================== - -int I_CDMusStop(void) -{ - memset(&RegBlock, 0, sizeof(RegBlock)); - RegBlock.eax = CDROM_SENDDEVICEREQ; - RegBlock.ecx = cd_CurDrive; - RegBlock.ebx = 0; - RegBlock.es = cd_StopReqSeg; - DPMI_SimRealInt(MULTIPLEX_INT, &RegBlock); - if (cd_StopReq->status & 0x8000) - { - cd_Error = CDERR_DEVREQBASE + (cd_StopReq->status) & 0x00ff; - return -1; - } - return 0; -} - -//========================================================================== -// -// I_CDMusResume -// -// Resumes the playing of an audio CD. -// -// Returns: 0 (ok) or -1 (error, in cd_Error). -// -//========================================================================== - -int I_CDMusResume(void) -{ - memset(&RegBlock, 0, sizeof(RegBlock)); - RegBlock.eax = CDROM_SENDDEVICEREQ; - RegBlock.ecx = cd_CurDrive; - RegBlock.ebx = 0; - RegBlock.es = cd_ResumeReqSeg; - DPMI_SimRealInt(MULTIPLEX_INT, &RegBlock); - if (cd_ResumeReq->status & 0x8000) - { - cd_Error = CDERR_DEVREQBASE + (cd_ResumeReq->status) & 0x00ff; - return -1; - } - return 0; -} - -//========================================================================== -// -// I_CDMusSetVolume -// -// Sets the CD audio volume (0 - 255). -// -// Returns: 0 (ok) or -1 (error, in cd_Error). -// -//========================================================================== - -int I_CDMusSetVolume(int volume) -{ - - if (!OkInit) - { - cd_Error = CDERR_NOTINSTALLED; - return -1; - } - - // Read current channel info - InputIOCTL(AUDIOCHANINFO, cd_AudChanInfoSeg); - - // Change the volumes - cd_AudChanInfo->volumeOut0 = - cd_AudChanInfo->volumeOut1 = - cd_AudChanInfo->volumeOut2 = cd_AudChanInfo->volumeOut3 = volume; - - // Write modified channel info - OutputIOCTL(AUDIOCHANCONTROL, cd_AudChanInfoSeg); - - return 0; -} - -//========================================================================== -// -// I_CDMusFirstTrack -// -// Returns: the number of the first track. -// -//========================================================================== - -int I_CDMusFirstTrack(void) -{ - return cd_FirstTrack; -} - -//========================================================================== -// -// I_CDMusLastTrack -// -// Returns: the number of the last track. -// -//========================================================================== - -int I_CDMusLastTrack(void) -{ - return cd_LastTrack; -} - -//========================================================================== -// -// I_CDMusTrackLength -// -// Returns: Length of the given track in seconds, or -1 (error, in -// cd_Error). -// -//========================================================================== - -int I_CDMusTrackLength(int track) -{ - if (track < cd_FirstTrack || track > cd_LastTrack) - { - cd_Error = CDERR_BADTRACK; - return -1; - } - return cd_AudioTracks[track].lengthMin * 60 - + cd_AudioTracks[track].lengthSec; -} - -//========================================================================== -// -// AllocIOCTLBuffers -// -// Allocates conventional memory for the IOCTL input and output buffers. -// Sets cd_IOCTLBufferTotal to the total allocated. -// -// Returns: 0 (ok) or -1 (error, in cd_Error). -// -//========================================================================== - -static int AllocIOCTLBuffers(void) -{ - int i; - int size; - DOSChunk_t *ck; - - cd_IOCTLBufferTotal = 0; - for (i = 0; DOSChunks[i].size != 0; i++) - { - ck = &DOSChunks[i]; - size = ck->size; - cd_IOCTLBufferTotal += (size + 15) & 0xfffffff0; - *ck->address = DPMI_AllocRealMem(size, ck->segment, ck->selector); - if (*ck->address == NULL) - { - return -1; - } - memset(*ck->address, 0, size); - } - cd_IOCTLIn->headerSize = sizeof(struct IOCTLIn_s); - cd_IOCTLIn->command = DRC_IOCTLINPUT; - cd_IOCTLOut->headerSize = sizeof(struct IOCTLOut_s); - cd_IOCTLOut->command = DRC_IOCTLOUTPUT; - cd_PlayReq->headerSize = sizeof(struct PlayReq_s); - cd_PlayReq->command = DRC_PLAYAUDIO; - cd_StopReq->headerSize = sizeof(struct StopReq_s); - cd_StopReq->command = DRC_STOPAUDIO; - cd_ResumeReq->headerSize = sizeof(struct ResumeReq_s); - cd_ResumeReq->command = DRC_RESUMEAUDIO; - return 0; -} - -//========================================================================== -// -// InputIOCTL -// -// Sends an IOCTL input device request command. -// -// Returns: the status of the request. -// -//========================================================================== - -static U_WORD InputIOCTL(S_LONG request, U_WORD buffSeg) -{ - U_BYTE *code; - - code = (U_BYTE *) (buffSeg << 4); - *code = (U_BYTE) request; - cd_IOCTLIn->ctrlBlkAddr = buffSeg << 16; - cd_IOCTLIn->tranSize = InCtrlBlkSize[request]; - memset(&RegBlock, 0, sizeof(RegBlock)); - RegBlock.eax = CDROM_SENDDEVICEREQ; - RegBlock.ecx = cd_CurDrive; - RegBlock.ebx = 0; - RegBlock.es = cd_IOCTLInSeg; - DPMI_SimRealInt(MULTIPLEX_INT, &RegBlock); - return cd_IOCTLIn->status; -} - -//========================================================================== -// -// OutputIOCTL -// -// Sends an IOCTL output device request command. -// -// Returns: the status of the request. -// -//========================================================================== - -static U_WORD OutputIOCTL(S_LONG request, U_WORD buffSeg) -{ - U_BYTE *code; - - code = (U_BYTE *) (buffSeg << 4); - *code = (U_BYTE) request; - cd_IOCTLOut->ctrlBlkAddr = buffSeg << 16; - cd_IOCTLOut->tranSize = OutCtrlBlkSize[request]; - RegBlock.eax = CDROM_SENDDEVICEREQ; - RegBlock.ecx = cd_CurDrive; - RegBlock.ebx = 0; - RegBlock.es = cd_IOCTLOutSeg; - DPMI_SimRealInt(MULTIPLEX_INT, &RegBlock); - return cd_IOCTLOut->status; -} - -//========================================================================== -// -// RedToSectors -// -// Converts Red Book addresses to HSG sectors. -// Sectors = Minutes * 60 * 75 + Seconds * 75 + Frame - 150 -// -// Returns: HSG sectors. -// -//========================================================================== - -static U_LONG RedToSectors(U_LONG red) -{ - U_LONG sector; - - sector = ((red & 0x00ff0000) >> 16) * 60 * 75; - sector += ((red & 0x0000ff00) >> 8) * 75; - sector += (red & 0x000000ff); - return sector - 150; -} - -//========================================================================== -// -// DPMI_SimRealInt -// -//========================================================================== - -static void DPMI_SimRealInt(U_LONG intr, RegBlock_t * rBlock) -{ - union REGS regs; - struct SREGS sRegs; - - regs.x.eax = DPMI_SIMREALINT; - regs.x.ebx = intr; - regs.x.ecx = 0; - regs.x.edi = FP_OFF((void far *) rBlock); - sRegs.es = FP_SEG((void far *) rBlock); - sRegs.ds = FP_SEG((void far *) rBlock); - int386x(DPMI_INT, ®s, ®s, &sRegs); -} - -//========================================================================== -// -// DPMI_AllocRealMem -// -//========================================================================== - -static void *DPMI_AllocRealMem(U_LONG size, U_WORD * segment, - U_WORD * selector) -{ - union REGS inRegs; - union REGS outRegs; - - inRegs.x.eax = DPMI_ALLOCREALMEM; - inRegs.x.ebx = (size + 15) / 16; - int386(DPMI_INT, &inRegs, &outRegs); - if (outRegs.x.cflag) - { - return NULL; - } - *segment = outRegs.x.eax & 0xffff; - *selector = outRegs.x.edx & 0xffff; - return (void *) (outRegs.x.eax << 4); -} - -//========================================================================== -// -// DPMI_FreeRealMem -// -//========================================================================== - -static void DPMI_FreeRealMem(U_WORD selector) -{ - union REGS regs; - - regs.x.eax = DPMI_FREEREALMEM; - regs.x.edx = selector; - int386(DPMI_INT, ®s, ®s); -} |