- Added GetTime funcs to utils
- Added Time() to App class to gather the apps run time in seconds
- Updated almost every part of the sourcecode to the D7 Style guide
This commit is contained in:
2025-11-26 13:46:46 +01:00
parent 830524c9eb
commit 2a2a670e1a
32 changed files with 913 additions and 813 deletions

View File

@@ -1,58 +1,46 @@
#include <amethyst.hpp> #include <amethyst.hpp>
#include <iostream>
#include "amethyst/iron.hpp" #include "amethyst/iron.hpp"
class example : public amy::app { class example : public Amy::App {
public: public:
example() { example() {
amy::ctru::init(); Amy::Ctr::Init();
consoleInit(GFX_BOTTOM, NULL); consoleInit(GFX_BOTTOM, NULL);
amy::c3d::init(); Amy::C3D::Init();
m_top = amy::c3d::createScreen(GFX_TOP, GFX_LEFT); m_top = Amy::C3D::CreateScreen(GFX_TOP, GFX_LEFT);
amy::iron::init(); Amy::Iron::Init();
dl = new amy::iron::drawlist(); dl = new Amy::Iron::Drawlist();
dl->drawSolid(); dl->DrawSolid();
auto cmd = std::make_unique<amy::iron::command>();
cmd->index = 0;
cmd->layer = 0;
cmd->tex = amy::iron::whiteTex();
cmd->add(0).add(1).add(2);
cmd->add(amy::iron::vertex(200, 50, 0, 0, 0xff0000ff));
cmd->add(amy::iron::vertex(100, 190, 0, 0, 0xff00ff00));
cmd->add(amy::iron::vertex(300, 190, 0, 0, 0xffff0000));
cmdl.push_back(std::move(cmd));
// throw std::runtime_error(std::format(
// "solid tex: {:#08x}\nsize: {}\nptr: {:#08x}",
// (amy::ui)amy::iron::whiteTex(), amy::iron::whiteTex()->size(),
// (amy::ui)amy::iron::whiteTex()->ptr()));
}; };
~example() { ~example() {
amy::c3d::deleteScreen(m_top); Amy::C3D::DeleteScreen(m_top);
amy::c3d::deinit(); Amy::C3D::Deinit();
}; };
void main() { void Main() override {
amy::c3d::startFrame(); Amy::C3D::StartFrame();
m_top->startDraw(); m_top->Use();
m_top->clear(); m_top->Clear();
// dl->drawRectFilled(0, 50, 0xff00ff00); dl->DrawRectFilled(0, 50, 0xff00ff00);
amy::iron::newFrame(); Amy::Iron::NewFrame();
amy::iron::drawOn(m_top); Amy::Iron::DrawOn(m_top);
// amy::iron::draw(dl->data()); Amy::Iron::Draw(*dl);
amy::iron::draw(cmdl); dl->Clear();
// dl->clear(); Amy::C3D::EndFrame();
amy::c3d::endFrame(); std::cout << std::format("\x1b[1;1HDelta: {:.3f}\x1b[K", this->Delta());
std::cout << std::format("\x1b[2;1HTime: {:.2f}\x1b[K", this->Time());
} }
private: private:
amy::c3d::screen* m_top = nullptr; Amy::C3D::Screen* m_top = nullptr;
amy::iron::drawlist* dl = nullptr; Amy::Iron::Drawlist* dl = nullptr;
std::vector<amy::iron::command::ref> cmdl;
}; };
int main() { int main() {
amy::registerCxxExceptionHandler(); Amy::RegisterCxxExceptionHandler();
example app; example app;
app.run(); app.Run();
return 0; return 0;
} }

View File

@@ -8,6 +8,6 @@
#include <amethyst/renderer.hpp> #include <amethyst/renderer.hpp>
#include <amethyst/texture.hpp> #include <amethyst/texture.hpp>
namespace amy { namespace Amy {
void registerCxxExceptionHandler(); void RegisterCxxExceptionHandler();
} }

View File

