2022-07-27 11:25:25 -04:00
|
|
|
#include "gx.hpp"
|
2026-02-17 17:35:13 -07:00
|
|
|
#include "__gx.h"
|
2026-03-02 07:19:39 +01:00
|
|
|
#include "dolphin/mtx/GeoTypes.h"
|
2022-07-27 11:25:25 -04:00
|
|
|
|
2026-03-11 02:19:34 -06:00
|
|
|
static inline void CacheProjectionVector(const f32* ptr, GXProjectionType type) {
|
|
|
|
|
__gx->projType = type;
|
|
|
|
|
for (int i = 0; i < 6; ++i) {
|
|
|
|
|
__gx->projMtx[i] = ptr[i + 1];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-04 19:19:25 -07:00
|
|
|
extern "C" {
|
|
|
|
|
|
2022-07-27 11:25:25 -04:00
|
|
|
void GXSetProjection(const void* mtx_, GXProjectionType type) {
|
|
|
|
|
const auto& mtx = *reinterpret_cast<const aurora::Mat4x4<float>*>(mtx_);
|
2026-03-11 02:19:34 -06:00
|
|
|
const f32 projVec[] = {
|
|
|
|
|
static_cast<f32>(type == GX_ORTHOGRAPHIC),
|
|
|
|
|
mtx[0][0],
|
|
|
|
|
type == GX_ORTHOGRAPHIC ? mtx[0][3] : mtx[0][2],
|
|
|
|
|
mtx[1][1],
|
|
|
|
|
type == GX_ORTHOGRAPHIC ? mtx[1][3] : mtx[1][2],
|
|
|
|
|
mtx[2][2],
|
|
|
|
|
mtx[2][3],
|
|
|
|
|
};
|
|
|
|
|
CacheProjectionVector(projVec, type);
|
2026-02-17 17:35:13 -07:00
|
|
|
|
|
|
|
|
// XF bulk write: 6 params + projection type at 0x1020-0x1026
|
|
|
|
|
GX_WRITE_U8(0x10);
|
2026-02-17 20:44:09 -07:00
|
|
|
GX_WRITE_U32(0x00061020);
|
2026-02-17 17:35:13 -07:00
|
|
|
GX_WRITE_XF_REG_F(32, __gx->projMtx[0]);
|
|
|
|
|
GX_WRITE_XF_REG_F(33, __gx->projMtx[1]);
|
|
|
|
|
GX_WRITE_XF_REG_F(34, __gx->projMtx[2]);
|
|
|
|
|
GX_WRITE_XF_REG_F(35, __gx->projMtx[3]);
|
|
|
|
|
GX_WRITE_XF_REG_F(36, __gx->projMtx[4]);
|
|
|
|
|
GX_WRITE_XF_REG_F(37, __gx->projMtx[5]);
|
|
|
|
|
GX_WRITE_XF_REG_2(38, __gx->projType);
|
|
|
|
|
__gx->bpSent = 0;
|
2026-03-11 02:19:34 -06:00
|
|
|
}
|
2026-02-17 17:35:13 -07:00
|
|
|
|
2026-03-11 02:19:34 -06:00
|
|
|
void GXSetProjectionv(const f32* ptr) {
|
|
|
|
|
CHECK(ptr != nullptr, "null projection vector");
|
|
|
|
|
|
|
|
|
|
const GXProjectionType type = ptr[0] == 0.0f ? GX_PERSPECTIVE : GX_ORTHOGRAPHIC;
|
|
|
|
|
CacheProjectionVector(ptr, type);
|
|
|
|
|
|
|
|
|
|
// XF bulk write: 6 params + projection type at 0x1020-0x1026
|
|
|
|
|
GX_WRITE_U8(0x10);
|
|
|
|
|
GX_WRITE_U32(0x00061020);
|
|
|
|
|
for (int i = 0; i < 6; ++i) {
|
|
|
|
|
GX_WRITE_F32(__gx->projMtx[i]);
|
|
|
|
|
}
|
|
|
|
|
GX_WRITE_U32(__gx->projType);
|
|
|
|
|
__gx->bpSent = 0;
|
2026-02-17 17:35:13 -07:00
|
|
|
}
|
2022-07-27 11:25:25 -04:00
|
|
|
|
|
|
|
|
void GXLoadPosMtxImm(const void* mtx_, u32 id) {
|
2022-08-09 02:05:33 -04:00
|
|
|
CHECK(id >= GX_PNMTX0 && id <= GX_PNMTX9, "invalid pn mtx {}", static_cast<int>(id));
|
2026-02-17 17:35:13 -07:00
|
|
|
const auto* mtx = reinterpret_cast<const f32*>(mtx_);
|
2022-07-27 11:25:25 -04:00
|
|
|
|
2026-02-17 17:35:13 -07:00
|
|
|
GX_WRITE_U8(0x10);
|
2026-02-17 20:44:09 -07:00
|
|
|
GX_WRITE_U32((id * 4) | 0xB0000);
|
2026-02-17 17:35:13 -07:00
|
|
|
for (int i = 0; i < 12; i++) {
|
|
|
|
|
GX_WRITE_F32(mtx[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-07-27 11:25:25 -04:00
|
|
|
|
|
|
|
|
void GXLoadNrmMtxImm(const void* mtx_, u32 id) {
|
2022-08-09 02:05:33 -04:00
|
|
|
CHECK(id >= GX_PNMTX0 && id <= GX_PNMTX9, "invalid pn mtx {}", static_cast<int>(id));
|
2026-02-17 17:35:13 -07:00
|
|
|
const auto* mtx = reinterpret_cast<const f32*>(mtx_);
|
2022-07-27 11:25:25 -04:00
|
|
|
|
2026-02-17 17:35:13 -07:00
|
|
|
GX_WRITE_U8(0x10);
|
2026-02-17 20:44:09 -07:00
|
|
|
GX_WRITE_U32((id * 3 + 0x400) | 0x80000);
|
2026-02-17 17:35:13 -07:00
|
|
|
// Write 3x3 from 3x4 matrix (skip translation column)
|
|
|
|
|
GX_WRITE_F32(mtx[0]);
|
|
|
|
|
GX_WRITE_F32(mtx[1]);
|
|
|
|
|
GX_WRITE_F32(mtx[2]);
|
|
|
|
|
GX_WRITE_F32(mtx[4]);
|
|
|
|
|
GX_WRITE_F32(mtx[5]);
|
|
|
|
|
GX_WRITE_F32(mtx[6]);
|
|
|
|
|
GX_WRITE_F32(mtx[8]);
|
|
|
|
|
GX_WRITE_F32(mtx[9]);
|
|
|
|
|
GX_WRITE_F32(mtx[10]);
|
|
|
|
|
}
|
2022-07-27 11:25:25 -04:00
|
|
|
|
|
|
|
|
void GXSetCurrentMtx(u32 id) {
|
2025-04-14 17:16:13 -06:00
|
|
|
CHECK(id >= GX_PNMTX0 && id <= GX_PNMTX9, "invalid pn mtx {}", id);
|
2026-02-17 17:35:13 -07:00
|
|
|
SET_REG_FIELD(0, __gx->matIdxA, 6, 0, id);
|
|
|
|
|
__GXSetMatrixIndex(GX_VA_PNMTXIDX);
|
2022-07-27 11:25:25 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GXLoadTexMtxImm(const void* mtx_, u32 id, GXTexMtxType type) {
|
2022-08-09 02:05:33 -04:00
|
|
|
CHECK((id >= GX_TEXMTX0 && id <= GX_IDENTITY) || (id >= GX_PTTEXMTX0 && id <= GX_PTIDENTITY), "invalid tex mtx {}",
|
2025-04-14 17:16:13 -06:00
|
|
|
id);
|
2026-02-17 17:35:13 -07:00
|
|
|
|
|
|
|
|
u32 addr;
|
2022-07-27 11:25:25 -04:00
|
|
|
if (id >= GX_PTTEXMTX0) {
|
2026-02-17 17:35:13 -07:00
|
|
|
addr = (id - GX_PTTEXMTX0) * 4 + 0x500;
|
2025-04-14 17:16:13 -06:00
|
|
|
CHECK(type == GX_MTX3x4, "invalid pt mtx type {}", underlying(type));
|
2022-07-27 11:25:25 -04:00
|
|
|
} else {
|
2026-02-17 17:35:13 -07:00
|
|
|
addr = id * 4;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u32 count = (type == GX_MTX2x4) ? 8 : 12;
|
|
|
|
|
u32 reg = addr | ((count - 1) << 16);
|
|
|
|
|
|
|
|
|
|
GX_WRITE_U8(0x10);
|
|
|
|
|
GX_WRITE_U32(reg);
|
|
|
|
|
|
|
|
|
|
const auto* mtx = reinterpret_cast<const f32*>(mtx_);
|
|
|
|
|
for (u32 i = 0; i < count; i++) {
|
|
|
|
|
GX_WRITE_F32(mtx[i]);
|
2022-07-27 11:25:25 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GXSetViewport(float left, float top, float width, float height, float nearZ, float farZ) {
|
2026-03-11 02:19:34 -06:00
|
|
|
GXSetViewportJitter(left, top, width, height, nearZ, farZ, 1);
|
2022-07-27 11:25:25 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GXSetViewportJitter(float left, float top, float width, float height, float nearZ, float farZ, u32 field) {
|
2026-04-18 14:10:32 -06:00
|
|
|
float sx;
|
|
|
|
|
float sy;
|
|
|
|
|
float sz;
|
|
|
|
|
float ox;
|
|
|
|
|
float oy;
|
|
|
|
|
float oz;
|
|
|
|
|
float zmin;
|
|
|
|
|
float zmax;
|
|
|
|
|
|
2026-03-11 02:19:34 -06:00
|
|
|
if (field == 0) {
|
|
|
|
|
top -= 0.5f;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-18 14:10:32 -06:00
|
|
|
sx = width / 2.0f;
|
|
|
|
|
sy = -height / 2.0f;
|
|
|
|
|
ox = 340.0f + (left + width / 2.0f);
|
|
|
|
|
oy = 340.0f + (top + height / 2.0f);
|
|
|
|
|
zmin = 1.6777215e7f * nearZ;
|
|
|
|
|
zmax = 1.6777215e7f * farZ;
|
|
|
|
|
sz = zmax - zmin;
|
|
|
|
|
oz = zmax;
|
|
|
|
|
|
2026-03-11 02:19:34 -06:00
|
|
|
__gx->vpLeft = left;
|
|
|
|
|
__gx->vpTop = top;
|
|
|
|
|
__gx->vpWd = width;
|
|
|
|
|
__gx->vpHt = height;
|
|
|
|
|
__gx->vpNearz = nearZ;
|
|
|
|
|
__gx->vpFarz = farZ;
|
|
|
|
|
|
2026-04-18 14:10:32 -06:00
|
|
|
GX_WRITE_U8(0x10);
|
|
|
|
|
GX_WRITE_U32(0x0005101A);
|
|
|
|
|
GX_WRITE_XF_REG_F(26, sx);
|
|
|
|
|
GX_WRITE_XF_REG_F(27, sy);
|
|
|
|
|
GX_WRITE_XF_REG_F(28, sz);
|
|
|
|
|
GX_WRITE_XF_REG_F(29, ox);
|
|
|
|
|
GX_WRITE_XF_REG_F(30, oy);
|
|
|
|
|
GX_WRITE_XF_REG_F(31, oz);
|
|
|
|
|
__gx->bpSent = 0;
|
2022-07-27 11:25:25 -04:00
|
|
|
}
|
|
|
|
|
|
2026-03-02 07:19:39 +01:00
|
|
|
void GXProject(f32 x, f32 y, f32 z, const f32 mtx[3][4], const f32* pm, const f32* vp, f32* sx,
|
|
|
|
|
f32* sy, f32* sz) {
|
|
|
|
|
Vec peye;
|
|
|
|
|
f32 xc;
|
|
|
|
|
f32 yc;
|
|
|
|
|
f32 zc;
|
|
|
|
|
f32 wc;
|
|
|
|
|
|
|
|
|
|
peye.x = mtx[0][3] + ((mtx[0][2] * z) + ((mtx[0][0] * x) + (mtx[0][1] * y)));
|
|
|
|
|
peye.y = mtx[1][3] + ((mtx[1][2] * z) + ((mtx[1][0] * x) + (mtx[1][1] * y)));
|
|
|
|
|
peye.z = mtx[2][3] + ((mtx[2][2] * z) + ((mtx[2][0] * x) + (mtx[2][1] * y)));
|
|
|
|
|
if (pm[0] == 0.0f) {
|
|
|
|
|
xc = (peye.x * pm[1]) + (peye.z * pm[2]);
|
|
|
|
|
yc = (peye.y * pm[3]) + (peye.z * pm[4]);
|
|
|
|
|
zc = pm[6] + (peye.z * pm[5]);
|
|
|
|
|
wc = 1.0f / -peye.z;
|
|
|
|
|
} else {
|
|
|
|
|
xc = pm[2] + (peye.x * pm[1]);
|
|
|
|
|
yc = pm[4] + (peye.y * pm[3]);
|
|
|
|
|
zc = pm[6] + (peye.z * pm[5]);
|
|
|
|
|
wc = 1.0f;
|
|
|
|
|
}
|
|
|
|
|
*sx = (vp[2] / 2.0f) + (vp[0] + (wc * (xc * vp[2] / 2.0f)));
|
|
|
|
|
*sy = (vp[3] / 2.0f) + (vp[1] + (wc * (-yc * vp[3] / 2.0f)));
|
|
|
|
|
*sz = vp[5] + (wc * (zc * (vp[5] - vp[4])));
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-17 17:35:13 -07:00
|
|
|
// TODO GXLoadPosMtxIndx
|
|
|
|
|
// TODO GXLoadNrmMtxImm3x3
|
|
|
|
|
// TODO GXLoadNrmMtxIndx3x3
|
|
|
|
|
// TODO GXLoadTexMtxIndx
|
2022-07-27 11:25:25 -04:00
|
|
|
// TODO GXSetZScaleOffset
|
2026-02-17 17:35:13 -07:00
|
|
|
}
|