⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i_cdmus.c

📁 制作游戏 魔法师传奇 源代码设计 MOFASHICHUANQI 经典老游戏
💻 C
📖 第 1 页 / 共 2 页
字号:

//**************************************************************************
//**
//** i_cdmus.c
//**
//**************************************************************************

// 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),

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -