load param.sfo

This commit is contained in:
InoriRus
2022-05-31 16:18:55 +10:00
parent 50b54b2607
commit 877560b7f6
54 changed files with 10562 additions and 245 deletions
@@ -0,0 +1,312 @@
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_COLOR_H_
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_COLOR_H_
#include "Kyty/Core/Common.h"
#include "Kyty/Math/MathAll.h"
#include "Emulator/Common.h"
#ifdef KYTY_EMU_ENABLED
namespace Kyty::Libs::Graphics {
using rgba32_t = uint32_t;
struct ColorHsv
{
explicit ColorHsv(float h = 0.0f, float s = 0.0f, float v = 0.0f): H(h), S(s), V(v) {}
float H; /*NOLINT(readability-identifier-naming)*/ // [0..360]
float S; /*NOLINT(readability-identifier-naming)*/ // [0..1]
float V; /*NOLINT(readability-identifier-naming)*/ // [0..1]
};
constexpr float COLOR_LAB_L_MIN = (0.0f);
constexpr float COLOR_LAB_L_MAX = (100.0f);
constexpr float COLOR_LAB_A_MIN = (-128.0f);
constexpr float COLOR_LAB_A_MAX = (+127.0f);
constexpr float COLOR_LAB_B_MIN = (-128.0f);
constexpr float COLOR_LAB_B_MAX = (+127.0f);
using lab64_t = uint64_t;
constexpr lab64_t COLOR_LAB_L_BITS = 16u;
constexpr lab64_t COLOR_LAB_A_BITS = 16u;
constexpr lab64_t COLOR_LAB_B_BITS = 16u;
constexpr lab64_t COLOR_LAB_L_MASK = ((static_cast<lab64_t>(1) << (COLOR_LAB_L_BITS)) - static_cast<lab64_t>(1));
constexpr lab64_t COLOR_LAB_A_MASK = ((static_cast<lab64_t>(1) << (COLOR_LAB_A_BITS)) - static_cast<lab64_t>(1));
constexpr lab64_t COLOR_LAB_B_MASK = ((static_cast<lab64_t>(1) << (COLOR_LAB_B_BITS)) - static_cast<lab64_t>(1));
struct ColorLab
{
ColorLab() = default;
ColorLab(float l, float a, float b): L(l), A(a), B(b) {}
float L = 0; /*NOLINT(readability-identifier-naming)*/ // [COLOR_LAB_L_MIN..COLOR_LAB_L_MAX]
float A = 0; /*NOLINT(readability-identifier-naming)*/ // [COLOR_LAB_A_MIN..COLOR_LAB_A_MAX]
float B = 0; /*NOLINT(readability-identifier-naming)*/ // [COLOR_LAB_B_MIN..COLOR_LAB_B_MAX]
explicit ColorLab(lab64_t lab32)
: ColorLab((static_cast<float>((lab32 >> (0u)) & COLOR_LAB_L_MASK) / static_cast<float>(COLOR_LAB_L_MASK)) *
(COLOR_LAB_L_MAX - COLOR_LAB_L_MIN) +
COLOR_LAB_L_MIN,
(static_cast<float>((lab32 >> (COLOR_LAB_L_BITS)) & COLOR_LAB_A_MASK) / static_cast<float>(COLOR_LAB_A_MASK)) *
(COLOR_LAB_A_MAX - COLOR_LAB_A_MIN) +
COLOR_LAB_A_MIN,
(static_cast<float>((lab32 >> (COLOR_LAB_L_BITS + COLOR_LAB_A_BITS)) & COLOR_LAB_B_MASK) /
static_cast<float>(COLOR_LAB_B_MASK)) *
(COLOR_LAB_B_MAX - COLOR_LAB_B_MIN) +
COLOR_LAB_B_MIN)
{
}
[[nodiscard]] lab64_t ToLab64() const
{
auto l = static_cast<int64_t>(
Math::math_round(static_cast<float>(COLOR_LAB_L_MASK) * ((L - COLOR_LAB_L_MIN) / (COLOR_LAB_L_MAX - COLOR_LAB_L_MIN))));
if (l < 0)
{
l = 0;
}
if (l > static_cast<int64_t>(COLOR_LAB_L_MASK))
{
l = static_cast<int64_t>(COLOR_LAB_L_MASK);
}
auto a = static_cast<int64_t>(
Math::math_round(static_cast<float>(COLOR_LAB_A_MASK) * ((A - COLOR_LAB_A_MIN) / (COLOR_LAB_A_MAX - COLOR_LAB_A_MIN))));
if (a < 0)
{
a = 0;
}
if (a > static_cast<int64_t>(COLOR_LAB_A_MASK))
{
a = static_cast<int64_t>(COLOR_LAB_A_MASK);
}
auto b = static_cast<int64_t>(
Math::math_round(static_cast<float>(COLOR_LAB_B_MASK) * ((B - COLOR_LAB_B_MIN) / (COLOR_LAB_B_MAX - COLOR_LAB_B_MIN))));
if (b < 0)
{
b = 0;
}
if (b > static_cast<int64_t>(COLOR_LAB_B_MASK))
{
b = static_cast<int64_t>(COLOR_LAB_B_MASK);
}
return (static_cast<lab64_t>(l) << 0u) | (static_cast<lab64_t>(a) << (COLOR_LAB_L_BITS)) |
(static_cast<lab64_t>(b) << (COLOR_LAB_L_BITS + COLOR_LAB_A_BITS));
}
[[nodiscard]] float Distance(const ColorLab& other) const
{
float d1 = L - other.L;
float d2 = A - other.A;
float d3 = B - other.B;
return sqrtf(d1 * d1 + d2 * d2 + d3 * d3);
}
bool operator==(const ColorLab& c) const { return (L == c.L && A == c.A && B == c.B); }
bool operator!=(const ColorLab& c) const { return (L != c.L || A != c.A || B != c.B); }
void Clip();
};
struct ColorXyz
{
float X; /*NOLINT(readability-identifier-naming)*/
float Y; /*NOLINT(readability-identifier-naming)*/
float Z; /*NOLINT(readability-identifier-naming)*/
[[nodiscard]] float Distance(const ColorXyz& other) const
{
float d1 = X - other.X;
float d2 = Y - other.Y;
float d3 = Z - other.Z;
return sqrtf(d1 * d1 + d2 * d2 + d3 * d3);
}
};
inline rgba32_t Rgb(int r, int g, int b, int a = 255)
{
return (static_cast<uint32_t>(r) << 0u) | (static_cast<uint32_t>(g) << 8u) | (static_cast<uint32_t>(b) << 16u) |
(static_cast<uint32_t>(a) << 24u);
}
inline int RgbToRed(rgba32_t c)
{
return static_cast<int>(c & 0xffU);
}
inline int RgbToGreen(rgba32_t c)
{
return static_cast<int>((c >> 8u) & 0xffU);
}
inline int RgbToBlue(rgba32_t c)
{
return static_cast<int>((c >> 16u) & 0xffU);
}
inline int RgbToAlpha(rgba32_t c)
{
return static_cast<int>((c >> 24u) & 0xffU);
}
inline float RgbDistance(rgba32_t a, rgba32_t b)
{
int dr = RgbToRed(a) - RgbToRed(b);
int dg = RgbToGreen(a) - RgbToGreen(b);
int db = RgbToBlue(a) - RgbToBlue(b);
return sqrtf(static_cast<float>(dr * dr + dg * dg + db * db));
}
class Color final
{
public:
Color() = default;
~Color() = default;
Color(float r, float g, float b, float a = 1.0f): m_v(r, g, b, a) {}
explicit Color(const vec4& av): m_v(av) {}
KYTY_CLASS_DEFAULT_COPY(Color);
static Color FromRgb(int r, int g, int b, int a = 255)
{
return {static_cast<float>(r) / 255.0f, static_cast<float>(g) / 255.0f, static_cast<float>(b) / 255.0f,
static_cast<float>(a) / 255.0f};
}
explicit Color(rgba32_t rgba32)
: m_v(static_cast<float>((rgba32 >> 0u) & 0xffU) / 255.0f, static_cast<float>((rgba32 >> 8u) & 0xffU) / 255.0f,
static_cast<float>((rgba32 >> 16u) & 0xffU) / 255.0f, static_cast<float>((rgba32 >> 24u) & 0xffU) / 255.0f)
{
}
[[nodiscard]] rgba32_t ToRgba32() const
{
return (static_cast<uint32_t>(Red()) << 0u) | (static_cast<uint32_t>(Green()) << 8u) | (static_cast<uint32_t>(Blue()) << 16u) |
(static_cast<uint32_t>(Alpha()) << 24u);
}
[[nodiscard]] ColorXyz ToXyz() const;
[[nodiscard]] ColorLab ToLab() const;
[[nodiscard]] Color ToLinear() const;
[[nodiscard]] Color ToAdobeRGB() const;
void ToHcl(float* h, float* c, float* l) const;
[[nodiscard]] ColorHsv ToHsv() const;
[[nodiscard]] Color AlphaBlendOver(const Color& bg) const
{
return {m_v.r * m_v.a + bg.m_v.r * (1.0f - m_v.a), m_v.g * m_v.a + bg.m_v.g * (1.0f - m_v.a),
m_v.b * m_v.a + bg.m_v.b * (1.0f - m_v.a), 1.0f};
}
static Color FromLab(const ColorLab& l);
static Color FromXyz(const ColorXyz& l);
static Color FromLinear(const Color& l);
static Color FromAdobeRGB(const Color& c);
static Color FromHsl(float h, float s, float l, float a = 1.0f);
static Color FromHsv(const ColorHsv& l);
static Color Black() { return FromRgb(0, 0, 0); }
static Color White() { return FromRgb(255, 255, 255); }
void Clip();
[[nodiscard]] bool InGamut() const;
[[nodiscard]] float Distance(const Color& other) const
{
float d1 = m_v.x - other.m_v.x;
float d2 = m_v.y - other.m_v.y;
float d3 = m_v.z - other.m_v.z;
return sqrtf(d1 * d1 + d2 * d2 + d3 * d3);
}
[[nodiscard]] uint8_t Red() const
{
int t = static_cast<int>(Math::math_round(m_v.r * 255.0f));
if (t < 0)
{
t = 0;
}
if (t > 255)
{
t = 255;
}
return t;
}
[[nodiscard]] uint8_t Green() const
{
int t = static_cast<int>(Math::math_round(m_v.g * 255.0f));
if (t < 0)
{
t = 0;
}
if (t > 255)
{
t = 255;
}
return t;
}
[[nodiscard]] uint8_t Blue() const
{
int t = static_cast<int>(Math::math_round(m_v.b * 255.0f));
if (t < 0)
{
t = 0;
}
if (t > 255)
{
t = 255;
}
return t;
}
[[nodiscard]] uint8_t Alpha() const
{
int t = static_cast<int>(Math::math_round(m_v.a * 255.0f));
if (t < 0)
{
t = 0;
}
if (t > 255)
{
t = 255;
}
return t;
}
[[nodiscard]] bool IsBlack() const { return (m_v.r == 0.0f && m_v.g == 0.0f && m_v.b == 0.0f); }
[[nodiscard]] bool IsWhite() const { return (m_v.r == 1.0f && m_v.g == 1.0f && m_v.b == 1.0f); }
[[nodiscard]] vec3 Rgb() const { return m_v.Rgb(); }
[[nodiscard]] vec4 Rgba() const { return m_v; }
[[nodiscard]] const float& R() const { return m_v.r; }
[[nodiscard]] const float& G() const { return m_v.g; }
[[nodiscard]] const float& B() const { return m_v.b; }
[[nodiscard]] const float& A() const { return m_v.a; }
float& R() { return m_v.r; }
float& G() { return m_v.g; }
float& B() { return m_v.b; }
float& A() { return m_v.a; }
friend bool operator==(const Color& v1, const Color& v2) { return v1.m_v == v2.m_v; }
friend bool operator!=(const Color& v1, const Color& v2) { return v1.m_v != v2.m_v; }
private:
vec4 m_v;
};
} // namespace Kyty::Libs::Graphics
using Color = Kyty::Libs::Graphics::Color;
#endif // KYTY_EMU_ENABLED
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_COLOR_H_ */
@@ -0,0 +1,86 @@
#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_IMAGE_H_
#define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_IMAGE_H_
#include "Kyty/Core/Common.h"
#include "Kyty/Core/String.h"
#include "Kyty/Math/MathAll.h"
#include "Emulator/Common.h"
#include "Emulator/Graphics/Color.h"
#ifdef KYTY_EMU_ENABLED
namespace Kyty::Libs::Graphics {
enum class ImageOrder
{
Unknown,
Rgb,
Rgba,
Argb,
Bgr,
Bgra,
Abgr,
Alpha
};
class ImagePrivate;
class Image
{
public:
explicit Image(const String& name);
virtual ~Image();
[[nodiscard]] Image* Clone() const;
void LoadSdl(void* sdl);
void Load();
void Load(const String& file_name);
void Save(const String& file_name) const;
[[nodiscard]] const String& GetName() const { return m_name; }
[[nodiscard]] uint32_t GetWidth() const { return m_width; }
[[nodiscard]] uint32_t GetHeight() const { return m_height; }
[[nodiscard]] uint32_t GetPitch() const { return m_pitch; }
[[nodiscard]] int GetBitsPerPixel() const { return m_bits_per_pixel; }
[[nodiscard]] int GetBytesPerPixel() const { return static_cast<int>(static_cast<unsigned int>(m_bits_per_pixel) >> 3u); }
[[nodiscard]] int GetAlignment() const
{
static const int p[] = {8, 1, 2, 1, 4, 1, 2, 1};
return p[m_pitch & 7u];
}
[[nodiscard]] ImageOrder GetOrder() const { return m_order; }
[[nodiscard]] const void* GetData() const { return m_pixels; }
[[nodiscard]] void* GetSdlSurface() const;
void DbgPrint() const;
bool DbgEqual(const Image* img) const;
static Image* Create(const String& name, uint32_t width, uint32_t height, int bits_per_pixel);
static Math::Size GetSize(const String& name);
bool BlitTo(Image* img, const Math::Rect& src, const Math::Rect& dst) const;
[[nodiscard]] rgba32_t GetPixel(uint32_t x, uint32_t y) const;
[[nodiscard]] rgba32_t GetAvgPixel(uint32_t x, uint32_t y, uint32_t width, uint32_t height) const;
void SetPixel(uint32_t x, uint32_t y, rgba32_t color);
KYTY_CLASS_NO_COPY(Image);
private:
String m_name;
uint32_t m_width = 0;
uint32_t m_height = 0;
uint32_t m_pitch = 0;
int m_bits_per_pixel = 0;
ImageOrder m_order = ImageOrder::Unknown;
void* m_pixels = nullptr;
ImagePrivate* m_image = nullptr;
};
} // namespace Kyty::Libs::Graphics
#endif // KYTY_EMU_ENABLED
#endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_IMAGE_H_ */