diff --git a/include/kabufuda/BlockAllocationTable.hpp b/include/kabufuda/BlockAllocationTable.hpp index f4ac51d..309388b 100644 --- a/include/kabufuda/BlockAllocationTable.hpp +++ b/include/kabufuda/BlockAllocationTable.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include "kabufuda/Constants.hpp" @@ -15,9 +14,9 @@ class BlockAllocationTable { uint16_t m_updateCounter; uint16_t m_freeBlocks; uint16_t m_lastAllocated; - std::array m_map; + uint16_t m_map[0xFFB]; }; - std::array raw{}; + uint8_t __raw[BlockSize]; }; #pragma pack(pop) @@ -27,6 +26,7 @@ class BlockAllocationTable { public: explicit BlockAllocationTable(uint32_t blockCount = (uint32_t(ECardSize::Card2043Mb) * MbitToBlocks)); + BlockAllocationTable(uint8_t data[BlockSize]); ~BlockAllocationTable() = default; uint16_t getNextBlock(uint16_t block) const; diff --git a/include/kabufuda/Card.hpp b/include/kabufuda/Card.hpp index 6b913db..5783092 100644 --- a/include/kabufuda/Card.hpp +++ b/include/kabufuda/Card.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include @@ -38,8 +37,8 @@ struct CardStat { char x0_fileName[CARD_FILENAME_MAX]; uint32_t x20_length; uint32_t x24_time; /* seconds since 01/01/2000 midnight */ - std::array x28_gameName; - std::array x2c_company; + uint8_t x28_gameName[4]; + uint8_t x2c_company[2]; /* read/write (Set by Card::getStatus/Card::setStatus) */ uint8_t x2e_bannerFormat; @@ -52,7 +51,7 @@ struct CardStat { /* read-only (Set by Card::getStatus) */ uint32_t x3c_offsetBanner; uint32_t x40_offsetBannerTlut; - std::array x44_offsetIcon; + uint32_t x44_offsetIcon[CARD_ICON_MAX]; uint32_t x64_offsetIconTlut; uint32_t x68_offsetData; @@ -80,7 +79,7 @@ class Card { struct CardHeader { union { struct { - std::array m_serial; + uint8_t m_serial[12]; uint64_t m_formatTime; int32_t m_sramBias; uint32_t m_sramLanguage; @@ -88,12 +87,12 @@ class Card { uint16_t m_deviceId; /* 0 for Slot A, 1 for Slot B */ uint16_t m_sizeMb; uint16_t m_encoding; - std::array padding; + uint8_t __padding[468]; uint16_t m_updateCounter; uint16_t m_checksum; uint16_t m_checksumInv; }; - std::array raw; + uint8_t __raw[BlockSize]; }; void _swapEndian(); }; @@ -103,10 +102,10 @@ class Card { SystemString m_filename; AsyncIO m_fileHandle; - std::array m_dirs; - std::array m_bats; - std::array m_tmpDirs; - std::array m_tmpBats; + Directory m_dirs[2]; + BlockAllocationTable m_bats[2]; + Directory m_tmpDirs[2]; + BlockAllocationTable m_tmpBats[2]; uint8_t m_currentDir; uint8_t m_currentBat; diff --git a/include/kabufuda/Directory.hpp b/include/kabufuda/Directory.hpp index f73a4de..6b8b16d 100644 --- a/include/kabufuda/Directory.hpp +++ b/include/kabufuda/Directory.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include "kabufuda/File.hpp" @@ -10,13 +9,13 @@ class Directory { #pragma pack(push, 4) union { struct { - std::array m_files; - std::array padding; + File m_files[MaxFiles]; + uint8_t __padding[0x3a]; uint16_t m_updateCounter; uint16_t m_checksum; uint16_t m_checksumInv; }; - std::array raw; + uint8_t __raw[BlockSize]; }; #pragma pack(pop) diff --git a/include/kabufuda/File.hpp b/include/kabufuda/File.hpp index b7071a6..9586765 100644 --- a/include/kabufuda/File.hpp +++ b/include/kabufuda/File.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include "kabufuda/Constants.hpp" @@ -12,8 +11,8 @@ class File { #pragma pack(push, 4) union { struct { - std::array m_game; - std::array m_maker; + uint8_t m_game[4]; + uint8_t m_maker[2]; uint8_t m_reserved; uint8_t m_bannerFlags; char m_filename[0x20]; @@ -28,7 +27,7 @@ class File { uint16_t m_reserved2; uint32_t m_commentAddr; }; - std::array raw; + uint8_t __raw[0x40]; }; #pragma pack(pop) diff --git a/include/kabufuda/SRAM.hpp b/include/kabufuda/SRAM.hpp index c7ef3ea..a413e0a 100644 --- a/include/kabufuda/SRAM.hpp +++ b/include/kabufuda/SRAM.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include // Modified code taken from libogc @@ -42,7 +41,7 @@ union SRAMFlags { }; union SRAM { - std::array p_SRAM; + uint8_t p_SRAM[64]; struct // Stored configuration value from the system SRAM area { uint16_t checksum; // Holds the block checksum. @@ -56,14 +55,13 @@ union SRAM { SRAMFlags flags; // Device and operations flag // Stored configuration value from the extended SRAM area - using FlashID = std::array, 2>; - FlashID flash_id; // flash_id[2][12] 96bit memorycard unlock flash ID - uint32_t wirelessKbd_id; // Device ID of last connected wireless keyboard - std::array wirelessPad_id; // 16-bit device ID of last connected pad. - uint8_t dvderr_code; // last non-recoverable error from DVD interface - uint8_t __padding0; // reserved - std::array flashID_chksum; // 8-bit checksum of unlock flash ID - uint32_t __padding1; // padding + uint8_t flash_id[2][12]; // flash_id[2][12] 96bit memorycard unlock flash ID + uint32_t wirelessKbd_id; // Device ID of last connected wireless keyboard + uint16_t wirelessPad_id[4]; // 16-bit device ID of last connected pad. + uint8_t dvderr_code; // last non-recoverable error from DVD interface + uint8_t __padding0; // reserved + uint8_t flashID_chksum[2]; // 8-bit checksum of unlock flash ID + uint32_t __padding1; // padding }; }; #pragma pack(pop) diff --git a/lib/kabufuda/BlockAllocationTable.cpp b/lib/kabufuda/BlockAllocationTable.cpp index 2a16951..db8bfdf 100644 --- a/lib/kabufuda/BlockAllocationTable.cpp +++ b/lib/kabufuda/BlockAllocationTable.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include "kabufuda/Util.hpp" @@ -18,21 +19,23 @@ void BlockAllocationTable::swapEndian() { void BlockAllocationTable::updateChecksum() { swapEndian(); - calculateChecksumBE(reinterpret_cast(raw.data() + 4), 0xFFE, &m_checksum, &m_checksumInv); + calculateChecksumBE(reinterpret_cast(__raw + 4), 0xFFE, &m_checksum, &m_checksumInv); swapEndian(); } bool BlockAllocationTable::valid() const { uint16_t ckSum, ckSumInv; const_cast(*this).swapEndian(); - calculateChecksumBE(reinterpret_cast(raw.data() + 4), 0xFFE, &ckSum, &ckSumInv); + calculateChecksumBE(reinterpret_cast(__raw + 4), 0xFFE, &ckSum, &ckSumInv); bool res = (ckSum == m_checksum && ckSumInv == m_checksumInv); const_cast(*this).swapEndian(); return res; } -BlockAllocationTable::BlockAllocationTable(uint32_t blockCount) -: m_freeBlocks{uint16_t(blockCount - FSTBlocks)}, m_lastAllocated{4} { +BlockAllocationTable::BlockAllocationTable(uint32_t blockCount) { + memset(__raw, 0, BlockSize); + m_freeBlocks = uint16_t(blockCount - FSTBlocks); + m_lastAllocated = 4; updateChecksum(); } diff --git a/lib/kabufuda/Card.cpp b/lib/kabufuda/Card.cpp index ba79176..5d72f4e 100644 --- a/lib/kabufuda/Card.cpp +++ b/lib/kabufuda/Card.cpp @@ -26,36 +26,40 @@ void Card::CardHeader::_swapEndian() { m_checksumInv = SBig(m_checksumInv); } -Card::Card() { m_ch.raw.fill(0xFF); } +Card::Card() { memset(m_ch.__raw, 0xFF, BlockSize); } Card::Card(Card&& other) { - m_ch.raw = other.m_ch.raw; + memmove(m_ch.__raw, other.m_ch.__raw, BlockSize); m_filename = std::move(other.m_filename); m_fileHandle = std::move(other.m_fileHandle); - m_dirs = std::move(other.m_dirs); - m_bats = std::move(other.m_bats); + m_dirs[0] = std::move(other.m_dirs[0]); + m_dirs[1] = std::move(other.m_dirs[1]); + m_bats[0] = std::move(other.m_bats[0]); + m_bats[1] = std::move(other.m_bats[1]); m_currentDir = other.m_currentDir; m_currentBat = other.m_currentBat; m_maxBlock = other.m_maxBlock; - std::copy(std::cbegin(other.m_game), std::cend(other.m_game), std::begin(m_game)); - std::copy(std::cbegin(other.m_maker), std::cend(other.m_maker), std::begin(m_maker)); + memmove(m_game, other.m_game, 5); + memmove(m_maker, other.m_maker, 3); } Card& Card::operator=(Card&& other) { close(); - m_ch.raw = other.m_ch.raw; + memmove(m_ch.__raw, other.m_ch.__raw, BlockSize); m_filename = std::move(other.m_filename); m_fileHandle = std::move(other.m_fileHandle); - m_dirs = std::move(other.m_dirs); - m_bats = std::move(other.m_bats); + m_dirs[0] = std::move(other.m_dirs[0]); + m_dirs[1] = std::move(other.m_dirs[1]); + m_bats[0] = std::move(other.m_bats[0]); + m_bats[1] = std::move(other.m_bats[1]); m_currentDir = other.m_currentDir; m_currentBat = other.m_currentBat; m_maxBlock = other.m_maxBlock; - std::copy(std::cbegin(other.m_game), std::cend(other.m_game), std::begin(m_game)); - std::copy(std::cbegin(other.m_maker), std::cend(other.m_maker), std::begin(m_maker)); + memmove(m_game, other.m_game, 5); + memmove(m_maker, other.m_maker, 3); return *this; } @@ -105,14 +109,11 @@ ECardResult Card::_pumpOpen() { } Card::Card(const char* game, const char* maker) { - m_ch.raw.fill(0xFF); - - if (game != nullptr && std::strlen(game) == 4) { - std::memcpy(m_game, game, 4); - } - if (maker != nullptr && std::strlen(maker) == 2) { - std::memcpy(m_maker, maker, 2); - } + memset(m_ch.__raw, 0xFF, BlockSize); + if (game && strlen(game) == 4) + memcpy(m_game, game, 4); + if (maker && strlen(maker) == 2) + memcpy(m_maker, maker, 2); } Card::~Card() { close(); } @@ -165,7 +166,7 @@ void Card::_updateDirAndBat(const Directory& dir, const BlockAllocationTable& ba void Card::_updateChecksum() { m_ch._swapEndian(); - calculateChecksumBE(reinterpret_cast(m_ch.raw.data()), 0xFE, &m_ch.m_checksum, &m_ch.m_checksumInv); + calculateChecksumBE(reinterpret_cast(m_ch.__raw), 0xFE, &m_ch.m_checksum, &m_ch.m_checksumInv); m_ch._swapEndian(); } @@ -299,28 +300,25 @@ ECardResult Card::deleteFile(uint32_t fileno) { } ECardResult Card::renameFile(const char* oldName, const char* newName) { - const ECardResult openRes = _pumpOpen(); - if (openRes != ECardResult::READY) { + ECardResult openRes = _pumpOpen(); + if (openRes != ECardResult::READY) return openRes; - } - if (std::strlen(newName) > 32) { + if (strlen(newName) > 32) return ECardResult::NAMETOOLONG; - } Directory dir = m_dirs[m_currentDir]; File* f = dir.getFile(m_game, m_maker, oldName); - if (f == nullptr) { + if (!f) return ECardResult::NOFILE; - } if (File* replF = dir.getFile(m_game, m_maker, newName)) { BlockAllocationTable bat = m_bats[m_currentBat]; _deleteFile(*replF, bat); - std::strncpy(f->m_filename, newName, 32); + strncpy(f->m_filename, newName, 32); _updateDirAndBat(dir, bat); } else { - std::strncpy(f->m_filename, newName, 32); + strncpy(f->m_filename, newName, 32); _updateDirAndBat(dir, m_bats[m_currentBat]); } return ECardResult::READY; @@ -556,11 +554,11 @@ ECardResult Card::getStatus(uint32_t fileNo, CardStat& statOut) const { if (!file || file->m_game[0] == 0xFF) return ECardResult::NOFILE; - std::strncpy(statOut.x0_fileName, file->m_filename, 32); + strncpy(statOut.x0_fileName, file->m_filename, 32); statOut.x20_length = file->m_blockCount * BlockSize; statOut.x24_time = file->m_modifiedTime; - statOut.x28_gameName = file->m_game; - statOut.x2c_company = file->m_maker; + memcpy(statOut.x28_gameName, file->m_game, 4); + memcpy(statOut.x2c_company, file->m_maker, 2); statOut.x2e_bannerFormat = file->m_bannerFlags; statOut.x30_iconAddr = file->m_iconAddress; @@ -571,7 +569,8 @@ ECardResult Card::getStatus(uint32_t fileNo, CardStat& statOut) const { if (file->m_iconAddress == UINT32_MAX) { statOut.x3c_offsetBanner = UINT32_MAX; statOut.x40_offsetBannerTlut = UINT32_MAX; - statOut.x44_offsetIcon.fill(UINT32_MAX); + for (int i = 0; i < CARD_ICON_MAX; ++i) + statOut.x44_offsetIcon[i] = UINT32_MAX; statOut.x64_offsetIconTlut = UINT32_MAX; statOut.x68_offsetData = file->m_commentAddr + 64; } else { @@ -581,12 +580,11 @@ ECardResult Card::getStatus(uint32_t fileNo, CardStat& statOut) const { statOut.x40_offsetBannerTlut = cur; cur += TlutSize(statOut.GetBannerFormat()); bool palette = false; - for (size_t i = 0; i < statOut.x44_offsetIcon.size(); ++i) { + for (int i = 0; i < CARD_ICON_MAX; ++i) { statOut.x44_offsetIcon[i] = cur; - const EImageFormat fmt = statOut.GetIconFormat(int(i)); - if (fmt == EImageFormat::C8) { + EImageFormat fmt = statOut.GetIconFormat(i); + if (fmt == EImageFormat::C8) palette = true; - } cur += IconSize(fmt); } if (palette) { @@ -735,14 +733,11 @@ const uint8_t* Card::getCurrentMaker() const { void Card::getSerial(uint64_t& serial) { m_ch._swapEndian(); - - std::array serialBuf{}; - for (size_t i = 0; i < serialBuf.size(); i++) { - serialBuf[i] = SBig(*reinterpret_cast(m_ch.raw.data() + (i * 4))); - } + uint32_t serialBuf[8]; + for (uint32_t i = 0; i < 8; i++) + serialBuf[i] = SBig(*reinterpret_cast(m_ch.__raw + (i * 4))); serial = uint64_t(serialBuf[0] ^ serialBuf[2] ^ serialBuf[4] ^ serialBuf[6]) << 32 | (serialBuf[1] ^ serialBuf[3] ^ serialBuf[5] ^ serialBuf[7]); - m_ch._swapEndian(); } @@ -759,11 +754,10 @@ void Card::getFreeBlocks(int32_t& bytesNotUsed, int32_t& filesNotUsed) { static std::unique_ptr DummyBlock; void Card::format(ECardSlot id, ECardSize size, EEncoding encoding) { - m_ch.raw.fill(0xFF); - + memset(m_ch.__raw, 0xFF, BlockSize); uint64_t rand = uint64_t(getGCTime()); m_ch.m_formatTime = rand; - for (size_t i = 0; i < m_ch.m_serial.size(); i++) { + for (int i = 0; i < 12; i++) { rand = (((rand * uint64_t(0x41c64e6d)) + uint64_t(0x3039)) >> 16); m_ch.m_serial[i] = uint8_t(g_SRAM.flash_id[uint32_t(id)][i] + uint32_t(rand)); rand = (((rand * uint64_t(0x41c64e6d)) + uint64_t(0x3039)) >> 16); @@ -789,31 +783,30 @@ void Card::format(ECardSlot id, ECardSize size, EEncoding encoding) { m_fileHandle = AsyncIO(m_filename.c_str(), true); if (m_fileHandle) { - const uint32_t blockCount = (uint32_t(size) * MbitToBlocks) - 5; + uint32_t blockCount = (uint32_t(size) * MbitToBlocks) - 5; m_tmpCh = m_ch; m_tmpCh._swapEndian(); m_fileHandle.resizeQueue(5 + blockCount); - m_fileHandle.asyncWrite(0, m_tmpCh.raw.data(), BlockSize, 0); + m_fileHandle.asyncWrite(0, m_tmpCh.__raw, BlockSize, 0); m_tmpDirs[0] = m_dirs[0]; m_tmpDirs[0].swapEndian(); - m_fileHandle.asyncWrite(1, m_tmpDirs[0].raw.data(), BlockSize, BlockSize * 1); + m_fileHandle.asyncWrite(1, m_tmpDirs[0].__raw, BlockSize, BlockSize * 1); m_tmpDirs[1] = m_dirs[1]; m_tmpDirs[1].swapEndian(); - m_fileHandle.asyncWrite(2, m_tmpDirs[1].raw.data(), BlockSize, BlockSize * 2); + m_fileHandle.asyncWrite(2, m_tmpDirs[1].__raw, BlockSize, BlockSize * 2); m_tmpBats[0] = m_bats[0]; m_tmpBats[0].swapEndian(); - m_fileHandle.asyncWrite(3, m_tmpBats[0].raw.data(), BlockSize, BlockSize * 3); + m_fileHandle.asyncWrite(3, m_tmpBats[0].__raw, BlockSize, BlockSize * 3); m_tmpBats[1] = m_bats[1]; m_tmpBats[1].swapEndian(); - m_fileHandle.asyncWrite(4, m_tmpBats[1].raw.data(), BlockSize, BlockSize * 4); + m_fileHandle.asyncWrite(4, m_tmpBats[1].__raw, BlockSize, BlockSize * 4); if (!DummyBlock) { DummyBlock.reset(new uint8_t[BlockSize]); memset(DummyBlock.get(), 0xFF, BlockSize); } - for (uint32_t i = 0; i < blockCount; ++i) { + for (uint32_t i = 0; i < blockCount; ++i) m_fileHandle.asyncWrite(i + 5, DummyBlock.get(), BlockSize, BlockSize * (i + 5)); - } m_dirty = false; } } @@ -835,19 +828,19 @@ void Card::commit() { m_tmpDirs[0] = m_dirs[0]; m_tmpDirs[0].updateChecksum(); m_tmpDirs[0].swapEndian(); - m_fileHandle.asyncWrite(1, m_tmpDirs[0].raw.data(), BlockSize, BlockSize * 1); + m_fileHandle.asyncWrite(1, m_tmpDirs[0].__raw, BlockSize, BlockSize * 1); m_tmpDirs[1] = m_dirs[1]; m_tmpDirs[1].updateChecksum(); m_tmpDirs[1].swapEndian(); - m_fileHandle.asyncWrite(2, m_tmpDirs[1].raw.data(), BlockSize, BlockSize * 2); + m_fileHandle.asyncWrite(2, m_tmpDirs[1].__raw, BlockSize, BlockSize * 2); m_tmpBats[0] = m_bats[0]; m_tmpBats[0].updateChecksum(); m_tmpBats[0].swapEndian(); - m_fileHandle.asyncWrite(3, m_tmpBats[0].raw.data(), BlockSize, BlockSize * 3); + m_fileHandle.asyncWrite(3, m_tmpBats[0].__raw, BlockSize, BlockSize * 3); m_tmpBats[1] = m_bats[1]; m_tmpBats[1].updateChecksum(); m_tmpBats[1].swapEndian(); - m_fileHandle.asyncWrite(4, m_tmpBats[1].raw.data(), BlockSize, BlockSize * 4); + m_fileHandle.asyncWrite(4, m_tmpBats[1].__raw, BlockSize, BlockSize * 4); m_dirty = false; } } @@ -858,15 +851,15 @@ bool Card::open(SystemStringView filepath) { m_fileHandle = AsyncIO(m_filename); if (m_fileHandle) { m_fileHandle.resizeQueue(5); - if (!m_fileHandle.asyncRead(0, m_ch.raw.data(), BlockSize, 0)) + if (!m_fileHandle.asyncRead(0, m_ch.__raw, BlockSize, 0)) return false; - if (!m_fileHandle.asyncRead(1, m_dirs[0].raw.data(), BlockSize, BlockSize * 1)) + if (!m_fileHandle.asyncRead(1, m_dirs[0].__raw, BlockSize, BlockSize * 1)) return false; - if (!m_fileHandle.asyncRead(2, m_dirs[1].raw.data(), BlockSize, BlockSize * 2)) + if (!m_fileHandle.asyncRead(2, m_dirs[1].__raw, BlockSize, BlockSize * 2)) return false; - if (!m_fileHandle.asyncRead(3, m_bats[0].raw.data(), BlockSize, BlockSize * 3)) + if (!m_fileHandle.asyncRead(3, m_bats[0].__raw, BlockSize, BlockSize * 3)) return false; - if (!m_fileHandle.asyncRead(4, m_bats[1].raw.data(), BlockSize, BlockSize * 4)) + if (!m_fileHandle.asyncRead(4, m_bats[1].__raw, BlockSize, BlockSize * 4)) return false; return true; } @@ -896,7 +889,7 @@ ECardResult Card::getError() const { uint16_t ckSum, ckSumInv; const_cast(*this).m_ch._swapEndian(); - calculateChecksumBE(reinterpret_cast(m_ch.raw.data()), 0xFE, &ckSum, &ckSumInv); + calculateChecksumBE(reinterpret_cast(m_ch.__raw), 0xFE, &ckSum, &ckSumInv); bool res = (ckSum == m_ch.m_checksum && ckSumInv == m_ch.m_checksumInv); const_cast(*this).m_ch._swapEndian(); diff --git a/lib/kabufuda/Directory.cpp b/lib/kabufuda/Directory.cpp index 436aa1f..35486c3 100644 --- a/lib/kabufuda/Directory.cpp +++ b/lib/kabufuda/Directory.cpp @@ -16,124 +16,100 @@ void Directory::swapEndian() { void Directory::updateChecksum() { swapEndian(); - calculateChecksumBE(reinterpret_cast(raw.data()), 0xFFE, &m_checksum, &m_checksumInv); + calculateChecksumBE(reinterpret_cast(__raw), 0xFFE, &m_checksum, &m_checksumInv); swapEndian(); } bool Directory::valid() const { uint16_t ckSum, ckSumInv; const_cast(*this).swapEndian(); - calculateChecksumBE(reinterpret_cast(raw.data()), 0xFFE, &ckSum, &ckSumInv); + calculateChecksumBE(reinterpret_cast(__raw), 0xFFE, &ckSum, &ckSumInv); bool res = (ckSum == m_checksum && ckSumInv == m_checksumInv); const_cast(*this).swapEndian(); return res; } Directory::Directory() { - raw.fill(0xFF); + memset(__raw, 0xFF, BlockSize); m_updateCounter = 0; updateChecksum(); } -Directory::Directory(uint8_t data[]) { std::memcpy(raw.data(), data, BlockSize); } +Directory::Directory(uint8_t data[]) { memcpy(__raw, data, BlockSize); } bool Directory::hasFreeFile() const { - return std::any_of(m_files.cbegin(), m_files.cend(), [](const auto& file) { return file.m_game[0] == 0xFF; }); + for (uint16_t i = 0; i < 127; i++) + if (m_files[i].m_game[0] == 0xFF) + return true; + return false; } int32_t Directory::numFreeFiles() const { - return int32_t( - std::count_if(m_files.cbegin(), m_files.cend(), [](const auto& file) { return file.m_game[0] == 0xFF; })); + int32_t ret = 0; + for (uint16_t i = 0; i < 127; i++) + if (m_files[i].m_game[0] == 0xFF) + ++ret; + return ret; } File* Directory::getFirstFreeFile(const char* game, const char* maker, const char* filename) { - const auto iter = - std::find_if(m_files.begin(), m_files.end(), [](const auto& file) { return file.m_game[0] == 0xFF; }); - - if (iter == m_files.cend()) { - return nullptr; + for (uint16_t i = 0; i < 127; i++) { + if (m_files[i].m_game[0] == 0xFF) { + File* ret = &m_files[i]; + *ret = File(filename); + if (game && strlen(game) == 4) + memcpy(ret->m_game, game, 4); + if (maker && strlen(maker) == 2) + memcpy(ret->m_maker, maker, 2); + return ret; + } } - *iter = File(filename); - if (game != nullptr && std::strlen(game) == iter->m_game.size()) { - std::memcpy(iter->m_game.data(), game, iter->m_game.size()); - } - if (maker != nullptr && std::strlen(maker) == iter->m_maker.size()) { - std::memcpy(iter->m_maker.data(), maker, iter->m_maker.size()); - } - - return &*iter; + return nullptr; } File* Directory::getFirstNonFreeFile(uint32_t start, const char* game, const char* maker) { - const auto iter = std::find_if(m_files.begin(), m_files.end(), [game, maker](const auto& file) { - if (file.m_game[0] == 0xFF) { - return false; + for (uint16_t i = start; i < 127; i++) { + if (m_files[i].m_game[0] != 0xFF) { + File* ret = &m_files[i]; + if (game && std::strlen(game) == 4 && std::strncmp(reinterpret_cast(ret->m_game), game, 4) != 0) + continue; + if (maker && std::strlen(maker) == 2 && std::strncmp(reinterpret_cast(ret->m_maker), maker, 2) != 0) + continue; + return ret; } - - const auto* const game_ptr = reinterpret_cast(file.m_game.data()); - const auto game_size = file.m_game.size(); - if (game != nullptr && std::strlen(game) == game_size && std::strncmp(game_ptr, game, game_size) != 0) { - return false; - } - - const auto* const maker_ptr = reinterpret_cast(file.m_maker.data()); - const auto maker_size = file.m_maker.size(); - if (maker != nullptr && std::strlen(maker) == maker_size && std::strncmp(maker_ptr, maker, maker_size) != 0) { - return false; - } - - return true; - }); - - if (iter == m_files.cend()) { - return nullptr; } - return &*iter; + return nullptr; } File* Directory::getFile(const char* game, const char* maker, const char* filename) { - const auto iter = std::find_if(m_files.begin(), m_files.end(), [=](const auto& file) { - const auto game_size = file.m_game.size(); - if (game != nullptr && std::strlen(game) == game_size && std::memcmp(file.m_game.data(), game, game_size) != 0) { - return false; - } - - const auto maker_size = file.m_maker.size(); - if (maker != nullptr && std::strlen(maker) == maker_size && - std::memcmp(file.m_maker.data(), maker, maker_size) != 0) { - return false; - } - - return std::strcmp(file.m_filename, filename) == 0; - }); - - if (iter == m_files.cend()) { - return nullptr; + for (uint16_t i = 0; i < 127; i++) { + if (game && strlen(game) == 4 && memcmp(m_files[i].m_game, game, 4)) + continue; + if (maker && strlen(maker) == 2 && memcmp(m_files[i].m_maker, maker, 2)) + continue; + if (!strcmp(m_files[i].m_filename, filename)) + return &m_files[i]; } - return &*iter; + return nullptr; } File* Directory::getFile(uint32_t idx) { - if (idx >= m_files.size()) { + if (idx >= 127) return nullptr; - } return &m_files[idx]; } int32_t Directory::indexForFile(File* f) { - if (f == nullptr) { + if (!f) return -1; - } - const auto it = std::find_if(std::cbegin(m_files), std::cend(m_files), [&f](const File& file) { return f == &file; }); - if (it == std::cend(m_files)) { + auto it = std::find_if(std::begin(m_files), std::end(m_files), [&f](const File& file) -> bool { return f == &file; }); + if (it == std::end(m_files)) return -1; - } - - return it - std::cbegin(m_files); + return it - std::begin(m_files); } } // namespace kabufuda diff --git a/lib/kabufuda/File.cpp b/lib/kabufuda/File.cpp index 2afd3ba..821994f 100644 --- a/lib/kabufuda/File.cpp +++ b/lib/kabufuda/File.cpp @@ -1,19 +1,18 @@ #include "kabufuda/File.hpp" #include -#include #include "kabufuda/Util.hpp" namespace kabufuda { -File::File() { raw.fill(0xFF); } +File::File() { memset(__raw, 0xFF, 0x40); } -File::File(char data[]) { std::memcpy(raw.data(), data, raw.size()); } +File::File(char data[]) { memcpy(__raw, data, 0x40); } File::File(const char* filename) { - raw.fill(0); - std::memset(m_filename, 0, std::size(m_filename)); - std::strncpy(m_filename, filename, std::size(m_filename)); + memset(__raw, 0, 0x40); + memset(m_filename, 0, 32); + strncpy(m_filename, filename, 32); } void File::swapEndian() { m_modifiedTime = SBig(m_modifiedTime);