diff --git a/src/common/cd_image_bin.cpp b/src/common/cd_image_bin.cpp index 0ca461636..c84710175 100644 --- a/src/common/cd_image_bin.cpp +++ b/src/common/cd_image_bin.cpp @@ -108,7 +108,7 @@ bool CDImageBin::Open(const char* filename) bool CDImageBin::ReadSubChannelQ(SubChannelQ* subq) { - if (m_sbi.GetReplacementSubChannelQ(m_position_on_disc, subq->data)) + if (m_sbi.GetReplacementSubChannelQ(m_position_on_disc, subq)) return true; return CDImage::ReadSubChannelQ(subq); diff --git a/src/common/cd_image_chd.cpp b/src/common/cd_image_chd.cpp index 15d8800cf..7d3345ce6 100644 --- a/src/common/cd_image_chd.cpp +++ b/src/common/cd_image_chd.cpp @@ -231,7 +231,7 @@ bool CDImageCHD::Open(const char* filename) bool CDImageCHD::ReadSubChannelQ(SubChannelQ* subq) { - if (m_sbi.GetReplacementSubChannelQ(m_position_on_disc, subq->data)) + if (m_sbi.GetReplacementSubChannelQ(m_position_on_disc, subq)) return true; // TODO: Read subchannel data from CHD diff --git a/src/common/cd_image_cue.cpp b/src/common/cd_image_cue.cpp index f8dd04a08..689ae8c5b 100644 --- a/src/common/cd_image_cue.cpp +++ b/src/common/cd_image_cue.cpp @@ -219,7 +219,7 @@ bool CDImageCueSheet::OpenAndParse(const char* filename) bool CDImageCueSheet::ReadSubChannelQ(SubChannelQ* subq) { - if (m_sbi.GetReplacementSubChannelQ(m_position_on_disc, subq->data)) + if (m_sbi.GetReplacementSubChannelQ(m_position_on_disc, subq)) return true; return CDImage::ReadSubChannelQ(subq); diff --git a/src/common/cd_subchannel_replacement.cpp b/src/common/cd_subchannel_replacement.cpp index 23f4a5921..be4c1270d 100644 --- a/src/common/cd_subchannel_replacement.cpp +++ b/src/common/cd_subchannel_replacement.cpp @@ -1,6 +1,6 @@ #include "cd_subchannel_replacement.h" -#include "log.h" #include "file_system.h" +#include "log.h" #include #include Log_SetChannel(CDSubChannelReplacement); @@ -68,33 +68,42 @@ bool CDSubChannelReplacement::LoadSBI(const char* path) const u32 lba = MSFToLBA(entry.minute_bcd, entry.second_bcd, entry.frame_bcd); - ReplacementData subq_data; - std::copy_n(entry.data, countof(entry.data), subq_data.data()); + CDImage::SubChannelQ subq; + std::copy_n(entry.data, countof(entry.data), subq.data.data()); // generate an invalid crc by flipping all bits from the valid crc (will never collide) - const u16 crc = CDImage::SubChannelQ::ComputeCRC(subq_data) ^ 0xFFFF; - subq_data[10] = Truncate8(crc); - subq_data[11] = Truncate8(crc >> 8); + const u16 crc = subq.ComputeCRC(subq.data) ^ 0xFFFF; + subq.data[10] = Truncate8(crc); + subq.data[11] = Truncate8(crc >> 8); - m_replacement_subq.emplace(lba, subq_data); + m_replacement_subq.emplace(lba, subq); } Log_InfoPrintf("Loaded %zu replacement sectors from '%s'", m_replacement_subq.size(), path); return true; } -bool CDSubChannelReplacement::GetReplacementSubChannelQ(u8 minute_bcd, u8 second_bcd, u8 frame_bcd, - ReplacementData& subq_data) const +void CDSubChannelReplacement::AddReplacementSubChannelQ(u32 lba, const CDImage::SubChannelQ& subq) { - return GetReplacementSubChannelQ(MSFToLBA(minute_bcd, second_bcd, frame_bcd), subq_data); + auto iter = m_replacement_subq.find(lba); + if (iter != m_replacement_subq.end()) + iter->second.data = subq.data; + else + m_replacement_subq.emplace(lba, subq); } -bool CDSubChannelReplacement::GetReplacementSubChannelQ(u32 lba, ReplacementData& subq_data) const +bool CDSubChannelReplacement::GetReplacementSubChannelQ(u8 minute_bcd, u8 second_bcd, u8 frame_bcd, + CDImage::SubChannelQ* subq) const +{ + return GetReplacementSubChannelQ(MSFToLBA(minute_bcd, second_bcd, frame_bcd), subq); +} + +bool CDSubChannelReplacement::GetReplacementSubChannelQ(u32 lba, CDImage::SubChannelQ* subq) const { const auto iter = m_replacement_subq.find(lba); if (iter == m_replacement_subq.cend()) return false; - subq_data = iter->second; + *subq = iter->second; return true; } diff --git a/src/common/cd_subchannel_replacement.h b/src/common/cd_subchannel_replacement.h index 57148066d..4c622dfa2 100644 --- a/src/common/cd_subchannel_replacement.h +++ b/src/common/cd_subchannel_replacement.h @@ -8,13 +8,6 @@ class CDSubChannelReplacement { public: - enum : u32 - { - SUBCHANNEL_Q_SIZE = 12, - }; - - using ReplacementData = std::array; - CDSubChannelReplacement(); ~CDSubChannelReplacement(); @@ -22,14 +15,17 @@ public: bool LoadSBI(const char* path); + /// Adds a sector to the replacement map. + void AddReplacementSubChannelQ(u32 lba, const CDImage::SubChannelQ& subq); + /// Returns the replacement subchannel data for the specified position (in BCD). - bool GetReplacementSubChannelQ(u8 minute_bcd, u8 second_bcd, u8 frame_bcd, ReplacementData& subq_data) const; + bool GetReplacementSubChannelQ(u8 minute_bcd, u8 second_bcd, u8 frame_bcd, CDImage::SubChannelQ* subq) const; /// Returns the replacement subchannel data for the specified sector. - bool GetReplacementSubChannelQ(u32 lba, ReplacementData& subq_data) const; + bool GetReplacementSubChannelQ(u32 lba, CDImage::SubChannelQ* subq) const; private: - using ReplacementMap = std::unordered_map; + using ReplacementMap = std::unordered_map; ReplacementMap m_replacement_subq; };