# 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

@ -38,5 +38,12 @@ SOFTWARE.
#include <pd/maths/color.hpp>
#include <pd/maths/img_convert.hpp>
#include <pd/maths/vec.hpp>
// Overlays
#include <pd/overlays/keyboard.hpp>
#include <pd/overlays/message_mgr.hpp>
#include <pd/overlays/overlay_mgr.hpp>
#include <pd/overlays/performance.hpp>
// UI7
#include <pd/ui7/ui7.hpp>
// namespace Palladium = PD;

View File

@ -25,7 +25,10 @@ SOFTWARE.
#include <pd/common/common.hpp>
#include <pd/common/timetrace.hpp>
#include <pd/controls/hid.hpp>
#include <pd/graphics/lithium.hpp>
#include <pd/overlays/message_mgr.hpp>
#include <pd/overlays/overlay_mgr.hpp>
namespace PD {
/// @brief Template Class for User Application
@ -43,7 +46,7 @@ class App : public SmartCtor<App> {
/// @param delta Deltatime
/// @param time App RunTime
/// @return false to exit the app
virtual bool MainLoop(u64 delta, float time) { return false; }
virtual bool MainLoop(float delta, float time) { return false; }
/// @brief Function to run the App
/// (int main() {
@ -52,15 +55,19 @@ class App : public SmartCtor<App> {
/// return 0;
/// })
void Run();
LI::Renderer::Ref Renderer() { return renderer; }
MessageMgr::Ref Messages() { return msg_mgr; }
OverlayMgr::Ref Overlays() { return overlay_mgr; }
Hid::Ref Input() { return input_mgr; }
float GetFps() const { return fps; }
private:
void PreInit();
void PostDeinit();
LI::Renderer::Ref renderer;
MessageMgr::Ref msg_mgr;
OverlayMgr::Ref overlay_mgr;
Hid::Ref input_mgr;
u64 last_time;
float app_time;
float fps;

View File

@ -29,6 +29,7 @@ SOFTWARE.
#include <filesystem> // Requires C++ 17 or later
#include <format> // Requires C++ 20 or later
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <memory>

View File

@ -38,5 +38,6 @@ const std::string GetFileName(const std::string& path,
const std::string PathRemoveExtension(const std::string& path);
template <typename T>
const std::string ToHex(const T& v);
u32 FastHash(const std::string& s);
} // namespace Strings
} // namespace PD

View File

@ -0,0 +1,95 @@
#pragma once
#include <pd/common/common.hpp>
#include <pd/maths/vec.hpp>
namespace PD {
class Hid : public SmartCtor<Hid> {
public:
enum Key : u32 {
No = 0,
A = 1 << 0,
B = 1 << 1,
X = 1 << 2,
Y = 1 << 3,
Start = 1 << 4,
Select = 1 << 5,
L = 1 << 6,
R = 1 << 7,
DUp = 1 << 8,
DDown = 1 << 9,
DLeft = 1 << 10,
DRight = 1 << 11,
CPUp = 1 << 12,
CPDown = 1 << 13,
CPLeft = 1 << 14,
CPRight = 1 << 15,
CSUp = 1 << 16,
CSDown = 1 << 17,
CSLeft = 1 << 18,
CSRight = 1 << 19,
ZL = 1 << 20,
ZR = 1 << 21,
Touch = 1 << 22,
Up = DUp | CPUp,
Down = DDown | CPDown,
Left = DLeft | CPLeft,
Right = DRight | CPRight,
};
enum Event {
Event_Down,
Event_Held,
Event_Up,
};
Hid();
~Hid() {}
vec2 TouchPos() const { return touch[0]; }
vec2 TouchPosLast() const { return touch[1]; }
bool IsEvent(Event e, Key keys);
bool IsDown(Key keys) const { return key_events[0].at(Event_Down) & keys; }
bool IsHeld(Key keys) const { return key_events[0].at(Event_Held) & keys; }
bool IsUp(Key keys) const { return key_events[0].at(Event_Up) & keys; }
void Clear() {
for (int i = 0; i < 2; i++) {
key_events[i][Event_Down] = 0;
key_events[i][Event_Up] = 0;
key_events[i][Event_Held] = 0;
}
}
void Lock(bool v) {
if (v != locked) {
SwappyTable();
}
locked = v;
}
bool Locked() const { return locked; }
void Lock() {
if (!locked) {
SwappyTable();
}
locked = true;
}
void Unlock() {
if (locked) {
SwappyTable();
}
locked = false;
}
/// @brief Get the New Keystates etc
/// @note WOW not using the deltatime
void Update();
private:
void SwappyTable();
/// Using 2 Touch positions for current and last frame
vec2 touch[2];
bool locked = false;
std::unordered_map<Event, u32> key_events[2];
std::unordered_map<u32, u32> binds;
};
} // namespace PD

View File

@ -49,11 +49,11 @@ namespace LI {
class Rect {
public:
Rect() = default;
Rect(vec4 t, vec4 b) {
Rect(const vec4& t, const vec4& b) {
top = t;
bot = b;
}
Rect(vec2 tl, vec2 tr, vec2 bl, vec2 br) {
Rect(const vec2& tl, const vec2& tr, const vec2& bl, const vec2& br) {
top = vec4(tl, tr);
bot = vec4(bl, br);
}
@ -84,7 +84,7 @@ class Font : public SmartCtor<Font> {
return *this;
}
vec4 uv() const { return m_uv; }
Codepoint& uv(vec4 v) {
Codepoint& uv(const vec4& v) {
m_uv = v;
return *this;
}
@ -94,7 +94,7 @@ class Font : public SmartCtor<Font> {
return *this;
}
vec2 size() const { return m_size; }
Codepoint& size(vec2 v) {
Codepoint& size(const vec2& v) {
m_size = v;
return *this;
}
@ -134,7 +134,7 @@ class Font : public SmartCtor<Font> {
class Vertex {
public:
Vertex() {}
Vertex(vec2 p, vec2 u, u32 c) {
Vertex(const vec2& p, const vec2& u, u32 c) {
pos[0] = p[0];
pos[1] = p[1];
pos[2] = 0.f;
@ -143,18 +143,18 @@ class Vertex {
}
~Vertex() {}
Vertex& Pos(vec3 v) {
Vertex& Pos(const vec3& v) {
pos = v;
return *this;
}
// Lets support that as well
Vertex& Pos(vec2 v) {
Vertex& Pos(const vec2& v) {
pos[0] = v[0];
pos[1] = v[1];
pos[2] = 0.f;
return *this;
}
Vertex& Uv(vec2 v) {
Vertex& Uv(const vec2& v) {
uv = v;
return *this;
}
@ -179,6 +179,15 @@ class Command : public SmartCtor<Command> {
Command() {}
~Command() {}
Command(Command::Ref v) {
this->index = v->index;
this->index_buf = v->index_buf;
this->layer = v->layer;
this->mode = v->mode;
this->tex = v->tex;
this->vertex_buf = v->vertex_buf;
}
Command& Layer(int v) {
layer = v;
return *this;
@ -200,7 +209,7 @@ class Command : public SmartCtor<Command> {
Texture::Ref Tex() const { return tex; }
Command& PushVertex(Vertex v) {
Command& PushVertex(const Vertex& v) {
vertex_buf.push_back(v);
return *this;
}
@ -208,6 +217,10 @@ class Command : public SmartCtor<Command> {
const std::vector<u16>& IndexList() const { return index_buf; }
const std::vector<Vertex>& VertexList() const { return vertex_buf; }
/// ADVANCED ///
std::vector<u16>& IndexList() { return index_buf; }
std::vector<Vertex>& VertexList() { return vertex_buf; }
Command& PushIndex(u16 v) {
index_buf.push_back(vertex_buf.size() + v);
return *this;
@ -255,11 +268,74 @@ class TextBox {
bool optional;
std::string text; // TextWrap
};
class StaticObject : public SmartCtor<StaticObject> {
public:
StaticObject() {}
~StaticObject() {}
void PushCommand(Command::Ref v) { cmds.push_back(v); }
void ReCopy() {
cpy.clear();
for (auto it : cmds) {
cpy.push_back(Command::New(it));
}
}
void ReColorQuad(int idx, u32 col) {
if (idx > (int)cpy.size()) {
return;
}
for (auto& it : cpy[idx]->VertexList()) {
it.Color(col);
}
}
void MoveIt(vec2 off) {
for (auto& it : cpy) {
for (auto& jt : it->VertexList()) {
jt.pos += vec3(off, 0);
}
}
}
void ReColor(u32 col) {
for (auto& it : cpy) {
for (auto& jt : it->VertexList()) {
jt.Color(col);
}
}
}
void ReLayer(int base_layer) {
for (auto& it : cpy) {
it->Layer(it->Layer() + base_layer);
}
}
void ReIndex(int start) {
for (int i = 0; i < (int)cpy.size(); i++) {
cpy[i]->Index(start + i);
}
}
std::vector<Command::Ref>& List() {
if (cpy.size() != 0) {
return cpy;
}
return cmds;
}
private:
std::vector<Command::Ref> cpy;
std::vector<Command::Ref> cmds;
};
using RenderFlags = u32;
enum RenderFlags_ {
RenderFlags_None = 0,
RenderFlags_TMS = 1 << 0, ///< Text Map System
RenderFlags_LRS = 1 << 1, ///< Layer Render System
RenderFlags_AST = 1 << 2, ///< Auto Static Text
RenderFlags_Default = RenderFlags_TMS,
};
class Renderer : public SmartCtor<Renderer> {
@ -291,6 +367,13 @@ class Renderer : public SmartCtor<Renderer> {
void TextScale(float v) { text_size = v; }
void DefaultTextScale() { text_size = default_text_size; }
float TextScale() const { return text_size; }
void Layer(int v) { current_layer = v; }
int Layer() const { return current_layer; }
void Font(Font::Ref v) {
font = v;
font_update = true;
}
Font::Ref Font() const { return font; }
void UseTex(Texture::Ref v = nullptr) {
if (v == nullptr) {
@ -305,42 +388,43 @@ class Renderer : public SmartCtor<Renderer> {
/// @param size Size
/// @param color Color
/// @param uv UV Map
void DrawRect(vec2 pos, vec2 size, u32 color,
vec4 uv = vec4(0.f, 1.f, 1.f, 0.f));
void DrawRect(const vec2& pos, const vec2& size, u32 color,
const vec4& uv = vec4(0.f, 1.f, 1.f, 0.f));
/// @brief Draw a Solid Rect (uses white tex)
/// @note acts as a simplified Draw rect Wrapper
/// @param pos Position
/// @param size Size
/// @param color Color
void DrawRectSolid(vec2 pos, vec2 size, u32 color);
void DrawRectSolid(const vec2& pos, const vec2& size, u32 color);
/// @brief Render a Triangle
/// @param a Position Alpha
/// @param b Position Bravo
/// @param c Position Delta
/// @param color Color
/// @note Defaults to Solif Color
void DrawTriangle(vec2 a, vec2 b, vec2 c, u32 color);
void DrawTriangle(const vec2& a, const vec2& b, const vec2& c, u32 color);
/// @brief Draw a Circle (Supports Textures)
/// @param center_pos Center Position
/// @param r Radius
/// @param color Color
/// @param segments Segments to use
/// @note Textures could look a bit janky due to uv mapping
void DrawCircle(vec2 center_pos, float r, u32 color, int segments);
void DrawCircle(const vec2& center_pos, float r, u32 color, int segments);
/// @brief Draw a Line between to Positions
/// @param a Position Alpha
/// @param b Position Bravo
/// @param color Color
/// @param t Thickness
void DrawLine(vec2 a, vec2 b, u32 color, int t);
void DrawText(vec2 pos, u32 color, const std::string& text, u32 flags = 0,
vec2 ap = vec2());
void DrawLine(const vec2& a, const vec2& b, u32 color, int t);
void DrawText(const vec2& pos, u32 color, const std::string& text,
u32 flags = 0, const vec2& ap = vec2());
/// @brief Draw a Texture as 2D Image
/// @param pos Position
/// @param tex Texture reference
/// @param scale Scale (cause maybe wants to be resized)
/// @note Acts as a Simplified wrapper to DrawRect
void DrawImage(vec2 pos, Texture::Ref tex, vec2 scale = vec2(1.f));
void DrawImage(const vec2& pos, Texture::Ref tex,
const vec2& scale = vec2(1.f));
/// Debug STUFF
u32 Vertices() const { return vertices; }
@ -349,22 +433,28 @@ class Renderer : public SmartCtor<Renderer> {
u32 DrawCalls() const { return drawcalls; }
/// TOOLS ///
void RotateCorner(vec2& v, float s, float c);
Rect CreateRect(vec2 pos, vec2 size, float angle);
Rect CreateLine(vec2 a, vec2 b, int t);
bool InBox(vec2 pos, vec2 size, vec4 rect);
bool InBox(vec2 alpha, vec2 bravo, vec2 charlie, vec4 rect);
void OptiCommandList(std::vector<Command::Ref>& list);
static void RotateCorner(vec2& v, float s, float c);
static Rect CreateRect(const vec2& pos, const vec2& size, float angle);
static Rect CreateLine(const vec2& a, const vec2& b, int t);
static bool InBox(const vec2& pos, const vec2& size, const vec4& rect);
static bool InBox(const vec2& pos, const vec4& rect);
static bool InBox(const vec2& alpha, const vec2& bravo, const vec2& charlie,
const vec4& rect);
static void OptiCommandList(std::vector<Command::Ref>& list);
/// @brief Returns Viewport with xy
vec4 GetViewport();
/// @brief Push a Self Created command
void PushCommand(Command::Ref cmd) { draw_list[bottom].push_back(cmd); }
void PushCommand(Command::Ref cmd) {
cmd->Index(cmd_idx++); // Indexing
draw_list[bottom].push_back(cmd);
}
/// @brief Automatically sets up a command
void SetupCommand(Command::Ref cmd);
/// @brief Creates a default Quad Render Command
void QuadCommand(Command::Ref cmd, const Rect& quad, vec4 uv, u32 col);
void QuadCommand(Command::Ref cmd, const Rect& quad, const vec4& uv, u32 col);
/// @brief Create a Default Triangle
void TriangleCommand(Command::Ref cmd, vec2 a, vec2 b, vec2 c, u32 col);
void TriangleCommand(Command::Ref cmd, const vec2& a, const vec2& b,
const vec2& c, u32 col);
/// @brief Create List of a Text Commands
/// @param cmds Link to a command List
/// @param pos Position
@ -373,8 +463,8 @@ class Renderer : public SmartCtor<Renderer> {
/// @param flags Flags
/// @param box (Size for wrapping / Offset for Centered Text)
/// @note Funktion macht noch faxxen (Text nicht sichtbar)
void TextCommand(std::vector<Command::Ref>& cmds, vec2 pos, u32 color,
const std::string& text, LITextFlags flags, vec2 box);
void TextCommand(std::vector<Command::Ref>& cmds, const vec2& pos, u32 color,
const std::string& text, LITextFlags flags, const vec2& box);
vec2 GetTextDimensions(const std::string& text);
private:

138
include/pd/maths/tween.hpp Normal file
View File

@ -0,0 +1,138 @@
#pragma once
#include <pd/maths/vec.hpp>
namespace PD {
template <typename T>
class Tween {
public:
enum Effect {
Linear,
EaseInQuad,
EaseOutQuad,
EaseInOutQuad,
EaseInCubic,
EaseOutCubic,
EaseInOutCubic,
EaseInSine,
EaseOutSine,
EaseInOutSine,
};
Tween() {}
~Tween() {}
void Update(float delta) {
time += delta / 1000.f;
if (time > tend) {
finished = true;
time = tend;
}
}
bool IsFinished() const { return finished; }
Tween& Finish() {
time = tend;
finished = true;
return *this;
}
Tween& From(const T& start) {
Reset();
this->start = start;
return *this;
}
Tween& To(const T& end) {
Reset();
this->end = end;
return *this;
}
Tween& In(float seconds) {
Reset();
tend = seconds;
return *this;
}
Tween& As(const Effect& e) {
effect = e;
return *this;
}
Tween& Reset() {
finished = false;
time = 0.f;
return *this;
}
/// @brief Probably usefull for fading colors by animation
/// Used to create this caus dont wanted to create a
/// fade effect fpr keyboard without having to Tween functions
/// @return
float Progress() const { return time / tend; }
Tween& Swap() {
T temp = start;
start = end;
end = temp;
return *this;
}
operator T() {
float t = 0.f;
switch (effect) {
case EaseInQuad:
t = time / tend;
return (end - start) * t * t + start;
break;
case EaseOutQuad:
t = time / tend;
return -(end - start) * t * (t - 2) + start;
break;
case EaseInOutQuad:
t = time / (tend / 2);
if (t < 1) return (end - start) / 2 * t * t + start;
t--;
return -(end - start) / 2 * (t * (t - 2) - 1) + start;
break;
case EaseInCubic:
t = time / tend;
return (end - start) * t * t * t + start;
break;
case EaseOutCubic:
t = time / tend;
t--;
return (end - start) * (t * t * t + 1) + start;
break;
// case EaseInOutCubic:
// t = time / (tend / 2);
// if (t < 1) return (end - start) / 2 * t * t * t + start;
// t--;
// return (end - start) / 2 * (t * t * t * 2) + start;
// break;
case EaseInSine:
return -(end - start) * cos(time / tend * (M_PI / 2)) + (end - start) +
start;
break;
case EaseOutSine:
return (end - start) * sin(time / tend * (M_PI / 2)) + start;
break;
case EaseInOutSine:
return -(end - start) / 2 * (cos(M_PI * time / tend) - 1) + start;
break;
default: // Linear
return (end - start) * (time / tend) + start;
break;
}
}
private:
Effect effect;
float time = 0.f;
// Defaulting to one to prevent div zero
// without a safetey check
// not implementing one cause if the user is
// Writing a In(0.f) its their fault
float tend = 1.f;
T start;
T end;
bool finished = false;
};
} // namespace PD

View File

@ -332,6 +332,20 @@ struct vec4 {
v[3] = i;
}
vec4(const vec3 &xyz, float w) {
v[0] = xyz[0];
v[1] = xyz[1];
v[2] = xyz[2];
v[3] = w;
}
vec4(float x, const vec3 &yzw) {
v[0] = x;
v[1] = yzw[1];
v[2] = yzw[2];
v[3] = yzw[3];
}
// Operators
// Add
vec4 &operator+=(const vec4 &i) {
@ -371,7 +385,7 @@ struct vec4 {
}
// Base
vec3 operator-() const { return vec3(-v[0], -v[1], -v[2]); }
vec4 operator-() const { return vec4(-v[0], -v[1], -v[2], -v[3]); }
float operator[](int i) const { return v[i]; }
float &operator[](int i) { return v[i]; }
@ -380,7 +394,7 @@ struct vec4 {
return v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3];
}
// Vec2 Acess
// Vec Acess
float x() const { return v[0]; }
float &x() { return v[0]; }
float y() const { return v[1]; }
@ -389,6 +403,10 @@ struct vec4 {
float &z() { return v[2]; }
float w() const { return v[3]; }
float &w() { return v[3]; }
vec2 xy() const { return vec2(v[0], v[1]); }
vec2 zw() const { return vec2(v[2], v[3]); }
vec3 xyz() const { return vec3(v[0], v[1], v[2]); }
vec3 yzw() const { return vec3(v[1], v[2], v[3]); }
// Quaternion Acess
float r() const { return v[0]; }
float &r() { return v[0]; }
@ -398,6 +416,10 @@ struct vec4 {
float &j() { return v[2]; }
float i() const { return v[3]; }
float &i() { return v[3]; }
vec2 rk() const { return vec2(v[0], v[1]); }
vec2 ji() const { return vec2(v[2], v[3]); }
vec3 rkj() const { return vec3(v[0], v[1], v[2]); }
vec3 kji() const { return vec3(v[1], v[2], v[3]); }
// Internal Values
float v[4];
};

View File

@ -0,0 +1,105 @@
#pragma once
#include <pd/controls/hid.hpp>
#include <pd/maths/tween.hpp>
#include <pd/overlays/overlay.hpp>
namespace PD {
void DumpLayout(const std::string& path);
/// Keyboard class
/// @brief needs to be pushed with text and State reference as Overlay
/// to communicate with it
/// @note Hardcoded Rendering to get maximum Rendering Performance
class Keyboard : public Overlay {
public:
enum KeyOperation {
AppendSelf = 0,
Shift = 1,
Backspace = 2,
Enter = 3,
OpCancel = 4,
OpConfirm = 5,
Tab = 6,
Caps = 7,
Space = 8,
Op1 = 9,
Op2 = 10,
};
enum Type {
Default,
Numpad,
Password,
};
enum State {
None,
Cancel,
Confirm,
};
using Flags = u32;
enum Flags_ {
Flags_None = 0,
Flags_BlendTop = 1 << 0,
Flags_BlendBottom = 1 << 1,
Flags_LockControls = 1 << 2,
Flags_Default = Flags_BlendBottom | Flags_BlendTop | Flags_LockControls,
};
Keyboard(std::string& text, State& state, const std::string& hint = "",
Type type = Default, Flags flags = Flags_Default) {
too++;
if (too > 1) {
Kill();
return;
}
this->text = &text;
this->copy = text;
this->state = &state;
this->hint = hint;
this->type = type;
this->flags = flags;
this->raw_sel = -1;
flymgr.From(vec2(0, 240)).To(vec2(0, 115)).In(0.3f).As(flymgr.EaseInQuad);
chflymgr.From(vec2(-320, 0)).To(vec2(-320, 0)).In(0.1f).As(chflymgr.Linear);
}
~Keyboard() { too--; }
void Update(float delta, LI::Renderer::Ref ren, Hid::Ref inp) override;
void Rem() {
rem = true;
flymgr.From(vec2(0, 115)).To(vec2(0, 240)).In(0.2f).As(flymgr.EaseOutQuad);
}
private:
void LoadTheKeys(LI::Renderer::Ref ren);
void Movement(Hid::Ref inp);
void MoveSelector();
void DoOperation(KeyOperation op, const std::string& kname);
void RecolorBy(KeyOperation op, u32 color, int cm);
void InputOpBind(Hid::Key k, KeyOperation op, Hid::Ref inp, int cm);
std::string* text;
std::string copy;
std::string hint;
State* state;
Type type;
Flags flags;
int mode = 0; // def, caps, shift
// Stands for The Only One
static int too;
Tween<vec2> selector;
Tween<vec2> sel_szs;
vec2 cselszs;
int raw_sel;
// Performance Optimisation
LI::StaticObject::Ref keys[3];
bool keys_loadet = false;
// Some Animation
bool rem = false;
/// Probably a float would've done the job as well ;)
Tween<vec2> flymgr;
Tween<vec2> chflymgr;
bool show_help = true;
};
} // namespace PD

View File

@ -0,0 +1,45 @@
#pragma once
#include <pd/graphics/lithium.hpp>
#include <pd/maths/color.hpp>
#include <pd/maths/tween.hpp>
namespace PD {
class MessageMgr : public PD::SmartCtor<MessageMgr> {
public:
class Container : public PD::SmartCtor<Container> {
public:
Container(const std::string& title, const std::string& msg);
~Container() {}
void Render(PD::LI::Renderer::Ref ren);
void Update(int slot, float delta);
void FlyIn();
void ToBeMoved(int slot);
void ToBeRemoved();
bool ShouldBeRemoved() const { return (tbr && pos.IsFinished()) || kill; }
private:
PD::Color col_bg; // Background Color
PD::Color col_text; // Text Color
float lifetime = 0.f; // LifeTime
PD::Tween<vec2> pos; // Position effect
std::string title; // Title
std::string msg; // Message
vec2 size; // Size of the Background
bool tbr = false; // To be Removed ?
bool kill = false; // Instant Kill
int s = 0; // Slot
};
MessageMgr(PD::LI::Renderer::Ref r) { ren = r; }
~MessageMgr() {}
void Push(const std::string& title, const std::string& text);
void Update(float delta);
private:
std::vector<Container::Ref> msgs;
PD::LI::Renderer::Ref ren;
};
} // namespace PD

View File

@ -0,0 +1,23 @@
#pragma once
#include <pd/common/common.hpp>
#include <pd/controls/hid.hpp>
#include <pd/graphics/lithium.hpp>
namespace PD {
class Overlay : public SmartCtor<Overlay> {
public:
Overlay() {}
virtual ~Overlay() {}
virtual void Update(float delta, LI::Renderer::Ref ren, Hid::Ref inp) = 0;
bool IsKilled() const { return kill; }
protected:
void Kill() { kill = true; }
private:
bool kill = false;
};
} // namespace PD

View File

@ -0,0 +1,24 @@
#pragma once
#include <pd/controls/hid.hpp>
#include <pd/graphics/lithium.hpp>
#include <pd/overlays/overlay.hpp>
namespace PD {
class OverlayMgr : public SmartCtor<OverlayMgr> {
public:
OverlayMgr(LI::Renderer::Ref ren, Hid::Ref inp) {
this->ren = ren;
this->inp = inp;
}
~OverlayMgr() { overlays.clear(); }
void Push(Overlay::Ref overlay);
void Update(float delta);
private:
std::vector<Overlay::Ref> overlays;
LI::Renderer::Ref ren;
Hid::Ref inp;
};
} // namespace PD

View File

@ -0,0 +1,31 @@
#pragma once
#include <pd/overlays/overlay.hpp>
#include <pd/controls/hid.hpp>
namespace PD {
class Performance : public Overlay {
public:
Performance(bool& skill, bool& screen) {
too++;
if (too > 1) {
Kill();
return;
}
this->skill = &skill;
*this->skill = false; // Make sure its false
this->screen = &screen;
}
~Performance() { too--; }
void Update(float delta, LI::Renderer::Ref ren, Hid::Ref inp) override;
private:
void Line(vec2& pos, const std::string& text, LI::Renderer::Ref ren);
// Trace String Average
std::string TSA(const std::string& id);
// Described in Keyboard
static int too;
bool *skill, *screen;
};
} // namespace PD

View File

@ -0,0 +1,38 @@
#pragma once
#include <pd/maths/tween.hpp>
#include <pd/overlays/overlay.hpp>
#include <pd/controls/hid.hpp>
namespace PD {
class SettingsMenu : public Overlay {
public:
SettingsMenu() {
too++;
if (too > 1) {
Kill();
return;
}
flymgr.From(vec2(0, 240)).To(vec2(0, 115)).In(0.3f).As(flymgr.EaseInQuad);
}
~SettingsMenu() { too--; }
void Update(float delta, LI::Renderer::Ref ren, Hid::Ref inp) override;
void Rem() {
rem = true;
flymgr.From(vec2(0, 115)).To(vec2(0, 240)).In(0.2f).As(flymgr.EaseOutQuad);
}
private:
/// Section is used to determinate what
/// should be displayed on the top screen
int section = 0;
// Stands for The Only One
static int too;
// Some Animation
bool rem = false;
Tween<vec2> flymgr;
};
} // namespace PD

View File

@ -0,0 +1,33 @@
#pragma once
#include <pd/common/common.hpp>
#include <pd/controls/hid.hpp>
namespace PD {
namespace GamePadIcons {
enum ID {
A,
B,
X,
Y,
L,
R,
Dpad,
Start,
Select,
Home,
Steps,
PlayCoin,
AnalogStick,
Power3DS,
DpadUp,
DpadDown,
DpadLeft,
DpadRight,
DpadHorizontal,
DpadVertical,
};
std::string GetIcon(ID id);
std::string GetIcon(Hid::Key key);
} // namespace GamePadIcons
} // namespace PD

View File

@ -28,10 +28,11 @@ SOFTWARE.
#include <pd/ui7/theme.hpp>
namespace PD {
class UI7DrawList : SmartCtor<UI7DrawList> {
namespace UI7 {
class DrawList : public SmartCtor<DrawList> {
public:
UI7DrawList(LI::Renderer::Ref r) { ren = r; }
~UI7DrawList() = default;
DrawList(LI::Renderer::Ref r) { ren = r; }
~DrawList() = default;
void AddRectangle(vec2 pos, vec2 szs, const UI7Color& clr);
void AddTriangle(vec2 pos0, vec2 pos1, vec2 pos2, const UI7Color& clr);
@ -50,4 +51,5 @@ class UI7DrawList : SmartCtor<UI7DrawList> {
LI::Renderer::Ref ren;
std::vector<LI::Command::Ref> commands;
};
} // namespace UI7
} // namespace PD

View File

@ -31,5 +31,6 @@ enum UI7MenuFlags_ {
UI7MenuFlags_CenterTitle = 1 << 1,
UI7MenuFlags_HzScrolling = 1 << 2,
UI7MenuFlags_VtScrolling = 1 << 3,
UI7MenuFlags_NoBackground = 1 << 4,
UI7MenuFlags_Scrolling = UI7MenuFlags_HzScrolling | UI7MenuFlags_VtScrolling,
};

19
include/pd/ui7/id.hpp Normal file
View File

@ -0,0 +1,19 @@
#pragma once
#include <pd/common/common.hpp>
#include <pd/common/strings.hpp>
namespace PD {
namespace UI7 {
class ID {
public:
ID(const std::string& text) { id = PD::Strings::FastHash(text); }
~ID() {}
operator u32() const { return id; }
private:
u32 id;
};
} // namespace UI7
} // namespace PD

70
include/pd/ui7/menu.hpp Normal file
View File

@ -0,0 +1,70 @@
#pragma once
/*
MIT License
Copyright (c) 2024 René Amthor (tobid7)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include <pd/ui7/drawlist.hpp>
namespace PD {
namespace UI7 {
class Menu : public SmartCtor<Menu> {
public:
Menu(u32 id) {
this->id = id;
scrolling[0] = false;
scrolling[1] = false;
scrollbar[0] = false;
scrollbar[1] = false;
scroll_allowed[0] = false;
scroll_allowed[1] = false;
};
~Menu() {};
private:
u32 id;
vec2 cursor;
vec2 bcursor;
vec2 slcursor;
vec4 view_area;
vec2 scrolling_off;
bool scrolling[2];
vec2 scroll_mod;
float tbh;
bool scrollbar[2];
bool scroll_allowed[2];
bool has_touch;
Menu::Ref submenu;
// DrawLists
DrawList::Ref back;
DrawList::Ref main;
DrawList::Ref front;
vec2 max;
vec2 mouse;
vec2 bslpos;
vec2 last_size;
};
} // namespace UI7
} // namespace PD

View File

@ -25,14 +25,96 @@ SOFTWARE.
#include <pd/common/common.hpp>
using UI7Color = unsigned int;
using UI7Color = u32;
enum UI7Color_ {
UI7Color_Background,
UI7Color_Button,
UI7Color_ButtonDead,
UI7Color_ButtonActive,
UI7Color_ButtonDisabled,
UI7Color_Text,
UI7Color_TextDead,
UI7Color_Header,
UI7Color_Selector,
UI7Color_Checkmark,
UI7Color_FrameBackground,
UI7Color_FragmeBackgroundHovered,
UI7Color_Progressbar,
UI7Color_ListEven,
UI7Color_ListOdd,
};
namespace PD {
namespace UI7 {
/// @brief Theme Class
class Theme {
public:
public:
Theme() { Default(*this); }
~Theme() {}
/// @brief Simple static Loader for the Default Theme
/// @param theme Theme Reference
static void Default(Theme& theme);
/// @brief Revert the last Color Change
Theme& Pop() {
theme[changes[changes.size() - 1].first] =
changes[changes.size() - 1].second;
changes.pop_back();
return *this;
}
/// @brief Revert the last color Change done for a specific color
/// @param c Color to revert change from
Theme& Pop(UI7Color c) {
for (size_t i = changes.size() - 1; i > 0; i--) {
if (changes[i].first == c) {
theme[c] = changes[i].second;
changes.erase(changes.begin() + i);
break;
}
}
return *this;
}
/// @brief Change a Color
/// @param tc Color Identifier
/// @param color Color to change to
Theme& Change(UI7Color tc, u32 color) {
if (theme.find(tc) == theme.end()) {
return *this;
}
changes.push_back(std::make_pair(tc, theme[tc]));
theme[tc] = color;
return *this;
}
/// @brief Get the Color of a Color ReferenceID
/// @param c ReferenceID
u32 Get(UI7Color c) const {
auto e = theme.find(c);
if (e == theme.end()) {
return 0x00000000;
}
return e->second;
}
/// @brief Operator wrapper for get
/// @param c Color ReferenceID
u32 operator[](UI7Color c) const { return Get(c); }
/// @brief Change but just sets [can implement completly new ids]
/// @param tc Color ID (Can be self creeated ones as well)
/// @param clr Color it should be set to
void Set(UI7Color tc, u32 clr) { theme[tc] = clr; }
private:
std::unordered_map<u32, u32> theme;
std::vector<std::pair<UI7Color, u32>> changes;
};
} // namespace UI7
/// Using UI7Color as a Class to be able to
/// define it as struct as well as using it as enum
class UI7Color {

View File

@ -25,13 +25,19 @@ SOFTWARE.
#include <pd/ui7/drawlist.hpp>
#include <pd/ui7/flags.hpp>
#include <pd/ui7/id.hpp>
#include <pd/ui7/menu.hpp>
#include <pd/ui7/theme.hpp>
#include <unordered_map>
namespace PD {
class UI7Context : SmartCtor<UI7Context> {
namespace UI7 {
class Context : public SmartCtor<Context> {
public:
UI7Context() {}
~UI7Context() {}
Context() {}
~Context() {}
void Update(float delta);
private:
// Timing
@ -41,13 +47,15 @@ class UI7Context : SmartCtor<UI7Context> {
// Context
bool in_menu;
// Debug
bool debug;
bool debugging;
// Menu Handlers
std::unordered_map<u32, Menu::Ref> menus;
Menu::Ref current;
// Context DrawList
UI7DrawList::Ref debug;
UI7DrawList::Ref front;
UI7DrawList::Ref back;
DrawList::Ref debug;
DrawList::Ref front;
DrawList::Ref back;
// Promt Handler
};
} // namespace UI7
} // namespace PD