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:
parent
02172d8aef
commit
a58dc20562
@ -1,7 +1,14 @@
|
||||
# Palladium Changelog
|
||||
## 1.0.0
|
||||
- Switch from C2D to LI7
|
||||
- Switch from C2D to Lithium (LI7)
|
||||
- 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
|
||||
## 0.9.5
|
||||
- Remove Npi Intro and NVID Api
|
||||
|
65
build_shaders.py
Normal file
65
build_shaders.py
Normal 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")
|
@ -19,9 +19,6 @@ def fmt_dir(path):
|
||||
print('Formatting...')
|
||||
fmt_dir('source')
|
||||
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')
|
@ -6,19 +6,21 @@
|
||||
#include <pd/Hid.hpp>
|
||||
#include <pd/Image.hpp>
|
||||
#include <pd/Installer.hpp>
|
||||
#include <pd/LI7.hpp>
|
||||
#include <pd/Message.hpp>
|
||||
#include <pd/Net.hpp>
|
||||
#include <pd/Overlays.hpp>
|
||||
#include <pd/Rubidium.hpp>
|
||||
#include <pd/Sound.hpp>
|
||||
#include <pd/Texture.hpp>
|
||||
#include <pd/Timer.hpp>
|
||||
#include <pd/UI7.hpp>
|
||||
#include <pd/global_db.hpp>
|
||||
#include <pd/palladium.hpp>
|
||||
#include <pd/swr.hpp>
|
||||
#include <pd/Texture.hpp>
|
||||
|
||||
namespace Palladium {
|
||||
using Render2 = R2;
|
||||
}
|
||||
using Render2 = R2;
|
||||
using RB = Rubidium;
|
||||
} // namespace Palladium
|
||||
|
||||
namespace PD = Palladium;
|
||||
|
@ -44,11 +44,11 @@ enum PDColor_ {
|
||||
PDColor_TextDisabled, /// Text Disabled Color
|
||||
PDColor_Text2, ///< And This want for Texts on Dark Backgrounds
|
||||
PDColor_Background, ///< Your Bg Color
|
||||
PDColor_Header, ///< Header Color (if the header is dark text2 is used)
|
||||
PDColor_Selector, ///< Selector Color
|
||||
PDColor_SelectorFade, ///< Selector FadingTo Color
|
||||
PDColor_List0, ///< List Color1
|
||||
PDColor_List1, ///< List Color2
|
||||
PDColor_Header, ///< Header Color (if the header is dark text2 is used)
|
||||
PDColor_Selector, ///< Selector Color
|
||||
PDColor_SelectorFade, ///< Selector FadingTo Color
|
||||
PDColor_List0, ///< List Color1
|
||||
PDColor_List1, ///< List Color2
|
||||
PDColor_MessageBackground, ///< Message Background
|
||||
PDColor_Button, ///< Button Color
|
||||
PDColor_ButtonHovered, ///< Button Color if Hovered
|
||||
|
@ -8,7 +8,7 @@ inline void InlineError(const std::string& msg) {
|
||||
std::string location = __FILE__ + std::string(":") + std::to_string(__LINE__);
|
||||
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) {
|
||||
std::string location =
|
||||
__FILE__ + std::string(":") + std::to_string(__LINE__);
|
||||
|
@ -1,9 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <3ds.h>
|
||||
#include <citro2d.h>
|
||||
|
||||
#include <pd/NVec.hpp>
|
||||
#include <pd/Texture.hpp>
|
||||
#include <pd/nimg.hpp>
|
||||
#include <pd/smart_ctor.hpp>
|
||||
#include <string>
|
||||
@ -12,7 +12,6 @@ namespace Palladium {
|
||||
class Image {
|
||||
public:
|
||||
Image() = default;
|
||||
Image(C2D_Image img) { this->img = img; }
|
||||
Image(const std::string& path) { this->Load(path); }
|
||||
~Image() = default;
|
||||
PD_SMART_CTOR(Image)
|
||||
@ -20,14 +19,17 @@ class Image {
|
||||
void From_NIMG(const nimg& image);
|
||||
void Delete();
|
||||
|
||||
C2D_Image Get();
|
||||
C2D_Image& GetRef();
|
||||
void Set(const C2D_Image& i);
|
||||
Texture::Ref Get();
|
||||
void Set(Texture::Ref i, NVec4 uvs = NVec4(-1, -1, -1, -1));
|
||||
NVec2 GetSize();
|
||||
NVec4 GetUV() {
|
||||
return (custom_uvs.x != -1) ? custom_uvs : img->GetUV();
|
||||
}
|
||||
bool Loadet();
|
||||
|
||||
private:
|
||||
bool ext = false;
|
||||
C2D_Image img;
|
||||
Texture::Ref img;
|
||||
NVec4 custom_uvs = NVec4(-1, -1, -1, -1);
|
||||
};
|
||||
} // namespace Palladium
|
@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <3ds.h> // Result
|
||||
|
||||
#include <string>
|
||||
#include <3ds.h> // Result
|
||||
|
||||
namespace Palladium {
|
||||
struct InstallerInfo {
|
||||
|
@ -1,62 +1,94 @@
|
||||
#include <pd/NVec.hpp>
|
||||
#include <pd/Allocator.hpp>
|
||||
#include <pd/Texture.hpp>
|
||||
#pragma once
|
||||
#include <citro3d.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <pd/Allocator.hpp>
|
||||
#include <pd/NVec.hpp>
|
||||
#include <pd/Texture.hpp>
|
||||
#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 {
|
||||
class LIFont {
|
||||
public:
|
||||
struct CPI {
|
||||
unsigned char codepoint;
|
||||
NVec4 uv;
|
||||
Texture::Ref tex;
|
||||
};
|
||||
LIFont() = default;
|
||||
~LIFont() = default;
|
||||
PD_SMART_CTOR(LIFont)
|
||||
public:
|
||||
struct CPI {
|
||||
unsigned char codepoint;
|
||||
NVec4 uv;
|
||||
Texture::Ref tex;
|
||||
NVec2 szs;
|
||||
float off;
|
||||
};
|
||||
LIFont() = default;
|
||||
~LIFont() = default;
|
||||
PD_SMART_CTOR(LIFont)
|
||||
|
||||
void LoadTFF(const std::string path, int px_size = 32);
|
||||
void LoadBitmapFont(const std::string& path);
|
||||
void LoadSystemFont();
|
||||
void LoadTFF(const std::string path, int px_size = 32);
|
||||
void LoadBitmapFont(const std::string& path);
|
||||
void LoadSystemFont();
|
||||
|
||||
int GetPixelHeight();
|
||||
CPI GetCodepoint();
|
||||
int GetPixelHeight();
|
||||
CPI GetCodepoint(char c);
|
||||
std::string GetName() { return name; };
|
||||
|
||||
private:
|
||||
int pixel_height;
|
||||
unsigned char fontw[256];
|
||||
int charsize;
|
||||
std::vector<Texture::Ref> tex;
|
||||
void Dump();
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
int pixel_height;
|
||||
std::vector<CPI> cpmap;
|
||||
std::vector<Texture::Ref> tex;
|
||||
};
|
||||
class LI7 {
|
||||
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 uv[2];
|
||||
unsigned int col;
|
||||
};
|
||||
/// CMD TYPES ///
|
||||
/// 0 = SKIP
|
||||
/// 1 = TRIANGLE
|
||||
/// 2 = RECT
|
||||
/////////////////
|
||||
struct Cmd {
|
||||
};
|
||||
/// CMD TYPES ///
|
||||
/// 0 = SKIP
|
||||
/// 1 = TRIANGLE
|
||||
/// 2 = RECT
|
||||
/// 3 = RECT2P (2 Positions instead of pos,szs)
|
||||
/////////////////
|
||||
struct Cmd {
|
||||
NVec2 ppos;
|
||||
NVec2 pszs;
|
||||
NVec2 apos;
|
||||
NVec4 top;
|
||||
NVec4 bot;
|
||||
NVec4 uv;
|
||||
int layer = 0;
|
||||
int cmd_type = 0;
|
||||
unsigned int clr = 0;
|
||||
Texture::Ref tex = nullptr;
|
||||
};
|
||||
};
|
||||
LI7() = default;
|
||||
~LI7() = default;
|
||||
|
||||
@ -69,28 +101,39 @@ struct Cmd {
|
||||
static float Scale() { return m_scale; }
|
||||
static void BindTexture(Texture::Ref tex);
|
||||
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 Rect(NVec2 pos, NVec2 szs, NVec4 uvs);
|
||||
static void ColorRect(NVec2 pos, NVec2 szs, unsigned int clr);
|
||||
static void Rect(NVec2 pos, NVec2 szs);
|
||||
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,
|
||||
int wrap, int* ySize, const char* fmt, ...);
|
||||
static NVec2 GetTextDimensions(const std::string& text);
|
||||
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 Drawcalls() { return m_d_drawcalls; }
|
||||
static int DarwCommandss() { return m_d_commands; }
|
||||
static int DarwCommands() { return m_d_commands; }
|
||||
|
||||
private:
|
||||
static bool CompareCommands(const Cmd& a,
|
||||
const Cmd& b);
|
||||
static bool CompareCommands(const Cmd& a, const Cmd& b);
|
||||
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)
|
||||
static const float m_dffs;
|
||||
static const float m_dts;
|
||||
static float m_txt_scale;
|
||||
|
||||
static int m_uLoc_proj;
|
||||
static float m_scale;
|
||||
@ -101,25 +144,23 @@ struct Cmd {
|
||||
static int m_d_commands;
|
||||
|
||||
static const int m_char_height; // Constant
|
||||
static float m_rot;
|
||||
|
||||
// UI Stuff
|
||||
static std::vector<Cmd> m_top_draw_cmds;
|
||||
static std::vector<Cmd> m_bot_draw_cmds;
|
||||
static Texture::Ref m_current_texture;
|
||||
static Texture::Ref m_white;
|
||||
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;
|
||||
|
||||
// Matrix
|
||||
static C3D_Mtx m_icon_model_matrix;
|
||||
|
||||
// Ctx Stuff
|
||||
static bool m_bottom_active;
|
||||
|
||||
// Shader
|
||||
static DVLB_s *li7_dvlb;
|
||||
static shaderProgram_s li7_shader;
|
||||
static DVLB_s* li7_dvlb;
|
||||
static shaderProgram_s li7_prog;
|
||||
static C3D_AttrInfo li7_attr;
|
||||
};
|
||||
}
|
||||
} // namespace Palladium
|
@ -9,7 +9,9 @@ struct memory_metrics {
|
||||
unsigned int t_TotalAllocated = 0; ///< Total Allocated Memory
|
||||
unsigned int t_TotalFreed = 0; ///< Total Deleted 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
|
||||
/// @return Total Allocated Memory
|
||||
|
@ -36,6 +36,7 @@ struct NVec2 {
|
||||
// and swap it lol
|
||||
return !(*this == in);
|
||||
}
|
||||
|
||||
// Internal Values
|
||||
float x;
|
||||
float y;
|
||||
|
@ -48,7 +48,9 @@ class Ovl_Metrik : public Palladium::Ovl {
|
||||
mutable std::string mt_gpu;
|
||||
mutable std::string mt_cmd;
|
||||
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;
|
||||
|
||||
// Importand Adresses
|
||||
|
@ -4,24 +4,11 @@
|
||||
#include <pd/Color.hpp>
|
||||
#include <pd/Font.hpp>
|
||||
#include <pd/Image.hpp>
|
||||
#include <pd/LI7.hpp>
|
||||
#include <pd/NVec.hpp>
|
||||
#include <pd/Sprite.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 {
|
||||
R2Screen_Bottom,
|
||||
R2Screen_Top,
|
||||
@ -32,9 +19,9 @@ namespace Palladium {
|
||||
class R2 {
|
||||
public:
|
||||
struct R2Cmd {
|
||||
NVec2 pos; //< Position
|
||||
NVec2 pszs; //< Position or (TextBox) Size
|
||||
NVec2 ap; //< Additional Pos
|
||||
NVec2 pos; //< Position
|
||||
NVec2 pszs; //< Position or (TextBox) Size
|
||||
NVec2 ap; //< Additional Pos
|
||||
unsigned int clr; //< Color
|
||||
bool Screen; //< TopScreen
|
||||
Image::Ref img; //< Image Reference
|
||||
@ -45,7 +32,7 @@ class R2 {
|
||||
bool lined = false; //< Draw Lined Rect/Tri
|
||||
// Text Specific
|
||||
PDTextFlags flags; // Text Flags
|
||||
std::string text; // Text
|
||||
std::string text; // Text
|
||||
PD_SMART_CTOR(R2Cmd)
|
||||
};
|
||||
R2() = default;
|
||||
@ -73,8 +60,7 @@ class R2 {
|
||||
static void AddRect(NVec2 pos, NVec2 size, PDColor 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,
|
||||
unsigned int clr);
|
||||
static void AddTriangle(NVec2 pos0, NVec2 pos1, NVec2 pos2, unsigned int clr);
|
||||
static void AddText(NVec2 pos, const std::string& text, PDColor clr,
|
||||
PDTextFlags flags = 0, NVec2 tmb = NVec2());
|
||||
static void AddText(NVec2 pos, const std::string& text, unsigned int clr,
|
||||
|
30
include/pd/Rubidium.hpp
Normal file
30
include/pd/Rubidium.hpp
Normal 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
|
@ -1,35 +1,70 @@
|
||||
#include <pd/smart_ctor.hpp>
|
||||
#include <pd/NVec.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#pragma once
|
||||
#include <citro3d.h>
|
||||
|
||||
#include <pd/NVec.hpp>
|
||||
#include <pd/smart_ctor.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Palladium {
|
||||
class Texture {
|
||||
public:
|
||||
Texture() = default;
|
||||
~Texture() = default;
|
||||
PD_SMART_CTOR(Texture)
|
||||
class Texture {
|
||||
public:
|
||||
// Define Types supported by the texture loader
|
||||
// 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)
|
||||
|
||||
void Delete();
|
||||
void Delete();
|
||||
|
||||
void LoadFile(const std::string& path);
|
||||
void LoadFromMemory(const std::vector<unsigned char>& data);
|
||||
void LoadPixels(const std::vector<unsigned char>& data, int w, int h);
|
||||
/// @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);
|
||||
/// @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);
|
||||
/// @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);
|
||||
|
||||
C3D_Tex* Get() { return this->tex; }
|
||||
NVec2 GetTexSize() { return tex_size; }
|
||||
NVec2 GetSize() { return img_size; }
|
||||
// As the texture is a pow of 2 we need a uv
|
||||
NVec4 GetUV() { return uvs; }
|
||||
/// @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);
|
||||
|
||||
private:
|
||||
void MakeTex(std::vector<unsigned char> &buf, int w, int h);
|
||||
C3D_Tex* tex;
|
||||
NVec2 img_size;
|
||||
NVec2 tex_size;
|
||||
NVec4 uvs;
|
||||
};
|
||||
}
|
||||
C3D_Tex* Get() { return this->tex; }
|
||||
NVec2 GetTexSize();
|
||||
NVec2 GetSize() { return img_size; }
|
||||
// As the texture is a pow of 2 we need a uv
|
||||
NVec4 GetUV() { return uvs; }
|
||||
|
||||
void AutoDelete(bool enable) { ad = enable; }
|
||||
|
||||
private:
|
||||
void MakeTex(std::vector<unsigned char>& buf, int w, int h, Type type = RGBA32);
|
||||
C3D_Tex* tex = nullptr;
|
||||
NVec2 img_size;
|
||||
NVec4 uvs;
|
||||
bool ad = true;
|
||||
};
|
||||
} // namespace Palladium
|
8
include/pd/li7_shader.hpp
Normal file
8
include/pd/li7_shader.hpp
Normal 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;
|
@ -81,6 +81,7 @@ class RSettings : public Palladium::Scene {
|
||||
RFTRACE, // FTRace Menu
|
||||
RUI7, // UI7 Menu
|
||||
RLOGS, // Logs
|
||||
RFV, // Font Viewer
|
||||
};
|
||||
|
||||
/// @param shared_request Defines requests from Draw to Logic
|
||||
@ -89,7 +90,8 @@ class RSettings : public Palladium::Scene {
|
||||
/// editable by const functions
|
||||
mutable std::map<unsigned int, unsigned int> shared_request;
|
||||
/// @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
|
||||
int ftrace_index = 0;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#define PD_SMART_CTOR(type) \
|
||||
#define PD_SMART_CTOR(type) \
|
||||
using Ref = std::shared_ptr<type>; \
|
||||
template <typename... args> \
|
||||
static Ref New(args&&... cargs) { \
|
||||
|
@ -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
|
@ -1,3 +0,0 @@
|
||||
extern const u8 li7_shbin_end[];
|
||||
extern const u8 li7_shbin[];
|
||||
extern const u32 li7_shbin_size;
|
@ -24,19 +24,20 @@ void Error(const std::string& msg) {
|
||||
hidScanInput();
|
||||
if (hidKeysDown() & KEY_START) break;
|
||||
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
|
||||
Palladium::ClearTextBufs();
|
||||
C2D_TargetClear(pd_top, 0x00000000);
|
||||
C2D_TargetClear(pd_bottom, 0x00000000);
|
||||
C3D_RenderTargetClear(pd_top, C3D_CLEAR_ALL, 0x00000000, 0);
|
||||
C3D_RenderTargetClear(pd_top_right, C3D_CLEAR_ALL, 0x00000000, 0);
|
||||
C3D_RenderTargetClear(pd_bottom, C3D_CLEAR_ALL, 0x00000000, 0);
|
||||
Palladium::R2::OnScreen(R2Screen_Top);
|
||||
if (UI7::BeginMenu("Palladium - Error Manager", NVec2(),
|
||||
UI7MenuFlags_TitleMid)) {
|
||||
UI7::Label(msg, PDTextFlags_Wrap);
|
||||
UI7::Label(msg);
|
||||
UI7::Label("Press Start to Exit!");
|
||||
UI7::EndMenu();
|
||||
}
|
||||
Palladium::R2::OnScreen(R2Screen_Bottom);
|
||||
UI7::Update();
|
||||
Palladium::R2::Process();
|
||||
Palladium::LI7::Render(pd_top, pd_bottom);
|
||||
C3D_FrameEnd(0);
|
||||
}
|
||||
exit(0);
|
||||
|
@ -24,7 +24,7 @@ bool ___dir__predicate__(const Palladium::FileSystem::Entry &lhs,
|
||||
}
|
||||
|
||||
std::string Palladium::FileSystem::GetParentPath(std::string path,
|
||||
std::string mount_point) {
|
||||
std::string mount_point) {
|
||||
std::string tcl = path;
|
||||
if (path.substr(path.length() - 1, 1) != "/") {
|
||||
tcl += "/";
|
||||
|
@ -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 RegTouchCoords(NVec2 &touch_pos) {
|
||||
hid_handler.setTouchCoords(touch_pos);
|
||||
}
|
||||
void RegTouchCoords(NVec2 &touch_pos) { hid_handler.setTouchCoords(touch_pos); }
|
||||
|
||||
void RegAnalog1Movement(NVec2 &movement) {
|
||||
hid_handler.setJS1Movement(movement);
|
||||
|
159
source/Image.cpp
159
source/Image.cpp
@ -4,178 +4,41 @@
|
||||
#include <pd/internal_db.hpp>
|
||||
#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 {
|
||||
|
||||
void Image::Load(const std::string &path) {
|
||||
// Make sure to cleanup
|
||||
Delete();
|
||||
ext = false;
|
||||
// Setup Func and Load Data
|
||||
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};
|
||||
if (!img) img = Texture::New();
|
||||
img->LoadFile(path);
|
||||
}
|
||||
|
||||
void Image::From_NIMG(const nimg &image) {
|
||||
// Make sure to cleanup
|
||||
Delete();
|
||||
ext = false;
|
||||
if (image.width > 1024 || image.height > 1024) return;
|
||||
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};
|
||||
if (!img) img = Texture::New();
|
||||
img->LoadPixels(image.pixel_buffer, image.width, image.height);
|
||||
}
|
||||
|
||||
C2D_Image Image::Get() {
|
||||
if (!Loadet()) {
|
||||
_pdi_logger()->Write("Image not Loadet!");
|
||||
}
|
||||
return img;
|
||||
}
|
||||
C2D_Image &Image::GetRef() {
|
||||
Texture::Ref Image::Get() {
|
||||
if (!Loadet()) {
|
||||
_pdi_logger()->Write("Image not Loadet!");
|
||||
}
|
||||
return img;
|
||||
}
|
||||
|
||||
void Image::Set(const C2D_Image &i) {
|
||||
void Image::Set(Texture::Ref i, NVec4 uvs) {
|
||||
Delete();
|
||||
ext = true;
|
||||
if(uvs.x != -1) custom_uvs = uvs;
|
||||
img = i;
|
||||
}
|
||||
|
||||
NVec2 Image::GetSize() {
|
||||
if (!img.subtex) return NVec2(0, 0);
|
||||
return NVec2(img.subtex->width, img.subtex->height);
|
||||
if (!img) return NVec2(0, 0);
|
||||
return img->GetSize();
|
||||
}
|
||||
|
||||
void Image::Delete() {
|
||||
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;
|
||||
}
|
||||
}
|
||||
void Image::Delete() { img = nullptr; }
|
||||
|
||||
bool Image::Loadet() { return (img.subtex != nullptr && img.tex != nullptr); }
|
||||
bool Image::Loadet() { return img != nullptr; }
|
||||
} // namespace Palladium
|
521
source/LI7.cpp
521
source/LI7.cpp
@ -1,29 +1,20 @@
|
||||
#include <pd/LI7.hpp>
|
||||
#include <pd/Color.hpp>
|
||||
#include <pd/palladium.hpp>
|
||||
#include <pd/external/stb_truetype.h>
|
||||
|
||||
#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
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
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;
|
||||
float LI7::m_scale = 1.0f;
|
||||
int LI7::m_width, LI7::m_height;
|
||||
@ -31,92 +22,147 @@ int LI7::m_d_vertices = 0;
|
||||
int LI7::m_d_drawcalls = 0;
|
||||
int LI7::m_d_commands = 0;
|
||||
const int LI7::m_char_height = 8; // Constant
|
||||
float LI7::m_rot = 0.f;
|
||||
// UI Stuff
|
||||
std::vector<LI7::Cmd> LI7::m_top_draw_cmds;
|
||||
std::vector<LI7::Cmd> LI7::m_bot_draw_cmds;
|
||||
Texture::Ref LI7::m_current_texture;
|
||||
Texture::Ref LI7::m_white;
|
||||
std::vector<LI7::Vtx, LinearAllocator<LI7::Vtx>> LI7::m_vtx_list[2];
|
||||
// LI7::Font *LI7::m_font;
|
||||
LIFont::Ref LI7::m_font;
|
||||
std::vector<char> LI7::m_text_buffer;
|
||||
// Matrix
|
||||
C3D_Mtx LI7::m_icon_model_matrix;
|
||||
// Ctx Stuff
|
||||
bool LI7::m_bottom_active = false;
|
||||
// Shader
|
||||
DVLB_s *LI7::li7_dvlb;
|
||||
shaderProgram_s LI7::li7_shader;
|
||||
DVLB_s* LI7::li7_dvlb;
|
||||
shaderProgram_s LI7::li7_prog;
|
||||
C3D_AttrInfo LI7::li7_attr;
|
||||
|
||||
void LIFont::LoadTFF(const std::string path, int px_size) {
|
||||
// Supported Sizings (Tested [12, 16, 21, 24, 32, 48, 56, 63])
|
||||
this->pixel_height = px_size;
|
||||
if(!Palladium::FS::FileExist(path)) return;
|
||||
int type = px_size*16;
|
||||
// Load TTF
|
||||
stbtt_fontinfo inf;
|
||||
std::ifstream loader(path, std::ios::binary);
|
||||
if (!loader.is_open()) return;
|
||||
loader.seekg(0, std::ios::end);
|
||||
size_t len = loader.tellg();
|
||||
loader.seekg(0, std::ios::beg);
|
||||
unsigned char* buffer = new unsigned char[len];
|
||||
loader.read(reinterpret_cast<char*>(buffer), len);
|
||||
loader.close();
|
||||
stbtt_InitFont(&inf, buffer, 0);
|
||||
std::vector<unsigned char> fmap(type*type*4);
|
||||
float scale = stbtt_ScaleForPixelHeight(&inf, pixel_height);
|
||||
Palladium::Ftrace::ScopedTrace st(
|
||||
"LIFont", std::filesystem::path(path).filename().string());
|
||||
this->pixel_height = px_size;
|
||||
if (!Palladium::FS::FileExist(path)) return;
|
||||
int type = px_size * 16;
|
||||
// Load TTF
|
||||
stbtt_fontinfo inf;
|
||||
std::ifstream loader(path, std::ios::binary);
|
||||
if (!loader.is_open()) return;
|
||||
loader.seekg(0, std::ios::end);
|
||||
size_t len = loader.tellg();
|
||||
loader.seekg(0, std::ios::beg);
|
||||
unsigned char* buffer = new unsigned char[len];
|
||||
loader.read(reinterpret_cast<char*>(buffer), len);
|
||||
loader.close();
|
||||
stbtt_InitFont(&inf, buffer, 0);
|
||||
std::vector<unsigned char> fmap(type * type * 4);
|
||||
float scale = stbtt_ScaleForPixelHeight(&inf, pixel_height);
|
||||
|
||||
int ascent, descent, lineGap;
|
||||
stbtt_GetFontVMetrics(&inf, &ascent, &descent, &lineGap);
|
||||
int baseline = static_cast<int>(ascent * scale);
|
||||
int ascent, descent, lineGap;
|
||||
stbtt_GetFontVMetrics(&inf, &ascent, &descent, &lineGap);
|
||||
int baseline = static_cast<int>(ascent * scale);
|
||||
|
||||
for (int c = 0; c < 255; c++) {
|
||||
if (stbtt_IsGlyphEmpty(&inf, c)) continue;
|
||||
|
||||
int width, height, xOffset, yOffset;
|
||||
unsigned char* bitmap = stbtt_GetCodepointBitmap(
|
||||
&inf, scale, scale, c, &width, &height, &xOffset, &yOffset);
|
||||
int x0, y0, x1, y1;
|
||||
stbtt_GetCodepointBitmapBox(&inf, c, scale, scale, &x0, &y0, &x1, &y1);
|
||||
this->fontw[c] = x0 + x1;
|
||||
int i = c % 16;
|
||||
int j = c / 16;
|
||||
int xoff = i * pixel_height;
|
||||
int yoff = j * pixel_height + baseline + yOffset;
|
||||
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
int map_pos = ((yoff + y) * type + (xoff + x)) * 4;
|
||||
|
||||
fmap[map_pos + 0] = 255;
|
||||
fmap[map_pos + 1] = 255;
|
||||
fmap[map_pos + 2] = 255;
|
||||
fmap[map_pos + 3] = bitmap[x + y * width];
|
||||
}
|
||||
}
|
||||
|
||||
free(bitmap);
|
||||
name = path;
|
||||
auto ftex = Texture::New();
|
||||
NVec2 offset;
|
||||
for (int c = 0; c < 255; c++) {
|
||||
CPI codepoint;
|
||||
if (stbtt_IsGlyphEmpty(&inf, c)) {
|
||||
codepoint.codepoint = c;
|
||||
codepoint.tex = ftex;
|
||||
cpmap.push_back(codepoint);
|
||||
continue;
|
||||
}
|
||||
auto ftex = Texture::New();
|
||||
ftex->LoadPixels(fmap, type, type);
|
||||
this->tex.push_back(ftex);
|
||||
|
||||
int width, height, xOffset, yOffset;
|
||||
unsigned char* bitmap = stbtt_GetCodepointBitmap(
|
||||
&inf, scale, scale, c, &width, &height, &xOffset, &yOffset);
|
||||
int x0, y0, x1, y1;
|
||||
stbtt_GetCodepointBitmapBox(&inf, c, scale, scale, &x0, &y0, &x1, &y1);
|
||||
|
||||
if (offset.x + width > type) {
|
||||
offset.y += pixel_height;
|
||||
offset.x = 0;
|
||||
}
|
||||
|
||||
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 x = 0; x < width; ++x) {
|
||||
int map_pos = ((offset.y + y) * type + (offset.x + x)) * 4;
|
||||
|
||||
fmap[map_pos + 0] = 255;
|
||||
fmap[map_pos + 1] = 255;
|
||||
fmap[map_pos + 2] = 255;
|
||||
fmap[map_pos + 3] = bitmap[x + y * width];
|
||||
}
|
||||
}
|
||||
offset.x += width;
|
||||
if (offset.x + width > type) {
|
||||
offset.y += pixel_height;
|
||||
offset.x = 0;
|
||||
}
|
||||
free(bitmap);
|
||||
cpmap.push_back(codepoint);
|
||||
}
|
||||
ftex->LoadPixels(fmap, type, type);
|
||||
this->tex.push_back(ftex);
|
||||
}
|
||||
|
||||
void LIFont::LoadBitmapFont(const std::string& path) {
|
||||
|
||||
}
|
||||
void LIFont::LoadBitmapFont(const std::string& path) {}
|
||||
|
||||
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() {
|
||||
LIFont::CPI LIFont::GetCodepoint(char c) { return cpmap[c]; }
|
||||
|
||||
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() {
|
||||
@ -124,38 +170,47 @@ void LI7::Init() {
|
||||
m_vtx_list[0].reserve(2 * 4096);
|
||||
m_vtx_list[1].reserve(2 * 4096);
|
||||
|
||||
li7_dvlb = DVLB_ParseFile((u32*)li7_shbin, li7_shbin_size);
|
||||
shaderProgramInit(&li7_shader);
|
||||
shaderProgramSetVsh(&li7_shader, &li7_dvlb->DVLE[0]);
|
||||
li7_dvlb = DVLB_ParseFile((u32*)li7_shader, li7_shader_size);
|
||||
shaderProgramInit(&li7_prog);
|
||||
shaderProgramSetVsh(&li7_prog, &li7_dvlb->DVLE[0]);
|
||||
m_uLoc_proj =
|
||||
shaderInstanceGetUniformLocation(li7_shader.vertexShader, "projection");
|
||||
shaderInstanceGetUniformLocation(li7_prog.vertexShader, "projection");
|
||||
|
||||
AttrInfo_Init(&li7_attr);
|
||||
AttrInfo_AddLoader(&li7_attr, 0, GPU_FLOAT, 3);
|
||||
AttrInfo_AddLoader(&li7_attr, 1, GPU_FLOAT, 2);
|
||||
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() {
|
||||
shaderProgramFree(&li7_shader);
|
||||
shaderProgramFree(&li7_prog);
|
||||
DVLB_Free(li7_dvlb);
|
||||
}
|
||||
|
||||
void LI7::OnScreen(bool bottom) {
|
||||
m_width = bottom ? 320 : 400;
|
||||
m_height = 240;
|
||||
m_bottom_active = bottom;
|
||||
m_width = bottom ? 320 : 400;
|
||||
m_height = 240;
|
||||
m_bottom_active = bottom;
|
||||
}
|
||||
|
||||
bool LI7::CompareCommands(const LI7::Cmd &a,
|
||||
const LI7::Cmd &b) {
|
||||
if (a.layer == b.layer)
|
||||
return a.tex < b.tex;
|
||||
bool LI7::CompareCommands(const LI7::Cmd& a, const LI7::Cmd& b) {
|
||||
if (a.layer == b.layer) return a.tex < b.tex;
|
||||
return b.layer < a.layer;
|
||||
}
|
||||
|
||||
void LI7::RenderFrame(bool bottom) {
|
||||
m_rot += M_PI / 60.f;
|
||||
C3D_Mtx proj;
|
||||
Mtx_OrthoTilt(&proj, 0.f, (bottom ? 320 : 400), m_height, 0.f, 1.f, -1.f,
|
||||
false);
|
||||
@ -163,7 +218,7 @@ void LI7::RenderFrame(bool bottom) {
|
||||
|
||||
C3D_DepthTest(false, GPU_GREATER, GPU_WRITE_ALL);
|
||||
|
||||
C3D_TexEnv *env = C3D_GetTexEnv(0);
|
||||
C3D_TexEnv* env = C3D_GetTexEnv(0);
|
||||
C3D_TexEnvInit(env);
|
||||
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, (GPU_TEVSRC)0);
|
||||
C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE);
|
||||
@ -172,40 +227,48 @@ void LI7::RenderFrame(bool bottom) {
|
||||
|
||||
int total_vertices = 0;
|
||||
m_d_drawcalls = 0;
|
||||
auto &draw_cmds = bottom ? m_bot_draw_cmds : m_top_draw_cmds;
|
||||
std::sort(draw_cmds.begin(), draw_cmds.end(), CompareCommands);
|
||||
auto& draw_cmds = bottom ? m_bot_draw_cmds : m_top_draw_cmds;
|
||||
std::reverse(draw_cmds.begin(), draw_cmds.end());
|
||||
// std::sort(draw_cmds.begin(), draw_cmds.end(), CompareCommands);
|
||||
m_d_commands = draw_cmds.size();
|
||||
size_t vtx = 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;
|
||||
|
||||
while (draw_cmds.size() > 0 &&
|
||||
draw_cmds[draw_cmds.size() - 1].tex->Get() == texture) {
|
||||
auto c = draw_cmds[draw_cmds.size() - 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++] = Vtx{{c.pszs.x, c.pszs.y, 0}, {c.uv.x, c.uv.w}, c.clr};
|
||||
active_list[vtx++] = Vtx{{c.apos.x, c.apos.y, 0}, {c.uv.z, c.uv.w}, c.clr};
|
||||
if (c.cmd_type == 1) {
|
||||
active_list[vtx++] =
|
||||
Vtx(NVec2(c.bot.z, c.bot.w), 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) {
|
||||
// TRI1
|
||||
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};
|
||||
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++] = Vtx{{c.ppos.x, c.ppos.y, 0}, {c.uv.x, c.uv.w}, c.clr};
|
||||
// TRI2
|
||||
active_list[vtx++] = Vtx{{c.ppos.x, c.ppos.y, 0}, {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};
|
||||
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.z, c.top.w), c.uv.z, c.uv.w, c.clr);
|
||||
active_list[vtx++] =
|
||||
Vtx(NVec2(c.bot.x, c.bot.y), c.uv.x, c.uv.w, c.clr);
|
||||
}
|
||||
draw_cmds.pop_back();
|
||||
}
|
||||
|
||||
C3D_TexBind(0, texture);
|
||||
|
||||
C3D_BufInfo *bufinfo = C3D_GetBufInfo();
|
||||
C3D_BufInfo* bufinfo = C3D_GetBufInfo();
|
||||
BufInfo_Init(bufinfo);
|
||||
BufInfo_Add(bufinfo, active_list.data() + start_vtx, sizeof(Vtx), 3,
|
||||
0x210);
|
||||
BufInfo_Add(bufinfo, active_list.data() + start_vtx, sizeof(Vtx), 3, 0x210);
|
||||
|
||||
C3D_DrawArrays(GPU_TRIANGLES, 0, vtx - start_vtx);
|
||||
m_d_drawcalls++;
|
||||
@ -219,45 +282,108 @@ void LI7::RenderFrame(bool bottom) {
|
||||
}
|
||||
|
||||
void LI7::Render(C3D_RenderTarget* top, C3D_RenderTarget* bot) {
|
||||
C3D_BindProgram(&li7_shader);
|
||||
C3D_SetAttrInfo(&li7_attr);
|
||||
C3D_FrameDrawOn(top);
|
||||
Palladium::Ftrace::ScopedTrace st("Li7", "Render");
|
||||
C3D_BindProgram(&li7_prog);
|
||||
C3D_SetAttrInfo(&li7_attr);
|
||||
C3D_FrameDrawOn(top);
|
||||
RenderFrame(false);
|
||||
int d_tmp_cmds1 = m_d_commands;
|
||||
int d_tmp_dcls1 = m_d_drawcalls;
|
||||
int d_tmp_vtxs1 = m_d_vertices;
|
||||
C3D_FrameDrawOn(bot);
|
||||
RenderFrame(true);
|
||||
int d_tmp_cmds2 = m_d_commands;
|
||||
int d_tmp_dcls2 = m_d_drawcalls;
|
||||
int d_tmp_vtxs2 = m_d_vertices;
|
||||
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;
|
||||
m_d_commands += d_tmp_cmds1;
|
||||
m_d_drawcalls += d_tmp_dcls1;
|
||||
m_d_vertices += d_tmp_vtxs1;
|
||||
}
|
||||
|
||||
void LI7::ColorRect(NVec2 pos, NVec2 szs, NVec4 uvs, unsigned int clr) {
|
||||
Cmd c;
|
||||
c.ppos = pos;
|
||||
c.pszs = szs;
|
||||
c.uv = uvs;
|
||||
c.clr = bs32(clr);
|
||||
c.tex = m_current_texture;
|
||||
c.cmd_type = 2;
|
||||
if(m_bottom_active) m_bot_draw_cmds.push_back(c);
|
||||
else m_top_draw_cmds.push_back(c);
|
||||
Cmd c;
|
||||
if (pos.x > m_width || pos.x + szs.x < 0 || pos.y > m_height ||
|
||||
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.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::ColorRect(NVec2 pos, NVec2 szs, unsigned int clr) {
|
||||
ColorRect(pos, szs, NVec4(0, 0, 1, 1), clr);
|
||||
ColorRect(pos, szs, NVec4(0, 0, 1, 1), clr);
|
||||
}
|
||||
|
||||
void LI7::Rect(NVec2 pos, NVec2 szs, NVec4 uvs) {
|
||||
ColorRect(pos, szs, uvs, 0xffffffff);
|
||||
ColorRect(pos, szs, uvs, 0xffffffff);
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -270,57 +396,94 @@ void LI7::TexCutRect(NVec2 pos, NVec2 szs, NVec2 cb, NVec2 ce) {
|
||||
Rect(pos, szs, NVec4(u0, v0, u1, v1));
|
||||
}
|
||||
|
||||
int LI7::DrawTextVargs(int x, int y, int z, unsigned int color, bool shadow,
|
||||
int wrap, int* ySize, const char* fmt, va_list arg) {
|
||||
NVec2 LI7::GetTextDimensions(const std::string& text) {
|
||||
// FONT
|
||||
int len = vsnprintf(m_text_buffer.data(), m_text_buffer.size(), fmt, arg);
|
||||
m_text_buffer[len] = '\0';
|
||||
int offsetX = 0;
|
||||
int offsetY = 0;
|
||||
int maxWidth = 0;
|
||||
float cpm = m_dffs /1;// m_font->char_size;
|
||||
std::string txt = text + "\0";
|
||||
NVec2 pos(0, 0); // Temp Pos
|
||||
NVec2 offset;
|
||||
float maxWidth = 0.f;
|
||||
float ntxtszs = m_dffs * m_txt_scale;
|
||||
float cpm = ntxtszs / m_font->GetPixelHeight();
|
||||
float line_height = m_font->GetPixelHeight() * cpm * m_scale;
|
||||
|
||||
for (const auto &it : m_text_buffer) {
|
||||
if (it == '\0') break;
|
||||
bool implicitBreak = offsetX + 0/*m_font->fontWidth[(int)it]*/ >= wrap;
|
||||
if (it == '\n' || implicitBreak) {
|
||||
offsetY += /*m_font->char_size*/0 * cpm * m_scale;
|
||||
maxWidth = std::max(maxWidth, offsetX);
|
||||
offsetX = 0;
|
||||
for (size_t i = 0; i < txt.length(); i++) {
|
||||
if (txt[i] == '\0') break;
|
||||
auto cp = m_font->GetCodepoint(txt[i]);
|
||||
bool implicitBreak = false;
|
||||
if (txt[i] == '\n' || implicitBreak) {
|
||||
offset.y += line_height;
|
||||
maxWidth = std::max(maxWidth, offset.x);
|
||||
offset.x = 0;
|
||||
if (implicitBreak) continue;
|
||||
} else if (it == '\t') {
|
||||
offsetX = ((offsetX / m_dffs) / 4 + 1) * 4 * m_dffs;
|
||||
} else if (txt[i] == '\t') {
|
||||
offset.x = ((offset.x / ntxtszs) / 4 + 1) * 4 * ntxtszs;
|
||||
} else {
|
||||
if (it != ' ') {
|
||||
int texX = (it % 16) * /*m_font->char_size*/0;
|
||||
int texY = (/*m_font->texture.tex.height*/0 - /*m_font->char_size*/0) -
|
||||
(it / 16) * /*m_font->char_size*/0;
|
||||
ColorRect(NVec2(x + offsetX, y + offsetY), NVec2(m_dffs, m_dffs),
|
||||
NVec4(static_cast<float>(texX) / /*m_font->texture.tex.width*/0,
|
||||
static_cast<float>(texY) / /*m_font->texture.tex.height*/0,
|
||||
(static_cast<float>(texX) + /*m_font->char_size*/0) /
|
||||
/*m_font->texture.tex.width*/0,
|
||||
(static_cast<float>(texY) + /*m_font->char_size*/0) /
|
||||
/*m_font->texture.tex.height*/0),
|
||||
color);
|
||||
|
||||
if (shadow)
|
||||
ColorRect(NVec2(x + offsetX + 1, y + offsetY + 1), NVec2(m_dffs, m_dffs),
|
||||
NVec4(static_cast<float>(texX) / /*m_font->texture.tex.width*/0,
|
||||
static_cast<float>(texY) / /*m_font->texture.tex.height*/0,
|
||||
(static_cast<float>(texX) + /*m_font->char_size*/0) /
|
||||
/*m_font->texture.tex.width*/0,
|
||||
(static_cast<float>(texY) + /*m_font->char_size*/0) /
|
||||
/*m_font->texture.tex.height*/0),
|
||||
RGBA8(10, 10, 10, 255));
|
||||
if (txt[i] == ' ') {
|
||||
// this will make the space twice
|
||||
offset.x += 2 * m_txt_scale;
|
||||
}
|
||||
offsetX += /*m_font->fontWidth[(int)it]*/0 * cpm * m_scale +
|
||||
((/*m_font->char_size*/0 * 0.2) * cpm * m_scale);
|
||||
if (i == txt.length() - 1)
|
||||
offset.x += cp.szs.x * cpm + m_txt_scale;
|
||||
else
|
||||
offset.x += cp.szs.x * cpm + (2 * m_txt_scale);
|
||||
}
|
||||
}
|
||||
maxWidth = std::max(maxWidth, offsetX);
|
||||
maxWidth = std::max(maxWidth, offset.x);
|
||||
return NVec2(maxWidth, offset.y + (m_dffs * m_txt_scale));
|
||||
}
|
||||
|
||||
if (ySize != nullptr) *ySize = offsetY + /*m_font->char_size*/0;
|
||||
return maxWidth;
|
||||
}
|
||||
}
|
||||
void LI7::DrawText(NVec2 pos, unsigned int color, const std::string& text,
|
||||
PDTextFlags flags, NVec2 ap) {
|
||||
std::string txt = text;
|
||||
NVec2 offset;
|
||||
float ntxtszs = m_dffs * m_txt_scale;
|
||||
float cpm = ntxtszs / m_font->GetPixelHeight();
|
||||
float line_height = m_font->GetPixelHeight() * cpm * m_scale;
|
||||
NVec2 td = GetTextDimensions(text);
|
||||
if (flags & PDTextFlags_AlignRight) pos.x -= td.x;
|
||||
if (flags & PDTextFlags_AlignMid) {
|
||||
pos.x = (ap.x * 0.5) - (td.x * 0.5) + pos.x;
|
||||
}
|
||||
std::vector<std::string> lines;
|
||||
std::istringstream iss(txt);
|
||||
std::string temp;
|
||||
while (std::getline(iss, temp)) {
|
||||
lines.push_back(temp);
|
||||
}
|
||||
|
||||
for (auto& it : lines) {
|
||||
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
|
@ -8,18 +8,19 @@
|
||||
extern bool pdi_debugging;
|
||||
|
||||
static std::vector<std::shared_ptr<Palladium::Message>> msg_lst;
|
||||
static int fade_outs = 200; // Start of fadeout
|
||||
static int idles = 60; // start of Idle
|
||||
static int anim_len = 300; // Full Length of Animation
|
||||
static int fade_outs = 200; // Start of fadeout
|
||||
static int idles = 60; // start of Idle
|
||||
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) {
|
||||
float fol = anim_len - fade_outs;
|
||||
if (frame > fade_outs)
|
||||
return NVec2(5, 240 - ((entry + 1) * 55) - 5 +
|
||||
(float)((frame - fade_outs) / fol) * -20);
|
||||
(float)((frame - fade_outs) / fol) * -20);
|
||||
if (frame > idles) return NVec2(5, 240 - ((entry + 1) * 55) - 5);
|
||||
return NVec2(-150 + ((float)(frame / (float)idles) * 155),
|
||||
240 - ((entry + 1) * 55) - 5);
|
||||
240 - ((entry + 1) * 55) - 5);
|
||||
}
|
||||
|
||||
namespace Palladium {
|
||||
@ -51,12 +52,12 @@ void ProcessMessages() {
|
||||
.toRGBA();
|
||||
auto tc =
|
||||
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, 17), msg_lst[i]->message, tc);
|
||||
if (pdi_debugging)
|
||||
R2::AddText(pos + NVec2(155, 1),
|
||||
std::to_string(msg_lst[i]->animationframe), tc);
|
||||
R2::AddText(pos + NVec2(msg_box.x+5, 1),
|
||||
std::to_string(msg_lst[i]->animationframe), tc);
|
||||
// Why Frameadd? because Message uses int as frame and
|
||||
// It seems that lower 0.5 will be rounded to 0
|
||||
// Why not replace int with float ?
|
||||
|
@ -7,9 +7,9 @@
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <regex>
|
||||
#include <pd/Net.hpp>
|
||||
#include <pd/internal_db.hpp>
|
||||
#include <regex>
|
||||
|
||||
static Palladium::Net::Error pdi_check_wifi() {
|
||||
// if (pdi_is_citra) return 0;
|
||||
@ -18,14 +18,13 @@ static Palladium::Net::Error pdi_check_wifi() {
|
||||
}
|
||||
|
||||
static size_t pdi_handle_data(char* ptr, size_t size, size_t nmemb,
|
||||
void* userdata) {
|
||||
void* userdata) {
|
||||
size_t ms = size * nmemb;
|
||||
((std::string*)userdata)->append(ptr, ms);
|
||||
return ms;
|
||||
}
|
||||
|
||||
static size_t pdi_handle_file(char* ptr, size_t size, size_t nmemb,
|
||||
void* out) {
|
||||
static size_t pdi_handle_file(char* ptr, size_t size, size_t nmemb, void* out) {
|
||||
size_t ms = size * nmemb;
|
||||
((std::ofstream*)out)->write(reinterpret_cast<const char*>(ptr), ms);
|
||||
return ms;
|
||||
@ -43,18 +42,17 @@ struct pdi_net_dl {
|
||||
static pdi_net_dl pdi_net_dl_spec;
|
||||
|
||||
static int pdi_handle_curl_progress(CURL* hnd, curl_off_t dltotal,
|
||||
curl_off_t dlnow, curl_off_t ultotal,
|
||||
curl_off_t ulnow) {
|
||||
curl_off_t dlnow, curl_off_t ultotal,
|
||||
curl_off_t ulnow) {
|
||||
pdi_net_dl_spec.total = dltotal;
|
||||
pdi_net_dl_spec.current = dlnow;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pdi_setup_curl_context(CURL* hnd, const std::string& url,
|
||||
void* userptr, bool mem) {
|
||||
void* userptr, bool mem) {
|
||||
std::string user_agent =
|
||||
pdi_app_name + "/Palladium (Version: " + std::string(PDVSTRING) +
|
||||
")";
|
||||
pdi_app_name + "/Palladium (Version: " + std::string(PDVSTRING) + ")";
|
||||
|
||||
if (!mem) {
|
||||
curl_easy_setopt(hnd, CURLOPT_FAILONERROR, 1L);
|
||||
|
@ -278,9 +278,10 @@ void Ovl_Ftrace::Draw(void) const {
|
||||
for (auto const& it : Palladium::Ftrace::pd_traces)
|
||||
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++) {
|
||||
R2::AddText(NVec2(5, 30 + i * 15), dt[i].func_name, PDColor_Text);
|
||||
R2::AddText(NVec2(295, 30 + i * 15), Palladium::MsTimeFmt(dt[i].time_of),
|
||||
PDColor_Text);
|
||||
std::string text = dt[i].func_name + ": " + Palladium::MsTimeFmt(dt[i].time_of);
|
||||
auto dim = R2::GetTextDimensions(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);
|
||||
}
|
||||
@ -302,8 +303,7 @@ void Ovl_Metrik::Draw(void) const {
|
||||
float tmp_txt = R2::GetTextSize();
|
||||
R2::DefaultTextSize();
|
||||
R2::OnScreen(i_screen[0] ? R2Screen_Bottom : R2Screen_Top);
|
||||
std::string info =
|
||||
"Palladium " + std::string(PDVSTRING) + " Debug Overlay";
|
||||
std::string info = "Palladium " + std::string(PDVSTRING) + " Debug Overlay";
|
||||
float dim_y = R2::GetTextDimensions(info).y;
|
||||
float infoy = 240 - dim_y;
|
||||
mt_fps = "FPS: " + Palladium::GetFramerate();
|
||||
@ -320,55 +320,56 @@ void Ovl_Metrik::Draw(void) const {
|
||||
"CMD: " + std::to_string(C3D_GetCmdBufUsage() * 100.0f).substr(0, 4) +
|
||||
"%";
|
||||
mt_lfr = "Linear: " + Palladium::FormatBytes(linearSpaceFree());
|
||||
mt_tbs =
|
||||
"TextBuf: " + std::to_string(C2D_TextBufGetNumGlyphs(pdi_text_buffer)) +
|
||||
"/4096";
|
||||
if (pdi_enable_memtrack)
|
||||
mt_mem = "Mem: " + Palladium::FormatBytes(Palladium::Memory::GetCurrent()) +
|
||||
" | " +
|
||||
Palladium::FormatBytes(Palladium::Memory::GetTotalAllocated()) +
|
||||
" | " + 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),
|
||||
(unsigned int)i_mt_color[0]);
|
||||
(unsigned int)i_mt_color[0]);
|
||||
R2::AddRect(NVec2(0, 50), R2::GetTextDimensions(mt_cpu),
|
||||
(unsigned int)i_mt_color[0]);
|
||||
(unsigned int)i_mt_color[0]);
|
||||
R2::AddRect(NVec2(0, 50 + dim_y * 1), R2::GetTextDimensions(mt_gpu),
|
||||
(unsigned int)i_mt_color[0]);
|
||||
(unsigned int)i_mt_color[0]);
|
||||
R2::AddRect(NVec2(0, 50 + dim_y * 2), R2::GetTextDimensions(mt_cmd),
|
||||
(unsigned int)i_mt_color[0]);
|
||||
(unsigned int)i_mt_color[0]);
|
||||
R2::AddRect(NVec2(0, 50 + dim_y * 3), R2::GetTextDimensions(mt_lfr),
|
||||
(unsigned int)i_mt_color[0]);
|
||||
R2::AddRect(NVec2(0, 50 + dim_y * 4), R2::GetTextDimensions(mt_tbs),
|
||||
(unsigned int)i_mt_color[0]);
|
||||
(unsigned int)i_mt_color[0]);
|
||||
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]);
|
||||
if (pdi_enable_memtrack)
|
||||
R2::AddRect(NVec2(0, 50 + dim_y * 5), R2::GetTextDimensions(mt_mem),
|
||||
(unsigned int)i_mt_color[0]);
|
||||
R2::AddRect(NVec2(0, infoy), R2::GetTextDimensions(info),
|
||||
R2::AddRect(NVec2(0, 50 + dim_y * 7), R2::GetTextDimensions(mt_mem),
|
||||
(unsigned int)i_mt_color[0]);
|
||||
R2::AddRect(NVec2(0, infoy), R2::GetTextDimensions(info),
|
||||
(unsigned int)i_mt_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 + dim_y * 1), mt_gpu,
|
||||
(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 * 3), mt_lfr,
|
||||
(unsigned int)i_txt_color[0]);
|
||||
R2::AddText(NVec2(0, 50 + dim_y * 4), mt_tbs,
|
||||
(unsigned int)i_txt_color[0]);
|
||||
R2::AddText(NVec2(0, 50 + dim_y * 1), mt_gpu, (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 * 3), mt_lfr, (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 * 5), mt_dmc, (unsigned int)i_txt_color[0]);
|
||||
R2::AddText(NVec2(0, 50 + dim_y * 6), mt_drc, (unsigned int)i_txt_color[0]);
|
||||
if (pdi_enable_memtrack)
|
||||
R2::AddText(NVec2(0, 50 + dim_y * 5), mt_mem,
|
||||
(unsigned int)i_txt_color[0]);
|
||||
R2::AddText(NVec2(0, 50 + dim_y * 7), mt_mem, (unsigned int)i_txt_color[0]);
|
||||
R2::AddText(NVec2(0, infoy), info, (unsigned int)i_txt_color[0]);
|
||||
|
||||
// Force Bottom (Debug Touchpos)
|
||||
R2::OnScreen(R2Screen_Bottom);
|
||||
if (Hid::IsEvent("touch", Hid::Held)) {
|
||||
R2::AddLine(NVec2(Hid::GetTouchPosition().x, 0),
|
||||
NVec2(Hid::GetTouchPosition().x, 240),
|
||||
Palladium::Color::Hex("#ff0000"));
|
||||
NVec2(Hid::GetTouchPosition().x, 240),
|
||||
Palladium::Color::Hex("#ff0000"));
|
||||
R2::AddLine(NVec2(0, Hid::GetTouchPosition().y),
|
||||
NVec2(320, Hid::GetTouchPosition().y),
|
||||
Palladium::Color::Hex("#ff0000"));
|
||||
NVec2(320, Hid::GetTouchPosition().y),
|
||||
Palladium::Color::Hex("#ff0000"));
|
||||
}
|
||||
R2::SetTextSize(tmp_txt);
|
||||
}
|
||||
@ -407,14 +408,14 @@ void Ovl_Keyboard::Draw(void) const {
|
||||
key_table = keyboard_layout_shift;
|
||||
R2::OnScreen(R2Screen_Top);
|
||||
R2::AddRect(NVec2(0, 0), NVec2(400, 240),
|
||||
Palladium::Color::RGBA(PDColor_FrameBg).changeA(150).toRGBA());
|
||||
Palladium::Color::RGBA(PDColor_FrameBg).changeA(150).toRGBA());
|
||||
R2::OnScreen(R2Screen_Bottom);
|
||||
R2::AddRect(NVec2(0, 0), NVec2(320, 112),
|
||||
Palladium::Color::RGBA(PDColor_FrameBg).changeA(150).toRGBA());
|
||||
Palladium::Color::RGBA(PDColor_FrameBg).changeA(150).toRGBA());
|
||||
R2::AddRect(NVec2(0, 112), NVec2(320, 128), PDColor_FrameBg);
|
||||
R2::AddRect(NVec2(0, 112), NVec2(320, 20), PDColor_Header);
|
||||
R2::AddText(NVec2(5, 114), "> " + *typed_text,
|
||||
Palladium::ThemeActive()->AutoText(PDColor_Header));
|
||||
Palladium::ThemeActive()->AutoText(PDColor_Header));
|
||||
for (auto const& it : key_table) {
|
||||
NVec2 szs = it.size;
|
||||
NVec2 pos = it.pos;
|
||||
@ -454,7 +455,7 @@ void Ovl_Keyboard::Draw(void) const {
|
||||
szs += NVec2(2, 2);
|
||||
}
|
||||
NVec2 txtpos = NVec2(pos.x + szs.x * 0.5 - txtdim.x * 0.5,
|
||||
pos.y + szs.y * 0.5 - txtdim.y * 0.5);
|
||||
pos.y + szs.y * 0.5 - txtdim.y * 0.5);
|
||||
R2::AddRect(pos, szs, btn);
|
||||
R2::AddText(txtpos, it.disp, Palladium::ThemeActive()->AutoText(btn));
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include <citro2d.h>
|
||||
|
||||
#include <pd/LI7.hpp>
|
||||
#include <pd/Render2.hpp>
|
||||
#include <pd/internal_db.hpp>
|
||||
|
||||
@ -40,15 +39,10 @@ float R2::GetTextSize() { return text_size; }
|
||||
R2Screen R2::GetCurrentScreen() { return current_screen; }
|
||||
|
||||
NVec2 R2::GetTextDimensions(const std::string& text) {
|
||||
C2D_TextBufClear(pdi_d2_dimbuf);
|
||||
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);
|
||||
return LI7::GetTextDimensions(text);
|
||||
}
|
||||
|
||||
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 line;
|
||||
int line_x = 0;
|
||||
@ -63,7 +57,7 @@ std::string R2::WrapText(const std ::string& in, int maxlen) {
|
||||
} else {
|
||||
out += line + '\n';
|
||||
line = temp + ' ';
|
||||
line_x = dim.x;
|
||||
line_x = R2::GetTextDimensions(line).x;
|
||||
}
|
||||
}
|
||||
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) {
|
||||
auto textdim = R2::GetTextDimensions(in);
|
||||
if (textdim.x < (float)maxlen) return in;
|
||||
std::string ft = "";
|
||||
std::string ext = "";
|
||||
std::string ph = "(...)"; // placeholder
|
||||
std::string worker = in;
|
||||
if (in.find_last_of('.') != in.npos) {
|
||||
ft = in.substr(in.find_last_of('.'));
|
||||
worker = in.substr(0, in.find_last_of('.'));
|
||||
std::string out;
|
||||
size_t ext_pos = 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;
|
||||
float len_mod = (float)maxlen / textdim.x;
|
||||
int pos = (in.length() * len_mod) / pd_draw2_tsm;
|
||||
std::string out;
|
||||
maxlen -= R2::GetTextDimensions(ext).x;
|
||||
maxlen -= R2::GetTextDimensions(ph).x;
|
||||
|
||||
out = in.substr(0, pos);
|
||||
|
||||
for (size_t i = pos; i < worker.length(); i++) {
|
||||
out += worker[i];
|
||||
if (R2::GetTextDimensions(out + "(...)" + ft).x > (float)maxlen) {
|
||||
out += "(...)";
|
||||
out += ft;
|
||||
for (auto& it : worker) {
|
||||
if (R2::GetTextDimensions(out).x > (float)maxlen) {
|
||||
out += ph;
|
||||
out += ext;
|
||||
return out;
|
||||
}
|
||||
out += it;
|
||||
}
|
||||
return out; // Impossible to reach
|
||||
}
|
||||
@ -104,105 +97,59 @@ NVec2 R2::GetCurrentScreenSize() {
|
||||
|
||||
// Main Processing of Draw Calls
|
||||
void R2::Process() {
|
||||
Palladium::Ftrace::ScopedTrace st("Render2", "ProcessList");
|
||||
for (auto& it : R2::commands) {
|
||||
if (it->type <= 0 || it->type > 6) {
|
||||
// Skip
|
||||
continue;
|
||||
}
|
||||
C2D_SceneBegin(it->Screen ? pd_top : pd_bottom);
|
||||
LI7::OnScreen(!it->Screen);
|
||||
if (it->type == 1) {
|
||||
LI7::UseTexture();
|
||||
// Rect
|
||||
if (it->lined) {
|
||||
C2D_DrawLine(it->pos.x, it->pos.y, it->clr, it->pos.x + it->pszs.x,
|
||||
it->pos.y, it->clr, 1.f, 0.5f);
|
||||
C2D_DrawLine(it->pos.x, it->pos.y, it->clr, it->pos.x,
|
||||
it->pos.y + it->pszs.y, it->clr, 1.f, 0.5f);
|
||||
C2D_DrawLine(it->pos.x + it->pszs.x, it->pos.y, it->clr,
|
||||
it->pos.x + it->pszs.x, it->pos.y + it->pszs.y, it->clr,
|
||||
1.f, 0.5f);
|
||||
C2D_DrawLine(it->pos.x, it->pos.y + it->pszs.y, it->clr,
|
||||
it->pos.x + it->pszs.x, it->pos.y + it->pszs.y, it->clr,
|
||||
1.f, 0.5f);
|
||||
LI7::Line(it->pos, NVec2(it->pos.x + it->pszs.x, it->pos.y), it->clr,
|
||||
1.f);
|
||||
LI7::Line(it->pos, NVec2(it->pos.x, it->pos.y + it->pszs.y), it->clr,
|
||||
1.f);
|
||||
LI7::Line(NVec2(it->pos.x + it->pszs.x, it->pos.y),
|
||||
NVec2(it->pos.x + it->pszs.x, it->pos.y + it->pszs.y),
|
||||
it->clr, 1.f);
|
||||
LI7::Line(NVec2(it->pos.x, it->pos.y + it->pszs.y),
|
||||
NVec2(it->pos.x + it->pszs.x, it->pos.y + it->pszs.y),
|
||||
it->clr, 1.f);
|
||||
} else {
|
||||
C2D_DrawRectSolid(it->pos.x, it->pos.y, 0.5, it->pszs.x, it->pszs.y,
|
||||
it->clr);
|
||||
LI7::ColorRect(it->pos, it->pszs, it->clr);
|
||||
}
|
||||
} else if (it->type == 2) {
|
||||
LI7::UseTexture();
|
||||
// Triangle
|
||||
if (it->lined) {
|
||||
C2D_DrawLine(it->pos.x, it->pos.y, it->clr, it->pszs.x, it->pszs.y,
|
||||
it->clr, 1, 0.5f);
|
||||
C2D_DrawLine(it->pos.x, it->pos.y, it->clr, it->ap.x, it->ap.y, it->clr,
|
||||
1, 0.5f);
|
||||
C2D_DrawLine(it->pszs.x, it->pszs.y, it->clr, it->ap.x, it->ap.y,
|
||||
it->clr, 1, 0.5f);
|
||||
LI7::Line(it->pos, it->pszs, it->clr, 1);
|
||||
LI7::Line(it->pos, it->ap, it->clr, 1);
|
||||
LI7::Line(it->pszs, it->ap, it->clr, 1);
|
||||
} else {
|
||||
C2D_DrawTriangle(it->pos.x, it->pos.y, it->clr, it->pszs.x, it->pszs.y,
|
||||
it->clr, it->ap.x, it->ap.y, it->clr, 0.5);
|
||||
LI7::Triangle(it->pos, it->pszs, it->ap, it->clr);
|
||||
}
|
||||
} else if (it->type == 3) {
|
||||
// Text
|
||||
// little patch for a freeze
|
||||
if (it->text.length() < 1) continue;
|
||||
if (it->pszs.x == 0.0f) {
|
||||
it->pszs.x = it->Screen == R2Screen_Top ? 400 : 320;
|
||||
}
|
||||
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++;
|
||||
std::string txt = it->text;
|
||||
if (it->flags & PDTextFlags_Short) {
|
||||
txt = ShortText(txt, it->pszs.x - it->pos.x);
|
||||
} else if(it->flags & PDTextFlags_Wrap) {
|
||||
txt = WrapText(it->text, it->pszs.x-it->pos.x);
|
||||
}
|
||||
LI7::DrawText(it->pos, it->clr, txt, it->flags, it->pszs);
|
||||
} else if (it->type == 4) {
|
||||
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) {
|
||||
// TODO: Move the Draw Func into this API
|
||||
it->spr->Draw();
|
||||
// it->spr->Draw();
|
||||
} else if (it->type == 6) {
|
||||
C2D_DrawLine(it->pos.x, it->pos.y, it->clr, it->pszs.x, it->pszs.y,
|
||||
it->clr, it->ap.x, 0.5f);
|
||||
LI7::UseTexture();
|
||||
LI7::Line(it->pos, it->pszs, it->clr, it->ap.x);
|
||||
}
|
||||
}
|
||||
R2::commands.clear();
|
||||
|
124
source/Rubidium.cpp
Normal file
124
source/Rubidium.cpp
Normal 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
|
@ -45,7 +45,7 @@ void Palladium::Sprite::SetRotCenter(NVec2 percentage) {
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -1,9 +1,10 @@
|
||||
#include <pd/SpriteAnimation.hpp>
|
||||
|
||||
void Palladium::SpriteSheetAnimation::Setup(Palladium::Sheet::Ref sheet,
|
||||
size_t imagecount, size_t startimage,
|
||||
float frame_begin,
|
||||
float frame_finish) {
|
||||
size_t imagecount,
|
||||
size_t startimage,
|
||||
float frame_begin,
|
||||
float frame_finish) {
|
||||
D_totaltime = frame_begin;
|
||||
|
||||
this->images = imagecount;
|
||||
|
@ -1,11 +1,12 @@
|
||||
#include <pd/Texture.hpp>
|
||||
#include <pd/external/stb_image.h>
|
||||
#include <pd/internal_db.hpp>
|
||||
|
||||
#include <pd/external/stb_image_write.h>
|
||||
|
||||
#include <pd/Texture.hpp>
|
||||
#include <pd/internal_db.hpp>
|
||||
|
||||
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 >> 1;
|
||||
v |= v >> 2;
|
||||
@ -16,7 +17,7 @@ static u32 GP2O(u32 v) {
|
||||
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 int &h) {
|
||||
// Converts RGB24 to RGBA32
|
||||
@ -30,64 +31,107 @@ static void R24R32(std::vector<uint8_t> &out,
|
||||
out[dst + 3] = 255;
|
||||
}
|
||||
}
|
||||
}}
|
||||
}
|
||||
} // namespace pdi
|
||||
|
||||
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) {
|
||||
_pdi_logger()->Write("Invalid Input (object has 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;
|
||||
// Don't check here as check done before
|
||||
int bpp = GetBPP(type);
|
||||
if (bpp == 4) {
|
||||
// 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];
|
||||
auto a = buf[pos + 3];
|
||||
buf[pos + 0] = a;
|
||||
buf[pos + 1] = b;
|
||||
buf[pos + 2] = g;
|
||||
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
|
||||
this->tex_size.x = pdi::GP2O((unsigned int)w);
|
||||
this->tex_size.y = pdi::GP2O((unsigned int)h);
|
||||
if (!pdi::single_bit(w)) tex_size.x = pdi::get_pow2((unsigned int)w);
|
||||
if (!pdi::single_bit(h)) tex_size.y = pdi::get_pow2((unsigned int)h);
|
||||
|
||||
this->img_size.x = (u16)w;
|
||||
this->img_size.y = (u16)h;
|
||||
this->uvs.x = 0.0f;
|
||||
this->uvs.y = 1.0f;
|
||||
this->uvs.z = ((float)w / (float)this->tex_size.x);
|
||||
this->uvs.w = 1.0 - ((float)h / (float)this->tex_size.y);
|
||||
this->uvs.z = ((float)w / (float)tex_size.x);
|
||||
this->uvs.w = 1.0 - ((float)h / (float)tex_size.y);
|
||||
|
||||
// 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);
|
||||
|
||||
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) * ((int)this->tex_size.x >> 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;
|
||||
if (bpp == 3 || bpp == 4) {
|
||||
for (int x = 0; x < w; x++) {
|
||||
for (int y = 0; y < h; y++) {
|
||||
int dst_pos = ((((y >> 3) * ((int)tex_size.x >> 3) + (x >> 3)) << 6) +
|
||||
((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) |
|
||||
((y & 2) << 2) | ((x & 4) << 2) | ((y & 4) << 3))) *
|
||||
bpp;
|
||||
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);
|
||||
} else if (bpp == 1) {
|
||||
C3D_TexLoadImage(tex, buf.data(), GPU_TEXFACE_2D, 0);
|
||||
}
|
||||
|
||||
C3D_TexFlush(tex);
|
||||
tex->border = 0x00000000;
|
||||
C3D_TexSetWrap(tex, GPU_CLAMP_TO_BORDER, GPU_CLAMP_TO_BORDER);
|
||||
}
|
||||
void Texture::LoadFile(const std::string& path) {
|
||||
int w, h, c = 0;
|
||||
void Texture::LoadFile(const std::string &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);
|
||||
@ -107,8 +151,8 @@ void Texture::LoadFile(const std::string& path) {
|
||||
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);
|
||||
pdi::RGB24toRGBA32(
|
||||
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);
|
||||
@ -118,9 +162,10 @@ void Texture::LoadFile(const std::string& path) {
|
||||
MakeTex(wimg, w, h);
|
||||
}
|
||||
|
||||
void Texture::LoadFromMemory(const std::vector<unsigned char>& data) {
|
||||
int w, h, c = 0;
|
||||
unsigned char *image = stbi_load_from_memory(data.data(), data.size(), &w, &h, &c, 4);
|
||||
void Texture::LoadFromMemory(const std::vector<unsigned char> &data) {
|
||||
int w, h, c = 0;
|
||||
unsigned char *image =
|
||||
stbi_load_from_memory(data.data(), data.size(), &w, &h, &c, 4);
|
||||
if (image == nullptr) {
|
||||
//_pdi_logger()->Write("Failed to Load Image: " + path);
|
||||
return;
|
||||
@ -139,8 +184,8 @@ void Texture::LoadFromMemory(const std::vector<unsigned char>& data) {
|
||||
stbi_image_free(image);
|
||||
image = stbi_load_from_memory(data.data(), data.size(), &w, &h, &c, 3);
|
||||
wimg.resize(w * h * 4);
|
||||
pdi::R24R32(wimg, std::vector<unsigned char>(image, image + (w * h * 3)),
|
||||
w, h);
|
||||
pdi::RGB24toRGBA32(
|
||||
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);
|
||||
@ -150,28 +195,47 @@ void Texture::LoadFromMemory(const std::vector<unsigned char>& data) {
|
||||
MakeTex(wimg, w, h);
|
||||
}
|
||||
|
||||
void Texture::LoadPixels(const std::vector<unsigned char>& data, int w, int h) {
|
||||
Delete();
|
||||
if(w*h*4 != (int)data.size()) {
|
||||
return;
|
||||
}
|
||||
if (w > 1024 || h > 1024) {
|
||||
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();
|
||||
int bpp = GetBPP(type);
|
||||
Palladium::InlineAssert(bpp, "Invalid Type");
|
||||
if (w * h * bpp != (int)data.size()) {
|
||||
return;
|
||||
}
|
||||
if (w > 1024 || h > 1024) {
|
||||
// Reason: Image to Large
|
||||
//_pdi_logger()->Write("Image too Large!");
|
||||
return;
|
||||
}
|
||||
tex = new C3D_Tex;
|
||||
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() {
|
||||
if(tex) {
|
||||
delete tex;
|
||||
tex = nullptr;
|
||||
img_size = NVec2();
|
||||
tex_size = NVec2();
|
||||
uvs = NVec4();
|
||||
}
|
||||
if (!ad) return;
|
||||
if (tex) {
|
||||
C3D_TexDelete(tex);
|
||||
delete tex;
|
||||
tex = nullptr;
|
||||
img_size = NVec2();
|
||||
this->uvs.x = 0.0f;
|
||||
this->uvs.y = 1.0f;
|
||||
this->uvs.z = 1.0f;
|
||||
this->uvs.w = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace Palladium
|
@ -72,7 +72,7 @@ void Palladium::ThemeEditor::Draw() const {
|
||||
menu = 0;
|
||||
} else if (UI7::Button("Save")) {
|
||||
Palladium::AddOvl(std::make_unique<Ovl_Keyboard>(kbd_text, kbd_state,
|
||||
"<name>.theme"));
|
||||
"<name>.theme"));
|
||||
}
|
||||
for (auto& it : color_names) {
|
||||
UI7::ColorSelector(it.second, edit_theme->GetTableRef()[it.first]);
|
||||
@ -104,7 +104,7 @@ void Palladium::ThemeEditor::Draw() const {
|
||||
}
|
||||
} else {
|
||||
Palladium::PushMessage("ThemeEditor",
|
||||
"Cannot Delete\nPalladium.theme!");
|
||||
"Cannot Delete\nPalladium.theme!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
106
source/UI7.cpp
106
source/UI7.cpp
@ -116,14 +116,13 @@ class DrawCmd {
|
||||
}
|
||||
Palladium::R2::OnScreen(screen ? R2Screen_Top : R2Screen_Bottom);
|
||||
if (type == DrawCmdType_Rect) {
|
||||
Palladium::R2::AddRect(NVec2(rect.x, rect.y), NVec2(rect.z, rect.w),
|
||||
clr);
|
||||
Palladium::R2::AddRect(NVec2(rect.x, rect.y), NVec2(rect.z, rect.w), clr);
|
||||
} else if (type == DrawCmdType_Triangle) {
|
||||
Palladium::R2::AddTriangle(NVec2(rect.x, rect.y),
|
||||
NVec2(rect.z, rect.w), add_coords, clr);
|
||||
Palladium::R2::AddTriangle(NVec2(rect.x, rect.y), NVec2(rect.z, rect.w),
|
||||
add_coords, clr);
|
||||
} else if (type == DrawCmdType_Text) {
|
||||
Palladium::R2::AddText(NVec2(rect.x, rect.y), text, clr, text_flags,
|
||||
text_box);
|
||||
text_box);
|
||||
} else if (type == DrawCmdType_Image) {
|
||||
Palladium::R2::AddImage(NVec2(rect.x, rect.y), img);
|
||||
} else if (type == DrawCmdType_Debug) {
|
||||
@ -136,17 +135,16 @@ class DrawCmd {
|
||||
if (stype == DrawCmdType_Rect) {
|
||||
Palladium::R2::DrawNextLined();
|
||||
Palladium::R2::AddTriangle(NVec2(rect.x, rect.y),
|
||||
NVec2(rect.x + rect.z, rect.y),
|
||||
NVec2(rect.x, rect.y + rect.w), 0xff0000ff);
|
||||
NVec2(rect.x + rect.z, rect.y),
|
||||
NVec2(rect.x, rect.y + rect.w), 0xff0000ff);
|
||||
Palladium::R2::DrawNextLined();
|
||||
Palladium::R2::AddTriangle(NVec2(rect.x + rect.z, rect.y + rect.w),
|
||||
NVec2(rect.x + rect.z, rect.y),
|
||||
NVec2(rect.x, rect.y + rect.w), 0xff0000ff);
|
||||
NVec2(rect.x + rect.z, rect.y),
|
||||
NVec2(rect.x, rect.y + rect.w), 0xff0000ff);
|
||||
} else if (stype == DrawCmdType_Triangle) {
|
||||
Palladium::R2::DrawNextLined();
|
||||
Palladium::R2::AddTriangle(NVec2(rect.x, rect.y),
|
||||
NVec2(rect.z, rect.w), add_coords,
|
||||
0xff00ff00);
|
||||
Palladium::R2::AddTriangle(NVec2(rect.x, rect.y), NVec2(rect.z, rect.w),
|
||||
add_coords, 0xff00ff00);
|
||||
} else if (stype == DrawCmdType_Text) {
|
||||
auto szs = Palladium::R2::GetTextDimensions(text);
|
||||
if (text_flags & PDTextFlags_AlignRight) {
|
||||
@ -154,37 +152,37 @@ class DrawCmd {
|
||||
}
|
||||
Palladium::R2::DrawNextLined();
|
||||
Palladium::R2::AddTriangle(NVec2(rect.x, rect.y),
|
||||
NVec2(rect.x + szs.x, rect.y),
|
||||
NVec2(rect.x, rect.y + szs.y), 0xff00ffff);
|
||||
NVec2(rect.x + szs.x, rect.y),
|
||||
NVec2(rect.x, rect.y + szs.y), 0xff00ffff);
|
||||
Palladium::R2::DrawNextLined();
|
||||
Palladium::R2::AddTriangle(NVec2(rect.x + szs.x, rect.y + szs.y),
|
||||
NVec2(rect.x + szs.x, rect.y),
|
||||
NVec2(rect.x, rect.y + szs.y), 0xff00ffff);
|
||||
NVec2(rect.x + szs.x, rect.y),
|
||||
NVec2(rect.x, rect.y + szs.y), 0xff00ffff);
|
||||
} else if (stype == DrawCmdType_Image) {
|
||||
if (!img) return;
|
||||
rect.z = img->GetSize().x;
|
||||
rect.w = img->GetSize().y;
|
||||
Palladium::R2::DrawNextLined();
|
||||
Palladium::R2::AddTriangle(NVec2(rect.x, rect.y),
|
||||
NVec2(rect.x + rect.z, rect.y),
|
||||
NVec2(rect.x, rect.y + rect.w), 0xff0000ff);
|
||||
NVec2(rect.x + rect.z, rect.y),
|
||||
NVec2(rect.x, rect.y + rect.w), 0xff0000ff);
|
||||
Palladium::R2::DrawNextLined();
|
||||
Palladium::R2::AddTriangle(NVec2(rect.x + rect.z, rect.y + rect.w),
|
||||
NVec2(rect.x + rect.z, rect.y),
|
||||
NVec2(rect.x, rect.y + rect.w), 0xff0000ff);
|
||||
NVec2(rect.x + rect.z, rect.y),
|
||||
NVec2(rect.x, rect.y + rect.w), 0xff0000ff);
|
||||
}
|
||||
}
|
||||
PD_SMART_CTOR(DrawCmd)
|
||||
|
||||
NVec4 rect = NVec4(); // Position / Size
|
||||
NVec2 add_coords = NVec2(); // Additional Coords
|
||||
NVec4 rect = NVec4(); // Position / Size
|
||||
NVec2 add_coords = NVec2(); // Additional Coords
|
||||
unsigned int clr = 0; // Color
|
||||
std::string text = ""; // Text
|
||||
Palladium::Image::Ref img; // Image
|
||||
Palladium::Image::Ref img; // Image
|
||||
DrawCmdType type = DrawCmdType_Skip; // DrawCmd Type
|
||||
DrawCmdType stype = DrawCmdType_Skip; // Second Type
|
||||
PDTextFlags text_flags = 0; // Flags for Text Rendering
|
||||
NVec2 text_box = NVec2(); // Maximum text Box
|
||||
PDTextFlags text_flags = 0; // Flags for Text Rendering
|
||||
NVec2 text_box = NVec2(); // Maximum text Box
|
||||
bool screen = false; // Defines Top or Bottom
|
||||
};
|
||||
|
||||
@ -214,8 +212,7 @@ void UI7DrawList::AddRectangle(NVec2 pos, NVec2 szs, unsigned int clr) {
|
||||
AddCall(cmd);
|
||||
}
|
||||
|
||||
void UI7DrawList::AddTriangle(NVec2 pos0, NVec2 pos1, NVec2 pos2,
|
||||
PDColor clr) {
|
||||
void UI7DrawList::AddTriangle(NVec2 pos0, NVec2 pos1, NVec2 pos2, PDColor clr) {
|
||||
auto cmd = DrawCmd::New();
|
||||
cmd->screen = Palladium::R2::GetCurrentScreen();
|
||||
cmd->rect.x = pos0.x;
|
||||
@ -316,9 +313,9 @@ void UI7DrawList::AddDebugCall(std::shared_ptr<DrawCmd> cmd) {
|
||||
struct UI7Menu {
|
||||
UI7Menu() {}
|
||||
UI7ID menuid; // menu ID
|
||||
NVec2 cursor; // cursor
|
||||
NVec2 cb; // backup cursor
|
||||
NVec2 slc; // sameline cursor
|
||||
NVec2 cursor; // cursor
|
||||
NVec2 cb; // backup cursor
|
||||
NVec2 slc; // sameline cursor
|
||||
float scrolling_offset = 0.f; // MenuScrolling Pos
|
||||
bool enable_scrolling = false; // Menu Scrolling
|
||||
float scrolling_mod = 0.f; // For Menu Scrolling effect
|
||||
@ -452,8 +449,8 @@ void UI7CtxEndMenu() {
|
||||
(static_cast<float>(ui7_ctx->cm->scrolling_offset) /
|
||||
static_cast<float>(ui7_ctx->cm->ms.y - 240.f)))));
|
||||
// Render Slider
|
||||
ui7_ctx->cm->front->AddRectangle(
|
||||
NVec2(sw - 12, tsp), NVec2(slider_w * 2, szs), PDColor_List0);
|
||||
ui7_ctx->cm->front->AddRectangle(NVec2(sw - 12, tsp),
|
||||
NVec2(slider_w * 2, szs), PDColor_List0);
|
||||
ui7_ctx->cm->front->AddRectangle(NVec2(sw - 10, slider_pos + 2),
|
||||
NVec2(slider_w, slider_rh), slider_clr);
|
||||
}
|
||||
@ -586,7 +583,7 @@ bool Button(const std::string &label, NVec2 size) {
|
||||
}
|
||||
ui7_ctx->cm->main->AddRectangle(pos, size, btn);
|
||||
pos = NVec2(pos.x + size.x * 0.5f - textdim.x * 0.5,
|
||||
pos.y + size.y * 0.5f - textdim.y * 0.5);
|
||||
pos.y + size.y * 0.5f - textdim.y * 0.5);
|
||||
ui7_ctx->cm->main->AddText(pos, label,
|
||||
Palladium::ThemeActive()->AutoText(btn));
|
||||
return ret;
|
||||
@ -653,8 +650,7 @@ void Label(const std::string &label, PDTextFlags flags) {
|
||||
void Progressbar(float value) {
|
||||
if (!UI7CtxValidate()) return;
|
||||
NVec2 pos = GetCursorPos();
|
||||
NVec2 size =
|
||||
NVec2(Palladium::R2::GetCurrentScreenSize().x - (pos.x * 2), 20);
|
||||
NVec2 size = NVec2(Palladium::R2::GetCurrentScreenSize().x - (pos.x * 2), 20);
|
||||
if (ui7_ctx->cm->show_scroolbar && ui7_ctx->cm->enable_scrolling)
|
||||
size.x -= 16;
|
||||
MoveCursor(size);
|
||||
@ -719,9 +715,8 @@ void BrowserList(const std::vector<std::string> &entrys, int &selection,
|
||||
ui7_ctx->cm->main->AddText(
|
||||
pos + NVec2(5, 15 * i), entrys[list_index],
|
||||
Palladium::ThemeActive()->AutoText(
|
||||
selindex == (int)i
|
||||
? PDColor_Selector
|
||||
: (i % 2 == 0 ? PDColor_List0 : PDColor_List1)),
|
||||
selindex == (int)i ? PDColor_Selector
|
||||
: (i % 2 == 0 ? PDColor_List0 : PDColor_List1)),
|
||||
txtflags | PDTextFlags_Short, NVec2(size.x, 15));
|
||||
}
|
||||
Palladium::R2::SetTextSize(tmp_txt);
|
||||
@ -827,7 +822,7 @@ bool BeginMenu(const std::string &title, NVec2 size, UI7MenuFlags flags) {
|
||||
// Set modifier
|
||||
if (!InBox(np,
|
||||
NVec2(Palladium::R2::GetCurrentScreenSize().x - 8 - 5,
|
||||
5 + ui7_ctx->cm->tbh),
|
||||
5 + ui7_ctx->cm->tbh),
|
||||
NVec2(8, 240 - ui7_ctx->cm->tbh - 10))) {
|
||||
// Check if and do nothing if the scrolling ofset goes out of screen
|
||||
if (ui7_ctx->cm->scrolling_offset < ui7_ctx->cm->ms.y - 200 &&
|
||||
@ -874,7 +869,8 @@ bool BeginMenu(const std::string &title, NVec2 size, UI7MenuFlags flags) {
|
||||
|
||||
ui7_ctx->cm->front->AddText(
|
||||
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));
|
||||
@ -1043,8 +1039,7 @@ void ColorSelector(const std::string &label, unsigned int &color) {
|
||||
// Draw Color Name Shorted if needed
|
||||
ui7_ctx->cm->front->AddText(
|
||||
npos + NVec2(cbs.x + 7, 1), label,
|
||||
Palladium::ThemeActive()->AutoText(PDColor_FrameBg),
|
||||
PDTextFlags_Short);
|
||||
Palladium::ThemeActive()->AutoText(PDColor_FrameBg), PDTextFlags_Short);
|
||||
// Add luminance text
|
||||
ui7_ctx->cm->front->AddText(
|
||||
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(
|
||||
npos + NVec2(2, cbs.y * 3 + 4),
|
||||
NVec2(50 * ((float)clr.m_r / 255.f), cbs.y), 0xff0000ff);
|
||||
ui7_ctx->cm->front->AddText(
|
||||
npos + NVec2(2, cbs.y * 3 + 4), "R: " + std::to_string(clr.m_r),
|
||||
PDColor_Text, PDTextFlags_AlignMid, NVec2(50, 0));
|
||||
ui7_ctx->cm->front->AddText(npos + NVec2(2, cbs.y * 3 + 4),
|
||||
"R: " + std::to_string(clr.m_r), PDColor_Text,
|
||||
PDTextFlags_AlignMid, NVec2(50, 0));
|
||||
}
|
||||
// Green
|
||||
{
|
||||
@ -1074,9 +1069,9 @@ void ColorSelector(const std::string &label, unsigned int &color) {
|
||||
ui7_ctx->cm->front->AddRectangle(
|
||||
npos + NVec2(54, cbs.y * 3 + 4),
|
||||
NVec2(50 * ((float)clr.m_g / 255.f), cbs.y), 0xff00ff00);
|
||||
ui7_ctx->cm->front->AddText(
|
||||
npos + NVec2(54, cbs.y * 3 + 4), "G: " + std::to_string(clr.m_g),
|
||||
PDColor_Text, PDTextFlags_AlignMid, NVec2(50, 0));
|
||||
ui7_ctx->cm->front->AddText(npos + NVec2(54, cbs.y * 3 + 4),
|
||||
"G: " + std::to_string(clr.m_g), PDColor_Text,
|
||||
PDTextFlags_AlignMid, NVec2(50, 0));
|
||||
}
|
||||
// Blue
|
||||
{
|
||||
@ -1086,9 +1081,9 @@ void ColorSelector(const std::string &label, unsigned int &color) {
|
||||
ui7_ctx->cm->front->AddRectangle(
|
||||
npos + NVec2(2, cbs.y * 4 + 4),
|
||||
NVec2(50 * ((float)clr.m_b / 255.f), cbs.y), 0xffff0000);
|
||||
ui7_ctx->cm->front->AddText(
|
||||
npos + NVec2(2, cbs.y * 4 + 4), "B: " + std::to_string(clr.m_b),
|
||||
PDColor_Text, PDTextFlags_AlignMid, NVec2(50, 0));
|
||||
ui7_ctx->cm->front->AddText(npos + NVec2(2, cbs.y * 4 + 4),
|
||||
"B: " + std::to_string(clr.m_b), PDColor_Text,
|
||||
PDTextFlags_AlignMid, NVec2(50, 0));
|
||||
}
|
||||
// Alpha
|
||||
{
|
||||
@ -1098,15 +1093,14 @@ void ColorSelector(const std::string &label, unsigned int &color) {
|
||||
ui7_ctx->cm->front->AddRectangle(
|
||||
npos + NVec2(54, cbs.y * 4 + 4),
|
||||
NVec2(50 * ((float)clr.m_a / 255.f), cbs.y), 0xffffffff);
|
||||
ui7_ctx->cm->front->AddText(
|
||||
npos + NVec2(54, cbs.y * 4 + 4), "A: " + std::to_string(clr.m_a),
|
||||
PDColor_Text, PDTextFlags_AlignMid, NVec2(50, 0));
|
||||
ui7_ctx->cm->front->AddText(npos + NVec2(54, cbs.y * 4 + 4),
|
||||
"A: " + std::to_string(clr.m_a), PDColor_Text,
|
||||
PDTextFlags_AlignMid, NVec2(50, 0));
|
||||
}
|
||||
}
|
||||
|
||||
ui7_ctx->cm->main->AddRectangle(pos, cbs, outline);
|
||||
ui7_ctx->cm->main->AddRectangle(pos + NVec2(2, 2), cbs - NVec2(4, 4),
|
||||
color);
|
||||
ui7_ctx->cm->main->AddRectangle(pos + NVec2(2, 2), cbs - NVec2(4, 4), color);
|
||||
ui7_ctx->cm->main->AddText(
|
||||
pos + NVec2(cbs.x + 5, 1), label,
|
||||
Palladium::ThemeActive()->AutoText(PDColor_Background));
|
||||
|
@ -96,8 +96,9 @@ Palladium::Net::Error pdi_soc_init() {
|
||||
Result ret = socInit((u32 *)pdi_soc_buf, 0x100000);
|
||||
if (R_FAILED(ret)) {
|
||||
free(pdi_soc_buf);
|
||||
return ((static_cast<Palladium::Net::Error>(ret) << 32) |
|
||||
static_cast<Palladium::Net::Error>(Palladium::Net::Error_CtrStatus));
|
||||
return (
|
||||
(static_cast<Palladium::Net::Error>(ret) << 32) |
|
||||
static_cast<Palladium::Net::Error>(Palladium::Net::Error_CtrStatus));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -172,7 +173,7 @@ class tcp_server {
|
||||
};
|
||||
|
||||
#define stupid(x) &x, sizeof(x)
|
||||
#define pdi_reacttion(x) \
|
||||
#define pdi_reacttion(x) \
|
||||
{ \
|
||||
int code = x; \
|
||||
server.snd(stupid(code)); \
|
||||
|
10
source/li7_shader.cpp
Normal file
10
source/li7_shader.cpp
Normal 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;
|
@ -5,9 +5,9 @@
|
||||
// Use an Npi simplifier cause I am lazy
|
||||
#define reca_cc(x) reinterpret_cast<const char*>(x)
|
||||
#define reca_c(x) reinterpret_cast<char*>(x)
|
||||
#define pak32(q, w, e, r) \
|
||||
((((q) & 0xff) << 0) | (((w) & 0xff) << 8) | (((e) & 0xff) << 16) | \
|
||||
(((r) & 0xff) << 24))
|
||||
#define pak32(q, w, e, r) \
|
||||
((((q)&0xff) << 0) | (((w)&0xff) << 8) | (((e)&0xff) << 16) | \
|
||||
(((r)&0xff) << 24))
|
||||
|
||||
// Stupid RLE Algorithm
|
||||
void npi_compress(std::vector<unsigned char>& ret,
|
||||
|
@ -1,10 +1,10 @@
|
||||
#include <pd/Hid.hpp> // Integate HidApi
|
||||
#include <pd/LI7.hpp>
|
||||
#include <pd/Message.hpp>
|
||||
#include <pd/Overlays.hpp>
|
||||
#include <pd/ThemeEditor.hpp>
|
||||
#include <pd/UI7.hpp>
|
||||
#include <pd/palladium.hpp>
|
||||
#include <pd/LI7.hpp>
|
||||
|
||||
// Config 2
|
||||
#include <pd/external/json.hpp>
|
||||
@ -14,25 +14,20 @@
|
||||
#include <filesystem>
|
||||
#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;
|
||||
extern Palladium::LoggerBase::Ref pdi_logger;
|
||||
|
||||
static void pdi_ExitHook() {
|
||||
C2D_TextBufDelete(pdi_text_buffer);
|
||||
C2D_TextBufDelete(pdi_d2_dimbuf);
|
||||
void exit_romfs() {
|
||||
romfsExit();
|
||||
}
|
||||
|
||||
std::vector<std::string> string_to_lines(std::string input_str) {
|
||||
std::vector<std::string> lines;
|
||||
std::stringstream ss(input_str);
|
||||
std::string line;
|
||||
while (std::getline(ss, line)) {
|
||||
lines.push_back(line);
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
// TODO: Better Fader
|
||||
void Npifade() {
|
||||
if (pdi_fadein) {
|
||||
if (pdi_fadealpha < 255) {
|
||||
@ -121,8 +116,7 @@ void pdi_init_input() {
|
||||
}
|
||||
|
||||
void pdi_init_config() {
|
||||
pdi_config_path = "sdmc:/Palladium/Apps/";
|
||||
pdi_config_path += pdi_app_name;
|
||||
pdi_config_path = Palladium::GetAppDirectory();
|
||||
std::filesystem::create_directories(pdi_config_path.c_str());
|
||||
std::filesystem::create_directories("sdmc:/Palladium/Reports");
|
||||
bool renew = false;
|
||||
@ -222,7 +216,8 @@ void Palladium::Scene::doDraw() {
|
||||
|
||||
void Palladium::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) {
|
||||
@ -259,8 +254,8 @@ bool Palladium::MainLoop() {
|
||||
// Deltatime
|
||||
uint64_t currentTime = svcGetSystemTick();
|
||||
pdi_dtm = ((float)(currentTime / (float)TICKS_PER_MSEC) -
|
||||
(float)(pdi_last_tm / (float)TICKS_PER_MSEC)) /
|
||||
1000.f;
|
||||
(float)(pdi_last_tm / (float)TICKS_PER_MSEC)) /
|
||||
1000.f;
|
||||
pdi_time += pdi_dtm;
|
||||
pdi_last_tm = currentTime;
|
||||
|
||||
@ -274,11 +269,12 @@ bool Palladium::MainLoop() {
|
||||
Hid::Update();
|
||||
pdi_hid_touch_pos = NVec2(d7_touch.px, d7_touch.py);
|
||||
|
||||
Palladium::ClearTextBufs();
|
||||
// Palladium::ClearTextBufs();
|
||||
C3D_FrameBegin(C3D_FRAME_SYNCDRAW);
|
||||
|
||||
C2D_TargetClear(pd_top, C2D_Color32(0, 0, 0, 0));
|
||||
C2D_TargetClear(pd_bottom, C2D_Color32(0, 0, 0, 0));
|
||||
C3D_RenderTargetClear(pd_top, C3D_CLEAR_ALL, 0x00000000, 0);
|
||||
C3D_RenderTargetClear(pd_top_right, C3D_CLEAR_ALL, 0x00000000, 0);
|
||||
C3D_RenderTargetClear(pd_bottom, C3D_CLEAR_ALL, 0x00000000, 0);
|
||||
frameloop();
|
||||
if (pdi_enable_scene_system) {
|
||||
Palladium::Scene::doDraw();
|
||||
@ -287,8 +283,6 @@ bool Palladium::MainLoop() {
|
||||
return pdi_running;
|
||||
}
|
||||
|
||||
void Palladium::ClearTextBufs(void) { C2D_TextBufClear(pdi_text_buffer); }
|
||||
|
||||
void Palladium::Init::Graphics() {
|
||||
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
|
||||
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);
|
||||
atexit(C3D_Fini);
|
||||
C2D_Init((size_t)pd_max_objects);
|
||||
atexit(C2D_Fini);
|
||||
atexit(pdi_ExitHook);
|
||||
C2D_Prepare();
|
||||
pd_top = C2D_CreateScreenTarget(GFX_TOP, GFX_LEFT);
|
||||
pd_top_right = C2D_CreateScreenTarget(GFX_TOP, GFX_RIGHT);
|
||||
pd_bottom = C2D_CreateScreenTarget(GFX_BOTTOM, GFX_LEFT);
|
||||
pdi_text_buffer = C2D_TextBufNew(4096);
|
||||
pdi_d2_dimbuf = C2D_TextBufNew(4096);
|
||||
pdi_base_font = C2D_FontLoadSystem(CFG_REGION_USA);
|
||||
|
||||
pd_top =
|
||||
C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
|
||||
C3D_RenderTargetSetOutput(pd_top, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS);
|
||||
pd_top_right =
|
||||
C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
|
||||
C3D_RenderTargetSetOutput(pd_top_right, GFX_TOP, GFX_RIGHT,
|
||||
DISPLAY_TRANSFER_FLAGS);
|
||||
pd_bottom =
|
||||
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;
|
||||
@ -408,16 +408,21 @@ Result Palladium::Init::Minimal(std::string app_name) {
|
||||
osSetSpeedupEnable(true);
|
||||
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE);
|
||||
atexit(C3D_Fini);
|
||||
C2D_Init((size_t)pd_max_objects);
|
||||
atexit(C2D_Fini);
|
||||
atexit(pdi_ExitHook);
|
||||
C2D_Prepare();
|
||||
pd_top = C2D_CreateScreenTarget(GFX_TOP, GFX_LEFT);
|
||||
pd_top_right = C2D_CreateScreenTarget(GFX_TOP, GFX_RIGHT);
|
||||
pd_bottom = C2D_CreateScreenTarget(GFX_BOTTOM, GFX_LEFT);
|
||||
pdi_text_buffer = C2D_TextBufNew(4096);
|
||||
pdi_d2_dimbuf = C2D_TextBufNew(4096);
|
||||
pdi_base_font = C2D_FontLoadSystem(CFG_REGION_USA);
|
||||
|
||||
pd_top =
|
||||
C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
|
||||
C3D_RenderTargetSetOutput(pd_top, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS);
|
||||
pd_top_right =
|
||||
C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
|
||||
C3D_RenderTargetSetOutput(pd_top_right, GFX_TOP, GFX_RIGHT,
|
||||
DISPLAY_TRANSFER_FLAGS);
|
||||
pd_bottom =
|
||||
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();
|
||||
|
||||
pdi_graphics_on = true;
|
||||
@ -500,6 +505,7 @@ void Palladium::FrameEnd() {
|
||||
OvlHandler();
|
||||
Npifade();
|
||||
R2::Process();
|
||||
LI7::Render(pd_top, pd_bottom);
|
||||
C3D_FrameEnd(0);
|
||||
}
|
||||
|
||||
@ -530,6 +536,13 @@ std::vector<std::string> StrHelper(std::string input) {
|
||||
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 {
|
||||
if (m_state == RSETTINGS) {
|
||||
Palladium::R2::OnScreen(R2Screen_Top);
|
||||
@ -548,13 +561,17 @@ void Palladium::RSettings::Draw(void) const {
|
||||
UI7::EndMenu();
|
||||
}
|
||||
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")) {
|
||||
shared_request[0x00000001] = RFTRACE;
|
||||
}
|
||||
if (UI7::Button("UI7")) {
|
||||
shared_request[0x00000001] = RUI7;
|
||||
}
|
||||
UI7::SameLine();
|
||||
if (UI7::Button("Font")) {
|
||||
shared_request[0x00000001] = RFV;
|
||||
}
|
||||
if (UI7::Button("Overlays")) {
|
||||
shared_request[0x00000001] = ROVERLAYS;
|
||||
}
|
||||
@ -589,7 +606,7 @@ void Palladium::RSettings::Draw(void) const {
|
||||
UI7::EndMenu();
|
||||
}
|
||||
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")) {
|
||||
Palladium::IDB::Start();
|
||||
}
|
||||
@ -640,10 +657,10 @@ void Palladium::RSettings::Draw(void) const {
|
||||
// List Bg
|
||||
for (int i = 0; i < 12; i++) {
|
||||
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);
|
||||
else
|
||||
UI7::GetBackgroundList()->AddRectangle(NVec2(0, 40 + (i) * 15),
|
||||
UI7::GetBackgroundList()->AddRectangle(NVec2(0, 40 + (i)*15),
|
||||
NVec2(400, 15), PDColor_List1);
|
||||
}
|
||||
|
||||
@ -655,7 +672,7 @@ void Palladium::RSettings::Draw(void) const {
|
||||
std::string _fkey__ = "0";
|
||||
|
||||
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) {
|
||||
_fkey__ = it->first;
|
||||
UI7::GetBackgroundList()->AddRectangle(
|
||||
@ -665,9 +682,9 @@ void Palladium::RSettings::Draw(void) const {
|
||||
auto clr = ix == ftrace_index
|
||||
? PDColor_Selector
|
||||
: (ix % 2 == 0 ? PDColor_List0 : PDColor_List1);
|
||||
UI7::GetBackgroundList()->AddText(NVec2(5, 40 + (ix - start_index) * 15),
|
||||
it->second.func_name,
|
||||
Palladium::ThemeActive()->AutoText(clr));
|
||||
UI7::GetBackgroundList()->AddText(
|
||||
NVec2(5, 40 + (ix - start_index) * 15), it->second.func_name,
|
||||
Palladium::ThemeActive()->AutoText(clr));
|
||||
UI7::GetBackgroundList()->AddText(
|
||||
NVec2(395, 40 + (ix - start_index) * 15),
|
||||
Palladium::MsTimeFmt(it->second.time_of),
|
||||
@ -679,7 +696,7 @@ void Palladium::RSettings::Draw(void) const {
|
||||
Palladium::Ftrace::End("PDft", "display_traces");
|
||||
|
||||
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();
|
||||
std::advance(jt, ftrace_index);
|
||||
UI7::Label("Group: " + jt->second.group);
|
||||
@ -718,7 +735,7 @@ void Palladium::RSettings::Draw(void) const {
|
||||
}
|
||||
|
||||
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)) {
|
||||
if (UI7::Button("Go back")) {
|
||||
/// Request a state switch to state RSETTINGS
|
||||
@ -740,7 +757,7 @@ void Palladium::RSettings::Draw(void) const {
|
||||
}
|
||||
|
||||
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::Checkbox("Enable Overlay", pdi_metrikd);
|
||||
UI7::Checkbox("Bottom Screen", pdi_mt_screen);
|
||||
@ -763,11 +780,29 @@ void Palladium::RSettings::Draw(void) const {
|
||||
}
|
||||
|
||||
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)) {
|
||||
for (auto &it : pdi_logger->Lines()) UI7::Label(it, PDTextFlags_Wrap);
|
||||
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) {
|
||||
if (it.second) {
|
||||
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["internal_logger"]["nowritetxt"] = pdi_lggrf;
|
||||
cfg_wrt << pdi_config.dump(4);
|
||||
@ -808,9 +843,9 @@ void Palladium::RSettings::Logic() {
|
||||
stateftold = pdi_ftraced;
|
||||
|
||||
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);
|
||||
pdi_config["metrik-settings"]["enableoverlay"] = pdi_metrikd;
|
||||
pdi_config["metrik-settings"]["show"] = pdi_metrikd;
|
||||
pdi_config["metrik-settings"]["Screen"] = pdi_mt_screen;
|
||||
pdi_config["internal_logger"]["nowritetxt"] = pdi_lggrf;
|
||||
cfg_wrt << pdi_config.dump(4);
|
||||
@ -820,20 +855,20 @@ void Palladium::RSettings::Logic() {
|
||||
Palladium::Scene::Back();
|
||||
}
|
||||
}
|
||||
if (m_state == RUI7) {
|
||||
if (d7_hDown & KEY_B) {
|
||||
if (m_state == RUI7 || m_state == RFV) {
|
||||
if (d7_hUp & KEY_B) {
|
||||
m_state = RSETTINGS;
|
||||
}
|
||||
}
|
||||
if (m_state == ROVERLAYS) {
|
||||
mtovlstate = pdi_metrikd ? "true" : "false";
|
||||
mtscreenstate = pdi_mt_screen ? "Bottom" : "Top";
|
||||
if (d7_hDown & KEY_B) {
|
||||
if (d7_hUp & KEY_B) {
|
||||
m_state = RSETTINGS;
|
||||
}
|
||||
}
|
||||
if (m_state == RIDB || m_state == RLOGS) {
|
||||
if (d7_hDown & KEY_B) {
|
||||
if (d7_hUp & KEY_B) {
|
||||
m_state = RSETTINGS;
|
||||
}
|
||||
}
|
||||
@ -845,7 +880,7 @@ void Palladium::RSettings::Logic() {
|
||||
if (d7_hDown & KEY_UP) {
|
||||
if (ftrace_index > 0) ftrace_index--;
|
||||
}
|
||||
if (d7_hDown & KEY_B) {
|
||||
if (d7_hUp & KEY_B) {
|
||||
m_state = RSETTINGS;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
Loading…
Reference in New Issue
Block a user