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
+4 -4
View File
@@ -4,15 +4,17 @@
#include "Emulator/Common.h"
#ifdef KYTY_EMU_ENABLED
namespace Kyty::Emulator {
#ifdef KYTY_EMU_ENABLED
void kyty_reg();
#endif
KYTY_SUBSYSTEM_INIT(Emulator)
{
#ifdef KYTY_EMU_ENABLED
kyty_reg();
#endif
}
KYTY_SUBSYSTEM_UNEXPECTED_SHUTDOWN(Emulator) {}
@@ -20,5 +22,3 @@ KYTY_SUBSYSTEM_UNEXPECTED_SHUTDOWN(Emulator) {}
KYTY_SUBSYSTEM_DESTROY(Emulator) {}
} // namespace Kyty::Emulator
#endif // KYTY_EMU_ENABLED
+670
View File
@@ -0,0 +1,670 @@
#include "Emulator/Graphics/Color.h"
#ifdef KYTY_EMU_ENABLED
namespace Kyty::Libs::Graphics {
static void rgb_to_lab(const Color& c, ColorLab* l)
{
double var_r = c.R();
double var_g = c.G();
double var_b = c.B();
if (var_r > 0.04045)
{
var_r = pow(((var_r + 0.055) / 1.055), 2.4);
} else
{
var_r = var_r / 12.92;
}
if (var_g > 0.04045)
{
var_g = pow(((var_g + 0.055) / 1.055), 2.4);
} else
{
var_g = var_g / 12.92;
}
if (var_b > 0.04045)
{
var_b = pow(((var_b + 0.055) / 1.055), 2.4);
} else
{
var_b = var_b / 12.92;
}
var_r = var_r * 100.0;
var_g = var_g * 100.0;
var_b = var_b * 100.0;
// Observer. = 2°, Illuminant = D65
double x = var_r * 0.4124 + var_g * 0.3576 + var_b * 0.1805;
double y = var_r * 0.2126 + var_g * 0.7152 + var_b * 0.0722;
double z = var_r * 0.0193 + var_g * 0.1192 + var_b * 0.9505;
double ref_x = 95.047;
double ref_y = 100.000;
double ref_z = 108.883;
double var_x = x / ref_x;
double var_y = y / ref_y;
double var_z = z / ref_z;
if (var_x > 0.008856)
{
var_x = pow(var_x, (1.0 / 3.0));
} else
{
var_x = (7.787 * var_x) + (16.0 / 116.0);
}
if (var_y > 0.008856)
{
var_y = pow(var_y, (1.0 / 3.0));
} else
{
var_y = (7.787 * var_y) + (16.0 / 116.0);
}
if (var_z > 0.008856)
{
var_z = pow(var_z, (1.0 / 3.0));
} else
{
var_z = (7.787 * var_z) + (16.0 / 116.0);
}
l->L = static_cast<float>((116.0 * var_y) - 16.0);
l->A = static_cast<float>(500.0 * (var_x - var_y));
l->B = static_cast<float>(200.0 * (var_y - var_z));
}
static void lab_to_rgb(const ColorLab& l, Color* c)
{
double var_y = (l.L + 16.0) / 116.0;
double var_x = l.A / 500.0 + var_y;
double var_z = var_y - l.B / 200.0;
if (pow(var_y, 3) > 0.008856)
{
var_y = pow(var_y, 3);
} else
{
var_y = (var_y - 16.0 / 116.0) / 7.787;
}
if (pow(var_x, 3) > 0.008856)
{
var_x = pow(var_x, 3);
} else
{
var_x = (var_x - 16.0 / 116.0) / 7.787;
}
if (pow(var_z, 3) > 0.008856)
{
var_z = pow(var_z, 3);
} else
{
var_z = (var_z - 16.0 / 116.0) / 7.787;
}
double ref_x = 95.047;
double ref_y = 100.000;
double ref_z = 108.883;
// Observer. = 2°, Illuminant = D65
double x = ref_x * var_x;
double y = ref_y * var_y;
double z = ref_z * var_z;
var_x = x / 100.0;
var_y = y / 100.0;
var_z = z / 100.0;
double var_r = var_x * 3.2406 + var_y * -1.5372 + var_z * -0.4986;
double var_g = var_x * -0.9689 + var_y * 1.8758 + var_z * 0.0415;
double var_b = var_x * 0.0557 + var_y * -0.2040 + var_z * 1.0570;
if (var_r > 0.0031308)
{
var_r = 1.055 * (pow(var_r, (1.0 / 2.4))) - 0.055;
} else
{
var_r = 12.92 * var_r;
}
if (var_g > 0.0031308)
{
var_g = 1.055 * (pow(var_g, (1.0 / 2.4))) - 0.055;
} else
{
var_g = 12.92 * var_g;
}
if (var_b > 0.0031308)
{
var_b = 1.055 * (pow(var_b, (1.0 / 2.4))) - 0.055;
} else
{
var_b = 12.92 * var_b;
}
c->R() = static_cast<float>(var_r);
c->G() = static_cast<float>(var_g);
c->B() = static_cast<float>(var_b);
}
static void xyz_to_rgb(const ColorXyz& l, Color* c)
{
double x = l.X;
double y = l.Y;
double z = l.Z;
double var_x = x / 100.0;
double var_y = y / 100.0;
double var_z = z / 100.0;
double var_r = var_x * 3.2406 + var_y * -1.5372 + var_z * -0.4986;
double var_g = var_x * -0.9689 + var_y * 1.8758 + var_z * 0.0415;
double var_b = var_x * 0.0557 + var_y * -0.2040 + var_z * 1.0570;
if (var_r > 0.0031308)
{
var_r = 1.055 * (pow(var_r, (1.0 / 2.4))) - 0.055;
} else
{
var_r = 12.92 * var_r;
}
if (var_g > 0.0031308)
{
var_g = 1.055 * (pow(var_g, (1.0 / 2.4))) - 0.055;
} else
{
var_g = 12.92 * var_g;
}
if (var_b > 0.0031308)
{
var_b = 1.055 * (pow(var_b, (1.0 / 2.4))) - 0.055;
} else
{
var_b = 12.92 * var_b;
}
c->R() = static_cast<float>(var_r);
c->G() = static_cast<float>(var_g);
c->B() = static_cast<float>(var_b);
}
static void xyz_to_adobe_rgb(const ColorXyz& l, Color* c)
{
double x_a = l.X * 1.6;
double y_a = l.Y * 1.6;
double z_a = l.Z * 1.6;
double x_w = 152.07;
double y_w = 160.00;
double z_w = 174.25;
double x_k = 0.5282;
double y_k = 0.5557;
double z_k = 0.6052;
double x = ((x_a - x_k) / (x_w - x_k)) * (x_w / y_w);
double y = ((y_a - y_k) / (y_w - y_k));
double z = ((z_a - z_k) / (z_w - z_k)) * (z_w / y_w);
double r = x * 2.04159 + y * -0.56501 + z * -0.34473;
double g = x * -0.96924 + y * 1.87597 + z * 0.04156;
double b = x * 0.01344 + y * -0.11836 + z * 1.01517;
r = pow(r, (1.0 / 2.19921875));
g = pow(g, (1.0 / 2.19921875));
b = pow(b, (1.0 / 2.19921875));
c->R() = static_cast<float>(r);
c->G() = static_cast<float>(g);
c->B() = static_cast<float>(b);
}
static void adobe_rgb_to_xyz(const Color& c, ColorXyz* l)
{
double x_w = 152.07;
double y_w = 160.00;
double z_w = 174.25;
double x_k = 0.5282;
double y_k = 0.5557;
double z_k = 0.6052;
double r = c.R();
double g = c.G();
double b = c.B();
r = pow(r, (2.19921875));
g = pow(g, (2.19921875));
b = pow(b, (2.19921875));
double x = r * 0.57667 + g * 0.18556 + b * 0.18823;
double y = r * 0.29734 + g * 0.62736 + b * 0.07529;
double z = r * 0.02703 + g * 0.07069 + b * 0.99134;
double x_a = x * (x_w - x_k) * (y_w / x_w) + x_k;
double y_a = y * (y_w - y_k) * (y_w / y_w) + y_k;
double z_a = z * (z_w - z_k) * (y_w / z_w) + z_k;
l->X = static_cast<float>(x_a / 1.6);
l->Y = static_cast<float>(y_a / 1.6);
l->Z = static_cast<float>(z_a / 1.6);
}
static void linear_to_rgb(const Color& l, Color* c)
{
double var_r = l.R();
double var_g = l.G();
double var_b = l.B();
if (var_r > 0.0031308)
{
var_r = 1.055 * (pow(var_r, (1.0 / 2.4))) - 0.055;
} else
{
var_r = 12.92 * var_r;
}
if (var_g > 0.0031308)
{
var_g = 1.055 * (pow(var_g, (1.0 / 2.4))) - 0.055;
} else
{
var_g = 12.92 * var_g;
}
if (var_b > 0.0031308)
{
var_b = 1.055 * (pow(var_b, (1.0 / 2.4))) - 0.055;
} else
{
var_b = 12.92 * var_b;
}
c->R() = static_cast<float>(var_r); // if (c.r < 0.0) c.r = 0.0; if (c.r > 1.0) c.r = 1.0;
c->G() = static_cast<float>(var_g); // if (c.g < 0.0) c.g = 0.0; if (c.g > 1.0) c.g = 1.0;
c->B() = static_cast<float>(var_b); // if (c.b < 0.0) c.b = 0.0; if (c.b > 1.0) c.b = 1.0;
}
static void rgb_to_xyz(const Color& c, ColorXyz* l)
{
double var_r = c.R();
double var_g = c.G();
double var_b = c.B();
if (var_r > 0.04045)
{
var_r = pow(((var_r + 0.055) / 1.055), 2.4);
} else
{
var_r = var_r / 12.92;
}
if (var_g > 0.04045)
{
var_g = pow(((var_g + 0.055) / 1.055), 2.4);
} else
{
var_g = var_g / 12.92;
}
if (var_b > 0.04045)
{
var_b = pow(((var_b + 0.055) / 1.055), 2.4);
} else
{
var_b = var_b / 12.92;
}
var_r = var_r * 100.0;
var_g = var_g * 100.0;
var_b = var_b * 100.0;
// Observer. = 2°, Illuminant = D65
double x = var_r * 0.4124 + var_g * 0.3576 + var_b * 0.1805;
double y = var_r * 0.2126 + var_g * 0.7152 + var_b * 0.0722;
double z = var_r * 0.0193 + var_g * 0.1192 + var_b * 0.9505;
l->X = static_cast<float>(x);
l->Y = static_cast<float>(y);
l->Z = static_cast<float>(z);
}
static void rgb_to_linear(const Color& c, Color* l)
{
double var_r = c.R();
double var_g = c.G();
double var_b = c.B();
if (var_r > 0.04045)
{
var_r = pow(((var_r + 0.055) / 1.055), 2.4);
} else
{
var_r = var_r / 12.92;
}
if (var_g > 0.04045)
{
var_g = pow(((var_g + 0.055) / 1.055), 2.4);
} else
{
var_g = var_g / 12.92;
}
if (var_b > 0.04045)
{
var_b = pow(((var_b + 0.055) / 1.055), 2.4);
} else
{
var_b = var_b / 12.92;
}
l->R() = static_cast<float>(var_r);
l->G() = static_cast<float>(var_g);
l->B() = static_cast<float>(var_b);
}
static float Max(float x, float y)
{
if (x < y)
{
return y;
}
return x;
}
static float Min(float x, float y)
{
if (x < y)
{
return x;
}
return y;
}
void rgb_to_hsv(const Color& c, ColorHsv* l)
{
float r = c.R();
float g = c.G();
float b = c.B();
float m_x = Max(r, Max(g, b));
float mn = Min(r, Min(g, b));
if (m_x == mn)
{
l->H = 0.0f;
} else if (m_x == r)
{
if (g >= b)
{
l->H = 60.0f * (g - b) / (m_x - mn);
} else
{
l->H = 60.0f * (g - b) / (m_x - mn) + 360;
}
} else if (m_x == g)
{
l->H = 60.0f * (b - r) / (m_x - mn) + 120;
} else
{
l->H = 60.0f * (r - g) / (m_x - mn) + 240;
}
l->S = (m_x == 0.0f) ? 0.0f : 1.0f - mn / m_x;
l->V = m_x;
}
void hsv_to_rgb(const ColorHsv& l, Color* c)
{
float h = fmodf((l.H >= 0.0 ? l.H : l.H + 360.0f) / 60.0f, 6.0f);
float cc = l.V * l.S;
float x = cc * (1.0f - fabsf(fmodf(h, 2.0f) - 1.0f));
float r = 0;
float g = 0;
float b = 0;
if (0.0f <= h && h <= 1.0f)
{
r = cc;
g = x;
} else if (1.0f <= h && h <= 2.0f)
{
r = x;
g = cc;
} else if (2.0f <= h && h <= 3.0f)
{
g = cc;
b = x;
} else if (3.0f <= h && h <= 4.0f)
{
g = x;
b = cc;
} else if (4.0f <= h && h <= 5.0f)
{
r = x;
b = cc;
} else if (5.0f <= h && h <= 6.0f)
{
r = cc;
b = x;
}
float m = l.V - cc;
c->R() = r + m;
c->G() = g + m;
c->B() = b + m;
}
void rgb_to_hcl(float r, float g, float b, float* h, float* c, float* l)
{
float m_x = Max(r, Max(g, b));
float mn = Min(r, Min(g, b));
float cc = m_x - mn;
if (cc == 0)
{
*h = -1;
} else if (m_x == r)
{
if (g >= b)
{
*h = ((g - b) / cc);
} else
{
*h = ((g - b) / cc) + 6;
}
} else if (m_x == g)
{
*h = ((b - r) / cc) + 2;
} else
{
*h = ((r - g) / cc) + 4;
}
if (*h > 0)
{
*h *= 60;
}
*c = cc;
*l = static_cast<float>(0.3 * r + 0.59 * g + 0.11 * b);
}
bool Color::InGamut() const
{
return !(R() < 0.0f || R() > 1.0f || G() < 0.0f || G() > 1.0f || B() < 0.0f || B() > 1.0f || A() < 0.0f || A() > 1.0f);
}
ColorXyz Color::ToXyz() const
{
ColorXyz r {};
rgb_to_xyz(*this, &r);
return r;
}
ColorLab Color::ToLab() const
{
ColorLab r;
rgb_to_lab(*this, &r);
return r;
}
Color Color::FromLab(const ColorLab& l)
{
Color r {};
lab_to_rgb(l, &r);
r.A() = 1.0f;
return r;
}
Color Color::FromXyz(const ColorXyz& l)
{
Color r {};
xyz_to_rgb(l, &r);
r.A() = 1.0f;
return r;
}
vec3 HUEToRGB(float h)
{
h = fmodf(h, 1.0f);
if (h < 0.0f)
{
h += 1.0f;
}
float r = fabsf(h * 6.0f - 3.0f) - 1.0f;
float g = 2 - fabsf(h * 6.0f - 2.0f);
float b = 2 - fabsf(h * 6.0f - 4.0f);
return Math::math_clamp(vec3(r, g, b), 0.0f, 1.0f);
}
// All values are all in range [0..1]
Color Color::FromHsl(float h, float s, float l, float a)
{
vec3 r_g_b = HUEToRGB(h);
float cc = (1.0f - fabsf(2.0f * l - 1.0f)) * s;
vec3 rgb = (r_g_b - 0.5f) * cc + l;
return {rgb.r, rgb.g, rgb.b, a};
}
void Color::ToHcl(float* h, float* c, float* l) const
{
rgb_to_hcl(Red(), Green(), Blue(), h, c, l);
}
ColorHsv Color::ToHsv() const
{
ColorHsv r;
rgb_to_hsv(*this, &r);
return r;
}
Color Color::FromHsv(const ColorHsv& l)
{
Color r {};
hsv_to_rgb(l, &r);
r.A() = 1.0f;
return r;
}
void Color::Clip()
{
if (R() < 0.0f)
{
R() = 0.0f;
}
if (R() > 1.0f)
{
R() = 1.0f;
}
if (G() < 0.0f)
{
G() = 0.0f;
}
if (G() > 1.0f)
{
G() = 1.0f;
}
if (B() < 0.0f)
{
B() = 0.0f;
}
if (B() > 1.0f)
{
B() = 1.0f;
}
if (A() < 0.0f)
{
A() = 0.0f;
}
if (A() > 1.0f)
{
A() = 1.0f;
}
}
Color Color::ToLinear() const
{
Color r {};
rgb_to_linear(*this, &r);
r.A() = A();
return r;
}
Color Color::FromLinear(const Color& l)
{
Color r {};
linear_to_rgb(l, &r);
r.A() = l.A();
return r;
}
Color Color::ToAdobeRGB() const
{
Color r {};
ColorXyz xyz {};
rgb_to_xyz(*this, &xyz);
xyz_to_adobe_rgb(xyz, &r);
r.A() = A();
return r;
}
Color Color::FromAdobeRGB(const Color& c)
{
Color r {};
ColorXyz xyz {};
adobe_rgb_to_xyz(c, &xyz);
xyz_to_rgb(xyz, &r);
r.A() = c.A();
return r;
}
void ColorLab::Clip()
{
if (L < COLOR_LAB_L_MIN)
{
L = COLOR_LAB_L_MIN;
}
if (L > COLOR_LAB_L_MAX)
{
L = COLOR_LAB_L_MAX;
}
if (A < COLOR_LAB_A_MIN)
{
A = COLOR_LAB_A_MIN;
}
if (A > COLOR_LAB_A_MAX)
{
A = COLOR_LAB_A_MAX;
}
if (B < COLOR_LAB_B_MIN)
{
B = COLOR_LAB_B_MIN;
}
if (B > COLOR_LAB_B_MAX)
{
B = COLOR_LAB_B_MAX;
}
}
} // namespace Kyty::Libs::Graphics
#endif // KYTY_EMU_ENABLED
+559
View File
@@ -0,0 +1,559 @@
#include "Emulator/Graphics/Image.h"
#include "Kyty/Core/DbgAssert.h"
#include "Kyty/Core/File.h"
#include "Kyty/Core/SafeDelete.h"
#include "SDL_blendmode.h"
#include "SDL_error.h"
#include "SDL_pixels.h"
#include "SDL_rect.h"
#include "SDL_rwops.h"
#include "SDL_surface.h"
#define STB_IMAGE_IMPLEMENTATION
#define STBI_ASSERT ASSERT
#define STBI_NO_SIMD
#include "stb_image.h"
#define KYTY_SDL_BITSPERPIXEL(X) (((X) >> 8u) & 0xFFu)
#define KYTY_SDL_PIXELTYPE(X) (((X) >> 24u) & 0x0Fu)
#define KYTY_SDL_PIXELLAYOUT(X) (((X) >> 16u) & 0x0Fu)
#define KYTY_SDL_PIXELORDER(X) (((X) >> 20u) & 0x0Fu)
#ifdef KYTY_EMU_ENABLED
namespace Kyty::Libs::Graphics {
// using namespace Core;
using Core::File;
class ImagePrivate
{
public:
KYTY_CLASS_NO_COPY(ImagePrivate);
explicit ImagePrivate(SDL_Surface* s): sdl(s) {}
virtual ~ImagePrivate() { SDL_FreeSurface(sdl); }
void BgrToRgb() const
{
auto* rowptr = static_cast<uint8_t*>(sdl->pixels);
int row_num = sdl->h;
int col_num = sdl->w;
int pitch = sdl->pitch;
for (int row = 0; row < row_num; row++)
{
uint8_t* colptr = rowptr;
for (int col = 0; col < col_num; col++)
{
uint8_t t = colptr[0];
colptr[0] = colptr[2];
colptr[2] = t;
colptr += 3;
}
rowptr += pitch;
}
}
void BgraToRgba() const
{
auto* rowptr = static_cast<uint8_t*>(sdl->pixels);
int row_num = sdl->h;
int col_num = sdl->w;
int pitch = sdl->pitch;
for (int row = 0; row < row_num; row++)
{
uint8_t* colptr = rowptr;
for (int col = 0; col < col_num; col++)
{
uint8_t t = colptr[0];
colptr[0] = colptr[2];
colptr[2] = t;
colptr += 4;
}
rowptr += pitch;
}
}
SDL_Surface* sdl;
};
Image::Image(const String& name): m_name(name) {}
Image::~Image()
{
if (m_image != nullptr)
{
Delete(m_image);
}
}
void Image::Load(const String& file_name)
{
m_name = file_name;
Load();
}
static int read(void* user, char* data, int size)
{
auto* src = static_cast<SDL_RWops*>(user);
return static_cast<int>(src->read(src, data, 1, size));
}
static void skip(void* user, int n)
{
auto* src = static_cast<SDL_RWops*>(user);
src->seek(src, n, RW_SEEK_CUR);
}
static int eof(void* user)
{
auto* src = static_cast<SDL_RWops*>(user);
return (src->seek(src, 0, RW_SEEK_CUR) >= src->size(src) ? 1 : 0);
}
static SDL_Surface* IMG_LoadPNG_RW(SDL_RWops* src)
{
int width = 0;
int height = 0;
int bytes_per_pixel = 0;
stbi_io_callbacks cb {};
cb.read = read;
cb.skip = skip;
cb.eof = eof;
void* data = stbi_load_from_callbacks(&cb, src, &width, &height, &bytes_per_pixel, 0);
uint32_t pitch = (width * bytes_per_pixel + 3u) & ~3u;
uint32_t r_mask = 0x000000FF;
uint32_t g_mask = 0x0000FF00;
uint32_t b_mask = 0x00FF0000;
uint32_t a_mask = (bytes_per_pixel == 4) ? 0xFF000000 : 0;
SDL_Surface* surface =
SDL_CreateRGBSurfaceFrom(data, width, height, bytes_per_pixel * 8, static_cast<int>(pitch), r_mask, g_mask, b_mask, a_mask);
EXIT_NOT_IMPLEMENTED(surface == nullptr);
return surface;
}
void Image::Load()
{
if (m_image != nullptr)
{
Delete(m_image);
}
auto file_name = m_name;
File f;
if (!f.Open(file_name, File::Mode::Read))
{
EXIT("Can't open file %s\n", file_name.C_Str());
}
SDL_RWops* ops = f.CreateSdlRWops();
EXIT_IF(ops == nullptr);
SDL_Surface* sdl = nullptr;
if (file_name.EndsWith(U".bmp", String::Case::Insensitive))
{
/* sdl = IMG_LoadBMP_RW(ops); */
KYTY_NOT_IMPLEMENTED;
} else if (file_name.EndsWith(U".tga", String::Case::Insensitive))
{
/* sdl = IMG_LoadTGA_RW(ops); */
KYTY_NOT_IMPLEMENTED;
} else if (file_name.EndsWith(U".png", String::Case::Insensitive))
{
sdl = IMG_LoadPNG_RW(ops);
// KYTY_NOT_IMPLEMENTED;
} else if (file_name.EndsWith(U".webp", String::Case::Insensitive))
{
/* sdl = IMG_LoadWEBP_RW(ops); */
KYTY_NOT_IMPLEMENTED;
} else
{
EXIT("Unknown image type %s\n", file_name.utf8_str().GetData());
}
LoadSdl(sdl);
SDL_RWclose(ops);
}
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
void Image::LoadSdl(void* s)
{
auto* sdl = static_cast<SDL_Surface*>(s);
EXIT_IF(sdl == nullptr);
m_bits_per_pixel = static_cast<int>(KYTY_SDL_BITSPERPIXEL(sdl->format->format));
EXIT_IF(sdl->format->palette != nullptr && m_bits_per_pixel != 8);
m_image = new ImagePrivate(sdl);
m_width = m_image->sdl->w;
m_height = m_image->sdl->h;
m_pitch = m_image->sdl->pitch;
EXIT_IF(KYTY_SDL_PIXELTYPE(m_image->sdl->format->format) != SDL_PIXELTYPE_ARRAYU8 &&
KYTY_SDL_PIXELTYPE(m_image->sdl->format->format) != SDL_PIXELTYPE_INDEX8 &&
KYTY_SDL_PIXELTYPE(m_image->sdl->format->format) != SDL_PIXELTYPE_PACKED32);
EXIT_IF(KYTY_SDL_PIXELLAYOUT(m_image->sdl->format->format) != 0 &&
KYTY_SDL_PIXELLAYOUT(m_image->sdl->format->format) != SDL_PACKEDLAYOUT_8888);
if (m_bits_per_pixel == 8)
{
m_order = ImageOrder::Alpha;
} else if (SDL_ISPIXELFORMAT_PACKED(m_image->sdl->format->format)) // NOLINT(hicpp-signed-bitwise)
{
switch (KYTY_SDL_PIXELORDER(m_image->sdl->format->format))
{
case SDL_PACKEDORDER_NONE: EXIT("SDL_PACKEDORDER_NONE\n"); break;
case SDL_PACKEDORDER_XRGB: EXIT("SDL_PACKEDORDER_XRGB\n"); break;
case SDL_PACKEDORDER_RGBX: EXIT("SDL_PACKEDORDER_RGBX\n"); break;
// TGA32, BMP32
case SDL_PACKEDORDER_ARGB:
m_image->BgraToRgba();
m_order = ImageOrder::Rgba;
break;
case SDL_PACKEDORDER_RGBA: EXIT("SDL_PACKEDORDER_RGBA\n"); break;
case SDL_PACKEDORDER_XBGR: EXIT("SDL_PACKEDORDER_XBGR\n"); break;
case SDL_PACKEDORDER_BGRX: EXIT("SDL_PACKEDORDER_BGRX\n"); break;
// WEBP32, PNG32
case SDL_PACKEDORDER_ABGR: m_order = ImageOrder::Rgba; break;
case SDL_PACKEDORDER_BGRA: EXIT("SDL_PACKEDORDER_BGRA\n"); break;
default: EXIT("unknown packed format %d\n", int(KYTY_SDL_PIXELORDER(m_image->sdl->format->format)));
}
} else if (SDL_ISPIXELFORMAT_ARRAY(m_image->sdl->format->format)) // NOLINT(hicpp-signed-bitwise)
{
switch (KYTY_SDL_PIXELORDER(m_image->sdl->format->format))
{
case SDL_ARRAYORDER_NONE: EXIT("SDL_ARRAYORDER_NONE\n"); break;
// WEBP24, PNG24
case SDL_ARRAYORDER_RGB: m_order = ImageOrder::Rgb; break;
case SDL_ARRAYORDER_RGBA: EXIT("SDL_ARRAYORDER_RGBA\n"); break;
case SDL_ARRAYORDER_ARGB: EXIT("SDL_ARRAYORDER_ARGB\n"); break;
// TGA24, BMP24,
case SDL_ARRAYORDER_BGR:
m_image->BgrToRgb();
m_order = ImageOrder::Rgb;
break;
case SDL_ARRAYORDER_BGRA: EXIT("SDL_ARRAYORDER_BGRA\n"); break;
case SDL_ARRAYORDER_ABGR: EXIT("SDL_ARRAYORDER_ABGR\n"); break;
default: EXIT("unknown array format %d\n", int(KYTY_SDL_PIXELORDER(m_image->sdl->format->format)));
}
} else
{
EXIT("invalid format\n");
}
EXIT_IF((int)KYTY_SDL_BITSPERPIXEL(m_image->sdl->format->format) != m_image->sdl->format->BitsPerPixel);
EXIT_IF(m_bits_per_pixel != 24 && m_bits_per_pixel != 32 && m_bits_per_pixel != 8);
EXIT_IF(m_pitch - ((m_width * m_bits_per_pixel) >> 3u) >= 4);
m_pixels = m_image->sdl->pixels;
}
void Image::DbgPrint() const
{
printf("------\n");
printf("%s:\n", m_name.utf8_str().GetData());
printf("width = %d\n", (m_image->sdl->w));
printf("height = %d\n", (m_image->sdl->h));
printf("pitch = %d\n", (m_image->sdl->pitch));
printf("type = %d\n", static_cast<int>(KYTY_SDL_PIXELTYPE(m_image->sdl->format->format)));
if (m_bits_per_pixel == 8)
{
printf("order = alpha\n");
} else if (SDL_ISPIXELFORMAT_PACKED(m_image->sdl->format->format)) // NOLINT(hicpp-signed-bitwise)
{
switch (KYTY_SDL_PIXELORDER(m_image->sdl->format->format))
{
case SDL_PACKEDORDER_NONE: printf("order = SDL_PACKEDORDER_NONE\n"); break;
case SDL_PACKEDORDER_XRGB: printf("order = SDL_PACKEDORDER_XRGB\n"); break;
case SDL_PACKEDORDER_RGBX: printf("order = SDL_PACKEDORDER_RGBX\n"); break;
case SDL_PACKEDORDER_ARGB: printf("order = SDL_PACKEDORDER_ARGB\n"); break;
case SDL_PACKEDORDER_RGBA: printf("order = SDL_PACKEDORDER_RGBA\n"); break;
case SDL_PACKEDORDER_XBGR: printf("order = SDL_PACKEDORDER_XBGR\n"); break;
case SDL_PACKEDORDER_BGRX: printf("order = SDL_PACKEDORDER_BGRX\n"); break;
case SDL_PACKEDORDER_ABGR: printf("order = SDL_PACKEDORDER_ABGR\n"); break;
case SDL_PACKEDORDER_BGRA: printf("order = SDL_PACKEDORDER_BGRA\n"); break;
default: printf("order = <packed_invalid>\n");
}
} else if (SDL_ISPIXELFORMAT_ARRAY(m_image->sdl->format->format)) // NOLINT(hicpp-signed-bitwise)
{
switch (KYTY_SDL_PIXELORDER(m_image->sdl->format->format))
{
case SDL_ARRAYORDER_NONE: printf("order = SDL_ARRAYORDER_NONE\n"); break;
case SDL_ARRAYORDER_RGB: printf("order = SDL_ARRAYORDER_RGB\n"); break;
case SDL_ARRAYORDER_RGBA: printf("order = SDL_ARRAYORDER_RGBA\n"); break;
case SDL_ARRAYORDER_ARGB: printf("order = SDL_ARRAYORDER_ARGB\n"); break;
case SDL_ARRAYORDER_BGR: printf("order = SDL_ARRAYORDER_BGR\n"); break;
case SDL_ARRAYORDER_BGRA: printf("order = SDL_ARRAYORDER_BGRA\n"); break;
case SDL_ARRAYORDER_ABGR: printf("order = SDL_ARRAYORDER_ABGR\n"); break;
default: printf("order = <array_invalid>\n");
}
}
printf("layout = %d\n", static_cast<int>(KYTY_SDL_PIXELLAYOUT(m_image->sdl->format->format)));
printf("bits_per_pixel = %d\n", static_cast<int>(KYTY_SDL_BITSPERPIXEL(m_image->sdl->format->format)));
printf("bytes_per_pixel = %d\n", static_cast<int>(SDL_BYTESPERPIXEL(m_image->sdl->format->format))); // NOLINT(hicpp-signed-bitwise)
printf("bits_per_pixel = %d\n", static_cast<int>(m_image->sdl->format->BitsPerPixel));
printf("bytes_per_pixel = %d\n", static_cast<int>(m_image->sdl->format->BytesPerPixel));
}
bool Image::DbgEqual(const Image* img) const
{
if (m_width != img->m_width || m_height != img->m_height || m_pitch != img->m_pitch || m_bits_per_pixel != img->m_bits_per_pixel ||
m_order != img->m_order)
{
return false;
}
for (uint32_t yi = 0; yi < m_height; yi++)
{
for (uint32_t xi = 0; xi < m_width; xi++)
{
if (GetPixel(xi, yi) != img->GetPixel(xi, yi))
{
return false;
}
}
}
return true;
}
void Image::Save(const String& file_name) const
{
EXIT_IF(m_image == nullptr);
File f;
f.Create(file_name);
SDL_RWops* ops = f.CreateSdlRWops();
int result = -1;
if (file_name.EndsWith(U".png", String::Case::Insensitive))
{
/*result = IMG_SavePNG_RW(m_image->sdl, ops, 1);*/
KYTY_NOT_IMPLEMENTED;
} else if (file_name.EndsWith(U".bmp", String::Case::Insensitive))
{
result = SDL_SaveBMP_RW(m_image->sdl, ops, 1);
} else
{
EXIT("Unknown image type %s\n", file_name.utf8_str().GetData());
}
if (result != 0)
{
EXIT("SDL error: %s\n", SDL_GetError());
}
}
Image* Image::Clone() const
{
auto* img = new Image(m_name);
if (m_image != nullptr)
{
SDL_Surface* copy_sdl = SDL_ConvertSurface(m_image->sdl, m_image->sdl->format, SDL_SWSURFACE);
img->LoadSdl(copy_sdl);
}
return img;
}
Image* Image::Create(const String& name, uint32_t width, uint32_t height, int bits_per_pixel)
{
auto* img = new Image(name);
EXIT_IF(bits_per_pixel != 24 && bits_per_pixel != 32);
// uint32_t rmask = 0;
// uint32_t gmask = 0;
// uint32_t bmask = 0;
// uint32_t amask = 0;
//
// if (bits_per_pixel == 32)
// {
uint32_t amask = 0xFF000000;
uint32_t bmask = 0x00FF0000;
uint32_t gmask = 0x0000FF00;
uint32_t rmask = 0x000000FF;
// }
SDL_Surface* sdl =
SDL_CreateRGBSurface(0, static_cast<int>(width), static_cast<int>(height), bits_per_pixel, rmask, gmask, bmask, amask);
SDL_Rect r = {0, 0, static_cast<int>(width), static_cast<int>(height)};
SDL_FillRect(sdl, &r, 0);
img->LoadSdl(sdl);
return img;
}
rgba32_t Image::GetPixel(uint32_t x, uint32_t y) const
{
if (m_order == ImageOrder::Rgb && m_bits_per_pixel == 24)
{
uint8_t* p = ((static_cast<uint8_t*>(m_pixels)) + m_pitch * static_cast<size_t>(y) + 3 * static_cast<size_t>(x));
return Rgb(p[0], p[1], p[2]);
}
if (m_order == ImageOrder::Rgba && m_bits_per_pixel == 32)
{
uint8_t* p = ((static_cast<uint8_t*>(m_pixels)) + m_pitch * static_cast<size_t>(y) + 4 * static_cast<size_t>(x));
return Rgb(p[0], p[1], p[2], p[3]);
}
EXIT("invalid format: order = %d, bits = %d\n", int(m_order), int(m_bits_per_pixel));
return 0;
}
void Image::SetPixel(uint32_t x, uint32_t y, rgba32_t color)
{
if (m_order == ImageOrder::Rgb && m_bits_per_pixel == 24)
{
uint8_t* p = ((static_cast<uint8_t*>(m_pixels)) + m_pitch * static_cast<size_t>(y) + 3 * static_cast<size_t>(x));
p[0] = RgbToRed(color);
p[1] = RgbToGreen(color);
p[2] = RgbToBlue(color);
} else if (m_order == ImageOrder::Rgba && m_bits_per_pixel == 32)
{
uint8_t* p = ((static_cast<uint8_t*>(m_pixels)) + m_pitch * static_cast<size_t>(y) + 4 * static_cast<size_t>(x));
p[0] = RgbToRed(color);
p[1] = RgbToGreen(color);
p[2] = RgbToBlue(color);
p[3] = RgbToAlpha(color);
} else
{
EXIT("invalid format: order = %d, bits = %d\n", int(m_order), int(m_bits_per_pixel));
}
}
rgba32_t Image::GetAvgPixel(uint32_t x, uint32_t y, uint32_t w, uint32_t h) const
{
EXIT_IF(x >= m_width);
EXIT_IF(y >= m_height);
EXIT_IF(x + w > m_width);
EXIT_IF(y + h > m_height);
vec4 sum(0.0f);
for (uint32_t yi = y; yi < y + h; yi++)
{
for (uint32_t xi = x; xi < x + w; xi++)
{
Color s(GetPixel(xi, yi));
sum = sum + s.Rgba();
}
}
sum /= static_cast<float>(w * h);
return Color(sum).ToRgba32();
}
bool Image::BlitTo(Image* img, const Math::Rect& src, const Math::Rect& dst) const
{
EXIT_IF(!img);
EXIT_IF(src.x >= m_width || src.y >= m_height || src.x + src.width - 1 >= m_width || src.y + src.height - 1 >= m_height);
EXIT_IF(dst.x >= img->m_width || dst.y >= img->m_height || dst.x + dst.width - 1 >= img->m_width ||
dst.y + dst.height - 1 >= img->m_height);
SDL_SetSurfaceBlendMode(m_image->sdl, SDL_BLENDMODE_NONE);
int result = 0;
SDL_Rect r1 = {static_cast<int>(src.x), static_cast<int>(src.y), static_cast<int>(src.width), static_cast<int>(src.height)};
SDL_Rect r2 = {static_cast<int>(dst.x), static_cast<int>(dst.y), static_cast<int>(dst.width), static_cast<int>(dst.height)};
if (src.width != dst.width || src.height != dst.height)
{
result = SDL_BlitScaled(m_image->sdl, &r1, img->m_image->sdl, &r2);
} else
{
result = SDL_BlitSurface(m_image->sdl, &r1, img->m_image->sdl, &r2);
}
if (result != 0)
{
printf("Blit failed: %s\n", SDL_GetError());
return false;
}
return true;
}
void* Image::GetSdlSurface() const
{
return m_image->sdl;
}
Math::Size Image::GetSize(const String& name)
{
if (!name.EndsWith(U".png", String::Case::Insensitive))
{
EXIT("unsupported format: %s\n", name.C_Str());
}
File f;
if (!f.Open(name, File::Mode::Read))
{
EXIT("Can't open file %s\n", name.C_Str());
}
Math::Size s(0, 0);
uint32_t header = 0;
f.Seek(12);
f.Read(&header, 4);
if (header != 0x52444849)
{
EXIT("wrong png file: %s\n", name.C_Str());
}
f.ReadR(&s.width, 4);
f.ReadR(&s.height, 4);
f.Close();
return s;
}
} // namespace Kyty::Libs::Graphics
#endif // KYTY_EMU_ENABLED
+30 -4
View File
@@ -13,10 +13,12 @@
#include "Emulator/Controller.h"
#include "Emulator/Graphics/GraphicContext.h"
#include "Emulator/Graphics/GraphicsRender.h"
#include "Emulator/Graphics/Image.h"
#include "Emulator/Graphics/Utils.h"
#include "Emulator/Graphics/VideoOut.h"
#include "Emulator/Loader/Param.h"
#include "Emulator/Loader/VirtualMemory.h"
#include "Emulator/Profiler.h"
#include "Emulator/VirtualMemory.h"
#include "SDL.h"
#include "SDL_error.h"
@@ -27,6 +29,7 @@
#include "SDL_keycode.h"
#include "SDL_mouse.h"
#include "SDL_stdinc.h"
#include "SDL_surface.h"
#include "SDL_thread.h"
#include "SDL_touch.h"
#include "SDL_video.h"
@@ -2163,12 +2166,33 @@ GraphicContext* WindowGetGraphicContext()
return &g_window_ctx->graphic_ctx;
}
void WindowShowFps()
void WindowUpdateIcon()
{
EXIT_IF(g_window_ctx == nullptr);
static Image* icon = Loader::ParamSfoGetIcon();
if (icon != nullptr)
{
SDL_SetWindowIcon(g_window_ctx->window, static_cast<SDL_Surface*>(icon->GetSdlSurface()));
}
}
void WindowUpdateTitle()
{
EXIT_IF(g_window_ctx == nullptr);
EXIT_IF(g_window_ctx->game == nullptr);
auto fps = String::FromPrintf("[%s] [%s], frame: %d, fps: %f", g_window_ctx->device_name, g_window_ctx->processor_name,
static char title[128];
static char title_id[12];
static char app_ver[8];
static bool has_title = Loader::ParamSfoGetString("TITLE", title, sizeof(title));
static bool has_title_id = Loader::ParamSfoGetString("TITLE_ID", title_id, sizeof(title_id));
static bool has_app_ver = Loader::ParamSfoGetString("APP_VER", app_ver, sizeof(app_ver));
auto fps = String::FromPrintf("%s%s%s%s%s%s[%s] [%s], frame: %d, fps: %f", (has_title ? title : ""), (has_title ? ", " : ""),
(has_title_id ? title_id : ""), (has_title_id ? ", " : ""), (has_app_ver ? app_ver : ""),
(has_app_ver ? ", " : ""), g_window_ctx->device_name, g_window_ctx->processor_name,
g_window_ctx->game->m_frame_num, g_window_ctx->game->m_current_fps);
SDL_SetWindowTitle(g_window_ctx->window, fps.C_Str());
@@ -2184,6 +2208,8 @@ void WindowDrawBuffer(VideoOutVulkanImage* image)
if (g_window_ctx->window_hidden)
{
WindowUpdateIcon();
SDL_ShowWindow(g_window_ctx->window);
g_window_ctx->window_hidden = false;
@@ -2257,7 +2283,7 @@ void WindowDrawBuffer(VideoOutVulkanImage* image)
result = vkQueuePresentKHR(g_window_ctx->graphic_ctx.queue[GraphicContext::QUEUE_PRESENT], &present);
EXIT_NOT_IMPLEMENTED(result != VK_SUCCESS);
WindowShowFps();
WindowUpdateTitle();
}
} // namespace Kyty::Libs::Graphics
+1 -1
View File
@@ -11,7 +11,7 @@
#include "Emulator/Graphics/Window.h"
#include "Emulator/Libs/Errno.h"
#include "Emulator/Libs/Libs.h"
#include "Emulator/VirtualMemory.h"
#include "Emulator/Loader/VirtualMemory.h"
#include <algorithm>
+2 -2
View File
@@ -11,8 +11,8 @@
#include "Emulator/Libs/Errno.h"
#include "Emulator/Libs/Libs.h"
#include "Emulator/RuntimeLinker.h"
#include "Emulator/Timer.h"
#include "Emulator/Loader/RuntimeLinker.h"
#include "Emulator/Loader/Timer.h"
#include <atomic>
#include <cerrno>
+24 -3
View File
@@ -20,11 +20,12 @@
#include "Emulator/Kernel/Memory.h"
#include "Emulator/Kernel/Pthread.h"
#include "Emulator/Libs/Libs.h"
#include "Emulator/Loader/Param.h"
#include "Emulator/Loader/RuntimeLinker.h"
#include "Emulator/Loader/Timer.h"
#include "Emulator/Loader/VirtualMemory.h"
#include "Emulator/Network.h"
#include "Emulator/Profiler.h"
#include "Emulator/RuntimeLinker.h"
#include "Emulator/Timer.h"
#include "Emulator/VirtualMemory.h"
#include <cstdlib>
@@ -211,6 +212,25 @@ KYTY_SCRIPT_FUNC(kyty_load_symbols_func)
return 0;
}
KYTY_SCRIPT_FUNC(kyty_load_param_sfo_func)
{
auto count = Scripts::ArgGetVarCount();
if (count != 1)
{
EXIT("invalid args\n");
}
auto file_name = Scripts::ArgGetVar(0).ToString();
if (!file_name.IsEmpty())
{
Loader::ParamSfoLoad(Scripts::ArgGetVar(0).ToString());
}
return 0;
}
KYTY_SCRIPT_FUNC(kyty_dbg_dump_func)
{
if (Scripts::ArgGetVarCount() != 1)
@@ -385,6 +405,7 @@ void kyty_reg()
Scripts::RegisterFunc("kyty_load_elf", LuaFunc::kyty_load_elf_func, LuaFunc::kyty_help);
Scripts::RegisterFunc("kyty_save_main_elf", LuaFunc::kyty_save_main_elf_func, LuaFunc::kyty_help);
Scripts::RegisterFunc("kyty_load_symbols", LuaFunc::kyty_load_symbols_func, LuaFunc::kyty_help);
Scripts::RegisterFunc("kyty_load_param_sfo", LuaFunc::kyty_load_param_sfo_func, LuaFunc::kyty_help);
Scripts::RegisterFunc("kyty_dbg_dump", LuaFunc::kyty_dbg_dump_func, LuaFunc::kyty_help);
Scripts::RegisterFunc("kyty_execute", LuaFunc::kyty_execute_func, LuaFunc::kyty_help);
Scripts::RegisterFunc("kyty_mount", LuaFunc::kyty_mount_func, LuaFunc::kyty_help);
+32 -1
View File
@@ -5,7 +5,8 @@
#include "Emulator/Common.h"
#include "Emulator/Libs/Errno.h"
#include "Emulator/Libs/Libs.h"
#include "Emulator/SymbolDatabase.h"
#include "Emulator/Loader/Param.h"
#include "Emulator/Loader/SymbolDatabase.h"
#ifdef KYTY_EMU_ENABLED
@@ -66,12 +67,42 @@ int KYTY_SYSV_ABI AppContentGetAddcontInfoList(uint32_t service_label, AppConten
return OK;
}
int KYTY_SYSV_ABI AppContentAppParamGetInt(uint32_t param_id, int32_t* value)
{
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(value == nullptr);
*value = 0;
bool found = false;
printf("\t param_id = %u\n", param_id);
switch (param_id)
{
case 0:
*value = 3;
found = true;
break;
case 1: found = Loader::ParamSfoGetInt("USER_DEFINED_PARAM_1", value); break;
case 2: found = Loader::ParamSfoGetInt("USER_DEFINED_PARAM_2", value); break;
case 3: found = Loader::ParamSfoGetInt("USER_DEFINED_PARAM_3", value); break;
case 4: found = Loader::ParamSfoGetInt("USER_DEFINED_PARAM_4", value); break;
default: EXIT("unknown param_id: %u\n", param_id);
}
printf("\t value = %d [%s]\n", *value, found ? "found" : "not found");
return OK;
}
} // namespace AppContent
LIB_DEFINE(InitAppContent_1)
{
LIB_FUNC("R9lA82OraNs", AppContent::AppContentInitialize);
LIB_FUNC("xnd8BJzAxmk", AppContent::AppContentGetAddcontInfoList);
LIB_FUNC("99b82IKXpH4", AppContent::AppContentAppParamGetInt);
}
} // namespace Kyty::Libs
+1 -1
View File
@@ -1,7 +1,7 @@
#include "Emulator/Audio.h"
#include "Emulator/Common.h"
#include "Emulator/Libs/Libs.h"
#include "Emulator/SymbolDatabase.h"
#include "Emulator/Loader/SymbolDatabase.h"
#ifdef KYTY_EMU_ENABLED
+1 -1
View File
@@ -9,7 +9,7 @@
#include "Emulator/Libs/Libs.h"
#include "Emulator/Libs/Printf.h"
#include "Emulator/Libs/VaContext.h"
#include "Emulator/SymbolDatabase.h"
#include "Emulator/Loader/SymbolDatabase.h"
#include <cstdlib>
+1 -1
View File
@@ -3,7 +3,7 @@
#include "Emulator/Common.h"
#include "Emulator/Libs/Libs.h"
#include "Emulator/SymbolDatabase.h"
#include "Emulator/Loader/SymbolDatabase.h"
#ifdef KYTY_EMU_ENABLED
+1 -1
View File
@@ -1,7 +1,7 @@
#include "Emulator/Common.h"
#include "Emulator/Dialog.h"
#include "Emulator/Libs/Libs.h"
#include "Emulator/SymbolDatabase.h"
#include "Emulator/Loader/SymbolDatabase.h"
#ifdef KYTY_EMU_ENABLED
+1 -1
View File
@@ -3,7 +3,7 @@
#include "Emulator/Common.h"
#include "Emulator/Libs/Libs.h"
#include "Emulator/SymbolDatabase.h"
#include "Emulator/Loader/SymbolDatabase.h"
#ifdef KYTY_EMU_ENABLED
@@ -1,7 +1,7 @@
#include "Emulator/Common.h"
#include "Emulator/Graphics/Graphics.h"
#include "Emulator/Libs/Libs.h"
#include "Emulator/SymbolDatabase.h"
#include "Emulator/Loader/SymbolDatabase.h"
#ifdef KYTY_EMU_ENABLED
+2 -2
View File
@@ -14,8 +14,8 @@
#include "Emulator/Kernel/Semaphore.h"
#include "Emulator/Libs/Errno.h"
#include "Emulator/Libs/Libs.h"
#include "Emulator/RuntimeLinker.h"
#include "Emulator/SymbolDatabase.h"
#include "Emulator/Loader/RuntimeLinker.h"
#include "Emulator/Loader/SymbolDatabase.h"
#include <cstdlib>
+1 -1
View File
@@ -2,8 +2,8 @@
#include "Emulator/Common.h"
#include "Emulator/Libs/Libs.h"
#include "Emulator/Loader/SymbolDatabase.h"
#include "Emulator/Network.h"
#include "Emulator/SymbolDatabase.h"
#ifdef KYTY_EMU_ENABLED
+1 -1
View File
@@ -1,7 +1,7 @@
#include "Emulator/Common.h"
#include "Emulator/Controller.h"
#include "Emulator/Libs/Libs.h"
#include "Emulator/SymbolDatabase.h"
#include "Emulator/Loader/SymbolDatabase.h"
#ifdef KYTY_EMU_ENABLED
+1 -1
View File
@@ -5,7 +5,7 @@
#include "Emulator/Common.h"
#include "Emulator/Libs/Errno.h"
#include "Emulator/Libs/Libs.h"
#include "Emulator/SymbolDatabase.h"
#include "Emulator/Loader/SymbolDatabase.h"
#ifdef KYTY_EMU_ENABLED
+1 -1
View File
@@ -7,7 +7,7 @@
#include "Emulator/Kernel/FileSystem.h"
#include "Emulator/Libs/Errno.h"
#include "Emulator/Libs/Libs.h"
#include "Emulator/SymbolDatabase.h"
#include "Emulator/Loader/SymbolDatabase.h"
#ifdef KYTY_EMU_ENABLED
+1 -1
View File
@@ -4,7 +4,7 @@
#include "Emulator/Common.h"
#include "Emulator/Libs/Libs.h"
#include "Emulator/SymbolDatabase.h"
#include "Emulator/Loader/SymbolDatabase.h"
#ifdef KYTY_EMU_ENABLED
@@ -5,7 +5,7 @@
#include "Emulator/Common.h"
#include "Emulator/Libs/Errno.h"
#include "Emulator/Libs/Libs.h"
#include "Emulator/SymbolDatabase.h"
#include "Emulator/Loader/SymbolDatabase.h"
#ifdef KYTY_EMU_ENABLED
+1 -1
View File
@@ -4,7 +4,7 @@
#include "Emulator/Common.h"
#include "Emulator/Libs/Errno.h"
#include "Emulator/Libs/Libs.h"
#include "Emulator/SymbolDatabase.h"
#include "Emulator/Loader/SymbolDatabase.h"
#include <cstdio>
+1 -1
View File
@@ -1,7 +1,7 @@
#include "Emulator/Common.h"
#include "Emulator/Graphics/VideoOut.h"
#include "Emulator/Libs/Libs.h"
#include "Emulator/SymbolDatabase.h"
#include "Emulator/Loader/SymbolDatabase.h"
#ifdef KYTY_EMU_ENABLED
@@ -1,4 +1,4 @@
#include "Emulator/Elf.h"
#include "Emulator/Loader/Elf.h"
#include "Kyty/Core/DbgAssert.h"
#include "Kyty/Core/File.h"
+327
View File
@@ -0,0 +1,327 @@
#include "Emulator/Loader/Param.h"
#include "Kyty/Core/ByteBuffer.h"
#include "Kyty/Core/Common.h"
#include "Kyty/Core/DbgAssert.h"
#include "Kyty/Core/File.h"
#include "Kyty/Core/Singleton.h"
#include "Kyty/Core/Threads.h"
#include "Emulator/Graphics/Image.h"
#ifdef KYTY_EMU_ENABLED
namespace Kyty::Loader {
class Psf
{
public:
Psf() = default;
virtual ~Psf();
KYTY_CLASS_NO_COPY(Psf);
void Open(const String& file_name);
void Close();
bool IsValid();
bool GetParamInt(const char* name, int32_t* value);
bool GetParamString(const char* name, String* value);
bool GetParamString(const char* name, char* value, size_t value_size);
void DbgPrint();
private:
struct ParamInfo
{
uint16_t name_offset;
uint16_t type;
uint32_t size1;
uint32_t size2;
uint32_t value_offset;
};
Core::File m_f;
Core::Mutex m_mutex;
bool m_opened = false;
uint32_t m_name_tbl_offset = 0;
uint32_t m_value_tbl_offset = 0;
uint32_t m_params_num = 0;
ParamInfo* m_params = nullptr;
char* m_name_tbl = nullptr;
};
struct SystemContent
{
String psf_path;
Psf psf;
String icon_path;
Libs::Graphics::Image* icon = nullptr;
};
Psf::~Psf()
{
Close();
}
void Psf::Open(const String& file_name)
{
Core::LockGuard lock(m_mutex);
Close();
m_f.Open(file_name, Core::File::Mode::Read);
if (m_f.IsInvalid())
{
printf("Can't open %s\n", file_name.C_Str());
return;
}
uint32_t magic1 = 0;
uint32_t magic2 = 0;
m_f.Read(&magic1, 4);
m_f.Read(&magic2, 4);
if (magic1 != 0x46535000 && magic2 != 0x00000101)
{
printf("invalid file: magic1 = %08" PRIx32 ", magic2 = %08" PRIx32 "\n", magic1, magic2);
return;
}
m_f.Read(&m_name_tbl_offset, 4);
m_f.Read(&m_value_tbl_offset, 4);
m_f.Read(&m_params_num, 4);
EXIT_NOT_IMPLEMENTED(m_name_tbl_offset == 0);
EXIT_NOT_IMPLEMENTED(m_value_tbl_offset == 0);
EXIT_NOT_IMPLEMENTED(m_value_tbl_offset <= m_name_tbl_offset);
EXIT_NOT_IMPLEMENTED(m_params_num == 0);
uint32_t name_tbl_size = m_value_tbl_offset - m_name_tbl_offset;
m_params = new ParamInfo[m_params_num];
m_name_tbl = new char[name_tbl_size];
for (uint32_t i = 0; i < m_params_num; i++)
{
m_f.Read(&m_params[i].name_offset, 2);
m_f.Read(&m_params[i].type, 2);
m_f.Read(&m_params[i].size1, 4);
m_f.Read(&m_params[i].size2, 4);
m_f.Read(&m_params[i].value_offset, 4);
if (m_params[i].type != 0x0204 && m_params[i].type != 0x0404)
{
printf("unknown type %02" PRIx16 "\n", m_params[i].type);
return;
}
}
m_f.Seek(m_name_tbl_offset);
m_f.Read(m_name_tbl, name_tbl_size);
m_opened = true;
}
void Psf::Close()
{
Core::LockGuard lock(m_mutex);
if (!m_f.IsInvalid())
{
m_f.Close();
}
delete[] m_params;
delete[] m_name_tbl;
m_name_tbl = nullptr;
m_params = nullptr;
m_opened = false;
}
bool Psf::IsValid()
{
Core::LockGuard lock(m_mutex);
return m_opened;
}
void Psf::DbgPrint()
{
Core::LockGuard lock(m_mutex);
if (m_opened)
{
for (uint32_t i = 0; i < m_params_num; i++)
{
printf("%s, ", m_name_tbl + m_params[i].name_offset);
switch (m_params[i].type)
{
case 0x0204:
{
m_f.Seek(m_value_tbl_offset + m_params[i].value_offset);
auto buf = m_f.Read(m_params[i].size1);
auto str = String::FromUtf8(reinterpret_cast<const char*>(buf.GetDataConst())).ReplaceChar(U'\n', U',');
printf("string = %s\n", str.C_Str());
break;
}
case 0x0404:
{
uint32_t value = 0;
m_f.Seek(m_value_tbl_offset + m_params[i].value_offset);
m_f.Read(&value, 4);
printf("int = 0x%08" PRIx32 "\n", value);
break;
}
default: EXIT("unknown type %02" PRIx16 "\n", m_params[i].type);
}
}
}
}
bool Psf::GetParamInt(const char* name, int32_t* value)
{
Core::LockGuard lock(m_mutex);
if (m_opened)
{
for (uint32_t i = 0; i < m_params_num; i++)
{
if (strcmp(name, m_name_tbl + m_params[i].name_offset) == 0 && m_params[i].type == 0x0404 && m_params[i].size1 == 4)
{
m_f.Seek(m_value_tbl_offset + m_params[i].value_offset);
m_f.Read(value, 4);
return true;
}
}
}
return false;
}
bool Psf::GetParamString(const char* name, String* value)
{
Core::LockGuard lock(m_mutex);
if (m_opened)
{
for (uint32_t i = 0; i < m_params_num; i++)
{
if (strcmp(name, m_name_tbl + m_params[i].name_offset) == 0 && m_params[i].type == 0x0204)
{
m_f.Seek(m_value_tbl_offset + m_params[i].value_offset);
auto buf = m_f.Read(m_params[i].size1);
*value = String::FromUtf8(reinterpret_cast<const char*>(buf.GetDataConst()));
return true;
}
}
}
return false;
}
bool Psf::GetParamString(const char* name, char* value, size_t value_size)
{
Core::LockGuard lock(m_mutex);
if (m_opened)
{
for (uint32_t i = 0; i < m_params_num; i++)
{
if (strcmp(name, m_name_tbl + m_params[i].name_offset) == 0 && m_params[i].type == 0x0204 && m_params[i].size1 <= value_size)
{
m_f.Seek(m_value_tbl_offset + m_params[i].value_offset);
m_f.Read(value, m_params[i].size1);
return true;
}
}
}
return false;
}
void ParamSfoLoad(const String& file_name)
{
auto* sc = Core::Singleton<SystemContent>::Instance();
if (!Core::File::IsFileExisting(file_name))
{
EXIT("Can't find file: %s\n", file_name.C_Str());
}
sc->psf.Open(file_name);
if (!sc->psf.IsValid())
{
EXIT("invalid file: %s\n", file_name.C_Str());
}
sc->psf_path = file_name;
sc->psf.DbgPrint();
sc->icon_path = file_name.DirectoryWithoutFilename() + U"icon0.png";
delete sc->icon;
if (Core::File::IsFileExisting(sc->icon_path))
{
sc->icon = new Libs::Graphics::Image(sc->icon_path);
sc->icon->Load();
} else
{
sc->icon = nullptr;
}
}
bool ParamSfoGetInt(const char* name, int32_t* value)
{
if (name == nullptr || value == nullptr)
{
return false;
}
auto* sc = Core::Singleton<SystemContent>::Instance();
return sc->psf.GetParamInt(name, value);
}
bool ParamSfoGetString(const char* name, String* value)
{
if (name == nullptr || value == nullptr)
{
return false;
}
auto* sc = Core::Singleton<SystemContent>::Instance();
return sc->psf.GetParamString(name, value);
}
bool ParamSfoGetString(const char* name, char* value, size_t value_size)
{
if (name == nullptr || value == nullptr)
{
return false;
}
auto* sc = Core::Singleton<SystemContent>::Instance();
return sc->psf.GetParamString(name, value, value_size);
}
Libs::Graphics::Image* ParamSfoGetIcon()
{
auto* sc = Core::Singleton<SystemContent>::Instance();
return sc->icon;
}
} // namespace Kyty::Loader
#endif // KYTY_EMU_ENABLED
@@ -1,4 +1,4 @@
#include "Emulator/RuntimeLinker.h"
#include "Emulator/Loader/RuntimeLinker.h"
#include "Kyty/Core/Common.h"
#include "Kyty/Core/DbgAssert.h"
@@ -9,13 +9,13 @@
#include "Kyty/Core/Threads.h"
#include "Kyty/Sys/SysDbg.h"
#include "Emulator/Elf.h"
#include "Emulator/Graphics/Objects/GpuMemory.h"
#include "Emulator/Jit.h"
#include "Emulator/Kernel/Pthread.h"
#include "Emulator/Loader/Elf.h"
#include "Emulator/Loader/Jit.h"
#include "Emulator/Loader/SymbolDatabase.h"
#include "Emulator/Loader/VirtualMemory.h"
#include "Emulator/Profiler.h"
#include "Emulator/SymbolDatabase.h"
#include "Emulator/VirtualMemory.h"
#ifdef KYTY_EMU_ENABLED
@@ -725,9 +725,10 @@ Program* RuntimeLinker::LoadProgram(const String& elf_name)
Libs::LibKernel::SetProgName(elf_name.FilenameWithoutDirectory());
}
if (elf_name.FilenameWithoutExtension().EndsWith(U"libc") || elf_name.FilenameWithoutExtension().EndsWith(U"Fios2") ||
if (/*elf_name.FilenameWithoutExtension().EndsWith(U"libc") || elf_name.FilenameWithoutExtension().EndsWith(U"Fios2") ||
elf_name.FilenameWithoutExtension().EndsWith(U"Fios2_debug") || elf_name.FilenameWithoutExtension().EndsWith(U"NpToolkit") ||
elf_name.FilenameWithoutExtension().EndsWith(U"NpToolkit2") || elf_name.FilenameWithoutExtension().EndsWith(U"JobManager"))
elf_name.FilenameWithoutExtension().EndsWith(U"NpToolkit2") || elf_name.FilenameWithoutExtension().EndsWith(U"JobManager")*/
elf_name.DirectoryWithoutFilename().EndsWith(U"_module/", String::Case::Insensitive))
{
program->fail_if_global_not_resolved = false;
}
@@ -1,4 +1,4 @@
#include "Emulator/SymbolDatabase.h"
#include "Emulator/Loader/SymbolDatabase.h"
#include "Kyty/Core/File.h"
#include "Kyty/Core/MagicEnum.h"
@@ -4,7 +4,7 @@
#include "Kyty/Core/Subsystems.h"
#include "Emulator/Common.h"
#include "Emulator/Timer.h"
#include "Emulator/Loader/Timer.h"
#ifdef KYTY_EMU_ENABLED
@@ -1,9 +1,9 @@
#include "Emulator/VirtualMemory.h"
#include "Emulator/Loader/VirtualMemory.h"
#include "Kyty/Core/DbgAssert.h"
#include "Emulator/Common.h"
#include "Emulator/Jit.h"
#include "Emulator/Loader/Jit.h"
#include "Emulator/Profiler.h"
#include "cpuinfo.h"