# Rewrite Stage 1.5

- Added Overlays (Performance / Keyboaed)
- Keyboard has Gamepad Movement WIP (kinda)
- Work on UI7 Started
- Added Input Manager
- Added Message Boxes (Animated)
- Added Signle Header Tween func for animated stuff (Keyboard Messages, etc)
- Add FastHash (Maybe useful later)
- Using const & for vec in lithium
- Add ability to copy a command by a Ref
- Make Lists in Commands OpenAccess for Modification (StaticObject)
- Add Static Object (System to PreRender Suff that never changes) but can still be recolored or moved
- Add Layer and Font change functions
- Make Renderer Tools (RotateCorner, CreateRect, CreateLine, InBox, OptiCommandList) static (OpenAccess)
- Add ReIndexing to PushCommand
- Add Ability to Init vec3 and vec4 with vec2 and add .xy and .zw to vec4
- Fully Animated Keyboard that currently has problem of Top Down GamePad movement
- Add Func to Get GamePad Icon Codepoints for TextRenderer
- Made deltatime a float
- Using filesystem::path().wstring for convertation (works)
- Add a New InBox to Renderer that only checks if a point is inside a boundingbox
- Disable Font loading on Renderer Init due to 3ds Freezes when using SystemFont
- Make SystemFont lineheight 10% larger than it is to be nearly the same size as the ttf fonts
- Fix Some SpaceOffsets between TTF and SystemFont Rendering
- Cleanup the Update Rendermode Func
- Use LayerRenderSystem by default now as it now runs faster even with ttf fonts
This commit is contained in:
2025-01-19 20:16:43 +01:00
parent d815bb5674
commit b4a4b6a426
35 changed files with 1919 additions and 131 deletions

View File

