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 // get raw sector
u8 raw_sector[RAW_SECTOR_SIZE]; u8 raw_sector[RAW_SECTOR_SIZE];
if (!ReadRawSector(raw_sector)) if (!ReadRawSector(raw_sector, nullptr))
break; break;
switch (read_mode) switch (read_mode)
@ -225,7 +225,7 @@ u32 CDImage::Read(ReadMode read_mode, u32 sector_count, void* buffer)
return sectors_read; return sectors_read;
} }
bool CDImage::ReadRawSector(void* buffer) bool CDImage::ReadRawSector(void* buffer, SubChannelQ* subq)
{ {
if (m_position_in_index == m_current_index->length) if (m_position_in_index == m_current_index->length)
{ {
@ -233,41 +233,46 @@ bool CDImage::ReadRawSector(void* buffer)
return false; 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 (m_current_index->file_sector_size > 0)
if (!ReadSectorFromIndex(buffer, *m_current_index, m_position_in_index))
{ {
Log_ErrorPrintf("Read of LBA %u failed", m_position_on_disc); // TODO: This is where we'd reconstruct the header for other mode tracks.
Seek(m_position_on_disc); if (!ReadSectorFromIndex(buffer, *m_current_index, m_position_in_index))
return false; {
} Log_ErrorPrintf("Read of LBA %u failed", m_position_on_disc);
} Seek(m_position_on_disc);
else return false;
{ }
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 else
{ {
// This in an implicit pregap. Return silence. if (m_current_index->track_number == LEAD_OUT_TRACK_NUMBER)
std::fill(static_cast<u8*>(buffer), static_cast<u8*>(buffer) + RAW_SECTOR_SIZE, u8(0)); {
// 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_on_disc++;
m_position_in_index++; m_position_in_index++;
m_position_in_track++; m_position_in_track++;
return true; 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) bool CDImage::ReadSubChannelQ(SubChannelQ* subq, const Index& index, LBA lba_in_index)
{ {
GenerateSubChannelQ(subq, index, 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. // Read from the current LBA. Returns the number of sectors read.
u32 Read(ReadMode read_mode, u32 sector_count, void* buffer); u32 Read(ReadMode read_mode, u32 sector_count, void* buffer);
// Read a single raw sector from the current LBA. // Read a single raw sector, and subchannel from the current LBA.
bool ReadRawSector(void* buffer); bool ReadRawSector(void* buffer, SubChannelQ* subq);
// Reads sub-channel Q for the current LBA.
bool ReadSubChannelQ(SubChannelQ* subq);
// Reads sub-channel Q for the specified index+LBA. // Reads sub-channel Q for the specified index+LBA.
virtual bool ReadSubChannelQ(SubChannelQ* subq, const Index& index, LBA lba_in_index); 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) if ((lba % update_interval) == 0)
progress_callback->SetProgressValue(lba); 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()); progress_callback->DisplayFormattedModalError("Failed to read sector %u from image", image->GetPositionOnDisc());
return false; 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... // reading TOC? interestingly this doesn't work for GetlocL though...
CDImage::SubChannelQ subq; 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_last_subq = subq;
m_reader.SetMedia(std::move(media)); m_reader.SetMedia(std::move(media));

View file

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