Fix inconsistent EOL

This commit is contained in:
2025-01-08 22:27:37 +01:00
parent 57671ac79d
commit 1f7141c517
184 changed files with 13686 additions and 13685 deletions

View File

@@ -1,241 +1,241 @@
#pragma once
#include "gte_instruction.hpp"
namespace JabyEngine {
namespace GTE {
static constexpr auto StackSize = 16;
/*
matrix: first input
Sets the 3x3 constant rotation matrix and the parallel transfer vector from input
*/
void set_matrix(const MATRIX& matrix);
/*
returns: current matrix
Gets the current 3x3 constant rotation matrix and the parallel transfer vector
*/
MATRIX get_matrix();
/*
RotTrans
Perform coordinate transformation using a rotation matrix
input: Input vector
output: Output vector
flag: flag output
*/
static void rot_trans(const SVECTOR& input, VECTOR& output, int32_t& flag) {
ldv0(input);
rt();
stlvnl(output);
stflg(flag);
}
/*
ScaleMatrix
m: Pointer to matrix (input/output)
v: Pointer to scale vector (input)
result: m
Scales m by v. The components of v are fixed point decimals in which 1.0 represents 4096
*/
static ROTMATRIX& scale_matrix(ROTMATRIX& m, const VECTOR& v) {
static const auto multiply_matrix_row = [](int32_t value, ROTMATRIX& matrix, size_t row) {
ldir0(value); // lwc2 r8, v.x
ldclmv(matrix, row); // load matrix row to r9 - r11 (mtc2)
gpf12(); // gte_gpf12
stclmv(matrix, row); // store matrix row
};
multiply_matrix_row(v.x, m, 0);
multiply_matrix_row(v.y, m, 1);
multiply_matrix_row(v.z, m, 2);
return m;
}
/*
SetRotMatrix
Sets a 3x3 matrix m as a constant rotation matrix.
matrix: The rotation matrix to set
*/
static void set_rot_matrix(const ROTMATRIX& matrix) {
__asm__ volatile("lw $12, 0(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("lw $13, 4(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $12, $0" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $13, $1" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("lw $12, 8(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("lw $13, 12(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("lw $14, 16(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $12, $2" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $13, $3" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $14, $4" :: "r"(&matrix) : "$12", "$13", "$14");
}
/*
GetRotMatrix
Writes the current 3x3 constant rotation matrix to matrix
(This doesn't require us to use memory clobber)
*/
static void get_rot_matrix(ROTMATRIX &matrix) {
__asm__ volatile("cfc2 $12, $0" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("cfc2 $13, $1" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("sw $12, 0(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("sw $13, 4(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("cfc2 $12, $2" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("cfc2 $13, $3" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("cfc2 $14, $4" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("sw $12, 8(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("sw $13, 12(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("sw $14, 16(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
}
/*
SetTransMatrix
Sets a constant parallel transfer vector specified by m
*/
static void set_trans_vector(const TRANSFERVECTOR& vector) {
__asm__ volatile("lw $12, 0(%0)" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("lw $13, 4(%0)" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $12, $5" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("lw $14, 8(%0)" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $13, $6" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $14, $7" :: "r"(&vector) : "$12", "$13", "$14");
}
/*
GetTransMatrix
Writes the current constant parallel transfer vector to matrix
(This doesn't require us to use memory clobber)
*/
static void get_trans_vector(TRANSFERVECTOR& vector) {
__asm__ volatile("cfc2 $14, $7" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("cfc2 $13, $6" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("sw $14, 8(%0)" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("cfc2 $12, $5" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("sw $13, 4(%0)" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("sw $12, 0(%0)" :: "r"(&vector) : "$12", "$13", "$14");
}
/*
ApplyMatrix
m0: Matrix to apply
v0: Vector to apply to
v1: Result
returns: result
Applies the matrix to the vector
The function destroys the constant rotation matrix and transfer vector
*/
static SVECTOR& apply_matrix(const MATRIX& m0, const SVECTOR& v0, SVECTOR& v1) {
set_matrix(m0);
JabyEngine::GTE::ldv0(v0);
JabyEngine::GTE::rt();
JabyEngine::GTE::stsv(v1);
return v1;
}
/*
Same as apply_matrix but works on Vertex
*/
static GPU::Vertex& apply_matrix(const MATRIX& m0, const GPU::Vertex& v0, GPU::Vertex& v1) {
set_matrix(m0);
JabyEngine::GTE::ldgv0(v0);
JabyEngine::GTE::rt();
JabyEngine::GTE::stgv(v1);
return v1;
}
/*
MulMatrix0
m0: first input
m1: second input
result: result of multiplication
returns: result
Multiplies two matrices m0 and m1.
The function destroys the constant rotation matrix
*/
ROTMATRIX& multiply_matrix(const ROTMATRIX& m0, const ROTMATRIX& m1, ROTMATRIX& result);
/*
CompMatrix
m0: first input
m1: second input
result: result of computing m0 and m1
return: returns result
*/
static MATRIX& comp_matrix(const MATRIX& m0, const MATRIX& m1, MATRIX& result) {
multiply_matrix(m0.rotation, m1.rotation, result.rotation);
set_trans_vector(m0.transfer);
GTE::ldlv0(reinterpret_cast<const VECTOR&>(m1.transfer));
GTE::rt();
GTE::stlvnl(reinterpret_cast<VECTOR&>(result.transfer));
return result;
}
/*
matrix: optional input
Pushes the current matrix (rotation and parallel) to an internal stack
Optional: replaces current matrix (rotation and parallel) with input
*/
void push_matrix();
void push_matrix_and_set(const MATRIX& matrix);
/*
Restores the previous stored matrix (rotation and parallel)
*/
MATRIX get_and_pop_matrix();
void pop_matrix();
/*
SetGeomOffset(ofx,ofy)
Load GTE-offset.
*/
static void set_geom_offset(int32_t off_x, int32_t off_y) {
__asm__ volatile("sll $12, %0, 16" :: "r"(off_x), "r"(off_y) : "$12", "$13");
__asm__ volatile("sll $13, %1, 16" :: "r"(off_x), "r"(off_y) : "$12", "$13");
__asm__ volatile("ctc2 $12, $24" :: "r"(off_x), "r"(off_y) : "$12", "$13");
__asm__ volatile("ctc2 $13, $25" :: "r"(off_x), "r"(off_y) : "$12", "$13");
}
/*
SetGeomScreen(h)
Load distance from viewpoint to screen.
*/
static void set_geom_screen(int32_t h) {
__asm__ volatile("ctc2 %0, $26" :: "r"(h));
}
// Implementations for the MATRIX struct
inline MATRIX& MATRIX :: comp(const MATRIX& matrix) {
return comp_matrix(matrix, *this, *this);
}
inline GPU::Vertex& MATRIX :: apply_to(GPU::Vertex& vertex) const {
return apply_matrix(*this, vertex, vertex);
}
inline GPU::Vertex MATRIX :: apply_to(const GPU::Vertex& vertex) const {
GPU::Vertex result;
apply_matrix(*this, vertex, result);
return result;
}
}
#pragma once
#include "gte_instruction.hpp"
namespace JabyEngine {
namespace GTE {
static constexpr auto StackSize = 16;
/*
matrix: first input
Sets the 3x3 constant rotation matrix and the parallel transfer vector from input
*/
void set_matrix(const MATRIX& matrix);
/*
returns: current matrix
Gets the current 3x3 constant rotation matrix and the parallel transfer vector
*/
MATRIX get_matrix();
/*
RotTrans
Perform coordinate transformation using a rotation matrix
input: Input vector
output: Output vector
flag: flag output
*/
static void rot_trans(const SVECTOR& input, VECTOR& output, int32_t& flag) {
ldv0(input);
rt();
stlvnl(output);
stflg(flag);
}
/*
ScaleMatrix
m: Pointer to matrix (input/output)
v: Pointer to scale vector (input)
result: m
Scales m by v. The components of v are fixed point decimals in which 1.0 represents 4096
*/
static ROTMATRIX& scale_matrix(ROTMATRIX& m, const VECTOR& v) {
static const auto multiply_matrix_row = [](int32_t value, ROTMATRIX& matrix, size_t row) {
ldir0(value); // lwc2 r8, v.x
ldclmv(matrix, row); // load matrix row to r9 - r11 (mtc2)
gpf12(); // gte_gpf12
stclmv(matrix, row); // store matrix row
};
multiply_matrix_row(v.x, m, 0);
multiply_matrix_row(v.y, m, 1);
multiply_matrix_row(v.z, m, 2);
return m;
}
/*
SetRotMatrix
Sets a 3x3 matrix m as a constant rotation matrix.
matrix: The rotation matrix to set
*/
static void set_rot_matrix(const ROTMATRIX& matrix) {
__asm__ volatile("lw $12, 0(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("lw $13, 4(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $12, $0" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $13, $1" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("lw $12, 8(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("lw $13, 12(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("lw $14, 16(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $12, $2" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $13, $3" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $14, $4" :: "r"(&matrix) : "$12", "$13", "$14");
}
/*
GetRotMatrix
Writes the current 3x3 constant rotation matrix to matrix
(This doesn't require us to use memory clobber)
*/
static void get_rot_matrix(ROTMATRIX &matrix) {
__asm__ volatile("cfc2 $12, $0" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("cfc2 $13, $1" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("sw $12, 0(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("sw $13, 4(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("cfc2 $12, $2" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("cfc2 $13, $3" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("cfc2 $14, $4" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("sw $12, 8(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("sw $13, 12(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
__asm__ volatile("sw $14, 16(%0)" :: "r"(&matrix) : "$12", "$13", "$14");
}
/*
SetTransMatrix
Sets a constant parallel transfer vector specified by m
*/
static void set_trans_vector(const TRANSFERVECTOR& vector) {
__asm__ volatile("lw $12, 0(%0)" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("lw $13, 4(%0)" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $12, $5" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("lw $14, 8(%0)" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $13, $6" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("ctc2 $14, $7" :: "r"(&vector) : "$12", "$13", "$14");
}
/*
GetTransMatrix
Writes the current constant parallel transfer vector to matrix
(This doesn't require us to use memory clobber)
*/
static void get_trans_vector(TRANSFERVECTOR& vector) {
__asm__ volatile("cfc2 $14, $7" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("cfc2 $13, $6" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("sw $14, 8(%0)" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("cfc2 $12, $5" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("sw $13, 4(%0)" :: "r"(&vector) : "$12", "$13", "$14");
__asm__ volatile("sw $12, 0(%0)" :: "r"(&vector) : "$12", "$13", "$14");
}
/*
ApplyMatrix
m0: Matrix to apply
v0: Vector to apply to
v1: Result
returns: result
Applies the matrix to the vector
The function destroys the constant rotation matrix and transfer vector
*/
static SVECTOR& apply_matrix(const MATRIX& m0, const SVECTOR& v0, SVECTOR& v1) {
set_matrix(m0);
JabyEngine::GTE::ldv0(v0);
JabyEngine::GTE::rt();
JabyEngine::GTE::stsv(v1);
return v1;
}
/*
Same as apply_matrix but works on Vertex
*/
static GPU::Vertex& apply_matrix(const MATRIX& m0, const GPU::Vertex& v0, GPU::Vertex& v1) {
set_matrix(m0);
JabyEngine::GTE::ldgv0(v0);
JabyEngine::GTE::rt();
JabyEngine::GTE::stgv(v1);
return v1;
}
/*
MulMatrix0
m0: first input
m1: second input
result: result of multiplication
returns: result
Multiplies two matrices m0 and m1.
The function destroys the constant rotation matrix
*/
ROTMATRIX& multiply_matrix(const ROTMATRIX& m0, const ROTMATRIX& m1, ROTMATRIX& result);
/*
CompMatrix
m0: first input
m1: second input
result: result of computing m0 and m1
return: returns result
*/
static MATRIX& comp_matrix(const MATRIX& m0, const MATRIX& m1, MATRIX& result) {
multiply_matrix(m0.rotation, m1.rotation, result.rotation);
set_trans_vector(m0.transfer);
GTE::ldlv0(reinterpret_cast<const VECTOR&>(m1.transfer));
GTE::rt();
GTE::stlvnl(reinterpret_cast<VECTOR&>(result.transfer));
return result;
}
/*
matrix: optional input
Pushes the current matrix (rotation and parallel) to an internal stack
Optional: replaces current matrix (rotation and parallel) with input
*/
void push_matrix();
void push_matrix_and_set(const MATRIX& matrix);
/*
Restores the previous stored matrix (rotation and parallel)
*/
MATRIX get_and_pop_matrix();
void pop_matrix();
/*
SetGeomOffset(ofx,ofy)
Load GTE-offset.
*/
static void set_geom_offset(int32_t off_x, int32_t off_y) {
__asm__ volatile("sll $12, %0, 16" :: "r"(off_x), "r"(off_y) : "$12", "$13");
__asm__ volatile("sll $13, %1, 16" :: "r"(off_x), "r"(off_y) : "$12", "$13");
__asm__ volatile("ctc2 $12, $24" :: "r"(off_x), "r"(off_y) : "$12", "$13");
__asm__ volatile("ctc2 $13, $25" :: "r"(off_x), "r"(off_y) : "$12", "$13");
}
/*
SetGeomScreen(h)
Load distance from viewpoint to screen.
*/
static void set_geom_screen(int32_t h) {
__asm__ volatile("ctc2 %0, $26" :: "r"(h));
}
// Implementations for the MATRIX struct
inline MATRIX& MATRIX :: comp(const MATRIX& matrix) {
return comp_matrix(matrix, *this, *this);
}
inline GPU::Vertex& MATRIX :: apply_to(GPU::Vertex& vertex) const {
return apply_matrix(*this, vertex, vertex);
}
inline GPU::Vertex MATRIX :: apply_to(const GPU::Vertex& vertex) const {
GPU::Vertex result;
apply_matrix(*this, vertex, result);
return result;
}
}
}

View File

@@ -1,137 +1,137 @@
#pragma once
#include "gte_types.hpp"
namespace JabyEngine {
namespace GTE {
// Load vertex or normal to vertex register 0
static __always_inline void ldv0(const SVECTOR& vector) {
__asm__ volatile("lwc2 $0, 0(%0)" :: "r"(&vector));
__asm__ volatile("lwc2 $1, 4(%0)" :: "r"(&vector));
}
// Load vertex or normal to vertex register 1
static __always_inline void ldv1(const SVECTOR& vector) {
__asm__ volatile("lwc2 $2, 0(%0)" :: "r"(&vector));
__asm__ volatile("lwc2 $3, 4(%0)" :: "r"(&vector));
}
// Load vertex or normal to vertex register 2
static __always_inline void ldv2(const SVECTOR& vector) {
__asm__ volatile("lwc2 $4, 0(%0)" :: "r"(&vector));
__asm__ volatile("lwc2 $5, 4(%0)" :: "r"(&vector));
}
// Load int32_t to ir0 register (for multiplying usually)
static __always_inline void ldir0(const int32_t& value) {
__asm__ volatile("lwc2 $8, 0(%0)" :: "r"(&value));
}
// Load LS 16 bits of VECTOR to 16 bit universal vector.
static __always_inline void ldlv0(const VECTOR& vector) {
__asm__ volatile("lhu $13, 4(%0)" :: "r"(&vector) : "$12", "$13");
__asm__ volatile("lhu $12, 0(%0)" :: "r"(&vector) : "$12", "$13");
__asm__ volatile("sll $13, $13, 16" :: "r"(&vector) : "$12", "$13");
__asm__ volatile("or $12, $12, $13" :: "r"(&vector) : "$12", "$13");
__asm__ volatile("mtc2 $12, $0" :: "r"(&vector) : "$12", "$13");
__asm__ volatile("lwc2 $1, 8(%0)" :: "r"(&vector) : "$12", "$13");
}
// Loads a GPU VERTEX type
static __always_inline void ldgv0(const GPU::Vertex& vertex) {
__asm__ volatile("lwc2 $0, 0(%0)" :: "r"(&vertex));
__asm__ volatile("lwc2 $1, 0" :: "r"(&vertex));
}
// Load column vector of MATRIX to universal register
static __always_inline void ldclmv(const ROTMATRIX& matrix, size_t col) {
__asm__ volatile("lhu $12, 0(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
__asm__ volatile("lhu $13, 6(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
__asm__ volatile("lhu $14, 12(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
__asm__ volatile("mtc2 $12, $9" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
__asm__ volatile("mtc2 $13, $10" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
__asm__ volatile("mtc2 $14, $11" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
}
// Store flag
static __always_inline void stflg(int32_t& flag) {
__asm__ volatile("cfc2 $12, $31" :: "r"(&flag) : "$12", "memory");
__asm__ volatile("nop" :: "r"(&flag) : "$12", "memory");
__asm__ volatile("sw $12, 0(%0)" :: "r"(&flag) : "$12", "memory");
}
// Store MATRIX column from 16 bit universal register
static __always_inline void stclmv(ROTMATRIX& matrix, size_t col) {
__asm__ volatile("mfc2 $12, $9" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
__asm__ volatile("mfc2 $13, $10" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
__asm__ volatile("mfc2 $14, $11" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $12, 0(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $13, 6(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $14, 12(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
}
// Store VECTOR from 32 bit universal register
static __always_inline void stlvnl(VECTOR& out_vector) {
__asm__ volatile("swc2 $25, 0(%0)" :: "r"(&out_vector) : "memory");
__asm__ volatile("swc2 $26, 4(%0)" :: "r"(&out_vector) : "memory");
__asm__ volatile("swc2 $27, 8(%0)" :: "r"(&out_vector) : "memory");
}
// Modify to store in VERTEX?
// Store SVECTOR from 16 bit universal register
static __always_inline void stsv(SVECTOR& out_vector) {
__asm__ volatile("mfc2 $12, $9" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
__asm__ volatile("mfc2 $13, $10" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
__asm__ volatile("mfc2 $14, $11" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $12, 0(%0)" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $13, 2(%0)" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $14, 4(%0)" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
}
// Stores result into a GPU Vertex type
static __always_inline void stgv(GPU::Vertex& out_vertex) {
__asm__ volatile("mfc2 $12, $9" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory");
__asm__ volatile("mfc2 $13, $10" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $12, 0(%0)" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $13, 2(%0)" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory");
}
/*
Kernel of RotTrans
(Transfer vector)+(Rotation Matrix)*(vertex register 0)
*/
static __always_inline void rt() {
__asm__ volatile("nop");
__asm__ volatile("nop");
__asm__ volatile("cop2 0x0480012");
}
/*
Variation of gte_rt
(Rotation Matrix)*(vertex register 0).
*/
static __always_inline void rtv0() {
__asm__ volatile("nop;");
__asm__ volatile("nop;");
__asm__ volatile("cop2 0x0486012;");
}
/*
Variation of gte_rt
(Rotation Matrix)*(16 bit universal vector)
*/
static __always_inline void rtir() {
__asm__ volatile("nop");
__asm__ volatile("nop");
__asm__ volatile("cop2 0x049E012");
}
/*
Last half of LoadAverage12.
*/
static __always_inline void gpf12(){
__asm__ volatile("nop");
__asm__ volatile("nop");
__asm__ volatile("cop2 0x0198003D");
}
}
#pragma once
#include "gte_types.hpp"
namespace JabyEngine {
namespace GTE {
// Load vertex or normal to vertex register 0
static __always_inline void ldv0(const SVECTOR& vector) {
__asm__ volatile("lwc2 $0, 0(%0)" :: "r"(&vector));
__asm__ volatile("lwc2 $1, 4(%0)" :: "r"(&vector));
}
// Load vertex or normal to vertex register 1
static __always_inline void ldv1(const SVECTOR& vector) {
__asm__ volatile("lwc2 $2, 0(%0)" :: "r"(&vector));
__asm__ volatile("lwc2 $3, 4(%0)" :: "r"(&vector));
}
// Load vertex or normal to vertex register 2
static __always_inline void ldv2(const SVECTOR& vector) {
__asm__ volatile("lwc2 $4, 0(%0)" :: "r"(&vector));
__asm__ volatile("lwc2 $5, 4(%0)" :: "r"(&vector));
}
// Load int32_t to ir0 register (for multiplying usually)
static __always_inline void ldir0(const int32_t& value) {
__asm__ volatile("lwc2 $8, 0(%0)" :: "r"(&value));
}
// Load LS 16 bits of VECTOR to 16 bit universal vector.
static __always_inline void ldlv0(const VECTOR& vector) {
__asm__ volatile("lhu $13, 4(%0)" :: "r"(&vector) : "$12", "$13");
__asm__ volatile("lhu $12, 0(%0)" :: "r"(&vector) : "$12", "$13");
__asm__ volatile("sll $13, $13, 16" :: "r"(&vector) : "$12", "$13");
__asm__ volatile("or $12, $12, $13" :: "r"(&vector) : "$12", "$13");
__asm__ volatile("mtc2 $12, $0" :: "r"(&vector) : "$12", "$13");
__asm__ volatile("lwc2 $1, 8(%0)" :: "r"(&vector) : "$12", "$13");
}
// Loads a GPU VERTEX type
static __always_inline void ldgv0(const GPU::Vertex& vertex) {
__asm__ volatile("lwc2 $0, 0(%0)" :: "r"(&vertex));
__asm__ volatile("lwc2 $1, 0" :: "r"(&vertex));
}
// Load column vector of MATRIX to universal register
static __always_inline void ldclmv(const ROTMATRIX& matrix, size_t col) {
__asm__ volatile("lhu $12, 0(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
__asm__ volatile("lhu $13, 6(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
__asm__ volatile("lhu $14, 12(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
__asm__ volatile("mtc2 $12, $9" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
__asm__ volatile("mtc2 $13, $10" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
__asm__ volatile("mtc2 $14, $11" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14");
}
// Store flag
static __always_inline void stflg(int32_t& flag) {
__asm__ volatile("cfc2 $12, $31" :: "r"(&flag) : "$12", "memory");
__asm__ volatile("nop" :: "r"(&flag) : "$12", "memory");
__asm__ volatile("sw $12, 0(%0)" :: "r"(&flag) : "$12", "memory");
}
// Store MATRIX column from 16 bit universal register
static __always_inline void stclmv(ROTMATRIX& matrix, size_t col) {
__asm__ volatile("mfc2 $12, $9" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
__asm__ volatile("mfc2 $13, $10" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
__asm__ volatile("mfc2 $14, $11" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $12, 0(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $13, 6(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $14, 12(%0)" :: "r"(reinterpret_cast<uintptr_t>(&matrix) + (col << 1)) : "$12", "$13", "$14", "memory");
}
// Store VECTOR from 32 bit universal register
static __always_inline void stlvnl(VECTOR& out_vector) {
__asm__ volatile("swc2 $25, 0(%0)" :: "r"(&out_vector) : "memory");
__asm__ volatile("swc2 $26, 4(%0)" :: "r"(&out_vector) : "memory");
__asm__ volatile("swc2 $27, 8(%0)" :: "r"(&out_vector) : "memory");
}
// Modify to store in VERTEX?
// Store SVECTOR from 16 bit universal register
static __always_inline void stsv(SVECTOR& out_vector) {
__asm__ volatile("mfc2 $12, $9" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
__asm__ volatile("mfc2 $13, $10" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
__asm__ volatile("mfc2 $14, $11" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $12, 0(%0)" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $13, 2(%0)" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $14, 4(%0)" :: "r"(&out_vector) : "$12", "$13", "$14", "memory");
}
// Stores result into a GPU Vertex type
static __always_inline void stgv(GPU::Vertex& out_vertex) {
__asm__ volatile("mfc2 $12, $9" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory");
__asm__ volatile("mfc2 $13, $10" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $12, 0(%0)" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory");
__asm__ volatile("sh $13, 2(%0)" :: "r"(&out_vertex) : "$12", "$13", "$14", "memory");
}
/*
Kernel of RotTrans
(Transfer vector)+(Rotation Matrix)*(vertex register 0)
*/
static __always_inline void rt() {
__asm__ volatile("nop");
__asm__ volatile("nop");
__asm__ volatile("cop2 0x0480012");
}
/*
Variation of gte_rt
(Rotation Matrix)*(vertex register 0).
*/
static __always_inline void rtv0() {
__asm__ volatile("nop;");
__asm__ volatile("nop;");
__asm__ volatile("cop2 0x0486012;");
}
/*
Variation of gte_rt
(Rotation Matrix)*(16 bit universal vector)
*/
static __always_inline void rtir() {
__asm__ volatile("nop");
__asm__ volatile("nop");
__asm__ volatile("cop2 0x049E012");
}
/*
Last half of LoadAverage12.
*/
static __always_inline void gpf12(){
__asm__ volatile("nop");
__asm__ volatile("nop");
__asm__ volatile("cop2 0x0198003D");
}
}
}

View File

@@ -1,138 +1,138 @@
#pragma once
#include "../GPU/Primitives/primitive_poly_types.hpp"
#include "../GPU/gpu_types.hpp"
#include "../../math.hpp"
#include "../../stdio.hpp"
namespace JabyEngine {
namespace GTE {
namespace internal {
template<typename T>
struct VECTOR {
T x;
T y;
T z;
T pad;
static constexpr VECTOR create() {
return VECTOR::create(0, 0, 0);
}
static constexpr VECTOR create(T x, T y, T z) {
return VECTOR{.x = x, .y = y, .z = z, .pad = 0};
}
static constexpr VECTOR create(gte_float x, gte_float y, gte_float z) {
return VECTOR{.x = static_cast<T>(x), .y = static_cast<T>(y), .z = static_cast<T>(z)};
}
template<typename S>
static constexpr VECTOR from(const GPU::Position<S>& pos) {
return VECTOR::create(static_cast<T>(pos.x), static_cast<T>(pos.y), 0);
}
template<typename S>
constexpr S to() const {
return S::create(static_cast<S::PrimitiveType>(this->x), static_cast<S::PrimitiveType>(this->y));
}
};
}
using VECTOR = internal::VECTOR<int32_t>;
using SVECTOR = internal::VECTOR<int16_t>;
struct ROTMATRIX {
int16_t matrix[3][3];
static constexpr ROTMATRIX identity() {
return ROTMATRIX{.matrix = {
{static_cast<int16_t>(gte_float::one()), 0, 0},
{0, static_cast<int16_t>(gte_float::one()), 0},
{0, 0, static_cast<int16_t>(gte_float::one())}
}
};
}
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 {
static constexpr TRANSFERVECTOR identity() {
return TRANSFERVECTOR::translated();
}
static constexpr TRANSFERVECTOR translated(int32_t x = 0, int32_t y = 0, int32_t z = 0) {
return TRANSFERVECTOR{{.x = x, .y = y, .z = z}};
}
};
struct MATRIX {
ROTMATRIX rotation;
TRANSFERVECTOR transfer;
static constexpr MATRIX identity() {
return MATRIX{.rotation = ROTMATRIX::identity(), .transfer = TRANSFERVECTOR::identity()};
}
static constexpr MATRIX translated(int32_t x = 0, int32_t y = 0, int32_t z = 0) {
return MATRIX{.rotation = ROTMATRIX::identity(), .transfer = TRANSFERVECTOR::translated(x, y, z)};
}
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()};
}
static MATRIX comp(MATRIX new_matrix, const MATRIX& matrix) {
new_matrix.comp(matrix);
return new_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;
template<typename T>
T& apply_to_area(T& poly, const GPU::AreaI16& area) const {
poly.vertex0 = MATRIX::apply_to(GPU::POLY_G4::vertex0_from(area));
poly.vertex1 = MATRIX::apply_to(GPU::POLY_G4::vertex1_from(area));
poly.vertex2 = MATRIX::apply_to(GPU::POLY_G4::vertex2_from(area));
poly.vertex3 = MATRIX::apply_to(GPU::POLY_G4::vertex3_from(area));
return poly;
}
};
}
#pragma once
#include "../GPU/Primitives/primitive_poly_types.hpp"
#include "../GPU/gpu_types.hpp"
#include "../../math.hpp"
#include "../../stdio.hpp"
namespace JabyEngine {
namespace GTE {
namespace internal {
template<typename T>
struct VECTOR {
T x;
T y;
T z;
T pad;
static constexpr VECTOR create() {
return VECTOR::create(0, 0, 0);
}
static constexpr VECTOR create(T x, T y, T z) {
return VECTOR{.x = x, .y = y, .z = z, .pad = 0};
}
static constexpr VECTOR create(gte_float x, gte_float y, gte_float z) {
return VECTOR{.x = static_cast<T>(x), .y = static_cast<T>(y), .z = static_cast<T>(z)};
}
template<typename S>
static constexpr VECTOR from(const GPU::Position<S>& pos) {
return VECTOR::create(static_cast<T>(pos.x), static_cast<T>(pos.y), 0);
}
template<typename S>
constexpr S to() const {
return S::create(static_cast<S::PrimitiveType>(this->x), static_cast<S::PrimitiveType>(this->y));
}
};
}
using VECTOR = internal::VECTOR<int32_t>;
using SVECTOR = internal::VECTOR<int16_t>;
struct ROTMATRIX {
int16_t matrix[3][3];
static constexpr ROTMATRIX identity() {
return ROTMATRIX{.matrix = {
{static_cast<int16_t>(gte_float::one()), 0, 0},
{0, static_cast<int16_t>(gte_float::one()), 0},
{0, 0, static_cast<int16_t>(gte_float::one())}
}
};
}
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 {
static constexpr TRANSFERVECTOR identity() {
return TRANSFERVECTOR::translated();
}
static constexpr TRANSFERVECTOR translated(int32_t x = 0, int32_t y = 0, int32_t z = 0) {
return TRANSFERVECTOR{{.x = x, .y = y, .z = z}};
}
};
struct MATRIX {
ROTMATRIX rotation;
TRANSFERVECTOR transfer;
static constexpr MATRIX identity() {
return MATRIX{.rotation = ROTMATRIX::identity(), .transfer = TRANSFERVECTOR::identity()};
}
static constexpr MATRIX translated(int32_t x = 0, int32_t y = 0, int32_t z = 0) {
return MATRIX{.rotation = ROTMATRIX::identity(), .transfer = TRANSFERVECTOR::translated(x, y, z)};
}
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()};
}
static MATRIX comp(MATRIX new_matrix, const MATRIX& matrix) {
new_matrix.comp(matrix);
return new_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;
template<typename T>
T& apply_to_area(T& poly, const GPU::AreaI16& area) const {
poly.vertex0 = MATRIX::apply_to(GPU::POLY_G4::vertex0_from(area));
poly.vertex1 = MATRIX::apply_to(GPU::POLY_G4::vertex1_from(area));
poly.vertex2 = MATRIX::apply_to(GPU::POLY_G4::vertex2_from(area));
poly.vertex3 = MATRIX::apply_to(GPU::POLY_G4::vertex3_from(area));
return poly;
}
};
}
}