diff --git a/.gitattributes b/.gitattributes index aa8a277202d..682f72ba70a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1539,6 +1539,8 @@ src/lib/util/cdrom.c svneol=native#text/plain src/lib/util/cdrom.h svneol=native#text/plain src/lib/util/chd.c svneol=native#text/plain src/lib/util/chd.h svneol=native#text/plain +src/lib/util/chdcd.c svneol=native#text/plain +src/lib/util/chdcd.h svneol=native#text/plain src/lib/util/corefile.c svneol=native#text/plain src/lib/util/corefile.h svneol=native#text/plain src/lib/util/corestr.c svneol=native#text/plain @@ -4938,8 +4940,6 @@ src/osd/windows/winutf8.h svneol=native#text/plain src/osd/windows/winutil.c svneol=native#text/plain src/osd/windows/winutil.h svneol=native#text/plain src/osd/windows/winwork.c svneol=native#text/plain -src/tools/chdcd.c svneol=native#text/plain -src/tools/chdcd.h svneol=native#text/plain src/tools/chdman.c svneol=native#text/plain src/tools/jedutil.c svneol=native#text/plain src/tools/ldresample.c svneol=native#text/plain diff --git a/src/emu/imagedev/chd_cd.c b/src/emu/imagedev/chd_cd.c index 8687882605e..dea7020cf1f 100644 --- a/src/emu/imagedev/chd_cd.c +++ b/src/emu/imagedev/chd_cd.c @@ -96,8 +96,8 @@ void cdrom_image_device::device_config_complete() image_device_format *format = global_alloc_clear(image_device_format);; format->m_index = 0; format->m_name = "chdcd"; - format->m_description = "CHD CD-ROM drive"; - format->m_extensions = "chd"; + format->m_description = "CD-ROM drive"; + format->m_extensions = "chd,cue,toc,nrg,gdi"; format->m_optspec = cd_option_spec; format->m_next = NULL; @@ -129,15 +129,21 @@ bool cdrom_image_device::call_load() if (software_entry() == NULL) { - err = chd_open_file( image_core_file(), CHD_OPEN_READ, NULL, &chd ); /* CDs are never writeable */ - if ( err ) - goto error; + if (strstr(m_image_name,".chd")) { + err = chd_open_file( image_core_file(), CHD_OPEN_READ, NULL, &chd ); /* CDs are never writeable */ + if ( err ) + goto error; + } } else { chd = get_disk_handle(device().machine(), device().subtag(tempstring,"cdrom")); } /* open the CHD file */ - m_cdrom_handle = cdrom_open( chd ); + if (chd) { + m_cdrom_handle = cdrom_open( chd ); + } else { + m_cdrom_handle = cdrom_open( m_image_name ); + } if ( ! m_cdrom_handle ) goto error; diff --git a/src/lib/lib.mak b/src/lib/lib.mak index 6f3fbb552b3..608782fefe8 100644 --- a/src/lib/lib.mak +++ b/src/lib/lib.mak @@ -34,6 +34,7 @@ UTILOBJS = \ $(LIBOBJ)/util/bitmap.o \ $(LIBOBJ)/util/cdrom.o \ $(LIBOBJ)/util/chd.o \ + $(LIBOBJ)/util/chdcd.o \ $(LIBOBJ)/util/corefile.o \ $(LIBOBJ)/util/corestr.o \ $(LIBOBJ)/util/coreutil.o \ diff --git a/src/lib/util/cdrom.c b/src/lib/util/cdrom.c index a4057934b7b..91ed6e29958 100644 --- a/src/lib/util/cdrom.c +++ b/src/lib/util/cdrom.c @@ -48,7 +48,7 @@ #include "cdrom.h" #include - +#include "chdcd.h" /*************************************************************************** @@ -74,9 +74,11 @@ struct _cdrom_file { chd_file * chd; /* CHD file */ cdrom_toc cdtoc; /* TOC for the CD */ + chdcd_track_input_info track_info; /* track info */ UINT32 hunksectors; /* sectors per hunk */ UINT32 cachehunk; /* which hunk is cached */ UINT8 * cache; /* cache of the current hunk */ + core_file * fhandle[CD_MAX_TRACKS];/* file handle */ }; @@ -122,6 +124,80 @@ INLINE UINT32 physical_to_chd_lba(cdrom_file *file, UINT32 physlba, UINT32 *trac BASE FUNCTIONALITY ***************************************************************************/ +cdrom_file *cdrom_open(const char *inputfile) +{ + int i; + cdrom_file *file; + UINT32 physofs, chdofs; + + /* allocate memory for the CD-ROM file */ + file = (cdrom_file *)malloc(sizeof(cdrom_file)); + if (file == NULL) + return NULL; + + /* setup the CDROM module and get the disc info */ + chd_error err = chdcd_parse_toc(inputfile, &file->cdtoc, &file->track_info); + if (err != CHDERR_NONE) + { + fprintf(stderr, "Error reading input file: %s\n", chd_error_string(err)); + return NULL; + } + + /* fill in the data */ + file->chd = NULL; + file->hunksectors = 1; + file->cachehunk = -1; + + LOG(("CD has %d tracks\n", file->cdtoc.numtrks)); + + for (i = 0; i < file->cdtoc.numtrks; i++) + { + file_error filerr = core_fopen(file->track_info.fname[i], OPEN_FLAG_READ, &file->fhandle[i]); + if (filerr != FILERR_NONE) + { + fprintf(stderr, "Unable to open file: %s\n", file->track_info.fname[i]); + return NULL; + } + } + /* calculate the starting frame for each track, keeping in mind that CHDMAN + pads tracks out with extra frames to fit hunk size boundries + */ + physofs = chdofs = 0; + for (i = 0; i < file->cdtoc.numtrks; i++) + { + file->cdtoc.tracks[i].physframeofs = physofs; + file->cdtoc.tracks[i].chdframeofs = chdofs; + + physofs += file->cdtoc.tracks[i].frames; + chdofs += file->cdtoc.tracks[i].frames; + chdofs += file->cdtoc.tracks[i].extraframes; + + LOG(("Track %02d is format %d subtype %d datasize %d subsize %d frames %d extraframes %d physofs %d chdofs %d\n", i+1, + file->cdtoc.tracks[i].trktype, + file->cdtoc.tracks[i].subtype, + file->cdtoc.tracks[i].datasize, + file->cdtoc.tracks[i].subsize, + file->cdtoc.tracks[i].frames, + file->cdtoc.tracks[i].extraframes, + file->cdtoc.tracks[i].physframeofs, + file->cdtoc.tracks[i].chdframeofs)); + } + + /* fill out dummy entries for the last track to help our search */ + file->cdtoc.tracks[i].physframeofs = physofs; + file->cdtoc.tracks[i].chdframeofs = chdofs; + + /* allocate a cache */ + file->cache = (UINT8 *)malloc(CD_FRAME_SIZE); + if (file->cache == NULL) + { + free(file); + return NULL; + } + + return file; +} + /*------------------------------------------------- cdrom_open - "open" a CD-ROM file from an already-opened CHD file @@ -215,6 +291,12 @@ void cdrom_close(cdrom_file *file) /* free the cache */ if (file->cache) free(file->cache); + + for (int i = 0; i < file->cdtoc.numtrks; i++) + { + core_fclose(file->fhandle[i]); + } + free(file); } @@ -639,9 +721,32 @@ static chd_error read_sector_into_cache(cdrom_file *file, UINT32 lbasector, UINT /* if we haven't cached this hunk, read it now */ if (file->cachehunk != hunknum) { - err = chd_read(file->chd, hunknum, file->cache); - if (err != CHDERR_NONE) - return err; + if (file->chd) { + err = chd_read(file->chd, hunknum, file->cache); + if (err != CHDERR_NONE) + return err; + } else { + core_file *srcfile = file->fhandle[*tracknum]; + + UINT64 sourcefileoffset = file->track_info.offset[*tracknum]; + int bytespersector = file->cdtoc.tracks[*tracknum].datasize + file->cdtoc.tracks[*tracknum].subsize; + + sourcefileoffset += chdsector * bytespersector; + + core_fseek(srcfile, sourcefileoffset, SEEK_SET); + core_fread(srcfile, file->cache, bytespersector); + + if (file->track_info.swap[*tracknum]) + { + for (int swapindex = 0; swapindex < 2352; swapindex += 2 ) + { + int swaptemp = file->cache[ swapindex ]; + file->cache[ swapindex ] = file->cache[ swapindex + 1 ]; + file->cache[ swapindex + 1 ] = swaptemp; + } + } + } + file->cachehunk = hunknum; } return CHDERR_NONE; diff --git a/src/lib/util/cdrom.h b/src/lib/util/cdrom.h index 10f4a09acb7..22e4234e8a0 100644 --- a/src/lib/util/cdrom.h +++ b/src/lib/util/cdrom.h @@ -130,6 +130,8 @@ struct _cdrom_toc cdrom_file *cdrom_open(chd_file *chd); void cdrom_close(cdrom_file *file); +cdrom_file *cdrom_open(const char *inputfile); + /* core read access */ UINT32 cdrom_read_data(cdrom_file *file, UINT32 lbasector, void *buffer, UINT32 datatype); UINT32 cdrom_read_subcode(cdrom_file *file, UINT32 lbasector, void *buffer); diff --git a/src/tools/chdcd.c b/src/lib/util/chdcd.c similarity index 100% rename from src/tools/chdcd.c rename to src/lib/util/chdcd.c diff --git a/src/tools/chdcd.h b/src/lib/util/chdcd.h similarity index 100% rename from src/tools/chdcd.h rename to src/lib/util/chdcd.h diff --git a/src/tools/tools.mak b/src/tools/tools.mak index 8adb4c73165..d864774fa1e 100644 --- a/src/tools/tools.mak +++ b/src/tools/tools.mak @@ -83,7 +83,6 @@ romcmp$(EXE): $(ROMCMPOBJS) $(LIBUTIL) $(ZLIB) $(EXPAT) $(LIBOCORE) CHDMANOBJS = \ $(TOOLSOBJ)/chdman.o \ - $(TOOLSOBJ)/chdcd.o \ chdman$(EXE): $(VERSIONOBJ) $(CHDMANOBJS) $(LIBUTIL) $(ZLIB) $(EXPAT) $(LIBOCORE) @echo Linking $@...