@@ -40,6 +40,20 @@ static void crc_append_u32(u32* crc, u32 value)
4040 *crc = CalculateCRC32 (*crc, data, sizeof (data));
4141}
4242
43+ static bool raw_sector_has_mode1_sync (const u8 * raw)
44+ {
45+ static const u8 sync[12 ] = { 0x00 , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF ,
46+ 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0x00 };
47+
48+ for (int i = 0 ; i < 12 ; i++)
49+ {
50+ if (raw[i] != sync[i])
51+ return false ;
52+ }
53+
54+ return raw[15 ] == 1 ;
55+ }
56+
4357CdRomPhysicalImage::CdRomPhysicalImage ()
4458{
4559 m_worker_running.store (false );
@@ -253,6 +267,8 @@ bool CdRomPhysicalImage::ReadTOC()
253267 }
254268
255269 m_toc.sector_count = lead_out_lba;
270+ NormalizeTrackBoundaries ();
271+
256272 LbaToMsf (m_toc.sector_count + 150 , &m_toc.total_length );
257273
258274 for (size_t i = 0 ; i < m_toc.tracks .size (); i++)
@@ -269,6 +285,58 @@ bool CdRomPhysicalImage::ReadTOC()
269285 return true ;
270286}
271287
288+ void CdRomPhysicalImage::NormalizeTrackBoundaries ()
289+ {
290+ if (m_toc.tracks .size () < 2 )
291+ return ;
292+
293+ for (size_t i = 0 ; (i + 1 ) < m_toc.tracks .size (); i++)
294+ {
295+ Track& track = m_toc.tracks [i];
296+ Track& next_track = m_toc.tracks [i + 1 ];
297+
298+ if ((track.type == GG_CDROM_AUDIO_TRACK ) || (next_track.type != GG_CDROM_AUDIO_TRACK ))
299+ continue ;
300+
301+ if (next_track.start_lba < CDROM_PHYSICAL_STANDARD_PREGAP_SECTORS )
302+ continue ;
303+
304+ u32 pregap_lba = next_track.start_lba - CDROM_PHYSICAL_STANDARD_PREGAP_SECTORS ;
305+ if ((pregap_lba <= track.start_lba ) || (pregap_lba > track.end_lba ))
306+ continue ;
307+
308+ if (IsMode1DataSector (pregap_lba))
309+ continue ;
310+
311+ if (!IsMode1DataSector (pregap_lba - 1 ))
312+ continue ;
313+
314+ Debug (" Physical CD-ROM trimming %u-sector pregap before audio track %u at LBA %u" ,
315+ (u32 )CDROM_PHYSICAL_STANDARD_PREGAP_SECTORS , (u32 )(i + 2 ), pregap_lba);
316+
317+ track.end_lba = pregap_lba - 1 ;
318+ track.sector_count = track.end_lba - track.start_lba + 1 ;
319+ LbaToMsf (track.end_lba , &track.end_msf );
320+ next_track.has_lead_in = true ;
321+ next_track.lead_in_lba = pregap_lba;
322+ }
323+ }
324+
325+ bool CdRomPhysicalImage::IsMode1DataSector (u32 lba)
326+ {
327+ if (lba >= m_toc.sector_count )
328+ return false ;
329+
330+ u8 raw[CDROM_PHYSICAL_SECTOR_SIZE ];
331+ memset (raw, 0 , sizeof (raw));
332+
333+ std::lock_guard<std::mutex> lock (m_drive_mutex);
334+ if (!m_drive.ReadRawSector2352 (lba, raw, false ))
335+ return false ;
336+
337+ return raw_sector_has_mode1_sync (raw);
338+ }
339+
272340bool CdRomPhysicalImage::DetectDataTrackType (Track& track)
273341{
274342 u8 raw[CDROM_PHYSICAL_SECTOR_SIZE ];
0 commit comments