summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib
diff options
context:
space:
mode:
author R. Belmont <rb6502@users.noreply.github.com>2012-03-04 02:17:35 +0000
committer R. Belmont <rb6502@users.noreply.github.com>2012-03-04 02:17:35 +0000
commitbb993d1174a63b09b040251dec236a0a2c60aeb2 (patch)
tree76497c6e90eb4f2d0fb92d69f1a6c15e81a84e1f /src/lib
parentb89d7c94c7a2000cb896eb7fd0efa5cc012c672f (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.c75
-rw-r--r--src/lib/util/cdrom.h6
-rw-r--r--src/lib/util/chd.c4
-rw-r--r--src/lib/util/chd.h2
-rw-r--r--src/lib/util/chdcd.c50
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)