Support proper scaling and other MATRIX operations

This commit is contained in:
jaby 2024-04-23 23:04:17 +02:00
parent b4099a7f97
commit 0d16995895
5 changed files with 133 additions and 32 deletions

View File

@ -11,14 +11,14 @@ namespace GTETest {
namespace Jaby { namespace Jaby {
static constexpr auto Position = Make::PositionI16(GPU::Display::Width - 64, GPU::Display::Height - 64); 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) { static constexpr GTE_Sprite make_star_eye(GPU::PositionI16 pos) {
return Make::POLY_FT4( return GTE_Sprite::create(Make::POLY_FT4(
Make::AreaI16(pos, GPU::SizeI16(8, 8)), Make::AreaI16(pos, GPU::SizeI16(8, 8)),
JabySTARTim.get_page_offset_clut4().add(0, 64), JabySTARTim.get_page_offset_clut4().add(0, 64),
Make::TPage(JabySTARTim.get_texture_position(), GPU::SemiTransparency::B_add_F, GPU::TextureColorMode::clut4), Make::TPage(JabySTARTim.get_texture_position(), GPU::SemiTransparency::B_add_F, GPU::TextureColorMode::clut4),
Make::PageClut(JabySTARTim.get_clut_position()), Make::PageClut(JabySTARTim.get_clut_position()),
GPU::Color24::Grey() GPU::Color24::Grey()
).linked(); ).linked());
} }
static auto star_base = Make::SPRT( 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())) Make::OffsetPageWithClut(JabySTARTim.get_page_offset_clut4(), Make::PageClut(JabySTARTim.get_clut_position()))
).linked(); ).linked();
static GPU::POLY_FT4::Linked star_eyes[2] = { static GTE_Sprite star_eyes[2] = {
make_star_eye(Position.add(12, 31)), make_star_eye(Position.add(11, 30)),
make_star_eye(Position.add(33, 33))}; make_star_eye(Position.add(33, 31))
};
} }
static auto doener_fish = GTE_Sprite::create(Make::POLY_FT4( 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::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()), Make::PageClut(Assets::Main::DoenerFishInfo.tim.get_clut_position()),
GPU::Color24::Grey() GPU::Color24::Grey()
)); ).linked());
static auto gbl_rotation = 0.0_deg; static auto gbl_rotation = 0.0_deg;
static void setup() { 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); doener_fish.area.position = GPU::PositionI16::create(100, 100);
Shared::back_menu.reset(); Shared::back_menu.reset();
@ -57,8 +61,11 @@ namespace GTETest {
return true; 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); doener_fish.apply(matrix);
Jaby::star_eyes[0].apply();
Jaby::star_eyes[1].apply();
doener_fish.angle += 25.0_deg; doener_fish.angle += 25.0_deg;
gbl_rotation += 2.5_deg; gbl_rotation += 2.5_deg;
return false; return false;

View File

@ -3,37 +3,41 @@
#include <PSX/GPU/gpu.hpp> #include <PSX/GPU/gpu.hpp>
#include <PSX/GTE/gte.hpp> #include <PSX/GTE/gte.hpp>
#include <stdio.hpp>
namespace GTETest { namespace GTETest {
using namespace JabyEngine; using namespace JabyEngine;
struct GTE_Sprite { struct GTE_Sprite {
GPU::AreaI16 area; GPU::AreaI16 area;
GPU::PositionI16 pivot; GPU::PositionI16 pivot;
deg_t angle; deg_t angle;
GPU::POLY_FT4 display; 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{ return GTE_Sprite{
.area = GPU::AreaI16::create(base.get_rect_pos(), base.get_rect_size()), .area = GPU::AreaI16::create(base->get_rect_pos(), rect_size),
.pivot = GPU::PositionI16::create(base.get_rect_size().width/2, base.get_rect_size().height/2), .pivot = GPU::PositionI16::create(rect_size.width/2, rect_size.height/2),
.angle = 0.0_deg, .angle = 0.0_deg,
.scale = 1.0_gf,
.display = base .display = base
}; };
} }
void apply(const GTE::MATRIX& gbl_matrix) { void apply(const GTE::MATRIX& gbl_matrix = GTE::MATRIX::identity()) {
auto matrix = GTE::MATRIX::translated(-this->pivot.x, -this->pivot.y, 0).comp( const auto matrix =
GTE::MATRIX::rotated(0.0_deg, 0.0_deg, this->angle) GTE::MATRIX::translated(-this->pivot.x, -this->pivot.y, 0)
).comp( .rotate(0.0_deg, 0.0_deg, this->angle)
GTE::MATRIX::translated(this->pivot.x, this->pivot.y, 0) .scale(this->scale, this->scale)
).comp( .translate(this->area.position.x + this->pivot.x, this->area.position.y + this->pivot.y, 0)
GTE::MATRIX::translated(this->area.position.x, this->area.position.y) .comp(gbl_matrix);
).comp(gbl_matrix);
this->display.vertex0 = matrix.apply_to(GPU::Vertex::create(0, 0)); 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->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->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->vertex3 = matrix.apply_to(GPU::Vertex::create(this->area.size.width, this->area.size.height));
} }
void render() { void render() {

View File

@ -1,6 +1,8 @@
#pragma once #pragma once
#include "../GPU/Primitives/primitive_poly_types.hpp"
#include "../GPU/gpu_types.hpp" #include "../GPU/gpu_types.hpp"
#include "../../math.hpp" #include "../../math.hpp"
#include "../../stdio.hpp"
namespace JabyEngine { namespace JabyEngine {
namespace GTE { 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<int16_t>(sx), 0, 0},
{0, static_cast<int16_t>(sy), 0},
{0, 0, static_cast<int16_t>(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 { struct TRANSFERVECTOR : public VECTOR {
@ -75,7 +86,11 @@ namespace JabyEngine {
return MATRIX{.rotation = ROTMATRIX::identity(), .transfer = TRANSFERVECTOR::translated(x, y, z)}; 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()}; return MATRIX{.rotation = ROTMATRIX::rotated(x, y, z), .transfer = TRANSFERVECTOR::identity()};
} }
@ -84,9 +99,40 @@ namespace JabyEngine {
return new_matrix; 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(GPU::Vertex& vertex) const;
GPU::Vertex apply_to(const 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;
}
}; };
} }
} }

View File

@ -2,4 +2,9 @@
#include "PSX/jabyengine_defines.hpp" #include "PSX/jabyengine_defines.hpp"
int strncmp(const char* s1, const char* s2, size_t n); int strncmp(const char* s1, const char* s2, size_t n);
size_t strlen(const char* str); size_t strlen(const char* str);
extern "C" {
// Needs to be provided for GCC optimizations
void* memset(void* dest, int val, size_t len);
}

View File

@ -22,4 +22,43 @@ size_t strlen(const char *str) {
for(; *end; ++end); for(; *end; ++end);
return(end - str); return(end - str);
}
template<typename T>
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<uint8_t*>(dest), val, len);
return dest;
}
static void* cplx_memset(void* dst, int val, size_t len) {
void*const org_dst = dst;
if(reinterpret_cast<uintptr_t>(dst) & 0x2 == 0) {
dst = core_memset(static_cast<uint32_t*>(dst), val, len);
}
if(reinterpret_cast<uintptr_t>(dst) & 0x1 == 0) {
dst = core_memset(static_cast<uint16_t*>(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);
}
} }