Add new BasicFrame class.

This commit is contained in:
King_DuckZ 2020-03-20 16:21:17 +01:00
parent 4eaa2fc734
commit db70dead33
11 changed files with 115 additions and 38 deletions

View file

@ -19,7 +19,7 @@ void print_blocks (const std::string& mc_path) {
for (const auto& blk : mc) { for (const auto& blk : mc) {
if (blk.has_magic()) { 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() << '"'; << ": \"" << blk.title() << '"';
if (blk.block_count() > 1) { if (blk.block_count() > 1) {
std::cout << " [" << blk.block_count() << ']'; std::cout << " [" << blk.block_count() << ']';

View file

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "memcard/frame.hpp"
#include <cstdint> #include <cstdint>
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
@ -20,26 +21,22 @@ enum class IconDisplayFlag {
template <bool Const> template <bool Const>
class BasicBlock { class BasicBlock {
public:
using data_type = typename std::conditional<Const, const uint8_t, uint8_t>::type; 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 FrameCount = 64;
static const constexpr std::size_t ToCBlockIndex = 0xff; static const constexpr std::size_t TOCBlockIndex = 0;
BasicBlock (data_type* beg, std::size_t index); BasicBlock (data_type* beg, std::size_t index);
~BasicBlock(); ~BasicBlock();
data_type* begin() { return m_begin; } data_type* data() { return m_begin; }
data_type* end() { return m_begin + size(); } const data_type* data() const { return m_begin; }
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); BasicFrame<Const> frame(unsigned int idx);
const data_type* frame(unsigned int idx) const; 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; std::vector<uint8_t> icon_palette() const;
bool has_magic() const; bool has_magic() const;

View file

@ -3,8 +3,8 @@
#include <cstdint> #include <cstdint>
namespace mc::psx { namespace mc::psx {
template <bool Const> class BasicBlock; template <bool Const> class BasicFrame;
using ConstBlock = BasicBlock<true>; using ConstFrame = BasicFrame<true>;
enum class BlockContent : uint8_t { enum class BlockContent : uint8_t {
Available = 0xA0, Available = 0xA0,
@ -15,7 +15,7 @@ enum class BlockContent : uint8_t {
}; };
struct ContentInfo { struct ContentInfo {
ContentInfo (const ConstBlock& block); ContentInfo (const ConstFrame& block);
uint32_t use_byte; uint32_t use_byte;
uint16_t magic; uint16_t magic;

View 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

View file

@ -33,6 +33,9 @@ public:
const_iterator end() const; const_iterator end() const;
private: private:
Block block_at_index(std::size_t index);
ConstBlock block_at_index(std::size_t index) const;
std::vector<uint8_t> m_data; std::vector<uint8_t> m_data;
}; };

View file

@ -14,6 +14,7 @@ memcard = shared_library('memcard',
'src/content_info.cpp', 'src/content_info.cpp',
'src/make_memory_card.cpp', 'src/make_memory_card.cpp',
'src/part_iterator.cpp', 'src/part_iterator.cpp',
'src/frame.cpp',
install: true, install: true,
include_directories: [private_incl, library_incl], include_directories: [private_incl, library_incl],
) )

View file

@ -18,10 +18,12 @@ namespace {
} }
#endif #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; std::vector<uint8_t> retval;
retval.reserve(16 * 4); retval.reserve(16 * 4);
auto b = frame.cbegin();
const auto e = frame.cend();
{ {
if (e - b < 96) if (e - b < 96)
throw std::runtime_error("Not enough data to advance and extract an icon palette"); 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; BasicBlock<Const>::~BasicBlock() = default;
template <bool Const> template <bool Const>
auto BasicBlock<Const>::frame(unsigned int idx) -> data_type* { BasicFrame<Const> BasicBlock<Const>::frame(unsigned int idx) {
return const_cast<data_type*>(const_cast<const BasicBlock<Const>*>(this)->frame(idx)); assert(idx < size());
return {this->data() + Frame::Size * idx, idx};
} }
template <bool Const> template <bool Const>
auto BasicBlock<Const>::frame(unsigned int idx) const -> const data_type* { ConstFrame BasicBlock<Const>::frame(unsigned int idx) const {
assert(idx * FrameSize + FrameSize <= this->size()); assert(idx < size());
return this->begin() + FrameSize * idx; return {this->data() + Frame::Size * idx, idx};
} }
template <bool Const> template <bool Const>
std::vector<uint8_t> BasicBlock<Const>::icon_palette() const { std::vector<uint8_t> BasicBlock<Const>::icon_palette() const {
const auto ptr = frame(0); return extract_palette(frame(0));
return extract_palette(ptr, ptr + FrameSize);
} }
template <bool Const> template <bool Const>
bool BasicBlock<Const>::has_magic() const { bool BasicBlock<Const>::has_magic() const {
const constexpr uint16_t magic = ('S' << 8) | 'C'; //0x5343 "SC" 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]); return magic == static_cast<uint16_t>((ptr[0] << 8) | ptr[1]);
} }
@ -123,7 +125,7 @@ int BasicBlock<Const>::block_count() const {
template <bool Const> template <bool Const>
std::string BasicBlock<Const>::title() const { std::string BasicBlock<Const>::title() const {
char mem[64 + 1]; 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)); std::string_view temp(mem, std::strlen(mem));
auto name = full_to_halfwidth_ascii(shiftjis_to_utf8(temp)); auto name = full_to_halfwidth_ascii(shiftjis_to_utf8(temp));

View file

@ -1,27 +1,27 @@
#include "memcard/content_info.hpp" #include "memcard/content_info.hpp"
#include "memcard/block.hpp" #include "memcard/frame.hpp"
#include <algorithm> #include <algorithm>
namespace mc::psx { namespace mc::psx {
namespace { namespace {
template <typename T> 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; T retval;
std::copy( std::copy(
block.begin() + offset, frame.begin() + offset,
block.begin() + offset + sizeof(T), frame.begin() + offset + sizeof(T),
reinterpret_cast<uint8_t*>(&retval) reinterpret_cast<uint8_t*>(&retval)
); );
return retval; return retval;
} }
} //unnamed namespace } //unnamed namespace
ContentInfo::ContentInfo (const ConstBlock& block) : ContentInfo::ContentInfo (const ConstFrame& frame) :
use_byte(read_as<uint32_t>(block, 0x84)), use_byte(read_as<uint32_t>(frame, 0x84)),
magic(read_as<uint16_t>(block, 0x00)), magic(read_as<uint16_t>(frame, 0x00)),
available_blocks(BlockContent::Available) 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) { switch (block_content & 0xf) {
case 0x0: case 0x0:
available_blocks = BlockContent::Available; available_blocks = BlockContent::Available;

View 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

View file

@ -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); orig_rgb.resize(in_scan_sz * in_height);
for (int y = 0; y < in_height; ++y) { for (int y = 0; y < in_height; ++y) {
for (int x = 0; x < in_width / 2; ++x) { 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); orig_rgb[y * in_scan_sz + x] = ((curr bitand 0xf0) >> 4) bitor ((curr bitand 0x0f) << 4);
} }
} }

View file

@ -1,5 +1,6 @@
#include "memcard/memorycard.hpp" #include "memcard/memorycard.hpp"
#include "memcard/block.hpp" #include "memcard/block.hpp"
#include "memcard/frame.hpp"
#include <iterator> #include <iterator>
#include <cassert> #include <cassert>
@ -17,16 +18,16 @@ MemoryCard::~MemoryCard() = default;
Block MemoryCard::operator[] (std::size_t index) { Block MemoryCard::operator[] (std::size_t index) {
assert(index < 15); 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 { ConstBlock MemoryCard::operator[] (std::size_t index) const {
assert(index < 15); assert(index < 15);
return ConstBlock(m_data.data() + (index + 1) * Block::size(), index); return block_at_index(index + 1);
} }
ContentInfo MemoryCard::content_info() const { 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 { std::size_t MemoryCard::size() const {
@ -61,6 +62,14 @@ auto MemoryCard::end() const -> const_iterator {
return const_iterator(this, size()); 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> block_group (const MemoryCard& mc, std::size_t index) {
std::vector<std::size_t> retval; std::vector<std::size_t> retval;