mirror of
https://github.com/libretro/RetroArch
synced 2025-03-30 07:20:36 +00:00
(cheevos) support for identifying Dreamcast CHDs (#13628)
* support for identifying Dreamcast CHDs * fix copy/paste error
This commit is contained in:
parent
0e22b1ec73
commit
5d3654ddbb
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user