📄 cd.c
字号:
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)
{
int volume;
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;
}
volume = (int)(bgmvolume.value * 255.0);
if (volume < 0)
{
Cvar_SetValue ("bgmvolume", 0.0);
volume = 0;
}
else if (volume > 255)
{
Cvar_SetValue ("bgmvolume", 1.0);
volume = 255;
}
CDAudio_SetVolume (volume);
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 != cdvolume)
{
if (newVolume < 0)
{
Cvar_SetValue ("bgmvolume", 0.0);
newVolume = 0;
}
else if (newVolume > 255)
{
Cvar_SetValue ("bgmvolume", 1.0);
newVolume = 255;
}
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();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -