Adapted from Changelog:

- swr -> Rubidium
- LIFont (TTF Font Renderer)
- Implement shbin as c++ array
- Larger Mesaage Box
- Add Texture Loader
- Update Image/Error and other sytems to Lithium
- Optimize Render2 for Lithium
This commit is contained in:
tobid7 2024-08-02 13:50:36 +02:00
parent 02172d8aef
commit a58dc20562
41 changed files with 1182 additions and 922 deletions

View File

@ -1,7 +1,14 @@
# Palladium Changelog # Palladium Changelog
## 1.0.0 ## 1.0.0
- Switch from C2D to LI7 - Switch from C2D to Lithium (LI7)
- For the Rest See RenderD7 Changelog below - For the Rest See RenderD7 Changelog below
- swr -> Rubidium
- LIFont (TTF Font Renderer)
- Implement shbin as c++ array
- Larger Mesaage Box
- Add Texture Loader
- Update Image/Error and other sytems to Lithium
- Optimize Render2 for Lithium
# RenderD7 Changelog # RenderD7 Changelog
## 0.9.5 ## 0.9.5
- Remove Npi Intro and NVID Api - Remove Npi Intro and NVID Api

65
build_shaders.py Normal file
View File

@ -0,0 +1,65 @@
import os
import glob
import shutil
from pathlib import Path
# Simple Script to generate/update Shaders
# WHY? Cause having this stupid .v.pica files in
# sourcecode is pain with some buildsystems
def file2array(path, custom_incluse_path):
print(path)
cip = len(custom_incluse_path)
sip = ''
if cip > 0:
sip = custom_incluse_path
name = Path(path).stem
filei = open(path, 'rb')
buf = filei.read()
filei.close()
fs = open(name + '.cpp', 'w')
fs.write("// THIS FILE WAS GENERATED BY build_shaders.py!!!\n\n")
fs.write('#include <'+ sip + name + '.hpp>\n\n')
fs.write('// clang-format off\n')
fs.write('unsigned char ' + name + '[] = {\n')
for byte in buf:
fs.write(hex(byte) + ', ')
fs.write('\n};\n')
fs.write('// clang-format on\n')
fs.write('size_t ' + name + '_size = ' + hex(len(buf)) + ';')
fs.close()
fh = open(name + '.hpp', 'w')
fh.write("// THIS FILE WAS GENERATED BY build_shaders.py!!!\n\n")
fh.write('#pragma once\n\n')
fh.write('#include <cstddef>\n\n')
fh.write('extern unsigned char ' + name + '[];\n')
fh.write('extern size_t ' + name + '_size;')
fh.close()
def build_shader(path):
p = os.path.dirname(path)
n = Path(Path(path).stem).stem
os.system('picasso -o ' + p + '/' + n + '.shbin ' + path)
def cleanup():
t3x = glob.glob('shaders/*.shbin')
for f in t3x:
os.remove(f)
def install_code(what, where):
if Path(what).is_dir:
os.error('Must be a file!!!')
shutil.move(what, where + Path(what).name)
print("Generating...")
shaders = glob.glob('shaders/*v.pica')
for object in shaders:
name = Path(Path(object).stem).stem
bp = os.path.dirname(object)
build_shader(object)
file2array(bp + '/' + name + '.shbin', 'pd/')
install_code(name + '.cpp', 'source/')
install_code(name + '.hpp', 'include/pd/')
cleanup()
print("Done")

View File

@ -19,9 +19,6 @@ def fmt_dir(path):
print('Formatting...') print('Formatting...')
fmt_dir('source') fmt_dir('source')
fmt_dir('include') fmt_dir('include')
fmt_dir('include/renderd7') fmt_dir('include/pd')
# Format LE and TF as well
fmt_dir('rd7tf/source')
#fmt_dir('rd7le/source')
print('Done') print('Done')

View File

@ -6,19 +6,21 @@
#include <pd/Hid.hpp> #include <pd/Hid.hpp>
#include <pd/Image.hpp> #include <pd/Image.hpp>
#include <pd/Installer.hpp> #include <pd/Installer.hpp>
#include <pd/LI7.hpp>
#include <pd/Message.hpp> #include <pd/Message.hpp>
#include <pd/Net.hpp> #include <pd/Net.hpp>
#include <pd/Overlays.hpp> #include <pd/Overlays.hpp>
#include <pd/Rubidium.hpp>
#include <pd/Sound.hpp> #include <pd/Sound.hpp>
#include <pd/Texture.hpp>
#include <pd/Timer.hpp> #include <pd/Timer.hpp>
#include <pd/UI7.hpp> #include <pd/UI7.hpp>
#include <pd/global_db.hpp> #include <pd/global_db.hpp>
#include <pd/palladium.hpp> #include <pd/palladium.hpp>
#include <pd/swr.hpp>
#include <pd/Texture.hpp>
namespace Palladium { namespace Palladium {
using Render2 = R2; using Render2 = R2;
} using RB = Rubidium;
} // namespace Palladium
namespace PD = Palladium; namespace PD = Palladium;

View File

