diff --git a/config/GMPE01_00/symbols.txt b/config/GMPE01_00/symbols.txt index 9917938b..fe79ab23 100644 --- a/config/GMPE01_00/symbols.txt +++ b/config/GMPE01_00/symbols.txt @@ -475,7 +475,7 @@ Hu3DParticleAttrSet = .text:0x8002A544; // type:function size:0x40 Hu3DParticleAttrReset = .text:0x8002A584; // type:function size:0x44 Hu3DParticleCntSet = .text:0x8002A5C8; // type:function size:0x3C Hu3DParticleAnimModeSet = .text:0x8002A604; // type:function size:0x60 -Hu3DParticleAttrReset = .text:0x8002A664; // type:function size:0xAD4 scope:local +_Hu3DParticleAttrReset = .text:0x8002A664; // type:function size:0xAD4 scope:local Hu3DParManInit = .text:0x8002B138; // type:function size:0x48 Hu3DParManCreate = .text:0x8002B180; // type:function size:0x1D4 Hu3DParManLink = .text:0x8002B354; // type:function size:0x17C diff --git a/configure.py b/configure.py index c22aa893..eda83503 100644 --- a/configure.py +++ b/configure.py @@ -328,7 +328,7 @@ config.libs = [ Object(NonMatching, "game/hsfdraw.c"), Object(Matching, "game/hsfman.c"), Object(NonMatching, "game/hsfmotion.c"), - Object(NonMatching, "game/hsfanim.c"), + Object(Matching, "game/hsfanim.c"), Object(NonMatching, "game/hsfex.c"), Object(Matching, "game/perf.c"), Object(Matching, "game/objmain.c"), diff --git a/include/dolphin/os/OSFastCast.h b/include/dolphin/os/OSFastCast.h index be1ef556..cd81d882 100644 --- a/include/dolphin/os/OSFastCast.h +++ b/include/dolphin/os/OSFastCast.h @@ -44,9 +44,9 @@ static inline void OSInitFastCast(void) { static inline s16 __OSf32tos16(register f32 inF) { - register s16 out; u32 tmp; register u32* tmpPtr = &tmp; + register s16 out; // clang-format off asm { psq_st inF, 0(tmpPtr), 0x1, OS_FASTCAST_S16 diff --git a/include/game/hsfanim.h b/include/game/hsfanim.h index 2df98f9c..d519a890 100644 --- a/include/game/hsfanim.h +++ b/include/game/hsfanim.h @@ -2,12 +2,140 @@ #define GAME_HSFANIM_H #include "common.h" +#include "game/hsfformat.h" +#include "game/hsfman.h" #include "game/sprite.h" +typedef struct model_data ModelData; + +typedef struct { + /* 0x00 */ union { + u16 unk00; + s16 unk00_s16; + }; + /* 0x02 */ s16 unk02; + /* 0x04 */ s16 unk04; + /* 0x06 */ s16 unk06; + /* 0x08 */ Vec unk08; + /* 0x14 */ Vec unk14; + /* 0x20 */ float unk20; + /* 0x24 */ float unk24; + /* 0x28 */ float unk28; + /* 0x2C */ float unk2C; + /* 0x30 */ float unk30; + /* 0x34 */ Vec unk34; + /* 0x40 */ GXColor unk40; +} HsfanimStruct01; // Size 0x44 + typedef struct particle_data { - char unk_00[0x44]; - AnimData *unk_44; - char unk_48[0x10]; -} ParticleData; + /* 0x00 */ s16 unk_00; + /* 0x02 */ s16 unk_02; + /* 0x04 */ char unk_04[0x1C]; + /* 0x20 */ s16 unk_20; + /* 0x22 */ s16 unk_22; + /* 0x24 */ float unk_24; + /* 0x28 */ float unk_28; + /* 0x2C */ u8 unk_2C; + /* 0x2D */ u8 unk_2D; + /* 0x2E */ char unk_2E[2]; + /* 0x30 */ s16 unk_30; + /* 0x32 */ char unk_32[2]; + /* 0x34 */ s32 unk_34; + /* 0x38 */ s32 unk_38; + /* 0x3C */ u32 unk_3C; + /* 0x40 */ s32 unk_40; + /* 0x44 */ AnimData *unk_44; + /* 0x48 */ HsfanimStruct01 *unk_48; + /* 0x4C */ Vec *unk_4C; + /* 0x50 */ void *unk_50; + /* 0x54 */ void *unk_54; +} ParticleData; // Size 0x58 + +typedef struct { + /* 0x00 */ s16 unk00; + /* 0x02 */ char unk02[2]; + /* 0x04 */ float unk04; + /* 0x08 */ float unk08; + /* 0x0C */ float unk0C; + /* 0x10 */ Vec unk10; + /* 0x1C */ float unk1C; + /* 0x20 */ float unk20; + /* 0x24 */ float unk24; + /* 0x28 */ float unk28; + /* 0x2C */ s16 unk2C; + /* 0x2E */ GXColor unk2E[4]; + /* 0x3E */ GXColor unk3E[4]; +} HsfanimStruct00; // Size unknown + +typedef struct { + /* 0x00 */ u16 unk00; + /* 0x02 */ s16 unk02; + /* 0x04 */ s16 unk04; + /* 0x06 */ s16 unk06; + /* 0x08 */ float unk08; + /* 0x0C */ float unk0C; + /* 0x10 */ AnimData *unk10; +} Hu3DTexAnimDataStruct; // Size 0x14 + +typedef struct { + /* 0x00 */ u16 unk00; + /* 0x02 */ s16 unk02; + /* 0x04 */ Vec unk04; + /* 0x10 */ char unk10[0xC]; + /* 0x1C */ Vec unk1C; + /* 0x28 */ char unk28[0xC]; + /* 0x34 */ float unk34; + /* 0x38 */ float unk38; + /* 0x3C */ Mtx unk3C; +} Hu3DTexScrDataStruct; // Size 0x6C + +void Hu3DAnimInit(void); +s16 Hu3DAnimCreate(void *arg0, s16 arg1, char *arg2); +s16 Hu3DAnimLink(s16 arg0, s16 arg1, char *arg2); +void Hu3DAnimKill(s16 arg0); +void Hu3DAnimModelKill(s16 arg0); +void Hu3DAnimAllKill(void); +void Hu3DAnimAttrSet(s16 arg0, u16 arg1); +void Hu3DAnimAttrReset(s16 arg0, s32 arg1); +void Hu3DAnimSpeedSet(s16 arg0, float arg1); +void Hu3DAnimBankSet(s16 arg0, s32 arg1); +void Hu3DAnmNoSet(s16 arg0, s32 arg1); +s32 Hu3DAnimSet(ModelData *arg0, HsfAttribute *arg1, s16 arg2); +void Hu3DAnimExec(void); +s16 Hu3DTexScrollCreate(s16 arg0, char *arg1); +void Hu3DTexScrollKill(s16 arg0); +void Hu3DTexScrollAllKill(void); +void Hu3DTexScrollPosSet(s16 arg0, float arg1, float arg2, float arg3); +void Hu3DTexScrollPosMoveSet(s16 arg0, float arg1, float arg2, float arg3); +void Hu3DTexScrollRotSet(s16 arg0, float arg1); +void Hu3DTexScrollRotMoveSet(s16 arg0, float arg1); +void Hu3DTexScrollPauseDisableSet(s16 arg0, s32 arg1); +s16 Hu3DParticleCreate(AnimData *arg0, s16 arg1); +void Hu3DParticleScaleSet(s16 arg0, float arg1); +void Hu3DParticleZRotSet(s16 arg0, float arg1); +void Hu3DParticleColSet(s16 arg0, u8 arg1, u8 arg2, u8 arg3); +void Hu3DParticleTPLvlSet(s16 arg0, float arg1); +void Hu3DParticleBlendModeSet(s16 arg0, u8 arg1); +void Hu3DParticleAttrSet(s16 arg0, u8 arg1); +void Hu3DParticleAttrReset(s16 arg0, u8 arg1); +void Hu3DParticleAnimModeSet(s16 arg0, s16 arg1); +void Hu3DParManInit(void); +s16 Hu3DParManCreate(AnimData *arg0, s16 arg1, HsfanimStruct00 *arg2); +s16 Hu3DParManLink(s16 arg0, HsfanimStruct00 *arg1); +void Hu3DParManKill(s16 arg0); +void Hu3DParManAllKill(void); +void *Hu3DParManPtrGet(s16 arg0); +void Hu3DParManPosSet(s16 arg0, float arg1, float arg2, float arg3); +void Hu3DParManVecSet(s16 arg0, float arg1, float arg2, float arg3); +void Hu3DParManRotSet(s16 arg0, float arg1, float arg2, float arg3); +void Hu3DParManAttrSet(s16 arg0, s32 arg1); +void Hu3DParManAttrReset(s16 arg0, s32 arg1); +s16 Hu3DParManModelIDGet(s16 arg0); +void Hu3DParManTimeLimitSet(s16 arg0, s32 arg1); +void Hu3DParManVacumeSet(s16 arg0, float arg1, float arg2, float arg3, float arg4); +void Hu3DParManColorSet(s16 arg0, s16 arg1); + +extern Hu3DTexAnimDataStruct Hu3DTexAnimData[256]; +extern Hu3DTexScrDataStruct Hu3DTexScrData[16]; #endif diff --git a/include/game/hsfdraw.h b/include/game/hsfdraw.h new file mode 100755 index 00000000..9632e55d --- /dev/null +++ b/include/game/hsfdraw.h @@ -0,0 +1,28 @@ +#ifndef _GAME_HSFDRAW_H +#define _GAME_HSFDRAW_H + +#include "game/hsfman.h" +#include "dolphin.h" + +void Hu3DDrawPreInit(void); +void Hu3DDraw(ModelData *arg0, Mtx arg1, Vec *arg2); +s32 ObjCullCheck(HsfData *arg0, HsfObject *arg1, Mtx arg2); +void Hu3DDrawPost(void); +void MakeDisplayList(s16 arg0, HsfData *arg1); +HsfConstData *ObjConstantMake(HsfObject *arg0, u32 arg1); +void mtxTransCat(Mtx arg0, float arg1, float arg2, float arg3); +void mtxRotCat(Mtx arg0, float arg1, float arg2, float arg3); +void mtxRot(Mtx arg0, float arg1, float arg2, float arg3); +void mtxScaleCat(Mtx arg0, float arg1, float arg2, float arg3); +s16 HmfInverseMtxF3X3(Mtx arg0, Mtx arg1); +void SetDefLight(Vec arg0, Vec arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5, u8 arg6, u8 arg7, u8 arg8, u8 arg9, u8 argA); +void Hu3DModelObjPosGet(s16 arg0, char *arg1, Vec *arg2); +void Hu3DModelObjMtxGet(s16 arg0, char *arg1, Mtx arg2); +void PGObjCall(ModelData *arg0, HsfObject *arg1); +void PGObjCalc(ModelData *arg0, HsfObject *arg1); +void PGObjReplica(ModelData *arg0, HsfObject *arg1); +HsfObject *Hu3DObjDuplicate(HsfData *arg0, u32 arg1); +void Hu3DModelObjDrawInit(void); +void Hu3DModelObjDraw(s16 arg0, char *arg1, Mtx arg2); + +#endif diff --git a/include/game/hsfformat.h b/include/game/hsfformat.h index b0b40ed2..5eac6a3b 100644 --- a/include/game/hsfformat.h +++ b/include/game/hsfformat.h @@ -2,7 +2,7 @@ #define _GAME_HSFFORMAT_H #include "dolphin.h" -#include "game/hsfanim.h" +#include "game/sprite.h" #define HSF_OBJ_NULL1 0 #define HSF_OBJ_REPLICA 1 @@ -78,7 +78,7 @@ typedef struct hsf_scene { typedef struct hsf_bitmap { char *name; - s32 maxLod; + u32 maxLod; u8 dataFmt; u8 pixSize; s16 sizeX; @@ -99,10 +99,23 @@ typedef struct hsf_palette { typedef struct hsf_attribute { char *name; - u8 unk4[96]; + void *unk04; + u8 unk8[4]; + float unk0C; + u8 unk10[4]; + float unk14; + u8 unk18[8]; + float unk20; + u8 unk24[4]; + float unk28; + float unk2C; + float unk30; + float unk34; + u8 unk38[44]; u32 wrap_s; u32 wrap_t; - u8 unk6C[16]; + u8 unk6C[12]; + u32 unk78; u32 flag; HsfBitmap *bitmap; } HsfAttribute; @@ -123,7 +136,7 @@ typedef struct hsf_material { float unk2C; u32 flags; u32 numAttrs; - HsfAttribute **attrs; + s32 *attrs; } HsfMaterial; typedef struct hsf_vertex_buf { @@ -153,7 +166,10 @@ typedef struct hsf_face { typedef struct hsf_const_data { u32 flags; s16 hook; - u8 unk6[0x3A]; + u8 unk6[2]; + void *unk08; + void *unk0C; + Mtx unk10; AnimData *hilite_map; } HsfConstData; @@ -267,6 +283,7 @@ typedef struct hsf_object_data { HsfAttribute *attribute; u8 unk120[2]; u8 shapeType; + u8 unk123; u32 vertexShapeCnt; HsfBuffer **vertexShape; u32 clusterCnt; diff --git a/include/game/hsfman.h b/include/game/hsfman.h index b888ce52..02f151da 100644 --- a/include/game/hsfman.h +++ b/include/game/hsfman.h @@ -14,11 +14,13 @@ #define Hu3DModelCreateFile(data_id) (Hu3DModelCreate(HuDataSelHeapReadNum((data_id), MEMORY_DEFAULT_NUM, HEAP_DATA))) +typedef struct particle_data ParticleData; + typedef struct model_data { u8 unk_00; u8 unk_01; u8 unk_02; - s8 unk_03; + u8 unk_03; s8 unk_04; s8 unk_05; s16 layer; @@ -119,7 +121,7 @@ extern void EnvelopeProc(HsfData*); /* extern */ extern void GXWaitDrawDone(); /* extern */ extern void Hu3DAnimExec(); /* extern */ extern void Hu3DCameraMotionExec(s16); /* extern */ -extern void Hu3DDraw(ModelData*, f32*, f32*); /* extern */ +extern void Hu3DDraw(ModelData*, Mtx, Vec*); /* extern */ extern void Hu3DDrawPost(); /* extern */ extern void Hu3DDrawPreInit(); /* extern */ extern void Hu3DMotionNext(s16); /* extern */ @@ -259,6 +261,24 @@ void Hu3DProjectionPosSet(s16, Vec, Vec, Vec); void Hu3DProjectionTPLvlSet(s16, f32); void Hu3DMipMapSet(char*, s16, s32, f32); +extern ModelData Hu3DData[0x200]; +extern CameraData Hu3DCamera[0x10]; +extern AnimData *reflectAnim[5]; +extern AnimData *hiliteAnim[4]; +extern ThreeDProjectionStruct Hu3DProjection[4]; +extern ShadowData Hu3DShadowData; +extern Mtx Hu3DCameraMtx; +extern Mtx Hu3DCameraMtxXPose; +extern LightData Hu3DGlobalLight[0x8]; +extern s16 reflectMapNo; +extern AnimData *toonAnim; +extern s16 Hu3DShadowCamBit; +extern s32 Hu3DShadowF; +extern s32 shadowModelDrawF; +extern s16 Hu3DCameraNo; +extern s16 Hu3DCameraBit; +extern s16 Hu3DPauseF; + extern MotionData Hu3DMotion[0x100]; extern u32 totalMatCnt; extern u32 totalMatCnted; diff --git a/src/game/hsfanim.c b/src/game/hsfanim.c new file mode 100755 index 00000000..8e8ca948 --- /dev/null +++ b/src/game/hsfanim.c @@ -0,0 +1,1283 @@ +#include "game/hsfanim.h" +#include "game/hsfdraw.h" +#include "game/memory.h" +#include "game/process.h" + +#include "math.h" +#include "string.h" + +typedef struct { + /* 0x00 */ s16 unk00; + /* 0x02 */ s16 unk02; + /* 0x04 */ s16 unk04; + /* 0x06 */ s16 unk06; + /* 0x08 */ s16 unk08; + /* 0x0A */ char unk0A[2]; + /* 0x0C */ Vec unk0C; + /* 0x18 */ Vec unk18; + /* 0x24 */ Vec unk24; + /* 0x30 */ float unk30; + /* 0x34 */ float unk34; + /* 0x38 */ s32 unk38; + /* 0x3C */ HsfanimStruct00 *unk3C; +} ParManProcUserData; // Size 0x40 + +static void _Hu3DParticleAttrReset(ModelData *arg0, Mtx arg1); +static void ParManFunc(void); +static void ParManHook(ModelData *arg0, ParticleData *arg1); + +u32 frand(void); + +extern u32 GlobalCounter; + +Hu3DTexAnimDataStruct Hu3DTexAnimData[256]; +Hu3DTexScrDataStruct Hu3DTexScrData[16]; +static Process *parManProc[64]; + +// TODO: move to GXVert +static inline void GXUnknownu16(const u16 x, const u16 y, const u16 z) { + GXWGFifo.u16 = x; + GXWGFifo.u16 = y; + GXWGFifo.u16 = z; +} + +void Hu3DAnimInit(void) { + Hu3DTexAnimDataStruct *var_r30; + Hu3DTexScrDataStruct *var_r29; + s16 i; + + var_r30 = Hu3DTexAnimData; + for (i = 0; i < 256; i++, var_r30++) { + var_r30->unk06 = -1; + } + var_r29 = Hu3DTexScrData; + for (i = 0; i < 16; i++, var_r29++) { + var_r29->unk02 = -1; + } +} + +s16 Hu3DAnimCreate(void *arg0, s16 arg1, char *arg2) { + Hu3DTexAnimDataStruct *var_r31; + HsfAttribute *var_r29; + HsfData *temp_r27; + HsfanimStruct01 *var_r30; + s16 i; + s16 var_r25; + s16 var_r28; + + var_r31 = Hu3DTexAnimData; + for (var_r28 = 0; var_r28 < 256; var_r28++, var_r31++) { + if (var_r31->unk06 == -1) { + break; + } + } + if (var_r28 == 256) { + OSReport("Error: TexAnim Over\n"); + return -1; + } + temp_r27 = Hu3DData[arg1].hsfData; + var_r29 = temp_r27->attribute; + for (i = var_r25 = 0; i < temp_r27->attributeCnt; i++, var_r29++) { + if (strcmp(arg2, var_r29->bitmap->name) == 0) { + if (var_r29->unk04 == 0) { + var_r30 = HuMemDirectMallocNum(HEAP_DATA, sizeof(HsfanimStruct01), (u32) Hu3DData[arg1].unk_48); + var_r29->unk04 = var_r30; + var_r30->unk00 = 0; + } else { + var_r30 = var_r29->unk04; + } + var_r30->unk00 |= 1; + var_r30->unk02 = var_r28; + var_r30->unk2C = var_r30->unk30 = 1.0f; + var_r30->unk34.x = var_r30->unk34.y = 0.0f; + var_r25++; + } + } + if (var_r25 == 0) { + OSReport("Error: Not Found TexAnim Name\n"); + return -1; + } + if (arg0 == 0) { + var_r31->unk10 = NULL; + } else { + var_r31->unk10 = HuSprAnimRead(arg0); + } + var_r31->unk06 = arg1; + var_r31->unk08 = 0.0f; + var_r31->unk02 = 0; + var_r31->unk04 = 0; + var_r31->unk00 = 0; + var_r31->unk0C = 1.0f; + return var_r28; +} + +s16 Hu3DAnimLink(s16 arg0, s16 arg1, char *arg2) { + Hu3DTexAnimDataStruct *var_r24 = &Hu3DTexAnimData[arg0]; + Hu3DTexAnimDataStruct *var_r31; + AnimData *temp_r4; + HsfAttribute *var_r29; + HsfData *temp_r27; + HsfanimStruct01 *var_r30; + s16 var_r28; + s16 i; + s16 var_r25; + + var_r31 = Hu3DTexAnimData; + for (var_r28 = 0; var_r28 < 256; var_r28++, var_r31++) { + if (var_r31->unk06 == -1) { + break; + } + } + if (var_r28 == 256) { + OSReport("Error: TexAnim Over\n"); + return -1; + } + temp_r27 = Hu3DData[arg1].hsfData; + var_r29 = temp_r27->attribute; + for (i = var_r25 = 0; i < temp_r27->attributeCnt; i++, var_r29++) { + if (strcmp(arg2, var_r29->bitmap->name) == 0) { + if (var_r29->unk04 == 0) { + var_r30 = HuMemDirectMallocNum(HEAP_DATA, sizeof(HsfanimStruct01), (u32) Hu3DData[arg1].unk_48); + var_r29->unk04 = var_r30; + } else { + var_r30 = var_r29->unk04; + } + var_r30->unk02 = var_r28; + var_r30->unk2C = var_r30->unk30 = 1.0f; + var_r30->unk34.x = var_r30->unk34.y = 0.0f; + var_r25++; + } + } + if (var_r25 == 0) { + OSReport("Error: Not Found TexAnim Name\n"); + return -1; + } + var_r31->unk10 = var_r24->unk10; + var_r31->unk10->useNum++; + var_r31->unk06 = arg1; + var_r31->unk08 = 0.0f; + var_r31->unk02 = 0; + var_r31->unk04 = 0; + var_r31->unk00 = 0; + var_r31->unk0C = 1.0f; + return var_r28; +} + +void Hu3DAnimKill(s16 arg0) { + Hu3DTexAnimDataStruct *temp_r31 = &Hu3DTexAnimData[arg0]; + HsfData *temp_r28 = Hu3DData[temp_r31->unk06].hsfData; + HsfAttribute *var_r30; + HsfanimStruct01 *temp_r29; + s16 i; + + if (temp_r28) { + var_r30 = temp_r28->attribute; + for (i = 0; i < temp_r28->attributeCnt; i++, var_r30++) { + if (var_r30->unk04) { + temp_r29 = var_r30->unk04; + if (temp_r29->unk02 == arg0) { + temp_r29->unk00 &= ~1; + if (temp_r29->unk00 == 0) { + var_r30->unk04 = NULL; + HuMemDirectFree(temp_r29); + } + } + } + } + } + temp_r31->unk06 = -1; + if (--temp_r31->unk10->useNum <= 0) { + HuMemDirectFree(temp_r31->unk10); + } +} + +void Hu3DAnimModelKill(s16 arg0) { + Hu3DTexAnimDataStruct *var_r26 = &Hu3DTexAnimData[0]; + s16 i; + + for (i = 0; i < 256; i++, var_r26++) { + if (var_r26->unk06 == arg0) { + Hu3DAnimKill(i); + } + } +} + +void Hu3DAnimAllKill(void) { + Hu3DTexAnimDataStruct *var_r26 = &Hu3DTexAnimData[0]; + s16 i; + + for (i = 0; i < 256; i++, var_r26++) { + if (var_r26->unk06 != -1) { + Hu3DAnimKill(i); + } + } + Hu3DTexScrollAllKill(); +} + +void Hu3DAnimAttrSet(s16 arg0, u16 arg1) { + Hu3DTexAnimDataStruct *temp_r31 = &Hu3DTexAnimData[arg0]; + + temp_r31->unk00 |= arg1; +} + +void Hu3DAnimAttrReset(s16 arg0, s32 arg1) { + Hu3DTexAnimDataStruct *temp_r31 = &Hu3DTexAnimData[arg0]; + + temp_r31->unk00 &= ~arg1; +} + +void Hu3DAnimSpeedSet(s16 arg0, float arg1) { + Hu3DTexAnimDataStruct *temp_r31 = &Hu3DTexAnimData[arg0]; + + temp_r31->unk0C = arg1; +} + +void Hu3DAnimBankSet(s16 arg0, s32 arg1) { + Hu3DTexAnimDataStruct *temp_r31 = &Hu3DTexAnimData[arg0]; + + temp_r31->unk02 = arg1; + temp_r31->unk04 = temp_r31->unk08 = 0.0f; +} + +void Hu3DAnmNoSet(s16 arg0, s32 arg1) { + Hu3DTexAnimDataStruct *temp_r31 = &Hu3DTexAnimData[arg0]; + + temp_r31->unk04 = arg1; + temp_r31->unk08 = 0.0f; +} + +s32 Hu3DAnimSet(ModelData *arg0, HsfAttribute *arg1, s16 arg2) { + HsfanimStruct01 *temp_r30; + Hu3DTexAnimDataStruct *temp_r29; + AnimData *temp_r27; + AnimBmpData *temp_r28; + AnimLayerData *temp_r31; + AnimPatData *temp_r25; + s16 temp_r24; + s16 var_r23; + s16 var_r22; + + temp_r30 = arg1->unk04; + temp_r29 = &Hu3DTexAnimData[temp_r30->unk02]; + temp_r27 = temp_r29->unk10; + temp_r24 = temp_r27->bank[temp_r29->unk02].frame[temp_r29->unk04].pat; + if (temp_r24 == -1) { + return 0; + } + var_r23 = (arg1->wrap_s == 1) ? 1 : 0; + var_r22 = (arg1->wrap_t == 1) ? 1 : 0; + temp_r25 = &temp_r27->pat[temp_r24]; + temp_r31 = temp_r25->layer; + temp_r28 = &temp_r27->bmp[temp_r31->bmpNo]; + HuSprTexLoad(temp_r29->unk10, temp_r31->bmpNo, arg2, var_r23, var_r22, + (arg0->attr & 0x40) ? GX_NEAR : GX_LINEAR); + temp_r30->unk2C = (float) temp_r31->sizeX / temp_r28->sizeX; + temp_r30->unk30 = (float) temp_r31->sizeY / temp_r28->sizeY; + temp_r30->unk34.x = (float) temp_r31->startX / temp_r28->sizeX; + temp_r30->unk34.y = (float) temp_r31->startY / temp_r28->sizeY; + return 1; +} + +void Hu3DAnimExec(void) { + Hu3DTexAnimDataStruct *var_r30; + Hu3DTexScrDataStruct *var_r31; + AnimData *var_r25; + AnimBankData *temp_r28; + AnimFrameData *var_r29; + s16 var_r26; + s16 i; + + var_r30 = Hu3DTexAnimData; + for (i = 0; i < 256; i++, var_r30++) { + if (var_r30->unk06 != -1 && (Hu3DPauseF == 0 || (var_r30->unk00 & 0x20))) { + var_r25 = var_r30->unk10; + temp_r28 = &var_r25->bank[var_r30->unk02]; + var_r29 = &temp_r28->frame[var_r30->unk04]; + if (!(var_r30->unk00 & 1) || (var_r29->time == -1 && (var_r30->unk00 & 2))) { + for (var_r26 = 0; var_r26 < (s32) var_r30->unk0C * minimumVcount; var_r26++) { + var_r30->unk08 += 1.0f; + if (var_r30->unk08 >= var_r29->time) { + var_r30->unk04++; + var_r30->unk08 -= var_r29->time; + if (var_r30->unk04 >= temp_r28->timeNum || var_r29[1].time == -1) { + var_r30->unk04 = 0; + } + var_r29 = &temp_r28->frame[var_r30->unk04]; + } + } + var_r30->unk08 += var_r30->unk0C * minimumVcount - var_r26; + if (var_r30->unk08 >= var_r29->time) { + var_r30->unk04++; + var_r30->unk08 -= var_r29->time; + if (var_r30->unk04 >= temp_r28->timeNum || var_r29[1].time == -1) { + var_r30->unk04 = 0; + } + } + } + } + } + var_r31 = Hu3DTexScrData; + for (i = 0; i < 16; i++, var_r31++) { + if (var_r31->unk02 != -1) { + if (Hu3DPauseF != 0 && !(var_r31->unk00 & 8)) { + PSMTXRotRad(var_r31->unk3C, 'Z', MTXDegToRad(var_r31->unk34)); + mtxTransCat(var_r31->unk3C, var_r31->unk04.x, var_r31->unk04.y, var_r31->unk04.z); + } else { + if (var_r31->unk00 & 1) { + PSVECAdd(&var_r31->unk04, &var_r31->unk1C, &var_r31->unk04); + if (var_r31->unk04.x > 1.0f) { + var_r31->unk04.x -= 1.0f; + } + if (var_r31->unk04.y > 1.0f) { + var_r31->unk04.y -= 1.0f; + } + if (var_r31->unk04.z > 1.0f) { + var_r31->unk04.z -= 1.0f; + } + if (var_r31->unk04.x < -1.0f) { + var_r31->unk04.x += 1.0f; + } + if (var_r31->unk04.y < -1.0f) { + var_r31->unk04.y += 1.0f; + } + if (var_r31->unk04.z < -1.0f) { + var_r31->unk04.z += 1.0f; + } + } + if (var_r31->unk00 & 2) { + var_r31->unk34 += var_r31->unk38; + if (var_r31->unk34 > 360.0f) { + var_r31->unk34 -= 360.0f; + } + if (var_r31->unk34 < -360.0f) { + var_r31->unk34 += 360.0f; + } + } + PSMTXRotRad(var_r31->unk3C, 'Z', MTXDegToRad(var_r31->unk34)); + mtxTransCat(var_r31->unk3C, var_r31->unk04.x, var_r31->unk04.y, var_r31->unk04.z); + } + } + } +} + +s16 Hu3DTexScrollCreate(s16 arg0, char *arg1) { + Hu3DTexScrDataStruct *var_r31; + HsfData *temp_r27; + HsfAttribute *var_r29; + HsfanimStruct01 *var_r30; + s16 i; + s16 var_r25; + s16 var_r28; + + var_r31 = Hu3DTexScrData; + for (var_r28 = 0; var_r28 < 16; var_r28++, var_r31++) { + if (var_r31->unk02 == -1) { + break; + } + } + if (var_r28 == 16) { + OSReport("Error: TexScroll Over\n"); + return -1; + } + temp_r27 = Hu3DData[arg0].hsfData; + var_r29 = temp_r27->attribute; + for (i = var_r25 = 0; i < temp_r27->attributeCnt; i++, var_r29++) { + if (strcmp(arg1, var_r29->bitmap->name) == 0) { + if (var_r29->unk04 == 0) { + var_r30 = HuMemDirectMallocNum(HEAP_DATA, sizeof(HsfanimStruct01), (u32) Hu3DData[arg0].unk_48); + var_r29->unk04 = var_r30; + var_r30->unk00 = 0; + } else { + var_r30 = var_r29->unk04; + } + var_r30->unk00 |= 2; + var_r30->unk04 = var_r28; + var_r30->unk2C = var_r30->unk30 = 1.0f; + var_r30->unk34.x = var_r30->unk34.y = 0.0f; + var_r25++; + } + } + if (var_r25 == 0) { + OSReport("Error: Not Found TexAnim Name\n"); + return -1; + } + var_r31->unk02 = arg0; + var_r31->unk00 = 0; + var_r31->unk04.x = var_r31->unk04.y = var_r31->unk04.z = 0.0f; + var_r31->unk34 = 0.0f; + PSMTXIdentity(var_r31->unk3C); + return var_r28; +} + +void Hu3DTexScrollKill(s16 arg0) { + Hu3DTexScrDataStruct *temp_r28 = &Hu3DTexScrData[arg0]; + HsfData *temp_r29 = Hu3DData[temp_r28->unk02].hsfData; + HsfAttribute *var_r31; + HsfanimStruct01 *temp_r30; + s16 i; + + if (temp_r29) { + var_r31 = temp_r29->attribute; + for (i = 0; i < temp_r29->attributeCnt; i++, var_r31++) { + if (var_r31->unk04) { + temp_r30 = var_r31->unk04; + if (temp_r30->unk04 == arg0) { + temp_r30->unk00 &= ~2; + if (temp_r30->unk00 == 0) { + var_r31->unk04 = NULL; + HuMemDirectFree(temp_r30); + } + } + } + } + } + temp_r28->unk02 = -1; +} + +void Hu3DTexScrollAllKill(void) { + Hu3DTexScrDataStruct *var_r27; + s16 i; + + var_r27 = Hu3DTexScrData; + for (i = 0; i < 16; i++, var_r27++) { + if (var_r27->unk02 != -1) { + Hu3DTexScrollKill(i); + } + } +} + +void Hu3DTexScrollPosSet(s16 arg0, float arg1, float arg2, float arg3) { + Hu3DTexScrDataStruct *temp_r31 = &Hu3DTexScrData[arg0]; + + temp_r31->unk00 &= ~1; + temp_r31->unk04.x = arg1; + temp_r31->unk04.y = arg2; + temp_r31->unk04.z = arg3; +} + +void Hu3DTexScrollPosMoveSet(s16 arg0, float arg1, float arg2, float arg3) { + Hu3DTexScrDataStruct *temp_r31 = &Hu3DTexScrData[arg0]; + + temp_r31->unk00 |= 1; + temp_r31->unk1C.x = arg1 * minimumVcount; + temp_r31->unk1C.y = arg2 * minimumVcount; + temp_r31->unk1C.z = arg3 * minimumVcount; +} + +void Hu3DTexScrollRotSet(s16 arg0, float arg1) { + Hu3DTexScrDataStruct *temp_r31 = &Hu3DTexScrData[arg0]; + + temp_r31->unk00 &= ~2; + temp_r31->unk34 = arg1; +} + +void Hu3DTexScrollRotMoveSet(s16 arg0, float arg1) { + Hu3DTexScrDataStruct *temp_r31 = &Hu3DTexScrData[arg0]; + + temp_r31->unk00 |= 2; + temp_r31->unk38 = arg1 * minimumVcount; +} + +void Hu3DTexScrollPauseDisableSet(s16 arg0, s32 arg1) { + Hu3DTexScrDataStruct *temp_r31 = &Hu3DTexScrData[arg0]; + + if (arg1 != 0) { + temp_r31->unk00 |= 8; + return; + } else { + temp_r31->unk00 &= ~8; + } +} + +s16 Hu3DParticleCreate(AnimData *arg0, s16 arg1) { + ModelData *temp_r28; + ParticleData *temp_r31; + HsfanimStruct01 *var_r30; + Vec *var_r27; + s16 temp_r25; + s16 i; + void *temp_r24; + + temp_r25 = Hu3DHookFuncCreate((void*) &_Hu3DParticleAttrReset); + temp_r28 = &Hu3DData[temp_r25]; + Hu3DModelAttrSet(temp_r25, 0x20); + temp_r31 = HuMemDirectMallocNum(HEAP_DATA, sizeof(ParticleData), (u32) temp_r28->unk_48); + temp_r28->unk_120 = temp_r31; + temp_r31->unk_44 = arg0; + arg0->useNum++; + temp_r31->unk_30 = arg1; + temp_r31->unk_2C = 0; + temp_r31->unk_54 = NULL; + temp_r31->unk_34 = 0; + temp_r31->unk_2D = 0; + temp_r31->unk_3C = 0; + temp_r31->unk_00 = temp_r31->unk_02 = 0; + var_r30 = HuMemDirectMallocNum(HEAP_DATA, arg1 * sizeof(HsfanimStruct01), (u32) temp_r28->unk_48); + temp_r31->unk_48 = var_r30; + temp_r31->unk_38 = -1; + for (i = 0; i < arg1; i++, var_r30++) { + var_r30->unk2C = 0.0f; + var_r30->unk04 = 0; + var_r30->unk06 = -1; + var_r30->unk30 = 0.0f; + var_r30->unk34.x = ((s32) (frand() & 0x7F) - 0x40) * 0x14; + var_r30->unk34.y = ((s32) (frand() & 0x7F) - 0x40) * 0x1E; + var_r30->unk34.z = ((s32) (frand() & 0x7F) - 0x40) * 0x14; + var_r30->unk40.r = var_r30->unk40.g = var_r30->unk40.b = var_r30->unk40.a = 0xFF; + } + var_r27 = HuMemDirectMallocNum(HEAP_DATA, arg1 * sizeof(Vec) * 4, (u32) temp_r28->unk_48); + temp_r31->unk_4C = var_r27; + for (i = 0; i < arg1 * 4; i++, var_r27++) { + var_r27->x = var_r27->y = var_r27->z = 0.0f; + } + temp_r24 = HuMemDirectMallocNum(HEAP_DATA, arg1 * 0x60 + 0x80, (u32) temp_r28->unk_48); + temp_r31->unk_50 = temp_r24; + DCInvalidateRange(temp_r24, arg1 * 0x60 + 0x80); + GXBeginDisplayList(temp_r24, 0x20000); + GXBegin(GX_QUADS, GX_VTXFMT0, arg1 * 4); + for (i = 0; i < arg1; i++) { + GXUnknownu16(i * 4, i, 0); + GXUnknownu16(i * 4 + 1, i, 1); + GXUnknownu16(i * 4 + 2, i, 2); + GXUnknownu16(i * 4 + 3, i, 3); + } + temp_r31->unk_40 = GXEndDisplayList(); + return temp_r25; +} + +void Hu3DParticleScaleSet(s16 arg0, float arg1) { + ModelData *temp_r25 = &Hu3DData[arg0]; + ParticleData *temp_r31 = temp_r25->unk_120; + HsfanimStruct01 *var_r30; + s16 i; + + var_r30 = temp_r31->unk_48; + for (i = 0; i < temp_r31->unk_30; i++, var_r30++) { + var_r30->unk2C = arg1; + } +} + +void Hu3DParticleZRotSet(s16 arg0, float arg1) { + ModelData *temp_r28 = &Hu3DData[arg0]; + ParticleData *temp_r31 = temp_r28->unk_120; + HsfanimStruct01 *var_r30; + s16 i; + + var_r30 = temp_r31->unk_48; + for (i = 0; i < temp_r31->unk_30; i++, var_r30++) { + var_r30->unk30 = arg1; + } +} + +void Hu3DParticleColSet(s16 arg0, u8 arg1, u8 arg2, u8 arg3) { + ModelData *temp_r28 = &Hu3DData[arg0]; + ParticleData *temp_r30 = temp_r28->unk_120; + HsfanimStruct01 *var_r31; + s16 i; + + var_r31 = temp_r30->unk_48; + for (i = 0; i < temp_r30->unk_30; i++, var_r31++) { + var_r31->unk40.r = arg1; + var_r31->unk40.g = arg2; + var_r31->unk40.b = arg3; + } +} + +void Hu3DParticleTPLvlSet(s16 arg0, float arg1) { + ModelData *temp_r28 = &Hu3DData[arg0]; + ParticleData *temp_r31 = temp_r28->unk_120; + HsfanimStruct01 *var_r30; + u8 var_r27; + s16 i; + + var_r30 = temp_r31->unk_48; + var_r27 = arg1 * 255.0f; + for (i = 0; i < temp_r31->unk_30; i++, var_r30++) { + var_r30->unk40.a = var_r27; + } +} + +void Hu3DParticleBlendModeSet(s16 arg0, u8 arg1) { + ModelData *temp_r31 = &Hu3DData[arg0]; + ParticleData *temp_r30 = temp_r31->unk_120; + + temp_r30->unk_2C = arg1; +} + +void Hu3DParticleHookSet(s16 arg0, void *arg1) { + ModelData *temp_r31 = &Hu3DData[arg0]; + ParticleData *temp_r30 = temp_r31->unk_120; + + temp_r30->unk_54 = arg1; +} + +void Hu3DParticleAttrSet(s16 arg0, u8 arg1) { + ModelData *temp_r31 = &Hu3DData[arg0]; + ParticleData *temp_r30 = temp_r31->unk_120; + + temp_r30->unk_2D |= arg1; +} + +void Hu3DParticleAttrReset(s16 arg0, u8 arg1) { + ModelData *temp_r31 = &Hu3DData[arg0]; + ParticleData *temp_r30 = temp_r31->unk_120; + + temp_r30->unk_2D &= ~arg1; +} + +void Hu3DParticleCntSet(s16 arg0, s16 arg1) { + ModelData *temp_r31 = &Hu3DData[arg0]; + ParticleData *temp_r30 = temp_r31->unk_120; + + temp_r30->unk_34 = arg1; +} + +void Hu3DParticleAnimModeSet(s16 arg0, s16 arg1) { + ModelData *temp_r30 = &Hu3DData[arg0]; + ParticleData *temp_r31 = temp_r30->unk_120; + + temp_r31->unk_2D |= 8; + temp_r31->unk_20 = arg1; + temp_r31->unk_28 = 0.0f; + temp_r31->unk_22 = 0; + temp_r31->unk_24 = 1.0f; +} + +static Vec basePos[] = { + { -0.5f, 0.5f, 0.0f }, + { 0.5f, 0.5f, 0.0f }, + { 0.5f, -0.5f, 0.0f }, + { -0.5f, -0.5f, 0.0f } +}; + +static float baseST[] = { + 0.0f, 0.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 0.0f, 1.0f +}; + +static void _Hu3DParticleAttrReset(ModelData *arg0, Mtx arg1) { + Vec *var_r30; + float temp_f31; + float temp_f29; + float temp_f30; + s16 temp_r20; + s16 var_r19; + s32 i; + AnimFrameData *var_r28; + AnimPatData *temp_r21; + AnimData *temp_r22; + AnimBankData *temp_r25; + AnimBmpData *temp_r24; + AnimLayerData *temp_r27; + ParticleData *temp_r31; + HsfanimStruct01 *var_r29; + void (*var_r17)(void*, void*, Mtx); + Mtx sp128; + Mtx spF8; + Mtx spC8; + Vec sp98[4]; + Vec sp68[4]; + Vec sp38[4]; + ROMtx sp8; + + temp_r31 = arg0->unk_120; + temp_r22 = temp_r31->unk_44; + if (HmfInverseMtxF3X3(arg1, sp128) == 0) { + PSMTXIdentity(sp128); + } + PSMTXReorder(sp128, sp8); + if ((Hu3DPauseF == 0 || (arg0->attr & 0x200000)) && temp_r31->unk_54 && temp_r31->unk_38 != GlobalCounter) { + var_r17 = temp_r31->unk_54; + var_r17(arg0, temp_r31, arg1); + } + var_r29 = temp_r31->unk_48; + var_r30 = temp_r31->unk_4C; + PSMTXROMultVecArray(sp8, &basePos[0], sp38, 4); + for (i = 0, var_r19 = 0; i < temp_r31->unk_30; i++, var_r29++) { + if (var_r29->unk2C && (var_r29->unk06 & Hu3DCameraBit)) { + if (!var_r29->unk30) { + temp_f31 = var_r29->unk2C; + var_r30->x = sp38[0].x * temp_f31 + var_r29->unk34.x; + var_r30->y = sp38[0].y * temp_f31 + var_r29->unk34.y; + var_r30->z = sp38[0].z * temp_f31 + var_r29->unk34.z; + var_r30++; + var_r30->x = sp38[1].x * temp_f31 + var_r29->unk34.x; + var_r30->y = sp38[1].y * temp_f31 + var_r29->unk34.y; + var_r30->z = sp38[1].z * temp_f31 + var_r29->unk34.z; + var_r30++; + var_r30->x = sp38[2].x * temp_f31 + var_r29->unk34.x; + var_r30->y = sp38[2].y * temp_f31 + var_r29->unk34.y; + var_r30->z = sp38[2].z * temp_f31 + var_r29->unk34.z; + var_r30++; + var_r30->x = sp38[3].x * temp_f31 + var_r29->unk34.x; + var_r30->y = sp38[3].y * temp_f31 + var_r29->unk34.y; + var_r30->z = sp38[3].z * temp_f31 + var_r29->unk34.z; + var_r30++; + } else { + PSVECScale(&basePos[0], &sp98[0], var_r29->unk2C); + PSVECScale(&basePos[1], &sp98[1], var_r29->unk2C); + PSVECScale(&basePos[2], &sp98[2], var_r29->unk2C); + PSVECScale(&basePos[3], &sp98[3], var_r29->unk2C); + PSMTXRotRad(spC8, 'Z', var_r29->unk30); + PSMTXConcat(sp128, spC8, spF8); + PSMTXMultVecArray(spF8, sp98, sp68, 4); + PSVECAdd(&sp68[0], &var_r29->unk34, var_r30++); + PSVECAdd(&sp68[1], &var_r29->unk34, var_r30++); + PSVECAdd(&sp68[2], &var_r29->unk34, var_r30++); + PSVECAdd(&sp68[3], &var_r29->unk34, var_r30++); + } + var_r19 = 1; + } else { + var_r30->x = var_r30->y = var_r30->z = 0.0f; + var_r30++; + var_r30->x = var_r30->y = var_r30->z = 0.0f; + var_r30++; + var_r30->x = var_r30->y = var_r30->z = 0.0f; + var_r30++; + var_r30->x = var_r30->y = var_r30->z = 0.0f; + var_r30++; + } + } + if (var_r19 != 0) { + DCFlushRangeNoSync(temp_r31->unk_4C, temp_r31->unk_30 * sizeof(Vec) * 4); + GXLoadPosMtxImm(arg1, 0); + GXSetNumTevStages(1); + GXSetNumTexGens(1); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); + if (shadowModelDrawF != 0) { + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ONE, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO); + GXSetZMode(0, GX_LEQUAL, 0); + } else { + temp_r20 = (temp_r31->unk_44->bmp->dataFmt & 0xF); + if (temp_r20 == 7 || temp_r20 == 8) { + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ONE, GX_CC_RASC, GX_CC_ZERO); + } else { + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_RASC, GX_CC_ZERO); + } + if (arg0->attr & 2) { + GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE); + } else { + GXSetZMode(GX_TRUE, GX_LEQUAL, GX_FALSE); + } + } + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_TEXA, GX_CA_RASA, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetNumChans(1); + GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_CLAMP, GX_AF_NONE); + if (temp_r31->unk_2D & 8) { + temp_r25 = &temp_r22->bank[temp_r31->unk_20]; + var_r28 = &temp_r25->frame[temp_r31->unk_22]; + temp_r21 = &temp_r22->pat[var_r28->pat]; + HuSprTexLoad(temp_r31->unk_44, temp_r21->layer->bmpNo, 0, GX_CLAMP, GX_CLAMP, GX_LINEAR); + if (Hu3DPauseF == 0 || (arg0->attr & 0x200000)) { + for (i = 0; i < (s32) temp_r31->unk_24 * minimumVcount; i++) { + temp_r31->unk_28 += 1.0f; + if (temp_r31->unk_28 >= var_r28->time) { + temp_r31->unk_22++; + temp_r31->unk_28 -= var_r28->time; + if (temp_r31->unk_22 >= temp_r25->timeNum || var_r28[1].time == -1) { + temp_r31->unk_22 = 0; + } + } + var_r28 = &temp_r25->frame[temp_r31->unk_22]; + } + temp_r31->unk_28 += temp_r31->unk_24 * minimumVcount - i; + if (temp_r31->unk_28 >= var_r28->time) { + temp_r31->unk_22++; + temp_r31->unk_28 -= var_r28->time; + if (temp_r31->unk_22 >= temp_r25->timeNum || var_r28[1].time == -1) { + temp_r31->unk_22 = 0; + } + } + } + temp_r27 = temp_r21->layer; + temp_r24 = &temp_r22->bmp[temp_r27->bmpNo]; + temp_f29 = (float) temp_r27->sizeX / temp_r24->sizeX; + temp_f30 = (float) temp_r27->sizeY / temp_r24->sizeY; + PSMTXScale(sp128, temp_f29, temp_f30, 1.0f); + temp_f29 = (float) temp_r27->startX / temp_r24->sizeX; + temp_f30 = (float) temp_r27->startY / temp_r24->sizeY; + mtxTransCat(sp128, temp_f29, temp_f30, 0.0f); + GXLoadTexMtxImm(sp128, GX_TEXMTX0, GX_MTX2x4); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX0, GX_FALSE, GX_PTIDENTITY); + } else { + HuSprTexLoad(temp_r31->unk_44, 0, 0, GX_CLAMP, GX_CLAMP, GX_LINEAR); + } + GXSetAlphaCompare(GX_GEQUAL, 1, GX_AOP_AND, GX_GEQUAL, 1); + GXSetZCompLoc(0); + switch (temp_r31->unk_2C) { + case 0: + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP); + break; + case 1: + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_ONE, GX_LO_NOOP); + break; + case 2: + GXSetBlendMode(GX_BM_BLEND, GX_BL_ZERO, GX_BL_INVDSTCLR, GX_LO_NOOP); + break; + } + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_INDEX16); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_TEX_ST, GX_RGBA6, 0); + GXSetArray(GX_VA_POS, temp_r31->unk_4C, 0xC); + GXSetVtxDesc(GX_VA_CLR0, GX_INDEX16); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_TEX_ST, GX_RGBA8, 0); + GXSetArray(GX_VA_CLR0, (u8*) temp_r31->unk_48 + 0x40, 0x44); + GXSetVtxDesc(GX_VA_TEX0, GX_INDEX16); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_RGBA6, 0); + GXSetArray(GX_VA_TEX0, baseST, 8); + GXCallDisplayList(temp_r31->unk_50, temp_r31->unk_40); + } + if (shadowModelDrawF == 0) { + if (!(temp_r31->unk_2D & 2) && Hu3DPauseF == 0) { + temp_r31->unk_34++; + } + if (temp_r31->unk_3C != 0 && temp_r31->unk_3C <= temp_r31->unk_34) { + if (temp_r31->unk_2D & 1) { + temp_r31->unk_34 = 0; + } + temp_r31->unk_34 = temp_r31->unk_3C; + } + temp_r31->unk_38 = GlobalCounter; + } +} + +void Hu3DParManInit(void) { + s16 i; + + for (i = 0; i < 64; i++) { + parManProc[i] = NULL; + } +} + +s16 Hu3DParManCreate(AnimData *arg0, s16 arg1, HsfanimStruct00 *arg2) { + ModelData *temp_r25; + ParticleData *temp_r29; + ParManProcUserData *temp_r3_2; + HsfanimStruct01 *var_r28; + s16 temp_r3; + s16 var_r26; + s16 var_r30; + + for (var_r30 = 0; var_r30 < 64; var_r30++) { + if (parManProc[var_r30] == 0) { + break; + } + } + if (var_r30 == 64) { + return -1; + } + temp_r3 = Hu3DParticleCreate(arg0, arg1); + Hu3DParticleHookSet(temp_r3, &ParManHook); + temp_r25 = &Hu3DData[temp_r3]; + temp_r29 = temp_r25->unk_120; + temp_r29->unk_00 = var_r30; + var_r28 = temp_r29->unk_48; + for (var_r26 = 0; var_r26 < temp_r29->unk_30; var_r26++, var_r28++) { + var_r28->unk2C = 0.0f; + } + parManProc[var_r30] = HuPrcCreate(ParManFunc, 100, 0x1000, 0); + temp_r3_2 = HuMemDirectMallocNum(HEAP_SYSTEM, sizeof(ParManProcUserData), MEMORY_DEFAULT_NUM); + parManProc[var_r30]->user_data = temp_r3_2; + temp_r3_2->unk00 = temp_r3; + temp_r3_2->unk3C = arg2; + temp_r3_2->unk02 = 0; + temp_r3_2->unk0C.x = temp_r3_2->unk0C.y = temp_r3_2->unk0C.z = 0.0f; + temp_r3_2->unk18.x = 0.0f; + temp_r3_2->unk18.y = 1.0f; + temp_r3_2->unk18.z = 1.0f; + temp_r3_2->unk24.x = 0.0f; + temp_r3_2->unk24.y = 0.0f; + temp_r3_2->unk24.z = 0.0f; + temp_r3_2->unk30 = 1.0f; + temp_r3_2->unk34 = 0.0f; + temp_r3_2->unk04 = 0; + temp_r3_2->unk06 = var_r30; + return var_r30; +} + +s16 Hu3DParManLink(s16 arg0, HsfanimStruct00 *arg1) { + ParManProcUserData *temp_r29; + ParManProcUserData *temp_r3; + s16 var_r30; + + for (var_r30 = 0; var_r30 < 64; var_r30++) { + if (parManProc[var_r30] == 0) { + break; + } + } + if (var_r30 == 64) { + return -1; + } + temp_r29 = parManProc[arg0]->user_data; + parManProc[var_r30] = HuPrcCreate(ParManFunc, 100, 0x1000, 0); + temp_r3 = HuMemDirectMallocNum(HEAP_SYSTEM, sizeof(ParManProcUserData), MEMORY_DEFAULT_NUM); + parManProc[var_r30]->user_data = temp_r3; + temp_r3->unk00 = temp_r29->unk00; + temp_r3->unk3C = arg1; + temp_r3->unk02 = 0; + temp_r3->unk0C.x = temp_r3->unk0C.y = temp_r3->unk0C.z = 0.0f; + temp_r3->unk18.x = 0.0f; + temp_r3->unk18.y = 1.0f; + temp_r3->unk18.z = 1.0f; + temp_r3->unk24.x = 0.0f; + temp_r3->unk24.y = 0.0f; + temp_r3->unk24.z = 0.0f; + temp_r3->unk30 = 1.0f; + temp_r3->unk34 = 0.0f; + temp_r3->unk04 = 0; + temp_r3->unk06 = var_r30; + return var_r30; +} + +void Hu3DParManKill(s16 arg0) { + ParManProcUserData *temp_r26; + ParManProcUserData *temp_r30; + HsfanimStruct01 *var_r29; + ModelData *temp_r25; + ParticleData *temp_r27; + s16 i; + + if (parManProc[arg0]) { + temp_r30 = parManProc[arg0]->user_data; + temp_r25 = &Hu3DData[temp_r30->unk00]; + temp_r27 = temp_r25->unk_120; + var_r29 = temp_r27->unk_48; + for (i = 0; i < temp_r27->unk_30; i++, var_r29++) { + if (var_r29->unk02 == arg0) { + var_r29->unk2C = 0.0f; + } + } + for (i = 0; i < 64; i++) { + if (parManProc[i] && i != arg0) { + temp_r26 = parManProc[i]->user_data; + if (temp_r26->unk00 == temp_r30->unk00) { + break; + } + } + } + if (i == 64) { + Hu3DModelKill(temp_r30->unk00); + } + HuPrcKill(parManProc[arg0]); + parManProc[arg0] = NULL; + HuMemDirectFree(temp_r30); + } +} + +void Hu3DParManAllKill(void) { + s16 i; + + for (i = 0; i < 64; i++) { + if (parManProc[i]) { + Hu3DParManKill(i); + } + } +} + +void *Hu3DParManPtrGet(s16 arg0) { + return parManProc[arg0]->user_data; +} + +void Hu3DParManPosSet(s16 arg0, float arg1, float arg2, float arg3) { + ParManProcUserData *temp_r31 = parManProc[arg0]->user_data; + + temp_r31->unk0C.x = arg1; + temp_r31->unk0C.y = arg2; + temp_r31->unk0C.z = arg3; +} + +void Hu3DParManVecSet(s16 arg0, float arg1, float arg2, float arg3) { + ParManProcUserData *temp_r31 = parManProc[arg0]->user_data; + + temp_r31->unk18.x = arg1; + temp_r31->unk18.y = arg2; + temp_r31->unk18.z = arg3; +} + +void Hu3DParManRotSet(s16 arg0, float arg1, float arg2, float arg3) { + ParManProcUserData *temp_r31 = parManProc[arg0]->user_data; + Mtx sp18; + + mtxRot(sp18, arg1, arg2, arg3); + temp_r31->unk18.x = sp18[0][2]; + temp_r31->unk18.y = sp18[1][2]; + temp_r31->unk18.z = sp18[2][2]; +} + +void Hu3DParManAttrSet(s16 arg0, s32 arg1) { + ParManProcUserData *temp_r31 = parManProc[arg0]->user_data; + + temp_r31->unk02 |= arg1; +} + +void Hu3DParManAttrReset(s16 arg0, s32 arg1) { + ParManProcUserData *temp_r31 = parManProc[arg0]->user_data; + + temp_r31->unk02 &= ~arg1; +} + +s16 Hu3DParManModelIDGet(s16 arg0) { + ParManProcUserData *temp_r31 = parManProc[arg0]->user_data; + + return temp_r31->unk00; +} + +void Hu3DParManTimeLimitSet(s16 arg0, s32 arg1) { + ParManProcUserData *temp_r31 = parManProc[arg0]->user_data; + + temp_r31->unk04 = arg1; +} + +void Hu3DParManVacumeSet(s16 arg0, float arg1, float arg2, float arg3, float arg4) { + ParManProcUserData *temp_r31; + + Hu3DParManAttrSet(arg0, 0x200); + temp_r31 = parManProc[arg0]->user_data; + temp_r31->unk24.x = arg1; + temp_r31->unk24.y = arg2; + temp_r31->unk24.z = arg3; + temp_r31->unk30 = arg4; +} + +void Hu3DParManColorSet(s16 arg0, s16 arg1) { + ParManProcUserData *temp_r31; + + Hu3DParManAttrSet(arg0, 0x1000); + temp_r31 = parManProc[arg0]->user_data; + temp_r31->unk08 = arg1; +} + +static void ParManFunc(void) { + Process *temp_r25; + ParManProcUserData *temp_r31; + HsfanimStruct00 *temp_r30; + ModelData *temp_r27; + ParticleData *temp_r28; + HsfanimStruct01 *var_r29; + HsfanimStruct01 *temp_r23; + Vec sp2C; + Vec sp20; + Vec sp14; + Vec sp8; + float temp_f30; + float temp_f31; + float var_f26; + float var_f28; + float var_f27; + float var_f29; + s16 var_r24; + s16 var_r26; + + temp_r25 = HuPrcCurrentGet(); + temp_r31 = temp_r25->user_data; + temp_r30 = temp_r31->unk3C; + temp_r27 = &Hu3DData[temp_r31->unk00]; + while (1) { + if (Hu3DPauseF != 0 && !(temp_r27->attr & 0x200000)) { + HuPrcVSleep(); + continue; + } + temp_r28 = temp_r27->unk_120; + var_r29 = temp_r28->unk_48; + if (temp_r31->unk02 & 0x400) { + // Bug? Likely to be (u32) (temp_r30->unk04 * 0.1 * 1000.0) + var_f27 = temp_r30->unk04 * 0.9 + (s32) frandmod((u32) temp_r30->unk04 * 0.1 * 1000.0) / 1000.0f; + } else if (temp_r31->unk02 & 0x800) { + var_f27 = temp_r30->unk04 * 0.7 + (s32) frandmod((u32) temp_r30->unk04 * 0.3 * 1000.0) / 1000.0f; + } else { + var_f27 = temp_r30->unk04; + } + temp_r31->unk34 += var_f27; + var_r26 = 0; + temp_r23 = &((HsfanimStruct01*) temp_r28->unk_48)[temp_r28->unk_30]; + if (temp_r31->unk02 & 0x100) { + var_f26 = (s32) frandmod((u32) (360.0f / temp_r30->unk04) * 100) / 100; + } + while (temp_r31->unk34 >= 1.0f) { + if (temp_r31->unk02 & 1) { + temp_r31->unk34 -= 1.0f; + } else { + while (var_r29 < temp_r23) { + if (!var_r29->unk2C) { + temp_f31 = temp_r30->unk24; + if (temp_r31->unk02 & 0x10) { + temp_f31 = temp_f31 * 0.9 + (s32) frandmod((u32) (temp_f31 * 0.1 * 1000.0)) / 1000.0f; + } else if (temp_r31->unk02 & 0x20) { + temp_f31 = temp_f31 * 0.7 + (s32) frandmod((u32) (temp_f31 * 0.3 * 1000.0)) / 1000.0f; + } + var_r29->unk28 = temp_f31; + var_r29->unk2C = temp_f31; + var_r29->unk34 = temp_r31->unk0C; + sp20.x = (s32) frandmod((u32) (temp_r30->unk08 * 2.0f)) - temp_r30->unk08; + sp20.y = (s32) frandmod((u32) (temp_r30->unk08 * 2.0f)) - temp_r30->unk08; + sp20.z = (s32) frandmod((u32) (temp_r30->unk08 * 2.0f)) - temp_r30->unk08; + PSVECNormalize(&sp20, &sp20); + PSVECScale(&sp20, &sp20, temp_r30->unk08); + PSVECAdd(&sp20, &var_r29->unk34, &var_r29->unk34); + PSVECNormalize(&temp_r31->unk18, &sp2C); + if (temp_r31->unk02 & 0x100) { + var_f28 = var_f26 + (360.0f / temp_r30->unk04) * var_r26; + var_f29 = temp_r30->unk0C; + } else { + var_f28 = (s32) frandmod(360); + if (temp_r30->unk0C) { + var_f29 = (s32) frandmod((u32) temp_r30->unk0C); + } else { + var_f29 = 0.0f; + } + } + if (sp2C.x * sp2C.x < 0.000001 && sp2C.z * sp2C.z < 0.000001) { + sp8.x = 1.0f; + sp8.y = sp8.z = 0.0f; + } else { + if (sp2C.y * sp2C.y > 0.000001) { + sp14.x = sp2C.x; + sp14.y = 0.0f; + sp14.z = sp2C.z; + } else { + sp14.x = sp2C.x; + sp14.y = 1.0f; + sp14.z = sp2C.z; + } + PSVECCrossProduct(&sp14, &sp2C, &sp8); + } + PSVECNormalize(&sp8, &sp8); + temp_f31 = sin(M_PI * var_f28 / 180.0); + temp_f30 = cos(M_PI * var_f28 / 180.0); + sp14.x = sp8.x * (sp2C.x * sp2C.x + temp_f30 * (1.0f - sp2C.x * sp2C.x)) + + sp8.y * (sp2C.x * sp2C.y * (1.0f - temp_f30) - sp2C.z * temp_f31) + + sp8.z * (sp2C.x * sp2C.z * (1.0f - temp_f30) + sp2C.y * temp_f31); + sp14.y = sp8.x * (sp2C.x * sp2C.y * (1.0f - temp_f30) + sp2C.z * temp_f31) + + sp8.y * (sp2C.y * sp2C.y + temp_f30 * (1.0f - sp2C.y * sp2C.y)) + + sp8.z * (sp2C.y * sp2C.z * (1.0f - temp_f30) - sp2C.x * temp_f31); + sp14.z = sp8.x * (sp2C.x * sp2C.z * (1.0f - temp_f30) - sp2C.y * temp_f31) + + sp8.y * (sp2C.y * sp2C.z * (1.0f - temp_f30) + sp2C.x * temp_f31) + + sp8.z * (sp2C.z * sp2C.z + temp_f30 * (1.0f - sp2C.z * sp2C.z)); + PSVECCrossProduct(&sp14, &sp2C, &sp8); + temp_f31 = sin(M_PI * var_f29 / 180.0); + temp_f30 = cos(M_PI * var_f29 / 180.0); + sp14.x = sp2C.x * (sp8.x * sp8.x + temp_f30 * (1.0f - sp8.x * sp8.x)) + + sp2C.y * (sp8.x * sp8.y * (1.0f - temp_f30) - sp8.z * temp_f31) + + sp2C.z * (sp8.x * sp8.z * (1.0f - temp_f30) + sp8.y * temp_f31); + sp14.y = sp2C.x * (sp8.x * sp8.y * (1.0f - temp_f30) + sp8.z * temp_f31) + + sp2C.y * (sp8.y * sp8.y + temp_f30 * (1.0f - sp8.y * sp8.y)) + + sp2C.z * (sp8.y * sp8.z * (1.0f - temp_f30) - sp8.x * temp_f31); + sp14.z = sp2C.x * (sp8.x * sp8.z * (1.0f - temp_f30) - sp8.y * temp_f31) + + sp2C.y * (sp8.y * sp8.z * (1.0f - temp_f30) + sp8.x * temp_f31) + + sp2C.z * (sp8.z * sp8.z + temp_f30 * (1.0f - sp8.z * sp8.z)); + PSVECNormalize(&sp14, &sp14); + temp_f31 = temp_r30->unk1C; + if (temp_r31->unk02 & 2) { + temp_f31 = temp_f31 * 0.9 + (s32) frandmod((u32) (temp_f31 * 0.1 * 1000.0)) / 1000.0f; + } else if (temp_r31->unk02 & 4) { + temp_f31 = temp_f31 * 0.7 + (s32) frandmod((u32) (temp_f31 * 0.3 * 1000.0)) / 1000.0f; + } else if (temp_r31->unk02 & 8) { + temp_f31 = (s32) frandmod((u32) (temp_f31 * 1000.0f)) / 1000.0f; + } + PSVECScale(&sp14, &var_r29->unk08, temp_f31); + var_r29->unk14 = temp_r30->unk10; + var_r29->unk20 = temp_r30->unk20; + if (temp_r31->unk02 & 0x1000) { + var_r29->unk24 = var_r24 = temp_r31->unk08; + } else { + var_r29->unk24 = var_r24 = frandmod(temp_r30->unk2C); + } + var_r29->unk40 = temp_r30->unk2E[var_r24]; + var_r29->unk00 = 0; + var_r29->unk02 = temp_r31->unk06; + break; + } else { + var_r29++; + } + } + temp_r31->unk34 -= 1.0f; + var_r26++; + } + } + if (temp_r31->unk04 != 0) { + temp_r31->unk04--; + if (temp_r31->unk04 == 0) { + temp_r31->unk02 |= 1; + } + } + HuPrcVSleep(); + } +} + +static float jitterTbl[] = { + 1.0f, 0.9f, 0.7f, 0.5f, + 0.5f, 0.7f, 0.9f, 1.0f +}; + +static void ParManHook(ModelData *arg0, ParticleData *arg1) { + HsfanimStruct00 *temp_r26; + ParManProcUserData *temp_r28; + HsfanimStruct01 *var_r29; + GXColor *temp_r24; + GXColor *temp_r27; + Vec sp1C; + Vec sp10; + float temp_f29; + float var_f30; + s16 temp_r31; + s16 sp8; + s16 i; + + if (Hu3DPauseF == 0 || (arg0->attr & 0x200000)) { + var_r29 = arg1->unk_48; + for (i = 0; i < arg1->unk_30; i++, var_r29++) { + if (var_r29->unk2C) { + temp_r28 = parManProc[var_r29->unk02]->user_data; + temp_r26 = temp_r28->unk3C; + if (temp_r28->unk02 & 0x40) { + var_r29->unk2C = var_r29->unk28 * jitterTbl[(temp_r28->unk38 + i) & 7]; + } else { + var_r29->unk2C = var_r29->unk28; + } + if (!(temp_r28->unk02 & 0x80)) { + sp8 = var_r29->unk00_s16; + var_r29->unk34.x += var_r29->unk08.x + var_r29->unk14.x; + var_r29->unk34.y += var_r29->unk08.y + var_r29->unk14.y; + var_r29->unk34.z += var_r29->unk08.z + var_r29->unk14.z; + PSVECScale(&var_r29->unk08, &var_r29->unk08, var_r29->unk20); + PSVECAdd(&temp_r26->unk10, &var_r29->unk14, &var_r29->unk14); + if (temp_r28->unk02 & 0x200) { + PSVECSubtract(&temp_r28->unk24, &var_r29->unk34, &sp1C); + PSVECNormalize(&sp1C, &sp1C); + PSVECScale(&sp1C, &sp1C, temp_r28->unk30); + PSVECAdd(&sp1C, &var_r29->unk14, &var_r29->unk14); + PSVECAdd(&var_r29->unk08, &var_r29->unk14, &sp1C); + PSVECSubtract(&temp_r28->unk24, &var_r29->unk34, &sp10); + temp_f29 = PSVECSquareMag(&sp1C); + if (PSVECSquareMag(&sp10) <= temp_f29) { + var_r29->unk2C = 0.0f; + continue; + } + } + var_r29->unk28 *= temp_r26->unk28; + var_f30 = (float) var_r29->unk00_s16 / temp_r26->unk00; + if (var_f30 > 1.0f) { + var_f30 = 1.0f; + } + OSf32tos16(&var_r29->unk24, &temp_r31); + temp_r27 = &temp_r26->unk2E[temp_r31]; + temp_r24 = &temp_r26->unk3E[temp_r31]; + var_r29->unk40.r = temp_r27->r + var_f30 * (temp_r24->r - temp_r27->r); + var_r29->unk40.g = temp_r27->g + var_f30 * (temp_r24->g - temp_r27->g); + var_r29->unk40.b = temp_r27->b + var_f30 * (temp_r24->b - temp_r27->b); + var_r29->unk40.a = temp_r27->a + var_f30 * (temp_r24->a - temp_r27->a); + if (var_r29->unk2C < 0.01 || var_r29->unk00_s16 >= temp_r26->unk00) { + var_r29->unk2C = 0.0f; + } + var_r29->unk00_s16++; + } + } + } + temp_r28 = parManProc[arg1->unk_00]->user_data; + temp_r28->unk38++; + DCStoreRangeNoSync(arg1->unk_48, arg1->unk_30 * sizeof(HsfanimStruct01)); + } +} diff --git a/src/game/hsfdraw.c b/src/game/hsfdraw.c new file mode 100755 index 00000000..93a8f6d0 --- /dev/null +++ b/src/game/hsfdraw.c @@ -0,0 +1,3276 @@ +#include "game/hsfdraw.h" +#include "game/hsfanim.h" +#include "game/hsfformat.h" +#include "game/hsfload.h" + +#include "math.h" +#include "string.h" + +#define ABS(x) ((x < 0) ? -x : x) + +typedef struct { + /* 0x00 */ ModelData *unk00; + /* 0x04 */ HsfObject *unk04; + /* 0x08 */ float unk08; + /* 0x0C */ Mtx unk0C; + /* 0x3C */ Vec unk3C; +} HsfdrawStruct00; // Size 0x48 + +typedef struct { + /* 0x00 */ u16 unk00; + /* 0x02 */ s16 unk02; + /* 0x04 */ s16 unk04; + /* 0x06 */ char unk06[2]; + /* 0x08 */ float unk08; + /* 0x0C */ float unk0C; + /* 0x10 */ float unk10; + /* 0x14 */ float unk14; + /* 0x18 */ float unk18; + /* 0x1C */ float unk1C; + /* 0x20 */ float unk20; + /* 0x24 */ float unk24; + /* 0x28 */ float unk28; + /* 0x2C */ float unk2C; + /* 0x30 */ float unk30; + /* 0x34 */ float unk34; + /* 0x38 */ float unk38; + /* 0x3C */ HsfBitmap *unk3C; +} HsfdrawStruct01; // Size unknown + +typedef struct { + s32 unk00; + s32 unk04; + u16 unk08; + char unk0A[2]; + u32 unk0C; +} DrawDataStruct; // Size 0x10 + +typedef struct { + /* 0x00 */ s16 unk00; + /* 0x02 */ s16 unk02; + /* 0x04 */ s16 unk04[3][4]; // goes up to index [3][3] (union?) + /* 0x1C */ u32 unk1C; + /* 0x20 */ void *unk20; + /* 0x24 */ char unk24[0xC]; +} HsfdrawStruct02; // Size 0x30 + +static void objCall(ModelData *arg0, HsfObject *arg1); +static void objMesh(ModelData *arg0, HsfObject *arg1); +static void FaceDraw(HsfdrawStruct00 *arg0, HsfdrawStruct02 *arg1); +static void SetTevStageNoTex(HsfdrawStruct00 *arg0, HsfMaterial *arg1); +static void SetTevStageTex(HsfdrawStruct00 *arg0, HsfMaterial *arg1); +static GXTevKColorSel SetKColor(GXTevStageID arg0, u8 arg1); +static GXTevKColorSel SetKColorRGB(GXTevStageID arg0, GXColor *arg1); +static void FlushKColor(void); +static void SetReflect(HsfdrawStruct00 *arg0, s16 arg1, s16 arg2, u8 arg3); +static void SetProjection(HsfdrawStruct00 *arg0, s16 arg1, s16 arg2, s16 arg3, GXTexMapID arg4, u32 arg5); +static void SetShadowTex(void); +static void SetShadow(HsfdrawStruct00 *arg0, s16 arg1, s16 arg2); +static void FaceDrawShadow(HsfdrawStruct00 *arg0, HsfdrawStruct02 *arg1); +static void LoadTexture(ModelData *arg0, HsfBitmap *arg1, HsfAttribute *arg2, s16 arg3); +static void objNull(ModelData *arg0, HsfObject *arg1); +static void objRoot(ModelData *arg0, HsfObject *arg1); +static void objJoint(ModelData *arg0, HsfObject *arg1); +static void objMap(ModelData *arg0, HsfObject *arg1); +static void objReplica(ModelData *arg0, HsfObject *arg1); +static void ObjDraw(HsfdrawStruct00 *arg0); +static void MDObjCall(HsfData *arg0, HsfObject *arg1); +static void MDObjMesh(HsfData *arg0, HsfObject *arg1); +static void MDFaceDraw(HsfObject *arg0, HsfdrawStruct02 *arg1); +static s32 MakeCalcNBT(HsfObject *arg0, HsfdrawStruct02 *arg1, s16 arg2, s16 arg3); +static s32 MakeNBT(HsfObject *arg0, HsfdrawStruct02 *arg1, s16 arg2, s16 arg3); +static void MDFaceCnt(HsfObject *arg0, HsfdrawStruct02 *arg1); + +void GXResetWriteGatherPipe(void); + +static const Vec lbl_8011DD20 = { 0.0f, 0.0f, -1.0f }; + +static HsfdrawStruct00 DrawObjData[512]; +static HsfAttribute *BmpPtrBak[8]; +static Mtx MTXBuf[96]; +static Vec scaleBuf[96]; +static GXColor texCol[16]; +static Mtx hiliteMtx; +static s16 DrawObjNum[512]; +static Vec NBTB; +static Vec NBTT; +Vec PGMaxPos; +Vec PGMinPos; + +s16 MTXIdx; +static HsfMaterial *materialBak; +static u8 polyTypeBak; +static s32 shadingBak; +static void *DLBufP; +static void *DLBufStartP; +static DrawDataStruct *DrawData; +static s32 drawCnt; +static s16 lightBit; +static s16 DrawObjIdx; +static HsfConstData *Hu3DObjInfoP; +static s16 reflectionMapNo; +static s16 hiliteMapNo; +static s16 vtxModeBak; +static s32 attachMotionF; +static s16 shadowMapNo; +static s16 toonMapNo; +static s16 projectionMapNo; +static GXColor kColor; +static s32 kColorIdx; +static s16 hookIdx; +u32 totalPolyCnt; +u32 totalPolyCnted; +u32 totalMatCnt; +u32 totalMatCnted; +u32 totalTexCnt; +u32 totalTexCnted; +u32 totalTexCacheCnt; +u32 totalTexCacheCnted; +s16 modelMeshNum; +s16 modelObjNum; +static s32 DLFirstF; +static u16 matChgCnt; +static u16 triCnt; +static u16 quadCnt; +static u16 faceCnt; +static u16 *faceNumBuf; +static s32 DLTotalNum; +static u32 totalSize; +static u32 mallocNo; +static s32 curModelID; +static s16 polySize; +static s32 PGFinishF; +static u8 *PGName; +static s32 TL32F; +static s32 CancelTRXF; + +u8 texMtxTbl[] = { + GX_TEXMTX0, GX_TEXMTX1, + GX_TEXMTX2, GX_TEXMTX3, + GX_TEXMTX4, GX_TEXMTX5, + GX_TEXMTX6, GX_TEXMTX7, + GX_TEXMTX8, GX_TEXMTX9 +}; + +static s16 oneceF = 1; +static GXColor firstTev = { 0xFF, 0xFF, 0x00, 0x00 }; +static GXColor secondTev = { 0x00, 0x00, 0xFF, 0xFF }; + +// TODO: move to GXVert +static inline void GXUnknownu16(const u16 x) { + GXWGFifo.u16 = x; +} + +void Hu3DDrawPreInit(void) { + DrawObjIdx = 0; +} + +void Hu3DDraw(ModelData *arg0, Mtx arg1, Vec *arg2) { + HsfdrawStruct00 *temp_r31; + HsfData *temp_r28; + float temp_f31; + Vec sp8; + s16 i; + + temp_r28 = arg0->hsfData; + if (arg0->attr & 0x10) { + temp_r31 = &DrawObjData[DrawObjIdx]; + PSMTXCopy(arg1, temp_r31->unk0C); + sp8.x = temp_r31->unk0C[0][3]; + sp8.y = temp_r31->unk0C[1][3]; + sp8.z = temp_r31->unk0C[2][3]; + temp_f31 = PSVECMag(&sp8); + temp_r31->unk08 = temp_f31; + temp_r31->unk00 = arg0; + DrawObjIdx++; + return; + } + modelMeshNum = 0; + modelObjNum = 0; + GXSetCullMode(GX_CULL_BACK); + for (i = 0; i < 8; i++) { + BmpPtrBak[i] = (HsfAttribute*) -1; + } + PSMTXCopy(arg1, MTXBuf[0]); + scaleBuf[0] = *arg2; + MTXIdx = 1; + CancelTRXF = 0; + hookIdx = -1; + shadingBak = -1; + vtxModeBak = -1; + materialBak = (HsfMaterial*) -1; + if (arg0->unk_08 != -1) { + attachMotionF = 1; + } else { + attachMotionF = 0; + } + objCall(arg0, temp_r28->root); + GXSetNumTevStages(1); + oneceF = 1; +} + +static void objCall(ModelData *arg0, HsfObject *arg1) { + modelObjNum++; + switch (arg1->type) { + case 2: + objMesh(arg0, arg1); + modelMeshNum++; + break; + case 4: + objJoint(arg0, arg1); + break; + case 5: + objNull(arg0, arg1); + break; + case 0: + objNull(arg0, arg1); + break; + case 1: + objReplica(arg0, arg1); + break; + case 3: + objRoot(arg0, arg1); + break; + case 6: + objNull(arg0, arg1); + break; + case 9: + objMap(arg0, arg1); + break; + } +} + +static void objMesh(ModelData *arg0, HsfObject *arg1) { + HsfdrawStruct00 *temp_r29; + HsfConstData *temp_r25; + HsfTransform *var_r30; + HsfData *temp_r20; + ModelData *temp_r31; + Mtx sp1C; + Vec sp10; + Vec *temp_r24; + Vec *temp_r28; + void *spC; + s16 sp8; + s16 temp_r21; + s16 var_r18; + s16 var_r19; + float temp_f31; + HsfBuffer *temp_r17; + + temp_r17 = arg1->data.face; + spC = temp_r17->data; + temp_r29 = &DrawObjData[DrawObjIdx]; + temp_r20 = arg0->hsfData; + if (attachMotionF == 0) { + var_r30 = &arg1->data.base; + } else { + var_r30 = &arg1->data.curr; + } + temp_r25 = arg1->constData; + if (!(temp_r25->flags & 0x1000)) { + if (CancelTRXF == 0) { + if (arg1->data.hook != 0 && hookIdx == -1) { + temp_r21 = arg1 - temp_r20->object; + PSMTXConcat(MTXBuf[0], temp_r20->matrix->data[temp_r21 + temp_r20->matrix->base_idx], MTXBuf[MTXIdx]); + } else { + PSMTXScale(sp1C, var_r30->scale.x, var_r30->scale.y, var_r30->scale.z); + mtxRotCat(sp1C, var_r30->rot.x, var_r30->rot.y, var_r30->rot.z); + mtxTransCat(sp1C, var_r30->pos.x, var_r30->pos.y, var_r30->pos.z); + PSMTXConcat(MTXBuf[MTXIdx - 1], sp1C, MTXBuf[MTXIdx]); + } + temp_r28 = &scaleBuf[MTXIdx]; + temp_r24 = temp_r28 - 1; + temp_r28->x = temp_r24->x * var_r30->scale.x; + temp_r28->y = temp_r24->y * var_r30->scale.y; + temp_r28->z = temp_r24->z * var_r30->scale.z; + temp_r29->unk3C = *temp_r28; + if (arg1->flags & 1) { + PSMTXInverse(MTXBuf[MTXIdx], sp1C); + sp1C[0][3] = sp1C[1][3] = sp1C[2][3] = 0.0f; + PSMTXConcat(MTXBuf[MTXIdx], sp1C, temp_r29->unk0C); + mtxScaleCat(temp_r29->unk0C, temp_r28->x, temp_r28->y, temp_r28->z); + } else { + PSMTXCopy(MTXBuf[MTXIdx], temp_r29->unk0C); + } + MTXIdx++; + var_r18 = 1; + } else { + if (arg1->flags & 1) { + PSMTXInverse(MTXBuf[MTXIdx - 1], sp1C); + sp1C[0][3] = sp1C[1][3] = sp1C[2][3] = 0.0f; + PSMTXConcat(MTXBuf[MTXIdx - 1], sp1C, temp_r29->unk0C); + mtxScaleCat(temp_r29->unk0C, scaleBuf[MTXIdx - 1].x, scaleBuf[MTXIdx - 1].y, scaleBuf[MTXIdx - 1].z); + } else { + PSMTXCopy(MTXBuf[MTXIdx - 1], temp_r29->unk0C); + } + temp_r29->unk3C = scaleBuf[MTXIdx - 1]; + CancelTRXF = 0; + var_r18 = 0; + } + PSMTXCopy(temp_r29->unk0C, temp_r25->unk10); + if (temp_r25->hook != -1) { + temp_r31 = &Hu3DData[temp_r25->hook]; + if (!(temp_r31->attr & 1)) { + temp_r21 = attachMotionF; + if (temp_r31->unk_08 != -1) { + attachMotionF = 1; + } else { + attachMotionF = 0; + } + sp8 = hookIdx; + hookIdx = temp_r25->hook; + PSMTXScale(sp1C, temp_r31->scale.x, temp_r31->scale.y, temp_r31->scale.z); + mtxRotCat(sp1C, temp_r31->rot.x, temp_r31->rot.y, temp_r31->rot.z); + mtxTransCat(sp1C, temp_r31->pos.x, temp_r31->pos.y, temp_r31->pos.z); + PSMTXConcat(sp1C, temp_r31->unk_F0, sp1C); + PSMTXConcat(temp_r29->unk0C, sp1C, MTXBuf[MTXIdx]); + temp_r28 = &scaleBuf[MTXIdx]; + temp_r24 = temp_r28 - 1; + temp_r28->x = temp_r24->x * temp_r31->scale.x; + temp_r28->y = temp_r24->y * temp_r31->scale.y; + temp_r28->z = temp_r24->z * temp_r31->scale.z; + MTXIdx++; + objCall(temp_r31, temp_r31->hsfData->root); + MTXIdx--; + hookIdx = sp8; + attachMotionF = temp_r21; + } + } else { + if (arg0->attr & 0x4000) { + var_r19 = ObjCullCheck(arg0->hsfData, arg1, temp_r29->unk0C); + } else { + var_r19 = 1; + } + if ((temp_r25->flags & 0x2000) || (arg1->flags & 0x400)) { + var_r19 = 0; + } + if (var_r19 != 0 && (var_r30->scale.x != 0.0f || var_r30->scale.y != 0.0f || var_r30->scale.z != 0.0f)) { + temp_r29->unk00 = arg0; + temp_r29->unk04 = arg1; + if ((temp_r25->flags & 0x10801) && shadowModelDrawF == 0) { + sp10.x = temp_r29->unk0C[0][3]; + sp10.y = temp_r29->unk0C[1][3]; + sp10.z = temp_r29->unk0C[2][3]; + temp_f31 = PSVECMag(&sp10); + if (temp_r25->flags & 0x10000) { + temp_r29->unk08 = -(900000.0f - temp_f31); + } else { + temp_r29->unk08 = -(1000000.0f - temp_f31); + } + DrawObjIdx++; + if (DrawObjIdx > 0x200) { + OSReport("Error: DrawObjIdx Over\n"); + DrawObjIdx--; + } + } else if (arg0->attr & 0x400000) { + temp_r29->unk08 = -1000000.0f; + DrawObjIdx++; + if (DrawObjIdx > 0x200) { + OSReport("Error: DrawObjIdx Over\n"); + DrawObjIdx--; + } + } else { + materialBak = (HsfMaterial*) -1; + ObjDraw(temp_r29); + } + } + } + for (temp_r21 = 0; temp_r21 < arg1->data.childrenCount; temp_r21++) { + objCall(arg0, arg1->data.children[temp_r21]); + } + if (var_r18 != 0) { + MTXIdx--; + } + } +} + +s32 ObjCullCheck(HsfData *arg0, HsfObject *arg1, Mtx arg2) { + CameraData *temp_r30; + HsfVector3f *temp_r29; + HsfVector3f *temp_r31; + Mtx sp28; + float sp24; + float temp_f20; + float temp_f19; + float temp_f18; + float temp_f21; + float temp_f24; + float temp_f23; + float temp_f22; + float temp_f27; + float var_f26; + float temp_f25; + float temp_f31; + float temp_f30; + float temp_f29; + + temp_r30 = &Hu3DCamera[Hu3DCameraNo]; + temp_r31 = &arg1->data.mesh.min; + temp_r29 = &arg1->data.mesh.max; + temp_f23 = scaleBuf[MTXIdx - 1].x; + temp_f22 = scaleBuf[MTXIdx - 1].y; + temp_f25 = scaleBuf[MTXIdx - 1].z; + if (temp_f23 > temp_f22) { + if (temp_f23 > temp_f25) { + var_f26 = temp_f23; + } else if (temp_f22 > temp_f25) { + var_f26 = temp_f22; + } else { + var_f26 = temp_f25; + } + } else if (temp_f22 > temp_f25) { + var_f26 = temp_f22; + } else if (temp_f23 > temp_f25) { + var_f26 = temp_f23; + } else { + var_f26 = temp_f25; + } + temp_f31 = (temp_r29->x - temp_r31->x) * 0.5; + temp_f30 = (temp_r29->y - temp_r31->y) * 0.5; + temp_f29 = (temp_r29->z - temp_r31->z) * 0.5; + PSMTXTrans(sp28, temp_f31 + temp_r31->x, temp_f30 + temp_r31->y, temp_f29 + temp_r31->z); + PSMTXConcat(arg2, sp28, sp28); + temp_f21 = var_f26 * sqrtf(temp_f31 * temp_f31 + temp_f30 * temp_f30 + temp_f29 * temp_f29); + temp_f20 = sp28[0][3]; + temp_f19 = sp28[1][3]; + temp_f18 = -sp28[2][3]; + if (temp_f18 + temp_f21 < temp_r30->near || temp_f18 - temp_f21 > temp_r30->far) { + return 0; + } + sp24 = sin(temp_r30->fov * 0.5 * M_PI / 180.0) / cos(temp_r30->fov * 0.5 * M_PI / 180.0); + temp_f27 = sp24 * temp_f18; + temp_f24 = 1.2f * temp_f27; + temp_f24 = temp_f21 + ABS(temp_f24); + temp_f27 = temp_f21 + ABS(temp_f27); + if (ABS(temp_f20) < temp_f24 && ABS(temp_f19) < temp_f27) { + return 1; + } + return 0; +} + +// TODO: not matching (https://decomp.me/scratch/54Pjw) +static void FaceDraw(HsfdrawStruct00 *arg0, HsfdrawStruct02 *arg1) { + GXColor sp2C; + void *sp28; + Hu3DTexAnimDataStruct *sp24; + HsfAttribute *temp_r26; + HsfBitmap *temp_r27; + s16 var_r22; + s16 var_r18; + s16 var_r21; + s16 var_r24; + s16 var_r31; + s16 var_r17; + u32 temp_r19; + HsfConstData *temp_r20; + HsfMaterial *temp_r30; + HsfObject *temp_r28; + ModelData *temp_r29; + HsfdrawStruct01 *temp_r23; + + temp_r28 = arg0->unk04; + temp_r29 = arg0->unk00; + temp_r20 = temp_r28->constData; + kColorIdx = 0; + temp_r30 = &temp_r28->data.material[arg1->unk02 & 0xFFF]; + temp_r19 = temp_r28->flags | temp_r30->flags; + if (temp_r19 & 0x30) { + if (temp_r19 & 0x10) { + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_ONE, GX_LO_NOOP); + } else { + GXSetBlendMode(GX_BM_BLEND, GX_BL_ZERO, GX_BL_INVDSTCLR, GX_LO_NOOP); + } + } else { + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP); + } + if (temp_r30 != materialBak) { + totalMatCnt++; + materialBak = temp_r30; + sp2C.r = temp_r30->litColor[0] * temp_r29->unk_58.x; + sp2C.g = temp_r30->litColor[1] * temp_r29->unk_58.z; + sp2C.b = temp_r30->litColor[2] * temp_r29->unk_58.y; + sp2C.a = 0xFF; + GXSetChanAmbColor(GX_COLOR0A0, sp2C); + sp2C.r = temp_r30->color[0]; + sp2C.g = temp_r30->color[1]; + sp2C.b = temp_r30->color[2]; + sp2C.a = 0xFF; + GXSetChanMatColor(GX_COLOR0A0, sp2C); + if (temp_r29->attr & 0x400000) { + var_r31 = GX_FALSE; + } else { + var_r31 = GX_TRUE; + } + if ((temp_r30->invAlpha != 0.0f || (temp_r30->pass & 0xF) || (temp_r20->flags & 0x800)) && !((temp_r29->attr & 2) | (temp_r19 & 0x1200))) { + GXSetZMode(var_r31, GX_LEQUAL, GX_FALSE); + } else { + GXSetZMode(var_r31, GX_LEQUAL, GX_TRUE); + } + if (temp_r19 & 0x1200) { + GXSetAlphaCompare(GX_GEQUAL, 0x80, GX_AOP_OR, GX_GEQUAL, 0x80); + } else { + GXSetAlphaCompare(GX_GEQUAL, 1, GX_AOP_AND, GX_GEQUAL, 1); + } + if (temp_r29->attr & 0x800000) { + GXSetCullMode(GX_CULL_FRONT); + } else if (temp_r19 & 2) { + GXSetCullMode(GX_CULL_NONE); + } else { + GXSetCullMode(GX_CULL_BACK); + } + if (TL32F != 0) { + for (var_r31 = GX_TEVSTAGE0; var_r31 < GX_MAX_TEVSTAGE; var_r31++) { + GXSetTevSwapMode(var_r31, GX_TEV_SWAP0, GX_TEV_SWAP0); + } + TL32F = 0; + } + for (var_r31 = GX_TEVSTAGE0; var_r31 < GX_MAX_TEVSTAGE; var_r31++) { + GXSetTevKAlphaSel(var_r31, GX_TEV_KASEL_1); + } + if (temp_r30->numAttrs == 0) { + var_r22 = (temp_r30->vtxMode == 5) ? 4 : 0; + if (var_r22 != vtxModeBak) { + vtxModeBak = var_r22; + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_INDEX16); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_TEX_ST, GX_RGBA6, 0); + GXSetArray(GX_VA_POS, temp_r28->data.vertex->data, 0xC); + GXSetVtxDesc(GX_VA_NRM, GX_INDEX16); + if (temp_r29->hsfData->cenvCnt == 0) { + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_TEX_S, GX_RGB8, 0); + GXSetArray(GX_VA_NRM, temp_r28->data.normal->data, 3); + } else { + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_TEX_S, GX_RGBA6, 0); + GXSetArray(GX_VA_NRM, temp_r28->data.normal->data, 0xC); + } + if (var_r22 & 4) { + GXSetVtxDesc(GX_VA_CLR0, GX_INDEX16); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_TEX_ST, GX_RGBA8, 0); + GXSetArray(GX_VA_CLR0, temp_r28->data.color->data, 4); + } + GXSetZCompLoc(1); + } + if (temp_r30->refAlpha != 0.0f) { + reflectionMapNo = 0; + BmpPtrBak[0] = (HsfAttribute*) -1; + if (temp_r29->unk_04 != -1) { + var_r17 = temp_r29->unk_04; + } else { + var_r17 = reflectMapNo; + } + HuSprTexLoad(reflectAnim[var_r17], 0, reflectionMapNo, GX_REPEAT, GX_REPEAT, GX_LINEAR); + } + if (Hu3DShadowF != 0 && Hu3DShadowCamBit != 0 && (Hu3DObjInfoP->flags & 8)) { + shadowMapNo = 1; + SetShadowTex(); + BmpPtrBak[1] = (HsfAttribute*) -1; + } + if (temp_r29->attr & 0x200) { + toonMapNo = 2; + HuSprTexLoad(toonAnim, 0, toonMapNo, GX_CLAMP, GX_CLAMP, GX_LINEAR); + BmpPtrBak[2] = (HsfAttribute*) -1; + } + if (temp_r29->unk_02 != 0) { + projectionMapNo = 3; + hiliteMapNo = projectionMapNo + 1; + for (var_r31 = 0, var_r24 = 1; var_r31 < 4; var_r31++, var_r24 <<= 1) { + if (var_r24 & temp_r29->unk_02) { + HuSprTexLoad(Hu3DProjection[var_r31].unk_04, 0, projectionMapNo + var_r31, GX_CLAMP, GX_CLAMP, GX_LINEAR); + BmpPtrBak[projectionMapNo + var_r31] = (HsfAttribute*) -1; + hiliteMapNo++; + } + } + } else { + hiliteMapNo = 3; + } + if ((temp_r29->attr & 0x20000) || (temp_r19 & 0x100)) { + if (temp_r20->hilite_map == 0) { + if (temp_r30->flags != 0) { + var_r18 = (temp_r30->pass >> 4) & 0xF; + } else { + var_r18 = (temp_r28->data.unk123 >> 4) & 0xF; + } + HuSprTexLoad(hiliteAnim[var_r18], 0, hiliteMapNo, GX_CLAMP, GX_CLAMP, GX_LINEAR); + } else { + HuSprTexLoad(temp_r20->hilite_map, 0, hiliteMapNo, GX_CLAMP, GX_CLAMP, GX_LINEAR); + } + BmpPtrBak[hiliteMapNo] = (HsfAttribute*) -1; + } + SetTevStageNoTex(arg0, temp_r30); + } else { + var_r22 = (temp_r30->vtxMode == 5) ? 5 : 1; + if (DrawData[drawCnt].unk0C & 2) { + var_r22 |= 2; + } + if (var_r22 != vtxModeBak) { + vtxModeBak = var_r22; + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_INDEX16); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_TEX_ST, GX_RGBA6, 0); + GXSetArray(GX_VA_POS, temp_r28->data.vertex->data, 0xC); + if (var_r22 & 2) { + GXSetVtxDesc(GX_VA_NBT, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NBT, GX_TEX_ST, GX_RGBA4, 8); + } else { + GXSetVtxDesc(GX_VA_NRM, GX_INDEX16); + if (temp_r29->hsfData->cenvCnt == 0) { + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_TEX_S, GX_RGB8, 0); + GXSetArray(GX_VA_NRM, temp_r28->data.normal->data, 3); + } else { + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_TEX_S, GX_RGBA6, 0); + GXSetArray(GX_VA_NRM, temp_r28->data.normal->data, 0xC); + } + } + GXSetVtxDesc(GX_VA_TEX0, GX_INDEX16); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_RGBA6, 0); + GXSetArray(GX_VA_TEX0, temp_r28->data.st->data, 8); + if (var_r22 & 4) { + GXSetVtxDesc(GX_VA_CLR0, GX_INDEX16); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_TEX_ST, GX_RGBA8, 0); + GXSetArray(GX_VA_CLR0, temp_r28->data.color->data, 4); + } + GXSetZCompLoc(0); + } + var_r21 = temp_r30->numAttrs; + for (var_r31 = 0; var_r31 < temp_r30->numAttrs; var_r31++) { + temp_r26 = &temp_r28->data.attribute[temp_r30->attrs[var_r31]]; + temp_r27 = temp_r26->bitmap; + if (temp_r26->unk04 != 0) { + texCol[var_r31].a = 0; + temp_r23 = temp_r26->unk04; + sp24 = &Hu3DTexAnimData[temp_r23->unk02]; + if ((temp_r23->unk00 & 1) && !(sp24->unk00 & 4)) { + if (Hu3DAnimSet(arg0->unk00, temp_r26, (s16) var_r31) != 0) { + BmpPtrBak[var_r31] = (HsfAttribute*) -1; + totalTexCnt++; + continue; + } + } else if (temp_r23->unk00 & 8) { + temp_r27 = temp_r23->unk3C; + if (temp_r27->dataFmt != 0xB) { + LoadTexture(arg0->unk00, temp_r27, temp_r26, (s16) var_r31); + } else { + LoadTexture(arg0->unk00, temp_r23->unk3C, temp_r26, (s16) var_r31); + LoadTexture(arg0->unk00, temp_r23->unk3C, temp_r26, var_r21 | 0x8000); + texCol[var_r31].r = (s16) var_r21; + texCol[var_r31].a = 2; + var_r21++; + } + if (temp_r27->sizeX * temp_r27->sizeY * temp_r27->pixSize > 0x40000) { + for (var_r24 = 0; var_r24 < 8; var_r24++) { + BmpPtrBak[var_r24] = (HsfAttribute*) -1; + } + } else { + BmpPtrBak[var_r31] = (HsfAttribute*) -1; + } + totalTexCnt++; + continue; + } + } + if (BmpPtrBak[var_r31] != temp_r26) { + if (BmpPtrBak[var_r31] != (HsfAttribute*) -1 && BmpPtrBak[var_r31]->bitmap == temp_r27 && temp_r26->wrap_s == BmpPtrBak[var_r31]->wrap_s && temp_r26->wrap_t == BmpPtrBak[var_r31]->wrap_t) { + if (temp_r27->dataFmt == 0xB) { + TL32F = 1; + } + totalTexCacheCnt++; + } else { + texCol[var_r31].a = 0; + if (temp_r27->dataFmt != 0xB) { + LoadTexture(arg0->unk00, temp_r27, temp_r26, (s16) var_r31); + } else { + LoadTexture(arg0->unk00, temp_r27, temp_r26, (s16) var_r31); + LoadTexture(arg0->unk00, temp_r27, temp_r26, var_r21 | 0x8000); + texCol[var_r31].r = (s16) var_r21; + texCol[var_r31].a = 2; + var_r21++; + } + if (temp_r27->sizeX * temp_r27->sizeY * temp_r27->pixSize > 0x40000) { + for (var_r24 = 0; var_r24 < 8; var_r24++) { + BmpPtrBak[var_r24] = (HsfAttribute*) -1; + } + } else { + BmpPtrBak[var_r31] = temp_r26; + } + totalTexCnt++; + } + } else { + totalTexCacheCnt++; + } + } + if (temp_r30->refAlpha != 0.0f) { + reflectionMapNo = (s16) var_r21; + shadowMapNo = reflectionMapNo + 1; + if (temp_r29->unk_04 != -1) { + var_r17 = temp_r29->unk_04; + } else { + var_r17 = reflectMapNo; + } + HuSprTexLoad(reflectAnim[var_r17], 0, reflectionMapNo, GX_REPEAT, GX_REPEAT, GX_LINEAR); + BmpPtrBak[reflectionMapNo] = (HsfAttribute*) -1; + } else { + shadowMapNo = (s16) var_r21; + } + if (Hu3DShadowF != 0 && Hu3DShadowCamBit != 0 && (Hu3DObjInfoP->flags & 8)) { + toonMapNo = shadowMapNo + 1; + SetShadowTex(); + BmpPtrBak[shadowMapNo] = (HsfAttribute*) -1; + } else { + toonMapNo = shadowMapNo; + } + if (temp_r29->attr & 0x200) { + HuSprTexLoad(toonAnim, 0, toonMapNo, GX_CLAMP, GX_CLAMP, GX_LINEAR); + BmpPtrBak[toonMapNo] = (HsfAttribute*) -1; + projectionMapNo = toonMapNo + 1; + } else { + projectionMapNo = toonMapNo; + } + if (temp_r29->unk_02 != 0) { + for (var_r31 = 0, var_r24 = 1; var_r31 < 4; var_r31++, var_r24 <<= 1) { + if (var_r24 & temp_r29->unk_02) { + HuSprTexLoad(Hu3DProjection[var_r31].unk_04, 0, projectionMapNo + var_r31, GX_CLAMP, GX_CLAMP, GX_LINEAR); + BmpPtrBak[projectionMapNo + var_r31] = (HsfAttribute*) -1; + hiliteMapNo = projectionMapNo + var_r31 + 1; + } + } + } else { + hiliteMapNo = projectionMapNo; + } + if ((temp_r29->attr & 0x20000) || (temp_r19 & 0x100)) { + if (temp_r20->hilite_map == 0) { + if (temp_r30->flags != 0) { + var_r18 = (temp_r30->pass >> 4) & 0xF; + } else { + var_r18 = (temp_r28->data.unk123 >> 4) & 0xF; + } + HuSprTexLoad(hiliteAnim[var_r18], 0, hiliteMapNo, GX_CLAMP, GX_CLAMP, GX_LINEAR); + } else { + HuSprTexLoad(temp_r20->hilite_map, 0, hiliteMapNo, GX_CLAMP, GX_CLAMP, GX_LINEAR); + } + BmpPtrBak[toonMapNo] = (HsfAttribute*) -1; + } + SetTevStageTex(arg0, temp_r30); + } + sp28 = (u8*) DLBufStartP + DrawData[drawCnt].unk00; + GXCallDisplayList(sp28, DrawData[drawCnt].unk04); + } else { + sp28 = (u8*) DLBufStartP + DrawData[drawCnt].unk00; + GXCallDisplayList(sp28, DrawData[drawCnt].unk04); + } + drawCnt++; +} + +static void SetTevStageNoTex(HsfdrawStruct00 *arg0, HsfMaterial *arg1) { + GXColor sp1C; + ModelData *temp_r28; + HsfObject *var_r21; + float var_f30; + float var_f31; + s16 var_r23; + s16 var_r26; + s16 var_r25; + s16 var_r29; + s16 var_r30; + s16 var_r24; + u32 var_r20; + GXChannelID var_r19; + GXTevAlphaArg var_r18; + u32 var_r22; + u32 sp18; + Mtx sp20; + + var_r30 = 1; + var_r29 = 0; + var_r21 = arg0->unk04; + temp_r28 = arg0->unk00; + sp18 = var_r21->flags | arg1->flags; + if (arg1->vtxMode == 2 || arg1->vtxMode == 3) { + var_r26 = 1; + var_r24 = 1; + } else { + var_r26 = 0; + if (arg1->vtxMode == 0 || arg1->vtxMode == 5) { + var_r24 = 0; + } else { + var_r24 = 1; + } + } + if ((Hu3DObjInfoP->flags & 0x4000) && arg1->vtxMode == 5) { + var_r19 = GX_COLOR0A0; + var_r18 = GX_CA_RASA; + var_r22 = 1; + } else { + var_r19 = GX_COLOR0; + var_r18 = GX_CA_KONST; + var_r22 = 0; + } + sp1C.a = 255.0f * (1.0f - arg1->invAlpha); + if (temp_r28->attr & 0x200) { + sp1C.r = arg1->color[0]; + sp1C.g = arg1->color[1]; + sp1C.b = arg1->color[2]; + GXSetTevColor(GX_TEVREG0, sp1C); + GXSetTexCoordGen2(var_r29, GX_TG_SRTG, GX_TG_COLOR0, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + GXSetTevOrder(GX_TEVSTAGE0, var_r29, toonMapNo, GX_COLOR0A0); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_C0, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_KONST, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + var_r29++; + } else { + GXSetTevColor(GX_TEVREG0, sp1C); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, var_r19); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_RASC); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, var_r18); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + } + if (arg1->refAlpha != 0.0f) { + SetReflect(arg0, var_r30, (s16) var_r29, arg1->refAlpha * 255.0f); + var_r30++; + var_r29++; + } + if (Hu3DShadowF != 0 && Hu3DShadowCamBit != 0 && (Hu3DObjInfoP->flags & 8)) { + SetShadow(arg0, var_r30, (s16) var_r29); + var_r30++; + var_r29++; + } + if (var_r26 != 0) { + if ((temp_r28->attr & 0x20000) || (sp18 & 0x100)) { + GXSetTexCoordGen2(var_r29, GX_TG_MTX2x4, GX_TG_NRM, GX_TEXMTX7, GX_FALSE, GX_PTIDENTITY); + GXSetTevOrder(var_r30, var_r29, hiliteMapNo, GX_COLOR0A0); + GXSetTevColorIn(var_r30, GX_CC_ZERO, GX_CC_ONE, GX_CC_TEXC, GX_CC_CPREV); + GXSetTevColorOp(var_r30, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(var_r30, GX_CA_ZERO, GX_CA_APREV, GX_CA_A0, GX_CA_ZERO); + GXSetTevAlphaOp(var_r30, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); + var_f31 = 6.0f * (arg1->hilite_scale / 300.0f); + if (var_f31 < 0.1) { + var_f31 = 0.1f; + } + PSMTXCopy(hiliteMtx, sp20); + mtxScaleCat(sp20, var_f31, var_f31, var_f31); + GXLoadTexMtxImm(sp20, GX_TEXMTX7, GX_MTX2x4); + var_r30++; + var_r29++; + var_r24 = 1; + var_r26 = 0; + } else { + GXSetTevOrder(var_r30, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR1A1); + GXSetTevColorIn(var_r30, GX_CC_CPREV, GX_CC_ONE, GX_CC_RASC, GX_CC_ZERO); + GXSetTevColorOp(var_r30, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(var_r30, GX_CA_ZERO, GX_CA_APREV, GX_CA_A0, GX_CA_ZERO); + GXSetTevAlphaOp(var_r30, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + var_r30++; + } + } else if (arg1->invAlpha != 0.0f) { + GXSetTevOrder(var_r30, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetTevColorIn(var_r30, GX_CC_ZERO, GX_CC_ONE, GX_CC_CPREV, GX_CC_ZERO); + GXSetTevColorOp(var_r30, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(var_r30, GX_CA_ZERO, GX_CA_APREV, GX_CA_A0, GX_CA_ZERO); + GXSetTevAlphaOp(var_r30, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + var_r30++; + } + if (temp_r28->unk_02 != 0) { + for (var_r25 = 0, var_r23 = 1; var_r25 < 4; var_r25++, var_r23 <<= 1) { + if (var_r23 & temp_r28->unk_02) { + SetProjection(arg0, var_r30, var_r25, (GXTexMapID) var_r29, projectionMapNo + var_r25, texMtxTbl[var_r25 + 3]); + var_r29++; + var_r30 += 2; + } + } + } + FlushKColor(); + GXSetNumTexGens(var_r29); + GXSetNumTevStages(var_r30); + var_r20 = (var_r26 != 0) ? 2 : arg1->vtxMode; + if (var_r20 != shadingBak) { + shadingBak = var_r20; + if (var_r26 != 0) { + var_f30 = arg1->hilite_scale; + } else { + var_f30 = 0.0f; + } + lightBit = Hu3DLightSet(arg0->unk00, &Hu3DCameraMtx, &Hu3DCameraMtxXPose, var_f30); + } + if (var_r26 != 0) { + GXSetNumChans(2); + if (arg1->vtxMode == 5) { + GXSetChanCtrl(GX_COLOR0, GX_TRUE, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_CLAMP, GX_AF_NONE); + GXSetChanCtrl(GX_COLOR1, GX_TRUE, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_NONE, GX_AF_SPEC); + if (var_r22 != 0) { + GXSetChanCtrl(GX_ALPHA0, GX_TRUE, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_CLAMP, GX_AF_NONE); + GXSetChanCtrl(GX_ALPHA1, GX_TRUE, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_CLAMP, GX_AF_SPEC); + } else { + GXSetChanCtrl(GX_ALPHA0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_CLAMP, GX_AF_NONE); + GXSetChanCtrl(GX_ALPHA1, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_CLAMP, GX_AF_NONE); + } + } else { + GXSetChanCtrl(GX_COLOR0, GX_TRUE, GX_SRC_REG, GX_SRC_REG, lightBit, GX_DF_CLAMP, GX_AF_NONE); + GXSetChanCtrl(GX_COLOR1, GX_TRUE, GX_SRC_REG, GX_SRC_REG, lightBit, GX_DF_NONE, GX_AF_SPEC); + GXSetChanCtrl(GX_ALPHA0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_CLAMP, GX_AF_NONE); + GXSetChanCtrl(GX_ALPHA1, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_CLAMP, GX_AF_NONE); + } + } else { + GXSetNumChans(1); + if (arg1->vtxMode == 5) { + GXSetChanCtrl(GX_COLOR0, var_r24, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_CLAMP, GX_AF_SPOT); + if (var_r22 != 0) { + GXSetChanCtrl(GX_ALPHA0, GX_TRUE, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_CLAMP, GX_AF_SPOT); + } else { + GXSetChanCtrl(GX_ALPHA0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_CLAMP, GX_AF_NONE); + } + } else { + GXSetChanCtrl(GX_COLOR0, var_r24, GX_SRC_REG, GX_SRC_REG, lightBit, GX_DF_CLAMP, GX_AF_SPOT); + GXSetChanCtrl(GX_ALPHA0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_CLAMP, GX_AF_NONE); + } + GXSetChanCtrl(GX_COLOR1A1, GX_FALSE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + } +} + +static Mtx refMtx = { + { 0.25f, 0.0f, 0.0f, -0.5f }, + { 0.0f, -0.25f, 0.0f, -0.5f }, + { 0.0f, 0.0f, 0.25f, -0.5f } +}; + +static inline void SetTevStageTexInlineFunc(u16 arg0, u32 arg1) { + GXSetTexCoordGen2(arg0, GX_TG_MTX2x4, GX_TG_TEX0, arg1, GX_FALSE, GX_PTIDENTITY); +} + +static void SetTevStageTex(HsfdrawStruct00 *arg0, HsfMaterial *arg1) { + GXColor sp50; + GXTexMapID sp4C; + GXTevStageID sp48; + s32 sp44; + u32 sp40; + GXChannelID sp3C; + u32 sp38; + HsfAttribute *temp_r29; + HsfObject *temp_r19; + ModelData *temp_r25; + HsfdrawStruct01 *temp_r28; + GXTevAlphaArg var_r17; + float var_f30; + float var_f31; + u16 sp8; + u16 temp_r23; + u16 var_r22; + u16 var_r30; + u16 var_r31; + u16 var_r21; + u16 var_r18; + u16 i; + s16 var_r20; + Mtx sp54; + + sp8 = 0; + var_r20 = -1; + temp_r19 = arg0->unk04; + temp_r25 = arg0->unk00; + sp40 = temp_r19->flags | arg1->flags; + if (arg1->vtxMode == 2 || arg1->vtxMode == 3) { + var_r21 = 1; + } else { + var_r21 = 0; + if (arg1->vtxMode == 0 || arg1->vtxMode == 5) { + var_r18 = 0; + } else { + var_r18 = 1; + } + } + if ((Hu3DObjInfoP->flags & 0x4000) && arg1->vtxMode == 5) { + sp3C = GX_COLOR0A0; + var_r17 = GX_CA_RASA; + sp38 = 1; + } else { + sp3C = GX_COLOR0; + var_r17 = GX_CA_KONST; + sp38 = 0; + } + if (arg1->numAttrs == 1) { + var_r30 = var_r31 = 1; + temp_r29 = &temp_r19->data.attribute[arg1->attrs[0]]; + if (temp_r29->unk28 != 1.0f || temp_r29->unk2C != 1.0f) { + PSMTXScale(sp54, 1.0f / temp_r29->unk28, 1.0f / temp_r29->unk2C, 1.0f); + mtxTransCat(sp54, -temp_r29->unk30, -temp_r29->unk34, 0.0f); + GXLoadTexMtxImm(sp54, texMtxTbl[var_r30], GX_MTX2x4); + SetTevStageTexInlineFunc(GX_TEXCOORD0, texMtxTbl[var_r30]); + } else if (temp_r29->unk30 != 0.0f || temp_r29->unk34 != 0.0f) { + PSMTXTrans(sp54, -temp_r29->unk30, -temp_r29->unk34, 0.0f); + GXLoadTexMtxImm(sp54, texMtxTbl[var_r30], GX_MTX2x4); + SetTevStageTexInlineFunc(GX_TEXCOORD0, texMtxTbl[var_r30]); + } else { + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + } + if (temp_r29->unk20 == 1.0f) { + if (temp_r29->unk04) { + temp_r28 = temp_r29->unk04; + if (temp_r28->unk00 & 2) { + GXLoadTexMtxImm(Hu3DTexScrData[temp_r28->unk04].unk3C, GX_TEXMTX0, GX_MTX2x4); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX0, GX_FALSE, GX_PTIDENTITY); + } else if (temp_r28->unk00 & 4) { + PSMTXScale(sp54, 1.0f / temp_r28->unk20, 1.0f / temp_r28->unk24, 1.0f / temp_r28->unk28); + mtxRotCat(sp54, temp_r28->unk14, temp_r28->unk18, temp_r28->unk1C); + mtxTransCat(sp54, -temp_r28->unk08, -temp_r28->unk0C, -temp_r28->unk10); + GXLoadTexMtxImm(sp54, GX_TEXMTX0, GX_MTX2x4); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX0, GX_FALSE, GX_PTIDENTITY); + } else if (temp_r28->unk00 & 1) { + PSMTXScale(sp54, temp_r28->unk2C, temp_r28->unk30, 1.0f); + mtxTransCat(sp54, temp_r28->unk34, temp_r28->unk38, 0.0f); + GXLoadTexMtxImm(sp54, GX_TEXMTX0, GX_MTX2x4); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX0, GX_FALSE, GX_PTIDENTITY); + } + } + if (temp_r29->unk8[2] == 0) { + GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR); + GXSetTevOrder(var_r31, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); + GXSetTevColorIn(var_r31, GX_CC_CPREV, GX_CC_TEXC, GX_CC_TEXA, GX_CC_ZERO); + GXSetTevColorOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_KONST); + GXSetTevAlphaOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + var_r31++; + } else { + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0); + if (!(temp_r25->attr & 0x200)) { + if (texCol[0].a == 1) { + sp50 = texCol[0]; + sp50.a = 0xFF; + SetKColorRGB(GX_TEVSTAGE0, &sp50); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_KONST, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_TEXA, GX_CA_KONST, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevOrder(var_r31, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, sp3C); + GXSetTevColorIn(var_r31, GX_CC_ZERO, GX_CC_CPREV, GX_CC_RASC, GX_CC_ZERO); + GXSetTevColorOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_APREV, var_r17, GX_CA_ZERO); + GXSetTevAlphaOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + var_r31++; + } else if (texCol[0].a == 2) { + GXSetTevSwapModeTable(GX_TEV_SWAP1, GX_CH_RED, GX_CH_ALPHA, GX_CH_ALPHA, GX_CH_ALPHA); + GXSetTevSwapModeTable(GX_TEV_SWAP2, GX_CH_BLUE, GX_CH_BLUE, GX_CH_BLUE, GX_CH_ALPHA); + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP1); + SetKColorRGB(GX_TEVSTAGE0, &firstTev); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_KONST, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + GXSetTevSwapMode(var_r31, GX_TEV_SWAP0, GX_TEV_SWAP2); + SetKColorRGB(var_r31, &secondTev); + GXSetTevColorIn(var_r31, GX_CC_ZERO, GX_CC_TEXC, GX_CC_KONST, GX_CC_CPREV); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_KONST, GX_CA_TEXA, GX_CA_ZERO); + GXSetTevColorOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevOrder(var_r31, GX_TEXCOORD0, texCol->r, GX_COLOR_NULL); + var_r31++; + } else { + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_RASC, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_TEXA, var_r17, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + } + } else { + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_ONE, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_TEXA, GX_CA_KONST, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + } + } + } else { + GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR); + } + if (temp_r25->attr & 0x200) { + GXSetTexCoordGen2(var_r30, GX_TG_SRTG, GX_TG_COLOR0, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + GXSetTevOrder(var_r31, var_r30, toonMapNo, GX_COLOR0A0); + GXSetTevColorIn(var_r31, GX_CC_ZERO, GX_CC_TEXC, GX_CC_CPREV, GX_CC_ZERO); + GXSetTevColorOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_KONST, GX_CA_APREV, GX_CA_ZERO); + GXSetTevAlphaOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + var_r30++; + var_r31++; + } + sp50.a = 255.0f * (1.0f - arg1->invAlpha); + GXSetTevColor(GX_TEVREG0, sp50); + if (arg1->refAlpha != 0.0f) { + SetReflect(arg0, var_r31, (u16) var_r30, 255.0f * arg1->refAlpha); + var_r30++; + var_r31++; + } + if (Hu3DShadowF != 0 && Hu3DShadowCamBit != 0 && (Hu3DObjInfoP->flags & 8)) { + SetShadow(arg0, var_r31, (u16) var_r30); + var_r30++; + var_r31++; + } + if (var_r21 != 0) { + if ((temp_r25->attr & 0x20000) || (sp40 & 0x100)) { + GXSetTexCoordGen2(var_r30, GX_TG_MTX2x4, GX_TG_NRM, GX_TEXMTX7, GX_FALSE, GX_PTIDENTITY); + GXSetTevOrder(var_r31, var_r30, hiliteMapNo, GX_COLOR0A0); + GXSetTevColorIn(var_r31, GX_CC_ZERO, GX_CC_TEXC, GX_CC_ONE, GX_CC_CPREV); + GXSetTevColorOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_APREV, GX_CA_A0, GX_CA_ZERO); + GXSetTevAlphaOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); + var_f31 = 6.0f * (arg1->hilite_scale / 300.0f); + if (var_f31 < 0.1) { + var_f31 = 0.1f; + } + PSMTXCopy(hiliteMtx, sp54); + mtxScaleCat(sp54, var_f31, var_f31, var_f31); + GXLoadTexMtxImm(sp54, GX_TEXMTX7, GX_MTX2x4); + var_r31++; + var_r30++; + var_r21 = 0; + var_r18 = 1; + } else { + if (temp_r29->unk20 == 1.0f) { + GXSetTevOrder(var_r31, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR1A1); + GXSetTevColorIn(var_r31, GX_CC_CPREV, GX_CC_ONE, GX_CC_RASC, GX_CC_ZERO); + } else { + GXSetTexCoordGen2(var_r30, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + GXSetTevOrder(var_r31, var_r30, GX_TEXMAP0, GX_COLOR1A1); + GXSetTevColorIn(var_r31, GX_CC_ZERO, GX_CC_TEXC, GX_CC_RASC, GX_CC_CPREV); + var_r30++; + } + GXSetTevColorOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_APREV, GX_CA_A0, GX_CA_ZERO); + GXSetTevAlphaOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + var_r31++; + } + } else if (arg1->invAlpha != 0.0f) { + GXSetTevOrder(var_r31, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetTevColorIn(var_r31, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_CPREV); + GXSetTevColorOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_APREV, GX_CA_A0, GX_CA_ZERO); + GXSetTevAlphaOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + var_r31++; + } + if (temp_r25->unk_02 != 0) { + for (i = 0, var_r22 = 1; i < 4; i++, var_r22 <<= 1) { + if (var_r22 & temp_r25->unk_02) { + SetProjection(arg0, var_r31, i, (u16) var_r30, projectionMapNo + i, texMtxTbl[i + 3]); + var_r30++; + var_r31 += 2; + } + } + } + } else { + sp44 = 0; + var_r30 = 0; + sp4C = -1; + for (i = var_r31 = 0; i < arg1->numAttrs; i++) { + temp_r29 = &temp_r19->data.attribute[arg1->attrs[i]]; + if (temp_r29->unk14 != 0.0f) { + GXSetTexCoordGen2(var_r30, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + GXSetTexCoordGen2(GX_TEXCOORD2, GX_TG_BUMP0, GX_TG_TEXCOORD0, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + SetKColor(var_r31, temp_r29->unk14 * 10.0f); + GXSetTevOrder(var_r31, var_r30, i, GX_COLOR0A0); + GXSetTevColorIn(var_r31, GX_CC_ZERO, GX_CC_TEXC, GX_CC_KONST, GX_CC_RASC); + GXSetTevColorOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); + GXSetTevAlphaOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); + var_r31++; + sp4C = i; + sp48 = var_r31; + GXSetTevColorIn(var_r31, GX_CC_ZERO, GX_CC_TEXC, GX_CC_A1, GX_CC_CPREV); + GXSetTevColorOp(var_r31, GX_TEV_SUB, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); + GXSetTevAlphaOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); + var_r30++; + sp44 = 1; + } else if (temp_r29->unk20 != 1.0f) { + var_r20 = i; + continue; + } else { + if (temp_r29->unk04) { + temp_r28 = temp_r29->unk04; + if (temp_r28->unk00 & 2) { + GXLoadTexMtxImm(Hu3DTexScrData[temp_r28->unk04].unk3C, texMtxTbl[var_r30], GX_MTX2x4); + SetTevStageTexInlineFunc(var_r30, texMtxTbl[var_r30]); + temp_r23 = (u16) var_r30; + var_r30++; + } else if (temp_r28->unk00 & 4) { + PSMTXScale(sp54, 1.0f / temp_r28->unk20, 1.0f / temp_r28->unk24, 1.0f / temp_r28->unk28); + mtxRotCat(sp54, temp_r28->unk14, temp_r28->unk18, temp_r28->unk1C); + mtxTransCat(sp54, -temp_r28->unk08, -temp_r28->unk0C, -temp_r28->unk10); + GXLoadTexMtxImm(sp54, texMtxTbl[var_r30], GX_MTX2x4); + SetTevStageTexInlineFunc(var_r30, texMtxTbl[var_r30]); + temp_r23 = (u16) var_r30; + var_r30++; + } else if (temp_r28->unk00 & 1) { + PSMTXScale(sp54, temp_r28->unk2C, temp_r28->unk30, 1.0f); + mtxTransCat(sp54, temp_r28->unk34, temp_r28->unk38, 0.0f); + GXLoadTexMtxImm(sp54, texMtxTbl[var_r30], GX_MTX2x4); + SetTevStageTexInlineFunc(var_r30, texMtxTbl[var_r30]); + temp_r23 = (u16) var_r30; + var_r30++; + } else { + GXSetTexCoordGen2(var_r30, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + temp_r23 = (u16) var_r30; + var_r30++; + } + } else { + if (temp_r29->unk28 != 1.0f || temp_r29->unk2C != 1.0f) { + PSMTXScale(sp54, 1.0f / temp_r29->unk28, 1.0f / temp_r29->unk2C, 1.0f); + mtxTransCat(sp54, -temp_r29->unk30, -temp_r29->unk34, 0.0f); + GXLoadTexMtxImm(sp54, texMtxTbl[var_r30], GX_MTX2x4); + SetTevStageTexInlineFunc(var_r30, texMtxTbl[var_r30]); + } else if (temp_r29->unk30 != 0.0f || temp_r29->unk34 != 0.0f) { + PSMTXTrans(sp54, -temp_r29->unk30, -temp_r29->unk34, 0.0f); + GXLoadTexMtxImm(sp54, texMtxTbl[var_r30], GX_MTX2x4); + SetTevStageTexInlineFunc(var_r30, texMtxTbl[var_r30]); + } else { + GXSetTexCoordGen2(var_r30, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + } + temp_r23 = (u16) var_r30; + var_r30++; + } + GXSetTevOrder(var_r31, temp_r23, i, GX_COLOR0A0); + if (i == 0) { + if (texCol[i].a == 1) { + sp50 = texCol[i]; + sp50.a = 0xFF; + sp8 = SetKColorRGB(GX_TEVSTAGE0, &sp50); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_KONST, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVREG2); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVREG2); + var_r31++; + GXSetTevKColorSel(var_r31, sp8); + GXSetTevOrder(var_r31, temp_r23, i, sp3C); + GXSetTevColorIn(var_r31, GX_CC_ZERO, GX_CC_CPREV, GX_CC_KONST, GX_CC_ZERO); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_TEXA, GX_CA_KONST, GX_CA_ZERO); + } else if (texCol[i].a == 2) { + GXSetTevSwapModeTable(GX_TEV_SWAP1, GX_CH_RED, GX_CH_ALPHA, GX_CH_ALPHA, GX_CH_ALPHA); + GXSetTevSwapModeTable(GX_TEV_SWAP2, GX_CH_BLUE, GX_CH_BLUE, GX_CH_BLUE, GX_CH_ALPHA); + GXSetTevSwapMode(var_r31, GX_TEV_SWAP0, GX_TEV_SWAP1); + SetKColorRGB(var_r31, &firstTev); + GXSetTevColorIn(var_r31, GX_CC_ZERO, GX_CC_TEXC, GX_CC_KONST, GX_CC_ZERO); + GXSetTevColorOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVREG2); + GXSetTevOrder(var_r31, GX_TEXCOORD0, i, GX_COLOR_NULL); + var_r31++; + GXSetTevSwapMode(var_r31, GX_TEV_SWAP0, GX_TEV_SWAP2); + SetKColorRGB(var_r31, &secondTev); + GXSetTevColorIn(var_r31, GX_CC_CPREV, GX_CC_TEXC, GX_CC_KONST, GX_CC_C2); + GXSetTevAlphaIn(var_r31, GX_CA_APREV, GX_CA_KONST, GX_CA_TEXA, GX_CA_ZERO); + GXSetTevOrder(var_r31, GX_TEXCOORD0, texCol->r, GX_COLOR_NULL); + } else { + GXSetTevColorIn(var_r31, GX_CC_ZERO, GX_CC_TEXC, GX_CC_RASC, GX_CC_ZERO); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_TEXA, var_r17, GX_CA_ZERO); + } + } else if (sp44 != 0) { + GXSetTevColorIn(var_r31, GX_CC_ZERO, GX_CC_CPREV, GX_CC_TEXC, GX_CC_ZERO); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + sp44 = 0; + } else if (temp_r29->unk8[2] == 0) { + if (temp_r29->unk0C != 1.0f) { + sp50.a = temp_r29->unk0C * 255.0f; + SetKColorRGB(var_r31, &sp50); + GXSetTevColorIn(var_r31, GX_CC_ZERO, GX_CC_TEXC, GX_CC_RASC, GX_CC_ZERO); + GXSetTevColorOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVREG2); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_TEXA, GX_CA_KONST, GX_CA_ZERO); + GXSetTevAlphaOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVREG2); + var_r31++; + GXSetTevOrder(var_r31, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetTevColorIn(var_r31, GX_CC_CPREV, GX_CC_C2, GX_CC_A2, GX_CC_ZERO); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV); + } else { + GXSetTevColorIn(var_r31, GX_CC_ZERO, GX_CC_TEXC, GX_CC_RASC, GX_CC_ZERO); + GXSetTevColorOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVREG2); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); + GXSetTevAlphaOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVREG2); + var_r31++; + GXSetTevOrder(var_r31, temp_r23, i, GX_COLOR0A0); + GXSetTevColorIn(var_r31, GX_CC_CPREV, GX_CC_C2, GX_CC_TEXA, GX_CC_ZERO); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV); + } + } else if (texCol[i].a == 1) { + sp50 = texCol[i]; + sp50.a = 0xFF; + SetKColorRGB(var_r31, &sp50); + GXSetTevColorIn(var_r31, GX_CC_ZERO, GX_CC_TEXC, GX_CC_KONST, GX_CC_ZERO); + GXSetTevColorOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVREG2); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_KONST, GX_CA_APREV, GX_CA_ZERO); + GXSetTevAlphaOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVREG2); + var_r31++; + GXSetTevOrder(var_r31, temp_r23, i, GX_COLOR0A0); + SetKColor(var_r31, temp_r29->unk0C * 255.0f); + GXSetTevColorIn(var_r31, GX_CC_CPREV, GX_CC_C2, GX_CC_KONST, GX_CC_ZERO); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_TEXA, GX_CA_APREV, GX_CA_ZERO); + } else if (texCol[i].a == 2) { + GXSetTevSwapModeTable(GX_TEV_SWAP1, GX_CH_RED, GX_CH_ALPHA, GX_CH_ALPHA, GX_CH_ALPHA); + GXSetTevSwapModeTable(GX_TEV_SWAP2, GX_CH_BLUE, GX_CH_BLUE, GX_CH_BLUE, GX_CH_ALPHA); + GXSetTevSwapMode(var_r31, GX_TEV_SWAP0, GX_TEV_SWAP1); + SetKColorRGB(var_r31, &firstTev); + GXSetTevColorIn(var_r31, GX_CC_ZERO, GX_CC_TEXC, GX_CC_KONST, GX_CC_ZERO); + GXSetTevColorOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVREG2); + GXSetTevOrder(var_r31, GX_TEXCOORD0, i, GX_COLOR_NULL); + var_r31++; + GXSetTevSwapMode(var_r31, GX_TEV_SWAP0, GX_TEV_SWAP2); + SetKColorRGB(var_r31, &secondTev); + GXSetTevColorIn(var_r31, GX_CC_CPREV, GX_CC_TEXC, GX_CC_KONST, GX_CC_C2); + GXSetTevAlphaIn(var_r31, GX_CA_APREV, GX_CA_KONST, GX_CA_TEXA, GX_CA_ZERO); + GXSetTevOrder(var_r31, GX_TEXCOORD0, texCol->r, GX_COLOR_NULL); + } else { + SetKColor(var_r31, temp_r29->unk0C * 255.0f); + GXSetTevColorIn(var_r31, GX_CC_CPREV, GX_CC_TEXC, GX_CC_KONST, GX_CC_ZERO); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_TEXA, GX_CA_APREV, GX_CA_ZERO); + } + GXSetTevColorOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + } + var_r31++; + } + if (temp_r25->attr & 0x200) { + GXSetTexCoordGen2(var_r30, GX_TG_SRTG, GX_TG_COLOR0, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + GXSetTevOrder(var_r31, var_r30, toonMapNo, GX_COLOR0A0); + GXSetTevColorIn(var_r31, GX_CC_ZERO, GX_CC_TEXC, GX_CC_CPREV, GX_CC_ZERO); + GXSetTevColorOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_KONST, GX_CA_APREV, GX_CA_ZERO); + GXSetTevAlphaOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + var_r30++; + var_r31++; + } + if (arg1->refAlpha != 0.0f) { + if (var_r20 != -1) { + SetKColor(var_r31, arg1->refAlpha * 255.0f); + GXSetTexCoordGen2(var_r30, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + GXSetTevOrder(var_r31, var_r30, var_r20, GX_COLOR0A0); + GXSetTevColorIn(var_r31, GX_CC_ZERO, GX_CC_TEXC, GX_CC_KONST, GX_CC_ZERO); + GXSetTevColorOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVREG2); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV); + GXSetTevAlphaOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVREG2); + var_r31++; + var_r30++; + GXSetTexCoordGen2(var_r30, GX_TG_MTX2x4, GX_TG_NRM, GX_TEXMTX8, GX_FALSE, GX_PTIDENTITY); + GXSetTevOrder(var_r31, var_r30, reflectionMapNo, GX_COLOR0A0); + GXSetTevColorIn(var_r31, GX_CC_CPREV, GX_CC_TEXC, GX_CC_C2, GX_CC_ZERO); + GXSetTevColorOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV); + GXSetTevAlphaOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); + } else { + SetKColor(var_r31, arg1->refAlpha * 255.0f); + GXSetTexCoordGen2(var_r30, GX_TG_MTX2x4, GX_TG_NRM, GX_TEXMTX8, GX_FALSE, GX_PTIDENTITY); + GXSetTevOrder(var_r31, var_r30, reflectionMapNo, GX_COLOR0A0); + GXSetTevColorIn(var_r31, GX_CC_CPREV, GX_CC_TEXC, GX_CC_KONST, GX_CC_ZERO); + GXSetTevColorOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV); + GXSetTevAlphaOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); + } + PSMTXScale(sp54, 1.0f / arg0->unk3C.x, 1.0f / arg0->unk3C.y, 1.0f / arg0->unk3C.z); + PSMTXConcat(arg0->unk0C, sp54, sp54); + sp54[0][3] = sp54[1][3] = sp54[2][3] = 0.0f; + PSMTXConcat(sp54, Hu3DCameraMtxXPose, sp54); + PSMTXConcat(refMtx, sp54, sp54); + GXLoadTexMtxImm(sp54, 0x36, GX_MTX2x4); + var_r31++; + var_r30++; + } + if (Hu3DShadowF != 0 && Hu3DShadowCamBit != 0 && (Hu3DObjInfoP->flags & 8)) { + SetShadow(arg0, var_r31, (u16) var_r30); + var_r30++; + var_r31++; + } + sp50.a = (1.0f - arg1->invAlpha) * 255.0f; + GXSetTevColor(GX_TEVREG0, sp50); + if (var_r21 != 0) { + if ((temp_r25->attr & 0x20000) || (sp40 & 0x100)) { + var_f31 = (arg1->hilite_scale / 300.0f) * 6.0f; + if (var_f31 < 0.1) { + var_f31 = 0.1f; + } + PSMTXCopy(hiliteMtx, sp54); + mtxScaleCat(sp54, var_f31, var_f31, var_f31); + GXLoadTexMtxImm(sp54, 0x33, GX_MTX2x4); + if (var_r20 == -1) { + GXSetTexCoordGen2(var_r30, GX_TG_MTX2x4, GX_TG_NRM, GX_TEXMTX7, GX_FALSE, GX_PTIDENTITY); + GXSetTevOrder(var_r31, var_r30, hiliteMapNo, GX_COLOR0A0); + GXSetTevColorIn(var_r31, GX_CC_ZERO, GX_CC_TEXC, GX_CC_ONE, GX_CC_CPREV); + GXSetTevColorOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_APREV, GX_CA_A0, GX_CA_ZERO); + GXSetTevAlphaOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); + } else { + GXSetTexCoordGen2(var_r30, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + GXSetTevOrder(var_r31, var_r30, var_r20, GX_COLOR0A0); + GXSetTevColorIn(var_r31, GX_CC_ZERO, GX_CC_TEXC, GX_CC_ONE, GX_CC_ZERO); + GXSetTevColorOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVREG0); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); + GXSetTevAlphaOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVREG0); + var_r31++; + var_r30++; + GXSetTexCoordGen2(var_r30, GX_TG_MTX2x4, GX_TG_NRM, GX_TEXMTX7, GX_FALSE, GX_PTIDENTITY); + GXSetTevOrder(var_r31, var_r30, hiliteMapNo, GX_COLOR0A0); + GXSetTevColorIn(var_r31, GX_CC_ZERO, GX_CC_TEXC, GX_CC_C0, GX_CC_CPREV); + GXSetTevColorOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV); + GXSetTevAlphaOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); + } + var_r31++; + var_r30++; + var_r21 = 0; + var_r18 = 1; + } else { + if (var_r20 == -1) { + GXSetTevOrder(var_r31, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR1A1); + GXSetTevColorIn(var_r31, GX_CC_CPREV, GX_CC_ONE, GX_CC_RASC, GX_CC_ZERO); + } else { + GXSetTexCoordGen2(var_r30, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + GXSetTevOrder(var_r31, var_r30, var_r20, GX_COLOR1A1); + GXSetTevColorIn(var_r31, GX_CC_ZERO, GX_CC_TEXC, GX_CC_RASC, GX_CC_CPREV); + var_r30++; + } + GXSetTevColorOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_APREV, GX_CA_A0, GX_CA_ZERO); + GXSetTevAlphaOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + var_r31++; + } + } else if (arg1->invAlpha != 0.0f) { + GXSetTevOrder(var_r31, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetTevColorIn(var_r31, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_CPREV); + GXSetTevColorOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(var_r31, GX_CA_ZERO, GX_CA_APREV, GX_CA_A0, GX_CA_ZERO); + GXSetTevAlphaOp(var_r31, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + var_r31++; + } + if (temp_r25->unk_02 != 0) { + for (i = 0, var_r22 = 1; i < 4; i++, var_r22 <<= 1) { + if (var_r22 & temp_r25->unk_02) { + SetProjection(arg0, var_r31, i, (u16) var_r30, projectionMapNo + i, texMtxTbl[i + 3]); + var_r30++; + var_r31 += 2; + } + } + } + if (sp4C != -1) { + GXSetTexCoordGen2(var_r30, GX_TG_BUMP0, GX_TG_TEXCOORD0, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + GXSetTevOrder(sp48, var_r30, sp4C, GX_COLOR0A0); + var_r30++; + } + } + FlushKColor(); + GXSetNumTexGens(var_r30); + GXSetNumTevStages(var_r31); + if (arg1->vtxMode != shadingBak) { + shadingBak = arg1->vtxMode; + if (var_r21 != 0) { + var_f30 = arg1->hilite_scale; + } else { + var_f30 = 0.0f; + } + lightBit = Hu3DLightSet(arg0->unk00, &Hu3DCameraMtx, &Hu3DCameraMtxXPose, var_f30); + } + if (var_r21 != 0) { + GXSetNumChans(2); + if (arg1->vtxMode == 5) { + GXSetChanCtrl(GX_COLOR0, GX_TRUE, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_CLAMP, GX_AF_NONE); + GXSetChanCtrl(GX_COLOR1, GX_TRUE, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_NONE, GX_AF_SPEC); + if (sp38 != 0) { + GXSetChanCtrl(GX_ALPHA0, GX_TRUE, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_CLAMP, GX_AF_NONE); + GXSetChanCtrl(GX_ALPHA1, GX_TRUE, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_CLAMP, GX_AF_SPEC); + } else { + GXSetChanCtrl(GX_ALPHA0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_CLAMP, GX_AF_NONE); + GXSetChanCtrl(GX_ALPHA1, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_CLAMP, GX_AF_NONE); + } + } else { + GXSetChanCtrl(GX_COLOR0, GX_TRUE, GX_SRC_REG, GX_SRC_REG, lightBit, GX_DF_CLAMP, GX_AF_NONE); + GXSetChanCtrl(GX_COLOR1, GX_TRUE, GX_SRC_REG, GX_SRC_REG, lightBit, GX_DF_NONE, GX_AF_SPEC); + GXSetChanCtrl(GX_ALPHA0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_CLAMP, GX_AF_NONE); + GXSetChanCtrl(GX_ALPHA1, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_CLAMP, GX_AF_NONE); + } + } else { + GXSetNumChans(1); + if (arg1->vtxMode == 5) { + GXSetChanCtrl(GX_COLOR0, var_r18, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_CLAMP, GX_AF_SPOT); + if (sp38 != 0) { + GXSetChanCtrl(GX_ALPHA0, GX_TRUE, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_CLAMP, GX_AF_SPOT); + } else { + GXSetChanCtrl(GX_ALPHA0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_CLAMP, GX_AF_NONE); + } + } else { + GXSetChanCtrl(GX_COLOR0, var_r18, GX_SRC_REG, GX_SRC_REG, lightBit, GX_DF_CLAMP, GX_AF_SPOT); + GXSetChanCtrl(GX_ALPHA0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, lightBit, GX_DF_CLAMP, GX_AF_NONE); + } + GXSetChanCtrl(GX_COLOR1A1, GX_FALSE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + } +} + +static s32 kColorSelTbl[] = { + GX_TEV_KCSEL_K0_R, + GX_TEV_KCSEL_K0_G, + GX_TEV_KCSEL_K0_B, + GX_TEV_KCSEL_K1_R, + GX_TEV_KCSEL_K1_G, + GX_TEV_KCSEL_K1_B, + GX_TEV_KCSEL_K2_R, + GX_TEV_KCSEL_K2_G, + GX_TEV_KCSEL_K2_B, + GX_TEV_KCSEL_K3_R, + GX_TEV_KCSEL_K3_G, + GX_TEV_KCSEL_K3_B +}; + +static s32 kColorTbl[] = { + GX_KCOLOR0, + GX_KCOLOR1, + GX_KCOLOR2, + GX_KCOLOR3 +}; + +static s32 kColorSelTbl2[] = { + GX_TEV_KCSEL_K0, + GX_TEV_KCSEL_K1, + GX_TEV_KCSEL_K2, + GX_TEV_KCSEL_K3 +}; + +static s32 kColorSelATbl[] = { + GX_TEV_KASEL_K0_A, + GX_TEV_KASEL_K1_A, + GX_TEV_KASEL_K2_A, + GX_TEV_KASEL_K3_A +}; + +static GXTevKColorSel SetKColor(GXTevStageID arg0, u8 arg1) { + GXTevKColorSel temp_r30; + + switch (kColorIdx % 3) { + case 0: + kColor.r = arg1; + break; + case 1: + kColor.g = arg1; + break; + case 2: + kColor.b = arg1; + kColor.a = 0xFF; + GXSetTevKColor(kColorTbl[kColorIdx / 3], kColor); + break; + } + temp_r30 = kColorSelTbl[kColorIdx]; + GXSetTevKColorSel(arg0, temp_r30); + GXSetTevKAlphaSel(arg0, kColorSelATbl[kColorIdx / 3]); + kColorIdx++; + if (kColorIdx > 0xC) { + kColorIdx = 0xB; + } + return temp_r30; +} + +static GXTevKColorSel SetKColorRGB(GXTevStageID arg0, GXColor *arg1) { + GXTevKColorSel temp_r30; + + GXSetTevKColor(kColorTbl[kColorIdx / 3], kColor); + kColorIdx = ((kColorIdx / 3) + 1) * 3; + GXSetTevKColor(kColorTbl[kColorIdx / 3], *arg1); + temp_r30 = kColorSelTbl2[kColorIdx / 3]; + GXSetTevKColorSel(arg0, temp_r30); + GXSetTevKAlphaSel(arg0, kColorSelATbl[kColorIdx / 3]); + kColorIdx += 3; + if (kColorIdx > 0xC) { + kColorIdx = 0xB; + } + return temp_r30; +} + +static void FlushKColor(void) { + kColor.a = 0xFF; + if (kColorIdx % 3 != 0) { + GXSetTevKColor(kColorTbl[kColorIdx / 3], kColor); + } +} + +static void SetReflect(HsfdrawStruct00 *arg0, s16 arg1, s16 arg2, u8 arg3) { + GXTevKColorSel var_r27; + Mtx sp3C; + Mtx spC; + + switch (kColorIdx % 3) { + case 0: + kColor.r = arg3; + break; + case 1: + kColor.g = arg3; + break; + case 2: + kColor.b = arg3; + kColor.a = 0xFF; + GXSetTevKColor(kColorTbl[kColorIdx / 3], kColor); + break; + } + var_r27 = kColorSelTbl[kColorIdx]; + GXSetTevKColorSel(arg1, var_r27); + GXSetTevKAlphaSel(arg1, kColorSelATbl[kColorIdx / 3]); + kColorIdx++; + if (kColorIdx > 0xC) { + kColorIdx = 0xB; + } + GXSetTexCoordGen2(arg2, GX_TG_MTX2x4, GX_TG_NRM, GX_TEXMTX8, GX_FALSE, GX_PTIDENTITY); + GXSetTevOrder(arg1, arg2, reflectionMapNo, GX_COLOR0A0); + GXSetTevColorIn(arg1, GX_CC_CPREV, GX_CC_TEXC, GX_CC_KONST, GX_CC_ZERO); + GXSetTevColorOp(arg1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(arg1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV); + GXSetTevAlphaOp(arg1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); + PSMTXScale(sp3C, 1.0f / arg0->unk3C.x, 1.0f / arg0->unk3C.y, 1.0f / arg0->unk3C.z); + PSMTXConcat(arg0->unk0C, sp3C, spC); + spC[0][3] = spC[1][3] = spC[2][3] = 0.0f; + PSMTXConcat(spC, Hu3DCameraMtxXPose, sp3C); + PSMTXConcat(refMtx, sp3C, spC); + GXLoadTexMtxImm(spC, GX_TEXMTX8, GX_MTX2x4); +} + +static void SetProjection(HsfdrawStruct00 *arg0, s16 arg1, s16 arg2, s16 arg3, GXTexMapID arg4, u32 arg5) { + GXTevKColorSel var_r26; + u8 temp_r30; + + GXSetTexCoordGen2(arg3, GX_TG_MTX3x4, GX_TG_POS, arg5, GX_FALSE, GX_PTIDENTITY); + GXSetTevOrder(arg1, arg3, arg4, GX_COLOR0A0); + temp_r30 = Hu3DProjection[arg2].unk_00; + switch (kColorIdx % 3) { + case 0: + kColor.r = temp_r30; + break; + case 1: + kColor.g = temp_r30; + break; + case 2: + kColor.b = temp_r30; + kColor.a = 0xFF; + GXSetTevKColor(kColorTbl[kColorIdx / 3], kColor); + break; + } + var_r26 = kColorSelTbl[kColorIdx]; + GXSetTevKColorSel(arg1, var_r26); + GXSetTevKAlphaSel(arg1, kColorSelATbl[kColorIdx / 3]); + kColorIdx++; + if (kColorIdx > 0xC) { + kColorIdx = 0xB; + } + GXSetTevColorIn(arg1, GX_CC_ZERO, GX_CC_TEXA, GX_CC_KONST, GX_CC_ZERO); + GXSetTevColorOp(arg1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVREG2); + GXSetTevAlphaIn(arg1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV); + GXSetTevAlphaOp(arg1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVREG2); + arg1++; + GXSetTevOrder(arg1, arg3, arg4, GX_COLOR0A0); + GXSetTevColorIn(arg1, GX_CC_CPREV, GX_CC_TEXC, GX_CC_C2, GX_CC_ZERO); + GXSetTevColorOp(arg1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(arg1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV); + GXSetTevAlphaOp(arg1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); +} + +static void SetShadowTex(void) { + GXTexObj sp8; + + GXInitTexObj(&sp8, Hu3DShadowData.unk_04, Hu3DShadowData.unk_02, Hu3DShadowData.unk_02, GX_TF_I8, GX_CLAMP, GX_CLAMP, GX_FALSE); + GXInitTexObjLOD(&sp8, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1); + GXLoadTexObj(&sp8, shadowMapNo); +} + +static void SetShadow(HsfdrawStruct00 *arg0, s16 arg1, s16 arg2) { + GXSetTexCoordGen2(arg2, GX_TG_MTX3x4, GX_TG_POS, GX_TEXMTX9, GX_FALSE, GX_PTIDENTITY); + GXSetTevOrder(arg1, arg2, shadowMapNo, GX_COLOR0A0); + GXSetTevColorIn(arg1, GX_CC_CPREV, GX_CC_ZERO, GX_CC_TEXC, GX_CC_ZERO); + GXSetTevColorOp(arg1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(arg1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV); + GXSetTevAlphaOp(arg1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); +} + +static void FaceDrawShadow(HsfdrawStruct00 *arg0, HsfdrawStruct02 *arg1) { + HsfObject *temp_r31; + ModelData *temp_r28; + HsfConstData *temp_r27; + HsfMaterial *temp_r29; + void *var_r26; + GXColor spC; + s16 var_r30; + + temp_r31 = arg0->unk04; + temp_r28 = arg0->unk00; + temp_r27 = temp_r31->constData; + temp_r29 = &temp_r31->data.material[arg1->unk02 & 0xFFF]; + if (temp_r29 != materialBak) { + if (!(temp_r27->flags & 0x400)) { + drawCnt++; + return; + } + materialBak = temp_r29; + spC.a = 255.0f * (1.0f - temp_r29->invAlpha); + GXSetTevColor(GX_TEVREG0, spC); + GXSetZMode(GX_FALSE, GX_LEQUAL, GX_FALSE); + if (temp_r29->numAttrs == 0) { + var_r30 = (temp_r31->data.color) ? 4 : 0; + if (var_r30 != vtxModeBak) { + vtxModeBak = var_r30; + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_INDEX16); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_TEX_ST, GX_RGBA6, 0); + GXSetArray(GX_VA_POS, temp_r31->data.vertex->data, 0xC); + GXSetVtxDesc(GX_VA_NRM, GX_INDEX16); + if (temp_r28->hsfData->cenvCnt == 0) { + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_TEX_S, GX_RGB8, 0); + GXSetArray(GX_VA_NRM, temp_r31->data.normal->data, 3); + } else { + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_TEX_S, GX_RGBA6, 0); + GXSetArray(GX_VA_NRM, temp_r31->data.normal->data, 0xC); + } + if (var_r30 & 4) { + GXSetVtxDesc(GX_VA_CLR0, GX_INDEX16); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_TEX_ST, GX_RGBA8, 0); + GXSetArray(GX_VA_CLR0, temp_r31->data.color->data, 4); + } + GXSetZCompLoc(1); + } + GXSetNumTexGens(0); + GXSetNumTevStages(1); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_A1, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + } else { + var_r30 = (temp_r29->vtxMode == 5) ? 5 : 1; + if (DrawData[drawCnt].unk0C & 2) { + var_r30 |= 2; + } + if (var_r30 != vtxModeBak) { + vtxModeBak = var_r30; + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_INDEX16); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_TEX_ST, GX_RGBA6, 0); + GXSetArray(GX_VA_POS, temp_r31->data.vertex->data, 0xC); + if (var_r30 & 2) { + GXSetVtxDesc(GX_VA_NBT, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NBT, GX_TEX_ST, GX_RGBA4, 8); + } else { + GXSetVtxDesc(GX_VA_NRM, GX_INDEX16); + if (temp_r28->hsfData->cenvCnt == 0) { + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_TEX_S, GX_RGB8, 0); + GXSetArray(GX_VA_NRM, temp_r31->data.normal->data, 3); + } else { + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_TEX_S, GX_RGBA6, 0); + GXSetArray(GX_VA_NRM, temp_r31->data.normal->data, 0xC); + } + } + GXSetVtxDesc(GX_VA_TEX0, GX_INDEX16); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_RGBA6, 0); + GXSetArray(GX_VA_TEX0, temp_r31->data.st->data, 8); + if (var_r30 & 4) { + GXSetVtxDesc(GX_VA_CLR0, GX_INDEX16); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_TEX_ST, GX_RGBA8, 0); + GXSetArray(GX_VA_CLR0, temp_r31->data.color->data, 4); + } + GXSetZCompLoc(0); + } + GXSetNumTexGens(0); + GXSetNumTevStages(1); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_A1, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + } + 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); + var_r26 = (u8*) DLBufStartP + DrawData[drawCnt].unk00; + GXCallDisplayList(var_r26, DrawData[drawCnt].unk04); + } else { + if (!(temp_r27->flags & 0x400)) { + drawCnt++; + return; + } + var_r26 = (u8*) DLBufStartP + DrawData[drawCnt].unk00; + GXCallDisplayList(var_r26, DrawData[drawCnt].unk04); + } + drawCnt++; +} + +static void LoadTexture(ModelData *arg0, HsfBitmap *arg1, HsfAttribute *arg2, s16 arg3) { + GXTexObj sp1C; + GXTlutObj sp10; + s16 var_r27; + s16 var_r26; + s16 var_r22; + s16 var_r21; + s32 var_r20; + s16 var_r30; + + if (arg1 == 0) { + OSReport("Error: No Texture\n"); + return; + } + var_r27 = arg1->sizeX; + var_r26 = arg1->sizeY; + var_r22 = (arg2->wrap_s == 1) ? GX_REPEAT : GX_CLAMP; + var_r21 = (arg2->wrap_t == 1) ? GX_REPEAT : GX_CLAMP; + var_r20 = (arg2->flag & 0x80) ? GX_TRUE : GX_FALSE; + switch (arg1->dataFmt) { + case 6: + GXInitTexObj(&sp1C, arg1->data, var_r27, var_r26, GX_TF_RGBA8, var_r22, var_r21, var_r20); + break; + case 4: + GXInitTexObj(&sp1C, arg1->data, var_r27, var_r26, GX_TF_RGB565, var_r22, var_r21, var_r20); + break; + case 5: + GXInitTexObj(&sp1C, arg1->data, var_r27, var_r26, GX_TF_RGB5A3, var_r22, var_r21, var_r20); + break; + case 9: + if (arg1->pixSize < 8) { + GXInitTlutObj(&sp10, arg1->palData, GX_TL_RGB565, arg1->palSize); + GXLoadTlut(&sp10, arg3); + GXInitTexObjCI(&sp1C, arg1->data, var_r27, var_r26, GX_TF_C4, var_r22, var_r21, var_r20, arg3); + } else { + GXInitTlutObj(&sp10, arg1->palData, GX_TL_RGB565, arg1->palSize); + GXLoadTlut(&sp10, arg3); + GXInitTexObjCI(&sp1C, arg1->data, var_r27, var_r26, GX_TF_C8, var_r22, var_r21, var_r20, arg3); + } + break; + case 10: + if (arg1->pixSize < 8) { + GXInitTlutObj(&sp10, arg1->palData, GX_TL_RGB5A3, arg1->palSize); + GXLoadTlut(&sp10, arg3); + GXInitTexObjCI(&sp1C, arg1->data, var_r27, var_r26, GX_TF_C4, var_r22, var_r21, var_r20, arg3); + } else { + GXInitTlutObj(&sp10, arg1->palData, GX_TL_RGB5A3, arg1->palSize); + GXLoadTlut(&sp10, arg3); + GXInitTexObjCI(&sp1C, arg1->data, var_r27, var_r26, GX_TF_C8, var_r22, var_r21, var_r20, arg3); + } + break; + case 0: + var_r30 = (s16) arg3; + texCol[var_r30].r = arg1->tint.r; + texCol[var_r30].g = arg1->tint.g; + texCol[var_r30].b = arg1->tint.b; + texCol[var_r30].a = 1; + GXInitTexObj(&sp1C, arg1->data, var_r27, var_r26, GX_TF_I4, var_r22, var_r21, var_r20); + break; + case 1: + var_r30 = (s16) arg3; + texCol[var_r30].r = arg1->tint.r; + texCol[var_r30].g = arg1->tint.g; + texCol[var_r30].b = arg1->tint.b; + texCol[var_r30].a = 1; + GXInitTexObj(&sp1C, arg1->data, var_r27, var_r26, GX_TF_I8, var_r22, var_r21, var_r20); + break; + case 2: + var_r30 = (s16) arg3; + texCol[var_r30].r = arg1->tint.r; + texCol[var_r30].g = arg1->tint.g; + texCol[var_r30].b = arg1->tint.b; + texCol[var_r30].a = 1; + GXInitTexObj(&sp1C, arg1->data, var_r27, var_r26, GX_TF_IA4, var_r22, var_r21, var_r20); + break; + case 3: + var_r30 = (s16) arg3; + texCol[var_r30].r = arg1->tint.r; + texCol[var_r30].g = arg1->tint.g; + texCol[var_r30].b = arg1->tint.b; + texCol[var_r30].a = 1; + GXInitTexObj(&sp1C, arg1->data, var_r27, var_r26, GX_TF_IA8, var_r22, var_r21, var_r20); + break; + case 7: + GXInitTexObj(&sp1C, arg1->data, var_r27, var_r26, GX_TF_CMPR, var_r22, var_r21, var_r20); + break; + case 11: + if (arg3 & 0x8000) { + GXInitTlutObj(&sp10, &((s16*) arg1->palData)[(arg1->palSize + 0xF) & 0xFFF0], GX_TL_IA8, arg1->palSize); + } else { + GXInitTlutObj(&sp10, arg1->palData, GX_TL_IA8, arg1->palSize); + } + arg3 &= 0x7FFF; + if (arg1->pixSize < 8) { + GXLoadTlut(&sp10, arg3); + GXInitTexObjCI(&sp1C, arg1->data, var_r27, var_r26, GX_TF_C4, var_r22, var_r21, var_r20, arg3); + } else { + GXLoadTlut(&sp10, arg3); + GXInitTexObjCI(&sp1C, arg1->data, var_r27, var_r26, GX_TF_C8, var_r22, var_r21, var_r20, arg3); + } + TL32F = 1; + break; + } + if ((arg0->attr & 0x40) || (arg2->flag & 0x40)) { + GXInitTexObjLOD(&sp1C, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1); + } else if (var_r20) { + GXInitTexObjLOD(&sp1C, GX_LIN_MIP_LIN, GX_LINEAR, 0.0f, arg2->unk78, 0.0f, GX_FALSE, GX_TRUE, GX_ANISO_2); + } else if (arg1->maxLod == 0) { + GXInitTexObjLOD(&sp1C, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1); + } else { + GXInitTexObjLOD(&sp1C, GX_LIN_MIP_LIN, GX_LINEAR, 0.0f, arg1->maxLod - 1, 0.0f, GX_TRUE, GX_TRUE, GX_ANISO_1); + } + GXLoadTexObj(&sp1C, arg3); +} + +static void objNull(ModelData *arg0, HsfObject *arg1) { + HsfTransform *var_r31; + Vec *temp_r27; + Vec *temp_r28; + s16 var_r24; + s16 i; + Mtx sp8; + + if (CancelTRXF == 0) { + if (attachMotionF == 0) { + var_r31 = &arg1->data.base; + } else { + var_r31 = &arg1->data.curr; + } + if (arg0->hsfData->cenvCnt == 0 || hookIdx != -1) { + PSMTXScale(sp8, var_r31->scale.x, var_r31->scale.y, var_r31->scale.z); + mtxRotCat(sp8, var_r31->rot.x, var_r31->rot.y, var_r31->rot.z); + mtxTransCat(sp8, var_r31->pos.x, var_r31->pos.y, var_r31->pos.z); + PSMTXConcat(MTXBuf[MTXIdx - 1], sp8, MTXBuf[MTXIdx]); + } + temp_r28 = &scaleBuf[MTXIdx]; + temp_r27 = temp_r28 - 1; + temp_r28->x = temp_r27->x * var_r31->scale.x; + temp_r28->y = temp_r27->y * var_r31->scale.y; + temp_r28->z = temp_r27->z * var_r31->scale.z; + MTXIdx++; + var_r24 = 1; + } else { + CancelTRXF = 0; + var_r24 = 0; + } + for (i = 0; i < arg1->data.childrenCount; i++) { + objCall(arg0, arg1->data.children[i]); + } + if (var_r24 != 0) { + MTXIdx--; + } +} + +static void objRoot(ModelData *arg0, HsfObject *arg1) { + HsfTransform *var_r31; + Vec *temp_r29; + Vec *temp_r30; + s16 var_r26; + s16 i; + Mtx sp8; + + if (CancelTRXF == 0) { + if (attachMotionF == 0) { + var_r31 = &arg1->data.base; + } else { + var_r31 = &arg1->data.curr; + } + if (arg0->hsfData->cenvCnt == 0 || hookIdx != -1) { + PSMTXScale(sp8, var_r31->scale.x, var_r31->scale.y, var_r31->scale.z); + mtxRotCat(sp8, var_r31->rot.x, var_r31->rot.y, var_r31->rot.z); + mtxTransCat(sp8, var_r31->pos.x, var_r31->pos.y, var_r31->pos.z); + PSMTXConcat(MTXBuf[MTXIdx - 1], sp8, MTXBuf[MTXIdx]); + } + temp_r30 = &scaleBuf[MTXIdx]; + temp_r29 = temp_r30 - 1; + temp_r30->x = temp_r29->x * var_r31->scale.x; + temp_r30->y = temp_r29->y * var_r31->scale.y; + temp_r30->z = temp_r29->z * var_r31->scale.z; + MTXIdx++; + var_r26 = 1; + } else { + CancelTRXF = 0; + var_r26 = 0; + } + for (i = 0; i < arg1->data.childrenCount; i++) { + objCall(arg0, arg1->data.children[i]); + } + if (var_r26 != 0) { + MTXIdx--; + } +} + +static void objJoint(ModelData *arg0, HsfObject *arg1) { + HsfTransform *var_r31; + Vec *temp_r27; + Vec *temp_r28; + s16 var_r24; + s16 i; + Mtx sp8; + + if (CancelTRXF == 0) { + if (attachMotionF == 0) { + var_r31 = &arg1->data.base; + } else { + var_r31 = &arg1->data.curr; + } + if (arg0->hsfData->cenvCnt == 0 || hookIdx != -1) { + PSMTXScale(sp8, var_r31->scale.x, var_r31->scale.y, var_r31->scale.z); + mtxRotCat(sp8, var_r31->rot.x, var_r31->rot.y, var_r31->rot.z); + mtxTransCat(sp8, var_r31->pos.x, var_r31->pos.y, var_r31->pos.z); + PSMTXConcat(MTXBuf[MTXIdx - 1], sp8, MTXBuf[MTXIdx]); + } + temp_r28 = &scaleBuf[MTXIdx]; + temp_r27 = temp_r28 - 1; + temp_r28->x = temp_r27->x * var_r31->scale.x; + temp_r28->y = temp_r27->y * var_r31->scale.y; + temp_r28->z = temp_r27->z * var_r31->scale.z; + MTXIdx++; + var_r24 = 1; + } else { + CancelTRXF = 0; + var_r24 = 0; + } + for (i = 0; i < arg1->data.childrenCount; i++) { + objCall(arg0, arg1->data.children[i]); + } + if (var_r24 != 0) { + MTXIdx--; + } +} + +static void objMap(ModelData *arg0, HsfObject *arg1) { + HsfTransform *var_r31; + Vec *temp_r29; + Vec *temp_r30; + s16 var_r26; + s16 i; + Mtx spC; + + if (CancelTRXF == 0) { + if (attachMotionF == 0) { + var_r31 = &arg1->data.base; + } else { + var_r31 = &arg1->data.curr; + } + PSMTXScale(spC, var_r31->scale.x, var_r31->scale.y, var_r31->scale.z); + mtxRotCat(spC, var_r31->rot.x, var_r31->rot.y, var_r31->rot.z); + mtxTransCat(spC, var_r31->pos.x, var_r31->pos.y, var_r31->pos.z); + PSMTXConcat(MTXBuf[MTXIdx - 1], spC, MTXBuf[MTXIdx]); + temp_r30 = &scaleBuf[MTXIdx]; + temp_r29 = temp_r30 - 1; + temp_r30->x = temp_r29->x * var_r31->scale.x; + temp_r30->y = temp_r29->y * var_r31->scale.y; + temp_r30->z = temp_r29->z * var_r31->scale.z; + MTXIdx++; + var_r26 = 1; + } else { + CancelTRXF = 0; + var_r26 = 0; + } + for (i = 0; i < arg1->data.childrenCount; i++) { + objCall(arg0, arg1->data.children[i]); + } + if (var_r26 != 0) { + MTXIdx--; + } +} + +static void objReplica(ModelData *arg0, HsfObject *arg1) { + HsfTransform *var_r31; + Mtx sp3C; + Mtx spC; + + if (attachMotionF == 0) { + var_r31 = &arg1->data.base; + } else { + var_r31 = &arg1->data.curr; + } + mtxRot(spC, var_r31->rot.x, var_r31->rot.y, var_r31->rot.z); + PSMTXScale(sp3C, var_r31->scale.x, var_r31->scale.y, var_r31->scale.z); + PSMTXConcat(spC, sp3C, sp3C); + mtxTransCat(sp3C, var_r31->pos.x, var_r31->pos.y, var_r31->pos.z); + PSMTXConcat(MTXBuf[MTXIdx - 1], sp3C, MTXBuf[MTXIdx]); + scaleBuf[MTXIdx].x = var_r31->scale.x * scaleBuf[MTXIdx - 1].x; + scaleBuf[MTXIdx].y = var_r31->scale.y * scaleBuf[MTXIdx - 1].y; + scaleBuf[MTXIdx].z = var_r31->scale.z * scaleBuf[MTXIdx - 1].z; + MTXIdx++; + CancelTRXF = 1; + objCall(arg0, arg1->data.replica); + CancelTRXF = 0; + MTXIdx--; +} + +void Hu3DDrawPost(void) { + Vec sp54; + Vec sp48; + Vec sp3C; + Vec sp30; + GXColor sp2C; + void (*sp28)(ModelData*, Mtx); + s16 spA; + s16 sp8; + HsfBuffer *temp_r24; + HsfdrawStruct00 *temp_r28; + s16 var_r21; + s16 var_r20; + s16 var_r19; + s16 var_r23; + s16 var_r25; + s16 var_r26; + s16 i; + float temp_f30; + float temp_f29; + float temp_f28; + float temp_f27; + float temp_f26; + float temp_f25; + LightData *temp_r22; + HsfdrawStruct02 *var_r27; + Mtx sp150; + Mtx sp120; + Mtx spF0; + Mtx spC0; + Mtx sp90; + Mtx sp60; + + spA = 0; + if (DrawObjIdx != 0) { + for (i = 0; i < DrawObjIdx; i++) { + DrawObjNum[i] = i; + } + if (shadowModelDrawF == 0) { + var_r25 = 1; + while (var_r25 <= DrawObjIdx) { + var_r25 = var_r25 * 3 + 1; + } + while ((var_r25 /= 3) >= 1) { + for (i = var_r25; i < DrawObjIdx; i++) { + var_r20 = DrawObjNum[i]; + temp_f29 = DrawObjData[DrawObjNum[i]].unk08; + var_r26 = i - var_r25; + while (var_r26 >= 0) { + if (DrawObjData[DrawObjNum[var_r26]].unk08 < temp_f29) { + DrawObjNum[var_r26 + var_r25] = DrawObjNum[var_r26]; + var_r26 -= var_r25; + } else { + break; + } + } + DrawObjNum[var_r26 + var_r25] = var_r20; + } + } + for (i = 0; i < DrawObjIdx - 1; i++) { + for (var_r26 = i + 1; var_r26 < DrawObjIdx; var_r26++) { + if (DrawObjData[DrawObjNum[i]].unk08 != DrawObjData[DrawObjNum[var_r26]].unk08) { + break; + } + if (DrawObjNum[var_r26] < DrawObjNum[i]) { + var_r20 = DrawObjNum[i]; + DrawObjNum[i] = DrawObjNum[var_r26]; + DrawObjNum[var_r26] = var_r20; + } + } + } + } + GXInvalidateTexAll(); + GXInvalidateVtxCache(); + materialBak = (HsfMaterial*) -1; + for (i = 0; i < 8; i++) { + BmpPtrBak[i] = (HsfAttribute*) -1; + } + GXSetCullMode(GX_CULL_BACK); + for (var_r23 = 0; var_r23 < DrawObjIdx; var_r23++) { + temp_r28 = &DrawObjData[DrawObjNum[var_r23]]; + if (temp_r28->unk00->attr & 0x10) { + sp28 = (void*) temp_r28->unk00->hsfData; + sp28(temp_r28->unk00, temp_r28->unk0C); + for (i = 0; i < 8; i++) { + BmpPtrBak[i] = (HsfAttribute*) -1; + } + materialBak = (HsfMaterial*) -1; + Hu3DCameraSet(Hu3DCameraNo, Hu3DCameraMtx); + } else { + Hu3DObjInfoP = temp_r28->unk04->constData; + DLBufStartP = Hu3DObjInfoP->unk0C; + DrawData = Hu3DObjInfoP->unk08; + GXLoadPosMtxImm(temp_r28->unk0C, GX_PNMTX0); + PSMTXInvXpose(temp_r28->unk0C, sp120); + GXLoadNrmMtxImm(sp120, 0); + if (Hu3DShadowF != 0 && Hu3DShadowCamBit != 0 && (Hu3DObjInfoP->flags & 8)) { + PSMTXInverse(Hu3DCameraMtx, spF0); + PSMTXConcat(spF0, temp_r28->unk0C, sp120); + PSMTXConcat(Hu3DShadowData.unk_68, Hu3DShadowData.unk_38, sp150); + PSMTXConcat(sp150, sp120, sp120); + GXLoadTexMtxImm(sp120, GX_TEXMTX9, GX_MTX3x4); + var_r19 = 1; + } else { + var_r19 = 0; + } + if (temp_r28->unk00->unk_02 != 0) { + if (var_r19 == 0) { + PSMTXInverse(Hu3DCameraMtx, spF0); + } + for (i = 0, var_r21 = 1; i < 4; i++, var_r21 <<= 1) { + if (var_r21 & temp_r28->unk00->unk_02) { + PSMTXConcat(spF0, temp_r28->unk0C, sp120); + PSMTXConcat(Hu3DProjection[i].unk_68, Hu3DProjection[i].unk_38, sp150); + PSMTXConcat(sp150, sp120, sp120); + GXLoadTexMtxImm(sp120, texMtxTbl[i + 3], GX_MTX3x4); + } + } + } + if ((temp_r28->unk00->attr & 0x20000) || (Hu3DObjInfoP->flags & 0x8000)) { + sp54 = lbl_8011DD20; + temp_r22 = &Hu3DGlobalLight[temp_r28->unk00->unk_03]; + sp30 = temp_r22->unk_28; + if (temp_r22->unk_00 & 0x8000) { + PSMTXMultVecSR(Hu3DCameraMtx, &sp30, &sp30); + } + temp_f30 = PSVECDotProduct(&sp30, &sp54); + temp_f30 *= 10000.0f; + OSf32tos16(&temp_f30, &sp8); + if (sp8 == -10000) { + PSMTXScale(hiliteMtx, 0.0f, 0.0f, 0.0f); + } else { + C_VECHalfAngle(&sp30, &sp54, &sp3C); + sp3C.x = -sp3C.x; + sp3C.y = -sp3C.y; + sp3C.z = -sp3C.z; + PSMTXScale(sp60, 1.0f / temp_r28->unk3C.x, 1.0f / temp_r28->unk3C.y, 1.0f / temp_r28->unk3C.z); + PSMTXConcat(temp_r28->unk0C, sp60, spC0); + spC0[0][3] = spC0[1][3] = spC0[2][3] = 0.0f; + PSMTXInvXpose(spC0, sp90); + if (sp8 == 10000) { + PSMTXIdentity(spC0); + } else { + PSVECCrossProduct(&sp3C, &sp54, &sp48); + temp_f27 = PSVECDotProduct(&sp54, &sp3C); + temp_f26 = acos(temp_f27); + temp_f25 = temp_f26; + temp_f28 = temp_f25; + PSMTXRotAxisRad(spC0, &sp48, temp_f28); + } + PSMTXConcat(spC0, sp90, sp60); + PSMTXTrans(spC0, 0.5f, 0.5f, 0.0f); + PSMTXConcat(spC0, sp60, hiliteMtx); + } + } + temp_r24 = temp_r28->unk04->data.face; + var_r27 = temp_r24->data; + drawCnt = 0; + shadingBak = -1; + vtxModeBak = -1; + materialBak = (HsfMaterial*) -1; + if (shadowModelDrawF == 0) { + for (i = 0; i < temp_r24->count;) { + FaceDraw(temp_r28, var_r27); + if (var_r27->unk00 == 4) { + totalPolyCnt += DrawData[drawCnt - 1].unk08; + i++; + var_r27++; + } else { + totalPolyCnt += DrawData[drawCnt - 1].unk08 * ((var_r27->unk00 & 7) == 3 ? 2 : 1); + i += DrawData[drawCnt - 1].unk08; + var_r27 += DrawData[drawCnt - 1].unk08; + } + } + } else { + sp2C.a = 0xFF; + GXSetChanAmbColor(GX_COLOR0A0, sp2C); + GXSetChanMatColor(GX_COLOR0A0, sp2C); + sp2C.a = Hu3DShadowData.unk_00; + GXSetTevColor(GX_TEVREG1, sp2C); + GXSetNumChans(1); + for (i = 0; i < temp_r24->count;) { + FaceDrawShadow(temp_r28, var_r27); + if (var_r27->unk00 == 4) { + i++; + var_r27++; + } else { + i += DrawData[drawCnt - 1].unk08; + var_r27 += DrawData[drawCnt - 1].unk08; + } + } + } + if (TL32F != 0) { + for (i = GX_TEVSTAGE0; i < GX_MAX_TEVSTAGE; i++) { + GXSetTevSwapMode(i, GX_TEV_SWAP0, GX_TEV_SWAP0); + } + TL32F = 0; + } + } + } + } + (void)var_r19; // required to match +} + +static void ObjDraw(HsfdrawStruct00 *arg0) { + Vec sp44; + Vec sp38; + Vec sp2C; + Vec sp20; + GXColor sp1C; + HsfBuffer *temp_r26; + s16 var_r22; + s16 var_r21; + s16 var_r23; + s16 i; + s32 var_r20; + float temp_f30; + float temp_f29; + float temp_f28; + float temp_f27; + float temp_f26; + LightData *temp_r24; + DrawDataStruct *temp_r25; + HsfdrawStruct02 *var_r27; + Mtx sp140; + Mtx sp110; + Mtx spE0; + Mtx spB0; + Mtx sp80; + Mtx sp50; + + Hu3DObjInfoP = arg0->unk04->constData; + DLBufStartP = Hu3DObjInfoP->unk0C; + DrawData = Hu3DObjInfoP->unk08; + GXLoadPosMtxImm(arg0->unk0C, GX_PNMTX0); + PSMTXInvXpose(arg0->unk0C, sp110); + GXLoadNrmMtxImm(sp110, 0); + GXInvalidateVtxCache(); + if (Hu3DShadowF != 0 && Hu3DShadowCamBit != 0 && (Hu3DObjInfoP->flags & 8)) { + PSMTXInverse(Hu3DCameraMtx, spE0); + PSMTXConcat(spE0, arg0->unk0C, sp110); + PSMTXConcat(Hu3DShadowData.unk_68, Hu3DShadowData.unk_38, sp140); + PSMTXConcat(sp140, sp110, sp110); + GXLoadTexMtxImm(sp110, GX_TEXMTX9, GX_MTX3x4); + var_r22 = 1; + } else { + var_r22 = 0; + } + if (arg0->unk00->unk_02 != 0) { + if (var_r22 == 0) { + PSMTXInverse(Hu3DCameraMtx, spE0); + } + for (i = 0, var_r23 = 1; i < 4; i++, var_r23 <<= 1) { + if (var_r23 & arg0->unk00->unk_02) { + PSMTXConcat(spE0, arg0->unk0C, sp110); + PSMTXConcat(Hu3DProjection[i].unk_68, Hu3DProjection[i].unk_38, sp140); + PSMTXConcat(sp140, sp110, sp110); + GXLoadTexMtxImm(sp110, texMtxTbl[i + 3], GX_MTX3x4); + } + } + } + if ((arg0->unk00->attr & 0x20000) || (Hu3DObjInfoP->flags & 0x8000)) { + sp44 = lbl_8011DD20; + temp_r24 = &Hu3DGlobalLight[arg0->unk00->unk_03]; + sp20 = temp_r24->unk_28; + if (temp_r24->unk_00 & 0x8000) { + PSMTXMultVecSR(Hu3DCameraMtx, &sp20, &sp20); + } + temp_f30 = PSVECDotProduct(&sp20, &sp44); + temp_f30 *= 10000.0f; + OSf32tos16(&temp_f30, &var_r21); + if (var_r21 == -10000) { + PSMTXScale(hiliteMtx, 0.0f, 0.0f, 0.0f); + } else { + C_VECHalfAngle(&sp20, &sp44, &sp2C); + sp2C.x = -sp2C.x; + sp2C.y = -sp2C.y; + sp2C.z = -sp2C.z; + PSMTXScale(sp50, 1.0f / arg0->unk3C.x, 1.0f / arg0->unk3C.y, 1.0f / arg0->unk3C.z); + PSMTXConcat(arg0->unk0C, sp50, spB0); + spB0[0][3] = spB0[1][3] = spB0[2][3] = 0.0f; + PSMTXInvXpose(spB0, sp80); + if (var_r21 == 10000) { + PSMTXIdentity(spB0); + } else { + PSVECCrossProduct(&sp2C, &sp44, &sp38); + temp_f28 = PSVECDotProduct(&sp44, &sp2C); + temp_f27 = acos(temp_f28); + temp_f26 = temp_f27; + temp_f29 = temp_f26; + PSMTXRotAxisRad(spB0, &sp38, temp_f29); + } + PSMTXConcat(spB0, sp80, sp50); + PSMTXTrans(spB0, 0.5f, 0.5f, 0.0f); + PSMTXConcat(spB0, sp50, hiliteMtx); + } + } + temp_r26 = arg0->unk04->data.face; + var_r27 = temp_r26->data; + drawCnt = 0; + shadingBak = -1; + vtxModeBak = -1; + materialBak = (HsfMaterial*) -1; + if (shadowModelDrawF == 0) { + for (i = 0; i < temp_r26->count;) { + FaceDraw(arg0, var_r27); + if (var_r27->unk00 == 4) { + totalPolyCnt += DrawData[drawCnt - 1].unk08; + i++; + var_r27++; + } else { + temp_r25 = &DrawData[drawCnt - 1]; + if ((var_r27->unk00 & 7) == 3) { + var_r20 = 2; + } else { + var_r20 = 1; + } + totalPolyCnt += temp_r25->unk08 * var_r20; + i += temp_r25->unk08; + var_r27 += temp_r25->unk08; + } + } + } else { + sp1C.a = 0xFF; + GXSetChanAmbColor(GX_COLOR0A0, sp1C); + GXSetChanMatColor(GX_COLOR0A0, sp1C); + sp1C.a = Hu3DShadowData.unk_00; + GXSetTevColor(GX_TEVREG1, sp1C); + GXSetNumChans(1); + for (i = 0; i < temp_r26->count;) { + FaceDrawShadow(arg0, var_r27); + if (var_r27->unk00 == 4) { + i++; + var_r27++; + } else { + i += DrawData[drawCnt - 1].unk08; + var_r27 += DrawData[drawCnt - 1].unk08; + } + } + } + if (TL32F != 0) { + for (i = GX_TEVSTAGE0; i < GX_MAX_TEVSTAGE; i++) { + GXSetTevSwapMode(i, GX_TEV_SWAP0, GX_TEV_SWAP0); + } + TL32F = 0; + } +} + +void MakeDisplayList(s16 arg0, HsfData *arg1) { + HsfData *temp_r31; + ModelData *var_r30; + + temp_r31 = Hu3DData[arg0].hsfData; + var_r30 = &Hu3DData[arg0]; + curModelID = arg0; + mallocNo = (u32) arg1; + faceNumBuf = HuMemDirectMallocNum(HEAP_DATA, 0x800 * sizeof(u16), mallocNo); + MDObjCall(temp_r31, temp_r31->root); + HuMemDirectFree(faceNumBuf); + if (var_r30->attr & 4) { + Hu3DShadowCamBit++; + } +} + +static void MDObjCall(HsfData *arg0, HsfObject *arg1) { + s16 i; + + switch (arg1->type) { + case 0: + case 1: + case 3: + case 4: + case 5: + case 6: + case 9: + for (i = 0; i < arg1->data.childrenCount; i++) { + MDObjCall(arg0, arg1->data.children[i]); + } + break; + case 2: + MDObjMesh(arg0, arg1); + break; + } +} + +static void MDObjMesh(HsfData *arg0, HsfObject *arg1) { + HsfBuffer *temp_r29; + HsfdrawStruct02 *var_r28; + s16 i; + + temp_r29 = arg1->data.face; + DLFirstF = 0; + drawCnt = matChgCnt = triCnt = quadCnt = 0; + faceNumBuf[0] = 0; + materialBak = (HsfMaterial*) -1; + polyTypeBak = 0xFF; + DLTotalNum = 0; + var_r28 = temp_r29->data; + for (i = 0; i < temp_r29->count; i++, var_r28++) { + MDFaceCnt(arg1, var_r28); + } + DLTotalNum = (DLTotalNum + 0x40) & ~0x1F; + Hu3DObjInfoP = ObjConstantMake(arg1, mallocNo); + Hu3DObjInfoP->unk08 = DrawData = HuMemDirectMallocNum(HEAP_DATA, matChgCnt * sizeof(DrawDataStruct), mallocNo); + memset(DrawData, 0, matChgCnt * sizeof(DrawDataStruct)); + DLBufP = DLBufStartP = HuMemDirectMallocNum(HEAP_DATA, DLTotalNum, mallocNo); + DCInvalidateRange(DLBufStartP, DLTotalNum); + DLFirstF = 0; + materialBak = (HsfMaterial*) -1; + polyTypeBak = 0xFF; + totalSize = drawCnt = 0; + var_r28 = temp_r29->data; + if (arg1->flags & 4) { + Hu3DObjInfoP->flags |= 0x400; + Hu3DModelAttrSet(curModelID, 4); + } + if (arg1->flags & 8) { + Hu3DObjInfoP->flags |= 8; + } + if (arg1->flags & 0x30) { + Hu3DObjInfoP->flags |= 0x800; + } + if (arg1->flags & 0x100) { + Hu3DObjInfoP->flags |= 0x8000; + } + for (i = 0; i < temp_r29->count; i++, var_r28++) { + MDFaceDraw(arg1, var_r28); + } + Hu3DObjInfoP->unk0C = DLBufStartP; + if (DLTotalNum < totalSize) { + OSReport("DLBuf Over >>>>>>>>>>>>>"); + OSReport("%x:%x:%x\n", Hu3DObjInfoP->unk0C, totalSize, DLTotalNum); + } + for (i = 0; i < arg1->data.childrenCount; i++) { + MDObjCall(arg0, arg1->data.children[i]); + } +} + +HsfConstData *ObjConstantMake(HsfObject *arg0, u32 arg1) { + HsfConstData *temp_r3; + + temp_r3 = HuMemDirectMallocNum(HEAP_DATA, sizeof(HsfConstData), arg1); + arg0->constData = temp_r3; + temp_r3->flags = 0; + temp_r3->hook = -1; + temp_r3->hilite_map = NULL; + return temp_r3; +} + +static void MDFaceDraw(HsfObject *arg0, HsfdrawStruct02 *arg1) { + HsfMaterial *temp_r30; + s16 *var_r24; + s16 var_r26; + s16 var_r27; + s16 var_r22; + s32 temp_r28; + s32 temp_r3; + s32 var_r25; + + var_r26 = -1; + temp_r30 = &arg0->data.material[arg1->unk02 & 0xFFF]; + if (temp_r30 != materialBak || polyTypeBak != (arg1->unk00 & 7) || (arg1->unk00 & 7) == 4) { + polyTypeBak = arg1->unk00 & 7; + materialBak = temp_r30; + DrawData[drawCnt].unk00 = (u32) DLBufP - (u32) DLBufStartP; + GXBeginDisplayList(DLBufP, 0x20000); + GXResetWriteGatherPipe(); + if (temp_r30->numAttrs == 0) { + var_r25 = 0; + } else { + var_r25 = 1; + for (var_r27 = 0; var_r27 < temp_r30->numAttrs; var_r27++) { + if (arg0->data.attribute[temp_r30->attrs[var_r27]].unk14 != 0.0) { + Hu3DObjInfoP->flags |= 2; + DrawData[drawCnt].unk0C |= 2; + var_r26 = var_r27; + } + } + if (var_r26 != -1 && var_r26 != 0) { + var_r22 = temp_r30->attrs[var_r26]; + for (var_r27 = temp_r30->numAttrs - 2; var_r27 >= 0; var_r27--) { + if (var_r27 != var_r26) { + temp_r30->attrs[var_r27 + 1] = temp_r30->attrs[var_r27]; + } + } + temp_r30->attrs[0] = var_r22; + } + } + if (temp_r30->invAlpha != 0.0 || (temp_r30->pass & 0xF)) { + Hu3DObjInfoP->flags |= 1; + } + if (temp_r30->flags & 0x30) { + Hu3DObjInfoP->flags |= 0x800; + } + if (temp_r30->refAlpha != 0.0) { + Hu3DObjInfoP->flags |= 4; + } + if (temp_r30->flags & 0x100) { + Hu3DObjInfoP->flags |= 0x8000; + } + if (temp_r30->flags & 0x1000) { + Hu3DObjInfoP->flags |= 0x10000; + } + faceCnt = 0; + switch (arg1->unk00 & 7) { + case 0: + case 1: + break; + case 2: + GXBegin(GX_TRIANGLES, GX_VTXFMT0, faceNumBuf[drawCnt]); + for (var_r27 = 0; var_r27 < faceNumBuf[drawCnt] / 3; var_r27++, arg1++) { + GXUnknownu16(arg1->unk04[0][0]); + if (var_r26 == -1) { + GXUnknownu16(arg1->unk04[0][1]); + } else { + MakeCalcNBT(arg0, arg1, 0, 1); + } + if (temp_r30->vtxMode == 5) { + temp_r28 = arg1->unk04[0][2]; + GXUnknownu16(temp_r28); + if (((GXColor*) arg0->data.color->data)[temp_r28].a != 0xFF) { + Hu3DObjInfoP->flags |= 0x4001; + } + } + if (var_r25 != 0) { + GXUnknownu16(arg1->unk04[0][3]); + } + GXUnknownu16(arg1->unk04[2][0]); + if (var_r26 == -1) { + GXUnknownu16(arg1->unk04[2][1]); + } else { + MakeNBT(arg0, arg1, 2, 0); + } + if (temp_r30->vtxMode == 5) { + temp_r28 = arg1->unk04[2][2]; + GXUnknownu16(temp_r28); + if (((GXColor*) arg0->data.color->data)[temp_r28].a != 0xFF) { + Hu3DObjInfoP->flags |= 0x4001; + } + } + if (var_r25 != 0) { + GXUnknownu16(arg1->unk04[2][3]); + } + GXUnknownu16(arg1->unk04[1][0]); + if (var_r26 == -1) { + GXUnknownu16(arg1->unk04[1][1]); + } else { + MakeNBT(arg0, arg1, 1, 2); + } + if (temp_r30->vtxMode == 5) { + temp_r28 = arg1->unk04[1][2]; + GXUnknownu16(temp_r28); + if (((GXColor*) arg0->data.color->data)[temp_r28].a != 0xFF) { + Hu3DObjInfoP->flags |= 0x4001; + } + } + if (var_r25 != 0) { + GXUnknownu16(arg1->unk04[1][3]); + } + } + faceCnt = faceNumBuf[drawCnt] / 3; + break; + case 3: + GXBegin(GX_QUADS, GX_VTXFMT0, faceNumBuf[drawCnt]); + for (var_r27 = 0; var_r27 < faceNumBuf[drawCnt] / 4; var_r27++, arg1++) { + GXUnknownu16(arg1->unk04[0][0]); + if (var_r26 == -1) { + GXUnknownu16(arg1->unk04[0][1]); + } else { + MakeCalcNBT(arg0, arg1, 0, 1); + } + if (temp_r30->vtxMode == 5) { + temp_r28 = arg1->unk04[0][2]; + GXUnknownu16(temp_r28); + if (((GXColor*) arg0->data.color->data)[temp_r28].a != 0xFF) { + Hu3DObjInfoP->flags |= 0x4001; + } + } + if (var_r25 != 0) { + GXUnknownu16(arg1->unk04[0][3]); + } + GXUnknownu16(arg1->unk04[2][0]); + if (var_r26 == -1) { + GXUnknownu16(arg1->unk04[2][1]); + } else { + MakeNBT(arg0, arg1, 2, 0); + } + if (temp_r30->vtxMode == 5) { + temp_r28 = arg1->unk04[2][2]; + GXUnknownu16(temp_r28); + if (((GXColor*) arg0->data.color->data)[temp_r28].a != 0xFF) { + Hu3DObjInfoP->flags |= 0x4001; + } + } + if (var_r25 != 0) { + GXUnknownu16(arg1->unk04[2][3]); + } + GXUnknownu16(arg1->unk04[3][0]); + if (var_r26 == -1) { + GXUnknownu16(arg1->unk04[3][1]); + } else { + MakeNBT(arg0, arg1, 3, 2); + } + if (temp_r30->vtxMode == 5) { + temp_r28 = arg1->unk04[3][2]; + GXUnknownu16(temp_r28); + if (((GXColor*) arg0->data.color->data)[temp_r28].a != 0xFF) { + Hu3DObjInfoP->flags |= 0x4001; + } + } + if (var_r25 != 0) { + GXUnknownu16(arg1->unk04[3][3]); + } + GXUnknownu16(arg1->unk04[1][0]); + if (var_r26 == -1) { + GXUnknownu16(arg1->unk04[1][1]); + } else { + MakeNBT(arg0, arg1, 1, 3); + } + if (temp_r30->vtxMode == 5) { + temp_r28 = arg1->unk04[1][2]; + GXUnknownu16(temp_r28); + if (((GXColor*) arg0->data.color->data)[temp_r28].a != 0xFF) { + Hu3DObjInfoP->flags |= 0x4001; + } + } + if (var_r25 != 0) { + GXUnknownu16(arg1->unk04[1][3]); + } + } + faceCnt = faceNumBuf[drawCnt] / 4; + break; + case 4: + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, faceNumBuf[drawCnt]); + GXUnknownu16(arg1->unk04[0][0]); + if (var_r26 == -1) { + GXUnknownu16(arg1->unk04[0][1]); + } else { + MakeCalcNBT(arg0, arg1, 0, 1); + } + if (temp_r30->vtxMode == 5) { + temp_r28 = arg1->unk04[0][2]; + GXUnknownu16(temp_r28); + if (((GXColor*) arg0->data.color->data)[temp_r28].a != 0xFF) { + Hu3DObjInfoP->flags |= 0x4001; + } + } + if (var_r25 != 0) { + GXUnknownu16(arg1->unk04[0][3]); + } + GXUnknownu16(arg1->unk04[2][0]); + if (var_r26 == -1) { + GXUnknownu16(arg1->unk04[2][1]); + } else { + MakeNBT(arg0, arg1, 2, 0); + } + if (temp_r30->vtxMode == 5) { + temp_r28 = arg1->unk04[2][2]; + GXUnknownu16(temp_r28); + if (((GXColor*) arg0->data.color->data)[temp_r28].a != 0xFF) { + Hu3DObjInfoP->flags |= 0x4001; + } + } + if (var_r25 != 0) { + GXUnknownu16(arg1->unk04[2][3]); + } + GXUnknownu16(arg1->unk04[1][0]); + if (var_r26 == -1) { + GXUnknownu16(arg1->unk04[1][1]); + } else { + MakeNBT(arg0, arg1, 1, 2); + } + if (temp_r30->vtxMode == 5) { + temp_r28 = arg1->unk04[1][2]; + GXUnknownu16(temp_r28); + if (((GXColor*) arg0->data.color->data)[temp_r28].a != 0xFF) { + Hu3DObjInfoP->flags |= 0x4001; + } + } + if (var_r25 != 0) { + GXUnknownu16(arg1->unk04[1][3]); + } + var_r24 = arg1->unk20; + for (var_r27 = 0; var_r27 < arg1->unk1C; var_r27++, var_r24 += 4) { + GXUnknownu16(var_r24[0]); + if (var_r26 == -1) { + GXUnknownu16(var_r24[1]); + } else { + MakeCalcNBT(arg0, arg1, 0, 1); + } + if (temp_r30->vtxMode == 5) { + temp_r28 = var_r24[2]; + GXUnknownu16(temp_r28); + if (((GXColor*) arg0->data.color->data)[temp_r28].a != 0xFF) { + Hu3DObjInfoP->flags |= 0x4001; + } + } + if (var_r25 != 0) { + GXUnknownu16(var_r24[3]); + } + } + faceCnt = arg1->unk1C + 1; + break; + } + temp_r3 = GXEndDisplayList(); + DrawData[drawCnt].unk04 = temp_r3; + DrawData[drawCnt].unk08 = faceCnt; + totalSize += temp_r3; + drawCnt++; + DLBufP = (u8*) DLBufP + temp_r3; + } +} + +static s32 MakeCalcNBT(HsfObject *arg0, HsfdrawStruct02 *arg1, s16 arg2, s16 arg3) { + Vec sp10; + Vec *temp_r29; + Vec *temp_r31; + s8 (*temp_r28)[3]; + s16 temp_r25; + s16 temp_r24; + s16 temp_r27; + + temp_r31 = arg0->data.vertex->data; + temp_r27 = arg1->unk04[arg2][1]; + temp_r25 = arg1->unk04[arg2][0]; + temp_r24 = arg1->unk04[arg3][0]; + if (arg0->data.hook != 0) { + temp_r29 = arg0->data.normal->data; + sp10.x = temp_r29[temp_r27].x; + sp10.y = temp_r29[temp_r27].y; + sp10.z = temp_r29[temp_r27].z; + } else { + temp_r28 = arg0->data.normal->data; + sp10.x = temp_r28[temp_r27][0]; + sp10.y = temp_r28[temp_r27][1]; + sp10.z = temp_r28[temp_r27][2]; + PSVECNormalize(&sp10, &sp10); + } + NBTB.x = temp_r31[temp_r25].x - temp_r31[temp_r24].x; + NBTB.y = temp_r31[temp_r25].y - temp_r31[temp_r24].y; + NBTB.z = temp_r31[temp_r25].z - temp_r31[temp_r24].z; + PSVECNormalize(&NBTB, &NBTB); + PSVECCrossProduct(&NBTB, &sp10, &NBTT); + GXPosition3s16(sp10.x * 256.0f, sp10.y * 256.0f, sp10.z * 256.0f); + GXPosition3s16(NBTB.x * 256.0f, NBTB.y * 256.0f, NBTB.z * 256.0f); + GXPosition3s16(NBTT.x * 256.0f, NBTT.y * 256.0f, NBTT.z * 256.0f); +} + +static s32 MakeNBT(HsfObject *arg0, HsfdrawStruct02 *arg1, s16 arg2, s16 arg3) { + Vec sp10; + Vec *temp_r30; + Vec *spC; + s8 (*temp_r29)[3]; + s16 temp_r28; + + spC = arg0->data.vertex->data; + temp_r28 = arg1->unk04[arg2][1]; + if (arg0->data.hook != 0) { + temp_r30 = arg0->data.normal->data; + sp10.x = temp_r30[temp_r28].x; + sp10.y = temp_r30[temp_r28].y; + sp10.z = temp_r30[temp_r28].z; + } else { + temp_r29 = arg0->data.normal->data; + sp10.x = temp_r29[temp_r28][0]; + sp10.y = temp_r29[temp_r28][1]; + sp10.z = temp_r29[temp_r28][2]; + PSVECNormalize(&sp10, &sp10); + } + GXPosition3s16(sp10.x * 256.0f, sp10.y * 256.0f, sp10.z * 256.0f); + GXPosition3s16(NBTB.x * 256.0f, NBTB.y * 256.0f, NBTB.z * 256.0f); + GXPosition3s16(NBTT.x * 256.0f, NBTT.y * 256.0f, NBTT.z * 256.0f); +} + +static void MDFaceCnt(HsfObject *arg0, HsfdrawStruct02 *arg1) { + HsfMaterial *temp_r30; + s16 i; + + temp_r30 = &arg0->data.material[arg1->unk02 & 0xFFF]; + // Bug? Likely to be polyTypeBak != (arg1->unk00 & 7) + if (temp_r30 != materialBak || ((polyTypeBak != arg1->unk00) & 7) || (arg1->unk00 & 7) == 4) { + polySize = 4; + polyTypeBak = arg1->unk00 & 7; + materialBak = temp_r30; + matChgCnt++; + if (DLFirstF != 0) { + drawCnt++; + faceNumBuf[drawCnt] = 0; + DLTotalNum = ((DLTotalNum + 0x20) & ~0x1F) + 0x20; + } else { + DLFirstF = 1; + } + if (temp_r30->numAttrs != 0) { + polySize += 2; + for (i = 0; i < temp_r30->numAttrs; i++) { + if (arg0->data.attribute[temp_r30->attrs[i]].unk14 != 0.0) { + polySize += 0x12; + } + } + } + if (temp_r30->vtxMode == 5) { + polySize += 2; + } + } + switch (arg1->unk00 & 7) { + case 0: + OSReport("Error\n"); + break; + case 1: + OSReport("Error\n"); + break; + case 2: + triCnt++; + faceNumBuf[drawCnt] += 3; + DLTotalNum += polySize * 3; + break; + case 3: + quadCnt++; + faceNumBuf[drawCnt] += 4; + DLTotalNum += polySize * 4; + break; + case 4: + triCnt++; + faceNumBuf[drawCnt] += arg1->unk1C + 3; + DLTotalNum += polySize * 3; + DLTotalNum += polySize * arg1->unk1C; + break; + default: + OSReport("Error\n"); + break; + } +} + +void mtxTransCat(Mtx arg0, float arg1, float arg2, float arg3) { + if (arg1 != 0.0f || arg2 != 0.0f || arg3 != 0.0f) { + arg0[0][3] += arg1; + arg0[1][3] += arg2; + arg0[2][3] += arg3; + } +} + +void mtxRotCat(Mtx arg0, float arg1, float arg2, float arg3) { + Mtx sp8; + + if (arg1 != 0.0f) { + PSMTXRotRad(sp8, 'X', MTXDegToRad(arg1)); + PSMTXConcat(sp8, arg0, arg0); + } + if (arg2 != 0.0f) { + PSMTXRotRad(sp8, 'Y', MTXDegToRad(arg2)); + PSMTXConcat(sp8, arg0, arg0); + } + if (arg3 != 0.0f) { + PSMTXRotRad(sp8, 'Z', MTXDegToRad(arg3)); + PSMTXConcat(sp8, arg0, arg0); + } +} + +void mtxRot(Mtx arg0, float arg1, float arg2, float arg3) { + Mtx sp38; + Mtx sp8; + + if (arg1 != 0.0f) { + PSMTXRotRad(arg0, 'X', MTXDegToRad(arg1)); + } else { + PSMTXIdentity(arg0); + } + if (arg2 != 0.0f) { + PSMTXRotRad(sp38, 'Y', MTXDegToRad(arg2)); + PSMTXConcat(sp38, arg0, arg0); + } + if (arg3 != 0.0f) { + PSMTXRotRad(sp8, 'Z', MTXDegToRad(arg3)); + PSMTXConcat(sp8, arg0, arg0); + } +} + +void mtxScaleCat(Mtx arg0, float arg1, float arg2, float arg3) { + arg0[0][0] *= arg1; + arg0[1][0] *= arg1; + arg0[2][0] *= arg1; + arg0[0][1] *= arg2; + arg0[1][1] *= arg2; + arg0[2][1] *= arg2; + arg0[0][2] *= arg3; + arg0[1][2] *= arg3; + arg0[2][2] *= arg3; +} + +s16 HmfInverseMtxF3X3(Mtx arg0, Mtx arg1) { + float temp_f30; + float temp_f29; + float temp_f28; + float temp_f31; + + temp_f30 = arg0[1][1] * arg0[2][2] - arg0[2][1] * arg0[1][2]; + temp_f29 = arg0[2][1] * arg0[0][2] - arg0[0][1] * arg0[2][2]; + temp_f28 = arg0[0][1] * arg0[1][2] - arg0[1][1] * arg0[0][2]; + temp_f31 = arg0[0][0] * temp_f30 + arg0[1][0] * temp_f29 + arg0[2][0] * temp_f28; + if (temp_f31 == 0.0f) { + return 0; + } + temp_f31 = 1.0f / temp_f31; + arg1[0][0] = temp_f30 * temp_f31; + arg1[0][1] = temp_f29 * temp_f31; + arg1[0][2] = temp_f28 * temp_f31; + arg1[1][0] = temp_f31 * (arg0[2][0] * arg0[1][2] - arg0[1][0] * arg0[2][2]); + arg1[2][0] = temp_f31 * (arg0[1][0] * arg0[2][1] - arg0[2][0] * arg0[1][1]); + arg1[1][1] = temp_f31 * (arg0[0][0] * arg0[2][2] - arg0[2][0] * arg0[0][2]); + arg1[2][1] = temp_f31 * (arg0[2][0] * arg0[0][1] - arg0[0][0] * arg0[2][1]); + arg1[1][2] = temp_f31 * (arg0[1][0] * arg0[0][2] - arg0[0][0] * arg0[1][2]); + arg1[2][2] = temp_f31 * (arg0[0][0] * arg0[1][1] - arg0[1][0] * arg0[0][1]); + arg1[0][3] = arg1[1][3] = arg1[2][3] = 0.0f; + return 1; +} + +static inline void SetDefLightInlineFunc(GXLightObj *arg0, u8 arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5, u8 arg6, u8 arg7, u8 arg8, u8 arg9) { + GXColor spE; + + spE.r = arg1; + spE.g = arg2; + spE.b = arg3; + spE.a = 0xFF; + GXInitLightColor(arg0, spE); + GXLoadLightObjImm(arg0, GX_LIGHT0); + spE.r = arg4; + spE.g = arg5; + spE.b = arg6; + GXSetChanAmbColor(GX_COLOR0A0, spE); + spE.r = arg7; + spE.g = arg8; + spE.b = arg9; + GXSetChanMatColor(GX_COLOR0A0, spE); +} + +void SetDefLight(Vec arg0, Vec arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5, u8 arg6, u8 arg7, u8 arg8, u8 arg9, u8 argA) { + GXLightObj sp20; + + GXInitLightAttn(&sp20, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f); + GXInitLightSpot(&sp20, 20.0f, GX_SP_COS); + GXInitLightPos(&sp20, arg0.x, arg0.y, arg0.z); + GXInitLightDir(&sp20, arg1.x, arg1.y, arg1.z); + SetDefLightInlineFunc(&sp20, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, argA); +} + +void Hu3DModelObjPosGet(s16 arg0, char *arg1, Vec *arg2) { + Mtx spC; + + Hu3DModelObjMtxGet(arg0, arg1, spC); + arg2->x = spC[0][3]; + arg2->y = spC[1][3]; + arg2->z = spC[2][3]; + if (PGFinishF == 0) { + OSReport("Error: Not Found %s for ObjPosGet\n", arg1); + arg2->x = arg2->y = arg2->z = 0.0f; + } +} + +void Hu3DModelObjMtxGet(s16 arg0, char *arg1, Mtx arg2) { + ModelData *temp_r31; + HsfData *temp_r30; + Mtx spA0; + Mtx sp70; + Mtx sp40; + + temp_r31 = &Hu3DData[arg0]; + temp_r30 = temp_r31->hsfData; + mtxRot(sp70, temp_r31->rot.x, temp_r31->rot.y, temp_r31->rot.z); + PSMTXScale(spA0, temp_r31->scale.x, temp_r31->scale.y, temp_r31->scale.z); + PSMTXConcat(sp70, spA0, MTXBuf[0]); + mtxTransCat(MTXBuf[0], temp_r31->pos.x, temp_r31->pos.y, temp_r31->pos.z); + PGMaxPos.x = PGMaxPos.y = PGMaxPos.z = -1000000.0f; + PGMinPos.x = PGMinPos.y = PGMinPos.z = 1000000.0f; + MTXIdx = 1; + CancelTRXF = 0; + PGFinishF = 0; + hookIdx = -1; + PGName = HuMemDirectMallocNum(HEAP_SYSTEM, 0x200, MEMORY_DEFAULT_NUM); + strcpy((char*) PGName, MakeObjectName(arg1)); + if (temp_r31->unk_08 != -1) { + attachMotionF = 1; + } else { + attachMotionF = 0; + } + PGObjCall(temp_r31, temp_r30->root); + PSMTXCopy(MTXBuf[MTXIdx - 1], arg2); + if (PGFinishF == 0 && *PGName != 0) { + OSReport("Error: Not Found %s for ObjPosGet\n", arg1); + PSMTXIdentity(MTXBuf[MTXIdx]); + } + HuMemDirectFree(PGName); +} + +void PGObjCall(ModelData *arg0, HsfObject *arg1) { + switch (arg1->type) { + case 0: + case 2: + case 3: + case 4: + case 5: + case 6: + case 9: + PGObjCalc(arg0, arg1); + break; + case 1: + PGObjReplica(arg0, arg1); + break; + } +} + +void PGObjCalc(ModelData *arg0, HsfObject *arg1) { + Vec sp8; + s16 temp_r22; + s16 var_r24; + s16 var_r27; + HsfObject *var_r23; + HsfConstData *temp_r28; + HsfTransform *var_r30; + ModelData *temp_r31; + Mtx spD4; + Mtx spA4; + Mtx sp74; + + if (CancelTRXF == 0) { + if (attachMotionF == 0) { + var_r30 = &arg1->data.base; + } else { + var_r30 = &arg1->data.curr; + } + mtxRot(spA4, var_r30->rot.x, var_r30->rot.y, var_r30->rot.z); + PSMTXScale(spD4, var_r30->scale.x, var_r30->scale.y, var_r30->scale.z); + PSMTXConcat(spA4, spD4, spD4); + mtxTransCat(spD4, var_r30->pos.x, var_r30->pos.y, var_r30->pos.z); + PSMTXConcat(MTXBuf[MTXIdx - 1], spD4, MTXBuf[MTXIdx]); + MTXIdx++; + var_r24 = 1; + } else { + CancelTRXF = 0; + var_r24 = 0; + } + if (strcmp((char*) PGName, arg1->name) == 0) { + PGFinishF = 1; + return; + } + temp_r28 = arg1->constData; + if (temp_r28 && temp_r28->hook != -1) { + temp_r31 = &Hu3DData[temp_r28->hook]; + if (!(temp_r31->attr & 1)) { + var_r27 = attachMotionF; + if (temp_r31->unk_08 != -1) { + attachMotionF = 1; + } else { + attachMotionF = 0; + } + temp_r22 = hookIdx; + hookIdx = temp_r28->hook; + PSMTXScale(spD4, temp_r31->scale.x, temp_r31->scale.y, temp_r31->scale.z); + mtxRotCat(spD4, temp_r31->rot.x, temp_r31->rot.y, temp_r31->rot.z); + mtxTransCat(spD4, temp_r31->pos.x, temp_r31->pos.y, temp_r31->pos.z); + PSMTXConcat(spD4, temp_r31->unk_F0, spD4); + PSMTXConcat(MTXBuf[MTXIdx - 1], spD4, MTXBuf[MTXIdx]); + MTXIdx++; + PGObjCall(temp_r31, temp_r31->hsfData->root); + MTXIdx--; + hookIdx = temp_r22; + attachMotionF = var_r27; + } + } + if (*PGName == 0 && arg1->type == 2) { + var_r23 = arg1; + PSMTXMultVec(MTXBuf[MTXIdx - 1], (Vec*) &var_r23->data.mesh.min, &sp8); + if (sp8.x < PGMinPos.x) { + PGMinPos.x = sp8.x; + } + if (sp8.y < PGMinPos.y) { + PGMinPos.y = sp8.y; + } + if (sp8.z < PGMinPos.z) { + PGMinPos.z = sp8.z; + } + if (sp8.x > PGMaxPos.x) { + PGMaxPos.x = sp8.x; + } + if (sp8.y > PGMaxPos.y) { + PGMaxPos.y = sp8.y; + } + if (sp8.z > PGMaxPos.z) { + PGMaxPos.z = sp8.z; + } + PSMTXMultVec(MTXBuf[MTXIdx - 1], (Vec*) &var_r23->data.mesh.max, &sp8); + if (sp8.x < PGMinPos.x) { + PGMinPos.x = sp8.x; + } + if (sp8.y < PGMinPos.y) { + PGMinPos.y = sp8.y; + } + if (sp8.z < PGMinPos.z) { + PGMinPos.z = sp8.z; + } + if (sp8.x > PGMaxPos.x) { + PGMaxPos.x = sp8.x; + } + if (sp8.y > PGMaxPos.y) { + PGMaxPos.y = sp8.y; + } + if (sp8.z > PGMaxPos.z) { + PGMaxPos.z = sp8.z; + } + } + for (var_r27 = 0; var_r27 < arg1->data.childrenCount; var_r27++) { + PGObjCall(arg0, arg1->data.children[var_r27]); + if (PGFinishF != 0) { + return; + } + } + if (var_r24 != 0) { + MTXIdx--; + } +} + +void PGObjReplica(ModelData *arg0, HsfObject *arg1) { + HsfTransform *var_r31; + Mtx sp1B8; + Mtx sp188; + + if (attachMotionF == 0) { + var_r31 = &arg1->data.base; + } else { + var_r31 = &arg1->data.curr; + } + mtxRot(sp188, var_r31->rot.x, var_r31->rot.y, var_r31->rot.z); + PSMTXScale(sp1B8, var_r31->scale.x, var_r31->scale.y, var_r31->scale.z); + PSMTXConcat(sp188, sp1B8, sp1B8); + mtxTransCat(sp1B8, var_r31->pos.x, var_r31->pos.y, var_r31->pos.z); + PSMTXConcat(MTXBuf[MTXIdx - 1], sp1B8, MTXBuf[MTXIdx]); + MTXIdx++; + CancelTRXF = 1; + PGObjCall(arg0, arg1->data.replica); + if (PGFinishF == 0) { + CancelTRXF = 0; + MTXIdx--; + } +} + +HsfObject *Hu3DObjDuplicate(HsfData *arg0, u32 arg1) { + HsfObject *temp_r27; + HsfObject *var_r30; + HsfObject *var_r31; + s16 i; + s16 j; + + var_r31 = HuMemDirectMallocNum(HEAP_DATA, arg0->objectCnt * sizeof(HsfObject), arg1); + temp_r27 = var_r31; + var_r30 = arg0->object; + memcpy(temp_r27, var_r30, arg0->objectCnt * sizeof(HsfObject)); + for (i = 0; i < arg0->objectCnt; i++, var_r31++, var_r30++) { + if (var_r31->type != 8 && var_r31->type != 7) { + if (var_r31->data.parent) { + var_r31->data.parent = (HsfObject*) ((u8*) temp_r27 + ((u32) var_r30->data.parent - (u32) arg0->object)); + } + var_r31->data.children = HuMemDirectMallocNum(HEAP_DATA, var_r30->data.childrenCount * 4, arg1); + if (var_r30->constData) { + var_r31->constData = HuMemDirectMallocNum(HEAP_DATA, sizeof(HsfConstData), arg1); + memcpy(var_r31->constData, var_r30->constData, sizeof(HsfConstData)); + } + for (j = 0; j < var_r30->data.childrenCount; j++) { + var_r31->data.children[j] = (HsfObject*) ((u8*) temp_r27 + ((u32) var_r30->data.children[j] - (u32) arg0->object)); + } + } + } + return temp_r27; +} + +void Hu3DModelObjDrawInit(void) { + s16 i; + + GXSetCullMode(GX_CULL_BACK); + for (i = 0; i < 8; i++) { + BmpPtrBak[i] = (HsfAttribute*) -1; + } + CancelTRXF = 0; + hookIdx = -1; + shadingBak = -1; + vtxModeBak = -1; + materialBak = (HsfMaterial*) -1; + attachMotionF = 0; +} + +void Hu3DModelObjDraw(s16 arg0, char *arg1, Mtx arg2) { + HsfdrawStruct00 sp14; + HsfConstData *sp10; + HsfObject *temp_r3; + + sp14.unk00 = &Hu3DData[arg0]; + sp14.unk04 = temp_r3 = Hu3DModelObjPtrGet(arg0, arg1); + sp10 = temp_r3->constData; + PSMTXCopy(arg2, sp14.unk0C); + sp14.unk3C.x = sp14.unk3C.y = sp14.unk3C.z = 1.0f; + ObjDraw(&sp14); +} diff --git a/src/game/hsfload.c b/src/game/hsfload.c index d10256b4..88c10c51 100644 --- a/src/game/hsfload.c +++ b/src/game/hsfload.c @@ -216,7 +216,7 @@ static void MaterialLoad(void) new_mat->refAlpha = curr_mat->refAlpha; new_mat->unk2C = curr_mat->unk2C; new_mat->numAttrs = curr_mat->numAttrs; - new_mat->attrs = (HsfAttribute **)(NSymIndex+((u32)curr_mat->attrs)); + new_mat->attrs = (s32 *)(NSymIndex+((u32)curr_mat->attrs)); rgba[i].r = new_mat->litColor[0]; rgba[i].g = new_mat->litColor[1]; rgba[i].b = new_mat->litColor[2]; diff --git a/src/game/hsfman.c b/src/game/hsfman.c index 71bdfa6f..836ab428 100644 --- a/src/game/hsfman.c +++ b/src/game/hsfman.c @@ -234,7 +234,7 @@ void Hu3DExec(void) { mtxTransCat(sp40, data->pos.x, data->pos.y, data->pos.z); PSMTXConcat(Hu3DCameraMtx, sp40, sp10); PSMTXConcat(sp10, data->unk_F0, sp10); - Hu3DDraw(data, sp10[0], &data->scale.x); + Hu3DDraw(data, sp10, &data->scale); } data->unk_00++; var_r23++; @@ -1971,7 +1971,7 @@ void Hu3DShadowExec(void) { mtxTransCat(spB8, var_r31->pos.x, var_r31->pos.y, var_r31->pos.z); PSMTXConcat(Hu3DCameraMtx, spB8, sp88); PSMTXConcat(sp88, var_r31->unk_F0, sp88); - Hu3DDraw(var_r31, sp88[0], &var_r31->scale.x); + Hu3DDraw(var_r31, sp88, &var_r31->scale); } } Hu3DDrawPost(); diff --git a/src/game/main.c b/src/game/main.c index 13f9cce5..92d38265 100644 --- a/src/game/main.c +++ b/src/game/main.c @@ -14,7 +14,7 @@ #include "game/gamework.h" extern FileListEntry _ovltbl[]; -s32 GlobalCounter; +u32 GlobalCounter; u32 lbl_801D3A50; u32 lbl_801D3A4C; u32 lbl_801D3A48;