memoserv/subprojects/memcard/include/memcard/block.hpp

77 lines
1.9 KiB
C++

#pragma once
#include <cstdint>
#include <type_traits>
#include <vector>
#include <string>
//see: https://www.psdevwiki.com/ps3/PS1_Savedata#Memory_Card_Formats_PS1
namespace mc::psx {
enum class IconDisplayFlag {
NoIcon = 0x00,
OneFrame = 0x11,
TwoFrames = 0x12,
ThreeFrames = 0x13,
OneFrameAlt = 0x16,
TwoFramesAlt = 0x17,
ThreeFramesAlt = 0x18
};
template <bool Const>
class BasicBlock {
public:
using data_type = typename std::conditional<Const, const uint8_t, uint8_t>::type;
static const constexpr unsigned int FrameSize = 128;
static const constexpr std::size_t ToCBlockIndex = 0xff;
BasicBlock (data_type* beg, std::size_t index);
~BasicBlock();
data_type* begin() { return m_begin; }
data_type* end() { return m_begin + size(); }
const data_type* cbegin() const { return m_begin; }
const data_type* cend() const { return m_begin + size(); }
const data_type* begin() const { return m_begin; }
const data_type* end() const { return m_begin + size(); }
data_type* frame(unsigned int idx);
const data_type* frame(unsigned int idx) const;
static constexpr std::size_t size() { return FrameSize * 64; }
std::vector<uint8_t> icon_palette() const;
bool has_magic() const;
IconDisplayFlag icon_display_flag() const;
int block_count() const;
std::size_t index() const { return m_index; }
std::string title() const;
private:
std::size_t m_index;
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<false>;
using ConstBlock = BasicBlock<true>;
} //namespace mc::psx