CDImage: Fix incorrect index returned for track-relative 00:02:00

Fixes some voice lines being very briefly cut off in Tomb Raider.
This commit is contained in:
Connor McLaughlin 2021-05-27 03:46:33 +10:00
parent e8e8b910a5
commit 56c08254c9
5 changed files with 35 additions and 33 deletions

View file

@ -196,7 +196,7 @@ u32 CDImage::Read(ReadMode read_mode, u32 sector_count, void* buffer)
{
// get raw sector
u8 raw_sector[RAW_SECTOR_SIZE];
if (!ReadRawSector(raw_sector))
if (!ReadRawSector(raw_sector, nullptr))
break;
switch (read_mode)
@ -225,7 +225,7 @@ u32 CDImage::Read(ReadMode read_mode, u32 sector_count, void* buffer)
return sectors_read;
}
bool CDImage::ReadRawSector(void* buffer)
bool CDImage::ReadRawSector(void* buffer, SubChannelQ* subq)
{
if (m_position_in_index == m_current_index->length)
{
@ -233,41 +233,46 @@ bool CDImage::ReadRawSector(void* buffer)
return false;
}
if (m_current_index->file_sector_size > 0)
if (buffer)
{
// TODO: This is where we'd reconstruct the header for other mode tracks.
if (!ReadSectorFromIndex(buffer, *m_current_index, m_position_in_index))
if (m_current_index->file_sector_size > 0)
{
Log_ErrorPrintf("Read of LBA %u failed", m_position_on_disc);
Seek(m_position_on_disc);
return false;
}
}
else
{
if (m_current_index->track_number == LEAD_OUT_TRACK_NUMBER)
{
// Lead-out area.
std::fill(static_cast<u8*>(buffer), static_cast<u8*>(buffer) + RAW_SECTOR_SIZE, u8(0xAA));
// TODO: This is where we'd reconstruct the header for other mode tracks.
if (!ReadSectorFromIndex(buffer, *m_current_index, m_position_in_index))
{
Log_ErrorPrintf("Read of LBA %u failed", m_position_on_disc);
Seek(m_position_on_disc);
return false;
}
}
else
{
// This in an implicit pregap. Return silence.
std::fill(static_cast<u8*>(buffer), static_cast<u8*>(buffer) + RAW_SECTOR_SIZE, u8(0));
if (m_current_index->track_number == LEAD_OUT_TRACK_NUMBER)
{
// Lead-out area.
std::fill(static_cast<u8*>(buffer), static_cast<u8*>(buffer) + RAW_SECTOR_SIZE, u8(0xAA));
}
else
{
// This in an implicit pregap. Return silence.
std::fill(static_cast<u8*>(buffer), static_cast<u8*>(buffer) + RAW_SECTOR_SIZE, u8(0));
}
}
}
if (subq && !ReadSubChannelQ(subq, *m_current_index, m_position_in_index))
{
Log_ErrorPrintf("Subchannel read of LBA %u failed", m_position_on_disc);
Seek(m_position_on_disc);
return false;
}
m_position_on_disc++;
m_position_in_index++;
m_position_in_track++;
return true;
}
bool CDImage::ReadSubChannelQ(SubChannelQ* subq)
{
return ReadSubChannelQ(subq, *m_current_index, m_position_in_index);
}
bool CDImage::ReadSubChannelQ(SubChannelQ* subq, const Index& index, LBA lba_in_index)
{
GenerateSubChannelQ(subq, index, lba_in_index);

View file

@ -244,11 +244,8 @@ public:
// Read from the current LBA. Returns the number of sectors read.
u32 Read(ReadMode read_mode, u32 sector_count, void* buffer);
// Read a single raw sector from the current LBA.
bool ReadRawSector(void* buffer);
// Reads sub-channel Q for the current LBA.
bool ReadSubChannelQ(SubChannelQ* subq);
// Read a single raw sector, and subchannel from the current LBA.
bool ReadRawSector(void* buffer, SubChannelQ* subq);
// Reads sub-channel Q for the specified index+LBA.
virtual bool ReadSubChannelQ(SubChannelQ* subq, const Index& index, LBA lba_in_index);

View file

@ -27,7 +27,7 @@ static bool ReadIndex(CDImage* image, u8 track, u8 index, MD5Digest* digest, Pro
if ((lba % update_interval) == 0)
progress_callback->SetProgressValue(lba);
if (!image->ReadRawSector(sector.data()))
if (!image->ReadRawSector(sector.data(), nullptr))
{
progress_callback->DisplayFormattedModalError("Failed to read sector %u from image", image->GetPositionOnDisc());
return false;

View file

@ -280,7 +280,7 @@ void CDROM::InsertMedia(std::unique_ptr<CDImage> media)
// reading TOC? interestingly this doesn't work for GetlocL though...
CDImage::SubChannelQ subq;
if (media->Seek(0) && media->ReadSubChannelQ(&subq) && subq.IsCRCValid())
if (media->Seek(0) && media->ReadRawSector(nullptr, &subq) && subq.IsCRCValid())
m_last_subq = subq;
m_reader.SetMedia(std::move(media));

View file

@ -88,7 +88,7 @@ bool CDROMAsyncReader::ReadSectorUncached(CDImage::LBA lba, CDImage::SubChannelQ
return false;
}
if ((subq && !m_media->ReadSubChannelQ(subq)) || (data && !m_media->ReadRawSector(data->data())))
if (!m_media->ReadRawSector(data, subq))
{
Log_WarningPrintf("Read of LBA %u failed", lba);
return false;
@ -149,8 +149,8 @@ void CDROMAsyncReader::DoSectorRead()
}
}
CDImage::LBA pos = m_media->GetPositionOnDisc();
if (!m_media->ReadSubChannelQ(&m_subq) || !m_media->ReadRawSector(m_sector_buffer.data()))
const CDImage::LBA pos = m_media->GetPositionOnDisc();
if (!m_media->ReadRawSector(m_sector_buffer.data(), &m_subq))
{
m_sector_read_result.store(false);
Log_WarningPrintf("Read of LBA %u failed", pos);