mirror of https://github.com/InoriRus/Kyty.git
load param.sfo
This commit is contained in:
parent
50b54b2607
commit
877560b7f6
|
@ -1,4 +1,4 @@
|
|||
version: 0.1.3.build-{build}
|
||||
version: 0.1.4.build-{build}
|
||||
image: Visual Studio 2019
|
||||
environment:
|
||||
matrix:
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
This software is available under 2 licenses -- choose whichever you prefer.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE A - MIT License
|
||||
Copyright (c) 2017 Sean Barrett
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||
This is free and unencumbered software released into the public domain.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
commercial or non-commercial, and by any means.
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
this software under copyright law.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
File diff suppressed because it is too large
Load Diff
|
@ -82,7 +82,7 @@ if (KYTY_LINKER STREQUAL LD)
|
|||
set(KYTY_LD_OPTIONS "-Wl,--image-base=0x100000000000")
|
||||
endif()
|
||||
|
||||
project(Kyty${KYTY_PROJECT_NAME}${CMAKE_BUILD_TYPE}${KYTY_COMPILER} VERSION 0.1.3)
|
||||
project(Kyty${KYTY_PROJECT_NAME}${CMAKE_BUILD_TYPE}${KYTY_COMPILER} VERSION 0.1.4)
|
||||
|
||||
include(src_script.cmake)
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ file(GLOB emulator_src
|
|||
src/Graphics/*.cpp
|
||||
src/Graphics/Objects/*.cpp
|
||||
src/Kernel/*.cpp
|
||||
src/Loader/*.cpp
|
||||
include/*.h
|
||||
)
|
||||
|
||||
|
@ -27,6 +28,7 @@ list(APPEND inc_headers
|
|||
${CMAKE_SOURCE_DIR}/3rdparty/easy_profiler/include
|
||||
${CMAKE_SOURCE_DIR}/3rdparty/xxhash/include
|
||||
${CMAKE_SOURCE_DIR}/3rdparty/cpuinfo/include
|
||||
${CMAKE_SOURCE_DIR}/3rdparty/stb
|
||||
)
|
||||
|
||||
if (MSVC AND CLANG)
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
#include "Kyty/Core/Common.h"
|
||||
|
||||
#if (KYTY_COMPILER == KYTY_COMPILER_CLANG || KYTY_COMPILER == KYTY_COMPILER_MINGW) && KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS && KYTY_BITNESS == 64 && \
|
||||
KYTY_ENDIAN == KYTY_ENDIAN_LITTLE && KYTY_ABI == KYTY_ABI_X86_64 && KYTY_PROJECT == KYTY_PROJECT_EMULATOR
|
||||
#if (KYTY_COMPILER == KYTY_COMPILER_CLANG || KYTY_COMPILER == KYTY_COMPILER_MINGW) && KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS && \
|
||||
KYTY_BITNESS == 64 && KYTY_ENDIAN == KYTY_ENDIAN_LITTLE && KYTY_ABI == KYTY_ABI_X86_64 && KYTY_PROJECT == KYTY_PROJECT_EMULATOR
|
||||
#define KYTY_EMU_ENABLED
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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_ */
|
|
@ -4,7 +4,7 @@
|
|||
#include "Kyty/Core/String.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
#include "Emulator/Timer.h" // IWYU pragma: keep
|
||||
#include "Emulator/Loader/Timer.h" // IWYU pragma: keep
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef EMULATOR_INCLUDE_EMULATOR_ELF_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_ELF_H_
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_LOADER_ELF_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_LOADER_ELF_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/String.h"
|
||||
|
@ -306,4 +306,4 @@ private:
|
|||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_ELF_H_ */
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_LOADER_ELF_H_ */
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef EMULATOR_INCLUDE_EMULATOR_JIT_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_JIT_H_
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_LOADER_JIT_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_LOADER_JIT_H_
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
|
||||
|
@ -147,4 +147,4 @@ struct SafeCall
|
|||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_JIT_H_ */
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_LOADER_JIT_H_ */
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef EMULATOR_INCLUDE_EMULATOR_LOADER_PARAM_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_LOADER_PARAM_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/String.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
class Image;
|
||||
} // namespace Kyty::Libs::Graphics
|
||||
|
||||
namespace Kyty::Loader {
|
||||
|
||||
void ParamSfoLoad(const String& file_name);
|
||||
bool ParamSfoGetInt(const char* name, int32_t* value);
|
||||
bool ParamSfoGetString(const char* name, String* value);
|
||||
bool ParamSfoGetString(const char* name, char* value, size_t value_size);
|
||||
Libs::Graphics::Image* ParamSfoGetIcon();
|
||||
|
||||
} // namespace Kyty::Loader
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_LOADER_PARAM_H_ */
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef EMULATOR_INCLUDE_EMULATOR_RUNTIMELINKER_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_RUNTIMELINKER_H_
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_LOADER_RUNTIMELINKER_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_LOADER_RUNTIMELINKER_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/Hashmap.h"
|
||||
|
@ -8,7 +8,7 @@
|
|||
#include "Kyty/Core/Vector.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
#include "Emulator/SymbolDatabase.h"
|
||||
#include "Emulator/Loader/SymbolDatabase.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
|
@ -186,4 +186,4 @@ private:
|
|||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_RUNTIMELINKER_H_ */
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_LOADER_RUNTIMELINKER_H_ */
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef EMULATOR_INCLUDE_EMULATOR_SYMBOLDATABASE_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_SYMBOLDATABASE_H_
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_LOADER_SYMBOLDATABASE_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_LOADER_SYMBOLDATABASE_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/Hashmap.h"
|
||||
|
@ -65,4 +65,4 @@ private:
|
|||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_SYMBOLDATABASE_H_ */
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_LOADER_SYMBOLDATABASE_H_ */
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef EMULATOR_INCLUDE_EMULATOR_TIMER_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_TIMER_H_
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_LOADER_TIMER_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_LOADER_TIMER_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/DateTime.h"
|
||||
|
@ -23,4 +23,4 @@ uint64_t GetFrequency();
|
|||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_TIMER_H_ */
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_LOADER_TIMER_H_ */
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef EMULATOR_INCLUDE_EMULATOR_VIRTUALMEMORY_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_VIRTUALMEMORY_H_
|
||||
#ifndef EMULATOR_INCLUDE_EMULATOR_LOADER_VIRTUALMEMORY_H_
|
||||
#define EMULATOR_INCLUDE_EMULATOR_LOADER_VIRTUALMEMORY_H_
|
||||
|
||||
#include "Kyty/Core/Common.h"
|
||||
#include "Kyty/Core/String.h"
|
||||
|
@ -112,4 +112,4 @@ bool PatchReplace(uint64_t vaddr, uint64_t value);
|
|||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_VIRTUALMEMORY_H_ */
|
||||
#endif /* EMULATOR_INCLUDE_EMULATOR_LOADER_VIRTUALMEMORY_H_ */
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,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
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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/Dialog.h"
|
||||
#include "Emulator/Libs/Libs.h"
|
||||
#include "Emulator/SymbolDatabase.h"
|
||||
#include "Emulator/Loader/SymbolDatabase.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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,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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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,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"
|
|
@ -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"
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>697</width>
|
||||
<height>587</height>
|
||||
<width>837</width>
|
||||
<height>822</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -17,6 +17,19 @@
|
|||
<locale language="English" country="UnitedStates"/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0" rowspan="2">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="sizeConstraint">
|
||||
|
@ -89,6 +102,12 @@
|
|||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="MandatoryLineEdit" name="base_directory_lineedit">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>550</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Name of the directory where game is located</p></body></html></string>
|
||||
</property>
|
||||
|
@ -109,6 +128,43 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_17">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Param file</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="param_file_lineedit">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Path to <span style=" font-weight:600;">param.sfo</span> file</p></body></html></string>
|
||||
</property>
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="browse_param_file_button">
|
||||
<property name="text">
|
||||
<string>Browse...</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -132,20 +188,6 @@
|
|||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
<string>Screen resoultion:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="comboBox_screen_resolution">
|
||||
<property name="toolTip">
|
||||
<string>Window resolution</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QFrame" name="frame_4">
|
||||
<property name="frameShape">
|
||||
|
@ -168,19 +210,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_shader_validation">
|
||||
<property name="toolTip">
|
||||
<string>Validate SPIR-V binary</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Shader validation</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_vulkan_validation">
|
||||
<property name="toolTip">
|
||||
|
@ -194,6 +223,19 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_shader_validation">
|
||||
<property name="toolTip">
|
||||
<string>Validate SPIR-V binary</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Shader validation</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_cmd_dump">
|
||||
<property name="toolTip">
|
||||
|
@ -207,22 +249,36 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_spirv_printf">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
<item row="1" column="2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Enable GL_EXT_debug_printf extension</string>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Spirv debug printf</string>
|
||||
</property>
|
||||
</widget>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
<string>Screen resoultion:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="comboBox_screen_resolution">
|
||||
<property name="toolTip">
|
||||
<string>Window resolution</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_20">
|
||||
<property name="text">
|
||||
|
@ -237,6 +293,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_21">
|
||||
<property name="text">
|
||||
<string>Shader log direction:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="comboBox_shader_log_direction">
|
||||
<property name="toolTip">
|
||||
|
@ -244,6 +307,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_22">
|
||||
<property name="text">
|
||||
<string>Shader log folder:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="MandatoryLineEdit" name="lineEdit_shader_log_folder">
|
||||
<property name="toolTip">
|
||||
|
@ -254,6 +324,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_24">
|
||||
<property name="text">
|
||||
<string>Command buffer dump folder:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="MandatoryLineEdit" name="lineEdit_cmd_dump_folder">
|
||||
<property name="toolTip">
|
||||
|
@ -264,6 +341,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_25">
|
||||
<property name="text">
|
||||
<string>Printf direction:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QComboBox" name="comboBox_printf_direction">
|
||||
<property name="toolTip">
|
||||
|
@ -271,6 +355,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_26">
|
||||
<property name="text">
|
||||
<string>Printf output file:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="MandatoryLineEdit" name="lineEdit_printf_file">
|
||||
<property name="toolTip">
|
||||
|
@ -281,6 +372,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_27">
|
||||
<property name="text">
|
||||
<string>Profiler direction:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QComboBox" name="comboBox_profiler_direction">
|
||||
<property name="toolTip">
|
||||
|
@ -288,45 +386,10 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_21">
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="label_28">
|
||||
<property name="text">
|
||||
<string>Shader log direction:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_22">
|
||||
<property name="text">
|
||||
<string>Shader log folder:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_24">
|
||||
<property name="text">
|
||||
<string>Command buffer dump folder:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_25">
|
||||
<property name="text">
|
||||
<string>Printf direction:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_26">
|
||||
<property name="text">
|
||||
<string>Printf output file:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_27">
|
||||
<property name="text">
|
||||
<string>Profiler direction:</string>
|
||||
<string>Profiler output file:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -340,12 +403,54 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="label_28">
|
||||
<property name="text">
|
||||
<string>Profiler output file:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<item row="11" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="image">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>240</width>
|
||||
<height>135</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
@ -426,21 +531,11 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableWidget" name="params_table"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
|
|
|
@ -102,8 +102,9 @@ public:
|
|||
|
||||
Configuration() = default;
|
||||
|
||||
QString Name;
|
||||
QString BaseDir; /* Game base directory */
|
||||
QString name;
|
||||
QString basedir; /* Game base directory */
|
||||
QString param_file; /* Path to param.sfo */
|
||||
|
||||
Resolution screen_resolution = Resolution::R1280X720;
|
||||
bool neo = true;
|
||||
|
@ -118,7 +119,6 @@ public:
|
|||
QString printf_output_file = "_kyty.txt";
|
||||
ProfilerDirection profiler_direction = ProfilerDirection::None;
|
||||
QString profiler_output_file = "_profile.prof";
|
||||
bool spirv_debug_printf_enabled = false;
|
||||
|
||||
QStringList elfs;
|
||||
QStringList elfs_selected;
|
||||
|
@ -127,8 +127,9 @@ public:
|
|||
|
||||
void WriteSettings(QSettings* s) const
|
||||
{
|
||||
KYTY_CFG_SET(Name);
|
||||
KYTY_CFG_SET(BaseDir);
|
||||
KYTY_CFG_SET(name);
|
||||
KYTY_CFG_SET(basedir);
|
||||
KYTY_CFG_SET(param_file);
|
||||
KYTY_CFG_SET(screen_resolution);
|
||||
KYTY_CFG_SET(neo);
|
||||
KYTY_CFG_SET(vulkan_validation_enabled);
|
||||
|
@ -142,7 +143,6 @@ public:
|
|||
KYTY_CFG_SET(printf_output_file);
|
||||
KYTY_CFG_SET(profiler_direction);
|
||||
KYTY_CFG_SET(profiler_output_file);
|
||||
KYTY_CFG_SET(spirv_debug_printf_enabled);
|
||||
KYTY_CFG_SETL(elfs);
|
||||
KYTY_CFG_SETL(elfs_selected);
|
||||
KYTY_CFG_SETL(libs);
|
||||
|
@ -151,8 +151,9 @@ public:
|
|||
|
||||
void ReadSettings(QSettings* s)
|
||||
{
|
||||
KYTY_CFG_GET(Name);
|
||||
KYTY_CFG_GET(BaseDir);
|
||||
KYTY_CFG_GET(name);
|
||||
KYTY_CFG_GET(basedir);
|
||||
KYTY_CFG_GET(param_file);
|
||||
KYTY_CFG_GET(screen_resolution);
|
||||
KYTY_CFG_GET(neo);
|
||||
KYTY_CFG_GET(vulkan_validation_enabled);
|
||||
|
@ -166,7 +167,6 @@ public:
|
|||
KYTY_CFG_GET(printf_output_file);
|
||||
KYTY_CFG_GET(profiler_direction);
|
||||
KYTY_CFG_GET(profiler_output_file);
|
||||
KYTY_CFG_GET(spirv_debug_printf_enabled);
|
||||
KYTY_CFG_GETL(elfs);
|
||||
KYTY_CFG_GETL(elfs_selected);
|
||||
KYTY_CFG_GETL(libs);
|
||||
|
|
|
@ -53,8 +53,10 @@ protected:
|
|||
void adjust_size();
|
||||
void save();
|
||||
void browse_base_path();
|
||||
void browse_param_file();
|
||||
void scan_elfs();
|
||||
void scan_libs();
|
||||
void load_param_sfo();
|
||||
void clear();
|
||||
void test();
|
||||
};
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
#ifndef LAUNCHER_INCLUDE_PSF_H_
|
||||
#define LAUNCHER_INCLUDE_PSF_H_
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QString>
|
||||
|
||||
class Psf
|
||||
{
|
||||
public:
|
||||
Psf() = default;
|
||||
virtual ~Psf() = default;
|
||||
|
||||
KYTY_QT_CLASS_NO_COPY(Psf);
|
||||
|
||||
void Load(const QString& file_name);
|
||||
|
||||
[[nodiscard]] const QMap<QString, QVariant>& GetMap() const { return m_map; }
|
||||
|
||||
private:
|
||||
QMap<QString, QVariant> m_map;
|
||||
};
|
||||
|
||||
inline void Psf::Load(const QString& file_name)
|
||||
{
|
||||
struct ParamInfo
|
||||
{
|
||||
uint16_t name_offset;
|
||||
uint16_t type;
|
||||
uint32_t size1;
|
||||
uint32_t size2;
|
||||
uint32_t value_offset;
|
||||
};
|
||||
|
||||
QFile f(file_name);
|
||||
if (!f.open(QIODevice::ReadOnly))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QDataStream s(&f);
|
||||
|
||||
s.setByteOrder(QDataStream::LittleEndian);
|
||||
|
||||
uint32_t magic1 = 0;
|
||||
uint32_t magic2 = 0;
|
||||
|
||||
s >> magic1;
|
||||
s >> magic2;
|
||||
|
||||
if (magic1 != 0x46535000 && magic2 != 0x00000101)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t name_tbl_offset = 0;
|
||||
uint32_t value_tbl_offset = 0;
|
||||
uint32_t params_num = 0;
|
||||
|
||||
s >> name_tbl_offset;
|
||||
s >> value_tbl_offset;
|
||||
s >> params_num;
|
||||
|
||||
if (name_tbl_offset == 0 || value_tbl_offset == 0 || value_tbl_offset <= name_tbl_offset || params_num == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t name_tbl_size = value_tbl_offset - name_tbl_offset;
|
||||
|
||||
auto* params = new ParamInfo[params_num];
|
||||
auto* name_tbl = new char[name_tbl_size];
|
||||
|
||||
for (uint32_t i = 0; i < params_num; i++)
|
||||
{
|
||||
s >> params[i].name_offset;
|
||||
s >> params[i].type;
|
||||
s >> params[i].size1;
|
||||
s >> params[i].size2;
|
||||
s >> params[i].value_offset;
|
||||
}
|
||||
|
||||
s.device()->seek(name_tbl_offset);
|
||||
s.readRawData(name_tbl, static_cast<int>(name_tbl_size));
|
||||
|
||||
for (uint32_t i = 0; i < params_num; i++)
|
||||
{
|
||||
QString name = name_tbl + params[i].name_offset;
|
||||
|
||||
switch (params[i].type)
|
||||
{
|
||||
case 0x0204:
|
||||
{
|
||||
s.device()->seek(value_tbl_offset + params[i].value_offset);
|
||||
QByteArray buf(static_cast<int>(params[i].size1), Qt::Uninitialized);
|
||||
s.readRawData(buf.data(), static_cast<int>(params[i].size1));
|
||||
QString value(buf);
|
||||
m_map.insert(name, value);
|
||||
break;
|
||||
}
|
||||
case 0x0404:
|
||||
{
|
||||
uint32_t value = 0;
|
||||
s.device()->seek(value_tbl_offset + params[i].value_offset);
|
||||
s >> value;
|
||||
m_map.insert(name, value);
|
||||
break;
|
||||
}
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
delete[] params;
|
||||
delete[] name_tbl;
|
||||
}
|
||||
|
||||
#endif /* LAUNCHER_INCLUDE_PSF_H_ */
|
|
@ -4,6 +4,7 @@
|
|||
#include "ConfigurationListWidget.h"
|
||||
#include "MainDialog.h"
|
||||
#include "MandatoryLineEdit.h"
|
||||
#include "Psf.h"
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QCheckBox>
|
||||
|
@ -20,6 +21,7 @@
|
|||
#include <QListWidget>
|
||||
#include <QListWidgetItem>
|
||||
#include <QMessageBox>
|
||||
#include <QPicture>
|
||||
#include <QPushButton>
|
||||
#include <QSettings>
|
||||
#include <QStringList>
|
||||
|
@ -32,6 +34,7 @@ constexpr char SETTINGS_CFG_LAST_GEOMETRY[] = "geometry";
|
|||
constexpr char SETTINGS_LAST_BASE_DIR[] = "last_base_dir";
|
||||
constexpr char COLOR_SELECTED[] = "#e2ffe2";
|
||||
constexpr char COLOR_NOT_SELECTED[] = "#ffffff";
|
||||
constexpr char COLOR_ODD_ROW[] = "#fff5e5";
|
||||
|
||||
static void ChangeColor(QListWidgetItem* item)
|
||||
{
|
||||
|
@ -53,6 +56,7 @@ ConfigurationEditDialog::ConfigurationEditDialog(Kyty::Configuration* info, Conf
|
|||
connect(m_ui->clear_button, &QPushButton::clicked, this, &ConfigurationEditDialog::clear);
|
||||
connect(m_ui->test_button, &QPushButton::clicked, this, &ConfigurationEditDialog::test);
|
||||
connect(m_ui->browse_base_dir_button, &QPushButton::clicked, this, &ConfigurationEditDialog::browse_base_path);
|
||||
connect(m_ui->browse_param_file_button, &QPushButton::clicked, this, &ConfigurationEditDialog::browse_param_file);
|
||||
connect(m_ui->comboBox_shader_log_direction, &QComboBox::currentTextChanged,
|
||||
[=](const QString& text)
|
||||
{
|
||||
|
@ -74,6 +78,7 @@ ConfigurationEditDialog::ConfigurationEditDialog(Kyty::Configuration* info, Conf
|
|||
log == Kyty::Configuration::ProfilerDirection::FileAndNetwork);
|
||||
});
|
||||
connect(m_ui->base_directory_lineedit, &QLineEdit::textChanged, this, &ConfigurationEditDialog::scan_elfs);
|
||||
connect(m_ui->param_file_lineedit, &QLineEdit::textChanged, this, &ConfigurationEditDialog::load_param_sfo);
|
||||
connect(m_ui->listWidget_elfs, &QListWidget::itemChanged, this, &ChangeColor);
|
||||
connect(m_ui->listWidget_libs, &QListWidget::itemChanged, this, &ChangeColor);
|
||||
connect(&m_process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
|
||||
|
@ -83,10 +88,17 @@ ConfigurationEditDialog::ConfigurationEditDialog(Kyty::Configuration* info, Conf
|
|||
|
||||
restoreGeometry(g_last_geometry);
|
||||
|
||||
m_ui->params_table->setWordWrap(false);
|
||||
m_ui->params_table->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||
m_ui->params_table->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||
m_ui->params_table->horizontalHeader()->setStretchLastSection(true);
|
||||
m_ui->params_table->setStyleSheet("selection-background-color: lightgray; selection-color: black;");
|
||||
|
||||
Init();
|
||||
|
||||
scan_libs();
|
||||
scan_elfs();
|
||||
load_param_sfo();
|
||||
}
|
||||
|
||||
QString ConfigurationEditDialog::g_last_base_dir;
|
||||
|
@ -134,8 +146,9 @@ static void ListInit(QComboBox* combo, T value)
|
|||
|
||||
void ConfigurationEditDialog::Init()
|
||||
{
|
||||
m_ui->name_lineedit->setText(m_info->Name);
|
||||
m_ui->base_directory_lineedit->setText(m_info->BaseDir);
|
||||
m_ui->name_lineedit->setText(m_info->name);
|
||||
m_ui->base_directory_lineedit->setText(m_info->basedir);
|
||||
m_ui->param_file_lineedit->setText(m_info->param_file);
|
||||
ListInit(m_ui->comboBox_screen_resolution, m_info->screen_resolution);
|
||||
m_ui->checkBox_neo->setChecked(m_info->neo);
|
||||
m_ui->checkBox_shader_validation->setChecked(m_info->shader_validation_enabled);
|
||||
|
@ -149,7 +162,6 @@ void ConfigurationEditDialog::Init()
|
|||
m_ui->lineEdit_printf_file->setText(m_info->printf_output_file);
|
||||
ListInit(m_ui->comboBox_profiler_direction, m_info->profiler_direction);
|
||||
m_ui->lineEdit_profiler_file->setText(m_info->profiler_output_file);
|
||||
m_ui->checkBox_spirv_printf->setChecked(m_info->spirv_debug_printf_enabled);
|
||||
}
|
||||
|
||||
void ConfigurationEditDialog::SetTitle(const QString& str)
|
||||
|
@ -184,8 +196,9 @@ static void UpdateList(QStringList* list, QStringList* list_selected, QListWidge
|
|||
|
||||
static void UpdateInfo(Kyty::Configuration* info, Ui::ConfigurationEditDialog* ui)
|
||||
{
|
||||
info->Name = ui->name_lineedit->text();
|
||||
info->BaseDir = ui->base_directory_lineedit->text();
|
||||
info->name = ui->name_lineedit->text();
|
||||
info->basedir = ui->base_directory_lineedit->text();
|
||||
info->param_file = ui->param_file_lineedit->text();
|
||||
info->screen_resolution = TextToEnum<Kyty::Configuration::Resolution>(ui->comboBox_screen_resolution->currentText());
|
||||
info->neo = ui->checkBox_neo->isChecked();
|
||||
info->vulkan_validation_enabled = ui->checkBox_vulkan_validation->isChecked();
|
||||
|
@ -200,7 +213,6 @@ static void UpdateInfo(Kyty::Configuration* info, Ui::ConfigurationEditDialog* u
|
|||
info->printf_output_file = ui->lineEdit_printf_file->text();
|
||||
info->profiler_direction = TextToEnum<Kyty::Configuration::ProfilerDirection>(ui->comboBox_profiler_direction->currentText());
|
||||
info->profiler_output_file = ui->lineEdit_profiler_file->text();
|
||||
info->spirv_debug_printf_enabled = ui->checkBox_spirv_printf->isChecked();
|
||||
|
||||
info->elfs.clear();
|
||||
info->elfs_selected.clear();
|
||||
|
@ -258,6 +270,23 @@ void ConfigurationEditDialog::browse_base_path()
|
|||
}
|
||||
}
|
||||
|
||||
void ConfigurationEditDialog::browse_param_file()
|
||||
{
|
||||
QString text = m_ui->param_file_lineedit->text();
|
||||
|
||||
if (text.isEmpty())
|
||||
{
|
||||
text = m_ui->base_directory_lineedit->text();
|
||||
}
|
||||
|
||||
QString file = QFileDialog::getOpenFileName(this, tr("Select param.sfo"), text.isEmpty() ? g_last_base_dir : text, "param.sfo");
|
||||
|
||||
if (!file.isEmpty())
|
||||
{
|
||||
m_ui->param_file_lineedit->setText(file);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigurationEditDialog::scan_elfs()
|
||||
{
|
||||
auto dir = m_ui->base_directory_lineedit->text();
|
||||
|
@ -356,6 +385,62 @@ void ConfigurationEditDialog::scan_libs()
|
|||
m_ui->listWidget_libs->sortItems();
|
||||
}
|
||||
|
||||
void ConfigurationEditDialog::load_param_sfo()
|
||||
{
|
||||
auto file_name = m_ui->param_file_lineedit->text();
|
||||
|
||||
m_ui->image->clear();
|
||||
m_ui->params_table->clear();
|
||||
m_ui->params_table->setRowCount(0);
|
||||
m_ui->params_table->setColumnCount(2);
|
||||
m_ui->params_table->setHorizontalHeaderLabels({tr("Parameter"), tr("Value")});
|
||||
m_ui->params_table->resizeColumnsToContents();
|
||||
|
||||
QFile param(file_name);
|
||||
|
||||
if (param.exists())
|
||||
{
|
||||
Psf psf;
|
||||
psf.Load(file_name);
|
||||
|
||||
const auto& map = psf.GetMap();
|
||||
|
||||
m_ui->params_table->setColumnCount(2);
|
||||
m_ui->params_table->setRowCount(map.size());
|
||||
|
||||
int index = 0;
|
||||
for (auto& m: map.toStdMap())
|
||||
{
|
||||
auto* item1 = new QTableWidgetItem(m.first);
|
||||
item1->setFlags(item1->flags() ^ Qt::ItemIsEditable);
|
||||
auto* item2 = new QTableWidgetItem(
|
||||
m.second.type() == QVariant::UInt ? QString("0x%1").arg(m.second.toUInt(), 8, 16, QLatin1Char('0')) : m.second.toString());
|
||||
item2->setFlags(item2->flags() ^ Qt::ItemIsEditable);
|
||||
if (index % 2 != 0)
|
||||
{
|
||||
item1->setBackground(QColor(COLOR_ODD_ROW));
|
||||
item2->setBackground(QColor(COLOR_ODD_ROW));
|
||||
}
|
||||
m_ui->params_table->setItem(index, 0, item1);
|
||||
m_ui->params_table->setItem(index, 1, item2);
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
m_ui->params_table->resizeRowsToContents();
|
||||
m_ui->params_table->resizeColumnToContents(0);
|
||||
|
||||
QFile image(QFileInfo(file_name).absoluteDir().filePath("pic1.png"));
|
||||
|
||||
if (image.exists())
|
||||
{
|
||||
QPixmap picture;
|
||||
picture.load(image.fileName());
|
||||
m_ui->image->setPixmap(picture.scaledToWidth(m_ui->image->width(), Qt::SmoothTransformation));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigurationEditDialog::clear()
|
||||
{
|
||||
auto* old_info = m_info;
|
||||
|
@ -368,6 +453,7 @@ void ConfigurationEditDialog::clear()
|
|||
|
||||
scan_elfs();
|
||||
scan_libs();
|
||||
load_param_sfo();
|
||||
}
|
||||
|
||||
void ConfigurationEditDialog::test()
|
||||
|
|
|
@ -11,7 +11,7 @@ ConfigurationItem::ConfigurationItem(Kyty::Configuration* info, QListWidget* par
|
|||
setSizeHint(QSize(0, 18));
|
||||
if (m_info != nullptr)
|
||||
{
|
||||
setText(m_info->Name);
|
||||
setText(m_info->name);
|
||||
}
|
||||
SetRunning(false);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ void ConfigurationItem::Update()
|
|||
{
|
||||
if (m_info != nullptr)
|
||||
{
|
||||
setText(m_info->Name);
|
||||
setText(m_info->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ constexpr char KYTY_MOUNT[] = "kyty_mount";
|
|||
constexpr char KYTY_EXECUTE[] = "kyty_execute";
|
||||
constexpr char KYTY_LOAD_ELF[] = "kyty_load_elf";
|
||||
constexpr char KYTY_LOAD_SYMBOLS[] = "kyty_load_symbols";
|
||||
constexpr char KYTY_LOAD_PARAM_SFO[] = "kyty_load_param_sfo";
|
||||
constexpr char KYTY_INIT[] = "kyty_init";
|
||||
constexpr char KYTY_LUA_FILE[] = "kyty_run.lua";
|
||||
constexpr DWORD CMD_X_CHARS = 175;
|
||||
|
@ -183,6 +184,7 @@ void MainDialogPrivate::FindInterpreter()
|
|||
found = found && lines.contains(QString("Lua function: ") + KYTY_EXECUTE);
|
||||
found = found && lines.contains(QString("Lua function: ") + KYTY_LOAD_ELF);
|
||||
found = found && lines.contains(QString("Lua function: ") + KYTY_LOAD_SYMBOLS);
|
||||
found = found && lines.contains(QString("Lua function: ") + KYTY_LOAD_PARAM_SFO);
|
||||
found = found && lines.contains(QString("Lua function: ") + KYTY_INIT);
|
||||
}
|
||||
|
||||
|
@ -234,11 +236,13 @@ static bool CreateLuaScript(Kyty::Configuration* info, const QString& file_name)
|
|||
s << "\t PrintfOutputFile = '" << info->printf_output_file << "';\n";
|
||||
s << "\t ProfilerDirection = '" << EnumToText(info->profiler_direction) << "';\n";
|
||||
s << "\t ProfilerOutputFile = '" << info->profiler_output_file << "';\n";
|
||||
s << "\t SpirvDebugPrintfEnabled = " << (info->spirv_debug_printf_enabled ? "true" : "false") << ";\n";
|
||||
s << "\t SpirvDebugPrintfEnabled = false;\n";
|
||||
s << "}\n";
|
||||
|
||||
s << KYTY_INIT << "(cfg);\n";
|
||||
s << KYTY_MOUNT << "('" << info->BaseDir << "', '/app0');\n";
|
||||
s << KYTY_MOUNT << "('" << info->basedir << "', '/app0');\n";
|
||||
|
||||
s << KYTY_LOAD_PARAM_SFO << "('" << info->param_file << "');\n";
|
||||
|
||||
for (const auto& elf: info->elfs_selected)
|
||||
{
|
||||
|
@ -357,7 +361,7 @@ void MainDialogPrivate::Update()
|
|||
if (run_enabled && item != nullptr)
|
||||
{
|
||||
const auto* info = item->GetInfo();
|
||||
auto dir = info->BaseDir;
|
||||
auto dir = info->basedir;
|
||||
run_enabled = !dir.isEmpty() && QDir(dir).exists();
|
||||
}
|
||||
|
||||
|
|
|
@ -9,225 +9,241 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="43"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="56"/>
|
||||
<source>Name:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="50"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="63"/>
|
||||
<source><html><head/><body><p>Configuration name</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="84"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="97"/>
|
||||
<source>Mount app0 to</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="93"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="112"/>
|
||||
<source><html><head/><body><p>Name of the directory where game is located</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="103"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="122"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="159"/>
|
||||
<source>Browse...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="138"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="271"/>
|
||||
<source>Screen resoultion:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="145"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="278"/>
|
||||
<source>Window resolution</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="161"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="203"/>
|
||||
<source>Enable PS4 Pro mode</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="164"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="206"/>
|
||||
<source>Neo</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="174"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="229"/>
|
||||
<source>Validate SPIR-V binary</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="177"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="232"/>
|
||||
<source>Shader validation</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="187"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="216"/>
|
||||
<source>Enable Vulkan validation layers</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="190"/>
|
||||
<source>Vulkan validation</source>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="140"/>
|
||||
<source>Param file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="200"/>
|
||||
<source>Dump command buffers</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="203"/>
|
||||
<source>Command buffer dump</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="216"/>
|
||||
<source>Enable GL_EXT_debug_printf extension</source>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="149"/>
|
||||
<source><html><head/><body><p>Path to <span style=" font-weight:600;">param.sfo</span> file</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="219"/>
|
||||
<source>Spirv debug printf</source>
|
||||
<source>Vulkan validation</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="229"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="242"/>
|
||||
<source>Dump command buffers</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="245"/>
|
||||
<source>Command buffer dump</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="285"/>
|
||||
<source>Shader optimization type:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="236"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="292"/>
|
||||
<source>Optimize shaders for code size or performance</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="243"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="306"/>
|
||||
<source>Dump shaders to file or console window. If enabled may decrease emulator performance</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="250"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="320"/>
|
||||
<source>Specify directory to dump shaders</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="260"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="337"/>
|
||||
<source>Specify directory to dump command buffers</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="270"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="354"/>
|
||||
<source>Print logs to file or console window. If enabled may decrease emulator performance</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="277"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="368"/>
|
||||
<source>Specify file to dump logs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="287"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="385"/>
|
||||
<source>Enable/disable profiler. If enabled may decrease emulator performance</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="294"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="299"/>
|
||||
<source>Shader log direction:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="301"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="313"/>
|
||||
<source>Shader log folder:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="308"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="330"/>
|
||||
<source>Command buffer dump folder:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="315"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="347"/>
|
||||
<source>Printf direction:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="322"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="361"/>
|
||||
<source>Printf output file:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="329"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="378"/>
|
||||
<source>Profiler direction:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="336"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="399"/>
|
||||
<source>Specify file to dump profiler info</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="346"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="392"/>
|
||||
<source>Profiler output file:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="373"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="478"/>
|
||||
<source>Load elf:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="380"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="485"/>
|
||||
<source>Select executables to load</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="408"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="513"/>
|
||||
<source>Select libraries to load</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="418"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="523"/>
|
||||
<source>Load library:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="455"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="550"/>
|
||||
<source>Save</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="471"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="566"/>
|
||||
<source>Cancel</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="491"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="586"/>
|
||||
<source>Clear</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="507"/>
|
||||
<location filename="../forms/configuration_edit_dialog.ui" line="602"/>
|
||||
<source>Test</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/ConfigurationEditDialog.cpp" line="239"/>
|
||||
<location filename="../src/ConfigurationEditDialog.cpp" line="251"/>
|
||||
<source>Save failed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/ConfigurationEditDialog.cpp" line="239"/>
|
||||
<location filename="../src/ConfigurationEditDialog.cpp" line="251"/>
|
||||
<source>Please fill all mandatory fields</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/ConfigurationEditDialog.cpp" line="252"/>
|
||||
<location filename="../src/ConfigurationEditDialog.cpp" line="264"/>
|
||||
<source>Open Directory</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/ConfigurationEditDialog.cpp" line="282"/>
|
||||
<source>Select param.sfo</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/ConfigurationEditDialog.cpp" line="396"/>
|
||||
<source>Parameter</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/ConfigurationEditDialog.cpp" line="396"/>
|
||||
<source>Value</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ConfigurationListWidget</name>
|
||||
|
@ -322,12 +338,12 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainDialog.cpp" line="272"/>
|
||||
<location filename="../src/MainDialog.cpp" line="276"/>
|
||||
<source>Error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainDialog.cpp" line="272"/>
|
||||
<location filename="../src/MainDialog.cpp" line="276"/>
|
||||
<source>Can't create file:
|
||||
</source>
|
||||
<translation type="unfinished"></translation>
|
||||
|
@ -336,27 +352,27 @@
|
|||
<context>
|
||||
<name>MainDialogPrivate</name>
|
||||
<message>
|
||||
<location filename="../src/MainDialog.cpp" line="138"/>
|
||||
<location filename="../src/MainDialog.cpp" line="139"/>
|
||||
<source>Settings file: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainDialog.cpp" line="164"/>
|
||||
<location filename="../src/MainDialog.cpp" line="165"/>
|
||||
<source>Emulator: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainDialog.cpp" line="176"/>
|
||||
<location filename="../src/MainDialog.cpp" line="177"/>
|
||||
<source>Version: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainDialog.cpp" line="191"/>
|
||||
<location filename="../src/MainDialog.cpp" line="193"/>
|
||||
<source>Error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainDialog.cpp" line="191"/>
|
||||
<location filename="../src/MainDialog.cpp" line="193"/>
|
||||
<source>Can't find emulator</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
|
|
@ -13,7 +13,7 @@ add_library(unit_test STATIC ${unit_test_src})
|
|||
target_link_libraries(unit_test core)
|
||||
target_link_libraries(unit_test math)
|
||||
|
||||
target_include_directories(unit_test PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
#target_include_directories(unit_test PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
|
||||
list(APPEND inc_headers
|
||||
${PROJECT_BINARY_DIR}
|
||||
|
|
Loading…
Reference in New Issue