@@ -3,18 +3,24 @@
#include <amethyst/asset.hpp> #include <amethyst/asset.hpp>
#include <amethyst/types.hpp> #include <amethyst/types.hpp>
namespace amy { namespace Amy {
class app { class App {
public: public:
app() {} App() {
~app() {} pDelta = 0.0;
pTime = 0.0;
pLast = 0LL;
}
~App() {}
virtual void main() {} virtual void Main() {}
void run(); void Run();
double delta() const { return m_delta; } double Delta() const { return pDelta; }
double Time() const { return pTime; }
private: private:
ull m_last; ull pLast;
double m_delta; double pDelta;
double pTime;
}; };
} // namespace amy } // namespace Amy

View File

@@ -1,9 +1,9 @@
#pragma once #pragma once
namespace amy { namespace Amy {
class asset { class Asset {
public: public:
asset() = default; Asset() = default;
virtual ~asset() = default; virtual ~Asset() = default;
}; };
} // namespace amy } // namespace Amy

View File

@@ -3,22 +3,22 @@
#include <amethyst/texture.hpp> #include <amethyst/texture.hpp>
#include <amethyst/types.hpp> #include <amethyst/types.hpp>
namespace amy { namespace Amy {
class assets { class Assets {
public: public:
assets() = default; Assets() = default;
~assets() = default; ~Assets() = default;
void add(cstr& id, asset* v) { m_assets[id] = v; } void add(ksr id, Asset* v) { pAssets[id] = v; }
void remove(cstr& id) { void remove(ksr id) {
if (m_assets.count(id)) { if (pAssets.count(id)) {
m_assets.erase(id); pAssets.erase(id);
} }
} }
template <typename T> template <typename T>
T* get(cstr& id) { T* get(ksr id) {
auto r = m_assets.find(id); auto r = pAssets.find(id);
if (r == m_assets.end()) { if (r == pAssets.end()) {
throw std::runtime_error("[amy] assets: unable to find " + id); throw std::runtime_error("[amy] assets: unable to find " + id);
} }
if (auto v = dynamic_cast<T*>(r->second)) { if (auto v = dynamic_cast<T*>(r->second)) {
@@ -29,6 +29,6 @@ class assets {
} }
private: private:
std::map<str, asset*> m_assets; std::map<str, Asset*> pAssets;
}; };
} // namespace amy } // namespace Amy

View File

@@ -9,115 +9,115 @@
#include <amethyst/types.hpp> #include <amethyst/types.hpp>
#include <string> #include <string>
namespace amy { namespace Amy {
class c3d { class C3D {
public: public:
c3d() = default; C3D() = default;
~c3d() = default; ~C3D() = default;
class screen { class Screen {
public: public:
screen(C3D_RenderTarget* t) { Screen(C3D_RenderTarget* t) {
m_target = t; pTarget = t;
// Width and height are swapped on 3ds due to screen layout // Width and height are swapped on 3ds due to screen layout
m_width = m_target->frameBuf.height; pWidth = pTarget->frameBuf.height;
m_height = m_target->frameBuf.width; pHeight = pTarget->frameBuf.width;
} }
~screen() { C3D_RenderTargetDelete(m_target); } ~Screen() { C3D_RenderTargetDelete(pTarget); }
int width() const { return m_width; } int Width() const { return pWidth; }
int height() const { return m_height; } int Height() const { return pHeight; }
ivec2 size() const { return ivec2(m_width, m_height); } ivec2 Size() const { return ivec2(pWidth, pHeight); }
void clear() { C3D_RenderTargetClear(m_target, C3D_CLEAR_ALL, 0, 0); } void Clear() { C3D_RenderTargetClear(pTarget, C3D_CLEAR_ALL, 0, 0); }
void startDraw() { C3D_FrameDrawOn(m_target); } void Use() { C3D_FrameDrawOn(pTarget); }
private: private:
C3D_RenderTarget* m_target = nullptr; C3D_RenderTarget* pTarget = nullptr;
int m_width = 0; int pWidth = 0;
int m_height = 0; int pHeight = 0;
}; };
class shader : public asset { class Shader : public Asset {
public: public:
shader(const std::string& path); Shader(ksr path);
shader() {} Shader() {}
~shader(); ~Shader();
void load(const std::string& path); void Load(ksr path);
void load(const std::vector<uc>& data); void Load(kvr<uc> data);
void compile(const std::string& code); void Compile(ksr code);
void use(); void Use();
void input(int reg, GPU_FORMATS f, int num); void Input(int reg, GPU_FORMATS f, int num);
void input(GPU_FORMATS f, int num) { input(m_reg++, f, num); } void Input(GPU_FORMATS f, int num) { Input(pReg++, f, num); }
void setMat4(int loc, C3D_Mtx* m); void SetMat4(int loc, C3D_Mtx* m);
void setMat4(int loc, const mat4& m); void SetMat4(int loc, const mat4& m);
int loc(const std::string& name); int loc(ksr name);
private: private:
C3D_AttrInfo m_info; C3D_AttrInfo pInfo;
shaderProgram_s m_program; shaderProgram_s pProgram;
DVLB_s* m_code; DVLB_s* pCode;
int m_reg = 0; int pReg = 0;
}; };
class frag { class Frag {
public: public:
frag() = default; Frag() = default;
~frag() = default; ~Frag() = default;
static void edit(int id = 0); static void Edit(int id = 0);
static void src(C3D_TexEnvMode mode, GPU_TEVSRC s1 = GPU_PRIMARY_COLOR, static void Src(C3D_TexEnvMode mode, GPU_TEVSRC s1 = GPU_PRIMARY_COLOR,
GPU_TEVSRC s2 = GPU_PRIMARY_COLOR, GPU_TEVSRC s2 = GPU_PRIMARY_COLOR,
GPU_TEVSRC s3 = GPU_PRIMARY_COLOR); GPU_TEVSRC s3 = GPU_PRIMARY_COLOR);
static void func(C3D_TexEnvMode mode, GPU_COMBINEFUNC func); static void Func(C3D_TexEnvMode mode, GPU_COMBINEFUNC func);
private: private:
static C3D_TexEnv* m_env; static C3D_TexEnv* pEnv;
}; };
static void init(); static void Init();
static void deinit(); static void Deinit();
static void startFrame(bool sync = true); static void StartFrame(bool sync = true);
static void endFrame(); static void EndFrame();
static screen* createScreen(gfxScreen_t screen, gfx3dSide_t side = GFX_LEFT); static Screen* CreateScreen(gfxScreen_t screen, gfx3dSide_t side = GFX_LEFT);
static void deleteScreen(screen* screen); static void DeleteScreen(Screen* screen);
static void drawArrays(int start, int count, static void DrawArrays(int start, int count,
GPU_Primitive_t prim = GPU_TRIANGLES); GPU_Primitive_t prim = GPU_TRIANGLES);
static void drawElements(int count, const void* idx_ptr, static void DrawElements(int count, const void* idx_ptr,
int type = C3D_UNSIGNED_SHORT, int type = C3D_UNSIGNED_SHORT,
GPU_Primitive_t prim = GPU_TRIANGLES); GPU_Primitive_t prim = GPU_TRIANGLES);
static void depthTest(bool on, GPU_TESTFUNC func = GPU_GREATER, static void DepthTest(bool on, GPU_TESTFUNC func = GPU_GREATER,
GPU_WRITEMASK mask = GPU_WRITE_ALL); GPU_WRITEMASK mask = GPU_WRITE_ALL);
static void disableScissor(); static void DisableScissor();
static void enableScissor(const ivec4 rect); static void EnableScissor(const ivec4 rect);
/** /**
* Buf cfg die permutation at runtime berechnet * Buf cfg die permutation at runtime berechnet
*/ */
static void bufCfg(void* ptr, int stride, int shader_attribs); static void BufCfg(void* ptr, int stride, int shader_attribs);
/** /**
* Klassische config bei der man selber die permutation eintragen muss * Klassische config bei der man selber die permutation eintragen muss
*/ */
static void bufCfg(void* ptr, int stride, int shader_attribs, static void BufCfg(void* ptr, int stride, int shader_attribs,
u64 permutation); u64 permutation);
/** /**
* Hacky funktion um die permutation automatisch at compile time zu berechnen, * Hacky funktion um die permutation automatisch at compile time zu berechnen,
* falls diese immer gleich bleibt. * falls diese immer gleich bleibt.
* In der <> steht die anzahl der shader input werte * In der <> steht die anzahl der shader input werte
* usage: c3d::bufCfg<3>(data, sizeof(vertex)); * usage: C3D::bufCfg<3>(data, sizeof(vertex));
*/ */
template <int attribs> template <int attribs>
constexpr static void bufCfg(void* ptr, int stride) { constexpr static void BufCfg(void* ptr, int stride) {
auto buf = C3D_GetBufInfo(); auto buf = C3D_GetBufInfo();
BufInfo_Init(buf); BufInfo_Init(buf);
constexpr int pm = permutation(attribs); constexpr int pm = pPermutation(attribs);
BufInfo_Add(buf, ptr, stride, attribs, pm); BufInfo_Add(buf, ptr, stride, attribs, pm);
} }
static int drawcalls() { return m_drawcalls; } static int Drawcalls() { return pDrawcalls; }
private: private:
static int m_drawcalls; static int pDrawcalls;
static int m__dc__; static int p__dc__; // draw-calls internal
/** /**
* Funktion die anhand von **ac** genau den permu station wert für BufInfo * Funktion die anhand von **ac** genau den permu station wert für BufInfo
@@ -127,7 +127,7 @@ class c3d {
* ac = 4 -> 0x3210 * ac = 4 -> 0x3210
* ``` * ```
*/ */
constexpr static u64 permutation(int ac) { constexpr static u64 pPermutation(int ac) {
u64 ret = 0; u64 ret = 0;
if (ac < 1 || ac > 15) { if (ac < 1 || ac > 15) {
throw std::runtime_error("[amy] " + std::to_string(ac) + throw std::runtime_error("[amy] " + std::to_string(ac) +
@@ -139,4 +139,4 @@ class c3d {
return ret; return ret;
} }
}; };
} // namespace amy } // namespace Amy

View File

@@ -2,16 +2,16 @@
#include <amethyst/types.hpp> #include <amethyst/types.hpp>
namespace amy { namespace Amy {
namespace ctru { namespace Ctr {
enum services { enum Services {
romfs = 1 << 0, Romfs = 1 << 0,
cfgu = 1 << 1, Cfgu = 1 << 1,
gfx = 1 << 2, Gfx = 1 << 2,
gfx_def = 1 << 3, GfxDefault = 1 << 3,
def = romfs | gfx_def Default = Romfs | GfxDefault,
}; };
void init(unsigned int srv = def); void Init(ui srv = Default);
ull getTime(); ull GetTime();
} // namespace ctru } // namespace Ctr
} // namespace amy } // namespace Amy

View File

@@ -2,12 +2,12 @@
#include <string> #include <string>
namespace amy { namespace Amy {
class gtrace { class GTrace {
public: public:
gtrace() = default; GTrace() = default;
~gtrace() = default; ~GTrace() = default;
private: private:
}; };
} // namespace amy } // namespace Amy

View File

@@ -2,10 +2,10 @@
#include <amethyst/types.hpp> #include <amethyst/types.hpp>
namespace amy { namespace Amy {
class image { class Image {
public: public:
enum format { enum Format {
RGBA, // bpp == 4 RGBA, // bpp == 4
RGB, // bpp == 3 RGB, // bpp == 3
RGB565, // bpp == 2 (not supported in laoding) RGB565, // bpp == 2 (not supported in laoding)
@@ -13,43 +13,43 @@ class image {
ABGR, // bpp == 4 ABGR, // bpp == 4
BGRA, // bpp == 4 BGRA, // bpp == 4
}; };
image() = default; Image() = default;
image(cstr& path) { this->load(path); } Image(ksr path) { this->Load(path); }
image(const std::vector<uc>& buf) { this->load(buf); } Image(kvr<uc> buf) { this->Load(buf); }
image(const std::vector<uc>& buf, int w, int h, const format& fmt) { Image(kvr<uc> buf, int w, int h, const Format& fmt) {
this->copy(buf, w, h, fmt); this->Copy(buf, w, h, fmt);
} }
~image() = default; ~Image() = default;
void load(cstr& path); void Load(ksr path);
void load(const std::vector<uc>& buf); void Load(kvr<uc> buf);
void copy(const std::vector<uc>& buf, int w, int h, const format& fmt); void Copy(kvr<uc> buf, int w, int h, const Format& fmt);
std::vector<uc>& getBuffer() { return m_buffer; } vec<uc>& GetBuffer() { return pBuffer; }
std::vector<uc> getBuffer() const { return m_buffer; } vec<uc> GetBuffer() const { return pBuffer; }
int width() const { return m_w; } int Width() const { return pW; }
int height() const { return m_h; } int Height() const { return pH; }
int bpp() const { return getBppOfFmt(m_fmt); } int Bpp() const { return GetBppOfFmt(pFmt); }
format fmt() const { return m_fmt; } Format Fmt() const { return pFmt; }
void convert(const format& dst) { convert(*this, dst); } void Convert(const Format& dst) { Convert(*this, dst); }
void retile(std::function<ui(int x, int y, int w)> src, void Retile(std::function<ui(int x, int y, int w)> src,
std::function<ui(int x, int y, int w)> dst) { std::function<ui(int x, int y, int w)> dst) {
retile(*this, src, dst); Retile(*this, src, dst);
} }
uc& operator[](int idx) { return m_buffer[idx]; } uc& operator[](int idx) { return pBuffer[idx]; }
uc operator[](int idx) const { return m_buffer[idx]; } uc operator[](int idx) const { return pBuffer[idx]; }
static void convert(image& img, const format& dst); static void Convert(Image& img, const Format& dst);
static void retile(image& img, std::function<ui(int x, int y, int w)> src, static void Retile(Image& img, std::function<ui(int x, int y, int w)> src,
std::function<ui(int x, int y, int w)> dst); std::function<ui(int x, int y, int w)> dst);
static int getBppOfFmt(const format& fmt); static int GetBppOfFmt(const Format& fmt);
private: private:
std::vector<uc> m_buffer; vec<uc> pBuffer;
int m_w = 0; int pW = 0;
int m_h = 0; int pH = 0;
format m_fmt = RGBA; Format pFmt = RGBA;
}; };
} // namespace amy } // namespace Amy

View File

@@ -8,157 +8,157 @@
#include <amethyst/texture.hpp> #include <amethyst/texture.hpp>
#include <amethyst/types.hpp> #include <amethyst/types.hpp>
namespace amy { namespace Amy {
class iron { class Iron {
public: public:
struct vertex { struct Vertex {
vertex(float x, float y, float u, float v, ui clr) { Vertex(float x, float y, float u, float v, ui clr) {
pos.x = x; pos.x = x;
pos.y = y; pos.y = y;
uv.x = x; uv.x = x;
uv.y = y; uv.y = y;
color = clr; color = clr;
} }
vertex(const fvec2& pos, const fvec2& uv, ui clr) { Vertex(const fvec2& pos, const fvec2& uv, ui clr) {
this->pos = pos; this->pos = pos;
this->uv = uv; this->uv = uv;
this->color = clr; this->color = clr;
} }
vertex() {} Vertex() {}
amy::fvec2 pos; fvec2 pos;
amy::fvec2 uv; fvec2 uv;
ui color = 0; ui color = 0;
}; };
class command { class Command {
public: public:
command() = default; Command() = default;
using ref = up<command>; using ref = up<Command>;
command& add(const u16& idx) { Command& Add(const u16& idx) {
indexBuf.push_back(vertexBuf.size() + idx); IndexBuf.push_back(VertexBuf.size() + idx);
return *this; return *this;
} }
command& add(const vertex& vtx) { Command& Add(const Vertex& vtx) {
vertexBuf.push_back(std::move(vtx)); VertexBuf.push_back(std::move(vtx));
return *this; return *this;
} }
std::vector<vertex> vertexBuf; std::vector<Vertex> VertexBuf;
std::vector<u16> indexBuf; std::vector<u16> IndexBuf;
ivec4 scissorRect; ivec4 ScissorRect;
bool scissorOn = false; bool ScissorOn = false;
int layer; int Layer;
int index; int Index;
texture* tex; Texture* Tex;
}; };
class drawlist { class Drawlist {
public: public:
drawlist() { drawSolid(); } Drawlist() { DrawSolid(); }
~drawlist() { m_data.clear(); } ~Drawlist() { pData.clear(); }
// required due to memory management // required due to memory management
drawlist(const drawlist&) = delete; Drawlist(const Drawlist&) = delete;
drawlist& operator=(const drawlist&) = delete; Drawlist& operator=(const Drawlist&) = delete;
drawlist(drawlist&&) noexcept = default; Drawlist(Drawlist&&) noexcept = default;
drawlist& operator=(drawlist&&) noexcept = default; Drawlist& operator=(Drawlist&&) noexcept = default;
std::vector<command::ref>& data() { return m_data; } std::vector<Command::ref>& Data() { return pData; }
void merge(drawlist* list); void Merge(Drawlist* list);
command::ref newCommand(); Command::ref NewCommand();
void push(command ::ref cmd); void Push(Command ::ref cmd);
void clear(); void Clear();
void drawSolid(); void DrawSolid();
void drawTex(texture* tex) { m_tex = tex; } void DrawTex(Texture* tex) { pTex = tex; }
/** Draw Api */ /** Draw Api */
void drawRect(const fvec2& pos, const fvec2& size, ui color, void DrawRect(const fvec2& pos, const fvec2& size, ui color,
int thickness = 1); int thickness = 1);
void drawRectFilled(const fvec2& pos, const fvec2& size, ui color); void DrawRectFilled(const fvec2& pos, const fvec2& size, ui color);
void drawTriangle(const fvec2& a, const fvec2& b, const fvec2& c, ui color, void DrawTriangle(const fvec2& a, const fvec2& b, const fvec2& c, ui color,
int thickness = 1); int thickness = 1);
void drawTriangleFilled(const fvec2& a, const fvec2& b, const fvec2& c, void DrawTriangleFilled(const fvec2& a, const fvec2& b, const fvec2& c,
ui color); ui color);
void drawCircle(const fvec2& center, float radius, ui color, int segments, void DrawCircle(const fvec2& center, float radius, ui color, int segments,
int thickness = 1); int thickness = 1);
void drawCircleFilled(const fvec2& center, float radius, ui color, void DrawCircleFilled(const fvec2& center, float radius, ui color,
int segments); int segments);
void drawText(const fvec2& pos, const std::string& text, ui color); void DrawText(const fvec2& pos, const std::string& text, ui color);
void drawTextEx(const fvec2& pos, const std::string& text, ui color, void DrawTextEx(const fvec2& pos, const std::string& text, ui color,
ui flags, const fvec2& box = 0); ui flags, const fvec2& box = 0);
void drawLine(const fvec2& a, const fvec2& b, ui color, int thickness = 1); void DrawLine(const fvec2& a, const fvec2& b, ui color, int thickness = 1);
void drawPolyLine(const std::vector<fvec2>& points, ui color, ui flags = 0, void DrawPolyLine(const std::vector<fvec2>& points, ui color, ui flags = 0,
int thickness = 1); int thickness = 1);
void drawConvexPolyFilled(const std::vector<fvec2>& points, ui color); void DrawConvexPolyFilled(const std::vector<fvec2>& points, ui color);
/** Path api */ /** Path api */
void pathAdd(const fvec2& pos) { m_path.push_back(std::move(pos)); } void PathAdd(const fvec2& pos) { pPath.push_back(std::move(pos)); }
void pathClear() { m_path.clear(); } void PathClear() { pPath.clear(); }
void pathReserve(size_t count) { m_path.reserve(m_path.size() + count); } void PathReserve(size_t count) { pPath.reserve(pPath.size() + count); }
void pathStroke(ui color, int thickness = 1, ui flags = 0) { void PathStroke(ui color, int thickness = 1, ui flags = 0) {
drawPolyLine(m_path, color, flags, thickness); DrawPolyLine(pPath, color, flags, thickness);
pathClear(); PathClear();
} }
void pathFill(ui color) { drawConvexPolyFilled(m_path, color); } void PathFill(ui color) { DrawConvexPolyFilled(pPath, color); }
void pathArcToN(const fvec2& c, float radius, float a_min, float a_max, void PathArcToN(const fvec2& c, float radius, float a_min, float a_max,
int segments); int segments);
void pathFastArcToN(const fvec2& c, float radius, float a_min, float a_max, void PathFastArcToN(const fvec2& c, float radius, float a_min, float a_max,
int segments); int segments);
void pathRect(const fvec2& a, const fvec2& b, float rounding = 0.f); void PathRect(const fvec2& a, const fvec2& b, float rounding = 0.f);
void pathRectEx(const fvec2& a, const fvec2& b, float rounfing, ui flags); void PathRectEx(const fvec2& a, const fvec2& b, float rounfing, ui flags);
void pushClipRect(const fvec4& clip) { clipRects.push(clip); } void PushClipRect(const fvec4& clip) { ClipRects.push(clip); }
void popClipRect() { void PopClipRect() {
if (!clipRects.empty()) clipRects.pop(); if (!ClipRects.empty()) ClipRects.pop();
} }
operator std::vector<command::ref>&() { return m_data; } operator std::vector<Command::ref>&() { return pData; }
private: private:
void clipCmd(command* ptr); void clipCmd(Command* ptr);
std::vector<command::ref> m_data; std::vector<Command::ref> pData;
std::vector<fvec2> m_path; std::vector<fvec2> pPath;
texture* m_tex = nullptr; Texture* pTex = nullptr;
std::stack<fvec4> clipRects; std::stack<fvec4> ClipRects;
int m_layer = 0; int pLayer = 0;
}; };
iron() = default; Iron() = default;
~iron() = default; ~Iron() = default;
static void init(); static void Init();
static void newFrame(); static void NewFrame();
static void drawOn(c3d::screen* screen); static void DrawOn(C3D::Screen* screen);
static void draw(const std::vector<command::ref>& data); static void Draw(const std::vector<Command::ref>& data);
static texture* whiteTex() { return m_solid; } static Texture* WhiteTex() { return m_solid; }
/** Static renderer utility funcs */ /** Static renderer utility funcs */
static void rotateCorner(fvec2& pos, float s, float c); static void RotateCorner(fvec2& pos, float s, float c);
static rect primRect(const fvec2& pos, const fvec2& size, float angle = 0.f); static Rect PrimRect(const fvec2& pos, const fvec2& size, float angle = 0.f);
static rect primLine(const fvec2& a, const fvec2& b, int thickness = 1); static Rect PrimLine(const fvec2& a, const fvec2& b, int thickness = 1);
static void cmdQuad(command* cmd, const rect& q, const rect& uv, ui color); static void CmdQuad(Command* cmd, const Rect& q, const Rect& uv, ui color);
static void cmdTriangle(command* cmd, const fvec2& a, const fvec2& b, static void CmdTriangle(Command* cmd, const fvec2& a, const fvec2& b,
const fvec2& c, ui clr); const fvec2& c, ui clr);
static void cmdConvexPolyFilled(command* cmd, static void CmdConvexPolyFilled(Command* cmd,
const std::vector<fvec2>& points, ui clr, const std::vector<fvec2>& points, ui clr,
texture* tex); Texture* tex);
static bool inBox(const fvec2& pos, const fvec2& size, const fvec4& area); static bool InBox(const fvec2& pos, const fvec2& size, const fvec4& area);
static bool inBox(const fvec2& pos, const fvec4& area); static bool InBox(const fvec2& pos, const fvec4& area);
static bool inBox(const fvec2& a, const fvec2& b, const fvec2& c, static bool InBox(const fvec2& a, const fvec2& b, const fvec2& c,
const fvec4& area); const fvec4& area);
private: private:
static void setupShader(); static void pSetupShader();
static void fragConfig(); static void pFragConfig();
static void initSolidTex(); static void pInitSolidTex();
static std::vector<vertex, linearAllocator<vertex>> m_vbuf; static std::vector<Vertex, linearAllocator<Vertex>> m_vbuf;
static std::vector<u16, linearAllocator<u16>> m_ibuf; static std::vector<u16, linearAllocator<u16>> m_ibuf;
static int uLocProj; static int uLocProj;
static c3d::shader* m_shader; static C3D::Shader* m_shader;
static mat4 m_mtx; static mat4 m_mtx;
static int m_idx, m_vtx; static int m_idx, m_vtx;
static texture* m_solid; static Texture* m_solid;
}; };
} // namespace amy } // namespace Amy

View File

@@ -9,7 +9,7 @@
// based on this guide: // based on this guide:
// https://johnfarrier.com/custom-allocators-in-c-high-performance-memory-management/ // https://johnfarrier.com/custom-allocators-in-c-high-performance-memory-management/
namespace amy { namespace Amy {
template <typename T> template <typename T>
class linearAllocator { class linearAllocator {
public: public:
@@ -37,4 +37,4 @@ class linearAllocator {
// or to b eable to see a crash report screen. // or to b eable to see a crash report screen.
size_t max_size() const noexcept { return linearSpaceFree(); } size_t max_size() const noexcept { return linearSpaceFree(); }
}; };
} // namespace amy } // namespace Amy

View File

@@ -29,11 +29,11 @@ SOFTWARE.
#include <cmath> #include <cmath>
#include <numbers> #include <numbers>
namespace amy { namespace Amy {
namespace numbers { namespace Numbers {
constexpr float Tau = std::numbers::pi * 2.f; constexpr float Tau = std::numbers::pi * 2.f;
} }
constexpr float Radians(float v) { return v * (numbers::Tau / 360.0f); } constexpr float Radians(float v) { return v * (Numbers::Tau / 360.0f); }
/** /**
* Minimal Mtx4 Lib that precomputes * Minimal Mtx4 Lib that precomputes
* basic stuff stuff at compiletime * basic stuff stuff at compiletime
@@ -141,4 +141,4 @@ struct mat4 {
static mat4 perspective(float fov, float aspect, float n, float f); static mat4 perspective(float fov, float aspect, float n, float f);
static mat4 lookAt(const fvec3& pos, const fvec3& center, const fvec3& up); static mat4 lookAt(const fvec3& pos, const fvec3& center, const fvec3& up);
}; };
} // namespace amy } // namespace Amy

View File

@@ -36,25 +36,25 @@ SOFTWARE.
*/ */
template <typename T, typename CharT> template <typename T, typename CharT>
struct std::formatter<amy::vec2<T>, CharT> : std::formatter<T, CharT> { struct std::formatter<Amy::vec2<T>, CharT> : std::formatter<T, CharT> {
template <typename FormatContext> template <typename FormatContext>
auto format(const amy::vec2<T> &v, FormatContext &ctx) const { auto format(const Amy::vec2<T>& v, FormatContext& ctx) const {
return std::format_to(ctx.out(), "{}, {}", v.x, v.y); return std::format_to(ctx.out(), "{}, {}", v.x, v.y);
} }
}; };
template <typename T, typename CharT> template <typename T, typename CharT>
struct std::formatter<amy::vec3<T>, CharT> : std::formatter<T, CharT> { struct std::formatter<Amy::vec3<T>, CharT> : std::formatter<T, CharT> {
template <typename FormatContext> template <typename FormatContext>
auto format(const amy::vec3<T> &v, FormatContext &ctx) const { auto format(const Amy::vec3<T>& v, FormatContext& ctx) const {
return std::format_to(ctx.out(), "{}, {}, {}", v.x, v.y, v.z); return std::format_to(ctx.out(), "{}, {}, {}", v.x, v.y, v.z);
} }
}; };
template <typename T, typename CharT> template <typename T, typename CharT>
struct std::formatter<amy::vec4<T>, CharT> : std::formatter<T, CharT> { struct std::formatter<Amy::vec4<T>, CharT> : std::formatter<T, CharT> {
template <typename FormatContext> template <typename FormatContext>
auto format(const amy::vec4<T> &v, FormatContext &ctx) const { auto format(const Amy::vec4<T>& v, FormatContext& ctx) const {
return std::format_to(ctx.out(), "{}, {}, {}, {}", v.x, v.y, v.z, v.w); return std::format_to(ctx.out(), "{}, {}, {}, {}", v.x, v.y, v.z, v.w);
} }
}; };

View File

@@ -27,8 +27,9 @@ SOFTWARE.
#include <cmath> #include <cmath>
namespace amy { namespace Amy {
template <typename T> class vec2 { template <typename T>
class vec2 {
public: public:
T x; T x;
T y; T y;
@@ -36,12 +37,14 @@ public:
// Constructors // Constructors
constexpr vec2() : x(0), y(0) {} constexpr vec2() : x(0), y(0) {}
template <typename T1> constexpr vec2(T1 v) { template <typename T1>
constexpr vec2(T1 v) {
x = (T)v; x = (T)v;
y = (T)v; y = (T)v;
} }
template <typename T1> constexpr vec2(const vec2<T1> &v) { template <typename T1>
constexpr vec2(const vec2<T1>& v) {
x = (T)v.x; x = (T)v.x;
y = (T)v.y; y = (T)v.y;
} }
@@ -50,93 +53,111 @@ public:
// Operations // Operations
template <typename T1> vec2<T> &operator+=(T1 v) { template <typename T1>
vec2<T>& operator+=(T1 v) {
x += (T)v; x += (T)v;
y += (T)v; y += (T)v;
return *this; return *this;
} }
template <typename T1> vec2<T> &operator+=(const vec2<T1> &v) { template <typename T1>
vec2<T>& operator+=(const vec2<T1>& v) {
x += (T)v.x; x += (T)v.x;
y += (T)v.y; y += (T)v.y;
return *this; return *this;
} }
template <typename T1> vec2<T> operator+(T1 v) const { template <typename T1>
vec2<T> operator+(T1 v) const {
return vec2<T>(x + (T)v, y + (T)v); return vec2<T>(x + (T)v, y + (T)v);
} }
template <typename T1> vec2<T> operator+(const vec2<T1> &v) const { template <typename T1>
vec2<T> operator+(const vec2<T1>& v) const {
return vec2<T>(x + (T)v.x, y + (T)v.y); return vec2<T>(x + (T)v.x, y + (T)v.y);
} }
template <typename T1> vec2<T> &operator-=(T1 v) { template <typename T1>
vec2<T>& operator-=(T1 v) {
x -= (T)v; x -= (T)v;
y -= (T)v; y -= (T)v;
return *this; return *this;
} }
template <typename T1> vec2<T> &operator-=(const vec2<T1> &v) { template <typename T1>
vec2<T>& operator-=(const vec2<T1>& v) {
x -= (T)v.x; x -= (T)v.x;
y -= (T)v.y; y -= (T)v.y;
return *this; return *this;
} }
template <typename T1> vec2<T> operator-(T1 v) const { template <typename T1>
vec2<T> operator-(T1 v) const {
return vec2<T>(x - (T)v, y - (T)v); return vec2<T>(x - (T)v, y - (T)v);
} }
template <typename T1> vec2<T> operator-(const vec2<T1> &v) const { template <typename T1>
vec2<T> operator-(const vec2<T1>& v) const {
return vec2<T>(x - (T)v.x, y - (T)v.y); return vec2<T>(x - (T)v.x, y - (T)v.y);
} }
template <typename T1> vec2<T> &operator*=(T1 v) { template <typename T1>
vec2<T>& operator*=(T1 v) {
x *= (T)v; x *= (T)v;
y *= (T)v; y *= (T)v;
return *this; return *this;
} }
template <typename T1> vec2<T> &operator*=(const vec2<T1> &v) { template <typename T1>
vec2<T>& operator*=(const vec2<T1>& v) {
x *= (T)v.x; x *= (T)v.x;
y *= (T)v.y; y *= (T)v.y;
return *this; return *this;
} }
template <typename T1> vec2<T> operator*(T1 v) const { template <typename T1>
vec2<T> operator*(T1 v) const {
return vec2<T>(x * (T)v, y * (T)v); return vec2<T>(x * (T)v, y * (T)v);
} }
template <typename T1> vec2<T> operator*(const vec2<T1> &v) const { template <typename T1>
vec2<T> operator*(const vec2<T1>& v) const {
return vec2<T>(x * (T)v.x, y * (T)v.y); return vec2<T>(x * (T)v.x, y * (T)v.y);
} }
template <typename T1> vec2<T> &operator/=(T1 v) { template <typename T1>
vec2<T>& operator/=(T1 v) {
x /= (T)v; x /= (T)v;
y /= (T)v; y /= (T)v;
return *this; return *this;
} }
template <typename T1> vec2<T> &operator/=(const vec2<T1> &v) { template <typename T1>
vec2<T>& operator/=(const vec2<T1>& v) {
x /= (T)v.x; x /= (T)v.x;
y /= (T)v.y; y /= (T)v.y;
return *this; return *this;
} }
template <typename T1> vec2<T> operator/(T1 v) const { template <typename T1>
vec2<T> operator/(T1 v) const {
return vec2<T>(x / (T)v, y / (T)v); return vec2<T>(x / (T)v, y / (T)v);
} }
template <typename T1> vec2<T> operator/(const vec2<T1> &v) const { template <typename T1>
vec2<T> operator/(const vec2<T1>& v) const {
return vec2<T>(x / (T)v.x, y / (T)v.y); return vec2<T>(x / (T)v.x, y / (T)v.y);
} }
// Generic Operations // Generic Operations
vec2 operator-() const { return vec2(-x, -y); } vec2 operator-() const { return vec2(-x, -y); }
template <typename T1> bool operator==(const vec2<T1> &v) const { template <typename T1>
bool operator==(const vec2<T1>& v) const {
return x == (T)v.x && y == (T)v.y; return x == (T)v.x && y == (T)v.y;
} }
template <typename T1> bool operator!=(const vec2<T1> &v) const { template <typename T1>
bool operator!=(const vec2<T1>& v) const {
return !(*this == v); return !(*this == v);
} }
@@ -145,7 +166,8 @@ public:
double Len() const { return std::sqrt(SqLen()); } double Len() const { return std::sqrt(SqLen()); }
double SqLen() const { return x * x + y * y; } double SqLen() const { return x * x + y * y; }
template <typename T1> double Distance(const vec2<T1> &v) const { template <typename T1>
double Distance(const vec2<T1>& v) const {
return (*this - v).Len(); return (*this - v).Len();
} }
@@ -157,7 +179,8 @@ public:
return *this / (T)l; return *this / (T)l;
} }
template <typename T1> T Dot(const vec2<T1> &v) const { template <typename T1>
T Dot(const vec2<T1>& v) const {
return x * (T)v.x + y * (T)v.y; return x * (T)v.x + y * (T)v.y;
} }
@@ -171,4 +194,4 @@ public:
using fvec2 = vec2<float>; using fvec2 = vec2<float>;
using ivec2 = vec2<int>; using ivec2 = vec2<int>;
using dvec2 = vec2<double>; using dvec2 = vec2<double>;
} // namespace amy } // namespace Amy

View File

@@ -29,8 +29,9 @@ SOFTWARE.
// Extended includes (rename if you use other filenames/paths) // Extended includes (rename if you use other filenames/paths)
#include <amethyst/maths/vec2.hpp> #include <amethyst/maths/vec2.hpp>
namespace amy { namespace Amy {
template <typename T> class vec3 { template <typename T>
class vec3 {
public: public:
T x; T x;
T y; T y;
@@ -39,13 +40,15 @@ public:
// Constructors // Constructors
constexpr vec3() : x(0), y(0), z(0) {} constexpr vec3() : x(0), y(0), z(0) {}
template <typename T1> constexpr vec3(T1 v) { template <typename T1>
constexpr vec3(T1 v) {
x = (T)v; x = (T)v;
y = (T)v; y = (T)v;
z = (T)v; z = (T)v;
} }
template <typename T1> constexpr vec3(const vec3<T1> &v) { template <typename T1>
constexpr vec3(const vec3<T1>& v) {
x = (T)v.x; x = (T)v.x;
y = (T)v.y; y = (T)v.y;
z = (T)v.z; z = (T)v.z;
@@ -54,7 +57,8 @@ public:
constexpr explicit vec3(T x, T y, T z) : x(x), y(y), z(z) {} constexpr explicit vec3(T x, T y, T z) : x(x), y(y), z(z) {}
// Extended Constructors // Extended Constructors
template <typename T1> constexpr explicit vec3(const vec2<T1> &xy, T1 z) { template <typename T1>
constexpr explicit vec3(const vec2<T1>& xy, T1 z) {
{ {
x = (T)xy.x; x = (T)xy.x;
y = (T)xy.y; y = (T)xy.y;
@@ -64,101 +68,119 @@ public:
// Operations // Operations
template <typename T1> vec3<T> &operator+=(T1 v) { template <typename T1>
vec3<T>& operator+=(T1 v) {
x += (T)v; x += (T)v;
y += (T)v; y += (T)v;
z += (T)v; z += (T)v;
return *this; return *this;
} }
template <typename T1> vec3<T> &operator+=(const vec3<T1> &v) { template <typename T1>
vec3<T>& operator+=(const vec3<T1>& v) {
x += (T)v.x; x += (T)v.x;
y += (T)v.y; y += (T)v.y;
z += (T)v.z; z += (T)v.z;
return *this; return *this;
} }
template <typename T1> vec3<T> operator+(T1 v) const { template <typename T1>
vec3<T> operator+(T1 v) const {
return vec3<T>(x + (T)v, y + (T)v, z + (T)v); return vec3<T>(x + (T)v, y + (T)v, z + (T)v);
} }
template <typename T1> vec3<T> operator+(const vec3<T1> &v) const { template <typename T1>
vec3<T> operator+(const vec3<T1>& v) const {
return vec3<T>(x + (T)v.x, y + (T)v.y, z + (T)v.z); return vec3<T>(x + (T)v.x, y + (T)v.y, z + (T)v.z);
} }
template <typename T1> vec3<T> &operator-=(T1 v) { template <typename T1>
vec3<T>& operator-=(T1 v) {
x -= (T)v; x -= (T)v;
y -= (T)v; y -= (T)v;
z -= (T)v; z -= (T)v;
return *this; return *this;
} }
template <typename T1> vec3<T> &operator-=(const vec3<T1> &v) { template <typename T1>
vec3<T>& operator-=(const vec3<T1>& v) {
x -= (T)v.x; x -= (T)v.x;
y -= (T)v.y; y -= (T)v.y;
z -= (T)v.z; z -= (T)v.z;
return *this; return *this;
} }
template <typename T1> vec3<T> operator-(T1 v) const { template <typename T1>
vec3<T> operator-(T1 v) const {
return vec3<T>(x - (T)v, y - (T)v, z - (T)v); return vec3<T>(x - (T)v, y - (T)v, z - (T)v);
} }
template <typename T1> vec3<T> operator-(const vec3<T1> &v) const { template <typename T1>
vec3<T> operator-(const vec3<T1>& v) const {
return vec3<T>(x - (T)v.x, y - (T)v.y, z - (T)v.z); return vec3<T>(x - (T)v.x, y - (T)v.y, z - (T)v.z);
} }
template <typename T1> vec3<T> &operator*=(T1 v) { template <typename T1>
vec3<T>& operator*=(T1 v) {
x *= (T)v; x *= (T)v;
y *= (T)v; y *= (T)v;
z *= (T)v; z *= (T)v;
return *this; return *this;
} }
template <typename T1> vec3<T> &operator*=(const vec3<T1> &v) { template <typename T1>
vec3<T>& operator*=(const vec3<T1>& v) {
x *= (T)v.x; x *= (T)v.x;
y *= (T)v.y; y *= (T)v.y;
z *= (T)v.z; z *= (T)v.z;
return *this; return *this;
} }
template <typename T1> vec3<T> operator*(T1 v) const { template <typename T1>
vec3<T> operator*(T1 v) const {
return vec3<T>(x * (T)v, y * (T)v, z * (T)v); return vec3<T>(x * (T)v, y * (T)v, z * (T)v);
} }
template <typename T1> vec3<T> operator*(const vec3<T1> &v) const { template <typename T1>
vec3<T> operator*(const vec3<T1>& v) const {
return vec3<T>(x * (T)v.x, y * (T)v.y, z * (T)v.z); return vec3<T>(x * (T)v.x, y * (T)v.y, z * (T)v.z);
} }
template <typename T1> vec3<T> &operator/=(T1 v) { template <typename T1>
vec3<T>& operator/=(T1 v) {
x /= (T)v; x /= (T)v;
y /= (T)v; y /= (T)v;
z /= (T)v; z /= (T)v;
return *this; return *this;
} }
template <typename T1> vec3<T> &operator/=(const vec3<T1> &v) { template <typename T1>
vec3<T>& operator/=(const vec3<T1>& v) {
x /= (T)v.x; x /= (T)v.x;
y /= (T)v.y; y /= (T)v.y;
z /= (T)v.z; z /= (T)v.z;
return *this; return *this;
} }
template <typename T1> vec3<T> operator/(T1 v) const { template <typename T1>
vec3<T> operator/(T1 v) const {
return vec3<T>(x / (T)v, y / (T)v, z / (T)v); return vec3<T>(x / (T)v, y / (T)v, z / (T)v);
} }
template <typename T1> vec3<T> operator/(const vec3<T1> &v) const { template <typename T1>
vec3<T> operator/(const vec3<T1>& v) const {
return vec3<T>(x / (T)v.x, y / (T)v.y, z / (T)v.z); return vec3<T>(x / (T)v.x, y / (T)v.y, z / (T)v.z);
} }
// Generic Operations // Generic Operations
vec3 operator-() const { return vec3(-x, -y, -z); } vec3 operator-() const { return vec3(-x, -y, -z); }
template <typename T1> bool operator==(const vec3<T1> &v) const { template <typename T1>
bool operator==(const vec3<T1>& v) const {
return x == (T)v.x && y == (T)v.y && z == (T)v.z; return x == (T)v.x && y == (T)v.y && z == (T)v.z;
} }
template <typename T1> bool operator!=(const vec3<T1> &v) const { template <typename T1>
bool operator!=(const vec3<T1>& v) const {
return !(*this == v); return !(*this == v);
} }
@@ -167,7 +189,8 @@ public:
double Len() const { return std::sqrt(SqLen()); } double Len() const { return std::sqrt(SqLen()); }
double SqLen() const { return x * x + y * y + z * z; } double SqLen() const { return x * x + y * y + z * z; }
template <typename T1> double Distance(const vec3<T1> &v) const { template <typename T1>
double Distance(const vec3<T1>& v) const {
return (*this - v).Len(); return (*this - v).Len();
} }
@@ -179,11 +202,13 @@ public:
return *this / (T)l; return *this / (T)l;
} }
template <typename T1> T Dot(const vec3<T1> &v) const { template <typename T1>
T Dot(const vec3<T1>& v) const {
return x * (T)v.x + y * (T)v.y + z * (T)v.z; return x * (T)v.x + y * (T)v.y + z * (T)v.z;
} }
template <typename T1> vec3<T> Cross(const vec3<T1> &v) const { template <typename T1>
vec3<T> Cross(const vec3<T1>& v) const {
return vec3<T>(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x); return vec3<T>(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x);
} }
@@ -207,4 +232,4 @@ public:
using fvec3 = vec3<float>; using fvec3 = vec3<float>;
using ivec3 = vec3<int>; using ivec3 = vec3<int>;
using dvec3 = vec3<double>; using dvec3 = vec3<double>;
} // namespace amy } // namespace Amy

View File

@@ -30,8 +30,9 @@ SOFTWARE.
#include <amethyst/maths/vec2.hpp> #include <amethyst/maths/vec2.hpp>
#include <amethyst/maths/vec3.hpp> #include <amethyst/maths/vec3.hpp>
namespace amy { namespace Amy {
template <typename T> class vec4 { template <typename T>
class vec4 {
public: public:
T x; T x;
T y; T y;
@@ -41,14 +42,16 @@ public:
// Constructors // Constructors
constexpr vec4() : x(0), y(0), z(0), w(0) {} constexpr vec4() : x(0), y(0), z(0), w(0) {}
template <typename T1> constexpr vec4(T1 v) { template <typename T1>
constexpr vec4(T1 v) {
x = (T)v; x = (T)v;
y = (T)v; y = (T)v;
z = (T)v; z = (T)v;
w = (T)v; w = (T)v;
} }
template <typename T1> constexpr vec4(const vec4<T1> &v) { template <typename T1>
constexpr vec4(const vec4<T1>& v) {
x = (T)v.x; x = (T)v.x;
y = (T)v.y; y = (T)v.y;
z = (T)v.z; z = (T)v.z;
@@ -68,7 +71,8 @@ public:
} }
} }
template <typename T1> constexpr explicit vec4(const vec3<T1> &xyz, T1 w) { template <typename T1>
constexpr explicit vec4(const vec3<T1>& xyz, T1 w) {
{ {
x = (T)xyz.x; x = (T)xyz.x;
y = (T)xyz.y; y = (T)xyz.y;
@@ -79,7 +83,8 @@ public:
// Operations // Operations
template <typename T1> vec4<T> &operator+=(T1 v) { template <typename T1>
vec4<T>& operator+=(T1 v) {
x += (T)v; x += (T)v;
y += (T)v; y += (T)v;
z += (T)v; z += (T)v;
@@ -87,7 +92,8 @@ public:
return *this; return *this;
} }
template <typename T1> vec4<T> &operator+=(const vec4<T1> &v) { template <typename T1>
vec4<T>& operator+=(const vec4<T1>& v) {
x += (T)v.x; x += (T)v.x;
y += (T)v.y; y += (T)v.y;
z += (T)v.z; z += (T)v.z;
@@ -95,15 +101,18 @@ public:
return *this; return *this;
} }
template <typename T1> vec4<T> operator+(T1 v) const { template <typename T1>
vec4<T> operator+(T1 v) const {
return vec4<T>(x + (T)v, y + (T)v, z + (T)v, w + (T)v); return vec4<T>(x + (T)v, y + (T)v, z + (T)v, w + (T)v);
} }
template <typename T1> vec4<T> operator+(const vec4<T1> &v) const { template <typename T1>
vec4<T> operator+(const vec4<T1>& v) const {
return vec4<T>(x + (T)v.x, y + (T)v.y, z + (T)v.z, w + (T)v.w); return vec4<T>(x + (T)v.x, y + (T)v.y, z + (T)v.z, w + (T)v.w);
} }
template <typename T1> vec4<T> &operator-=(T1 v) { template <typename T1>
vec4<T>& operator-=(T1 v) {
x -= (T)v; x -= (T)v;
y -= (T)v; y -= (T)v;
z -= (T)v; z -= (T)v;
@@ -111,7 +120,8 @@ public:
return *this; return *this;
} }
template <typename T1> vec4<T> &operator-=(const vec4<T1> &v) { template <typename T1>
vec4<T>& operator-=(const vec4<T1>& v) {
x -= (T)v.x; x -= (T)v.x;
y -= (T)v.y; y -= (T)v.y;
z -= (T)v.z; z -= (T)v.z;
@@ -119,15 +129,18 @@ public:
return *this; return *this;
} }
template <typename T1> vec4<T> operator-(T1 v) const { template <typename T1>
vec4<T> operator-(T1 v) const {
return vec4<T>(x - (T)v, y - (T)v, z - (T)v, w - (T)v); return vec4<T>(x - (T)v, y - (T)v, z - (T)v, w - (T)v);
} }
template <typename T1> vec4<T> operator-(const vec4<T1> &v) const { template <typename T1>
vec4<T> operator-(const vec4<T1>& v) const {
return vec4<T>(x - (T)v.x, y - (T)v.y, z - (T)v.z, w - (T)v.w); return vec4<T>(x - (T)v.x, y - (T)v.y, z - (T)v.z, w - (T)v.w);
} }
template <typename T1> vec4<T> &operator*=(T1 v) { template <typename T1>
vec4<T>& operator*=(T1 v) {
x *= (T)v; x *= (T)v;
y *= (T)v; y *= (T)v;
z *= (T)v; z *= (T)v;
@@ -135,7 +148,8 @@ public:
return *this; return *this;
} }
template <typename T1> vec4<T> &operator*=(const vec4<T1> &v) { template <typename T1>
vec4<T>& operator*=(const vec4<T1>& v) {
x *= (T)v.x; x *= (T)v.x;
y *= (T)v.y; y *= (T)v.y;
z *= (T)v.z; z *= (T)v.z;
@@ -143,15 +157,18 @@ public:
return *this; return *this;
} }
template <typename T1> vec4<T> operator*(T1 v) const { template <typename T1>
vec4<T> operator*(T1 v) const {
return vec4<T>(x * (T)v, y * (T)v, z * (T)v, w * (T)v); return vec4<T>(x * (T)v, y * (T)v, z * (T)v, w * (T)v);
} }
template <typename T1> vec4<T> operator*(const vec4<T1> &v) const { template <typename T1>
vec4<T> operator*(const vec4<T1>& v) const {
return vec4<T>(x * (T)v.x, y * (T)v.y, z * (T)v.z, w * (T)v.w); return vec4<T>(x * (T)v.x, y * (T)v.y, z * (T)v.z, w * (T)v.w);
} }
template <typename T1> vec4<T> &operator/=(T1 v) { template <typename T1>
vec4<T>& operator/=(T1 v) {
x /= (T)v; x /= (T)v;
y /= (T)v; y /= (T)v;
z /= (T)v; z /= (T)v;
@@ -159,7 +176,8 @@ public:
return *this; return *this;
} }
template <typename T1> vec4<T> &operator/=(const vec4<T1> &v) { template <typename T1>
vec4<T>& operator/=(const vec4<T1>& v) {
x /= (T)v.x; x /= (T)v.x;
y /= (T)v.y; y /= (T)v.y;
z /= (T)v.z; z /= (T)v.z;
@@ -167,21 +185,25 @@ public:
return *this; return *this;
} }
template <typename T1> vec4<T> operator/(T1 v) const { template <typename T1>
vec4<T> operator/(T1 v) const {
return vec4<T>(x / (T)v, y / (T)v, z / (T)v, w / (T)v); return vec4<T>(x / (T)v, y / (T)v, z / (T)v, w / (T)v);
} }
template <typename T1> vec4<T> operator/(const vec4<T1> &v) const { template <typename T1>
vec4<T> operator/(const vec4<T1>& v) const {
return vec4<T>(x / (T)v.x, y / (T)v.y, z / (T)v.z, w / (T)v.w); return vec4<T>(x / (T)v.x, y / (T)v.y, z / (T)v.z, w / (T)v.w);
} }
// Generic Operations // Generic Operations
vec4 operator-() const { return vec4(-x, -y, -z, -w); } vec4 operator-() const { return vec4(-x, -y, -z, -w); }
template <typename T1> bool operator==(const vec4<T1> &v) const { template <typename T1>
bool operator==(const vec4<T1>& v) const {
return x == (T)v.x && y == (T)v.y && z == (T)v.z && w == (T)v.w; return x == (T)v.x && y == (T)v.y && z == (T)v.z && w == (T)v.w;
} }
template <typename T1> bool operator!=(const vec4<T1> &v) const { template <typename T1>
bool operator!=(const vec4<T1>& v) const {
return !(*this == v); return !(*this == v);
} }
@@ -190,7 +212,8 @@ public:
double Len() const { return std::sqrt(SqLen()); } double Len() const { return std::sqrt(SqLen()); }
double SqLen() const { return x * x + y * y + z * z + w * w; } double SqLen() const { return x * x + y * y + z * z + w * w; }
template <typename T1> double Distance(const vec4<T1> &v) const { template <typename T1>
double Distance(const vec4<T1>& v) const {
return (*this - v).Len(); return (*this - v).Len();
} }
@@ -202,7 +225,8 @@ public:
return *this / (T)l; return *this / (T)l;
} }
template <typename T1> T Dot(const vec4<T1> &v) const { template <typename T1>
T Dot(const vec4<T1>& v) const {
return x * (T)v.x + y * (T)v.y + z * (T)v.z + w * (T)v.w; return x * (T)v.x + y * (T)v.y + z * (T)v.z + w * (T)v.w;
} }
@@ -241,4 +265,4 @@ public:
using fvec4 = vec4<float>; using fvec4 = vec4<float>;
using ivec4 = vec4<int>; using ivec4 = vec4<int>;
using dvec4 = vec4<double>; using dvec4 = vec4<double>;
} // namespace amy } // namespace Amy

View File

@@ -2,60 +2,60 @@
#include <amethyst/types.hpp> #include <amethyst/types.hpp>
namespace amy { namespace Amy {
class rect { class Rect {
public: public:
rect() : m_top(0), m_bot(0) {} Rect() : pTop(0), pBot(0) {}
~rect() = default; ~Rect() = default;
rect(const fvec4& t, const fvec4& b) : m_top(t), m_bot(b) {} Rect(const fvec4& t, const fvec4& b) : pTop(t), pBot(b) {}
rect(const fvec2& tl, const fvec2& tr, const fvec2& bl, const fvec2& br) Rect(const fvec2& tl, const fvec2& tr, const fvec2& bl, const fvec2& br)
: m_top(tl, tr), m_bot(bl, br) {} : pTop(tl, tr), pBot(bl, br) {}
rect(const fvec4& duv) Rect(const fvec4& duv)
: m_top(duv.x, duv.y, duv.z, duv.y), m_bot(duv.x, duv.w, duv.z, duv.w) {} : pTop(duv.x, duv.y, duv.z, duv.y), pBot(duv.x, duv.w, duv.z, duv.w) {}
fvec2 topLeft() const { return fvec2(m_top.x, m_top.y); } fvec2 TopLeft() const { return fvec2(pTop.x, pTop.y); }
fvec2 topRight() const { return fvec2(m_top.z, m_top.w); } fvec2 TopRight() const { return fvec2(pTop.z, pTop.w); }
fvec2 botLeft() const { return fvec2(m_bot.x, m_bot.y); } fvec2 BotLeft() const { return fvec2(pBot.x, pBot.y); }
fvec2 botRight() const { return fvec2(m_bot.z, m_bot.w); } fvec2 BotRight() const { return fvec2(pBot.z, pBot.w); }
fvec4 top() const { return m_top; } fvec4 Top() const { return pTop; }
fvec4& top() { return m_top; } fvec4& Top() { return pTop; }
fvec4 bot() const { return m_bot; } fvec4 Bot() const { return pBot; }
fvec4& bot() { return m_bot; } fvec4& Bot() { return pBot; }
rect& topLeft(const fvec2& v) { Rect& TopLeft(const fvec2& v) {
m_top.x = v.x; pTop.x = v.x;
m_top.y = v.y; pTop.y = v.y;
return *this; return *this;
} }
rect& topRight(const fvec2& v) { Rect& TopRight(const fvec2& v) {
m_top.z = v.x; pTop.z = v.x;
m_top.w = v.y; pTop.w = v.y;
return *this; return *this;
} }
rect& botLeft(const fvec2& v) { Rect& BotLeft(const fvec2& v) {
m_bot.x = v.x; pBot.x = v.x;
m_bot.y = v.y; pBot.y = v.y;
return *this; return *this;
} }
rect& botRight(const fvec2& v) { Rect& BotRight(const fvec2& v) {
m_bot.z = v.x; pBot.z = v.x;
m_bot.w = v.y; pBot.w = v.y;
return *this; return *this;
} }
void swapVec2XY() { void SwapVec2XY() {
m_top.SwapXY(); pTop.SwapXY();
m_top.SwapZW(); pTop.SwapZW();
m_bot.SwapXY(); pBot.SwapXY();
m_bot.SwapZW(); pBot.SwapZW();
} }
private: private:
fvec4 m_top; fvec4 pTop;
fvec4 m_bot; fvec4 pBot;
}; };
} // namespace amy } // namespace Amy

View File

@@ -1,9 +1,9 @@
#pragma once #pragma once
namespace amy { namespace Amy {
class Renderer { class Renderer {
public: public:
Renderer(); Renderer();
~Renderer(); ~Renderer();
}; };
} // namespace amys } // namespace Amy

View File

@@ -7,33 +7,33 @@
#include <amethyst/rect.hpp> #include <amethyst/rect.hpp>
#include <amethyst/types.hpp> #include <amethyst/types.hpp>
namespace amy { namespace Amy {
class texture : public asset { class Texture : public Asset {
public: public:
texture() = default; Texture() = default;
texture(cstr& path); Texture(ksr path);
~texture(); ~Texture();
void load(cstr& path); void Load(ksr path);
void load(const std::vector<uc>& pixels, int w, int h, int bpp = 4, void Load(kvr<uc> pixels, int w, int h, int bpp = 4,
image::format fmt = image::RGBA); Image::Format fmt = Image::RGBA);
void unload(); void Unload();
int w() const { return m_size.x; } int W() const { return pSize.x; }
int& w() { return m_size.x; } int& W() { return pSize.x; }
int h() const { return m_size.y; } int H() const { return pSize.y; }
int& h() { return m_size.y; } int& H() { return pSize.y; }
ivec2 size() const { return m_size; } ivec2 Size() const { return pSize; }
ivec2& size() { return m_size; } ivec2& Size() { return pSize; }
rect& uv() { return m_uv; } Rect& Uv() { return pUv; }
C3D_Tex* ptr() { return m_loaded ? &m_tex : nullptr; } C3D_Tex* Ptr() { return pLoaded ? &pTex : nullptr; }
void bind(int reg = 0); void Bind(int reg = 0);
private: private:
C3D_Tex m_tex; C3D_Tex pTex;
ivec2 m_size; ivec2 pSize;
rect m_uv; Rect pUv;
bool m_loaded = false; bool pLoaded = false;
}; };
} // namespace amy } // namespace Amy

View File

@@ -2,6 +2,7 @@
#include <algorithm> #include <algorithm>
#include <amethyst/maths/vec.hpp> #include <amethyst/maths/vec.hpp>
#include <chrono>
#include <cinttypes> #include <cinttypes>
#include <functional> #include <functional>
#include <map> #include <map>
@@ -12,18 +13,30 @@
#include <string> #include <string>
#include <vector> #include <vector>
namespace amy { namespace Amy {
using uc = unsigned char; using uc = unsigned char;
using us = unsigned short; using us = unsigned short;
using ui = unsigned int; using ui = unsigned int;
using ull = unsigned long long; using ull = unsigned long long;
// string
using str = std::string; using str = std::string;
using cstr = const std::string; // const string
using kstr = const std::string;
// const string reference
using ksr = const std::string&; using ksr = const std::string&;
// vector
template <typename T> template <typename T>
using vec = std::vector<T>; using vec = std::vector<T>;
// const vector reference
template <typename T> template <typename T>
using cvec = const std::vector<T>; using kvr = const std::vector<T>&;
// const vector
template <typename T>
using kvec = const std::vector<T>;
// unique pointer
template <typename T> template <typename T>
using up = std::unique_ptr<T>; using up = std::unique_ptr<T>;
} // namespace amy // shared pointer
template <typename T>
using sp = std::shared_ptr<T>;
} // namespace Amy

View File

@@ -2,17 +2,20 @@
#include <amethyst/types.hpp> #include <amethyst/types.hpp>
namespace amy { namespace Amy {
namespace utils { namespace Utils {
ui fastHash(cstr& s); ui FastHash(ksr s);
vec<uc> loadFile2Mem(cstr& path); vec<uc> LoadFile2Mem(ksr path);
ui hashMemory(cvec<uc>& data); ui HashMemory(kvr<uc> data);
ui nextPow2(ui v); ui NextPow2(ui v);
bool isSingleBitNum(ui v); bool IsSingleBitNum(ui v);
namespace image { ull GetTimeNano();
void reverseBuf(vec<uc>& buf, int w, int h, int c); ull GetTimeMicro();
void removeAlphaChannel(vec<uc>& buf, int w, int h); ull GetTimeMilli();
void addAlphaChannel(vec<uc>& buf, int w, int h); namespace Image {
} // namespace image void ReverseBuf(vec<uc>& buf, int w, int h, int c);
} // namespace utils void RemoveAlphaChannel(vec<uc>& buf, int w, int h);
} // namespace amy void AddAlphaChannel(vec<uc>& buf, int w, int h);
} // namespace Image
} // namespace Utils
} // namespace Amy

View File

@@ -26,10 +26,10 @@ void NpiD7CxxExceptionHandler() {
} }
#endif #endif
namespace amy { namespace Amy {
void registerCxxExceptionHandler() { void RegisterCxxExceptionHandler() {
#ifdef AMY_3DS #ifdef AMY_3DS
std::set_terminate(NpiD7CxxExceptionHandler); std::set_terminate(NpiD7CxxExceptionHandler);
#endif #endif
} }
} // namespace amy } // namespace Amy

View File

@@ -2,14 +2,20 @@
#include <amethyst/app.hpp> #include <amethyst/app.hpp>
#include <amethyst/ctru.hpp> #include <amethyst/ctru.hpp>
#include <amethyst/utils.hpp>
namespace amy { namespace Amy {
void app::run() { void App::Run() {
pLast = Utils::GetTimeNano();
consoleInit(GFX_BOTTOM, NULL);
while (aptMainLoop()) { while (aptMainLoop()) {
ull c = ctru::getTime(); ull c = Utils::GetTimeNano();
m_delta = static_cast<double>(c) - static_cast<float>(m_last); pDelta = static_cast<double>(static_cast<double>(c) -
m_last = c; static_cast<double>(pLast)) *
main(); 0.000001;
pTime += pDelta * 0.001;
pLast = c;
Main();
} }
} }
} // namespace amy } // namespace Amy

View File

@@ -4,131 +4,131 @@
#include <amethyst/utils.hpp> #include <amethyst/utils.hpp>
#include <pica.hpp> #include <pica.hpp>
namespace amy { namespace Amy {
const auto DISPLAY_TRANSFER_FLAGS = const auto DISPLAY_TRANSFER_FLAGS =
GX_TRANSFER_FLIP_VERT(0) | GX_TRANSFER_OUT_TILED(0) | GX_TRANSFER_FLIP_VERT(0) | GX_TRANSFER_OUT_TILED(0) |
GX_TRANSFER_RAW_COPY(0) | GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_RAW_COPY(0) | GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) |
GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) |
GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO); GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO);
C3D_TexEnv* c3d::frag::m_env = nullptr; C3D_TexEnv* C3D::Frag::pEnv = nullptr;
int c3d::m_drawcalls = 0; int C3D::pDrawcalls = 0;
int c3d::m__dc__ = 0; int C3D::p__dc__ = 0;
void c3d::init() { C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); } void C3D::Init() { C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); }
void c3d::deinit() { C3D_Fini(); } void C3D::Deinit() { C3D_Fini(); }
void c3d::startFrame(bool sync) { void C3D::StartFrame(bool sync) {
C3D_FrameBegin(sync ? C3D_FRAME_SYNCDRAW : C3D_FRAME_NONBLOCK); C3D_FrameBegin(sync ? C3D_FRAME_SYNCDRAW : C3D_FRAME_NONBLOCK);
m__dc__ = 0; p__dc__ = 0;
} }
void c3d::endFrame() { void C3D::EndFrame() {
C3D_FrameEnd(0); C3D_FrameEnd(0);
m_drawcalls = m__dc__; pDrawcalls = p__dc__;
} }
c3d::screen* c3d::createScreen(gfxScreen_t screen, gfx3dSide_t side) { C3D::Screen* C3D::CreateScreen(gfxScreen_t screen, gfx3dSide_t side) {
auto t = C3D_RenderTargetCreate(240, screen == GFX_TOP ? 400 : 320, auto t = C3D_RenderTargetCreate(240, screen == GFX_TOP ? 400 : 320,
GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
C3D_RenderTargetSetOutput(t, screen, side, DISPLAY_TRANSFER_FLAGS); C3D_RenderTargetSetOutput(t, screen, side, DISPLAY_TRANSFER_FLAGS);
return new c3d::screen(t); return new C3D::Screen(t);
} }
void c3d::deleteScreen(c3d::screen* screen) { delete screen; } void C3D::DeleteScreen(C3D::Screen* screen) { delete screen; }
c3d::shader::shader(const std::string& path) { load(path); } C3D::Shader::Shader(const std::string& path) { Load(path); }
c3d::shader::~shader() {} C3D::Shader::~Shader() {}
void c3d::shader::load(const std::string& path) { void C3D::Shader::Load(const std::string& path) {
auto code = utils::loadFile2Mem(path); auto code = Utils::LoadFile2Mem(path);
if (!code.size()) { if (!code.size()) {
throw std::runtime_error( throw std::runtime_error(
std::format("[amy] unsable to load shader ({})", path)); std::format("[amy] unsable to load shader ({})", path));
} }
load(code); Load(code);
} }
void c3d::shader::load(const std::vector<uc>& data) { void C3D::Shader::Load(const std::vector<uc>& data) {
m_code = DVLB_ParseFile((u32*)&data[0], data.size()); pCode = DVLB_ParseFile((u32*)&data[0], data.size());
shaderProgramInit(&m_program); shaderProgramInit(&pProgram);
shaderProgramSetVsh(&m_program, &m_code->DVLE[0]); shaderProgramSetVsh(&pProgram, &pCode->DVLE[0]);
C3D_BindProgram(&m_program); C3D_BindProgram(&pProgram);
AttrInfo_Init(&m_info); AttrInfo_Init(&pInfo);
} }
void c3d::shader::compile(const std::string& code) { void C3D::Shader::Compile(const std::string& code) {
auto ret = Pica::AssembleCode(code.c_str()); auto ret = Pica::AssembleCode(code.c_str());
load(ret); Load(ret);
} }
void c3d::shader::use() { void C3D::Shader::Use() {
C3D_BindProgram(&m_program); C3D_BindProgram(&pProgram);
// for some reason i need both ??? // for some reason i need both ???
// code works perfectly without C3D_BindProgram // code works perfectly without C3D_BindProgram
// but nor withour shaderProgramUse ... // but nor withour shaderProgramUse ...
shaderProgramUse(&m_program); shaderProgramUse(&pProgram);
C3D_SetAttrInfo(&m_info); C3D_SetAttrInfo(&pInfo);
} }
void c3d::shader::setMat4(int loc, C3D_Mtx* m) { void C3D::Shader::SetMat4(int loc, C3D_Mtx* m) {
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, loc, m); C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, loc, m);
} }
void c3d::shader::setMat4(int loc, const mat4& m) { void C3D::Shader::SetMat4(int loc, const mat4& m) {
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, loc, (const C3D_Mtx*)&m); C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, loc, (const C3D_Mtx*)&m);
} }
int c3d::shader::loc(const std::string& name) { int C3D::Shader::loc(const std::string& name) {
return shaderInstanceGetUniformLocation(m_program.vertexShader, name.c_str()); return shaderInstanceGetUniformLocation(pProgram.vertexShader, name.c_str());
} }
void c3d::shader::input(int reg, GPU_FORMATS f, int num) { void C3D::Shader::Input(int reg, GPU_FORMATS f, int num) {
AttrInfo_AddLoader(&m_info, reg, f, num); AttrInfo_AddLoader(&pInfo, reg, f, num);
} }
void c3d::frag::src(C3D_TexEnvMode mode, GPU_TEVSRC s1, GPU_TEVSRC s2, void C3D::Frag::Src(C3D_TexEnvMode mode, GPU_TEVSRC s1, GPU_TEVSRC s2,
GPU_TEVSRC s3) { GPU_TEVSRC s3) {
C3D_TexEnvSrc(m_env, mode, s1, s2, s3); C3D_TexEnvSrc(pEnv, mode, s1, s2, s3);
} }
void c3d::frag::func(C3D_TexEnvMode mode, GPU_COMBINEFUNC func) { void C3D::Frag::Func(C3D_TexEnvMode mode, GPU_COMBINEFUNC func) {
C3D_TexEnvFunc(m_env, mode, func); C3D_TexEnvFunc(pEnv, mode, func);
} }
void c3d::frag::edit(int id) { void C3D::Frag::Edit(int id) {
m_env = C3D_GetTexEnv(id); pEnv = C3D_GetTexEnv(id);
C3D_TexEnvInit(m_env); C3D_TexEnvInit(pEnv);
} }
void c3d::drawArrays(int start, int count, GPU_Primitive_t prim) { void C3D::DrawArrays(int start, int count, GPU_Primitive_t prim) {
C3D_DrawArrays(prim, start, count); C3D_DrawArrays(prim, start, count);
m__dc__++; p__dc__++;
} }
void c3d::drawElements(int count, const void* idx_ptr, int type, void C3D::DrawElements(int count, const void* idx_ptr, int type,
GPU_Primitive_t prim) { GPU_Primitive_t prim) {
C3D_DrawElements(prim, count, type, idx_ptr); C3D_DrawElements(prim, count, type, idx_ptr);
m__dc__++; p__dc__++;
} }
void c3d::depthTest(bool on, GPU_TESTFUNC func, GPU_WRITEMASK mask) { void C3D::DepthTest(bool on, GPU_TESTFUNC func, GPU_WRITEMASK mask) {
C3D_DepthTest(on, func, mask); C3D_DepthTest(on, func, mask);
} }
void c3d::disableScissor() { C3D_SetScissor(GPU_SCISSOR_DISABLE, 0, 0, 0, 0); } void C3D::DisableScissor() { C3D_SetScissor(GPU_SCISSOR_DISABLE, 0, 0, 0, 0); }
void c3d::enableScissor(const ivec4 rect) { void C3D::EnableScissor(const ivec4 rect) {
C3D_SetScissor(GPU_SCISSOR_NORMAL, rect.x, rect.y, rect.z, rect.w); C3D_SetScissor(GPU_SCISSOR_NORMAL, rect.x, rect.y, rect.z, rect.w);
} }
void c3d::bufCfg(void* ptr, int stride, int shader_attribs, u64 permutation) { void C3D::BufCfg(void* ptr, int stride, int shader_attribs, u64 permutation) {
auto buf = C3D_GetBufInfo(); auto buf = C3D_GetBufInfo();
BufInfo_Init(buf); BufInfo_Init(buf);
BufInfo_Add(buf, ptr, stride, shader_attribs, permutation); BufInfo_Add(buf, ptr, stride, shader_attribs, permutation);
} }
void c3d::bufCfg(void* ptr, int stride, int shader_attribs) { void C3D::BufCfg(void* ptr, int stride, int shader_attribs) {
bufCfg(ptr, stride, shader_attribs, permutation(shader_attribs)); BufCfg(ptr, stride, shader_attribs, pPermutation(shader_attribs));
} }
} // namespace amy } // namespace Amy

View File

@@ -2,16 +2,16 @@
#include <amethyst/ctru.hpp> #include <amethyst/ctru.hpp>
namespace amy { namespace Amy {
namespace ctru { namespace Ctr {
void init(unsigned int srvs) { void Init(ui srvs) {
if (srvs & romfs) { if (srvs & Romfs) {
romfsInit(); romfsInit();
} }
if (srvs & gfx_def) { if (srvs & GfxDefault) {
gfxInitDefault(); gfxInitDefault();
} }
} }
ull getTime() { return osGetTime(); } ull GetTime() { return osGetTime(); }
} // namespace ctru } // namespace Ctr
} // namespace amy } // namespace Amy

View File

@@ -5,64 +5,63 @@
// #define STB_IMAGE_IMPLEMENTATION // #define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h> #include <stb_image.h>
namespace amy { namespace Amy {
void image::load(cstr& path) { void Image::Load(ksr path) {
int c = 0; int c = 0;
uc* buf = stbi_load(path.c_str(), &m_w, &m_h, &c, 4); uc* buf = stbi_load(path.c_str(), &pW, &pH, &c, 4);
if (c == 3) { if (c == 3) {
// Releoading the Image with tree channels requestet // Releoading the Image with tree channels requestet
// Still need to find a better way for this :( // Still need to find a better way for this :(
stbi_image_free(buf); stbi_image_free(buf);
buf = stbi_load(path.c_str(), &m_w, &m_h, &c, 3); buf = stbi_load(path.c_str(), &pW, &pH, &c, 3);
m_buffer.assign(buf, buf + (m_w * m_h * 3)); pBuffer.assign(buf, buf + (pW * pH * 3));
m_fmt = RGB; pFmt = RGB;
stbi_image_free(buf); stbi_image_free(buf);
} else if (c == 4) { } else if (c == 4) {
m_buffer.assign(buf, buf + (m_w * m_h * 4)); pBuffer.assign(buf, buf + (pW * pH * 4));
m_fmt = RGBA; pFmt = RGBA;
stbi_image_free(buf); stbi_image_free(buf);
} else { } else {
throw std::runtime_error(path + " is using an unsupported image format!"); throw std::runtime_error(path + " is using an unsupported image format!");
} }
} }
void image::load(const std::vector<uc>& data) { void Image::Load(const std::vector<uc>& data) {
int c = 0; int c = 0;
uc* buf = stbi_load_from_memory(data.data(), data.size(), &m_w, &m_h, &c, 4); uc* buf = stbi_load_from_memory(data.data(), data.size(), &pW, &pH, &c, 4);
if (c == 3) { if (c == 3) {
// Releoading the Image with tree channels requestet // Releoading the Image with tree channels requestet
// Still need to find a better way for this :( // Still need to find a better way for this :(
stbi_image_free(buf); stbi_image_free(buf);
buf = stbi_load_from_memory(data.data(), data.size(), &m_w, &m_h, &c, 3); buf = stbi_load_from_memory(data.data(), data.size(), &pW, &pH, &c, 3);
m_buffer.assign(buf, buf + (m_w * m_h * 3)); pBuffer.assign(buf, buf + (pW * pH * 3));
m_fmt = RGB; pFmt = RGB;
stbi_image_free(buf); stbi_image_free(buf);
} else if (m_fmt == 4) { } else if (pFmt == 4) {
m_buffer.assign(buf, buf + (m_w * m_h * 4)); pBuffer.assign(buf, buf + (pW * pH * 4));
m_fmt = RGBA; pFmt = RGBA;
stbi_image_free(buf); stbi_image_free(buf);
} else { } else {
throw std::runtime_error("image mem using an unsupported image format!"); throw std::runtime_error("image mem using an unsupported image format!");
} }
} }
void image::copy(const std::vector<uc>& pixels, int w, int h, void Image::Copy(kvr<uc> pixels, int w, int h, const Format& fmt) {
const format& fmt) { int f = GetBppOfFmt(fmt);
int f = getBppOfFmt(fmt);
if (pixels.size() != static_cast<size_t>(w * h * f)) { if (pixels.size() != static_cast<size_t>(w * h * f)) {
throw std::runtime_error("Connot copy image due to size error!"); throw std::runtime_error("Connot copy image due to size error!");
} }
m_fmt = fmt; pFmt = fmt;
m_w = w; pW = w;
m_h = h; pH = h;
m_buffer.clear(); pBuffer.clear();
m_buffer.resize(w * h * f); pBuffer.resize(w * h * f);
for (size_t i = 0; i < m_buffer.size(); i++) { for (size_t i = 0; i < pBuffer.size(); i++) {
m_buffer[i] = pixels[i]; pBuffer[i] = pixels[i];
} }
} }
int image::getBppOfFmt(const image::format& fmt) { int Image::GetBppOfFmt(const Image::Format& fmt) {
switch (fmt) { switch (fmt) {
case RGBA: case RGBA:
case ABGR: case ABGR:
@@ -83,28 +82,28 @@ int image::getBppOfFmt(const image::format& fmt) {
} }
} }
void image::convert(image& img, const format& dst) { void Image::Convert(Image& img, const Format& dst) {
if (img.m_fmt == dst) { if (img.pFmt == dst) {
return; return;
} else if (img.m_fmt == RGB && dst == BGR) { } else if (img.pFmt == RGB && dst == BGR) {
utils::image::reverseBuf(img.m_buffer, img.m_w, img.m_h, 3); Utils::Image::ReverseBuf(img.pBuffer, img.pW, img.pH, 3);
img.m_fmt = BGR; img.pFmt = BGR;
} else if (img.m_fmt == RGB && dst == RGBA) { } else if (img.pFmt == RGB && dst == RGBA) {
utils::image::addAlphaChannel(img.m_buffer, img.m_w, img.m_h); Utils::Image::AddAlphaChannel(img.pBuffer, img.pW, img.pH);
img.m_fmt = RGBA; img.pFmt = RGBA;
} else if (img.m_fmt == RGBA && dst == RGB) { } else if (img.pFmt == RGBA && dst == RGB) {
utils::image::removeAlphaChannel(img.m_buffer, img.m_w, img.m_h); Utils::Image::RemoveAlphaChannel(img.pBuffer, img.pW, img.pH);
img.m_fmt = RGB; img.pFmt = RGB;
} else if (img.m_fmt == RGBA && dst == ABGR) { } else if (img.pFmt == RGBA && dst == ABGR) {
utils::image::reverseBuf(img.m_buffer, img.m_w, img.m_h, 4); Utils::Image::ReverseBuf(img.pBuffer, img.pW, img.pH, 4);
img.m_fmt = ABGR; img.pFmt = ABGR;
} else if (img.m_fmt == RGB && dst == ABGR) { } else if (img.pFmt == RGB && dst == ABGR) {
convert(img, RGBA); Convert(img, RGBA);
convert(img, ABGR); Convert(img, ABGR);
} else if (img.m_fmt == RGBA && dst == RGB565) { } else if (img.pFmt == RGBA && dst == RGB565) {
convert(img, RGB); Convert(img, RGB);
convert(img, RGB565); Convert(img, RGB565);
} else if (img.m_fmt == RGB && dst == RGB565) { } else if (img.pFmt == RGB && dst == RGB565) {
// Inlined make pixel 565 func // Inlined make pixel 565 func
auto f = [](uc r, uc g, uc b) -> unsigned short { auto f = [](uc r, uc g, uc b) -> unsigned short {
unsigned short _r = (r >> 3); unsigned short _r = (r >> 3);
@@ -112,35 +111,35 @@ void image::convert(image& img, const format& dst) {
unsigned short _b = (b >> 3); unsigned short _b = (b >> 3);
return (_r << 11) | (_g << 5) | _b; return (_r << 11) | (_g << 5) | _b;
}; };
std::vector<uc> cpy = img.m_buffer; std::vector<uc> cpy = img.pBuffer;
img.m_buffer.resize(img.m_w * img.m_h * 2); img.pBuffer.resize(img.pW * img.pH * 2);
for (int y = 0; y < img.m_w; y++) { for (int y = 0; y < img.pW; y++) {
for (int x = 0; x < img.m_h; x++) { for (int x = 0; x < img.pH; x++) {
int src = (y * img.m_w + x) * 3; int src = (y * img.pW + x) * 3;
int dst = (y * img.m_w + x) * 2; int dst = (y * img.pW + x) * 2;
unsigned short new_px = f(cpy[src + 0], cpy[src + 1], cpy[src + 2]); unsigned short new_px = f(cpy[src + 0], cpy[src + 1], cpy[src + 2]);
img.m_buffer[dst + 0] = new_px >> 8; img.pBuffer[dst + 0] = new_px >> 8;
img.m_buffer[dst + 1] = new_px & 0xff; img.pBuffer[dst + 1] = new_px & 0xff;
} }
} }
img.m_fmt = RGB565; img.pFmt = RGB565;
} }
} }
void image::retile(image& img, std::function<ui(int x, int y, int w)> src, void Image::Retile(Image& img, std::function<ui(int x, int y, int w)> src,
std::function<ui(int x, int y, int w)> dst) { std::function<ui(int x, int y, int w)> dst) {
std::vector<uc> cpy = img.m_buffer; std::vector<uc> cpy = img.pBuffer;
/** could use fmt here but for 565 that woulnt work as it is not supported by /** could use fmt here but for 565 that woulnt work as it is not supported by
* file loading where fmt is used */ * file loading where fmt is used */
int bpp = img.bpp(); int bpp = img.Bpp();
for (int y = 0; y < img.m_h; y++) { for (int y = 0; y < img.pH; y++) {
for (int x = 0; x < img.m_w; x++) { for (int x = 0; x < img.pW; x++) {
int src_idx = src(x, y, img.m_w); int src_idx = src(x, y, img.pW);
int dst_idx = dst(x, y, img.m_w); int dst_idx = dst(x, y, img.pW);
for (int i = 0; i < bpp; i++) { for (int i = 0; i < bpp; i++) {
img.m_buffer[dst_idx + i] = cpy[src_idx + i]; img.pBuffer[dst_idx + i] = cpy[src_idx + i];
} }
} }
} }
} }
} // namespace amy } // namespace Amy

View File

@@ -1,7 +1,7 @@
#include <amethyst/iron.hpp> #include <amethyst/iron.hpp>
/** Setup for everything (oder so) */ /** Setup for everything (oder so) */
enum LiPathRectFlags_ : amy::ui { enum LiPathRectFlags_ : Amy::ui {
LiPathRectFlags_None = 0, LiPathRectFlags_None = 0,
LiPathRectFlags_KeepTopLeft = (1 << 0), LiPathRectFlags_KeepTopLeft = (1 << 0),
LiPathRectFlags_KeepTopRight = (1 << 1), LiPathRectFlags_KeepTopRight = (1 << 1),
@@ -13,69 +13,67 @@ enum LiPathRectFlags_ : amy::ui {
LiPathRectFlags_KeepRight = (1 << 1) | (1 << 2), LiPathRectFlags_KeepRight = (1 << 1) | (1 << 2),
}; };
namespace amy { namespace Amy {
constexpr auto __pi = std::numbers::pi; constexpr auto __pi = std::numbers::pi;
void iron::drawlist::merge(iron::drawlist* list) { void Iron::Drawlist::Merge(Iron::Drawlist* list) {
for (size_t i = 0; i < list->m_data.size(); i++) { for (size_t i = 0; i < list->pData.size(); i++) {
m_data.push_back(std::move(list->m_data[i])); pData.push_back(std::move(list->pData[i]));
} }
list->clear(); list->Clear();
} }
void iron::drawlist::clear() { m_data.clear(); } void Iron::Drawlist::Clear() { pData.clear(); }
iron::command::ref iron::drawlist::newCommand() { Iron::Command::ref Iron::Drawlist::NewCommand() {
auto ret = std::make_unique<command>(); auto ret = std::make_unique<Command>();
ret->layer = m_layer; ret->Layer = pLayer;
ret->index = m_data.size(); ret->Index = pData.size();
ret->tex = m_tex; ret->Tex = pTex;
return ret; return ret;
} }
void iron::drawlist::clipCmd(command* ptr) { void Iron::Drawlist::clipCmd(Command* ptr) {
if (!clipRects.empty()) { if (!ClipRects.empty()) {
ptr->scissorOn = true; ptr->ScissorOn = true;
ptr->scissorRect = ivec4(clipRects.top()); ptr->ScissorRect = ivec4(ClipRects.top());
} }
} }
void iron::drawlist::push(command::ref cmd) { void Iron::Drawlist::Push(Command::ref cmd) { pData.push_back(std::move(cmd)); }
m_data.push_back(std::move(cmd));
}
void iron::drawlist::drawSolid() { m_tex = iron::whiteTex(); } void Iron::Drawlist::DrawSolid() { pTex = Iron::WhiteTex(); }
void iron::drawlist::pathArcToN(const fvec2& c, float radius, float a_min, void Iron::Drawlist::PathArcToN(const fvec2& c, float radius, float a_min,
float a_max, int segments) { float a_max, int segments) {
// pathAdd(c) // pathAdd(c)
pathReserve(segments + 1); PathReserve(segments + 1);
for (int i = 0; i < segments; i++) { for (int i = 0; i < segments; i++) {
float a = a_min + ((float)i / (float)segments) * (a_max - a_min); float a = a_min + ((float)i / (float)segments) * (a_max - a_min);
pathAdd(fvec2(c.x + std::cos(a) * radius, c.y + std::sin(a) * radius)); PathAdd(fvec2(c.x + std::cos(a) * radius, c.y + std::sin(a) * radius));
} }
} }
void iron::drawlist::pathFastArcToN(const fvec2& c, float r, float amin, void Iron::Drawlist::PathFastArcToN(const fvec2& c, float r, float amin,
float amax, int s) { float amax, int s) {
/** /**
* Funcion with less division overhead * Funcion with less division overhead
* Usefull for stuff where a lot of calculations are required * Usefull for stuff where a lot of calculations are required
*/ */
float d = (amax - amin) / s; float d = (amax - amin) / s;
pathReserve(s + 1); PathReserve(s + 1);
for (int i = 0; i <= s; i++) { for (int i = 0; i <= s; i++) {
float a = amin + i * d; float a = amin + i * d;
pathAdd(fvec2(c.x + std::cos(a) * r, c.y + std::sin(a) * r)); PathAdd(fvec2(c.x + std::cos(a) * r, c.y + std::sin(a) * r));
} }
} }
void iron::drawlist::pathRect(const fvec2& a, const fvec2& b, float rounding) { void Iron::Drawlist::PathRect(const fvec2& a, const fvec2& b, float rounding) {
if (rounding == 0.f) { if (rounding == 0.f) {
pathAdd(a); PathAdd(a);
pathAdd(fvec2(b.x, a.y)); PathAdd(fvec2(b.x, a.y));
pathAdd(b); PathAdd(b);
pathAdd(fvec2(a.x, b.y)); PathAdd(fvec2(a.x, b.y));
} else { } else {
float r = std::min({rounding, (b.x - a.x) * 0.5f, (b.y - a.y) * 0.5f}); float r = std::min({rounding, (b.x - a.x) * 0.5f, (b.y - a.y) * 0.5f});
/** Calculate Optimal segment count automatically */ /** Calculate Optimal segment count automatically */
@@ -87,28 +85,28 @@ void iron::drawlist::pathRect(const fvec2& a, const fvec2& b, float rounding) {
* The Commands need to be setup clockwise * The Commands need to be setup clockwise
*/ */
/** Top Left */ /** Top Left */
pathAdd(fvec2(a.x + r, a.y)); PathAdd(fvec2(a.x + r, a.y));
pathFastArcToN(fvec2(b.x - r, a.y + r), r, -__pi / 2.0f, 0.0f, segments); PathFastArcToN(fvec2(b.x - r, a.y + r), r, -__pi / 2.0f, 0.0f, segments);
/** Top Right */ /** Top Right */
pathAdd(fvec2(b.x, b.y - r)); PathAdd(fvec2(b.x, b.y - r));
pathFastArcToN(fvec2(b.x - r, b.y - r), r, 0.0f, __pi / 2.0f, segments); PathFastArcToN(fvec2(b.x - r, b.y - r), r, 0.0f, __pi / 2.0f, segments);
/** Bottom Right */ /** Bottom Right */
pathAdd(fvec2(a.x + r, b.y)); PathAdd(fvec2(a.x + r, b.y));
pathFastArcToN(fvec2(a.x + r, b.y - r), r, __pi / 2.0f, __pi, segments); PathFastArcToN(fvec2(a.x + r, b.y - r), r, __pi / 2.0f, __pi, segments);
/** Bottom Left */ /** Bottom Left */
pathAdd(fvec2(a.x, a.y + r)); PathAdd(fvec2(a.x, a.y + r));
pathFastArcToN(fvec2(a.x + r, a.y + r), r, __pi, 3.0f * __pi / 2.0f, PathFastArcToN(fvec2(a.x + r, a.y + r), r, __pi, 3.0f * __pi / 2.0f,
segments); segments);
} }
} }
void iron::drawlist::pathRectEx(const fvec2& a, const fvec2& b, float rounding, void Iron::Drawlist::PathRectEx(const fvec2& a, const fvec2& b, float rounding,
ui flags) { ui flags) {
if (rounding == 0.f) { if (rounding == 0.f) {
pathAdd(a); PathAdd(a);
pathAdd(fvec2(b.x, a.y)); PathAdd(fvec2(b.x, a.y));
pathAdd(b); PathAdd(b);
pathAdd(fvec2(a.x, b.y)); PathAdd(fvec2(a.x, b.y));
} else { } else {
float r = std::min({rounding, (b.x - a.x) * 0.5f, (b.y - a.y) * 0.5f}); float r = std::min({rounding, (b.x - a.x) * 0.5f, (b.y - a.y) * 0.5f});
/** Calculate Optimal segment count automatically */ /** Calculate Optimal segment count automatically */
@@ -121,95 +119,95 @@ void iron::drawlist::pathRectEx(const fvec2& a, const fvec2& b, float rounding,
*/ */
/** Top Left */ /** Top Left */
if (flags & LiPathRectFlags_KeepTopLeft) { if (flags & LiPathRectFlags_KeepTopLeft) {
pathAdd(a); PathAdd(a);
} else { } else {
pathAdd(fvec2(a.x + r, a.y)); PathAdd(fvec2(a.x + r, a.y));
pathFastArcToN(fvec2(b.x - r, a.y + r), r, -__pi / 2.0f, 0.0f, segments); PathFastArcToN(fvec2(b.x - r, a.y + r), r, -__pi / 2.0f, 0.0f, segments);
} }
/** Top Right */ /** Top Right */
if (flags & LiPathRectFlags_KeepTopRight) { if (flags & LiPathRectFlags_KeepTopRight) {
pathAdd(fvec2(b.x, a.y)); PathAdd(fvec2(b.x, a.y));
} else { } else {
pathAdd(fvec2(b.x, b.y - r)); PathAdd(fvec2(b.x, b.y - r));
pathFastArcToN(fvec2(b.x - r, b.y - r), r, 0.0f, __pi / 2.0f, segments); PathFastArcToN(fvec2(b.x - r, b.y - r), r, 0.0f, __pi / 2.0f, segments);
} }
/** Bottom Right */ /** Bottom Right */
if (flags & LiPathRectFlags_KeepBotRight) { if (flags & LiPathRectFlags_KeepBotRight) {
pathAdd(b); PathAdd(b);
} else { } else {
pathAdd(fvec2(a.x + r, b.y)); PathAdd(fvec2(a.x + r, b.y));
pathFastArcToN(fvec2(a.x + r, b.y - r), r, __pi / 2.0f, __pi, segments); PathFastArcToN(fvec2(a.x + r, b.y - r), r, __pi / 2.0f, __pi, segments);
} }
/** Bottom Left */ /** Bottom Left */
if (flags & LiPathRectFlags_KeepBotLeft) { if (flags & LiPathRectFlags_KeepBotLeft) {
pathAdd(fvec2(a.x, b.y)); PathAdd(fvec2(a.x, b.y));
} else { } else {
pathAdd(fvec2(a.x, a.y + r)); PathAdd(fvec2(a.x, a.y + r));
pathFastArcToN(fvec2(a.x + r, a.y + r), r, __pi, 3.0f * __pi / 2.0f, PathFastArcToN(fvec2(a.x + r, a.y + r), r, __pi, 3.0f * __pi / 2.0f,
segments); segments);
} }
} }
} }
void iron::drawlist::drawRect(const fvec2& pos, const fvec2& size, ui color, void Iron::Drawlist::DrawRect(const fvec2& pos, const fvec2& size, ui color,
int thickness) { int thickness) {
pathRect(pos, pos + size); PathRect(pos, pos + size);
pathStroke(color, thickness, 1); PathStroke(color, thickness, 1);
} }
void iron::drawlist::drawRectFilled(const fvec2& pos, const fvec2& size, void Iron::Drawlist::DrawRectFilled(const fvec2& pos, const fvec2& size,
ui color) { ui color) {
pathRect(pos, pos + size); PathRect(pos, pos + size);
pathFill(color); PathFill(color);
} }
void iron::drawlist::drawTriangle(const fvec2& a, const fvec2& b, void Iron::Drawlist::DrawTriangle(const fvec2& a, const fvec2& b,
const fvec2& c, ui color, int thickness) { const fvec2& c, ui color, int thickness) {
pathAdd(a); PathAdd(a);
pathAdd(b); PathAdd(b);
pathAdd(c); PathAdd(c);
pathStroke(color, thickness, 1); PathStroke(color, thickness, 1);
} }
void iron::drawlist::drawTriangleFilled(const fvec2& a, const fvec2& b, void Iron::Drawlist::DrawTriangleFilled(const fvec2& a, const fvec2& b,
const fvec2& c, ui color) { const fvec2& c, ui color) {
pathAdd(a); PathAdd(a);
pathAdd(b); PathAdd(b);
pathAdd(c); PathAdd(c);
pathFill(color); PathFill(color);
} }
void iron::drawlist::drawCircle(const fvec2& center, float rad, ui color, void Iron::Drawlist::DrawCircle(const fvec2& center, float rad, ui color,
int segments, int thickness) { int segments, int thickness) {
if (segments <= 0) { if (segments <= 0) {
// Auto Segment // Auto Segment
} else { } else {
float am = (__pi * 2.0f) * ((float)segments) / (float)segments; float am = (__pi * 2.0f) * ((float)segments) / (float)segments;
pathArcToN(center, rad, 0.f, am, segments); PathArcToN(center, rad, 0.f, am, segments);
} }
drawSolid(); // Only Solid Color Supported DrawSolid(); // Only Solid Color Supported
pathStroke(color, thickness, 1); PathStroke(color, thickness, 1);
} }
void iron::drawlist::drawCircleFilled(const fvec2& center, float rad, ui color, void Iron::Drawlist::DrawCircleFilled(const fvec2& center, float rad, ui color,
int segments) { int segments) {
if (segments <= 0) { if (segments <= 0) {
// Auto Segment // Auto Segment
} else { } else {
float am = (__pi * 2.0f) * ((float)segments) / (float)segments; float am = (__pi * 2.0f) * ((float)segments) / (float)segments;
pathArcToN(center, rad, 0.f, am, segments); PathArcToN(center, rad, 0.f, am, segments);
} }
pathFill(color); PathFill(color);
} }
void iron::drawlist::drawPolyLine(const std::vector<fvec2>& points, ui clr, void Iron::Drawlist::DrawPolyLine(const std::vector<fvec2>& points, ui clr,
ui flags, int thickness) { ui flags, int thickness) {
if (points.size() < 2) { if (points.size() < 2) {
return; return;
} }
drawSolid(); DrawSolid();
auto cmd = newCommand(); auto cmd = NewCommand();
bool close = (flags & (1 << 0)); bool close = (flags & (1 << 0));
int num_points = close ? (int)points.size() : (int)points.size() - 1; int num_points = close ? (int)points.size() : (int)points.size() - 1;
if (flags & (1 << 1)) { if (flags & (1 << 1)) {
@@ -218,24 +216,24 @@ void iron::drawlist::drawPolyLine(const std::vector<fvec2>& points, ui clr,
// Non antialiased lines look awful when rendering with thickness != 1 // Non antialiased lines look awful when rendering with thickness != 1
for (int i = 0; i < num_points; i++) { for (int i = 0; i < num_points; i++) {
int j = (i + 1) == (int)points.size() ? 0 : (i + 1); int j = (i + 1) == (int)points.size() ? 0 : (i + 1);
auto line = primLine(points[i], points[j], thickness); auto line = PrimLine(points[i], points[j], thickness);
cmdQuad(cmd.get(), line, fvec4(0.f, 1.f, 1.f, 0.f), clr); CmdQuad(cmd.get(), line, fvec4(0.f, 1.f, 1.f, 0.f), clr);
} }
} }
push(std::move(cmd)); Push(std::move(cmd));
} }
void iron::drawlist::drawConvexPolyFilled(const std::vector<fvec2>& points, void Iron::Drawlist::DrawConvexPolyFilled(const std::vector<fvec2>& points,
ui clr) { ui clr) {
if (points.size() < 3) { if (points.size() < 3) {
return; // Need at least three points return; // Need at least three points
} }
auto cmd = newCommand(); auto cmd = NewCommand();
cmdConvexPolyFilled(cmd.get(), points, clr, m_tex); CmdConvexPolyFilled(cmd.get(), points, clr, pTex);
push(std::move(cmd)); Push(std::move(cmd));
} }
void iron::drawlist::drawText(const fvec2& pos, const std::string& text, void Iron::Drawlist::DrawText(const fvec2& pos, const std::string& text,
ui color) { ui color) {
/*if (!pCurrentFont) { /*if (!pCurrentFont) {
return; return;
@@ -243,13 +241,13 @@ void iron::drawlist::drawText(const fvec2& pos, const std::string& text,
std::vector<Command::Ref> cmds; std::vector<Command::Ref> cmds;
pCurrentFont->CmdTextEx(cmds, pos, color, pFontScale, text); pCurrentFont->CmdTextEx(cmds, pos, color, pFontScale, text);
for (size_t i = 0; i < cmds.size(); i++) { for (size_t i = 0; i < cmds.size(); i++) {
cmds[i]->Index = pDrawList.size(); cmds[i]->Index = pDrawlist.size();
cmds[i]->Layer = Layer; cmds[i]->Layer = Layer;
AddCommand(std::move(cmds[i])); AddCommand(std::move(cmds[i]));
}*/ }*/
} }
void iron::drawlist::drawTextEx(const fvec2& p, const std::string& text, void Iron::Drawlist::DrawTextEx(const fvec2& p, const std::string& text,
ui color, ui flags, const fvec2& box) { ui color, ui flags, const fvec2& box) {
/*if (!pCurrentFont) { /*if (!pCurrentFont) {
return; return;
@@ -257,15 +255,15 @@ void iron::drawlist::drawTextEx(const fvec2& p, const std::string& text,
std::vector<Command::Ref> cmds; std::vector<Command::Ref> cmds;
pCurrentFont->CmdTextEx(cmds, p, color, pFontScale, text, flags, box); pCurrentFont->CmdTextEx(cmds, p, color, pFontScale, text, flags, box);
for (size_t i = 0; i < cmds.size(); i++) { for (size_t i = 0; i < cmds.size(); i++) {
cmds[i]->Index = pDrawList.size(); cmds[i]->Index = pDrawlist.size();
cmds[i]->Layer = Layer; cmds[i]->Layer = Layer;
AddCommand(std::move(cmds[i])); AddCommand(std::move(cmds[i]));
}*/ }*/
} }
void iron::drawlist::drawLine(const fvec2& a, const fvec2& b, ui color, int t) { void Iron::Drawlist::DrawLine(const fvec2& a, const fvec2& b, ui color, int t) {
pathAdd(a); PathAdd(a);
pathAdd(b); PathAdd(b);
pathStroke(color, t); PathStroke(color, t);
} }
} // namespace amy } // namespace Amy

View File

@@ -14,7 +14,7 @@
} \ } \
}) })
namespace amy { namespace Amy {
const char* __ironshader__ = R"(; LI7 Shader const char* __ironshader__ = R"(; LI7 Shader
; Constants ; Constants
.constf myconst(0.0, 1.0, 0.00392156862745, 0.0) .constf myconst(0.0, 1.0, 0.00392156862745, 0.0)
@@ -56,117 +56,117 @@ unsigned char li_shader[] = {
}; };
// clang-format on // clang-format on
size_t li_shader_size = 0x124; size_t li_shader_size = 0x124;
std::vector<iron::vertex, linearAllocator<iron::vertex>> iron::m_vbuf; std::vector<Iron::Vertex, linearAllocator<Iron::Vertex>> Iron::m_vbuf;
std::vector<u16, linearAllocator<u16>> iron::m_ibuf; std::vector<u16, linearAllocator<u16>> Iron::m_ibuf;
int iron::uLocProj = 0; int Iron::uLocProj = 0;
c3d::shader* iron::m_shader = nullptr; C3D::Shader* Iron::m_shader = nullptr;
mat4 iron::m_mtx; mat4 Iron::m_mtx;
int iron::m_idx = 0, iron::m_vtx = 0; int Iron::m_idx = 0, Iron::m_vtx = 0;
texture* iron::m_solid = nullptr; Texture* Iron::m_solid = nullptr;
void iron::init() { void Iron::Init() {
setupShader(); pSetupShader();
m_vbuf.resize(4 * 4096); m_vbuf.resize(4 * 4096);
m_ibuf.resize(6 * 4096); m_ibuf.resize(6 * 4096);
initSolidTex(); pInitSolidTex();
} }
void iron::newFrame() { void Iron::NewFrame() {
m_idx = 0; m_idx = 0;
m_vtx = 0; m_vtx = 0;
} }
void iron::drawOn(c3d::screen* screen) { void Iron::DrawOn(C3D::Screen* screen) {
m_shader->use(); m_shader->Use();
m_mtx = mat4::ortho(0.f, (float)screen->width(), (float)screen->height(), 0.f, m_mtx = mat4::ortho(0.f, (float)screen->Width(), (float)screen->Height(), 0.f,
1.f, -1.f); 1.f, -1.f);
m_shader->setMat4(uLocProj, m_mtx); m_shader->SetMat4(uLocProj, m_mtx);
} }
void iron::draw(const std::vector<iron::command::ref>& data) { void Iron::Draw(const std::vector<Iron::Command::ref>& data) {
// disable depthtest cause we have no z buffer // disable depthtest cause we have no z buffer
c3d::depthTest(false); C3D::DepthTest(false);
fragConfig(); pFragConfig();
size_t i = 0; size_t i = 0;
while (i < data.size()) { while (i < data.size()) {
texture* tex = data[i]->tex; Texture* tex = data[i]->Tex;
if (!tex) { if (!tex) {
i++; i++;
continue; continue;
} }
auto scissorOn = data[i]->scissorOn; auto scissorOn = data[i]->ScissorOn;
auto scissor = data[i]->scissorRect; auto scissor = data[i]->ScissorRect;
auto start = i; auto start = i;
// Loop until a statgechange and copy all data into vertex/index buf // Loop until a statgechange and copy all data into Vertex/index buf
while (i < data.size() && scissorOn == data[i]->scissorOn && while (i < data.size() && scissorOn == data[i]->ScissorOn &&
scissor == data[i]->scissorRect && tex == data[i]->tex) { scissor == data[i]->ScissorRect && tex == data[i]->Tex) {
auto c = data[i].get(); auto c = data[i].get();
for (int j = 0; j < c->indexBuf.size(); j++) { for (int j = 0; j < c->IndexBuf.size(); j++) {
m_ibuf[m_idx++] = m_vtx + c->indexBuf[j]; m_ibuf[m_idx++] = m_vtx + c->IndexBuf[j];
} }
for (int j = 0; j < c->vertexBuf.size(); j++) { for (int j = 0; j < c->VertexBuf.size(); j++) {
m_vbuf[m_vtx++] = c->vertexBuf[j]; m_vbuf[m_vtx++] = c->VertexBuf[j];
} }
i++; i++;
} }
///// SCISSOR LOGIC BEG ///// ///// SCISSOR LOGIC BEG /////
///// SCISSOR LOGIC END ///// ///// SCISSOR LOGIC END /////
tex->bind(); tex->Bind();
c3d::bufCfg<3>(m_vbuf.data(), sizeof(vertex)); C3D::BufCfg<3>(m_vbuf.data(), sizeof(Vertex));
c3d::drawElements(i - start, m_ibuf.data() + start); C3D::DrawElements(i - start, m_ibuf.data() + start);
} }
c3d::depthTest(true); C3D::DepthTest(true);
} }
void iron::setupShader() { void Iron::pSetupShader() {
m_shader = new c3d::shader(); m_shader = new C3D::Shader();
m_shader->load("romfs:/shaders/lithium.shbin"); m_shader->Load("romfs:/shaders/lithium.shbin");
// m_shader->compile(__ironshader__); // m_shader->Compile(__ironshader__);
m_shader->input(GPU_FLOAT, 2); // pos m_shader->Input(GPU_FLOAT, 2); // pos
m_shader->input(GPU_FLOAT, 2); // uv m_shader->Input(GPU_FLOAT, 2); // uv
m_shader->input(GPU_UNSIGNED_BYTE, 4); // color m_shader->Input(GPU_UNSIGNED_BYTE, 4); // color
uLocProj = m_shader->loc("projection"); uLocProj = m_shader->loc("projection");
} }
void iron::fragConfig() { void Iron::pFragConfig() {
c3d::frag::edit(); C3D::Frag::Edit();
c3d::frag::src(C3D_Both, GPU_TEXTURE0); C3D::Frag::Src(C3D_Both, GPU_TEXTURE0);
c3d::frag::func(C3D_Both, GPU_MODULATE); C3D::Frag::Func(C3D_Both, GPU_MODULATE);
} }
void iron::initSolidTex() { void Iron::pInitSolidTex() {
// i know there is a lot of memory wasted :( // i know there is a lot of memory wasted :(
std::vector<uc> pixels(16 * 16 * 4, 0xff); std::vector<uc> pixels(16 * 16 * 4, 0xff);
m_solid = new texture(); m_solid = new Texture();
m_solid->load(pixels, 16, 16); m_solid->Load(pixels, 16, 16);
} }
bool iron::inBox(const fvec2& pos, const fvec2& size, const fvec4& area) { bool Iron::InBox(const fvec2& pos, const fvec2& size, const fvec4& area) {
return (pos.x + size.x >= area.x && pos.y + size.y >= area.y && return (pos.x + size.x >= area.x && pos.y + size.y >= area.y &&
pos.x <= area.z && pos.y <= area.w); pos.x <= area.z && pos.y <= area.w);
} }
bool iron::inBox(const fvec2& pos, const fvec4& area) { bool Iron::InBox(const fvec2& pos, const fvec4& area) {
return (pos.x > area.x && pos.x < area.x + area.z && pos.y > area.y && return (pos.x > area.x && pos.x < area.x + area.z && pos.y > area.y &&
pos.y < area.y + area.w); pos.y < area.y + area.w);
} }
bool iron::inBox(const fvec2& a, const fvec2& b, const fvec2& c, bool Iron::InBox(const fvec2& a, const fvec2& b, const fvec2& c,
const fvec4& area) { const fvec4& area) {
return ((a.x < area.z && b.x < area.z && c.x < area.z) || return ((a.x < area.z && b.x < area.z && c.x < area.z) ||
(a.y < area.w && b.y < area.w && c.y < area.w) || (a.y < area.w && b.y < area.w && c.y < area.w) ||
(a.x > 0 && b.x > 0 && c.x > 0) || (a.y > 0 && b.y > 0 && c.y > 0)); (a.x > 0 && b.x > 0 && c.x > 0) || (a.y > 0 && b.y > 0 && c.y > 0));
} }
void iron::rotateCorner(fvec2& pos, float s, float c) { void Iron::RotateCorner(fvec2& pos, float s, float c) {
float x = pos.x * c - pos.y * s; float x = pos.x * c - pos.y * s;
float y = pos.y * c - pos.x * s; float y = pos.y * c - pos.x * s;
pos = fvec2(x, y); pos = fvec2(x, y);
} }
rect iron::primRect(const fvec2& pos, const fvec2& size, float angle) { Rect Iron::PrimRect(const fvec2& pos, const fvec2& size, float angle) {
fvec2 c = size * 0.5f; // Center fvec2 c = size * 0.5f; // Center
fvec2 corner[4] = { fvec2 corner[4] = {
fvec2(-c.x, -c.y), fvec2(-c.x, -c.y),
@@ -180,16 +180,16 @@ rect iron::primRect(const fvec2& pos, const fvec2& size, float angle) {
float s = std::sin(angle); float s = std::sin(angle);
float co = std::cos(angle); float co = std::cos(angle);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
rotateCorner(corner[i], s, co); RotateCorner(corner[i], s, co);
} }
} }
// Return Result // Return Result
return rect(corner[0] + pos + c, corner[1] + pos + c, corner[2] + pos + c, return Rect(corner[0] + pos + c, corner[1] + pos + c, corner[2] + pos + c,
corner[3] + pos + c); corner[3] + pos + c);
} }
rect iron::primLine(const fvec2& a, const fvec2& b, int thickness) { Rect Iron::PrimLine(const fvec2& a, const fvec2& b, int thickness) {
// Using the vec maths api makes the code as short as it is // Using the vec maths api makes the code as short as it is
fvec2 dir = a - b; fvec2 dir = a - b;
float len = dir.Len(); float len = dir.Len();
@@ -197,35 +197,35 @@ rect iron::primLine(const fvec2& a, const fvec2& b, int thickness) {
fvec2 perpendicular(-unit_dir.y, unit_dir.x); fvec2 perpendicular(-unit_dir.y, unit_dir.x);
fvec2 off = perpendicular * ((float)thickness * 0.5f); fvec2 off = perpendicular * ((float)thickness * 0.5f);
return rect(a + off, b + off, a - off, b - off); return Rect(a + off, b + off, a - off, b - off);
} }
void iron::cmdQuad(command* cmd, const rect& q, const rect& uv, ui color) { void Iron::CmdQuad(Command* cmd, const Rect& q, const Rect& uv, ui color) {
cmd->add(0).add(1).add(2); cmd->Add(0).Add(1).Add(2);
cmd->add(0).add(2).add(3); cmd->Add(0).Add(2).Add(3);
cmd->add(vertex(q.botRight(), uv.botRight(), color)); cmd->Add(Vertex(q.BotRight(), uv.BotRight(), color));
cmd->add(vertex(q.topRight(), uv.topRight(), color)); cmd->Add(Vertex(q.TopRight(), uv.TopRight(), color));
cmd->add(vertex(q.topLeft(), uv.topLeft(), color)); cmd->Add(Vertex(q.TopLeft(), uv.TopLeft(), color));
cmd->add(vertex(q.botLeft(), uv.botLeft(), color)); cmd->Add(Vertex(q.BotLeft(), uv.BotLeft(), color));
} }
void iron::cmdTriangle(command* cmd, const fvec2& a, const fvec2& b, void Iron::CmdTriangle(Command* cmd, const fvec2& a, const fvec2& b,
const fvec2& c, ui color) { const fvec2& c, ui color) {
cmd->add(2).add(1).add(0); // reverse cause otherwise invisible cmd->Add(2).Add(1).Add(0); // reverse cause otherwise invisible
cmd->add(vertex(a, fvec2(0, 1), color)); cmd->Add(Vertex(a, fvec2(0, 1), color));
cmd->add(vertex(b, fvec2(1, 1), color)); cmd->Add(Vertex(b, fvec2(1, 1), color));
cmd->add(vertex(c, fvec2(1, 0), color)); cmd->Add(Vertex(c, fvec2(1, 0), color));
} }
void iron::cmdConvexPolyFilled(command* cmd, const std::vector<fvec2>& points, void Iron::CmdConvexPolyFilled(Command* cmd, const std::vector<fvec2>& points,
ui color, texture* tex) { ui color, Texture* tex) {
if (points.size() < 3 || tex == nullptr) { if (points.size() < 3 || tex == nullptr) {
#ifdef AMY_GOD_DEV #ifdef AMY_GOD_DEV
return; return;
#else #else
throw std::runtime_error("[amy] iron: trying to render convex poly with " + throw std::runtime_error("[amy] iron: trying to render convex poly with " +
std::to_string(points.size()) + std::to_string(points.size()) +
" points and texture " + std::to_string((ui)tex)); " points and Texture " + std::to_string((ui)tex));
#endif #endif
} }
// Support for Custom Textures (UV calculation) // Support for Custom Textures (UV calculation)
@@ -240,13 +240,13 @@ void iron::cmdConvexPolyFilled(command* cmd, const std::vector<fvec2>& points,
} }
// Get Short defines for UV // Get Short defines for UV
// (Bottom Right is not required) // (Bottom Right is not required)
auto uv_tl = tex->uv().topLeft(); auto uv_tl = tex->Uv().TopLeft();
auto uv_tr = tex->uv().topRight(); auto uv_tr = tex->Uv().TopRight();
auto uv_bl = tex->uv().botLeft(); auto uv_bl = tex->Uv().BotLeft();
// Render // Render
for (int i = 2; i < (int)points.size(); i++) { for (int i = 2; i < (int)points.size(); i++) {
cmd->add(0).add(i).add(i - 1); cmd->Add(0).Add(i).Add(i - 1);
} }
for (int i = 0; i < (int)points.size(); i++) { for (int i = 0; i < (int)points.size(); i++) {
// Calculate U and V coords // Calculate U and V coords
@@ -254,7 +254,7 @@ void iron::cmdConvexPolyFilled(command* cmd, const std::vector<fvec2>& points,
uv_tl.x + ((points[i].x - minX) / (maxX - minX)) * (uv_tr.x - uv_tl.x); uv_tl.x + ((points[i].x - minX) / (maxX - minX)) * (uv_tr.x - uv_tl.x);
float v = float v =
uv_tl.y + ((points[i].y - minY) / (maxY - minY)) * (uv_bl.y - uv_tl.y); uv_tl.y + ((points[i].y - minY) / (maxY - minY)) * (uv_bl.y - uv_tl.y);
cmd->add(vertex(points[i], fvec2(u, v), color)); cmd->Add(Vertex(points[i], fvec2(u, v), color));
} }
} }
} // namespace amy } // namespace Amy

View File

@@ -24,7 +24,7 @@ SOFTWARE.
#include <amethyst/maths/mat.hpp> #include <amethyst/maths/mat.hpp>
namespace amy { namespace Amy {
mat4 mat4::rotateX(float a) { mat4 mat4::rotateX(float a) {
float c = std::cos(a); float c = std::cos(a);
float s = std::sin(a); float s = std::sin(a);
@@ -118,4 +118,4 @@ mat4 mat4::lookAt(const fvec3& pos, const fvec3& center, const fvec3& up) {
ret(2, 3) = f.Dot(pos); ret(2, 3) = f.Dot(pos);
return ret; return ret;
} }
} // namespace amy } // namespace Amy

View File

@@ -1,7 +1,7 @@
#include <amethyst/renderer.hpp> #include <amethyst/renderer.hpp>
namespace amy { namespace Amy {
Renderer::Renderer() {} Renderer::Renderer() {}
Renderer::~Renderer() {} Renderer::~Renderer() {}
} // namespace amy } // namespace Amy

View File

@@ -6,88 +6,87 @@
#include <amethyst/utils.hpp> #include <amethyst/utils.hpp>
#include <stdexcept> #include <stdexcept>
namespace amy { namespace Amy {
ui tile3dsTex(int x, int y, int w) { ui tile3dsTex(int x, int y, int w) {
return ((((y >> 3) * ((int)w >> 3) + (x >> 3)) << 6) + return ((((y >> 3) * ((int)w >> 3) + (x >> 3)) << 6) +
((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) | ((y & 2) << 2) | ((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) | ((y & 2) << 2) |
((x & 4) << 2) | ((y & 4) << 3))); ((x & 4) << 2) | ((y & 4) << 3)));
} }
GPU_TEXCOLOR image2TexFmt(const image::format& fmt) { GPU_TEXCOLOR image2TexFmt(const Image::Format& fmt) {
switch (fmt) { switch (fmt) {
case image::RGB: case Image::RGB:
return GPU_RGB8; return GPU_RGB8;
break; break;
case image::RGBA: case Image::RGBA:
return GPU_RGBA8; return GPU_RGBA8;
break; break;
case image::RGB565: case Image::RGB565:
return GPU_RGB565; return GPU_RGB565;
break; break;
default: default:
// Dummy // Dummy
return GPU_A4; return GPU_A4;
throw std::runtime_error( throw std::runtime_error(
"[amy] texture: Unsupported texture format used!"); "[amy] texture: Unsupported texture Format used!");
break; break;
} }
} }
texture::texture(cstr& path) { load(path); } Texture::Texture(ksr path) { Load(path); }
texture::~texture() { unload(); } Texture::~Texture() { Unload(); }
void texture::unload() { void Texture::Unload() {
if (m_loaded) { if (pLoaded) {
C3D_TexDelete(&m_tex); C3D_TexDelete(&pTex);
m_loaded = false; pLoaded = false;
} }
} }
void texture::load(cstr& path) { void Texture::Load(ksr path) {
image img(path); Image img(path);
if (img.width() > 1024 || img.height() > 1024) { if (img.Width() > 1024 || img.Height() > 1024) {
throw std::runtime_error("Max Texture Size is 1024x1024!"); throw std::runtime_error("Max Texture Size is 1024x1024!");
} }
load(img.getBuffer(), img.width(), img.height(), img.bpp(), img.fmt()); Load(img.GetBuffer(), img.Width(), img.Height(), img.Bpp(), img.Fmt());
} }
void texture::load(const std::vector<uc>& pixels, int w, int h, int bpp, void Texture::Load(kvr<uc> pixels, int w, int h, int bpp, Image::Format fmt) {
image::format fmt) {
if (w > 1024 || h > 1024) { if (w > 1024 || h > 1024) {
throw std::runtime_error("Max Texture Size is 1024x1024!"); throw std::runtime_error("Max Texture Size is 1024x1024!");
} }
unload(); Unload();
m_size.x = w; pSize.x = w;
if (utils::isSingleBitNum(m_size.x)) { if (Utils::IsSingleBitNum(pSize.x)) {
m_size.x = utils::nextPow2(m_size.x); pSize.x = Utils::NextPow2(pSize.x);
} }
m_size.y = h; pSize.y = h;
if (utils::isSingleBitNum(m_size.y)) { if (Utils::IsSingleBitNum(pSize.y)) {
m_size.y = utils::nextPow2(m_size.y); pSize.y = Utils::NextPow2(pSize.y);
} }
auto filter = GPU_NEAREST; auto filter = GPU_NEAREST;
auto format = image2TexFmt(fmt); auto Format = image2TexFmt(fmt);
C3D_TexInit(&m_tex, (u16)m_size.x, (u16)m_size.y, format); C3D_TexInit(&pTex, (u16)pSize.x, (u16)pSize.y, Format);
C3D_TexSetFilter(&m_tex, filter, filter); C3D_TexSetFilter(&pTex, filter, filter);
// Using std::fill_n instead cause i hate this error lines // Using std::fill_n instead cause i hate this error lines
// under the memset func in my editor // under the memset func in my editor
std::fill_n((unsigned char*)m_tex.data, m_tex.size, 0); std::fill_n((unsigned char*)pTex.data, pTex.size, 0);
for (int x = 0; x < w; x++) { for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) { for (int y = 0; y < h; y++) {
int dst_pos = tile3dsTex(x, y, m_size.x) * bpp; int dst_pos = tile3dsTex(x, y, pSize.x) * bpp;
int src_pos = (y * w + x) * bpp; int src_pos = (y * w + x) * bpp;
/// Best idea i had /// Best idea i had
for (int i = 0; i < bpp; i++) { for (int i = 0; i < bpp; i++) {
((u8*)m_tex.data)[dst_pos + bpp - 1 - i] = pixels[src_pos + i]; ((u8*)pTex.data)[dst_pos + bpp - 1 - i] = pixels[src_pos + i];
} }
} }
} }
C3D_TexFlush(&m_tex); C3D_TexFlush(&pTex);
m_tex.border = 0x00000000; pTex.border = 0x00000000;
C3D_TexSetWrap(&m_tex, GPU_REPEAT, GPU_REPEAT); C3D_TexSetWrap(&pTex, GPU_REPEAT, GPU_REPEAT);
m_loaded = true; pLoaded = true;
} }
void texture::bind(int reg) { C3D_TexBind(reg, &m_tex); } void Texture::Bind(int reg) { C3D_TexBind(reg, &pTex); }
} // namespace amy } // namespace Amy

View File

@@ -1,9 +1,9 @@
#include <amethyst/utils.hpp> #include <amethyst/utils.hpp>
#include <fstream> #include <fstream>
namespace amy { namespace Amy {
namespace utils { namespace Utils {
ui fastHash(cstr& s) { ui fastHash(ksr s) {
ui hash = 5381; ui hash = 5381;
for (auto& it : s) { for (auto& it : s) {
hash = (hash * 33) + static_cast<uc>(it); hash = (hash * 33) + static_cast<uc>(it);
@@ -11,7 +11,7 @@ ui fastHash(cstr& s) {
return hash; return hash;
} }
vec<uc> loadFile2Mem(cstr& path) { vec<uc> LoadFile2Mem(ksr path) {
std::ifstream iff(path, std::ios::binary); std::ifstream iff(path, std::ios::binary);
if (!iff) { if (!iff) {
return vec<uc>(); return vec<uc>();
@@ -25,7 +25,7 @@ vec<uc> loadFile2Mem(cstr& path) {
return res; return res;
} }
ui hashMemory(cvec<uc>& data) { ui HashMemory(kvr<uc> data) {
ui hash = 4477; ui hash = 4477;
for (auto& it : data) { for (auto& it : data) {
hash = (hash * 33) + it; hash = (hash * 33) + it;
@@ -33,7 +33,7 @@ ui hashMemory(cvec<uc>& data) {
return hash; return hash;
} }
ui nextPow2(ui v) { ui NextPow2(ui v) {
v--; v--;
v |= v >> 1; v |= v >> 1;
v |= v >> 2; v |= v >> 2;
@@ -44,10 +44,26 @@ ui nextPow2(ui v) {
return (v >= 64 ? v : 64); return (v >= 64 ? v : 64);
} }
bool isSingleBitNum(ui v) { return v && !(v & (v - 1)); } bool IsSingleBitNum(ui v) { return v && !(v & (v - 1)); }
namespace image { ull GetTimeNano() {
void reverseBuf(vec<uc>& buf, int w, int h, int c) { return std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::steady_clock::now().time_since_epoch())
.count();
}
ull GetTimeMicro() {
return std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now().time_since_epoch())
.count();
}
ull GetTimeMilli() {
return std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now().time_since_epoch())
.count();
}
namespace Image {
void ReverseBuf(vec<uc>& buf, int w, int h, int c) {
vec<uc> cpy = buf; vec<uc> cpy = buf;
for (int x = 0; x < w; x++) { for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) { for (int y = 0; y < h; y++) {
@@ -59,7 +75,7 @@ void reverseBuf(vec<uc>& buf, int w, int h, int c) {
} }
} }
void removeAlphaChannel(vec<uc>& buf, int w, int h) { void RemoveAlphaChannel(vec<uc>& buf, int w, int h) {
vec<uc> cpy = buf; vec<uc> cpy = buf;
buf.resize(w * h * 3); buf.resize(w * h * 3);
for (int y = 0; y < h; y++) { for (int y = 0; y < h; y++) {
@@ -73,7 +89,7 @@ void removeAlphaChannel(vec<uc>& buf, int w, int h) {
} }
} }
void addAlphaChannel(vec<uc>& buf, int w, int h) { void AddAlphaChannel(vec<uc>& buf, int w, int h) {
vec<uc> cpy = buf; vec<uc> cpy = buf;
buf.resize(w * h * 4); buf.resize(w * h * 4);
for (int y = 0; y < h; y++) { for (int y = 0; y < h; y++) {
@@ -87,6 +103,6 @@ void addAlphaChannel(vec<uc>& buf, int w, int h) {
} }
} }
} }
} // namespace image } // namespace Image
} // namespace utils } // namespace Utils
} // namespace amy } // namespace Amy