Add new BasicFrame class.
This commit is contained in:
parent
4eaa2fc734
commit
db70dead33
11 changed files with 115 additions and 38 deletions
|
@ -19,7 +19,7 @@ void print_blocks (const std::string& mc_path) {
|
|||
|
||||
for (const auto& blk : mc) {
|
||||
if (blk.has_magic()) {
|
||||
std::cout << "Block " << std::setfill(' ') << std::setw(2) << blk.index() + 1
|
||||
std::cout << "Block " << std::setfill(' ') << std::setw(2) << blk.index()
|
||||
<< ": \"" << blk.title() << '"';
|
||||
if (blk.block_count() > 1) {
|
||||
std::cout << " [" << blk.block_count() << ']';
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "memcard/frame.hpp"
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
@ -20,26 +21,22 @@ enum class IconDisplayFlag {
|
|||
|
||||
template <bool Const>
|
||||
class BasicBlock {
|
||||
public:
|
||||
using data_type = typename std::conditional<Const, const uint8_t, uint8_t>::type;
|
||||
public:
|
||||
|
||||
static const constexpr unsigned int FrameSize = 128;
|
||||
static const constexpr std::size_t ToCBlockIndex = 0xff;
|
||||
static const constexpr std::size_t FrameCount = 64;
|
||||
static const constexpr std::size_t TOCBlockIndex = 0;
|
||||
|
||||
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* data() { return m_begin; }
|
||||
const data_type* data() const { return m_begin; }
|
||||
|
||||
data_type* frame(unsigned int idx);
|
||||
const data_type* frame(unsigned int idx) const;
|
||||
BasicFrame<Const> frame(unsigned int idx);
|
||||
ConstFrame frame(unsigned int idx) const;
|
||||
|
||||
static constexpr std::size_t size() { return FrameSize * 64; }
|
||||
static constexpr std::size_t size() { return FrameCount; }
|
||||
|
||||
std::vector<uint8_t> icon_palette() const;
|
||||
bool has_magic() const;
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
#include <cstdint>
|
||||
|
||||
namespace mc::psx {
|
||||
template <bool Const> class BasicBlock;
|
||||
using ConstBlock = BasicBlock<true>;
|
||||
template <bool Const> class BasicFrame;
|
||||
using ConstFrame = BasicFrame<true>;
|
||||
|
||||
enum class BlockContent : uint8_t {
|
||||
Available = 0xA0,
|
||||
|
@ -15,7 +15,7 @@ enum class BlockContent : uint8_t {
|
|||
};
|
||||
|
||||
struct ContentInfo {
|
||||
ContentInfo (const ConstBlock& block);
|
||||
ContentInfo (const ConstFrame& block);
|
||||
|
||||
uint32_t use_byte;
|
||||
uint16_t magic;
|
||||
|
|
39
subprojects/memcard/include/memcard/frame.hpp
Normal file
39
subprojects/memcard/include/memcard/frame.hpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace mc::psx {
|
||||
template <bool Const>
|
||||
class BasicFrame {
|
||||
using data_type = typename std::conditional<Const, const uint8_t, uint8_t>::type;
|
||||
public:
|
||||
static const constexpr unsigned int Size = 128;
|
||||
|
||||
BasicFrame (data_type* data, std::size_t index);
|
||||
BasicFrame (const BasicFrame&) = default;
|
||||
BasicFrame (BasicFrame&&) = default;
|
||||
|
||||
data_type* begin() { return m_data; }
|
||||
data_type* end() { return m_data + size(); }
|
||||
const data_type* cbegin() const { return m_data; }
|
||||
const data_type* cend() const { return m_data + size(); }
|
||||
const data_type* begin() const { return m_data; }
|
||||
const data_type* end() const { return m_data + size(); }
|
||||
data_type& operator[] (std::size_t index);
|
||||
const data_type& operator[] (std::size_t index) const;
|
||||
|
||||
static constexpr std::size_t size() { return Size; }
|
||||
|
||||
data_type* data() { return m_data; }
|
||||
const data_type* data() const { return m_data; }
|
||||
|
||||
private:
|
||||
std::size_t m_index;
|
||||
data_type* m_data;
|
||||
};
|
||||
|
||||
using Frame = BasicFrame<false>;
|
||||
using ConstFrame = BasicFrame<true>;
|
||||
} //namespace mc::psx
|
|
@ -33,6 +33,9 @@ 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<uint8_t> m_data;
|
||||
};
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ memcard = shared_library('memcard',
|
|||
'src/content_info.cpp',
|
||||
'src/make_memory_card.cpp',
|
||||
'src/part_iterator.cpp',
|
||||
'src/frame.cpp',
|
||||
install: true,
|
||||
include_directories: [private_incl, library_incl],
|
||||
)
|
||||
|
|
|
@ -18,10 +18,12 @@ namespace {
|
|||
}
|
||||
#endif
|
||||
|
||||
std::vector<uint8_t> extract_palette (const uint8_t* b, const uint8_t* e) {
|
||||
std::vector<uint8_t> extract_palette (const ConstFrame& frame) {
|
||||
std::vector<uint8_t> retval;
|
||||
retval.reserve(16 * 4);
|
||||
|
||||
auto b = frame.cbegin();
|
||||
const auto e = frame.cend();
|
||||
{
|
||||
if (e - b < 96)
|
||||
throw std::runtime_error("Not enough data to advance and extract an icon palette");
|
||||
|
@ -86,26 +88,26 @@ template <bool Const>
|
|||
BasicBlock<Const>::~BasicBlock() = default;
|
||||
|
||||
template <bool Const>
|
||||
auto BasicBlock<Const>::frame(unsigned int idx) -> data_type* {
|
||||
return const_cast<data_type*>(const_cast<const BasicBlock<Const>*>(this)->frame(idx));
|
||||
BasicFrame<Const> BasicBlock<Const>::frame(unsigned int idx) {
|
||||
assert(idx < size());
|
||||
return {this->data() + Frame::Size * idx, idx};
|
||||
}
|
||||
|
||||
template <bool Const>
|
||||
auto BasicBlock<Const>::frame(unsigned int idx) const -> const data_type* {
|
||||
assert(idx * FrameSize + FrameSize <= this->size());
|
||||
return this->begin() + FrameSize * idx;
|
||||
ConstFrame BasicBlock<Const>::frame(unsigned int idx) const {
|
||||
assert(idx < size());
|
||||
return {this->data() + Frame::Size * idx, idx};
|
||||
}
|
||||
|
||||
template <bool Const>
|
||||
std::vector<uint8_t> BasicBlock<Const>::icon_palette() const {
|
||||
const auto ptr = frame(0);
|
||||
return extract_palette(ptr, ptr + FrameSize);
|
||||
return extract_palette(frame(0));
|
||||
}
|
||||
|
||||
template <bool Const>
|
||||
bool BasicBlock<Const>::has_magic() const {
|
||||
const constexpr uint16_t magic = ('S' << 8) | 'C'; //0x5343 "SC"
|
||||
const data_type* const ptr = frame(0);
|
||||
const data_type* const ptr = frame(0).data();
|
||||
return magic == static_cast<uint16_t>((ptr[0] << 8) | ptr[1]);
|
||||
}
|
||||
|
||||
|
@ -123,7 +125,7 @@ int BasicBlock<Const>::block_count() const {
|
|||
template <bool Const>
|
||||
std::string BasicBlock<Const>::title() const {
|
||||
char mem[64 + 1];
|
||||
std::strncpy(mem, reinterpret_cast<const char*>(frame(0) + 4), sizeof(mem) / sizeof(mem[0]));
|
||||
std::strncpy(mem, reinterpret_cast<const char*>(frame(0).data() + 4), sizeof(mem) / sizeof(mem[0]));
|
||||
std::string_view temp(mem, std::strlen(mem));
|
||||
auto name = full_to_halfwidth_ascii(shiftjis_to_utf8(temp));
|
||||
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
#include "memcard/content_info.hpp"
|
||||
#include "memcard/block.hpp"
|
||||
#include "memcard/frame.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
namespace mc::psx {
|
||||
namespace {
|
||||
template <typename T>
|
||||
T read_as (const ConstBlock& block, std::size_t offset) {
|
||||
T read_as (const ConstFrame& frame, std::size_t offset) {
|
||||
T retval;
|
||||
std::copy(
|
||||
block.begin() + offset,
|
||||
block.begin() + offset + sizeof(T),
|
||||
frame.begin() + offset,
|
||||
frame.begin() + offset + sizeof(T),
|
||||
reinterpret_cast<uint8_t*>(&retval)
|
||||
);
|
||||
return retval;
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
ContentInfo::ContentInfo (const ConstBlock& block) :
|
||||
use_byte(read_as<uint32_t>(block, 0x84)),
|
||||
magic(read_as<uint16_t>(block, 0x00)),
|
||||
ContentInfo::ContentInfo (const ConstFrame& frame) :
|
||||
use_byte(read_as<uint32_t>(frame, 0x84)),
|
||||
magic(read_as<uint16_t>(frame, 0x00)),
|
||||
available_blocks(BlockContent::Available)
|
||||
{
|
||||
auto block_content = read_as<uint8_t>(block, 0x80);
|
||||
auto block_content = read_as<uint8_t>(frame, 0x80);
|
||||
switch (block_content & 0xf) {
|
||||
case 0x0:
|
||||
available_blocks = BlockContent::Available;
|
||||
|
|
26
subprojects/memcard/src/frame.cpp
Normal file
26
subprojects/memcard/src/frame.cpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
#include "memcard/frame.hpp"
|
||||
#include <cassert>
|
||||
|
||||
namespace mc::psx {
|
||||
template <bool Const>
|
||||
BasicFrame<Const>::BasicFrame (data_type* data, std::size_t index) :
|
||||
m_index(index),
|
||||
m_data(data)
|
||||
{
|
||||
}
|
||||
|
||||
template <bool Const>
|
||||
auto BasicFrame<Const>::operator[] (std::size_t index) -> data_type& {
|
||||
assert(index < size());
|
||||
return m_data[index];
|
||||
}
|
||||
|
||||
template <bool Const>
|
||||
auto BasicFrame<Const>::operator[] (std::size_t index) const -> const data_type& {
|
||||
assert(index < size());
|
||||
return m_data[index];
|
||||
}
|
||||
|
||||
template class BasicFrame<true>;
|
||||
template class BasicFrame<false>;
|
||||
} //namespace mc::psx
|
|
@ -164,7 +164,7 @@ std::vector<std::vector<char>> icon_fetch (const psx::ConstBlock& block, int wid
|
|||
orig_rgb.resize(in_scan_sz * in_height);
|
||||
for (int y = 0; y < in_height; ++y) {
|
||||
for (int x = 0; x < in_width / 2; ++x) {
|
||||
const uint8_t curr = *(block.frame(1 + icon_num) + (in_width / 2 * y) + x);
|
||||
const uint8_t curr = *(block.frame(1 + icon_num).data() + (in_width / 2 * y) + x);
|
||||
orig_rgb[y * in_scan_sz + x] = ((curr bitand 0xf0) >> 4) bitor ((curr bitand 0x0f) << 4);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "memcard/memorycard.hpp"
|
||||
#include "memcard/block.hpp"
|
||||
#include "memcard/frame.hpp"
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
|
||||
|
@ -17,16 +18,16 @@ MemoryCard::~MemoryCard() = default;
|
|||
|
||||
Block MemoryCard::operator[] (std::size_t index) {
|
||||
assert(index < 15);
|
||||
return Block(m_data.data() + (index + 1) * Block::size(), index);
|
||||
return block_at_index(index + 1);
|
||||
}
|
||||
|
||||
ConstBlock MemoryCard::operator[] (std::size_t index) const {
|
||||
assert(index < 15);
|
||||
return ConstBlock(m_data.data() + (index + 1) * Block::size(), index);
|
||||
return block_at_index(index + 1);
|
||||
}
|
||||
|
||||
ContentInfo MemoryCard::content_info() const {
|
||||
return {ConstBlock(m_data.data(), ConstBlock::ToCBlockIndex)};
|
||||
return {block_at_index(0).frame(0)};
|
||||
}
|
||||
|
||||
std::size_t MemoryCard::size() const {
|
||||
|
@ -61,6 +62,14 @@ auto MemoryCard::end() const -> const_iterator {
|
|||
return const_iterator(this, size());
|
||||
}
|
||||
|
||||
Block MemoryCard::block_at_index(std::size_t index) {
|
||||
return Block(m_data.data() + index * Block::size() * Frame::size(), index);
|
||||
}
|
||||
|
||||
ConstBlock MemoryCard::block_at_index(std::size_t index) const {
|
||||
return ConstBlock(m_data.data() + index * Block::size() * Frame::size(), index);
|
||||
}
|
||||
|
||||
std::vector<std::size_t> block_group (const MemoryCard& mc, std::size_t index) {
|
||||
std::vector<std::size_t> retval;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue