Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 85 additions & 77 deletions src/open_viii/graphics/BPPT.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,94 +20,94 @@ namespace open_viii::graphics {
* \ingroup graphics
* @brief Contains 4 to 24 bits per pixel flags. Also a CLP flag for color
* lookup table.
* @note Lack of documentation on mixed_format but from what I understand
* neither of the bpp8 or bpp16 bits are set. And the color lookup table might
* be used.
*/
struct BPPT
{
private:
mutable bool m_bpp8 : 1 { false };
mutable bool m_bpp16 : 1 { false };
/**
* might be used sometimes. for some files. I think it could be for multi
* format
*/
mutable bool m_unused1 : 1 { false };
mutable bool m_color_lookup_table_present : 1 { false };
bool m_unused2 : 1 { false };
bool m_unused3 : 1 { false };
bool m_unused4 : 1 { false };
bool m_unused5 : 1 { false };
constexpr static auto RAW8_VALUE = 0b1U;
constexpr static auto RAW16_VALUE = 0b10U;
constexpr static auto CLP_VALUE = 0b1000U;
bool m_bpp8 : 1 { false };
bool m_bpp16 : 1 { false };
bool m_mixed_format : 1 { false };
bool m_color_lookup_table_present : 1 { false };
bool m_unused2 : 1 { false };
bool m_unused3 : 1 { false };
bool m_unused4 : 1 { false };
bool m_unused5 : 1 { false };
enum : std::uint8_t {
RAW8_VALUE = 0b1U,
RAW16_VALUE = 0b10U,
MIXED_VALUE = 0b100U,
CLP_VALUE = 0b1000U
};
constexpr BPPT(bool bpp8, bool bpp16, bool color_lookup_table_present)
: m_bpp8(bpp8),
m_bpp16(bpp16),
m_color_lookup_table_present(color_lookup_table_present)
{}

public:
constexpr static auto BPP4 = 4U;
constexpr static auto BPP8 = 8U;
constexpr static auto BPP16 = 16U;
constexpr static auto BPP24 = 24U;
// consteval friend BPPT operator"" _bpp(unsigned long long int value);
auto operator<=>(const BPPT &) const = default;
[[nodiscard]] constexpr bool unused() const noexcept
{
return m_unused1 && m_unused2 && m_unused3 && m_unused4 && m_unused5;
constexpr BPPT() = default;
enum : unsigned int {
BPP4 = 4U,
BPP8 = 8U,
BPP16 = 16U,
BPP24 = 24U,
};
auto operator<=>(const BPPT &) const = default;
[[nodiscard]] constexpr bool
unused() const noexcept
{
return m_mixed_format && m_unused2 && m_unused3 && m_unused4 && m_unused5;
}
/**
* Test bits to check if color lookup table is present and 8bpp and 16bpp are
* not set;
* @return true if 4bpp
*/
constexpr void bpp4(bool in) const noexcept
static constexpr BPPT
as_bpp4() noexcept
{
if (in) {
m_bpp8 = false;
m_bpp16 = false;
m_color_lookup_table_present = true;
}
return BPPT(false, false, true);
}
/**
* Test bits to check if color lookup table is present and 8bpp is set and
* 16bpp is not set;
* @return true if 8bpp
*/
constexpr void bpp8(bool in) const
static constexpr BPPT
as_bpp8() noexcept
{
if (in) {
m_bpp8 = true;
m_bpp16 = false;
m_color_lookup_table_present = true;
}
return BPPT(true, false, true);
}
/**
* Test bits to check if color lookup table is not present and 8bpp is not set
* and 16bpp is set;
* @return true if 16bpp
*/
constexpr void bpp16(bool in) const
static constexpr BPPT
as_bpp16() noexcept
{
if (in) {
m_bpp8 = false;
m_bpp16 = true;
m_color_lookup_table_present = false;
}
return BPPT(false, true, false);
}
/**
* Test bits to check if color lookup table is not present and 8bpp is set and
* 16bpp is set;
* @return true if 24bpp
*/
constexpr void bpp24(bool in) const
static constexpr BPPT
as_bpp24() noexcept
{
if (in) {
m_bpp8 = true;
m_bpp16 = true;
m_color_lookup_table_present = false;
}
return BPPT(true, true, false);
}
/**
* Test bits to check if color lookup table is present and 8bpp and 16bpp are
* not set;
* @return true if 4bpp
*/
[[nodiscard]] constexpr bool bpp4() const noexcept
[[nodiscard]] constexpr bool
bpp4() const noexcept
{
return !unused() && !m_bpp8 && !m_bpp16 && m_color_lookup_table_present;
}
Expand All @@ -116,7 +116,8 @@ struct BPPT
* 16bpp is not set;
* @return true if 8bpp
*/
[[nodiscard]] constexpr bool bpp8() const noexcept
[[nodiscard]] constexpr bool
bpp8() const noexcept
{
return !unused() && m_bpp8 && !m_bpp16 && m_color_lookup_table_present;
}
Expand All @@ -125,7 +126,8 @@ struct BPPT
* and 16bpp is set;
* @return true if 16bpp
*/
[[nodiscard]] constexpr bool bpp16() const noexcept
[[nodiscard]] constexpr bool
bpp16() const noexcept
{
return !unused() && !m_bpp8 && m_bpp16 && !m_color_lookup_table_present;
}
Expand All @@ -134,7 +136,8 @@ struct BPPT
* 16bpp is set;
* @return true if 24bpp
*/
[[nodiscard]] constexpr bool bpp24() const noexcept
[[nodiscard]] constexpr bool
bpp24() const noexcept
{
return !unused() && m_bpp8 && m_bpp16 && !m_color_lookup_table_present;
}
Expand All @@ -143,25 +146,26 @@ struct BPPT
* 16bpp is not set;
* @return true if 16bpp
*/
[[nodiscard]] constexpr bool color_lookup_table_present() const
[[nodiscard]] constexpr bool
color_lookup_table_present() const
{
return !unused() && !m_bpp16 && m_color_lookup_table_present;
}
/**
* Test that one of the valid states is true.
* @return true if is a valid state.
*/
[[nodiscard]] constexpr bool check() const noexcept
[[nodiscard]] constexpr bool
check() const noexcept
{
return bpp4() || bpp8() || bpp16() || bpp24();
}
[[nodiscard]] constexpr explicit operator bool() const noexcept
{
return check();
}
[[nodiscard]] constexpr explicit operator int() const
[[nodiscard]] constexpr explicit operator char() const
{
//[[maybe_unused]] static constexpr auto size_ = sizeof(BPPT);
if (bpp4()) {
return BPP4;
}
Expand All @@ -176,22 +180,32 @@ struct BPPT
}
return 0;
}
// _4bpp = 0b0U, /**< is coded as std::uint8_t of value 0. 4 bits per per
// pixel */ _8bpp = 0b1U, /**< is coded as std::uint8_t of value 1. 8 bits
// per per pixel */ _16bpp = 0b10U, /**< is coded as std::uint8_t of value 2.
// 16 bits per per pixel */ _24bpp = _8bpp | _16bpp, /**< is coded as
// std::uint8_t of value 3. 24 bits per per pixel */ CLP = 0b1000, /**< is
// coded as std::uint8_t of value 8. CLP flag for color lookup table present.
// This is required for
// 4bpp and 8bpp. */
constexpr std::uint8_t raw() const noexcept
[[nodiscard]] constexpr explicit operator int() const
{
return static_cast<int>(operator char());
}
/**
* _4bpp = 0b0U, is coded as std::uint8_t of value 0. 4 bits per per
pixel
_8bpp = 0b1U, is coded as std::uint8_t of value 1. 8 bits
per per pixel
_16bpp = 0b10U, is coded as std::uint8_t of value 2.
16 bits per per pixel
_24bpp = _8bpp | _16bpp, is coded as
std::uint8_t of value 3. 24 bits per per pixel
CLP = 0b1000U, is
coded as std::uint8_t of value 8. CLP flag for color lookup table present.
This is required for 4bpp and 8bpp.
*/
constexpr std::uint8_t
raw() const noexcept
{
return static_cast<std::uint8_t>(
(m_bpp8 ? RAW8_VALUE : 0U) + (m_bpp16 ? RAW16_VALUE : 0U)
+ (m_color_lookup_table_present ? CLP_VALUE : 0U));
}
friend std::ostream &operator<<(std::ostream & os,
[[maybe_unused]] const BPPT &input)
friend std::ostream &
operator<<(std::ostream &os, [[maybe_unused]] const BPPT &input)
{
return os << "{BPP: " << static_cast<int>(input)
<< ", CLP: " << input.m_color_lookup_table_present << '}';
Expand All @@ -200,22 +214,16 @@ struct BPPT
namespace literals {
consteval BPPT operator""_bpp(unsigned long long int value)
{
BPPT r{};
switch (value) {
case BPPT::BPP4:
r.bpp4(true);
break;
return BPPT::as_bpp4();
case BPPT::BPP8:
r.bpp8(true);
break;
return BPPT::as_bpp8();
case BPPT::BPP16:
r.bpp16(true);
break;
return BPPT::as_bpp16();
case BPPT::BPP24:
r.bpp24(true);
break;
return BPPT::as_bpp24();
}
return r;
}
}// namespace literals
static_assert(sizeof(BPPT) == 1U);
Expand Down
54 changes: 29 additions & 25 deletions src/open_viii/graphics/One.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,48 @@
//
#ifndef VIIIARCHIVE_ONE_HPP
#define VIIIARCHIVE_ONE_HPP
#include "BPPT.hpp"
#include "Mch.hpp"
#include "one/OneModel.hpp"
namespace open_viii::graphics {
/**
* @note world\esk\chara.one has 16 tim files
*/
struct One
constexpr auto
get_tim_header_start(const BPPT bpp)
{
return std::array<char, 5U>{ 0x10, 0x0, 0x0, 0x0, static_cast<char>(bpp) };
}
constexpr auto get_time_header_starts()
{
private:
std::vector<char> m_buffer{};
std::uint32_t m_count{};
static constexpr auto SIZE_TIM_START = 5U;
/**
* 4 bit color tim.
*/
static constexpr std::string_view TIM4_START{ "\x10\x00\x00\x00\x08",
SIZE_TIM_START };
constexpr auto TIM4_START = get_tim_header_start(BPPT::as_bpp4());
/**
* 8 bit color tim.
*/
static constexpr std::string_view TIM8_START{ "\x10\x00\x00\x00\x09",
SIZE_TIM_START };
constexpr auto TIM8_START = get_tim_header_start(BPPT::as_bpp8());
/**
* 16 bit color tim.
*/
static constexpr std::string_view TIM16_START{ "\x10\x00\x00\x00\x02",
SIZE_TIM_START };
constexpr auto TIM16_START = get_tim_header_start(BPPT::as_bpp16());
/**
* 24 bit color tim.
*/
static constexpr std::string_view TIM24_START{ "\x10\x00\x00\x00\x03",
SIZE_TIM_START };
static_assert(std::ranges::size(TIM4_START) == SIZE_TIM_START);
static_assert(std::ranges::size(TIM8_START) == SIZE_TIM_START);
static_assert(std::ranges::size(TIM16_START) == SIZE_TIM_START);
static_assert(std::ranges::size(TIM24_START) == SIZE_TIM_START);
static constexpr std::array TIM_STARTS{
constexpr auto TIM24_START = get_tim_header_start(BPPT::as_bpp24());
return std::array{
TIM4_START, TIM8_START, TIM16_START, TIM24_START
};
auto get_next_offset(const std::span<const char> &buffer) const
}
/**
* @note world\esk\chara.one has 16 tim files
*/
struct One
{
private:
std::vector<char> m_buffer{};
std::uint32_t m_count{};
static constexpr auto TIM_STARTS = get_time_header_starts();
auto
get_next_offset(const std::span<const char> &buffer) const
{
// could be a coroutine using std::generator
// because these tim can be in any order.
Expand All @@ -57,7 +59,7 @@ struct One
{
buffer = std::span<const char>(offset, std::ranges::end(buffer));
const Tim tim = Tim(buffer);
buffer = buffer.subspan(SIZE_TIM_START);
buffer = buffer.subspan(std::ranges::size(TIM_STARTS.front()));
return tim;
}

Expand All @@ -66,7 +68,8 @@ struct One
: m_buffer(std::move(buffer)),
m_count(tools::read_val<std::uint32_t>(m_buffer))
{}
bool save_tim(const std::string &path, const size_t i, const Tim &tim) const
bool
save_tim(const std::string &path, const size_t i, const Tim &tim) const
{
if (tim) {
auto path_parts = std::filesystem::path(path);
Expand All @@ -79,7 +82,8 @@ struct One
}
return false;
}
void save([[maybe_unused]] const std::string &path) const
void
save([[maybe_unused]] const std::string &path) const
{
// todo make this generic, extract tim file code to a free function.
size_t i{};
Expand Down
7 changes: 4 additions & 3 deletions src/open_viii/graphics/Tim.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ namespace open_viii::graphics {
* @see https://github.com/myst6re/deling/blob/master/FF8Image.cpp#L30
* @see http://www.raphnet.net/electronique/psx_adaptor/Playstation.txt
* @see http://www.psxdev.net/forum/viewtopic.php?t=109
* @see https://mrclick.zophar.net/TilEd/download/timgfx.txt
* @see http://www.elisanet.fi/6581/PSX/doc/Playstation_Hardware.pdf
* @see http://www.elisanet.fi/6581/PSX/doc/psx.pdf
* @see http://www.elisanet.fi/6581/PSX/doc/Playstation_Hardware.pdf // link has died
* @see https://retrocdn.net/File:PlayStation_Hardware.pdf
* @see http://www.elisanet.fi/6581/PSX/doc/psx.pdf // link has died
* @see https://gamehacking.org/faqs/PSX.pdf
* @see http://www.romhacking.net/documents/31/
* @see http://mrclick.zophar.net/TilEd/download/timgfx.txt
* @see http://fileformats.archiveteam.org/wiki/TIM_(PlayStation_graphics)
Expand Down