mirror of
https://github.com/holub/mame
synced 2025-04-27 18:53:05 +03:00
chd updates: [MetalliC]
- Bugfixed byte order for GD-ROM audio tracks so FLAC compression is effective - Fixed uninitialized struct on MSVC (and possibly other) builds nw: this will change the SHA1s of every GD-ROM CHD in MAME; a patch to reflect that is pending (the old images still work, they just take a little more space than is necessary). "chdman copy" suffices to upgrade; no downloading is necessary.
This commit is contained in:
parent
02df8f4487
commit
3eb1f14701
@ -142,6 +142,7 @@ cdrom_file *cdrom_open(const char *inputfile)
|
|||||||
file = new cdrom_file();
|
file = new cdrom_file();
|
||||||
if (file == NULL)
|
if (file == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
memset(file, 0, sizeof(cdrom_file));
|
||||||
|
|
||||||
/* setup the CDROM module and get the disc info */
|
/* setup the CDROM module and get the disc info */
|
||||||
chd_error err = chdcd_parse_toc(inputfile, file->cdtoc, file->track_info);
|
chd_error err = chdcd_parse_toc(inputfile, file->cdtoc, file->track_info);
|
||||||
@ -239,6 +240,7 @@ cdrom_file *cdrom_open(chd_file *chd)
|
|||||||
file = new cdrom_file();
|
file = new cdrom_file();
|
||||||
if (file == NULL)
|
if (file == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
memset(file, 0, sizeof(cdrom_file));
|
||||||
|
|
||||||
/* fill in the data */
|
/* fill in the data */
|
||||||
file->chd = chd;
|
file->chd = chd;
|
||||||
@ -330,18 +332,27 @@ void cdrom_close(cdrom_file *file)
|
|||||||
|
|
||||||
chd_error read_partial_sector(cdrom_file *file, void *dest, UINT32 lbasector, UINT32 chdsector, UINT32 tracknum, UINT32 startoffs, UINT32 length)
|
chd_error read_partial_sector(cdrom_file *file, void *dest, UINT32 lbasector, UINT32 chdsector, UINT32 tracknum, UINT32 startoffs, UINT32 length)
|
||||||
{
|
{
|
||||||
|
chd_error result = CHDERR_NONE;
|
||||||
|
bool needswap = false;
|
||||||
|
|
||||||
// if this is pregap info that isn't actually in the file, just return blank data
|
// if this is pregap info that isn't actually in the file, just return blank data
|
||||||
if ((file->cdtoc.tracks[tracknum].pgdatasize == 0) && (lbasector < (file->cdtoc.tracks[tracknum].logframeofs + file->cdtoc.tracks[tracknum].pregap)))
|
if ((file->cdtoc.tracks[tracknum].pgdatasize == 0) && (lbasector < (file->cdtoc.tracks[tracknum].logframeofs + file->cdtoc.tracks[tracknum].pregap)))
|
||||||
{
|
{
|
||||||
// printf("PG missing sector: LBA %d, trklog %d\n", lbasector, file->cdtoc.tracks[tracknum].logframeofs);
|
// printf("PG missing sector: LBA %d, trklog %d\n", lbasector, file->cdtoc.tracks[tracknum].logframeofs);
|
||||||
memset(dest, 0, length);
|
memset(dest, 0, length);
|
||||||
return CHDERR_NONE;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if a CHD, just read
|
// if a CHD, just read
|
||||||
if (file->chd != NULL)
|
if (file->chd != NULL)
|
||||||
return file->chd->read_bytes(UINT64(chdsector) * UINT64(CD_FRAME_SIZE) + startoffs, dest, length);
|
{
|
||||||
|
result = file->chd->read_bytes(UINT64(chdsector) * UINT64(CD_FRAME_SIZE) + startoffs, dest, length);
|
||||||
|
/* swap CDDA in the case of LE GDROMs */
|
||||||
|
if ((file->cdtoc.flags & CD_FLAG_GDROMLE) && (file->cdtoc.tracks[tracknum].trktype == CD_TRACK_AUDIO))
|
||||||
|
needswap = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// else read from the appropriate file
|
// else read from the appropriate file
|
||||||
core_file *srcfile = file->fhandle[tracknum];
|
core_file *srcfile = file->fhandle[tracknum];
|
||||||
|
|
||||||
@ -355,7 +366,10 @@ chd_error read_partial_sector(cdrom_file *file, void *dest, UINT32 lbasector, UI
|
|||||||
core_fseek(srcfile, sourcefileoffset, SEEK_SET);
|
core_fseek(srcfile, sourcefileoffset, SEEK_SET);
|
||||||
core_fread(srcfile, dest, length);
|
core_fread(srcfile, dest, length);
|
||||||
|
|
||||||
if (file->track_info.track[tracknum].swap)
|
needswap = file->track_info.track[tracknum].swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needswap)
|
||||||
{
|
{
|
||||||
UINT8 *buffer = (UINT8 *)dest - startoffs;
|
UINT8 *buffer = (UINT8 *)dest - startoffs;
|
||||||
for (int swapindex = startoffs; swapindex < 2352; swapindex += 2 )
|
for (int swapindex = startoffs; swapindex < 2352; swapindex += 2 )
|
||||||
@ -365,7 +379,7 @@ chd_error read_partial_sector(cdrom_file *file, void *dest, UINT32 lbasector, UI
|
|||||||
buffer[ swapindex + 1 ] = swaptemp;
|
buffer[ swapindex + 1 ] = swaptemp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return CHDERR_NONE;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -839,6 +853,11 @@ chd_error cdrom_parse_metadata(chd_file *chd, cdrom_toc *toc)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
err = chd->read_metadata(GDROM_OLD_METADATA_TAG, toc->numtrks, metadata);
|
||||||
|
if (err == CHDERR_NONE)
|
||||||
|
/* legacy GDROM track was detected */
|
||||||
|
toc->flags |= CD_FLAG_GDROMLE;
|
||||||
|
else
|
||||||
err = chd->read_metadata(GDROM_TRACK_METADATA_TAG, toc->numtrks, metadata);
|
err = chd->read_metadata(GDROM_TRACK_METADATA_TAG, toc->numtrks, metadata);
|
||||||
|
|
||||||
if (err == CHDERR_NONE)
|
if (err == CHDERR_NONE)
|
||||||
|
@ -56,6 +56,7 @@ enum
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define CD_FLAG_GDROM 0x00000001 // disc is a GD-ROM, all tracks should be stored with GD-ROM metadata
|
#define CD_FLAG_GDROM 0x00000001 // disc is a GD-ROM, all tracks should be stored with GD-ROM metadata
|
||||||
|
#define CD_FLAG_GDROMLE 0x00000002 // legacy GD-ROM, with little-endian CDDA data
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
TYPE DEFINITIONS
|
TYPE DEFINITIONS
|
||||||
|
@ -1412,6 +1412,7 @@ UINT32 chd_file::guess_unitbytes()
|
|||||||
if (read_metadata(CDROM_OLD_METADATA_TAG, 0, metadata) == CHDERR_NONE ||
|
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_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_OLD_METADATA_TAG, 0, metadata) == CHDERR_NONE ||
|
||||||
read_metadata(GDROM_TRACK_METADATA_TAG, 0, metadata) == CHDERR_NONE)
|
read_metadata(GDROM_TRACK_METADATA_TAG, 0, metadata) == CHDERR_NONE)
|
||||||
return CD_FRAME_SIZE;
|
return CD_FRAME_SIZE;
|
||||||
|
|
||||||
|
@ -225,7 +225,8 @@ const chd_metadata_tag CDROM_TRACK_METADATA_TAG = CHD_MAKE_TAG('C','H','T','R');
|
|||||||
extern const char *CDROM_TRACK_METADATA_FORMAT;
|
extern const char *CDROM_TRACK_METADATA_FORMAT;
|
||||||
const chd_metadata_tag CDROM_TRACK_METADATA2_TAG = CHD_MAKE_TAG('C','H','T','2');
|
const chd_metadata_tag CDROM_TRACK_METADATA2_TAG = CHD_MAKE_TAG('C','H','T','2');
|
||||||
extern const char *CDROM_TRACK_METADATA2_FORMAT;
|
extern const char *CDROM_TRACK_METADATA2_FORMAT;
|
||||||
const chd_metadata_tag GDROM_TRACK_METADATA_TAG = CHD_MAKE_TAG('C','H','G','T');
|
const chd_metadata_tag GDROM_OLD_METADATA_TAG = CHD_MAKE_TAG('C','H','G','T');
|
||||||
|
const chd_metadata_tag GDROM_TRACK_METADATA_TAG = CHD_MAKE_TAG('C', 'H', 'G', 'D');
|
||||||
extern const char *GDROM_TRACK_METADATA_FORMAT;
|
extern const char *GDROM_TRACK_METADATA_FORMAT;
|
||||||
|
|
||||||
// standard A/V metadata
|
// standard A/V metadata
|
||||||
|
@ -634,6 +634,7 @@ static chd_error chdcd_parse_gdi(const char *tocfname, cdrom_toc &outtoc, chdcd_
|
|||||||
outtoc.tracks[trknum].datasize = 0;
|
outtoc.tracks[trknum].datasize = 0;
|
||||||
outtoc.tracks[trknum].subtype = CD_SUB_NONE;
|
outtoc.tracks[trknum].subtype = CD_SUB_NONE;
|
||||||
outtoc.tracks[trknum].subsize = 0;
|
outtoc.tracks[trknum].subsize = 0;
|
||||||
|
outtoc.tracks[trknum].pgsub = CD_SUB_NONE;
|
||||||
|
|
||||||
tok=strtok(NULL," ");
|
tok=strtok(NULL," ");
|
||||||
outtoc.tracks[trknum].physframeofs=atoi(tok);
|
outtoc.tracks[trknum].physframeofs=atoi(tok);
|
||||||
@ -658,6 +659,7 @@ static chd_error chdcd_parse_gdi(const char *tocfname, cdrom_toc &outtoc, chdcd_
|
|||||||
{
|
{
|
||||||
outtoc.tracks[trknum].trktype=CD_TRACK_AUDIO;
|
outtoc.tracks[trknum].trktype=CD_TRACK_AUDIO;
|
||||||
outtoc.tracks[trknum].datasize=2352;
|
outtoc.tracks[trknum].datasize=2352;
|
||||||
|
outinfo.track[trknum].swap = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
astring name;
|
astring name;
|
||||||
|
@ -215,7 +215,8 @@ class chd_chdfile_compressor : public chd_file_compressor
|
|||||||
public:
|
public:
|
||||||
// construction/destruction
|
// construction/destruction
|
||||||
chd_chdfile_compressor(chd_file &file, UINT64 offset = 0, UINT64 maxoffset = ~0)
|
chd_chdfile_compressor(chd_file &file, UINT64 offset = 0, UINT64 maxoffset = ~0)
|
||||||
: m_file(file),
|
: m_toc(NULL),
|
||||||
|
m_file(file),
|
||||||
m_offset(offset),
|
m_offset(offset),
|
||||||
m_maxoffset(MIN(maxoffset, file.logical_bytes())) { }
|
m_maxoffset(MIN(maxoffset, file.logical_bytes())) { }
|
||||||
|
|
||||||
@ -230,9 +231,46 @@ public:
|
|||||||
chd_error err = m_file.read_bytes(offset, dest, length);
|
chd_error err = m_file.read_bytes(offset, dest, length);
|
||||||
if (err != CHDERR_NONE)
|
if (err != CHDERR_NONE)
|
||||||
throw err;
|
throw err;
|
||||||
|
|
||||||
|
// if we have TOC - detect audio sectors and swap data
|
||||||
|
if (m_toc)
|
||||||
|
{
|
||||||
|
assert(offset % CD_FRAME_SIZE == 0);
|
||||||
|
assert(length % CD_FRAME_SIZE == 0);
|
||||||
|
|
||||||
|
int startlba = offset / CD_FRAME_SIZE;
|
||||||
|
int lenlba = length / CD_FRAME_SIZE;
|
||||||
|
UINT8 *_dest = reinterpret_cast<UINT8 *>(dest);
|
||||||
|
|
||||||
|
for (int chdlba = 0; chdlba < lenlba; chdlba++)
|
||||||
|
{
|
||||||
|
// find current frame's track number
|
||||||
|
int tracknum = m_toc->numtrks;
|
||||||
|
for (int track = 0; track < m_toc->numtrks; track++)
|
||||||
|
if ((chdlba + startlba) < m_toc->tracks[track + 1].chdframeofs)
|
||||||
|
{
|
||||||
|
tracknum = track;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// is it audio ?
|
||||||
|
if (m_toc->tracks[tracknum].trktype != CD_TRACK_AUDIO)
|
||||||
|
continue;
|
||||||
|
// byteswap if yes
|
||||||
|
int dataoffset = chdlba * CD_FRAME_SIZE;
|
||||||
|
for (UINT32 swapindex = dataoffset; swapindex < (dataoffset + CD_MAX_SECTOR_DATA); swapindex += 2)
|
||||||
|
{
|
||||||
|
UINT8 temp = _dest[swapindex];
|
||||||
|
_dest[swapindex] = _dest[swapindex + 1];
|
||||||
|
_dest[swapindex + 1] = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cdrom_toc * m_toc;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// internal state
|
// internal state
|
||||||
chd_file & m_file;
|
chd_file & m_file;
|
||||||
@ -2042,7 +2080,9 @@ static void do_copy(parameters_t ¶ms)
|
|||||||
memcpy(compression, s_default_ld_compression, sizeof(compression));
|
memcpy(compression, s_default_ld_compression, sizeof(compression));
|
||||||
else if (input_chd.read_metadata(CDROM_OLD_METADATA_TAG, 0, metadata) == CHDERR_NONE ||
|
else if (input_chd.read_metadata(CDROM_OLD_METADATA_TAG, 0, metadata) == CHDERR_NONE ||
|
||||||
input_chd.read_metadata(CDROM_TRACK_METADATA_TAG, 0, metadata) == CHDERR_NONE ||
|
input_chd.read_metadata(CDROM_TRACK_METADATA_TAG, 0, metadata) == CHDERR_NONE ||
|
||||||
input_chd.read_metadata(CDROM_TRACK_METADATA2_TAG, 0, metadata) == CHDERR_NONE)
|
input_chd.read_metadata(CDROM_TRACK_METADATA2_TAG, 0, metadata) == CHDERR_NONE ||
|
||||||
|
input_chd.read_metadata(GDROM_OLD_METADATA_TAG, 0, metadata) == CHDERR_NONE ||
|
||||||
|
input_chd.read_metadata(GDROM_TRACK_METADATA_TAG, 0, metadata) == CHDERR_NONE)
|
||||||
memcpy(compression, s_default_cd_compression, sizeof(compression));
|
memcpy(compression, s_default_cd_compression, sizeof(compression));
|
||||||
else
|
else
|
||||||
memcpy(compression, s_default_raw_compression, sizeof(compression));
|
memcpy(compression, s_default_raw_compression, sizeof(compression));
|
||||||
@ -2087,6 +2127,7 @@ static void do_copy(parameters_t ¶ms)
|
|||||||
UINT8 metaflags;
|
UINT8 metaflags;
|
||||||
UINT32 index = 0;
|
UINT32 index = 0;
|
||||||
bool redo_cd = false;
|
bool redo_cd = false;
|
||||||
|
bool cdda_swap = false;
|
||||||
for (err = input_chd.read_metadata(CHDMETATAG_WILDCARD, index++, metadata, metatag, metaflags); err == CHDERR_NONE; err = input_chd.read_metadata(CHDMETATAG_WILDCARD, index++, metadata, metatag, metaflags))
|
for (err = input_chd.read_metadata(CHDMETATAG_WILDCARD, index++, metadata, metatag, metaflags); err == CHDERR_NONE; err = input_chd.read_metadata(CHDMETATAG_WILDCARD, index++, metadata, metatag, metaflags))
|
||||||
{
|
{
|
||||||
// if this is an old CD-CHD tag, note that we want to re-do it
|
// if this is an old CD-CHD tag, note that we want to re-do it
|
||||||
@ -2095,6 +2136,12 @@ static void do_copy(parameters_t ¶ms)
|
|||||||
redo_cd = true;
|
redo_cd = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// if this is old GD tag we want re-do it and swap CDDA
|
||||||
|
if (metatag == GDROM_OLD_METADATA_TAG)
|
||||||
|
{
|
||||||
|
cdda_swap = redo_cd = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// otherwise, clone it
|
// otherwise, clone it
|
||||||
err = chd->write_metadata(metatag, CHDMETAINDEX_APPEND, metadata, metaflags);
|
err = chd->write_metadata(metatag, CHDMETAINDEX_APPEND, metadata, metaflags);
|
||||||
@ -2112,6 +2159,8 @@ static void do_copy(parameters_t ¶ms)
|
|||||||
err = cdrom_write_metadata(chd, toc);
|
err = cdrom_write_metadata(chd, toc);
|
||||||
if (err != CHDERR_NONE)
|
if (err != CHDERR_NONE)
|
||||||
report_error(1, "Error writing upgraded CD metadata: %s", chd_file::error_string(err));
|
report_error(1, "Error writing upgraded CD metadata: %s", chd_file::error_string(err));
|
||||||
|
if (cdda_swap)
|
||||||
|
chd->m_toc = toc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// compress it generically
|
// compress it generically
|
||||||
@ -2354,8 +2403,9 @@ static void do_extract_cd(parameters_t ¶ms)
|
|||||||
// read the data
|
// read the data
|
||||||
cdrom_read_data(cdrom, cdrom_get_track_start_phys(cdrom, tracknum) + frame, &buffer[bufferoffs], trackinfo.trktype, true);
|
cdrom_read_data(cdrom, cdrom_get_track_start_phys(cdrom, tracknum) + frame, &buffer[bufferoffs], trackinfo.trktype, true);
|
||||||
|
|
||||||
// for CDRWin, audio tracks must be reversed
|
// for CDRWin and GDI audio tracks must be reversed
|
||||||
if ((mode == MODE_CUEBIN) && (trackinfo.trktype == CD_TRACK_AUDIO))
|
// in the case of GDI and CHD version < 5 we assuming source CHD image is GDROM so audio tracks is already reversed
|
||||||
|
if (((mode == MODE_GDI && input_chd.version() > 4) || (mode == MODE_CUEBIN)) && (trackinfo.trktype == CD_TRACK_AUDIO))
|
||||||
for (int swapindex = 0; swapindex < trackinfo.datasize; swapindex += 2)
|
for (int swapindex = 0; swapindex < trackinfo.datasize; swapindex += 2)
|
||||||
{
|
{
|
||||||
UINT8 swaptemp = buffer[bufferoffs + swapindex];
|
UINT8 swaptemp = buffer[bufferoffs + swapindex];
|
||||||
|
Loading…
Reference in New Issue
Block a user