Merge branch 'main' into 26-02-27-allocator-isolation

This commit is contained in:
PJB3005
2026-03-05 00:15:09 +01:00
5530 changed files with 252979 additions and 26830 deletions
@@ -0,0 +1,243 @@
/**
* J3DDrawBuffer.cpp
*
*/
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/J3DGraphBase/J3DDrawBuffer.h"
#include "JSystem/J3DGraphBase/J3DMaterial.h"
#include "JSystem/JKernel/JKRHeap.h"
void J3DDrawBuffer::calcZRatio() {
mZRatio = (mZFar - mZNear) / (f32)mEntryTableSize;
}
void J3DDrawBuffer::initialize() {
mDrawMode = J3DDrawBufDrawMode_Head;
mSortMode = J3DDrawBufSortMode_Mat;
mZNear = 1.0f;
mZFar = 10000.0f;
mpZMtx = NULL;
mpCallBackPacket = NULL;
mEntryTableSize = 0x20;
calcZRatio();
}
int J3DDrawBuffer::allocBuffer(u32 size) {
mpBuffer = JKR_NEW_ARGS (0x20) J3DPacket*[size];
if (mpBuffer == NULL)
return kJ3DError_Alloc;
mEntryTableSize = size;
frameInit();
calcZRatio();
return kJ3DError_Success;
}
J3DDrawBuffer::~J3DDrawBuffer() {
frameInit();
JKR_DELETE_ARRAY(mpBuffer);
mpBuffer = NULL;
}
void J3DDrawBuffer::frameInit() {
u32 bufSize = mEntryTableSize;
for (u32 i = 0; i < bufSize; i++)
mpBuffer[i] = NULL;
mpCallBackPacket = NULL;
}
int J3DDrawBuffer::entryMatSort(J3DMatPacket* pMatPacket) {
J3D_ASSERT_NULLPTR(122, pMatPacket != NULL);
pMatPacket->drawClear();
pMatPacket->getShapePacket()->drawClear();
if (pMatPacket->isChanged()) {
pMatPacket->setNextPacket(mpBuffer[0]);
mpBuffer[0] = pMatPacket;
return 1;
}
J3DTexture* pTexture = j3dSys.getTexture();
u16 texNo = pMatPacket->getMaterial()->getTexNo(0);
J3D_ASSERT_NULLPTR(150, pTexture != NULL);
u32 hash;
if (texNo == 0xFFFF) {
hash = 0;
} else {
hash = ((uintptr_t)pTexture->getResTIMG(texNo) + pTexture->getResTIMG(texNo)->imageOffset) >> 5;
}
u32 slot = hash & (mEntryTableSize - 1);
if (mpBuffer[slot] == NULL) {
mpBuffer[slot] = pMatPacket;
return 1;
}
J3DMatPacket* packet;
for (packet = (J3DMatPacket*)mpBuffer[slot]; packet != NULL; packet = (J3DMatPacket*)packet->getNextPacket())
{
if (packet->isSame(pMatPacket)) {
packet->addShapePacket(pMatPacket->getShapePacket());
return 0;
}
}
pMatPacket->setNextPacket(mpBuffer[slot]);
mpBuffer[slot] = pMatPacket;
return 1;
}
int J3DDrawBuffer::entryMatAnmSort(J3DMatPacket* pMatPacket) {
J3D_ASSERT_NULLPTR(199, pMatPacket != NULL);
J3DMaterialAnm* pMaterialAnm = pMatPacket->mpMaterialAnm;
u32 slot = (uintptr_t)pMaterialAnm & (mEntryTableSize - 1);
if (pMaterialAnm == NULL) {
return entryMatSort(pMatPacket);
}
pMatPacket->drawClear();
pMatPacket->getShapePacket()->drawClear();
if (mpBuffer[slot] == NULL) {
mpBuffer[slot] = pMatPacket;
return 1;
}
J3DMatPacket* packet;
for (packet = (J3DMatPacket*)mpBuffer[slot]; packet != NULL; packet = (J3DMatPacket*)packet->getNextPacket())
{
if (packet->mpMaterialAnm == pMaterialAnm) {
packet->addShapePacket(pMatPacket->getShapePacket());
return 0;
}
}
pMatPacket->setNextPacket(mpBuffer[slot]);
mpBuffer[slot] = pMatPacket;
return 1;
}
int J3DDrawBuffer::entryZSort(J3DMatPacket* pMatPacket) {
J3D_ASSERT_NULLPTR(257, pMatPacket != NULL);
pMatPacket->drawClear();
pMatPacket->getShapePacket()->drawClear();
Vec tmp;
tmp.x = mpZMtx[0][3];
tmp.y = mpZMtx[1][3];
tmp.z = mpZMtx[2][3];
f32 value = -J3DCalcZValue(j3dSys.getViewMtx(), tmp);
u32 index;
if (mZNear + mZRatio < value) {
if (mZFar - mZRatio > value) {
index = value / mZRatio;
} else {
index = mEntryTableSize - 1;
}
} else {
index = 0;
}
index = (mEntryTableSize - 1) - index;
pMatPacket->setNextPacket(mpBuffer[index]);
mpBuffer[index] = pMatPacket;
return 1;
}
int J3DDrawBuffer::entryModelSort(J3DMatPacket* pMatPacket) {
J3D_ASSERT_NULLPTR(316, pMatPacket != NULL);
pMatPacket->drawClear();
pMatPacket->getShapePacket()->drawClear();
if (mpCallBackPacket != NULL) {
mpCallBackPacket->addChildPacket(pMatPacket);
return 1;
}
return 0;
}
int J3DDrawBuffer::entryInvalidSort(J3DMatPacket* pMatPacket) {
J3D_ASSERT_NULLPTR(343, pMatPacket != NULL);
pMatPacket->drawClear();
pMatPacket->getShapePacket()->drawClear();
if (mpCallBackPacket != NULL) {
mpCallBackPacket->addChildPacket(pMatPacket->getShapePacket());
return 1;
}
return 0;
}
int J3DDrawBuffer::entryNonSort(J3DMatPacket* pMatPacket) {
J3D_ASSERT_NULLPTR(370, pMatPacket != NULL);
pMatPacket->drawClear();
pMatPacket->getShapePacket()->drawClear();
pMatPacket->setNextPacket(mpBuffer[0]);
mpBuffer[0] = pMatPacket;
return 1;
}
int J3DDrawBuffer::entryImm(J3DPacket* pPacket, u16 index) {
J3D_ASSERT_NULLPTR(394, pPacket != NULL);
J3D_ASSERT_RANGE(395, index < mEntryTableSize);
pPacket->setNextPacket(mpBuffer[index]);
mpBuffer[index] = pPacket;
return 1;
}
J3DDrawBuffer::sortFunc J3DDrawBuffer::sortFuncTable[6] = {
&J3DDrawBuffer::entryMatSort, &J3DDrawBuffer::entryMatAnmSort, &J3DDrawBuffer::entryZSort,
&J3DDrawBuffer::entryModelSort, &J3DDrawBuffer::entryInvalidSort, &J3DDrawBuffer::entryNonSort,
};
J3DDrawBuffer::drawFunc J3DDrawBuffer::drawFuncTable[2] = {
&J3DDrawBuffer::drawHead,
&J3DDrawBuffer::drawTail,
};
int J3DDrawBuffer::entryNum;
void J3DDrawBuffer::draw() const {
J3D_ASSERT_RANGE(411, mDrawMode < J3DDrawBufDrawMode_MAX);
drawFunc func = drawFuncTable[mDrawMode];
(this->*func)();
}
void J3DDrawBuffer::drawHead() const {
u32 size = mEntryTableSize;
J3DPacket** buf = mpBuffer;
for (u32 i = 0; i < size; i++) {
for (J3DPacket* packet = buf[i]; packet != NULL; packet = packet->getNextPacket()) {
packet->draw();
}
}
}
void J3DDrawBuffer::drawTail() const {
for (int i = mEntryTableSize - 1; i >= 0; i--) {
for (J3DPacket* packet = mpBuffer[i]; packet != NULL; packet = packet->getNextPacket()) {
packet->draw();
}
}
}
+707
View File
@@ -0,0 +1,707 @@
//
// J3DGD
//
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/J3DGraphBase/J3DGD.h"
#include "JSystem/J3DGraphBase/J3DFifo.h"
void J3DGDSetGenMode(u8 nTexGens, u8 nChans, u8 nTevs, u8 nInds,
GXCullMode cm) {
static u8 cm2hw[4] = {0, 2, 1, 3};
GDOverflowCheck(10);
J3DGDWriteBPCmd(0xFE07FC3F);
J3DGDWriteBPCmd(BP_GEN_MODE(nTexGens, nChans, nTevs - 1, cm2hw[cm], nInds));
}
void J3DGDSetGenMode_3Param(u8 nTexGens, u8 nTevs, u8 nInds) {
GDOverflowCheck(10);
J3DGDWriteBPCmd(0xFE073C0F);
J3DGDWriteBPCmd(BP_GEN_MODE(nTexGens, 0, nTevs - 1, 0, nInds));
}
void J3DGDSetLightAttn(GXLightID light, f32 a0, f32 a1, f32 a2, f32 k0, f32 k1, f32 k2) {
J3DGDWriteXFCmdHdr(XF_LIGHT_ATTN_ID + __GDLightID2Offset(light), 6);
J3DGDWrite_f32(a0);
J3DGDWrite_f32(a1);
J3DGDWrite_f32(a2);
J3DGDWrite_f32(k0);
J3DGDWrite_f32(k1);
J3DGDWrite_f32(k2);
}
void J3DGDSetLightColor(GXLightID light, GXColor color) {
J3DGDWriteXFCmd(XF_LIGHT_COLOR_ID + __GDLightID2Offset(light),
(color.r << 24) | (color.g << 16) | (color.b << 8) | (color.a << 0));
}
void J3DGDSetLightPos(GXLightID light, f32 x, f32 y, f32 z) {
J3DGDWriteXFCmdHdr(XF_LIGHT_POS_ID + __GDLightID2Offset(light), 3);
J3DGDWrite_f32(x);
J3DGDWrite_f32(y);
J3DGDWrite_f32(z);
}
void J3DGDSetLightDir(GXLightID light, f32 nx, f32 ny, f32 nz) {
J3DGDWriteXFCmdHdr(XF_LIGHT_DIR_ID + __GDLightID2Offset(light), 3);
J3DGDWrite_f32(nx);
J3DGDWrite_f32(ny);
J3DGDWrite_f32(nz);
}
void J3DGDSetVtxAttrFmtv(GXVtxFmt vtxfmt, const GXVtxAttrFmtList* list, bool param_2) {
u32 posCnt = GX_POS_XYZ;
u32 posType = GX_F32;
u32 posFrac = 0;
u32 nrmCnt = GX_NRM_XYZ;
u32 nrmType = GX_F32;
u32 nrmIdx3 = 0;
u32 c0Cnt = GX_CLR_RGBA;
u32 c0Type = GX_RGBA8;
u32 c1Cnt = GX_CLR_RGBA;
u32 c1Type = GX_RGBA8;
u32 tx0Cnt = GX_TEX_ST;
u32 tx0Type = GX_F32;
u32 tx0Frac = 0;
u32 tx1Cnt = GX_TEX_ST;
u32 tx1Type = GX_F32;
u32 tx1Frac = 0;
u32 tx2Cnt = GX_TEX_ST;
u32 tx2Type = GX_F32;
u32 tx2Frac = 0;
u32 tx3Cnt = GX_TEX_ST;
u32 tx3Type = GX_F32;
u32 tx3Frac = 0;
u32 tx4Cnt = GX_TEX_ST;
u32 tx4Type = GX_F32;
u32 tx4Frac = 0;
u32 tx5Cnt = GX_TEX_ST;
u32 tx5Type = GX_F32;
u32 tx5Frac = 0;
u32 tx6Cnt = GX_TEX_ST;
u32 tx6Type = GX_F32;
u32 tx6Frac = 0;
u32 tx7Cnt = GX_TEX_ST;
u32 tx7Type = GX_F32;
u32 tx7Frac = 0;
ASSERTMSGLINE(240, vtxfmt < GX_MAX_VTXFMT, "GDSetVtxAttrFmtv: invalid vtx fmt");
for (; list->attr != GX_VA_NULL; ++list) {
ASSERTMSGLINE(245, list->attr >= GX_VA_POS && list->attr <= GX_VA_TEX7, "GDSetVtxAttrFmtv: invalid attribute");
ASSERTMSGLINE(246, list->frac < 32, "GDSetVtxAttrFmtv: invalid frac value");
switch (list->attr) {
case GX_VA_POS:
posCnt = list->cnt;
posType = list->type;
posFrac = list->frac;
break;
case GX_VA_NRM:
case GX_VA_NBT:
nrmType = list->type;
if (list->cnt == GX_NRM_NBT3) {
nrmCnt = GX_NRM_NBT;
nrmIdx3 = 1;
} else {
if (param_2) {
nrmCnt = GX_NRM_NBT;
} else {
nrmCnt = list->cnt;
}
nrmIdx3 = 0;
}
break;
case GX_VA_CLR0:
c0Cnt = list->cnt;
c0Type = list->type;
break;
case GX_VA_CLR1:
c1Cnt = list->cnt;
c1Type = list->type;
break;
case GX_VA_TEX0:
tx0Cnt = list->cnt;
tx0Type = list->type;
tx0Frac = list->frac;
break;
case GX_VA_TEX1:
tx1Cnt = list->cnt;
tx1Type = list->type;
tx1Frac = list->frac;
break;
case GX_VA_TEX2:
tx2Cnt = list->cnt;
tx2Type = list->type;
tx2Frac = list->frac;
break;
case GX_VA_TEX3:
tx3Cnt = list->cnt;
tx3Type = list->type;
tx3Frac = list->frac;
break;
case GX_VA_TEX4:
tx4Cnt = list->cnt;
tx4Type = list->type;
tx4Frac = list->frac;
break;
case GX_VA_TEX5:
tx5Cnt = list->cnt;
tx5Type = list->type;
tx5Frac = list->frac;
break;
case GX_VA_TEX6:
tx6Cnt = list->cnt;
tx6Type = list->type;
tx6Frac = list->frac;
break;
case GX_VA_TEX7:
tx7Cnt = list->cnt;
tx7Type = list->type;
tx7Frac = list->frac;
}
}
GDOverflowCheck(18);
J3DGDWriteCPCmd(vtxfmt + CP_REG_VAT_GRP0_ID, CP_REG_VAT_GRP0(posCnt, posType, posFrac, nrmCnt, nrmType, c0Cnt, c0Type, c1Cnt, c1Type, tx0Cnt, tx0Type, tx0Frac, 1, nrmIdx3));
J3DGDWriteCPCmd(vtxfmt + CP_REG_VAT_GRP1_ID, CP_REG_VAT_GRP1(tx1Cnt, tx1Type, tx1Frac, tx2Cnt, tx2Type, tx2Frac, tx3Cnt, tx3Type, tx3Frac, tx4Cnt, tx4Type, 1));
J3DGDWriteCPCmd(vtxfmt + CP_REG_VAT_GRP2_ID, CP_REG_VAT_GRP2(tx4Frac, tx5Cnt, tx5Type, tx5Frac, tx6Cnt, tx6Type, tx6Frac, tx7Cnt, tx7Type, tx7Frac));
}
void J3DGDSetTexCoordGen(GXTexGenType func, GXTexGenSrc src_param) {
u32 tgType;
u32 form;
u32 proj;
u32 row;
u32 embossRow;
u32 embossLit;
form = 0;
proj = 0;
row = 5;
embossRow = 5;
embossLit = 0;
switch(src_param) {
case GX_TG_POS:
row = 0;
form = 1;
break;
case GX_TG_NRM:
row = 1;
form = 1;
break;
case GX_TG_BINRM:
row = 3;
form = 1;
break;
case GX_TG_TANGENT:
row = 4;
form = 1;
break;
case GX_TG_COLOR0:
row = 2;
break;
case GX_TG_COLOR1:
row = 2;
break;
case GX_TG_TEX0:
row = 5;
break;
case GX_TG_TEX1:
row = 6;
break;
case GX_TG_TEX2:
row = 7;
break;
case GX_TG_TEX3:
row = 8;
break;
case GX_TG_TEX4:
row = 9;
break;
case GX_TG_TEX5:
row = 10;
break;
case GX_TG_TEX6:
row = 11;
break;
case GX_TG_TEX7:
row = 12;
break;
case GX_TG_TEXCOORD0:
embossRow = 0;
break;
case GX_TG_TEXCOORD1:
embossRow = 1;
break;
case GX_TG_TEXCOORD2:
embossRow = 2;
break;
case GX_TG_TEXCOORD3:
embossRow = 3;
break;
case GX_TG_TEXCOORD4:
embossRow = 4;
break;
case GX_TG_TEXCOORD5:
embossRow = 5;
break;
case GX_TG_TEXCOORD6:
embossRow = 6;
break;
default:
ASSERTMSGLINE(433, 0, "GDSetTexCoordGen: invalid texgen source");
break;
}
switch (func) {
case GX_TG_MTX2x4:
tgType = 0;
break;
case GX_TG_MTX3x4:
tgType = 0;
proj = 1;
break;
case GX_TG_BUMP0:
case GX_TG_BUMP1:
case GX_TG_BUMP2:
case GX_TG_BUMP3:
case GX_TG_BUMP4:
case GX_TG_BUMP5:
case GX_TG_BUMP6:
case GX_TG_BUMP7:
ASSERTMSGLINE(457, src_param >= GX_TG_TEXCOORD0 && src_param <= GX_TG_TEXCOORD6, "GDSetTexCoordGen: invalid emboss source");
tgType = 1;
embossLit = func - GX_TG_BUMP0;
break;
case GX_TG_SRTG:
if (src_param == GX_TG_COLOR0) {
tgType = 2;
} else {
tgType = 3;
}
break;
default:
ASSERTMSGLINE(473, 0, "GDSetTexCoordGen: invalid texgen function");
break;
}
J3DGDWrite_u32(XF_REG_TEX(proj, form, tgType, row, embossRow, embossLit));
}
void J3DGDSetTexCoordScale2(GXTexCoordID coord, u16 s_scale, u8 s_bias,
u8 s_wrap, u16 t_scale, u8 t_bias, u8 t_wrap) {
GDOverflowCheck(15);
J3DGDWriteBPCmd(0xFE03FFFF);
J3DGDWriteBPCmd(BP_TEXCOORD_S_SCALE(s_scale - 1, s_bias, s_wrap, 0, 0, coord * 2 + 0x30));
J3DGDWriteBPCmd(BP_TEXCOORD_T_SCALE(t_scale - 1, t_bias, t_wrap, coord * 2 + 0x31));
}
static u8 J3DGDTexMode0Ids[8] = {
0x80, 0x81, 0x82, 0x83, 0xA0, 0xA1, 0xA2, 0xA3,
};
static u8 J3DGDTexMode1Ids[8] = {
0x84, 0x85, 0x86, 0x87, 0xA4, 0xA5, 0xA6, 0xA7,
};
static u8 J3DGDTexImage0Ids[8] = {
0x88, 0x89, 0x8A, 0x8B, 0xA8, 0xA9, 0xAA, 0xAB,
};
static u8 J3DGDTexImage3Ids[8] = {
0x94, 0x95, 0x96, 0x97, 0xB4, 0xB5, 0xB6, 0xB7,
};
static u8 J3DGDTexTlutIds[8] = {
0x98, 0x99, 0x9A, 0x9B, 0xB8, 0xB9, 0xBA, 0xBB,
};
static u8 GX2HWFiltConv[6] = {
0x00, 0x04, 0x01, 0x05, 0x02, 0x06,
};
void J3DGDSetTexLookupMode(GXTexMapID id, GXTexWrapMode wrap_s,
GXTexWrapMode wrap_t, GXTexFilter min_filt,
GXTexFilter mag_filt, f32 min_lod, f32 max_lod,
f32 lod_bias, u8 bias_clamp, u8 do_edge_lod,
GXAnisotropy max_aniso) {
J3DGDWriteBPCmd(BP_TEX_MODE0(wrap_s, wrap_t, mag_filt == TRUE, GX2HWFiltConv[min_filt], !do_edge_lod, (u8)(32.0f * lod_bias), max_aniso, bias_clamp, J3DGDTexMode0Ids[id]));
J3DGDWriteBPCmd(BP_TEX_MODE1((u8)(16.0f * min_lod), (u8)(16.0f * max_lod), J3DGDTexMode1Ids[id]));
}
void J3DGDSetTexImgAttr(GXTexMapID id, u16 width, u16 height, GXTexFmt format) {
J3DGDWriteBPCmd(BP_IMAGE_ATTR(width - 1, height - 1, format, J3DGDTexImage0Ids[id]));
}
void J3DGDSetTexImgPtr(GXTexMapID id, void* image_ptr) {
#if TARGET_PC
puts("J3DGDSetTexImgPtr is a stub");
#else
J3DGDWriteBPCmd(BP_IMAGE_PTR(OSCachedToPhysical(image_ptr) >> 5, J3DGDTexImage3Ids[id]));
#endif
}
void J3DGDSetTexImgPtrRaw(GXTexMapID id, u32 image_ptr_raw) {
GDOverflowCheck(5);
J3DGDWriteBPCmd(BP_IMAGE_PTR(image_ptr_raw, J3DGDTexImage3Ids[id]));
}
void J3DGDSetTexTlut(GXTexMapID id, u32 tmem_addr, GXTlutFmt format) {
J3DGDWriteBPCmd(BP_TEX_TLUT((tmem_addr - 0x80000) >> 9, format, J3DGDTexTlutIds[id]));
}
void J3DGDLoadTlut(void* tlut_ptr, u32 tmem_addr, GXTlutSize size) {
ASSERTMSGLINE(735, !(tmem_addr & 0x1ff), "GDLoadTlut: invalid TMEM pointer");
ASSERTMSGLINE(736, size <= 0x400, "GDLoadTlut: invalid TLUT size");
J3DGDWriteBPCmd(0xFEFFFF00);
J3DGDWriteBPCmd(0xF000000);
#if TARGET_PC
puts("J3DGDLoadTlut is a stub");
return;
#endif
J3DGDWriteBPCmd(BP_LOAD_TLUT0(OSCachedToPhysical(tlut_ptr) >> 5, 0x64));
J3DGDWriteBPCmd(BP_LOAD_TLUT1((tmem_addr - 0x80000) >> 9, size, 0x65));
J3DGDWriteBPCmd(0xFEFFFF00);
J3DGDWriteBPCmd(0xF000000);
}
void J3DGDSetIndTexMtx(GXIndTexMtxID mtx_id, f32 offset[2][3], s8 scale_exp) {
s32 offsetS32[6];
u32 id_offset;
switch (mtx_id) {
case GX_ITM_0:
case GX_ITM_1:
case GX_ITM_2:
id_offset = (u32)(mtx_id - GX_ITM_0);
break;
case GX_ITM_S0:
case GX_ITM_S1:
case GX_ITM_S2:
id_offset = (u32)(mtx_id - GX_ITM_S0);
break;
case GX_ITM_T0:
case GX_ITM_T1:
case GX_ITM_T2:
id_offset = (u32)(mtx_id - GX_ITM_T0);
break;
default:
id_offset = 0;
break;
}
offsetS32[0] = (s32)(offset[0][0] * 0x400) & 0x7FF;
offsetS32[1] = (s32)(offset[1][0] * 0x400) & 0x7FF;
offsetS32[2] = (s32)(offset[0][1] * 0x400) & 0x7FF;
offsetS32[3] = (s32)(offset[1][1] * 0x400) & 0x7FF;
offsetS32[4] = (s32)(offset[0][2] * 0x400) & 0x7FF;
offsetS32[5] = (s32)(offset[1][2] * 0x400) & 0x7FF;
scale_exp += (s8)17;
GDOverflowCheck(15);
J3DGDWriteBPCmd(BP_IND_MTX(
offsetS32[0],
offsetS32[1],
scale_exp & 3,
6 + id_offset * 3
));
J3DGDWriteBPCmd(BP_IND_MTX(
offsetS32[2],
offsetS32[3],
(scale_exp >> 2) & 3,
7 + id_offset * 3
));
J3DGDWriteBPCmd(BP_IND_MTX(
offsetS32[4],
offsetS32[5],
(scale_exp >> 4) & 3,
8 + id_offset * 3
));
}
void J3DGDSetIndTexCoordScale(GXIndTexStageID indStageEven, GXIndTexScale scaleS0,
GXIndTexScale scaleT0, GXIndTexScale scaleS1,
GXIndTexScale scaleT1) {
GDOverflowCheck(5);
J3DGDWriteBPCmd(BP_IND_TEXCOORD_SCALE(
scaleS0,
scaleT0,
scaleS1,
scaleT1,
0x25 + (indStageEven >> 1)
));
}
void J3DGDSetIndTexOrder(u32 count, GXTexCoordID texCoord0, GXTexMapID texMap0,
GXTexCoordID texCoord1, GXTexMapID texMap1,
GXTexCoordID texCoord2, GXTexMapID texMap2,
GXTexCoordID texCoord3, GXTexMapID texMap3) {
GDOverflowCheck(10);
J3DGDWriteBPCmd(BP_IND_TEX_ORDER(
texMap0 & 7,
texCoord0 & 7,
texMap1 & 7,
texCoord1 & 7,
texMap2 & 7,
texCoord2 & 7,
texMap3 & 7,
texCoord3 & 7,
0x27
));
u32 mask = 0;
for (u32 i = 0; i < count; i++) {
switch (i) {
case 0:
mask |= 1 << (texMap0 & 7);
break;
case 1:
mask |= 1 << (texMap1 & 7);
break;
case 2:
mask |= 1 << (texMap2 & 7);
break;
case 3:
mask |= 1 << (texMap3 & 7);
break;
}
}
J3DGDWriteBPCmd(BP_IND_MASK(mask, 0xF));
}
void J3DGDSetTevOrder(GXTevStageID evenStage, GXTexCoordID coord0, GXTexMapID map0,
GXChannelID color0, GXTexCoordID coord1, GXTexMapID map1,
GXChannelID color1) {
static u8 c2r[] = {0, 1, 0, 1, 0, 1, 7, 5, 6, 0, 0, 0, 0, 0, 0, 7};
GXTexCoordID coord0_ = coord0 >= GX_MAX_TEXCOORD ? GX_TEXCOORD0 : coord0;
GXTexCoordID coord1_ = coord1 >= GX_MAX_TEXCOORD ? GX_TEXCOORD0 : coord1;
GDOverflowCheck(5);
J3DGDWriteBPCmd(BP_TEV_ORDER(
map0 & 7,
coord0_,
map0 != GX_TEXMAP_NULL && !(map0 & GX_TEX_DISABLE),
c2r[color0 & 0xF],
map1 & 7,
coord1_,
map1 != GX_TEXMAP_NULL && !(map1 & GX_TEX_DISABLE),
c2r[color1 & 0xF],
evenStage / 2 + 0x28
));
}
void J3DGDSetTevKColor(GXTevKColorID reg, GXColor color) {
u32 regRA;
u32 regBG;
regRA = BP_TEV_COLOR_REG_RA(color.r, color.a, 1, 0xE0 + reg * 2);
regBG = BP_TEV_COLOR_REG_BG(color.b, color.g, 1, 0xE1 + reg * 2);
GDOverflowCheck(0xa);
J3DGDWriteBPCmd(regRA);
J3DGDWriteBPCmd(regBG);
}
void J3DGDSetTevColorS10(GXTevRegID reg, GXColorS10 color) {
u32 regRA;
u32 regBG;
regRA = BP_TEV_COLOR_REG_RA(color.r & 0x7FF, color.a & 0x7FF, 0, 0xE0 + reg * 2);
regBG = BP_TEV_COLOR_REG_BG(color.b & 0x7FF, color.g & 0x7FF, 0, 0xE1 + reg * 2);
GDOverflowCheck(0x14);
J3DGDWriteBPCmd(regRA);
J3DGDWriteBPCmd(regBG);
J3DGDWriteBPCmd(regBG);
J3DGDWriteBPCmd(regBG);
}
void J3DGDSetFog(GXFogType type, f32 startz, f32 endz, f32 nearz, f32 farz, GXColor color) {
f32 A;
f32 B;
f32 B_mant;
f32 C;
f32 A_f;
u32 b_expn;
u32 b_m;
u32 a_hex;
u32 c_hex;
ASSERTMSGLINE(1036, farz >= 0.0f, "GDSetFog: The farz should be positive value");
ASSERTMSGLINE(1037, farz >= nearz, "GDSetFog: The farz should be larger than nearz");
if (farz == nearz || endz == startz) {
A = 0.0f;
B = 0.5f;
C = 0.0f;
} else {
A = (farz * nearz) / ((farz - nearz) * (endz - startz));
B = farz / (farz - nearz);
C = startz / (endz - startz);
}
B_mant = B;
b_expn = 1;
while (B_mant > 1.0) {
B_mant *= 0.5f;
b_expn++;
}
while (B_mant > 0.0f && B_mant < 0.5) {
B_mant *= 2.0f;
b_expn--;
}
A_f = A / (1 << b_expn);
b_m = (u32) (8388638.0f * B_mant);
a_hex = *(u32*)&A_f;
c_hex = *(u32*)&C;
J3DGDWriteBPCmd(BP_FOG_UNK0(a_hex >> 12, 0xEE));
J3DGDWriteBPCmd(BP_FOG_UNK1(b_m, 0xEF));
J3DGDWriteBPCmd(BP_FOG_UNK2(b_expn, 0xF0));
J3DGDWriteBPCmd(BP_FOG_UNK3(c_hex >> 12, 0, type, 0xF1));
J3DGDWriteBPCmd(BP_FOG_COLOR(color.r, color.g, color.b, 0xF2));
}
#define BP_FOG_RANGE_ADJ_K0(arg0, arg1, arg2) \
( \
(u32)(arg2) << 24 | \
(u32)(arg1) << 12 | \
(u32)(arg0) << 0 \
)
#define BP_FOG_RANGE_ADJ(arg0, arg1, arg2) \
( \
(u32)(arg2) << 24 | \
(u32)(arg0) << 0 | \
(u32)(arg1) << 10 \
)
void J3DGDSetFogRangeAdj(GXBool enable, u16 center, GXFogAdjTable* table) {
if (enable) {
for (int i = 0; i < 10; i += 2) {
u32 range_adj = BP_FOG_RANGE_ADJ_K0(table->r[i], table->r[i + 1], i / 2 + 0xE9);
J3DGDWriteBPCmd(range_adj);
}
}
u32 range_c = BP_FOG_RANGE_ADJ(center + 342, enable, GX_BP_REG_FOGRANGE);
J3DGDWriteBPCmd(range_c);
}
void J3DFifoLoadPosMtxImm(MtxP mtx, u32 id) {
J3DFifoWriteXFCmdHdr(4 * id, 12);
J3DGXCmd1f32ptr(&mtx[0][0]);
J3DGXCmd1f32ptr(&mtx[0][1]);
J3DGXCmd1f32ptr(&mtx[0][2]);
J3DGXCmd1f32ptr(&mtx[0][3]);
J3DGXCmd1f32ptr(&mtx[1][0]);
J3DGXCmd1f32ptr(&mtx[1][1]);
J3DGXCmd1f32ptr(&mtx[1][2]);
J3DGXCmd1f32ptr(&mtx[1][3]);
J3DGXCmd1f32ptr(&mtx[2][0]);
J3DGXCmd1f32ptr(&mtx[2][1]);
J3DGXCmd1f32ptr(&mtx[2][2]);
J3DGXCmd1f32ptr(&mtx[2][3]);
}
void J3DFifoLoadNrmMtxImm(MtxP mtx, u32 id) {
J3DFifoWriteXFCmdHdr(id * 3 + 0x400, 9);
J3DGXCmd1f32ptr(&mtx[0][0]);
J3DGXCmd1f32ptr(&mtx[0][1]);
J3DGXCmd1f32ptr(&mtx[0][2]);
J3DGXCmd1f32ptr(&mtx[1][0]);
J3DGXCmd1f32ptr(&mtx[1][1]);
J3DGXCmd1f32ptr(&mtx[1][2]);
J3DGXCmd1f32ptr(&mtx[2][0]);
J3DGXCmd1f32ptr(&mtx[2][1]);
J3DGXCmd1f32ptr(&mtx[2][2]);
}
void J3DFifoLoadNrmMtxImm3x3(Mtx3P mtx, u32 id) {
J3DFifoWriteXFCmdHdr(id * 3 + 0x400, 9);
J3DGXCmd1f32ptr(&mtx[0][0]);
J3DGXCmd1f32ptr(&mtx[0][1]);
J3DGXCmd1f32ptr(&mtx[0][2]);
J3DGXCmd1f32ptr(&mtx[1][0]);
J3DGXCmd1f32ptr(&mtx[1][1]);
J3DGXCmd1f32ptr(&mtx[1][2]);
J3DGXCmd1f32ptr(&mtx[2][0]);
J3DGXCmd1f32ptr(&mtx[2][1]);
J3DGXCmd1f32ptr(&mtx[2][2]);
}
void J3DFifoLoadNrmMtxToTexMtx(MtxP mtx, u32 id) {
J3DFifoWriteXFCmdHdr(4 * id, 12);
J3DGXCmd1f32ptr(&mtx[0][0]);
J3DGXCmd1f32ptr(&mtx[0][1]);
J3DGXCmd1f32ptr(&mtx[0][2]);
J3DGXCmd1f32(0.0f);
J3DGXCmd1f32ptr(&mtx[1][0]);
J3DGXCmd1f32ptr(&mtx[1][1]);
J3DGXCmd1f32ptr(&mtx[1][2]);
J3DGXCmd1f32(0.0f);
J3DGXCmd1f32ptr(&mtx[2][0]);
J3DGXCmd1f32ptr(&mtx[2][1]);
J3DGXCmd1f32ptr(&mtx[2][2]);
J3DGXCmd1f32(0.0f);
}
void J3DFifoLoadNrmMtxToTexMtx3x3(Mtx3P mtx, u32 id) {
J3DFifoWriteXFCmdHdr(4 * id, 0xc);
J3DGXCmd1f32ptr(&mtx[0][0]);
J3DGXCmd1f32ptr(&mtx[0][1]);
J3DGXCmd1f32ptr(&mtx[0][2]);
J3DGXCmd1f32(0.0f);
J3DGXCmd1f32ptr(&mtx[1][0]);
J3DGXCmd1f32ptr(&mtx[1][1]);
J3DGXCmd1f32ptr(&mtx[1][2]);
J3DGXCmd1f32(0.0f);
J3DGXCmd1f32ptr(&mtx[2][0]);
J3DGXCmd1f32ptr(&mtx[2][1]);
J3DGXCmd1f32ptr(&mtx[2][2]);
J3DGXCmd1f32(0.0f);
}
static u8 J3DTexImage1Ids[8] = {
0x8C, 0x8D, 0x8E, 0x8F, 0xAC, 0xAD, 0xAE, 0xAF,
};
static u8 J3DTexImage2Ids[8] = {
0x90, 0x91, 0x92, 0x93, 0xB0, 0xB1, 0xB2, 0xB3,
};
void J3DFifoLoadTexCached(GXTexMapID id, u32 tmem_even, GXTexCacheSize size_even,
u32 tmem_odd, GXTexCacheSize size_odd) {
J3DFifoLoadBPCmd(BP_TEX_CACHE_EVEN(tmem_even >> 5, size_even + 3, size_even + 3, 0, J3DTexImage1Ids[id]));
if (size_odd != 3 && tmem_odd < 0x100000) {
J3DFifoLoadBPCmd(BP_TEX_CACHE_ODD(tmem_odd >> 5, size_odd + 3, size_odd + 3, J3DTexImage2Ids[id]));
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,422 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/J3DGraphBase/J3DGD.h"
#include "JSystem/J3DGraphBase/J3DMaterial.h"
#include "JSystem/JKernel/JKRHeap.h"
J3DColorBlock* J3DMaterial::createColorBlock(u32 flags) {
J3DColorBlock* rv = NULL;
switch (flags) {
case 0:
rv = JKR_NEW J3DColorBlockLightOff();
break;
case 0x40000000:
rv = JKR_NEW J3DColorBlockLightOn();
break;
case 0x80000000:
rv = JKR_NEW J3DColorBlockAmbientOn();
break;
}
J3D_ASSERT_ALLOCMEM(55, rv != NULL);
return rv;
}
J3DTexGenBlock* J3DMaterial::createTexGenBlock(u32 flags) {
J3DTexGenBlock* rv = NULL;
switch (flags) {
case 0x8000000:
rv = JKR_NEW J3DTexGenBlock4();
break;
case 0:
default:
rv = JKR_NEW J3DTexGenBlockBasic();
}
J3D_ASSERT_ALLOCMEM(83, rv != NULL);
return rv;
}
J3DTevBlock* J3DMaterial::createTevBlock(int tevStageNum) {
J3DTevBlock* rv = NULL;
if (tevStageNum <= 1) {
rv = JKR_NEW J3DTevBlock1();
} else if (tevStageNum == 2) {
rv = JKR_NEW J3DTevBlock2();
} else if (tevStageNum <= 4) {
rv = JKR_NEW J3DTevBlock4();
} else if (tevStageNum <= 16) {
rv = JKR_NEW J3DTevBlock16();
}
J3D_ASSERT_ALLOCMEM(116, rv != NULL);
return rv;
}
J3DIndBlock* J3DMaterial::createIndBlock(int flags) {
J3DIndBlock* rv = NULL;
if (flags != 0) {
rv = JKR_NEW J3DIndBlockFull();
} else {
rv = JKR_NEW J3DIndBlockNull();
}
J3D_ASSERT_ALLOCMEM(139, rv != NULL);
return rv;
}
J3DPEBlock* J3DMaterial::createPEBlock(u32 flags, u32 materialMode) {
J3DPEBlock* rv = NULL;
if (flags == 0) {
if (materialMode & 1) {
rv = JKR_NEW J3DPEBlockOpa();
J3D_ASSERT_ALLOCMEM(166, rv != NULL);
return rv;
} else if (materialMode & 2) {
rv = JKR_NEW J3DPEBlockTexEdge();
J3D_ASSERT_ALLOCMEM(172, rv != NULL);
return rv;
} else if (materialMode & 4) {
rv = JKR_NEW J3DPEBlockXlu();
J3D_ASSERT_ALLOCMEM(178, rv != NULL);
return rv;
}
}
if (flags == 0x10000000) {
rv = JKR_NEW J3DPEBlockFull();
} else if (flags == 0x20000000) {
rv = JKR_NEW J3DPEBlockFogOff();
}
J3D_ASSERT_ALLOCMEM(188, rv != NULL);
return rv;
}
u32 J3DMaterial::calcSizeColorBlock(u32 flags) {
u32 rv = 0;
switch (flags) {
case 0:
rv += sizeof(J3DColorBlockLightOff);
break;
case 0x40000000:
rv += sizeof(J3DColorBlockLightOn);
break;
case 0x80000000:
rv += sizeof(J3DColorBlockAmbientOn);
break;
}
return rv;
}
u32 J3DMaterial::calcSizeTexGenBlock(u32 flags) {
u32 rv = 0;
switch (flags) {
case 0x8000000:
rv += sizeof(J3DTexGenBlock4);
break;
case 0:
default:
rv += sizeof(J3DTexGenBlockBasic);
}
return rv;
}
u32 J3DMaterial::calcSizeTevBlock(int tevStageNum) {
u32 rv = 0;
if (tevStageNum <= 1) {
rv += sizeof(J3DTevBlock1);
} else if (tevStageNum == 2) {
rv += sizeof(J3DTevBlock2);
} else if (tevStageNum <= 4) {
rv += sizeof(J3DTevBlock4);
} else if (tevStageNum <= 16) {
rv += sizeof(J3DTevBlock16);
}
return rv;
}
u32 J3DMaterial::calcSizeIndBlock(int flags) {
u32 rv = 0;
if (flags != 0) {
rv += sizeof(J3DIndBlockFull);
} else {
rv += sizeof(J3DIndBlockNull);
}
return rv;
}
u32 J3DMaterial::calcSizePEBlock(u32 flags, u32 materialMode) {
u32 rv = 0;
if (flags == 0) {
if (materialMode & 1) {
rv += sizeof(J3DPEBlockOpa);
} else if (materialMode & 2) {
rv += sizeof(J3DPEBlockTexEdge);
} else if (materialMode & 4) {
rv += sizeof(J3DPEBlockXlu);
}
} else if (flags == 0x10000000) {
rv += sizeof(J3DPEBlockFull);
} else if (flags == 0x20000000) {
rv += sizeof(J3DPEBlockFogOff);
}
return rv;
}
void J3DMaterial::initialize() {
mShape = NULL;
mNext = NULL;
mJoint = NULL;
mMaterialMode = 1;
mIndex = -1;
mInvalid = 0;
mDiffFlag = 0;
mColorBlock = NULL;
mTexGenBlock = NULL;
mTevBlock = NULL;
mIndBlock = NULL;
mPEBlock = NULL;
mpOrigMaterial = NULL;
mMaterialAnm = NULL;
mSharedDLObj = NULL;
}
u32 J3DMaterial::countDLSize() {
return (mColorBlock->countDLSize() + mTexGenBlock->countDLSize() + mTevBlock->countDLSize() +
mIndBlock->countDLSize() + mPEBlock->countDLSize() + 31) & ~0x1f;
}
void J3DMaterial::makeDisplayList_private(J3DDisplayListObj* pDLObj) {
pDLObj->beginDL();
mTevBlock->load();
mIndBlock->load();
mPEBlock->load();
J3DGDSetGenMode(mTexGenBlock->getTexGenNum(), mColorBlock->getColorChanNum(), mTevBlock->getTevStageNum(), mIndBlock->getIndTexStageNum(), (GXCullMode)(u8)mColorBlock->getCullMode());
mTexGenBlock->load();
mColorBlock->load();
J3DGDSetNumChans(mColorBlock->getColorChanNum());
J3DGDSetNumTexGens(mTexGenBlock->getTexGenNum());
pDLObj->endDL();
}
void J3DMaterial::makeDisplayList() {
if (!j3dSys.getMatPacket()->isLocked()) {
j3dSys.getMatPacket()->mDiffFlag = mDiffFlag;
makeDisplayList_private(j3dSys.getMatPacket()->getDisplayListObj());
}
}
void J3DMaterial::makeSharedDisplayList() {
makeDisplayList_private(mSharedDLObj);
}
void J3DMaterial::load() {
j3dSys.setMaterialMode(mMaterialMode);
if (!j3dSys.checkFlag(2)) {
loadNBTScale(*mTexGenBlock->getNBTScale());
}
}
void J3DMaterial::loadSharedDL() {
j3dSys.setMaterialMode(mMaterialMode);
if (!j3dSys.checkFlag(2)) {
mSharedDLObj->callDL();
loadNBTScale(*mTexGenBlock->getNBTScale());
}
}
void J3DMaterial::patch() {
j3dSys.getMatPacket()->mDiffFlag = mDiffFlag;
j3dSys.getMatPacket()->beginPatch();
mTevBlock->patch();
mColorBlock->patch();
mTexGenBlock->patch();
j3dSys.getMatPacket()->endPatch();
}
void J3DMaterial::diff(u32 diffFlags) {
if (j3dSys.getMatPacket()->isEnabled_Diff()) {
j3dSys.getMatPacket()->beginDiff();
mTevBlock->diff(diffFlags);
mIndBlock->diff(diffFlags);
mPEBlock->diff(diffFlags);
if (diffFlags & J3DDiffFlag_KonstColor) {
J3DGDSetGenMode_3Param(mTexGenBlock->getTexGenNum(), mTevBlock->getTevStageNum(), mIndBlock->getIndTexStageNum());
J3DGDSetNumTexGens(mTexGenBlock->getTexGenNum());
}
mTexGenBlock->diff(diffFlags);
mColorBlock->diff(diffFlags);
j3dSys.getMatPacket()->endDiff();
}
}
void J3DMaterial::calc(f32 const (*param_0)[4]) {
if (j3dSys.checkFlag(0x40000000)) {
mTexGenBlock->calcPostTexMtx(param_0);
} else {
mTexGenBlock->calc(param_0);
}
calcCurrentMtx();
setCurrentMtx();
}
void J3DMaterial::calcDiffTexMtx(f32 const (*param_0)[4]) {
if (j3dSys.checkFlag(0x40000000)) {
mTexGenBlock->calcPostTexMtxWithoutViewMtx(param_0);
} else {
mTexGenBlock->calcWithoutViewMtx(param_0);
}
}
void J3DMaterial::setCurrentMtx() {
mShape->setCurrentMtx(mCurrentMtx);
}
void J3DMaterial::calcCurrentMtx() {
if (!j3dSys.checkFlag(0x40000000)) {
mCurrentMtx.setCurrentTexMtx(
getTexCoord(0)->getTexGenMtx(),
getTexCoord(1)->getTexGenMtx(),
getTexCoord(2)->getTexGenMtx(),
getTexCoord(3)->getTexGenMtx(),
getTexCoord(4)->getTexGenMtx(),
getTexCoord(5)->getTexGenMtx(),
getTexCoord(6)->getTexGenMtx(),
getTexCoord(7)->getTexGenMtx()
);
} else {
mCurrentMtx.setCurrentTexMtx(
getTexCoord(0)->getTexMtxReg(),
getTexCoord(1)->getTexMtxReg(),
getTexCoord(2)->getTexMtxReg(),
getTexCoord(3)->getTexMtxReg(),
getTexCoord(4)->getTexMtxReg(),
getTexCoord(5)->getTexMtxReg(),
getTexCoord(6)->getTexMtxReg(),
getTexCoord(7)->getTexMtxReg()
);
}
}
void J3DMaterial::copy(J3DMaterial* pOther) {
J3D_ASSERT_NULLPTR(620, pOther != NULL);
mColorBlock->reset(pOther->mColorBlock);
mTexGenBlock->reset(pOther->mTexGenBlock);
mTevBlock->reset(pOther->mTevBlock);
mIndBlock->reset(pOther->mIndBlock);
mPEBlock->reset(pOther->mPEBlock);
}
void J3DMaterial::reset() {
if ((~mDiffFlag & J3DDiffFlag_Changed) == 0) {
mDiffFlag &= ~J3DDiffFlag_Changed;
mMaterialMode = mpOrigMaterial->mMaterialMode;
mInvalid = mpOrigMaterial->mInvalid;
mMaterialAnm = NULL;
copy(mpOrigMaterial);
}
}
void J3DMaterial::change() {
if ((mDiffFlag & (J3DDiffFlag_Changed | J3DDiffFlag_Unk40000000)) == 0) {
mDiffFlag |= J3DDiffFlag_Changed;
mMaterialAnm = NULL;
}
}
s32 J3DMaterial::newSharedDisplayList(u32 dlSize) {
if (mSharedDLObj == NULL) {
mSharedDLObj = JKR_NEW J3DDisplayListObj();
if (mSharedDLObj == NULL) {
return kJ3DError_Alloc;
}
s32 ret = mSharedDLObj->newDisplayList(dlSize);
if (ret != kJ3DError_Success) {
return ret;
}
}
return kJ3DError_Success;
}
s32 J3DMaterial::newSingleSharedDisplayList(u32 dlSize) {
if (mSharedDLObj == NULL) {
mSharedDLObj = JKR_NEW J3DDisplayListObj();
if (mSharedDLObj == NULL) {
return kJ3DError_Alloc;
}
s32 ret = mSharedDLObj->newSingleDisplayList(dlSize);
if (ret != kJ3DError_Success) {
return ret;
}
}
return kJ3DError_Success;
}
void J3DPatchedMaterial::initialize() {
J3DMaterial::initialize();
}
void J3DPatchedMaterial::makeDisplayList() {}
void J3DPatchedMaterial::makeSharedDisplayList() {}
void J3DPatchedMaterial::load() {
j3dSys.setMaterialMode(mMaterialMode);
if (j3dSys.checkFlag(2)) {
return;
}
}
void J3DPatchedMaterial::loadSharedDL() {
j3dSys.setMaterialMode(mMaterialMode);
if (!j3dSys.checkFlag(0x02))
mSharedDLObj->callDL();
}
void J3DPatchedMaterial::reset() {}
void J3DPatchedMaterial::change() {}
void J3DLockedMaterial::initialize() {
J3DMaterial::initialize();
}
void J3DLockedMaterial::makeDisplayList() {}
void J3DLockedMaterial::makeSharedDisplayList() {}
void J3DLockedMaterial::load() {
j3dSys.setMaterialMode(mMaterialMode);
if (j3dSys.checkFlag(2)) {
return;
}
}
void J3DLockedMaterial::loadSharedDL() {
j3dSys.setMaterialMode(mMaterialMode);
if (!j3dSys.checkFlag(0x02))
mSharedDLObj->callDL();
}
void J3DLockedMaterial::patch() {}
void J3DLockedMaterial::diff(u32 diffFlags) {}
void J3DLockedMaterial::calc(const Mtx param_0) {}
void J3DLockedMaterial::reset() {}
void J3DLockedMaterial::change() {}
+389
View File
@@ -0,0 +1,389 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/J3DGraphBase/J3DPacket.h"
#include "JSystem/J3DGraphAnimator/J3DModel.h"
#include "JSystem/J3DGraphBase/J3DDrawBuffer.h"
#include "JSystem/J3DGraphBase/J3DMaterial.h"
#include "JSystem/J3DGraphBase/J3DShapeMtx.h"
#include "JSystem/JKernel/JKRHeap.h"
#include <os.h>
#include <cstring>
#include "global.h"
J3DError J3DDisplayListObj::newDisplayList(u32 maxSize) {
mMaxSize = ALIGN_NEXT(maxSize, 0x20);
mpDisplayList[0] = JKR_NEW_ARGS (0x20) char[mMaxSize];
mpDisplayList[1] = JKR_NEW_ARGS (0x20) char[mMaxSize];
mSize = 0;
if (mpDisplayList[0] == NULL || mpDisplayList[1] == NULL)
return kJ3DError_Alloc;
return kJ3DError_Success;
}
J3DError J3DDisplayListObj::newSingleDisplayList(u32 maxSize) {
mMaxSize = ALIGN_NEXT(maxSize, 0x20);
mpDisplayList[0] = JKR_NEW_ARGS (0x20) char[mMaxSize];
mpDisplayList[1] = mpDisplayList[0];
mSize = 0;
if (mpDisplayList[0] == NULL)
return kJ3DError_Alloc;
return kJ3DError_Success;
}
int J3DDisplayListObj::single_To_Double() {
if (mpDisplayList[0] == mpDisplayList[1]) {
mpDisplayList[1] = JKR_NEW_ARGS (0x20) char[mMaxSize];
if (mpDisplayList[1] == NULL)
return kJ3DError_Alloc;
memcpy(mpDisplayList[1], mpDisplayList[0], mMaxSize);
DCStoreRange(mpDisplayList[1], mMaxSize);
}
return kJ3DError_Success;
}
void J3DDisplayListObj::setSingleDisplayList(void* pDLData, u32 size) {
J3D_ASSERT_NULLPTR(148, pDLData != NULL);
mMaxSize = ALIGN_NEXT(size, 0x20);
mpDisplayList[0] = pDLData;
mpDisplayList[1] = mpDisplayList[0];
mSize = size;
}
void J3DDisplayListObj::swapBuffer() {
void* pTmp = mpDisplayList[0];
mpDisplayList[0] = mpDisplayList[1];
mpDisplayList[1] = pTmp;
}
void J3DDisplayListObj::callDL() const {
GXCallDisplayList(mpDisplayList[0], mSize);
}
GDLObj J3DDisplayListObj::sGDLObj;
s32 J3DDisplayListObj::sInterruptFlag;
void J3DDisplayListObj::beginDL() {
swapBuffer();
sInterruptFlag = OSDisableInterrupts();
GDInitGDLObj(&sGDLObj, (u8*)mpDisplayList[0], mMaxSize);
GDSetCurrent(&sGDLObj);
}
u32 J3DDisplayListObj::endDL() {
GDPadCurr32();
OSRestoreInterrupts(sInterruptFlag);
mSize = GDGetGDLObjOffset(&sGDLObj);
GDFlushCurrToMem();
GDSetCurrent(NULL);
return mSize;
}
void J3DDisplayListObj::beginPatch() {
beginDL();
}
u32 J3DDisplayListObj::endPatch() {
OSRestoreInterrupts(sInterruptFlag);
GDSetCurrent(NULL);
return mSize;
}
int J3DPacket::entry(J3DDrawBuffer* pBuffer) {
J3D_ASSERT_NULLPTR(290, pBuffer != NULL);
return 1;
}
void J3DPacket::addChildPacket(J3DPacket* pPacket) {
J3D_ASSERT_NULLPTR(304, pPacket != NULL);
if (mpFirstChild == NULL) {
mpFirstChild = pPacket;
} else {
pPacket->setNextPacket(mpFirstChild);
mpFirstChild = pPacket;
}
}
static u32 sDifferedRegister[8] = {
J3DDiffFlag_AmbColor,
J3DDiffFlag_MatColor,
J3DDiffFlag_ColorChan,
J3DDiffFlag_TevReg,
J3DDiffFlag_Fog,
J3DDiffFlag_Blend,
J3DDiffFlag_KonstColor,
J3DDiffFlag_TevStageIndirect,
};
static s32 sSizeOfDiffered[8] = {
13,
13,
21,
120,
55,
15,
19,
45,
};
J3DDrawPacket::J3DDrawPacket() {
mFlags = 0;
mpDisplayListObj = NULL;
mpTexMtxObj = NULL;
}
J3DDrawPacket::~J3DDrawPacket() {}
J3DError J3DDrawPacket::newDisplayList(u32 size) {
mpDisplayListObj = JKR_NEW J3DDisplayListObj();
if (mpDisplayListObj == NULL)
return kJ3DError_Alloc;
J3DError ret = mpDisplayListObj->newDisplayList(size);
if (ret != kJ3DError_Success)
return ret;
return kJ3DError_Success;
}
J3DError J3DDrawPacket::newSingleDisplayList(u32 size) {
mpDisplayListObj = JKR_NEW J3DDisplayListObj();
if (mpDisplayListObj == NULL)
return kJ3DError_Alloc;
J3DError ret = mpDisplayListObj->newSingleDisplayList(size);
if (ret != kJ3DError_Success)
return ret;
return kJ3DError_Success;
}
void J3DDrawPacket::draw() {
callDL();
}
J3DMatPacket::J3DMatPacket() {
mpInitShapePacket = NULL;
mpShapePacket = NULL;
mpMaterial = NULL;
mDiffFlag = 0xFFFFFFFF;
mpTexture = NULL;
mpMaterialAnm = NULL;
}
J3DMatPacket::~J3DMatPacket() {}
void J3DMatPacket::addShapePacket(J3DShapePacket* pShape) {
if (mpShapePacket == NULL) {
mpShapePacket = pShape;
} else {
pShape->setNextPacket(mpShapePacket);
mpShapePacket = pShape;
}
}
void J3DMatPacket::beginDiff() {
mpInitShapePacket->beginDL();
}
void J3DMatPacket::endDiff() {
mpInitShapePacket->endDL();
}
bool J3DMatPacket::isSame(J3DMatPacket* pOther) const {
J3D_ASSERT_NULLPTR(521, pOther != NULL);
return mDiffFlag == pOther->mDiffFlag && (mDiffFlag >> 31) == 0;
}
void J3DMatPacket::draw() {
mpMaterial->load();
callDL();
J3DShapePacket* packet = getShapePacket();
packet->getShape()->loadPreDrawSetting();
while (packet != NULL) {
if (packet->getDisplayListObj() != NULL) {
packet->getDisplayListObj()->callDL();
}
packet->drawFast();
packet = (J3DShapePacket*)packet->getNextPacket();
}
J3DShape::resetVcdVatCache();
}
J3DShapePacket::J3DShapePacket() {
mpShape = NULL;
mpMtxBuffer = NULL;
mpBaseMtxPtr = NULL;
mDiffFlag = 0;
mpModel = NULL;
}
J3DShapePacket::~J3DShapePacket() {}
u32 J3DShapePacket::calcDifferedBufferSize(u32 diffFlags) {
u32 bufferSize = 0;
for (u32 i = 0; i < 8; i++) {
if ((diffFlags & sDifferedRegister[i]) != 0) {
bufferSize += sSizeOfDiffered[i];
}
}
u32 lightObjNum = getDiffFlag_LightObjNum(diffFlags);
bufferSize += lightObjNum * 0x48;
u32 texGenNum = getDiffFlag_TexGenNum(diffFlags);
if (texGenNum != 0) {
u32 mat_texGenNum = mpShape->getMaterial()->getTexGenNum();
u32 sp30 = texGenNum > mat_texGenNum ? texGenNum : mat_texGenNum;
if (diffFlags & J3DDiffFlag_TexGen) {
bufferSize += calcDifferedBufferSize_TexGenSize(sp30);
} else {
bufferSize += calcDifferedBufferSize_TexMtxSize(sp30);
}
}
u32 texNoNum = getDiffFlag_TexNoNum(diffFlags);
if (texNoNum != 0) {
u8 sp9;
if (mpShape->getMaterial()->getTevStageNum() > 8) {
sp9 = 8;
} else {
sp9 = mpShape->getMaterial()->getTevStageNum();
}
u32 mat_texNoNum = sp9;
u32 sp24 = texNoNum > mat_texNoNum ? texNoNum : mat_texNoNum;
if (diffFlags & J3DDiffFlag_TexCoordScale) {
bufferSize += calcDifferedBufferSize_TexNoAndTexCoordScaleSize(sp24);
} else {
bufferSize += calcDifferedBufferSize_TexNoSize(sp24);
}
}
u32 tevStageNum = getDiffFlag_TevStageNum(diffFlags);
if (tevStageNum != 0) {
u8 sp8;
if (mpShape->getMaterial()->getTevStageNum() > 8) {
sp8 = 8;
} else {
sp8 = mpShape->getMaterial()->getTevStageNum();
}
u32 mat_tevStageNum = sp8;
u32 sp18 = tevStageNum > mat_tevStageNum ? tevStageNum : mat_tevStageNum;
bufferSize += calcDifferedBufferSize_TevStageSize(sp18);
if (diffFlags & J3DDiffFlag_TevStageIndirect) {
bufferSize += calcDifferedBufferSize_TevStageDirectSize(sp18);
}
}
return OSRoundUp32B(bufferSize);
}
int J3DShapePacket::newDifferedDisplayList(u32 diffFlags) {
mDiffFlag = diffFlags;
u32 bufSize = calcDifferedBufferSize(diffFlags);
int ret = newDisplayList(bufSize);
if (ret != kJ3DError_Success) {
return ret;
}
J3DDisplayListObj* dlobj = getDisplayListObj();
setDisplayListObj(dlobj);
return kJ3DError_Success;
}
void J3DShapePacket::prepareDraw() const {
mpModel->getVertexBuffer()->setArray();
j3dSys.setModel(mpModel);
j3dSys.setShapePacket((J3DShapePacket*)this);
J3DShapeMtx::setLODFlag(mpModel->checkFlag(J3DMdlFlag_EnableLOD) != 0);
if (mpModel->checkFlag(J3DMdlFlag_SkinPosCpu)) {
mpShape->onFlag(J3DShpFlag_SkinPosCpu);
} else {
mpShape->offFlag(J3DShpFlag_SkinPosCpu);
}
if (mpModel->checkFlag(J3DMdlFlag_SkinNrmCpu) &&
mpShape->checkFlag(J3DShpFlag_EnableLod) == false)
{
mpShape->onFlag(J3DShpFlag_SkinNrmCpu);
} else {
mpShape->offFlag(J3DShpFlag_SkinNrmCpu);
}
mpShape->setCurrentViewNoPtr(mpMtxBuffer->getCurrentViewNoPtr());
mpShape->setScaleFlagArray(mpMtxBuffer->getScaleFlagArray());
mpShape->setDrawMtx(mpMtxBuffer->getDrawMtxPtrPtr());
if (!mpShape->getNBTFlag()) {
mpShape->setNrmMtx(mpMtxBuffer->getNrmMtxPtrPtr());
} else {
mpShape->setNrmMtx(mpMtxBuffer->mpBumpMtxArr[1][mpShape->getBumpMtxOffset()]);
}
mpModel->getModelData()->syncJ3DSysFlags();
}
void J3DShapePacket::draw() {
if (!checkFlag(J3DShpFlag_Hidden) && mpShape != NULL) {
prepareDraw();
if (mpTexMtxObj != NULL) {
J3DDifferedTexMtx::sTexGenBlock = mpShape->getMaterial()->getTexGenBlock();
J3DDifferedTexMtx::sTexMtxObj = getTexMtxObj();
} else {
J3DDifferedTexMtx::sTexGenBlock = NULL;
}
if (mpDisplayListObj != NULL) {
mpDisplayListObj->callDL();
}
mpShape->draw();
}
}
void J3DShapePacket::drawFast() {
if (!checkFlag(J3DShpFlag_Hidden) && mpShape != NULL) {
prepareDraw();
if (mpTexMtxObj != NULL) {
J3DDifferedTexMtx::sTexGenBlock = mpShape->getMaterial()->getTexGenBlock();
J3DDifferedTexMtx::sTexMtxObj = getTexMtxObj();
} else {
J3DDifferedTexMtx::sTexGenBlock = NULL;
}
mpShape->drawFast();
}
}
void J3DPacket::draw() {}
int J3DMatPacket::entry(J3DDrawBuffer* pBuffer) {
J3DDrawBuffer::sortFunc func = J3DDrawBuffer::sortFuncTable[pBuffer->getSortMode()];
return (pBuffer->*func)(this);
}
+342
View File
@@ -0,0 +1,342 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/J3DGraphBase/J3DShape.h"
#include <dolphin/gd.h>
#include "JSystem/J3DGraphBase/J3DFifo.h"
#include "JSystem/J3DGraphBase/J3DPacket.h"
#include "JSystem/J3DGraphBase/J3DVertex.h"
#include "JSystem/J3DGraphBase/J3DFifo.h"
#include <gd.h>
#include "JSystem/JKernel/JKRHeap.h"
void J3DGDSetVtxAttrFmtv(GXVtxFmt, GXVtxAttrFmtList const*, bool);
void J3DFifoLoadPosMtxImm(Mtx, u32);
void J3DFifoLoadNrmMtxImm(Mtx, u32);
void J3DShape::initialize() {
mMaterial = NULL;
mIndex = -1;
mMtxGroupNum = 0;
mFlags = 0;
mRadius = 0.0f;
mMin.x = 0.0f;
mMin.y = 0.0f;
mMin.z = 0.0f;
mMax.x = 0.0f;
mMax.y = 0.0f;
mMax.z = 0.0f;
mVtxDesc = NULL;
mShapeMtx = NULL;
mShapeDraw = NULL;
mVertexData = NULL;
mDrawMtxData = NULL;
mScaleFlagArray = NULL;
mDrawMtx = NULL;
mNrmMtx = NULL;
mCurrentViewNo = &j3dDefaultViewNo;
mHasNBT = false;
mHasPNMTXIdx = false;
}
void J3DShape::addTexMtxIndexInDL(GXAttr attr, u32 valueBase) {
u32 kSize[] = {0, 1, 1, 2};
s32 pnmtxidxOffs = -1;
s32 attrOffs = -1;
s32 stride = 0;
bool found = false;
for (GXVtxDescList* vtxDesc = getVtxDesc(); vtxDesc->attr != GX_VA_NULL; vtxDesc++) {
if (vtxDesc->attr == GX_VA_PNMTXIDX)
pnmtxidxOffs = stride;
if (attr < vtxDesc->attr && !found) {
attrOffs = stride;
found = true;
}
stride = stride + kSize[vtxDesc->type];
}
if (pnmtxidxOffs == -1)
return;
for (u16 i = 0; i < (u16)getMtxGroupNum(); i++)
getShapeDraw(i)->addTexMtxIndexInDL(stride, attrOffs, (s32)valueBase);
}
void J3DShape::addTexMtxIndexInVcd(GXAttr attr) {
u32 kSize[] = {0, 1, 1, 2}; // stripped data
s32 attrIdx = -1;
s32 attrOffs = -1;
s32 stride = 0;
GXVtxDescList* vtxDesc = getVtxDesc();
s32 attrCount = 0;
for (; vtxDesc->attr != GX_VA_NULL; vtxDesc++) {
if (vtxDesc->attr == GX_VA_PNMTXIDX) {
attrIdx = stride;
}
attrCount++;
}
if (attrIdx == -1)
return;
GXVtxDescList* newVtxDesc = JKR_NEW GXVtxDescList[attrCount + 2];
bool inserted = false;
vtxDesc = getVtxDesc();
GXVtxDescList* dst = newVtxDesc;
for (; vtxDesc->attr != GX_VA_NULL; vtxDesc++) {
if ((attr < vtxDesc->attr) && !inserted) {
dst->attr = attr;
dst->type = GX_DIRECT;
attrOffs = stride;
dst++;
inserted = true;
}
dst->attr = vtxDesc->attr;
dst->type = vtxDesc->type;
stride = stride + kSize[vtxDesc->type];
dst++;
}
dst->attr = GX_VA_NULL;
dst->type = GX_NONE;
mVtxDesc = newVtxDesc;
makeVcdVatCmd();
}
void J3DShape::calcNBTScale(const Vec& param_0, f32 (*param_1)[3][3], f32 (*param_2)[3][3]) {
for (u16 i = 0; i < mMtxGroupNum; i++)
mShapeMtx[i]->calcNBTScale(param_0, param_1, param_2);
}
u16 J3DShape::countBumpMtxNum() const {
u16 num = 0;
for (u16 i = 0; i < mMtxGroupNum; i++)
num += mShapeMtx[i]->getUseMtxNum();
return num;
}
void J3DLoadCPCmd(u8 addr, u32 val) {
GXCmd1u8(GX_LOAD_CP_REG);
GXCmd1u8(addr);
GXCmd1u32(val);
}
static void J3DLoadArrayBasePtr(GXAttr attr, void* data) {
u32 idx = (attr == GX_VA_NBT) ? 1 : (attr - GX_VA_POS);
J3DLoadCPCmd(0xA0 + idx, ((uintptr_t)data & 0x7FFFFFFF));
}
void J3DShape::loadVtxArray() const {
J3DLoadArrayBasePtr(GX_VA_POS, j3dSys.getVtxPos());
if (!mHasNBT) {
J3DLoadArrayBasePtr(GX_VA_NRM, j3dSys.getVtxNrm());
}
J3DLoadArrayBasePtr(GX_VA_CLR0, j3dSys.getVtxCol());
}
bool J3DShape::isSameVcdVatCmd(J3DShape* other) {
u8* a = (u8*)other->getVcdVatCmd();
u8* b = mVcdVatCmd;
for (u32 i = 0; i < kVcdVatDLSize; i++)
if (a[i] != b[i])
return false;
return true;
}
void J3DShape::makeVtxArrayCmd() {
GXVtxAttrFmtList* vtxAttr = mVertexData->getVtxAttrFmtList();
u8 stride[12];
void* array[12];
for (u32 i = 0; i < 12; i++) {
stride[i] = 0;
array[i] = 0;
}
for (; vtxAttr->attr != GX_VA_NULL; vtxAttr++) {
switch (vtxAttr->attr) {
case GX_VA_POS: {
if (vtxAttr->type == GX_F32)
stride[vtxAttr->attr - GX_VA_POS] = 12;
else
stride[vtxAttr->attr - GX_VA_POS] = 6;
array[vtxAttr->attr - GX_VA_POS] = mVertexData->getVtxPosArray();
mVertexData->setVtxPosFrac((u8)vtxAttr->frac);
mVertexData->setVtxPosType((GXCompType)vtxAttr->type);
} break;
case GX_VA_NRM: {
if (vtxAttr->type == GX_F32)
stride[vtxAttr->attr - GX_VA_POS] = 12;
else
stride[vtxAttr->attr - GX_VA_POS] = 6;
array[vtxAttr->attr - GX_VA_POS] = mVertexData->getVtxNrmArray();
mVertexData->setVtxNrmFrac((u8)vtxAttr->frac);
mVertexData->setVtxNrmType((GXCompType)vtxAttr->type);
} break;
case GX_VA_CLR0:
case GX_VA_CLR1: {
stride[vtxAttr->attr - GX_VA_POS] = 4;
array[vtxAttr->attr - GX_VA_POS] = mVertexData->getVtxColorArray(vtxAttr->attr - GX_VA_CLR0);
} break;
case GX_VA_TEX0:
case GX_VA_TEX1:
case GX_VA_TEX2:
case GX_VA_TEX3:
case GX_VA_TEX4:
case GX_VA_TEX5:
case GX_VA_TEX6:
case GX_VA_TEX7: {
if (vtxAttr->type == GX_F32)
stride[vtxAttr->attr - GX_VA_POS] = 8;
else
stride[vtxAttr->attr - GX_VA_POS] = 4;
array[vtxAttr->attr - GX_VA_POS] = mVertexData->getVtxTexCoordArray(vtxAttr->attr - GX_VA_TEX0);
} break;
default:
break;
}
}
GXVtxDescList* vtxDesc = mVtxDesc;
mHasPNMTXIdx = false;
for (; vtxDesc->attr != GX_VA_NULL; vtxDesc++) {
if (vtxDesc->attr == GX_VA_NBT && vtxDesc->type != GX_NONE) {
mHasNBT = true;
stride[GX_VA_NRM - GX_VA_POS] *= 3;
array[GX_VA_NRM - GX_VA_POS] = mVertexData->getVtxNBTArray();
} else if (vtxDesc->attr == GX_VA_PNMTXIDX && vtxDesc->type != GX_NONE) {
mHasPNMTXIdx = true;
}
}
for (u32 i = 0; i < 12; i++) {
if (array[i] != 0)
GDSetArray((GXAttr)(i + GX_VA_POS), array[i], stride[i]);
else
GDSetArrayRaw((GXAttr)(i + GX_VA_POS), 0, stride[i]);
}
}
void J3DShape::makeVcdVatCmd() {
static BOOL sInterruptFlag = OSDisableInterrupts();
OSDisableScheduler();
GDLObj gdl_obj;
GDInitGDLObj(&gdl_obj, mVcdVatCmd, kVcdVatDLSize);
GDSetCurrent(&gdl_obj);
GDSetVtxDescv(mVtxDesc);
makeVtxArrayCmd();
J3DGDSetVtxAttrFmtv(GX_VTXFMT0, mVertexData->getVtxAttrFmtList(), mHasNBT);
GDPadCurr32();
GDFlushCurrToMem();
GDSetCurrent(NULL);
OSEnableScheduler();
OSRestoreInterrupts(sInterruptFlag);
}
void* J3DShape::sOldVcdVatCmd;
void J3DShape::loadCurrentMtx() const {
mCurrentMtx.load();
}
void J3DShape::loadPreDrawSetting() const {
if (sOldVcdVatCmd != mVcdVatCmd) {
GXCallDisplayList(mVcdVatCmd, kVcdVatDLSize);
sOldVcdVatCmd = mVcdVatCmd;
}
mCurrentMtx.load();
}
bool J3DShape::sEnvelopeFlag;
void J3DShape::setArrayAndBindPipeline() const {
J3DShapeMtx::setCurrentPipeline((mFlags & 0x1C) >> 2);
loadVtxArray();
j3dSys.setModelDrawMtx(mDrawMtx[*mCurrentViewNo]);
j3dSys.setModelNrmMtx(mNrmMtx[*mCurrentViewNo]);
J3DShapeMtx::sCurrentScaleFlag = mScaleFlagArray;
J3DShapeMtx::sNBTFlag = mHasNBT;
sEnvelopeFlag = mHasPNMTXIdx;
J3DShapeMtx::sTexMtxLoadType = getTexMtxLoadType();
}
void J3DShape::drawFast() const {
if (sOldVcdVatCmd != mVcdVatCmd) {
GXCallDisplayList(mVcdVatCmd, kVcdVatDLSize);
sOldVcdVatCmd = mVcdVatCmd;
}
if (sEnvelopeFlag != 0 && !mHasPNMTXIdx)
mCurrentMtx.load();
setArrayAndBindPipeline();
if (!checkFlag(J3DShpFlag_NoMtx)) {
if (J3DShapeMtx::getLODFlag())
J3DShapeMtx::resetMtxLoadCache();
for (u16 n = mMtxGroupNum, i = 0; i < n; i++) {
if (mShapeMtx[i] != NULL)
mShapeMtx[i]->load();
if (mShapeDraw[i] != NULL)
mShapeDraw[i]->draw();
}
} else {
J3DFifoLoadPosMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), GX_PNMTX0);
J3DFifoLoadNrmMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), GX_PNMTX0);
for (u16 n = mMtxGroupNum, i = 0; i < n; i++)
if (mShapeDraw[i] != NULL)
mShapeDraw[i]->draw();
}
}
void J3DShape::draw() const {
resetVcdVatCache();
loadPreDrawSetting();
drawFast();
}
void J3DShape::simpleDraw() const {
resetVcdVatCache();
loadPreDrawSetting();
J3DShapeMtx::setCurrentPipeline((mFlags & 0x1C) >> 2);
loadVtxArray();
for (u16 n = mMtxGroupNum, i = 0; i < n; i++) {
if (mShapeDraw[i] != NULL) {
mShapeDraw[i]->draw();
}
}
}
void J3DShape::simpleDrawCache() const {
if (sOldVcdVatCmd != mVcdVatCmd) {
GXCallDisplayList(mVcdVatCmd, kVcdVatDLSize);
sOldVcdVatCmd = mVcdVatCmd;
}
if (sEnvelopeFlag && !mHasPNMTXIdx)
mCurrentMtx.load();
loadVtxArray();
for (u16 n = mMtxGroupNum, i = 0; i < n; i++)
if (mShapeDraw[i] != NULL)
mShapeDraw[i]->draw();
}
@@ -0,0 +1,82 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/J3DGraphBase/J3DShapeDraw.h"
#include "JSystem/JKernel/JKRHeap.h"
#include <cstring>
#include <stdint.h>
#include <gx.h>
u32 J3DShapeDraw::countVertex(u32 stride) {
u32 count = 0;
u8* dlStart = (u8*)getDisplayList();
for (u8* dl = dlStart; (dl - dlStart) < getDisplayListSize();) {
u8 cmd = *(u8*)dl;
dl++;
if (cmd != GX_TRIANGLEFAN && cmd != GX_TRIANGLESTRIP)
break;
int vtxNum = be16(*((u16*)(dl)));
dl += 2;
count += vtxNum;
dl = (u8*)dl + stride * vtxNum;
}
return count;
}
void J3DShapeDraw::addTexMtxIndexInDL(u32 stride, u32 attrOffs, u32 valueBase) {
u32 byteNum = countVertex(stride);
u32 oldSize = mDisplayListSize;
u32 newSize = ALIGN_NEXT(oldSize + byteNum, 0x20);
u8* newDLStart = JKR_NEW_ARGS (0x20) u8[newSize];
u8* oldDLStart = (u8*)mDisplayList;
u8* oldDL = oldDLStart;
u8* newDL = newDLStart;
for (; (oldDL - oldDLStart) < mDisplayListSize;) {
// Copy command
u8 cmd = *(u8*)oldDL;
oldDL++;
*newDL++ = cmd;
if (cmd != GX_TRIANGLEFAN && cmd != GX_TRIANGLESTRIP)
break;
// Copy count
int vtxNum = *(u16*)oldDL;
oldDL += 2;
*(u16*)newDL = vtxNum;
newDL += 2;
for (int i = 0; i < be16(vtxNum); i++) {
u8* oldDLVtx = &oldDL[stride * i];
u8 pnmtxidx = *oldDLVtx;
memcpy(newDL, oldDLVtx, (int)attrOffs);
newDL += attrOffs;
*newDL++ = valueBase + pnmtxidx;
memcpy(newDL, oldDLVtx + attrOffs, stride - attrOffs);
newDL += (stride - attrOffs);
}
oldDL = (u8*)oldDL + stride * vtxNum;
}
u32 realSize = ALIGN_NEXT((uintptr_t)newDL - (uintptr_t)newDLStart, 0x20);
for (; (newDL - newDLStart) < newSize; newDL++)
*newDL = 0;
mDisplayListSize = realSize;
mDisplayList = newDLStart;
DCStoreRange(newDLStart, mDisplayListSize);
}
J3DShapeDraw::J3DShapeDraw(const u8* displayList, u32 displayListSize) {
mDisplayList = (void*)displayList;
mDisplayListSize = displayListSize;
}
void J3DShapeDraw::draw() const {
GXCallDisplayList(mDisplayList, mDisplayListSize);
}
J3DShapeDraw::~J3DShapeDraw() {}
@@ -0,0 +1,552 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/J3DGraphBase/J3DShapeMtx.h"
#include "JSystem/J3DGraphAnimator/J3DModel.h"
#include "JSystem/J3DGraphBase/J3DFifo.h"
#include "JSystem/J3DGraphBase/J3DMatBlock.h"
#include "JSystem/J3DGraphBase/J3DSys.h"
#include "JSystem/J3DGraphBase/J3DTexture.h"
u16 J3DShapeMtx::sMtxLoadCache[10];
void J3DShapeMtx::resetMtxLoadCache() {
sMtxLoadCache[0] =
sMtxLoadCache[1] =
sMtxLoadCache[2] =
sMtxLoadCache[3] =
sMtxLoadCache[4] =
sMtxLoadCache[5] =
sMtxLoadCache[6] =
sMtxLoadCache[7] =
sMtxLoadCache[8] =
sMtxLoadCache[9] = 0xFFFF;
}
void J3DShapeMtx::loadMtxIndx_PNGP(int slot, u16 indx) const {
// J3DFifoLoadPosMtxIndx(indx, slot * 3); // matches debug, but not retail
J3DFifoLoadIndx(GX_LOAD_INDX_A, indx, 0xB000 | ((u16)(slot * 0x0C)));
J3DFifoLoadNrmMtxIndx3x3(indx, slot * 3);
}
void J3DShapeMtx::loadMtxIndx_PCPU(int slot, u16 indx) const {
J3DFifoLoadPosMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), slot * 3);
j3dSys.loadNrmMtxIndx(slot, indx);
}
void J3DShapeMtx::loadMtxIndx_NCPU(int slot, u16 indx) const {
j3dSys.loadPosMtxIndx(slot, indx);
J3DFifoLoadNrmMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), slot * 3);
}
void J3DShapeMtx::loadMtxIndx_PNCPU(int slot, u16 indx) const {
J3DFifoLoadPosMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), slot * 3);
J3DFifoLoadNrmMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), slot * 3);
}
J3DShapeMtx_LoadFunc J3DShapeMtx::sMtxLoadPipeline[4] = {
&J3DShapeMtx::loadMtxIndx_PNGP,
&J3DShapeMtx::loadMtxIndx_PCPU,
&J3DShapeMtx::loadMtxIndx_NCPU,
&J3DShapeMtx::loadMtxIndx_PNCPU,
};
J3DShapeMtxConcatView_LoadFunc J3DShapeMtxConcatView::sMtxLoadPipeline[4] = {
&J3DShapeMtxConcatView::loadMtxConcatView_PNGP,
&J3DShapeMtxConcatView::loadMtxConcatView_PCPU,
&J3DShapeMtxConcatView::loadMtxConcatView_NCPU,
&J3DShapeMtxConcatView::loadMtxConcatView_PNCPU,
};
J3DShapeMtxConcatView_LoadFunc J3DShapeMtxConcatView::sMtxLoadLODPipeline[4] = {
&J3DShapeMtxConcatView::loadMtxConcatView_PNGP_LOD,
&J3DShapeMtxConcatView::loadMtxConcatView_PCPU,
&J3DShapeMtxConcatView::loadMtxConcatView_NCPU,
&J3DShapeMtxConcatView::loadMtxConcatView_PNCPU,
};
u32 J3DShapeMtx::sCurrentPipeline;
u8* J3DShapeMtx::sCurrentScaleFlag;
bool J3DShapeMtx::sNBTFlag;
bool J3DShapeMtx::sLODFlag;
u32 J3DShapeMtx::sTexMtxLoadType;
MtxP J3DShapeMtxConcatView::sMtxPtrTbl[2];
J3DTexGenBlock* J3DDifferedTexMtx::sTexGenBlock;
J3DTexMtxObj* J3DDifferedTexMtx::sTexMtxObj;
void J3DDifferedTexMtx::loadExecute(f32 const (*param_0)[4]) {
static Mtx qMtx = {
{0.5f, 0.0f, 0.5f, 0.0f},
{0.0f, -0.5f, 0.5f, 0.0f},
{0.0f, 0.0f, 1.0f, 0.0f},
};
static Mtx qMtx2 = {
{0.5f, 0.0f, 0.0f, 0.5f},
{0.0f, -0.5f, 0.0f, 0.5f},
{0.0f, 0.0f, 1.0f, 0.0f}
};
Mtx* mtx; // sp_64
Mtx sp_e8;
Mtx44 sp_a8, sp_68;
J3DTexGenBlock* tex_gen_block = sTexGenBlock; // sp_60
J3D_ASSERT_NULLPTR(195, tex_gen_block != NULL);
J3DTexMtxObj* tex_mtx_obj = sTexMtxObj; // sp_5c
J3D_ASSERT_NULLPTR(198, tex_mtx_obj != NULL);
J3DTexMtxInfo* tex_mtx_info_1; // sp_58
int tex_gen_type; // sp_54
J3DTexMtx* tex_mtx_2; // sp_50
u16 tex_mtx_num = tex_mtx_obj->getNumTexMtx();
if (j3dSys.checkFlag(J3DSysFlag_PostTexMtx)) {
for (u16 i = 0; i < tex_mtx_num; i++) {
tex_gen_type = tex_gen_block->getTexCoord(i)->getTexGenType();
if (tex_gen_type == 1 || tex_gen_type == 0) {
tex_mtx_2 = tex_gen_block->getTexMtx(i);
J3D_ASSERT_NULLPTR(215, tex_mtx_2 != NULL);
tex_mtx_info_1 = &tex_mtx_2->getTexMtxInfo();
u32 sp_4c = tex_mtx_info_1->mInfo & 0x3f;
switch (sp_4c) {
case 3:
case 9: {
mtx = &tex_mtx_obj->getMtx(i);
break;
}
case 1:
case 6:
case 7: {
mtx = &tex_mtx_obj->getMtx(i);
break;
}
case 2:
case 8: {
MTXInverse(j3dSys.getViewMtx(), sp_e8);
MTXConcat(tex_mtx_obj->getMtx(i), sp_e8, sp_e8);
mtx = &sp_e8;
break;
}
case 5: {
J3DTexMtxInfo* tex_mtx_info_2 = &tex_mtx_2->getTexMtxInfo(); // sp_48
u32 sp_44 = (u32)(tex_mtx_info_2->mInfo & 0x80) >> 7;
if (sp_44 == 0) {
J3DGetTextureMtxOld(tex_mtx_info_2->mSRT, tex_mtx_info_2->mCenter, sp_68);
} else if (sp_44 == 1) {
J3DGetTextureMtxMayaOld(tex_mtx_info_2->mSRT, sp_68);
}
J3DMtxProjConcat(sp_68, tex_mtx_obj->getEffectMtx(i), sp_e8);
MTXInverse(j3dSys.getViewMtx(), sp_a8);
MTXConcat(sp_e8, sp_a8, sp_e8);
sp_e8[0][3] = sp_e8[1][3] = sp_e8[2][3] = 0.0f;
mtx = &sp_e8;
break;
}
case 11: {
J3DTexMtxInfo* tex_mtx_info_2 = &tex_mtx_2->getTexMtxInfo(); // sp_40
u32 sp_3c = (u32)(tex_mtx_info_2->mInfo & 0x80) >> 7;
if (sp_3c == 0) {
J3DGetTextureMtx(tex_mtx_info_2->mSRT, tex_mtx_info_2->mCenter, sp_68);
} else if (sp_3c == 1) {
J3DGetTextureMtxMaya(tex_mtx_info_2->mSRT, sp_68);
}
MTXConcat(sp_68, qMtx, sp_68);
J3DMtxProjConcat(sp_68, tex_mtx_obj->getEffectMtx(i), sp_e8);
MTXInverse(j3dSys.getViewMtx(), sp_a8);
MTXConcat(sp_e8, sp_a8, sp_e8);
sp_e8[0][3] = sp_e8[1][3] = sp_e8[2][3] = 0.0f;
mtx = &sp_e8;
break;
}
case 10: {
J3DTexMtxInfo* tex_mtx_info_2 = &tex_mtx_2->getTexMtxInfo(); // sp_38
u32 sp_34 = (u32)(tex_mtx_info_2->mInfo & 0x80) >> 7;
if (sp_34 == 0) {
J3DGetTextureMtx(tex_mtx_info_2->mSRT, tex_mtx_info_2->mCenter, sp_68);
} else if (sp_34 == 1) {
J3DGetTextureMtxMaya(tex_mtx_info_2->mSRT, sp_68);
}
MTXConcat(sp_68, qMtx2, sp_68);
J3DMtxProjConcat(sp_68, tex_mtx_obj->getEffectMtx(i), sp_e8);
MTXInverse(j3dSys.getViewMtx(), sp_a8);
MTXConcat(sp_e8, sp_a8, sp_e8);
sp_e8[0][3] = sp_e8[1][3] = sp_e8[2][3] = 0.0f;
mtx = &sp_e8;
break;
}
case 0:
case 4:
default: {
mtx = &tex_mtx_obj->getMtx(i);
}
}
GXLoadTexMtxImm(*mtx, i * 3 + GX_PTTEXMTX0, GX_MTX3x4);
}
}
} else {
for (u16 i = 0; i < tex_mtx_num; i++) {
int tex_gen_type = tex_gen_block->getTexCoord(i)->getTexGenType();
if (tex_gen_type == 1 || tex_gen_type == 0) {
J3DTexMtx* tex_mtx = tex_gen_block->getTexMtx(i); // sp_2c
J3D_ASSERT_NULLPTR(325, tex_mtx != NULL);
tex_mtx_info_1 = &tex_mtx->getTexMtxInfo();
u32 tex_gen_src = tex_mtx_info_1->mInfo & 0x3f; // sp_28
switch (tex_gen_src) {
case 3:
case 9:
MTXConcat(tex_mtx_obj->getMtx(i), param_0, sp_e8);
mtx = &sp_e8;
break;
case 1:
case 6:
case 7:
MTXCopy(param_0, sp_a8);
sp_a8[0][3] = sp_a8[1][3] = sp_a8[2][3] = 0.0f;
MTXConcat(tex_mtx_obj->getMtx(i), sp_a8, sp_e8);
mtx = &sp_e8;
break;
case 2:
case 8:
mtx = &tex_mtx_obj->getMtx(i);
break;
case 5: {
J3DTexMtxInfo* tex_mtx_info_2 = &tex_mtx->getTexMtxInfo(); // sp_24
u32 sp_24 = (u32)(tex_mtx_info_2->mInfo & 0x80) >> 7;
if (sp_24 == 0) {
J3DGetTextureMtxOld(tex_mtx_info_2->mSRT, tex_mtx_info_2->mCenter, sp_68);
} else if (sp_24 == 1) {
J3DGetTextureMtxMayaOld(tex_mtx_info_2->mSRT, sp_68);
}
J3DMtxProjConcat(sp_68, tex_mtx_obj->getEffectMtx(i), sp_e8);
MTXInverse(j3dSys.getViewMtx(), sp_a8);
MTXConcat(sp_e8, sp_a8, sp_e8);
MTXConcat(sp_e8, param_0, sp_e8);
sp_e8[0][3] = sp_e8[1][3] = sp_e8[2][3] = 0.0f;
mtx = &sp_e8;
break;
}
case 11: {
J3DTexMtxInfo* tex_mtx_info_2 = &tex_mtx->getTexMtxInfo(); // sp_1c
u32 sp_18 = (u32)(tex_mtx_info_2->mInfo & 0x80) >> 7;
if (sp_18 == 0) {
J3DGetTextureMtx(tex_mtx_info_2->mSRT, tex_mtx_info_2->mCenter, sp_68);
} else if (sp_18 == 1) {
J3DGetTextureMtxMaya(tex_mtx_info_2->mSRT, sp_68);
}
MTXConcat(sp_68, qMtx, sp_68);
J3DMtxProjConcat(sp_68, tex_mtx_obj->getEffectMtx(i), sp_e8);
MTXInverse(j3dSys.getViewMtx(), sp_a8);
MTXConcat(sp_e8, sp_a8, sp_e8);
MTXConcat(sp_e8, param_0, sp_e8);
sp_e8[0][3] = sp_e8[1][3] = sp_e8[2][3] = 0.0f;
mtx = &sp_e8;
break;
}
case 10: {
J3DTexMtxInfo* tex_mtx_info_2 = &tex_mtx->getTexMtxInfo(); // sp_14
u32 sp_10 = (u32)(tex_mtx_info_2->mInfo & 0x80) >> 7;
if (sp_10 == 0) {
J3DGetTextureMtx(tex_mtx_info_2->mSRT, tex_mtx_info_2->mCenter, sp_68);
} else if (sp_10 == 1) {
J3DGetTextureMtxMaya(tex_mtx_info_2->mSRT, sp_68);
}
MTXConcat(sp_68, qMtx2, sp_68);
J3DMtxProjConcat(sp_68, tex_mtx_obj->getEffectMtx(i), sp_e8);
MTXInverse(j3dSys.getViewMtx(), sp_a8);
MTXConcat(sp_e8, sp_a8, sp_e8);
MTXConcat(sp_e8, param_0, sp_e8);
sp_e8[0][3] = sp_e8[1][3] = sp_e8[2][3] = 0.0f;
mtx = &sp_e8;
break;
}
case 0:
case 4:
default: {
mtx = &tex_mtx_obj->getMtx(i);
break;
}
}
GXLoadTexMtxImm(*mtx, i * 3 + GX_TEXMTX0, (GXTexMtxType)tex_mtx_info_1->mProjection);
}
}
}
}
void J3DShapeMtxConcatView::loadMtxConcatView_PNGP(int slot, u16 drw) const {
Mtx m;
MTXConcat(*j3dSys.getShapePacket()->getBaseMtxPtr(), j3dSys.getModelDrawMtx(drw), m);
J3DDifferedTexMtx::load(m);
J3DFifoLoadPosMtxImm(m, slot * 3);
loadNrmMtx(slot, drw, m);
}
void J3DShapeMtxConcatView::loadMtxConcatView_PCPU(int slot, u16 drw) const {
Mtx m;
MTXConcat(*j3dSys.getShapePacket()->getBaseMtxPtr(), j3dSys.getModelDrawMtx(drw), m);
J3DDifferedTexMtx::load(m);
J3DFifoLoadPosMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), slot * 3);
loadNrmMtx(slot, drw, m);
}
void J3DShapeMtxConcatView::loadMtxConcatView_NCPU(int slot, u16 drw) const {
Mtx m;
MTXConcat(*j3dSys.getShapePacket()->getBaseMtxPtr(), j3dSys.getModelDrawMtx(drw), m);
J3DDifferedTexMtx::load(m);
J3DFifoLoadPosMtxImm(m, slot * 3);
J3DFifoLoadNrmMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), slot * 3);
if (J3DShapeMtx::sTexMtxLoadType == 0x2000)
J3DFifoLoadNrmMtxToTexMtx(*j3dSys.getShapePacket()->getBaseMtxPtr(), slot * 3 + GX_TEXMTX0);
}
void J3DShapeMtxConcatView::loadMtxConcatView_PNCPU(int slot, u16 drw) const {
if (J3DDifferedTexMtx::sTexGenBlock != NULL) {
Mtx m;
MTXConcat(*j3dSys.getShapePacket()->getBaseMtxPtr(), j3dSys.getModelDrawMtx(drw), m);
J3DDifferedTexMtx::loadExecute(m);
}
J3DFifoLoadPosMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), slot * 3);
J3DFifoLoadNrmMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), slot * 3);
if (J3DShapeMtx::sTexMtxLoadType == 0x2000)
J3DFifoLoadNrmMtxToTexMtx(*j3dSys.getShapePacket()->getBaseMtxPtr(), slot * 3 + GX_TEXMTX0);
}
void J3DShapeMtxConcatView::loadMtxConcatView_PNGP_LOD(int slot, u16 drw) const {
Mtx m;
MTXConcat(*j3dSys.getShapePacket()->getBaseMtxPtr(), j3dSys.getModelDrawMtx(drw), m);
MTXConcat(m, j3dSys.getModel()->getModelData()->getInvJointMtx(drw), m);
J3DDifferedTexMtx::load(m);
J3DFifoLoadPosMtxImm(m, slot * 3);
loadNrmMtx(slot, drw, m);
}
void J3DShapeMtx::load() const {
J3DShapeMtx_LoadFunc func = sMtxLoadPipeline[sCurrentPipeline];
(this->*func)(0, mUseMtxIndex);
}
void J3DShapeMtx::calcNBTScale(Vec const& param_0, Mtx33* param_1, Mtx33* param_2) {
J3DPSMtx33Copy(param_1[mUseMtxIndex], param_2[mUseMtxIndex]);
J3DScaleNrmMtx33(param_2[mUseMtxIndex], param_0);
}
void J3DShapeMtxConcatView::load() const {
sMtxPtrTbl[0] = j3dSys.getModel()->getMtxBuffer()->getUserAnmMtx(0);
sMtxPtrTbl[1] = j3dSys.getModel()->getWeightAnmMtx(0);
J3DShapeMtxConcatView_LoadFunc func = sMtxLoadPipeline[sCurrentPipeline];
j3dSys.setModelDrawMtx((Mtx*)sMtxPtrTbl[j3dSys.getModel()->getModelData()->getDrawMtxFlag(mUseMtxIndex)]);
u16 draw_mtx_index = j3dSys.getModel()->getModelData()->getDrawMtxIndex(mUseMtxIndex);
(this->*func)(0, draw_mtx_index);
}
void J3DShapeMtxConcatView::loadNrmMtx(int param_0, u16 param_1, MtxP param_2) const {
if (sCurrentScaleFlag[param_1] == 1) {
if (sTexMtxLoadType == 0x2000) {
J3DFifoLoadNrmMtxToTexMtx(param_2, GX_TEXMTX0);
}
if (!sNBTFlag) {
J3DFifoLoadNrmMtxImm(param_2, GX_PNMTX0);
} else {
Mtx33 mtx;
BE(Vec)* scale = j3dSys.getNBTScale();
J3DPSMtx33CopyFrom34(param_2, mtx);
J3DScaleNrmMtx33(mtx, *scale);
J3DFifoLoadNrmMtxImm3x3(mtx, GX_PNMTX0);
}
} else {
Mtx33 mtx;
J3DPSCalcInverseTranspose(param_2, mtx);
if (sTexMtxLoadType == 0x2000) {
J3DFifoLoadNrmMtxToTexMtx3x3(mtx, GX_TEXMTX0);
}
if (!sNBTFlag) {
J3DFifoLoadNrmMtxImm3x3(mtx, GX_PNMTX0);
} else {
BE(Vec)* scale = j3dSys.getNBTScale();
J3DScaleNrmMtx33(mtx, *scale);
J3DFifoLoadNrmMtxImm3x3(mtx, GX_PNMTX0);
}
}
}
void J3DShapeMtxMulti::load() const {
J3DShapeMtx_LoadFunc func = sMtxLoadPipeline[sCurrentPipeline];
int use_mtx_num = mUseMtxNum;
for (int i = 0; i < use_mtx_num; i++) {
if (mUseMtxIndexTable[i] != 0xffff) {
(this->*func)(i, mUseMtxIndexTable[i]);
}
}
}
void J3DShapeMtxMulti::calcNBTScale(Vec const& param_0, Mtx33* param_1, Mtx33* param_2) {
int use_mtx_num = mUseMtxNum;
for (int i = 0; i < use_mtx_num; i++) {
if (mUseMtxIndexTable[i] != 0xffff) {
J3DPSMtx33Copy(param_1[mUseMtxIndexTable[i]], param_2[mUseMtxIndexTable[i]]);
J3DScaleNrmMtx33(param_2[mUseMtxIndexTable[i]], param_0);
}
}
}
void J3DShapeMtxMultiConcatView::load() const {
static u8 mtxCache[20] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
sMtxPtrTbl[0] = j3dSys.getModel()->getMtxBuffer()->getUserAnmMtx(0);
sMtxPtrTbl[1] = j3dSys.getModel()->getWeightAnmMtx(0);
if (!sLODFlag) {
J3DShapeMtxConcatView_LoadFunc func = sMtxLoadPipeline[sCurrentPipeline];
int use_mtx_num = mUseMtxNum;
for (int i = 0; i < use_mtx_num; i++) {
if (mUseMtxIndexTable[i] != 0xffff) {
u16 draw_mtx_index = j3dSys.getModel()->getModelData()->getDrawMtxIndex(mUseMtxIndexTable[i]);
j3dSys.setModelDrawMtx((Mtx*)sMtxPtrTbl[j3dSys.getModel()->getModelData()->getDrawMtxFlag(mUseMtxIndexTable[i])]);
(this->*func)(i, draw_mtx_index);
}
}
} else {
u16* important_mtx_indices = j3dSys.getModel()->getModelData()->getWEvlpImportantMtxIndex();
j3dSys.setModelDrawMtx((Mtx*)sMtxPtrTbl[0]);
int use_mtx_num = mUseMtxNum;
for (int i = 0; i < use_mtx_num; i++) {
J3DShapeMtxConcatView_LoadFunc func = sMtxLoadLODPipeline[sCurrentPipeline];
if (mUseMtxIndexTable[i] != 0xffff) {
u16 important_mtx_index = important_mtx_indices[mUseMtxIndexTable[i]];
if (important_mtx_index != sMtxLoadCache[i]) {
if (j3dSys.getModel()->getModelData()->getDrawMtxFlag(mUseMtxIndexTable[i]) == 0) {
func = sMtxLoadPipeline[sCurrentPipeline];
}
(this->*func)(i, important_mtx_index);
sMtxLoadCache[i] = important_mtx_index;
}
}
}
}
}
void J3DShapeMtxMultiConcatView::loadNrmMtx(int param_0, u16 param_1, MtxP param_2) const {
Mtx33 mtx1, mtx2;
if (sCurrentScaleFlag[param_1] == 1) {
if (sTexMtxLoadType == 0x2000) {
J3DFifoLoadNrmMtxToTexMtx(param_2, param_0 * 3 + GX_TEXMTX0);
}
if (!sNBTFlag) {
J3DFifoLoadNrmMtxImm(param_2, param_0 * 3 + GX_PNMTX0);
} else {
BE(Vec)* nbt_scale = j3dSys.getNBTScale();
J3DPSMtx33CopyFrom34(param_2, mtx1);
J3DScaleNrmMtx33(mtx1, *nbt_scale);
J3DFifoLoadNrmMtxImm3x3(mtx1, GX_PNMTX0);
}
} else {
J3DPSCalcInverseTranspose(param_2, mtx2);
if (sTexMtxLoadType == 0x2000) {
J3DFifoLoadNrmMtxToTexMtx3x3(mtx2, param_0 * 3 + GX_TEXMTX0);
}
if (!sNBTFlag) {
J3DFifoLoadNrmMtxImm3x3(mtx2, param_0 * 3 + GX_PNMTX0);
} else {
BE(Vec)* nbt_scale = j3dSys.getNBTScale();
J3DScaleNrmMtx33(mtx2, *nbt_scale);
J3DFifoLoadNrmMtxImm3x3(mtx2, param_0 * 3 + GX_PNMTX0);
}
}
}
void J3DShapeMtxBBoardConcatView::load() const {
Mtx mtx;
u16 draw_mtx_index = j3dSys.getModel()->getModelData()->getDrawMtxIndex(mUseMtxIndex);
if (j3dSys.getModel()->getModelData()->getDrawMtxFlag(mUseMtxIndex) == 0) {
MTXConcat(j3dSys.getViewMtx(), j3dSys.getModel()->getMtxBuffer()->getUserAnmMtx(draw_mtx_index), mtx);
} else {
MTXConcat(j3dSys.getViewMtx(), j3dSys.getModel()->getWeightAnmMtx(draw_mtx_index), mtx);
}
J3DCalcBBoardMtx(mtx);
J3DFifoLoadPosMtxImm(mtx, GX_PNMTX0);
mtx[0][0] = 1.0f / mtx[0][0];
mtx[1][1] = 1.0f / mtx[1][1];
mtx[2][2] = 1.0f / mtx[2][2];
mtx[0][3] = 0.0f;
mtx[1][3] = 0.0f;
mtx[2][3] = 0.0f;
if (!sNBTFlag) {
J3DFifoLoadNrmMtxImm(mtx, GX_PNMTX0);
} else {
BE(Vec)* nbt_scale = j3dSys.getNBTScale();
J3DScaleNrmMtx(mtx, *nbt_scale);
J3DFifoLoadNrmMtxImm(mtx, GX_PNMTX0);
}
}
void J3DShapeMtxYBBoardConcatView::load() const {
Mtx mtx1;
Mtx33 mtx2;
u16 draw_mtx_index = j3dSys.getModel()->getModelData()->getDrawMtxIndex(mUseMtxIndex);
if (j3dSys.getModel()->getModelData()->getDrawMtxFlag(mUseMtxIndex) == 0) {
MTXConcat(j3dSys.getViewMtx(), j3dSys.getModel()->getMtxBuffer()->getUserAnmMtx(draw_mtx_index), mtx1);
} else {
MTXConcat(j3dSys.getViewMtx(), j3dSys.getModel()->getWeightAnmMtx(draw_mtx_index), mtx1);
}
J3DCalcYBBoardMtx(mtx1);
J3DFifoLoadPosMtxImm(mtx1, GX_PNMTX0);
if (sCurrentScaleFlag[mUseMtxIndex] == 1) {
if (!sNBTFlag) {
J3DFifoLoadNrmMtxImm(mtx1, GX_PNMTX0);
} else {
BE(Vec)* nbt_scale = j3dSys.getNBTScale();
J3DScaleNrmMtx(mtx1, *nbt_scale);
J3DFifoLoadNrmMtxImm(mtx1, GX_PNMTX0);
}
} else {
J3DPSCalcInverseTranspose(mtx1, mtx2);
if (!sNBTFlag) {
J3DFifoLoadNrmMtxImm3x3(mtx2, GX_PNMTX0);
} else {
BE(Vec)* nbt_scale = j3dSys.getNBTScale();
J3DScaleNrmMtx33(mtx2, *nbt_scale);
J3DFifoLoadNrmMtxImm3x3(mtx2, GX_PNMTX0);
}
}
}
static void dummy() {
}
+185
View File
@@ -0,0 +1,185 @@
//
// J3DStruct
//
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/J3DGraphBase/J3DStruct.h"
#include "JSystem/JMath/JMath.h"
bool J3DTextureSRTInfo::operator==(J3DTextureSRTInfo& other) const {
if (mScaleX == other.mScaleX &&
mScaleY == other.mScaleY &&
mRotation == other.mRotation &&
mTranslationX == other.mTranslationX &&
mTranslationY == other.mTranslationY
) {
return true;
}
return false;
}
bool J3DLightInfo::operator==(J3DLightInfo& other) const {
if (mLightPosition.x == other.mLightPosition.x &&
mLightPosition.y == other.mLightPosition.y &&
mLightPosition.z == other.mLightPosition.z &&
mLightDirection.x == other.mLightDirection.x &&
mLightDirection.y == other.mLightDirection.y &&
mLightDirection.z == other.mLightDirection.z &&
mColor.r == other.mColor.r &&
mColor.g == other.mColor.g &&
mColor.b == other.mColor.b &&
mColor.a == other.mColor.a &&
mCosAtten.x == other.mCosAtten.x &&
mCosAtten.y == other.mCosAtten.y &&
mCosAtten.z == other.mCosAtten.z &&
mDistAtten.x == other.mDistAtten.x &&
mDistAtten.y == other.mDistAtten.y &&
mDistAtten.z == other.mDistAtten.z
) {
return true;
}
return false;
}
J3DLightInfo& J3DLightInfo::operator=(J3DLightInfo const& param_0) {
JMath::gekko_ps_copy6(&mLightPosition, &param_0.mLightPosition);
mColor = param_0.mColor;
JMath::gekko_ps_copy6(&mCosAtten, &param_0.mCosAtten);
return *this;
}
bool J3DTexMtxInfo::operator==(J3DTexMtxInfo& other) const {
if (mProjection != other.mProjection ||
mInfo != other.mInfo ||
!(mSRT == other.mSRT)
) {
return false;
}
if (mEffectMtx[0][0] != other.mEffectMtx[0][0] ||
mEffectMtx[0][1] != other.mEffectMtx[0][1] ||
mEffectMtx[0][2] != other.mEffectMtx[0][2] ||
mEffectMtx[0][3] != other.mEffectMtx[0][3] ||
mEffectMtx[1][0] != other.mEffectMtx[1][0] ||
mEffectMtx[1][1] != other.mEffectMtx[1][1] ||
mEffectMtx[1][2] != other.mEffectMtx[1][2] ||
mEffectMtx[1][3] != other.mEffectMtx[1][3] ||
mEffectMtx[2][0] != other.mEffectMtx[2][0] ||
mEffectMtx[2][1] != other.mEffectMtx[2][1] ||
mEffectMtx[2][2] != other.mEffectMtx[2][2] ||
mEffectMtx[2][3] != other.mEffectMtx[2][3] ||
mEffectMtx[3][0] != other.mEffectMtx[3][0] ||
mEffectMtx[3][1] != other.mEffectMtx[3][1] ||
mEffectMtx[3][2] != other.mEffectMtx[3][2] ||
mEffectMtx[3][3] != other.mEffectMtx[3][3]
) {
return false;
}
if (
mCenter.x != other.mCenter.x ||
mCenter.y != other.mCenter.y ||
mCenter.z != other.mCenter.z
) {
return false;
}
return true;
}
J3DTexMtxInfo& J3DTexMtxInfo::operator=(J3DTexMtxInfo const& param_0) {
mProjection = param_0.mProjection;
mInfo = param_0.mInfo;
JMath::gekko_ps_copy3(&mCenter, &param_0.mCenter);
mSRT = param_0.mSRT;
JMath::gekko_ps_copy16(&mEffectMtx, &param_0.mEffectMtx);
return *this;
}
// Helper functions to set float literal order
static f32 dummyLiteralOrder() {
return 1.0f;
}
void J3DTexMtxInfo::setEffectMtx(Mtx param_0) {
#ifdef __MWERKS__
JMath::gekko_ps_copy12(&mEffectMtx, param_0);
register f32 zero = 0.0f;
register f32* mtx = (f32*)mEffectMtx;
asm {
psq_st zero, 0x30(mtx), 0, 0
};
mEffectMtx[3][2] = 0.0f;
mEffectMtx[3][3] = 1.0f;
#else
JMath::gekko_ps_copy12(&mEffectMtx, param_0);
mEffectMtx[3][0] = 0.0f;
mEffectMtx[3][1] = 0.0f;
mEffectMtx[3][2] = 0.0f;
mEffectMtx[3][3] = 1.0f;
#endif
}
J3DIndTexMtxInfo& J3DIndTexMtxInfo::operator=(J3DIndTexMtxInfo const& param_0) {
JMath::gekko_ps_copy6(field_0x0, param_0.field_0x0);
field_0x18 = param_0.field_0x18;
return *this;
}
bool J3DFogInfo::operator==(J3DFogInfo& other) const {
if (mType == other.mType &&
mAdjEnable == other.mAdjEnable &&
mCenter == other.mCenter &&
mStartZ == other.mStartZ &&
mEndZ == other.mEndZ &&
mNearZ == other.mNearZ &&
mFarZ == other.mFarZ &&
mColor.r == other.mColor.r &&
mColor.g == other.mColor.g &&
mColor.b == other.mColor.b &&
mColor.a == other.mColor.a
) {
for (int i = 0; i < 10; i++) {
if (mFogAdjTable.r[i] != other.mFogAdjTable.r[i]) {
return false;
}
}
return true;
}
return false;
}
J3DFogInfo& J3DFogInfo::operator=(const J3DFogInfo& param_0) {
mType = param_0.mType;
mAdjEnable = param_0.mAdjEnable;
mCenter = param_0.mCenter;
mStartZ = param_0.mStartZ;
mEndZ = param_0.mEndZ;
mNearZ = param_0.mNearZ;
mFarZ = param_0.mFarZ;
mColor.r = param_0.mColor.r;
mColor.g = param_0.mColor.g;
mColor.b = param_0.mColor.b;
mColor.a = param_0.mColor.a;
for (int i = 0; i < 10; i++) {
mFogAdjTable.r[i] = param_0.mFogAdjTable.r[i];
}
return *this;
}
bool J3DNBTScaleInfo::operator==(const J3DNBTScaleInfo& other) const {
if (mbHasScale == other.mbHasScale &&
mScale.x == other.mScale.x &&
mScale.y == other.mScale.y &&
mScale.z == other.mScale.z
) {
return true;
}
return false;
}
J3DNBTScaleInfo& J3DNBTScaleInfo::operator=(const J3DNBTScaleInfo& other) {
mbHasScale = other.mbHasScale;
mScale.x = other.mScale.x;
mScale.y = other.mScale.y;
mScale.z = other.mScale.z;
return *this;
}
+354
View File
@@ -0,0 +1,354 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/J3DGraphBase/J3DSys.h"
#include "JSystem/J3DGraphBase/J3DTevs.h"
#include "JSystem/J3DGraphBase/J3DTexture.h"
#include "JSystem/J3DGraphBase/J3DFifo.h"
#include "global.h"
J3DSys j3dSys;
Mtx J3DSys::mCurrentMtx;
Vec J3DSys::mCurrentS;
Vec J3DSys::mParentS;
J3DTexCoordScaleInfo J3DSys::sTexCoordScaleTable[8];
static u8 NullTexData[0x10] ATTRIBUTE_ALIGN(32) = {0};
static Mtx j3dIdentityMtx = {
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
};
static Mtx23 IndMtx = {
0.5f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f,
};
u32 j3dDefaultViewNo;
static GXColor ColorBlack = {0x00, 0x00, 0x00, 0x00};
static GXColor ColorWhite = {0xFF, 0xFF, 0xFF, 0xFF};
J3DSys::J3DSys() {
makeTexCoordTable();
makeTevSwapTable();
makeAlphaCmpTable();
makeZModeTable();
mFlags = 0;
MTXIdentity(mViewMtx);
mDrawMode = 1;
mMaterialMode = 0;
mModel = NULL;
mShape = NULL;
for (int i = 0; i < 2; i++)
mDrawBuffer[i] = NULL;
mTexture = NULL;
mMatPacket = NULL;
mShapePacket = NULL;
mModelDrawMtx = NULL;
mModelNrmMtx = NULL;
mVtxPos = NULL;
mVtxNrm = NULL;
mVtxCol = NULL;
for (int i = 0; i < 8; i++) {
sTexCoordScaleTable[i].field_0x00 = 1;
sTexCoordScaleTable[i].field_0x02 = 1;
sTexCoordScaleTable[i].field_0x04 = 0;
sTexCoordScaleTable[i].field_0x06 = 0;
}
}
void J3DSys::loadPosMtxIndx(int addr, u16 indx) const {
//J3DFifoLoadPosMtxIndx(indx, addr * 3); // matches debug, not retail
J3DFifoLoadIndx(GX_LOAD_INDX_A, indx, 0xB000 | ((u16)(addr * 0x0C)));
}
void J3DSys::loadNrmMtxIndx(int addr, u16 indx) const {
J3DFifoLoadNrmMtxIndx3x3(indx, addr * 3);
}
void J3DSys::setTexCacheRegion(GXTexCacheSize size) {
J3D_ASSERT_RANGE(173, size >= 0 && size < 3);
const u32 kSize[] = {
0x00008000,
0x00020000,
0x00080000,
0x00000000,
};
const u32 kRegionNum[] = {8, 4, 1, 0};
mTexCacheRegionNum = kRegionNum[size];
if (checkFlag(0x80000000)) {
for (u32 i = 0; i < kRegionNum[size]; i++) {
if (i & 1) {
GXInitTexCacheRegion(&mTexCacheRegion[i], GX_FALSE, i * kSize[size] + 0x80000, size,
i * kSize[size], size);
J3DFifoLoadTexCached((GXTexMapID)i, i * kSize[size] + 0x80000, size,
i * kSize[size], size);
} else {
GXInitTexCacheRegion(&mTexCacheRegion[i], GX_FALSE, i * kSize[size], size,
i * kSize[size] + 0x80000, size);
J3DFifoLoadTexCached((GXTexMapID)i, i * kSize[size], size,
i * kSize[size] + 0x80000, size);
}
}
} else {
for (u32 i = 0; i < kRegionNum[size]; i++) {
GXInitTexCacheRegion(&mTexCacheRegion[i], GX_FALSE, i * kSize[size], size,
i * kSize[size] + 0x80000, size);
J3DFifoLoadTexCached((GXTexMapID)i, i * kSize[size], size, i * kSize[size] + 0x80000,
size);
}
}
}
void J3DSys::drawInit() {
GXInvalidateVtxCache();
GXSetCurrentMtx(GX_PNMTX0);
GXSetCullMode(GX_CULL_BACK);
GXSetCoPlanar(GX_FALSE);
GXSetClipMode(GX_CLIP_ENABLE);
GXSetColorUpdate(GX_TRUE);
GXSetDither(GX_TRUE);
GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP);
GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0);
GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
GXSetZCompLoc(GX_TRUE);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR1, GX_CLR_RGBA, GX_RGBA8, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGBA4, 7);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX1, GX_CLR_RGBA, GX_RGBA4, 7);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX2, GX_CLR_RGBA, GX_RGBA4, 7);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX3, GX_CLR_RGBA, GX_RGBA4, 7);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX4, GX_CLR_RGBA, GX_RGBA4, 7);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX5, GX_CLR_RGBA, GX_RGBA4, 7);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX6, GX_CLR_RGBA, GX_RGBA4, 7);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX7, GX_CLR_RGBA, GX_RGBA4, 7);
GXSetNumIndStages(0);
reinitTexture();
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE3, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE4, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE5, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE6, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE7, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE8, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE9, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE10, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE11, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE12, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE13, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE14, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE15, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
for (u32 i = 0; i < 10; i++)
GXLoadTexMtxImm(j3dIdentityMtx, GX_TEXMTX0 + i * 3, GX_MTX3x4);
Mtx23 indTexMtx = {
{0.5f, 0.0f, 0.0f},
{0.0f, 0.5f, 0.0f},
};
u8 i;
for (i = 0; i < 3; i++)
GXSetIndTexMtx((GXIndTexMtxID)(GX_ITM_0 + i), indTexMtx, 1);
GXSetChanMatColor(GX_COLOR0A0, j3dDefaultColInfo);
GXSetChanMatColor(GX_COLOR1A1, j3dDefaultColInfo);
GXSetNumChans(j3dDefaultNumChans);
GXSetNumTexGens(1);
GXSetNumTevStages(1);
GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_REG, GX_SRC_REG, 0, GX_DF_CLAMP, GX_AF_NONE);
GXSetChanCtrl(GX_COLOR1A1, GX_FALSE, GX_SRC_REG, GX_SRC_REG, 0, GX_DF_CLAMP, GX_AF_NONE);
for (i = 0; i < GX_MAX_TEXMAP; i++)
GXSetTexCoordGen((GXTexCoordID)i, (GXTexGenType)j3dDefaultTexCoordInfo[i].mTexGenType,
(GXTexGenSrc)j3dDefaultTexCoordInfo[i].mTexGenSrc,
j3dDefaultTexCoordInfo[i].mTexGenMtx);
for (i = 0; i < GX_MAX_INDTEXSTAGE; i++)
GXSetIndTexCoordScale((GXIndTexStageID)i, GX_ITS_1, GX_ITS_1);
for (i = 0; i < GX_MAX_TEVREG; i++)
GXSetTevKColor((GXTevKColorID)i, j3dDefaultTevKColor);
for (i = 0; i < GX_MAX_TEVREG; i++)
GXSetTevColorS10((GXTevRegID)i, j3dDefaultTevColor);
for (i = 0; i < GX_MAX_TEVSTAGE; i++) {
GXSetTevColorIn((GXTevStageID)i, GX_CC_RASC, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO);
GXSetTevColorOp((GXTevStageID)i, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE,
GX_TEVPREV);
GXSetTevAlphaIn((GXTevStageID)i, GX_CA_RASA, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO);
GXSetTevAlphaOp((GXTevStageID)i, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE,
GX_TEVPREV);
}
for (i = 0; i < GX_MAX_TEVSTAGE; i++)
GXSetTevSwapMode((GXTevStageID)i, GX_TEV_SWAP0, GX_TEV_SWAP0);
GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA);
GXSetTevSwapModeTable(GX_TEV_SWAP1, GX_CH_RED, GX_CH_RED, GX_CH_RED, GX_CH_ALPHA);
GXSetTevSwapModeTable(GX_TEV_SWAP2, GX_CH_GREEN, GX_CH_GREEN, GX_CH_GREEN, GX_CH_ALPHA);
GXSetTevSwapModeTable(GX_TEV_SWAP3, GX_CH_BLUE, GX_CH_BLUE, GX_CH_BLUE, GX_CH_ALPHA);
for (i = 0; i < GX_MAX_TEVSTAGE; i++)
GXSetTevIndirect((GXTevStageID)i, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_OFF,
GX_ITW_OFF, GX_ITW_OFF, GX_FALSE, GX_FALSE, GX_ITBA_OFF);
OSInitFastCast();
setTexCacheRegion(GX_TEXCACHE_32K);
}
void J3DSys::reinitGX() {
reinitGenMode();
reinitLighting();
reinitTransform();
reinitTexture();
reinitTevStages();
reinitIndStages();
reinitPixelProc();
GXFlush();
}
void J3DSys::reinitGenMode() {
GXSetNumChans(0);
GXSetNumTexGens(1);
GXSetNumTevStages(1);
GXSetNumIndStages(0);
GXSetCullMode(GX_CULL_BACK);
GXSetCoPlanar(GX_FALSE);
}
void J3DSys::reinitLighting() {
GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE,
GX_AF_NONE);
GXSetChanCtrl(GX_COLOR1A1, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE,
GX_AF_NONE);
GXSetChanAmbColor(GX_COLOR0A0, ColorBlack);
GXSetChanAmbColor(GX_COLOR1A1, ColorBlack);
GXSetChanMatColor(GX_COLOR0A0, ColorWhite);
GXSetChanMatColor(GX_COLOR1A1, ColorWhite);
}
void J3DSys::reinitTransform() {
GXSetCurrentMtx(GX_PNMTX0);
GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
GXSetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX1, GX_IDENTITY);
GXSetTexCoordGen(GX_TEXCOORD2, GX_TG_MTX2x4, GX_TG_TEX2, GX_IDENTITY);
GXSetTexCoordGen(GX_TEXCOORD3, GX_TG_MTX2x4, GX_TG_TEX3, GX_IDENTITY);
GXSetTexCoordGen(GX_TEXCOORD4, GX_TG_MTX2x4, GX_TG_TEX4, GX_IDENTITY);
GXSetTexCoordGen(GX_TEXCOORD5, GX_TG_MTX2x4, GX_TG_TEX5, GX_IDENTITY);
GXSetTexCoordGen(GX_TEXCOORD6, GX_TG_MTX2x4, GX_TG_TEX6, GX_IDENTITY);
GXSetTexCoordGen(GX_TEXCOORD7, GX_TG_MTX2x4, GX_TG_TEX7, GX_IDENTITY);
}
void J3DSys::reinitTexture() {
GXTexObj texObj;
GXInitTexObj(&texObj, NullTexData, 4, 4, GX_TF_IA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
GXLoadTexObj(&texObj, GX_TEXMAP0);
GXLoadTexObj(&texObj, GX_TEXMAP1);
GXLoadTexObj(&texObj, GX_TEXMAP2);
GXLoadTexObj(&texObj, GX_TEXMAP3);
GXLoadTexObj(&texObj, GX_TEXMAP4);
GXLoadTexObj(&texObj, GX_TEXMAP5);
GXLoadTexObj(&texObj, GX_TEXMAP6);
GXLoadTexObj(&texObj, GX_TEXMAP7);
}
void J3DSys::reinitTevStages() {
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE3, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE4, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE5, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE6, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE7, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE8, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE9, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE10, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE11, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE12, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE13, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE14, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE15, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevColor(GX_TEVREG0, ColorWhite);
GXSetTevColor(GX_TEVREG1, ColorWhite);
GXSetTevColor(GX_TEVREG2, ColorWhite);
GXSetTevKColor(GX_KCOLOR0, ColorWhite);
GXSetTevKColor(GX_KCOLOR1, ColorWhite);
GXSetTevKColor(GX_KCOLOR2, ColorWhite);
GXSetTevKColor(GX_KCOLOR3, ColorWhite);
u32 i;
u32 numStages = GX_MAX_TEVSTAGE;
for (i = 0; i < numStages; i++) {
GXSetTevColorIn((GXTevStageID)i, GX_CC_RASC, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO);
GXSetTevColorOp((GXTevStageID)i, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE,
GX_TEVPREV);
GXSetTevAlphaIn((GXTevStageID)i, GX_CA_RASA, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO);
GXSetTevAlphaOp((GXTevStageID)i, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE,
GX_TEVPREV);
GXSetTevKColorSel((GXTevStageID)i, GX_TEV_KCSEL_1_4);
GXSetTevKAlphaSel((GXTevStageID)i, GX_TEV_KASEL_1);
GXSetTevSwapMode((GXTevStageID)i, GX_TEV_SWAP0, GX_TEV_SWAP0);
}
GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA);
GXSetTevSwapModeTable(GX_TEV_SWAP1, GX_CH_RED, GX_CH_RED, GX_CH_RED, GX_CH_ALPHA);
GXSetTevSwapModeTable(GX_TEV_SWAP2, GX_CH_GREEN, GX_CH_GREEN, GX_CH_GREEN, GX_CH_ALPHA);
GXSetTevSwapModeTable(GX_TEV_SWAP3, GX_CH_BLUE, GX_CH_BLUE, GX_CH_BLUE, GX_CH_ALPHA);
GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0);
}
void J3DSys::reinitIndStages() {
u32 i;
for (i = 0; i < GX_MAX_TEVSTAGE; i++) {
GXSetTevDirect((GXTevStageID)i);
}
GXSetIndTexOrder(GX_INDTEXSTAGE0, GX_TEXCOORD0, GX_TEXMAP0);
GXSetIndTexOrder(GX_INDTEXSTAGE1, GX_TEXCOORD1, GX_TEXMAP1);
GXSetIndTexOrder(GX_INDTEXSTAGE2, GX_TEXCOORD2, GX_TEXMAP2);
GXSetIndTexOrder(GX_INDTEXSTAGE3, GX_TEXCOORD3, GX_TEXMAP3);
GXSetIndTexCoordScale(GX_INDTEXSTAGE0, GX_ITS_1, GX_ITS_1);
GXSetIndTexCoordScale(GX_INDTEXSTAGE1, GX_ITS_1, GX_ITS_1);
GXSetIndTexCoordScale(GX_INDTEXSTAGE2, GX_ITS_1, GX_ITS_1);
GXSetIndTexCoordScale(GX_INDTEXSTAGE3, GX_ITS_1, GX_ITS_1);
GXSetIndTexMtx(GX_ITM_0, IndMtx, 1);
GXSetIndTexMtx(GX_ITM_1, IndMtx, 1);
GXSetIndTexMtx(GX_ITM_2, IndMtx, 1);
}
void J3DSys::reinitPixelProc() {
GXSetBlendMode(GX_BM_NONE, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR);
GXSetColorUpdate(GX_TRUE);
GXSetAlphaUpdate(GX_FALSE);
GXSetDither(GX_TRUE);
GXSetFog(GX_FOG_NONE, 0.0f, 1.0f, 0.1f, 1.0f, ColorBlack);
GXSetFogRangeAdj(GX_FALSE, 0, NULL);
GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
GXSetZCompLoc(GX_TRUE);
}
+538
View File
@@ -0,0 +1,538 @@
//
// J3DTevs
//
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/J3DGraphBase/J3DTevs.h"
#include "JSystem/J3DGraphBase/J3DGD.h"
#include "JSystem/J3DGraphBase/J3DMatBlock.h"
#include "JSystem/J3DGraphBase/J3DSys.h"
#include "JSystem/J3DGraphBase/J3DTransform.h"
#include "global.h"
static void J3DGDLoadTexMtxImm(f32 (*)[4], u32, GXTexMtxType);
static void J3DGDLoadPostTexMtxImm(f32 (*)[4], u32);
void J3DLightObj::load(u32 lightIdx) const {
GDOverflowCheck(0x48);
J3DGDSetLightPos(GXLightID(1 << lightIdx), mInfo.mLightPosition.x, mInfo.mLightPosition.y, mInfo.mLightPosition.z);
J3DGDSetLightAttn(GXLightID(1 << lightIdx), mInfo.mCosAtten.x, mInfo.mCosAtten.y, mInfo.mCosAtten.z, mInfo.mDistAtten.x, mInfo.mDistAtten.y, mInfo.mDistAtten.z);
J3DGDSetLightColor(GXLightID(1 << lightIdx), mInfo.mColor);
J3DGDSetLightDir(GXLightID(1 << lightIdx), mInfo.mLightDirection.x, mInfo.mLightDirection.y, mInfo.mLightDirection.z);
}
void loadTexCoordGens(u32 texGenNum, J3DTexCoord* texCoords) {
u32 var_r28;
GDOverflowCheck(texGenNum * 4 * 2 + 10);
J3DGDWriteXFCmdHdr(GX_XF_REG_TEX0, texGenNum);
for (int i = 0; i < texGenNum; i++) {
J3DGDSetTexCoordGen(
GXTexGenType(texCoords[i].getTexGenType()),
GXTexGenSrc(texCoords[i].getTexGenSrc())
);
}
var_r28 = 61;
J3DGDWriteXFCmdHdr(GX_XF_REG_DUALTEX0, texGenNum);
if (j3dSys.checkFlag(0x40000000)) {
for (int i = 0; i < texGenNum; i++) {
if (texCoords[i].getTexGenMtx() != 60) {
var_r28 = i * 3;
} else {
var_r28 = 61;
}
J3DGDWrite_u32(var_r28);
}
} else {
for (int i = 0; i < texGenNum; i++) {
J3DGDWrite_u32(var_r28);
}
}
}
void J3DTexMtx::load(u32 mtxIdx) const {
if (j3dSys.checkFlag(J3DSysFlag_PostTexMtx)) {
loadPostTexMtx(mtxIdx);
} else {
loadTexMtx(mtxIdx);
}
}
void J3DTexMtx::calc(f32 const (*param_0)[4]) {
calcTexMtx(param_0);
}
void J3DTexMtx::calcTexMtx(const Mtx param_0) {
Mtx44 mtx1;
Mtx44 mtx2;
static Mtx qMtx = {
0.5f, 0.0f, 0.5f, 0.0f,
0.0f, -0.5f, 0.5f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
};
static Mtx qMtx2 = {
0.5f, 0.0f, 0.0f, 0.5f,
0.0f, -0.5f, 0.0f, 0.5f,
0.0f, 0.0f, 1.0f, 0.0f,
};
u32 r28 = mTexMtxInfo.mInfo & 0x3f;
u32 r30 = u32(mTexMtxInfo.mInfo & 0x80) >> 7;
switch (r28) {
case 8:
case 9:
case 11:
if (r30 == 0) {
J3DGetTextureMtx(mTexMtxInfo.mSRT, mTexMtxInfo.mCenter, mtx2);
} else if (r30 == 1) {
J3DGetTextureMtxMaya(mTexMtxInfo.mSRT, mtx2);
}
MTXConcat(mtx2, qMtx, mtx2);
J3DMtxProjConcat(mtx2, mTexMtxInfo.mEffectMtx, mtx1);
MTXConcat(mtx1, param_0, mMtx);
break;
case 7:
if (r30 == 0) {
J3DGetTextureMtx(mTexMtxInfo.mSRT, mTexMtxInfo.mCenter, mtx1);
} else if (r30 == 1) {
J3DGetTextureMtxMaya(mTexMtxInfo.mSRT, mtx1);
}
MTXConcat(mtx1, qMtx, mtx1);
MTXConcat(mtx1, param_0, mMtx);
break;
case 10:
if (r30 == 0) {
J3DGetTextureMtxOld(mTexMtxInfo.mSRT, mTexMtxInfo.mCenter, mtx2);
} else if (r30 == 1) {
J3DGetTextureMtxMayaOld(mTexMtxInfo.mSRT, mtx2);
}
MTXConcat(mtx2, qMtx2, mtx2);
J3DMtxProjConcat(mtx2, mTexMtxInfo.mEffectMtx, mtx1);
MTXConcat(mtx1, param_0, mMtx);
break;
case 6:
if (r30 == 0) {
J3DGetTextureMtxOld(mTexMtxInfo.mSRT, mTexMtxInfo.mCenter, mtx1);
} else if (r30 == 1) {
J3DGetTextureMtxMayaOld(mTexMtxInfo.mSRT, mtx1);
}
MTXConcat(mtx1, qMtx2, mtx1);
MTXConcat(mtx1, param_0, mMtx);
break;
case 1:
if (r30 == 0) {
J3DGetTextureMtxOld(mTexMtxInfo.mSRT, mTexMtxInfo.mCenter, mtx1);
} else if (r30 == 1) {
J3DGetTextureMtxMayaOld(mTexMtxInfo.mSRT, mtx1);
}
MTXConcat(mtx1, param_0, mMtx);
break;
case 2:
case 3:
case 5:
if (r30 == 0) {
J3DGetTextureMtxOld(mTexMtxInfo.mSRT, mTexMtxInfo.mCenter, mtx2);
} else if (r30 == 1) {
J3DGetTextureMtxMayaOld(mTexMtxInfo.mSRT, mtx2);
}
J3DMtxProjConcat(mtx2, mTexMtxInfo.mEffectMtx, mtx1);
MTXConcat(mtx1, param_0, mMtx);
break;
case 4:
if (r30 == 0) {
J3DGetTextureMtxOld(mTexMtxInfo.mSRT, mTexMtxInfo.mCenter, mtx2);
} else if (r30 == 1) {
J3DGetTextureMtxMayaOld(mTexMtxInfo.mSRT, mtx2);
}
J3DMtxProjConcat(mtx2, mTexMtxInfo.mEffectMtx, mMtx);
break;
default:
if (r30 == 0) {
J3DGetTextureMtxOld(mTexMtxInfo.mSRT, mTexMtxInfo.mCenter, mMtx);
} else if (r30 == 1) {
J3DGetTextureMtxMayaOld(mTexMtxInfo.mSRT, mMtx);
}
break;
}
}
void J3DTexMtx::calcPostTexMtx(const Mtx param_0) {
Mtx44 mtx1;
Mtx44 mtx2;
static Mtx qMtx = {
0.5f, 0.0f, 0.5f, 0.0f,
0.0f, -0.5f, 0.5f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
};
static Mtx qMtx2 = {
0.5f, 0.0f, 0.0f, 0.5f,
0.0f, -0.5f, 0.0f, 0.5f,
0.0f, 0.0f, 1.0f, 0.0f,
};
u32 r29 = mTexMtxInfo.mInfo & 0x3f;
u32 r30 = u32(mTexMtxInfo.mInfo & 0x80) >> 7;
switch (r29) {
case 8:
case 11:
if (r30 == 0) {
J3DGetTextureMtx(mTexMtxInfo.mSRT, mTexMtxInfo.mCenter, mtx2);
} else if (r30 == 1) {
J3DGetTextureMtxMaya(mTexMtxInfo.mSRT, mtx2);
}
MTXConcat(mtx2, qMtx, mtx2);
J3DMtxProjConcat(mtx2, mTexMtxInfo.mEffectMtx, mtx1);
MTXConcat(mtx1, param_0, mMtx);
break;
case 9:
if (r30 == 0) {
J3DGetTextureMtx(mTexMtxInfo.mSRT, mTexMtxInfo.mCenter, mtx2);
} else if (r30 == 1) {
J3DGetTextureMtxMaya(mTexMtxInfo.mSRT, mtx2);
}
MTXConcat(mtx2, qMtx, mtx2);
J3DMtxProjConcat(mtx2, mTexMtxInfo.mEffectMtx, mMtx);
break;
case 7:
if (r30 == 0) {
J3DGetTextureMtx(mTexMtxInfo.mSRT, mTexMtxInfo.mCenter, mtx1);
} else if (r30 == 1) {
J3DGetTextureMtxMaya(mTexMtxInfo.mSRT, mtx1);
}
MTXConcat(mtx1, qMtx, mMtx);
break;
case 10:
if (r30 == 0) {
J3DGetTextureMtxOld(mTexMtxInfo.mSRT, mTexMtxInfo.mCenter, mtx2);
} else if (r30 == 1) {
J3DGetTextureMtxMayaOld(mTexMtxInfo.mSRT, mtx2);
}
MTXConcat(mtx2, qMtx2, mtx2);
J3DMtxProjConcat(mtx2, mTexMtxInfo.mEffectMtx, mtx1);
MTXConcat(mtx1, param_0, mMtx);
break;
case 6:
if (r30 == 0) {
J3DGetTextureMtxOld(mTexMtxInfo.mSRT, mTexMtxInfo.mCenter, mtx1);
} else if (r30 == 1) {
J3DGetTextureMtxMayaOld(mTexMtxInfo.mSRT, mtx1);
}
MTXConcat(mtx1, qMtx2, mMtx);
break;
case 1:
if (r30 == 0) {
J3DGetTextureMtxOld(mTexMtxInfo.mSRT, mTexMtxInfo.mCenter, mMtx);
} else if (r30 == 1) {
J3DGetTextureMtxMayaOld(mTexMtxInfo.mSRT, mMtx);
}
break;
case 2:
case 5:
if (r30 == 0) {
J3DGetTextureMtxOld(mTexMtxInfo.mSRT, mTexMtxInfo.mCenter, mtx2);
} else if (r30 == 1) {
J3DGetTextureMtxMayaOld(mTexMtxInfo.mSRT, mtx2);
}
J3DMtxProjConcat(mtx2, mTexMtxInfo.mEffectMtx, mtx1);
MTXConcat(mtx1, param_0, mMtx);
break;
case 3:
if (r30 == 0) {
J3DGetTextureMtxOld(mTexMtxInfo.mSRT, mTexMtxInfo.mCenter, mtx2);
} else if (r30 == 1) {
J3DGetTextureMtxMayaOld(mTexMtxInfo.mSRT, mtx2);
}
J3DMtxProjConcat(mtx2, mTexMtxInfo.mEffectMtx, mMtx);
break;
case 4:
if (r30 == 0) {
J3DGetTextureMtxOld(mTexMtxInfo.mSRT, mTexMtxInfo.mCenter, mtx2);
} else if (r30 == 1) {
J3DGetTextureMtxMayaOld(mTexMtxInfo.mSRT, mtx2);
}
J3DMtxProjConcat(mtx2, mTexMtxInfo.mEffectMtx, mMtx);
break;
default:
if (r30 == 0) {
J3DGetTextureMtxOld(mTexMtxInfo.mSRT, mTexMtxInfo.mCenter, mMtx);
} else if (r30 == 1) {
J3DGetTextureMtxMayaOld(mTexMtxInfo.mSRT, mMtx);
}
break;
}
}
bool isTexNoReg(void* pDL) {
u8 r31 = ((u8*)pDL)[1];
if (r31 >= 0x80 && r31 <= 0xbb) {
return true;
}
return false;
}
u16 getTexNoReg(void* pDL) {
u32 var_r31 = *(u32*)((u8*)pDL + 1);
return var_r31 & 0xFFFFFF;
}
void loadTexNo(u32 param_0, const u16& texNo) {
ResTIMG* resTIMG = j3dSys.getTexture()->getResTIMG(texNo);
J3D_ASSERT_NULLPTR(462, resTIMG != NULL);
J3DSys::sTexCoordScaleTable[param_0].field_0x00 = (u16)resTIMG->width;
J3DSys::sTexCoordScaleTable[param_0].field_0x02 = (u16)resTIMG->height;
GDOverflowCheck(0x14);
J3DGDSetTexImgPtr(GXTexMapID(param_0), (u8*)resTIMG + resTIMG->imageOffset);
J3DGDSetTexImgAttr(GXTexMapID(param_0), resTIMG->width, resTIMG->height, GXTexFmt(resTIMG->format & 0x0f));
J3DGDSetTexLookupMode(GXTexMapID(param_0), GXTexWrapMode(resTIMG->wrapS), GXTexWrapMode(resTIMG->wrapT), GXTexFilter(resTIMG->minFilter), GXTexFilter(resTIMG->magFilter), resTIMG->minLOD * 0.125f, resTIMG->maxLOD * 0.125f, resTIMG->LODBias * 0.01f, resTIMG->biasClamp, resTIMG->doEdgeLOD, GXAnisotropy(resTIMG->maxAnisotropy));
if (resTIMG->indexTexture == true) {
GXTlutSize tlutSize = resTIMG->numColors > 16 ? GX_TLUT_256 : GX_TLUT_16;
GDOverflowCheck(0x14);
J3DGDLoadTlut((u8*)resTIMG + resTIMG->paletteOffset, (param_0 << 13) + 0xf0000, tlutSize);
J3DGDSetTexTlut(GXTexMapID(param_0), (param_0 << 13) + 0xf0000, GXTlutFmt(resTIMG->colorFormat));
}
}
void patchTexNo_PtrToIdx(u32 texID, const u16& idx) {
ResTIMG* timg = j3dSys.getTexture()->getResTIMG(idx);
J3D_ASSERT_NULLPTR(523, timg != NULL);
J3DGDSetTexImgPtrRaw(GXTexMapID(texID), idx);
}
void loadNBTScale(J3DNBTScale& NBTScale) {
if (NBTScale.mbHasScale == true) {
j3dSys.setNBTScale(&NBTScale.mScale);
} else {
j3dSys.setNBTScale(NULL);
}
}
const J3DLightInfo j3dDefaultLightInfo = {
0.0f, 0.0f, 0.0f,
0.0f, -1.0f, 0.0f,
0xff, 0xff, 0xff, 0xff,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
};
J3DTexCoordInfo const j3dDefaultTexCoordInfo[8] = {
{GX_MTX2x4, GX_TG_TEX0, GX_IDENTITY, 0}, {GX_MTX2x4, GX_TG_TEX1, GX_IDENTITY, 0},
{GX_MTX2x4, GX_TG_TEX2, GX_IDENTITY, 0}, {GX_MTX2x4, GX_TG_TEX3, GX_IDENTITY, 0},
{GX_MTX2x4, GX_TG_TEX4, GX_IDENTITY, 0}, {GX_MTX2x4, GX_TG_TEX5, GX_IDENTITY, 0},
{GX_MTX2x4, GX_TG_TEX6, GX_IDENTITY, 0}, {GX_MTX2x4, GX_TG_TEX7, GX_IDENTITY, 0},
};
J3DTexMtxInfo const j3dDefaultTexMtxInfo = {
0x01,
0x00,
0xFF,
0xFF,
{0.0f, 0.0f, 0.0f},
{1.0f, 1.0f, 0, 0.0f, 0.0f},
{1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
1.0f},
};
J3DIndTexMtxInfo const j3dDefaultIndTexMtxInfo = {
0.5f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f,
1
};
J3DTevStageInfo const j3dDefaultTevStageInfo = {
0x04, 0x0A, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
0x05, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
};
J3DIndTevStageInfo const j3dDefaultIndTevStageInfo = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
J3DFogInfo const j3dDefaultFogInfo = {
0x00, 0x00, 0x0140, 0.0f, 0.0f, 0.1f, 10000.0f, 0xFF, 0xFF, 0xFF, 0x00,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
};
J3DNBTScaleInfo const j3dDefaultNBTScaleInfo = {
#if TARGET_PC
0x00, {1.0f, 1.0f, 1.0f},
#else
0x00, 1.0f, 1.0f, 1.0f,
#endif
};
static u8 j3dTexCoordTable[7623];
void makeTexCoordTable() {
u8 texMtx[] = {
GX_TEXMTX0,
GX_TEXMTX1,
GX_TEXMTX2,
GX_TEXMTX3,
GX_TEXMTX4,
GX_TEXMTX5,
GX_TEXMTX6,
GX_TEXMTX7,
GX_TEXMTX8,
GX_TEXMTX9,
GX_IDENTITY,
};
u8* table = j3dTexCoordTable;
for (u32 i = 0; i < 11; i++) {
for (u32 j = 0; j < 21; j++) {
for (int k = 0; k < ARRAY_SIZE(texMtx); k++) {
u32 idx = j * 11 + i * 0xe7 + k;
table[idx * 3 + 0] = i;
table[idx * 3 + 1] = j;
table[idx * 3 + 2] = texMtx[k];
}
}
}
}
u8 j3dTevSwapTableTable[1024];
u8 j3dAlphaCmpTable[768];
void makeAlphaCmpTable() {
u8* table = j3dAlphaCmpTable;
for (u32 i = 0; i < 8; i++) {
for (int j = 0; j < 4; j++) {
for (u32 k = 0; k < 8; k++) {
u32 idx = i * 32 + j * 8 + k;
table[idx * 3] = i;
table[idx * 3 + 1] = j;
table[idx * 3 + 2] = k;
}
}
}
}
u8 j3dZModeTable[96];
void makeZModeTable() {
u8* table = j3dZModeTable;
for (int i = 0; i < 2; i++) {
for (u32 j = 0; j < 8; j++) {
for (int k = 0; k < 2; k++) {
u32 idx = j * 2 + i * 16 + k;
table[idx * 3 + 0] = i;
table[idx * 3 + 1] = j;
table[idx * 3 + 2] = k;
}
}
}
}
void makeTevSwapTable() {
u8* table = j3dTevSwapTableTable;
int i = 0;
do {
table[0] = i >> 6;
table[1] = (i >> 4) & 3;
table[2] = (i >> 2) & 3;
table[3] = i & 3;
i++;
table += 4;
} while (i < 256);
}
void J3DTexMtx::loadTexMtx(u32 param_0) const {
GDOverflowCheck(0x35);
J3DGDLoadTexMtxImm((MtxP)mMtx, param_0 * 3 + 30, (GXTexMtxType)mTexMtxInfo.mProjection);
}
void J3DTexMtx::loadPostTexMtx(u32 param_0) const {
GDOverflowCheck(0x35);
J3DGDLoadPostTexMtxImm((MtxP)mMtx, param_0 * 3 + 0x40);
}
static void J3DGDLoadTexMtxImm(f32 (*param_1)[4], u32 param_2, GXTexMtxType param_3) {
u16 addr = param_2 << 2;
u8 len = param_3 == GX_MTX2x4 ? 8 : 12;
J3DGDWriteXFCmdHdr(addr, len);
J3DGDWrite_f32(param_1[0][0]);
J3DGDWrite_f32(param_1[0][1]);
J3DGDWrite_f32(param_1[0][2]);
J3DGDWrite_f32(param_1[0][3]);
J3DGDWrite_f32(param_1[1][0]);
J3DGDWrite_f32(param_1[1][1]);
J3DGDWrite_f32(param_1[1][2]);
J3DGDWrite_f32(param_1[1][3]);
if (param_3 == GX_MTX3x4) {
J3DGDWrite_f32(param_1[2][0]);
J3DGDWrite_f32(param_1[2][1]);
J3DGDWrite_f32(param_1[2][2]);
J3DGDWrite_f32(param_1[2][3]);
}
}
static void J3DGDLoadPostTexMtxImm(f32 (*param_1)[4], u32 param_2) {
u16 addr = (param_2 - 0x40) * 4 + 0x500;
int stride = 12;
J3DGDWriteXFCmdHdr(addr, stride);
J3DGDWrite_f32(param_1[0][0]);
J3DGDWrite_f32(param_1[0][1]);
J3DGDWrite_f32(param_1[0][2]);
J3DGDWrite_f32(param_1[0][3]);
J3DGDWrite_f32(param_1[1][0]);
J3DGDWrite_f32(param_1[1][1]);
J3DGDWrite_f32(param_1[1][2]);
J3DGDWrite_f32(param_1[1][3]);
J3DGDWrite_f32(param_1[2][0]);
J3DGDWrite_f32(param_1[2][1]);
J3DGDWrite_f32(param_1[2][2]);
J3DGDWrite_f32(param_1[2][3]);
}
const GXColor j3dDefaultColInfo = {0xFF, 0xFF, 0xFF, 0xFF};
const GXColor j3dDefaultAmbInfo = {0x32, 0x32, 0x32, 0x32};
const u8 j3dDefaultNumChans = 1;
const J3DTevOrderInfo j3dDefaultTevOrderInfoNull = {0xFF, 0xFF, 0xFF, 0x00};
const J3DIndTexOrderInfo j3dDefaultIndTexOrderNull = {0xFF, 0xFF, 0x00, 0x00};
const GXColorS10 j3dDefaultTevColor = {0xFF, 0xFF, 0xFF, 0xFF};
const J3DIndTexCoordScaleInfo j3dDefaultIndTexCoordScaleInfo = {
0x00,
0x00,
0x00,
0x00,
};
const GXColor j3dDefaultTevKColor = {0xFF, 0xFF, 0xFF, 0xFF};
J3DTevSwapModeInfo const j3dDefaultTevSwapMode = {
0x00,
0x00,
0x00,
0x00,
};
const J3DTevSwapModeTableInfo j3dDefaultTevSwapModeTable = {0x00, 0x01, 0x02, 0x03};
const J3DBlendInfo j3dDefaultBlendInfo = {GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP};
const J3DColorChanInfo j3dDefaultColorChanInfo = {
0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0xFF, 0xFF,
};
const u8 j3dDefaultTevSwapTableID = 0x1B;
const u16 j3dDefaultAlphaCmpID = 0x00E7;
const u16 j3dDefaultZModeID = 0x0017;
@@ -0,0 +1,67 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/J3DAssert.h"
#include "JSystem/J3DGraphBase/J3DTexture.h"
#include "JSystem/JKernel/JKRHeap.h"
void J3DTexture::loadGX(u16 idx, GXTexMapID texMapID) const {
J3D_ASSERT_RANGE(29, idx < mNum);
ResTIMG* timg = getResTIMG(idx);
GXTexObj texObj;
GXTlutObj tlutObj;
if (!timg->indexTexture) {
GXInitTexObj(&texObj, ((u8*)timg) + timg->imageOffset, timg->width, timg->height,
(GXTexFmt)timg->format, (GXTexWrapMode)timg->wrapS, (GXTexWrapMode)timg->wrapT,
timg->mipmapEnabled);
} else {
GXInitTexObjCI(&texObj, ((u8*)timg) + timg->imageOffset, timg->width, timg->height,
(GXCITexFmt)timg->format, (GXTexWrapMode)timg->wrapS,
(GXTexWrapMode)timg->wrapT, timg->mipmapEnabled, (u32)texMapID);
GXInitTlutObj(&tlutObj, ((u8*)timg) + timg->paletteOffset, (GXTlutFmt)timg->colorFormat,
timg->numColors);
GXLoadTlut(&tlutObj, texMapID);
}
const f32 kLODClampScale = 1.0f / 8.0f;
const f32 kLODBiasScale = 1.0f / 100.0f;
GXInitTexObjLOD(&texObj, (GXTexFilter)timg->minFilter, (GXTexFilter)timg->magFilter,
timg->minLOD * kLODClampScale, timg->maxLOD * kLODClampScale,
timg->LODBias * kLODBiasScale, timg->biasClamp, timg->doEdgeLOD,
(GXAnisotropy)timg->maxAnisotropy);
GXLoadTexObj(&texObj, texMapID);
}
void J3DTexture::entryNum(u16 num) {
J3D_ASSERT_NONZEROARG(79, num != 0);
mNum = num;
mpRes = JKR_NEW ResTIMG[num];
J3D_ASSERT_ALLOCMEM(83, mpRes != NULL);
for (int i = 0; i < mNum; i++) {
mpRes[i].paletteOffset = 0;
mpRes[i].imageOffset = 0;
}
}
void J3DTexture::addResTIMG(u16 newNum, const ResTIMG* newRes) {
if (newNum == 0)
return;
J3D_ASSERT_NULLPTR(105, newRes != NULL);
u16 oldNum = mNum;
ResTIMG* oldRes = mpRes;
entryNum(mNum + newNum);
for (u16 i = 0; i < oldNum; i++) {
setResTIMG(i, oldRes[i]);
}
for (u16 i = oldNum; i < mNum; i++) {
setResTIMG(i, newRes[i]);
}
}
@@ -0,0 +1,616 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/J3DGraphBase/J3DTransform.h"
#include "JSystem/J3DGraphBase/J3DStruct.h"
#include "JSystem/JMath/JMATrigonometric.h"
#include "JSystem/JMath/JMath.h"
void __MTGQR7(__REGISTER u32 v) {
#ifdef __MWERKS__
// clang-format off
asm {
mtspr GQR7, v
}
// clang-format on
#endif
}
void J3DGQRSetup7(u32 r0, u32 r1, u32 r2, u32 r3) {
u32 v = ((r0 << 8) + r1) << 16;
v |= (r2 << 8) + r3;
__MTGQR7(v);
}
// this uses a non-standard sqrtf, not sure why or how its supposed to be setup
#if !PLATFORM_SHIELD
inline f32 J3D_sqrtf(__REGISTER f32 x) {
__REGISTER f32 recip;
if (x > 0.0f) {
#ifdef __MWERKS__ // clang-format off
asm { frsqrte recip, x }
#endif // clang-format on
return recip * x;
}
return x;
}
#else
#define J3D_sqrtf sqrtf
#endif
void J3DCalcBBoardMtx(__REGISTER Mtx mtx) {
f32 x = (mtx[0][0] * mtx[0][0]) + (mtx[1][0] * mtx[1][0]) + (mtx[2][0] * mtx[2][0]);
f32 y = (mtx[0][1] * mtx[0][1]) + (mtx[1][1] * mtx[1][1]) + (mtx[2][1] * mtx[2][1]);
f32 z = (mtx[0][2] * mtx[0][2]) + (mtx[1][2] * mtx[1][2]) + (mtx[2][2] * mtx[2][2]);
if (x > 0.0f) {
x = J3D_sqrtf(x);
}
if (y > 0.0f) {
y = J3D_sqrtf(y);
}
if (z > 0.0f) {
z = J3D_sqrtf(z);
}
__REGISTER f32 zero = 0.0f;
// zero out gaps of zeroes
#if DEBUG || !defined(__MWERKS__)
mtx[0][1] = 0.0f;
mtx[0][2] = 0.0f;
mtx[2][0] = 0.0f;
mtx[2][1] = 0.0f;
#else // clang-format off
asm {
psq_st zero, 0x04(mtx), 0, 0
psq_st zero, 0x20(mtx), 0, 0
}
#endif // clang-format on
mtx[0][0] = x;
mtx[1][0] = 0.0f;
mtx[1][1] = y;
mtx[1][2] = 0.0f;
mtx[2][2] = z;
}
J3DTransformInfo const j3dDefaultTransformInfo = {
{1.0f, 1.0f, 1.0f}, {0, 0, 0}, {0.0f, 0.0f, 0.0f}};
Vec const j3dDefaultScale = {1.0f, 1.0f, 1.0f};
Mtx const j3dDefaultMtx = {
{1.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f, 0.0f}};
void J3DCalcYBBoardMtx(Mtx mtx) {
f32 x = (mtx[0][0] * mtx[0][0]) + (mtx[1][0] * mtx[1][0]) + (mtx[2][0] * mtx[2][0]);
f32 z = (mtx[0][2] * mtx[0][2]) + (mtx[1][2] * mtx[1][2]) + (mtx[2][2] * mtx[2][2]);
if (x > 0.0f) {
x = JMath::fastSqrt(x);
}
if (z > 0.0f) {
z = JMath::fastSqrt(z);
}
Vec vec = { 0.0f, -mtx[2][1], mtx[1][1] };
VECNormalize(&vec, &vec);
mtx[0][0] = x;
mtx[0][2] = 0.0f;
mtx[1][0] = 0.0f;
mtx[1][2] = vec.y * z;
mtx[2][0] = 0.0f;
mtx[2][2] = vec.z * z;
}
ASM void J3DPSCalcInverseTranspose(__REGISTER Mtx src, __REGISTER Mtx33 dst) {
#ifdef __MWERKS__ // clang-format off
psq_l f0, 0(src), 1, 0
psq_l f1, 4(src), 0, 0
psq_l f2, 16(src), 1, 0
ps_merge10 f6, f1, f0
psq_l f3, 20(src), 0, 0
psq_l f4, 32(src), 1, 0
ps_merge10 f7, f3, f2
psq_l f5, 36(src), 0, 0
ps_mul f11, f3, f6
ps_merge10 f8, f5, f4
ps_mul f13, f5, f7
ps_msub f11, f1, f7, f11
ps_mul f12, f1, f8
ps_msub f13, f3, f8, f13
ps_msub f12, f5, f6, f12
ps_mul f10, f3, f4
ps_mul f9, f0, f5
ps_mul f8, f1, f2
ps_msub f10, f2, f5, f10
ps_msub f9, f1, f4, f9
ps_msub f8, f0, f3, f8
ps_mul f7, f0, f13
ps_sub f1, f1, f1
ps_madd f7, f2, f12, f7
ps_madd f7, f4, f11, f7
ps_cmpo0 cr0, f7, f1
bne lbl_8005F118
li r3, 0
blr
lbl_8005F118:
fres f0, f7
ps_add f6, f0, f0
ps_mul f5, f0, f0
ps_nmsub f0, f7, f5, f6
ps_add f6, f0, f0
ps_mul f5, f0, f0
ps_nmsub f0, f7, f5, f6
ps_muls0 f13, f13, f0
ps_muls0 f12, f12, f0
psq_st f13, 0(dst), 0, 0
ps_muls0 f11, f11, f0
psq_st f12, 12(dst), 0, 0
ps_muls0 f10, f10, f0
psq_st f11, 24(dst), 0, 0
ps_muls0 f9, f9, f0
psq_st f10, 8(dst), 1, 0
ps_muls0 f8, f8, f0
psq_st f9, 20(r4), 1, 0
li r3, 1
psq_st f8, 32(r4), 1, 0
blr
#else
Mtx invX;
if (C_MTXInvXpose(src, invX) == 0) {
return;
}
J3DPSMtx33CopyFrom34(invX, dst);
#endif // clang-format on
}
void J3DGetTranslateRotateMtx(const J3DTransformInfo& tx, Mtx dst) {
f32 cxsz;
f32 sxcz;
f32 sx = JMASSin(tx.mRotation.x), cx = JMASCos(tx.mRotation.x);
f32 sy = JMASSin(tx.mRotation.y), cy = JMASCos(tx.mRotation.y);
f32 sz = JMASSin(tx.mRotation.z), cz = JMASCos(tx.mRotation.z);
dst[2][0] = -sy;
dst[0][0] = cz * cy;
dst[1][0] = sz * cy;
dst[2][1] = cy * sx;
dst[2][2] = cy * cx;
cxsz = cx * sz;
sxcz = sx * cz;
dst[0][1] = sxcz * sy - cxsz;
dst[1][2] = cxsz * sy - sxcz;
cxsz = sx * sz;
sxcz = cx * cz;
dst[0][2] = sxcz * sy + cxsz;
dst[1][1] = cxsz * sy + sxcz;
dst[0][3] = tx.mTranslate.x;
dst[1][3] = tx.mTranslate.y;
dst[2][3] = tx.mTranslate.z;
}
void J3DGetTranslateRotateMtx(s16 rx, s16 ry, s16 rz, f32 tx, f32 ty, f32 tz, Mtx dst) {
f32 cxsz;
f32 sxcz;
f32 sx = JMASSin(rx), cx = JMASCos(rx);
f32 sy = JMASSin(ry), cy = JMASCos(ry);
f32 sz = JMASSin(rz), cz = JMASCos(rz);
dst[2][0] = -sy;
dst[0][0] = cz * cy;
dst[1][0] = sz * cy;
dst[2][1] = cy * sx;
dst[2][2] = cy * cx;
cxsz = cx * sz;
sxcz = sx * cz;
dst[0][1] = sxcz * sy - cxsz;
dst[1][2] = cxsz * sy - sxcz;
cxsz = sx * sz;
sxcz = cx * cz;
dst[0][2] = sxcz * sy + cxsz;
dst[1][1] = cxsz * sy + sxcz;
dst[0][3] = tx;
dst[1][3] = ty;
dst[2][3] = tz;
}
void J3DGetTextureMtx(const J3DTextureSRTInfo& srt, const Vec& center, Mtx dst) {
f32 sr = JMASSin(srt.mRotation), cr = JMASCos(srt.mRotation);
f32 cx = srt.mScaleX * cr;
f32 sx = srt.mScaleX * sr;
f32 sy = srt.mScaleY * sr;
f32 cy = srt.mScaleY * cr;
dst[0][0] = cx;
dst[0][1] = -sx;
dst[0][2] = (-cx * center.x + sx * center.y) + center.x + srt.mTranslationX;
dst[1][0] = sy;
dst[1][1] = cy;
dst[1][2] = (-sy * center.x - cy * center.y) + center.y + srt.mTranslationY;
dst[0][3] = dst[1][3] = dst[2][0] = dst[2][1] = dst[2][3] = 0.0f;
dst[2][2] = 1.0f;
}
void J3DGetTextureMtxOld(const J3DTextureSRTInfo& srt, const Vec& center, Mtx dst) {
f32 sr = JMASSin(srt.mRotation), cr = JMASCos(srt.mRotation);
f32 cx = srt.mScaleX * cr;
f32 sx = srt.mScaleX * sr;
f32 sy = srt.mScaleY * sr;
f32 cy = srt.mScaleY * cr;
dst[0][0] = cx;
dst[0][1] = -sx;
dst[0][3] = (-cx * center.x + sx * center.y) + center.x + srt.mTranslationX;
dst[1][0] = sy;
dst[1][1] = cy;
dst[1][3] = (-sy * center.x - cy * center.y) + center.y + srt.mTranslationY;
dst[0][2] = dst[1][2] = dst[2][0] = dst[2][1] = dst[2][3] = 0.0f;
dst[2][2] = 1.0f;
}
void J3DGetTextureMtxMaya(const J3DTextureSRTInfo& srt, Mtx dst) {
f32 sr = JMASSin(srt.mRotation), cr = JMASCos(srt.mRotation);
f32 tx = srt.mTranslationX - 0.5f;
f32 ty = srt.mTranslationY - 0.5f;
dst[0][0] = srt.mScaleX * cr;
dst[0][1] = srt.mScaleY * sr;
dst[0][2] = tx * cr - sr * (ty + srt.mScaleY) + 0.5f;
dst[1][0] = -srt.mScaleX * sr;
dst[1][1] = srt.mScaleY * cr;
dst[1][2] = -tx * sr - cr * (ty + srt.mScaleY) + 0.5f;
dst[0][3] = dst[1][3] = dst[2][0] = dst[2][1] = dst[2][3] = 0.0f;
dst[2][2] = 1.0f;
}
void J3DGetTextureMtxMayaOld(const J3DTextureSRTInfo& srt, Mtx dst) {
f32 sr = JMASSin(srt.mRotation), cr = JMASCos(srt.mRotation);
f32 tx = srt.mTranslationX - 0.5f;
f32 ty = srt.mTranslationY - 0.5f;
dst[0][0] = srt.mScaleX * cr;
dst[0][1] = srt.mScaleY * sr;
dst[0][3] = tx * cr - sr * (ty + srt.mScaleY) + 0.5f;
dst[1][0] = -srt.mScaleX * sr;
dst[1][1] = srt.mScaleY * cr;
dst[1][3] = -tx * sr - cr * (ty + srt.mScaleY) + 0.5f;
dst[0][2] = dst[1][2] = dst[2][0] = dst[2][1] = dst[2][3] = 0.0f;
dst[2][2] = 1.0f;
}
ASM void J3DScaleNrmMtx(__REGISTER Mtx mtx, const __REGISTER Vec& scl) {
#ifdef __MWERKS__ // clang-format off
nofralloc;
psq_l fp2, 0(scl), 0, 0
psq_l fp0, 0(mtx), 0, 0
lfs fp3, 8(scl)
lfs fp1, 8(mtx)
ps_mul f4, fp0, fp2
psq_st f4, 0(mtx), 0, 0
fmuls f4, fp1, fp3
stfs f4, 8(mtx)
/* Row 1 */
psq_l fp2, 0(scl), 0, 0
psq_l fp0, 16(mtx), 0, 0
lfs fp3, 8(scl)
lfs fp1, 24(mtx)
ps_mul f4, fp0, fp2
psq_st f4, 16(mtx), 0, 0
fmuls f4, fp1, fp3
stfs f4, 24(mtx)
/* Row 2 */
psq_l fp2, 0(scl), 0, 0
psq_l fp0, 32(mtx), 0, 0
lfs fp3, 8(scl)
lfs fp1, 40(mtx)
ps_mul f4, fp0, fp2
psq_st f4, 32(mtx), 0, 0
fmuls f4, fp1, fp3
stfs f4, 40(mtx)
blr
#else
f32 sx = scl.x;
f32 sy = scl.y;
f32 sz = scl.z;
mtx[0][0] *= sx;
mtx[0][1] *= sy;
mtx[0][2] *= sz;
mtx[1][0] *= sx;
mtx[1][1] *= sy;
mtx[1][2] *= sz;
mtx[2][0] *= sx;
mtx[2][1] *= sy;
mtx[2][2] *= sz;
#endif // clang-format on
}
ASM void J3DScaleNrmMtx33(__REGISTER Mtx33 mtx, const __REGISTER Vec& scale) {
#ifdef __MWERKS__ // clang-format off
psq_l f0, 0(mtx), 0, 0
psq_l f6, 0(scale), 0, 0
lfs f1, 8(mtx)
lfs f7, 8(scale)
ps_mul f0, f0, f6
psq_l f2, 12(mtx), 0, 0
fmuls f1, f1, f7
lfs f3, 0x14(mtx)
ps_mul f2, f2, f6
psq_l f4, 24(mtx), 0, 0
fmuls f3, f3, f7
lfs f5, 0x20(mtx)
ps_mul f4, f4, f6
psq_st f0, 0(mtx), 0, 0
fmuls f5, f5, f7
stfs f1, 8(mtx)
psq_st f2, 12(mtx), 0, 0
stfs f3, 0x14(mtx)
psq_st f4, 24(mtx), 0, 0
stfs f5, 0x20(mtx)
blr
#else
f32 sx = scale.x;
f32 sy = scale.y;
f32 sz = scale.z;
mtx[0][0] *= sx;
mtx[0][1] *= sy;
mtx[0][2] *= sz;
mtx[1][0] *= sx;
mtx[1][1] *= sy;
mtx[1][2] *= sz;
mtx[2][0] *= sx;
mtx[2][1] *= sy;
mtx[2][2] *= sz;
#endif // clang-format on
}
ASM void J3DMtxProjConcat(__REGISTER Mtx mtx1, __REGISTER Mtx mtx2, __REGISTER Mtx dst) {
#ifdef __MWERKS__ // clang-format off
psq_l f2, 0(mtx1), 0, 0
psq_l f3, 8(mtx1), 0, 0
ps_merge00 f6, f2, f2
ps_merge11 f7, f2, f2
ps_merge00 f8, f3, f3
ps_merge11 f9, f3, f3
psq_l f10, 0(mtx2), 0, 0
psq_l f11, 16(mtx2), 0, 0
psq_l f12, 32(mtx2), 0, 0
psq_l f13, 48(mtx2), 0, 0
ps_mul f0, f6, f10
ps_madd f0, f7, f11, f0
ps_madd f0, f8, f12, f0
ps_madd f0, f9, f13, f0
psq_st f0, 0(dst), 0, 0
psq_l f10, 8(mtx2), 0, 0
psq_l f11, 24(mtx2), 0, 0
psq_l f12, 40(mtx2), 0, 0
psq_l f13, 56(mtx2), 0, 0
ps_mul f0, f6, f10
ps_madd f0, f7, f11, f0
ps_madd f0, f8, f12, f0
ps_madd f0, f9, f13, f0
psq_st f0, 8(dst), 0, 0
psq_l f2, 16(mtx1), 0, 0
psq_l f3, 24(mtx1), 0, 0
ps_merge00 f6, f2, f2
ps_merge11 f7, f2, f2
ps_merge00 f8, f3, f3
ps_merge11 f9, f3, f3
psq_l f10, 0(mtx2), 0, 0
psq_l f11, 16(mtx2), 0, 0
psq_l f12, 32(mtx2), 0, 0
psq_l f13, 48(mtx2), 0, 0
ps_mul f0, f6, f10
ps_madd f0, f7, f11, f0
ps_madd f0, f8, f12, f0
ps_madd f0, f9, f13, f0
psq_st f0, 16(dst), 0, 0
psq_l f10, 8(mtx2), 0, 0
psq_l f11, 24(mtx2), 0, 0
psq_l f12, 40(mtx2), 0, 0
psq_l f13, 56(mtx2), 0, 0
ps_mul f0, f6, f10
ps_madd f0, f7, f11, f0
ps_madd f0, f8, f12, f0
ps_madd f0, f9, f13, f0
psq_st f0, 24(dst), 0, 0
psq_l f2, 32(mtx1), 0, 0
psq_l f3, 40(mtx1), 0, 0
ps_merge00 f6, f2, f2
ps_merge11 f7, f2, f2
ps_merge00 f8, f3, f3
ps_merge11 f9, f3, f3
psq_l f10, 0(mtx2), 0, 0
psq_l f11, 16(mtx2), 0, 0
psq_l f12, 32(mtx2), 0, 0
psq_l f13, 48(mtx2), 0, 0
ps_mul f0, f6, f10
ps_madd f0, f7, f11, f0
ps_madd f0, f8, f12, f0
ps_madd f0, f9, f13, f0
psq_st f0, 32(dst), 0, 0
psq_l f10, 8(mtx2), 0, 0
psq_l f11, 24(mtx2), 0, 0
psq_l f12, 40(mtx2), 0, 0
psq_l f13, 56(mtx2), 0, 0
ps_mul f0, f6, f10
ps_madd f0, f7, f11, f0
ps_madd f0, f8, f12, f0
ps_madd f0, f9, f13, f0
psq_st f0, 40(dst), 0, 0
blr
#else
Mtx tmp;
for (int i = 0; i < 3; i++) {
f32 a0 = mtx1[i][0];
f32 a1 = mtx1[i][1];
f32 a2 = mtx1[i][2];
f32 a3 = mtx1[i][3];
tmp[i][0] = a0 * mtx2[0][0] + a1 * mtx2[1][0] + a2 * mtx2[2][0] + a3 * mtx2[3][0];
tmp[i][1] = a0 * mtx2[0][1] + a1 * mtx2[1][1] + a2 * mtx2[2][1] + a3 * mtx2[3][1];
tmp[i][2] = a0 * mtx2[0][2] + a1 * mtx2[1][2] + a2 * mtx2[2][2] + a3 * mtx2[3][2];
tmp[i][3] = a0 * mtx2[0][3] + a1 * mtx2[1][3] + a2 * mtx2[2][3] + a3 * mtx2[3][3];
}
JMath::gekko_ps_copy12(dst, tmp);
#endif // clang-format on
}
static f32 Unit01[2] = {
0.0f, 1.0f
};
#ifdef __MWERKS__ // clang-format off
asm void J3DPSMtxArrayConcat(register Mtx mA, register Mtx mB, register Mtx mAB, register u32 count) {
#define FP0 fp0
#define FP1 fp1
#define FP2 fp2
#define FP3 fp3
#define FP4 fp4
#define FP5 fp5
#define FP6 fp6
#define FP7 fp7
#define FP8 fp8
#define FP9 fp9
#define FP10 fp10
#define FP11 fp11
#define FP12 fp12
#define FP13 fp13
#define FP14 fp14
#define FP15 fp15
#define FP31 fp31
#define UNIT_R r7
// this is just PSMtxConcat???
nofralloc
stwu sp, -0x40(sp)
stfd FP14, 0x08(sp)
addis UNIT_R, 0, Unit01@ha
stfd FP15, 0x10(sp)
addi UNIT_R, UNIT_R, Unit01@l
stfd FP31, 0x28(sp)
subi mB, mB, 0x08
subi mAB, mAB, 0x08
mtctr count
loop:
psq_l FP0, 0x00(mA), 0, 0
psq_l FP6, 0x08(mB), 0, 0
psq_l FP7, 0x10(mB), 0, 0
psq_l FP8, 0x18(mB), 0, 0
ps_muls0 FP12, FP6, FP0
psq_l FP2, 0x10(mA), 0, 0
ps_muls0 FP13, FP7, FP0
psq_l FP31, 0x00(UNIT_R), 0, 0
ps_muls0 FP14, FP6, FP2
psq_l FP9, 0x20(mB), 0, 0
ps_muls0 FP15, FP7, FP2
psq_l FP1, 0x08(mA), 0, 0
ps_madds1 FP12, FP8, FP0, FP12
psq_l FP3, 0x18(mA), 0, 0
ps_madds1 FP14, FP8, FP2, FP14
psq_l FP10, 0x28(mB), 0, 0
ps_madds1 FP13, FP9, FP0, FP13
psq_lu FP11, 0x30(mB), 0, 0
ps_madds1 FP15, FP9, FP2, FP15
psq_l FP4, 0x20(mA), 0, 0
psq_l FP5, 0x28(mA), 0, 0
ps_madds0 FP12, FP10, FP1, FP12
ps_madds0 FP13, FP11, FP1, FP13
ps_madds0 FP14, FP10, FP3, FP14
ps_madds0 FP15, FP11, FP3, FP15
psq_st FP12, 0x08(mAB), 0, 0
ps_muls0 FP2, FP6, FP4
ps_madds1 FP13, FP31, FP1, FP13
ps_muls0 FP0, FP7, FP4
psq_st FP14, 0x18(mAB), 0, 0
ps_madds1 FP15, FP31, FP3, FP15
psq_st FP13, 0x10(mAB), 0, 0
ps_madds1 FP2, FP8, FP4, FP2
ps_madds1 FP0, FP9, FP4, FP0
ps_madds0 FP2, FP10, FP5, FP2
psq_st FP15, 0x20(mAB), 0, 0
ps_madds0 FP0, FP11, FP5, FP0
psq_st FP2, 0x28(mAB), 0, 0
ps_madds1 FP0, FP31, FP5, FP0
psq_stu FP0, 0x30(mAB), 0, 0
bdnz loop
lfd FP14, 0x08(sp)
lfd FP15, 0x10(sp)
lfd FP31, 0x28(sp)
addi sp, sp, 0x40
blr
#undef FP0
#undef FP1
#undef FP2
#undef FP3
#undef FP4
#undef FP5
#undef FP6
#undef FP7
#undef FP8
#undef FP9
#undef FP10
#undef FP11
#undef FP12
#undef FP13
#undef FP14
#undef FP15
#undef FP31
#undef UNIT_R
}
#else
void J3DPSMtxArrayConcat(Mtx mA, Mtx mB, Mtx mAB, u32 count) {
Mtx* src = (Mtx*)mB;
Mtx* dst = (Mtx*)mAB;
for (u32 i = 0; i < count; i++) {
C_MTXConcat(mA, src[i], dst[i]);
}
}
#endif // clang-format on
f32 const PSMulUnit01[] = {
0.0f,
-1.0f,
};
+223
View File
@@ -0,0 +1,223 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/J3DGraphBase/J3DVertex.h"
#include "JSystem/J3DGraphAnimator/J3DJointTree.h"
#include "JSystem/J3DGraphBase/J3DSys.h"
#include "JSystem/JKernel/JKRHeap.h"
#include <cstring>
J3DVertexData::J3DVertexData() {
mVtxNum = 0;
mNrmNum = 0;
mColNum = 0;
mTexCoordNum = 0;
mPacketNum = 0;
mVtxAttrFmtList = NULL;
mVtxPosArray = NULL;
mVtxNrmArray = NULL;
mVtxNBTArray = NULL;
for (int i = 0; i < 2; i++)
mVtxColorArray[i] = NULL;
for (int i = 0; i < 8; i++)
mVtxTexCoordArray[i] = NULL;
mVtxPosFrac = 0;
mVtxPosType = GX_F32;
mVtxNrmFrac = 0;
mVtxNrmType = GX_F32;
}
void J3DVertexBuffer::setVertexData(J3DVertexData* pVtxData) {
J3D_ASSERT_NULLPTR(175, pVtxData != NULL);
mVtxData = pVtxData;
mVtxPosArray[0] = pVtxData->getVtxPosArray();
mVtxNrmArray[0] = pVtxData->getVtxNrmArray();
mVtxColArray[0] = pVtxData->getVtxColorArray(0);
mVtxPosArray[1] = NULL;
mVtxNrmArray[1] = NULL;
mVtxColArray[1] = NULL;
mTransformedVtxPosArray[0] = pVtxData->getVtxPosArray();
mTransformedVtxNrmArray[0] = pVtxData->getVtxNrmArray();
mTransformedVtxPosArray[1] = NULL;
mTransformedVtxNrmArray[1] = NULL;
frameInit();
}
void J3DVertexBuffer::init() {
mVtxData = NULL;
mVtxPosArray[0] = mVtxPosArray[1] = NULL;
mVtxNrmArray[0] = mVtxNrmArray[1] = NULL;
mVtxColArray[0] = mVtxColArray[1] = NULL;
mTransformedVtxPosArray[0] = mTransformedVtxPosArray[1] = NULL;
mTransformedVtxNrmArray[0] = mTransformedVtxNrmArray[1] = NULL;
mCurrentVtxPos = NULL;
mCurrentVtxNrm = NULL;
mCurrentVtxCol = NULL;
frameInit();
}
J3DVertexBuffer::~J3DVertexBuffer() {}
void J3DVertexBuffer::setArray() const {
j3dSys.setVtxPos(mCurrentVtxPos);
j3dSys.setVtxNrm(mCurrentVtxNrm);
j3dSys.setVtxCol(mCurrentVtxCol);
}
s32 J3DVertexBuffer::copyLocalVtxPosArray(u32 flag) {
if (flag & 1) {
for (int i = 0; i < 2; i++) {
mVtxPosArray[i] = JKR_NEW_ARGS (0x20) char[mVtxData->getVtxNum() * 3 * 4];
if (mVtxPosArray[i] == NULL) {
return kJ3DError_Alloc;
}
memcpy(mVtxPosArray[i], mVtxData->getVtxPosArray(), mVtxData->getVtxNum() * 3 * 4);
DCStoreRange(mVtxPosArray[i], mVtxData->getVtxNum() * 3 * 4);
}
} else {
mVtxPosArray[0] = mVtxData->getVtxPosArray();
if (mVtxPosArray[1] == NULL) {
mVtxPosArray[1] = JKR_NEW_ARGS (0x20) char[mVtxData->getVtxNum() * 3 * 4];
if (mVtxPosArray[1] == NULL) {
return kJ3DError_Alloc;
}
}
memcpy(mVtxPosArray[1], mVtxData->getVtxPosArray(), mVtxData->getVtxNum() * 3 * 4);
DCStoreRange(mVtxPosArray[1], mVtxData->getVtxNum() * 3 * 4);
}
return kJ3DError_Success;
}
s32 J3DVertexBuffer::copyLocalVtxNrmArray(u32 flag) {
if (flag & 1) {
for (int i = 0; i < 2; i++) {
mVtxNrmArray[i] = JKR_NEW_ARGS (0x20) char[mVtxData->getNrmNum() * 3 * 4];
if (mVtxNrmArray[i] == NULL) {
return kJ3DError_Alloc;
}
memcpy(mVtxNrmArray[i], mVtxData->getVtxNrmArray(), mVtxData->getNrmNum() * 3 * 4);
DCStoreRange(mVtxNrmArray[i], mVtxData->getNrmNum() * 3 * 4);
}
} else {
mVtxNrmArray[0] = mVtxData->getVtxNrmArray();
if (mVtxNrmArray[1] == NULL) {
mVtxNrmArray[1] = JKR_NEW_ARGS (0x20) char[mVtxData->getNrmNum() * 3 * 4];
if (mVtxNrmArray[1] == NULL) {
return kJ3DError_Alloc;
}
}
memcpy(mVtxNrmArray[1], mVtxData->getVtxNrmArray(), mVtxData->getNrmNum() * 3 * 4);
DCStoreRange(mVtxNrmArray[1], mVtxData->getNrmNum() * 3 * 4);
}
return kJ3DError_Success;
}
s32 J3DVertexBuffer::copyLocalVtxArray(u32 flag) {
void* oldPosArray[2];
void* oldNrmArray[2];
for (int i = 0; i < 2; i++)
oldPosArray[i] = mVtxPosArray[i];
if (~flag & 2) {
s32 ret = copyLocalVtxPosArray(flag);
if (ret != 0) {
for (int i = 0; i < 2; i++) {
if (oldPosArray[i] != mVtxPosArray[i]) {
if (mVtxPosArray[i] != mVtxData->getVtxPosArray())
JKR_DELETE(mVtxPosArray[i]);
mVtxPosArray[i] = oldPosArray[i];
}
}
return ret;
}
} else {
mVtxPosArray[0] = mVtxPosArray[1] = mVtxData->getVtxPosArray();
}
for (int i = 0; i < 2; i++)
oldNrmArray[i] = mVtxNrmArray[i];
if (~flag & 4) {
s32 ret = copyLocalVtxNrmArray(flag);
if (ret != 0) {
for (int i = 0; i < 2; i++) {
if (oldPosArray[i] != mVtxPosArray[i]) {
if (mVtxPosArray[i] != mVtxData->getVtxPosArray())
JKR_DELETE(mVtxPosArray[i]);
mVtxPosArray[i] = oldPosArray[i];
}
if (oldNrmArray[i] != mVtxNrmArray[i]) {
if (mVtxNrmArray[i] != mVtxData->getVtxNrmArray())
JKR_DELETE(mVtxNrmArray[i]);
mVtxNrmArray[i] = oldNrmArray[i];
}
}
return ret;
}
} else {
mVtxNrmArray[0] = mVtxNrmArray[1] = mVtxData->getVtxNrmArray();
}
return kJ3DError_Success;
}
s32 J3DVertexBuffer::allocTransformedVtxPosArray() {
if (mTransformedVtxPosArray[0] != NULL && mTransformedVtxPosArray[1] != NULL)
return kJ3DError_Success;
for (int i = 0; i < 2; i++) {
if (i == 0 || mTransformedVtxPosArray[i] == NULL) {
mTransformedVtxPosArray[i] = JKR_NEW_ARGS (0x20) char[mVtxData->getVtxNum() * 3 * 4];
if (mTransformedVtxPosArray[i] == NULL)
return kJ3DError_Alloc;
}
}
return kJ3DError_Success;
}
s32 J3DVertexBuffer::allocTransformedVtxNrmArray() {
if (mTransformedVtxNrmArray[0] != NULL && mTransformedVtxNrmArray[1] != NULL)
return kJ3DError_Success;
for (int i = 0; i < 2; i++) {
if (i == 0 || mTransformedVtxNrmArray[i] == NULL) {
mTransformedVtxNrmArray[i] = JKR_NEW_ARGS (0x20) char[mVtxData->getNrmNum() * 3 * 4];
if (mTransformedVtxNrmArray[i] == NULL)
return kJ3DError_Alloc;
}
}
return kJ3DError_Success;
}
static void dummy(J3DVertexData* vertexData) {
vertexData->getColNum();
}
J3DDrawMtxData::J3DDrawMtxData() {
mEntryNum = 0;
mDrawMtxFlag = NULL;
mDrawMtxIndex = NULL;
}
J3DDrawMtxData::~J3DDrawMtxData() {}