Readd font support (not workign yet)
This commit is contained in:
+3
-2
@@ -46,9 +46,10 @@ set(PD_SOURCES
|
||||
source/drivers/gfx.cpp
|
||||
|
||||
# Lithium
|
||||
source/lithium/pools.cpp
|
||||
source/lithium/math.cpp
|
||||
source/lithium/drawlist.cpp
|
||||
source/lithium/font.cpp
|
||||
source/lithium/math.cpp
|
||||
source/lithium/pools.cpp
|
||||
)
|
||||
|
||||
if(${PD_BUILD_SHARED})
|
||||
|
||||
@@ -119,6 +119,7 @@ void GfxCitro3D::SysInit() {
|
||||
if (impl) return;
|
||||
PDLOG("GfxCitro3D::SysInit();");
|
||||
impl = new Impl();
|
||||
Flags |= PDBackendFlags_FlipUV_Y;
|
||||
impl->pShaderRaw = Pica::AssembleCode(LIShaderCTR);
|
||||
impl->pCode = DVLB_ParseFile((uint32_t*)impl->pShaderRaw.data(),
|
||||
impl->pShaderRaw.size());
|
||||
|
||||
@@ -149,7 +149,7 @@ class U8Iterator {
|
||||
}
|
||||
|
||||
bool PeekNext32(u32& ret) {
|
||||
// if ((ptr + 1) == 0 || *(ptr + 1) == 0) return false;
|
||||
if (ptr == nullptr || *(ptr + 1) == 0) return false;
|
||||
u8 c = *ptr;
|
||||
if (c < 0x80) {
|
||||
ret = c;
|
||||
|
||||
@@ -40,6 +40,7 @@ class PD_API GfxDriver : public DriverInterface {
|
||||
virtual void DeleteTexture(const Li::Texture& tex) {}
|
||||
virtual void Draw(const Pool<Li::Command>& commands) {}
|
||||
Li::Texture::Ptr GetWhiteTexture() { return &pWhite; }
|
||||
PDBackendFlags GetFlags() { return Flags; }
|
||||
|
||||
protected:
|
||||
virtual void SysDeinit() {}
|
||||
@@ -62,6 +63,7 @@ class PD_API GfxDriver : public DriverInterface {
|
||||
ivec2 ViewPort;
|
||||
std::unordered_map<TextureID, Li::Texture> pTextureRegestry;
|
||||
Li::Texture pWhite;
|
||||
PDBackendFlags Flags = 0;
|
||||
};
|
||||
|
||||
struct DefaultGfxConfig {
|
||||
@@ -166,6 +168,8 @@ class PD_API Gfx {
|
||||
return driver->GetWhiteTexture();
|
||||
}
|
||||
|
||||
static PDBackendFlags GetFlags() { return driver->GetFlags(); }
|
||||
|
||||
static const char* GetDriverName() { return driver->GetName(); }
|
||||
|
||||
private:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <pd/lithium/command.hpp>
|
||||
#include <pd/lithium/font.hpp>
|
||||
#include <pd/lithium/texture.hpp>
|
||||
|
||||
using LiPathRectFlags = PD::u32;
|
||||
@@ -27,18 +28,6 @@ enum LiDrawFlags_ : PD::u32 {
|
||||
LiDrawFlags_Close = 1 << 0,
|
||||
};
|
||||
|
||||
using LiTextFlags = PD::u32;
|
||||
enum LiTextFlags_ : PD::u32 {
|
||||
LiTextFlags_None = 0, ///< Do nothing
|
||||
LiTextFlags_AlignRight = 1 << 0, ///< Align Right of position
|
||||
LiTextFlags_AlignMid = 1 << 1, ///< Align in the middle of pos and box
|
||||
LiTextFlags_Shaddow = 1 << 2, ///< Draws the text twice to create shaddow
|
||||
LiTextFlags_Wrap = 1 << 3, ///< Wrap Text: May be runs better with TMS
|
||||
LiTextFlags_Short = 1 << 4, ///< Short Text: May be runs better with TMS
|
||||
LiTextFlags_Scroll = 1 << 5, ///< Not implemented [scoll text if to long]
|
||||
LiTextFlags_NoOOS = 1 << 6, ///< No Out of Screen Rendering
|
||||
};
|
||||
|
||||
namespace PD {
|
||||
namespace Li {
|
||||
class PD_API Drawlist {
|
||||
@@ -78,6 +67,10 @@ class PD_API Drawlist {
|
||||
void BindTexture(const Texture& tex);
|
||||
void UnbindTexture() { pCurrentTexture = Texture(); }
|
||||
|
||||
/** Font Handling */
|
||||
void SetFont(Font* font) { pFont = font; }
|
||||
void SetFontscale(float fontscale = 1.f) { pFontScale = fontscale; }
|
||||
|
||||
/** Data geters */
|
||||
const Pool<Command>& Data() const { return pCommands; }
|
||||
operator const Pool<Command>&() const { return pCommands; }
|
||||
@@ -111,6 +104,8 @@ class PD_API Drawlist {
|
||||
Pool<fvec2> pPath;
|
||||
Pool<Vertex> pVertices;
|
||||
Pool<u16> pIndices;
|
||||
Font* pFont = nullptr;
|
||||
float pFontScale = 1.f;
|
||||
};
|
||||
} // namespace Li
|
||||
} // namespace PD
|
||||
@@ -0,0 +1,103 @@
|
||||
#pragma once
|
||||
|
||||
#include <pd/lithium/texture.hpp>
|
||||
|
||||
using LiTextFlags = PD::u32;
|
||||
enum LiTextFlags_ : PD::u32 {
|
||||
LiTextFlags_None = 0, ///< Do nothing
|
||||
LiTextFlags_AlignRight = 1 << 0, ///< Align Right of position
|
||||
LiTextFlags_AlignMid = 1 << 1, ///< Align in the middle of pos and box
|
||||
LiTextFlags_Shaddow = 1 << 2, ///< Draws the text twice to create shaddow
|
||||
LiTextFlags_Wrap = 1 << 3, ///< Wrap Text: May be runs better with TMS
|
||||
LiTextFlags_Short = 1 << 4, ///< Short Text: May be runs better with TMS
|
||||
LiTextFlags_Scroll = 1 << 5, ///< Not implemented [scoll text if to long]
|
||||
LiTextFlags_NoOOS = 1 << 6, ///< No Out of Screen Rendering
|
||||
};
|
||||
|
||||
namespace PD {
|
||||
namespace Li {
|
||||
class Drawlist;
|
||||
class PD_API Font {
|
||||
public:
|
||||
struct Codepoint {
|
||||
u32 pCodepoint;
|
||||
fvec4 SimpleUV;
|
||||
size_t Tex;
|
||||
fvec2 Size;
|
||||
float Offset = 0.f;
|
||||
bool pInvalid;
|
||||
};
|
||||
Font() {}
|
||||
~Font() {}
|
||||
|
||||
/**
|
||||
* Load a TTF File
|
||||
* @param path Path to the TTF file
|
||||
* @param px_height Pixelheight of the codepoints (limit by 64)
|
||||
*/
|
||||
void LoadTTF(const std::string& path, int px_height = 32);
|
||||
/**
|
||||
* Load a TTF File from Memory
|
||||
* @param data File data
|
||||
* @param px_height Pixelheight of the codepoints (limit by 64)
|
||||
*/
|
||||
void LoadTTF(const std::vector<u8>& data, int px_height = 32);
|
||||
/**
|
||||
* Function that loads a default integrated font...
|
||||
* This will only work if PD_LI_INCLUDE_FONTS was set
|
||||
* on lithium build cause otherwise the font data is not included
|
||||
*/
|
||||
void LoadDefaultFont(int id = 0, int pixel_height = 32);
|
||||
/**
|
||||
* Getter for Codepoint reference
|
||||
* @return codepoint dataholder reference
|
||||
*/
|
||||
Codepoint& GetCodepoint(u32 c);
|
||||
|
||||
/**
|
||||
* Get Text Bounding Box
|
||||
*/
|
||||
fvec2 GetTextBounds(const char* text, float scale);
|
||||
/**
|
||||
* Extended Draw Text Function that vreates a Command List
|
||||
*/
|
||||
void CmdTextEx(Drawlist& dl, const fvec2& pos, u32 color, float scale,
|
||||
const char* text, LiTextFlags flags = 0, const fvec2& box = 0);
|
||||
|
||||
/**
|
||||
* Garbage collection for TextMapSystem
|
||||
*/
|
||||
void CleanupTMS();
|
||||
/**
|
||||
* Utility function to create a font atlas
|
||||
* During TTF loading (Internal and should not be called)
|
||||
*/
|
||||
void BakeAndPush(bool final, std::vector<u8>& font_tex, int texszs);
|
||||
std::string pWrapText(const std::string& txt, float scale,
|
||||
const PD::fvec2& max, PD::fvec2& dim);
|
||||
std::string pShortText(const std::string& txt, float scale,
|
||||
const PD::fvec2& max, PD::fvec2& dim);
|
||||
|
||||
/** Data Section */
|
||||
int PixelHeight = 0;
|
||||
int DefaultPixelHeight = 24;
|
||||
std::vector<TextureID> Textures;
|
||||
/**
|
||||
* 32Bit Codepoint Dataholder reference map
|
||||
* **Now using unordered map**
|
||||
*/
|
||||
std::unordered_map<u32, Codepoint> CodeMap;
|
||||
/** TMS */
|
||||
struct TMELEM {
|
||||
PD::u32 ID;
|
||||
PD::fvec2 Size;
|
||||
std::string Text;
|
||||
u64 TimeStamp;
|
||||
};
|
||||
std::unordered_map<u32, TMELEM> pTMS;
|
||||
|
||||
private:
|
||||
size_t pCurrentTex = 0;
|
||||
};
|
||||
} // namespace Li
|
||||
} // namespace PD
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <pd/lithium/command.hpp>
|
||||
#include <pd/lithium/drawlist.hpp>
|
||||
#include <pd/lithium/font.hpp>
|
||||
#include <pd/lithium/math.hpp>
|
||||
#include <pd/lithium/pools.hpp>
|
||||
#include <pd/lithium/vertex.hpp>
|
||||
|
||||
@@ -203,10 +203,16 @@ PD_API void Drawlist::DrawCircleFilled(const fvec2& center, float rad,
|
||||
PathFill(color);
|
||||
}
|
||||
|
||||
PD_API void Drawlist::DrawText(const fvec2& p, const char* text, u32 color) {}
|
||||
PD_API void Drawlist::DrawText(const fvec2& p, const char* text, u32 color) {
|
||||
if (!pFont) return;
|
||||
pFont->CmdTextEx(*this, p, color, pFontScale, text);
|
||||
}
|
||||
|
||||
PD_API void Drawlist::DrawTextEx(const fvec2& p, const char* text, u32 color,
|
||||
LiTextFlags flags, const fvec2& box) {}
|
||||
LiTextFlags flags, const fvec2& box) {
|
||||
if (!pFont) return;
|
||||
pFont->CmdTextEx(*this, p, color, pFontScale, text, flags, box);
|
||||
}
|
||||
|
||||
PD_API void Drawlist::DrawPolyLine(const Pool<fvec2>& points, u32 color,
|
||||
LiDrawFlags flags, int t) {
|
||||
@@ -270,6 +276,7 @@ PD_API void Drawlist::DrawConvexPolyFilled(const Pool<fvec2>& points,
|
||||
|
||||
PD_API void Drawlist::PrimQuad(Command& cmd, const Rect& quad, const Rect& uv,
|
||||
u32 color) {
|
||||
cmd.Reserve(4, 6);
|
||||
cmd.Add(2, 1, 0);
|
||||
cmd.Add(3, 2, 0);
|
||||
cmd.Add(Vertex(quad.TopLeft(), uv.TopLeft(), color));
|
||||
@@ -280,6 +287,7 @@ PD_API void Drawlist::PrimQuad(Command& cmd, const Rect& quad, const Rect& uv,
|
||||
|
||||
PD_API void Drawlist::PrimTriangle(Command& cmd, const fvec2& a, const fvec2& b,
|
||||
const fvec2& c, u32 color) {
|
||||
cmd.Reserve(3, 3);
|
||||
cmd.Add(2, 1, 0);
|
||||
cmd.Add(Vertex(a, vec2(0.f, 1.f), color));
|
||||
cmd.Add(Vertex(b, vec2(1.f, 1.f), color));
|
||||
|
||||
@@ -0,0 +1,275 @@
|
||||
#include <pd/core/core.hpp>
|
||||
#include <pd/drivers/gfx.hpp>
|
||||
#include <pd/lithium/drawlist.hpp>
|
||||
#include <pd/lithium/font.hpp>
|
||||
#include <pd/lithium/math.hpp>
|
||||
|
||||
#define STB_TRUETYPE_IMPLEMENTATION
|
||||
#include <stb_truetype.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace PD {
|
||||
namespace Li {
|
||||
PD_API void Font::LoadTTF(const std::string& path, int px_height) {
|
||||
/**
|
||||
* Just use LoadFile2Mem which looks way cleaner
|
||||
* and helps not having the font loading code twice
|
||||
* when adding LoadTTF with mem support
|
||||
*/
|
||||
PDLOG("Font: Loading {}...", path);
|
||||
TT::Scope st("LI_LoadTTF_" + path);
|
||||
auto font = PD::IO::LoadFile2Mem(path);
|
||||
LoadTTF(font, px_height);
|
||||
}
|
||||
|
||||
PD_API void Font::LoadTTF(const std::vector<u8>& data, int px_height) {
|
||||
/**
|
||||
* Some additional Info:
|
||||
* Removed the stbtt get bitmapbox as we dont need to place
|
||||
* the glyps nicely in the tex. next step would be using the free
|
||||
* space on the y axis to get mor glyphs inside
|
||||
*/
|
||||
PixelHeight = px_height;
|
||||
int texszs = PD::Bits::GetPow2(px_height * 16);
|
||||
if (texszs > 1024) {
|
||||
texszs = 1024; // Max size
|
||||
}
|
||||
|
||||
stbtt_fontinfo inf;
|
||||
if (!stbtt_InitFont(&inf, data.data(), 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
float scale = stbtt_ScaleForPixelHeight(&inf, PixelHeight);
|
||||
|
||||
int ascent, descent, lineGap;
|
||||
stbtt_GetFontVMetrics(&inf, &ascent, &descent, &lineGap);
|
||||
int baseline = static_cast<int>(ascent * scale);
|
||||
|
||||
// Cache to not render same codepoint tex twice
|
||||
std::map<u32, int> buf_cache;
|
||||
|
||||
std::vector<u8> font_tex(texszs * texszs * 4, 0);
|
||||
fvec2 off;
|
||||
|
||||
bool empty = true;
|
||||
|
||||
for (u32 ii = 0x0000; ii <= 0xFFFF; ii++) {
|
||||
int gi = stbtt_FindGlyphIndex(&inf, ii);
|
||||
if (gi == 0) continue;
|
||||
if (stbtt_IsGlyphEmpty(&inf, gi)) continue;
|
||||
|
||||
int w = 0, h = 0, xo = 0, yo = 0;
|
||||
unsigned char* bitmap =
|
||||
stbtt_GetCodepointBitmap(&inf, scale, scale, ii, &w, &h, &xo, &yo);
|
||||
if (!bitmap || w <= 0 || h <= 0) {
|
||||
if (bitmap) free(bitmap);
|
||||
continue;
|
||||
}
|
||||
|
||||
u32 hashed_map = IO::HashMemory(std::vector<u8>(bitmap, bitmap + (w * h)));
|
||||
if (buf_cache.find(hashed_map) != buf_cache.end()) {
|
||||
Codepoint c = GetCodepoint(buf_cache[hashed_map]);
|
||||
c.pCodepoint = ii;
|
||||
CodeMap[ii] = c;
|
||||
free(bitmap);
|
||||
continue;
|
||||
} else {
|
||||
buf_cache[hashed_map] = ii;
|
||||
}
|
||||
|
||||
// Next row
|
||||
if (off.x + w > texszs) {
|
||||
off.y += PixelHeight;
|
||||
off.x = 0.0f;
|
||||
}
|
||||
// Bake cause we go out of the tex
|
||||
if (off.y + PixelHeight > texszs) {
|
||||
BakeAndPush(false, font_tex, texszs);
|
||||
off = 0;
|
||||
std::fill(font_tex.begin(), font_tex.end(), 0);
|
||||
empty = true;
|
||||
}
|
||||
|
||||
// UVs & Codepoint
|
||||
Codepoint c;
|
||||
fvec4 uvs;
|
||||
// cast the ints to floats and not the floats...
|
||||
// dont know where my mind was when creating the code
|
||||
uvs.x = off.x / static_cast<float>(texszs);
|
||||
uvs.y = off.y / static_cast<float>(texszs);
|
||||
uvs.z = (off.x + w) / static_cast<float>(texszs);
|
||||
uvs.w = (off.y + h) / static_cast<float>(texszs);
|
||||
// Flip if needed
|
||||
if (PD::Gfx::GetFlags() & PDBackendFlags_FlipUV_Y) {
|
||||
uvs.y = 1.f - uvs.y;
|
||||
uvs.w = 1.f - uvs.w;
|
||||
}
|
||||
c.SimpleUV = uvs;
|
||||
c.Tex = pCurrentTex;
|
||||
c.Size = fvec2(w, h);
|
||||
c.Offset = baseline + yo;
|
||||
c.pCodepoint = ii;
|
||||
|
||||
for (int y = 0; y < h; ++y) {
|
||||
for (int x = 0; x < w; ++x) {
|
||||
int map_pos = ((static_cast<int>(off.y) + y) * texszs +
|
||||
(static_cast<int>(off.x) + x)) *
|
||||
4;
|
||||
font_tex[map_pos + 0] = 255;
|
||||
font_tex[map_pos + 1] = 255;
|
||||
font_tex[map_pos + 2] = 255;
|
||||
font_tex[map_pos + 3] = bitmap[x + y * w];
|
||||
}
|
||||
}
|
||||
|
||||
empty = false;
|
||||
CodeMap[ii] = c;
|
||||
free(bitmap);
|
||||
|
||||
// offset by 1 (prevents visual glitches i had)
|
||||
off.x += w + 1;
|
||||
}
|
||||
|
||||
if (!empty) {
|
||||
BakeAndPush(true, font_tex, texszs);
|
||||
}
|
||||
}
|
||||
|
||||
PD_API void Font::LoadDefaultFont(int id, int pixel_height) {}
|
||||
|
||||
PD_API Font::Codepoint& Font::GetCodepoint(u32 c) {
|
||||
// Check if codepoijt exist or return a static invalid one
|
||||
auto res = CodeMap.find(c);
|
||||
if (res == CodeMap.end()) {
|
||||
static Codepoint invalid;
|
||||
invalid.pInvalid = true;
|
||||
return invalid;
|
||||
}
|
||||
return res->second;
|
||||
}
|
||||
|
||||
PD_API fvec2 Font::GetTextBounds(const char* text, float scale) {
|
||||
// Create a temp position and offset as [0, 0]
|
||||
fvec2 res;
|
||||
float x = 0;
|
||||
// Curent Font Scale
|
||||
float cfs = (DefaultPixelHeight * scale) / (float)PixelHeight;
|
||||
float lh = (float)PixelHeight * cfs;
|
||||
U8Iterator it(text);
|
||||
u32 c;
|
||||
while (it.Decode32(c)) {
|
||||
auto cp = GetCodepoint(c);
|
||||
if (!cp.pInvalid && c != '\n' && c != '\t' && c != ' ') {
|
||||
continue;
|
||||
}
|
||||
switch (c) {
|
||||
case L'\n':
|
||||
res.y += lh;
|
||||
res.x = std::max(res.x, x);
|
||||
x = 0.f;
|
||||
break;
|
||||
case L'\t':
|
||||
x += 16 * cfs;
|
||||
break;
|
||||
case L' ':
|
||||
x += 4 * cfs;
|
||||
// Fall trough here to get the same result as in
|
||||
// TextCommand if/else Section
|
||||
default:
|
||||
x += cp.Size.x * cfs;
|
||||
// Omly passing c cause i know its not used
|
||||
if (it.PeekNext32(c)) {
|
||||
x += 2 * cfs;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
res.x = std::max(res.x, x);
|
||||
res.y += lh;
|
||||
return res;
|
||||
}
|
||||
|
||||
PD_API void Font::CmdTextEx(Drawlist& dl, const fvec2& pos, u32 color,
|
||||
float scale, const char* text, LiTextFlags flags,
|
||||
const fvec2& box) {
|
||||
fvec2 off;
|
||||
float cfs = (DefaultPixelHeight * scale) / (float)PixelHeight;
|
||||
float lh = (float)PixelHeight * cfs;
|
||||
fvec2 td;
|
||||
fvec2 rpos = pos;
|
||||
fvec2 rbox = box;
|
||||
|
||||
if (flags & (LiTextFlags_AlignMid | LiTextFlags_AlignRight)) {
|
||||
td = GetTextBounds(text, scale);
|
||||
}
|
||||
if (flags & LiTextFlags_AlignMid) rpos = rbox * 0.5 - td * 0.5 + pos;
|
||||
if (flags & LiTextFlags_AlignRight) rpos.x -= td.x;
|
||||
|
||||
U8Iterator it(text);
|
||||
u32 c;
|
||||
Command* cmd = nullptr;
|
||||
|
||||
while (it.Decode32(c)) {
|
||||
auto cp = GetCodepoint(c);
|
||||
if ((!cp.pInvalid && c != '\n' && c != '\t' && c != ' ') && c != '\r')
|
||||
continue;
|
||||
|
||||
if (c == L'\n') {
|
||||
off.y += lh;
|
||||
off.x = 0.f;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == L'\t') {
|
||||
off.x += 16 * cfs;
|
||||
continue;
|
||||
}
|
||||
if (c == L' ') {
|
||||
off.x += 4 * cfs;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cmd == nullptr || cmd->Tex != Textures[cp.Tex]) {
|
||||
if (cp.Tex >= Textures.size()) continue;
|
||||
cmd = &dl.NewCommand();
|
||||
cmd->Tex = Textures[cp.Tex];
|
||||
}
|
||||
|
||||
if (flags & LiTextFlags_Shaddow) {
|
||||
Rect rec = Math::PrimRect(rpos + off + fvec2(1, cp.Offset * cfs + 1),
|
||||
cp.Size * cfs, 0.f);
|
||||
dl.PrimQuad(*cmd, rec, cp.SimpleUV, 0xff111111);
|
||||
}
|
||||
|
||||
Rect rec = Math::PrimRect(rpos + off + fvec2(0, cp.Offset * cfs),
|
||||
cp.Size * cfs, 0.f);
|
||||
dl.PrimQuad(*cmd, rec, cp.SimpleUV, color);
|
||||
|
||||
off.x += cp.Size.x * cfs + 2 * cfs;
|
||||
}
|
||||
}
|
||||
|
||||
PD_API void Font::CleanupTMS() {}
|
||||
|
||||
PD_API void Font::BakeAndPush(bool final, std::vector<u8>& font_tex,
|
||||
int texszs) {
|
||||
auto t = PD::Gfx::LoadTexture(font_tex, texszs, texszs);
|
||||
PDLOG("Font: Texture backed as 0x{:X} at {}", t.GetID(), pCurrentTex);
|
||||
Textures.push_back(t.GetID());
|
||||
pCurrentTex = Textures.size();
|
||||
}
|
||||
|
||||
PD_API std::string Font::pWrapText(const std::string& txt, float scale,
|
||||
const PD::fvec2& max, PD::fvec2& dim) {
|
||||
return "";
|
||||
}
|
||||
|
||||
PD_API std::string Font::pShortText(const std::string& txt, float scale,
|
||||
const PD::fvec2& max, PD::fvec2& dim) {
|
||||
return "";
|
||||
}
|
||||
|
||||
} // namespace Li
|
||||
} // namespace PD
|
||||
Binary file not shown.
@@ -16,7 +16,7 @@ const char* ResourcePath(const char* in) {
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
PD::LogFilter(PD::LogLevel::Warning);
|
||||
// PD::LogFilter(PD::LogLevel::Warning);
|
||||
Driver drv = Driver::OpenGL3;
|
||||
if (argc == 2) {
|
||||
if (std::string(argv[1]) == "gl2") {
|
||||
@@ -39,6 +39,10 @@ int main(int argc, char** argv) {
|
||||
PD::Li::Drawlist pList;
|
||||
PD::Image img(ResourcePath("icon.png"));
|
||||
auto pTex = PD::Gfx::LoadTexture(img, img.Width(), img.Height());
|
||||
PD::Li::Font font;
|
||||
font.LoadTTF(ResourcePath("default.ttf"));
|
||||
pList.SetFont(&font);
|
||||
pList.SetFontscale(0.7f);
|
||||
while (pOs->Mainloop()) {
|
||||
pOs->ClearViewPort();
|
||||
PD::Li::ResetPools();
|
||||
@@ -48,6 +52,7 @@ int main(int argc, char** argv) {
|
||||
pList.BindTexture(pTex);
|
||||
pList.DrawRectFilled(pOs->PositionTranslate(PD::fvec2(0.02f, 0.5f)),
|
||||
pOs->SizeTranslate(PD::fvec2(0.3)), 0xffffffff);
|
||||
pList.DrawText(5, "Hello World!", 0xff0000ff);
|
||||
PD::Gfx::Reset();
|
||||
PD::Gfx::Draw(pList);
|
||||
pList.Clear();
|
||||
|
||||
@@ -15,11 +15,21 @@ namespace PD {
|
||||
struct HorizonCtr::Impl {
|
||||
C3D_RenderTarget* Top = nullptr;
|
||||
C3D_RenderTarget* Bottom = nullptr;
|
||||
uint32_t* pSocBuf = nullptr;
|
||||
};
|
||||
|
||||
void HorizonCtr::Init() {
|
||||
if (impl) return;
|
||||
impl = new Impl();
|
||||
impl->pSocBuf = (uint32_t*)std::aligned_alloc(0x1000, 0x100000);
|
||||
if (impl->pSocBuf) {
|
||||
Result ret = socInit(impl->pSocBuf, 0x100000);
|
||||
if (R_FAILED(ret)) {
|
||||
free(impl->pSocBuf);
|
||||
impl->pSocBuf = nullptr;
|
||||
}
|
||||
}
|
||||
link3dsStdio();
|
||||
romfsInit();
|
||||
gfxInitDefault();
|
||||
consoleInit(GFX_BOTTOM, nullptr);
|
||||
@@ -41,6 +51,7 @@ void HorizonCtr::Deinit() {
|
||||
C3D_Fini();
|
||||
gfxExit();
|
||||
romfsExit();
|
||||
socExit();
|
||||
delete impl;
|
||||
impl = nullptr;
|
||||
}
|
||||
@@ -48,7 +59,9 @@ void HorizonCtr::Deinit() {
|
||||
|
||||
bool HorizonCtr::Mainloop() {
|
||||
pViewPort = ivec2(400, 240);
|
||||
return aptMainLoop();
|
||||
hidScanInput();
|
||||
bool _kill = hidKeysUp() & KEY_START;
|
||||
return aptMainLoop() && !_kill;
|
||||
}
|
||||
|
||||
void HorizonCtr::ClearViewPort() {
|
||||
|
||||
@@ -16,6 +16,8 @@ struct HorizonNX::Impl {
|
||||
void HorizonNX::Init() {
|
||||
if (impl) return;
|
||||
impl = new Impl();
|
||||
socketInitializeDefault();
|
||||
nxlinkStdio();
|
||||
romfsInit();
|
||||
glfwInit();
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
|
||||
Reference in New Issue
Block a user