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:
2024-08-02 13:50:36 +02:00
parent 02172d8aef
commit a58dc20562
41 changed files with 1182 additions and 922 deletions

View File

@ -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);

View File

@ -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 += "/";

View File

@ -89,9 +89,7 @@ void RegKeyUp(uint32_t &key_up) { hid_handler.setKup(key_up); }
void RegKeyRepeat(uint32_t &repeat) { hid_handler.setKrepeat(repeat); }
void 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);

View File

@ -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

View File

@ -1,29 +1,20 @@
#include <pd/LI7.hpp>
#include <pd/Color.hpp>
#include <pd/palladium.hpp>
#include <pd/external/stb_truetype.h>
#include <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

View File

@ -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 ?

View File

@ -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);

View File

@ -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));
}

View File

@ -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
View File

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

View File

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

View File

@ -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;

View File

@ -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

View File

@ -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!");
}
}
}

View File

@ -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));

View File

@ -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)); \

View File

@ -1,34 +0,0 @@
; LI7 Shader
; Constants
.constf myconst(0.0, 1.0, 0.00392156862745, 0.0)
.alias ones myconst.yyyy ; Vector full of ones
; Uniforms
.fvec projection[4]
; Outputs
.out out_position position
.out out_color color
.out out_uv texcoord0
; Inputs
.alias in_xyz v0
.alias in_uvc v1
.alias in_col v2
.entry vmain
.proc vmain
mov r0.xyz, in_xyz.xyz
mov r0.w, ones
dp4 out_position.x, projection[0], r0
dp4 out_position.y, projection[1], r0
dp4 out_position.z, projection[2], r0
dp4 out_position.w, projection[3], r0
mov out_uv, in_uvc.xy
mul r1, myconst.zzzz, in_col
mov out_color, r1
end
.end

10
source/li7_shader.cpp Normal file
View File

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

View File

@ -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,

View File

@ -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;
}
}

View File

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