123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848 |
- #include <dpmi.h>
- #include "quakedef.h"
- #include "dosisms.h"
- extern cvar_t bgmvolume;
- #define ADDRESS_MODE_HSG 0
- #define ADDRESS_MODE_RED_BOOK 1
- #define STATUS_ERROR_BIT 0x8000
- #define STATUS_BUSY_BIT 0x0200
- #define STATUS_DONE_BIT 0x0100
- #define STATUS_ERROR_MASK 0x00ff
- #define ERROR_WRITE_PROTECT 0
- #define ERROR_UNKNOWN_UNIT 1
- #define ERROR_DRIVE_NOT_READY 2
- #define ERROR_UNKNOWN_COMMAND 3
- #define ERROR_CRC_ERROR 4
- #define ERROR_BAD_REQUEST_LEN 5
- #define ERROR_SEEK_ERROR 6
- #define ERROR_UNKNOWN_MEDIA 7
- #define ERROR_SECTOR_NOT_FOUND 8
- #define ERROR_OUT_OF_PAPER 9
- #define ERROR_WRITE_FAULT 10
- #define ERROR_READ_FAULT 11
- #define ERROR_GENERAL_FAILURE 12
- #define ERROR_RESERVED_13 13
- #define ERROR_RESERVED_14 14
- #define ERROR_BAD_DISK_CHANGE 15
- #define COMMAND_READ 3
- #define COMMAND_WRITE 12
- #define COMMAND_PLAY_AUDIO 132
- #define COMMAND_STOP_AUDIO 133
- #define COMMAND_RESUME_AUDIO 136
- #define READ_REQUEST_AUDIO_CHANNEL_INFO 4
- #define READ_REQUEST_DEVICE_STATUS 6
- #define READ_REQUEST_MEDIA_CHANGE 9
- #define READ_REQUEST_AUDIO_DISK_INFO 10
- #define READ_REQUEST_AUDIO_TRACK_INFO 11
- #define READ_REQUEST_AUDIO_STATUS 15
- #define WRITE_REQUEST_EJECT 0
- #define WRITE_REQUEST_RESET 2
- #define WRITE_REQUEST_AUDIO_CHANNEL_INFO 3
- #define STATUS_DOOR_OPEN 0x00000001
- #define STATUS_DOOR_UNLOCKED 0x00000002
- #define STATUS_RAW_SUPPORT 0x00000004
- #define STATUS_READ_WRITE 0x00000008
- #define STATUS_AUDIO_SUPPORT 0x00000010
- #define STATUS_INTERLEAVE_SUPPORT 0x00000020
- #define STATUS_BIT_6_RESERVED 0x00000040
- #define STATUS_PREFETCH_SUPPORT 0x00000080
- #define STATUS_AUDIO_MANIPLUATION_SUPPORT 0x00000100
- #define STATUS_RED_BOOK_ADDRESS_SUPPORT 0x00000200
- #define MEDIA_NOT_CHANGED 1
- #define MEDIA_STATUS_UNKNOWN 0
- #define MEDIA_CHANGED -1
- #define AUDIO_CONTROL_MASK 0xd0
- #define AUDIO_CONTROL_DATA_TRACK 0x40
- #define AUDIO_CONTROL_AUDIO_2_TRACK 0x00
- #define AUDIO_CONTROL_AUDIO_2P_TRACK 0x10
- #define AUDIO_CONTROL_AUDIO_4_TRACK 0x80
- #define AUDIO_CONTROL_AUDIO_4P_TRACK 0x90
- #define AUDIO_STATUS_PAUSED 0x0001
- #pragma pack(1)
- struct playAudioRequest
- {
- char addressingMode;
- int startLocation;
- int sectors;
- };
- struct readRequest
- {
- char mediaDescriptor;
- short bufferOffset;
- short bufferSegment;
- short length;
- short startSector;
- int volumeID;
- };
- struct writeRequest
- {
- char mediaDescriptor;
- short bufferOffset;
- short bufferSegment;
- short length;
- short startSector;
- int volumeID;
- };
- struct cd_request
- {
- char headerLength;
- char unit;
- char command;
- short status;
- char reserved[8];
- union
- {
- struct playAudioRequest playAudio;
- struct readRequest read;
- struct writeRequest write;
- } x;
- };
- struct audioChannelInfo_s
- {
- char code;
- char channel0input;
- char channel0volume;
- char channel1input;
- char channel1volume;
- char channel2input;
- char channel2volume;
- char channel3input;
- char channel3volume;
- };
- struct deviceStatus_s
- {
- char code;
- int status;
- };
- struct mediaChange_s
- {
- char code;
- char status;
- };
- struct audioDiskInfo_s
- {
- char code;
- char lowTrack;
- char highTrack;
- int leadOutStart;
- };
- struct audioTrackInfo_s
- {
- char code;
- char track;
- int start;
- char control;
- };
- struct audioStatus_s
- {
- char code;
- short status;
- int PRstartLocation;
- int PRendLocation;
- };
- struct reset_s
- {
- char code;
- };
- union readInfo_u
- {
- struct audioChannelInfo_s audioChannelInfo;
- struct deviceStatus_s deviceStatus;
- struct mediaChange_s mediaChange;
- struct audioDiskInfo_s audioDiskInfo;
- struct audioTrackInfo_s audioTrackInfo;
- struct audioStatus_s audioStatus;
- struct reset_s reset;
- };
- #pragma pack()
- #define MAXIMUM_TRACKS 32
- typedef struct
- {
- int start;
- int length;
- qboolean isData;
- } track_info;
- typedef struct
- {
- qboolean valid;
- int leadOutAddress;
- track_info track[MAXIMUM_TRACKS];
- byte lowTrack;
- byte highTrack;
- } cd_info;
- static struct cd_request *cdRequest;
- static union readInfo_u *readInfo;
- static cd_info cd;
- static qboolean playing = false;
- static qboolean wasPlaying = false;
- static qboolean mediaCheck = false;
- static qboolean initialized = false;
- static qboolean enabled = true;
- static qboolean playLooping = false;
- static short cdRequestSegment;
- static short cdRequestOffset;
- static short readInfoSegment;
- static short readInfoOffset;
- static byte remap[256];
- static byte cdrom;
- static byte playTrack;
- static byte cdvolume;
- static int RedBookToSector(int rb)
- {
- byte minute;
- byte second;
- byte frame;
- minute = (rb >> 16) & 0xff;
- second = (rb >> 8) & 0xff;
- frame = rb & 0xff;
- return minute * 60 * 75 + second * 75 + frame;
- }
- static void CDAudio_Reset(void)
- {
- cdRequest->headerLength = 13;
- cdRequest->unit = 0;
- cdRequest->command = COMMAND_WRITE;
- cdRequest->status = 0;
- cdRequest->x.write.mediaDescriptor = 0;
- cdRequest->x.write.bufferOffset = readInfoOffset;
- cdRequest->x.write.bufferSegment = readInfoSegment;
- cdRequest->x.write.length = sizeof(struct reset_s);
- cdRequest->x.write.startSector = 0;
- cdRequest->x.write.volumeID = 0;
- readInfo->reset.code = WRITE_REQUEST_RESET;
- regs.x.ax = 0x1510;
- regs.x.cx = cdrom;
- regs.x.es = cdRequestSegment;
- regs.x.bx = cdRequestOffset;
- dos_int86 (0x2f);
- }
- static void CDAudio_Eject(void)
- {
- cdRequest->headerLength = 13;
- cdRequest->unit = 0;
- cdRequest->command = COMMAND_WRITE;
- cdRequest->status = 0;
- cdRequest->x.write.mediaDescriptor = 0;
- cdRequest->x.write.bufferOffset = readInfoOffset;
- cdRequest->x.write.bufferSegment = readInfoSegment;
- cdRequest->x.write.length = sizeof(struct reset_s);
- cdRequest->x.write.startSector = 0;
- cdRequest->x.write.volumeID = 0;
- readInfo->reset.code = WRITE_REQUEST_EJECT;
- regs.x.ax = 0x1510;
- regs.x.cx = cdrom;
- regs.x.es = cdRequestSegment;
- regs.x.bx = cdRequestOffset;
- dos_int86 (0x2f);
- }
- static int CDAudio_GetAudioTrackInfo(byte track, int *start)
- {
- byte control;
- cdRequest->headerLength = 13;
- cdRequest->unit = 0;
- cdRequest->command = COMMAND_READ;
- cdRequest->status = 0;
- cdRequest->x.read.mediaDescriptor = 0;
- cdRequest->x.read.bufferOffset = readInfoOffset;
- cdRequest->x.read.bufferSegment = readInfoSegment;
- cdRequest->x.read.length = sizeof(struct audioTrackInfo_s);
- cdRequest->x.read.startSector = 0;
- cdRequest->x.read.volumeID = 0;
- readInfo->audioTrackInfo.code = READ_REQUEST_AUDIO_TRACK_INFO;
- readInfo->audioTrackInfo.track = track;
- regs.x.ax = 0x1510;
- regs.x.cx = cdrom;
- regs.x.es = cdRequestSegment;
- regs.x.bx = cdRequestOffset;
- dos_int86 (0x2f);
- if (cdRequest->status & STATUS_ERROR_BIT)
- {
- Con_DPrintf("CDAudio_GetAudioTrackInfo %04x\n", cdRequest->status & 0xffff);
- return -1;
- }
- *start = readInfo->audioTrackInfo.start;
- control = readInfo->audioTrackInfo.control & AUDIO_CONTROL_MASK;
- return (control & AUDIO_CONTROL_DATA_TRACK);
- }
- static int CDAudio_GetAudioDiskInfo(void)
- {
- int n;
- cdRequest->headerLength = 13;
- cdRequest->unit = 0;
- cdRequest->command = COMMAND_READ;
- cdRequest->status = 0;
- cdRequest->x.read.mediaDescriptor = 0;
- cdRequest->x.read.bufferOffset = readInfoOffset;
- cdRequest->x.read.bufferSegment = readInfoSegment;
- cdRequest->x.read.length = sizeof(struct audioDiskInfo_s);
- cdRequest->x.read.startSector = 0;
- cdRequest->x.read.volumeID = 0;
- readInfo->audioDiskInfo.code = READ_REQUEST_AUDIO_DISK_INFO;
- regs.x.ax = 0x1510;
- regs.x.cx = cdrom;
- regs.x.es = cdRequestSegment;
- regs.x.bx = cdRequestOffset;
- dos_int86 (0x2f);
- if (cdRequest->status & STATUS_ERROR_BIT)
- {
- Con_DPrintf("CDAudio_GetAudioDiskInfo %04x\n", cdRequest->status & 0xffff);
- return -1;
- }
- cd.valid = true;
- cd.lowTrack = readInfo->audioDiskInfo.lowTrack;
- cd.highTrack = readInfo->audioDiskInfo.highTrack;
- cd.leadOutAddress = readInfo->audioDiskInfo.leadOutStart;
- for (n = cd.lowTrack; n <= cd.highTrack; n++)
- {
- cd.track[n].isData = CDAudio_GetAudioTrackInfo (n, &cd.track[n].start);
- if (n > cd.lowTrack)
- {
- cd.track[n-1].length = RedBookToSector(cd.track[n].start) - RedBookToSector(cd.track[n-1].start);
- if (n == cd.highTrack)
- cd.track[n].length = RedBookToSector(cd.leadOutAddress) - RedBookToSector(cd.track[n].start);
- }
- }
- return 0;
- }
- static int CDAudio_GetAudioStatus(void)
- {
- cdRequest->headerLength = 13;
- cdRequest->unit = 0;
- cdRequest->command = COMMAND_READ;
- cdRequest->status = 0;
- cdRequest->x.read.mediaDescriptor = 0;
- cdRequest->x.read.bufferOffset = readInfoOffset;
- cdRequest->x.read.bufferSegment = readInfoSegment;
- cdRequest->x.read.length = sizeof(struct audioStatus_s);
- cdRequest->x.read.startSector = 0;
- cdRequest->x.read.volumeID = 0;
- readInfo->audioDiskInfo.code = READ_REQUEST_AUDIO_STATUS;
- regs.x.ax = 0x1510;
- regs.x.cx = cdrom;
- regs.x.es = cdRequestSegment;
- regs.x.bx = cdRequestOffset;
- dos_int86 (0x2f);
- if (cdRequest->status & STATUS_ERROR_BIT)
- return -1;
- return 0;
- }
- static int CDAudio_MediaChange(void)
- {
- cdRequest->headerLength = 13;
- cdRequest->unit = 0;
- cdRequest->command = COMMAND_READ;
- cdRequest->status = 0;
- cdRequest->x.read.mediaDescriptor = 0;
- cdRequest->x.read.bufferOffset = readInfoOffset;
- cdRequest->x.read.bufferSegment = readInfoSegment;
- cdRequest->x.read.length = sizeof(struct mediaChange_s);
- cdRequest->x.read.startSector = 0;
- cdRequest->x.read.volumeID = 0;
- readInfo->mediaChange.code = READ_REQUEST_MEDIA_CHANGE;
- regs.x.ax = 0x1510;
- regs.x.cx = cdrom;
- regs.x.es = cdRequestSegment;
- regs.x.bx = cdRequestOffset;
- dos_int86 (0x2f);
- return readInfo->mediaChange.status;
- }
- byte CDAudio_GetVolume (void)
- {
- return cdvolume;
- }
- // we set the volume to 0 first and then to the desired volume
- // some cd-rom drivers seem to need it done this way
- void CDAudio_SetVolume (byte volume)
- {
- if (!initialized || !enabled)
- return;
- cdRequest->headerLength = 13;
- cdRequest->unit = 0;
- cdRequest->command = COMMAND_WRITE;
- cdRequest->status = 0;
- cdRequest->x.read.mediaDescriptor = 0;
- cdRequest->x.read.bufferOffset = readInfoOffset;
- cdRequest->x.read.bufferSegment = readInfoSegment;
- cdRequest->x.read.length = sizeof(struct audioChannelInfo_s);
- cdRequest->x.read.startSector = 0;
- cdRequest->x.read.volumeID = 0;
- readInfo->audioChannelInfo.code = WRITE_REQUEST_AUDIO_CHANNEL_INFO;
- readInfo->audioChannelInfo.channel0input = 0;
- readInfo->audioChannelInfo.channel0volume = 0;
- readInfo->audioChannelInfo.channel1input = 1;
- readInfo->audioChannelInfo.channel1volume = 0;
- readInfo->audioChannelInfo.channel2input = 2;
- readInfo->audioChannelInfo.channel2volume = 0;
- readInfo->audioChannelInfo.channel3input = 3;
- readInfo->audioChannelInfo.channel3volume = 0;
- regs.x.ax = 0x1510;
- regs.x.cx = cdrom;
- regs.x.es = cdRequestSegment;
- regs.x.bx = cdRequestOffset;
- dos_int86 (0x2f);
- readInfo->audioChannelInfo.channel0volume = volume;
- readInfo->audioChannelInfo.channel1volume = volume;
- regs.x.ax = 0x1510;
- regs.x.cx = cdrom;
- regs.x.es = cdRequestSegment;
- regs.x.bx = cdRequestOffset;
- dos_int86 (0x2f);
- cdvolume = volume;
- }
- void CDAudio_Play(byte track, qboolean looping)
- {
- if (!initialized || !enabled)
- return;
-
- if (!cd.valid)
- return;
- track = remap[track];
- if (playing)
- {
- if (playTrack == track)
- return;
- CDAudio_Stop();
- }
- playLooping = looping;
- if (track < cd.lowTrack || track > cd.highTrack)
- {
- Con_DPrintf("CDAudio_Play: Bad track number %u.\n", track);
- return;
- }
- playTrack = track;
- if (cd.track[track].isData)
- {
- Con_DPrintf("CDAudio_Play: Can not play data.\n");
- return;
- }
- cdRequest->headerLength = 13;
- cdRequest->unit = 0;
- cdRequest->command = COMMAND_PLAY_AUDIO;
- cdRequest->status = 0;
- cdRequest->x.playAudio.addressingMode = ADDRESS_MODE_RED_BOOK;
- cdRequest->x.playAudio.startLocation = cd.track[track].start;
- cdRequest->x.playAudio.sectors = cd.track[track].length;
- regs.x.ax = 0x1510;
- regs.x.cx = cdrom;
- regs.x.es = cdRequestSegment;
- regs.x.bx = cdRequestOffset;
- dos_int86 (0x2f);
- if (cdRequest->status & STATUS_ERROR_BIT)
- {
- Con_DPrintf("CDAudio_Play: track %u failed\n", track);
- cd.valid = false;
- playing = false;
- return;
- }
- playing = true;
- }
- void CDAudio_Stop(void)
- {
- if (!initialized || !enabled)
- return;
-
- cdRequest->headerLength = 13;
- cdRequest->unit = 0;
- cdRequest->command = COMMAND_STOP_AUDIO;
- cdRequest->status = 0;
- regs.x.ax = 0x1510;
- regs.x.cx = cdrom;
- regs.x.es = cdRequestSegment;
- regs.x.bx = cdRequestOffset;
- dos_int86 (0x2f);
- wasPlaying = playing;
- playing = false;
- }
- void CDAudio_Resume(void)
- {
- if (!initialized || !enabled)
- return;
-
- if (!cd.valid)
- return;
- if (!wasPlaying)
- return;
-
- cdRequest->headerLength = 13;
- cdRequest->unit = 0;
- cdRequest->command = COMMAND_RESUME_AUDIO;
- cdRequest->status = 0;
- regs.x.ax = 0x1510;
- regs.x.cx = cdrom;
- regs.x.es = cdRequestSegment;
- regs.x.bx = cdRequestOffset;
- dos_int86 (0x2f);
- playing = true;
- }
- static void CD_f (void)
- {
- char *command;
- int ret;
- int n;
- int startAddress;
- if (Cmd_Argc() < 2)
- return;
- command = Cmd_Argv (1);
- if (Q_strcasecmp(command, "on") == 0)
- {
- enabled = true;
- return;
- }
- if (Q_strcasecmp(command, "off") == 0)
- {
- if (playing)
- CDAudio_Stop();
- enabled = false;
- return;
- }
- if (Q_strcasecmp(command, "reset") == 0)
- {
- enabled = true;
- if (playing)
- CDAudio_Stop();
- for (n = 0; n < 256; n++)
- remap[n] = n;
- CDAudio_Reset();
- CDAudio_GetAudioDiskInfo();
- return;
- }
- if (Q_strcasecmp(command, "remap") == 0)
- {
- ret = Cmd_Argc() - 2;
- if (ret <= 0)
- {
- for (n = 1; n < 256; n++)
- if (remap[n] != n)
- Con_Printf(" %u -> %u\n", n, remap[n]);
- return;
- }
- for (n = 1; n <= ret; n++)
- remap[n] = Q_atoi(Cmd_Argv (n+1));
- return;
- }
- if (!cd.valid)
- {
- Con_Printf("No CD in player.\n");
- return;
- }
- if (Q_strcasecmp(command, "play") == 0)
- {
- CDAudio_Play(Q_atoi(Cmd_Argv (2)), false);
- return;
- }
- if (Q_strcasecmp(command, "loop") == 0)
- {
- CDAudio_Play(Q_atoi(Cmd_Argv (2)), true);
- return;
- }
- if (Q_strcasecmp(command, "stop") == 0)
- {
- CDAudio_Stop();
- return;
- }
- if (Q_strcasecmp(command, "resume") == 0)
- {
- CDAudio_Resume();
- return;
- }
- if (Q_strcasecmp(command, "eject") == 0)
- {
- if (playing)
- CDAudio_Stop();
- CDAudio_Eject();
- cd.valid = false;
- return;
- }
- if (Q_strcasecmp(command, "info") == 0)
- {
- Con_Printf("%u tracks\n", cd.highTrack - cd.lowTrack + 1);
- for (n = cd.lowTrack; n <= cd.highTrack; n++)
- {
- ret = CDAudio_GetAudioTrackInfo (n, &startAddress);
- Con_Printf("Track %2u: %s at %2u:%02u\n", n, ret ? "data " : "music", (startAddress >> 16) & 0xff, (startAddress >> 8) & 0xff);
- }
- if (playing)
- Con_Printf("Currently %s track %u\n", playLooping ? "looping" : "playing", playTrack);
- Con_Printf("Volume is %u\n", cdvolume);
- CDAudio_MediaChange();
- Con_Printf("Status %04x\n", cdRequest->status & 0xffff);
- return;
- }
- }
- void CDAudio_Update(void)
- {
- int ret;
- int newVolume;
- static double lastUpdate;
- if (!initialized || !enabled)
- return;
- if ((realtime - lastUpdate) < 0.25)
- return;
- lastUpdate = realtime;
- if (mediaCheck)
- {
- static double lastCheck;
- if ((realtime - lastCheck) < 5.0)
- return;
- lastCheck = realtime;
- ret = CDAudio_MediaChange();
- if (ret == MEDIA_CHANGED)
- {
- Con_DPrintf("CDAudio: media changed\n");
- playing = false;
- wasPlaying = false;
- cd.valid = false;
- CDAudio_GetAudioDiskInfo();
- return;
- }
- }
- newVolume = (int)(bgmvolume.value * 255.0);
- if (newVolume < 0)
- {
- Cvar_SetValue ("bgmvolume", 0.0);
- newVolume = 0;
- }
- else if (newVolume > 255)
- {
- Cvar_SetValue ("bgmvolume", 1.0);
- newVolume = 255;
- }
- if (cdvolume != newVolume)
- CDAudio_SetVolume (newVolume);
- if (playing)
- {
- CDAudio_GetAudioStatus();
- if ((cdRequest->status & STATUS_BUSY_BIT) == 0)
- {
- playing = false;
- if (playLooping)
- CDAudio_Play(playTrack, true);
- }
- }
- }
- qboolean CDAudio_Playing(void)
- {
- return playing;
- }
- int CDAudio_Init(void)
- {
- char *memory;
- int n;
- if (cls.state == ca_dedicated)
- return -1;
- if (COM_CheckParm("-nocdaudio"))
- return -1;
- if (COM_CheckParm("-cdmediacheck"))
- mediaCheck = true;
- regs.x.ax = 0x1500;
- regs.x.bx = 0;
- dos_int86 (0x2f);
- if (regs.x.bx == 0)
- {
- Con_NotifyBox (
- "MSCDEX not loaded, music is\n"
- "disabled. Use \"-nocdaudio\" if you\n"
- "wish to avoid this message in the\n"
- "future. See README.TXT for help.\n"
- );
- return -1;
- }
- if (regs.x.bx > 1)
- Con_DPrintf("CDAudio_Init: First CD-ROM drive will be used\n");
- cdrom = regs.x.cx;
- regs.x.ax = 0x150c;
- regs.x.bx = 0;
- dos_int86 (0x2f);
- if (regs.x.bx == 0)
- {
- Con_NotifyBox (
- "MSCDEX version 2.00 or later\n"
- "required for music. See README.TXT\n"
- "for help.\n"
- );
- Con_DPrintf("CDAudio_Init: MSCDEX version 2.00 or later required.\n");
- return -1;
- }
- memory = dos_getmemory(sizeof(struct cd_request
- ) + sizeof(union readInfo_u));
- if (memory == NULL)
- {
- Con_DPrintf("CDAudio_Init: Unable to allocate low memory.\n");
- return -1;
- }
- cdRequest = (struct cd_request *)memory;
- cdRequestSegment = ptr2real(cdRequest) >> 4;
- cdRequestOffset = ptr2real(cdRequest) & 0xf;
- readInfo = (union readInfo_u *)(memory + sizeof(struct cd_request));
- readInfoSegment = ptr2real(readInfo) >> 4;
- readInfoOffset = ptr2real(readInfo) & 0xf;
- for (n = 0; n < 256; n++)
- remap[n] = n;
- initialized = true;
- CDAudio_SetVolume (255);
- if (CDAudio_GetAudioDiskInfo())
- {
- Con_Printf("CDAudio_Init: No CD in player.\n");
- enabled = false;
- }
- Cmd_AddCommand ("cd", CD_f);
- Con_Printf("CD Audio Initialized\n");
- return 0;
- }
- void CDAudio_Shutdown(void)
- {
- if (!initialized)
- return;
- CDAudio_Stop();
- }
|