CDROM: Limit XA playback to first-identified file/channel
Fixes background music in initial menu of Tomb Raider III.
This commit is contained in:
parent
cae2e09957
commit
45d7294c3c
|
@ -57,8 +57,11 @@ void CDROM::SoftReset()
|
||||||
m_play_after_seek = false;
|
m_play_after_seek = false;
|
||||||
m_muted = false;
|
m_muted = false;
|
||||||
m_adpcm_muted = false;
|
m_adpcm_muted = false;
|
||||||
m_filter_file_number = 0;
|
m_xa_filter_file_number = 0;
|
||||||
m_filter_channel_number = 0;
|
m_xa_filter_channel_number = 0;
|
||||||
|
m_xa_current_file_number = 0;
|
||||||
|
m_xa_current_channel_number = 0;
|
||||||
|
m_xa_current_set = false;
|
||||||
std::memset(&m_last_sector_header, 0, sizeof(m_last_sector_header));
|
std::memset(&m_last_sector_header, 0, sizeof(m_last_sector_header));
|
||||||
std::memset(&m_last_sector_subheader, 0, sizeof(m_last_sector_subheader));
|
std::memset(&m_last_sector_subheader, 0, sizeof(m_last_sector_subheader));
|
||||||
m_last_sector_header_valid = false;
|
m_last_sector_header_valid = false;
|
||||||
|
@ -114,8 +117,11 @@ bool CDROM::DoState(StateWrapper& sw)
|
||||||
sw.Do(&m_play_after_seek);
|
sw.Do(&m_play_after_seek);
|
||||||
sw.Do(&m_muted);
|
sw.Do(&m_muted);
|
||||||
sw.Do(&m_adpcm_muted);
|
sw.Do(&m_adpcm_muted);
|
||||||
sw.Do(&m_filter_file_number);
|
sw.Do(&m_xa_filter_file_number);
|
||||||
sw.Do(&m_filter_channel_number);
|
sw.Do(&m_xa_filter_channel_number);
|
||||||
|
sw.Do(&m_xa_current_file_number);
|
||||||
|
sw.Do(&m_xa_current_channel_number);
|
||||||
|
sw.Do(&m_xa_current_set);
|
||||||
sw.DoBytes(&m_last_sector_header, sizeof(m_last_sector_header));
|
sw.DoBytes(&m_last_sector_header, sizeof(m_last_sector_header));
|
||||||
sw.DoBytes(&m_last_sector_subheader, sizeof(m_last_sector_subheader));
|
sw.DoBytes(&m_last_sector_subheader, sizeof(m_last_sector_subheader));
|
||||||
sw.Do(&m_last_sector_header_valid);
|
sw.Do(&m_last_sector_header_valid);
|
||||||
|
@ -651,8 +657,8 @@ void CDROM::ExecuteCommand()
|
||||||
const u8 file = m_param_fifo.Peek(0);
|
const u8 file = m_param_fifo.Peek(0);
|
||||||
const u8 channel = m_param_fifo.Peek(1);
|
const u8 channel = m_param_fifo.Peek(1);
|
||||||
Log_DebugPrintf("CDROM setfilter command 0x%02X 0x%02X", ZeroExtend32(file), ZeroExtend32(channel));
|
Log_DebugPrintf("CDROM setfilter command 0x%02X 0x%02X", ZeroExtend32(file), ZeroExtend32(channel));
|
||||||
m_filter_file_number = file;
|
m_xa_filter_file_number = file;
|
||||||
m_filter_channel_number = channel;
|
m_xa_filter_channel_number = channel;
|
||||||
SendACKAndStat();
|
SendACKAndStat();
|
||||||
EndCommand();
|
EndCommand();
|
||||||
return;
|
return;
|
||||||
|
@ -958,8 +964,8 @@ void CDROM::ExecuteCommand()
|
||||||
m_response_fifo.Push(m_secondary_status.bits);
|
m_response_fifo.Push(m_secondary_status.bits);
|
||||||
m_response_fifo.Push(m_mode.bits);
|
m_response_fifo.Push(m_mode.bits);
|
||||||
m_response_fifo.Push(0);
|
m_response_fifo.Push(0);
|
||||||
m_response_fifo.Push(m_filter_file_number);
|
m_response_fifo.Push(m_xa_filter_file_number);
|
||||||
m_response_fifo.Push(m_filter_channel_number);
|
m_response_fifo.Push(m_xa_filter_channel_number);
|
||||||
SetInterrupt(Interrupt::ACK);
|
SetInterrupt(Interrupt::ACK);
|
||||||
EndCommand();
|
EndCommand();
|
||||||
}
|
}
|
||||||
|
@ -1143,6 +1149,9 @@ void CDROM::BeginReading(TickCount ticks_late)
|
||||||
m_drive_event->Schedule(ticks - ticks_late);
|
m_drive_event->Schedule(ticks - ticks_late);
|
||||||
m_current_read_sector_buffer = 0;
|
m_current_read_sector_buffer = 0;
|
||||||
m_current_write_sector_buffer = 0;
|
m_current_write_sector_buffer = 0;
|
||||||
|
m_xa_current_file_number = 0;
|
||||||
|
m_xa_current_channel_number = 0;
|
||||||
|
m_xa_current_set = false;
|
||||||
|
|
||||||
m_reader.QueueReadSector(m_last_requested_sector);
|
m_reader.QueueReadSector(m_last_requested_sector);
|
||||||
}
|
}
|
||||||
|
@ -1495,25 +1504,9 @@ void CDROM::ProcessDataSector(const u8* raw_sector, const CDImage::SubChannelQ&
|
||||||
|
|
||||||
if (m_mode.xa_enable && m_last_sector_header.sector_mode == 2)
|
if (m_mode.xa_enable && m_last_sector_header.sector_mode == 2)
|
||||||
{
|
{
|
||||||
if (m_last_sector_subheader.submode.eof)
|
|
||||||
{
|
|
||||||
Log_WarningPrintf("End of CD-XA file");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_last_sector_subheader.submode.realtime && m_last_sector_subheader.submode.audio)
|
if (m_last_sector_subheader.submode.realtime && m_last_sector_subheader.submode.audio)
|
||||||
{
|
{
|
||||||
// Check for automatic ADPCM filter.
|
ProcessXAADPCMSector(raw_sector, subq);
|
||||||
if (m_mode.xa_filter && (m_last_sector_subheader.file_number != m_filter_file_number ||
|
|
||||||
m_last_sector_subheader.channel_number != m_filter_channel_number))
|
|
||||||
{
|
|
||||||
Log_DebugPrintf("Skipping sector due to filter mismatch (expected %u/%u got %u/%u)", m_filter_file_number,
|
|
||||||
m_filter_channel_number, m_last_sector_subheader.file_number,
|
|
||||||
m_last_sector_subheader.channel_number);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ProcessXAADPCMSector(raw_sector, subq);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Audio+realtime sectors aren't delivered to the CPU.
|
// Audio+realtime sectors aren't delivered to the CPU.
|
||||||
return;
|
return;
|
||||||
|
@ -1646,8 +1639,46 @@ static void ResampleXAADPCM(const s16* frames_in, u32 num_frames_in, SPU* spu, s
|
||||||
*sixstep_ptr = sixstep;
|
*sixstep_ptr = sixstep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CDROM::ResetCurrentXAFile()
|
||||||
|
{
|
||||||
|
m_xa_current_channel_number = 0;
|
||||||
|
m_xa_current_file_number = 0;
|
||||||
|
m_xa_current_set = false;
|
||||||
|
}
|
||||||
|
|
||||||
void CDROM::ProcessXAADPCMSector(const u8* raw_sector, const CDImage::SubChannelQ& subq)
|
void CDROM::ProcessXAADPCMSector(const u8* raw_sector, const CDImage::SubChannelQ& subq)
|
||||||
{
|
{
|
||||||
|
// Check for automatic ADPCM filter.
|
||||||
|
if (m_mode.xa_filter && (m_last_sector_subheader.file_number != m_xa_filter_file_number ||
|
||||||
|
m_last_sector_subheader.channel_number != m_xa_filter_channel_number))
|
||||||
|
{
|
||||||
|
Log_DebugPrintf("Skipping sector due to filter mismatch (expected %u/%u got %u/%u)", m_xa_filter_file_number,
|
||||||
|
m_xa_filter_channel_number, m_last_sector_subheader.file_number,
|
||||||
|
m_last_sector_subheader.channel_number);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Track the current file being played. If this is not set by the filter, it'll be set by the first file/sector which
|
||||||
|
// is read. Fixes audio in Tomb Raider III menu.
|
||||||
|
if (!m_xa_current_set)
|
||||||
|
{
|
||||||
|
m_xa_current_file_number = m_last_sector_subheader.file_number;
|
||||||
|
m_xa_current_channel_number = m_last_sector_subheader.channel_number;
|
||||||
|
m_xa_current_set = true;
|
||||||
|
}
|
||||||
|
else if (m_last_sector_subheader.file_number != m_xa_current_file_number ||
|
||||||
|
m_last_sector_subheader.channel_number != m_xa_current_channel_number)
|
||||||
|
{
|
||||||
|
Log_DebugPrintf("Skipping sector due to current file mismatch (expected %u/%u got %u/%u)", m_xa_current_file_number,
|
||||||
|
m_xa_current_channel_number, m_last_sector_subheader.file_number,
|
||||||
|
m_last_sector_subheader.channel_number);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset current file on EOF, and play the file in the next sector.
|
||||||
|
if (m_last_sector_subheader.submode.eof)
|
||||||
|
ResetCurrentXAFile();
|
||||||
|
|
||||||
std::array<s16, CDXA::XA_ADPCM_SAMPLES_PER_SECTOR_4BIT> sample_buffer;
|
std::array<s16, CDXA::XA_ADPCM_SAMPLES_PER_SECTOR_4BIT> sample_buffer;
|
||||||
CDXA::DecodeADPCMSector(raw_sector, sample_buffer.data(), m_xa_last_samples.data());
|
CDXA::DecodeADPCMSector(raw_sector, sample_buffer.data(), m_xa_last_samples.data());
|
||||||
|
|
||||||
|
@ -1878,7 +1909,7 @@ void CDROM::DrawDebugWindow()
|
||||||
m_secondary_status.id_error ? "Yes" : "No");
|
m_secondary_status.id_error ? "Yes" : "No");
|
||||||
ImGui::NextColumn();
|
ImGui::NextColumn();
|
||||||
ImGui::TextColored(m_mode.xa_filter ? active_color : inactive_color, "XA Filter: %s (File %u Channel %u)",
|
ImGui::TextColored(m_mode.xa_filter ? active_color : inactive_color, "XA Filter: %s (File %u Channel %u)",
|
||||||
m_mode.xa_filter ? "Yes" : "No", m_filter_file_number, m_filter_channel_number);
|
m_mode.xa_filter ? "Yes" : "No", m_xa_filter_file_number, m_xa_filter_channel_number);
|
||||||
ImGui::NextColumn();
|
ImGui::NextColumn();
|
||||||
|
|
||||||
ImGui::TextColored(m_status.DRQSTS ? active_color : inactive_color, "DRQSTS: %s", m_status.DRQSTS ? "Yes" : "No");
|
ImGui::TextColored(m_status.DRQSTS ? active_color : inactive_color, "DRQSTS: %s", m_status.DRQSTS ? "Yes" : "No");
|
||||||
|
@ -1946,11 +1977,20 @@ void CDROM::DrawDebugWindow()
|
||||||
|
|
||||||
if (ImGui::CollapsingHeader("CD Audio", ImGuiTreeNodeFlags_DefaultOpen))
|
if (ImGui::CollapsingHeader("CD Audio", ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
{
|
{
|
||||||
const bool playing_anything = (m_secondary_status.reading && m_mode.xa_enable) || m_secondary_status.playing_cdda;
|
if (m_secondary_status.reading && m_mode.xa_enable)
|
||||||
ImGui::TextColored(playing_anything ? active_color : inactive_color, "Playing: %s",
|
{
|
||||||
(m_secondary_status.reading && m_mode.xa_enable) ?
|
ImGui::TextColored(active_color, "Playing: XA-ADPCM (File %u / Channel %u)", m_xa_current_channel_number,
|
||||||
"XA-ADPCM" :
|
m_xa_current_file_number);
|
||||||
(m_secondary_status.playing_cdda ? "CDDA" : "Disabled"));
|
}
|
||||||
|
else if (m_secondary_status.playing_cdda)
|
||||||
|
{
|
||||||
|
ImGui::TextColored(active_color, "Playing: CDDA (Track %x)", m_last_subq.track_number_bcd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui::TextColored(inactive_color, "Playing: Inactive");
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::TextColored(m_muted ? inactive_color : active_color, "Muted: %s", m_muted ? "Yes" : "No");
|
ImGui::TextColored(m_muted ? inactive_color : active_color, "Muted: %s", m_muted ? "Yes" : "No");
|
||||||
ImGui::Text("Left Output: Left Channel=%02X (%u%%), Right Channel=%02X (%u%%)", m_cd_audio_volume_matrix[0][0],
|
ImGui::Text("Left Output: Left Channel=%02X (%u%%), Right Channel=%02X (%u%%)", m_cd_audio_volume_matrix[0][0],
|
||||||
ZeroExtend32(m_cd_audio_volume_matrix[0][0]) * 100 / 0x80, m_cd_audio_volume_matrix[1][0],
|
ZeroExtend32(m_cd_audio_volume_matrix[0][0]) * 100 / 0x80, m_cd_audio_volume_matrix[1][0],
|
||||||
|
|
|
@ -235,6 +235,7 @@ private:
|
||||||
void ProcessXAADPCMSector(const u8* raw_sector, const CDImage::SubChannelQ& subq);
|
void ProcessXAADPCMSector(const u8* raw_sector, const CDImage::SubChannelQ& subq);
|
||||||
void ProcessCDDASector(const u8* raw_sector, const CDImage::SubChannelQ& subq);
|
void ProcessCDDASector(const u8* raw_sector, const CDImage::SubChannelQ& subq);
|
||||||
void BeginSeeking(bool logical, bool read_after_seek, bool play_after_seek);
|
void BeginSeeking(bool logical, bool read_after_seek, bool play_after_seek);
|
||||||
|
void ResetCurrentXAFile();
|
||||||
void LoadDataFIFO();
|
void LoadDataFIFO();
|
||||||
void ClearSectorBuffers();
|
void ClearSectorBuffers();
|
||||||
|
|
||||||
|
@ -266,8 +267,11 @@ private:
|
||||||
bool m_muted = false;
|
bool m_muted = false;
|
||||||
bool m_adpcm_muted = false;
|
bool m_adpcm_muted = false;
|
||||||
|
|
||||||
u8 m_filter_file_number = 0;
|
u8 m_xa_filter_file_number = 0;
|
||||||
u8 m_filter_channel_number = 0;
|
u8 m_xa_filter_channel_number = 0;
|
||||||
|
u8 m_xa_current_file_number = 0;
|
||||||
|
u8 m_xa_current_channel_number = 0;
|
||||||
|
u8 m_xa_current_set = false;
|
||||||
|
|
||||||
CDImage::SectorHeader m_last_sector_header{};
|
CDImage::SectorHeader m_last_sector_header{};
|
||||||
CDXA::XASubHeader m_last_sector_subheader{};
|
CDXA::XASubHeader m_last_sector_subheader{};
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
static constexpr u32 SAVE_STATE_MAGIC = 0x43435544;
|
static constexpr u32 SAVE_STATE_MAGIC = 0x43435544;
|
||||||
static constexpr u32 SAVE_STATE_VERSION = 17;
|
static constexpr u32 SAVE_STATE_VERSION = 18;
|
||||||
|
|
Loading…
Reference in New Issue