From 2a9c18534a5085763c191c151447d598c0f9e90f Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Tue, 28 Jun 2016 11:53:37 -0700 Subject: [PATCH] Finalize directory structure Remove unrelated classes from Card.{cpp,hpp} --- CMakeLists.txt | 14 +- include/kabufuda/BlockAllocationTable.hpp | 42 ++++ include/kabufuda/Card.hpp | 182 +---------------- include/kabufuda/Constants.hpp | 66 ++++++ include/kabufuda/Directory.hpp | 42 ++++ include/kabufuda/File.hpp | 49 +++++ include/kabufuda/Util.hpp | 15 +- include/kabufuda/WideStringConvert.hpp | 5 + lib/kabufuda/BlockAllocationTable.cpp | 113 +++++++++++ lib/{ => kabufuda}/Card.cpp | 237 ---------------------- lib/kabufuda/Directory.cpp | 89 ++++++++ lib/kabufuda/File.cpp | 35 ++++ lib/{ => kabufuda}/SRAM.cpp | 0 lib/{ => kabufuda}/Util.cpp | 18 ++ lib/{ => kabufuda}/WideStringConvert.cpp | 0 15 files changed, 487 insertions(+), 420 deletions(-) create mode 100644 include/kabufuda/BlockAllocationTable.hpp create mode 100644 include/kabufuda/Constants.hpp create mode 100644 include/kabufuda/Directory.hpp create mode 100644 include/kabufuda/File.hpp create mode 100644 lib/kabufuda/BlockAllocationTable.cpp rename lib/{ => kabufuda}/Card.cpp (69%) create mode 100644 lib/kabufuda/Directory.cpp create mode 100644 lib/kabufuda/File.cpp rename lib/{ => kabufuda}/SRAM.cpp (100%) rename lib/{ => kabufuda}/Util.cpp (51%) rename lib/{ => kabufuda}/WideStringConvert.cpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index e19c6c0..ab401a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,11 +11,15 @@ include_directories(include) set(KABUFUDA_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include CACHE PATH "kabufuda include path" FORCE) add_library(kabufuda STATIC - include/kabufuda/Card.hpp lib/Card.cpp - include/kabufuda/Util.hpp lib/Util.cpp - include/kabufuda/SRAM.hpp lib/SRAM.cpp - include/kabufuda/WideStringConvert.hpp lib/WideStringConvert.cpp) + include/kabufuda/Constants.hpp + include/kabufuda/BlockAllocationTable.hpp lib/kabufuda/BlockAllocationTable.cpp + include/kabufuda/Card.hpp lib/kabufuda/Card.cpp + include/kabufuda/Directory.hpp lib/kabufuda/Directory.cpp + include/kabufuda/File.hpp lib/kabufuda/File.cpp + include/kabufuda/Util.hpp lib/kabufuda/Util.cpp + include/kabufuda/SRAM.hpp lib/kabufuda/SRAM.cpp + include/kabufuda/WideStringConvert.hpp lib/kabufuda/WideStringConvert.cpp) -if (NOT TARGET urde) +if (NOT TARGET hecl) add_subdirectory(test) endif() diff --git a/include/kabufuda/BlockAllocationTable.hpp b/include/kabufuda/BlockAllocationTable.hpp new file mode 100644 index 0000000..ba0fa6e --- /dev/null +++ b/include/kabufuda/BlockAllocationTable.hpp @@ -0,0 +1,42 @@ +#ifndef __KABU_BLOCKALLOCATIONATABLE_HPP__ +#define __KABU_BLOCKALLOCATIONATABLE_HPP__ + +#include "Constants.hpp" + +namespace kabufuda +{ +class BlockAllocationTable +{ + friend class Card; +#pragma pack(push, 4) + union + { + struct + { + uint16_t m_checksum; + uint16_t m_checksumInv; + uint16_t m_updateCounter; + uint16_t m_freeBlocks; + uint16_t m_lastAllocated; + uint16_t m_map[0xFFB]; + }; + uint8_t __raw[BlockSize]; + }; +#pragma pack(pop) + + void swapEndian(); + void updateChecksum(); + bool valid() const; + +public: + explicit BlockAllocationTable(uint32_t blockCount = (uint32_t(ECardSize::Card2043Mb) * MbitToBlocks)); + BlockAllocationTable(uint8_t data[BlockSize]); + ~BlockAllocationTable() {} + + uint16_t getNextBlock(uint16_t block) const; + uint16_t nextFreeBlock(uint16_t maxBlock, uint16_t startingBlock) const; + bool clear(uint16_t first, uint16_t count); + uint16_t allocateBlocks(uint16_t count, uint16_t maxBlocks); +}; +} +#endif // __KABU_BLOCKALLOCATIONATABLE_HPP__ diff --git a/include/kabufuda/Card.hpp b/include/kabufuda/Card.hpp index f2a5832..25daba1 100644 --- a/include/kabufuda/Card.hpp +++ b/include/kabufuda/Card.hpp @@ -1,109 +1,17 @@ -#ifndef __CARD_HPP__ -#define __CARD_HPP__ +#ifndef __KABU_CARD_HPP__ +#define __KABU_CARD_HPP__ + +#include "BlockAllocationTable.hpp" +#include "Directory.hpp" +#include "File.hpp" +#include "Util.hpp" #include #include #include -#include "Util.hpp" namespace kabufuda { -uint32_t constexpr BlockSize = 0x2000; -uint32_t constexpr MaxFiles = 127; -uint32_t constexpr FSTBlocks = 5; -uint32_t constexpr MbitToBlocks = 0x10; -uint32_t constexpr BATSize = 0xFFB; - -/** - * @brief The EPermissions enum - */ -enum class EPermissions : uint8_t -{ -}; - -/** - * @brief The EBannerFlags enum - */ -enum class EBannerFlags : uint8_t -{ -}; - -enum class SeekOrigin -{ - Begin, - Current, - End -}; - -/** - * @brief The EDeviceId enum - */ -enum class EDeviceId : uint16_t -{ - SlotA, - SlotB -}; - -/** - * @brief The ECardSize enum - */ -enum class ECardSize : uint16_t -{ - Card59Mb = 0x04, - Card123Mb = 0x08, - Card251Mb = 0x10, - Card507Mb = 0x20, - Card1019Mb = 0x40, - Card2043Mb = 0x80 -}; - -/** - * @brief The EEncoding enum - */ -enum class EEncoding : uint16_t -{ - ASCII, /**< Standard ASCII Encoding */ - SJIS /**< SJIS Encoding for japanese */ -}; - -class File -{ - friend class FileHandle; - friend class Directory; - friend class Card; -#pragma pack(push, 4) - union - { - struct - { - uint8_t m_id[4]; - uint8_t m_maker[2]; - uint8_t m_reserved; - uint8_t m_bannerFlags; - char m_filename[0x20]; - uint32_t m_modifiedTime; - uint32_t m_imageOffset; - uint16_t m_iconFmt; - uint16_t m_animSpeed; - uint8_t m_permissions; - int8_t m_copyCounter; - uint16_t m_firstBlock; - uint16_t m_blockCount; - uint16_t m_reserved2; - uint32_t m_commentAddr; - }; - uint8_t __raw[0x40]; - }; - -#pragma pack(pop) - void swapEndian(); - -public: - File(); - File(char data[0x40]); - File(const char* filename); - ~File() {} -}; class IFileHandle { @@ -111,73 +19,6 @@ public: virtual ~IFileHandle(); }; -class BlockAllocationTable -{ - friend class Card; -#pragma pack(push, 4) - union - { - struct - { - uint16_t m_checksum; - uint16_t m_checksumInv; - uint16_t m_updateCounter; - uint16_t m_freeBlocks; - uint16_t m_lastAllocated; - uint16_t m_map[0xFFB]; - }; - uint8_t __raw[BlockSize]; - }; -#pragma pack(pop) - - void swapEndian(); - void updateChecksum(); - bool valid() const; - -public: - explicit BlockAllocationTable(uint32_t blockCount = (uint32_t(ECardSize::Card2043Mb) * MbitToBlocks)); - BlockAllocationTable(uint8_t data[BlockSize]); - ~BlockAllocationTable() {} - - uint16_t getNextBlock(uint16_t block) const; - uint16_t nextFreeBlock(uint16_t maxBlock, uint16_t startingBlock) const; - bool clear(uint16_t first, uint16_t count); - uint16_t allocateBlocks(uint16_t count, uint16_t maxBlocks); -}; - -class Directory -{ - friend class Card; -#pragma pack(push, 4) - union - { - struct - { - File m_files[MaxFiles]; - uint8_t __padding[0x3a]; - uint16_t m_updateCounter; - uint16_t m_checksum; - uint16_t m_checksumInv; - }; - uint8_t __raw[BlockSize]; - }; -#pragma pack(pop) - - void swapEndian(); - void updateChecksum(); - bool valid() const; - -public: - Directory(); - Directory(uint8_t data[BlockSize]); - Directory(const Directory& other); - void operator=(const Directory& other); - ~Directory() {} - - File* getFirstFreeFile(const char* game, const char* maker, const char* filename); - File* getFile(const char* game, const char* maker, const char* filename); -}; - class Card { #pragma pack(push, 4) @@ -293,15 +134,6 @@ public: operator bool() const; }; - -/** - * @brief calculateChecksum - * @param data - * @param len - * @param checksum - * @param checksumInv - */ -void calculateChecksumBE(const uint16_t* data, size_t len, uint16_t* checksum, uint16_t* checksumInv); } #endif // __CARD_HPP__ diff --git a/include/kabufuda/Constants.hpp b/include/kabufuda/Constants.hpp new file mode 100644 index 0000000..e2e1282 --- /dev/null +++ b/include/kabufuda/Constants.hpp @@ -0,0 +1,66 @@ +#ifndef __KABU_CONSTANTS_HPP__ +#define __KABU_CONSTANTS_HPP__ + +#include + +namespace kabufuda +{ +uint32_t constexpr BlockSize = 0x2000; +uint32_t constexpr MaxFiles = 127; +uint32_t constexpr FSTBlocks = 5; +uint32_t constexpr MbitToBlocks = 0x10; +uint32_t constexpr BATSize = 0xFFB; + +/** + * @brief The EPermissions enum + */ +enum class EPermissions : uint8_t +{ +}; + +/** + * @brief The EBannerFlags enum + */ +enum class EBannerFlags : uint8_t +{ +}; + +enum class SeekOrigin +{ + Begin, + Current, + End +}; + +/** + * @brief The EDeviceId enum + */ +enum class EDeviceId : uint16_t +{ + SlotA, + SlotB +}; + +/** + * @brief The ECardSize enum + */ +enum class ECardSize : uint16_t +{ + Card59Mb = 0x04, + Card123Mb = 0x08, + Card251Mb = 0x10, + Card507Mb = 0x20, + Card1019Mb = 0x40, + Card2043Mb = 0x80 +}; + +/** + * @brief The EEncoding enum + */ +enum class EEncoding : uint16_t +{ + ASCII, /**< Standard ASCII Encoding */ + SJIS /**< SJIS Encoding for japanese */ +}; +} +#endif // __KABU_CONSTANTS_HPP__ diff --git a/include/kabufuda/Directory.hpp b/include/kabufuda/Directory.hpp new file mode 100644 index 0000000..3697ae2 --- /dev/null +++ b/include/kabufuda/Directory.hpp @@ -0,0 +1,42 @@ +#ifndef __KABU_DIRECTORY_HPP__ +#define __KABU_DIRECTORY_HPP__ + +#include "File.hpp" + +namespace kabufuda +{ +class Directory +{ + friend class Card; +#pragma pack(push, 4) + union + { + struct + { + File m_files[MaxFiles]; + uint8_t __padding[0x3a]; + uint16_t m_updateCounter; + uint16_t m_checksum; + uint16_t m_checksumInv; + }; + uint8_t __raw[BlockSize]; + }; +#pragma pack(pop) + + void swapEndian(); + void updateChecksum(); + bool valid() const; + +public: + Directory(); + Directory(uint8_t data[BlockSize]); + Directory(const Directory& other); + void operator=(const Directory& other); + ~Directory() {} + + File* getFirstFreeFile(const char* game, const char* maker, const char* filename); + File* getFile(const char* game, const char* maker, const char* filename); +}; +} + +#endif // __KABU_DIRECTORY_HPP__ diff --git a/include/kabufuda/File.hpp b/include/kabufuda/File.hpp new file mode 100644 index 0000000..52491dc --- /dev/null +++ b/include/kabufuda/File.hpp @@ -0,0 +1,49 @@ +#ifndef __KABU_FILE_HPP__ +#define __KABU_FILE_HPP__ + +#include "Constants.hpp" + +namespace kabufuda +{ +class File +{ + friend class IFileHandle; + friend class Directory; + friend class Card; +#pragma pack(push, 4) + union + { + struct + { + uint8_t m_id[4]; + uint8_t m_maker[2]; + uint8_t m_reserved; + uint8_t m_bannerFlags; + char m_filename[0x20]; + uint32_t m_modifiedTime; + uint32_t m_imageOffset; + uint16_t m_iconFmt; + uint16_t m_animSpeed; + uint8_t m_permissions; + int8_t m_copyCounter; + uint16_t m_firstBlock; + uint16_t m_blockCount; + uint16_t m_reserved2; + uint32_t m_commentAddr; + }; + uint8_t __raw[0x40]; + }; + +#pragma pack(pop) + void swapEndian(); + +public: + File(); + File(char data[0x40]); + File(const char* filename); + ~File() {} +}; + +} + +#endif // __KABU_FILE_HPP__ diff --git a/include/kabufuda/Util.hpp b/include/kabufuda/Util.hpp index 2de5740..fd8a135 100644 --- a/include/kabufuda/Util.hpp +++ b/include/kabufuda/Util.hpp @@ -1,5 +1,5 @@ -#ifndef __UTIL_HPP__ -#define __UTIL_HPP__ +#ifndef __KABU_UTIL_HPP__ +#define __KABU_UTIL_HPP__ #ifndef _WIN32 #include @@ -305,6 +305,15 @@ static inline int Stat(const SystemChar* path, Sstat* statOut) return stat(path, statOut); #endif } + +/** + * @brief calculateChecksum + * @param data + * @param len + * @param checksum + * @param checksumInv + */ +void calculateChecksumBE(const uint16_t* data, size_t len, uint16_t* checksum, uint16_t* checksumInv); } -#endif // __UTIL_HPP__ +#endif // __KABU_UTIL_HPP__ diff --git a/include/kabufuda/WideStringConvert.hpp b/include/kabufuda/WideStringConvert.hpp index 80d0703..44757a9 100644 --- a/include/kabufuda/WideStringConvert.hpp +++ b/include/kabufuda/WideStringConvert.hpp @@ -1,3 +1,6 @@ +#ifndef __KABU_WIDESTRINGCONVERT_HPP__ +#define __KABU_WIDESTRINGCONVERT_HPP__ + #include namespace kabufuda @@ -5,3 +8,5 @@ namespace kabufuda std::string WideToUTF8(const std::wstring& src); std::wstring UTF8ToWide(const std::string& src); } + +#endif // __KABU_WIDESTRINGCONVERT_HPP__ diff --git a/lib/kabufuda/BlockAllocationTable.cpp b/lib/kabufuda/BlockAllocationTable.cpp new file mode 100644 index 0000000..f43e605 --- /dev/null +++ b/lib/kabufuda/BlockAllocationTable.cpp @@ -0,0 +1,113 @@ +#include "kabufuda/BlockAllocationTable.hpp" +#include "kabufuda/Util.hpp" +#include + + +namespace kabufuda +{ +void BlockAllocationTable::swapEndian() +{ + m_checksum = SBig(m_checksum); + m_checksumInv = SBig(m_checksumInv); + m_updateCounter = SBig(m_updateCounter); + m_freeBlocks = SBig(m_freeBlocks); + m_lastAllocated = SBig(m_lastAllocated); + std::for_each(std::begin(m_map), std::end(m_map), [](uint16_t& val){ + val = SBig(val); + }); +} + +void BlockAllocationTable::updateChecksum() +{ + swapEndian(); + calculateChecksumBE(reinterpret_cast(__raw + 4), 0xFFE, &m_checksum, &m_checksumInv); + swapEndian(); +} + +bool BlockAllocationTable::valid() const +{ + uint16_t ckSum, ckSumInv; + BlockAllocationTable tmp = *this; + tmp.swapEndian(); + calculateChecksumBE(reinterpret_cast(tmp.__raw + 4), 0xFFE, &ckSum, &ckSumInv); + return (SBig(ckSum) == m_checksum && SBig(ckSumInv) == m_checksumInv); +} + +BlockAllocationTable::BlockAllocationTable(uint32_t blockCount) +{ + memset(__raw, 0, BlockSize); + m_freeBlocks = uint16_t(blockCount - FSTBlocks); + m_lastAllocated = 4; + updateChecksum(); +} + +uint16_t BlockAllocationTable::getNextBlock(uint16_t block) const +{ + if ((block < FSTBlocks) || (block > (BATSize - FSTBlocks))) + return 0; + + return m_map[block - FSTBlocks]; +} + +uint16_t BlockAllocationTable::nextFreeBlock(uint16_t maxBlock, uint16_t startingBlock) const +{ + if (m_freeBlocks > 0) + { + maxBlock = std::min(maxBlock, uint16_t(BATSize)); + for (uint16_t i = startingBlock; i < maxBlock; ++i) + if (m_map[i - FSTBlocks] == 0) + return i; + + for (uint16_t i = FSTBlocks; i < startingBlock; ++i) + if (m_map[i - FSTBlocks] == 0) + return i; + } + + return 0xFFFF; +} + +bool BlockAllocationTable::clear(uint16_t first, uint16_t count) +{ + std::vector blocks; + while (first != 0xFFFF && first != 0) + { + blocks.push_back(first); + first = getNextBlock(first); + } + if (first > 0) + { + size_t length = blocks.size(); + if (length != count) + return false; + + for (size_t i= 0 ; i < length ; ++i) + m_map[blocks.at(i) - FSTBlocks] = 0; + m_freeBlocks += count; + return true; + } + return false; +} + +uint16_t BlockAllocationTable::allocateBlocks(uint16_t count, uint16_t maxBlocks) +{ + uint16_t firstBlock = nextFreeBlock(maxBlocks - FSTBlocks, m_lastAllocated + 1); + uint16_t freeBlock = firstBlock; + if (freeBlock != 0xFFFF) + { + uint16_t tmpCount = count; + while ((count--) > 0) + { + m_map[(freeBlock - FSTBlocks)] = 0xFFFF; + if (count != 0) + { + m_map[(freeBlock - FSTBlocks)] = nextFreeBlock(maxBlocks - FSTBlocks, m_lastAllocated + 1); + freeBlock = m_map[(freeBlock - FSTBlocks)]; + } + m_lastAllocated = freeBlock; + } + + m_freeBlocks -= tmpCount; + } + return firstBlock; +} +} diff --git a/lib/Card.cpp b/lib/kabufuda/Card.cpp similarity index 69% rename from lib/Card.cpp rename to lib/kabufuda/Card.cpp index d205db2..e2b3fb5 100644 --- a/lib/Card.cpp +++ b/lib/kabufuda/Card.cpp @@ -493,241 +493,4 @@ Card::operator bool() const return true; } - -File::File(char data[]) -{ - memcpy(__raw, data, 0x40); -} - -File::File(const char* filename) -{ - memset(__raw, 0xFF, 0x40); - memset(m_filename, 0, 32); - size_t len = strlen(filename); - len = std::min(len, 32); - memcpy(m_filename, filename, len); -} -void File::swapEndian() -{ - m_modifiedTime = SBig(m_modifiedTime); - m_imageOffset = SBig(m_imageOffset); - m_iconFmt = SBig(m_iconFmt); - m_animSpeed = SBig(m_animSpeed); - m_firstBlock = SBig(m_firstBlock); - m_blockCount = SBig(m_blockCount); - m_reserved2 = SBig(m_reserved2); - m_commentAddr = SBig(m_commentAddr); -} - -File::File() -{ - memset(__raw, 0xFF, 0x40); -} - -void BlockAllocationTable::swapEndian() -{ - m_checksum = SBig(m_checksum); - m_checksumInv = SBig(m_checksumInv); - m_updateCounter = SBig(m_updateCounter); - m_freeBlocks = SBig(m_freeBlocks); - m_lastAllocated = SBig(m_lastAllocated); - std::for_each(std::begin(m_map), std::end(m_map), [](uint16_t& val){ - val = SBig(val); - }); -} - -void BlockAllocationTable::updateChecksum() -{ - swapEndian(); - calculateChecksumBE(reinterpret_cast(__raw + 4), 0xFFE, &m_checksum, &m_checksumInv); - swapEndian(); -} - -bool BlockAllocationTable::valid() const -{ - uint16_t ckSum, ckSumInv; - BlockAllocationTable tmp = *this; - tmp.swapEndian(); - calculateChecksumBE(reinterpret_cast(tmp.__raw + 4), 0xFFE, &ckSum, &ckSumInv); - return (SBig(ckSum) == m_checksum && SBig(ckSumInv) == m_checksumInv); -} - -BlockAllocationTable::BlockAllocationTable(uint32_t blockCount) -{ - memset(__raw, 0, BlockSize); - m_freeBlocks = uint16_t(blockCount - FSTBlocks); - m_lastAllocated = 4; - updateChecksum(); -} - -uint16_t BlockAllocationTable::getNextBlock(uint16_t block) const -{ - if ((block < FSTBlocks) || (block > (BATSize - FSTBlocks))) - return 0; - - return m_map[block - FSTBlocks]; -} - -uint16_t BlockAllocationTable::nextFreeBlock(uint16_t maxBlock, uint16_t startingBlock) const -{ - if (m_freeBlocks > 0) - { - maxBlock = std::min(maxBlock, uint16_t(BATSize)); - for (uint16_t i = startingBlock; i < maxBlock; ++i) - if (m_map[i - FSTBlocks] == 0) - return i; - - for (uint16_t i = FSTBlocks; i < startingBlock; ++i) - if (m_map[i - FSTBlocks] == 0) - return i; - } - - return 0xFFFF; -} - -bool BlockAllocationTable::clear(uint16_t first, uint16_t count) -{ - std::vector blocks; - while (first != 0xFFFF && first != 0) - { - blocks.push_back(first); - first = getNextBlock(first); - } - if (first > 0) - { - size_t length = blocks.size(); - if (length != count) - return false; - - for (size_t i= 0 ; i < length ; ++i) - m_map[blocks.at(i) - FSTBlocks] = 0; - m_freeBlocks += count; - return true; - } - return false; -} - -uint16_t BlockAllocationTable::allocateBlocks(uint16_t count, uint16_t maxBlocks) -{ - uint16_t firstBlock = nextFreeBlock(maxBlocks - FSTBlocks, m_lastAllocated + 1); - uint16_t freeBlock = firstBlock; - if (freeBlock != 0xFFFF) - { - uint16_t tmpCount = count; - while ((count--) > 0) - { - m_map[(freeBlock - FSTBlocks)] = 0xFFFF; - if (count != 0) - { - m_map[(freeBlock - FSTBlocks)] = nextFreeBlock(maxBlocks - FSTBlocks, m_lastAllocated + 1); - freeBlock = m_map[(freeBlock - FSTBlocks)]; - } - m_lastAllocated = freeBlock; - } - - m_freeBlocks -= tmpCount; - } - return firstBlock; -} - -void Directory::swapEndian() -{ - std::for_each(std::begin(m_files), std::end(m_files), [](File& f){ - f.swapEndian(); - }); - - m_updateCounter = SBig(m_updateCounter); - m_checksum = SBig(m_checksum); - m_checksumInv = SBig(m_checksumInv); -} - -void Directory::updateChecksum() -{ - swapEndian(); - calculateChecksumBE(reinterpret_cast(__raw), 0xFFE, &m_checksum, &m_checksumInv); - swapEndian(); -} - -bool Directory::valid() const -{ - uint16_t ckSum, ckSumInv; - Directory tmp = *this; - tmp.swapEndian(); - calculateChecksumBE(reinterpret_cast(tmp.__raw), 0xFFE, &ckSum, &ckSumInv); - return (SBig(ckSum) == m_checksum && SBig(ckSumInv) == m_checksumInv); -} - -Directory::Directory() -{ - memset(__raw, 0xFF, BlockSize); - m_updateCounter = 0; - updateChecksum(); -} - -Directory::Directory(uint8_t data[]) -{ - memcpy(__raw, data, BlockSize); -} - -Directory::Directory(const Directory& other) -{ - memcpy(__raw, other.__raw, BlockSize); -} - -void Directory::operator=(const Directory& other) -{ - memcpy(__raw, other.__raw, BlockSize); -} - -File* Directory::getFirstFreeFile(const char* game, const char* maker, const char* filename) -{ - for (uint16_t i = 0 ; i < 127 ; i++) - { - if (m_files[i].m_id[0] == 0xFF) - { - File* ret = &m_files[i]; - *ret = File(filename); - if (game && strlen(game) == 4) - memcpy(ret->m_id, game, 4); - if (maker && strlen(maker) == 2) - memcpy(ret->m_maker, maker, 2); - return ret; - } - } - - return nullptr; -} - -File* Directory::getFile(const char* game, const char* maker, const char* filename) -{ - for (uint16_t i = 0 ; i < 127 ; i++) - { - if (game && strlen(game) == 4 && memcmp(m_files[i].m_id, 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 nullptr; -} - -void calculateChecksumBE(const uint16_t* data, size_t len, uint16_t* checksum, uint16_t* checksumInv) -{ - *checksum = 0; - *checksumInv = 0; - for (size_t i = 0; i < len; ++i) - { - *checksum += SBig(data[i]); - *checksumInv += SBig(uint16_t(data[i] ^ 0xFFFF)); - } - - *checksum = SBig(*checksum); - *checksumInv = SBig(*checksumInv); - if (*checksum == 0xFFFF) - *checksum = 0; - if (*checksumInv == 0xFFFF) - *checksumInv = 0; -} } diff --git a/lib/kabufuda/Directory.cpp b/lib/kabufuda/Directory.cpp new file mode 100644 index 0000000..255d202 --- /dev/null +++ b/lib/kabufuda/Directory.cpp @@ -0,0 +1,89 @@ +#include "kabufuda/Directory.hpp" +#include "kabufuda/Util.hpp" + + +namespace kabufuda +{ +void Directory::swapEndian() +{ + std::for_each(std::begin(m_files), std::end(m_files), [](File& f){ + f.swapEndian(); + }); + + m_updateCounter = SBig(m_updateCounter); + m_checksum = SBig(m_checksum); + m_checksumInv = SBig(m_checksumInv); +} + +void Directory::updateChecksum() +{ + swapEndian(); + calculateChecksumBE(reinterpret_cast(__raw), 0xFFE, &m_checksum, &m_checksumInv); + swapEndian(); +} + +bool Directory::valid() const +{ + uint16_t ckSum, ckSumInv; + Directory tmp = *this; + tmp.swapEndian(); + calculateChecksumBE(reinterpret_cast(tmp.__raw), 0xFFE, &ckSum, &ckSumInv); + return (SBig(ckSum) == m_checksum && SBig(ckSumInv) == m_checksumInv); +} + +Directory::Directory() +{ + memset(__raw, 0xFF, BlockSize); + m_updateCounter = 0; + updateChecksum(); +} + +Directory::Directory(uint8_t data[]) +{ + memcpy(__raw, data, BlockSize); +} + +Directory::Directory(const Directory& other) +{ + memcpy(__raw, other.__raw, BlockSize); +} + +void Directory::operator=(const Directory& other) +{ + memcpy(__raw, other.__raw, BlockSize); +} + +File* Directory::getFirstFreeFile(const char* game, const char* maker, const char* filename) +{ + for (uint16_t i = 0 ; i < 127 ; i++) + { + if (m_files[i].m_id[0] == 0xFF) + { + File* ret = &m_files[i]; + *ret = File(filename); + if (game && strlen(game) == 4) + memcpy(ret->m_id, game, 4); + if (maker && strlen(maker) == 2) + memcpy(ret->m_maker, maker, 2); + return ret; + } + } + + return nullptr; +} + +File* Directory::getFile(const char* game, const char* maker, const char* filename) +{ + for (uint16_t i = 0 ; i < 127 ; i++) + { + if (game && strlen(game) == 4 && memcmp(m_files[i].m_id, 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 nullptr; +} +} diff --git a/lib/kabufuda/File.cpp b/lib/kabufuda/File.cpp new file mode 100644 index 0000000..ecd663f --- /dev/null +++ b/lib/kabufuda/File.cpp @@ -0,0 +1,35 @@ +#include "kabufuda/File.hpp" +#include "kabufuda/Util.hpp" + +namespace kabufuda +{ +File::File(char data[]) +{ + memcpy(__raw, data, 0x40); +} + +File::File(const char* filename) +{ + memset(__raw, 0xFF, 0x40); + memset(m_filename, 0, 32); + size_t len = strlen(filename); + len = std::min(len, 32); + memcpy(m_filename, filename, len); +} +void File::swapEndian() +{ + m_modifiedTime = SBig(m_modifiedTime); + m_imageOffset = SBig(m_imageOffset); + m_iconFmt = SBig(m_iconFmt); + m_animSpeed = SBig(m_animSpeed); + m_firstBlock = SBig(m_firstBlock); + m_blockCount = SBig(m_blockCount); + m_reserved2 = SBig(m_reserved2); + m_commentAddr = SBig(m_commentAddr); +} + +File::File() +{ + memset(__raw, 0xFF, 0x40); +} +} diff --git a/lib/SRAM.cpp b/lib/kabufuda/SRAM.cpp similarity index 100% rename from lib/SRAM.cpp rename to lib/kabufuda/SRAM.cpp diff --git a/lib/Util.cpp b/lib/kabufuda/Util.cpp similarity index 51% rename from lib/Util.cpp rename to lib/kabufuda/Util.cpp index f2909c9..fef406d 100644 --- a/lib/Util.cpp +++ b/lib/kabufuda/Util.cpp @@ -23,4 +23,22 @@ uint64_t getGCTime() return (uint64_t)(sysTime + tzDiff + tzDST) - 0x386D4380; } + +void calculateChecksumBE(const uint16_t* data, size_t len, uint16_t* checksum, uint16_t* checksumInv) +{ + *checksum = 0; + *checksumInv = 0; + for (size_t i = 0; i < len; ++i) + { + *checksum += SBig(data[i]); + *checksumInv += SBig(uint16_t(data[i] ^ 0xFFFF)); + } + + *checksum = SBig(*checksum); + *checksumInv = SBig(*checksumInv); + if (*checksum == 0xFFFF) + *checksum = 0; + if (*checksumInv == 0xFFFF) + *checksumInv = 0; +} } diff --git a/lib/WideStringConvert.cpp b/lib/kabufuda/WideStringConvert.cpp similarity index 100% rename from lib/WideStringConvert.cpp rename to lib/kabufuda/WideStringConvert.cpp