# 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:
parent
d815bb5674
commit
b4a4b6a426
@ -32,6 +32,8 @@ set(SRC_FILES
|
||||
source/common/sys.cpp
|
||||
source/common/lang.cpp
|
||||
source/common/error.cpp
|
||||
# Controls
|
||||
source/controls/hid.cpp
|
||||
# Maths
|
||||
source/maths/color.cpp
|
||||
source/maths/bit_util.cpp
|
||||
@ -40,6 +42,15 @@ set(SRC_FILES
|
||||
source/graphics/texture.cpp
|
||||
source/graphics/li7_shader.cpp
|
||||
source/graphics/lithium.cpp
|
||||
# Overlays
|
||||
source/overlays/message_mgr.cpp
|
||||
source/overlays/overlay_mgr.cpp
|
||||
source/overlays/keyboard.cpp
|
||||
source/overlays/performance.cpp
|
||||
# Tools
|
||||
source/tools/gamepad_icons.cpp
|
||||
# UI7
|
||||
source/ui7/drawlist.cpp
|
||||
# External
|
||||
source/external/stb.cpp
|
||||
)
|
||||
@ -61,7 +72,7 @@ target_compile_definitions(${TARGET_NAME} PUBLIC
|
||||
)
|
||||
|
||||
add_executable(test test/main.cpp)
|
||||
target_include_directories(test PUBLIC include)
|
||||
target_include_directories(test PUBLIC include test)
|
||||
target_link_directories(test PUBLIC ${CMAKE_BINARY_DIR})
|
||||
target_link_libraries(test PUBLIC palladium citro3d ctru m)
|
||||
# Generate 3DSX
|
||||
|
@ -1,5 +1,7 @@
|
||||
# Palladium
|
||||
|
||||
**Framework / Engine to create Homebrew Apps / Games**
|
||||
|
||||
## Build types
|
||||
|
||||
```bash
|
||||
|
@ -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;
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -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
|
95
include/pd/controls/hid.hpp
Normal file
95
include/pd/controls/hid.hpp
Normal 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
|
@ -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
138
include/pd/maths/tween.hpp
Normal 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
|
@ -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];
|
||||
};
|
||||
|
105
include/pd/overlays/keyboard.hpp
Normal file
105
include/pd/overlays/keyboard.hpp
Normal 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
|
45
include/pd/overlays/message_mgr.hpp
Normal file
45
include/pd/overlays/message_mgr.hpp
Normal 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
|
23
include/pd/overlays/overlay.hpp
Normal file
23
include/pd/overlays/overlay.hpp
Normal 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
|
24
include/pd/overlays/overlay_mgr.hpp
Normal file
24
include/pd/overlays/overlay_mgr.hpp
Normal 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
|
31
include/pd/overlays/performance.hpp
Normal file
31
include/pd/overlays/performance.hpp
Normal 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
|
38
include/pd/overlays/settings.hpp
Normal file
38
include/pd/overlays/settings.hpp
Normal 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
|
33
include/pd/tools/gamepad_icons.hpp
Normal file
33
include/pd/tools/gamepad_icons.hpp
Normal 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
|
@ -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
|
@ -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
19
include/pd/ui7/id.hpp
Normal 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
70
include/pd/ui7/menu.hpp
Normal 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
|
@ -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 {
|
||||
|
@ -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
|
@ -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();
|
||||
|
@ -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
78
source/controls/hid.cpp
Normal 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
|
@ -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);
|
||||
}
|
||||
|
||||
|
549
source/overlays/keyboard.cpp
Normal file
549
source/overlays/keyboard.cpp
Normal 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
|
126
source/overlays/message_mgr.cpp
Normal file
126
source/overlays/message_mgr.cpp
Normal 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
|
14
source/overlays/overlay_mgr.cpp
Normal file
14
source/overlays/overlay_mgr.cpp
Normal 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
|
46
source/overlays/performance.cpp
Normal file
46
source/overlays/performance.cpp
Normal 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
|
57
source/tools/gamepad_icons.cpp
Normal file
57
source/tools/gamepad_icons.cpp
Normal 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
|
@ -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
24
source/ui7/theme.cpp
Normal 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
|
@ -25,6 +25,7 @@ SOFTWARE.
|
||||
|
||||
#include <ctime>
|
||||
#include <pd.hpp>
|
||||
#include <pd/maths/tween.hpp>
|
||||
|
||||
using vec2 = PD::vec2;
|
||||
using vec3 = PD::vec3;
|
||||
@ -37,37 +38,36 @@ class Test : public PD::App {
|
||||
|
||||
void Init() override {
|
||||
test = PD::Texture::New("romfs:/icon.png");
|
||||
cpu = PD::TimeStats::New(100);
|
||||
Overlays()->Push(PD::New<PD::Performance>(dbg, dbg_screen));
|
||||
font = PD::LI::Font::New();
|
||||
// font->LoadSystemFont();
|
||||
font->LoadTTF("romfs:/ComicNeue.ttf", 32);
|
||||
Renderer()->Font(font);
|
||||
ui7 = PD::UI7::Context::New();
|
||||
}
|
||||
|
||||
bool MainLoop(unsigned long long delta, float time) override {
|
||||
cpu->Add(C3D_GetProcessingTime());
|
||||
hidScanInput();
|
||||
bool MainLoop(float delta, float time) override {
|
||||
DrawFancyBG(time);
|
||||
Renderer()->TextScale(0.6f);
|
||||
vec2 start(5, 100);
|
||||
DebugText(start, "FPS: " + std::to_string((int)GetFps()));
|
||||
DebugText(start, "DrawCalls: " + std::to_string(Renderer()->DrawCalls()));
|
||||
DebugText(start, "DrawCommands: " + std::to_string(Renderer()->Commands()));
|
||||
DebugText(start, "Vertices: " + std::to_string(Renderer()->Vertices()));
|
||||
DebugText(start, "Indices: " + std::to_string(Renderer()->Indices()));
|
||||
DebugText(start, "Ren [AVG]: " + PD::Strings::FormatNanos(
|
||||
PD::Sys::GetTraceRef("LI_RenderAll")
|
||||
->GetProtocol()
|
||||
->GetAverage()));
|
||||
DebugText(start, "App [AVG]: " + PD::Strings::FormatNanos(
|
||||
PD::Sys::GetTraceRef("App_MainLoop")
|
||||
->GetProtocol()
|
||||
->GetAverage()));
|
||||
Renderer()->DefaultTextScale();
|
||||
Renderer()->OnScreen(PD::Screen::Bottom);
|
||||
Renderer()->DrawRectSolid(0, vec2(320, 240), PD::Color("#222222"));
|
||||
Renderer()->UseTex(test);
|
||||
Renderer()->DrawImage(vec2(130, 90), test);
|
||||
Renderer()->Layer(Renderer()->Layer() + 1);
|
||||
Renderer()->DrawImage(
|
||||
Renderer()->GetViewport().zw() * 0.5 - test->GetSize() * 0.5, test);
|
||||
Renderer()->DrawText(5, 0xffffffff, "Hello World!", LITextFlags_None);
|
||||
if (hidKeysDown() & KEY_START) {
|
||||
if (Input()->IsDown(PD::Hid::Start)) {
|
||||
return false;
|
||||
}
|
||||
if (Input()->IsDown(Input()->A)) {
|
||||
Overlays()->Push(PD::New<PD::Performance>(dbg, dbg_screen));
|
||||
Messages()->Push("Test", "Oder SO");
|
||||
// what.To(vec2(5, 200)).From(vec2(-100,
|
||||
// 200)).In(0.5).As(what.EaseInQuad);
|
||||
}
|
||||
if (Input()->IsUp(Input()->B)) {
|
||||
Overlays()->Push(PD::New<PD::Keyboard>(text, state));
|
||||
// what.To(vec2(5, 180)).From(vec2(5, 200)).In(0.5).As(what.EaseOutQuad);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -97,16 +97,13 @@ class Test : public PD::App {
|
||||
.36f + .38f * color_effect));
|
||||
}
|
||||
|
||||
void DebugText(vec2& pos, const std::string& text) {
|
||||
auto tbs = Renderer()->GetTextDimensions(text);
|
||||
Renderer()->DrawRectSolid(pos, tbs, 0xaa000000);
|
||||
Renderer()->DrawText(pos, 0xffff00ff, text);
|
||||
pos[1] += tbs[1]; // Auto set new pos
|
||||
}
|
||||
|
||||
private:
|
||||
PD::Texture::Ref test;
|
||||
PD::TimeStats::Ref cpu;
|
||||
bool dbg = false, dbg_screen = false;
|
||||
std::string text;
|
||||
PD::Keyboard::State state;
|
||||
PD::UI7::Context::Ref ui7;
|
||||
PD::LI::Font::Ref font;
|
||||
};
|
||||
|
||||
int main() {
|
||||
|
Loading…
Reference in New Issue
Block a user