mirror of
https://github.com/holub/mame
synced 2025-05-22 21:58:57 +03:00
CHDMAN: rewrote bin/cue support from specs, more images now work. [R. Belmont]
Not for whatsnew: This is not complete or well-tested yet, I'm checking in early mostly so Kale can play with it while I'm at work today. It should at least function better than current for most images.
This commit is contained in:
parent
164cc842bd
commit
f4aa843155
@ -232,23 +232,210 @@ static chd_error chdcd_parse_gdi(const char *tocfname, cdrom_toc *outtoc, chdcd_
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
chdcd_tracksize_helper - fixes up track sizes
|
||||
for bin/cue images
|
||||
chdcd_parse_toc - parse a CDRWin format CUE file
|
||||
-------------------------------------------------*/
|
||||
|
||||
static void chdcd_tracksize_helper(int trknum, cdrom_toc *outtoc, chdcd_track_input_info *outinfo)
|
||||
chd_error chdcd_parse_cue(const char *tocfname, cdrom_toc *outtoc, chdcd_track_input_info *outinfo)
|
||||
{
|
||||
if (outtoc->tracks[trknum].frames == 0)
|
||||
FILE *infile;
|
||||
int i, trknum;
|
||||
static char token[128];
|
||||
static char lastfname[128];
|
||||
|
||||
infile = fopen(tocfname, "rt");
|
||||
|
||||
if (infile == (FILE *)NULL)
|
||||
{
|
||||
return CHDERR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* clear structures */
|
||||
memset(outtoc, 0, sizeof(cdrom_toc));
|
||||
memset(outinfo, 0, sizeof(chdcd_track_input_info));
|
||||
|
||||
trknum = -1;
|
||||
|
||||
while (!feof(infile))
|
||||
{
|
||||
/* get the next line */
|
||||
fgets(linebuffer, 511, infile);
|
||||
|
||||
/* if EOF didn't hit, keep going */
|
||||
if (!feof(infile))
|
||||
{
|
||||
i = 0;
|
||||
|
||||
TOKENIZE
|
||||
|
||||
if (!strcmp(token, "FILE"))
|
||||
{
|
||||
/* found the data file for a track */
|
||||
TOKENIZE
|
||||
|
||||
/* keep the filename */
|
||||
strncpy(&outinfo->fname[trknum][0], token, strlen(token));
|
||||
strncpy(lastfname, token, 128);
|
||||
|
||||
/* get the file type */
|
||||
TOKENIZE
|
||||
|
||||
if (!strcmp(token, "BINARY"))
|
||||
{
|
||||
outinfo->swap[trknum] = 0;
|
||||
}
|
||||
else if (!strcmp(token, "MOTOROLA"))
|
||||
{
|
||||
outinfo->swap[trknum] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("ERROR: Unhandled track type %s\n", token);
|
||||
return CHDERR_FILE_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(token, "TRACK"))
|
||||
{
|
||||
/* get the track number */
|
||||
TOKENIZE
|
||||
trknum = strtoul(token, NULL, 10) - 1;
|
||||
|
||||
/* next token on the line is the track type */
|
||||
TOKENIZE
|
||||
|
||||
outtoc->tracks[trknum].trktype = CD_TRACK_MODE1;
|
||||
outtoc->tracks[trknum].datasize = 0;
|
||||
outtoc->tracks[trknum].subtype = CD_SUB_NONE;
|
||||
outtoc->tracks[trknum].subsize = 0;
|
||||
outtoc->tracks[trknum].pregap = 0;
|
||||
outinfo->idx0offs[trknum] = 0;
|
||||
outinfo->idx1offs[trknum] = 0;
|
||||
strcpy(&outinfo->fname[trknum][0], lastfname); // default filename to the last one
|
||||
// printf("trk %d: fname %s\n", trknum+1, &outinfo->fname[trknum][0]);
|
||||
|
||||
cdrom_convert_type_string_to_track_info(token, &outtoc->tracks[trknum]);
|
||||
if (outtoc->tracks[trknum].datasize == 0)
|
||||
{
|
||||
printf("ERROR: Unknown track type [%s]. Contact MAMEDEV.\n", token);
|
||||
return CHDERR_FILE_NOT_FOUND;
|
||||
}
|
||||
else if (outtoc->tracks[trknum].trktype != CD_TRACK_MODE1_RAW &&
|
||||
outtoc->tracks[trknum].trktype != CD_TRACK_MODE2_RAW &&
|
||||
outtoc->tracks[trknum].trktype != CD_TRACK_AUDIO)
|
||||
{
|
||||
printf("Note: MAME prefers and can accept RAW format images.\n");
|
||||
printf("At least one track of this rip is not either RAW or AUDIO.\n");
|
||||
}
|
||||
|
||||
/* next (optional) token on the line is the subcode type */
|
||||
TOKENIZE
|
||||
|
||||
cdrom_convert_subtype_string_to_track_info(token, &outtoc->tracks[trknum]);
|
||||
}
|
||||
else if (!strcmp(token, "INDEX")) /* only in bin/cue files */
|
||||
{
|
||||
int idx, frames;
|
||||
|
||||
/* get index number */
|
||||
TOKENIZE
|
||||
idx = strtoul(token, NULL, 10);
|
||||
|
||||
/* get index */
|
||||
TOKENIZE
|
||||
frames = msf_to_frames( token );
|
||||
|
||||
if (idx == 0)
|
||||
{
|
||||
outinfo->idx0offs[trknum] = frames;
|
||||
}
|
||||
else if (idx == 1)
|
||||
{
|
||||
outinfo->idx1offs[trknum] = frames;
|
||||
if (!outtoc->tracks[trknum].pregap)
|
||||
{
|
||||
outtoc->tracks[trknum].pregap = frames - outinfo->idx0offs[trknum];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(token, "PREGAP"))
|
||||
{
|
||||
int frames;
|
||||
|
||||
/* get index */
|
||||
TOKENIZE
|
||||
frames = msf_to_frames( token );
|
||||
|
||||
outtoc->tracks[trknum].pregap = frames;
|
||||
}
|
||||
else if (!strcmp(token, "POSTGAP"))
|
||||
{
|
||||
int frames;
|
||||
|
||||
/* get index */
|
||||
TOKENIZE
|
||||
frames = msf_to_frames( token );
|
||||
|
||||
outtoc->tracks[trknum].postgap = frames;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* close the input CUE */
|
||||
fclose(infile);
|
||||
|
||||
/* store the number of tracks found */
|
||||
outtoc->numtrks = trknum + 1;
|
||||
|
||||
/* now go over the files again and set the lengths */
|
||||
for (trknum = 0; trknum < outtoc->numtrks; trknum++)
|
||||
{
|
||||
UINT64 tlen;
|
||||
|
||||
tlen = get_file_size(outinfo->fname[trknum]) - outinfo->offset[trknum];
|
||||
// is this the last track?
|
||||
if (trknum == (outtoc->numtrks-1))
|
||||
{
|
||||
/* if we have the same filename as the last track, do it that way */
|
||||
if (!strcmp(&outinfo->fname[trknum][0], &outinfo->fname[trknum-1][0]))
|
||||
{
|
||||
tlen = get_file_size(outinfo->fname[trknum]);
|
||||
tlen /= (outtoc->tracks[trknum].datasize + outtoc->tracks[trknum].subsize);
|
||||
outinfo->offset[trknum] = outinfo->idx1offs[trknum];
|
||||
outtoc->tracks[trknum].frames = tlen - outinfo->offset[trknum];
|
||||
}
|
||||
else /* data files are different */
|
||||
{
|
||||
tlen = get_file_size(outinfo->fname[trknum]);
|
||||
tlen /= (outtoc->tracks[trknum].datasize + outtoc->tracks[trknum].subsize);
|
||||
|
||||
outtoc->tracks[trknum].frames = tlen;
|
||||
outinfo->offset[trknum] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if we have the same filename as the next track, do it that way */
|
||||
if (!strcmp(&outinfo->fname[trknum][0], &outinfo->fname[trknum+1][0]))
|
||||
{
|
||||
// datasize = the difference between the start of the next track and our start
|
||||
outtoc->tracks[trknum].frames = outinfo->idx1offs[trknum+1] - outinfo->idx1offs[trknum];
|
||||
outinfo->offset[trknum] = outinfo->idx1offs[trknum];
|
||||
|
||||
if (!outtoc->tracks[trknum].frames)
|
||||
{
|
||||
printf("ERROR: unable to determine size of track %d, missing INDEX 01 markers?\n", trknum+1);
|
||||
return CHDERR_FILE_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
else /* data files are different */
|
||||
{
|
||||
tlen = get_file_size(outinfo->fname[trknum]);
|
||||
tlen /= (outtoc->tracks[trknum].datasize + outtoc->tracks[trknum].subsize);
|
||||
outtoc->tracks[trknum].frames = tlen;
|
||||
outinfo->offset[trknum] = 0;
|
||||
}
|
||||
}
|
||||
// printf("trk %d: %d frames @ offset %d\n", trknum+1, outtoc->tracks[trknum].frames, outinfo->offset[trknum]);
|
||||
}
|
||||
|
||||
// printf("track %d: %d frames\n", trknum, outtoc->tracks[trknum].frames);
|
||||
return CHDERR_NONE;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
@ -258,7 +445,7 @@ static void chdcd_tracksize_helper(int trknum, cdrom_toc *outtoc, chdcd_track_in
|
||||
chd_error chdcd_parse_toc(const char *tocfname, cdrom_toc *outtoc, chdcd_track_input_info *outinfo)
|
||||
{
|
||||
FILE *infile;
|
||||
int i, trknum, cuemode = 0;
|
||||
int i, trknum;
|
||||
static char token[128];
|
||||
|
||||
if (strstr(tocfname,".gdi"))
|
||||
@ -268,7 +455,7 @@ chd_error chdcd_parse_toc(const char *tocfname, cdrom_toc *outtoc, chdcd_track_i
|
||||
|
||||
if (strstr(tocfname,".cue"))
|
||||
{
|
||||
cuemode = 1;
|
||||
return chdcd_parse_cue(tocfname, outtoc, outinfo);
|
||||
}
|
||||
|
||||
infile = fopen(tocfname, "rt");
|
||||
@ -300,17 +487,6 @@ chd_error chdcd_parse_toc(const char *tocfname, cdrom_toc *outtoc, chdcd_track_i
|
||||
{
|
||||
int f;
|
||||
|
||||
/* for bin/cue, this is where you increment the track # */
|
||||
if (cuemode)
|
||||
{
|
||||
/* make sure we have a size for the current track before moving on */
|
||||
if (trknum > -1)
|
||||
{
|
||||
chdcd_tracksize_helper(trknum, outtoc, outinfo);
|
||||
}
|
||||
trknum++;
|
||||
}
|
||||
|
||||
/* found the data file for a track */
|
||||
TOKENIZE
|
||||
|
||||
@ -385,22 +561,12 @@ chd_error chdcd_parse_toc(const char *tocfname, cdrom_toc *outtoc, chdcd_track_i
|
||||
outtoc->tracks[trknum].frames = f;
|
||||
}
|
||||
else if (!strcmp(token, "TRACK"))
|
||||
{
|
||||
/* found a new track if CDRDAO .toc, not if .cue */
|
||||
if (!cuemode)
|
||||
{
|
||||
trknum++;
|
||||
}
|
||||
|
||||
/* next token on the line is the track type */
|
||||
TOKENIZE
|
||||
|
||||
/* for bin/cue skip the track number */
|
||||
if (cuemode)
|
||||
{
|
||||
TOKENIZE
|
||||
}
|
||||
|
||||
outtoc->tracks[trknum].trktype = CD_TRACK_MODE1;
|
||||
outtoc->tracks[trknum].datasize = 0;
|
||||
outtoc->tracks[trknum].subtype = CD_SUB_NONE;
|
||||
@ -410,6 +576,7 @@ chd_error chdcd_parse_toc(const char *tocfname, cdrom_toc *outtoc, chdcd_track_i
|
||||
if (outtoc->tracks[trknum].datasize == 0)
|
||||
{
|
||||
printf("ERROR: Unknown track type [%s]. Contact MAMEDEV.\n", token);
|
||||
return CHDERR_FILE_NOT_FOUND;
|
||||
}
|
||||
else if (outtoc->tracks[trknum].trktype != CD_TRACK_MODE1_RAW &&
|
||||
outtoc->tracks[trknum].trktype != CD_TRACK_MODE2_RAW &&
|
||||
@ -424,24 +591,7 @@ chd_error chdcd_parse_toc(const char *tocfname, cdrom_toc *outtoc, chdcd_track_i
|
||||
|
||||
cdrom_convert_subtype_string_to_track_info(token, &outtoc->tracks[trknum]);
|
||||
}
|
||||
else if (!strcmp(token, "INDEX")) /* only in bin/cue files */
|
||||
{
|
||||
int idx, frames;
|
||||
|
||||
/* get index number */
|
||||
TOKENIZE
|
||||
idx = strtoul(token, NULL, 10);
|
||||
|
||||
/* get index */
|
||||
TOKENIZE
|
||||
frames = msf_to_frames( token );
|
||||
|
||||
if (idx == 1)
|
||||
{
|
||||
outtoc->tracks[trknum].pregap = frames;
|
||||
}
|
||||
}
|
||||
else if ((!strcmp(token, "START")) || (!strcmp(token, "PREGAP"))) /* START for CDRDAO, PREGAP for CDRWIN */
|
||||
else if (!strcmp(token, "START"))
|
||||
{
|
||||
int frames;
|
||||
|
||||
@ -451,24 +601,8 @@ chd_error chdcd_parse_toc(const char *tocfname, cdrom_toc *outtoc, chdcd_track_i
|
||||
|
||||
outtoc->tracks[trknum].pregap = frames;
|
||||
}
|
||||
else if (!strcmp(token, "POSTGAP")) /* only in CDRWIN files */
|
||||
{
|
||||
int frames;
|
||||
|
||||
/* get index */
|
||||
TOKENIZE
|
||||
frames = msf_to_frames( token );
|
||||
|
||||
outtoc->tracks[trknum].postgap = frames;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cuemode)
|
||||
{
|
||||
/* make sure we have a size for the last track before moving on */
|
||||
chdcd_tracksize_helper(trknum, outtoc, outinfo);
|
||||
}
|
||||
|
||||
/* close the input TOC */
|
||||
fclose(infile);
|
||||
|
@ -20,6 +20,8 @@ struct _chdcd_track_input_info /* used only at compression time */
|
||||
char fname[CD_MAX_TRACKS][256]; /* filename for each track */
|
||||
UINT32 offset[CD_MAX_TRACKS]; /* offset in the data file for each track */
|
||||
int swap[CD_MAX_TRACKS]; /* data needs to be byte swapped */
|
||||
UINT32 idx0offs[CD_MAX_TRACKS];
|
||||
UINT32 idx1offs[CD_MAX_TRACKS];
|
||||
};
|
||||
|
||||
|
||||
|
@ -776,7 +776,7 @@ static int do_createcd(int argc, char *argv[], int param)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
printf("Track %d/%d (%s:%d,%d frames,%d hunks,swap %d,pregap %d,postgap %d)\n", i+1, toc.numtrks, track_info.fname[i], track_info.offset[i], toc.tracks[i].frames, trackhunks, track_info.swap[i], toc.tracks[i].pregap, toc.tracks[i].postgap);
|
||||
printf("Track %02d/%02d (%s:%d,%d frames,%d hunks,swap %d,pregap %d,postgap %d)\n", i+1, toc.numtrks, track_info.fname[i], track_info.offset[i], toc.tracks[i].frames, trackhunks, track_info.swap[i], toc.tracks[i].pregap, toc.tracks[i].postgap);
|
||||
|
||||
/* loop over hunks */
|
||||
for (curhunk = 0; curhunk < trackhunks; curhunk++, totalhunks++)
|
||||
|
Loading…
Reference in New Issue
Block a user