diff --git a/subprojects/memcard/include/memcard/block.hpp b/subprojects/memcard/include/memcard/block.hpp index 4f7e47e..6d29621 100644 --- a/subprojects/memcard/include/memcard/block.hpp +++ b/subprojects/memcard/include/memcard/block.hpp @@ -46,8 +46,10 @@ public: typedef FrameIterator const_iterator; static const constexpr std::size_t FrameCount = 64; - static const constexpr std::size_t TOCBlockIndex = 0; + static const constexpr std::size_t TOCBlockIndex = 0xFF; + static const constexpr uint16_t LastLink = 0xFFFF; + BasicBlock() = default; BasicBlock (data_type* blk, std::size_t index); BasicBlock (data_type* blk, BasicFrame toc_entry, std::size_t index); template BasicBlock (const BasicBlock& other); @@ -85,6 +87,8 @@ public: uint8_t toc_checksum() const; uint8_t calculate_toc_checksum() const; + BasicBlock& operator= (const BasicBlock&) = default; + BasicBlock& operator= (BasicBlock&&) = default; private: BasicFrame m_toc_entry; diff --git a/subprojects/memcard/include/memcard/memorycard.hpp b/subprojects/memcard/include/memcard/memorycard.hpp index 09c4fff..f122996 100644 --- a/subprojects/memcard/include/memcard/memorycard.hpp +++ b/subprojects/memcard/include/memcard/memorycard.hpp @@ -34,12 +34,18 @@ public: typedef BlockIterator iterator; typedef BlockIterator const_iterator; + static const constexpr std::size_t GameBlocks = 16 - 1; + MemoryCard(); template explicit MemoryCard (IT beg, IT end); ~MemoryCard(); Block operator[] (std::size_t index); + Block block (std::size_t index); + Block toc_block(); ConstBlock operator[] (std::size_t index) const; + ConstBlock block (std::size_t index) const; + ConstBlock toc_block() const; ContentInfo content_info() const; std::size_t size() const; @@ -52,9 +58,6 @@ public: const_iterator end() const; private: - Block block_at_index(std::size_t index); - ConstBlock block_at_index(std::size_t index) const; - std::vector m_data; }; diff --git a/subprojects/memcard/src/memorycard.cpp b/subprojects/memcard/src/memorycard.cpp index 073d9f3..81f2cb7 100644 --- a/subprojects/memcard/src/memorycard.cpp +++ b/subprojects/memcard/src/memorycard.cpp @@ -27,12 +27,13 @@ namespace { template BasicBlock make_block_for_index (typename BasicBlock::data_type* data, std::size_t index) { + const auto new_index = (0 == index ? Block::TOCBlockIndex : index - 1); const auto retptr = data + index * Block::size() * Frame::size(); if (index > 0) { - return {retptr, BasicFrame(data + index * Frame::size(), index), index}; + return {retptr, BasicFrame(data + index * Frame::size(), index), new_index}; } else { - return {data + index, index}; + return {data + index, new_index}; } } } //unnamed namespace @@ -45,23 +46,39 @@ MemoryCard::MemoryCard() : MemoryCard::~MemoryCard() = default; Block MemoryCard::operator[] (std::size_t index) { - assert(index < 15); - return block_at_index(index + 1); + return block(index); +} + +Block MemoryCard::block (std::size_t index) { + assert(index < GameBlocks); + return make_block_for_index(m_data.data(), index + 1); +} + +Block MemoryCard::toc_block() { + return make_block_for_index(m_data.data(), 0); } ConstBlock MemoryCard::operator[] (std::size_t index) const { - assert(index < 15); - return block_at_index(index + 1); + return block(index); +} + +ConstBlock MemoryCard::block (std::size_t index) const { + assert(index < GameBlocks); + return make_block_for_index(m_data.data(), index + 1); +} + +ConstBlock MemoryCard::toc_block() const { + return make_block_for_index(m_data.data(), 0); } ContentInfo MemoryCard::content_info() const { - return {block_at_index(0).frame(0)}; + return {toc_block().frame(0)}; } std::size_t MemoryCard::size() const { return std::count_if( const_iterator(this, 0), - const_iterator(this, 15), + const_iterator(this, GameBlocks), [](const auto& blk) { return (blk.available_blocks() & 0xF) != 0 and (blk.available_blocks() & 0xF) != 0xF; } @@ -92,17 +109,25 @@ auto MemoryCard::end() const -> const_iterator { return const_iterator(this, size()); } -Block MemoryCard::block_at_index(std::size_t index) { - return make_block_for_index(m_data.data(), index); -} - -ConstBlock MemoryCard::block_at_index(std::size_t index) const { - return make_block_for_index(m_data.data(), index); -} - std::vector block_group (const MemoryCard& mc, std::size_t index) { std::vector retval; + retval.reserve(MemoryCard::GameBlocks); - auto block = mc[index]; + for (const auto& block : mc) { + retval.clear(); + std::size_t cur_idx = block.index(); + bool this_run = false; + ConstBlock cur_block; + do { + cur_block = mc[cur_idx]; + this_run |= static_cast(cur_idx == index); + retval.push_back(cur_idx); + cur_idx = cur_block.link_order(); + } while (cur_idx != Block::LastLink); + + if (this_run) + return retval; + } + return {}; } } //namespace mc::psx