diff options
| author | 2012-03-04 02:17:35 +0000 | |
|---|---|---|
| committer | 2012-03-04 02:17:35 +0000 | |
| commit | bb993d1174a63b09b040251dec236a0a2c60aeb2 (patch) | |
| tree | 76497c6e90eb4f2d0fb92d69f1a6c15e81a84e1f /src/lib | |
| parent | b89d7c94c7a2000cb896eb7fd0efa5cc012c672f (diff) | |
chdman: Correct processing of GDI files, add ability to extractcd to .gdi, verified perfect checksum round-tripping on .GDI files. [R. Belmont]
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/util/cdrom.c | 75 | ||||
| -rw-r--r-- | src/lib/util/cdrom.h | 6 | ||||
| -rw-r--r-- | src/lib/util/chd.c | 4 | ||||
| -rw-r--r-- | src/lib/util/chd.h | 2 | ||||
| -rw-r--r-- | src/lib/util/chdcd.c | 50 |
5 files changed, 86 insertions, 51 deletions
diff --git a/src/lib/util/cdrom.c b/src/lib/util/cdrom.c index d0977a1f534..9178fb5e5b3 100644 --- a/src/lib/util/cdrom.c +++ b/src/lib/util/cdrom.c @@ -702,11 +702,11 @@ chd_error cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc) /* start with no tracks */ for (toc->numtrks = 0; toc->numtrks < CD_MAX_TRACKS; toc->numtrks++) { - int tracknum = -1, frames = 0, pregap, postgap; + int tracknum = -1, frames = 0, pregap, postgap, padframes; char type[16], subtype[16], pgtype[16], pgsub[16]; cdrom_track_info *track; - pregap = postgap = 0; + pregap = postgap = padframes = 0; /* fetch the metadata for this track */ err = chd->read_metadata(CDROM_TRACK_METADATA_TAG, toc->numtrks, metadata); @@ -723,16 +723,37 @@ chd_error cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc) else { err = chd->read_metadata(CDROM_TRACK_METADATA2_TAG, toc->numtrks, metadata); - if (err != CHDERR_NONE) - break; - /* parse the metadata */ - type[0] = subtype[0] = 0; - pregap = postgap = 0; - if (sscanf(metadata, CDROM_TRACK_METADATA2_FORMAT, &tracknum, type, subtype, &frames, &pregap, pgtype, pgsub, &postgap) != 8) - return CHDERR_INVALID_DATA; - if (tracknum == 0 || tracknum > CD_MAX_TRACKS) - return CHDERR_INVALID_DATA; - track = &toc->tracks[tracknum - 1]; + if (err == CHDERR_NONE) + { + /* parse the metadata */ + type[0] = subtype[0] = 0; + pregap = postgap = 0; + if (sscanf(metadata, CDROM_TRACK_METADATA2_FORMAT, &tracknum, type, subtype, &frames, &pregap, pgtype, pgsub, &postgap) != 8) + return CHDERR_INVALID_DATA; + if (tracknum == 0 || tracknum > CD_MAX_TRACKS) + return CHDERR_INVALID_DATA; + track = &toc->tracks[tracknum - 1]; + } + else + { + err = chd->read_metadata(GDROM_TRACK_METADATA_TAG, toc->numtrks, metadata); + + if (err == CHDERR_NONE) + { + /* parse the metadata */ + type[0] = subtype[0] = 0; + pregap = postgap = 0; + if (sscanf(metadata, GDROM_TRACK_METADATA_FORMAT, &tracknum, type, subtype, &frames, &padframes, &pregap, pgtype, pgsub, &postgap) != 9) + return CHDERR_INVALID_DATA; + if (tracknum == 0 || tracknum > CD_MAX_TRACKS) + return CHDERR_INVALID_DATA; + track = &toc->tracks[tracknum - 1]; + } + else + { + break; + } + } } /* extract the track type and determine the data size */ @@ -749,6 +770,7 @@ chd_error cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc) /* set the frames and extra frames data */ track->frames = frames; + track->padframes = padframes; int padded = (frames + CD_TRACK_PADDING - 1) / CD_TRACK_PADDING; track->extraframes = padded * CD_TRACK_PADDING - frames; @@ -769,6 +791,8 @@ chd_error cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc) if (toc->numtrks > 0) return CHDERR_NONE; + printf("toc->numtrks = %d?!\n", toc->numtrks); + /* look for old-style metadata */ dynamic_buffer oldmetadata; err = chd->read_metadata(CDROM_OLD_METADATA_TAG, 0, oldmetadata); @@ -806,6 +830,7 @@ chd_error cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc) toc->tracks[i].datasize = FLIPENDIAN_INT32(toc->tracks[i].datasize); toc->tracks[i].subsize = FLIPENDIAN_INT32(toc->tracks[i].subsize); toc->tracks[i].frames = FLIPENDIAN_INT32(toc->tracks[i].frames); + toc->tracks[i].padframes = FLIPENDIAN_INT32(toc->tracks[i].padframes); toc->tracks[i].extraframes = FLIPENDIAN_INT32(toc->tracks[i].extraframes); } } @@ -826,13 +851,25 @@ chd_error cdrom_write_metadata(chd_file *chd, const cdrom_toc *toc) /* write the metadata */ for (i = 0; i < toc->numtrks; i++) { - astring metadata; - metadata.format(CDROM_TRACK_METADATA2_FORMAT, i + 1, cdrom_get_type_string(toc->tracks[i].trktype), - cdrom_get_subtype_string(toc->tracks[i].subtype), toc->tracks[i].frames, toc->tracks[i].pregap, - cdrom_get_type_string(toc->tracks[i].pgtype), cdrom_get_subtype_string(toc->tracks[i].pgsub), - toc->tracks[i].postgap); - - err = chd->write_metadata(CDROM_TRACK_METADATA2_TAG, i, metadata); + astring metadata; + if (!(toc->flags & CD_FLAG_GDROM)) + { + metadata.format(CDROM_TRACK_METADATA2_FORMAT, i + 1, cdrom_get_type_string(toc->tracks[i].trktype), + cdrom_get_subtype_string(toc->tracks[i].subtype), toc->tracks[i].frames, toc->tracks[i].pregap, + cdrom_get_type_string(toc->tracks[i].pgtype), cdrom_get_subtype_string(toc->tracks[i].pgsub), + toc->tracks[i].postgap); + + err = chd->write_metadata(CDROM_TRACK_METADATA2_TAG, i, metadata); + } + else + { + metadata.format(GDROM_TRACK_METADATA_FORMAT, i + 1, cdrom_get_type_string(toc->tracks[i].trktype), + cdrom_get_subtype_string(toc->tracks[i].subtype), toc->tracks[i].frames, toc->tracks[i].padframes, + toc->tracks[i].pregap, cdrom_get_type_string(toc->tracks[i].pgtype), + cdrom_get_subtype_string(toc->tracks[i].pgsub), toc->tracks[i].postgap); + + err = chd->write_metadata(GDROM_TRACK_METADATA_TAG, i, metadata); + } if (err != CHDERR_NONE) return err; } diff --git a/src/lib/util/cdrom.h b/src/lib/util/cdrom.h index 7ac5bead1b7..6a2832e21f8 100644 --- a/src/lib/util/cdrom.h +++ b/src/lib/util/cdrom.h @@ -84,7 +84,7 @@ enum CD_SUB_NONE /* no subcode data stored */ }; - +#define CD_FLAG_GDROM 0x00000001 // disc is a GD-ROM, all tracks should be stored with GD-ROM metadata /*************************************************************************** TYPE DEFINITIONS @@ -109,6 +109,9 @@ struct cdrom_track_info UINT32 pgdatasize; /* size of data in each sector of the pregap */ UINT32 pgsubsize; /* size of subchannel data in each sector of the pregap */ + /* fields used in CHDMAN only */ + UINT32 padframes; /* number of frames of padding to add to the end of the track; needed for GDI */ + /* fields used in MAME only */ UINT32 physframeofs; /* frame number on the real CD this track starts at */ UINT32 chdframeofs; /* frame number this track starts at on the CHD */ @@ -118,6 +121,7 @@ struct cdrom_track_info struct cdrom_toc { UINT32 numtrks; /* number of tracks */ + UINT32 flags; /* see FLAG_ above */ cdrom_track_info tracks[CD_MAX_TRACKS]; }; diff --git a/src/lib/util/chd.c b/src/lib/util/chd.c index eda906740f5..697d1ea7889 100644 --- a/src/lib/util/chd.c +++ b/src/lib/util/chd.c @@ -58,6 +58,7 @@ const char *HARD_DISK_METADATA_FORMAT = "CYLS:%d,HEADS:%d,SECS:%d,BPS:%d"; const char *CDROM_TRACK_METADATA_FORMAT = "TRACK:%d TYPE:%s SUBTYPE:%s FRAMES:%d"; const char *CDROM_TRACK_METADATA2_FORMAT = "TRACK:%d TYPE:%s SUBTYPE:%s FRAMES:%d PREGAP:%d PGTYPE:%s PGSUB:%s POSTGAP:%d"; +const char *GDROM_TRACK_METADATA_FORMAT = "TRACK:%d TYPE:%s SUBTYPE:%s FRAMES:%d PAD:%d PREGAP:%d PGTYPE:%s PGSUB:%s POSTGAP:%d"; const char *AV_METADATA_FORMAT = "FPS:%d.%06d WIDTH:%d HEIGHT:%d INTERLACED:%d CHANNELS:%d SAMPLERATE:%d"; static const UINT32 METADATA_HEADER_SIZE = 16; // metadata header size @@ -1440,7 +1441,8 @@ UINT32 chd_file::guess_unitbytes() // look for CD-ROM metadata; if found, then the unit size == CD frame size if (read_metadata(CDROM_OLD_METADATA_TAG, 0, metadata) == CHDERR_NONE || read_metadata(CDROM_TRACK_METADATA_TAG, 0, metadata) == CHDERR_NONE || - read_metadata(CDROM_TRACK_METADATA2_TAG, 0, metadata) == CHDERR_NONE) + read_metadata(CDROM_TRACK_METADATA2_TAG, 0, metadata) == CHDERR_NONE || + read_metadata(GDROM_TRACK_METADATA_TAG, 0, metadata) == CHDERR_NONE) return CD_FRAME_SIZE; // otherwise, just map 1:1 with the hunk size diff --git a/src/lib/util/chd.h b/src/lib/util/chd.h index 4eb54371e09..4ae65830dba 100644 --- a/src/lib/util/chd.h +++ b/src/lib/util/chd.h @@ -254,6 +254,8 @@ const chd_metadata_tag CDROM_TRACK_METADATA_TAG = CHD_MAKE_TAG('C','H','T','R'); extern const char *CDROM_TRACK_METADATA_FORMAT; const chd_metadata_tag CDROM_TRACK_METADATA2_TAG = CHD_MAKE_TAG('C','H','T','2'); extern const char *CDROM_TRACK_METADATA2_FORMAT; +const chd_metadata_tag GDROM_TRACK_METADATA_TAG = CHD_MAKE_TAG('C','H','G','T'); +extern const char *GDROM_TRACK_METADATA_FORMAT; // standard A/V metadata const chd_metadata_tag AV_METADATA_TAG = CHD_MAKE_TAG('A','V','A','V'); diff --git a/src/lib/util/chdcd.c b/src/lib/util/chdcd.c index 49eed70fce6..360258c9ea4 100644 --- a/src/lib/util/chdcd.c +++ b/src/lib/util/chdcd.c @@ -1,7 +1,7 @@ /*************************************************************************** TOC parser for CHD compression frontend - Handles CDRDAO .toc, CDRWIN .cue, and Sega GDROM .gdi + Handles CDRDAO .toc, CDRWIN .cue, Nero .nrg, and Sega GDROM .gdi Copyright Nicola Salmoria and the MAME Team. Visit http://mamedev.org for licensing and usage restrictions. @@ -301,7 +301,7 @@ UINT64 read_uint64(FILE *infile) } /*------------------------------------------------- - chdcd_parse_nero - parse a Nero format image file + chdcd_parse_nero - parse a Nero .NRG file -------------------------------------------------*/ chd_error chdcd_parse_nero(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo) @@ -427,6 +427,7 @@ chd_error chdcd_parse_nero(const char *tocfname, cdrom_toc &outtoc, chdcd_track_ outtoc.tracks[track-1].pgsub = CD_SUB_NONE; outtoc.tracks[track-1].pgdatasize = 0; outtoc.tracks[track-1].pgsubsize = 0; + outtoc.tracks[track-1].padframes = 0; offset += (UINT32)index2-index1; } @@ -455,7 +456,6 @@ static chd_error chdcd_parse_gdi(const char *tocfname, cdrom_toc &outtoc, chdcd_ { FILE *infile; int i, numtracks; - //int chdpos=0; astring path = astring(tocfname); @@ -471,6 +471,7 @@ static chd_error chdcd_parse_gdi(const char *tocfname, cdrom_toc &outtoc, chdcd_ memset(&outtoc, 0, sizeof(outtoc)); outinfo.reset(); + outtoc.flags = CD_FLAG_GDROM; fgets(linebuffer,511,infile); numtracks=atoi(linebuffer); @@ -481,8 +482,6 @@ static chd_error chdcd_parse_gdi(const char *tocfname, cdrom_toc &outtoc, chdcd_ int trknum; int trksize,trktype; int sz; - int hunks; - fgets(linebuffer,511,infile); @@ -493,8 +492,7 @@ static chd_error chdcd_parse_gdi(const char *tocfname, cdrom_toc &outtoc, chdcd_ outinfo.track[trknum].swap=false; outinfo.track[trknum].offset=0; - //outtoc.tracks[trknum].trktype = CD_TRACK_MODE1; - outtoc.tracks[trknum].datasize = 0; + outtoc.tracks[trknum].datasize = 0; outtoc.tracks[trknum].subtype = CD_SUB_NONE; outtoc.tracks[trknum].subsize = 0; @@ -519,7 +517,6 @@ static chd_error chdcd_parse_gdi(const char *tocfname, cdrom_toc &outtoc, chdcd_ } if(trktype==0) { - //assert(trksize==2352); outtoc.tracks[trknum].trktype=CD_TRACK_AUDIO; outtoc.tracks[trknum].datasize=2352; } @@ -540,35 +537,26 @@ static chd_error chdcd_parse_gdi(const char *tocfname, cdrom_toc &outtoc, chdcd_ } outinfo.track[trknum].fname.cpy(path).cat(name); - sz=get_file_size(outinfo.track[trknum].fname); + sz = get_file_size(outinfo.track[trknum].fname); - outtoc.tracks[trknum].frames=sz/trksize; - outtoc.tracks[trknum].extraframes=0; + outtoc.tracks[trknum].frames = sz/trksize; + outtoc.tracks[trknum].padframes = 0; - if(trknum!=0) + if (trknum != 0) { int dif=outtoc.tracks[trknum].physframeofs-(outtoc.tracks[trknum-1].frames+outtoc.tracks[trknum-1].physframeofs); - outtoc.tracks[trknum-1].frames+=dif; + outtoc.tracks[trknum-1].frames += dif; + outtoc.tracks[trknum-1].padframes = dif; } - -/* - if(trknum!=0) - { - outtoc.tracks[trknum-1].extraframes=outtoc.tracks[trknum].physframeofs-(outtoc.tracks[trknum-1].frames+outtoc.tracks[trknum-1].physframeofs); - } -*/ - hunks = (outtoc.tracks[trknum].frames+CD_FRAMES_PER_HUNK - 1) / CD_FRAMES_PER_HUNK; - outtoc.tracks[trknum].extraframes = hunks * CD_FRAMES_PER_HUNK - outtoc.tracks[trknum].frames; - - //chdpos+=outtoc.tracks[trknum].frames+outtoc.tracks[trknum].extraframes; - } - /* - for(i=0;i<numtracks;++i) + + #if 0 + for(i=0; i < numtracks; i++) { - printf("%s %d %d %d\n",outinfo.track[i].fname,outtoc.tracks[i].frames,outtoc.tracks[i].extraframes,outtoc.tracks[i].physframeofs); + printf("%s %d %d %d (true %d)\n", outinfo.track[i].fname.cstr(), outtoc.tracks[i].frames, outtoc.tracks[i].padframes, outtoc.tracks[i].physframeofs, outtoc.tracks[i].frames - outtoc.tracks[i].padframes); } - */ + #endif + /* close the input TOC */ fclose(infile); @@ -579,7 +567,7 @@ static chd_error chdcd_parse_gdi(const char *tocfname, cdrom_toc &outtoc, chdcd_ } /*------------------------------------------------- - chdcd_parse_cue - parse a CDRWin format CUE file + chdcd_parse_toc - parse a CDRWin format CUE file -------------------------------------------------*/ chd_error chdcd_parse_cue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_input_info &outinfo) @@ -683,6 +671,7 @@ chd_error chdcd_parse_cue(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i outtoc.tracks[trknum].subtype = CD_SUB_NONE; outtoc.tracks[trknum].subsize = 0; outtoc.tracks[trknum].pregap = 0; + outtoc.tracks[trknum].padframes = 0; outinfo.track[trknum].idx0offs = -1; outinfo.track[trknum].idx1offs = 0; @@ -988,6 +977,7 @@ chd_error chdcd_parse_toc(const char *tocfname, cdrom_toc &outtoc, chdcd_track_i outtoc.tracks[trknum].datasize = 0; outtoc.tracks[trknum].subtype = CD_SUB_NONE; outtoc.tracks[trknum].subsize = 0; + outtoc.tracks[trknum].padframes = 0; cdrom_convert_type_string_to_track_info(token, &outtoc.tracks[trknum]); if (outtoc.tracks[trknum].datasize == 0) |
