[libromdata] MultiTrackSparseDiscReader.hpp: New interface for multi-track sparse disc reader classes.

GdiReader and CdiReader now use MultiTrackSparseDiscReader for the
track-specific functions.

Dreamcast: Consolidate the GDI and CDI code using the new
MultiTrackSparseDiscReader interface.
This commit is contained in:
David Korth 2024-10-12 00:22:18 -04:00
parent 38f4c7439a
commit 209ea0d951
5 changed files with 117 additions and 74 deletions

View File

@ -343,6 +343,7 @@ SET(${PROJECT_NAME}_H
disc/GdiReader.hpp
disc/IResourceReader.hpp
disc/IsoPartition.hpp
disc/MultiTrackSparseDiscReader.hpp
disc/NASOSReader.hpp
disc/NCCHReader.hpp
disc/NCCHReader_p.hpp

View File

@ -198,28 +198,20 @@ rp_image_const_ptr DreamcastPrivate::load0GDTEX(void)
// Create the ISO-9660 file system reader if it isn't already opened.
if (!isoPartition) {
switch (discType) {
case DiscType::GDI: {
// Open track 3 as ISO-9660.
GdiReader *const gdiReader = dynamic_cast<GdiReader*>(discReader.get());
assert(gdiReader != nullptr);
if (!gdiReader) {
return {};
}
isoPartition = gdiReader->openIsoPartition(3);
break;
}
case DiscType::GDI:
case DiscType::CDI: {
// Open track 3 as ISO-9660.
CdiReader *const cdiReader = dynamic_cast<CdiReader*>(discReader.get());
if (!cdiReader) {
MultiTrackSparseDiscReader *const mtsDiscReader = dynamic_cast<MultiTrackSparseDiscReader*>(discReader.get());
assert(mtsDiscReader != nullptr);
if (!mtsDiscReader) {
return {};
}
isoPartition = cdiReader->openIsoPartition(3);
isoPartition = mtsDiscReader->openIsoPartition(3);
if (!isoPartition) {
// NOTE: Some CDIs only hvae two tracks.
// NOTE: Some CDIs only have two tracks.
// Try reading track 2 instead.
isoPartition = cdiReader->openIsoPartition(2);
isoPartition = mtsDiscReader->openIsoPartition(2);
}
break;
}
@ -401,37 +393,27 @@ Dreamcast::Dreamcast(const IRpFilePtr &file)
break;
}
case DreamcastPrivate::DiscType::GDI: {
// GD-ROM cuesheet
// iso_start_offset isn't used for GDI.
d->discReader = std::make_shared<GdiReader>(d->file);
GdiReader *const gdiReader = static_cast<GdiReader*>(d->discReader.get());
// Read the actual track 3 disc header.
const int lba_track03 = gdiReader->startingLBA(3);
if (lba_track03 < 0) {
// Error getting the track 03 LBA.
d->discReader.reset();
d->file.reset();
return;
}
// TODO: Don't hard-code 2048?
gdiReader->seekAndRead(lba_track03*2048, &d->discHeader, sizeof(d->discHeader));
d->mimeType = "application/x-gd-rom-cue"; // unofficial
break;
}
case DreamcastPrivate::DiscType::GDI:
case DreamcastPrivate::DiscType::CDI: {
// DiscJuggler image
// iso_start_offset isn't used for CDI.
// TODO: Base class for multi-track disc images, i.e. GDI and CDI?
d->discReader = std::make_shared<CdiReader>(d->file);
CdiReader *const cdiReader = static_cast<CdiReader*>(d->discReader.get());
// GD-ROM cuesheet or DiscJuggler image
// GDI does't use iso_start_offset.
// CDI manages its own iso_start_offset.
const char *mimeType;
if (d->discType == DreamcastPrivate::DiscType::GDI) {
d->discReader = std::make_shared<CdiReader>(d->file);
mimeType = "application/x-gd-rom-cue";
} else /*if (d->discType == DreamcastPrivate::DiscType::CDI)*/ {
d->discReader = std::make_shared<CdiReader>(d->file);
mimeType = "application/x-cdi";
}
MultiTrackSparseDiscReader *const mtsDiscReader = static_cast<MultiTrackSparseDiscReader*>(d->discReader.get());
// Read the actual track 3 disc header.
int lba_track03 = cdiReader->startingLBA(3);
int lba_track03 = mtsDiscReader->startingLBA(3);
if (lba_track03 < 0) {
// NOTE: Some CDIs only hvae two tracks.
// Try reading track 2 instead.
lba_track03 = cdiReader->startingLBA(2);
lba_track03 = mtsDiscReader->startingLBA(2);
if (lba_track03 < 0) {
// Error getting the track 03 LBA.
d->discReader.reset();
@ -439,9 +421,10 @@ Dreamcast::Dreamcast(const IRpFilePtr &file)
return;
}
}
// TODO: Don't hard-code 2048?
cdiReader->seekAndRead(lba_track03*2048, &d->discHeader, sizeof(d->discHeader));
d->mimeType = "application/x-cdi"; // unofficial
mtsDiscReader->seekAndRead(lba_track03*2048, &d->discHeader, sizeof(d->discHeader));
d->mimeType = mimeType;
break;
}
@ -822,22 +805,18 @@ int Dreamcast::loadFieldData(void)
// are used for field info only.
ISOPtr isoData;
switch (d->discType) {
case DreamcastPrivate::DiscType::GDI: {
// Open track 3 as ISO-9660.
GdiReader *const gdiReader = dynamic_cast<GdiReader*>(d->discReader.get());
assert(gdiReader != nullptr);
if (gdiReader) {
isoData = gdiReader->openIsoRomData(3);
}
break;
}
case DreamcastPrivate::DiscType::GDI:
case DreamcastPrivate::DiscType::CDI: {
// Open track 3 as ISO-9660.
CdiReader *const cdiReader = dynamic_cast<CdiReader*>(d->discReader.get());
assert(cdiReader != nullptr);
if (cdiReader) {
isoData = cdiReader->openIsoRomData(3);
MultiTrackSparseDiscReader *const mtsDiscReader = dynamic_cast<MultiTrackSparseDiscReader*>(d->discReader.get());
assert(mtsDiscReader != nullptr);
if (mtsDiscReader) {
isoData = mtsDiscReader->openIsoRomData(3);
if (!isoData) {
// NOTE: Some CDIs only have two tracks.
// Try reading track 2 instead.
isoData = mtsDiscReader->openIsoRomData(2);
}
}
break;
}

View File

@ -8,7 +8,7 @@
#pragma once
#include "librpbase/disc/SparseDiscReader.hpp"
#include "MultiTrackSparseDiscReader.hpp"
#include "IsoPartition.hpp"
// for ISOPtr
@ -17,7 +17,7 @@
namespace LibRomData {
class CdiReaderPrivate;
class CdiReader : public LibRpBase::SparseDiscReader
class CdiReader : public MultiTrackSparseDiscReader
{
public:
/**
@ -29,7 +29,7 @@ public:
explicit CdiReader(const LibRpFile::IRpFilePtr &file);
private:
typedef SparseDiscReader super;
typedef MultiTrackSparseDiscReader super;
RP_DISABLE_COPY(CdiReader)
private:
friend class CdiReaderPrivate;
@ -84,34 +84,34 @@ protected:
int readBlock(uint32_t blockIdx, int pos, void *ptr, size_t size) final;
public:
/** CDI-specific functions **/
/** MultiTrackSparseDiscReader functions **/
/**
* Get the track count.
* @return Track count.
*/
int trackCount(void) const;
int trackCount(void) const final;
/**
* Get the starting LBA of the specified track number.
* @param trackNumber Track number. (1-based)
* @return Starting LBA, or -1 if the track number is invalid.
*/
int startingLBA(int trackNumber) const;
int startingLBA(int trackNumber) const final;
/**
* Open a track using IsoPartition.
* @param trackNumber Track number. (1-based)
* @return IsoPartition, or nullptr on error.
*/
IsoPartitionPtr openIsoPartition(int trackNumber);
IsoPartitionPtr openIsoPartition(int trackNumber) final;
/**
* Create an ISO RomData object for a given track number.
* @param trackNumber Track number. (1-based)
* @return ISO object, or nullptr on error.
*/
ISOPtr openIsoRomData(int trackNumber);
ISOPtr openIsoRomData(int trackNumber) final;
};
typedef std::shared_ptr<CdiReader> CdiReaderPtr;

View File

@ -2,13 +2,13 @@
* ROM Properties Page shell extension. (libromdata) *
* GdiReader.hpp: GD-ROM reader for Dreamcast GDI images. *
* *
* Copyright (c) 2016-2023 by David Korth. *
* Copyright (c) 2016-2024 by David Korth. *
* SPDX-License-Identifier: GPL-2.0-or-later *
***************************************************************************/
#pragma once
#include "librpbase/disc/SparseDiscReader.hpp"
#include "MultiTrackSparseDiscReader.hpp"
#include "IsoPartition.hpp"
// for ISOPtr
@ -17,7 +17,7 @@
namespace LibRomData {
class GdiReaderPrivate;
class GdiReader : public LibRpBase::SparseDiscReader
class GdiReader : public MultiTrackSparseDiscReader
{
public:
/**
@ -29,7 +29,7 @@ public:
explicit GdiReader(const LibRpFile::IRpFilePtr &file);
private:
typedef SparseDiscReader super;
typedef MultiTrackSparseDiscReader super;
RP_DISABLE_COPY(GdiReader)
private:
friend class GdiReaderPrivate;
@ -90,28 +90,28 @@ public:
* Get the track count.
* @return Track count.
*/
int trackCount(void) const;
int trackCount(void) const final;
/**
* Get the starting LBA of the specified track number.
* @param trackNumber Track number. (1-based)
* @return Starting LBA, or -1 if the track number is invalid.
*/
int startingLBA(int trackNumber) const;
int startingLBA(int trackNumber) const final;
/**
* Open a track using IsoPartition.
* @param trackNumber Track number. (1-based)
* @return IsoPartition, or nullptr on error.
*/
IsoPartitionPtr openIsoPartition(int trackNumber);
IsoPartitionPtr openIsoPartition(int trackNumber) final;
/**
* Create an ISO RomData object for a given track number.
* @param trackNumber Track number. (1-based)
* @return ISO object, or nullptr on error.
*/
ISOPtr openIsoRomData(int trackNumber);
ISOPtr openIsoRomData(int trackNumber) final;
};
typedef std::shared_ptr<GdiReader> GdiReaderPtr;

View File

@ -0,0 +1,63 @@
/*******************************************************************************
* ROM Properties Page shell extension. (libromdata) *
* MultiTrackSparseDiscReader.hpp: Multi-track sparse image reader interface. *
* *
* Copyright (c) 2016-2024 by David Korth. *
* SPDX-License-Identifier: GPL-2.0-or-later *
*******************************************************************************/
#pragma once
#include "librpbase/disc/SparseDiscReader.hpp"
#include "IsoPartition.hpp"
// for ISOPtr
#include "../Media/ISO.hpp"
namespace LibRomData {
class NOVTABLE MultiTrackSparseDiscReader : public LibRpBase::SparseDiscReader
{
protected:
explicit MultiTrackSparseDiscReader(LibRpBase::SparseDiscReaderPrivate *d, const LibRpFile::IRpFilePtr &file)
: super(d, file)
{}
private:
typedef SparseDiscReader super;
RP_DISABLE_COPY(MultiTrackSparseDiscReader)
public:
/** MultiTrackSparseDiscReader functions **/
/**
* Get the track count.
* @return Track count
*/
virtual int trackCount(void) const = 0;
/**
* Get the starting LBA of the specified track number.
* @param trackNumber Track number (1-based)
* @return Starting LBA, or -1 if the track number is invalid
*/
virtual int startingLBA(int trackNumber) const = 0;
/**
* Open a track using IsoPartition.
* @param trackNumber Track number (1-based)
* @return IsoPartition, or nullptr on error
*/
virtual IsoPartitionPtr openIsoPartition(int trackNumber) = 0;
/**
* Create an ISO RomData object for a given track number.
* @param trackNumber Track number (1-based)
* @return ISO object, or nullptr on error
*/
virtual ISOPtr openIsoRomData(int trackNumber) = 0;
};
typedef std::shared_ptr<MultiTrackSparseDiscReader> MultiTrackSparseDiscReaderPtr;
} // namespace LibRomData