1212static void cdfs_determine_sector_size (cdfs_track_t * track )
1313{
1414 uint8_t buffer [32 ];
15- int64_t stream_size ;
16- const int toc_sector = track -> pregap_sectors + 16 ;
15+ const int toc_sector = 16 ;
1716
1817 /* MODE information is normally found in the CUE sheet, but we can try to determine it from the raw data.
1918 *
@@ -28,7 +27,7 @@ static void cdfs_determine_sector_size(cdfs_track_t* track)
2827 */
2928
3029 /* The boot record or primary volume descriptor is always at sector 16 and will contain a "CD001" marker */
31- intfstream_seek (track -> stream , toc_sector * 2352 , SEEK_SET );
30+ intfstream_seek (track -> stream , toc_sector * 2352 + track -> first_sector_offset , SEEK_SET );
3231 if (intfstream_read (track -> stream , buffer , sizeof (buffer )) < sizeof (buffer ))
3332 return ;
3433
@@ -59,34 +58,12 @@ static void cdfs_determine_sector_size(cdfs_track_t* track)
5958 track -> stream_sector_size = 2352 ;
6059 track -> stream_sector_header_size = 16 ;
6160 }
62- else
63- {
64- /* no recognizable header - attempt to determine sector size from stream size */
65- stream_size = intfstream_get_size (track -> stream );
66-
67- if ((stream_size % 2352 ) == 0 )
68- {
69- /* audio tracks use all 2352 bytes without a header */
70- track -> stream_sector_size = 2352 ;
71- }
72- else if ((stream_size % 2048 ) == 0 )
73- {
74- /* cooked tracks eliminate all header/footer data */
75- track -> stream_sector_size = 2048 ;
76- }
77- else if ((stream_size % 2336 ) == 0 )
78- {
79- /* MODE 2 format without 16-byte sync data */
80- track -> stream_sector_size = 2336 ;
81- track -> stream_sector_header_size = 8 ;
82- }
83- }
8461 }
8562}
8663
8764static void cdfs_seek_track_sector (cdfs_track_t * track , unsigned int sector )
8865{
89- intfstream_seek (track -> stream , ( sector + track -> pregap_sectors ) * track -> stream_sector_size + track -> stream_sector_header_size , SEEK_SET );
66+ intfstream_seek (track -> stream , sector * track -> stream_sector_size + track -> stream_sector_header_size + track -> first_sector_offset , SEEK_SET );
9067}
9168
9269void cdfs_seek_sector (cdfs_file_t * file , unsigned int sector )
@@ -155,8 +132,7 @@ static int cdfs_find_file(cdfs_file_t* file, const char* path)
155132 strncasecmp ((const char * )(tmp + 33 ), path , path_length ) == 0 )
156133 {
157134 /* the file size is in bytes 10-13 of the record */
158- if (!slash )
159- file -> size = tmp [10 ] | (tmp [11 ] << 8 ) | (tmp [12 ] << 16 ) | (tmp [13 ] << 24 );
135+ file -> size = tmp [10 ] | (tmp [11 ] << 8 ) | (tmp [12 ] << 16 ) | (tmp [13 ] << 24 );
160136
161137 /* the file contents are in the sector identified in bytes 2-4 of the record */
162138 sector = tmp [2 ] | (tmp [3 ] << 8 ) | (tmp [4 ] << 16 );
@@ -342,7 +318,7 @@ static void cdfs_skip_spaces(const char** ptr)
342318 ++ (* ptr );
343319}
344320
345- static cdfs_track_t * cdfs_wrap_stream (intfstream_t * stream , unsigned pregap_sectors )
321+ static cdfs_track_t * cdfs_wrap_stream (intfstream_t * stream , unsigned first_sector_offset )
346322{
347323 cdfs_track_t * track ;
348324
@@ -351,7 +327,7 @@ static cdfs_track_t* cdfs_wrap_stream(intfstream_t* stream, unsigned pregap_sect
351327
352328 track = (cdfs_track_t * )calloc (1 , sizeof (* track ));
353329 track -> stream = stream ;
354- track -> pregap_sectors = pregap_sectors ;
330+ track -> first_sector_offset = first_sector_offset ;
355331 cdfs_determine_sector_size (track );
356332 return track ;
357333}
@@ -363,11 +339,15 @@ static cdfs_track_t* cdfs_open_cue_track(const char* path, unsigned int track_in
363339 int found_track = 0 ;
364340 char current_track_path [PATH_MAX_LENGTH ] = {0 };
365341 char track_path [PATH_MAX_LENGTH ] = {0 };
366- unsigned int pregap_sectors = 0 ;
342+ unsigned int sector_size = 0 ;
343+ unsigned int previous_sector_size = 0 ;
344+ unsigned int previous_index_sector_offset = 0 ;
345+ unsigned int track_offset = 0 ;
367346 intfstream_t * cue_stream = intfstream_open_file (path , RETRO_VFS_FILE_ACCESS_READ , RETRO_VFS_FILE_ACCESS_HINT_NONE );
368347 int64_t stream_size = intfstream_get_size (cue_stream );
369348 char * cue_contents = (char * )malloc (stream_size + 1 );
370-
349+ cdfs_track_t * track = NULL ;
350+
371351 if (!cue_contents )
372352 {
373353 intfstream_close (cue_stream );
@@ -410,6 +390,10 @@ static cdfs_track_t* cdfs_open_cue_track(const char* path, unsigned int track_in
410390 memcpy (current_track_path , file , file_end - file );
411391 current_track_path [file_end - file ] = '\0' ;
412392 }
393+
394+ previous_sector_size = 0 ;
395+ previous_index_sector_offset = 0 ;
396+ track_offset = 0 ;
413397 }
414398 else if (!strncasecmp (line , "TRACK" , 5 ))
415399 {
@@ -419,58 +403,60 @@ static cdfs_track_t* cdfs_open_cue_track(const char* path, unsigned int track_in
419403 cdfs_skip_spaces (& track );
420404
421405 sscanf (track , "%d" , & track_number );
406+ while (* track && * track != ' ' && * track != '\n' )
407+ ++ track ;
408+
409+ previous_sector_size = sector_size ;
422410
423- if (track_index )
411+ cdfs_skip_spaces (& track );
412+
413+ if (!strncasecmp (track , "MODE" , 4 ))
424414 {
425- if (track_index == track_number )
415+ /* track_index = 0 means find the first data track */
416+ if (!track_index || track_index == track_number )
426417 found_track = track_number ;
418+
419+ sector_size = atoi (track + 6 );
427420 }
428- else /* track_index = 0 means find the first data track */
421+ else
429422 {
430- while (track [0 ] && track [0 ] != ' ' && track [0 ] != '\t' )
431- track ++ ;
432-
433- if (track [0 ])
434- {
435- cdfs_skip_spaces (& track );
436-
437- if (!strncasecmp (track , "MODE" , 4 ))
438- found_track = track_number ;
439- }
423+ /* assume AUDIO */
424+ sector_size = 2352 ;
440425 }
441426 }
442- else if (found_track && !strncasecmp (line , "INDEX" , 5 ))
427+ else if (!strncasecmp (line , "INDEX" , 5 ))
443428 {
429+ unsigned min = 0 , sec = 0 , frame = 0 ;
430+ unsigned index_number = 0 ;
431+ unsigned sector_offset ;
444432 const char * index = line + 5 ;
433+
434+ cdfs_skip_spaces (& index );
435+ sscanf (index , "%u" , & index_number );
436+ while (* index && * index != ' ' && * index != '\n' )
437+ ++ index ;
445438 cdfs_skip_spaces (& index );
446439
447- if (index [0 ])
448- {
449- unsigned index_number = 0 ;
450- sscanf (index , "%u" , & index_number );
440+ sscanf (index , "%u:%u:%u" , & min , & sec , & frame );
441+ sector_offset = ((min * 60 ) + sec ) * 75 + frame ;
442+ sector_offset -= previous_index_sector_offset ;
443+ track_offset += sector_offset * previous_sector_size ;
444+ previous_sector_size = sector_size ;
445+ previous_index_sector_offset += sector_offset ;
451446
452- if (index_number == 1 )
447+ if (found_track && index_number == 1 )
448+ {
449+ if (strstr (current_track_path , "/" ) || strstr (current_track_path , "\\" ))
453450 {
454- unsigned min = 0 , sec = 0 , frame = 0 ;
455- const char * ptr = index ;
456- while (* ptr && * ptr != ' ' && * ptr != '\n' )
457- ++ ptr ;
458- cdfs_skip_spaces (& ptr );
459- sscanf (ptr , "%u:%u:%u" , & min , & sec , & frame );
460- pregap_sectors = ((min * 60 ) + sec ) * 75 + frame ;
461-
462- if (strstr (current_track_path , "/" ) || strstr (current_track_path , "\\" ))
463- {
464- strncpy (track_path , current_track_path , sizeof (track_path ));
465- }
466- else
467- {
468- fill_pathname_basedir (track_path , path , sizeof (track_path ));
469- strlcat (track_path , current_track_path , sizeof (track_path ));
470- }
471-
472- break ;
451+ strncpy (track_path , current_track_path , sizeof (track_path ));
473452 }
453+ else
454+ {
455+ fill_pathname_basedir (track_path , path , sizeof (track_path ));
456+ strlcat (track_path , current_track_path , sizeof (track_path ));
457+ }
458+
459+ break ;
474460 }
475461 }
476462 }
@@ -480,27 +466,42 @@ static cdfs_track_t* cdfs_open_cue_track(const char* path, unsigned int track_in
480466 if (string_is_empty (track_path ))
481467 return NULL ;
482468
483- return cdfs_wrap_stream (intfstream_open_file (track_path , RETRO_VFS_FILE_ACCESS_READ , RETRO_VFS_FILE_ACCESS_HINT_NONE ), pregap_sectors );
469+ track = cdfs_wrap_stream (intfstream_open_file (track_path , RETRO_VFS_FILE_ACCESS_READ , RETRO_VFS_FILE_ACCESS_HINT_NONE ), track_offset );
470+ if (track && track -> stream_sector_size == 0 )
471+ {
472+ track -> stream_sector_size = sector_size ;
473+
474+ if (sector_size == 2352 )
475+ track -> stream_sector_header_size = 16 ;
476+ else if (sector_size == 2336 )
477+ track -> stream_sector_header_size = 8 ;
478+ }
479+
480+ return track ;
484481}
485482
486483#ifdef HAVE_CHD
487484static cdfs_track_t * cdfs_open_chd_track (const char * path , int32_t track_index )
488485{
489486 intfstream_t * intf_stream ;
490487 cdfs_track_t * track ;
491- unsigned int pregap_sectors ;
492488
493489 intf_stream = intfstream_open_chd_track (path , RETRO_VFS_FILE_ACCESS_READ , RETRO_VFS_FILE_ACCESS_HINT_NONE , track_index );
494490 if (!intf_stream )
495491 return NULL ;
496492
497- pregap_sectors = intfstream_get_chd_pregap (intf_stream );
493+ track = cdfs_wrap_stream (intf_stream , intfstream_get_offset_to_start ( intf_stream ) );
498494
499- track = cdfs_wrap_stream (intf_stream , pregap_sectors );
495+ if (track && track -> stream_sector_header_size == 0 )
496+ {
497+ track -> stream_sector_size = intfstream_get_frame_size (intf_stream );
498+
499+ if (track -> stream_sector_size == 2352 )
500+ track -> stream_sector_header_size = 16 ;
501+ else if (track -> stream_sector_size == 2336 )
502+ track -> stream_sector_header_size = 8 ;
503+ }
500504
501- /* CHD removes the markers from the header, so we can't detect the header size, just assume its 16 bytes */
502- if (track -> stream_sector_header_size == 0 )
503- track -> stream_sector_header_size = 16 ;
504505 return track ;
505506}
506507#endif
0 commit comments