(cheevos) support for identifying Dreamcast CHDs (#13628)

* support for identifying Dreamcast CHDs

* fix copy/paste error
This commit is contained in:
Jamiras 2022-02-15 07:09:43 -07:00 committed by GitHub
parent 0e22b1ec73
commit 5d3654ddbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 112 additions and 34 deletions

View File

@ -1278,7 +1278,7 @@ static void* rc_hash_handle_chd_open_track(
break;
case RC_HASH_CDTRACK_LARGEST:
cdfs_track = cdfs_open_track(path, CHDSTREAM_TRACK_LAST);
cdfs_track = cdfs_open_track(path, CHDSTREAM_TRACK_PRIMARY);
break;
default:
@ -1304,11 +1304,23 @@ static size_t rc_hash_handle_chd_read_sector(
void* buffer, size_t requested_bytes)
{
cdfs_file_t* file = (cdfs_file_t*)track_handle;
uint32_t track_sectors = cdfs_get_num_sectors(file);
sector -= cdfs_get_first_sector(file);
if (sector >= track_sectors)
return 0;
cdfs_seek_sector(file, sector);
return cdfs_read_file(file, buffer, requested_bytes);
}
static uint32_t rc_hash_handle_chd_first_track_sector(
void* track_handle)
{
cdfs_file_t* file = (cdfs_file_t*)track_handle;
return cdfs_get_first_sector(file);
}
static void rc_hash_handle_chd_close_track(void* track_handle)
{
cdfs_file_t* file = (cdfs_file_t*)track_handle;
@ -1337,6 +1349,7 @@ static void* rc_hash_handle_cd_open_track(
cdreader.open_track = rc_hash_handle_cd_open_track;
cdreader.read_sector = rc_hash_handle_chd_read_sector;
cdreader.close_track = rc_hash_handle_chd_close_track;
cdreader.first_track_sector = rc_hash_handle_chd_first_track_sector;
rc_hash_init_custom_cdreader(&cdreader);
return rc_hash_handle_chd_open_track(path, track);

View File

@ -58,30 +58,31 @@ static void cdfs_determine_sector_size(cdfs_track_t* track)
track->stream_sector_size = 2352;
track->stream_sector_header_size = 16;
}
else
{
/* attempt to determine stream_sector_size from file size */
size_t size = intfstream_get_size(track->stream);
}
}
if ((size % 2352) == 0)
{
/* raw tracks use all 2352 bytes and have a 24 byte header */
track->stream_sector_size = 2352;
track->stream_sector_header_size = 24;
}
else if ((size % 2048) == 0)
{
/* cooked tracks eliminate all header/footer data */
track->stream_sector_size = 2048;
track->stream_sector_header_size = 0;
}
else if ((size % 2336) == 0)
{
/* MODE 2 format without 16-byte sync data */
track->stream_sector_size = 2336;
track->stream_sector_header_size = 8;
}
}
static void cdfs_determine_sector_size_from_file_size(cdfs_track_t* track)
{
/* attempt to determine stream_sector_size from file size */
size_t size = intfstream_get_size(track->stream);
if ((size % 2352) == 0)
{
/* raw tracks use all 2352 bytes and have a 24 byte header */
track->stream_sector_size = 2352;
track->stream_sector_header_size = 24;
}
else if ((size % 2048) == 0)
{
/* cooked tracks eliminate all header/footer data */
track->stream_sector_size = 2048;
track->stream_sector_header_size = 0;
}
else if ((size % 2336) == 0)
{
/* MODE 2 format without 16-byte sync data */
track->stream_sector_size = 2336;
track->stream_sector_header_size = 8;
}
}
@ -109,6 +110,23 @@ void cdfs_seek_sector(cdfs_file_t* file, unsigned int sector)
}
}
uint32_t cdfs_get_num_sectors(cdfs_file_t* file)
{
uint32_t frame_size = intfstream_get_frame_size(file->track->stream);
if (frame_size == 0)
{
frame_size = file->track->stream_sector_size;
if (frame_size == 0)
frame_size = 1; /* prevent divide by 0 error if sector size is unknown */
}
return intfstream_get_size(file->track->stream) / frame_size;
}
uint32_t cdfs_get_first_sector(cdfs_file_t* file)
{
return file->track->first_sector_index;
}
static int cdfs_find_file(cdfs_file_t* file, const char* path)
{
size_t path_length;
@ -356,7 +374,7 @@ static void cdfs_skip_spaces(const char** ptr)
}
static cdfs_track_t* cdfs_wrap_stream(
intfstream_t* stream, unsigned first_sector_offset)
intfstream_t* stream, unsigned first_sector_offset, unsigned first_sector_index)
{
cdfs_track_t* track = NULL;
@ -367,6 +385,7 @@ static cdfs_track_t* cdfs_wrap_stream(
calloc(1, sizeof(*track));
track->stream = stream;
track->first_sector_offset = first_sector_offset;
track->first_sector_index = first_sector_index;
cdfs_determine_sector_size(track);
@ -507,9 +526,12 @@ static cdfs_track_t* cdfs_open_cue_track(
if (string_is_empty(track_path))
return NULL;
/* NOTE: previous_index_sector_offset will only be valid if all tracks are in the same BIN file.
* Otherwise, we need to determine how many tracks are in each previous BIN file, which is not
* stored in the CUE file. This will affect cdfs_get_first_sector, which luckily isn't used much. */
track = cdfs_wrap_stream(intfstream_open_file(
track_path, RETRO_VFS_FILE_ACCESS_READ,
RETRO_VFS_FILE_ACCESS_HINT_NONE), track_offset);
RETRO_VFS_FILE_ACCESS_HINT_NONE), track_offset, previous_index_sector_offset);
if (track && track->stream_sector_size == 0)
{
@ -537,7 +559,8 @@ static cdfs_track_t* cdfs_open_chd_track(const char* path, int32_t track_index)
return NULL;
track = cdfs_wrap_stream(intf_stream,
intfstream_get_offset_to_start(intf_stream));
intfstream_get_offset_to_start(intf_stream),
intfstream_get_first_sector(intf_stream));
if (track && track->stream_sector_header_size == 0)
{
@ -601,11 +624,15 @@ cdfs_track_t* cdfs_open_raw_track(const char* path)
intfstream_t* file = intfstream_open_file(path,
RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
track = cdfs_wrap_stream(file, 0);
track = cdfs_wrap_stream(file, 0, 0);
if (track != NULL && track->stream_sector_size == 0)
{
cdfs_close_track(track);
track = NULL;
cdfs_determine_sector_size_from_file_size(track);
if (track->stream_sector_size == 0)
{
cdfs_close_track(track);
track = NULL;
}
}
}
else

View File

@ -37,6 +37,7 @@ typedef struct cdfs_track_t
unsigned int stream_sector_size;
unsigned int stream_sector_header_size;
unsigned int first_sector_offset;
unsigned int first_sector_index;
} cdfs_track_t;
typedef struct cdfs_file_t
@ -70,6 +71,10 @@ int64_t cdfs_seek(cdfs_file_t* file, int64_t offset, int whence);
void cdfs_seek_sector(cdfs_file_t* file, unsigned int sector);
uint32_t cdfs_get_num_sectors(cdfs_file_t* file);
uint32_t cdfs_get_first_sector(cdfs_file_t* file);
/* opens the specified track in a CD or virtual CD file - the resulting stream should be passed to
* cdfs_open_file to get access to a file within the CD.
*

View File

@ -61,6 +61,8 @@ uint32_t chdstream_get_track_start(chdstream_t* stream);
uint32_t chdstream_get_frame_size(chdstream_t* stream);
uint32_t chdstream_get_first_track_sector(chdstream_t* stream);
RETRO_END_DECLS
#endif

View File

@ -106,6 +106,8 @@ uint32_t intfstream_get_offset_to_start(intfstream_internal_t *intf);
uint32_t intfstream_get_frame_size(intfstream_internal_t *intf);
uint32_t intfstream_get_first_sector(intfstream_internal_t* intf);
bool intfstream_is_compressed(intfstream_internal_t *intf);
bool intfstream_get_crc(intfstream_internal_t *intf, uint32_t *crc);

View File

@ -163,10 +163,7 @@ chdstream_find_special_track(chd_file *fd, int32_t track, metadata_t *meta)
if (!chdstream_find_track_number(fd, i, &iter))
{
if (track == CHDSTREAM_TRACK_LAST && i > 1)
{
*meta = iter;
return true;
}
return chdstream_find_track_number(fd, i - 1, meta);
if (track == CHDSTREAM_TRACK_PRIMARY && largest_track != 0)
return chdstream_find_track_number(fd, largest_track, meta);
@ -450,3 +447,22 @@ uint32_t chdstream_get_frame_size(chdstream_t *stream)
{
return stream->frame_size;
}
uint32_t chdstream_get_first_track_sector(chdstream_t* stream)
{
uint32_t i;
metadata_t meta;
uint32_t frame_offset = 0;
uint32_t sector_offset = 0;
for (i = 0; chdstream_get_meta(stream->chd, i, &meta); ++i)
{
if (stream->track_frame == frame_offset)
return sector_offset;
sector_offset += meta.frames;
frame_offset += meta.frames + meta.extra;
}
return 0;
}

View File

@ -604,6 +604,19 @@ uint32_t intfstream_get_frame_size(intfstream_internal_t *intf)
return 0;
}
uint32_t intfstream_get_first_sector(intfstream_internal_t* intf)
{
if (intf)
{
#ifdef HAVE_CHD
if (intf->type == INTFSTREAM_CHD)
return chdstream_get_first_track_sector(intf->chd.fp);
#endif
}
return 0;
}
bool intfstream_is_compressed(intfstream_internal_t *intf)
{
if (!intf)