CDROM: Add seek speedup enhancement

This commit is contained in:
Connor McLaughlin
2021-05-23 13:35:10 +10:00
parent 143a82b543
commit 98e4c181ca
8 changed files with 144 additions and 14 deletions

View File

@ -684,24 +684,30 @@ TickCount CDROM::GetTicksForRead()
TickCount CDROM::GetTicksForSeek(CDImage::LBA new_lba)
{
static constexpr TickCount MIN_TICKS = 20000;
if (g_settings.cdrom_seek_speedup == 0)
return MIN_TICKS;
const TickCount tps = System::GetTicksPerSecond();
const CDImage::LBA current_lba = m_secondary_status.motor_on ? m_current_lba : 0;
const u32 lba_diff = static_cast<u32>((new_lba > current_lba) ? (new_lba - current_lba) : (current_lba - new_lba));
// Formula from Mednafen.
TickCount ticks = std::max<TickCount>(
// Original formula based on Mednafen. Still not accurate, doesn't consider the varying number of sectors per track.
// TODO: Replace with algorithm based on mechacon behavior.
u32 ticks = std::max<u32>(
20000, static_cast<u32>(
((static_cast<u64>(lba_diff) * static_cast<u64>(tps) * static_cast<u64>(1000)) / (72 * 60 * 75)) / 1000));
if (!m_secondary_status.motor_on)
ticks += tps;
if (lba_diff >= 2550)
ticks += static_cast<TickCount>((u64(tps) * 300) / 1000);
ticks += static_cast<u32>((u64(tps) * 300) / 1000);
else
{
// When paused, the CDC seems to keep reading the disc until it hits the position it's set to, then skip 10-15
// sectors back (depending on how far into the disc it is). We'll be generous and use 4 sectors, since on average
// it's probably closer.
ticks += GetTicksForRead() * 4u;
ticks += static_cast<u32>(GetTicksForRead()) * 4u;
}
if (m_mode.double_speed != m_current_double_speed)
@ -714,8 +720,11 @@ TickCount CDROM::GetTicksForSeek(CDImage::LBA new_lba)
ticks += static_cast<u32>(static_cast<double>(tps) * 0.1);
}
Log_DevPrintf("Seek time for %u LBAs: %d", lba_diff, ticks);
return ticks;
if (g_settings.cdrom_seek_speedup > 1)
ticks = std::min<u32>(ticks / g_settings.cdrom_seek_speedup, MIN_TICKS);
Log_DevPrintf("Seek time for %u LBAs: %u", lba_diff, ticks);
return static_cast<u32>(ticks);
}
TickCount CDROM::GetTicksForStop(bool motor_was_on)