diff --git a/libretro-common/cdrom/cdrom.c b/libretro-common/cdrom/cdrom.c index 8559a607b6..742e59c420 100644 --- a/libretro-common/cdrom/cdrom.c +++ b/libretro-common/cdrom/cdrom.c @@ -213,7 +213,9 @@ retry: #endif { rv = 0; - memcpy(buf, xfer_buf + skip, len); + + if (buf) + memcpy(buf, xfer_buf + skip, len); } else { @@ -516,6 +518,7 @@ int cdrom_write_cue(libretro_vfs_implementation_file *stream, char **out_buf, si unsigned char pmin = buf[4 + (i * 11) + 8]; unsigned char psec = buf[4 + (i * 11) + 9]; unsigned char pframe = buf[4 + (i * 11) + 10]; + unsigned lba = msf_to_lba(pmin, psec, pframe); /*printf("i %d control %d adr %d tno %d point %d: ", i, control, adr, tno, point);*/ /* why is control always 0? */ @@ -538,6 +541,7 @@ int cdrom_write_cue(libretro_vfs_implementation_file *stream, char **out_buf, si toc->track[point - 1].min = pmin; toc->track[point - 1].sec = psec; toc->track[point - 1].frame = pframe; + toc->track[point - 1].lba = lba; toc->track[point - 1].mode = mode; toc->track[point - 1].audio = audio; diff --git a/libretro-common/include/cdrom/cdrom.h b/libretro-common/include/cdrom/cdrom.h index df35c3c9c1..c751af5658 100644 --- a/libretro-common/include/cdrom/cdrom.h +++ b/libretro-common/include/cdrom/cdrom.h @@ -44,10 +44,11 @@ RETRO_BEGIN_DECLS typedef struct { - unsigned lba_start; + unsigned lba_start; /* start of pregap */ + unsigned lba; /* start of data */ unsigned track_size; unsigned char track_num; - unsigned char min; + unsigned char min; /* start of data */ unsigned char sec; unsigned char frame; unsigned char mode; diff --git a/libretro-common/include/vfs/vfs_implementation.h b/libretro-common/include/vfs/vfs_implementation.h index 980ba5921f..9b69b7eb81 100644 --- a/libretro-common/include/vfs/vfs_implementation.h +++ b/libretro-common/include/vfs/vfs_implementation.h @@ -23,6 +23,7 @@ #ifndef __LIBRETRO_SDK_VFS_IMPLEMENTATION_H #define __LIBRETRO_SDK_VFS_IMPLEMENTATION_H +#include #include #include diff --git a/libretro-common/include/vfs/vfs_implementation_cdrom.h b/libretro-common/include/vfs/vfs_implementation_cdrom.h index 0cd5d5fdda..9a91f26d33 100644 --- a/libretro-common/include/vfs/vfs_implementation_cdrom.h +++ b/libretro-common/include/vfs/vfs_implementation_cdrom.h @@ -33,12 +33,13 @@ typedef struct { char *cue_buf; size_t cue_len; - size_t byte_pos; + int64_t byte_pos; char drive; unsigned char cur_min; unsigned char cur_sec; unsigned char cur_frame; unsigned char cur_track; + unsigned cur_lba; } vfs_cdrom_t; #ifdef VFS_FRONTEND diff --git a/libretro-common/vfs/vfs_implementation.c b/libretro-common/vfs/vfs_implementation.c index 166aaea987..18dc470676 100644 --- a/libretro-common/vfs/vfs_implementation.c +++ b/libretro-common/vfs/vfs_implementation.c @@ -555,17 +555,17 @@ int retro_vfs_file_close_impl(libretro_vfs_implementation_file *stream) close(stream->fd); #endif } +#ifdef HAVE_CDROM end: + if (stream->cdrom.cue_buf) + free(stream->cdrom.cue_buf); +#endif if (stream->buf) free(stream->buf); if (stream->orig_path) free(stream->orig_path); -#ifdef HAVE_CDROM - if (stream->cdrom.cue_buf) - free(stream->cdrom.cue_buf); -#endif free(stream); return 0; diff --git a/libretro-common/vfs/vfs_implementation_cdrom.c b/libretro-common/vfs/vfs_implementation_cdrom.c index 8d36224523..40bcf3e871 100644 --- a/libretro-common/vfs/vfs_implementation_cdrom.c +++ b/libretro-common/vfs/vfs_implementation_cdrom.c @@ -24,6 +24,7 @@ #include #include #include +#include #ifdef _WIN32 #include @@ -62,7 +63,7 @@ int64_t retro_vfs_file_seek_cdrom(libretro_vfs_implementation_file *stream, int6 } else if (string_is_equal_noncase(ext, "bin")) { - unsigned frames = (offset / 2352); + int lba = (offset / 2352); unsigned char min = 0; unsigned char sec = 0; unsigned char frame = 0; @@ -70,33 +71,25 @@ int64_t retro_vfs_file_seek_cdrom(libretro_vfs_implementation_file *stream, int6 (void)seek_type; - lba_to_msf(frames, &min, &sec, &frame); - switch (whence) { case SEEK_CUR: { - min += stream->cdrom.cur_min; - sec += stream->cdrom.cur_sec; - frame += stream->cdrom.cur_frame; + unsigned new_lba; stream->cdrom.byte_pos += offset; + new_lba = vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].lba + (stream->cdrom.byte_pos / 2352); seek_type = "SEEK_CUR"; + lba_to_msf(new_lba, &min, &sec, &frame); + break; } case SEEK_END: { - unsigned char end_min = 0; - unsigned char end_sec = 0; - unsigned char end_frame = 0; - size_t end_lba = (vfs_cdrom_toc.track[vfs_cdrom_toc.num_tracks - 1].lba_start + vfs_cdrom_toc.track[vfs_cdrom_toc.num_tracks - 1].track_size) - 1; + ssize_t end_lba = (vfs_cdrom_toc.track[vfs_cdrom_toc.num_tracks - 1].lba_start + vfs_cdrom_toc.track[vfs_cdrom_toc.num_tracks - 1].track_size) - 1; - lba_to_msf(end_lba, &min, &sec, &frame); - - min += end_min; - sec += end_sec; - frame += end_frame; + lba_to_msf(end_lba + lba, &min, &sec, &frame); stream->cdrom.byte_pos = end_lba * 2352; seek_type = "SEEK_END"; @@ -108,7 +101,7 @@ int64_t retro_vfs_file_seek_cdrom(libretro_vfs_implementation_file *stream, int6 { seek_type = "SEEK_SET"; stream->cdrom.byte_pos = offset; - + lba_to_msf(vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].lba + (stream->cdrom.byte_pos / 2352), &min, &sec, &frame); break; } } @@ -116,9 +109,10 @@ int64_t retro_vfs_file_seek_cdrom(libretro_vfs_implementation_file *stream, int6 stream->cdrom.cur_min = min; stream->cdrom.cur_sec = sec; stream->cdrom.cur_frame = frame; + stream->cdrom.cur_lba = msf_to_lba(min, sec, frame); #ifdef CDROM_DEBUG - printf("CDROM Seek %s: Path %s Offset %" PRIu64 " is now at %" PRIu64 " (MSF %02d:%02d:%02d) (LBA %u)...\n", seek_type, stream->orig_path, offset, stream->cdrom.byte_pos, stream->cdrom.cur_min, stream->cdrom.cur_sec, stream->cdrom.cur_frame, msf_to_lba(stream->cdrom.cur_min, stream->cdrom.cur_sec, stream->cdrom.cur_frame)); + printf("CDROM Seek %s: Path %s Offset %" PRIu64 " is now at %" PRIu64 " (MSF %02d:%02d:%02d) (LBA %u)...\n", seek_type, stream->orig_path, offset, stream->cdrom.byte_pos, stream->cdrom.cur_min, stream->cdrom.cur_sec, stream->cdrom.cur_frame, stream->cdrom.cur_lba); fflush(stdout); #endif } @@ -298,12 +292,14 @@ void retro_vfs_file_open_cdrom( stream->cdrom.cur_min = vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].min; stream->cdrom.cur_sec = vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].sec; stream->cdrom.cur_frame = vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].frame; + stream->cdrom.cur_lba = msf_to_lba(stream->cdrom.cur_min, stream->cdrom.cur_sec, stream->cdrom.cur_frame); } else { stream->cdrom.cur_min = vfs_cdrom_toc.track[0].min; stream->cdrom.cur_sec = vfs_cdrom_toc.track[0].sec; stream->cdrom.cur_frame = vfs_cdrom_toc.track[0].frame; + stream->cdrom.cur_lba = msf_to_lba(stream->cdrom.cur_min, stream->cdrom.cur_sec, stream->cdrom.cur_frame); } } @@ -342,13 +338,11 @@ int64_t retro_vfs_file_tell_cdrom(libretro_vfs_implementation_file *stream) } else if (string_is_equal_noncase(ext, "bin")) { - unsigned lba = msf_to_lba(stream->cdrom.cur_min, stream->cdrom.cur_sec, stream->cdrom.cur_frame); - #ifdef CDROM_DEBUG - printf("CDROM (bin) Tell: Path %s Position %u\n", stream->orig_path, lba * 2352); + printf("CDROM (bin) Tell: Path %s Position %" PRId64 "\n", stream->orig_path, stream->cdrom.byte_pos); fflush(stdout); #endif - return lba * 2352; + return stream->cdrom.byte_pos; } return -1; @@ -384,26 +378,15 @@ int64_t retro_vfs_file_read_cdrom(libretro_vfs_implementation_file *stream, } else if (string_is_equal_noncase(ext, "bin")) { - unsigned frames = len / 2352; - unsigned i; size_t skip = stream->cdrom.byte_pos % 2352; unsigned char min = 0; unsigned char sec = 0; unsigned char frame = 0; - unsigned lba_cur = 0; - unsigned lba_start = 0; - lba_cur = msf_to_lba(stream->cdrom.cur_min, stream->cdrom.cur_sec, stream->cdrom.cur_frame); - - if (vfs_cdrom_toc.num_tracks > 1 && stream->cdrom.cur_track) - lba_start = msf_to_lba(vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].min, vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].sec, vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].frame); - else - lba_start = msf_to_lba(vfs_cdrom_toc.track[0].min, vfs_cdrom_toc.track[0].sec, vfs_cdrom_toc.track[0].frame); - - lba_to_msf(lba_start + lba_cur, &min, &sec, &frame); + lba_to_msf(stream->cdrom.cur_lba, &min, &sec, &frame); #ifdef CDROM_DEBUG - printf("CDROM Read: Reading %" PRIu64 " bytes from %s starting at byte offset %" PRIu64 " (MSF %02d:%02d:%02d) (LBA %u) skip %" PRIu64 "...\n", len, stream->orig_path, stream->cdrom.byte_pos, min, sec, frame, msf_to_lba(min, sec, frame), skip); + printf("CDROM Read: Reading %" PRIu64 " bytes from %s starting at byte offset %" PRIu64 " (MSF %02d:%02d:%02d) (LBA %u) skip %" PRIu64 "...\n", len, stream->orig_path, stream->cdrom.byte_pos, min, sec, frame, stream->cdrom.cur_lba, skip); fflush(stdout); #endif @@ -419,11 +402,8 @@ int64_t retro_vfs_file_read_cdrom(libretro_vfs_implementation_file *stream, } stream->cdrom.byte_pos += len; - - for (i = 0; i < frames; i++) - { - increment_msf(&stream->cdrom.cur_min, &stream->cdrom.cur_sec, &stream->cdrom.cur_frame); - } + stream->cdrom.cur_lba = vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].lba + (stream->cdrom.byte_pos / 2352); + lba_to_msf(stream->cdrom.cur_lba, &stream->cdrom.cur_min, &stream->cdrom.cur_sec, &stream->cdrom.cur_frame); #ifdef CDROM_DEBUG printf("CDROM read %" PRIu64 " bytes, position is now: %" PRIu64 " (MSF %02d:%02d:%02d) (LBA %u)\n", len, stream->cdrom.byte_pos, stream->cdrom.cur_min, stream->cdrom.cur_sec, stream->cdrom.cur_frame, msf_to_lba(stream->cdrom.cur_min, stream->cdrom.cur_sec, stream->cdrom.cur_frame));