Files
tp/libs/dolphin/gx/GXTransform.c
T
hatal175 0de0339250 Some GX work (#1998)
* Some GX work

* GXFrameBuf work

* Import GXAttr functions and enums

* Import most of GXTev

* Import most of GXPixel

* Import GXFifo

* Import some of GXInit

* Import and work on GXTransform

* Import GXPerf

* A little work on GXTexture
2023-12-06 15:57:35 -08:00

432 lines
12 KiB
C

//
// Generated By: dol2asm
// Translation Unit: GXTransform
//
#include "dolphin/gx/GXTransform.h"
#include "dolphin/gx/GX.h"
#include "dol2asm.h"
//
// Forward References:
//
void GXSetProjection();
void GXSetProjectionv();
void GXGetProjectionv();
void GXLoadPosMtxImm();
void GXLoadNrmMtxImm();
void GXSetCurrentMtx();
void GXLoadTexMtxImm();
void __GXSetViewport();
void GXGetViewportv();
void GXSetScissor();
void GXGetScissor();
void GXSetScissorBoxOffset();
void GXSetClipMode();
void __GXSetMatrixIndex();
//
// Declarations:
//
/* ############################################################################################## */
/* 80456650-80456654 004C50 0004+00 3/3 0/0 0/0 .sdata2 @26 */
SECTION_SDATA2 static u8 lit_26[4] = {
0x00,
0x00,
0x00,
0x00,
};
static void Copy6Floats(register f32* dst, register const f32* src) {
register f32 ps_0, ps_1, ps_2;
// clang-format off
asm {
psq_l ps_0, 0(src), 0, 0
psq_l ps_1, 8(src), 0, 0
psq_l ps_2, 16(src), 0, 0
psq_st ps_0, 0(dst), 0, 0
psq_st ps_1, 8(dst), 0, 0
psq_st ps_2, 16(dst), 0, 0
}
// clang-format on
}
static void WriteProjPS(register volatile void* dst, register const f32* src) {
register f32 ps_0, ps_1, ps_2;
// clang-format off
asm {
psq_l ps_0, 0(src), 0, 0
psq_l ps_1, 8(src), 0, 0
psq_l ps_2, 16(src), 0, 0
psq_st ps_0, 0(dst), 0, 0
psq_st ps_1, 0(dst), 0, 0
psq_st ps_2, 0(dst), 0, 0
}
// clang-format on
}
/* 80456654-80456658 004C54 0004+00 2/2 0/0 0/0 .sdata2 @27 */
SECTION_SDATA2 static f32 lit_27 = 1.0f;
/* 80456658-8045665C 004C58 0004+00 2/2 0/0 0/0 .sdata2 @28 */
SECTION_SDATA2 static f32 lit_28 = 0.5f;
/* 8035FF60-803600D4 35A8A0 0174+00 0/0 1/1 0/0 .text GXProject */
// regalloc
#ifdef NONMATCHING
void GXProject(f32 model_x, f32 model_y, f32 model_z, Mtx model_mtx, f32* proj_mtx,
f32* viewpoint, f32* screen_x, f32* screen_y, f32* screen_z) {
f32 fVar1;
f32 fVar6;
f32 fVar7;
f32 fVar8;
f32 fVar9;
f32 fVar2;
f32 fVar3;
fVar1 = (model_mtx[0][0] * model_x) + (model_mtx[0][1] * model_y) + (model_mtx[0][2] * model_z) + model_mtx[0][3];
fVar6 = (model_mtx[1][0] * model_x) + (model_mtx[1][1] * model_y) + (model_mtx[1][2] * model_z) + model_mtx[1][3];
fVar7 = (model_mtx[2][0] * model_x) + (model_mtx[2][1] * model_y) + (model_mtx[2][2] * model_z) + model_mtx[2][3];
if (proj_mtx[0] == 0.0f) {
fVar8 = fVar1 * proj_mtx[1] + fVar7 * proj_mtx[2];
fVar3 = fVar6 * proj_mtx[3] + fVar7 * proj_mtx[4];
fVar9 = proj_mtx[6] + fVar7 * proj_mtx[5];
fVar2 = 1.0f / -fVar7;
} else {
fVar8 = proj_mtx[2] + fVar1 * proj_mtx[1];
fVar3 = proj_mtx[4] + fVar6 * proj_mtx[3];
fVar9 = proj_mtx[6] + fVar7 * proj_mtx[5];
fVar2 = 1.0f;
}
*screen_x = fVar2 * viewpoint[2] * fVar8 / 2.0f + viewpoint[2] / 2.0f + viewpoint[0];
*screen_y = fVar2 * viewpoint[3] * -fVar3 / 2.0f + viewpoint[3] / 2.0f + viewpoint[1];
*screen_z = fVar2 * (viewpoint[5] - viewpoint[4]) * fVar9 + viewpoint[5];
}
#else
#pragma push
#pragma optimization_level 0
#pragma optimizewithasm off
asm void GXProject(f32 model_x, f32 model_y, f32 model_z, Mtx model_mtx, f32* proj_mtx,
f32* viewpoint, f32* screen_x, f32* screen_y, f32* screen_z) {
nofralloc
#include "asm/dolphin/gx/GXTransform/GXProject.s"
}
#pragma pop
#endif
/* 803600D4-80360178 35AA14 00A4+00 0/0 15/15 2/2 .text GXSetProjection */
void GXSetProjection(Mtx44 mtx, GXProjectionType type) {
volatile void* fifo;
__GXData->projectionType = type;
__GXData->field_0x4dc = mtx[0][0];
__GXData->field_0x4e4 = mtx[1][1];
__GXData->field_0x4ec = mtx[2][2];
__GXData->field_0x4f0 = mtx[2][3];
if (type == GX_ORTHOGRAPHIC) {
__GXData->field_0x4e0 = mtx[0][3];
__GXData->field_0x4e8 = mtx[1][3];
} else {
__GXData->field_0x4e0 = mtx[0][2];
__GXData->field_0x4e8 = mtx[1][2];
}
GXFIFO.u8 = 0x10;
GXFIFO.u32 = 0x61020;
fifo = &GXFIFO;
WriteProjPS(fifo, &__GXData->field_0x4dc);
GXFIFO.u32 = __GXData->projectionType;
__GXData->bpSentNot = 1;
}
/* 80360178-80360204 35AAB8 008C+00 0/0 1/1 1/1 .text GXSetProjectionv */
// Matches with literals
#ifdef NONMATCHING
void GXSetProjectionv(f32* p) {
__GXData->projectionType = (*p == 0.0f) ? GX_PERSPECTIVE : GX_ORTHOGRAPHIC;
p++;
Copy6Floats(&__GXData->field_0x4dc, p);
GXFIFO.u8 = 0x10;
GXFIFO.u32 = 0x61020;
WriteProjPS(&GXFIFO, &__GXData->field_0x4dc);
GXFIFO.u32 = __GXData->projectionType;
__GXData->bpSentNot = 1;
}
#else
#pragma push
#pragma optimization_level 0
#pragma optimizewithasm off
asm void GXSetProjectionv(f32* p) {
nofralloc
#include "asm/dolphin/gx/GXTransform/GXSetProjectionv.s"
}
#pragma pop
#endif
/* 80360204-8036024C 35AB44 0048+00 0/0 1/1 1/1 .text GXGetProjectionv */
// Matches with literals
#ifdef NONMATCHING
void GXGetProjectionv(f32* p) {
*p = (u32)__GXData->projectionType != GX_PERSPECTIVE ? 1.0f : 0.5f;
Copy6Floats(p + 1, &__GXData->field_0x4dc);
}
#else
#pragma push
#pragma optimization_level 0
#pragma optimizewithasm off
asm void GXGetProjectionv(f32* p) {
nofralloc
#include "asm/dolphin/gx/GXTransform/GXGetProjectionv.s"
}
#pragma pop
#endif
static void WriteMTXPS4x3(register volatile void* dst, register const Mtx src) {
register f32 ps_0, ps_1, ps_2, ps_3, ps_4, ps_5;
// clang-format off
asm {
psq_l ps_0, 0(src), 0, 0
psq_l ps_1, 8(src), 0, 0
psq_l ps_2, 16(src), 0, 0
psq_l ps_3, 24(src), 0, 0
psq_l ps_4, 32(src), 0, 0
psq_l ps_5, 40(src), 0, 0
psq_st ps_0, 0(dst), 0, 0
psq_st ps_1, 0(dst), 0, 0
psq_st ps_2, 0(dst), 0, 0
psq_st ps_3, 0(dst), 0, 0
psq_st ps_4, 0(dst), 0, 0
psq_st ps_5, 0(dst), 0, 0
}
// clang-format on
}
/* 8036024C-8036029C 35AB8C 0050+00 0/0 83/83 9/9 .text GXLoadPosMtxImm */
void GXLoadPosMtxImm(Mtx mtx, u32 id) {
GX_XF_LOAD_REGS(4 * 3 - 1, id * 4 + GX_XF_MEM_POSMTX);
WriteMTXPS4x3(&GXFIFO, mtx);
}
static void WriteMTXPS3x3(register volatile void* dst, register const Mtx src) {
register f32 ps_0, ps_1, ps_2, ps_3, ps_4, ps_5;
// clang-format off
asm {
psq_l ps_0, 0(src), 0, 0
lfs ps_1, 8(src)
psq_l ps_2, 16(src), 0, 0
lfs ps_3, 24(src)
psq_l ps_4, 32(src), 0, 0
lfs ps_5, 40(src)
psq_st ps_0, 0(dst), 0, 0
stfs ps_1, 0(dst)
psq_st ps_2, 0(dst), 0, 0
stfs ps_3, 0(dst)
psq_st ps_4, 0(dst), 0, 0
stfs ps_5, 0(dst)
}
// clang-format on
}
/* 8036029C-803602EC 35ABDC 0050+00 0/0 11/11 7/7 .text GXLoadNrmMtxImm */
void GXLoadNrmMtxImm(Mtx mtx, u32 id) {
GX_XF_LOAD_REGS(3 * 3 - 1, id * 3 + GX_XF_MEM_NRMMTX);
WriteMTXPS3x3(&GXFIFO, mtx);
}
/* 803602EC-80360320 35AC2C 0034+00 0/0 51/51 2/2 .text GXSetCurrentMtx */
void GXSetCurrentMtx(u32 id) {
GX_SET_REG(__GXData->matIdxA, id, GX_XF_MTXIDX0_GEOM_ST, GX_XF_MTXIDX0_GEOM_END);
__GXSetMatrixIndex(GX_VA_PNMTXIDX);
}
static void WriteMTXPS4x2(register volatile void* dst, register const Mtx src){
register f32 ps_0, ps_1, ps_2, ps_3;
// clang-format off
asm {
psq_l ps_0, 0(src), 0, 0
psq_l ps_1, 8(src), 0, 0
psq_l ps_2, 16(src), 0, 0
psq_l ps_3, 24(src), 0, 0
psq_st ps_0, 0(dst), 0, 0
psq_st ps_1, 0(dst), 0, 0
psq_st ps_2, 0(dst), 0, 0
psq_st ps_3, 0(dst), 0, 0
}
// clang-format on
}
/* 80360320-803603D4 35AC60 00B4+00 0/0 15/15 0/0 .text GXLoadTexMtxImm */
void GXLoadTexMtxImm(const Mtx mtx, u32 id, GXTexMtxType type) {
u32 addr;
u32 num;
u32 reg;
// Matrix address in XF memory
addr = id >= GX_PTTEXMTX0 ? (id - GX_PTTEXMTX0) * 4 + GX_XF_MEM_DUALTEXMTX : id * 4 + (u64)GX_XF_MEM_POSMTX;
// Number of elements in matrix
num = type == GX_MTX2x4 ? (u64)(2 * 4) : 3 * 4;
reg = addr | (num - 1) << 16;
GX_XF_LOAD_REG_HDR(reg);
if (type == GX_MTX3x4) {
WriteMTXPS4x3(&GXFIFO, mtx);
} else {
WriteMTXPS4x2(&GXFIFO, mtx);
}
}
/* ############################################################################################## */
/* 8045665C-80456660 004C5C 0004+00 1/1 0/0 0/0 .sdata2 @201 */
SECTION_SDATA2 static f32 lit_201 = 342.0f;
/* 803603D4-80360464 35AD14 0090+00 1/1 0/0 0/0 .text __GXSetViewport */
// Matches with literals
#ifdef NONMATCHING
void __GXSetViewport(void) {
f32 a, b, c, d, e, f;
f32 near, far;
a = __GXData->vpWd / 2;
b = -__GXData->vpHt / 2;
d = __GXData->vpLeft + (__GXData->vpWd / 2) + 342.0f;
e = __GXData->vpTop + (__GXData->vpHt / 2) + 342.0f;
near = __GXData->vpNearz * __GXData->zScale;
far = __GXData->vpFarz * __GXData->zScale;
c = far - near;
f = far + __GXData->zOffset;
GX_XF_LOAD_REGS(5, GX_XF_REG_SCALEX);
GX_WRITE_F32(a);
GX_WRITE_F32(b);
GX_WRITE_F32(c);
GX_WRITE_F32(d);
GX_WRITE_F32(e);
GX_WRITE_F32(f);
}
#else
#pragma push
#pragma optimization_level 0
#pragma optimizewithasm off
asm void __GXSetViewport(void) {
nofralloc
#include "asm/dolphin/gx/GXTransform/__GXSetViewport.s"
}
#pragma pop
#endif
/* 80360464-803604AC 35ADA4 0048+00 0/0 10/10 1/1 .text GXSetViewport */
void GXSetViewport(f32 left, f32 top, f32 width, f32 height, f32 nearZ, f32 farZ) {
__GXData->vpLeft = left;
__GXData->vpTop = top;
__GXData->vpWd = width;
__GXData->vpHt = height;
__GXData->vpNearz = nearZ;
__GXData->vpFarz = farZ;
__GXSetViewport();
__GXData->bpSentNot = GX_TRUE;
}
/* 803604AC-803604D0 35ADEC 0024+00 0/0 1/1 1/1 .text GXGetViewportv */
void GXGetViewportv(f32* p) {
Copy6Floats(p, &__GXData->vpLeft);
}
/* 803604D0-80360548 35AE10 0078+00 0/0 11/11 4/4 .text GXSetScissor */
void GXSetScissor(u32 left, u32 top, u32 width, u32 height) {
u32 y1, x1, y2, x2;
u32 reg;
y1 = top + 342;
x1 = left + 342;
GX_SET_REG(__GXData->suScis0, y1, GX_BP_SCISSORTL_TOP_ST, GX_BP_SCISSORTL_TOP_END);
GX_SET_REG(__GXData->suScis0, x1, GX_BP_SCISSORTL_LEFT_ST, GX_BP_SCISSORTL_LEFT_END);
y2 = y1 + height - 1;
x2 = (x1 + width) - 1;
GX_SET_REG(__GXData->suScis1, y2, GX_BP_SCISSORBR_BOT_ST, GX_BP_SCISSORBR_BOT_END);
GX_SET_REG(__GXData->suScis1, x2, GX_BP_SCISSORBR_RIGHT_ST, GX_BP_SCISSORBR_RIGHT_END);
GX_BP_LOAD_REG(__GXData->suScis0);
GX_BP_LOAD_REG(__GXData->suScis1);
__GXData->bpSentNot = FALSE;
}
/* 80360548-80360590 35AE88 0048+00 0/0 6/6 2/2 .text GXGetScissor */
#ifdef NONMATCHING
void GXGetScissor(u32* left, u32* top, u32* width, u32* height) {
u32 y1, x1, y2, x2;
x1 = GX_GET_REG(__GXData->suScis0, GX_BP_SCISSORTL_LEFT_ST, GX_BP_SCISSORTL_LEFT_END);
x2 = GX_GET_REG(__GXData->suScis1, GX_BP_SCISSORBR_RIGHT_ST, GX_BP_SCISSORBR_RIGHT_END);
y1 = GX_GET_REG(__GXData->suScis0, GX_BP_SCISSORTL_TOP_ST, GX_BP_SCISSORTL_TOP_END);
y2 = GX_GET_REG(__GXData->suScis1, GX_BP_SCISSORBR_BOT_ST, GX_BP_SCISSORBR_BOT_END);
*left = x1 - 342;
*top = y1 - 342;
*width = x2 - x1 + 1;
*height = y2 - y1 + 1;
}
#else
#pragma push
#pragma optimization_level 0
#pragma optimizewithasm off
asm void GXGetScissor(u32* left, u32* top, u32* width, u32* height) {
nofralloc
#include "asm/dolphin/gx/GXTransform/GXGetScissor.s"
}
#pragma pop
#endif
/* 80360590-803605D0 35AED0 0040+00 0/0 1/1 0/0 .text GXSetScissorBoxOffset */
void GXSetScissorBoxOffset(s32 x, s32 y) {
u32 cmd = 0;
u32 x1;
u32 y1;
x1 = (u32)(x + 342) / 2;
y1 = (u32)(y + 342) / 2;
GX_SET_REG(cmd, x1, GX_BP_SCISSOROFS_OX_ST, GX_BP_SCISSOROFS_OX_END);
GX_SET_REG(cmd, y1, GX_BP_SCISSOROFS_OY_ST, GX_BP_SCISSOROFS_OY_END);
GX_SET_REG(cmd, GX_BP_REG_SCISSOROFFSET, 0, 7);
GX_BP_LOAD_REG(cmd);
__GXData->bpSentNot = GX_FALSE;
}
/* 803605D0-803605F8 35AF10 0028+00 0/0 27/27 2/2 .text GXSetClipMode */
void GXSetClipMode(GXClipMode mode) {
GX_XF_LOAD_REG(GX_XF_REG_CLIPDISABLE, mode);
__GXData->bpSentNot = GX_TRUE;
}
/* 803605F8-8036067C 35AF38 0084+00 1/1 1/1 0/0 .text __GXSetMatrixIndex */
void __GXSetMatrixIndex(GXAttr index) {
// Tex4 and after is stored in XF MatrixIndex1
if (index < GX_VA_TEX4MTXIDX) {
GX_CP_LOAD_REG(GX_CP_REG_MTXIDXA, __GXData->matIdxA);
GX_XF_LOAD_REG(GX_XF_REG_MATRIXINDEX0, __GXData->matIdxA);
} else {
GX_CP_LOAD_REG(GX_CP_REG_MTXIDXB, __GXData->matIdxB);
GX_XF_LOAD_REG(GX_XF_REG_MATRIXINDEX1, __GXData->matIdxB);
}
__GXData->bpSentNot = GX_TRUE;
}