# Update
- 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:
@@ -26,10 +26,10 @@ void NpiD7CxxExceptionHandler() {
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace amy {
|
||||
void registerCxxExceptionHandler() {
|
||||
namespace Amy {
|
||||
void RegisterCxxExceptionHandler() {
|
||||
#ifdef AMY_3DS
|
||||
std::set_terminate(NpiD7CxxExceptionHandler);
|
||||
#endif
|
||||
}
|
||||
} // namespace amy
|
||||
} // namespace Amy
|
||||
@@ -2,14 +2,20 @@
|
||||
|
||||
#include <amethyst/app.hpp>
|
||||
#include <amethyst/ctru.hpp>
|
||||
#include <amethyst/utils.hpp>
|
||||
|
||||
namespace amy {
|
||||
void app::run() {
|
||||
namespace Amy {
|
||||
void App::Run() {
|
||||
pLast = Utils::GetTimeNano();
|
||||
consoleInit(GFX_BOTTOM, NULL);
|
||||
while (aptMainLoop()) {
|
||||
ull c = ctru::getTime();
|
||||
m_delta = static_cast<double>(c) - static_cast<float>(m_last);
|
||||
m_last = c;
|
||||
main();
|
||||
ull c = Utils::GetTimeNano();
|
||||
pDelta = static_cast<double>(static_cast<double>(c) -
|
||||
static_cast<double>(pLast)) *
|
||||
0.000001;
|
||||
pTime += pDelta * 0.001;
|
||||
pLast = c;
|
||||
Main();
|
||||
}
|
||||
}
|
||||
} // namespace amy
|
||||
} // namespace Amy
|
||||
108
source/c3d.cpp
108
source/c3d.cpp
@@ -4,131 +4,131 @@
|
||||
#include <amethyst/utils.hpp>
|
||||
#include <pica.hpp>
|
||||
|
||||
namespace amy {
|
||||
namespace Amy {
|
||||
|
||||
const auto DISPLAY_TRANSFER_FLAGS =
|
||||
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_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) |
|
||||
GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO);
|
||||
C3D_TexEnv* c3d::frag::m_env = nullptr;
|
||||
int c3d::m_drawcalls = 0;
|
||||
int c3d::m__dc__ = 0;
|
||||
C3D_TexEnv* C3D::Frag::pEnv = nullptr;
|
||||
int C3D::pDrawcalls = 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);
|
||||
m__dc__ = 0;
|
||||
p__dc__ = 0;
|
||||
}
|
||||
|
||||
void c3d::endFrame() {
|
||||
void C3D::EndFrame() {
|
||||
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,
|
||||
GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8);
|
||||
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) {
|
||||
auto code = utils::loadFile2Mem(path);
|
||||
void C3D::Shader::Load(const std::string& path) {
|
||||
auto code = Utils::LoadFile2Mem(path);
|
||||
if (!code.size()) {
|
||||
throw std::runtime_error(
|
||||
std::format("[amy] unsable to load shader ({})", path));
|
||||
}
|
||||
load(code);
|
||||
Load(code);
|
||||
}
|
||||
|
||||
void c3d::shader::load(const std::vector<uc>& data) {
|
||||
m_code = DVLB_ParseFile((u32*)&data[0], data.size());
|
||||
shaderProgramInit(&m_program);
|
||||
shaderProgramSetVsh(&m_program, &m_code->DVLE[0]);
|
||||
C3D_BindProgram(&m_program);
|
||||
AttrInfo_Init(&m_info);
|
||||
void C3D::Shader::Load(const std::vector<uc>& data) {
|
||||
pCode = DVLB_ParseFile((u32*)&data[0], data.size());
|
||||
shaderProgramInit(&pProgram);
|
||||
shaderProgramSetVsh(&pProgram, &pCode->DVLE[0]);
|
||||
C3D_BindProgram(&pProgram);
|
||||
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());
|
||||
load(ret);
|
||||
Load(ret);
|
||||
}
|
||||
|
||||
void c3d::shader::use() {
|
||||
C3D_BindProgram(&m_program);
|
||||
void C3D::Shader::Use() {
|
||||
C3D_BindProgram(&pProgram);
|
||||
// for some reason i need both ???
|
||||
// code works perfectly without C3D_BindProgram
|
||||
// but nor withour shaderProgramUse ...
|
||||
shaderProgramUse(&m_program);
|
||||
C3D_SetAttrInfo(&m_info);
|
||||
shaderProgramUse(&pProgram);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
int c3d::shader::loc(const std::string& name) {
|
||||
return shaderInstanceGetUniformLocation(m_program.vertexShader, name.c_str());
|
||||
int C3D::Shader::loc(const std::string& name) {
|
||||
return shaderInstanceGetUniformLocation(pProgram.vertexShader, name.c_str());
|
||||
}
|
||||
|
||||
void c3d::shader::input(int reg, GPU_FORMATS f, int num) {
|
||||
AttrInfo_AddLoader(&m_info, reg, f, num);
|
||||
void C3D::Shader::Input(int reg, GPU_FORMATS f, int 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) {
|
||||
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) {
|
||||
C3D_TexEnvFunc(m_env, mode, func);
|
||||
void C3D::Frag::Func(C3D_TexEnvMode mode, GPU_COMBINEFUNC func) {
|
||||
C3D_TexEnvFunc(pEnv, mode, func);
|
||||
}
|
||||
void c3d::frag::edit(int id) {
|
||||
m_env = C3D_GetTexEnv(id);
|
||||
C3D_TexEnvInit(m_env);
|
||||
void C3D::Frag::Edit(int id) {
|
||||
pEnv = C3D_GetTexEnv(id);
|
||||
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);
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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();
|
||||
BufInfo_Init(buf);
|
||||
BufInfo_Add(buf, ptr, stride, shader_attribs, permutation);
|
||||
}
|
||||
|
||||
void c3d::bufCfg(void* ptr, int stride, int shader_attribs) {
|
||||
bufCfg(ptr, stride, shader_attribs, permutation(shader_attribs));
|
||||
void C3D::BufCfg(void* ptr, int stride, int shader_attribs) {
|
||||
BufCfg(ptr, stride, shader_attribs, pPermutation(shader_attribs));
|
||||
}
|
||||
} // namespace amy
|
||||
} // namespace Amy
|
||||
@@ -2,16 +2,16 @@
|
||||
|
||||
#include <amethyst/ctru.hpp>
|
||||
|
||||
namespace amy {
|
||||
namespace ctru {
|
||||
void init(unsigned int srvs) {
|
||||
if (srvs & romfs) {
|
||||
namespace Amy {
|
||||
namespace Ctr {
|
||||
void Init(ui srvs) {
|
||||
if (srvs & Romfs) {
|
||||
romfsInit();
|
||||
}
|
||||
if (srvs & gfx_def) {
|
||||
if (srvs & GfxDefault) {
|
||||
gfxInitDefault();
|
||||
}
|
||||
}
|
||||
ull getTime() { return osGetTime(); }
|
||||
} // namespace ctru
|
||||
} // namespace amy
|
||||
ull GetTime() { return osGetTime(); }
|
||||
} // namespace Ctr
|
||||
} // namespace Amy
|
||||
131
source/image.cpp
131
source/image.cpp
@@ -5,64 +5,63 @@
|
||||
// #define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb_image.h>
|
||||
|
||||
namespace amy {
|
||||
void image::load(cstr& path) {
|
||||
namespace Amy {
|
||||
void Image::Load(ksr path) {
|
||||
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) {
|
||||
// Releoading the Image with tree channels requestet
|
||||
// Still need to find a better way for this :(
|
||||
stbi_image_free(buf);
|
||||
buf = stbi_load(path.c_str(), &m_w, &m_h, &c, 3);
|
||||
m_buffer.assign(buf, buf + (m_w * m_h * 3));
|
||||
m_fmt = RGB;
|
||||
buf = stbi_load(path.c_str(), &pW, &pH, &c, 3);
|
||||
pBuffer.assign(buf, buf + (pW * pH * 3));
|
||||
pFmt = RGB;
|
||||
stbi_image_free(buf);
|
||||
} else if (c == 4) {
|
||||
m_buffer.assign(buf, buf + (m_w * m_h * 4));
|
||||
m_fmt = RGBA;
|
||||
pBuffer.assign(buf, buf + (pW * pH * 4));
|
||||
pFmt = RGBA;
|
||||
stbi_image_free(buf);
|
||||
} else {
|
||||
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;
|
||||
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) {
|
||||
// Releoading the Image with tree channels requestet
|
||||
// Still need to find a better way for this :(
|
||||
stbi_image_free(buf);
|
||||
buf = stbi_load_from_memory(data.data(), data.size(), &m_w, &m_h, &c, 3);
|
||||
m_buffer.assign(buf, buf + (m_w * m_h * 3));
|
||||
m_fmt = RGB;
|
||||
buf = stbi_load_from_memory(data.data(), data.size(), &pW, &pH, &c, 3);
|
||||
pBuffer.assign(buf, buf + (pW * pH * 3));
|
||||
pFmt = RGB;
|
||||
stbi_image_free(buf);
|
||||
} else if (m_fmt == 4) {
|
||||
m_buffer.assign(buf, buf + (m_w * m_h * 4));
|
||||
m_fmt = RGBA;
|
||||
} else if (pFmt == 4) {
|
||||
pBuffer.assign(buf, buf + (pW * pH * 4));
|
||||
pFmt = RGBA;
|
||||
stbi_image_free(buf);
|
||||
} else {
|
||||
throw std::runtime_error("image mem using an unsupported image format!");
|
||||
}
|
||||
}
|
||||
|
||||
void image::copy(const std::vector<uc>& pixels, int w, int h,
|
||||
const format& fmt) {
|
||||
int f = getBppOfFmt(fmt);
|
||||
void Image::Copy(kvr<uc> pixels, int w, int h, const Format& fmt) {
|
||||
int f = GetBppOfFmt(fmt);
|
||||
if (pixels.size() != static_cast<size_t>(w * h * f)) {
|
||||
throw std::runtime_error("Connot copy image due to size error!");
|
||||
}
|
||||
m_fmt = fmt;
|
||||
m_w = w;
|
||||
m_h = h;
|
||||
m_buffer.clear();
|
||||
m_buffer.resize(w * h * f);
|
||||
for (size_t i = 0; i < m_buffer.size(); i++) {
|
||||
m_buffer[i] = pixels[i];
|
||||
pFmt = fmt;
|
||||
pW = w;
|
||||
pH = h;
|
||||
pBuffer.clear();
|
||||
pBuffer.resize(w * h * f);
|
||||
for (size_t i = 0; i < pBuffer.size(); i++) {
|
||||
pBuffer[i] = pixels[i];
|
||||
}
|
||||
}
|
||||
|
||||
int image::getBppOfFmt(const image::format& fmt) {
|
||||
int Image::GetBppOfFmt(const Image::Format& fmt) {
|
||||
switch (fmt) {
|
||||
case RGBA:
|
||||
case ABGR:
|
||||
@@ -83,28 +82,28 @@ int image::getBppOfFmt(const image::format& fmt) {
|
||||
}
|
||||
}
|
||||
|
||||
void image::convert(image& img, const format& dst) {
|
||||
if (img.m_fmt == dst) {
|
||||
void Image::Convert(Image& img, const Format& dst) {
|
||||
if (img.pFmt == dst) {
|
||||
return;
|
||||
} else if (img.m_fmt == RGB && dst == BGR) {
|
||||
utils::image::reverseBuf(img.m_buffer, img.m_w, img.m_h, 3);
|
||||
img.m_fmt = BGR;
|
||||
} else if (img.m_fmt == RGB && dst == RGBA) {
|
||||
utils::image::addAlphaChannel(img.m_buffer, img.m_w, img.m_h);
|
||||
img.m_fmt = RGBA;
|
||||
} else if (img.m_fmt == RGBA && dst == RGB) {
|
||||
utils::image::removeAlphaChannel(img.m_buffer, img.m_w, img.m_h);
|
||||
img.m_fmt = RGB;
|
||||
} else if (img.m_fmt == RGBA && dst == ABGR) {
|
||||
utils::image::reverseBuf(img.m_buffer, img.m_w, img.m_h, 4);
|
||||
img.m_fmt = ABGR;
|
||||
} else if (img.m_fmt == RGB && dst == ABGR) {
|
||||
convert(img, RGBA);
|
||||
convert(img, ABGR);
|
||||
} else if (img.m_fmt == RGBA && dst == RGB565) {
|
||||
convert(img, RGB);
|
||||
convert(img, RGB565);
|
||||
} else if (img.m_fmt == RGB && dst == RGB565) {
|
||||
} else if (img.pFmt == RGB && dst == BGR) {
|
||||
Utils::Image::ReverseBuf(img.pBuffer, img.pW, img.pH, 3);
|
||||
img.pFmt = BGR;
|
||||
} else if (img.pFmt == RGB && dst == RGBA) {
|
||||
Utils::Image::AddAlphaChannel(img.pBuffer, img.pW, img.pH);
|
||||
img.pFmt = RGBA;
|
||||
} else if (img.pFmt == RGBA && dst == RGB) {
|
||||
Utils::Image::RemoveAlphaChannel(img.pBuffer, img.pW, img.pH);
|
||||
img.pFmt = RGB;
|
||||
} else if (img.pFmt == RGBA && dst == ABGR) {
|
||||
Utils::Image::ReverseBuf(img.pBuffer, img.pW, img.pH, 4);
|
||||
img.pFmt = ABGR;
|
||||
} else if (img.pFmt == RGB && dst == ABGR) {
|
||||
Convert(img, RGBA);
|
||||
Convert(img, ABGR);
|
||||
} else if (img.pFmt == RGBA && dst == RGB565) {
|
||||
Convert(img, RGB);
|
||||
Convert(img, RGB565);
|
||||
} else if (img.pFmt == RGB && dst == RGB565) {
|
||||
// Inlined make pixel 565 func
|
||||
auto f = [](uc r, uc g, uc b) -> unsigned short {
|
||||
unsigned short _r = (r >> 3);
|
||||
@@ -112,35 +111,35 @@ void image::convert(image& img, const format& dst) {
|
||||
unsigned short _b = (b >> 3);
|
||||
return (_r << 11) | (_g << 5) | _b;
|
||||
};
|
||||
std::vector<uc> cpy = img.m_buffer;
|
||||
img.m_buffer.resize(img.m_w * img.m_h * 2);
|
||||
for (int y = 0; y < img.m_w; y++) {
|
||||
for (int x = 0; x < img.m_h; x++) {
|
||||
int src = (y * img.m_w + x) * 3;
|
||||
int dst = (y * img.m_w + x) * 2;
|
||||
std::vector<uc> cpy = img.pBuffer;
|
||||
img.pBuffer.resize(img.pW * img.pH * 2);
|
||||
for (int y = 0; y < img.pW; y++) {
|
||||
for (int x = 0; x < img.pH; x++) {
|
||||
int src = (y * img.pW + x) * 3;
|
||||
int dst = (y * img.pW + x) * 2;
|
||||
unsigned short new_px = f(cpy[src + 0], cpy[src + 1], cpy[src + 2]);
|
||||
img.m_buffer[dst + 0] = new_px >> 8;
|
||||
img.m_buffer[dst + 1] = new_px & 0xff;
|
||||
img.pBuffer[dst + 0] = new_px >> 8;
|
||||
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::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
|
||||
* file loading where fmt is used */
|
||||
int bpp = img.bpp();
|
||||
for (int y = 0; y < img.m_h; y++) {
|
||||
for (int x = 0; x < img.m_w; x++) {
|
||||
int src_idx = src(x, y, img.m_w);
|
||||
int dst_idx = dst(x, y, img.m_w);
|
||||
int bpp = img.Bpp();
|
||||
for (int y = 0; y < img.pH; y++) {
|
||||
for (int x = 0; x < img.pW; x++) {
|
||||
int src_idx = src(x, y, img.pW);
|
||||
int dst_idx = dst(x, y, img.pW);
|
||||
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
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <amethyst/iron.hpp>
|
||||
|
||||
/** Setup for everything (oder so) */
|
||||
enum LiPathRectFlags_ : amy::ui {
|
||||
enum LiPathRectFlags_ : Amy::ui {
|
||||
LiPathRectFlags_None = 0,
|
||||
LiPathRectFlags_KeepTopLeft = (1 << 0),
|
||||
LiPathRectFlags_KeepTopRight = (1 << 1),
|
||||
@@ -13,69 +13,67 @@ enum LiPathRectFlags_ : amy::ui {
|
||||
LiPathRectFlags_KeepRight = (1 << 1) | (1 << 2),
|
||||
};
|
||||
|
||||
namespace amy {
|
||||
namespace Amy {
|
||||
constexpr auto __pi = std::numbers::pi;
|
||||
|
||||
void iron::drawlist::merge(iron::drawlist* list) {
|
||||
for (size_t i = 0; i < list->m_data.size(); i++) {
|
||||
m_data.push_back(std::move(list->m_data[i]));
|
||||
void Iron::Drawlist::Merge(Iron::Drawlist* list) {
|
||||
for (size_t i = 0; i < list->pData.size(); 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() {
|
||||
auto ret = std::make_unique<command>();
|
||||
ret->layer = m_layer;
|
||||
ret->index = m_data.size();
|
||||
ret->tex = m_tex;
|
||||
Iron::Command::ref Iron::Drawlist::NewCommand() {
|
||||
auto ret = std::make_unique<Command>();
|
||||
ret->Layer = pLayer;
|
||||
ret->Index = pData.size();
|
||||
ret->Tex = pTex;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void iron::drawlist::clipCmd(command* ptr) {
|
||||
if (!clipRects.empty()) {
|
||||
ptr->scissorOn = true;
|
||||
ptr->scissorRect = ivec4(clipRects.top());
|
||||
void Iron::Drawlist::clipCmd(Command* ptr) {
|
||||
if (!ClipRects.empty()) {
|
||||
ptr->ScissorOn = true;
|
||||
ptr->ScissorRect = ivec4(ClipRects.top());
|
||||
}
|
||||
}
|
||||
|
||||
void iron::drawlist::push(command::ref cmd) {
|
||||
m_data.push_back(std::move(cmd));
|
||||
}
|
||||
void Iron::Drawlist::Push(Command::ref cmd) { pData.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) {
|
||||
// pathAdd(c)
|
||||
pathReserve(segments + 1);
|
||||
PathReserve(segments + 1);
|
||||
for (int i = 0; i < segments; i++) {
|
||||
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) {
|
||||
/**
|
||||
* Funcion with less division overhead
|
||||
* Usefull for stuff where a lot of calculations are required
|
||||
*/
|
||||
float d = (amax - amin) / s;
|
||||
pathReserve(s + 1);
|
||||
PathReserve(s + 1);
|
||||
for (int i = 0; i <= s; i++) {
|
||||
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) {
|
||||
pathAdd(a);
|
||||
pathAdd(fvec2(b.x, a.y));
|
||||
pathAdd(b);
|
||||
pathAdd(fvec2(a.x, b.y));
|
||||
PathAdd(a);
|
||||
PathAdd(fvec2(b.x, a.y));
|
||||
PathAdd(b);
|
||||
PathAdd(fvec2(a.x, b.y));
|
||||
} else {
|
||||
float r = std::min({rounding, (b.x - a.x) * 0.5f, (b.y - a.y) * 0.5f});
|
||||
/** 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
|
||||
*/
|
||||
/** Top Left */
|
||||
pathAdd(fvec2(a.x + r, a.y));
|
||||
pathFastArcToN(fvec2(b.x - r, a.y + r), r, -__pi / 2.0f, 0.0f, segments);
|
||||
PathAdd(fvec2(a.x + r, a.y));
|
||||
PathFastArcToN(fvec2(b.x - r, a.y + r), r, -__pi / 2.0f, 0.0f, segments);
|
||||
/** Top Right */
|
||||
pathAdd(fvec2(b.x, b.y - r));
|
||||
pathFastArcToN(fvec2(b.x - r, b.y - r), r, 0.0f, __pi / 2.0f, segments);
|
||||
PathAdd(fvec2(b.x, b.y - r));
|
||||
PathFastArcToN(fvec2(b.x - r, b.y - r), r, 0.0f, __pi / 2.0f, segments);
|
||||
/** Bottom Right */
|
||||
pathAdd(fvec2(a.x + r, b.y));
|
||||
pathFastArcToN(fvec2(a.x + r, b.y - r), r, __pi / 2.0f, __pi, segments);
|
||||
PathAdd(fvec2(a.x + r, b.y));
|
||||
PathFastArcToN(fvec2(a.x + r, b.y - r), r, __pi / 2.0f, __pi, segments);
|
||||
/** Bottom Left */
|
||||
pathAdd(fvec2(a.x, a.y + r));
|
||||
pathFastArcToN(fvec2(a.x + r, a.y + r), r, __pi, 3.0f * __pi / 2.0f,
|
||||
PathAdd(fvec2(a.x, a.y + r));
|
||||
PathFastArcToN(fvec2(a.x + r, a.y + r), r, __pi, 3.0f * __pi / 2.0f,
|
||||
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) {
|
||||
if (rounding == 0.f) {
|
||||
pathAdd(a);
|
||||
pathAdd(fvec2(b.x, a.y));
|
||||
pathAdd(b);
|
||||
pathAdd(fvec2(a.x, b.y));
|
||||
PathAdd(a);
|
||||
PathAdd(fvec2(b.x, a.y));
|
||||
PathAdd(b);
|
||||
PathAdd(fvec2(a.x, b.y));
|
||||
} else {
|
||||
float r = std::min({rounding, (b.x - a.x) * 0.5f, (b.y - a.y) * 0.5f});
|
||||
/** Calculate Optimal segment count automatically */
|
||||
@@ -121,95 +119,95 @@ void iron::drawlist::pathRectEx(const fvec2& a, const fvec2& b, float rounding,
|
||||
*/
|
||||
/** Top Left */
|
||||
if (flags & LiPathRectFlags_KeepTopLeft) {
|
||||
pathAdd(a);
|
||||
PathAdd(a);
|
||||
} else {
|
||||
pathAdd(fvec2(a.x + r, a.y));
|
||||
pathFastArcToN(fvec2(b.x - r, a.y + r), r, -__pi / 2.0f, 0.0f, segments);
|
||||
PathAdd(fvec2(a.x + r, a.y));
|
||||
PathFastArcToN(fvec2(b.x - r, a.y + r), r, -__pi / 2.0f, 0.0f, segments);
|
||||
}
|
||||
|
||||
/** Top Right */
|
||||
if (flags & LiPathRectFlags_KeepTopRight) {
|
||||
pathAdd(fvec2(b.x, a.y));
|
||||
PathAdd(fvec2(b.x, a.y));
|
||||
} else {
|
||||
pathAdd(fvec2(b.x, b.y - r));
|
||||
pathFastArcToN(fvec2(b.x - r, b.y - r), r, 0.0f, __pi / 2.0f, segments);
|
||||
PathAdd(fvec2(b.x, b.y - r));
|
||||
PathFastArcToN(fvec2(b.x - r, b.y - r), r, 0.0f, __pi / 2.0f, segments);
|
||||
}
|
||||
/** Bottom Right */
|
||||
if (flags & LiPathRectFlags_KeepBotRight) {
|
||||
pathAdd(b);
|
||||
PathAdd(b);
|
||||
} else {
|
||||
pathAdd(fvec2(a.x + r, b.y));
|
||||
pathFastArcToN(fvec2(a.x + r, b.y - r), r, __pi / 2.0f, __pi, segments);
|
||||
PathAdd(fvec2(a.x + r, b.y));
|
||||
PathFastArcToN(fvec2(a.x + r, b.y - r), r, __pi / 2.0f, __pi, segments);
|
||||
}
|
||||
/** Bottom Left */
|
||||
if (flags & LiPathRectFlags_KeepBotLeft) {
|
||||
pathAdd(fvec2(a.x, b.y));
|
||||
PathAdd(fvec2(a.x, b.y));
|
||||
} else {
|
||||
pathAdd(fvec2(a.x, a.y + r));
|
||||
pathFastArcToN(fvec2(a.x + r, a.y + r), r, __pi, 3.0f * __pi / 2.0f,
|
||||
PathAdd(fvec2(a.x, a.y + r));
|
||||
PathFastArcToN(fvec2(a.x + r, a.y + r), r, __pi, 3.0f * __pi / 2.0f,
|
||||
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) {
|
||||
pathRect(pos, pos + size);
|
||||
pathStroke(color, thickness, 1);
|
||||
PathRect(pos, pos + size);
|
||||
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) {
|
||||
pathRect(pos, pos + size);
|
||||
pathFill(color);
|
||||
PathRect(pos, pos + size);
|
||||
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) {
|
||||
pathAdd(a);
|
||||
pathAdd(b);
|
||||
pathAdd(c);
|
||||
pathStroke(color, thickness, 1);
|
||||
PathAdd(a);
|
||||
PathAdd(b);
|
||||
PathAdd(c);
|
||||
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) {
|
||||
pathAdd(a);
|
||||
pathAdd(b);
|
||||
pathAdd(c);
|
||||
pathFill(color);
|
||||
PathAdd(a);
|
||||
PathAdd(b);
|
||||
PathAdd(c);
|
||||
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) {
|
||||
if (segments <= 0) {
|
||||
// Auto Segment
|
||||
} else {
|
||||
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
|
||||
pathStroke(color, thickness, 1);
|
||||
DrawSolid(); // Only Solid Color Supported
|
||||
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) {
|
||||
if (segments <= 0) {
|
||||
// Auto Segment
|
||||
} else {
|
||||
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) {
|
||||
if (points.size() < 2) {
|
||||
return;
|
||||
}
|
||||
drawSolid();
|
||||
auto cmd = newCommand();
|
||||
DrawSolid();
|
||||
auto cmd = NewCommand();
|
||||
bool close = (flags & (1 << 0));
|
||||
int num_points = close ? (int)points.size() : (int)points.size() - 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
|
||||
for (int i = 0; i < num_points; i++) {
|
||||
int j = (i + 1) == (int)points.size() ? 0 : (i + 1);
|
||||
auto line = primLine(points[i], points[j], thickness);
|
||||
cmdQuad(cmd.get(), line, fvec4(0.f, 1.f, 1.f, 0.f), clr);
|
||||
auto line = PrimLine(points[i], points[j], thickness);
|
||||
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) {
|
||||
if (points.size() < 3) {
|
||||
return; // Need at least three points
|
||||
}
|
||||
auto cmd = newCommand();
|
||||
cmdConvexPolyFilled(cmd.get(), points, clr, m_tex);
|
||||
push(std::move(cmd));
|
||||
auto cmd = NewCommand();
|
||||
CmdConvexPolyFilled(cmd.get(), points, clr, pTex);
|
||||
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) {
|
||||
/*if (!pCurrentFont) {
|
||||
return;
|
||||
@@ -243,13 +241,13 @@ void iron::drawlist::drawText(const fvec2& pos, const std::string& text,
|
||||
std::vector<Command::Ref> cmds;
|
||||
pCurrentFont->CmdTextEx(cmds, pos, color, pFontScale, text);
|
||||
for (size_t i = 0; i < cmds.size(); i++) {
|
||||
cmds[i]->Index = pDrawList.size();
|
||||
cmds[i]->Index = pDrawlist.size();
|
||||
cmds[i]->Layer = Layer;
|
||||
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) {
|
||||
/*if (!pCurrentFont) {
|
||||
return;
|
||||
@@ -257,15 +255,15 @@ void iron::drawlist::drawTextEx(const fvec2& p, const std::string& text,
|
||||
std::vector<Command::Ref> cmds;
|
||||
pCurrentFont->CmdTextEx(cmds, p, color, pFontScale, text, flags, box);
|
||||
for (size_t i = 0; i < cmds.size(); i++) {
|
||||
cmds[i]->Index = pDrawList.size();
|
||||
cmds[i]->Index = pDrawlist.size();
|
||||
cmds[i]->Layer = Layer;
|
||||
AddCommand(std::move(cmds[i]));
|
||||
}*/
|
||||
}
|
||||
|
||||
void iron::drawlist::drawLine(const fvec2& a, const fvec2& b, ui color, int t) {
|
||||
pathAdd(a);
|
||||
pathAdd(b);
|
||||
pathStroke(color, t);
|
||||
void Iron::Drawlist::DrawLine(const fvec2& a, const fvec2& b, ui color, int t) {
|
||||
PathAdd(a);
|
||||
PathAdd(b);
|
||||
PathStroke(color, t);
|
||||
}
|
||||
} // namespace amy
|
||||
} // namespace Amy
|
||||
@@ -14,7 +14,7 @@
|
||||
} \
|
||||
})
|
||||
|
||||
namespace amy {
|
||||
namespace Amy {
|
||||
const char* __ironshader__ = R"(; LI7 Shader
|
||||
; Constants
|
||||
.constf myconst(0.0, 1.0, 0.00392156862745, 0.0)
|
||||
@@ -56,117 +56,117 @@ unsigned char li_shader[] = {
|
||||
};
|
||||
// clang-format on
|
||||
size_t li_shader_size = 0x124;
|
||||
std::vector<iron::vertex, linearAllocator<iron::vertex>> iron::m_vbuf;
|
||||
std::vector<u16, linearAllocator<u16>> iron::m_ibuf;
|
||||
int iron::uLocProj = 0;
|
||||
c3d::shader* iron::m_shader = nullptr;
|
||||
mat4 iron::m_mtx;
|
||||
int iron::m_idx = 0, iron::m_vtx = 0;
|
||||
texture* iron::m_solid = nullptr;
|
||||
std::vector<Iron::Vertex, linearAllocator<Iron::Vertex>> Iron::m_vbuf;
|
||||
std::vector<u16, linearAllocator<u16>> Iron::m_ibuf;
|
||||
int Iron::uLocProj = 0;
|
||||
C3D::Shader* Iron::m_shader = nullptr;
|
||||
mat4 Iron::m_mtx;
|
||||
int Iron::m_idx = 0, Iron::m_vtx = 0;
|
||||
Texture* Iron::m_solid = nullptr;
|
||||
|
||||
void iron::init() {
|
||||
setupShader();
|
||||
void Iron::Init() {
|
||||
pSetupShader();
|
||||
m_vbuf.resize(4 * 4096);
|
||||
m_ibuf.resize(6 * 4096);
|
||||
initSolidTex();
|
||||
pInitSolidTex();
|
||||
}
|
||||
|
||||
void iron::newFrame() {
|
||||
void Iron::NewFrame() {
|
||||
m_idx = 0;
|
||||
m_vtx = 0;
|
||||
}
|
||||
|
||||
void iron::drawOn(c3d::screen* screen) {
|
||||
m_shader->use();
|
||||
m_mtx = mat4::ortho(0.f, (float)screen->width(), (float)screen->height(), 0.f,
|
||||
void Iron::DrawOn(C3D::Screen* screen) {
|
||||
m_shader->Use();
|
||||
m_mtx = mat4::ortho(0.f, (float)screen->Width(), (float)screen->Height(), 0.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
|
||||
c3d::depthTest(false);
|
||||
fragConfig();
|
||||
C3D::DepthTest(false);
|
||||
pFragConfig();
|
||||
size_t i = 0;
|
||||
while (i < data.size()) {
|
||||
texture* tex = data[i]->tex;
|
||||
Texture* tex = data[i]->Tex;
|
||||
if (!tex) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
auto scissorOn = data[i]->scissorOn;
|
||||
auto scissor = data[i]->scissorRect;
|
||||
auto scissorOn = data[i]->ScissorOn;
|
||||
auto scissor = data[i]->ScissorRect;
|
||||
auto start = i;
|
||||
|
||||
// Loop until a statgechange and copy all data into vertex/index buf
|
||||
while (i < data.size() && scissorOn == data[i]->scissorOn &&
|
||||
scissor == data[i]->scissorRect && tex == data[i]->tex) {
|
||||
// Loop until a statgechange and copy all data into Vertex/index buf
|
||||
while (i < data.size() && scissorOn == data[i]->ScissorOn &&
|
||||
scissor == data[i]->ScissorRect && tex == data[i]->Tex) {
|
||||
auto c = data[i].get();
|
||||
|
||||
for (int j = 0; j < c->indexBuf.size(); j++) {
|
||||
m_ibuf[m_idx++] = m_vtx + c->indexBuf[j];
|
||||
for (int j = 0; j < c->IndexBuf.size(); j++) {
|
||||
m_ibuf[m_idx++] = m_vtx + c->IndexBuf[j];
|
||||
}
|
||||
for (int j = 0; j < c->vertexBuf.size(); j++) {
|
||||
m_vbuf[m_vtx++] = c->vertexBuf[j];
|
||||
for (int j = 0; j < c->VertexBuf.size(); j++) {
|
||||
m_vbuf[m_vtx++] = c->VertexBuf[j];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
///// SCISSOR LOGIC BEG /////
|
||||
///// SCISSOR LOGIC END /////
|
||||
tex->bind();
|
||||
c3d::bufCfg<3>(m_vbuf.data(), sizeof(vertex));
|
||||
c3d::drawElements(i - start, m_ibuf.data() + start);
|
||||
tex->Bind();
|
||||
C3D::BufCfg<3>(m_vbuf.data(), sizeof(Vertex));
|
||||
C3D::DrawElements(i - start, m_ibuf.data() + start);
|
||||
}
|
||||
c3d::depthTest(true);
|
||||
C3D::DepthTest(true);
|
||||
}
|
||||
|
||||
void iron::setupShader() {
|
||||
m_shader = new c3d::shader();
|
||||
m_shader->load("romfs:/shaders/lithium.shbin");
|
||||
// m_shader->compile(__ironshader__);
|
||||
m_shader->input(GPU_FLOAT, 2); // pos
|
||||
m_shader->input(GPU_FLOAT, 2); // uv
|
||||
m_shader->input(GPU_UNSIGNED_BYTE, 4); // color
|
||||
void Iron::pSetupShader() {
|
||||
m_shader = new C3D::Shader();
|
||||
m_shader->Load("romfs:/shaders/lithium.shbin");
|
||||
// m_shader->Compile(__ironshader__);
|
||||
m_shader->Input(GPU_FLOAT, 2); // pos
|
||||
m_shader->Input(GPU_FLOAT, 2); // uv
|
||||
m_shader->Input(GPU_UNSIGNED_BYTE, 4); // color
|
||||
uLocProj = m_shader->loc("projection");
|
||||
}
|
||||
|
||||
void iron::fragConfig() {
|
||||
c3d::frag::edit();
|
||||
c3d::frag::src(C3D_Both, GPU_TEXTURE0);
|
||||
c3d::frag::func(C3D_Both, GPU_MODULATE);
|
||||
void Iron::pFragConfig() {
|
||||
C3D::Frag::Edit();
|
||||
C3D::Frag::Src(C3D_Both, GPU_TEXTURE0);
|
||||
C3D::Frag::Func(C3D_Both, GPU_MODULATE);
|
||||
}
|
||||
|
||||
void iron::initSolidTex() {
|
||||
void Iron::pInitSolidTex() {
|
||||
// i know there is a lot of memory wasted :(
|
||||
std::vector<uc> pixels(16 * 16 * 4, 0xff);
|
||||
m_solid = new texture();
|
||||
m_solid->load(pixels, 16, 16);
|
||||
m_solid = new Texture();
|
||||
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 &&
|
||||
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 &&
|
||||
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) {
|
||||
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.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 y = pos.y * c - pos.x * s;
|
||||
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 corner[4] = {
|
||||
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 co = std::cos(angle);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
rotateCorner(corner[i], s, co);
|
||||
RotateCorner(corner[i], s, co);
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
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
|
||||
fvec2 dir = a - b;
|
||||
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 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) {
|
||||
cmd->add(0).add(1).add(2);
|
||||
cmd->add(0).add(2).add(3);
|
||||
cmd->add(vertex(q.botRight(), uv.botRight(), color));
|
||||
cmd->add(vertex(q.topRight(), uv.topRight(), color));
|
||||
cmd->add(vertex(q.topLeft(), uv.topLeft(), color));
|
||||
cmd->add(vertex(q.botLeft(), uv.botLeft(), 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(2).Add(3);
|
||||
cmd->Add(Vertex(q.BotRight(), uv.BotRight(), color));
|
||||
cmd->Add(Vertex(q.TopRight(), uv.TopRight(), color));
|
||||
cmd->Add(Vertex(q.TopLeft(), uv.TopLeft(), 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) {
|
||||
cmd->add(2).add(1).add(0); // reverse cause otherwise invisible
|
||||
cmd->add(vertex(a, fvec2(0, 1), color));
|
||||
cmd->add(vertex(b, fvec2(1, 1), color));
|
||||
cmd->add(vertex(c, fvec2(1, 0), color));
|
||||
cmd->Add(2).Add(1).Add(0); // reverse cause otherwise invisible
|
||||
cmd->Add(Vertex(a, fvec2(0, 1), color));
|
||||
cmd->Add(Vertex(b, fvec2(1, 1), color));
|
||||
cmd->Add(Vertex(c, fvec2(1, 0), color));
|
||||
}
|
||||
|
||||
void iron::cmdConvexPolyFilled(command* cmd, const std::vector<fvec2>& points,
|
||||
ui color, texture* tex) {
|
||||
void Iron::CmdConvexPolyFilled(Command* cmd, const std::vector<fvec2>& points,
|
||||
ui color, Texture* tex) {
|
||||
if (points.size() < 3 || tex == nullptr) {
|
||||
#ifdef AMY_GOD_DEV
|
||||
return;
|
||||
#else
|
||||
throw std::runtime_error("[amy] iron: trying to render convex poly with " +
|
||||
std::to_string(points.size()) +
|
||||
" points and texture " + std::to_string((ui)tex));
|
||||
" points and Texture " + std::to_string((ui)tex));
|
||||
#endif
|
||||
}
|
||||
// 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
|
||||
// (Bottom Right is not required)
|
||||
auto uv_tl = tex->uv().topLeft();
|
||||
auto uv_tr = tex->uv().topRight();
|
||||
auto uv_bl = tex->uv().botLeft();
|
||||
auto uv_tl = tex->Uv().TopLeft();
|
||||
auto uv_tr = tex->Uv().TopRight();
|
||||
auto uv_bl = tex->Uv().BotLeft();
|
||||
|
||||
// Render
|
||||
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++) {
|
||||
// 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);
|
||||
float v =
|
||||
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
|
||||
@@ -24,7 +24,7 @@ SOFTWARE.
|
||||
|
||||
#include <amethyst/maths/mat.hpp>
|
||||
|
||||
namespace amy {
|
||||
namespace Amy {
|
||||
mat4 mat4::rotateX(float a) {
|
||||
float c = std::cos(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);
|
||||
return ret;
|
||||
}
|
||||
} // namespace amy
|
||||
} // namespace Amy
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <amethyst/renderer.hpp>
|
||||
|
||||
namespace amy {
|
||||
namespace Amy {
|
||||
Renderer::Renderer() {}
|
||||
|
||||
Renderer::~Renderer() {}
|
||||
} // namespace amy
|
||||
} // namespace Amy
|
||||
@@ -6,88 +6,87 @@
|
||||
#include <amethyst/utils.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace amy {
|
||||
namespace Amy {
|
||||
ui tile3dsTex(int x, int y, int w) {
|
||||
return ((((y >> 3) * ((int)w >> 3) + (x >> 3)) << 6) +
|
||||
((x & 1) | ((y & 1) << 1) | ((x & 2) << 1) | ((y & 2) << 2) |
|
||||
((x & 4) << 2) | ((y & 4) << 3)));
|
||||
}
|
||||
|
||||
GPU_TEXCOLOR image2TexFmt(const image::format& fmt) {
|
||||
GPU_TEXCOLOR image2TexFmt(const Image::Format& fmt) {
|
||||
switch (fmt) {
|
||||
case image::RGB:
|
||||
case Image::RGB:
|
||||
return GPU_RGB8;
|
||||
break;
|
||||
case image::RGBA:
|
||||
case Image::RGBA:
|
||||
return GPU_RGBA8;
|
||||
break;
|
||||
case image::RGB565:
|
||||
case Image::RGB565:
|
||||
return GPU_RGB565;
|
||||
break;
|
||||
default:
|
||||
// Dummy
|
||||
return GPU_A4;
|
||||
throw std::runtime_error(
|
||||
"[amy] texture: Unsupported texture format used!");
|
||||
"[amy] texture: Unsupported texture Format used!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
texture::texture(cstr& path) { load(path); }
|
||||
Texture::Texture(ksr path) { Load(path); }
|
||||
|
||||
texture::~texture() { unload(); }
|
||||
Texture::~Texture() { Unload(); }
|
||||
|
||||
void texture::unload() {
|
||||
if (m_loaded) {
|
||||
C3D_TexDelete(&m_tex);
|
||||
m_loaded = false;
|
||||
void Texture::Unload() {
|
||||
if (pLoaded) {
|
||||
C3D_TexDelete(&pTex);
|
||||
pLoaded = false;
|
||||
}
|
||||
}
|
||||
|
||||
void texture::load(cstr& path) {
|
||||
image img(path);
|
||||
if (img.width() > 1024 || img.height() > 1024) {
|
||||
void Texture::Load(ksr 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(const std::vector<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) {
|
||||
throw std::runtime_error("Max Texture Size is 1024x1024!");
|
||||
}
|
||||
unload();
|
||||
Unload();
|
||||
|
||||
m_size.x = w;
|
||||
if (utils::isSingleBitNum(m_size.x)) {
|
||||
m_size.x = utils::nextPow2(m_size.x);
|
||||
pSize.x = w;
|
||||
if (Utils::IsSingleBitNum(pSize.x)) {
|
||||
pSize.x = Utils::NextPow2(pSize.x);
|
||||
}
|
||||
m_size.y = h;
|
||||
if (utils::isSingleBitNum(m_size.y)) {
|
||||
m_size.y = utils::nextPow2(m_size.y);
|
||||
pSize.y = h;
|
||||
if (Utils::IsSingleBitNum(pSize.y)) {
|
||||
pSize.y = Utils::NextPow2(pSize.y);
|
||||
}
|
||||
auto filter = GPU_NEAREST;
|
||||
auto format = image2TexFmt(fmt);
|
||||
C3D_TexInit(&m_tex, (u16)m_size.x, (u16)m_size.y, format);
|
||||
C3D_TexSetFilter(&m_tex, filter, filter);
|
||||
auto Format = image2TexFmt(fmt);
|
||||
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
|
||||
// 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 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;
|
||||
/// Best idea i had
|
||||
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);
|
||||
m_tex.border = 0x00000000;
|
||||
C3D_TexSetWrap(&m_tex, GPU_REPEAT, GPU_REPEAT);
|
||||
m_loaded = true;
|
||||
C3D_TexFlush(&pTex);
|
||||
pTex.border = 0x00000000;
|
||||
C3D_TexSetWrap(&pTex, GPU_REPEAT, GPU_REPEAT);
|
||||
pLoaded = true;
|
||||
}
|
||||
|
||||
void texture::bind(int reg) { C3D_TexBind(reg, &m_tex); }
|
||||
} // namespace amy
|
||||
void Texture::Bind(int reg) { C3D_TexBind(reg, &pTex); }
|
||||
} // namespace Amy
|
||||
@@ -1,9 +1,9 @@
|
||||
#include <amethyst/utils.hpp>
|
||||
#include <fstream>
|
||||
|
||||
namespace amy {
|
||||
namespace utils {
|
||||
ui fastHash(cstr& s) {
|
||||
namespace Amy {
|
||||
namespace Utils {
|
||||
ui fastHash(ksr s) {
|
||||
ui hash = 5381;
|
||||
for (auto& it : s) {
|
||||
hash = (hash * 33) + static_cast<uc>(it);
|
||||
@@ -11,7 +11,7 @@ ui fastHash(cstr& s) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
vec<uc> loadFile2Mem(cstr& path) {
|
||||
vec<uc> LoadFile2Mem(ksr path) {
|
||||
std::ifstream iff(path, std::ios::binary);
|
||||
if (!iff) {
|
||||
return vec<uc>();
|
||||
@@ -25,7 +25,7 @@ vec<uc> loadFile2Mem(cstr& path) {
|
||||
return res;
|
||||
}
|
||||
|
||||
ui hashMemory(cvec<uc>& data) {
|
||||
ui HashMemory(kvr<uc> data) {
|
||||
ui hash = 4477;
|
||||
for (auto& it : data) {
|
||||
hash = (hash * 33) + it;
|
||||
@@ -33,7 +33,7 @@ ui hashMemory(cvec<uc>& data) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
ui nextPow2(ui v) {
|
||||
ui NextPow2(ui v) {
|
||||
v--;
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
@@ -44,10 +44,26 @@ ui nextPow2(ui v) {
|
||||
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 {
|
||||
void reverseBuf(vec<uc>& buf, int w, int h, int c) {
|
||||
ull GetTimeNano() {
|
||||
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;
|
||||
for (int x = 0; x < w; x++) {
|
||||
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;
|
||||
buf.resize(w * h * 3);
|
||||
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;
|
||||
buf.resize(w * h * 4);
|
||||
for (int y = 0; y < h; y++) {
|
||||
@@ -87,6 +103,6 @@ void addAlphaChannel(vec<uc>& buf, int w, int h) {
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace image
|
||||
} // namespace utils
|
||||
} // namespace amy
|
||||
} // namespace Image
|
||||
} // namespace Utils
|
||||
} // namespace Amy
|
||||
Reference in New Issue
Block a user