# Changes
- Add Debugstuff to main - Add IsType and AutoLoad to AssetManager - Add ID class for at compile time hashing - Add A8 to image (but not supported yet) - Fix error in Vertex constructor - Add PathClear to PathFill func - Add pCheckSize to check for overflows - Make Tex in Texture a pointer ref - Add default uv to texture - Add own c++ exception - Add FNV32 Hash func (compile and runtime) - Fix Power2 check in texture loader - Load Shader manualy in iron (cause it seems not working correctly with files)
This commit is contained in:
@@ -8,10 +8,11 @@ set(CMAKE_CXX_STANDARD_REQUIRED true)
|
|||||||
option(AMY_BUILD_3DS "Build for 3ds" ON)
|
option(AMY_BUILD_3DS "Build for 3ds" ON)
|
||||||
option(AMY_GOD_DEV "Turn this on if you think you are god" OFF)
|
option(AMY_GOD_DEV "Turn this on if you think you are god" OFF)
|
||||||
|
|
||||||
add_subdirectory(vendor/libpicasso)
|
# add_subdirectory(vendor/libpicasso)
|
||||||
|
|
||||||
add_library(${PROJECT_NAME} STATIC
|
add_library(${PROJECT_NAME} STATIC
|
||||||
source/app.cpp
|
source/app.cpp
|
||||||
|
source/assets.cpp
|
||||||
source/amethyst.cpp
|
source/amethyst.cpp
|
||||||
source/image.cpp
|
source/image.cpp
|
||||||
source/renderer.cpp
|
source/renderer.cpp
|
||||||
@@ -24,7 +25,7 @@ add_library(${PROJECT_NAME} STATIC
|
|||||||
source/maths/mat.cpp
|
source/maths/mat.cpp
|
||||||
)
|
)
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC include)
|
target_include_directories(${PROJECT_NAME} PUBLIC include)
|
||||||
target_link_libraries(${PROJECT_NAME} PUBLIC pica::pica)
|
# target_link_libraries(${PROJECT_NAME} PUBLIC pica::pica)
|
||||||
if(${AMY_BUILD_3DS})
|
if(${AMY_BUILD_3DS})
|
||||||
target_link_libraries(${PROJECT_NAME} PUBLIC m z ctru citro3d)
|
target_link_libraries(${PROJECT_NAME} PUBLIC m z ctru citro3d)
|
||||||
target_compile_definitions(${PROJECT_NAME} PUBLIC AMY_3DS )
|
target_compile_definitions(${PROJECT_NAME} PUBLIC AMY_3DS )
|
||||||
|
|||||||
@@ -1,18 +1,68 @@
|
|||||||
#include <amethyst.hpp>
|
#include <amethyst.hpp>
|
||||||
|
#include <cstdlib>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "amethyst/iron.hpp"
|
#include "amethyst/iron.hpp"
|
||||||
|
|
||||||
|
struct memory_metrics {
|
||||||
|
uint64_t t_TotalAllocated = 0; ///< Total Allocated Memory
|
||||||
|
uint64_t t_TotalFreed = 0; ///< Total Deleted Memory
|
||||||
|
/// @brief Gets the Currently Allocated Memory
|
||||||
|
uint32_t t_CurrentlyAllocated() { return t_TotalAllocated - t_TotalFreed; }
|
||||||
|
};
|
||||||
|
|
||||||
|
static memory_metrics metrics;
|
||||||
|
|
||||||
|
bool rd7i_enable_memtrack = true;
|
||||||
|
|
||||||
|
void* operator new(size_t size) {
|
||||||
|
void* ptr = malloc(size);
|
||||||
|
if (rd7i_enable_memtrack) metrics.t_TotalAllocated += size;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete(void* memory, size_t size) {
|
||||||
|
if (rd7i_enable_memtrack) metrics.t_TotalFreed += size;
|
||||||
|
free(memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetTotalAllocated() { return metrics.t_TotalAllocated; }
|
||||||
|
|
||||||
|
size_t GetTotalFreed() { return metrics.t_TotalFreed; }
|
||||||
|
|
||||||
|
size_t GetCurrent() { return metrics.t_CurrentlyAllocated(); }
|
||||||
|
|
||||||
|
std::string FormatBytes(unsigned long long bytes) {
|
||||||
|
static const std::vector<std::string> endings = {
|
||||||
|
"B", "KB", "MB", "GB", "TB", "Unk",
|
||||||
|
};
|
||||||
|
int i = 0;
|
||||||
|
double b = bytes;
|
||||||
|
while (b > 1024) {
|
||||||
|
i++;
|
||||||
|
b /= 1024;
|
||||||
|
}
|
||||||
|
if (i >= (int)endings.size()) {
|
||||||
|
i = (int)endings.size() - 1;
|
||||||
|
}
|
||||||
|
return std::format("{:.1f} {}", b, endings[i]);
|
||||||
|
}
|
||||||
|
|
||||||
class example : public Amy::App {
|
class example : public Amy::App {
|
||||||
public:
|
public:
|
||||||
example() {
|
example() {
|
||||||
Amy::Ctr::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);
|
||||||
Amy::Iron::Init();
|
Amy::Iron::Init();
|
||||||
dl = new Amy::Iron::Drawlist();
|
dl = new Amy::Iron::Drawlist();
|
||||||
dl->DrawSolid();
|
dl->DrawSolid();
|
||||||
|
mgr.AutoLoad("shader", "romfs:/shaders/shader2d.shbin");
|
||||||
|
mgr.Get<Amy::C3D::Shader>("shader")->Input(GPU_FLOAT, 3);
|
||||||
|
mgr.Get<Amy::C3D::Shader>("shader")->Input(GPU_FLOAT, 3);
|
||||||
|
mgr.AutoLoad("icon", "romfs:/icon.png");
|
||||||
};
|
};
|
||||||
~example() {
|
~example() {
|
||||||
Amy::C3D::DeleteScreen(m_top);
|
Amy::C3D::DeleteScreen(m_top);
|
||||||
@@ -20,22 +70,44 @@ class example : public Amy::App {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void Main() override {
|
void Main() override {
|
||||||
|
std::cout << std::format("\x1b[1;1HDelta: {:.3f} -> {:.3} FPS\x1b[K", this->Delta(), 1000.0/this->Delta());
|
||||||
|
std::cout << std::format("\x1b[2;1HTime: {:.3f}\x1b[K", this->Time());
|
||||||
|
std::cout << std::format(
|
||||||
|
"\x1b[3;1HMem: {}\n +{}\n -{}\nLin: {}\x1b[K",
|
||||||
|
FormatBytes(GetCurrent()), FormatBytes(GetTotalAllocated()),
|
||||||
|
FormatBytes(GetTotalFreed()), FormatBytes(linearSpaceFree()));
|
||||||
|
|
||||||
Amy::C3D::StartFrame();
|
Amy::C3D::StartFrame();
|
||||||
m_top->Use();
|
m_top->Use();
|
||||||
m_top->Clear();
|
m_top->Clear();
|
||||||
dl->DrawRectFilled(0, 50, 0xff00ff00);
|
dl->DrawTex(mgr.Get<Amy::Texture>("icon"));
|
||||||
|
dl->DrawRectFilled(100, 48, 0xffffffff);
|
||||||
|
dl->DrawSolid();
|
||||||
|
dl->DrawRectFilled(0, 50, 0xffffffff);
|
||||||
Amy::Iron::NewFrame();
|
Amy::Iron::NewFrame();
|
||||||
Amy::Iron::DrawOn(m_top);
|
Amy::Iron::DrawOn(m_top);
|
||||||
Amy::Iron::Draw(*dl);
|
Amy::Iron::Draw(*dl);
|
||||||
dl->Clear();
|
dl->Clear();
|
||||||
|
mgr.Get<Amy::C3D::Shader>("shader")->Use();
|
||||||
|
mgr.Get<Amy::C3D::Shader>("shader")->SetMat4(0, mtx);
|
||||||
|
C3D_ImmDrawBegin(GPU_TRIANGLES);
|
||||||
|
C3D_ImmSendAttrib(200, 50, 0, 0);
|
||||||
|
C3D_ImmSendAttrib(1, 0, 0, 1);
|
||||||
|
C3D_ImmSendAttrib(300, 190, 0, 0);
|
||||||
|
C3D_ImmSendAttrib(0, 1, 0, 1);
|
||||||
|
C3D_ImmSendAttrib(100, 190, 0, 0);
|
||||||
|
C3D_ImmSendAttrib(0, 0, 1, 1);
|
||||||
|
C3D_ImmDrawEnd();
|
||||||
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;
|
||||||
|
Amy::C3D::Shader* test = nullptr;
|
||||||
|
Amy::AssetMgr mgr;
|
||||||
|
Amy::mat4 mtx =
|
||||||
|
Amy::mat4::identity() * Amy::mat4::ortho(0, 400, 240, 0, 0, 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <amethyst/asset.hpp>
|
#include <amethyst/asset.hpp>
|
||||||
#include <amethyst/types.hpp>
|
#include <amethyst/types.hpp>
|
||||||
|
#include <amethyst/utils.hpp>
|
||||||
|
|
||||||
namespace Amy {
|
namespace Amy {
|
||||||
class App {
|
class App {
|
||||||
|
|||||||
@@ -1,34 +1,55 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <amethyst/id.hpp>
|
||||||
#include <amethyst/texture.hpp>
|
#include <amethyst/texture.hpp>
|
||||||
#include <amethyst/types.hpp>
|
#include <amethyst/types.hpp>
|
||||||
|
|
||||||
namespace Amy {
|
namespace Amy {
|
||||||
class Assets {
|
class AssetMgr {
|
||||||
public:
|
public:
|
||||||
Assets() = default;
|
AssetMgr() = default;
|
||||||
~Assets() = default;
|
~AssetMgr() = default;
|
||||||
|
|
||||||
void add(ksr id, Asset* v) { pAssets[id] = v; }
|
void AutoLoad(const ID& name, ksr path);
|
||||||
void remove(ksr id) {
|
|
||||||
|
void Add(const ID& id, Asset* v) {
|
||||||
|
if (pAssets.count(id)) {
|
||||||
|
throw std::runtime_error("[amy]: assets: " + id.GetName() +
|
||||||
|
" already exists!");
|
||||||
|
}
|
||||||
|
pAssets[id] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Remove(const ID& id) {
|
||||||
if (pAssets.count(id)) {
|
if (pAssets.count(id)) {
|
||||||
pAssets.erase(id);
|
pAssets.erase(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T* get(ksr id) {
|
T* Get(const ID& id) {
|
||||||
auto r = pAssets.find(id);
|
auto r = pAssets.find(id);
|
||||||
if (r == pAssets.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.GetName());
|
||||||
}
|
}
|
||||||
if (auto v = dynamic_cast<T*>(r->second)) {
|
if (auto v = dynamic_cast<T*>(r->second)) {
|
||||||
return v;
|
return v;
|
||||||
} else {
|
} else {
|
||||||
throw std::runtime_error(id + " is not of type " + typeid(T).name());
|
throw std::runtime_error(id.GetName() + " is not of type " +
|
||||||
|
typeid(T).name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool IsType(const ID& id) {
|
||||||
|
auto r = pAssets.find(id);
|
||||||
|
if (r == pAssets.end()) {
|
||||||
|
throw std::runtime_error("[amy] assets: unable to find " + id.GetName());
|
||||||
|
}
|
||||||
|
return dynamic_cast<T*>(r->second) != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<str, Asset*> pAssets;
|
std::map<ID, Asset*> pAssets;
|
||||||
};
|
};
|
||||||
} // namespace Amy
|
} // namespace Amy
|
||||||
@@ -53,7 +53,7 @@ class C3D {
|
|||||||
void SetMat4(int loc, const mat4& m);
|
void SetMat4(int loc, const mat4& m);
|
||||||
int loc(ksr name);
|
int loc(ksr name);
|
||||||
|
|
||||||
private:
|
// private:
|
||||||
C3D_AttrInfo pInfo;
|
C3D_AttrInfo pInfo;
|
||||||
shaderProgram_s pProgram;
|
shaderProgram_s pProgram;
|
||||||
DVLB_s* pCode;
|
DVLB_s* pCode;
|
||||||
|
|||||||
42
include/amethyst/id.hpp
Normal file
42
include/amethyst/id.hpp
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <amethyst/types.hpp>
|
||||||
|
#include <amethyst/utils.hpp>
|
||||||
|
|
||||||
|
namespace Amy {
|
||||||
|
class ID {
|
||||||
|
public:
|
||||||
|
constexpr ID(const ui& id) { pID = id; }
|
||||||
|
constexpr ID(std::string name) {
|
||||||
|
pID = Utils::FNV32(name);
|
||||||
|
#ifdef AMY_KEEP_STR_ID
|
||||||
|
pName = name;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
constexpr ID(const char* name) {
|
||||||
|
pID = Utils::FNV32(name);
|
||||||
|
#ifdef AMY_KEEP_STR_ID
|
||||||
|
pName = name;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
~ID() {}
|
||||||
|
|
||||||
|
ui GetID() { return pID; }
|
||||||
|
std::string GetName() const {
|
||||||
|
#ifdef AMY_KEEP_STR_ID
|
||||||
|
return pName;
|
||||||
|
#else
|
||||||
|
return std::format("hash({:#08x})", pID);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
operator ui() const { return pID; }
|
||||||
|
operator std::string() const { return GetName(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
ui pID;
|
||||||
|
#ifdef AMY_KEEP_STR_ID
|
||||||
|
str pName;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
} // namespace Amy
|
||||||
@@ -12,6 +12,7 @@ class Image {
|
|||||||
BGR, // bpp == 3
|
BGR, // bpp == 3
|
||||||
ABGR, // bpp == 4
|
ABGR, // bpp == 4
|
||||||
BGRA, // bpp == 4
|
BGRA, // bpp == 4
|
||||||
|
A8, // bpp == 1 (not supported in laoding)
|
||||||
};
|
};
|
||||||
Image() = default;
|
Image() = default;
|
||||||
Image(ksr path) { this->Load(path); }
|
Image(ksr path) { this->Load(path); }
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ class Iron {
|
|||||||
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 = u;
|
||||||
uv.y = y;
|
uv.y = v;
|
||||||
color = clr;
|
color = clr;
|
||||||
}
|
}
|
||||||
Vertex(const fvec2& pos, const fvec2& uv, ui clr) {
|
Vertex(const fvec2& pos, const fvec2& uv, ui clr) {
|
||||||
@@ -33,6 +33,7 @@ class Iron {
|
|||||||
class Command {
|
class Command {
|
||||||
public:
|
public:
|
||||||
Command() = default;
|
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);
|
||||||
@@ -100,7 +101,10 @@ class Iron {
|
|||||||
DrawPolyLine(pPath, color, flags, thickness);
|
DrawPolyLine(pPath, color, flags, thickness);
|
||||||
PathClear();
|
PathClear();
|
||||||
}
|
}
|
||||||
void PathFill(ui color) { DrawConvexPolyFilled(pPath, color); }
|
void PathFill(ui color) {
|
||||||
|
DrawConvexPolyFilled(pPath, color);
|
||||||
|
PathClear();
|
||||||
|
}
|
||||||
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,
|
||||||
@@ -152,6 +156,7 @@ class Iron {
|
|||||||
static void pSetupShader();
|
static void pSetupShader();
|
||||||
static void pFragConfig();
|
static void pFragConfig();
|
||||||
static void pInitSolidTex();
|
static void pInitSolidTex();
|
||||||
|
static bool pCheckSize(size_t idx, size_t vtx);
|
||||||
|
|
||||||
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;
|
||||||
|
|||||||
@@ -26,14 +26,14 @@ class Texture : public Asset {
|
|||||||
ivec2& Size() { return pSize; }
|
ivec2& Size() { return pSize; }
|
||||||
Rect& Uv() { return pUv; }
|
Rect& Uv() { return pUv; }
|
||||||
|
|
||||||
C3D_Tex* Ptr() { return pLoaded ? &pTex : nullptr; }
|
C3D_Tex* Ptr() { return pLoaded ? pTex : nullptr; }
|
||||||
|
|
||||||
void Bind(int reg = 0);
|
void Bind(int reg = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
C3D_Tex pTex;
|
C3D_Tex* pTex = nullptr;
|
||||||
ivec2 pSize;
|
ivec2 pSize;
|
||||||
Rect pUv;
|
Rect pUv = fvec4(0, 1, 1, 0);
|
||||||
bool pLoaded = false;
|
bool pLoaded = false;
|
||||||
};
|
};
|
||||||
} // namespace Amy
|
} // namespace Amy
|
||||||
@@ -3,8 +3,11 @@
|
|||||||
#include <amethyst/types.hpp>
|
#include <amethyst/types.hpp>
|
||||||
|
|
||||||
namespace Amy {
|
namespace Amy {
|
||||||
|
class Error : public std::runtime_error {
|
||||||
|
public:
|
||||||
|
Error(ksr str) : std::runtime_error("[amy] " + str) {}
|
||||||
|
};
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
ui FastHash(ksr s);
|
|
||||||
vec<uc> LoadFile2Mem(ksr path);
|
vec<uc> LoadFile2Mem(ksr path);
|
||||||
ui HashMemory(kvr<uc> data);
|
ui HashMemory(kvr<uc> data);
|
||||||
ui NextPow2(ui v);
|
ui NextPow2(ui v);
|
||||||
@@ -12,6 +15,20 @@ bool IsSingleBitNum(ui v);
|
|||||||
ull GetTimeNano();
|
ull GetTimeNano();
|
||||||
ull GetTimeMicro();
|
ull GetTimeMicro();
|
||||||
ull GetTimeMilli();
|
ull GetTimeMilli();
|
||||||
|
/**
|
||||||
|
* FNV Hash functiom (32 Bit)
|
||||||
|
* https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
|
||||||
|
* Able to run at compile time btw
|
||||||
|
*/
|
||||||
|
constexpr ui FNV32(std::string_view str) {
|
||||||
|
ui ret = 0x811C9DC5;
|
||||||
|
for (char it : str) {
|
||||||
|
ret ^= static_cast<ui>(it);
|
||||||
|
ret *= 16777619;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Image {
|
namespace Image {
|
||||||
void ReverseBuf(vec<uc>& buf, int w, int h, int c);
|
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);
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
namespace Amy {
|
namespace Amy {
|
||||||
void App::Run() {
|
void App::Run() {
|
||||||
pLast = Utils::GetTimeNano();
|
pLast = Utils::GetTimeNano();
|
||||||
consoleInit(GFX_BOTTOM, NULL);
|
|
||||||
while (aptMainLoop()) {
|
while (aptMainLoop()) {
|
||||||
ull c = Utils::GetTimeNano();
|
ull c = Utils::GetTimeNano();
|
||||||
pDelta = static_cast<double>(static_cast<double>(c) -
|
pDelta = static_cast<double>(static_cast<double>(c) -
|
||||||
|
|||||||
21
source/assets.cpp
Normal file
21
source/assets.cpp
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#include <amethyst/assets.hpp>
|
||||||
|
#include <amethyst/c3d.hpp>
|
||||||
|
#include <amethyst/texture.hpp>
|
||||||
|
|
||||||
|
namespace Amy {
|
||||||
|
void AssetMgr::AutoLoad(const ID& id, ksr path) {
|
||||||
|
if (path.ends_with(".png") || path.ends_with(".jpg") ||
|
||||||
|
path.ends_with(".bmp")) {
|
||||||
|
Texture* tex = new Texture();
|
||||||
|
tex->Load(path);
|
||||||
|
Add(id, tex);
|
||||||
|
} else if (path.ends_with(".shbin")) {
|
||||||
|
C3D::Shader* shader = new C3D::Shader();
|
||||||
|
shader->Load(path);
|
||||||
|
Add(id, shader);
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error("[amy]: assets: " + id.GetName() + " (" + path +
|
||||||
|
") is unsupported for AssetMgr::AutoLoad!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace Amy
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <amethyst/c3d.hpp>
|
#include <amethyst/c3d.hpp>
|
||||||
#include <amethyst/utils.hpp>
|
#include <amethyst/utils.hpp>
|
||||||
#include <pica.hpp>
|
// #include <pica.hpp>
|
||||||
|
|
||||||
namespace Amy {
|
namespace Amy {
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ 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] unable to load shader ({})", path));
|
||||||
}
|
}
|
||||||
Load(code);
|
Load(code);
|
||||||
}
|
}
|
||||||
@@ -60,8 +60,9 @@ void C3D::Shader::Load(const std::vector<uc>& data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void C3D::Shader::Compile(const std::string& code) {
|
void C3D::Shader::Compile(const std::string& code) {
|
||||||
auto ret = Pica::AssembleCode(code.c_str());
|
throw std::runtime_error("[amy]: unable to compile shader (not allowed)");
|
||||||
Load(ret);
|
/*auto ret = Pica::AssembleCode(code.c_str());
|
||||||
|
Load(ret);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void C3D::Shader::Use() {
|
void C3D::Shader::Use() {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
#include <amethyst/utils.hpp>
|
#include <amethyst/utils.hpp>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
// #define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#include <stb_image.h>
|
#include <stb_image.h>
|
||||||
|
|
||||||
namespace Amy {
|
namespace Amy {
|
||||||
@@ -75,6 +75,9 @@ int Image::GetBppOfFmt(const Image::Format& fmt) {
|
|||||||
case RGB565:
|
case RGB565:
|
||||||
return 2;
|
return 2;
|
||||||
break;
|
break;
|
||||||
|
case A8:
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0; // Unknown
|
return 0; // Unknown
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <amethyst/iron.hpp>
|
#include <amethyst/iron.hpp>
|
||||||
|
#include <amethyst/utils.hpp>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@@ -103,6 +104,12 @@ void Iron::Draw(const std::vector<Iron::Command::ref>& data) {
|
|||||||
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();
|
||||||
|
|
||||||
|
if (!pCheckSize(c->IndexBuf.size(), c->VertexBuf.size())) {
|
||||||
|
throw Error("iron: too much draw data!!!" +
|
||||||
|
std::format("\nIdx: {}\nVtx: {}", c->IndexBuf.size(),
|
||||||
|
c->VertexBuf.size()));
|
||||||
|
}
|
||||||
|
|
||||||
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];
|
||||||
}
|
}
|
||||||
@@ -118,15 +125,34 @@ void Iron::Draw(const std::vector<Iron::Command::ref>& data) {
|
|||||||
C3D::DrawElements(i - start, m_ibuf.data() + start);
|
C3D::DrawElements(i - start, m_ibuf.data() + start);
|
||||||
}
|
}
|
||||||
C3D::DepthTest(true);
|
C3D::DepthTest(true);
|
||||||
|
/*std::ofstream off("hello.txt");
|
||||||
|
for (int i = 0; i < m_idx; i++) {
|
||||||
|
auto& v = m_vbuf[m_ibuf[i]];
|
||||||
|
off << std::format("{} -> [{}] [{}] #{:08X}\n", m_ibuf[i], v.pos, v.uv,
|
||||||
|
v.color);
|
||||||
|
}
|
||||||
|
off.close();
|
||||||
|
throw std::runtime_error("halt");*/
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Iron::pCheckSize(size_t idx, size_t vtx) {
|
||||||
|
return idx < m_ibuf.size() && vtx < m_vbuf.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Iron::pSetupShader() {
|
void Iron::pSetupShader() {
|
||||||
m_shader = new C3D::Shader();
|
m_shader = new C3D::Shader();
|
||||||
m_shader->Load("romfs:/shaders/lithium.shbin");
|
m_shader->pCode = DVLB_ParseFile((u32*)li_shader, li_shader_size);
|
||||||
|
shaderProgramInit(&m_shader->pProgram);
|
||||||
|
shaderProgramSetVsh(&m_shader->pProgram, &m_shader->pCode->DVLE[0]);
|
||||||
|
AttrInfo_Init(&m_shader->pInfo);
|
||||||
|
AttrInfo_AddLoader(&m_shader->pInfo, 0, GPU_FLOAT, 2);
|
||||||
|
AttrInfo_AddLoader(&m_shader->pInfo, 1, GPU_FLOAT, 2);
|
||||||
|
AttrInfo_AddLoader(&m_shader->pInfo, 2, GPU_UNSIGNED_BYTE, 4);
|
||||||
|
// 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");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,6 +167,9 @@ void Iron::pInitSolidTex() {
|
|||||||
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);
|
||||||
|
if (!m_solid->Ptr()) {
|
||||||
|
throw Error("white tex failed to load!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Iron::InBox(const fvec2& pos, const fvec2& size, const fvec4& area) {
|
bool Iron::InBox(const fvec2& pos, const fvec2& size, const fvec4& area) {
|
||||||
|
|||||||
@@ -24,9 +24,11 @@ GPU_TEXCOLOR image2TexFmt(const Image::Format& fmt) {
|
|||||||
case Image::RGB565:
|
case Image::RGB565:
|
||||||
return GPU_RGB565;
|
return GPU_RGB565;
|
||||||
break;
|
break;
|
||||||
|
case Image::A8:
|
||||||
|
return GPU_A8;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// Dummy
|
// Dummy
|
||||||
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;
|
||||||
@@ -38,55 +40,55 @@ Texture::~Texture() { Unload(); }
|
|||||||
|
|
||||||
void Texture::Unload() {
|
void Texture::Unload() {
|
||||||
if (pLoaded) {
|
if (pLoaded) {
|
||||||
C3D_TexDelete(&pTex);
|
C3D_TexDelete(pTex);
|
||||||
|
delete pTex;
|
||||||
|
pTex = nullptr;
|
||||||
pLoaded = false;
|
pLoaded = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::Load(ksr path) {
|
void Texture::Load(ksr path) {
|
||||||
Image img(path);
|
Image img(path);
|
||||||
if (img.Width() > 1024 || img.Height() > 1024) {
|
|
||||||
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(kvr<uc> pixels, int w, int h, int bpp, Image::Format fmt) {
|
void Texture::Load(kvr<uc> pixels, int w, int h, int bpp, 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("[amy] texture: Max Texture Size is 1024x1024!");
|
||||||
}
|
}
|
||||||
Unload();
|
Unload();
|
||||||
|
|
||||||
pSize.x = w;
|
pSize.x = w;
|
||||||
if (Utils::IsSingleBitNum(pSize.x)) {
|
if (!Utils::IsSingleBitNum(pSize.x)) {
|
||||||
pSize.x = Utils::NextPow2(pSize.x);
|
pSize.x = Utils::NextPow2(pSize.x);
|
||||||
}
|
}
|
||||||
pSize.y = h;
|
pSize.y = h;
|
||||||
if (Utils::IsSingleBitNum(pSize.y)) {
|
if (!Utils::IsSingleBitNum(pSize.y)) {
|
||||||
pSize.y = Utils::NextPow2(pSize.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(&pTex, (u16)pSize.x, (u16)pSize.y, Format);
|
pTex = new C3D_Tex;
|
||||||
C3D_TexSetFilter(&pTex, filter, filter);
|
C3D_TexInit(pTex, (u16)pSize.x, (u16)pSize.y, Format);
|
||||||
|
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*)pTex.data, pTex.size, 0);
|
std::fill_n((uc*)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, pSize.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*)pTex.data)[dst_pos + bpp - 1 - i] = pixels[src_pos + i];
|
((u8*)pTex->data)[dst_pos + bpp - 1 - i] = pixels[src_pos + i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
C3D_TexFlush(&pTex);
|
C3D_TexFlush(pTex);
|
||||||
pTex.border = 0x00000000;
|
pTex->border = 0x00000000;
|
||||||
C3D_TexSetWrap(&pTex, GPU_REPEAT, GPU_REPEAT);
|
C3D_TexSetWrap(pTex, GPU_REPEAT, GPU_REPEAT);
|
||||||
pLoaded = true;
|
pLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::Bind(int reg) { C3D_TexBind(reg, &pTex); }
|
void Texture::Bind(int reg) { C3D_TexBind(reg, pTex); }
|
||||||
} // namespace Amy
|
} // namespace Amy
|
||||||
@@ -3,14 +3,6 @@
|
|||||||
|
|
||||||
namespace Amy {
|
namespace Amy {
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
ui fastHash(ksr s) {
|
|
||||||
ui hash = 5381;
|
|
||||||
for (auto& it : s) {
|
|
||||||
hash = (hash * 33) + static_cast<uc>(it);
|
|
||||||
}
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec<uc> LoadFile2Mem(ksr path) {
|
vec<uc> LoadFile2Mem(ksr path) {
|
||||||
std::ifstream iff(path, std::ios::binary);
|
std::ifstream iff(path, std::ios::binary);
|
||||||
if (!iff) {
|
if (!iff) {
|
||||||
|
|||||||
Reference in New Issue
Block a user