CDROM: Fix CDDA playback in some obscure edge cases
e.g. Roswell Conspiracies
This commit is contained in:
parent
4d74b203af
commit
0e4ca9cd93
|
@ -65,6 +65,7 @@ enum : u32
|
||||||
MAX_FAST_FORWARD_RATE = 12,
|
MAX_FAST_FORWARD_RATE = 12,
|
||||||
FAST_FORWARD_RATE_STEP = 4,
|
FAST_FORWARD_RATE_STEP = 4,
|
||||||
|
|
||||||
|
CDDA_REPORT_START_DELAY = 60, // 60 frames
|
||||||
MINIMUM_INTERRUPT_DELAY = 1000,
|
MINIMUM_INTERRUPT_DELAY = 1000,
|
||||||
INTERRUPT_DELAY_CYCLES = 500,
|
INTERRUPT_DELAY_CYCLES = 500,
|
||||||
};
|
};
|
||||||
|
@ -413,6 +414,7 @@ static CDImage::SectorHeader s_last_sector_header{};
|
||||||
static XASubHeader s_last_sector_subheader{};
|
static XASubHeader s_last_sector_subheader{};
|
||||||
static bool s_last_sector_header_valid = false; // TODO: Rename to "logical pause" or something.
|
static bool s_last_sector_header_valid = false; // TODO: Rename to "logical pause" or something.
|
||||||
static CDImage::SubChannelQ s_last_subq{};
|
static CDImage::SubChannelQ s_last_subq{};
|
||||||
|
static u8 s_cdda_report_start_delay = 0;
|
||||||
static u8 s_last_cdda_report_frame_nibble = 0xFF;
|
static u8 s_last_cdda_report_frame_nibble = 0xFF;
|
||||||
static u8 s_play_track_number_bcd = 0xFF;
|
static u8 s_play_track_number_bcd = 0xFF;
|
||||||
static u8 s_async_command_parameter = 0x00;
|
static u8 s_async_command_parameter = 0x00;
|
||||||
|
@ -565,6 +567,7 @@ void CDROM::Reset()
|
||||||
std::memset(&s_last_sector_subheader, 0, sizeof(s_last_sector_subheader));
|
std::memset(&s_last_sector_subheader, 0, sizeof(s_last_sector_subheader));
|
||||||
s_last_sector_header_valid = false;
|
s_last_sector_header_valid = false;
|
||||||
std::memset(&s_last_subq, 0, sizeof(s_last_subq));
|
std::memset(&s_last_subq, 0, sizeof(s_last_subq));
|
||||||
|
s_cdda_report_start_delay = 0;
|
||||||
s_last_cdda_report_frame_nibble = 0xFF;
|
s_last_cdda_report_frame_nibble = 0xFF;
|
||||||
|
|
||||||
s_next_cd_audio_volume_matrix[0][0] = 0x80;
|
s_next_cd_audio_volume_matrix[0][0] = 0x80;
|
||||||
|
@ -604,6 +607,7 @@ TickCount CDROM::SoftReset(TickCount ticks_late)
|
||||||
s_play_after_seek = false;
|
s_play_after_seek = false;
|
||||||
s_muted = false;
|
s_muted = false;
|
||||||
s_adpcm_muted = false;
|
s_adpcm_muted = false;
|
||||||
|
s_cdda_report_start_delay = 0;
|
||||||
s_last_cdda_report_frame_nibble = 0xFF;
|
s_last_cdda_report_frame_nibble = 0xFF;
|
||||||
|
|
||||||
ClearSectorBuffers();
|
ClearSectorBuffers();
|
||||||
|
@ -711,6 +715,7 @@ bool CDROM::DoState(StateWrapper& sw)
|
||||||
sw.DoBytes(&s_last_sector_subheader, sizeof(s_last_sector_subheader));
|
sw.DoBytes(&s_last_sector_subheader, sizeof(s_last_sector_subheader));
|
||||||
sw.Do(&s_last_sector_header_valid);
|
sw.Do(&s_last_sector_header_valid);
|
||||||
sw.DoBytes(&s_last_subq, sizeof(s_last_subq));
|
sw.DoBytes(&s_last_subq, sizeof(s_last_subq));
|
||||||
|
sw.DoEx(&s_cdda_report_start_delay, 72, static_cast<u8>(0));
|
||||||
sw.Do(&s_last_cdda_report_frame_nibble);
|
sw.Do(&s_last_cdda_report_frame_nibble);
|
||||||
sw.Do(&s_play_track_number_bcd);
|
sw.Do(&s_play_track_number_bcd);
|
||||||
sw.Do(&s_async_command_parameter);
|
sw.Do(&s_async_command_parameter);
|
||||||
|
@ -2582,7 +2587,6 @@ void CDROM::BeginReading(TickCount ticks_late /* = 0 */, bool after_seek /* = fa
|
||||||
void CDROM::BeginPlaying(u8 track, TickCount ticks_late /* = 0 */, bool after_seek /* = false */)
|
void CDROM::BeginPlaying(u8 track, TickCount ticks_late /* = 0 */, bool after_seek /* = false */)
|
||||||
{
|
{
|
||||||
DEBUG_LOG("Starting playing CDDA track {}", track);
|
DEBUG_LOG("Starting playing CDDA track {}", track);
|
||||||
s_last_cdda_report_frame_nibble = 0xFF;
|
|
||||||
s_play_track_number_bcd = track;
|
s_play_track_number_bcd = track;
|
||||||
s_fast_forward_rate = 0;
|
s_fast_forward_rate = 0;
|
||||||
|
|
||||||
|
@ -2614,6 +2618,9 @@ void CDROM::BeginPlaying(u8 track, TickCount ticks_late /* = 0 */, bool after_se
|
||||||
ClearSectorBuffers();
|
ClearSectorBuffers();
|
||||||
ResetAudioDecoder();
|
ResetAudioDecoder();
|
||||||
|
|
||||||
|
s_cdda_report_start_delay = CDDA_REPORT_START_DELAY;
|
||||||
|
s_last_cdda_report_frame_nibble = 0xFF;
|
||||||
|
|
||||||
s_drive_state = DriveState::Playing;
|
s_drive_state = DriveState::Playing;
|
||||||
s_drive_event.SetInterval(ticks);
|
s_drive_event.SetInterval(ticks);
|
||||||
s_drive_event.Schedule(first_sector_ticks);
|
s_drive_event.Schedule(first_sector_ticks);
|
||||||
|
@ -3556,6 +3563,8 @@ ALWAYS_INLINE_RELEASE void CDROM::ProcessCDDASector(const u8* raw_sector, const
|
||||||
|
|
||||||
// The reporting doesn't happen if we're reading with the CDDA mode bit set.
|
// The reporting doesn't happen if we're reading with the CDDA mode bit set.
|
||||||
if (s_drive_state == DriveState::Playing && s_mode.report_audio && subq_valid)
|
if (s_drive_state == DriveState::Playing && s_mode.report_audio && subq_valid)
|
||||||
|
{
|
||||||
|
if (s_cdda_report_start_delay == 0)
|
||||||
{
|
{
|
||||||
const u8 frame_nibble = subq.absolute_frame_bcd >> 4;
|
const u8 frame_nibble = subq.absolute_frame_bcd >> 4;
|
||||||
|
|
||||||
|
@ -3595,6 +3604,11 @@ ALWAYS_INLINE_RELEASE void CDROM::ProcessCDDASector(const u8* raw_sector, const
|
||||||
peak_volume);
|
peak_volume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s_cdda_report_start_delay--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Apply volume when pushing sectors to SPU.
|
// Apply volume when pushing sectors to SPU.
|
||||||
if (s_muted || g_settings.cdrom_mute_cd_audio)
|
if (s_muted || g_settings.cdrom_mute_cd_audio)
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
|
||||||
static constexpr u32 SAVE_STATE_MAGIC = 0x43435544;
|
static constexpr u32 SAVE_STATE_MAGIC = 0x43435544;
|
||||||
static constexpr u32 SAVE_STATE_VERSION = 71;
|
static constexpr u32 SAVE_STATE_VERSION = 72;
|
||||||
static constexpr u32 SAVE_STATE_MINIMUM_VERSION = 42;
|
static constexpr u32 SAVE_STATE_MINIMUM_VERSION = 42;
|
||||||
|
|
||||||
static_assert(SAVE_STATE_VERSION >= SAVE_STATE_MINIMUM_VERSION);
|
static_assert(SAVE_STATE_VERSION >= SAVE_STATE_MINIMUM_VERSION);
|
||||||
|
|
Loading…
Reference in New Issue