summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/util/cdrom.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/util/cdrom.h')
-rw-r--r--src/lib/util/cdrom.h81
1 files changed, 58 insertions, 23 deletions
diff --git a/src/lib/util/cdrom.h b/src/lib/util/cdrom.h
index 214a7ed39d6..b11ecb5b3ba 100644
--- a/src/lib/util/cdrom.h
+++ b/src/lib/util/cdrom.h
@@ -16,6 +16,12 @@
#include "ioprocs.h"
#include "osdcore.h"
+#include <algorithm>
+#include <string>
+#include <string_view>
+#include <system_error>
+
+
class cdrom_file {
public:
// tracks are padded to a multiple of this many frames
@@ -24,6 +30,7 @@ public:
static constexpr uint32_t MAX_TRACKS = 99; /* AFAIK the theoretical limit */
static constexpr uint32_t MAX_SECTOR_DATA = 2352;
static constexpr uint32_t MAX_SUBCODE_DATA = 96;
+ static constexpr uint32_t MAX_INDEX = 99;
static constexpr uint32_t FRAME_SIZE = MAX_SECTOR_DATA + MAX_SUBCODE_DATA;
static constexpr uint32_t FRAMES_PER_HUNK = 8;
@@ -53,29 +60,47 @@ public:
enum
{
- CD_FLAG_GDROM = 0x00000001, // disc is a GD-ROM, all tracks should be stored with GD-ROM metadata
- CD_FLAG_GDROMLE = 0x00000002 // legacy GD-ROM, with little-endian CDDA data
+ CD_FLAG_GDROM = 0x00000001, // disc is a GD-ROM, all tracks should be stored with GD-ROM metadata
+ CD_FLAG_GDROMLE = 0x00000002, // legacy GD-ROM, with little-endian CDDA data
+ CD_FLAG_MULTISESSION = 0x00000004, // multisession CD-ROM
+ };
+
+ enum
+ {
+ CD_FLAG_CONTROL_PREEMPHASIS = 1,
+ CD_FLAG_CONTROL_DIGITAL_COPY_PERMITTED = 2,
+ CD_FLAG_CONTROL_DATA_TRACK = 4,
+ CD_FLAG_CONTROL_4CH = 8,
+ };
+
+ enum
+ {
+ CD_FLAG_ADR_START_TIME = 1,
+ CD_FLAG_ADR_CATALOG_CODE,
+ CD_FLAG_ADR_ISRC_CODE,
};
struct track_info
{
/* fields used by CHDMAN and in MAME */
- uint32_t trktype; /* track type */
- uint32_t subtype; /* subcode data type */
- uint32_t datasize; /* size of data in each sector of this track */
- uint32_t subsize; /* size of subchannel data in each sector of this track */
- uint32_t frames; /* number of frames in this track */
- uint32_t extraframes; /* number of "spillage" frames in this track */
- uint32_t pregap; /* number of pregap frames */
- uint32_t postgap; /* number of postgap frames */
- uint32_t pgtype; /* type of sectors in pregap */
- uint32_t pgsub; /* type of subchannel data in pregap */
- uint32_t pgdatasize; /* size of data in each sector of the pregap */
- uint32_t pgsubsize; /* size of subchannel data in each sector of the pregap */
+ uint32_t trktype; /* track type */
+ uint32_t subtype; /* subcode data type */
+ uint32_t datasize; /* size of data in each sector of this track */
+ uint32_t subsize; /* size of subchannel data in each sector of this track */
+ uint32_t frames; /* number of frames in this track */
+ uint32_t extraframes; /* number of "spillage" frames in this track */
+ uint32_t pregap; /* number of pregap frames */
+ uint32_t postgap; /* number of postgap frames */
+ uint32_t pgtype; /* type of sectors in pregap */
+ uint32_t pgsub; /* type of subchannel data in pregap */
+ uint32_t pgdatasize; /* size of data in each sector of the pregap */
+ uint32_t pgsubsize; /* size of subchannel data in each sector of the pregap */
+ uint32_t control_flags; /* metadata flags associated with each track */
+ uint32_t session; /* session number */
/* fields used in CHDMAN only */
uint32_t padframes; /* number of frames of padding to add to the end of the track; needed for GDI */
- uint32_t splitframes; /* number of frames to read from the next file; needed for Redump split-bin GDI */
+ uint32_t splitframes; /* number of frames from the next file to add to the end of the current track after padding; needed for Redump split-bin GDI */
/* fields used in MAME/MESS only */
uint32_t logframeofs; /* logical frame of actual track data - offset by pregap size if pregap not physically present */
@@ -91,20 +116,21 @@ public:
struct toc
{
uint32_t numtrks; /* number of tracks */
+ uint32_t numsessions; /* number of sessions */
uint32_t flags; /* see FLAG_ above */
- track_info tracks[MAX_TRACKS];
+ track_info tracks[MAX_TRACKS + 1];
};
struct track_input_entry
{
track_input_entry() { reset(); }
- void reset() { fname.clear(); offset = idx0offs = idx1offs = 0; swap = false; }
+ void reset() { fname.clear(); offset = 0; leadin = leadout = -1; swap = false; std::fill(std::begin(idx), std::end(idx), -1); }
std::string fname; // filename for each track
uint32_t offset; // offset in the data file for each track
bool swap; // data needs to be byte swapped
- uint32_t idx0offs;
- uint32_t idx1offs;
+ int32_t idx[MAX_INDEX + 1];
+ int32_t leadin, leadout; // TODO: these should probably be their own tracks entirely
};
struct track_input_info
@@ -128,6 +154,7 @@ public:
uint32_t get_track(uint32_t frame) const;
uint32_t get_track_start(uint32_t track) const {return cdtoc.tracks[track == 0xaa ? cdtoc.numtrks : track].logframeofs; }
uint32_t get_track_start_phys(uint32_t track) const { return cdtoc.tracks[track == 0xaa ? cdtoc.numtrks : track].physframeofs; }
+ uint32_t get_track_index(uint32_t frame) const;
/* TOC utilities */
static std::error_condition parse_nero(std::string_view tocfname, toc &outtoc, track_input_info &outinfo);
@@ -135,10 +162,18 @@ public:
static std::error_condition parse_gdi(std::string_view tocfname, toc &outtoc, track_input_info &outinfo);
static std::error_condition parse_cue(std::string_view tocfname, toc &outtoc, track_input_info &outinfo);
static bool is_gdicue(std::string_view tocfname);
- static std::error_condition parse_gdicue(std::string_view tocfname, toc &outtoc, track_input_info &outinfo);
static std::error_condition parse_toc(std::string_view tocfname, toc &outtoc, track_input_info &outinfo);
+ int get_last_session() const { return cdtoc.numsessions ? cdtoc.numsessions : 1; }
int get_last_track() const { return cdtoc.numtrks; }
- int get_adr_control(int track) const { return track == 0xaa || cdtoc.tracks[track].trktype == CD_TRACK_AUDIO ? 0x10 : 0x14; }
+ int get_adr_control(int track) const
+ {
+ if (track == 0xaa)
+ track = get_last_track() - 1; // use last track's flags
+ int adrctl = (CD_FLAG_ADR_START_TIME << 4) | (cdtoc.tracks[track].control_flags & 0x0f);
+ if (cdtoc.tracks[track].trktype != CD_TRACK_AUDIO)
+ adrctl |= CD_FLAG_CONTROL_DATA_TRACK;
+ return adrctl;
+ }
int get_track_type(int track) const { return cdtoc.tracks[track].trktype; }
const toc &get_toc() const { return cdtoc; }
@@ -254,8 +289,8 @@ private:
static std::string get_file_path(std::string &path);
static uint64_t get_file_size(std::string_view filename);
- static int tokenize( const char *linebuffer, int i, int linebuffersize, char *token, int tokensize );
- static int msf_to_frames( char *token );
+ static int tokenize(const char *linebuffer, int i, int linebuffersize, char *token, int tokensize);
+ static int msf_to_frames(const char *token);
static uint32_t parse_wav_sample(std::string_view filename, uint32_t *dataoffs);
static uint16_t read_uint16(FILE *infile);
static uint32_t read_uint32(FILE *infile);