Add GXSetProjectionFull extension

This commit is contained in:
Luke Street
2026-07-07 12:04:14 -06:00
parent 352138a1b5
commit b135643394
3 changed files with 29 additions and 0 deletions
+11
View File
@@ -23,6 +23,12 @@ extern "C" {
*/
#define GX_AURORA_LOAD_SCISSOR_RENDER 0x0002
/**
* Loads a full 4x4 projection matrix, bypassing GXSetProjection's 6-parameter
* hardware encoding. Must be followed by sixteen f32 values in row-major order.
*/
#define GX_AURORA_LOAD_PROJECTION_FULL 0x0003
/**
* Aurora equivalent of CP_REG_ARRAYBASE_ID: sets the base address and size of a vertex array.
* This command must be followed by a 64-bit memory address, 32-bit size, and 1-byte little-endian flag.
@@ -144,6 +150,11 @@ void GXSetScissorRender(u32 left, u32 top, u32 wd, u32 ht);
void GX2SetPolygonOffset(f32 mFrontOffset, f32 mFrontScale, f32 mBackOffset, f32 mBackScale, f32 mClamp);
/**
* Load an arbitrary 4x4 projection matrix, avoiding the 6-parameter hardware encoding.
*/
void GXSetProjectionFull(const void* mtx);
/**
* Create an offscreen framebuffer and switch rendering to it.
* All subsequent GX rendering will target this framebuffer until GXRestoreFrameBuffer() is called.
+8
View File
@@ -66,6 +66,14 @@ void GXSetScissorRender(u32 left, u32 top, u32 wd, u32 ht) {
GX_WRITE_U32(ht);
}
void GXSetProjectionFull(const void* mtx) {
const f32* values = reinterpret_cast<const f32*>(mtx);
GX_WRITE_AURORA(GX_AURORA_LOAD_PROJECTION_FULL);
for (int i = 0; i < 16; ++i) {
GX_WRITE_F32(values[i]);
}
}
void GX2SetPolygonOffset(f32 mFrontOffset, f32 mFrontScale, f32 mBackOffset, f32 mBackScale, f32 mClamp) {
GX_WRITE_AURORA(GX2_SET_POLYGON_OFFSET);
GX_WRITE_F32(mFrontOffset);
+10
View File
@@ -1741,6 +1741,16 @@ void handle_aurora(const u8* data, u32& pos, u32 size, bool bigEndian) {
const int32_t height = static_cast<int32_t>(read_u32(data + pos, bigEndian));
pos += 4;
set_render_scissor({left, top, width, height});
} else if (subCmd == GX_AURORA_LOAD_PROJECTION_FULL) {
CHECK(pos + 64 <= size, "GX_AURORA_LOAD_PROJECTION_FULL read overrun");
auto& proj = g_gxState.proj;
for (int r = 0; r < 4; ++r) {
for (int c = 0; c < 4; ++c) {
proj[r][c] = read_f32(data + pos, bigEndian);
pos += 4;
}
}
g_gxState.stateDirty = true;
} else if (subCmd >= GX_AURORA_LOAD_ARRAYBASE && subCmd <= (GX_AURORA_LOAD_ARRAYBASE | 0x0f)) {
CHECK(pos + 13 <= size, "GX_AURORA_LOAD_ARRAYBASE read overrun");
u32 attrIdx = subCmd - GX_AURORA_LOAD_ARRAYBASE + GX_VA_POS;