Play-/Source/MdsDiscImage.cpp
Jean-Philip Desjardins 65fef48e64 Build fix (yet again).
2018-10-15 22:12:04 -04:00

131 lines
3.1 KiB
C++

#include <stdexcept>
#include <cstring>
#include "MdsDiscImage.h"
enum MDS_MEDIUM : uint16
{
CD = 0,
CD_R = 1,
CD_RW = 2,
DVD = 0x10,
DVD_MINUS_R = 0x12,
};
static const char g_mdsSignature[17] = "MEDIA DESCRIPTOR";
struct MDS_HEADER
{
uint8 signature[0x10];
uint8 version[2];
MDS_MEDIUM mediumType;
uint16 sessionCount;
uint16 dummy1[2];
uint16 bcaLength;
uint32 dummy2[2];
uint32 bcaDataOffset;
uint32 dummy3[6];
uint32 discStructuresOffset;
uint32 dummy4[3];
uint32 sessionsBlocksOffset;
uint32 dpmBlocksOffset;
};
static_assert(sizeof(MDS_HEADER) == 88, "MDS_HEADER must be 88 bytes long.");
//Read Disc Structure - Command 0x00
struct DVD_RDS_PHYSICALFORMATINFO
{
uint8 partVersion : 4;
uint8 bookType : 4;
uint8 maximumRate : 4;
uint8 discSize : 4;
uint8 layerType : 4;
uint8 trackPath : 1;
uint8 numberOfLayers : 2;
uint8 reserved0 : 1;
uint8 trackDensity : 4;
uint8 linearDensity : 4;
uint8 startSectorNumber[4];
uint8 endSectorNumber[4];
uint8 endSectorNumberLayer0[4];
uint8 reserved1 : 7;
uint8 bcaFlag : 1;
uint8 mediaSpecific[2031];
uint32 GetStartSectorNumber() const
{
return (startSectorNumber[1] << 16) | (startSectorNumber[2] << 8) | (startSectorNumber[3]);
}
uint32 GetEndSectorNumber() const
{
return (endSectorNumber[1] << 16) | (endSectorNumber[2] << 8) | (endSectorNumber[3]);
}
};
static_assert(sizeof(DVD_RDS_PHYSICALFORMATINFO) == 2048, "DVD_RDS_PHYSICALFORMATINFO must be 2048 bytes long.");
//Read Disc Structure - Command 0x01
struct DVD_RDS_COPYRIGHTINFO
{
uint32 info;
};
static_assert(sizeof(DVD_RDS_COPYRIGHTINFO) == 4, "DVD_RDS_COPYRIGHTINFO must be 4 bytes long.");
//Read Disc Structure - Command 0x04
struct DVD_RDS_MANUFACTURINGINFO
{
uint8 info[2048];
};
static_assert(sizeof(DVD_RDS_MANUFACTURINGINFO) == 2048, "DVD_RDS_MANUFACTURINGINFO must be 2048 bytes long.");
CMdsDiscImage::CMdsDiscImage(Framework::CStream& inputStream)
{
ParseMds(inputStream);
}
bool CMdsDiscImage::IsDualLayer() const
{
return m_isDualLayer;
}
uint32 CMdsDiscImage::GetLayerBreak() const
{
return m_layerBreak;
}
void CMdsDiscImage::ParseMds(Framework::CStream& inputStream)
{
MDS_HEADER header = {};
inputStream.Read(&header, sizeof(MDS_HEADER));
if(memcmp(header.signature, g_mdsSignature, 16) != 0)
{
throw std::runtime_error("Invalid MDS file.");
}
if(header.version[0] != 0x01)
{
throw std::runtime_error("Invalid MDS file version.");
}
if(header.mediumType == MDS_MEDIUM::DVD)
{
inputStream.Seek(header.discStructuresOffset, Framework::STREAM_SEEK_SET);
DVD_RDS_COPYRIGHTINFO copyrightInfo = {};
inputStream.Read(&copyrightInfo, sizeof(DVD_RDS_COPYRIGHTINFO));
DVD_RDS_MANUFACTURINGINFO manufacturingInfo = {};
inputStream.Read(&manufacturingInfo, sizeof(DVD_RDS_MANUFACTURINGINFO));
DVD_RDS_PHYSICALFORMATINFO physicalFormatInfo = {};
inputStream.Read(&physicalFormatInfo, sizeof(DVD_RDS_PHYSICALFORMATINFO));
uint32 startSectorNumber = physicalFormatInfo.GetStartSectorNumber();
uint32 endSectorNumber = physicalFormatInfo.GetEndSectorNumber();
if(physicalFormatInfo.numberOfLayers == 1)
{
m_isDualLayer = true;
m_layerBreak = endSectorNumber - startSectorNumber + 1;
}
}
}