From f2f259cb5a6d886b27e6e4213cdf8eb670b5f3e8 Mon Sep 17 00:00:00 2001 From: Jaby Date: Tue, 23 Apr 2024 23:04:17 +0200 Subject: [PATCH] Support proper scaling and other MATRIX operations --- .../src/Overlay/GTETest/gte_test.cpp | 25 +++++---- .../Overlay/GTETest/include/GTE_Sprite.hpp | 42 ++++++++------- include/PSX/GTE/gte_types.hpp | 52 +++++++++++++++++-- include/string.hpp | 7 ++- src/Library/src/System/string.cpp | 39 ++++++++++++++ 5 files changed, 133 insertions(+), 32 deletions(-) diff --git a/examples/PoolBox/application/src/Overlay/GTETest/gte_test.cpp b/examples/PoolBox/application/src/Overlay/GTETest/gte_test.cpp index c9a68f82..f2d1a0b1 100644 --- a/examples/PoolBox/application/src/Overlay/GTETest/gte_test.cpp +++ b/examples/PoolBox/application/src/Overlay/GTETest/gte_test.cpp @@ -11,14 +11,14 @@ namespace GTETest { namespace Jaby { static constexpr auto Position = Make::PositionI16(GPU::Display::Width - 64, GPU::Display::Height - 64); - static constexpr GPU::POLY_FT4::Linked make_star_eye(GPU::PositionI16 pos) { - return Make::POLY_FT4( + static constexpr GTE_Sprite make_star_eye(GPU::PositionI16 pos) { + return GTE_Sprite::create(Make::POLY_FT4( Make::AreaI16(pos, GPU::SizeI16(8, 8)), JabySTARTim.get_page_offset_clut4().add(0, 64), Make::TPage(JabySTARTim.get_texture_position(), GPU::SemiTransparency::B_add_F, GPU::TextureColorMode::clut4), Make::PageClut(JabySTARTim.get_clut_position()), GPU::Color24::Grey() - ).linked(); + ).linked()); } static auto star_base = Make::SPRT( @@ -27,9 +27,10 @@ namespace GTETest { Make::OffsetPageWithClut(JabySTARTim.get_page_offset_clut4(), Make::PageClut(JabySTARTim.get_clut_position())) ).linked(); - static GPU::POLY_FT4::Linked star_eyes[2] = { - make_star_eye(Position.add(12, 31)), - make_star_eye(Position.add(33, 33))}; + static GTE_Sprite star_eyes[2] = { + make_star_eye(Position.add(11, 30)), + make_star_eye(Position.add(33, 31)) + }; } static auto doener_fish = GTE_Sprite::create(Make::POLY_FT4( @@ -38,12 +39,15 @@ namespace GTETest { Make::TPage(Assets::Main::DoenerFishInfo.tim.get_texture_position(), GPU::SemiTransparency::B_add_F, GPU::TextureColorMode::clut4), Make::PageClut(Assets::Main::DoenerFishInfo.tim.get_clut_position()), GPU::Color24::Grey() - )); + ).linked()); static auto gbl_rotation = 0.0_deg; static void setup() { - Jaby::star_base.concat(Jaby::star_eyes[0].concat(Jaby::star_eyes[1])); + Jaby::star_base.concat(Jaby::star_eyes[0].display.concat(Jaby::star_eyes[1].display)); + Jaby::star_eyes[0].scale = 2.5_gf; + Jaby::star_eyes[1].scale = 3.5_gf; + doener_fish.area.position = GPU::PositionI16::create(100, 100); Shared::back_menu.reset(); @@ -57,8 +61,11 @@ namespace GTETest { return true; } - auto matrix = GTE::MATRIX::rotated(-gbl_rotation, gbl_rotation, -gbl_rotation); + auto matrix = GTE::MATRIX::rotated(0.0_deg, 0.0_deg, -gbl_rotation); //(-gbl_rotation, gbl_rotation, -gbl_rotation); doener_fish.apply(matrix); + Jaby::star_eyes[0].apply(); + Jaby::star_eyes[1].apply(); + doener_fish.angle += 25.0_deg; gbl_rotation += 2.5_deg; return false; diff --git a/examples/PoolBox/application/src/Overlay/GTETest/include/GTE_Sprite.hpp b/examples/PoolBox/application/src/Overlay/GTETest/include/GTE_Sprite.hpp index 51f1d0e7..e6bf841f 100644 --- a/examples/PoolBox/application/src/Overlay/GTETest/include/GTE_Sprite.hpp +++ b/examples/PoolBox/application/src/Overlay/GTETest/include/GTE_Sprite.hpp @@ -3,37 +3,41 @@ #include #include +#include + namespace GTETest { using namespace JabyEngine; struct GTE_Sprite { - GPU::AreaI16 area; - GPU::PositionI16 pivot; - deg_t angle; - GPU::POLY_FT4 display; + GPU::AreaI16 area; + GPU::PositionI16 pivot; + deg_t angle; + gte_float scale; + GPU::POLY_FT4::Linked display; - static constexpr GTE_Sprite create(const GPU::POLY_FT4& base) { + static constexpr GTE_Sprite create(const GPU::POLY_FT4::Linked& base) { + const auto rect_size = base->get_rect_size(); return GTE_Sprite{ - .area = GPU::AreaI16::create(base.get_rect_pos(), base.get_rect_size()), - .pivot = GPU::PositionI16::create(base.get_rect_size().width/2, base.get_rect_size().height/2), + .area = GPU::AreaI16::create(base->get_rect_pos(), rect_size), + .pivot = GPU::PositionI16::create(rect_size.width/2, rect_size.height/2), .angle = 0.0_deg, + .scale = 1.0_gf, .display = base }; } - void apply(const GTE::MATRIX& gbl_matrix) { - auto matrix = GTE::MATRIX::translated(-this->pivot.x, -this->pivot.y, 0).comp( - GTE::MATRIX::rotated(0.0_deg, 0.0_deg, this->angle) - ).comp( - GTE::MATRIX::translated(this->pivot.x, this->pivot.y, 0) - ).comp( - GTE::MATRIX::translated(this->area.position.x, this->area.position.y) - ).comp(gbl_matrix); + void apply(const GTE::MATRIX& gbl_matrix = GTE::MATRIX::identity()) { + const auto matrix = + GTE::MATRIX::translated(-this->pivot.x, -this->pivot.y, 0) + .rotate(0.0_deg, 0.0_deg, this->angle) + .scale(this->scale, this->scale) + .translate(this->area.position.x + this->pivot.x, this->area.position.y + this->pivot.y, 0) + .comp(gbl_matrix); - this->display.vertex0 = matrix.apply_to(GPU::Vertex::create(0, 0)); - this->display.vertex1 = matrix.apply_to(GPU::Vertex::create(this->area.size.width, 0)); - this->display.vertex2 = matrix.apply_to(GPU::Vertex::create(0, this->area.size.height)); - this->display.vertex3 = matrix.apply_to(GPU::Vertex::create(this->area.size.width, this->area.size.height)); + this->display->vertex0 = matrix.apply_to(GPU::Vertex::create(0, 0)); + this->display->vertex1 = matrix.apply_to(GPU::Vertex::create(this->area.size.width, 0)); + this->display->vertex2 = matrix.apply_to(GPU::Vertex::create(0, this->area.size.height)); + this->display->vertex3 = matrix.apply_to(GPU::Vertex::create(this->area.size.width, this->area.size.height)); } void render() { diff --git a/include/PSX/GTE/gte_types.hpp b/include/PSX/GTE/gte_types.hpp index 76924a6c..8c318b24 100644 --- a/include/PSX/GTE/gte_types.hpp +++ b/include/PSX/GTE/gte_types.hpp @@ -1,6 +1,8 @@ #pragma once +#include "../GPU/Primitives/primitive_poly_types.hpp" #include "../GPU/gpu_types.hpp" #include "../../math.hpp" +#include "../../stdio.hpp" namespace JabyEngine { namespace GTE { @@ -50,7 +52,16 @@ namespace JabyEngine { }; } - static ROTMATRIX rotated(deg_t x = deg_t::zero(), deg_t y = deg_t::zero(), deg_t z = deg_t::zero()); + static constexpr ROTMATRIX scaled(gte_float sx = 1.0_gf, gte_float sy = 1.0_gf, gte_float sz = 1.0_gf) { + return ROTMATRIX{.matrix = { + {static_cast(sx), 0, 0}, + {0, static_cast(sy), 0}, + {0, 0, static_cast(sz)} + } + }; + } + + static ROTMATRIX rotated(deg_t x = 0.0_deg, deg_t y = 0.0_deg, deg_t z = 0.0_deg); }; struct TRANSFERVECTOR : public VECTOR { @@ -75,7 +86,11 @@ namespace JabyEngine { return MATRIX{.rotation = ROTMATRIX::identity(), .transfer = TRANSFERVECTOR::translated(x, y, z)}; } - static MATRIX rotated(deg_t x = deg_t::zero(), deg_t y = deg_t::zero(), deg_t z = deg_t::zero()) { + static constexpr MATRIX scaled(gte_float sx = 1.0_gf, gte_float sy = 1.0_gf, gte_float sz = 1.0_gf) { + return MATRIX{.rotation = ROTMATRIX::scaled(sx, sy, sz), .transfer = TRANSFERVECTOR::identity()}; + } + + static MATRIX rotated(deg_t x = 0.0_deg, deg_t y = 0.0_deg, deg_t z = 0.0_deg) { return MATRIX{.rotation = ROTMATRIX::rotated(x, y, z), .transfer = TRANSFERVECTOR::identity()}; } @@ -84,9 +99,40 @@ namespace JabyEngine { return new_matrix; } - MATRIX& comp(const MATRIX& matrix); + void dump() const { + printf("---\n"); + printf("|%i|%i|%i|\n", this->rotation.matrix[0][0], this->rotation.matrix[0][1], this->rotation.matrix[0][2]); + printf("|%i|%i|%i|\n", this->rotation.matrix[1][0], this->rotation.matrix[1][1], this->rotation.matrix[1][2]); + printf("|%i|%i|%i|\n", this->rotation.matrix[2][0], this->rotation.matrix[2][1], this->rotation.matrix[2][2]); + printf("~~~\n"); + printf("|%i|%i|%i|\n", this->transfer.x, this->transfer.y, this->transfer.z); + printf("---\n"); + } + + MATRIX& comp(const MATRIX& matrix); + MATRIX& translate(int32_t x = 0, int32_t y = 0, int32_t z = 0) { + return MATRIX::comp(MATRIX::translated(x, y, z)); + } + + MATRIX& scale(gte_float sx = 1.0_gf, gte_float sy = 1.0_gf, gte_float sz = 1.0_gf) { + return MATRIX::comp(MATRIX::scaled(sx, sy, sz)); + } + + MATRIX& rotate(deg_t x = 0.0_deg, deg_t y = 0.0_deg, deg_t z = 0.0_deg) { + return MATRIX::comp(MATRIX::rotated(x, y, z)); + } + GPU::Vertex& apply_to(GPU::Vertex& vertex) const; GPU::Vertex apply_to(const GPU::Vertex& vertex) const; + + GPU::POLY_FT4& apply_to(GPU::POLY_FT4& poly) const { + MATRIX::apply_to(poly.vertex0); + MATRIX::apply_to(poly.vertex1); + MATRIX::apply_to(poly.vertex2); + MATRIX::apply_to(poly.vertex3); + + return poly; + } }; } } \ No newline at end of file diff --git a/include/string.hpp b/include/string.hpp index cbc601c6..072c20b8 100644 --- a/include/string.hpp +++ b/include/string.hpp @@ -2,4 +2,9 @@ #include "PSX/jabyengine_defines.hpp" int strncmp(const char* s1, const char* s2, size_t n); -size_t strlen(const char* str); \ No newline at end of file +size_t strlen(const char* str); + +extern "C" { + // Needs to be provided for GCC optimizations + void* memset(void* dest, int val, size_t len); +} \ No newline at end of file diff --git a/src/Library/src/System/string.cpp b/src/Library/src/System/string.cpp index 9d7ab7c4..593aecd5 100644 --- a/src/Library/src/System/string.cpp +++ b/src/Library/src/System/string.cpp @@ -22,4 +22,43 @@ size_t strlen(const char *str) { for(; *end; ++end); return(end - str); +} + +template +static void* core_memset(T* dst, int val, size_t &len) { + while(len >= sizeof(T)) { + *dst++ = val; + len -= sizeof(T); + } + + return dst; +} + +static void* simple_memset(void* dest, int val, size_t len) { + core_memset(static_cast(dest), val, len); + return dest; +} + +static void* cplx_memset(void* dst, int val, size_t len) { + void*const org_dst = dst; + + if(reinterpret_cast(dst) & 0x2 == 0) { + dst = core_memset(static_cast(dst), val, len); + } + + if(reinterpret_cast(dst) & 0x1 == 0) { + dst = core_memset(static_cast(dst), val, len); + } + + if(len > 0) { + simple_memset(dst, val, len); + } + return org_dst; +} + +extern "C" { + // TODO: Speed measure + void* memset(void* dest, int val, size_t len) { + return simple_memset(dest, val, len); + } } \ No newline at end of file