diff --git a/epsxe000_xa2.mcr b/epsxe000_xa2.mcr new file mode 100644 index 0000000..44ac69e Binary files /dev/null and b/epsxe000_xa2.mcr differ diff --git a/src/gui/block.cpp b/src/gui/block.cpp index e641f30..2d46aca 100644 --- a/src/gui/block.cpp +++ b/src/gui/block.cpp @@ -75,5 +75,17 @@ BasicBlock::BasicBlock (data_type* beg) : template BasicBlock::~BasicBlock() = default; +template +bool BasicBlock::has_magic() const { + const constexpr uint16_t magic = ('S' << 8) | 'C'; //0x5343 "SC" + return magic == static_cast((m_begin[0] << 8) | m_begin[1]); +} + +template +IconDisplayFlag BasicBlock::icon_display_flag() const { + const uint8_t val = m_begin[2]; + return static_cast(val); +} + template class BasicBlock; template class BasicBlock; diff --git a/src/gui/block.hpp b/src/gui/block.hpp index b5c50bd..41977fa 100644 --- a/src/gui/block.hpp +++ b/src/gui/block.hpp @@ -4,6 +4,18 @@ #include #include +//see: https://www.psdevwiki.com/ps3/PS1_Savedata#Memory_Card_Formats_PS1 + +enum class IconDisplayFlag { + NoIcon = 0x00, + OneFrame = 0x11, + TwoFrames = 0x12, + ThreeFrames = 0x13, + OneFrameAlt = 0x16, + TwoFramesAlt = 0x17, + ThreeFramesAlt = 0x18 +}; + template class BasicBlock { public: @@ -22,11 +34,32 @@ public: static constexpr std::size_t size() { return 8192; } const std::vector& palette() const { return m_icon_palette; } + bool has_magic() const; + IconDisplayFlag icon_display_flag() const; private: std::vector m_icon_palette; data_type* m_begin; }; +[[gnu::const]] +inline int32_t calc_icon_count (IconDisplayFlag idf) { + switch (idf) { + case IconDisplayFlag::OneFrame: + case IconDisplayFlag::OneFrameAlt: + return 1; + case IconDisplayFlag::TwoFrames: + case IconDisplayFlag::TwoFramesAlt: + return 2; + case IconDisplayFlag::ThreeFrames: + case IconDisplayFlag::ThreeFramesAlt: + return 3; + + case IconDisplayFlag::NoIcon: + default: + return 0; + } +} + using Block = BasicBlock; using ConstBlock = BasicBlock; diff --git a/src/gui/icon_fetch.cpp b/src/gui/icon_fetch.cpp index f6336eb..44c21ee 100644 --- a/src/gui/icon_fetch.cpp +++ b/src/gui/icon_fetch.cpp @@ -116,7 +116,7 @@ namespace { } //unnamed namespace std::vector> icon_fetch (const ConstBlock& block, int width, int height) { - const int in_height = 16, in_width = 16; + const constexpr int in_height = 16, in_width = 16; const bool scale = (in_width != width or in_height != height); const auto slot_begin = block.cbegin(); const std::vector& palette = block.palette(); @@ -142,10 +142,13 @@ std::vector> icon_fetch (const ConstBlock& block, int width, i ihead.biClrImportant = ihead.biClrUsed; ihead.biSizeImage = scan_sz * height; - std::vector> retval(3); - int32_t icon_num = 0; + const auto icon_count = calc_icon_count(block.icon_display_flag()); + std::vector> retval; + retval.reserve(icon_count); std::vector orig_rgb; - for (auto& frame : retval) { + for (int32_t icon_num = 0; icon_num < icon_count; ++icon_num) { + retval.emplace_back(); + auto& frame = retval.back(); frame.reserve(bmp_byte_size); std::copy(reinterpret_cast(&bmp::g_signature), reinterpret_cast(&bmp::g_signature + 1), std::back_inserter(frame)); diff --git a/src/gui/main.cpp b/src/gui/main.cpp index b07a010..3b999e3 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -16,7 +16,8 @@ namespace { int main() { nana::form frm; - const MemoryCard mc(std::ifstream("/home/michele/dev/code/cpp/memoserv/michele_epsxe000.mcr", std::ios::binary)); + const MemoryCard mc1(std::ifstream("/home/michele/dev/code/cpp/memoserv/epsxe000_xa2.mcr", std::ios::binary)); + const MemoryCard mc2(std::ifstream("/home/michele/dev/code/cpp/memoserv/michele_epsxe000.mcr", std::ios::binary)); #if !defined(NDEBUG) //grid1.bgcolor(nana::colors::azure); @@ -26,8 +27,10 @@ int main() { duck::widget::BlockGrid grid2{frm, 3, true}; for (int z = 0; z < 15; ++z) { - grid1.emplace_back(duck::make_nana_animation(mc[z], g_def_icon_size, g_def_icon_size, g_def_icon_fps)); - grid2.emplace_back(duck::make_nana_animation(mc[z], g_def_icon_size, g_def_icon_size, g_def_icon_fps)); + if (mc1[z].has_magic()) + grid1.emplace_back(duck::make_nana_animation(mc1[z], g_def_icon_size, g_def_icon_size, g_def_icon_fps)); + if (mc2[z].has_magic()) + grid2.emplace_back(duck::make_nana_animation(mc2[z], g_def_icon_size, g_def_icon_size, g_def_icon_fps)); } std::cout << "Hello world\n";