mirror of
https://github.com/zeldaret/ph
synced 2026-07-09 06:03:28 -04:00
Decomp sbc.c (100%) (#144)
* start sbc.cpp * add G3d_SBCRender_007 * match G3d_SBCRender_007 * match G3d_SBCRender_008 * match G3d_SBCRender_SKN * fix EUR relocs file * match G3d_SBCRender_00C * match G3d_SBCRender_00D * complete sbc.cpp * fix EUR delinks
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
#include "nds/math.h"
|
||||
|
||||
struct G3d_RenderState_;
|
||||
typedef void (*G3d_CallbackFunction)(struct G3d_RenderState_ *);
|
||||
|
||||
typedef struct G3d_NameList_ {
|
||||
/* 00 */ u8 dummy;
|
||||
/* 01 */ u8 numElmnts; // number of elements
|
||||
/* 02 */ u16 size; // size of this NameList in bytes
|
||||
/* 04 */ u16 dummy2;
|
||||
/* 06 */ u16 ofsHeader; // offset to the G3d_NameList_Header
|
||||
/* 08 */ void *entry[1]; // variable size
|
||||
/* 0c */
|
||||
} G3d_NameList;
|
||||
|
||||
typedef struct G3d_NameList_Header_ {
|
||||
/* 00 */ u16 element_size;
|
||||
/* 02 */ u16 data_section_size;
|
||||
/* 04 */ u8 data[4];
|
||||
/* 08 */
|
||||
} G3d_NameList_Header;
|
||||
|
||||
typedef struct G3d_InvBindMtx_ {
|
||||
/* 00 */ Mat4x3p mtx;
|
||||
/* 30 */ Mat3p unkMtx;
|
||||
/* 54 */
|
||||
} G3d_InvBindMtx;
|
||||
|
||||
typedef struct G3d_BoneMtxStruct_ {
|
||||
/* 00 */ u32 flag;
|
||||
/* 04 */ u8 mUnk_04[0x24];
|
||||
/* 28 */ Mat3p rot;
|
||||
/* 58 */ u8 mUnk_58[0xc];
|
||||
/* 64 */
|
||||
} G3d_BoneMtxStruct;
|
||||
|
||||
typedef enum {
|
||||
G3D_ANIMBIND_UNK = 0xff,
|
||||
G3D_ANIMBIND_EXISTS = 0x100,
|
||||
G3D_ANIMBIND_OFF = 0x200
|
||||
} G3d_AnimationBinds;
|
||||
|
||||
typedef struct G3d_Animation_ {
|
||||
/* 00 */ u8 mUnk_00[0x10];
|
||||
/* 10 */ struct G3d_Animation_ *next; // next animation in the list
|
||||
/* 14 */ u8 mUnk_14[0x5];
|
||||
/* 19 */ u8 numElmnts; // number of elements in the elementBinds array
|
||||
/* 1a */ u16 elementBinds[1]; // each bit corresponds to a bone/material and determines whether an animation exists for it
|
||||
/* 1c */
|
||||
} G3d_Animation;
|
||||
|
||||
// Structure representing the NSBMD model file
|
||||
typedef struct G3d_Model_ {
|
||||
/* 00 */ u32 size; // size of the model in bytes
|
||||
/* 04 */ u32 offSbc; // offset of the SBC commands list
|
||||
/* 08 */ u32 offMat; // offset of the material list
|
||||
/* 0c */ u32 offMesh; // offset of the mesh list
|
||||
/* 10 */ u32 offInvBMtx; // offset of the InvBindMatrix list
|
||||
/* 14 */ u8 dummy1;
|
||||
/* 15 */ u8 scalingHandler; // Determines which of the G3d_gScaleHandlers to use for this model
|
||||
/* 16 */ u8 textureHandler; // Determines which of the G3d_gTextureHandlers to use for this model
|
||||
/* 17 */ u8 numBones; // number of nodes
|
||||
/* 18 */ u8 numMat; // number of materials
|
||||
/* 19 */ u8 numMesh; // number of meshes
|
||||
/* 1a */ u8 dummy2[2];
|
||||
/* 1c */ q20 upScale;
|
||||
/* 20 */ q20 downScale;
|
||||
/* 24 */ u16 numVertex; // number of vertices
|
||||
/* 26 */ u16 numPolygon; // number of polygons
|
||||
/* 28 */ u16 numTriangle; // number of triangles
|
||||
/* 2a */ u16 numQuad; // number of quads
|
||||
/* 2c */ q4 boundingBoxMin[3]; // bounding box lower vertex
|
||||
/* 32 */ q4 boundingBoxMax[3]; // bounding box upper vertex
|
||||
/* 38 */ u8 dummy3[8];
|
||||
/* 40 */ G3d_NameList boneList; // bone list
|
||||
/* 4c */
|
||||
} G3d_Model;
|
||||
|
||||
static inline G3d_NameList *G3d_GetBoneList(const G3d_Model *mdl) {
|
||||
return (G3d_NameList *) &mdl->boneList;
|
||||
}
|
||||
|
||||
static inline void *G3d_GetMat(const G3d_Model *mdl) {
|
||||
|
||||
return (void *) ((u8 *) mdl + mdl->offMat);
|
||||
}
|
||||
|
||||
static inline G3d_NameList *G3d_GetMesh(const G3d_Model *mdl) {
|
||||
return (G3d_NameList *) ((u8 *) mdl + mdl->offMesh);
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
G3D_RENDEROBJ_FLAG_STORE = 0x1, // stores results in local cache
|
||||
G3D_RENDEROBJ_FLAG_SKIP_CMD = 0x2, // skips pushing geometry commands to the FIFO
|
||||
G3D_RENDEROBJ_FLAG_SKIP_SBC_DRAW = 0x4, // skips the execution of rendering commands
|
||||
G3D_RENDEROBJ_FLAG_SKIP_SBC_MTXCALC = 0x8, // skips the execution of matrix calculation commands
|
||||
G3D_RENDEROBJ_FLAG_ANIMMAP_OUTDATED = 0x10 // set when the animation map arrays in the render object are outdated
|
||||
} G3d_RenderObjFlag;
|
||||
|
||||
// Structure that handles the parameters for drawing a model
|
||||
typedef struct G3d_RenderObject_ {
|
||||
/* 00 */ u32 flag; // G3d_RenderObjFlag
|
||||
/* 04 */ G3d_Model *model;
|
||||
/* 08 */ G3d_Animation *matAnim; // material animation
|
||||
/* 0c */ void *mUnk_0c;
|
||||
/* 10 */ G3d_Animation *jntAnim; // joint animation
|
||||
/* 14 */ void *mUnk_14;
|
||||
/* 18 */ G3d_Animation *mUnk_18;
|
||||
/* 1c */ void *mUnk_1c;
|
||||
/* 20 */ G3d_CallbackFunction callbackFunction;
|
||||
/* 24 */ u8 callbackIdx; // index of the callbackFunction in the callback array of G3d_RenderState
|
||||
/* 25 */ u8 mUnk_25; // related to callback
|
||||
/* 26 */ u16 dummy_;
|
||||
/* 28 */ G3d_CallbackFunction callbackInitFunc; // initializes the G3d_RenderState callback array
|
||||
/* 2c */ void *modelRender; // pointer to the ModelRender that is rendering this model
|
||||
/* 30 */ u8 *unkCommandsList; // if not null, this command list is used instead of the one in the model
|
||||
/* 34 */ G3d_BoneMtxStruct *cacheJntAnm;
|
||||
/* 38 */ void *cacheMatAnm;
|
||||
/* 3c */ u32 matAnimBindMap[2];
|
||||
/* 44 */ u32 jntAnimBindMap[2];
|
||||
/* 4c */ u32 unkAnimBindMap[2];
|
||||
/* 54 */
|
||||
} G3d_RenderObject;
|
||||
|
||||
typedef struct G3d_Material_List_ {
|
||||
/* 00 */ u16 texture_pairings_off;
|
||||
/* 02 */ u16 palette_pairings_off;
|
||||
/* 04 */ G3d_NameList materials;
|
||||
/* 10 */
|
||||
} G3d_Material_List;
|
||||
|
||||
typedef struct G3d_Material_ {
|
||||
/* 00 */ u32 mUnk_00;
|
||||
/* 04 */ u32 dif_amb;
|
||||
/* 08 */ u32 spe_emi;
|
||||
/* 0c */ u32 polygon_attr;
|
||||
/* 10 */ u32 mUnk_10;
|
||||
/* 14 */ u32 teximage_params;
|
||||
/* 18 */ u32 mUnk_18;
|
||||
/* 1c */ u16 pltt_base;
|
||||
/* 1e */ u16 flag;
|
||||
/* 20 */ u16 width;
|
||||
/* 22 */ u16 height;
|
||||
/* 24 */ u8 mUnk_24[0x8];
|
||||
/* 2c */
|
||||
} G3d_Material;
|
||||
|
||||
typedef struct G3d_MaterialAnimation_ {
|
||||
/* 00 */ u32 flag;
|
||||
/* 04 */ u32 dif_amb;
|
||||
/* 08 */ u32 spe_emi;
|
||||
/* 0c */ u32 polygon_attr;
|
||||
/* 10 */ u32 teximage_params;
|
||||
/* 14 */ u32 pltt_base;
|
||||
/* 18 */ u8 mUnk_18[0x14];
|
||||
/* 2c */ u16 width;
|
||||
/* 2e */ u16 height;
|
||||
/* 30 */ u8 mUnk_30[0x8];
|
||||
/* 38 */
|
||||
} G3d_MaterialAnimation;
|
||||
|
||||
#define G3D_TEXIMAGE_PARM_TEX_COORD_MODE 0xc0000000
|
||||
|
||||
extern void *G3d_gScaleHandlers[3];
|
||||
extern void *G3d_gSRTTransformHandlers[3];
|
||||
extern void *G3d_gTextureHandlers[4];
|
||||
@@ -0,0 +1,110 @@
|
||||
#pragma once
|
||||
#include "g3d.h"
|
||||
|
||||
extern void PushGeometryCommand(u32 command, void *data, s32 length);
|
||||
|
||||
typedef enum {
|
||||
G3D_SBC_CMD_NOP = 0x0,
|
||||
G3D_SBC_CMD_END = 0x1,
|
||||
G3D_SBC_CMD_VIS = 0x2,
|
||||
G3D_SBC_CMD_007 = 0x7,
|
||||
G3D_SBC_CMD_008 = 0x8,
|
||||
G3D_SBC_CMD_SKN = 0x9,
|
||||
G3D_SBC_CMD_00A = 0xa,
|
||||
G3D_SBC_CMD_SCL = 0xb,
|
||||
G3D_SBC_CMD_00C = 0xc,
|
||||
G3D_SBC_CMD_00D = 0xd
|
||||
} G3d_SBC_Commands;
|
||||
|
||||
typedef enum {
|
||||
G3D_RENDERST_FLAG_BONE_VISIBLE = 0x1,
|
||||
G3D_RENDERST_FLAG_MAT_TRANSPARENT = 0x2,
|
||||
G3D_RENDERST_FLAG_VALID_NODE = 0x4,
|
||||
G3D_RENDERST_FLAG_VALID_MAT = 0x8,
|
||||
G3D_RENDERST_FLAG_VALID_BONEMTX = 0x10,
|
||||
G3D_RENDERST_FLAG_END = 0x20, // set when the end of the SBC command list is reached
|
||||
G3D_RENDERST_FLAG_SKIP_CALLBACK = 0x40, // skip callback
|
||||
G3D_RENDERST_FLAG_STORE = 0x80, // stores results in G3d_RenderObject local cache
|
||||
G3D_RENDERST_FLAG_SKIP_CMD = 0x100, // skips pushing geometry commands to the FIFO
|
||||
G3D_RENDERST_FLAG_SKIP_SBC_RENDER = 0x200, // skips the execution of rendering commands
|
||||
G3D_RENDERST_FLAG_SKIP_SBC_MTXCALC = 0x400 // skips the execution of matrix calculation commands
|
||||
} G3d_RenderStateFlag;
|
||||
|
||||
typedef struct G3d_RenderState_ {
|
||||
/* 00 */ u8 *currentCmd; // current command being processed
|
||||
/* 04 */ G3d_RenderObject *renderObj; // current render object being processed
|
||||
/* 08 */ u32 flag; // G3d_RenderStateFlag
|
||||
/* 0c */ G3d_CallbackFunction callbackFuncs[32]; // callback function for each SBC command
|
||||
/* 8c */ u8 callbackSegment[32]; // determines at which segment of the SBC command to invoke the callback
|
||||
/* ac */ u8 currentBoneId;
|
||||
/* ad */ u8 currentMaterialId;
|
||||
/* ae */ u8 currentBoneMtxId;
|
||||
/* af */ u8 dummy;
|
||||
/* b0 */ G3d_MaterialAnimation *matAnim;
|
||||
/* b4 */ void *mUnk_19;
|
||||
/* b8 */ u8 *visibilityPtr; // points to isVisible (0x187)
|
||||
/* bc */ u32 mUnk_bc[2];
|
||||
/* c4 */ u32 mUnk_c4[2];
|
||||
/* cc */ u32 mUnk_cc[2];
|
||||
/* d4 */ G3d_NameList *boneList;
|
||||
/* d8 */ const G3d_Material_List *materialList;
|
||||
/* dc */ G3d_NameList *meshList;
|
||||
/* e0 */ q20 upScale;
|
||||
/* e4 */ q20 downScale;
|
||||
/* e8 */ void *jntScalingHandler; // scaling handler
|
||||
/* ec */ void *jntSRTHandler; // SRT transform handler
|
||||
/* f0 */ void *textureHandler; // texture matrix handler
|
||||
/* f4 */ u8 mUnk_f4[0x93];
|
||||
/* 187 */ u8 isVisible;
|
||||
/* 188 */
|
||||
} G3d_RenderState;
|
||||
|
||||
typedef struct UnkStruct_0205ae08_ {
|
||||
/* 00 */ u8 mUnk_00[0x1400];
|
||||
/* 1400 */ struct {
|
||||
Mat4p mtx1;
|
||||
Mat3p mtx2;
|
||||
} mUnk_1400[64];
|
||||
} UnkStruct_0205ae08;
|
||||
|
||||
typedef void (*G3d_FuncSbc)(G3d_RenderState *, u32);
|
||||
extern G3d_FuncSbc G3d_FuncSbcTable[32];
|
||||
extern G3d_RenderState *G3d_gRenderState;
|
||||
extern UnkStruct_0205ae08 data_0205ae08;
|
||||
void G3d_Render(G3d_RenderObject *renderObj);
|
||||
|
||||
static inline u32 G3d_FindInBitArray(const u32 *arr, u32 idx) {
|
||||
return (u32) (arr[idx >> 5] & (1 << (idx & 31)));
|
||||
}
|
||||
|
||||
static inline void G3d_SetBitArray(u32 *arr, u32 idx) {
|
||||
arr[idx >> 5] |= 1 << (idx & 31);
|
||||
}
|
||||
|
||||
static inline void G3d_SetMtxMode_inline(u32 mode) {
|
||||
PushGeometryCommand(0x10, &mode, 1);
|
||||
}
|
||||
|
||||
static inline void G3d_RestoreMtx_inline(u32 idx) {
|
||||
PushGeometryCommand(0x14, &idx, 1);
|
||||
}
|
||||
|
||||
static inline void G3d_MtxMult33_inline(const Mat3p *m) {
|
||||
PushGeometryCommand(0x1a, (u32 *) m, 9);
|
||||
}
|
||||
|
||||
static inline void G3d_MtxMult43_inline(const Mat4x3p *m) {
|
||||
PushGeometryCommand(0x19, (u32 *) m, 12);
|
||||
}
|
||||
|
||||
static inline void G3d_MtxMult44_inline(const Mat4p *m) {
|
||||
PushGeometryCommand(0x18, (u32 *) m, 0x10);
|
||||
}
|
||||
|
||||
static inline void G3d_Scale_inline(q20 x, q20 y, q20 z) {
|
||||
Vec3p vec;
|
||||
vec.x = x;
|
||||
vec.y = y;
|
||||
vec.z = z;
|
||||
PushGeometryCommand(0x1b, (u32 *) &vec, 3);
|
||||
}
|
||||
@@ -8,6 +8,13 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define REG_GFX_FIFO (*(volatile u32 *) 0x04000400)
|
||||
#define GFX_FIFO_MTX_MODE (*(volatile u32 *) 0x04000440)
|
||||
#define GFX_FIFO_MTX_PUSH (*(volatile u32 *) 0x04000444)
|
||||
#define GFX_FIFO_MTX_POP (*(volatile u32 *) 0x04000448)
|
||||
#define GFX_FIFO_MTX_STORE (*(volatile u32 *) 0x0400044c)
|
||||
#define GFX_FIFO_MTX_RESTORE (*(volatile u32 *) 0x04000450)
|
||||
#define GFX_FIFO_MTX_IDENTITY (*(volatile u32 *) 0x04000454)
|
||||
#define GFX_FIFO_SWAP_BUFFERS (*(volatile u32 *) 0x04000540)
|
||||
#define GFX_FIFO_VIEWPORT (*(volatile u32 *) 0x04000580)
|
||||
#define REG_GFX_RAM_COUNT (*(volatile u16 *) 0x04000604)
|
||||
|
||||
@@ -0,0 +1,855 @@
|
||||
#include "nds/g3d/sbc.h"
|
||||
#include "DTCM/UnkStruct_027e037c.h"
|
||||
#include "nds/gfx.h"
|
||||
|
||||
#define G3D_SBC_CMD_MASK 0x1f
|
||||
#define G3D_SBC_FLG_MASK 0xe0
|
||||
#define GX_ST(s, t) ((u32) ((u16) (s16) (s >> 8) | ((u16) (s16) (t >> 8) << 16)))
|
||||
#define GX_PACK_TEXCOORD_PARAM(s, t) (GX_ST((s), (t)))
|
||||
|
||||
extern void Fill256(unk32, unk16 *, unk32);
|
||||
extern void Fill32(unk32, u32 *, unk32);
|
||||
extern void FlushGfxQueue();
|
||||
extern s32 func_0200598c(Mat4p *matrix);
|
||||
extern Mat4x3p *func_02018450();
|
||||
extern Mat4x3p *func_02018738();
|
||||
extern Mat4x3p *func_02018770();
|
||||
extern s32 func_020059bc(Mat3p *matrix);
|
||||
extern void func_0200567c(unk32 param1);
|
||||
extern void func_02005644(Mat4x3p *matrix);
|
||||
extern void func_01ffa94c(const void *param1, u32 param2);
|
||||
extern Mat3p gGeomMatrix;
|
||||
extern Vec3p gGeomTranslation;
|
||||
extern void G3d_GetCurrentMtx(Mat4x3p *mtx1, Mat3p *mtx2);
|
||||
|
||||
UnkStruct_0205ae08 data_0205ae08;
|
||||
|
||||
// Renders all SBC commands until the end of the list
|
||||
void G3d_RenderSBCCommands(G3d_RenderState *renderState) {
|
||||
do {
|
||||
renderState->flag &= ~G3D_RENDERST_FLAG_SKIP_CALLBACK;
|
||||
(*G3d_FuncSbcTable[(*renderState->currentCmd) & G3D_SBC_CMD_MASK])(renderState, (*renderState->currentCmd) &
|
||||
(u32) G3D_SBC_FLG_MASK);
|
||||
} while (!(renderState->flag & G3D_RENDERST_FLAG_END));
|
||||
}
|
||||
|
||||
// Initializes the render state and starts rendering the SBC command list
|
||||
void G3d_InitRenderState(G3d_RenderState *renderState, G3d_RenderObject *renderObj) {
|
||||
Fill256(0, (short *) renderState, sizeof(*renderState));
|
||||
renderState->mUnk_c4[0] = 1;
|
||||
renderState->flag = G3D_RENDERST_FLAG_BONE_VISIBLE;
|
||||
|
||||
if (renderObj->unkCommandsList) {
|
||||
renderState->currentCmd = renderObj->unkCommandsList;
|
||||
} else {
|
||||
renderState->currentCmd = (u8 *) renderObj->model + renderObj->model->offSbc;
|
||||
}
|
||||
|
||||
renderState->renderObj = renderObj;
|
||||
renderState->boneList = G3d_GetBoneList(renderObj->model);
|
||||
renderState->materialList = G3d_GetMat(renderObj->model);
|
||||
renderState->meshList = G3d_GetMesh(renderObj->model);
|
||||
renderState->jntScalingHandler = G3d_gScaleHandlers[renderObj->model->scalingHandler];
|
||||
renderState->jntSRTHandler = G3d_gSRTTransformHandlers[renderObj->model->scalingHandler];
|
||||
renderState->textureHandler = G3d_gTextureHandlers[renderObj->model->textureHandler];
|
||||
renderState->upScale = renderObj->model->upScale;
|
||||
renderState->downScale = renderObj->model->downScale;
|
||||
if (renderObj->callbackFunction && renderObj->callbackIdx < 32) {
|
||||
renderState->callbackFuncs[renderObj->callbackIdx] = renderObj->callbackFunction;
|
||||
renderState->callbackSegment[renderObj->callbackIdx] = renderObj->mUnk_25;
|
||||
}
|
||||
|
||||
if (renderObj->flag & G3D_RENDEROBJ_FLAG_STORE) {
|
||||
renderState->flag |= G3D_RENDERST_FLAG_STORE;
|
||||
}
|
||||
|
||||
if (renderObj->flag & G3D_RENDEROBJ_FLAG_SKIP_CMD) {
|
||||
renderState->flag |= G3D_RENDERST_FLAG_SKIP_CMD;
|
||||
}
|
||||
|
||||
if (renderObj->flag & G3D_RENDEROBJ_FLAG_SKIP_SBC_DRAW) {
|
||||
renderState->flag |= G3D_RENDERST_FLAG_SKIP_SBC_RENDER;
|
||||
}
|
||||
|
||||
if (renderObj->flag & G3D_RENDEROBJ_FLAG_SKIP_SBC_MTXCALC) {
|
||||
renderState->flag |= G3D_RENDERST_FLAG_SKIP_SBC_MTXCALC;
|
||||
}
|
||||
|
||||
if (renderObj->callbackInitFunc) {
|
||||
(*renderObj->callbackInitFunc)(renderState);
|
||||
}
|
||||
|
||||
G3d_RenderSBCCommands(renderState);
|
||||
|
||||
renderObj->flag &= ~G3D_RENDEROBJ_FLAG_STORE;
|
||||
}
|
||||
|
||||
// Sets the bits in the anim array according to the map data of the animation
|
||||
void G3d_SetRenderObjAnimationMap(u32 *arr, const G3d_Animation *anim) {
|
||||
while (anim) {
|
||||
int i;
|
||||
for (i = 0; i < anim->numElmnts; i++) {
|
||||
if (anim->elementBinds[i] & G3D_ANIMBIND_EXISTS) {
|
||||
arr[i >> 5] |= 1 << (i & 31);
|
||||
}
|
||||
}
|
||||
anim = anim->next;
|
||||
}
|
||||
}
|
||||
|
||||
// Renders a model by processing the SBC command list
|
||||
void G3d_Render(G3d_RenderObject *renderObj) {
|
||||
if ((renderObj->flag & G3D_RENDEROBJ_FLAG_ANIMMAP_OUTDATED) == G3D_RENDEROBJ_FLAG_ANIMMAP_OUTDATED) {
|
||||
Fill32(0, &renderObj->matAnimBindMap[0], 8);
|
||||
Fill32(0, &renderObj->jntAnimBindMap[0], 8);
|
||||
Fill32(0, &renderObj->unkAnimBindMap[0], 8);
|
||||
|
||||
if (renderObj->matAnim) {
|
||||
G3d_SetRenderObjAnimationMap(&renderObj->matAnimBindMap[0], renderObj->matAnim);
|
||||
}
|
||||
if (renderObj->jntAnim) {
|
||||
G3d_SetRenderObjAnimationMap(&renderObj->jntAnimBindMap[0], renderObj->jntAnim);
|
||||
}
|
||||
if (renderObj->mUnk_18) {
|
||||
G3d_SetRenderObjAnimationMap(&renderObj->unkAnimBindMap[0], renderObj->mUnk_18);
|
||||
}
|
||||
renderObj->flag &= ~G3D_RENDEROBJ_FLAG_ANIMMAP_OUTDATED;
|
||||
}
|
||||
|
||||
if (G3d_gRenderState) {
|
||||
G3d_InitRenderState(G3d_gRenderState, renderObj);
|
||||
} else {
|
||||
G3d_RenderState rs;
|
||||
G3d_gRenderState = &rs;
|
||||
G3d_InitRenderState(&rs, renderObj);
|
||||
G3d_gRenderState = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Renders the NOP SBC command
|
||||
void G3d_SBCRender_NOP(G3d_RenderState *renderState, u32) {
|
||||
if (renderState->callbackFuncs[G3D_SBC_CMD_NOP]) {
|
||||
(*renderState->callbackFuncs[G3D_SBC_CMD_NOP])(renderState);
|
||||
}
|
||||
renderState->currentCmd++;
|
||||
}
|
||||
|
||||
// Renders the END SBC command
|
||||
void G3d_SBCRender_END(G3d_RenderState *renderState, u32) {
|
||||
if (renderState->callbackFuncs[G3D_SBC_CMD_END]) {
|
||||
(*renderState->callbackFuncs[G3D_SBC_CMD_END])(renderState);
|
||||
}
|
||||
renderState->flag |= G3D_RENDERST_FLAG_END;
|
||||
}
|
||||
|
||||
// Renders the SBC command 0x7 (unknown)
|
||||
void G3d_SBCRender_007(G3d_RenderState *renderState, u32 opCode) {
|
||||
|
||||
u32 totalArgs = 2;
|
||||
|
||||
static u32 funcArgs[] = {0x1b171012, // MTX_POP | MTX_MODE | MTX_LOAD_4x3 | MTX_SCALE
|
||||
1, // MTX_MODE = Position
|
||||
2, 0x1000, 0, 0, 0, 0x1000, 0, 0, 0, 0x1000, // Identity MTX
|
||||
0, 0, 0, 0, 0, 0};
|
||||
|
||||
Vec3p *translationVec = (Vec3p *) &funcArgs[12];
|
||||
Vec3p *scaleVec = (Vec3p *) &funcArgs[15];
|
||||
Mat4p currentMtx;
|
||||
u8 callbackSkip;
|
||||
u32 callbackSegment;
|
||||
|
||||
if (renderState->flag & G3D_RENDERST_FLAG_SKIP_SBC_RENDER) {
|
||||
if (opCode == 0x40 || opCode == 0x60) {
|
||||
totalArgs++;
|
||||
}
|
||||
if (opCode == 0x20 || opCode == 0x60) {
|
||||
totalArgs++;
|
||||
}
|
||||
renderState->currentCmd += totalArgs;
|
||||
return;
|
||||
}
|
||||
|
||||
if (opCode == 0x40 || opCode == 0x60) {
|
||||
totalArgs++;
|
||||
|
||||
if (!(renderState->flag & G3D_RENDERST_FLAG_SKIP_CMD)) {
|
||||
u32 matrixIndex;
|
||||
if (opCode == 0x40) {
|
||||
matrixIndex = *(renderState->currentCmd + 2);
|
||||
} else {
|
||||
matrixIndex = *(renderState->currentCmd + 3);
|
||||
}
|
||||
PushGeometryCommand(0x14, &matrixIndex, 1); // MTX_RESTORE
|
||||
}
|
||||
}
|
||||
|
||||
if (renderState->callbackFuncs[G3D_SBC_CMD_007]) {
|
||||
callbackSegment = renderState->callbackSegment[G3D_SBC_CMD_007];
|
||||
} else {
|
||||
callbackSegment = 0;
|
||||
}
|
||||
|
||||
if (callbackSegment == 1) {
|
||||
renderState->flag &= ~G3D_RENDERST_FLAG_SKIP_CALLBACK;
|
||||
(*renderState->callbackFuncs[G3D_SBC_CMD_007])(renderState);
|
||||
if (renderState->callbackFuncs[G3D_SBC_CMD_007]) {
|
||||
callbackSegment = renderState->callbackSegment[G3D_SBC_CMD_007];
|
||||
} else {
|
||||
callbackSegment = 0;
|
||||
}
|
||||
callbackSkip = (renderState->flag & G3D_RENDERST_FLAG_SKIP_CALLBACK);
|
||||
} else {
|
||||
callbackSkip = 0;
|
||||
}
|
||||
|
||||
if (!(renderState->flag & G3D_RENDERST_FLAG_SKIP_CMD) && !callbackSkip) {
|
||||
FlushGfxQueue();
|
||||
|
||||
REG_GFX_FIFO = 0x151110; // MTX_MODE | MTX_PUSH | MTX_IDENTITY
|
||||
REG_GFX_FIFO = 0; // MTX_MODE = Projection
|
||||
|
||||
REG_GFX_FIFO = 0;
|
||||
|
||||
while (func_0200598c(¤tMtx))
|
||||
;
|
||||
|
||||
if (data_027e037c.flags & 1) {
|
||||
const Mat4x3p *mtx1 = func_02018738();
|
||||
Mat4p mtx2;
|
||||
|
||||
Mat4x3p_CopyToMat4p(mtx1, &mtx2);
|
||||
Mat4p_Multiply(¤tMtx, &mtx2, ¤tMtx);
|
||||
} else if (data_027e037c.flags & 2) {
|
||||
const Mat4x3p *mtx1 = &data_027e037c.mUnk_04c;
|
||||
Mat4p mtx2;
|
||||
|
||||
Mat4x3p_CopyToMat4p(mtx1, &mtx2);
|
||||
Mat4p_Multiply(¤tMtx, &mtx2, ¤tMtx);
|
||||
}
|
||||
|
||||
translationVec->x = currentMtx.wColumn.x;
|
||||
translationVec->y = currentMtx.wColumn.y;
|
||||
translationVec->z = currentMtx.wColumn.z;
|
||||
|
||||
scaleVec->x = Vec3p_Length((Vec3p *) ¤tMtx.xColumn);
|
||||
scaleVec->y = Vec3p_Length((Vec3p *) ¤tMtx.yColumn);
|
||||
scaleVec->z = Vec3p_Length((Vec3p *) ¤tMtx.zColumn);
|
||||
|
||||
if (data_027e037c.flags & 1) {
|
||||
REG_GFX_FIFO = 0x171012; // MTX_POP | MTX_MODE | MTX_LOAD_4x3
|
||||
Stream32(&funcArgs[1], ®_GFX_FIFO, 8); // MTX_MODE = Position
|
||||
Stream32(func_02018770(), ®_GFX_FIFO, 0x30);
|
||||
|
||||
REG_GFX_FIFO = 0x1b19; // MTX_MULT_4x3 | MTX_SCALE
|
||||
Stream32(&funcArgs[3], ®_GFX_FIFO, 0x3c); // Identity MTX
|
||||
} else if (data_027e037c.flags & 2) {
|
||||
REG_GFX_FIFO = 0x171012; // MTX_POP | MTX_MODE | MTX_LOAD_4x3
|
||||
Stream32(&funcArgs[1], ®_GFX_FIFO, 8); // MTX_MODE = Position
|
||||
Stream32(func_02018450(), ®_GFX_FIFO, 0x30);
|
||||
|
||||
REG_GFX_FIFO = 0x1b19; // MTX_MULT_4x3 | MTX_SCALE
|
||||
Stream32(&funcArgs[3], ®_GFX_FIFO, 0x3c); // Identity MTX
|
||||
} else {
|
||||
Stream32(&funcArgs, ®_GFX_FIFO, 0x48); // MTX_POP | MTX_MODE | MTX_LOAD_4x3 | MTX_SCALE
|
||||
}
|
||||
}
|
||||
|
||||
if (callbackSegment == 3) {
|
||||
renderState->flag &= ~G3D_RENDERST_FLAG_SKIP_CALLBACK;
|
||||
(*renderState->callbackFuncs[G3D_SBC_CMD_007])(renderState);
|
||||
callbackSkip = renderState->flag & G3D_RENDERST_FLAG_SKIP_CALLBACK;
|
||||
} else {
|
||||
callbackSkip = 0;
|
||||
}
|
||||
|
||||
if (opCode == 0x20 || opCode == 0x60) {
|
||||
totalArgs++;
|
||||
|
||||
if (!callbackSkip) {
|
||||
if (!(renderState->flag & G3D_RENDERST_FLAG_SKIP_CMD)) {
|
||||
u32 matrixIndex = *(renderState->currentCmd + 2);
|
||||
PushGeometryCommand(0x13, &matrixIndex, 1); // MTX_STORE
|
||||
}
|
||||
}
|
||||
}
|
||||
renderState->currentCmd += totalArgs;
|
||||
}
|
||||
|
||||
// Renders the SBC command 0x8 (unknown)
|
||||
void G3d_SBCRender_008(G3d_RenderState *renderState, u32 opCode) {
|
||||
u32 totalArgs = 2;
|
||||
Mat4p currentMtx;
|
||||
|
||||
static u32 funcArgs[] = {0x1b171012, // MTX_POP | MTX_MODE | MTX_LOAD_4x3 | MTX_SCALE
|
||||
1, // MTX_MODE = Position
|
||||
2, 0x1000, 0, 0, 0, 0x1000, 0, 0, 0, 0x1000, // Identity MTX
|
||||
0, 0, 0, 0, 0, 0};
|
||||
|
||||
Vec3p *translationVec = (Vec3p *) &funcArgs[12];
|
||||
Vec3p *scaleVec = (Vec3p *) &funcArgs[15];
|
||||
Mat4x3p *mtx = (Mat4x3p *) &funcArgs[3];
|
||||
u8 callbackSkip;
|
||||
u32 callbackSegment;
|
||||
|
||||
if (renderState->flag & G3D_RENDERST_FLAG_SKIP_SBC_RENDER) {
|
||||
if (opCode == 0x40 || opCode == 0x60) {
|
||||
totalArgs++;
|
||||
}
|
||||
if (opCode == 0x20 || opCode == 0x60) {
|
||||
totalArgs++;
|
||||
}
|
||||
renderState->currentCmd += totalArgs;
|
||||
return;
|
||||
}
|
||||
|
||||
if (opCode == 0x40 || opCode == 0x60) {
|
||||
totalArgs++;
|
||||
if (!(renderState->flag & G3D_RENDERST_FLAG_SKIP_CMD)) {
|
||||
u32 matrixIndex;
|
||||
if (opCode == 0x40) {
|
||||
matrixIndex = *(renderState->currentCmd + 2);
|
||||
} else {
|
||||
matrixIndex = *(renderState->currentCmd + 3);
|
||||
}
|
||||
PushGeometryCommand(0x14, &matrixIndex, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (renderState->callbackFuncs[G3D_SBC_CMD_008]) {
|
||||
callbackSegment = renderState->callbackSegment[G3D_SBC_CMD_008];
|
||||
} else {
|
||||
callbackSegment = 0;
|
||||
}
|
||||
|
||||
if (callbackSegment == 1) {
|
||||
renderState->flag &= ~G3D_RENDERST_FLAG_SKIP_CALLBACK;
|
||||
(*renderState->callbackFuncs[G3D_SBC_CMD_008])(renderState);
|
||||
if (renderState->callbackFuncs[G3D_SBC_CMD_008]) {
|
||||
callbackSegment = renderState->callbackSegment[G3D_SBC_CMD_008];
|
||||
} else {
|
||||
callbackSegment = 0;
|
||||
}
|
||||
callbackSkip = (renderState->flag & G3D_RENDERST_FLAG_SKIP_CALLBACK);
|
||||
} else {
|
||||
callbackSkip = 0;
|
||||
}
|
||||
|
||||
if (!(renderState->flag & G3D_RENDERST_FLAG_SKIP_CMD) && !callbackSkip) {
|
||||
FlushGfxQueue();
|
||||
|
||||
REG_GFX_FIFO = 0x151110; // MTX_MODE | MTX_PUSH | MTX_IDENTITY
|
||||
REG_GFX_FIFO = 0; // MTX_MODE = Projection
|
||||
|
||||
REG_GFX_FIFO = 0;
|
||||
|
||||
while (func_0200598c(¤tMtx))
|
||||
;
|
||||
|
||||
if (data_027e037c.flags & 1) {
|
||||
const Mat4x3p *mtx1 = func_02018738();
|
||||
Mat4p mtx2;
|
||||
|
||||
Mat4x3p_CopyToMat4p(mtx1, &mtx2);
|
||||
Mat4p_Multiply(¤tMtx, &mtx2, ¤tMtx);
|
||||
} else if (data_027e037c.flags & 2) {
|
||||
const Mat4x3p *mtx1 = &data_027e037c.mUnk_04c;
|
||||
Mat4p mtx2;
|
||||
|
||||
Mat4x3p_CopyToMat4p(mtx1, &mtx2);
|
||||
Mat4p_Multiply(¤tMtx, &mtx2, ¤tMtx);
|
||||
}
|
||||
|
||||
translationVec->x = currentMtx.wColumn.x;
|
||||
translationVec->y = currentMtx.wColumn.y;
|
||||
translationVec->z = currentMtx.wColumn.z;
|
||||
|
||||
scaleVec->x = Vec3p_Length((Vec3p *) ¤tMtx.xColumn);
|
||||
scaleVec->y = Vec3p_Length((Vec3p *) ¤tMtx.yColumn);
|
||||
scaleVec->z = Vec3p_Length((Vec3p *) ¤tMtx.zColumn);
|
||||
|
||||
if (currentMtx.yColumn.y != 0 || currentMtx.yColumn.z != 0) {
|
||||
Vec3p_Normalize((Vec3p *) ¤tMtx.yColumn, (Vec3p *) &mtx->yColumn);
|
||||
|
||||
mtx->zColumn.y = -mtx->yColumn.z;
|
||||
mtx->zColumn.z = mtx->yColumn.y;
|
||||
} else {
|
||||
Vec3p_Normalize((Vec3p *) ¤tMtx.zColumn, (Vec3p *) &mtx->zColumn);
|
||||
|
||||
mtx->yColumn.z = -mtx->zColumn.y;
|
||||
mtx->yColumn.y = mtx->zColumn.z;
|
||||
}
|
||||
|
||||
if (data_027e037c.flags & 1) {
|
||||
REG_GFX_FIFO = 0x171012; // MTX_POP | MTX_MODE | MTX_LOAD_4x3
|
||||
Stream32(&funcArgs[1], ®_GFX_FIFO, 8); // MTX_MODE = Position
|
||||
Stream32(func_02018770(), ®_GFX_FIFO, 0x30);
|
||||
|
||||
REG_GFX_FIFO = 0x1b19; // MTX_MULT_4x3 | MTX_SCALE
|
||||
Stream32(&funcArgs[3], ®_GFX_FIFO, 0x3c); // Identity MTX
|
||||
} else if (data_027e037c.flags & 2) {
|
||||
REG_GFX_FIFO = 0x171012; // MTX_POP | MTX_MODE | MTX_LOAD_4x3
|
||||
Stream32(&funcArgs[1], ®_GFX_FIFO, 8); // MTX_MODE = Position
|
||||
Stream32(func_02018450(), ®_GFX_FIFO, 0x30);
|
||||
|
||||
REG_GFX_FIFO = 0x1b19; // MTX_MULT_4x3 | MTX_SCALE
|
||||
Stream32(&funcArgs[3], ®_GFX_FIFO, 0x3c); // Identity MTX
|
||||
} else {
|
||||
Stream32(&funcArgs, ®_GFX_FIFO, 0x48); // MTX_POP | MTX_MODE | MTX_LOAD_4x3 | MTX_SCALE
|
||||
}
|
||||
}
|
||||
|
||||
if (callbackSegment == 3) {
|
||||
renderState->flag &= ~G3D_RENDERST_FLAG_SKIP_CALLBACK;
|
||||
(*renderState->callbackFuncs[G3D_SBC_CMD_008])(renderState);
|
||||
callbackSkip = renderState->flag & G3D_RENDERST_FLAG_SKIP_CALLBACK;
|
||||
} else {
|
||||
callbackSkip = 0;
|
||||
}
|
||||
|
||||
if (opCode == 0x20 || opCode == 0x60) {
|
||||
totalArgs++;
|
||||
|
||||
if (!callbackSkip) {
|
||||
if (!(renderState->flag & G3D_RENDERST_FLAG_SKIP_CMD)) {
|
||||
u32 matrixIndex = *(renderState->currentCmd + 2);
|
||||
PushGeometryCommand(0x13, &matrixIndex, 1); // MTX_STORE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
renderState->currentCmd += totalArgs;
|
||||
}
|
||||
|
||||
// Renders the Skinning Equation SBC command
|
||||
void G3d_SBCRender_SKN(G3d_RenderState *renderState, u32) {
|
||||
G3d_InvBindMtx *invBMtx =
|
||||
(G3d_InvBindMtx *) ((u8 *) renderState->renderObj->model + renderState->renderObj->model->offInvBMtx);
|
||||
u32 numTerms = *(renderState->currentCmd + 2);
|
||||
s64 weight = 0;
|
||||
u8 *termPtr = renderState->currentCmd + 3;
|
||||
u32 i;
|
||||
struct {
|
||||
Mat4x3p mtx1;
|
||||
Mat3p mtx2;
|
||||
} mtxStruct;
|
||||
Mat4p *mat4x;
|
||||
Mat3p *mat3x;
|
||||
|
||||
Fill256(0, (unk16 *) &mtxStruct, sizeof(mtxStruct));
|
||||
FlushGfxQueue();
|
||||
|
||||
GFX_FIFO_MTX_MODE = 0; // Projection
|
||||
GFX_FIFO_MTX_STORE = 1;
|
||||
GFX_FIFO_MTX_IDENTITY = 0;
|
||||
GFX_FIFO_MTX_MODE = 2; // Position + Vector
|
||||
|
||||
for (i = 0; i < numTerms; i++) {
|
||||
u32 jntIndex = *(termPtr + 1);
|
||||
u32 unk = G3d_FindInBitArray(&renderState->mUnk_cc[0], jntIndex);
|
||||
|
||||
mat4x = &data_0205ae08.mUnk_1400[jntIndex].mtx1;
|
||||
if (!unk) {
|
||||
G3d_SetBitArray(&renderState->mUnk_cc[0], jntIndex);
|
||||
|
||||
GFX_FIFO_MTX_RESTORE = (*termPtr);
|
||||
GFX_FIFO_MTX_MODE = 1; // Position
|
||||
func_0200567c(&invBMtx[jntIndex].mtx);
|
||||
}
|
||||
|
||||
if (i != 0) {
|
||||
mtxStruct.mtx2.xColumn.x += (weight * mat3x->xColumn.x) >> 0xc;
|
||||
mtxStruct.mtx2.xColumn.y += (weight * mat3x->xColumn.y) >> 0xc;
|
||||
mtxStruct.mtx2.xColumn.z += (weight * mat3x->xColumn.z) >> 0xc;
|
||||
|
||||
mtxStruct.mtx2.yColumn.x += (weight * mat3x->yColumn.x) >> 0xc;
|
||||
mtxStruct.mtx2.yColumn.y += (weight * mat3x->yColumn.y) >> 0xc;
|
||||
mtxStruct.mtx2.yColumn.z += (weight * mat3x->yColumn.z) >> 0xc;
|
||||
|
||||
mtxStruct.mtx2.zColumn.x += (weight * mat3x->zColumn.x) >> 0xc;
|
||||
mtxStruct.mtx2.zColumn.y += (weight * mat3x->zColumn.y) >> 0xc;
|
||||
mtxStruct.mtx2.zColumn.z += (weight * mat3x->zColumn.z) >> 0xc;
|
||||
}
|
||||
|
||||
if (!unk) {
|
||||
while (func_0200598c(mat4x))
|
||||
;
|
||||
GFX_FIFO_MTX_MODE = 2; // Position + Vector
|
||||
func_02005698(&invBMtx[jntIndex].unkMtx);
|
||||
}
|
||||
|
||||
weight = *(termPtr + 2) << 4;
|
||||
|
||||
mtxStruct.mtx1.xColumn.x += (weight * mat4x->xColumn.x) >> 0xc;
|
||||
mtxStruct.mtx1.xColumn.y += (weight * mat4x->xColumn.y) >> 0xc;
|
||||
mtxStruct.mtx1.xColumn.z += (weight * mat4x->xColumn.z) >> 0xc;
|
||||
|
||||
mtxStruct.mtx1.yColumn.x += (weight * mat4x->yColumn.x) >> 0xc;
|
||||
mtxStruct.mtx1.yColumn.y += (weight * mat4x->yColumn.y) >> 0xc;
|
||||
mtxStruct.mtx1.yColumn.z += (weight * mat4x->yColumn.z) >> 0xc;
|
||||
|
||||
mtxStruct.mtx1.zColumn.x += (weight * mat4x->zColumn.x) >> 0xc;
|
||||
mtxStruct.mtx1.zColumn.y += (weight * mat4x->zColumn.y) >> 0xc;
|
||||
mtxStruct.mtx1.zColumn.z += (weight * mat4x->zColumn.z) >> 0xc;
|
||||
|
||||
mtxStruct.mtx1.wColumn.x += (weight * mat4x->wColumn.x) >> 0xc;
|
||||
mtxStruct.mtx1.wColumn.y += (weight * mat4x->wColumn.y) >> 0xc;
|
||||
mtxStruct.mtx1.wColumn.z += (weight * mat4x->wColumn.z) >> 0xc;
|
||||
|
||||
termPtr += 3;
|
||||
mat3x = &data_0205ae08.mUnk_1400[jntIndex].mtx2;
|
||||
|
||||
if (!unk) {
|
||||
while (func_020059bc(mat3x))
|
||||
;
|
||||
}
|
||||
}
|
||||
mtxStruct.mtx2.xColumn.x += (weight * mat3x->xColumn.x) >> 0xc;
|
||||
mtxStruct.mtx2.xColumn.y += (weight * mat3x->xColumn.y) >> 0xc;
|
||||
mtxStruct.mtx2.xColumn.z += (weight * mat3x->xColumn.z) >> 0xc;
|
||||
|
||||
mtxStruct.mtx2.yColumn.x += (weight * mat3x->yColumn.x) >> 0xc;
|
||||
mtxStruct.mtx2.yColumn.y += (weight * mat3x->yColumn.y) >> 0xc;
|
||||
mtxStruct.mtx2.yColumn.z += (weight * mat3x->yColumn.z) >> 0xc;
|
||||
|
||||
mtxStruct.mtx2.zColumn.x += (weight * mat3x->zColumn.x) >> 0xc;
|
||||
mtxStruct.mtx2.zColumn.y += (weight * mat3x->zColumn.y) >> 0xc;
|
||||
mtxStruct.mtx2.zColumn.z += (weight * mat3x->zColumn.z) >> 0xc;
|
||||
|
||||
func_02005644((const Mat4x3p *) &mtxStruct.mtx2);
|
||||
GFX_FIFO_MTX_MODE = 1; // Position
|
||||
func_02005644(&mtxStruct.mtx1);
|
||||
GFX_FIFO_MTX_MODE = 0; // Projection
|
||||
GFX_FIFO_MTX_RESTORE = 1;
|
||||
GFX_FIFO_MTX_MODE = 2; // Position + Vector
|
||||
GFX_FIFO_MTX_STORE = (*(renderState->currentCmd + 1));
|
||||
renderState->currentCmd += 3 + *(renderState->currentCmd + 2) * 3;
|
||||
}
|
||||
|
||||
// Renders the SBC command 0xA (unknown)
|
||||
void G3d_SBCRender_00A(G3d_RenderState *renderState, u32) {
|
||||
u32 callbackSkip;
|
||||
u32 callbackSegment;
|
||||
|
||||
if (renderState->callbackFuncs[G3D_SBC_CMD_00A]) {
|
||||
callbackSegment = renderState->callbackSegment[G3D_SBC_CMD_00A];
|
||||
} else {
|
||||
callbackSegment = 0;
|
||||
}
|
||||
|
||||
if (callbackSegment == 1) {
|
||||
renderState->flag &= ~G3D_RENDERST_FLAG_SKIP_CALLBACK;
|
||||
(*renderState->callbackFuncs[G3D_SBC_CMD_00A])(renderState);
|
||||
if (renderState->callbackFuncs[G3D_SBC_CMD_00A]) {
|
||||
callbackSegment = renderState->callbackSegment[G3D_SBC_CMD_00A];
|
||||
} else {
|
||||
callbackSegment = 0;
|
||||
}
|
||||
callbackSkip = (renderState->flag & G3D_RENDERST_FLAG_SKIP_CALLBACK);
|
||||
} else {
|
||||
callbackSkip = 0;
|
||||
}
|
||||
|
||||
if (!(renderState->flag & G3D_RENDERST_FLAG_SKIP_CMD) && !callbackSkip) {
|
||||
u32 int1;
|
||||
u32 int2;
|
||||
int1 = (u32) ((*(renderState->currentCmd + 1)) | (*(renderState->currentCmd + 2) << 8) |
|
||||
(*(renderState->currentCmd + 3) << 16) | (*(renderState->currentCmd + 4) << 24));
|
||||
|
||||
int2 = (u32) ((*(renderState->currentCmd + 5) << 0) | (*(renderState->currentCmd + 6) << 8) |
|
||||
(*(renderState->currentCmd + 7) << 16) | (*(renderState->currentCmd + 8) << 24));
|
||||
|
||||
func_01ffa94c(renderState->currentCmd + int1, int2);
|
||||
}
|
||||
|
||||
if (callbackSegment == 3) {
|
||||
renderState->flag &= ~G3D_RENDERST_FLAG_SKIP_CALLBACK;
|
||||
(*renderState->callbackFuncs[G3D_SBC_CMD_00A])(renderState);
|
||||
callbackSkip = renderState->flag & G3D_RENDERST_FLAG_SKIP_CALLBACK;
|
||||
} else {
|
||||
callbackSkip = 0;
|
||||
}
|
||||
|
||||
renderState->currentCmd += 1 + sizeof(u32) + sizeof(u32);
|
||||
}
|
||||
|
||||
// Renders the Scale SBC command
|
||||
void G3d_SBCRender_SCL(G3d_RenderState *renderState, u32 opCode) {
|
||||
Vec3p scaleVector;
|
||||
|
||||
if (!(renderState->flag & G3D_RENDERST_FLAG_SKIP_CMD) && !(renderState->flag & G3D_RENDERST_FLAG_SKIP_SBC_RENDER)) {
|
||||
if (opCode == 0) {
|
||||
scaleVector.x = scaleVector.y = scaleVector.z = renderState->upScale;
|
||||
} else {
|
||||
scaleVector.x = scaleVector.y = scaleVector.z = renderState->downScale;
|
||||
}
|
||||
PushGeometryCommand(0x1b, &scaleVector.x, 3); // MTX_SCALE
|
||||
}
|
||||
renderState->currentCmd += 1;
|
||||
}
|
||||
|
||||
// Renders the SBC command 0xC (unknown)
|
||||
void G3d_SBCRender_00C(G3d_RenderState *renderState, u32) {
|
||||
if (!(renderState->flag & G3D_RENDERST_FLAG_SKIP_SBC_RENDER) && (renderState->flag & G3D_RENDERST_FLAG_BONE_VISIBLE)) {
|
||||
u32 callbackSkip;
|
||||
u32 callbackSegment;
|
||||
u32 mtxModeTex;
|
||||
|
||||
if ((renderState->matAnim->teximage_params & G3D_TEXIMAGE_PARM_TEX_COORD_MODE) != 0x80000000) { // Normal source
|
||||
static u32 funcArgs[] = {0x2a, 0};
|
||||
renderState->matAnim->teximage_params &= ~G3D_TEXIMAGE_PARM_TEX_COORD_MODE;
|
||||
renderState->matAnim->teximage_params |= 0x80000000; // Normal source
|
||||
|
||||
funcArgs[1] = renderState->matAnim->teximage_params;
|
||||
PushGeometryCommand(funcArgs[0], &funcArgs[1], 1);
|
||||
}
|
||||
|
||||
mtxModeTex = 3;
|
||||
PushGeometryCommand(0x10, &mtxModeTex, 1);
|
||||
|
||||
if (renderState->callbackFuncs[G3D_SBC_CMD_00C]) {
|
||||
callbackSegment = renderState->callbackSegment[G3D_SBC_CMD_00C];
|
||||
} else {
|
||||
callbackSegment = 0;
|
||||
}
|
||||
|
||||
if (callbackSegment == 1) {
|
||||
renderState->flag &= ~G3D_RENDERST_FLAG_SKIP_CALLBACK;
|
||||
(*renderState->callbackFuncs[G3D_SBC_CMD_00C])(renderState);
|
||||
if (renderState->callbackFuncs[G3D_SBC_CMD_00C]) {
|
||||
callbackSegment = renderState->callbackSegment[G3D_SBC_CMD_00C];
|
||||
} else {
|
||||
callbackSegment = 0;
|
||||
}
|
||||
callbackSkip = (renderState->flag & G3D_RENDERST_FLAG_SKIP_CALLBACK);
|
||||
} else {
|
||||
callbackSkip = 0;
|
||||
}
|
||||
|
||||
if (!callbackSkip) {
|
||||
s32 width = renderState->matAnim->width;
|
||||
s32 height = renderState->matAnim->height;
|
||||
Vec3p vec;
|
||||
u32 tmp;
|
||||
|
||||
G3d_Scale_inline(width << 15, -height << 15, INT_TO_Q20(1) << 4);
|
||||
|
||||
tmp = GX_PACK_TEXCOORD_PARAM(width << 11, height << 11);
|
||||
PushGeometryCommand(0x22, (u32 *) &tmp, 1); // TEXCOORD
|
||||
}
|
||||
|
||||
if (callbackSegment == 2) {
|
||||
renderState->flag &= ~G3D_RENDERST_FLAG_SKIP_CALLBACK;
|
||||
(*renderState->callbackFuncs[G3D_SBC_CMD_00C])(renderState);
|
||||
if (renderState->callbackFuncs[G3D_SBC_CMD_00C]) {
|
||||
callbackSegment = renderState->callbackSegment[G3D_SBC_CMD_00C];
|
||||
} else {
|
||||
callbackSegment = 0;
|
||||
}
|
||||
callbackSkip = (u32) (renderState->flag & G3D_RENDERST_FLAG_SKIP_CALLBACK);
|
||||
} else {
|
||||
callbackSkip = 0;
|
||||
}
|
||||
|
||||
if (!callbackSkip) {
|
||||
u32 matIndex = *(renderState->currentCmd + 1);
|
||||
G3d_NameList_Header *h = (G3d_NameList_Header *) ((u8 *) &renderState->materialList->materials +
|
||||
renderState->materialList->materials.ofsHeader);
|
||||
u32 *materialOffset = (u32 *) (&h->data[0] + h->element_size * matIndex);
|
||||
const G3d_Material *mat = (G3d_Material *) ((u8 *) renderState->materialList + *materialOffset);
|
||||
|
||||
if (mat->flag & 0x2000) {
|
||||
const u8 *p = (const u8 *) mat + sizeof(G3d_Material);
|
||||
|
||||
if (!(mat->flag & 2)) {
|
||||
p += 8;
|
||||
}
|
||||
|
||||
if (!(mat->flag & 4)) {
|
||||
p += 4;
|
||||
}
|
||||
|
||||
if (!(mat->flag & 8)) {
|
||||
p += 8;
|
||||
}
|
||||
|
||||
G3d_MtxMult44_inline((const Mat4p *) p); // MTX_MULT_4x4
|
||||
}
|
||||
}
|
||||
|
||||
if (callbackSegment == 3) {
|
||||
renderState->flag &= ~G3D_RENDERST_FLAG_SKIP_CALLBACK;
|
||||
(*renderState->callbackFuncs[G3D_SBC_CMD_00C])(renderState);
|
||||
callbackSkip = renderState->flag & G3D_RENDERST_FLAG_SKIP_CALLBACK;
|
||||
} else {
|
||||
callbackSkip = 0;
|
||||
}
|
||||
|
||||
if (!callbackSkip) {
|
||||
Mat3p m;
|
||||
G3d_SetMtxMode_inline(2); // MTX_MODE = Position + Vector
|
||||
G3d_GetCurrentMtx(0, &m);
|
||||
G3d_SetMtxMode_inline(3); // MTX_MODE = Texture
|
||||
|
||||
if (data_027e037c.flags & 1) {
|
||||
G3d_MtxMult33_inline((const Mat3p *) &data_027e037c.mUnk_04c); // MTX_MULT_3x3
|
||||
G3d_MtxMult33_inline(&gGeomMatrix); // MTX_MULT_3x3
|
||||
G3d_MtxMult33_inline(&m); // MTX_MULT_3x3
|
||||
} else if (data_027e037c.flags & 2) {
|
||||
G3d_MtxMult33_inline((const Mat3p *) &data_027e037c.mUnk_04c); // MTX_MULT_3x3
|
||||
G3d_MtxMult33_inline(&m); // MTX_MULT_3x3
|
||||
} else {
|
||||
G3d_MtxMult33_inline(&m); // MTX_MULT_3x3
|
||||
}
|
||||
}
|
||||
|
||||
G3d_SetMtxMode_inline(2); // MTX_MODE = Position + Vector
|
||||
}
|
||||
renderState->currentCmd += 3;
|
||||
}
|
||||
|
||||
// Renders the SBC command 0xD (unknown)
|
||||
void G3d_SBCRender_00D(G3d_RenderState *renderState, u32) {
|
||||
if (!(renderState->flag & G3D_RENDERST_FLAG_SKIP_SBC_RENDER) && (renderState->flag & G3D_RENDERST_FLAG_BONE_VISIBLE)) {
|
||||
u32 callbackSkip;
|
||||
u32 callbackSegment;
|
||||
u32 num;
|
||||
Mat4x3p m;
|
||||
|
||||
G3d_GetCurrentMtx(&m, 0);
|
||||
num = 30;
|
||||
PushGeometryCommand(0x13, &num, 1); // MTX_STORE
|
||||
|
||||
if ((renderState->matAnim->teximage_params & 0xc0000000) != (3 << 30)) {
|
||||
static u32 cmd[] = {0x2a, 0};
|
||||
renderState->matAnim->teximage_params &= ~0xc0000000;
|
||||
renderState->matAnim->teximage_params |= 3 << 30;
|
||||
|
||||
cmd[1] = renderState->matAnim->teximage_params;
|
||||
PushGeometryCommand(cmd[0], &cmd[1], 1);
|
||||
}
|
||||
|
||||
if (renderState->callbackFuncs[G3D_SBC_CMD_00D]) {
|
||||
callbackSegment = renderState->callbackSegment[G3D_SBC_CMD_00D];
|
||||
} else {
|
||||
callbackSegment = 0;
|
||||
}
|
||||
|
||||
if (callbackSegment == 1) {
|
||||
renderState->flag &= ~G3D_RENDERST_FLAG_SKIP_CALLBACK;
|
||||
(*renderState->callbackFuncs[G3D_SBC_CMD_00D])(renderState);
|
||||
if (renderState->callbackFuncs[G3D_SBC_CMD_00D]) {
|
||||
callbackSegment = renderState->callbackSegment[G3D_SBC_CMD_00D];
|
||||
} else {
|
||||
callbackSegment = 0;
|
||||
}
|
||||
callbackSkip = (renderState->flag & G3D_RENDERST_FLAG_SKIP_CALLBACK);
|
||||
} else {
|
||||
callbackSkip = 0;
|
||||
}
|
||||
|
||||
if (!callbackSkip) {
|
||||
s32 w, h;
|
||||
w = (s32) renderState->matAnim->width;
|
||||
h = (s32) renderState->matAnim->height;
|
||||
|
||||
{
|
||||
static Mat4p mtx = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10000, 0, 0, 0, 0, 0x10000};
|
||||
|
||||
mtx.xColumn.x = w << 15;
|
||||
mtx.yColumn.y = -h << 15;
|
||||
mtx.wColumn.x = w << 15;
|
||||
mtx.wColumn.y = h << 15;
|
||||
|
||||
PushGeometryCommand(0x16, &mtx, 0x10);
|
||||
}
|
||||
}
|
||||
|
||||
if (callbackSegment == 2) {
|
||||
renderState->flag &= ~G3D_RENDERST_FLAG_SKIP_CALLBACK;
|
||||
(*renderState->callbackFuncs[G3D_SBC_CMD_00D])(renderState);
|
||||
if (renderState->callbackFuncs[G3D_SBC_CMD_00D]) {
|
||||
callbackSegment = renderState->callbackSegment[G3D_SBC_CMD_00D];
|
||||
} else {
|
||||
callbackSegment = 0;
|
||||
}
|
||||
callbackSkip = (u32) (renderState->flag & G3D_RENDERST_FLAG_SKIP_CALLBACK);
|
||||
} else {
|
||||
callbackSkip = 0;
|
||||
}
|
||||
|
||||
if (!callbackSkip) {
|
||||
u32 idxMat = *(renderState->currentCmd + 1);
|
||||
u32 matIndex = *(renderState->currentCmd + 1);
|
||||
G3d_NameList_Header *h = (G3d_NameList_Header *) ((u8 *) &renderState->materialList->materials +
|
||||
renderState->materialList->materials.ofsHeader);
|
||||
u32 *materialOffset = (u32 *) (&h->data[0] + h->element_size * matIndex);
|
||||
const G3d_Material *mat = (G3d_Material *) ((u8 *) renderState->materialList + *materialOffset);
|
||||
|
||||
if (mat->flag & 0x2000) {
|
||||
const Mat4p *effect_mtx;
|
||||
const u8 *p = (const u8 *) mat + sizeof(G3d_Material);
|
||||
|
||||
if (!(mat->flag & 2)) {
|
||||
p += 8;
|
||||
}
|
||||
|
||||
if (!(mat->flag & 4)) {
|
||||
p += 4;
|
||||
}
|
||||
|
||||
if (!(mat->flag & 8)) {
|
||||
p += 8;
|
||||
}
|
||||
|
||||
G3d_MtxMult44_inline((const Mat4p *) p); // MTX_MULT_4x4
|
||||
}
|
||||
}
|
||||
|
||||
if (callbackSegment == 3) {
|
||||
renderState->flag &= ~G3D_RENDERST_FLAG_SKIP_CALLBACK;
|
||||
(*renderState->callbackFuncs[G3D_SBC_CMD_00D])(renderState);
|
||||
callbackSkip = renderState->flag & G3D_RENDERST_FLAG_SKIP_CALLBACK;
|
||||
} else {
|
||||
callbackSkip = 0;
|
||||
}
|
||||
|
||||
if (!callbackSkip) {
|
||||
Mat4p mtx;
|
||||
u32 tmp;
|
||||
|
||||
if (data_027e037c.flags & 1) {
|
||||
PushGeometryCommand(0x1c, &gGeomTranslation, 3); // MTX_TRANS
|
||||
G3d_MtxMult33_inline(&gGeomMatrix); // MTX_MULT_3x3
|
||||
G3d_MtxMult43_inline(&m); // MTX_MULT_4x3
|
||||
|
||||
} else if (data_027e037c.flags & 2) {
|
||||
G3d_MtxMult43_inline(&m);
|
||||
} else {
|
||||
G3d_MtxMult43_inline(func_02018450());
|
||||
G3d_MtxMult43_inline(&m);
|
||||
}
|
||||
|
||||
{
|
||||
FlushGfxQueue();
|
||||
|
||||
GFX_FIFO_MTX_MODE = 0; // Projection
|
||||
GFX_FIFO_MTX_PUSH = 0;
|
||||
GFX_FIFO_MTX_IDENTITY = 0;
|
||||
|
||||
while (func_0200598c(&mtx))
|
||||
;
|
||||
|
||||
GFX_FIFO_MTX_POP = 1;
|
||||
GFX_FIFO_MTX_MODE = 3; // Texture
|
||||
}
|
||||
|
||||
PushGeometryCommand(0x16, &mtx, 0x10);
|
||||
tmp = GX_PACK_TEXCOORD_PARAM((q20) (mtx.wColumn.x >> 4), (q20) (mtx.wColumn.y >> 4));
|
||||
PushGeometryCommand(0x22, (u32 *) &tmp, 1); // TEXCOORD
|
||||
}
|
||||
|
||||
G3d_SetMtxMode_inline(2); // MTX_MODE = Position + Vector
|
||||
G3d_RestoreMtx_inline(30);
|
||||
}
|
||||
renderState->currentCmd += 3;
|
||||
}
|
||||
Reference in New Issue
Block a user