@ -8,7 +8,7 @@ inline void InlineError(const std::string& msg) {
std::string location = __FILE__ + std::string(":") + std::to_string(__LINE__); std::string location = __FILE__ + std::string(":") + std::to_string(__LINE__);
Error("Error: \n" + location + "\n" + msg); Error("Error: \n" + location + "\n" + msg);
} }
inline void InlineAssert(bool v, const std::string& msg) { inline void InlineAssert(bool v, const std::string& msg = "") {
if (v == false) { if (v == false) {
std::string location = std::string location =
__FILE__ + std::string(":") + std::to_string(__LINE__); __FILE__ + std::string(":") + std::to_string(__LINE__);

View File

@ -1,9 +1,9 @@
#pragma once #pragma once
#include <3ds.h> #include <3ds.h>
#include <citro2d.h>
#include <pd/NVec.hpp> #include <pd/NVec.hpp>
#include <pd/Texture.hpp>
#include <pd/nimg.hpp> #include <pd/nimg.hpp>
#include <pd/smart_ctor.hpp> #include <pd/smart_ctor.hpp>
#include <string> #include <string>
@ -12,7 +12,6 @@ namespace Palladium {
class Image { class Image {
public: public:
Image() = default; Image() = default;
Image(C2D_Image img) { this->img = img; }
Image(const std::string& path) { this->Load(path); } Image(const std::string& path) { this->Load(path); }
~Image() = default; ~Image() = default;
PD_SMART_CTOR(Image) PD_SMART_CTOR(Image)
@ -20,14 +19,17 @@ class Image {
void From_NIMG(const nimg& image); void From_NIMG(const nimg& image);
void Delete(); void Delete();
C2D_Image Get(); Texture::Ref Get();
C2D_Image& GetRef(); void Set(Texture::Ref i, NVec4 uvs = NVec4(-1, -1, -1, -1));
void Set(const C2D_Image& i);
NVec2 GetSize(); NVec2 GetSize();
NVec4 GetUV() {
return (custom_uvs.x != -1) ? custom_uvs : img->GetUV();
}
bool Loadet(); bool Loadet();
private: private:
bool ext = false; bool ext = false;
C2D_Image img; Texture::Ref img;
NVec4 custom_uvs = NVec4(-1, -1, -1, -1);
}; };
} // namespace Palladium } // namespace Palladium

View File

@ -1,8 +1,9 @@
#pragma once #pragma once
#include <string>
#include <3ds.h> // Result #include <3ds.h> // Result
#include <string>
namespace Palladium { namespace Palladium {
struct InstallerInfo { struct InstallerInfo {
unsigned long long total; unsigned long long total;

View File

@ -1,14 +1,28 @@
#include <pd/NVec.hpp> #pragma once
#include <pd/Allocator.hpp>
#include <pd/Texture.hpp>
#include <citro3d.h> #include <citro3d.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <pd/Allocator.hpp>
#include <pd/NVec.hpp>
#include <pd/Texture.hpp>
#include <vector> #include <vector>
#define MAKEFLAG(x) (1 << x)
using PDTextFlags = unsigned int;
enum PDTextFlags_ {
PDTextFlags_None = 0, //< Align is Left and Other things are disabled
PDTextFlags_AlignRight = MAKEFLAG(0),
PDTextFlags_AlignMid = MAKEFLAG(1),
PDTextFlags_Shaddow = MAKEFLAG(2), // TextBuf Killer lol (doubled Text)
PDTextFlags_Wrap = MAKEFLAG(3),
PDTextFlags_Short = MAKEFLAG(4),
PDTextFlags_Scroll = MAKEFLAG(5),
};
namespace Palladium { namespace Palladium {
class LIFont { class LIFont {
public: public:
@ -16,6 +30,8 @@ class LIFont {
unsigned char codepoint; unsigned char codepoint;
NVec4 uv; NVec4 uv;
Texture::Ref tex; Texture::Ref tex;
NVec2 szs;
float off;
}; };
LIFont() = default; LIFont() = default;
~LIFont() = default; ~LIFont() = default;
@ -26,37 +42,53 @@ class LIFont {
void LoadSystemFont(); void LoadSystemFont();
int GetPixelHeight(); int GetPixelHeight();
CPI GetCodepoint(); CPI GetCodepoint(char c);
std::string GetName() { return name; };
void Dump();
private: private:
std::string name;
int pixel_height; int pixel_height;
unsigned char fontw[256]; std::vector<CPI> cpmap;
int charsize;
std::vector<Texture::Ref> tex; std::vector<Texture::Ref> tex;
}; };
class LI7 { class LI7 {
public: public:
struct Vtx struct Vtx {
{ Vtx() {}
Vtx(NVec2 xy, float u, float v, unsigned int clr) {
// Coords
xyz[0] = xy.x;
xyz[1] = xy.y;
xyz[2] = 0.5f; // Always 0
// UV
uv[0] = u;
uv[1] = v;
col = clr;
}
float xyz[3]; float xyz[3];
float uv[2]; float uv[2];
unsigned int col; unsigned int col;
}; };
/// CMD TYPES /// /// CMD TYPES ///
/// 0 = SKIP /// 0 = SKIP
/// 1 = TRIANGLE /// 1 = TRIANGLE
/// 2 = RECT /// 2 = RECT
///////////////// /// 3 = RECT2P (2 Positions instead of pos,szs)
struct Cmd { /////////////////
struct Cmd {
NVec2 ppos; NVec2 ppos;
NVec2 pszs; NVec2 pszs;
NVec2 apos; NVec2 apos;
NVec4 top;
NVec4 bot;
NVec4 uv; NVec4 uv;
int layer = 0; int layer = 0;
int cmd_type = 0; int cmd_type = 0;
unsigned int clr = 0; unsigned int clr = 0;
Texture::Ref tex = nullptr; Texture::Ref tex = nullptr;
}; };
LI7() = default; LI7() = default;
~LI7() = default; ~LI7() = default;
@ -69,28 +101,39 @@ struct Cmd {
static float Scale() { return m_scale; } static float Scale() { return m_scale; }
static void BindTexture(Texture::Ref tex); static void BindTexture(Texture::Ref tex);
static NVec2 ScreenSize() { return NVec2(m_width, m_height); } static NVec2 ScreenSize() { return NVec2(m_width, m_height); }
static LIFont::Ref GetFont() { return m_font; }
static void ColorRect(NVec2 pos, NVec2 szs, NVec4 uvs, unsigned int clr); static void ColorRect(NVec2 pos, NVec2 szs, NVec4 uvs, unsigned int clr);
static void Rect(NVec2 pos, NVec2 szs, NVec4 uvs); static void Rect(NVec2 pos, NVec2 szs, NVec4 uvs);
static void ColorRect(NVec2 pos, NVec2 szs, unsigned int clr); static void ColorRect(NVec2 pos, NVec2 szs, unsigned int clr);
static void Rect(NVec2 pos, NVec2 szs); static void Rect(NVec2 pos, NVec2 szs);
static void TexCutRect(NVec2 pos, NVec2 szs, NVec2 cb, NVec2 ce); static void TexCutRect(NVec2 pos, NVec2 szs, NVec2 cb, NVec2 ce);
static void Line(NVec2 a, NVec2 b, unsigned int clr, int t = 1);
static void Triangle(NVec2 a, NVec2 b, NVec2 c, unsigned int clr);
static void UseTexture(Texture::Ref tex = nullptr) {
m_current_texture = tex ? tex : m_white;
}
static int DrawText(int x, int y, int z, unsigned int color, bool shadow, static NVec2 GetTextDimensions(const std::string& text);
int wrap, int* ySize, const char* fmt, ...); static void DrawText(NVec2 pos, unsigned int color, const std::string& text,
PDTextFlags flags = 0, NVec2 ap = NVec2());
static float GetTextScale() { return m_txt_scale; }
static void SetTextScale(float scale) { m_txt_scale = scale; }
static void DefaultTextScale() { m_txt_scale = m_dts; }
static int Vertices() { return m_d_vertices; } static int Vertices() { return m_d_vertices; }
static int Drawcalls() { return m_d_drawcalls; } static int Drawcalls() { return m_d_drawcalls; }
static int DarwCommandss() { return m_d_commands; } static int DarwCommands() { return m_d_commands; }
private: private:
static bool CompareCommands(const Cmd& a, static bool CompareCommands(const Cmd& a, const Cmd& b);
const Cmd& b);
static void RenderFrame(bool bottom); static void RenderFrame(bool bottom);
static int DrawTextVargs(int x, int y, int z, unsigned int color, bool shadow,
int wrap, int* ySize, const char* fmt, va_list arg);
// Default Font Size in (px) // Default Font Size in (px)
static const float m_dffs; static const float m_dffs;
static const float m_dts;
static float m_txt_scale;
static int m_uLoc_proj; static int m_uLoc_proj;
static float m_scale; static float m_scale;
@ -101,25 +144,23 @@ struct Cmd {
static int m_d_commands; static int m_d_commands;
static const int m_char_height; // Constant static const int m_char_height; // Constant
static float m_rot;
// UI Stuff // UI Stuff
static std::vector<Cmd> m_top_draw_cmds; static std::vector<Cmd> m_top_draw_cmds;
static std::vector<Cmd> m_bot_draw_cmds; static std::vector<Cmd> m_bot_draw_cmds;
static Texture::Ref m_current_texture; static Texture::Ref m_current_texture;
static Texture::Ref m_white;
static std::vector<Vtx, LinearAllocator<Vtx>> m_vtx_list[2]; static std::vector<Vtx, LinearAllocator<Vtx>> m_vtx_list[2];
//static Font* m_font; // static Font* m_font;
static LIFont::Ref m_font;
static std::vector<char> m_text_buffer; static std::vector<char> m_text_buffer;
// Matrix
static C3D_Mtx m_icon_model_matrix;
// Ctx Stuff // Ctx Stuff
static bool m_bottom_active; static bool m_bottom_active;
// Shader // Shader
static DVLB_s *li7_dvlb; static DVLB_s* li7_dvlb;
static shaderProgram_s li7_shader; static shaderProgram_s li7_prog;
static C3D_AttrInfo li7_attr; static C3D_AttrInfo li7_attr;
}; };
} } // namespace Palladium

View File

@ -9,7 +9,9 @@ struct memory_metrics {
unsigned int t_TotalAllocated = 0; ///< Total Allocated Memory unsigned int t_TotalAllocated = 0; ///< Total Allocated Memory
unsigned int t_TotalFreed = 0; ///< Total Deleted Memory unsigned int t_TotalFreed = 0; ///< Total Deleted Memory
/// @brief Gets the Currently Allocated Memory /// @brief Gets the Currently Allocated Memory
unsigned int t_CurrentlyAllocated() { return t_TotalAllocated - t_TotalFreed; } unsigned int t_CurrentlyAllocated() {
return t_TotalAllocated - t_TotalFreed;
}
}; };
/// @brief Get Total Allocated Memory /// @brief Get Total Allocated Memory
/// @return Total Allocated Memory /// @return Total Allocated Memory

View File

@ -36,6 +36,7 @@ struct NVec2 {
// and swap it lol // and swap it lol
return !(*this == in); return !(*this == in);
} }
// Internal Values // Internal Values
float x; float x;
float y; float y;

View File

@ -48,7 +48,9 @@ class Ovl_Metrik : public Palladium::Ovl {
mutable std::string mt_gpu; mutable std::string mt_gpu;
mutable std::string mt_cmd; mutable std::string mt_cmd;
mutable std::string mt_lfr; mutable std::string mt_lfr;
mutable std::string mt_tbs; mutable std::string mt_vtx;
mutable std::string mt_drc;
mutable std::string mt_dmc;
mutable std::string mt_mem; mutable std::string mt_mem;
// Importand Adresses // Importand Adresses

View File

@ -4,24 +4,11 @@
#include <pd/Color.hpp> #include <pd/Color.hpp>
#include <pd/Font.hpp> #include <pd/Font.hpp>
#include <pd/Image.hpp> #include <pd/Image.hpp>
#include <pd/LI7.hpp>
#include <pd/NVec.hpp> #include <pd/NVec.hpp>
#include <pd/Sprite.hpp> #include <pd/Sprite.hpp>
#include <pd/smart_ctor.hpp> #include <pd/smart_ctor.hpp>
#define MAKEFLAG(x) (1 << x)
typedef unsigned int PDTextFlags;
enum PDTextFlags_ {
PDTextFlags_None = 0, //< Align is Left and Other things are disabled
PDTextFlags_AlignRight = MAKEFLAG(0),
PDTextFlags_AlignMid = MAKEFLAG(1),
PDTextFlags_Shaddow = MAKEFLAG(2), // TextBuf Killer lol (doubled Text)
PDTextFlags_Wrap = MAKEFLAG(3),
PDTextFlags_Short = MAKEFLAG(4),
PDTextFlags_Scroll = MAKEFLAG(5),
};
enum R2Screen { enum R2Screen {
R2Screen_Bottom, R2Screen_Bottom,
R2Screen_Top, R2Screen_Top,
@ -73,8 +60,7 @@ class R2 {
static void AddRect(NVec2 pos, NVec2 size, PDColor clr); static void AddRect(NVec2 pos, NVec2 size, PDColor clr);
static void AddRect(NVec2 pos, NVec2 size, unsigned int clr); static void AddRect(NVec2 pos, NVec2 size, unsigned int clr);
static void AddTriangle(NVec2 pos0, NVec2 pos1, NVec2 pos2, PDColor clr); static void AddTriangle(NVec2 pos0, NVec2 pos1, NVec2 pos2, PDColor clr);
static void AddTriangle(NVec2 pos0, NVec2 pos1, NVec2 pos2, static void AddTriangle(NVec2 pos0, NVec2 pos1, NVec2 pos2, unsigned int clr);
unsigned int clr);
static void AddText(NVec2 pos, const std::string& text, PDColor clr, static void AddText(NVec2 pos, const std::string& text, PDColor clr,
PDTextFlags flags = 0, NVec2 tmb = NVec2()); PDTextFlags flags = 0, NVec2 tmb = NVec2());
static void AddText(NVec2 pos, const std::string& text, unsigned int clr, static void AddText(NVec2 pos, const std::string& text, unsigned int clr,

30
include/pd/Rubidium.hpp Normal file
View File

@ -0,0 +1,30 @@
#pragma once
#include <pd/nimg.hpp>
#include <pd/smart_ctor.hpp>
namespace Palladium {
class Rubidium {
public:
Rubidium(int w, int h);
Rubidium();
~Rubidium();
PD_SMART_CTOR(Rubidium)
nimg& GetNimg() { return image; }
void LoadFile(const std::string& path);
void LoadNimg(const std::string& path);
// Rendering
void DrawPixel(int x, int y, unsigned int color);
void DrawRect(int x, int y, int w, int h, unsigned int color, int t = 1);
void DrawRectSolid(int x, int y, int w, int h, unsigned int color);
void DrawLine(int x1, int y1, int x2, int y2, unsigned int color, int t = 1);
void Flip(bool h, bool v);
void EnableAA(bool enable) { enable_aa = enable; }
private:
// Leinwand (dont know english word for that)
nimg image;
bool enable_aa = true;
};
} // namespace Palladium

View File

@ -1,35 +1,70 @@
#include <pd/smart_ctor.hpp> #pragma once
#include <pd/NVec.hpp>
#include <vector>
#include <string>
#include <citro3d.h> #include <citro3d.h>
#include <pd/NVec.hpp>
#include <pd/smart_ctor.hpp>
#include <string>
#include <vector>
namespace Palladium { namespace Palladium {
class Texture { class Texture {
public: public:
Texture() = default; // Define Types supported by the texture loader
~Texture() = default; // For example usefull to waste not as much space
// in linear mem
enum Type {
RGBA32,
RGB24,
A8,
};
Texture() {
// Set Default UV
this->uvs.x = 0.0f;
this->uvs.y = 1.0f;
this->uvs.z = 1.0f;
this->uvs.w = 0.0f;
};
~Texture() { Delete(); }
PD_SMART_CTOR(Texture) PD_SMART_CTOR(Texture)
void Delete(); void Delete();
/// @brief Loads an Image [png, jpg, bmp] as texture
/// by default it sets up the texture as RGBA32 and
/// only supports RGB24 and RGBA32 images
/// @param path Path to file
void LoadFile(const std::string& path); void LoadFile(const std::string& path);
/// @brief Loads an Image [png, jpg, bmp] as texture
/// by default it sets up the texture as RGBA32 and
/// only supports RGB24 and RGBA32 images
/// @param data Data of file
void LoadFromMemory(const std::vector<unsigned char>& data); void LoadFromMemory(const std::vector<unsigned char>& data);
void LoadPixels(const std::vector<unsigned char>& data, int w, int h); /// @brief Create Texture by pixel Data. This function supports
/// [RGBA32, RGB24, A8]
/// @param data Pixel Data
/// @param w Width of data
/// @param h Height of Data
/// @param type Type of Data (default is RGBA32)
void LoadPixels(const std::vector<unsigned char>& data, int w, int h, Type type = RGBA32);
/// @brief This function sets up a texture Object based on the input
/// Data and a self setup C3D_Tex. You dont need to delete it as
/// This class does this automatically
void ExternalLoad(C3D_Tex* tex, NVec2 rszs, NVec4 uvs);
C3D_Tex* Get() { return this->tex; } C3D_Tex* Get() { return this->tex; }
NVec2 GetTexSize() { return tex_size; } NVec2 GetTexSize();
NVec2 GetSize() { return img_size; } NVec2 GetSize() { return img_size; }
// As the texture is a pow of 2 we need a uv // As the texture is a pow of 2 we need a uv
NVec4 GetUV() { return uvs; } NVec4 GetUV() { return uvs; }
void AutoDelete(bool enable) { ad = enable; }
private: private:
void MakeTex(std::vector<unsigned char> &buf, int w, int h); void MakeTex(std::vector<unsigned char>& buf, int w, int h, Type type = RGBA32);
C3D_Tex* tex; C3D_Tex* tex = nullptr;
NVec2 img_size; NVec2 img_size;
NVec2 tex_size;
NVec4 uvs; NVec4 uvs;
}; bool ad = true;
} };
} // namespace Palladium

View File

@ -0,0 +1,8 @@
// THIS FILE WAS GENERATED BY build_shaders.py!!!
#pragma once
#include <cstddef>
extern unsigned char li7_shader[];
extern size_t li7_shader_size;

View File

@ -81,6 +81,7 @@ class RSettings : public Palladium::Scene {
RFTRACE, // FTRace Menu RFTRACE, // FTRace Menu
RUI7, // UI7 Menu RUI7, // UI7 Menu
RLOGS, // Logs RLOGS, // Logs
RFV, // Font Viewer
}; };
/// @param shared_request Defines requests from Draw to Logic /// @param shared_request Defines requests from Draw to Logic
@ -89,7 +90,8 @@ class RSettings : public Palladium::Scene {
/// editable by const functions /// editable by const functions
mutable std::map<unsigned int, unsigned int> shared_request; mutable std::map<unsigned int, unsigned int> shared_request;
/// @param m_state Current menu State (Default=MainMenu aka RSETTINGS) /// @param m_state Current menu State (Default=MainMenu aka RSETTINGS)
Palladium::RSettings::RState m_state = Palladium::RSettings::RState::RSETTINGS; Palladium::RSettings::RState m_state =
Palladium::RSettings::RState::RSETTINGS;
/// @brief Position in FTrace Menu /// @brief Position in FTrace Menu
int ftrace_index = 0; int ftrace_index = 0;

View File

@ -1,25 +0,0 @@
#pragma once
#include <pd/nimg.hpp>
namespace Palladium {
class swr {
public:
swr(int w, int h);
swr();
~swr();
nimg& get_image() { return image; }
void load_file(const std::string& path);
void load_nimg(const std::string& path);
// Rendering
void draw_pixel(int x, int y, unsigned int color);
void draw_rect(int x, int y, int w, int h, unsigned int color, int t = 1);
void draw_rect_solid(int x, int y, int w, int h, unsigned int color);
void draw_line(int x1, int y1, int x2, int y2, unsigned int color, int t = 1);
void flip(bool h, bool v);
private:
nimg image;
};
} // namespace Palladium

View File

@ -1,3 +0,0 @@
extern const u8 li7_shbin_end[];
extern const u8 li7_shbin[];
extern const u32 li7_shbin_size;

View File

@ -24,19 +24,20 @@ void Error(const std::string& msg) {
hidScanInput(); hidScanInput();
if (hidKeysDown() & KEY_START) break; if (hidKeysDown() & KEY_START) break;
C3D_FrameBegin(C3D_FRAME_SYNCDRAW); C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
Palladium::ClearTextBufs(); C3D_RenderTargetClear(pd_top, C3D_CLEAR_ALL, 0x00000000, 0);
C2D_TargetClear(pd_top, 0x00000000); C3D_RenderTargetClear(pd_top_right, C3D_CLEAR_ALL, 0x00000000, 0);
C2D_TargetClear(pd_bottom, 0x00000000); C3D_RenderTargetClear(pd_bottom, C3D_CLEAR_ALL, 0x00000000, 0);
Palladium::R2::OnScreen(R2Screen_Top); Palladium::R2::OnScreen(R2Screen_Top);
if (UI7::BeginMenu("Palladium - Error Manager", NVec2(), if (UI7::BeginMenu("Palladium - Error Manager", NVec2(),
UI7MenuFlags_TitleMid)) { UI7MenuFlags_TitleMid)) {
UI7::Label(msg, PDTextFlags_Wrap); UI7::Label(msg);
UI7::Label("Press Start to Exit!"); UI7::Label("Press Start to Exit!");
UI7::EndMenu(); UI7::EndMenu();
} }
Palladium::R2::OnScreen(R2Screen_Bottom); Palladium::R2::OnScreen(R2Screen_Bottom);
UI7::Update(); UI7::Update();
Palladium::R2::Process(); Palladium::R2::Process();
Palladium::LI7::Render(pd_top, pd_bottom);
C3D_FrameEnd(0); C3D_FrameEnd(0);
} }
exit(0); exit(0);

View File

@ -89,9 +89,7 @@ void RegKeyUp(uint32_t &key_up) { hid_handler.setKup(key_up); }
void RegKeyRepeat(uint32_t &repeat) { hid_handler.setKrepeat(repeat); } void RegKeyRepeat(uint32_t &repeat) { hid_handler.setKrepeat(repeat); }
void RegTouchCoords(NVec2 &touch_pos) { void RegTouchCoords(NVec2 &touch_pos) { hid_handler.setTouchCoords(touch_pos); }
hid_handler.setTouchCoords(touch_pos);
}
void RegAnalog1Movement(NVec2 &movement) { void RegAnalog1Movement(NVec2 &movement) {
hid_handler.setJS1Movement(movement); hid_handler.setJS1Movement(movement);

View File

@ -4,178 +4,41 @@
#include <pd/internal_db.hpp> #include <pd/internal_db.hpp>
#include <vector> #include <vector>
static u32 __pdi_gp2o__(u32 v) {
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v++;
return (v >= 64 ? v : 64);
}
static void __pdi_r24r32(std::vector<uint8_t> &out,
const std::vector<uint8_t> &in, const int &w,
const int &h) {
// Converts RGB24 to RGBA32
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
int src = (y * w + x) * 3;
int dst = (y * w + x) * 4;
out[dst + 0] = in[src + 0];
out[dst + 1] = in[src + 1];
out[dst + 2] = in[src + 2];
out[dst + 3] = 255;
}
}
}
static void __pdi_maketex__(C3D_Tex *tex, Tex3DS_SubTexture *sub,
std::vector<unsigned char> &buf, int w, int h) {
if (!tex || !sub) {
_pdi_logger()->Write("Invalid Inpit (objects have no adress!)");
return;
}
// RGBA -> Abgr
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
int pos = (x + y * w) * 4;
auto r = buf[pos + 0];
auto g = buf[pos + 1];
auto b = buf[pos + 2];
auto a = buf[pos + 3];
buf[pos + 0] = a;
buf[pos + 1] = b;
buf[pos + 2] = g;
buf[pos + 3] = r;
}
}
// Pow2
int wp2 = __pdi_gp2o__((unsigned int)w);
int hp2 = __pdi_gp2o__((unsigned int)h);
sub->width = (u16)w;
sub->height = (u16)h;
sub->left = 0.0f;
sub->top = 1.0f;
sub->right = ((float)w / (float)wp2);
sub->bottom = 1.0 - ((float)h / (float)hp2);
// Texture Setup
C3D_TexInit(tex, (u16)wp2, (u16)hp2, GPU_RGBA8);
C3D_TexSetFilter(tex, GPU_NEAREST, GPU_NEAREST);
memset(tex->data, 0, tex->size);
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
int dst_pos = ((((y >> 3) * (wp2 >> 3) + (x >> 3)) << 6) +
((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) |
((y & 2) << 2) | ((x & 4) << 2) | ((y & 4) << 3))) *
4;
int src_pos = (y * w + x) * 4;
memcpy(&((unsigned char *)tex->data)[dst_pos], &buf[src_pos], 4);
}
}
C3D_TexFlush(tex);
tex->border = 0x00000000;
C3D_TexSetWrap(tex, GPU_CLAMP_TO_BORDER, GPU_CLAMP_TO_BORDER);
}
namespace Palladium { namespace Palladium {
void Image::Load(const std::string &path) { void Image::Load(const std::string &path) {
// Make sure to cleanup // Make sure to cleanup
Delete(); Delete();
ext = false; if (!img) img = Texture::New();
// Setup Func and Load Data img->LoadFile(path);
int w, h, c = 0;
unsigned char *image = stbi_load(path.c_str(), &w, &h, &c, 4);
if (image == nullptr) {
//_pdi_logger()->Write("Failed to Load Image: " + path);
return;
}
// Size/Fmt Check
if (w > 1024 || h > 1024) {
// Reason: Image to Large
//_pdi_logger()->Write("Image too Large!");
stbi_image_free(image);
return;
}
std::vector<unsigned char> wimg;
if (c == 3) {
//_pdi_logger()->Write("Convert Image to RGBA");
stbi_image_free(image);
image = stbi_load(path.c_str(), &w, &h, &c, 3);
wimg.resize(w * h * 4);
__pdi_r24r32(wimg, std::vector<unsigned char>(image, image + (w * h * 3)),
w, h);
} else {
wimg.assign(&image[0], &image[(w * h * 4) - 1]);
stbi_image_free(image);
}
// Create C2D_Image
C3D_Tex *tex = new C3D_Tex;
Tex3DS_SubTexture *subtex = new Tex3DS_SubTexture;
__pdi_maketex__(tex, subtex, wimg, w, h);
_pdi_logger()->Write(Palladium::FormatString("Created Texture (%d, %d)",
tex->width, tex->height));
img = {tex, subtex};
} }
void Image::From_NIMG(const nimg &image) { void Image::From_NIMG(const nimg &image) {
// Make sure to cleanup // Make sure to cleanup
Delete(); Delete();
ext = false; if (!img) img = Texture::New();
if (image.width > 1024 || image.height > 1024) return; img->LoadPixels(image.pixel_buffer, image.width, image.height);
C3D_Tex *tex = new C3D_Tex;
Tex3DS_SubTexture *subtex = new Tex3DS_SubTexture;
std::vector<unsigned char> mdpb = image.pixel_buffer;
__pdi_maketex__(tex, subtex, mdpb, image.width, image.height);
img = {tex, subtex};
} }
C2D_Image Image::Get() { Texture::Ref Image::Get() {
if (!Loadet()) {
_pdi_logger()->Write("Image not Loadet!");
}
return img;
}
C2D_Image &Image::GetRef() {
if (!Loadet()) { if (!Loadet()) {
_pdi_logger()->Write("Image not Loadet!"); _pdi_logger()->Write("Image not Loadet!");
} }
return img; return img;
} }
void Image::Set(const C2D_Image &i) { void Image::Set(Texture::Ref i, NVec4 uvs) {
Delete(); Delete();
ext = true; if(uvs.x != -1) custom_uvs = uvs;
img = i; img = i;
} }
NVec2 Image::GetSize() { NVec2 Image::GetSize() {
if (!img.subtex) return NVec2(0, 0); if (!img) return NVec2(0, 0);
return NVec2(img.subtex->width, img.subtex->height); return img->GetSize();
} }
void Image::Delete() { void Image::Delete() { img = nullptr; }
if (ext) return;
if (img.subtex != nullptr) {
delete img.subtex;
img.subtex = nullptr;
}
if (img.tex != nullptr) {
C3D_TexDelete(img.tex);
delete img.tex;
img.tex = nullptr;
}
}
bool Image::Loadet() { return (img.subtex != nullptr && img.tex != nullptr); } bool Image::Loadet() { return img != nullptr; }
} // namespace Palladium } // namespace Palladium

View File

@ -1,29 +1,20 @@
#include <pd/LI7.hpp>
#include <pd/Color.hpp>
#include <pd/palladium.hpp>
#include <pd/external/stb_truetype.h> #include <pd/external/stb_truetype.h>
#include <algorithm> #include <algorithm>
#include <filesystem>
#include <pd/Color.hpp>
#include <pd/LI7.hpp>
#include <pd/li7_shader.hpp>
#include <pd/palladium.hpp>
#include <li7_shbin.h>
#define DISPLAY_TRANSFER_FLAGS \
(GX_TRANSFER_FLIP_VERT(0) | GX_TRANSFER_OUT_TILED(0) | \
GX_TRANSFER_RAW_COPY(0) | GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | \
GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) | \
GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO))
#ifndef __builtin_swap_32
#define __builtin_swap_32(x) \
((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | \
(((x) >> 24) & 0xff))
#endif
#define bs32(x) __builtin_swap_32(x)
#ifndef MAX #ifndef MAX
#define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif #endif
namespace Palladium { namespace Palladium {
const float LI7::m_dffs = 8.f; const float LI7::m_dffs = 24.f;
const float LI7::m_dts = 0.7f;
float LI7::m_txt_scale = 0.7f;
int LI7::m_uLoc_proj; int LI7::m_uLoc_proj;
float LI7::m_scale = 1.0f; float LI7::m_scale = 1.0f;
int LI7::m_width, LI7::m_height; int LI7::m_width, LI7::m_height;
@ -31,28 +22,28 @@ int LI7::m_d_vertices = 0;
int LI7::m_d_drawcalls = 0; int LI7::m_d_drawcalls = 0;
int LI7::m_d_commands = 0; int LI7::m_d_commands = 0;
const int LI7::m_char_height = 8; // Constant const int LI7::m_char_height = 8; // Constant
float LI7::m_rot = 0.f;
// UI Stuff // UI Stuff
std::vector<LI7::Cmd> LI7::m_top_draw_cmds; std::vector<LI7::Cmd> LI7::m_top_draw_cmds;
std::vector<LI7::Cmd> LI7::m_bot_draw_cmds; std::vector<LI7::Cmd> LI7::m_bot_draw_cmds;
Texture::Ref LI7::m_current_texture; Texture::Ref LI7::m_current_texture;
Texture::Ref LI7::m_white;
std::vector<LI7::Vtx, LinearAllocator<LI7::Vtx>> LI7::m_vtx_list[2]; std::vector<LI7::Vtx, LinearAllocator<LI7::Vtx>> LI7::m_vtx_list[2];
// LI7::Font *LI7::m_font; // LI7::Font *LI7::m_font;
LIFont::Ref LI7::m_font;
std::vector<char> LI7::m_text_buffer; std::vector<char> LI7::m_text_buffer;
// Matrix
C3D_Mtx LI7::m_icon_model_matrix;
// Ctx Stuff // Ctx Stuff
bool LI7::m_bottom_active = false; bool LI7::m_bottom_active = false;
// Shader // Shader
DVLB_s *LI7::li7_dvlb; DVLB_s* LI7::li7_dvlb;
shaderProgram_s LI7::li7_shader; shaderProgram_s LI7::li7_prog;
C3D_AttrInfo LI7::li7_attr; C3D_AttrInfo LI7::li7_attr;
void LIFont::LoadTFF(const std::string path, int px_size) { void LIFont::LoadTFF(const std::string path, int px_size) {
// Supported Sizings (Tested [12, 16, 21, 24, 32, 48, 56, 63]) Palladium::Ftrace::ScopedTrace st(
"LIFont", std::filesystem::path(path).filename().string());
this->pixel_height = px_size; this->pixel_height = px_size;
if(!Palladium::FS::FileExist(path)) return; if (!Palladium::FS::FileExist(path)) return;
int type = px_size*16; int type = px_size * 16;
// Load TTF // Load TTF
stbtt_fontinfo inf; stbtt_fontinfo inf;
std::ifstream loader(path, std::ios::binary); std::ifstream loader(path, std::ios::binary);
@ -64,30 +55,51 @@ void LIFont::LoadTFF(const std::string path, int px_size) {
loader.read(reinterpret_cast<char*>(buffer), len); loader.read(reinterpret_cast<char*>(buffer), len);
loader.close(); loader.close();
stbtt_InitFont(&inf, buffer, 0); stbtt_InitFont(&inf, buffer, 0);
std::vector<unsigned char> fmap(type*type*4); std::vector<unsigned char> fmap(type * type * 4);
float scale = stbtt_ScaleForPixelHeight(&inf, pixel_height); float scale = stbtt_ScaleForPixelHeight(&inf, pixel_height);
int ascent, descent, lineGap; int ascent, descent, lineGap;
stbtt_GetFontVMetrics(&inf, &ascent, &descent, &lineGap); stbtt_GetFontVMetrics(&inf, &ascent, &descent, &lineGap);
int baseline = static_cast<int>(ascent * scale); int baseline = static_cast<int>(ascent * scale);
name = path;
auto ftex = Texture::New();
NVec2 offset;
for (int c = 0; c < 255; c++) { for (int c = 0; c < 255; c++) {
if (stbtt_IsGlyphEmpty(&inf, c)) continue; CPI codepoint;
if (stbtt_IsGlyphEmpty(&inf, c)) {
codepoint.codepoint = c;
codepoint.tex = ftex;
cpmap.push_back(codepoint);
continue;
}
int width, height, xOffset, yOffset; int width, height, xOffset, yOffset;
unsigned char* bitmap = stbtt_GetCodepointBitmap( unsigned char* bitmap = stbtt_GetCodepointBitmap(
&inf, scale, scale, c, &width, &height, &xOffset, &yOffset); &inf, scale, scale, c, &width, &height, &xOffset, &yOffset);
int x0, y0, x1, y1; int x0, y0, x1, y1;
stbtt_GetCodepointBitmapBox(&inf, c, scale, scale, &x0, &y0, &x1, &y1); stbtt_GetCodepointBitmapBox(&inf, c, scale, scale, &x0, &y0, &x1, &y1);
this->fontw[c] = x0 + x1;
int i = c % 16; if (offset.x + width > type) {
int j = c / 16; offset.y += pixel_height;
int xoff = i * pixel_height; offset.x = 0;
int yoff = j * pixel_height + baseline + yOffset; }
codepoint.uv.x = static_cast<float>((float)offset.x / (float)type);
codepoint.uv.y = 1.0f - static_cast<float>((float)offset.y / (float)type);
codepoint.uv.z =
static_cast<float>(float(offset.x + width) / (float)type);
codepoint.uv.w =
1.0f - static_cast<float>(float(offset.y + height) / (float)type);
codepoint.tex = ftex;
codepoint.szs.x = width;
codepoint.szs.y = height;
codepoint.off = baseline + yOffset;
for (int y = 0; y < height; ++y) { for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) { for (int x = 0; x < width; ++x) {
int map_pos = ((yoff + y) * type + (xoff + x)) * 4; int map_pos = ((offset.y + y) * type + (offset.x + x)) * 4;
fmap[map_pos + 0] = 255; fmap[map_pos + 0] = 255;
fmap[map_pos + 1] = 255; fmap[map_pos + 1] = 255;
@ -95,28 +107,62 @@ void LIFont::LoadTFF(const std::string path, int px_size) {
fmap[map_pos + 3] = bitmap[x + y * width]; fmap[map_pos + 3] = bitmap[x + y * width];
} }
} }
offset.x += width;
free(bitmap); if (offset.x + width > type) {
offset.y += pixel_height;
offset.x = 0;
}
free(bitmap);
cpmap.push_back(codepoint);
} }
auto ftex = Texture::New();
ftex->LoadPixels(fmap, type, type); ftex->LoadPixels(fmap, type, type);
this->tex.push_back(ftex); this->tex.push_back(ftex);
} }
void LIFont::LoadBitmapFont(const std::string& path) { void LIFont::LoadBitmapFont(const std::string& path) {}
}
void LIFont::LoadSystemFont() { void LIFont::LoadSystemFont() {
name = "System Font";
float text_scale = 0.f;
// Code to Load the System Font
const auto fnt = fontGetSystemFont();
const auto fnt_info = fontGetInfo(fnt);
const auto glyph_info = fontGetGlyphInfo(fnt);
this->tex.resize(glyph_info->nSheets + 1);
text_scale = 30.f / glyph_info->cellHeight;
for (size_t i = 0; i < glyph_info->nSheets; i++) {
auto tex = this->tex[i];
tex = Texture::New();
auto tx = new C3D_Tex;
tx->data = fontGetGlyphSheetTex(fnt, i);
tx->fmt = (GPU_TEXCOLOR)glyph_info->sheetFmt;
tx->size = glyph_info->sheetSize;
tx->width = glyph_info->sheetWidth;
tx->height = glyph_info->sheetHeight;
tx->param = GPU_TEXTURE_MAG_FILTER(GPU_LINEAR) |
GPU_TEXTURE_MIN_FILTER(GPU_LINEAR) |
GPU_TEXTURE_WRAP_S(GPU_REPEAT) | GPU_TEXTURE_WRAP_T(GPU_REPEAT);
tx->border = 0xffffffff;
tx->lodParam = 0;
tex->ExternalLoad(tx, NVec2(tx->width, tx->height), NVec4(0, 1, 1, 0));
}
} }
int LIFont::GetPixelHeight() { int LIFont::GetPixelHeight() { return this->pixel_height; }
} LIFont::CPI LIFont::GetCodepoint(char c) { return cpmap[c]; }
LIFont::CPI LIFont::GetCodepoint() {
void LIFont::Dump() {
std::ofstream ofs("sdmc:/font.txt", std::ios::out);
ofs << "LI7 Font Dump" << std::endl;
ofs << "Pixel Height: " << (int)pixel_height << std::endl;
for (auto& it : this->cpmap) {
ofs << " Codepoint: " << (int)it.codepoint << std::endl;
ofs << " Width: " << (int)it.szs.x << std::endl;
ofs << " UV: (" << (float)it.uv.x << ", " << (float)it.uv.y << ", "
<< (float)it.uv.z << ", " << (float)it.uv.w << ")" << std::endl;
}
ofs.close();
} }
void LI7::Init() { void LI7::Init() {
@ -124,20 +170,32 @@ void LI7::Init() {
m_vtx_list[0].reserve(2 * 4096); m_vtx_list[0].reserve(2 * 4096);
m_vtx_list[1].reserve(2 * 4096); m_vtx_list[1].reserve(2 * 4096);
li7_dvlb = DVLB_ParseFile((u32*)li7_shbin, li7_shbin_size); li7_dvlb = DVLB_ParseFile((u32*)li7_shader, li7_shader_size);
shaderProgramInit(&li7_shader); shaderProgramInit(&li7_prog);
shaderProgramSetVsh(&li7_shader, &li7_dvlb->DVLE[0]); shaderProgramSetVsh(&li7_prog, &li7_dvlb->DVLE[0]);
m_uLoc_proj = m_uLoc_proj =
shaderInstanceGetUniformLocation(li7_shader.vertexShader, "projection"); shaderInstanceGetUniformLocation(li7_prog.vertexShader, "projection");
AttrInfo_Init(&li7_attr); AttrInfo_Init(&li7_attr);
AttrInfo_AddLoader(&li7_attr, 0, GPU_FLOAT, 3); AttrInfo_AddLoader(&li7_attr, 0, GPU_FLOAT, 3);
AttrInfo_AddLoader(&li7_attr, 1, GPU_FLOAT, 2); AttrInfo_AddLoader(&li7_attr, 1, GPU_FLOAT, 2);
AttrInfo_AddLoader(&li7_attr, 2, GPU_UNSIGNED_BYTE, 4); AttrInfo_AddLoader(&li7_attr, 2, GPU_UNSIGNED_BYTE, 4);
m_white = Texture::New();
std::vector<unsigned char> pixels(16 * 16 * 4, 255);
m_white->LoadPixels(pixels, 16, 16);
// C3D_Tex* w = new C3D_Tex;
// C3D_TexInit(w, 16, 16, GPU_L8);
// C3D_TexLoadImage(w, pixels.data(), GPU_TEXFACE_2D, 0);
// m_white->ExternalLoad(w, NVec2(16, 16), NVec4(0, 1, 1, 0));
m_font = LIFont::New();
// m_font->LoadSystemFont();
m_font->LoadTFF("romfs:/fonts/ComicNeue.ttf", 32);
} }
void LI7::Exit() { void LI7::Exit() {
shaderProgramFree(&li7_shader); shaderProgramFree(&li7_prog);
DVLB_Free(li7_dvlb); DVLB_Free(li7_dvlb);
} }
@ -147,15 +205,12 @@ void LI7::OnScreen(bool bottom) {
m_bottom_active = bottom; m_bottom_active = bottom;
} }
bool LI7::CompareCommands(const LI7::Cmd &a, bool LI7::CompareCommands(const LI7::Cmd& a, const LI7::Cmd& b) {
const LI7::Cmd &b) { if (a.layer == b.layer) return a.tex < b.tex;
if (a.layer == b.layer)
return a.tex < b.tex;
return b.layer < a.layer; return b.layer < a.layer;
} }
void LI7::RenderFrame(bool bottom) { void LI7::RenderFrame(bool bottom) {
m_rot += M_PI / 60.f;
C3D_Mtx proj; C3D_Mtx proj;
Mtx_OrthoTilt(&proj, 0.f, (bottom ? 320 : 400), m_height, 0.f, 1.f, -1.f, Mtx_OrthoTilt(&proj, 0.f, (bottom ? 320 : 400), m_height, 0.f, 1.f, -1.f,
false); false);
@ -163,7 +218,7 @@ void LI7::RenderFrame(bool bottom) {
C3D_DepthTest(false, GPU_GREATER, GPU_WRITE_ALL); C3D_DepthTest(false, GPU_GREATER, GPU_WRITE_ALL);
C3D_TexEnv *env = C3D_GetTexEnv(0); C3D_TexEnv* env = C3D_GetTexEnv(0);
C3D_TexEnvInit(env); C3D_TexEnvInit(env);
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, (GPU_TEVSRC)0); C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, (GPU_TEVSRC)0);
C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE); C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE);
@ -172,40 +227,48 @@ void LI7::RenderFrame(bool bottom) {
int total_vertices = 0; int total_vertices = 0;
m_d_drawcalls = 0; m_d_drawcalls = 0;
auto &draw_cmds = bottom ? m_bot_draw_cmds : m_top_draw_cmds; auto& draw_cmds = bottom ? m_bot_draw_cmds : m_top_draw_cmds;
std::sort(draw_cmds.begin(), draw_cmds.end(), CompareCommands); std::reverse(draw_cmds.begin(), draw_cmds.end());
// std::sort(draw_cmds.begin(), draw_cmds.end(), CompareCommands);
m_d_commands = draw_cmds.size(); m_d_commands = draw_cmds.size();
size_t vtx = 0; size_t vtx = 0;
while (draw_cmds.size() > 0) { while (draw_cmds.size() > 0) {
C3D_Tex *texture = draw_cmds[draw_cmds.size() - 1].tex->Get(); C3D_Tex* texture = draw_cmds[draw_cmds.size() - 1].tex->Get();
size_t start_vtx = vtx; size_t start_vtx = vtx;
while (draw_cmds.size() > 0 && while (draw_cmds.size() > 0 &&
draw_cmds[draw_cmds.size() - 1].tex->Get() == texture) { draw_cmds[draw_cmds.size() - 1].tex->Get() == texture) {
auto c = draw_cmds[draw_cmds.size() - 1]; auto c = draw_cmds[draw_cmds.size() - 1];
if(c.cmd_type == 1) { if (c.cmd_type == 1) {
active_list[vtx++] = Vtx{{c.ppos.x, c.ppos.y, 0}, {c.uv.x, c.uv.y}, c.clr}; active_list[vtx++] =
active_list[vtx++] = Vtx{{c.pszs.x, c.pszs.y, 0}, {c.uv.x, c.uv.w}, c.clr}; Vtx(NVec2(c.bot.z, c.bot.w), c.uv.z, c.uv.w, c.clr);
active_list[vtx++] = Vtx{{c.apos.x, c.apos.y, 0}, {c.uv.z, c.uv.w}, c.clr}; active_list[vtx++] =
Vtx(NVec2(c.top.z, c.top.w), c.uv.z, c.uv.y, c.clr);
active_list[vtx++] =
Vtx(NVec2(c.top.x, c.top.y), c.uv.x, c.uv.y, c.clr);
///
active_list[vtx++] =
Vtx(NVec2(c.top.x, c.top.y), c.uv.x, c.uv.y, c.clr);
active_list[vtx++] =
Vtx(NVec2(c.bot.x, c.bot.y), c.uv.x, c.uv.w, c.clr);
active_list[vtx++] =
Vtx(NVec2(c.bot.z, c.bot.w), c.uv.z, c.uv.w, c.clr);
} else if (c.cmd_type == 2) { } else if (c.cmd_type == 2) {
// TRI1 active_list[vtx++] =
active_list[vtx++] = Vtx{{c.ppos.x+c.pszs.x, c.ppos.y+c.pszs.y, 0}, {c.uv.z, c.uv.y}, c.clr}; Vtx(NVec2(c.top.x, c.top.y), c.uv.x, c.uv.y, c.clr);
active_list[vtx++] = Vtx{{c.ppos.x+c.pszs.x, c.ppos.y, 0}, {c.uv.z, c.uv.w}, c.clr}; active_list[vtx++] =
active_list[vtx++] = Vtx{{c.ppos.x, c.ppos.y, 0}, {c.uv.x, c.uv.w}, c.clr}; Vtx(NVec2(c.top.z, c.top.w), c.uv.z, c.uv.w, c.clr);
// TRI2 active_list[vtx++] =
active_list[vtx++] = Vtx{{c.ppos.x, c.ppos.y, 0}, {c.uv.x, c.uv.w}, c.clr}; Vtx(NVec2(c.bot.x, c.bot.y), c.uv.x, c.uv.w, c.clr);
active_list[vtx++] = Vtx{{c.ppos.x, c.ppos.y+c.pszs.y, 0}, {c.uv.x, c.uv.y}, c.clr};
active_list[vtx++] = Vtx{{c.ppos.x+c.pszs.x, c.ppos.y+c.pszs.y, 0}, {c.uv.z, c.uv.y}, c.clr};
} }
draw_cmds.pop_back(); draw_cmds.pop_back();
} }
C3D_TexBind(0, texture); C3D_TexBind(0, texture);
C3D_BufInfo *bufinfo = C3D_GetBufInfo(); C3D_BufInfo* bufinfo = C3D_GetBufInfo();
BufInfo_Init(bufinfo); BufInfo_Init(bufinfo);
BufInfo_Add(bufinfo, active_list.data() + start_vtx, sizeof(Vtx), 3, BufInfo_Add(bufinfo, active_list.data() + start_vtx, sizeof(Vtx), 3, 0x210);
0x210);
C3D_DrawArrays(GPU_TRIANGLES, 0, vtx - start_vtx); C3D_DrawArrays(GPU_TRIANGLES, 0, vtx - start_vtx);
m_d_drawcalls++; m_d_drawcalls++;
@ -219,7 +282,8 @@ void LI7::RenderFrame(bool bottom) {
} }
void LI7::Render(C3D_RenderTarget* top, C3D_RenderTarget* bot) { void LI7::Render(C3D_RenderTarget* top, C3D_RenderTarget* bot) {
C3D_BindProgram(&li7_shader); Palladium::Ftrace::ScopedTrace st("Li7", "Render");
C3D_BindProgram(&li7_prog);
C3D_SetAttrInfo(&li7_attr); C3D_SetAttrInfo(&li7_attr);
C3D_FrameDrawOn(top); C3D_FrameDrawOn(top);
RenderFrame(false); RenderFrame(false);
@ -228,24 +292,26 @@ void LI7::Render(C3D_RenderTarget* top, C3D_RenderTarget* bot) {
int d_tmp_vtxs1 = m_d_vertices; int d_tmp_vtxs1 = m_d_vertices;
C3D_FrameDrawOn(bot); C3D_FrameDrawOn(bot);
RenderFrame(true); RenderFrame(true);
int d_tmp_cmds2 = m_d_commands; m_d_commands += d_tmp_cmds1;
int d_tmp_dcls2 = m_d_drawcalls; m_d_drawcalls += d_tmp_dcls1;
int d_tmp_vtxs2 = m_d_vertices; m_d_vertices += d_tmp_vtxs1;
m_d_commands = d_tmp_cmds1 + d_tmp_cmds2;
m_d_drawcalls = d_tmp_dcls1 + d_tmp_dcls2;
m_d_vertices = d_tmp_vtxs1 + d_tmp_vtxs2;
} }
void LI7::ColorRect(NVec2 pos, NVec2 szs, NVec4 uvs, unsigned int clr) { void LI7::ColorRect(NVec2 pos, NVec2 szs, NVec4 uvs, unsigned int clr) {
Cmd c; Cmd c;
c.ppos = pos; if (pos.x > m_width || pos.x + szs.x < 0 || pos.y > m_height ||
c.pszs = szs; pos.y + szs.y < 0)
return;
c.top = NVec4(pos, NVec2(pos.x + szs.x, pos.y));
c.bot = NVec4(NVec2(pos.x, pos.y + szs.y), pos + szs);
c.uv = uvs; c.uv = uvs;
c.clr = bs32(clr); c.clr = clr;
c.tex = m_current_texture; c.tex = m_current_texture;
c.cmd_type = 2; c.cmd_type = 1;
if(m_bottom_active) m_bot_draw_cmds.push_back(c); if (m_bottom_active)
else m_top_draw_cmds.push_back(c); m_bot_draw_cmds.push_back(c);
else
m_top_draw_cmds.push_back(c);
} }
void LI7::ColorRect(NVec2 pos, NVec2 szs, unsigned int clr) { void LI7::ColorRect(NVec2 pos, NVec2 szs, unsigned int clr) {
@ -260,6 +326,66 @@ void LI7::Rect(NVec2 pos, NVec2 szs) {
ColorRect(pos, szs, NVec4(0, 0, 1, 1), 0xffffffff); ColorRect(pos, szs, NVec4(0, 0, 1, 1), 0xffffffff);
} }
void LI7::Triangle(NVec2 a, NVec2 b, NVec2 c, unsigned int clr) {
Cmd cmd;
if ((a.x > m_width && b.x > m_width && c.x > m_width) ||
(a.y > m_height && b.y > m_height && c.y > m_height) ||
(a.x < 0 && b.x < 0 && c.x < 0) || (a.y < 0 && b.y < 0 && c.y < 0))
return;
cmd.ppos = a;
cmd.pszs = b;
cmd.apos = c;
cmd.top = NVec4(a, b);
cmd.bot = NVec4(c, NVec2());
cmd.uv = NVec4(0, 1, 1, 0);
cmd.clr = clr;
cmd.tex = m_current_texture;
cmd.cmd_type = 1;
if (m_bottom_active)
m_bot_draw_cmds.push_back(cmd);
else
m_top_draw_cmds.push_back(cmd);
}
void LI7::Line(NVec2 a, NVec2 b, unsigned int clr, int t) {
// Calculate direction vector
NVec2 direction = {b.x - a.x, b.y - a.y};
float length =
std::sqrt(direction.x * direction.x + direction.y * direction.y);
// Normalize direction vector
NVec2 unit_direction = {direction.x / length, direction.y / length};
// Calculate perpendicular vector
NVec2 perpendicular = {-unit_direction.y, unit_direction.x};
// Scale perpendicular vector by half the thickness
float half_t = t / 2.0f;
NVec2 offset = {perpendicular.x * half_t, perpendicular.y * half_t};
// Calculate corner positions
float px0 = a.x + offset.x;
float py0 = a.y + offset.y;
float px1 = b.x + offset.x;
float py1 = b.y + offset.y;
float px2 = a.x - offset.x;
float py2 = a.y - offset.y;
float px3 = b.x - offset.x;
float py3 = b.y - offset.y;
Cmd c;
c.top = NVec4(px0, py0, px1, py1);
c.bot = NVec4(px2, py2, px3, py3);
c.uv = NVec4(0, 1, 1, 0);
c.clr = clr;
c.tex = m_current_texture;
c.cmd_type = 1;
if (m_bottom_active)
m_bot_draw_cmds.push_back(c);
else
m_top_draw_cmds.push_back(c);
}
void LI7::TexCutRect(NVec2 pos, NVec2 szs, NVec2 cb, NVec2 ce) { void LI7::TexCutRect(NVec2 pos, NVec2 szs, NVec2 cb, NVec2 ce) {
float u0 = (float)(cb.x / (float)m_current_texture->Get()->width); float u0 = (float)(cb.x / (float)m_current_texture->Get()->width);
float v1 = (float)(((float)m_current_texture->Get()->height - cb.y) / float v1 = (float)(((float)m_current_texture->Get()->height - cb.y) /
@ -270,57 +396,94 @@ void LI7::TexCutRect(NVec2 pos, NVec2 szs, NVec2 cb, NVec2 ce) {
Rect(pos, szs, NVec4(u0, v0, u1, v1)); Rect(pos, szs, NVec4(u0, v0, u1, v1));
} }
int LI7::DrawTextVargs(int x, int y, int z, unsigned int color, bool shadow, NVec2 LI7::GetTextDimensions(const std::string& text) {
int wrap, int* ySize, const char* fmt, va_list arg) {
// FONT // FONT
int len = vsnprintf(m_text_buffer.data(), m_text_buffer.size(), fmt, arg); std::string txt = text + "\0";
m_text_buffer[len] = '\0'; NVec2 pos(0, 0); // Temp Pos
int offsetX = 0; NVec2 offset;
int offsetY = 0; float maxWidth = 0.f;
int maxWidth = 0; float ntxtszs = m_dffs * m_txt_scale;
float cpm = m_dffs /1;// m_font->char_size; float cpm = ntxtszs / m_font->GetPixelHeight();
float line_height = m_font->GetPixelHeight() * cpm * m_scale;
for (const auto &it : m_text_buffer) { for (size_t i = 0; i < txt.length(); i++) {
if (it == '\0') break; if (txt[i] == '\0') break;
bool implicitBreak = offsetX + 0/*m_font->fontWidth[(int)it]*/ >= wrap; auto cp = m_font->GetCodepoint(txt[i]);
if (it == '\n' || implicitBreak) { bool implicitBreak = false;
offsetY += /*m_font->char_size*/0 * cpm * m_scale; if (txt[i] == '\n' || implicitBreak) {
maxWidth = std::max(maxWidth, offsetX); offset.y += line_height;
offsetX = 0; maxWidth = std::max(maxWidth, offset.x);
offset.x = 0;
if (implicitBreak) continue; if (implicitBreak) continue;
} else if (it == '\t') { } else if (txt[i] == '\t') {
offsetX = ((offsetX / m_dffs) / 4 + 1) * 4 * m_dffs; offset.x = ((offset.x / ntxtszs) / 4 + 1) * 4 * ntxtszs;
} else { } else {
if (it != ' ') { if (txt[i] == ' ') {
int texX = (it % 16) * /*m_font->char_size*/0; // this will make the space twice
int texY = (/*m_font->texture.tex.height*/0 - /*m_font->char_size*/0) - offset.x += 2 * m_txt_scale;
(it / 16) * /*m_font->char_size*/0; }
ColorRect(NVec2(x + offsetX, y + offsetY), NVec2(m_dffs, m_dffs), if (i == txt.length() - 1)
NVec4(static_cast<float>(texX) / /*m_font->texture.tex.width*/0, offset.x += cp.szs.x * cpm + m_txt_scale;
static_cast<float>(texY) / /*m_font->texture.tex.height*/0, else
(static_cast<float>(texX) + /*m_font->char_size*/0) / offset.x += cp.szs.x * cpm + (2 * m_txt_scale);
/*m_font->texture.tex.width*/0, }
(static_cast<float>(texY) + /*m_font->char_size*/0) / }
/*m_font->texture.tex.height*/0), maxWidth = std::max(maxWidth, offset.x);
color); return NVec2(maxWidth, offset.y + (m_dffs * m_txt_scale));
}
if (shadow) void LI7::DrawText(NVec2 pos, unsigned int color, const std::string& text,
ColorRect(NVec2(x + offsetX + 1, y + offsetY + 1), NVec2(m_dffs, m_dffs), PDTextFlags flags, NVec2 ap) {
NVec4(static_cast<float>(texX) / /*m_font->texture.tex.width*/0, std::string txt = text;
static_cast<float>(texY) / /*m_font->texture.tex.height*/0, NVec2 offset;
(static_cast<float>(texX) + /*m_font->char_size*/0) / float ntxtszs = m_dffs * m_txt_scale;
/*m_font->texture.tex.width*/0, float cpm = ntxtszs / m_font->GetPixelHeight();
(static_cast<float>(texY) + /*m_font->char_size*/0) / float line_height = m_font->GetPixelHeight() * cpm * m_scale;
/*m_font->texture.tex.height*/0), NVec2 td = GetTextDimensions(text);
RGBA8(10, 10, 10, 255)); if (flags & PDTextFlags_AlignRight) pos.x -= td.x;
if (flags & PDTextFlags_AlignMid) {
pos.x = (ap.x * 0.5) - (td.x * 0.5) + pos.x;
} }
offsetX += /*m_font->fontWidth[(int)it]*/0 * cpm * m_scale + std::vector<std::string> lines;
((/*m_font->char_size*/0 * 0.2) * cpm * m_scale); std::istringstream iss(txt);
std::string temp;
while (std::getline(iss, temp)) {
lines.push_back(temp);
} }
}
maxWidth = std::max(maxWidth, offsetX);
if (ySize != nullptr) *ySize = offsetY + /*m_font->char_size*/0; for (auto& it : lines) {
return maxWidth; if (pos.y + offset.y + line_height < 0) {
offset.y += line_height;
continue;
} else if (pos.y + offset.y > m_height) {
// Break func as we dont want loop over lines that get skipped too
break;
}
// Loop over line
for (auto& jt : it) {
auto cp = m_font->GetCodepoint(jt);
m_current_texture = cp.tex;
if (jt == '\t') {
offset.x = ((offset.x / ntxtszs) / 4 + 1) * 4 * ntxtszs;
} else {
if (jt != ' ') {
if (flags & PDTextFlags_Shaddow) {
ColorRect(pos + NVec2(offset.x + 1, (offset.y+(cp.off*cpm)) + 1),
NVec2(cp.szs.x*cpm, cp.szs.y*cpm), cp.uv,
Palladium::Color::RGBA(color).is_light() ? 0xff111111
: 0xffeeeeee);
}
ColorRect(pos + offset + NVec2(0, (cp.off*cpm)), NVec2(cp.szs.x*cpm, cp.szs.y*cpm), cp.uv, color);
} else {
// this will make the space twice
offset.x += 2 * m_txt_scale;
}
offset.x += cp.szs.x * cpm + (2 * m_txt_scale);
}
}
offset.y += line_height;
offset.x = 0;
} }
} }
} // namespace Palladium

View File

@ -11,6 +11,7 @@ static std::vector<std::shared_ptr<Palladium::Message>> msg_lst;
static int fade_outs = 200; // Start of fadeout static int fade_outs = 200; // Start of fadeout
static int idles = 60; // start of Idle static int idles = 60; // start of Idle
static int anim_len = 300; // Full Length of Animation static int anim_len = 300; // Full Length of Animation
static NVec2 msg_box = NVec2(170, 50); // Message Box Size
NVec2 MakePos(int frame, int entry) { NVec2 MakePos(int frame, int entry) {
float fol = anim_len - fade_outs; float fol = anim_len - fade_outs;
@ -51,11 +52,11 @@ void ProcessMessages() {
.toRGBA(); .toRGBA();
auto tc = auto tc =
Palladium::Color::RGBA(PDColor_Text2).changeA(new_alpha).toRGBA(); Palladium::Color::RGBA(PDColor_Text2).changeA(new_alpha).toRGBA();
R2::AddRect(pos, NVec2(150, 50), bgc); R2::AddRect(pos, msg_box, bgc);
R2::AddText(pos + NVec2(5, 1), msg_lst[i]->title, tc); R2::AddText(pos + NVec2(5, 1), msg_lst[i]->title, tc);
R2::AddText(pos + NVec2(5, 17), msg_lst[i]->message, tc); R2::AddText(pos + NVec2(5, 17), msg_lst[i]->message, tc);
if (pdi_debugging) if (pdi_debugging)
R2::AddText(pos + NVec2(155, 1), R2::AddText(pos + NVec2(msg_box.x+5, 1),
std::to_string(msg_lst[i]->animationframe), tc); std::to_string(msg_lst[i]->animationframe), tc);
// Why Frameadd? because Message uses int as frame and // Why Frameadd? because Message uses int as frame and
// It seems that lower 0.5 will be rounded to 0 // It seems that lower 0.5 will be rounded to 0

View File

@ -7,9 +7,9 @@
#include <filesystem> #include <filesystem>
#include <fstream> #include <fstream>
#include <regex>
#include <pd/Net.hpp> #include <pd/Net.hpp>
#include <pd/internal_db.hpp> #include <pd/internal_db.hpp>
#include <regex>
static Palladium::Net::Error pdi_check_wifi() { static Palladium::Net::Error pdi_check_wifi() {
// if (pdi_is_citra) return 0; // if (pdi_is_citra) return 0;
@ -24,8 +24,7 @@ static size_t pdi_handle_data(char* ptr, size_t size, size_t nmemb,
return ms; return ms;
} }
static size_t pdi_handle_file(char* ptr, size_t size, size_t nmemb, static size_t pdi_handle_file(char* ptr, size_t size, size_t nmemb, void* out) {
void* out) {
size_t ms = size * nmemb; size_t ms = size * nmemb;
((std::ofstream*)out)->write(reinterpret_cast<const char*>(ptr), ms); ((std::ofstream*)out)->write(reinterpret_cast<const char*>(ptr), ms);
return ms; return ms;
@ -53,8 +52,7 @@ static int pdi_handle_curl_progress(CURL* hnd, curl_off_t dltotal,
static void pdi_setup_curl_context(CURL* hnd, const std::string& url, static void pdi_setup_curl_context(CURL* hnd, const std::string& url,
void* userptr, bool mem) { void* userptr, bool mem) {
std::string user_agent = std::string user_agent =
pdi_app_name + "/Palladium (Version: " + std::string(PDVSTRING) + pdi_app_name + "/Palladium (Version: " + std::string(PDVSTRING) + ")";
")";
if (!mem) { if (!mem) {
curl_easy_setopt(hnd, CURLOPT_FAILONERROR, 1L); curl_easy_setopt(hnd, CURLOPT_FAILONERROR, 1L);

View File

@ -278,9 +278,10 @@ void Ovl_Ftrace::Draw(void) const {
for (auto const& it : Palladium::Ftrace::pd_traces) for (auto const& it : Palladium::Ftrace::pd_traces)
if (it.second.is_ovl && dt.size() < 10) dt.push_back(it.second); if (it.second.is_ovl && dt.size() < 10) dt.push_back(it.second);
for (size_t i = 0; i < (dt.size() < 10 ? dt.size() : 10); i++) { for (size_t i = 0; i < (dt.size() < 10 ? dt.size() : 10); i++) {
R2::AddText(NVec2(5, 30 + i * 15), dt[i].func_name, PDColor_Text); std::string text = dt[i].func_name + ": " + Palladium::MsTimeFmt(dt[i].time_of);
R2::AddText(NVec2(295, 30 + i * 15), Palladium::MsTimeFmt(dt[i].time_of), auto dim = R2::GetTextDimensions(text);
PDColor_Text); R2::AddRect(NVec2(5, 30+i*dim.y), dim, PDColor_TextDisabled);
R2::AddText(NVec2(5, 30 + i * dim.y), text, PDColor_Text2);
} }
R2::SetTextSize(tmp_txt); R2::SetTextSize(tmp_txt);
} }
@ -302,8 +303,7 @@ void Ovl_Metrik::Draw(void) const {
float tmp_txt = R2::GetTextSize(); float tmp_txt = R2::GetTextSize();
R2::DefaultTextSize(); R2::DefaultTextSize();
R2::OnScreen(i_screen[0] ? R2Screen_Bottom : R2Screen_Top); R2::OnScreen(i_screen[0] ? R2Screen_Bottom : R2Screen_Top);
std::string info = std::string info = "Palladium " + std::string(PDVSTRING) + " Debug Overlay";
"Palladium " + std::string(PDVSTRING) + " Debug Overlay";
float dim_y = R2::GetTextDimensions(info).y; float dim_y = R2::GetTextDimensions(info).y;
float infoy = 240 - dim_y; float infoy = 240 - dim_y;
mt_fps = "FPS: " + Palladium::GetFramerate(); mt_fps = "FPS: " + Palladium::GetFramerate();
@ -320,14 +320,14 @@ void Ovl_Metrik::Draw(void) const {
"CMD: " + std::to_string(C3D_GetCmdBufUsage() * 100.0f).substr(0, 4) + "CMD: " + std::to_string(C3D_GetCmdBufUsage() * 100.0f).substr(0, 4) +
"%"; "%";
mt_lfr = "Linear: " + Palladium::FormatBytes(linearSpaceFree()); mt_lfr = "Linear: " + Palladium::FormatBytes(linearSpaceFree());
mt_tbs =
"TextBuf: " + std::to_string(C2D_TextBufGetNumGlyphs(pdi_text_buffer)) +
"/4096";
if (pdi_enable_memtrack) if (pdi_enable_memtrack)
mt_mem = "Mem: " + Palladium::FormatBytes(Palladium::Memory::GetCurrent()) + mt_mem = "Mem: " + Palladium::FormatBytes(Palladium::Memory::GetCurrent()) +
" | " + " | " +
Palladium::FormatBytes(Palladium::Memory::GetTotalAllocated()) + Palladium::FormatBytes(Palladium::Memory::GetTotalAllocated()) +
" | " + Palladium::FormatBytes(Palladium::Memory::GetTotalFreed()); " | " + Palladium::FormatBytes(Palladium::Memory::GetTotalFreed());
mt_vtx = "Vertices: " + std::to_string(LI7::Vertices());
mt_dmc = "DrawCmds: " + std::to_string(LI7::DarwCommands());
mt_drc = "DrawCalls: " + std::to_string(LI7::Drawcalls());
R2::AddRect(NVec2(0, 0), R2::GetTextDimensions(mt_fps), R2::AddRect(NVec2(0, 0), R2::GetTextDimensions(mt_fps),
(unsigned int)i_mt_color[0]); (unsigned int)i_mt_color[0]);
R2::AddRect(NVec2(0, 50), R2::GetTextDimensions(mt_cpu), R2::AddRect(NVec2(0, 50), R2::GetTextDimensions(mt_cpu),
@ -338,26 +338,27 @@ void Ovl_Metrik::Draw(void) const {
(unsigned int)i_mt_color[0]); (unsigned int)i_mt_color[0]);
R2::AddRect(NVec2(0, 50 + dim_y * 3), R2::GetTextDimensions(mt_lfr), R2::AddRect(NVec2(0, 50 + dim_y * 3), R2::GetTextDimensions(mt_lfr),
(unsigned int)i_mt_color[0]); (unsigned int)i_mt_color[0]);
R2::AddRect(NVec2(0, 50 + dim_y * 4), R2::GetTextDimensions(mt_tbs), R2::AddRect(NVec2(0, 50 + dim_y * 4), R2::GetTextDimensions(mt_vtx),
(unsigned int)i_mt_color[0]);
R2::AddRect(NVec2(0, 50 + dim_y * 5), R2::GetTextDimensions(mt_dmc),
(unsigned int)i_mt_color[0]);
R2::AddRect(NVec2(0, 50 + dim_y * 6), R2::GetTextDimensions(mt_drc),
(unsigned int)i_mt_color[0]); (unsigned int)i_mt_color[0]);
if (pdi_enable_memtrack) if (pdi_enable_memtrack)
R2::AddRect(NVec2(0, 50 + dim_y * 5), R2::GetTextDimensions(mt_mem), R2::AddRect(NVec2(0, 50 + dim_y * 7), R2::GetTextDimensions(mt_mem),
(unsigned int)i_mt_color[0]); (unsigned int)i_mt_color[0]);
R2::AddRect(NVec2(0, infoy), R2::GetTextDimensions(info), R2::AddRect(NVec2(0, infoy), R2::GetTextDimensions(info),
(unsigned int)i_mt_color[0]); (unsigned int)i_mt_color[0]);
R2::AddText(NVec2(0, 0), mt_fps, (unsigned int)i_txt_color[0]); R2::AddText(NVec2(0, 0), mt_fps, (unsigned int)i_txt_color[0]);
R2::AddText(NVec2(0, 50), mt_cpu, (unsigned int)i_txt_color[0]); R2::AddText(NVec2(0, 50), mt_cpu, (unsigned int)i_txt_color[0]);
R2::AddText(NVec2(0, 50 + dim_y * 1), mt_gpu, R2::AddText(NVec2(0, 50 + dim_y * 1), mt_gpu, (unsigned int)i_txt_color[0]);
(unsigned int)i_txt_color[0]); R2::AddText(NVec2(0, 50 + dim_y * 2), mt_cmd, (unsigned int)i_txt_color[0]);
R2::AddText(NVec2(0, 50 + dim_y * 2), mt_cmd, R2::AddText(NVec2(0, 50 + dim_y * 3), mt_lfr, (unsigned int)i_txt_color[0]);
(unsigned int)i_txt_color[0]); R2::AddText(NVec2(0, 50 + dim_y * 4), mt_vtx, (unsigned int)i_txt_color[0]);
R2::AddText(NVec2(0, 50 + dim_y * 3), mt_lfr, R2::AddText(NVec2(0, 50 + dim_y * 5), mt_dmc, (unsigned int)i_txt_color[0]);
(unsigned int)i_txt_color[0]); R2::AddText(NVec2(0, 50 + dim_y * 6), mt_drc, (unsigned int)i_txt_color[0]);
R2::AddText(NVec2(0, 50 + dim_y * 4), mt_tbs,
(unsigned int)i_txt_color[0]);
if (pdi_enable_memtrack) if (pdi_enable_memtrack)
R2::AddText(NVec2(0, 50 + dim_y * 5), mt_mem, R2::AddText(NVec2(0, 50 + dim_y * 7), mt_mem, (unsigned int)i_txt_color[0]);
(unsigned int)i_txt_color[0]);
R2::AddText(NVec2(0, infoy), info, (unsigned int)i_txt_color[0]); R2::AddText(NVec2(0, infoy), info, (unsigned int)i_txt_color[0]);
// Force Bottom (Debug Touchpos) // Force Bottom (Debug Touchpos)

View File

@ -1,5 +1,4 @@
#include <citro2d.h> #include <pd/LI7.hpp>
#include <pd/Render2.hpp> #include <pd/Render2.hpp>
#include <pd/internal_db.hpp> #include <pd/internal_db.hpp>
@ -40,15 +39,10 @@ float R2::GetTextSize() { return text_size; }
R2Screen R2::GetCurrentScreen() { return current_screen; } R2Screen R2::GetCurrentScreen() { return current_screen; }
NVec2 R2::GetTextDimensions(const std::string& text) { NVec2 R2::GetTextDimensions(const std::string& text) {
C2D_TextBufClear(pdi_d2_dimbuf); return LI7::GetTextDimensions(text);
float w = 0, h = 0;
C2D_Text c2dtext;
C2D_TextFontParse(&c2dtext, font->Ptr(), pdi_d2_dimbuf, text.c_str());
C2D_TextGetDimensions(&c2dtext, R2::text_size, R2::text_size, &w, &h);
return NVec2(w, h);
} }
std::string R2::WrapText(const std ::string& in, int maxlen) { std::string R2::WrapText(const std::string& in, int maxlen) {
std::string out; std::string out;
std::string line; std::string line;
int line_x = 0; int line_x = 0;
@ -63,7 +57,7 @@ std::string R2::WrapText(const std ::string& in, int maxlen) {
} else { } else {
out += line + '\n'; out += line + '\n';
line = temp + ' '; line = temp + ' ';
line_x = dim.x; line_x = R2::GetTextDimensions(line).x;
} }
} }
out += line; out += line;
@ -73,27 +67,26 @@ std::string R2::WrapText(const std ::string& in, int maxlen) {
std::string R2::ShortText(const std::string& in, int maxlen) { std::string R2::ShortText(const std::string& in, int maxlen) {
auto textdim = R2::GetTextDimensions(in); auto textdim = R2::GetTextDimensions(in);
if (textdim.x < (float)maxlen) return in; if (textdim.x < (float)maxlen) return in;
std::string ft = ""; std::string ext = "";
std::string ph = "(...)"; // placeholder
std::string worker = in; std::string worker = in;
if (in.find_last_of('.') != in.npos) { std::string out;
ft = in.substr(in.find_last_of('.')); size_t ext_pos = in.find_last_of('.');
worker = in.substr(0, in.find_last_of('.')); if (ext_pos != in.npos) {
ext = in.substr(ext_pos);
worker = in.substr(0, ext_pos);
} }
maxlen -= R2::GetTextDimensions(ft).x - R2::GetTextDimensions("(...)").x; maxlen -= R2::GetTextDimensions(ext).x;
float len_mod = (float)maxlen / textdim.x; maxlen -= R2::GetTextDimensions(ph).x;
int pos = (in.length() * len_mod) / pd_draw2_tsm;
std::string out;
out = in.substr(0, pos); for (auto& it : worker) {
if (R2::GetTextDimensions(out).x > (float)maxlen) {
for (size_t i = pos; i < worker.length(); i++) { out += ph;
out += worker[i]; out += ext;
if (R2::GetTextDimensions(out + "(...)" + ft).x > (float)maxlen) {
out += "(...)";
out += ft;
return out; return out;
} }
out += it;
} }
return out; // Impossible to reach return out; // Impossible to reach
} }
@ -104,105 +97,59 @@ NVec2 R2::GetCurrentScreenSize() {
// Main Processing of Draw Calls // Main Processing of Draw Calls
void R2::Process() { void R2::Process() {
Palladium::Ftrace::ScopedTrace st("Render2", "ProcessList");
for (auto& it : R2::commands) { for (auto& it : R2::commands) {
if (it->type <= 0 || it->type > 6) { if (it->type <= 0 || it->type > 6) {
// Skip // Skip
continue; continue;
} }
C2D_SceneBegin(it->Screen ? pd_top : pd_bottom); LI7::OnScreen(!it->Screen);
if (it->type == 1) { if (it->type == 1) {
LI7::UseTexture();
// Rect // Rect
if (it->lined) { if (it->lined) {
C2D_DrawLine(it->pos.x, it->pos.y, it->clr, it->pos.x + it->pszs.x, LI7::Line(it->pos, NVec2(it->pos.x + it->pszs.x, it->pos.y), it->clr,
it->pos.y, it->clr, 1.f, 0.5f); 1.f);
C2D_DrawLine(it->pos.x, it->pos.y, it->clr, it->pos.x, LI7::Line(it->pos, NVec2(it->pos.x, it->pos.y + it->pszs.y), it->clr,
it->pos.y + it->pszs.y, it->clr, 1.f, 0.5f); 1.f);
C2D_DrawLine(it->pos.x + it->pszs.x, it->pos.y, it->clr, LI7::Line(NVec2(it->pos.x + it->pszs.x, it->pos.y),
it->pos.x + it->pszs.x, it->pos.y + it->pszs.y, it->clr, NVec2(it->pos.x + it->pszs.x, it->pos.y + it->pszs.y),
1.f, 0.5f); it->clr, 1.f);
C2D_DrawLine(it->pos.x, it->pos.y + it->pszs.y, it->clr, LI7::Line(NVec2(it->pos.x, it->pos.y + it->pszs.y),
it->pos.x + it->pszs.x, it->pos.y + it->pszs.y, it->clr, NVec2(it->pos.x + it->pszs.x, it->pos.y + it->pszs.y),
1.f, 0.5f); it->clr, 1.f);
} else { } else {
C2D_DrawRectSolid(it->pos.x, it->pos.y, 0.5, it->pszs.x, it->pszs.y, LI7::ColorRect(it->pos, it->pszs, it->clr);
it->clr);
} }
} else if (it->type == 2) { } else if (it->type == 2) {
LI7::UseTexture();
// Triangle // Triangle
if (it->lined) { if (it->lined) {
C2D_DrawLine(it->pos.x, it->pos.y, it->clr, it->pszs.x, it->pszs.y, LI7::Line(it->pos, it->pszs, it->clr, 1);
it->clr, 1, 0.5f); LI7::Line(it->pos, it->ap, it->clr, 1);
C2D_DrawLine(it->pos.x, it->pos.y, it->clr, it->ap.x, it->ap.y, it->clr, LI7::Line(it->pszs, it->ap, it->clr, 1);
1, 0.5f);
C2D_DrawLine(it->pszs.x, it->pszs.y, it->clr, it->ap.x, it->ap.y,
it->clr, 1, 0.5f);
} else { } else {
C2D_DrawTriangle(it->pos.x, it->pos.y, it->clr, it->pszs.x, it->pszs.y, LI7::Triangle(it->pos, it->pszs, it->ap, it->clr);
it->clr, it->ap.x, it->ap.y, it->clr, 0.5);
} }
} else if (it->type == 3) { } else if (it->type == 3) {
// Text std::string txt = it->text;
// little patch for a freeze if (it->flags & PDTextFlags_Short) {
if (it->text.length() < 1) continue; txt = ShortText(txt, it->pszs.x - it->pos.x);
if (it->pszs.x == 0.0f) { } else if(it->flags & PDTextFlags_Wrap) {
it->pszs.x = it->Screen == R2Screen_Top ? 400 : 320; txt = WrapText(it->text, it->pszs.x-it->pos.x);
}
if (it->pszs.y == 0.0f) {
it->pszs.y = 240;
}
std::string edit_text = it->text;
if (edit_text.substr(it->text.length() - 1) != "\n")
edit_text.append("\n"); // Add \n to end if not exist
int line = 0;
if (it->flags & PDTextFlags_Wrap) {
edit_text = WrapText(it->text, it->pszs.x - it->pos.x);
}
while (edit_text.find('\n') != edit_text.npos) {
std::string current_line = edit_text.substr(0, edit_text.find('\n'));
if (it->flags & PDTextFlags_Short)
current_line = R2::ShortText(current_line, it->pszs.x - it->pos.x);
NVec2 newpos = it->pos;
// Check Flags
NVec2 dim = R2::GetTextDimensions(current_line);
if (it->flags & PDTextFlags_AlignRight) newpos.x = newpos.x - dim.x;
if (it->flags & PDTextFlags_AlignMid) // Offset by inpos
newpos.x = (it->pszs.x * 0.5) - (dim.x * 0.5) + it->pos.x;
if (it->flags & PDTextFlags_Scroll) { // Scroll Text
// Look into Old Draw2 Code
// TODO: Create Code for this
}
if (pdi_debugging) {
R2::DrawNextLined();
R2::AddRect(newpos, dim, 0xff0000ff);
}
C2D_Text c2dtext;
C2D_TextFontParse(&c2dtext, font->Ptr(), pdi_text_buffer,
current_line.c_str());
C2D_TextOptimize(&c2dtext);
if (it->flags & PDTextFlags_Shaddow) // performance Killer xd
C2D_DrawText(&c2dtext, C2D_WithColor, newpos.x + 1 + (dim.y * line),
newpos.y + 1, 0.5, R2::text_size, R2::text_size,
Palladium::ThemeActive()->Get(PDColor_TextDisabled));
C2D_DrawText(&c2dtext, C2D_WithColor, newpos.x,
newpos.y + (dim.y * line), 0.5, R2::text_size,
R2::text_size, it->clr);
edit_text = edit_text.substr(edit_text.find('\n') + 1);
line++;
} }
LI7::DrawText(it->pos, it->clr, txt, it->flags, it->pszs);
} else if (it->type == 4) { } else if (it->type == 4) {
if (it->img->Loadet()) { if (it->img->Loadet()) {
C2D_DrawImageAt(it->img->Get(), it->pos.x, it->pos.y, 0.5f); LI7::UseTexture(it->img->Get());
LI7::Rect(it->pos, it->img->Get()->GetSize(), it->img->GetUV());
} }
} else if (it->type == 5) { } else if (it->type == 5) {
// TODO: Move the Draw Func into this API // TODO: Move the Draw Func into this API
it->spr->Draw(); // it->spr->Draw();
} else if (it->type == 6) { } else if (it->type == 6) {
C2D_DrawLine(it->pos.x, it->pos.y, it->clr, it->pszs.x, it->pszs.y, LI7::UseTexture();
it->clr, it->ap.x, 0.5f); LI7::Line(it->pos, it->pszs, it->clr, it->ap.x);
} }
} }
R2::commands.clear(); R2::commands.clear();

124
source/Rubidium.cpp Normal file
View File

@ -0,0 +1,124 @@
#include <pd/external/stb_image.h>
#include <pd/Color.hpp>
#include <pd/Rubidium.hpp>
void d7_pixel_blend(Palladium::Rubidium* rb, int x, int y, unsigned int clr,
float blend) {
Palladium::Color::RGBA cl(clr);
cl.fade_to(Palladium::Color::RGBA(0.f, 0.f, 0.f, 1.f), blend);
rb->DrawPixel(x, y, cl.toRGBA());
}
namespace Palladium {
Rubidium::Rubidium(int w, int h) { image = Palladium::nimg(w, h); }
Rubidium::Rubidium() { image = Palladium::nimg(1, 1); }
Rubidium::~Rubidium() {
// Do nothing
}
void Rubidium::LoadFile(const std::string& path) {
int w, h, c;
uint8_t* dat = stbi_load(path.c_str(), &w, &h, &c, 4);
image = nimg(w, h);
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
int pos = (y * w + x) * 4;
image.pixel_buffer[pos + 0] = dat[pos + 0];
image.pixel_buffer[pos + 1] = dat[pos + 1];
image.pixel_buffer[pos + 2] = dat[pos + 2];
image.pixel_buffer[pos + 3] = dat[pos + 3];
}
}
stbi_image_free(dat);
}
void Rubidium::LoadNimg(const std::string& path) {
image = Palladium::NIMG_Load(path);
}
void Rubidium::DrawPixel(int x, int y, unsigned int color) {
if (x > image.width || x < 0 || y > image.height || y < 0) return;
Palladium::Color::RGBA splitter(color);
image.pixel_buffer[((y * image.width + x) * 4) + 0] = splitter.m_r;
image.pixel_buffer[((y * image.width + x) * 4) + 1] = splitter.m_g;
image.pixel_buffer[((y * image.width + x) * 4) + 2] = splitter.m_b;
image.pixel_buffer[((y * image.width + x) * 4) + 3] = splitter.m_a;
}
void Rubidium::DrawRect(int x, int y, int w, int h, unsigned int color, int t) {
DrawLine(x, y, x + w, y, color, t);
DrawLine(x, y, x, y + h, color, t);
DrawLine(x, y + h, x + w, y + h, color, t);
DrawLine(x + w, y, x + w, y + h, color, t);
}
void Rubidium::DrawRectSolid(int x, int y, int w, int h, unsigned int color) {
for (int ix = x; ix < x + w; ix++) {
for (int iy = y; iy < y + h; iy++) {
DrawPixel(ix, iy, color);
}
}
}
void Rubidium::DrawLine(int x1, int y1, int x2, int y2, unsigned int color,
int t) {
// Reference
// https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
int dx = abs(x2 - x1);
int dy = abs(y2 - y1);
int sx = (x1 < x2) ? 1 : -1;
int sy = (y1 < y2) ? 1 : -1;
int err = dx - dy;
int ht = t / 2;
while (true) {
for (int i = -ht; i <= ht; i++) {
if (dy <= dx) {
DrawPixel(x1, y1 + i, color);
} else {
DrawPixel(x1 + i, y1, color);
}
}
if (x1 == x2 && y1 == y2) break;
int e2 = err * 2;
if (e2 > -dy) {
err -= dy;
x1 += sx;
}
if (e2 < dx) {
err += dx;
y1 += sy;
}
}
}
void Rubidium::Flip(bool h, bool v) {
const nimg _bak = image;
if (h) {
for (int x = 0; x < image.width; x++) {
for (int y = 0; y < image.height; y++) {
int src = (y * image.width + x) * 4;
int dst = ((image.height - 1 - y) * image.width + x) * 4;
image.pixel_buffer[src + 0] = _bak.pixel_buffer[dst + 0];
image.pixel_buffer[src + 1] = _bak.pixel_buffer[dst + 1];
image.pixel_buffer[src + 2] = _bak.pixel_buffer[dst + 2];
image.pixel_buffer[src + 3] = _bak.pixel_buffer[dst + 3];
}
}
}
if (v) {
for (int x = 0; x < image.width; x++) {
for (int y = 0; y < image.height; y++) {
int src = (y * image.width + x) * 4;
int dst = (y * image.width + (image.width - 1 - x)) * 4;
image.pixel_buffer[src + 0] = _bak.pixel_buffer[dst + 0];
image.pixel_buffer[src + 1] = _bak.pixel_buffer[dst + 1];
image.pixel_buffer[src + 2] = _bak.pixel_buffer[dst + 2];
image.pixel_buffer[src + 3] = _bak.pixel_buffer[dst + 3];
}
}
}
}
} // namespace Palladium

View File

@ -45,7 +45,7 @@ void Palladium::Sprite::SetRotCenter(NVec2 percentage) {
} }
void Palladium::Sprite::FromImage(Palladium::Image::Ref img) { void Palladium::Sprite::FromImage(Palladium::Image::Ref img) {
C2D_SpriteFromImage(&this->sprite, img->Get()); // C2D_SpriteFromImage(&this->sprite, img->Get());
} }
void Palladium::Sprite::SetScale(float x, float y) { void Palladium::Sprite::SetScale(float x, float y) {

View File

@ -1,7 +1,8 @@
#include <pd/SpriteAnimation.hpp> #include <pd/SpriteAnimation.hpp>
void Palladium::SpriteSheetAnimation::Setup(Palladium::Sheet::Ref sheet, void Palladium::SpriteSheetAnimation::Setup(Palladium::Sheet::Ref sheet,
size_t imagecount, size_t startimage, size_t imagecount,
size_t startimage,
float frame_begin, float frame_begin,
float frame_finish) { float frame_finish) {
D_totaltime = frame_begin; D_totaltime = frame_begin;

View File

@ -1,11 +1,12 @@
#include <pd/Texture.hpp>
#include <pd/external/stb_image.h> #include <pd/external/stb_image.h>
#include <pd/internal_db.hpp>
#include <pd/external/stb_image_write.h> #include <pd/external/stb_image_write.h>
#include <pd/Texture.hpp>
#include <pd/internal_db.hpp>
namespace pdi { namespace pdi {
static u32 GP2O(u32 v) { static bool single_bit(unsigned int v) { return v && !(v & (v - 1)); }
static u32 get_pow2(u32 v) {
v--; v--;
v |= v >> 1; v |= v >> 1;
v |= v >> 2; v |= v >> 2;
@ -16,7 +17,7 @@ static u32 GP2O(u32 v) {
return (v >= 64 ? v : 64); return (v >= 64 ? v : 64);
} }
static void R24R32(std::vector<uint8_t> &out, static void RGB24toRGBA32(std::vector<uint8_t> &out,
const std::vector<uint8_t> &in, const int &w, const std::vector<uint8_t> &in, const int &w,
const int &h) { const int &h) {
// Converts RGB24 to RGBA32 // Converts RGB24 to RGBA32
@ -30,18 +31,41 @@ static void R24R32(std::vector<uint8_t> &out,
out[dst + 3] = 255; out[dst + 3] = 255;
} }
} }
}} }
} // namespace pdi
namespace Palladium { namespace Palladium {
void Texture::MakeTex(std::vector<unsigned char> &buf, int w, int h) { GPU_TEXCOLOR GetTexFmt(Texture::Type type) {
if (type == Texture::RGBA32)
return GPU_RGBA8;
else if (type == Texture::RGB24)
return GPU_RGB8;
else if (type == Texture::A8)
return GPU_A8;
return GPU_RGBA8; // Default
}
int GetBPP(Texture::Type type) {
if (type == Texture::RGBA32)
return 4;
else if (type == Texture::RGB24)
return 3;
else if (type == Texture::A8)
return 1;
return 0; // Error
}
void Texture::MakeTex(std::vector<unsigned char> &buf, int w, int h,
Type type) {
if (!tex) { if (!tex) {
_pdi_logger()->Write("Invalid Input (object has no adress!)"); _pdi_logger()->Write("Invalid Input (object has no adress!)");
return; return;
} }
// Don't check here as check done before
int bpp = GetBPP(type);
if (bpp == 4) {
// RGBA -> Abgr // RGBA -> Abgr
for (int y = 0; y < h; y++) { for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) { for (int x = 0; x < w; x++) {
int pos = (x + y * w) * 4; int pos = (x + y * w) * bpp;
auto r = buf[pos + 0]; auto r = buf[pos + 0];
auto g = buf[pos + 1]; auto g = buf[pos + 1];
auto b = buf[pos + 2]; auto b = buf[pos + 2];
@ -52,41 +76,61 @@ void Texture::MakeTex(std::vector<unsigned char> &buf, int w, int h) {
buf[pos + 3] = r; buf[pos + 3] = r;
} }
} }
} else if (bpp == 3) {
// RGBA -> Abgr
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
int pos = (x + y * w) * bpp;
auto r = buf[pos + 0];
auto g = buf[pos + 1];
auto b = buf[pos + 2];
buf[pos + 0] = b;
buf[pos + 1] = g;
buf[pos + 2] = r;
}
}
}
NVec2 tex_size(w, h);
// Pow2 // Pow2
this->tex_size.x = pdi::GP2O((unsigned int)w); if (!pdi::single_bit(w)) tex_size.x = pdi::get_pow2((unsigned int)w);
this->tex_size.y = pdi::GP2O((unsigned int)h); if (!pdi::single_bit(h)) tex_size.y = pdi::get_pow2((unsigned int)h);
this->img_size.x = (u16)w; this->img_size.x = (u16)w;
this->img_size.y = (u16)h; this->img_size.y = (u16)h;
this->uvs.x = 0.0f; this->uvs.x = 0.0f;
this->uvs.y = 1.0f; this->uvs.y = 1.0f;
this->uvs.z = ((float)w / (float)this->tex_size.x); this->uvs.z = ((float)w / (float)tex_size.x);
this->uvs.w = 1.0 - ((float)h / (float)this->tex_size.y); this->uvs.w = 1.0 - ((float)h / (float)tex_size.y);
// Texture Setup // Texture Setup
C3D_TexInit(tex, (u16)this->tex_size.x, (u16)this->tex_size.y, GPU_RGBA8); auto tex_fmt = GetTexFmt(type);
C3D_TexInit(tex, (u16)tex_size.x, (u16)tex_size.y, tex_fmt);
C3D_TexSetFilter(tex, GPU_NEAREST, GPU_NEAREST); C3D_TexSetFilter(tex, GPU_NEAREST, GPU_NEAREST);
memset(tex->data, 0, tex->size); memset(tex->data, 0, tex->size);
if (bpp == 3 || bpp == 4) {
for (int x = 0; x < w; x++) { for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) { for (int y = 0; y < h; y++) {
int dst_pos = ((((y >> 3) * ((int)this->tex_size.x >> 3) + (x >> 3)) << 6) + int dst_pos = ((((y >> 3) * ((int)tex_size.x >> 3) + (x >> 3)) << 6) +
((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) | ((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) |
((y & 2) << 2) | ((x & 4) << 2) | ((y & 4) << 3))) * ((y & 2) << 2) | ((x & 4) << 2) | ((y & 4) << 3))) *
4; bpp;
int src_pos = (y * w + x) * 4; int src_pos = (y * w + x) * bpp;
memcpy(&((unsigned char *)tex->data)[dst_pos], &buf[src_pos], 4); memcpy(&((unsigned char *)tex->data)[dst_pos], &buf[src_pos], bpp);
} }
} }
C3D_TexFlush(tex); C3D_TexFlush(tex);
} else if (bpp == 1) {
C3D_TexLoadImage(tex, buf.data(), GPU_TEXFACE_2D, 0);
}
tex->border = 0x00000000; tex->border = 0x00000000;
C3D_TexSetWrap(tex, GPU_CLAMP_TO_BORDER, GPU_CLAMP_TO_BORDER); C3D_TexSetWrap(tex, GPU_CLAMP_TO_BORDER, GPU_CLAMP_TO_BORDER);
} }
void Texture::LoadFile(const std::string& path) { void Texture::LoadFile(const std::string &path) {
int w, h, c = 0; int w, h, c = 0;
unsigned char *image = stbi_load(path.c_str(), &w, &h, &c, 4); unsigned char *image = stbi_load(path.c_str(), &w, &h, &c, 4);
if (image == nullptr) { if (image == nullptr) {
@ -107,8 +151,8 @@ void Texture::LoadFile(const std::string& path) {
stbi_image_free(image); stbi_image_free(image);
image = stbi_load(path.c_str(), &w, &h, &c, 3); image = stbi_load(path.c_str(), &w, &h, &c, 3);
wimg.resize(w * h * 4); wimg.resize(w * h * 4);
pdi::R24R32(wimg, std::vector<unsigned char>(image, image + (w * h * 3)), pdi::RGB24toRGBA32(
w, h); wimg, std::vector<unsigned char>(image, image + (w * h * 3)), w, h);
} else { } else {
wimg.assign(&image[0], &image[(w * h * 4) - 1]); wimg.assign(&image[0], &image[(w * h * 4) - 1]);
stbi_image_free(image); stbi_image_free(image);
@ -118,9 +162,10 @@ void Texture::LoadFile(const std::string& path) {
MakeTex(wimg, w, h); MakeTex(wimg, w, h);
} }
void Texture::LoadFromMemory(const std::vector<unsigned char>& data) { void Texture::LoadFromMemory(const std::vector<unsigned char> &data) {
int w, h, c = 0; int w, h, c = 0;
unsigned char *image = stbi_load_from_memory(data.data(), data.size(), &w, &h, &c, 4); unsigned char *image =
stbi_load_from_memory(data.data(), data.size(), &w, &h, &c, 4);
if (image == nullptr) { if (image == nullptr) {
//_pdi_logger()->Write("Failed to Load Image: " + path); //_pdi_logger()->Write("Failed to Load Image: " + path);
return; return;
@ -139,8 +184,8 @@ void Texture::LoadFromMemory(const std::vector<unsigned char>& data) {
stbi_image_free(image); stbi_image_free(image);
image = stbi_load_from_memory(data.data(), data.size(), &w, &h, &c, 3); image = stbi_load_from_memory(data.data(), data.size(), &w, &h, &c, 3);
wimg.resize(w * h * 4); wimg.resize(w * h * 4);
pdi::R24R32(wimg, std::vector<unsigned char>(image, image + (w * h * 3)), pdi::RGB24toRGBA32(
w, h); wimg, std::vector<unsigned char>(image, image + (w * h * 3)), w, h);
} else { } else {
wimg.assign(&image[0], &image[(w * h * 4) - 1]); wimg.assign(&image[0], &image[(w * h * 4) - 1]);
stbi_image_free(image); stbi_image_free(image);
@ -150,9 +195,17 @@ void Texture::LoadFromMemory(const std::vector<unsigned char>& data) {
MakeTex(wimg, w, h); MakeTex(wimg, w, h);
} }
void Texture::LoadPixels(const std::vector<unsigned char>& data, int w, int h) { NVec2 Texture::GetTexSize() {
if (!tex) return NVec2();
return NVec2(tex->width, tex->height);
}
void Texture::LoadPixels(const std::vector<unsigned char> &data, int w, int h,
Type type) {
Delete(); Delete();
if(w*h*4 != (int)data.size()) { int bpp = GetBPP(type);
Palladium::InlineAssert(bpp, "Invalid Type");
if (w * h * bpp != (int)data.size()) {
return; return;
} }
if (w > 1024 || h > 1024) { if (w > 1024 || h > 1024) {
@ -162,16 +215,27 @@ void Texture::LoadPixels(const std::vector<unsigned char>& data, int w, int h) {
} }
tex = new C3D_Tex; tex = new C3D_Tex;
std::vector<unsigned char> wimg(data); std::vector<unsigned char> wimg(data);
MakeTex(wimg, w, h); MakeTex(wimg, w, h, type);
}
void Texture::ExternalLoad(C3D_Tex *tex, NVec2 rszs, NVec4 uvs) {
Delete();
this->tex = tex;
this->img_size = rszs;
this->uvs = uvs;
} }
void Texture::Delete() { void Texture::Delete() {
if(tex) { if (!ad) return;
if (tex) {
C3D_TexDelete(tex);
delete tex; delete tex;
tex = nullptr; tex = nullptr;
img_size = NVec2(); img_size = NVec2();
tex_size = NVec2(); this->uvs.x = 0.0f;
uvs = NVec4(); this->uvs.y = 1.0f;
this->uvs.z = 1.0f;
this->uvs.w = 0.0f;
} }
} }
} } // namespace Palladium

View File

@ -116,11 +116,10 @@ class DrawCmd {
} }
Palladium::R2::OnScreen(screen ? R2Screen_Top : R2Screen_Bottom); Palladium::R2::OnScreen(screen ? R2Screen_Top : R2Screen_Bottom);
if (type == DrawCmdType_Rect) { if (type == DrawCmdType_Rect) {
Palladium::R2::AddRect(NVec2(rect.x, rect.y), NVec2(rect.z, rect.w), Palladium::R2::AddRect(NVec2(rect.x, rect.y), NVec2(rect.z, rect.w), clr);
clr);
} else if (type == DrawCmdType_Triangle) { } else if (type == DrawCmdType_Triangle) {
Palladium::R2::AddTriangle(NVec2(rect.x, rect.y), Palladium::R2::AddTriangle(NVec2(rect.x, rect.y), NVec2(rect.z, rect.w),
NVec2(rect.z, rect.w), add_coords, clr); add_coords, clr);
} else if (type == DrawCmdType_Text) { } else if (type == DrawCmdType_Text) {
Palladium::R2::AddText(NVec2(rect.x, rect.y), text, clr, text_flags, Palladium::R2::AddText(NVec2(rect.x, rect.y), text, clr, text_flags,
text_box); text_box);
@ -144,9 +143,8 @@ class DrawCmd {
NVec2(rect.x, rect.y + rect.w), 0xff0000ff); NVec2(rect.x, rect.y + rect.w), 0xff0000ff);
} else if (stype == DrawCmdType_Triangle) { } else if (stype == DrawCmdType_Triangle) {
Palladium::R2::DrawNextLined(); Palladium::R2::DrawNextLined();
Palladium::R2::AddTriangle(NVec2(rect.x, rect.y), Palladium::R2::AddTriangle(NVec2(rect.x, rect.y), NVec2(rect.z, rect.w),
NVec2(rect.z, rect.w), add_coords, add_coords, 0xff00ff00);
0xff00ff00);
} else if (stype == DrawCmdType_Text) { } else if (stype == DrawCmdType_Text) {
auto szs = Palladium::R2::GetTextDimensions(text); auto szs = Palladium::R2::GetTextDimensions(text);
if (text_flags & PDTextFlags_AlignRight) { if (text_flags & PDTextFlags_AlignRight) {
@ -214,8 +212,7 @@ void UI7DrawList::AddRectangle(NVec2 pos, NVec2 szs, unsigned int clr) {
AddCall(cmd); AddCall(cmd);
} }
void UI7DrawList::AddTriangle(NVec2 pos0, NVec2 pos1, NVec2 pos2, void UI7DrawList::AddTriangle(NVec2 pos0, NVec2 pos1, NVec2 pos2, PDColor clr) {
PDColor clr) {
auto cmd = DrawCmd::New(); auto cmd = DrawCmd::New();
cmd->screen = Palladium::R2::GetCurrentScreen(); cmd->screen = Palladium::R2::GetCurrentScreen();
cmd->rect.x = pos0.x; cmd->rect.x = pos0.x;
@ -452,8 +449,8 @@ void UI7CtxEndMenu() {
(static_cast<float>(ui7_ctx->cm->scrolling_offset) / (static_cast<float>(ui7_ctx->cm->scrolling_offset) /
static_cast<float>(ui7_ctx->cm->ms.y - 240.f))))); static_cast<float>(ui7_ctx->cm->ms.y - 240.f)))));
// Render Slider // Render Slider
ui7_ctx->cm->front->AddRectangle( ui7_ctx->cm->front->AddRectangle(NVec2(sw - 12, tsp),
NVec2(sw - 12, tsp), NVec2(slider_w * 2, szs), PDColor_List0); NVec2(slider_w * 2, szs), PDColor_List0);
ui7_ctx->cm->front->AddRectangle(NVec2(sw - 10, slider_pos + 2), ui7_ctx->cm->front->AddRectangle(NVec2(sw - 10, slider_pos + 2),
NVec2(slider_w, slider_rh), slider_clr); NVec2(slider_w, slider_rh), slider_clr);
} }
@ -653,8 +650,7 @@ void Label(const std::string &label, PDTextFlags flags) {
void Progressbar(float value) { void Progressbar(float value) {
if (!UI7CtxValidate()) return; if (!UI7CtxValidate()) return;
NVec2 pos = GetCursorPos(); NVec2 pos = GetCursorPos();
NVec2 size = NVec2 size = NVec2(Palladium::R2::GetCurrentScreenSize().x - (pos.x * 2), 20);
NVec2(Palladium::R2::GetCurrentScreenSize().x - (pos.x * 2), 20);
if (ui7_ctx->cm->show_scroolbar && ui7_ctx->cm->enable_scrolling) if (ui7_ctx->cm->show_scroolbar && ui7_ctx->cm->enable_scrolling)
size.x -= 16; size.x -= 16;
MoveCursor(size); MoveCursor(size);
@ -719,8 +715,7 @@ void BrowserList(const std::vector<std::string> &entrys, int &selection,
ui7_ctx->cm->main->AddText( ui7_ctx->cm->main->AddText(
pos + NVec2(5, 15 * i), entrys[list_index], pos + NVec2(5, 15 * i), entrys[list_index],
Palladium::ThemeActive()->AutoText( Palladium::ThemeActive()->AutoText(
selindex == (int)i selindex == (int)i ? PDColor_Selector
? PDColor_Selector
: (i % 2 == 0 ? PDColor_List0 : PDColor_List1)), : (i % 2 == 0 ? PDColor_List0 : PDColor_List1)),
txtflags | PDTextFlags_Short, NVec2(size.x, 15)); txtflags | PDTextFlags_Short, NVec2(size.x, 15));
} }
@ -874,7 +869,8 @@ bool BeginMenu(const std::string &title, NVec2 size, UI7MenuFlags flags) {
ui7_ctx->cm->front->AddText( ui7_ctx->cm->front->AddText(
NVec2(5, 2), id.Title(), NVec2(5, 2), id.Title(),
Palladium::ThemeActive()->AutoText(PDColor_Header), txtflags); Palladium::ThemeActive()->AutoText(PDColor_Header), txtflags,
NVec2(size.x, 0));
} }
SetCursorPos(NVec2(5, ui7_ctx->cm->tbh + 5)); SetCursorPos(NVec2(5, ui7_ctx->cm->tbh + 5));
@ -1043,8 +1039,7 @@ void ColorSelector(const std::string &label, unsigned int &color) {
// Draw Color Name Shorted if needed // Draw Color Name Shorted if needed
ui7_ctx->cm->front->AddText( ui7_ctx->cm->front->AddText(
npos + NVec2(cbs.x + 7, 1), label, npos + NVec2(cbs.x + 7, 1), label,
Palladium::ThemeActive()->AutoText(PDColor_FrameBg), Palladium::ThemeActive()->AutoText(PDColor_FrameBg), PDTextFlags_Short);
PDTextFlags_Short);
// Add luminance text // Add luminance text
ui7_ctx->cm->front->AddText( ui7_ctx->cm->front->AddText(
npos + NVec2(2, cbs.y + 4), "lum: " + std::to_string(clr.luminance()), npos + NVec2(2, cbs.y + 4), "lum: " + std::to_string(clr.luminance()),
@ -1062,9 +1057,9 @@ void ColorSelector(const std::string &label, unsigned int &color) {
ui7_ctx->cm->front->AddRectangle( ui7_ctx->cm->front->AddRectangle(
npos + NVec2(2, cbs.y * 3 + 4), npos + NVec2(2, cbs.y * 3 + 4),
NVec2(50 * ((float)clr.m_r / 255.f), cbs.y), 0xff0000ff); NVec2(50 * ((float)clr.m_r / 255.f), cbs.y), 0xff0000ff);
ui7_ctx->cm->front->AddText( ui7_ctx->cm->front->AddText(npos + NVec2(2, cbs.y * 3 + 4),
npos + NVec2(2, cbs.y * 3 + 4), "R: " + std::to_string(clr.m_r), "R: " + std::to_string(clr.m_r), PDColor_Text,
PDColor_Text, PDTextFlags_AlignMid, NVec2(50, 0)); PDTextFlags_AlignMid, NVec2(50, 0));
} }
// Green // Green
{ {
@ -1074,9 +1069,9 @@ void ColorSelector(const std::string &label, unsigned int &color) {
ui7_ctx->cm->front->AddRectangle( ui7_ctx->cm->front->AddRectangle(
npos + NVec2(54, cbs.y * 3 + 4), npos + NVec2(54, cbs.y * 3 + 4),
NVec2(50 * ((float)clr.m_g / 255.f), cbs.y), 0xff00ff00); NVec2(50 * ((float)clr.m_g / 255.f), cbs.y), 0xff00ff00);
ui7_ctx->cm->front->AddText( ui7_ctx->cm->front->AddText(npos + NVec2(54, cbs.y * 3 + 4),
npos + NVec2(54, cbs.y * 3 + 4), "G: " + std::to_string(clr.m_g), "G: " + std::to_string(clr.m_g), PDColor_Text,
PDColor_Text, PDTextFlags_AlignMid, NVec2(50, 0)); PDTextFlags_AlignMid, NVec2(50, 0));
} }
// Blue // Blue
{ {
@ -1086,9 +1081,9 @@ void ColorSelector(const std::string &label, unsigned int &color) {
ui7_ctx->cm->front->AddRectangle( ui7_ctx->cm->front->AddRectangle(
npos + NVec2(2, cbs.y * 4 + 4), npos + NVec2(2, cbs.y * 4 + 4),
NVec2(50 * ((float)clr.m_b / 255.f), cbs.y), 0xffff0000); NVec2(50 * ((float)clr.m_b / 255.f), cbs.y), 0xffff0000);
ui7_ctx->cm->front->AddText( ui7_ctx->cm->front->AddText(npos + NVec2(2, cbs.y * 4 + 4),
npos + NVec2(2, cbs.y * 4 + 4), "B: " + std::to_string(clr.m_b), "B: " + std::to_string(clr.m_b), PDColor_Text,
PDColor_Text, PDTextFlags_AlignMid, NVec2(50, 0)); PDTextFlags_AlignMid, NVec2(50, 0));
} }
// Alpha // Alpha
{ {
@ -1098,15 +1093,14 @@ void ColorSelector(const std::string &label, unsigned int &color) {
ui7_ctx->cm->front->AddRectangle( ui7_ctx->cm->front->AddRectangle(
npos + NVec2(54, cbs.y * 4 + 4), npos + NVec2(54, cbs.y * 4 + 4),
NVec2(50 * ((float)clr.m_a / 255.f), cbs.y), 0xffffffff); NVec2(50 * ((float)clr.m_a / 255.f), cbs.y), 0xffffffff);
ui7_ctx->cm->front->AddText( ui7_ctx->cm->front->AddText(npos + NVec2(54, cbs.y * 4 + 4),
npos + NVec2(54, cbs.y * 4 + 4), "A: " + std::to_string(clr.m_a), "A: " + std::to_string(clr.m_a), PDColor_Text,
PDColor_Text, PDTextFlags_AlignMid, NVec2(50, 0)); PDTextFlags_AlignMid, NVec2(50, 0));
} }
} }
ui7_ctx->cm->main->AddRectangle(pos, cbs, outline); ui7_ctx->cm->main->AddRectangle(pos, cbs, outline);
ui7_ctx->cm->main->AddRectangle(pos + NVec2(2, 2), cbs - NVec2(4, 4), ui7_ctx->cm->main->AddRectangle(pos + NVec2(2, 2), cbs - NVec2(4, 4), color);
color);
ui7_ctx->cm->main->AddText( ui7_ctx->cm->main->AddText(
pos + NVec2(cbs.x + 5, 1), label, pos + NVec2(cbs.x + 5, 1), label,
Palladium::ThemeActive()->AutoText(PDColor_Background)); Palladium::ThemeActive()->AutoText(PDColor_Background));

View File

@ -96,7 +96,8 @@ Palladium::Net::Error pdi_soc_init() {
Result ret = socInit((u32 *)pdi_soc_buf, 0x100000); Result ret = socInit((u32 *)pdi_soc_buf, 0x100000);
if (R_FAILED(ret)) { if (R_FAILED(ret)) {
free(pdi_soc_buf); free(pdi_soc_buf);
return ((static_cast<Palladium::Net::Error>(ret) << 32) | return (
(static_cast<Palladium::Net::Error>(ret) << 32) |
static_cast<Palladium::Net::Error>(Palladium::Net::Error_CtrStatus)); static_cast<Palladium::Net::Error>(Palladium::Net::Error_CtrStatus));
} }
return 0; return 0;

10
source/li7_shader.cpp Normal file
View File

@ -0,0 +1,10 @@
// THIS FILE WAS GENERATED BY build_shaders.py!!!
#include <pd/li7_shader.hpp>
// clang-format off
unsigned char li7_shader[] = {
0x44, 0x56, 0x4c, 0x42, 0x1, 0x0, 0x0, 0x0, 0xa4, 0x0, 0x0, 0x0, 0x44, 0x56, 0x4c, 0x50, 0x0, 0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x98, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4e, 0x1, 0xf0, 0x7, 0x4e, 0x2, 0x8, 0x2, 0x8, 0x3, 0x18, 0x2, 0x8, 0x4, 0x28, 0x2, 0x8, 0x5, 0x38, 0x2, 0x8, 0x6, 0x10, 0x40, 0x4c, 0x7, 0xf1, 0x27, 0x22, 0x8, 0x10, 0x21, 0x4c, 0x0, 0x0, 0x0, 0x88, 0x4e, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa1, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x68, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x64, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x62, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x61, 0xc3, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaf, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4f, 0xd5, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6f, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x44, 0x56, 0x4c, 0x45, 0x2, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x54, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x6c, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x74, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x2, 0x0, 0x5f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x0, 0x1, 0x1, 0x37, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, 0x2, 0x0, 0x1, 0x0, 0xf, 0x0, 0x0, 0x0, 0x3, 0x0, 0x2, 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x13, 0x0, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0, 0x0,
};
// clang-format on
size_t li7_shader_size = 0x124;

View File

@ -6,8 +6,8 @@
#define reca_cc(x) reinterpret_cast<const char*>(x) #define reca_cc(x) reinterpret_cast<const char*>(x)
#define reca_c(x) reinterpret_cast<char*>(x) #define reca_c(x) reinterpret_cast<char*>(x)
#define pak32(q, w, e, r) \ #define pak32(q, w, e, r) \
((((q) & 0xff) << 0) | (((w) & 0xff) << 8) | (((e) & 0xff) << 16) | \ ((((q)&0xff) << 0) | (((w)&0xff) << 8) | (((e)&0xff) << 16) | \
(((r) & 0xff) << 24)) (((r)&0xff) << 24))
// Stupid RLE Algorithm // Stupid RLE Algorithm
void npi_compress(std::vector<unsigned char>& ret, void npi_compress(std::vector<unsigned char>& ret,

View File

@ -1,10 +1,10 @@
#include <pd/Hid.hpp> // Integate HidApi #include <pd/Hid.hpp> // Integate HidApi
#include <pd/LI7.hpp>
#include <pd/Message.hpp> #include <pd/Message.hpp>
#include <pd/Overlays.hpp> #include <pd/Overlays.hpp>
#include <pd/ThemeEditor.hpp> #include <pd/ThemeEditor.hpp>
#include <pd/UI7.hpp> #include <pd/UI7.hpp>
#include <pd/palladium.hpp> #include <pd/palladium.hpp>
#include <pd/LI7.hpp>
// Config 2 // Config 2
#include <pd/external/json.hpp> #include <pd/external/json.hpp>
@ -14,25 +14,20 @@
#include <filesystem> #include <filesystem>
#include <random> #include <random>
#define DISPLAY_TRANSFER_FLAGS \
(GX_TRANSFER_FLIP_VERT(0) | GX_TRANSFER_OUT_TILED(0) | \
GX_TRANSFER_RAW_COPY(0) | GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | \
GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) | \
GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO))
Palladium::LoggerBase::Ref pdi_glogger; Palladium::LoggerBase::Ref pdi_glogger;
extern Palladium::LoggerBase::Ref pdi_logger; extern Palladium::LoggerBase::Ref pdi_logger;
static void pdi_ExitHook() { void exit_romfs() {
C2D_TextBufDelete(pdi_text_buffer);
C2D_TextBufDelete(pdi_d2_dimbuf);
romfsExit(); romfsExit();
} }
std::vector<std::string> string_to_lines(std::string input_str) { // TODO: Better Fader
std::vector<std::string> lines;
std::stringstream ss(input_str);
std::string line;
while (std::getline(ss, line)) {
lines.push_back(line);
}
return lines;
}
void Npifade() { void Npifade() {
if (pdi_fadein) { if (pdi_fadein) {
if (pdi_fadealpha < 255) { if (pdi_fadealpha < 255) {
@ -121,8 +116,7 @@ void pdi_init_input() {
} }
void pdi_init_config() { void pdi_init_config() {
pdi_config_path = "sdmc:/Palladium/Apps/"; pdi_config_path = Palladium::GetAppDirectory();
pdi_config_path += pdi_app_name;
std::filesystem::create_directories(pdi_config_path.c_str()); std::filesystem::create_directories(pdi_config_path.c_str());
std::filesystem::create_directories("sdmc:/Palladium/Reports"); std::filesystem::create_directories("sdmc:/Palladium/Reports");
bool renew = false; bool renew = false;
@ -222,7 +216,8 @@ void Palladium::Scene::doDraw() {
void Palladium::Scene::doLogic() { void Palladium::Scene::doLogic() {
Ftrace::ScopedTrace st("pd-core", f2s(Scene::doLogic)); Ftrace::ScopedTrace st("pd-core", f2s(Scene::doLogic));
if (!Palladium::Scene::scenes.empty()) Palladium::Scene::scenes.top()->Logic(); if (!Palladium::Scene::scenes.empty())
Palladium::Scene::scenes.top()->Logic();
} }
void Palladium::Scene::Load(std::unique_ptr<Scene> scene, bool fade) { void Palladium::Scene::Load(std::unique_ptr<Scene> scene, bool fade) {
@ -274,11 +269,12 @@ bool Palladium::MainLoop() {
Hid::Update(); Hid::Update();
pdi_hid_touch_pos = NVec2(d7_touch.px, d7_touch.py); pdi_hid_touch_pos = NVec2(d7_touch.px, d7_touch.py);
Palladium::ClearTextBufs(); // Palladium::ClearTextBufs();
C3D_FrameBegin(C3D_FRAME_SYNCDRAW); C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
C2D_TargetClear(pd_top, C2D_Color32(0, 0, 0, 0)); C3D_RenderTargetClear(pd_top, C3D_CLEAR_ALL, 0x00000000, 0);
C2D_TargetClear(pd_bottom, C2D_Color32(0, 0, 0, 0)); C3D_RenderTargetClear(pd_top_right, C3D_CLEAR_ALL, 0x00000000, 0);
C3D_RenderTargetClear(pd_bottom, C3D_CLEAR_ALL, 0x00000000, 0);
frameloop(); frameloop();
if (pdi_enable_scene_system) { if (pdi_enable_scene_system) {
Palladium::Scene::doDraw(); Palladium::Scene::doDraw();
@ -287,8 +283,6 @@ bool Palladium::MainLoop() {
return pdi_running; return pdi_running;
} }
void Palladium::ClearTextBufs(void) { C2D_TextBufClear(pdi_text_buffer); }
void Palladium::Init::Graphics() { void Palladium::Init::Graphics() {
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
C2D_Init((size_t)pd_max_objects); C2D_Init((size_t)pd_max_objects);
@ -348,16 +342,22 @@ Result Palladium::Init::Main(std::string app_name) {
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
atexit(C3D_Fini); atexit(C3D_Fini);
C2D_Init((size_t)pd_max_objects);
atexit(C2D_Fini); pd_top =
atexit(pdi_ExitHook); C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
C2D_Prepare(); C3D_RenderTargetSetOutput(pd_top, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS);
pd_top = C2D_CreateScreenTarget(GFX_TOP, GFX_LEFT); pd_top_right =
pd_top_right = C2D_CreateScreenTarget(GFX_TOP, GFX_RIGHT); C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
pd_bottom = C2D_CreateScreenTarget(GFX_BOTTOM, GFX_LEFT); C3D_RenderTargetSetOutput(pd_top_right, GFX_TOP, GFX_RIGHT,
pdi_text_buffer = C2D_TextBufNew(4096); DISPLAY_TRANSFER_FLAGS);
pdi_d2_dimbuf = C2D_TextBufNew(4096); pd_bottom =
pdi_base_font = C2D_FontLoadSystem(CFG_REGION_USA); C3D_RenderTargetCreate(240, 320, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
C3D_RenderTargetSetOutput(pd_bottom, GFX_BOTTOM, GFX_LEFT,
DISPLAY_TRANSFER_FLAGS);
LI7::Init();
atexit(LI7::Exit);
atexit(exit_romfs);
R2::Init();
R2::Init(); R2::Init();
pdi_graphics_on = true; pdi_graphics_on = true;
@ -408,16 +408,21 @@ Result Palladium::Init::Minimal(std::string app_name) {
osSetSpeedupEnable(true); osSetSpeedupEnable(true);
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
atexit(C3D_Fini); atexit(C3D_Fini);
C2D_Init((size_t)pd_max_objects);
atexit(C2D_Fini); pd_top =
atexit(pdi_ExitHook); C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
C2D_Prepare(); C3D_RenderTargetSetOutput(pd_top, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS);
pd_top = C2D_CreateScreenTarget(GFX_TOP, GFX_LEFT); pd_top_right =
pd_top_right = C2D_CreateScreenTarget(GFX_TOP, GFX_RIGHT); C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
pd_bottom = C2D_CreateScreenTarget(GFX_BOTTOM, GFX_LEFT); C3D_RenderTargetSetOutput(pd_top_right, GFX_TOP, GFX_RIGHT,
pdi_text_buffer = C2D_TextBufNew(4096); DISPLAY_TRANSFER_FLAGS);
pdi_d2_dimbuf = C2D_TextBufNew(4096); pd_bottom =
pdi_base_font = C2D_FontLoadSystem(CFG_REGION_USA); C3D_RenderTargetCreate(240, 320, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
C3D_RenderTargetSetOutput(pd_bottom, GFX_BOTTOM, GFX_LEFT,
DISPLAY_TRANSFER_FLAGS);
LI7::Init();
atexit(LI7::Exit);
atexit(exit_romfs);
R2::Init(); R2::Init();
pdi_graphics_on = true; pdi_graphics_on = true;
@ -500,6 +505,7 @@ void Palladium::FrameEnd() {
OvlHandler(); OvlHandler();
Npifade(); Npifade();
R2::Process(); R2::Process();
LI7::Render(pd_top, pd_bottom);
C3D_FrameEnd(0); C3D_FrameEnd(0);
} }
@ -530,6 +536,13 @@ std::vector<std::string> StrHelper(std::string input) {
return test1; return test1;
} }
void DisplayCodepoint(char cp) {
if(!UI7::InMenu()) return;
NVec2 szs = NVec2(297, 52);
NVec2 pos = UI7::GetCursorPos();
UI7::MoveCursor(szs);
}
void Palladium::RSettings::Draw(void) const { void Palladium::RSettings::Draw(void) const {
if (m_state == RSETTINGS) { if (m_state == RSETTINGS) {
Palladium::R2::OnScreen(R2Screen_Top); Palladium::R2::OnScreen(R2Screen_Top);
@ -548,13 +561,17 @@ void Palladium::RSettings::Draw(void) const {
UI7::EndMenu(); UI7::EndMenu();
} }
Palladium::R2::OnScreen(R2Screen_Bottom); Palladium::R2::OnScreen(R2Screen_Bottom);
if (UI7::BeginMenu("Press \uE001 to go back!")) { if (UI7::BeginMenu("Press B to go back!")) {
if (UI7::Button("FTrace")) { if (UI7::Button("FTrace")) {
shared_request[0x00000001] = RFTRACE; shared_request[0x00000001] = RFTRACE;
} }
if (UI7::Button("UI7")) { if (UI7::Button("UI7")) {
shared_request[0x00000001] = RUI7; shared_request[0x00000001] = RUI7;
} }
UI7::SameLine();
if (UI7::Button("Font")) {
shared_request[0x00000001] = RFV;
}
if (UI7::Button("Overlays")) { if (UI7::Button("Overlays")) {
shared_request[0x00000001] = ROVERLAYS; shared_request[0x00000001] = ROVERLAYS;
} }
@ -589,7 +606,7 @@ void Palladium::RSettings::Draw(void) const {
UI7::EndMenu(); UI7::EndMenu();
} }
Palladium::R2::OnScreen(R2Screen_Bottom); Palladium::R2::OnScreen(R2Screen_Bottom);
if (UI7::BeginMenu("Press \uE001 to go back!")) { if (UI7::BeginMenu("Press B to go back!")) {
if (UI7::Button("Start Server")) { if (UI7::Button("Start Server")) {
Palladium::IDB::Start(); Palladium::IDB::Start();
} }
@ -640,10 +657,10 @@ void Palladium::RSettings::Draw(void) const {
// List Bg // List Bg
for (int i = 0; i < 12; i++) { for (int i = 0; i < 12; i++) {
if ((i % 2 == 0)) if ((i % 2 == 0))
UI7::GetBackgroundList()->AddRectangle(NVec2(0, 40 + (i) * 15), UI7::GetBackgroundList()->AddRectangle(NVec2(0, 40 + (i)*15),
NVec2(400, 15), PDColor_List0); NVec2(400, 15), PDColor_List0);
else else
UI7::GetBackgroundList()->AddRectangle(NVec2(0, 40 + (i) * 15), UI7::GetBackgroundList()->AddRectangle(NVec2(0, 40 + (i)*15),
NVec2(400, 15), PDColor_List1); NVec2(400, 15), PDColor_List1);
} }
@ -655,7 +672,7 @@ void Palladium::RSettings::Draw(void) const {
std::string _fkey__ = "0"; std::string _fkey__ = "0";
while (ix < (int)Palladium::Ftrace::pd_traces.size() && while (ix < (int)Palladium::Ftrace::pd_traces.size() &&
ix < start_index + 10 && it != Palladium::Ftrace::pd_traces.end()) { ix < start_index + 12 && it != Palladium::Ftrace::pd_traces.end()) {
if (ix == ftrace_index) { if (ix == ftrace_index) {
_fkey__ = it->first; _fkey__ = it->first;
UI7::GetBackgroundList()->AddRectangle( UI7::GetBackgroundList()->AddRectangle(
@ -665,8 +682,8 @@ void Palladium::RSettings::Draw(void) const {
auto clr = ix == ftrace_index auto clr = ix == ftrace_index
? PDColor_Selector ? PDColor_Selector
: (ix % 2 == 0 ? PDColor_List0 : PDColor_List1); : (ix % 2 == 0 ? PDColor_List0 : PDColor_List1);
UI7::GetBackgroundList()->AddText(NVec2(5, 40 + (ix - start_index) * 15), UI7::GetBackgroundList()->AddText(
it->second.func_name, NVec2(5, 40 + (ix - start_index) * 15), it->second.func_name,
Palladium::ThemeActive()->AutoText(clr)); Palladium::ThemeActive()->AutoText(clr));
UI7::GetBackgroundList()->AddText( UI7::GetBackgroundList()->AddText(
NVec2(395, 40 + (ix - start_index) * 15), NVec2(395, 40 + (ix - start_index) * 15),
@ -679,7 +696,7 @@ void Palladium::RSettings::Draw(void) const {
Palladium::Ftrace::End("PDft", "display_traces"); Palladium::Ftrace::End("PDft", "display_traces");
Palladium::R2::OnScreen(R2Screen_Bottom); Palladium::R2::OnScreen(R2Screen_Bottom);
if (UI7::BeginMenu("Press \uE001 to go back!")) { if (UI7::BeginMenu("Press B to go back!")) {
auto jt = Palladium::Ftrace::pd_traces.begin(); auto jt = Palladium::Ftrace::pd_traces.begin();
std::advance(jt, ftrace_index); std::advance(jt, ftrace_index);
UI7::Label("Group: " + jt->second.group); UI7::Label("Group: " + jt->second.group);
@ -718,7 +735,7 @@ void Palladium::RSettings::Draw(void) const {
} }
Palladium::R2::OnScreen(R2Screen_Bottom); Palladium::R2::OnScreen(R2Screen_Bottom);
if (UI7::BeginMenu("Press \uE001 to go back!", NVec2(), if (UI7::BeginMenu("Press B to go back!", NVec2(),
UI7MenuFlags_Scrolling)) { UI7MenuFlags_Scrolling)) {
if (UI7::Button("Go back")) { if (UI7::Button("Go back")) {
/// Request a state switch to state RSETTINGS /// Request a state switch to state RSETTINGS
@ -740,7 +757,7 @@ void Palladium::RSettings::Draw(void) const {
} }
Palladium::R2::OnScreen(R2Screen_Bottom); Palladium::R2::OnScreen(R2Screen_Bottom);
if (UI7::BeginMenu("Press \uE001 to go back!")) { if (UI7::BeginMenu("Press B to go back!")) {
UI7::Label("Metrik:"); UI7::Label("Metrik:");
UI7::Checkbox("Enable Overlay", pdi_metrikd); UI7::Checkbox("Enable Overlay", pdi_metrikd);
UI7::Checkbox("Bottom Screen", pdi_mt_screen); UI7::Checkbox("Bottom Screen", pdi_mt_screen);
@ -763,11 +780,29 @@ void Palladium::RSettings::Draw(void) const {
} }
Palladium::R2::OnScreen(R2Screen_Bottom); Palladium::R2::OnScreen(R2Screen_Bottom);
if (UI7::BeginMenu("Press \uE001 to go back!", NVec2(), if (UI7::BeginMenu("Press B to go back!", NVec2(),
UI7MenuFlags_Scrolling)) { UI7MenuFlags_Scrolling)) {
for (auto &it : pdi_logger->Lines()) UI7::Label(it, PDTextFlags_Wrap); for (auto &it : pdi_logger->Lines()) UI7::Label(it, PDTextFlags_Wrap);
UI7::EndMenu(); UI7::EndMenu();
} }
} else if (m_state == RFV) {
Palladium::R2::OnScreen(R2Screen_Top);
if (UI7::BeginMenu("Palladium -> Font Viewer")) {
UI7::SetCursorPos(NVec2(395, 2));
UI7::Label(PDVSTRING, PDTextFlags_AlignRight);
UI7::RestoreCursor();
UI7::Label("Font: "+LI7::GetFont()->GetName());
UI7::EndMenu();
}
Palladium::R2::OnScreen(R2Screen_Bottom);
if (UI7::BeginMenu("Press B to go back!", NVec2(),
UI7MenuFlags_Scrolling)) {
for(int i = 0; i < 255; i++) {
DisplayCodepoint(i);
}
UI7::EndMenu();
}
} }
} }
@ -779,7 +814,7 @@ void Palladium::RSettings::Logic() {
} else if (it.first == 0x00000002) { } else if (it.first == 0x00000002) {
if (it.second) { if (it.second) {
std::fstream cfg_wrt(pdi_config_path + "/config.rc7", std::ios::out); std::fstream cfg_wrt(pdi_config_path + "/config.rc7", std::ios::out);
pdi_config["metrik-settings"]["enableoverlay"] = pdi_metrikd; pdi_config["metrik-settings"]["show"] = pdi_metrikd;
pdi_config["metrik-settings"]["Screen"] = pdi_mt_screen; pdi_config["metrik-settings"]["Screen"] = pdi_mt_screen;
pdi_config["internal_logger"]["nowritetxt"] = pdi_lggrf; pdi_config["internal_logger"]["nowritetxt"] = pdi_lggrf;
cfg_wrt << pdi_config.dump(4); cfg_wrt << pdi_config.dump(4);
@ -808,9 +843,9 @@ void Palladium::RSettings::Logic() {
stateftold = pdi_ftraced; stateftold = pdi_ftraced;
if (m_state == RSETTINGS) { if (m_state == RSETTINGS) {
if (d7_hDown & KEY_B) { if (d7_hUp & KEY_B) {
std::fstream cfg_wrt(pdi_config_path + "/config.rc7", std::ios::out); std::fstream cfg_wrt(pdi_config_path + "/config.rc7", std::ios::out);
pdi_config["metrik-settings"]["enableoverlay"] = pdi_metrikd; pdi_config["metrik-settings"]["show"] = pdi_metrikd;
pdi_config["metrik-settings"]["Screen"] = pdi_mt_screen; pdi_config["metrik-settings"]["Screen"] = pdi_mt_screen;
pdi_config["internal_logger"]["nowritetxt"] = pdi_lggrf; pdi_config["internal_logger"]["nowritetxt"] = pdi_lggrf;
cfg_wrt << pdi_config.dump(4); cfg_wrt << pdi_config.dump(4);
@ -820,20 +855,20 @@ void Palladium::RSettings::Logic() {
Palladium::Scene::Back(); Palladium::Scene::Back();
} }
} }
if (m_state == RUI7) { if (m_state == RUI7 || m_state == RFV) {
if (d7_hDown & KEY_B) { if (d7_hUp & KEY_B) {
m_state = RSETTINGS; m_state = RSETTINGS;
} }
} }
if (m_state == ROVERLAYS) { if (m_state == ROVERLAYS) {
mtovlstate = pdi_metrikd ? "true" : "false"; mtovlstate = pdi_metrikd ? "true" : "false";
mtscreenstate = pdi_mt_screen ? "Bottom" : "Top"; mtscreenstate = pdi_mt_screen ? "Bottom" : "Top";
if (d7_hDown & KEY_B) { if (d7_hUp & KEY_B) {
m_state = RSETTINGS; m_state = RSETTINGS;
} }
} }
if (m_state == RIDB || m_state == RLOGS) { if (m_state == RIDB || m_state == RLOGS) {
if (d7_hDown & KEY_B) { if (d7_hUp & KEY_B) {
m_state = RSETTINGS; m_state = RSETTINGS;
} }
} }
@ -845,7 +880,7 @@ void Palladium::RSettings::Logic() {
if (d7_hDown & KEY_UP) { if (d7_hDown & KEY_UP) {
if (ftrace_index > 0) ftrace_index--; if (ftrace_index > 0) ftrace_index--;
} }
if (d7_hDown & KEY_B) { if (d7_hUp & KEY_B) {
m_state = RSETTINGS; m_state = RSETTINGS;
} }
} }

View File

@ -1,94 +0,0 @@
#include <pd/external/stb_image.h>
#include <pd/Color.hpp>
#include <pd/swr.hpp>
namespace Palladium {
swr::swr(int w, int h) { image = Palladium::nimg(w, h); }
swr::swr() { image = Palladium::nimg(1, 1); }
swr::~swr() {
// Do nothing
}
void swr::load_file(const std::string& path) {
int w, h, c;
uint8_t* dat = stbi_load(path.c_str(), &w, &h, &c, 4);
image = nimg(w, h);
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
int pos = (y * w + x) * 4;
image.pixel_buffer[pos + 0] = dat[pos + 0];
image.pixel_buffer[pos + 1] = dat[pos + 1];
image.pixel_buffer[pos + 2] = dat[pos + 2];
image.pixel_buffer[pos + 3] = dat[pos + 3];
}
}
stbi_image_free(dat);
}
void swr::load_nimg(const std::string& path) {
image = Palladium::NIMG_Load(path);
}
void swr::draw_pixel(int x, int y, unsigned int color) {
if (x > image.width || x < 0 || y > image.height || y < 0) return;
Palladium::Color::RGBA splitter(color);
image.pixel_buffer[((y * image.width + x) * 4) + 0] = splitter.m_r;
image.pixel_buffer[((y * image.width + x) * 4) + 1] = splitter.m_g;
image.pixel_buffer[((y * image.width + x) * 4) + 2] = splitter.m_b;
image.pixel_buffer[((y * image.width + x) * 4) + 3] = splitter.m_a;
}
void swr::draw_rect(int x, int y, int w, int h, unsigned int color, int t) {
draw_line(x, y, x + w, y, color, t);
draw_line(x, y, x, y + h, color, t);
draw_line(x, y + h, x + w, y + h, color, t);
draw_line(x + w, y + h, x + w, y + h, color, t);
}
void swr::draw_rect_solid(int x, int y, int w, int h, unsigned int color) {
for (int ix = x; ix < x + w; ix++) {
for (int iy = y; iy < y + h; iy++) {
draw_pixel(ix, iy, color);
}
}
}
void swr::draw_line(int x1, int y1, int x2, int y2, unsigned int color, int t) {
for (int ix = x1; ix < x2 * t; ix++) {
for (int iy = y1; iy < y2 * t; iy++) {
draw_pixel(ix, iy, color);
}
}
}
void swr::flip(bool h, bool v) {
const nimg _bak = image;
if (h) {
for (int x = 0; x < image.width; x++) {
for (int y = 0; y < image.height; y++) {
int src = (y * image.width + x) * 4;
int dst = ((image.height - 1 - y) * image.width + x) * 4;
image.pixel_buffer[src + 0] = _bak.pixel_buffer[dst + 3];
image.pixel_buffer[src + 1] = _bak.pixel_buffer[dst + 2];
image.pixel_buffer[src + 2] = _bak.pixel_buffer[dst + 1];
image.pixel_buffer[src + 3] = _bak.pixel_buffer[dst + 0];
}
}
}
if (v) {
for (int x = 0; x < image.width; x++) {
for (int y = 0; y < image.height; y++) {
int src = (y * image.width + x) * 4;
int dst = (y * image.width + (image.width - 1 - x)) * 4;
image.pixel_buffer[src + 0] = _bak.pixel_buffer[dst + 3];
image.pixel_buffer[src + 1] = _bak.pixel_buffer[dst + 2];
image.pixel_buffer[src + 2] = _bak.pixel_buffer[dst + 1];
image.pixel_buffer[src + 3] = _bak.pixel_buffer[dst + 0];
}
}
}
}
} // namespace Palladium