CDImageCHD: Support reading subchannel from CHD

This commit is contained in:
Stenzek
2023-11-05 20:36:28 +10:00
parent ee3c770082
commit e739c114a4
9 changed files with 123 additions and 69 deletions

View File

@ -14,8 +14,15 @@ Log_SetChannel(CDImageDevice);
#if defined(_WIN32)
// The include order here is critical.
// clang-format off
#include "common/windows_headers.h"
#include <winioctl.h>
#include <ntddcdrm.h>
#include <ntddscsi.h>
// clang-format on
static constexpr u32 MAX_TRACK_NUMBER = 99;
static constexpr int ALL_SUBCODE_SIZE = 96;
static u32 BEToU32(const u8* val)
{
@ -29,47 +36,6 @@ static void U16ToBE(u8* beval, u16 leval)
beval[1] = static_cast<u8>(leval);
}
// Adapted from
// https://github.com/saramibreak/DiscImageCreator/blob/5a8fe21730872d67991211f1319c87f0780f2d0f/DiscImageCreator/convert.cpp
static void DeinterleaveSubcode(const u8* subcode_in, u8* subcode_out)
{
std::memset(subcode_out, 0, ALL_SUBCODE_SIZE);
int row = 0;
for (int bitNum = 0; bitNum < 8; bitNum++)
{
for (int nColumn = 0; nColumn < ALL_SUBCODE_SIZE; row++)
{
u32 mask = 0x80;
for (int nShift = 0; nShift < 8; nShift++, nColumn++)
{
const int n = nShift - bitNum;
if (n > 0)
{
subcode_out[row] |= static_cast<u8>((subcode_in[nColumn] >> n) & mask);
}
else
{
subcode_out[row] |= static_cast<u8>((subcode_in[nColumn] << std::abs(n)) & mask);
}
mask >>= 1;
}
}
}
}
#endif
#if defined(_WIN32)
// The include order here is critical.
// clang-format off
#include "common/windows_headers.h"
#include <winioctl.h>
#include <ntddcdrm.h>
#include <ntddscsi.h>
// clang-format on
class CDImageDeviceWin32 : public CDImage
{
public:
@ -217,6 +183,7 @@ bool CDImageDeviceWin32::Open(const char* filename, Error* error)
pregap_index.track_number = track_num;
pregap_index.index_number = 0;
pregap_index.mode = track_mode;
pregap_index.submode = CDImage::SubchannelMode::None;
pregap_index.control.bits = control.bits;
pregap_index.is_pregap = true;
m_indices.push_back(pregap_index);
@ -227,7 +194,8 @@ bool CDImageDeviceWin32::Open(const char* filename, Error* error)
if (track_num <= MAX_TRACK_NUMBER)
{
// add the track itself
m_tracks.push_back(Track{track_num, disc_lba, static_cast<u32>(m_indices.size()), 0, track_mode, control});
m_tracks.push_back(
Track{track_num, disc_lba, static_cast<u32>(m_indices.size()), 0, track_mode, SubchannelMode::None, control});
Index index1;
index1.start_lba_on_disc = disc_lba;
@ -239,6 +207,7 @@ bool CDImageDeviceWin32::Open(const char* filename, Error* error)
index1.file_sector_size = 2048;
index1.file_offset = static_cast<u64>(track_lba) * index1.file_sector_size;
index1.mode = track_mode;
index1.submode = CDImage::SubchannelMode::None;
index1.control.bits = control.bits;
index1.is_pregap = false;
m_indices.push_back(index1);