@ -33,16 +33,21 @@ void App::Run() {
this->Init();
last_time = Sys::GetTime();
while (aptMainLoop()) {
u64 current = Sys::GetTime();
u64 dt = current - last_time;
app_time += float(dt / 1000.f);
input_mgr->Update();
u64 current = Sys::GetNanoTime();
float dt = static_cast<float>(current - last_time) / 1000000.f;
app_time += dt / 1000.f;
last_time = current;
fps = 1000.f / (float)dt;
fps = 1000.f / dt;
PD::TT::Beg("App_MainLoop");
if (!this->MainLoop(dt, app_time)) {
break;
}
PD::TT::End("App_MainLoop");
PD::TT::Beg("Ovl_Update");
overlay_mgr->Update(dt);
msg_mgr->Update(dt);
PD::TT::End("Ovl_Update");
renderer->Render();
}
this->Deinit();
@ -54,11 +59,17 @@ void App::PreInit() {
gfxInitDefault();
cfguInit();
romfsInit();
input_mgr = Hid::New();
renderer = LI::Renderer::New();
msg_mgr = MessageMgr::New(renderer);
overlay_mgr = OverlayMgr::New(renderer, input_mgr);
}
void App::PostDeinit() {
renderer = nullptr;
msg_mgr = nullptr;
overlay_mgr = nullptr;
input_mgr = nullptr;
gfxExit();
cfguExit();
romfsExit();

View File

@ -45,7 +45,9 @@ bool StringEndsWith(const std::string& str,
}
std::wstring MakeWstring(const std::string& s) {
return std::wstring(s.begin(), s.end());
// As std::wstring(s.begin(), s.end()); doesn't convert it
// Normally this should not be done like this but it works
return std::filesystem::path(s).wstring();
}
const std::string FormatNanos(unsigned long long nanos) {
@ -125,4 +127,12 @@ const std::string ToHex(const T& v) {
s << "0x" << std::setfill('0') << std::setw(sizeof(v) * 2) << std::hex << v;
return s.str();
}
u32 FastHash(const std::string& s) {
u32 hash = 5381;
for (auto& it : s) {
hash = (hash * 33) + static_cast<u8>(it);
}
return hash;
}
} // namespace PD::Strings

78
source/controls/hid.cpp Normal file
View File

@ -0,0 +1,78 @@
#include <3ds.h>
#include <pd/controls/hid.hpp>
/// Reform of the RenderD7 095 Hid Api
/// Using Custom Keybindings for future
/// Porting of the library
namespace PD {
Hid::Hid() {
binds[KEY_A] = A;
binds[KEY_B] = B;
binds[KEY_X] = X;
binds[KEY_Y] = Y;
binds[KEY_START] = Start;
binds[KEY_SELECT] = Select;
binds[KEY_L] = L;
binds[KEY_R] = R;
binds[KEY_DUP] = DUp;
binds[KEY_DDOWN] = DDown;
binds[KEY_DLEFT] = DLeft;
binds[KEY_DRIGHT] = DRight;
binds[KEY_CPAD_UP] = CPUp;
binds[KEY_CPAD_DOWN] = CPDown;
binds[KEY_CPAD_LEFT] = CPLeft;
binds[KEY_CPAD_RIGHT] = CPRight;
binds[KEY_CSTICK_UP] = CSUp;
binds[KEY_CSTICK_DOWN] = CSDown;
binds[KEY_CSTICK_LEFT] = CSLeft;
binds[KEY_CSTICK_RIGHT] = CSRight;
binds[KEY_ZL] = ZL;
binds[KEY_ZR] = ZR;
binds[KEY_TOUCH] = Touch;
}
void Hid::Update() {
hidScanInput();
for (int i = 0; i < 2; i++) {
key_events[i][Event_Down] = 0;
key_events[i][Event_Held] = 0;
key_events[i][Event_Up] = 0;
}
u32 kd = hidKeysDown();
u32 kh = hidKeysHeld();
u32 ku = hidKeysUp();
for (auto &b : binds) {
if (b.first & kd) {
key_events[0][Event_Down] |= b.second;
}
if (b.first & kh) {
key_events[0][Event_Held] |= b.second;
}
if (b.first & ku) {
key_events[0][Event_Up] |= b.second;
}
}
if (locked) {
SwappyTable();
}
touchPosition t;
hidTouchRead(&t);
touch[1] = touch[0]; // Cycle touch pos
touch[0] = vec2(t.px, t.py);
}
bool Hid::IsEvent(Event e, Key keys) { return key_events[0][e] & keys; }
void Hid::SwappyTable() {
auto tkd = key_events[1][Event_Down];
auto tkh = key_events[1][Event_Held];
auto tku = key_events[1][Event_Up];
key_events[1][Event_Down] = key_events[0][Event_Down];
key_events[1][Event_Held] = key_events[0][Event_Held];
key_events[1][Event_Up] = key_events[0][Event_Up];
key_events[0][Event_Down] = tkd;
key_events[0][Event_Held] = tkh;
key_events[0][Event_Up] = tku;
}
} // namespace PD

View File

@ -75,10 +75,12 @@ void Font::LoadTTF(const std::string& path, int height) {
off[0] = 0;
}
c.uv(vec4(static_cast<float>(off.x() / (float)quad),
static_cast<float>(1.f - (off.y() / (float)quad)),
static_cast<float>((float)(off.x() + w) / (float)quad),
static_cast<float>((float)(off.y() + h) / (float)quad)));
vec4 uvs;
uvs[0] = static_cast<float>(off.x() / (float)quad);
uvs[1] = static_cast<float>(1.f - (off.y() / (float)quad));
uvs[2] = static_cast<float>((float)(off.x() + w) / (float)quad);
uvs[3] = static_cast<float>(1.f - (float)(off.y() + h) / (float)quad);
c.uv(uvs);
c.tex(tex);
c.size(vec2(w, h));
@ -94,7 +96,8 @@ void Font::LoadTTF(const std::string& path, int height) {
font_tex[map_pos + 3] = bitmap[x + y * w];
}
}
off[0] += w;
// Small Patch to avoid some possible artifacts
off[0] += w + 1;
if (off[0] + w > quad) {
off[1] += pixel_height;
off[0] = 0;
@ -123,7 +126,9 @@ void Font::LoadSystemFont() {
const auto fnt_info = fontGetInfo(fnt);
const auto glyph_info = fontGetGlyphInfo(fnt);
this->textures.resize(glyph_info->nSheets + 1);
pixel_height = glyph_info->cellHeight;
/// Modify the Pixel Height by 1.1f to fit the
/// Size og ttf font Rendering
pixel_height = glyph_info->cellHeight * 1.1f;
for (size_t i = 0; i < glyph_info->nSheets; i++) {
auto stex = Texture::New();
auto tx = new C3D_Tex;
@ -226,9 +231,9 @@ Renderer::Renderer(RenderFlags flags) {
white = Texture::New(pixels, 16, 16);
UseTex(white);
font = Font::New();
font->LoadSystemFont();
// font->LoadTTF("romfs:/ComicNeue.ttf", 32);
// Not Loading as Systemfont is freezing
// font = Font::New();
// font->LoadSystemFont();
area_size = top->GetSize();
}
@ -238,12 +243,18 @@ Renderer::~Renderer() {
C3D_Fini();
}
bool Renderer::InBox(vec2 pos, vec2 szs, vec4 rect) {
bool Renderer::InBox(const vec2& pos, const vec2& szs, const vec4& rect) {
return (pos[0] < rect[2] || pos[1] < rect[3] || pos[0] + szs[0] > rect[0] ||
pos[1] + szs[1] > rect[1]);
}
bool Renderer::InBox(vec2 alpha, vec2 bravo, vec2 charlie, vec4 rect) {
bool Renderer::InBox(const vec2& pos, const vec4& rect) {
return (pos.x() > rect.x() && pos.x() < rect.x() + rect.z() &&
pos.y() > rect.y() && pos.y() < rect.y() + rect.w());
}
bool Renderer::InBox(const vec2& alpha, const vec2& bravo, const vec2& charlie,
const vec4& rect) {
return ((alpha[0] < rect[2] && bravo[0] < rect[2] && charlie[0] < rect[2]) ||
(alpha[1] < rect[3] && bravo[1] < rect[3] && charlie[1] < rect[3]) ||
(alpha[0] > 0 && bravo[0] > 0 && charlie[0] > 0) ||
@ -256,7 +267,7 @@ void Renderer::RotateCorner(vec2& v, float s, float c) {
v = vec2(x, y);
}
Rect Renderer::CreateRect(vec2 pos, vec2 size, float angle) {
Rect Renderer::CreateRect(const vec2& pos, const vec2& size, float angle) {
vec2 c = size * 0.5f; // Center
vec2 corner[4] = {
vec2(-c[0], -c[1]),
@ -279,7 +290,7 @@ Rect Renderer::CreateRect(vec2 pos, vec2 size, float angle) {
corner[3] + pos + c);
}
Rect Renderer::CreateLine(vec2 a, vec2 b, int t) {
Rect Renderer::CreateLine(const vec2& a, const vec2& b, int t) {
// Usin g th evec maths api makes the code as short as it is
vec2 dir = a - b;
float len = dir.len();
@ -306,7 +317,7 @@ void Renderer::SetupCommand(Command::Ref cmd) {
cmd->Index(cmd_idx++).Layer(current_layer).Tex(current_tex);
}
void Renderer::QuadCommand(Command::Ref cmd, const Rect& quad, vec4 uv,
void Renderer::QuadCommand(Command::Ref cmd, const Rect& quad, const vec4& uv,
u32 col) {
cmd->PushIndex(0).PushIndex(1).PushIndex(2);
cmd->PushIndex(0).PushIndex(2).PushIndex(3);
@ -320,8 +331,8 @@ void Renderer::QuadCommand(Command::Ref cmd, const Rect& quad, vec4 uv,
Vertex(vec2(quad.Bot().x(), quad.Bot().y()), vec2(uv.x(), uv.w()), col));
}
void Renderer::TriangleCommand(Command::Ref cmd, vec2 a, vec2 b, vec2 c,
u32 col) {
void Renderer::TriangleCommand(Command::Ref cmd, const vec2& a, const vec2& b,
const vec2& c, u32 col) {
cmd->Index(cmd_idx++).Layer(current_layer).Tex(current_tex);
cmd->PushIndex(2).PushIndex(1).PushIndex(0);
cmd->PushVertex(Vertex(a, vec2(0.f, 1.f), col));
@ -330,9 +341,9 @@ void Renderer::TriangleCommand(Command::Ref cmd, vec2 a, vec2 b, vec2 c,
}
/// TO BE REWRITTEN
void Renderer::TextCommand(std::vector<Command::Ref>& cmds, vec2 pos, u32 color,
const std::string& text, LITextFlags flags,
vec2 box) {
void Renderer::TextCommand(std::vector<Command::Ref>& cmds, const vec2& pos,
u32 color, const std::string& text,
LITextFlags flags, const vec2& box) {
if (!font) {
return;
}
@ -378,7 +389,7 @@ void Renderer::TextCommand(std::vector<Command::Ref>& cmds, vec2 pos, u32 color,
}
}
if (jt == '\t') {
off[0] += 4 * cfs;
off[0] += 16 * cfs;
} else {
if (jt != ' ') {
int lr = current_layer;
@ -395,6 +406,10 @@ void Renderer::TextCommand(std::vector<Command::Ref>& cmds, vec2 pos, u32 color,
cp.size() * cfs, 0.f);
QuadCommand(cmd, rec, cp.uv(), color);
current_layer = lr;
} else {
if (!font->SystemFont()) {
off[0] += 2 * cfs;
}
}
off[0] += cp.size().x() * cfs + 2 * cfs;
}
@ -449,8 +464,14 @@ vec2 Renderer::GetTextDimensions(const std::string& text) {
x = 0.f;
break;
case '\t':
x += 8 * cfs;
x += 16 * cfs;
break;
case ' ':
if (!font->SystemFont()) {
x += 2 * cfs;
}
// Fall trough here to get the same result as in
// TextCommand if/else Section
default:
x += cp.size().x() * cfs;
if (index != wtext.size()) {
@ -472,19 +493,16 @@ void Renderer::UpdateRenderMode(const RenderMode& mode) {
switch (mode) {
case RenderMode_SysFont:
C3D_TexEnvInit(env);
C3D_TexEnvSrc(env, C3D_RGB, GPU_PRIMARY_COLOR, (GPU_TEVSRC)0,
(GPU_TEVSRC)0);
C3D_TexEnvSrc(env, C3D_RGB, GPU_PRIMARY_COLOR);
C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE);
C3D_TexEnvSrc(env, C3D_Alpha, GPU_PRIMARY_COLOR, GPU_TEXTURE0,
(GPU_TEVSRC)0);
C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0);
C3D_TexEnvFunc(env, C3D_Alpha, GPU_MODULATE);
break;
// Fall trough instead of defining twice
case RenderMode_RGBA:
default:
C3D_TexEnvInit(env);
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR,
(GPU_TEVSRC)0);
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0);
C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE);
break;
}
@ -506,9 +524,9 @@ void Renderer::RenderOn(bool bot) {
commands = cmds.size();
size_t index = 0;
if (flags & RenderFlags_LRS) {
OptiCommandList(cmds);
}
// if (flags & RenderFlags_LRS) {
OptiCommandList(cmds);
//}
while (index < cmds.size()) {
C3D_Tex* tex = cmds[index]->Tex()->GetTex();
@ -589,7 +607,8 @@ void Renderer::Render() {
}
}
void Renderer::DrawRect(vec2 pos, vec2 size, u32 color, vec4 uv) {
void Renderer::DrawRect(const vec2& pos, const vec2& size, u32 color,
const vec4& uv) {
if (!InBox(pos, size, GetViewport())) {
// Instand abort as it is out of screen
return;
@ -601,12 +620,13 @@ void Renderer::DrawRect(vec2 pos, vec2 size, u32 color, vec4 uv) {
draw_list[bottom].push_back(cmd);
}
void Renderer::DrawRectSolid(vec2 pos, vec2 size, u32 color) {
void Renderer::DrawRectSolid(const vec2& pos, const vec2& size, u32 color) {
UseTex();
DrawRect(pos, size, color);
}
void Renderer::DrawTriangle(vec2 a, vec2 b, vec2 c, u32 color) {
void Renderer::DrawTriangle(const vec2& a, const vec2& b, const vec2& c,
u32 color) {
if (!InBox(a, b, c, GetViewport())) {
return;
}
@ -617,7 +637,8 @@ void Renderer::DrawTriangle(vec2 a, vec2 b, vec2 c, u32 color) {
draw_list[bottom].push_back(cmd);
}
void Renderer::DrawCircle(vec2 center_pos, float r, u32 color, int segments) {
void Renderer::DrawCircle(const vec2& center_pos, float r, u32 color,
int segments) {
if (segments < 3) {
return;
}
@ -639,7 +660,7 @@ void Renderer::DrawCircle(vec2 center_pos, float r, u32 color, int segments) {
draw_list[bottom].push_back(cmd);
}
void Renderer::DrawLine(vec2 a, vec2 b, u32 color, int t) {
void Renderer::DrawLine(const vec2& a, const vec2& b, u32 color, int t) {
UseTex();
Rect line = CreateLine(a, b, t);
@ -649,13 +670,13 @@ void Renderer::DrawLine(vec2 a, vec2 b, u32 color, int t) {
draw_list[bottom].push_back(cmd);
}
void Renderer::DrawImage(vec2 pos, Texture::Ref tex, vec2 scale) {
void Renderer::DrawImage(const vec2& pos, Texture::Ref tex, const vec2& scale) {
UseTex(tex);
DrawRect(pos, tex->GetSize() * scale, 0xffffffff, tex->GetUV());
}
void Renderer::DrawText(vec2 pos, u32 color, const std::string& text, u32 flags,
vec2 ap) {
void Renderer::DrawText(const vec2& pos, u32 color, const std::string& text,
u32 flags, const vec2& ap) {
TextCommand(draw_list[bottom], pos, color, text, flags, ap);
}

View File

@ -0,0 +1,549 @@
#include <pd/external/json.hpp>
#include <pd/maths/color.hpp>
#include <pd/overlays/keyboard.hpp>
#include <pd/tools/gamepad_icons.hpp>
namespace PD {
struct Key {
Key(const std::string& key, const vec2& p, const vec2& s,
Keyboard::KeyOperation o) {
k = key;
pos = p;
size = s;
op = o;
}
std::string k;
vec2 pos;
vec2 size;
Keyboard::KeyOperation op;
};
using Layout = std::vector<Key>;
Layout layouts[3] = {
{
// 1st row
Key("`", vec2(5, 0), 18, Keyboard::AppendSelf),
Key("1", vec2(25, 0), 18, Keyboard::AppendSelf),
Key("2", vec2(45, 0), 18, Keyboard::AppendSelf),
Key("3", vec2(65, 0), 18, Keyboard::AppendSelf),
Key("4", vec2(85, 0), 18, Keyboard::AppendSelf),
Key("5", vec2(105, 0), 18, Keyboard::AppendSelf),
Key("6", vec2(125, 0), 18, Keyboard::AppendSelf),
Key("7", vec2(145, 0), 18, Keyboard::AppendSelf),
Key("8", vec2(165, 0), 18, Keyboard::AppendSelf),
Key("9", vec2(185, 0), 18, Keyboard::AppendSelf),
Key("0", vec2(205, 0), 18, Keyboard::AppendSelf),
Key("-", vec2(225, 0), 18, Keyboard::AppendSelf),
Key("=", vec2(245, 0), 18, Keyboard::AppendSelf),
Key("<---", vec2(265, 0), vec2(50, 18), Keyboard::Backspace),
// 2nd row
Key("Tab", vec2(5, 20), vec2(40, 18), Keyboard::Tab),
Key("q", vec2(47, 20), 18, Keyboard::AppendSelf),
Key("w", vec2(67, 20), 18, Keyboard::AppendSelf),
Key("e", vec2(87, 20), 18, Keyboard::AppendSelf),
Key("r", vec2(107, 20), 18, Keyboard::AppendSelf),
Key("t", vec2(127, 20), 18, Keyboard::AppendSelf),
Key("y", vec2(147, 20), 18, Keyboard::AppendSelf),
Key("u", vec2(167, 20), 18, Keyboard::AppendSelf),
Key("i", vec2(187, 20), 18, Keyboard::AppendSelf),
Key("o", vec2(207, 20), 18, Keyboard::AppendSelf),
Key("p", vec2(227, 20), 18, Keyboard::AppendSelf),
Key("[", vec2(247, 20), 18, Keyboard::AppendSelf),
Key("]", vec2(267, 20), 18, Keyboard::AppendSelf),
Key("\\", vec2(287, 20), vec2(28, 18), Keyboard::AppendSelf),
// 3rd row
Key("Caps", vec2(5, 40), vec2(50, 18), Keyboard::Caps),
Key("a", vec2(57, 40), 18, Keyboard::AppendSelf),
Key("s", vec2(77, 40), 18, Keyboard::AppendSelf),
Key("d", vec2(97, 40), 18, Keyboard::AppendSelf),
Key("f", vec2(117, 40), 18, Keyboard::AppendSelf),
Key("g", vec2(137, 40), 18, Keyboard::AppendSelf),
Key("h", vec2(157, 40), 18, Keyboard::AppendSelf),
Key("j", vec2(177, 40), 18, Keyboard::AppendSelf),
Key("k", vec2(197, 40), 18, Keyboard::AppendSelf),
Key("l", vec2(217, 40), 18, Keyboard::AppendSelf),
Key(";", vec2(237, 40), 18, Keyboard::AppendSelf),
Key("'", vec2(257, 40), 18, Keyboard::AppendSelf),
Key("Enter", vec2(277, 40), vec2(38, 18), Keyboard::Enter),
// 4th row
Key("Shift", vec2(5, 60), vec2(60, 18), Keyboard::Shift),
Key("z", vec2(67, 60), 18, Keyboard::AppendSelf),
Key("x", vec2(87, 60), 18, Keyboard::AppendSelf),
Key("c", vec2(107, 60), 18, Keyboard::AppendSelf),
Key("v", vec2(127, 60), 18, Keyboard::AppendSelf),
Key("b", vec2(147, 60), 18, Keyboard::AppendSelf),
Key("n", vec2(167, 60), 18, Keyboard::AppendSelf),
Key("m", vec2(187, 60), 18, Keyboard::AppendSelf),
Key(",", vec2(207, 60), 18, Keyboard::AppendSelf),
Key(".", vec2(227, 60), 18, Keyboard::AppendSelf),
Key("/", vec2(247, 60), 18, Keyboard::AppendSelf),
Key("Shift", vec2(267, 60), vec2(48, 18), Keyboard::Shift),
// 5th row
Key("Cancel", vec2(5, 80), vec2(70, 18), Keyboard::OpCancel),
Key("(X)", vec2(77, 80), vec2(23, 18), Keyboard::Op1),
Key("Space", vec2(102, 80), vec2(108, 18), Keyboard::Space),
Key("(!)", vec2(212, 80), vec2(23, 18), Keyboard::Op2),
Key("Confirm", vec2(237, 80), vec2(78, 18), Keyboard::OpConfirm),
},
{
// 1st row
Key("`", vec2(5, 0), 18, Keyboard::AppendSelf),
Key("1", vec2(25, 0), 18, Keyboard::AppendSelf),
Key("2", vec2(45, 0), 18, Keyboard::AppendSelf),
Key("3", vec2(65, 0), 18, Keyboard::AppendSelf),
Key("4", vec2(85, 0), 18, Keyboard::AppendSelf),
Key("5", vec2(105, 0), 18, Keyboard::AppendSelf),
Key("6", vec2(125, 0), 18, Keyboard::AppendSelf),
Key("7", vec2(145, 0), 18, Keyboard::AppendSelf),
Key("8", vec2(165, 0), 18, Keyboard::AppendSelf),
Key("9", vec2(185, 0), 18, Keyboard::AppendSelf),
Key("0", vec2(205, 0), 18, Keyboard::AppendSelf),
Key("-", vec2(225, 0), 18, Keyboard::AppendSelf),
Key("=", vec2(245, 0), 18, Keyboard::AppendSelf),
Key("<---", vec2(265, 0), vec2(50, 18), Keyboard::Backspace),
// 2nd row
Key("Tab", vec2(5, 20), vec2(40, 18), Keyboard::Tab),
Key("Q", vec2(47, 20), 18, Keyboard::AppendSelf),
Key("W", vec2(67, 20), 18, Keyboard::AppendSelf),
Key("E", vec2(87, 20), 18, Keyboard::AppendSelf),
Key("R", vec2(107, 20), 18, Keyboard::AppendSelf),
Key("T", vec2(127, 20), 18, Keyboard::AppendSelf),
Key("Y", vec2(147, 20), 18, Keyboard::AppendSelf),
Key("U", vec2(167, 20), 18, Keyboard::AppendSelf),
Key("I", vec2(187, 20), 18, Keyboard::AppendSelf),
Key("O", vec2(207, 20), 18, Keyboard::AppendSelf),
Key("P", vec2(227, 20), 18, Keyboard::AppendSelf),
Key("[", vec2(247, 20), 18, Keyboard::AppendSelf),
Key("]", vec2(267, 20), 18, Keyboard::AppendSelf),
Key("\\", vec2(287, 20), vec2(28, 18), Keyboard::AppendSelf),
// 3rd row
Key("Caps", vec2(5, 40), vec2(50, 18), Keyboard::Caps),
Key("A", vec2(57, 40), 18, Keyboard::AppendSelf),
Key("S", vec2(77, 40), 18, Keyboard::AppendSelf),
Key("D", vec2(97, 40), 18, Keyboard::AppendSelf),
Key("F", vec2(117, 40), 18, Keyboard::AppendSelf),
Key("G", vec2(137, 40), 18, Keyboard::AppendSelf),
Key("H", vec2(157, 40), 18, Keyboard::AppendSelf),
Key("J", vec2(177, 40), 18, Keyboard::AppendSelf),
Key("K", vec2(197, 40), 18, Keyboard::AppendSelf),
Key("L", vec2(217, 40), 18, Keyboard::AppendSelf),
Key(";", vec2(237, 40), 18, Keyboard::AppendSelf),
Key("'", vec2(257, 40), 18, Keyboard::AppendSelf),
Key("Enter", vec2(277, 40), vec2(38, 18), Keyboard::Enter),
// 4th row
Key("Shift", vec2(5, 60), vec2(60, 18), Keyboard::Shift),
Key("Z", vec2(67, 60), 18, Keyboard::AppendSelf),
Key("X", vec2(87, 60), 18, Keyboard::AppendSelf),
Key("C", vec2(107, 60), 18, Keyboard::AppendSelf),
Key("V", vec2(127, 60), 18, Keyboard::AppendSelf),
Key("B", vec2(147, 60), 18, Keyboard::AppendSelf),
Key("N", vec2(167, 60), 18, Keyboard::AppendSelf),
Key("M", vec2(187, 60), 18, Keyboard::AppendSelf),
Key(",", vec2(207, 60), 18, Keyboard::AppendSelf),
Key(".", vec2(227, 60), 18, Keyboard::AppendSelf),
Key("/", vec2(247, 60), 18, Keyboard::AppendSelf),
Key("Shift", vec2(267, 60), vec2(48, 18), Keyboard::Shift),
// 5th row
Key("Cancel", vec2(5, 80), vec2(70, 18), Keyboard::OpCancel),
Key("(X)", vec2(77, 80), vec2(23, 18), Keyboard::Op1),
Key("Space", vec2(102, 80), vec2(108, 18), Keyboard::Space),
Key("(!)", vec2(212, 80), vec2(23, 18), Keyboard::Op2),
Key("Confirm", vec2(237, 80), vec2(78, 18), Keyboard::OpConfirm),
},
{
// 1st row
Key("~", vec2(5, 0), 18, Keyboard::AppendSelf),
Key("!", vec2(25, 0), 18, Keyboard::AppendSelf),
Key("@", vec2(45, 0), 18, Keyboard::AppendSelf),
Key("#", vec2(65, 0), 18, Keyboard::AppendSelf),
Key("$", vec2(85, 0), 18, Keyboard::AppendSelf),
Key("%", vec2(105, 0), 18, Keyboard::AppendSelf),
Key("^", vec2(125, 0), 18, Keyboard::AppendSelf),
Key("&", vec2(145, 0), 18, Keyboard::AppendSelf),
Key("*", vec2(165, 0), 18, Keyboard::AppendSelf),
Key("(", vec2(185, 0), 18, Keyboard::AppendSelf),
Key(")", vec2(205, 0), 18, Keyboard::AppendSelf),
Key("_", vec2(225, 0), 18, Keyboard::AppendSelf),
Key("+", vec2(245, 0), 18, Keyboard::AppendSelf),
Key("<---", vec2(265, 0), vec2(50, 18), Keyboard::Backspace),
// 2nd row
Key("Tab", vec2(5, 20), vec2(40, 18), Keyboard::Tab),
Key("Q", vec2(47, 20), 18, Keyboard::AppendSelf),
Key("W", vec2(67, 20), 18, Keyboard::AppendSelf),
Key("E", vec2(87, 20), 18, Keyboard::AppendSelf),
Key("R", vec2(107, 20), 18, Keyboard::AppendSelf),
Key("T", vec2(127, 20), 18, Keyboard::AppendSelf),
Key("Y", vec2(147, 20), 18, Keyboard::AppendSelf),
Key("U", vec2(167, 20), 18, Keyboard::AppendSelf),
Key("I", vec2(187, 20), 18, Keyboard::AppendSelf),
Key("O", vec2(207, 20), 18, Keyboard::AppendSelf),
Key("P", vec2(227, 20), 18, Keyboard::AppendSelf),
Key("{", vec2(247, 20), 18, Keyboard::AppendSelf),
Key("}", vec2(267, 20), 18, Keyboard::AppendSelf),
Key("|", vec2(287, 20), vec2(28, 18), Keyboard::AppendSelf),
// 3rd row
Key("Caps", vec2(5, 40), vec2(50, 18), Keyboard::Caps),
Key("A", vec2(57, 40), 18, Keyboard::AppendSelf),
Key("S", vec2(77, 40), 18, Keyboard::AppendSelf),
Key("D", vec2(97, 40), 18, Keyboard::AppendSelf),
Key("F", vec2(117, 40), 18, Keyboard::AppendSelf),
Key("G", vec2(137, 40), 18, Keyboard::AppendSelf),
Key("H", vec2(157, 40), 18, Keyboard::AppendSelf),
Key("J", vec2(177, 40), 18, Keyboard::AppendSelf),
Key("K", vec2(197, 40), 18, Keyboard::AppendSelf),
Key("L", vec2(217, 40), 18, Keyboard::AppendSelf),
Key(":", vec2(237, 40), 18, Keyboard::AppendSelf),
Key("\"", vec2(257, 40), 18, Keyboard::AppendSelf),
Key("Enter", vec2(277, 40), vec2(38, 18), Keyboard::Enter),
// 4th row
Key("Shift", vec2(5, 60), vec2(60, 18), Keyboard::Shift),
Key("Z", vec2(67, 60), 18, Keyboard::AppendSelf),
Key("X", vec2(87, 60), 18, Keyboard::AppendSelf),
Key("C", vec2(107, 60), 18, Keyboard::AppendSelf),
Key("V", vec2(127, 60), 18, Keyboard::AppendSelf),
Key("B", vec2(147, 60), 18, Keyboard::AppendSelf),
Key("N", vec2(167, 60), 18, Keyboard::AppendSelf),
Key("M", vec2(187, 60), 18, Keyboard::AppendSelf),
Key("<", vec2(207, 60), 18, Keyboard::AppendSelf),
Key(">", vec2(227, 60), 18, Keyboard::AppendSelf),
Key("?", vec2(247, 60), 18, Keyboard::AppendSelf),
Key("Shift", vec2(267, 60), vec2(48, 18), Keyboard::Shift),
// 5th row
Key("Cancel", vec2(5, 80), vec2(70, 18), Keyboard::OpCancel),
Key("(X)", vec2(77, 80), vec2(23, 18), Keyboard::Op1),
Key("Space", vec2(102, 80), vec2(108, 18), Keyboard::Space),
Key("(!)", vec2(212, 80), vec2(23, 18), Keyboard::Op2),
Key("Confirm", vec2(237, 80), vec2(78, 18), Keyboard::OpConfirm),
},
};
void DumpLayout(const std::string& path) {
nlohmann::json l0;
l0["name"] = "Default US";
for (int i = 0; i < 3; i++) {
nlohmann::json l1;
for (size_t j = 0; j < layouts[0].size(); j++) {
nlohmann::json key;
key["display_char"] = layouts[i][j].k;
key["pos_x"] = layouts[i][j].pos[0];
key["pos_y"] = layouts[i][j].pos[1];
key["size_x"] = layouts[i][j].size[0];
key["size_y"] = layouts[i][j].size[1];
key["op"] = layouts[i][j].op;
l1.push_back(key);
}
l0[std::to_string(i)] = l1;
}
std::ofstream off(path);
off << l0.dump(3);
off.close();
}
/// The Only One (too) is a static var to make sur
/// THe Keyboard can only exist once in the overlay mgr
int Keyboard::too = 0;
void Keyboard::MoveSelector() {
/// Move from Current position to New Position
selector.From(selector).To(layouts[0][raw_sel].pos).In(0.2f);
/// If Button Size Changed, animate to the new size
if (cselszs != layouts[0][raw_sel].size) {
cselszs = layouts[0][raw_sel].size;
sel_szs.Swap();
sel_szs.To(cselszs).In(0.2);
}
}
void Keyboard::LoadTheKeys(LI::Renderer::Ref ren) {
for (int i = 0; i < 3; i++) {
keys[i] = LI::StaticObject::New();
for (auto it : layouts[i]) {
vec2 pos = it.pos + it.size * 0.5 - ren->GetTextDimensions(it.k) * 0.5;
auto c = LI::Command::New();
auto r = ren->CreateRect(it.pos, it.size, 0.f);
int l = ren->Layer();
ren->UseTex();
ren->Layer(1);
ren->SetupCommand(c);
ren->QuadCommand(c, r, vec4(0.f, 1.f, 1.f, 0.f), 0xff444444);
keys[i]->PushCommand(c);
ren->Layer(2);
ren->TextCommand(keys[i]->List(), pos, 0xffffffff, it.k, 0, 0);
ren->Layer(l);
}
ren->OptiCommandList(keys[i]->List());
}
keys_loadet = true;
}
void Keyboard::Movement(Hid::Ref inp) {
/// Any Key if no selector
if (raw_sel < 0) {
/// Initial Selector PopUp
if (inp->IsUp((Hid::Key)(inp->Up | inp->Down | inp->Left | inp->Right))) {
raw_sel = 0;
vec2 dst = layouts[0][0].pos;
cselszs = layouts[0][0].size;
selector.As(selector.Linear).From(dst + (cselszs * 0.5)).To(dst).In(0.1f);
sel_szs.As(sel_szs.Linear).From(0).To(cselszs).In(0.1f);
}
} else {
/// Go Up Movement
if (inp->IsUp(inp->Up)) {
// beginning pos of the keyboard
vec2 sp = flymgr;
// Keys are offset by 22
sp.y() += 22;
// temp pos to save selector tween to
vec2 tp = selector;
// set its offset to startpos to
// create a box over all rows
tp.y() = sp.y();
// Get the selector tween size
vec2 tszs = sel_szs;
// Get the last keys pos and size
// to calculate the size of temp szs
auto const& lok = layouts[0][layouts[0].size() - 1];
tszs.y() = lok.pos.y() + lok.size.y();
// Backwards loop
for (int i = raw_sel; i >= 0; i--) {
if (LI::Renderer::InBox(
sp + layouts[0][i].pos - vec2(0, layouts[0][i].size.y()),
layouts[0][i].size, vec4(tp, tszs))) {
raw_sel = i;
break;
}
}
MoveSelector();
}
/// Go Down Movement
if (inp->IsUp(inp->Down)) {
vec2 fly = flymgr;
vec2 sel = selector;
vec2 selszs = sel_szs;
vec4 box(fly + sel, selszs);
// clang-format off
int start = layouts[0][raw_sel].pos.y() ==
layouts[0][layouts[0].size() - 1].pos.y()
? 0 : raw_sel + 3;
// clang-format on
for (int i = start; i < (int)layouts[0].size(); i++) {
if (LI::Renderer::InBox(fly + layouts[0][i].pos, sel_szs, box)) {
raw_sel = i;
break;
}
}
MoveSelector();
}
if (inp->IsUp(inp->Right)) {
if ((raw_sel + 1 >= (int)layouts[0].size()) ||
layouts[0][raw_sel].pos.y() != layouts[0][raw_sel + 1].pos.y()) {
for (int i = raw_sel - 1; i > 0; i--) {
if (i - 1 <= 0) {
raw_sel = 0;
break;
}
if (layouts[0][i].pos.y() != layouts[0][i - 1].pos.y()) {
raw_sel = i;
break;
}
}
} else {
raw_sel++;
}
MoveSelector();
}
if (inp->IsUp(inp->Left)) {
if (raw_sel - 1 < 0 ||
layouts[0][raw_sel].pos.y() != layouts[0][raw_sel - 1].pos.y()) {
for (int i = raw_sel; i < (int)layouts[0].size(); i++) {
if (i >= (int)layouts[0].size()) {
raw_sel = (int)layouts[0].size();
}
if (layouts[0][i].pos.y() != layouts[0][i + 1].pos.y()) {
raw_sel = i;
break;
}
}
} else {
raw_sel--;
}
MoveSelector();
}
}
}
void Keyboard::DoOperation(KeyOperation op, const std::string& kname) {
switch (op) {
case AppendSelf:
*text += kname;
if (mode == 2) {
mode = 0;
}
break;
case OpCancel:
Rem();
*text = copy;
break;
case OpConfirm:
Rem();
break;
case Shift:
mode = mode == 2 ? 0 : 2;
break;
case Caps:
mode = mode == 1 ? 0 : 1;
break;
case Backspace: {
std::string c = *text;
*text = c.substr(0, c.size() - 1);
} break;
case Space:
*text += ' ';
break;
case Tab:
*text += '\t';
break;
default:
break;
}
}
void Keyboard::RecolorBy(KeyOperation op, u32 color, int cm) {
int i = 0;
/// Not the fastest but the best for custom layouts
for (auto& it : layouts[cm]) {
if (it.op == op) {
keys[cm]->ReColorQuad(i, PD::Color(0xff222222));
break;
}
i++;
}
}
void Keyboard::InputOpBind(Hid::Key k, KeyOperation op, Hid::Ref inp, int cm) {
if (inp->IsUp(k)) {
RecolorBy(op, PD::Color(0xff222222), cm);
DoOperation(op, "");
} else if (inp->IsHeld(k)) {
RecolorBy(op, PD::Color(0xff333333), cm);
}
}
void Keyboard::Update(float delta, LI::Renderer::Ref ren, Hid::Ref inp) {
/// Load Keys if not present
if (!keys_loadet) {
inp->Clear();
LoadTheKeys(ren);
}
/// Unlock Input
inp->Unlock();
/// Kill Overlay if rem was toggeled and
/// Animation is finished
if (rem && flymgr.IsFinished()) {
// Should be already unlocked ...
// ist mit aber egal
inp->Unlock();
Kill();
return; // Break to not lock again
}
/// Process Controller Movement
Movement(inp);
/// Declare RenderLayer (10 above the latest)
ren->Layer(ren->Layer() + 10);
/// Update animations
flymgr.Update(delta);
selector.Update(delta);
sel_szs.Update(delta);
/// Blend Top or|and Bottom Screen
if (flags & Flags_BlendBottom || flags & Flags_BlendTop) {
Color fade(0.3f, 0.3f, 0.3f);
if (rem) {
fade.a(fade.a() * (1.f - flymgr.Progress()));
} else {
fade.a(fade.a() * flymgr.Progress());
}
if (flags & Flags_BlendTop) {
ren->OnScreen(Screen::Top);
ren->DrawRectSolid(0, vec2(400, 240), fade);
}
if (flags & Flags_BlendBottom) {
ren->OnScreen(Screen::Bottom);
ren->DrawRectSolid(0, vec2(320, 240), fade);
}
}
/// Get the current start possition
vec2 start = flymgr;
// Draw head and Keyboard background
ren->DrawRectSolid(vec2(0, start.y()), vec2(320, 17), 0xaa000000);
ren->DrawRectSolid(vec2(0, start.y()), vec2(320, 125), 0xaa222222);
/// Grab the base layer and go one up for texts
int l = ren->Layer();
ren->Layer(l + 2);
// if (ren->Font()->SystemFont()) {
// std::stringstream s;
// s << GamePadIcons::GetIcon(GamePadIcons::B) << " Backspace ";
// s << GamePadIcons::GetIcon(GamePadIcons::Y) << " Space\n";
// s << GamePadIcons::GetIcon(GamePadIcons::X) << " Cancel ";
// s << GamePadIcons::GetIcon(GamePadIcons::Start) << " Confirm\n";
// s << GamePadIcons::GetIcon(GamePadIcons::L) << " Shift ";
// s << GamePadIcons::GetIcon(GamePadIcons::R) << " CAPS\n";
// s << GamePadIcons::GetIcon(GamePadIcons::Dpad) << " Move ";
// s << GamePadIcons::GetIcon(GamePadIcons::A) << " Select\n";
// ren->DrawText(vec2(5, start.y() -
// ren->GetTextDimensions(s.str()).y()+16),
// 0xffffffff, s.str());
// }
ren->DrawText(vec2(5, start.y()), 0xffffffff, "> " + *text);
ren->Layer(l + 1);
/// Offset Keys start height by 22
start[1] += 22;
/// Cache Mode to not render on 0, 0
int cm = mode;
keys[cm]->ReCopy();
int ii = 0;
for (auto& it : layouts[mode]) {
PD::Color bgc(0xff444444);
if (((ren->InBox(inp->TouchPosLast(), vec4(start + it.pos, it.size)) &&
inp->IsHeld(inp->Touch)) ||
(inp->IsHeld(inp->A) && ii == raw_sel)) &&
flymgr.IsFinished()) {
bgc = PD::Color(0xff333333);
}
if (((ren->InBox(inp->TouchPosLast(), vec4(start + it.pos, it.size)) &&
inp->IsUp(inp->Touch)) ||
(inp->IsUp(inp->A) && ii == raw_sel)) &&
flymgr.IsFinished()) {
bgc = PD::Color(0xff222222);
DoOperation(it.op, it.k);
}
/// This is hardcoded shit guessing that the
/// Buttons are in the beginning of the list
/// (Should be the case as OptiCmdList sorts by layer)
keys[cm]->ReColorQuad(ii, bgc);
ii++;
}
// Bind Key Operations
InputOpBind(inp->B, Backspace, inp, cm);
InputOpBind(inp->Y, Space, inp, cm);
InputOpBind(inp->Start, OpConfirm, inp, cm);
InputOpBind(inp->X, OpCancel, inp, cm);
InputOpBind(inp->L, Shift, inp, cm);
InputOpBind(inp->R, Caps, inp, cm);
if (raw_sel != -1) {
ren->Layer(l);
ren->DrawRectSolid(start + selector - vec2(1), vec2(sel_szs) + vec2(2),
0xffffffff);
ren->Layer(l);
}
keys[cm]->ReLayer(l);
keys[cm]->MoveIt(start);
for (auto it : keys[cm]->List()) {
ren->PushCommand(it);
}
inp->Lock();
}
} // namespace PD

View File

@ -0,0 +1,126 @@
#include <pd/overlays/message_mgr.hpp>
namespace PD {
MessageMgr::Container::Container(const std::string& title,
const std::string& msg) {
this->title = title;
this->msg = msg;
size = vec2(150, 50);
// Precalculate colors
col_bg = PD::Color("#111111aa");
col_text = PD::Color("#ffffff");
// Setup Flyin Animation
FlyIn();
}
void MessageMgr::Container::Render(PD::LI::Renderer::Ref ren) {
// Create a Temp var to not recalculate
// the position everytime we use it
// even if the calculation would always
// result in the same we would waste a lot
// of cpu performance which is a big issue
// espeacilly on the Old3ds...
vec2 tpos = pos;
// Check if it goes out of screen
// Instant kills cause it will never be on
// Screen agains
if (tpos[1] + size[1] < 0) {
kill = true;
}
// If should be removed modify the color by fade
// Use a temp var as well to not call it twice
if (tbr) {
float f = 1.f - pos.Progress();
col_bg.a(col_bg.a() * f);
col_text.a(col_text.a() * f);
}
// Create a backup Layer to Render
// Text onto the next layer
int l = ren->Layer();
ren->DrawRectSolid(tpos, size, col_bg);
ren->Layer(l + 1);
ren->DrawText(tpos + vec2(4, 2), col_text, title);
ren->DrawText(tpos + vec2(4, 16), col_text, msg);
ren->Layer(l);
}
void MessageMgr::Container::Update(int slot, float delta) {
// Increase lifetime
lifetime += delta / 1000.f;
// Trigger move up Animation if
// the slot got changed
if (s != slot) {
ToBeMoved(slot);
s = slot;
}
// Update the animations
pos.Update(delta);
// Trigger the remove Event if lifetime
// goes beyond 4 secods
if (lifetime > 4 && !tbr) {
ToBeRemoved();
}
}
void MessageMgr::Container::FlyIn() {
// Come from out of the screen to 5, 185 into
// The screen as EaseInSine in 0.5 seconds
pos.From(vec2(-size[0], 240 - size[1] - 5))
.To(vec2(5, 240 - size[1] - 5))
.In(0.5)
.As(pos.EaseInSine);
}
void MessageMgr::Container::ToBeMoved(int slot) {
// Bit more special
// Get the current pos as temp one
vec2 tpos = pos;
// Calculate a temp Startpos which
// is the endpos of Flyin if
// it is fully playd (see next comment)
float spos = 240 - size[1] - 5;
// Now from the Current Position Move up by
// The Number of slot * the size.y + 5
// and make sure it flys diagonal if the
// Flyin hasn't ended yet. This animation uses EaseInSine
// And does it's move in 0.4 seconds to not have
// The new one and this one in collision for to much time
pos.From(tpos)
.To(vec2(5, spos - slot * (size[1] + 5)))
.As(pos.EaseInSine)
.In(0.4);
}
void MessageMgr::Container::ToBeRemoved() {
// This effect uses EaseOutSine and as well uses the fade anim
tbr = true;
// We Force set the Position to Finished to avoid collision
// to the ToBeMoved Animation And then set an EaseOutSine in 0.5
// seconds to move the Message 30 pixels up while fading out
pos.Finish();
vec2 tpos = pos;
pos.From(tpos).To(tpos - vec2(0, 30)).As(pos.EaseOutSine).In(0.5);
}
void MessageMgr::Push(const std::string& title, const std::string& text) {
// Simply Add a New Message Container
msgs.push_back(Container::New(title, text));
}
void MessageMgr::Update(float delta) {
// Go two layers up and Render on Top
ren->Layer(ren->Layer() + 2);
ren->OnScreen(Screen::Top);
for (size_t i = 0; i < msgs.size(); i++) {
// Update the Animation Handlers and Move older
// Messages up if a new one got pushed
msgs[i]->Update(msgs.size() - i - 1, delta);
msgs[i]->Render(ren);
}
/// OMG HE LOOPS TWICE OVER THE OBJECTS TO
/// CHECK IF THEY CAN BE REMOVED WOW.......
/// Just my Stupid fix for the flickering
/// Of the other messages if one get's removed
for (size_t i = 0; i < msgs.size(); i++) {
if (msgs[i]->ShouldBeRemoved()) {
msgs.erase(msgs.begin() + i);
}
}
}
} // namespace PD

View File

@ -0,0 +1,14 @@
#include <pd/overlays/overlay_mgr.hpp>
namespace PD {
void OverlayMgr::Push(Overlay::Ref overlay) { overlays.push_back(overlay); }
void OverlayMgr::Update(float delta) {
for (size_t i = 0; i < overlays.size(); i++) {
if (overlays[i]->IsKilled()) {
overlays.erase(overlays.begin() + i);
continue;
}
overlays[i]->Update(delta, ren, inp);
}
}
} // namespace PD

View File

@ -0,0 +1,46 @@
#include <pd/common/strings.hpp>
#include <pd/common/sys.hpp>
#include <pd/overlays/performance.hpp>
namespace PD {
int Performance::too = 0;
void Performance::Update(float delta, LI::Renderer::Ref ren, Hid::Ref inp) {
if (*skill) {
Kill();
}
ren->OnScreen(Screen::Top);
ren->TextScale(0.6);
vec2 pos;
Line(pos, std::format("FPS {:.1f} FPS | {:.2f}ms", 1000.f / delta, delta),
ren);
Line(pos, "Ren [AVG]: " + TSA("LI_RenderAll"), ren);
Line(pos, "App [AVG]: " + TSA("App_MainLoop"), ren);
Line(pos, "Ovl [AVG]: " + TSA("Ovl_Update"), ren);
Line(pos,
"VI: [" + std::to_string(ren->Vertices()) + ", " +
std::to_string(ren->Indices()) + "]",
ren);
Line(pos,
"DC: [" + std::to_string(ren->DrawCalls()) + ", " +
std::to_string(ren->Commands()) + "]",
ren);
ren->DefaultTextScale();
}
void Performance::Line(vec2& pos, const std::string& text,
LI::Renderer::Ref ren) {
auto tbs = ren->GetTextDimensions(text);
int l = ren->Layer();
ren->DrawRectSolid(pos, tbs, 0xaa000000);
ren->Layer(l + 1);
ren->DrawText(pos, 0xffff00ff, text);
ren->Layer(l);
pos[1] += tbs[1]; // Auto set new pos
}
std::string Performance::TSA(const std::string& id) {
return PD::Strings::FormatNanos(
PD::Sys::GetTraceRef(id)->GetProtocol()->GetAverage());
}
} // namespace PD

View File

@ -0,0 +1,57 @@
#include <pd/tools/gamepad_icons.hpp>
namespace PD {
namespace GamePadIcons {
/// For Reference see docs at 3DBrew
std::unordered_map<ID, std::string> gp_icons{
{A, "\uE000"},
{B, "\uE001"},
{X, "\uE002"},
{Y, "\uE003"},
{L, "\uE004"},
{R, "\uE005"},
{Dpad, "\uE006"},
{Start, "\uE045"},
{Select, "\uE046"},
{Home, "\uE073"},
{Steps, "\uE074"},
{PlayCoin, "\uE075"},
{AnalogStick, "\uE077"},
{Power3DS, "\uE078"},
{DpadUp, "\uE079"},
{DpadDown, "\uE07A"},
{DpadLeft, "\uE07B"},
{DpadRight, "\uE07C"},
{DpadHorizontal, "\uE07D"},
{DpadVertical, "\uE07E"},
};
std::unordered_map<Hid::Key, ID> gp_link{
{Hid::A, ID::A},
{Hid::B, ID::B},
{Hid::X, ID::X},
{Hid::Y, ID::Y},
{Hid::L, ID::L},
{Hid::R, ID::R},
{Hid::Start, ID::Start},
{Hid::Select, ID::Select},
{Hid::DUp, ID::DpadUp},
{Hid::DDown, ID::DpadDown},
{Hid::DLeft, ID::DpadLeft},
{Hid::DRight, ID::DpadRight},
};
std::string GetIcon(ID id) {
auto e = gp_icons.find(id);
if (e == gp_icons.end()) {
return "";
}
return e->second;
}
std::string GetIcon(Hid::Key key) {
auto e = gp_link.find(key);
if (e == gp_link.end()) {
return "";
}
return gp_icons[gp_link[key]];
}
} // namespace GamePadIcons
} // namespace PD

View File

@ -24,7 +24,8 @@ SOFTWARE.
#include <pd/ui7/drawlist.hpp>
namespace PD {
void UI7DrawList::AddRectangle(vec2 pos, vec2 szs, const UI7Color& clr) {
namespace UI7 {
void DrawList::AddRectangle(vec2 pos, vec2 szs, const UI7Color& clr) {
if (!ren->InBox(pos, szs, ren->GetViewport())) {
return;
}
@ -37,8 +38,8 @@ void UI7DrawList::AddRectangle(vec2 pos, vec2 szs, const UI7Color& clr) {
commands.push_back(cmd);
}
void UI7DrawList::AddTriangle(vec2 pos0, vec2 pos1, vec2 pos2,
const UI7Color& clr) {
void DrawList::AddTriangle(vec2 pos0, vec2 pos1, vec2 pos2,
const UI7Color& clr) {
if (!ren->InBox(pos0, pos1, pos2, ren->GetViewport())) {
return;
}
@ -50,16 +51,15 @@ void UI7DrawList::AddTriangle(vec2 pos0, vec2 pos1, vec2 pos2,
commands.push_back(cmd);
}
void UI7DrawList::AddText(vec2 pos, const std::string& text,
const UI7Color& clr, LITextFlags flags = 0,
vec2 box = vec2()) {
void DrawList::AddText(vec2 pos, const std::string& text, const UI7Color& clr,
LITextFlags flags, vec2 box) {
// Dont create a Command here as TextCommand has autosetup
// cause it needs to generate multiple commands if
// Font uses multiple textures
ren->TextCommand(commands, pos, clr, text, flags, box);
}
void UI7DrawList::AddImage(vec2 pos, Texture::Ref img) {
void DrawList::AddImage(vec2 pos, Texture::Ref img) {
if (!ren->InBox(pos, img->GetSize(), ren->GetViewport())) {
return;
}
@ -72,14 +72,14 @@ void UI7DrawList::AddImage(vec2 pos, Texture::Ref img) {
commands.push_back(cmd);
}
void UI7DrawList::Clear() { commands.clear(); }
void DrawList::Clear() { commands.clear(); }
void UI7DrawList::Process() {
void DrawList::Process() {
// UI7 Commands Use LI7 as default feature
ren->OptiCommandList(commands);
for (auto command : commands) {
ren->PushCommand(command);
}
}
} // namespace UI7
} // namespace PD

24
source/ui7/theme.cpp Normal file
View File

@ -0,0 +1,24 @@
#include <pd/maths/color.hpp>
#include <pd/ui7/theme.hpp>
namespace PD {
namespace UI7 {
void Theme::Default(Theme& theme) {
theme.Set(UI7Color_Text, Color("#FFFFFFFF"));
theme.Set(UI7Color_TextDead, Color("#AAAAAAFF"));
theme.Set(UI7Color_Background, Color("#EEEEEEFF"));
theme.Set(UI7Color_Button, Color("#111111FF"));
theme.Set(UI7Color_ButtonDead, Color("#080808FF"));
theme.Set(UI7Color_ButtonActive, Color("#2A2A2AFF"));
theme.Set(UI7Color_ButtonDisabled, Color("#222222FF"));
theme.Set(UI7Color_Header, Color("#111111FF"));
theme.Set(UI7Color_Selector, Color("#222222FF"));
theme.Set(UI7Color_Checkmark, Color("#2A2A2AFF"));
theme.Set(UI7Color_FrameBackground, Color("#555555FF"));
theme.Set(UI7Color_FragmeBackgroundHovered, Color("#777777FF"));
theme.Set(UI7Color_Progressbar, Color("#00FF00FF"));
theme.Set(UI7Color_ListEven, Color("#CCCCCCFF"));
theme.Set(UI7Color_ListOdd, Color("#BBBBBBFF"));
}
} // namespace UI7
} // namespace PD