diff --git a/LEGO1/lego/legoomni/include/legoactors.h b/LEGO1/lego/legoomni/include/legoactors.h index aa31343d..f88f6a57 100644 --- a/LEGO1/lego/legoomni/include/legoactors.h +++ b/LEGO1/lego/legoomni/include/legoactors.h @@ -11,12 +11,12 @@ class LegoROI; struct LegoActorInfo { // SIZE 0x18 struct Part { - MxU8* m_unk0x00; // 0x00 - const char** m_unk0x04; // 0x04 - MxU8 m_unk0x08; // 0x08 - MxU8* m_unk0x0c; // 0x0c - const char** m_unk0x10; // 0x10 - MxU8 m_unk0x14; // 0x14 + MxU8* m_partNameIndices; // 0x00 + const char** m_partName; // 0x04 + MxU8 m_partNameIndex; // 0x08 + MxU8* m_nameIndices; // 0x0c + const char** m_names; // 0x10 + MxU8 m_nameIndex; // 0x14 }; const char* m_name; // 0x00 @@ -31,8 +31,8 @@ struct LegoActorInfo { // SIZE 0x58 struct LegoActorLOD { enum { - c_flag1 = 0x01, - c_flag2 = 0x02 + c_useTexture = 0x01, + c_useColor = 0x02 }; const char* m_name; // 0x00 diff --git a/LEGO1/lego/legoomni/include/legocharactermanager.h b/LEGO1/lego/legoomni/include/legocharactermanager.h index 8e470fdd..2f9d9551 100644 --- a/LEGO1/lego/legoomni/include/legocharactermanager.h +++ b/LEGO1/lego/legoomni/include/legocharactermanager.h @@ -78,7 +78,7 @@ class LegoCharacterManager { void ReleaseActor(const char* p_name); void ReleaseActor(LegoROI* p_roi); void ReleaseAutoROI(LegoROI* p_roi); - MxBool FUN_100849a0(LegoROI* p_roi, LegoTextureInfo* p_texture); + MxBool SetHeadTexture(LegoROI* p_roi, LegoTextureInfo* p_texture); LegoExtraActor* GetExtraActor(const char* p_name); LegoActorInfo* GetActorInfo(const char* p_name); LegoActorInfo* GetActorInfo(LegoROI* p_roi); @@ -91,7 +91,7 @@ class LegoCharacterManager { MxU32 GetSoundId(LegoROI* p_roi, MxBool p_und); MxU8 GetMood(LegoROI* p_roi); LegoROI* CreateAutoROI(const char* p_name, const char* p_lodName, MxBool p_createEntity); - MxResult FUN_10085870(LegoROI* p_roi); + MxResult UpdateBoundingSphereAndBox(LegoROI* p_roi); LegoROI* FUN_10085a80(const char* p_name, const char* p_lodName, MxBool p_createEntity); static const char* GetCustomizeAnimFile() { return g_customizeAnimFile; } diff --git a/LEGO1/lego/legoomni/src/common/legoactors.cpp b/LEGO1/lego/legoomni/src/common/legoactors.cpp index 7bf10520..67731d25 100644 --- a/LEGO1/lego/legoomni/src/common/legoactors.cpp +++ b/LEGO1/lego/legoomni/src/common/legoactors.cpp @@ -10,7 +10,7 @@ DECOMP_SIZE_ASSERT(LegoActorLOD, 0x58) LegoActorLOD g_actorLODs[] = { {"top", "top", 0, 0.000267f, 0.780808f, -0.01906f, 0.951612f, -0.461166f, -0.002794f, -0.299442f, 0.4617f, 1.56441f, 0.261321f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f}, - {"body", "body", LegoActorLOD::c_flag1, + {"body", "body", LegoActorLOD::c_useTexture, 0.00158332f, 0.401828f, -0.00048697f, 0.408071f, -0.287507f, 0.150419f, -0.147452f, 0.289219f, 0.649774f, @@ -18,7 +18,7 @@ LegoActorLOD g_actorLODs[] = { 0.007277f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f}, - {"infohat", "infohat", LegoActorLOD::c_flag2, + {"infohat", "infohat", LegoActorLOD::c_useColor, 0.0f, -0.00938f, -0.01955f, 0.35f, -0.231822f, -0.140237f, -0.320954f, 0.234149f, 0.076968f, @@ -26,7 +26,7 @@ LegoActorLOD g_actorLODs[] = { 0.001767f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f}, - {"infogron", "infogron", LegoActorLOD::c_flag2, + {"infogron", "infogron", LegoActorLOD::c_useColor, 0.0f, 0.11477f, 0.00042f, 0.26f, -0.285558f, -0.134391f, -0.142231f, 0.285507f, 0.152986f, @@ -34,7 +34,7 @@ LegoActorLOD g_actorLODs[] = { 0.007277f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f}, - {"head", "head", LegoActorLOD::c_flag1, + {"head", "head", LegoActorLOD::c_useTexture, 0.0f, -0.03006f, 0.0f, 0.3f, -0.189506f, -0.209665f, -0.189824f, 0.189532f, 0.228822f, @@ -42,7 +42,7 @@ LegoActorLOD g_actorLODs[] = { 0.001781f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f}, - {"arm-lft", "arm-lft", LegoActorLOD::c_flag2, + {"arm-lft", "arm-lft", LegoActorLOD::c_useColor, -0.06815f, -0.0973747f, 0.0154655f, 0.237f, -0.137931f, -0.282775f, -0.105316f, 0.000989f, 0.100221f, @@ -50,7 +50,7 @@ LegoActorLOD g_actorLODs[] = { 0.023286f, -0.003031f, -0.017187f, 0.999848f, 0.173622f, 0.984658f, 0.017453f}, - {"arm-rt", "arm-rt", LegoActorLOD::c_flag2, + {"arm-rt", "arm-rt", LegoActorLOD::c_useColor, 0.0680946f, -0.097152f, 0.0152722f, 0.237f, 0.00141f, -0.289604f, -0.100831f, 0.138786f, 0.09291f, @@ -58,7 +58,7 @@ LegoActorLOD g_actorLODs[] = { 0.018302f, 0.0f, 0.0f, 1.0f, -0.173648f, 0.984808f, 0.0f}, - {"claw-lft", "claw-lft", LegoActorLOD::c_flag2, + {"claw-lft", "claw-lft", LegoActorLOD::c_useColor, 0.000773381f, -0.101422f, -0.0237761f, 0.15f, -0.089838f, -0.246208f, -0.117735f, 0.091275f, 0.000263f, @@ -66,7 +66,7 @@ LegoActorLOD g_actorLODs[] = { 0.092779f, 0.000001f, 0.000003f, 1.0f, 0.190812f, 0.981627f, -0.000003f}, - {"claw-rt", "claw-lft", LegoActorLOD::c_flag2, + {"claw-rt", "claw-lft", LegoActorLOD::c_useColor, 0.000773381f, -0.101422f, -0.0237761f, 0.15f, -0.095016f, -0.245349f, -0.117979f, 0.086528f, 0.00067f, @@ -74,7 +74,7 @@ LegoActorLOD g_actorLODs[] = { 0.096123f, 0.00606f, -0.034369f, 0.999391f, -0.190704f, 0.981027f, 0.034894f}, - {"leg-lft", "leg", LegoActorLOD::c_flag2, + {"leg-lft", "leg", LegoActorLOD::c_useColor, 0.00433584f, -0.177404f, -0.0313928f, 0.33f, -0.129782f, -0.440428f, -0.184207f, 0.13817f, 0.118415f, @@ -82,7 +82,7 @@ LegoActorLOD g_actorLODs[] = { 0.006822f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f}, - {"leg-rt", "leg", LegoActorLOD::c_flag2, + {"leg-rt", "leg", LegoActorLOD::c_useColor, 0.00433584f, -0.177404f, -0.0313928f, 0.33f, -0.132864f, -0.437138f, -0.183944f, 0.134614f, 0.12043f, @@ -93,64 +93,64 @@ LegoActorLOD g_actorLODs[] = { }; // GLOBAL: LEGO1 0x100da778 -MxU8 g_unk0x100da778[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0xff}; +MxU8 g_hatPartIndices[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0xff}; // GLOBAL: LEGO1 0x100da790 -MxU8 g_unk0x100da790[] = {21, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0xff}; +MxU8 g_pepperHatPartIndices[] = {21, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0xff}; // GLOBAL: LEGO1 0x100da7a8 -MxU8 g_unk0x100da7a8[] = {22, 0xff}; +MxU8 g_infomanHatPartIndices[] = {22, 0xff}; // GLOBAL: LEGO1 0x100da7ac -MxU8 g_unk0x100da7ac[] = {20, 0xff}; +MxU8 g_ghostHatPartIndices[] = {20, 0xff}; // GLOBAL: LEGO1 0x100da7b0 -MxU8 g_unk0x100da7b0[] = {0, 1, 2, 3, 4, 5, 6, 7, 0xff}; +MxU8 g_bodyPartIndices[] = {0, 1, 2, 3, 4, 5, 6, 7, 0xff}; // GLOBAL: LEGO1 0x100da7c0 -MxU8 g_unk0x100da7c0[] = {0, 1, 2, 3, 4, 5, 6, 7, 0xff}; +MxU8 g_hatColorIndices[] = {0, 1, 2, 3, 4, 5, 6, 7, 0xff}; // GLOBAL: LEGO1 0x100da7d0 -MxU8 g_unk0x100da7d0[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0xff}; +MxU8 g_faceTextureIndices[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0xff}; // GLOBAL: LEGO1 0x100da7e0 -MxU8 g_unk0x100da7e0[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 0xff}; +MxU8 g_chestTextureIndices[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 0xff}; // GLOBAL: LEGO1 0x100da800 -MxU8 g_unk0x100da800[] = {0, 1, 2, 3, 4, 5, 6, 7, 0xff}; +MxU8 g_armColorIndices[] = {0, 1, 2, 3, 4, 5, 6, 7, 0xff}; // GLOBAL: LEGO1 0x100da810 -MxU8 g_unk0x100da810[] = {0, 1, 2, 3, 4, 5, 6, 7, 0xff}; +MxU8 g_clawRightColorIndices[] = {0, 1, 2, 3, 4, 5, 6, 7, 0xff}; // GLOBAL: LEGO1 0x100da820 -MxU8 g_unk0x100da820[] = {0, 1, 2, 3, 4, 5, 6, 7, 0xff}; +MxU8 g_clawLeftColorIndices[] = {0, 1, 2, 3, 4, 5, 6, 7, 0xff}; // GLOBAL: LEGO1 0x100da830 -MxU8 g_unk0x100da830[] = {0, 1, 2, 3, 4, 5, 6, 7, 0xff}; +MxU8 g_gronColorIndices[] = {0, 1, 2, 3, 4, 5, 6, 7, 0xff}; // GLOBAL: LEGO1 0x100da840 -MxU8 g_unk0x100da840[] = {0, 1, 2, 3, 4, 5, 6, 7, 0xff}; +MxU8 g_legColorIndices[] = {0, 1, 2, 3, 4, 5, 6, 7, 0xff}; // GLOBAL: LEGO1 0x100f7f78 -const char* g_unk0x100f7f78[] = {"baseball", "chef", "cap", "cophat", "helmet", "ponytail", "pageboy", "shrthair", - "bald", "flower", "cboyhat", "cuphat", "cathat", "backbcap", "pizhat", "caprc", - "capch", "capdb", "capjs", "capmd", "sheet", "phat", "icap", NULL}; +const char* g_hatPartName[] = {"baseball", "chef", "cap", "cophat", "helmet", "ponytail", "pageboy", "shrthair", + "bald", "flower", "cboyhat", "cuphat", "cathat", "backbcap", "pizhat", "caprc", + "capch", "capdb", "capjs", "capmd", "sheet", "phat", "icap", NULL}; // GLOBAL: LEGO1 0x100f7fd8 -const char* g_unk0x100f7fd8[] = +const char* g_bodyPartName[] = {"body", "bodyred", "bodyblck", "bodywhte", "bodyyllw", "bodyblue", "bodygren", "bodybrwn"}; // GLOBAL: LEGO1 0x100f7ff8 -const char* g_unk0x100f7ff8[] = {"peprchst.gif", "mamachst.gif", "papachst.gif", "nickchst.gif", "norachst.gif", - "infochst.gif", "shftchst.gif", "rac1chst.gif", "rac2chst.gif", "bth1chst.gif", - "bth2chst.gif", "mech.gif", "polkadot.gif", "bowtie.gif", "postchst.gif", - "vest.gif", "doctor.gif", "copchest.gif", "l.gif", "e.gif", - "g.gif", "o.gif", "fruit.gif", "flowers.gif", "construct.gif", - "paint.gif", "l6.gif", "unkchst.gif"}; +const char* g_chestTexture[] = {"peprchst.gif", "mamachst.gif", "papachst.gif", "nickchst.gif", "norachst.gif", + "infochst.gif", "shftchst.gif", "rac1chst.gif", "rac2chst.gif", "bth1chst.gif", + "bth2chst.gif", "mech.gif", "polkadot.gif", "bowtie.gif", "postchst.gif", + "vest.gif", "doctor.gif", "copchest.gif", "l.gif", "e.gif", + "g.gif", "o.gif", "fruit.gif", "flowers.gif", "construct.gif", + "paint.gif", "l6.gif", "unkchst.gif"}; // GLOBAL: LEGO1 0x100f8068 -const char* g_unk0x100f8068[] = { +const char* g_faceTexture[] = { "peprface.gif", "mamaface.gif", "papaface.gif", @@ -168,7 +168,7 @@ const char* g_unk0x100f8068[] = { }; // GLOBAL: LEGO1 0x100f80a0 -const char* g_unk0x100f80a0[] = +const char* g_colorAlias[] = {"lego white", "lego black", "lego yellow", "lego red", "lego blue", "lego brown", "lego lt grey", "lego green"}; // GLOBAL: LEGO1 0x100f80c0 @@ -179,1054 +179,1054 @@ LegoActorInfo g_actorInfoInit[] = { 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 1, g_unk0x100da7e0, g_unk0x100f7ff8, 0}, - {g_unk0x100da790, g_unk0x100f7f78, 0, g_unk0x100da7c0, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}}}, + {{g_bodyPartIndices, g_bodyPartName, 1, g_chestTextureIndices, g_chestTexture, 0}, + {g_pepperHatPartIndices, g_hatPartName, 0, g_hatColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}}}, {"mama", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 1, g_unk0x100da7e0, g_unk0x100f7ff8, 1}, - {g_unk0x100da778, g_unk0x100f7f78, 1, g_unk0x100da7c0, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 1}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}}}, + {{g_bodyPartIndices, g_bodyPartName, 1, g_chestTextureIndices, g_chestTexture, 1}, + {g_hatPartIndices, g_hatPartName, 1, g_hatColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 1}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}}}, {"papa", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 2, g_unk0x100da7e0, g_unk0x100f7ff8, 2}, - {g_unk0x100da778, g_unk0x100f7f78, 1, g_unk0x100da7c0, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 2}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}}}, + {{g_bodyPartIndices, g_bodyPartName, 2, g_chestTextureIndices, g_chestTexture, 2}, + {g_hatPartIndices, g_hatPartName, 1, g_hatColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 2}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}}}, {"nick", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 2, g_unk0x100da7e0, g_unk0x100f7ff8, 3}, - {g_unk0x100da778, g_unk0x100f7f78, 3, g_unk0x100da7c0, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 3}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}}}, + {{g_bodyPartIndices, g_bodyPartName, 2, g_chestTextureIndices, g_chestTexture, 3}, + {g_hatPartIndices, g_hatPartName, 3, g_hatColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 3}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}}}, {"laura", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 2, g_unk0x100da7e0, g_unk0x100f7ff8, 4}, - {g_unk0x100da778, g_unk0x100f7f78, 3, g_unk0x100da7c0, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 4}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}}}, + {{g_bodyPartIndices, g_bodyPartName, 2, g_chestTextureIndices, g_chestTexture, 4}, + {g_hatPartIndices, g_hatPartName, 3, g_hatColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 4}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}}}, {"infoman", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 1, g_unk0x100da7e0, g_unk0x100f7ff8, 5}, - {g_unk0x100da7a8, g_unk0x100f7f78, 0, g_unk0x100da7c0, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 5}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}}}, + {{g_bodyPartIndices, g_bodyPartName, 1, g_chestTextureIndices, g_chestTexture, 5}, + {g_infomanHatPartIndices, g_hatPartName, 0, g_hatColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 5}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}}}, {"brickstr", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 3, g_unk0x100da7e0, g_unk0x100f7ff8, 6}, - {g_unk0x100da778, g_unk0x100f7f78, 13, g_unk0x100da7c0, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 6}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}}}, + {{g_bodyPartIndices, g_bodyPartName, 3, g_chestTextureIndices, g_chestTexture, 6}, + {g_hatPartIndices, g_hatPartName, 13, g_hatColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 6}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}}}, {"studs", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 1, g_unk0x100da7e0, g_unk0x100f7ff8, 7}, - {g_unk0x100da778, g_unk0x100f7f78, 4, g_unk0x100da7c0, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 7}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}}}, + {{g_bodyPartIndices, g_bodyPartName, 1, g_chestTextureIndices, g_chestTexture, 7}, + {g_hatPartIndices, g_hatPartName, 4, g_hatColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 7}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}}}, {"rhoda", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 5, g_unk0x100da7e0, g_unk0x100f7ff8, 8}, - {g_unk0x100da778, g_unk0x100f7f78, 4, g_unk0x100da7c0, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 8}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}}}, + {{g_bodyPartIndices, g_bodyPartName, 5, g_chestTextureIndices, g_chestTexture, 8}, + {g_hatPartIndices, g_hatPartName, 4, g_hatColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 8}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}}}, {"valerie", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 1, g_unk0x100da7e0, g_unk0x100f7ff8, 9}, - {g_unk0x100da778, g_unk0x100f7f78, 5, g_unk0x100da7c0, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 8}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 2}}}, + {{g_bodyPartIndices, g_bodyPartName, 1, g_chestTextureIndices, g_chestTexture, 9}, + {g_hatPartIndices, g_hatPartName, 5, g_hatColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 8}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 2}}}, {"snap", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 3, g_unk0x100da7e0, g_unk0x100f7ff8, 10}, - {g_unk0x100da778, g_unk0x100f7f78, 0, g_unk0x100da7c0, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 9}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 2}}}, + {{g_bodyPartIndices, g_bodyPartName, 3, g_chestTextureIndices, g_chestTexture, 10}, + {g_hatPartIndices, g_hatPartName, 0, g_hatColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 9}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 2}}}, {"pt", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 5, g_unk0x100da7e0, g_unk0x100f7ff8, 11}, - {g_unk0x100da778, g_unk0x100f7f78, 6, g_unk0x100da7c0, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 8}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}}}, + {{g_bodyPartIndices, g_bodyPartName, 5, g_chestTextureIndices, g_chestTexture, 11}, + {g_hatPartIndices, g_hatPartName, 6, g_hatColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 8}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}}}, {"mg", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 1, g_unk0x100da7e0, g_unk0x100f7ff8, 12}, - {g_unk0x100da778, g_unk0x100f7f78, 6, g_unk0x100da7c0, g_unk0x100f80a0, 5}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 10}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}}}, + {{g_bodyPartIndices, g_bodyPartName, 1, g_chestTextureIndices, g_chestTexture, 12}, + {g_hatPartIndices, g_hatPartName, 6, g_hatColorIndices, g_colorAlias, 5}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 10}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}}}, {"bu", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 3, g_unk0x100da7e0, g_unk0x100f7ff8, 13}, - {g_unk0x100da778, g_unk0x100f7f78, 7, g_unk0x100da7c0, g_unk0x100f80a0, 5}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 5}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 11}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 5}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 5}}}, + {{g_bodyPartIndices, g_bodyPartName, 3, g_chestTextureIndices, g_chestTexture, 13}, + {g_hatPartIndices, g_hatPartName, 7, g_hatColorIndices, g_colorAlias, 5}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 5}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 11}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 5}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 5}}}, {"ml", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 5, g_unk0x100da7e0, g_unk0x100f7ff8, 14}, - {g_unk0x100da778, g_unk0x100f7f78, 2, g_unk0x100da7c0, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 12}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}}}, + {{g_bodyPartIndices, g_bodyPartName, 5, g_chestTextureIndices, g_chestTexture, 14}, + {g_hatPartIndices, g_hatPartName, 2, g_hatColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 12}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}}}, {"nu", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 5, g_unk0x100da7e0, g_unk0x100f7ff8, 11}, - {g_unk0x100da778, g_unk0x100f7f78, 7, g_unk0x100da7c0, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 7}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}}}, + {{g_bodyPartIndices, g_bodyPartName, 5, g_chestTextureIndices, g_chestTexture, 11}, + {g_hatPartIndices, g_hatPartName, 7, g_hatColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 7}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}}}, {"na", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 3, g_unk0x100da7e0, g_unk0x100f7ff8, 15}, - {g_unk0x100da778, g_unk0x100f7f78, 10, g_unk0x100da7c0, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 8}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 3}}}, + {{g_bodyPartIndices, g_bodyPartName, 3, g_chestTextureIndices, g_chestTexture, 15}, + {g_hatPartIndices, g_hatPartName, 10, g_hatColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 8}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 3}}}, {"cl", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 3, g_unk0x100da7e0, g_unk0x100f7ff8, 16}, - {g_unk0x100da778, g_unk0x100f7f78, 19, g_unk0x100da7c0, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 12}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}}}, + {{g_bodyPartIndices, g_bodyPartName, 3, g_chestTextureIndices, g_chestTexture, 16}, + {g_hatPartIndices, g_hatPartName, 19, g_hatColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 12}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}}}, {"en", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 3, g_unk0x100da7e0, g_unk0x100f7ff8, 16}, - {g_unk0x100da778, g_unk0x100f7f78, 0, g_unk0x100da7c0, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 11}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}}}, + {{g_bodyPartIndices, g_bodyPartName, 3, g_chestTextureIndices, g_chestTexture, 16}, + {g_hatPartIndices, g_hatPartName, 0, g_hatColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 11}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}}}, {"re", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 3, g_unk0x100da7e0, g_unk0x100f7ff8, 16}, - {g_unk0x100da778, g_unk0x100f7f78, 0, g_unk0x100da7c0, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 11}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}}}, + {{g_bodyPartIndices, g_bodyPartName, 3, g_chestTextureIndices, g_chestTexture, 16}, + {g_hatPartIndices, g_hatPartName, 0, g_hatColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 11}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}}}, {"ro", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 2, g_unk0x100da7e0, g_unk0x100f7ff8, 17}, - {g_unk0x100da778, g_unk0x100f7f78, 3, g_unk0x100da7c0, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 9}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}}}, + {{g_bodyPartIndices, g_bodyPartName, 2, g_chestTextureIndices, g_chestTexture, 17}, + {g_hatPartIndices, g_hatPartName, 3, g_hatColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 9}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}}}, {"d1", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 5, g_unk0x100da7e0, g_unk0x100f7ff8, 11}, - {g_unk0x100da778, g_unk0x100f7f78, 15, g_unk0x100da7c0, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 11}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}}}, + {{g_bodyPartIndices, g_bodyPartName, 5, g_chestTextureIndices, g_chestTexture, 11}, + {g_hatPartIndices, g_hatPartName, 15, g_hatColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 11}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}}}, {"d2", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 5, g_unk0x100da7e0, g_unk0x100f7ff8, 11}, - {g_unk0x100da778, g_unk0x100f7f78, 16, g_unk0x100da7c0, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 11}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}}}, + {{g_bodyPartIndices, g_bodyPartName, 5, g_chestTextureIndices, g_chestTexture, 11}, + {g_hatPartIndices, g_hatPartName, 16, g_hatColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 11}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}}}, {"d3", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 5, g_unk0x100da7e0, g_unk0x100f7ff8, 11}, - {g_unk0x100da778, g_unk0x100f7f78, 17, g_unk0x100da7c0, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 11}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}}}, + {{g_bodyPartIndices, g_bodyPartName, 5, g_chestTextureIndices, g_chestTexture, 11}, + {g_hatPartIndices, g_hatPartName, 17, g_hatColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 11}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}}}, {"d4", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 5, g_unk0x100da7e0, g_unk0x100f7ff8, 11}, - {g_unk0x100da778, g_unk0x100f7f78, 18, g_unk0x100da7c0, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 11}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}}}, + {{g_bodyPartIndices, g_bodyPartName, 5, g_chestTextureIndices, g_chestTexture, 11}, + {g_hatPartIndices, g_hatPartName, 18, g_hatColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 11}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}}}, {"l1", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 1, g_unk0x100da7e0, g_unk0x100f7ff8, 18}, - {g_unk0x100da778, g_unk0x100f7f78, 5, g_unk0x100da7c0, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 11}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}}}, + {{g_bodyPartIndices, g_bodyPartName, 1, g_chestTextureIndices, g_chestTexture, 18}, + {g_hatPartIndices, g_hatPartName, 5, g_hatColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 11}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}}}, {"l2", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 1, g_unk0x100da7e0, g_unk0x100f7ff8, 19}, - {g_unk0x100da778, g_unk0x100f7f78, 6, g_unk0x100da7c0, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 12}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}}}, + {{g_bodyPartIndices, g_bodyPartName, 1, g_chestTextureIndices, g_chestTexture, 19}, + {g_hatPartIndices, g_hatPartName, 6, g_hatColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 12}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}}}, {"l3", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 1, g_unk0x100da7e0, g_unk0x100f7ff8, 20}, - {g_unk0x100da778, g_unk0x100f7f78, 7, g_unk0x100da7c0, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 11}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}}}, + {{g_bodyPartIndices, g_bodyPartName, 1, g_chestTextureIndices, g_chestTexture, 20}, + {g_hatPartIndices, g_hatPartName, 7, g_hatColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 11}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}}}, {"l4", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 1, g_unk0x100da7e0, g_unk0x100f7ff8, 21}, - {g_unk0x100da778, g_unk0x100f7f78, 7, g_unk0x100da7c0, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 11}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}}}, + {{g_bodyPartIndices, g_bodyPartName, 1, g_chestTextureIndices, g_chestTexture, 21}, + {g_hatPartIndices, g_hatPartName, 7, g_hatColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 11}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}}}, {"l5", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 1, g_unk0x100da7e0, g_unk0x100f7ff8, 26}, - {g_unk0x100da778, g_unk0x100f7f78, 7, g_unk0x100da7c0, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 12}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}}}, + {{g_bodyPartIndices, g_bodyPartName, 1, g_chestTextureIndices, g_chestTexture, 26}, + {g_hatPartIndices, g_hatPartName, 7, g_hatColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 12}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}}}, {"l6", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 1, g_unk0x100da7e0, g_unk0x100f7ff8, 26}, - {g_unk0x100da778, g_unk0x100f7f78, 0, g_unk0x100da7c0, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 11}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}}}, + {{g_bodyPartIndices, g_bodyPartName, 1, g_chestTextureIndices, g_chestTexture, 26}, + {g_hatPartIndices, g_hatPartName, 0, g_hatColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 11}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}}}, {"b1", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 0, g_unk0x100da840, g_unk0x100f80a0, 1}, - {g_unk0x100da778, g_unk0x100f7f78, 7, g_unk0x100da7c0, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 12}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}}}, + {{g_bodyPartIndices, g_bodyPartName, 0, g_legColorIndices, g_colorAlias, 1}, + {g_hatPartIndices, g_hatPartName, 7, g_hatColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 12}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}}}, {"b2", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 0, g_unk0x100da840, g_unk0x100f80a0, 1}, - {g_unk0x100da778, g_unk0x100f7f78, 5, g_unk0x100da7c0, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 10}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}}}, + {{g_bodyPartIndices, g_bodyPartName, 0, g_legColorIndices, g_colorAlias, 1}, + {g_hatPartIndices, g_hatPartName, 5, g_hatColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 10}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}}}, {"b3", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 0, g_unk0x100da840, g_unk0x100f80a0, 4}, - {g_unk0x100da778, g_unk0x100f7f78, 7, g_unk0x100da7c0, g_unk0x100f80a0, 5}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 11}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}}}, + {{g_bodyPartIndices, g_bodyPartName, 0, g_legColorIndices, g_colorAlias, 4}, + {g_hatPartIndices, g_hatPartName, 7, g_hatColorIndices, g_colorAlias, 5}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 11}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}}}, {"b4", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 0, g_unk0x100da840, g_unk0x100f80a0, 1}, - {g_unk0x100da778, g_unk0x100f7f78, 7, g_unk0x100da7c0, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 9}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}}}, + {{g_bodyPartIndices, g_bodyPartName, 0, g_legColorIndices, g_colorAlias, 1}, + {g_hatPartIndices, g_hatPartName, 7, g_hatColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 9}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}}}, {"cm", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 4, g_unk0x100da7e0, g_unk0x100f7ff8, 22}, - {g_unk0x100da778, g_unk0x100f7f78, 9, g_unk0x100da7c0, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 8}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 3}}}, + {{g_bodyPartIndices, g_bodyPartName, 4, g_chestTextureIndices, g_chestTexture, 22}, + {g_hatPartIndices, g_hatPartName, 9, g_hatColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 8}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 3}}}, {"gd", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 0, g_unk0x100da840, g_unk0x100f80a0, 1}, - {g_unk0x100da778, g_unk0x100f7f78, 7, g_unk0x100da7c0, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 6}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 11}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 6}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 6}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 6}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 6}}}, + {{g_bodyPartIndices, g_bodyPartName, 0, g_legColorIndices, g_colorAlias, 1}, + {g_hatPartIndices, g_hatPartName, 7, g_hatColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 6}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 11}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 6}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 6}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 6}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 6}}}, {"rd", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 0, g_unk0x100da840, g_unk0x100f80a0, 3}, - {g_unk0x100da778, g_unk0x100f7f78, 0, g_unk0x100da7c0, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 7}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 9}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 7}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 7}}}, + {{g_bodyPartIndices, g_bodyPartName, 0, g_legColorIndices, g_colorAlias, 3}, + {g_hatPartIndices, g_hatPartName, 0, g_hatColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 7}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 9}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 7}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 7}}}, {"pg", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 0, g_unk0x100da840, g_unk0x100f80a0, 3}, - {g_unk0x100da778, g_unk0x100f7f78, 5, g_unk0x100da7c0, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 11}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 3}}}, + {{g_bodyPartIndices, g_bodyPartName, 0, g_legColorIndices, g_colorAlias, 3}, + {g_hatPartIndices, g_hatPartName, 5, g_hatColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 11}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 3}}}, {"bd", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 0, g_unk0x100da840, g_unk0x100f80a0, 6}, - {g_unk0x100da778, g_unk0x100f7f78, 0, g_unk0x100da7c0, g_unk0x100f80a0, 6}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 12}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}}}, + {{g_bodyPartIndices, g_bodyPartName, 0, g_legColorIndices, g_colorAlias, 6}, + {g_hatPartIndices, g_hatPartName, 0, g_hatColorIndices, g_colorAlias, 6}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 12}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}}}, {"sy", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 0, g_unk0x100da840, g_unk0x100f80a0, 4}, - {g_unk0x100da778, g_unk0x100f7f78, 5, g_unk0x100da7c0, g_unk0x100f80a0, 6}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 10}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}}}, + {{g_bodyPartIndices, g_bodyPartName, 0, g_legColorIndices, g_colorAlias, 4}, + {g_hatPartIndices, g_hatPartName, 5, g_hatColorIndices, g_colorAlias, 6}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 10}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}}}, {"gn", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 6, g_unk0x100da7e0, g_unk0x100f7ff8, 13}, - {g_unk0x100da778, g_unk0x100f7f78, 7, g_unk0x100da7c0, g_unk0x100f80a0, 5}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 5}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 9}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 5}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 5}}}, + {{g_bodyPartIndices, g_bodyPartName, 6, g_chestTextureIndices, g_chestTexture, 13}, + {g_hatPartIndices, g_hatPartName, 7, g_hatColorIndices, g_colorAlias, 5}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 5}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 9}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 5}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 5}}}, {"df", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 5, g_unk0x100da7e0, g_unk0x100f7ff8, 23}, - {g_unk0x100da778, g_unk0x100f7f78, 6, g_unk0x100da7c0, g_unk0x100f80a0, 5}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 6}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 8}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 6}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 6}}}, + {{g_bodyPartIndices, g_bodyPartName, 5, g_chestTextureIndices, g_chestTexture, 23}, + {g_hatPartIndices, g_hatPartName, 6, g_hatColorIndices, g_colorAlias, 5}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 6}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 8}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 6}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 6}}}, {"bs", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 3, g_unk0x100da7e0, g_unk0x100f7ff8, 10}, - {g_unk0x100da778, g_unk0x100f7f78, 7, g_unk0x100da7c0, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 7}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 11}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 2}}}, + {{g_bodyPartIndices, g_bodyPartName, 3, g_chestTextureIndices, g_chestTexture, 10}, + {g_hatPartIndices, g_hatPartName, 7, g_hatColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 7}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 11}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 2}}}, {"lt", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 3, g_unk0x100da7e0, g_unk0x100f7ff8, 10}, - {g_unk0x100da778, g_unk0x100f7f78, 7, g_unk0x100da7c0, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 11}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 2}}}, + {{g_bodyPartIndices, g_bodyPartName, 3, g_chestTextureIndices, g_chestTexture, 10}, + {g_hatPartIndices, g_hatPartName, 7, g_hatColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 11}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 2}}}, {"st", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 1, g_unk0x100da7e0, g_unk0x100f7ff8, 9}, - {g_unk0x100da778, g_unk0x100f7f78, 5, g_unk0x100da7c0, g_unk0x100f80a0, 5}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 10}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 2}}}, + {{g_bodyPartIndices, g_bodyPartName, 1, g_chestTextureIndices, g_chestTexture, 9}, + {g_hatPartIndices, g_hatPartName, 5, g_hatColorIndices, g_colorAlias, 5}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 10}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 2}}}, {"bm", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 3, g_unk0x100da7e0, g_unk0x100f7ff8, 24}, - {g_unk0x100da778, g_unk0x100f7f78, 0, g_unk0x100da7c0, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 7}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 6}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 6}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}}}, + {{g_bodyPartIndices, g_bodyPartName, 3, g_chestTextureIndices, g_chestTexture, 24}, + {g_hatPartIndices, g_hatPartName, 0, g_hatColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 7}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 6}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 6}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}}}, {"jk", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 3, g_unk0x100da7e0, g_unk0x100f7ff8, 24}, - {g_unk0x100da778, g_unk0x100f7f78, 0, g_unk0x100da7c0, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 9}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 6}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 6}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}}}, + {{g_bodyPartIndices, g_bodyPartName, 3, g_chestTextureIndices, g_chestTexture, 24}, + {g_hatPartIndices, g_hatPartName, 0, g_hatColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 9}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 6}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 6}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}}}, {"ghost", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 0, g_unk0x100da840, g_unk0x100f80a0, 0}, - {g_unk0x100da7ac, g_unk0x100f7f78, 0, g_unk0x100da7c0, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 13}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}}}, + {{g_bodyPartIndices, g_bodyPartName, 0, g_legColorIndices, g_colorAlias, 0}, + {g_ghostHatPartIndices, g_hatPartName, 0, g_hatColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 13}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}}}, {"ghost01", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 0, g_unk0x100da840, g_unk0x100f80a0, 0}, - {g_unk0x100da7ac, g_unk0x100f7f78, 0, g_unk0x100da7c0, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 13}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}}}, + {{g_bodyPartIndices, g_bodyPartName, 0, g_legColorIndices, g_colorAlias, 0}, + {g_ghostHatPartIndices, g_hatPartName, 0, g_hatColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 13}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}}}, {"ghost02", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 0, g_unk0x100da840, g_unk0x100f80a0, 0}, - {g_unk0x100da7ac, g_unk0x100f7f78, 0, g_unk0x100da7c0, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 13}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}}}, + {{g_bodyPartIndices, g_bodyPartName, 0, g_legColorIndices, g_colorAlias, 0}, + {g_ghostHatPartIndices, g_hatPartName, 0, g_hatColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 13}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}}}, {"ghost03", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 0, g_unk0x100da840, g_unk0x100f80a0, 0}, - {g_unk0x100da7ac, g_unk0x100f7f78, 0, g_unk0x100da7c0, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 13}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}}}, + {{g_bodyPartIndices, g_bodyPartName, 0, g_legColorIndices, g_colorAlias, 0}, + {g_ghostHatPartIndices, g_hatPartName, 0, g_hatColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 13}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}}}, {"ghost04", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 0, g_unk0x100da840, g_unk0x100f80a0, 0}, - {g_unk0x100da7ac, g_unk0x100f7f78, 0, g_unk0x100da7c0, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 13}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}}}, + {{g_bodyPartIndices, g_bodyPartName, 0, g_legColorIndices, g_colorAlias, 0}, + {g_ghostHatPartIndices, g_hatPartName, 0, g_hatColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 13}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}}}, {"ghost05", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 0, g_unk0x100da840, g_unk0x100f80a0, 0}, - {g_unk0x100da7ac, g_unk0x100f7f78, 0, g_unk0x100da7c0, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 13}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 0}}}, + {{g_bodyPartIndices, g_bodyPartName, 0, g_legColorIndices, g_colorAlias, 0}, + {g_ghostHatPartIndices, g_hatPartName, 0, g_hatColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 13}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 0}}}, {"hg", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 0, g_unk0x100da840, g_unk0x100f80a0, 3}, - {g_unk0x100da778, g_unk0x100f7f78, 8, g_unk0x100da7c0, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 8}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 3}}}, + {{g_bodyPartIndices, g_bodyPartName, 0, g_legColorIndices, g_colorAlias, 3}, + {g_hatPartIndices, g_hatPartName, 8, g_hatColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 8}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 3}}}, {"pntgy", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 0, g_unk0x100da840, g_unk0x100f80a0, 3}, - {g_unk0x100da778, g_unk0x100f7f78, 0, g_unk0x100da7c0, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 7}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 3}}}, + {{g_bodyPartIndices, g_bodyPartName, 0, g_legColorIndices, g_colorAlias, 3}, + {g_hatPartIndices, g_hatPartName, 0, g_hatColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 7}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 3}}}, {"pep", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 1, g_unk0x100da7e0, g_unk0x100f7ff8, 0}, - {g_unk0x100da790, g_unk0x100f7f78, 0, g_unk0x100da7c0, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}}}, + {{g_bodyPartIndices, g_bodyPartName, 1, g_chestTextureIndices, g_chestTexture, 0}, + {g_pepperHatPartIndices, g_hatPartName, 0, g_hatColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}}}, {"cop01", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 2, g_unk0x100da7e0, g_unk0x100f7ff8, 17}, - {g_unk0x100da778, g_unk0x100f7f78, 3, g_unk0x100da7c0, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 9}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}}}, + {{g_bodyPartIndices, g_bodyPartName, 2, g_chestTextureIndices, g_chestTexture, 17}, + {g_hatPartIndices, g_hatPartName, 3, g_hatColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 9}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}}}, {"actor_01", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 0, g_unk0x100da840, g_unk0x100f80a0, 4}, - {g_unk0x100da778, g_unk0x100f7f78, 5, g_unk0x100da7c0, g_unk0x100f80a0, 6}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 10}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}}}, + {{g_bodyPartIndices, g_bodyPartName, 0, g_legColorIndices, g_colorAlias, 4}, + {g_hatPartIndices, g_hatPartName, 5, g_hatColorIndices, g_colorAlias, 6}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 10}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}}}, {"actor_02", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 0, g_unk0x100da840, g_unk0x100f80a0, 6}, - {g_unk0x100da778, g_unk0x100f7f78, 0, g_unk0x100da7c0, g_unk0x100f80a0, 6}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 12}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 1}}}, + {{g_bodyPartIndices, g_bodyPartName, 0, g_legColorIndices, g_colorAlias, 6}, + {g_hatPartIndices, g_hatPartName, 0, g_hatColorIndices, g_colorAlias, 6}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 12}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 1}}}, {"actor_03", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 0, g_unk0x100da840, g_unk0x100f80a0, 1}, - {g_unk0x100da778, g_unk0x100f7f78, 7, g_unk0x100da7c0, g_unk0x100f80a0, 1}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 6}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 11}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 6}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 6}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 6}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 6}}}, + {{g_bodyPartIndices, g_bodyPartName, 0, g_legColorIndices, g_colorAlias, 1}, + {g_hatPartIndices, g_hatPartName, 7, g_hatColorIndices, g_colorAlias, 1}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 6}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 11}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 6}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 6}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 6}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 6}}}, {"actor_04", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 1, g_unk0x100da7e0, g_unk0x100f7ff8, 12}, - {g_unk0x100da778, g_unk0x100f7f78, 6, g_unk0x100da7c0, g_unk0x100f80a0, 5}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 10}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 4}}}, + {{g_bodyPartIndices, g_bodyPartName, 1, g_chestTextureIndices, g_chestTexture, 12}, + {g_hatPartIndices, g_hatPartName, 6, g_hatColorIndices, g_colorAlias, 5}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 10}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 4}}}, {"actor_05", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 4, g_unk0x100da7e0, g_unk0x100f7ff8, 22}, - {g_unk0x100da778, g_unk0x100f7f78, 9, g_unk0x100da7c0, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 8}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 3}}}, + {{g_bodyPartIndices, g_bodyPartName, 4, g_chestTextureIndices, g_chestTexture, 22}, + {g_hatPartIndices, g_hatPartName, 9, g_hatColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 8}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 3}}}, {"btmncycl", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 0, g_unk0x100da840, g_unk0x100f80a0, 3}, - {g_unk0x100da778, g_unk0x100f7f78, 5, g_unk0x100da7c0, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 11}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 0}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 3}}}, + {{g_bodyPartIndices, g_bodyPartName, 0, g_legColorIndices, g_colorAlias, 3}, + {g_hatPartIndices, g_hatPartName, 5, g_hatColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 11}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 0}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 3}}}, {"cboycycl", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 3, g_unk0x100da7e0, g_unk0x100f7ff8, 10}, - {g_unk0x100da778, g_unk0x100f7f78, 7, g_unk0x100da7c0, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 7}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 11}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 2}}}, + {{g_bodyPartIndices, g_bodyPartName, 3, g_chestTextureIndices, g_chestTexture, 10}, + {g_hatPartIndices, g_hatPartName, 7, g_hatColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 7}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 11}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 2}}}, {"boatman", NULL, NULL, 0, 0, 0, - {{g_unk0x100da7b0, g_unk0x100f7fd8, 0, g_unk0x100da840, g_unk0x100f80a0, 3}, - {g_unk0x100da778, g_unk0x100f7f78, 0, g_unk0x100da7c0, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da830, g_unk0x100f80a0, 7}, - {NULL, NULL, 0, g_unk0x100da7d0, g_unk0x100f8068, 9}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da800, g_unk0x100f80a0, 3}, - {NULL, NULL, 0, g_unk0x100da820, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da810, g_unk0x100f80a0, 2}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 7}, - {NULL, NULL, 0, g_unk0x100da840, g_unk0x100f80a0, 7}}} + {{g_bodyPartIndices, g_bodyPartName, 0, g_legColorIndices, g_colorAlias, 3}, + {g_hatPartIndices, g_hatPartName, 0, g_hatColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_gronColorIndices, g_colorAlias, 7}, + {NULL, NULL, 0, g_faceTextureIndices, g_faceTexture, 9}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_armColorIndices, g_colorAlias, 3}, + {NULL, NULL, 0, g_clawLeftColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_clawRightColorIndices, g_colorAlias, 2}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 7}, + {NULL, NULL, 0, g_legColorIndices, g_colorAlias, 7}}} }; diff --git a/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp b/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp index 4d92b15b..dc270900 100644 --- a/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp @@ -39,19 +39,19 @@ MxU32 g_characterAnimationId = 10; char* LegoCharacterManager::g_customizeAnimFile = NULL; // GLOBAL: LEGO1 0x100fc4d8 -MxU32 g_unk0x100fc4d8 = 50; +MxU32 g_soundIdOffset = 50; // GLOBAL: LEGO1 0x100fc4dc -MxU32 g_unk0x100fc4dc = 66; +MxU32 g_soundIdMoodOffset = 66; // GLOBAL: LEGO1 0x100fc4e8 -MxU32 g_unk0x100fc4e8 = 0; +MxU32 g_headTextureCounter = 0; // GLOBAL: LEGO1 0x100fc4ec -MxU32 g_unk0x100fc4ec = 2; +MxU32 g_infohatVariantCounter = 2; // GLOBAL: LEGO1 0x100fc4f0 -MxU32 g_unk0x100fc4f0 = 0; +MxU32 g_autoRoiCounter = 0; // GLOBAL: LEGO1 0x10104f20 LegoActorInfo g_actorInfo[66]; @@ -134,33 +134,41 @@ MxResult LegoCharacterManager::Write(LegoStorage* p_storage) if (p_storage->Write(&info->m_mood, sizeof(info->m_mood)) != SUCCESS) { goto done; } - if (p_storage->Write(&info->m_parts[c_infohatPart].m_unk0x08, sizeof(info->m_parts[c_infohatPart].m_unk0x08)) != - SUCCESS) { + if (p_storage->Write( + &info->m_parts[c_infohatPart].m_partNameIndex, + sizeof(info->m_parts[c_infohatPart].m_partNameIndex) + ) != SUCCESS) { goto done; } - if (p_storage->Write(&info->m_parts[c_infohatPart].m_unk0x14, sizeof(info->m_parts[c_infohatPart].m_unk0x14)) != + if (p_storage->Write( + &info->m_parts[c_infohatPart].m_nameIndex, + sizeof(info->m_parts[c_infohatPart].m_nameIndex) + ) != SUCCESS) { + goto done; + } + if (p_storage->Write( + &info->m_parts[c_infogronPart].m_nameIndex, + sizeof(info->m_parts[c_infogronPart].m_nameIndex) + ) != SUCCESS) { + goto done; + } + if (p_storage->Write( + &info->m_parts[c_armlftPart].m_nameIndex, + sizeof(info->m_parts[c_armlftPart].m_nameIndex) + ) != SUCCESS) { + goto done; + } + if (p_storage->Write(&info->m_parts[c_armrtPart].m_nameIndex, sizeof(info->m_parts[c_armrtPart].m_nameIndex)) != SUCCESS) { goto done; } if (p_storage->Write( - &info->m_parts[c_infogronPart].m_unk0x14, - sizeof(info->m_parts[c_infogronPart].m_unk0x14) + &info->m_parts[c_leglftPart].m_nameIndex, + sizeof(info->m_parts[c_leglftPart].m_nameIndex) ) != SUCCESS) { goto done; } - if (p_storage->Write(&info->m_parts[c_armlftPart].m_unk0x14, sizeof(info->m_parts[c_armlftPart].m_unk0x14)) != - SUCCESS) { - goto done; - } - if (p_storage->Write(&info->m_parts[c_armrtPart].m_unk0x14, sizeof(info->m_parts[c_armrtPart].m_unk0x14)) != - SUCCESS) { - goto done; - } - if (p_storage->Write(&info->m_parts[c_leglftPart].m_unk0x14, sizeof(info->m_parts[c_leglftPart].m_unk0x14)) != - SUCCESS) { - goto done; - } - if (p_storage->Write(&info->m_parts[c_legrtPart].m_unk0x14, sizeof(info->m_parts[c_legrtPart].m_unk0x14)) != + if (p_storage->Write(&info->m_parts[c_legrtPart].m_nameIndex, sizeof(info->m_parts[c_legrtPart].m_nameIndex)) != SUCCESS) { goto done; } @@ -189,25 +197,25 @@ MxResult LegoCharacterManager::Read(LegoStorage* p_storage) if (p_storage->Read(&info->m_mood, sizeof(MxU8)) != SUCCESS) { goto done; } - if (p_storage->Read(&info->m_parts[c_infohatPart].m_unk0x08, sizeof(MxU8)) != SUCCESS) { + if (p_storage->Read(&info->m_parts[c_infohatPart].m_partNameIndex, sizeof(MxU8)) != SUCCESS) { goto done; } - if (p_storage->Read(&info->m_parts[c_infohatPart].m_unk0x14, sizeof(MxU8)) != SUCCESS) { + if (p_storage->Read(&info->m_parts[c_infohatPart].m_nameIndex, sizeof(MxU8)) != SUCCESS) { goto done; } - if (p_storage->Read(&info->m_parts[c_infogronPart].m_unk0x14, sizeof(MxU8)) != SUCCESS) { + if (p_storage->Read(&info->m_parts[c_infogronPart].m_nameIndex, sizeof(MxU8)) != SUCCESS) { goto done; } - if (p_storage->Read(&info->m_parts[c_armlftPart].m_unk0x14, sizeof(MxU8)) != SUCCESS) { + if (p_storage->Read(&info->m_parts[c_armlftPart].m_nameIndex, sizeof(MxU8)) != SUCCESS) { goto done; } - if (p_storage->Read(&info->m_parts[c_armrtPart].m_unk0x14, sizeof(MxU8)) != SUCCESS) { + if (p_storage->Read(&info->m_parts[c_armrtPart].m_nameIndex, sizeof(MxU8)) != SUCCESS) { goto done; } - if (p_storage->Read(&info->m_parts[c_leglftPart].m_unk0x14, sizeof(MxU8)) != SUCCESS) { + if (p_storage->Read(&info->m_parts[c_leglftPart].m_nameIndex, sizeof(MxU8)) != SUCCESS) { goto done; } - if (p_storage->Read(&info->m_parts[c_legrtPart].m_unk0x14, sizeof(MxU8)) != SUCCESS) { + if (p_storage->Read(&info->m_parts[c_legrtPart].m_nameIndex, sizeof(MxU8)) != SUCCESS) { goto done; } } @@ -505,7 +513,7 @@ LegoROI* LegoCharacterManager::CreateActorROI(const char* p_key) const char* parentName; if (i == 0 || i == 1) { - parentName = part.m_unk0x04[part.m_unk0x00[part.m_unk0x08]]; + parentName = part.m_partName[part.m_partNameIndices[part.m_partNameIndex]]; } else { parentName = g_actorLODs[i + 1].m_parentName; @@ -555,18 +563,19 @@ LegoROI* LegoCharacterManager::CreateActorROI(const char* p_key) ); childROI->WrappedSetLocal2WorldWithWorldDataUpdate(mat); - if (g_actorLODs[i + 1].m_flags & LegoActorLOD::c_flag1 && (i != 0 || part.m_unk0x00[part.m_unk0x08] != 0)) { + if (g_actorLODs[i + 1].m_flags & LegoActorLOD::c_useTexture && + (i != 0 || part.m_partNameIndices[part.m_partNameIndex] != 0)) { - LegoTextureInfo* textureInfo = textureContainer->Get(part.m_unk0x10[part.m_unk0x0c[part.m_unk0x14]]); + LegoTextureInfo* textureInfo = textureContainer->Get(part.m_names[part.m_nameIndices[part.m_nameIndex]]); if (textureInfo != NULL) { childROI->SetTextureInfo(textureInfo); childROI->SetLodColor(1.0F, 1.0F, 1.0F, 0.0F); } } - else if (g_actorLODs[i + 1].m_flags & LegoActorLOD::c_flag2 || (i == 0 && part.m_unk0x00[part.m_unk0x08] == 0)) { + else if (g_actorLODs[i + 1].m_flags & LegoActorLOD::c_useColor || (i == 0 && part.m_partNameIndices[part.m_partNameIndex] == 0)) { LegoFloat red, green, blue, alpha; - childROI->GetRGBAColor(part.m_unk0x10[part.m_unk0x0c[part.m_unk0x14]], red, green, blue, alpha); + childROI->GetRGBAColor(part.m_names[part.m_nameIndices[part.m_nameIndex]], red, green, blue, alpha); childROI->SetLodColor(red, green, blue, alpha); } @@ -595,7 +604,7 @@ LegoROI* LegoCharacterManager::CreateActorROI(const char* p_key) // FUNCTION: LEGO1 0x100849a0 // FUNCTION: BETA10 0x10075b51 -MxBool LegoCharacterManager::FUN_100849a0(LegoROI* p_roi, LegoTextureInfo* p_texture) +MxBool LegoCharacterManager::SetHeadTexture(LegoROI* p_roi, LegoTextureInfo* p_texture) { LegoResult result = SUCCESS; LegoROI* head = FindChildROI(p_roi, g_actorLODs[c_headLOD].m_name); @@ -607,7 +616,7 @@ MxBool LegoCharacterManager::FUN_100849a0(LegoROI* p_roi, LegoTextureInfo* p_tex assert(lodList); MxS32 lodSize = lodList->Size(); - sprintf(lodName, "%s%s%d", p_roi->GetName(), "head", g_unk0x100fc4e8++); + sprintf(lodName, "%s%s%d", p_roi->GetName(), "head", g_headTextureCounter++); ViewLODList* dupLodList = GetViewLODListManager()->Create(lodName, lodSize); assert(dupLodList); @@ -618,7 +627,7 @@ MxBool LegoCharacterManager::FUN_100849a0(LegoROI* p_roi, LegoTextureInfo* p_tex assert(info); LegoActorInfo::Part& part = info->m_parts[c_headPart]; - p_texture = TextureContainer()->Get(part.m_unk0x10[part.m_unk0x0c[part.m_unk0x14]]); + p_texture = TextureContainer()->Get(part.m_names[part.m_nameIndices[part.m_nameIndex]]); assert(p_texture); } @@ -751,23 +760,23 @@ MxBool LegoCharacterManager::SwitchColor(LegoROI* p_roi, LegoROI* p_targetROI) assert(partIndex < numParts); MxBool findChild = TRUE; - if (partIndex == 6) { - partIndex = 4; + if (partIndex == c_clawlftPart) { + partIndex = c_armlftPart; } - else if (partIndex == 7) { - partIndex = 5; + else if (partIndex == c_clawrtPart) { + partIndex = c_armrtPart; } - else if (partIndex == 3) { - partIndex = 1; + else if (partIndex == c_headPart) { + partIndex = c_infohatPart; } - else if (partIndex == 0) { - partIndex = 2; + else if (partIndex == c_bodyPart) { + partIndex = c_infogronPart; } else { findChild = FALSE; } - if (!(g_actorLODs[partIndex + 1].m_flags & LegoActorLOD::c_flag2)) { + if (!(g_actorLODs[partIndex + 1].m_flags & LegoActorLOD::c_useColor)) { return FALSE; } @@ -783,13 +792,13 @@ MxBool LegoCharacterManager::SwitchColor(LegoROI* p_roi, LegoROI* p_targetROI) LegoActorInfo::Part& part = info->m_parts[partIndex]; - part.m_unk0x14++; - if (part.m_unk0x0c[part.m_unk0x14] == 0xff) { - part.m_unk0x14 = 0; + part.m_nameIndex++; + if (part.m_nameIndices[part.m_nameIndex] == 0xff) { + part.m_nameIndex = 0; } LegoFloat red, green, blue, alpha; - LegoROI::GetRGBAColor(part.m_unk0x10[part.m_unk0x0c[part.m_unk0x14]], red, green, blue, alpha); + LegoROI::GetRGBAColor(part.m_names[part.m_nameIndices[part.m_nameIndex]], red, green, blue, alpha); p_targetROI->SetLodColor(red, green, blue, alpha); return TRUE; } @@ -805,12 +814,12 @@ MxBool LegoCharacterManager::SwitchVariant(LegoROI* p_roi) LegoActorInfo::Part& part = info->m_parts[c_infohatPart]; - part.m_unk0x08++; - MxU8 unk0x00 = part.m_unk0x00[part.m_unk0x08]; + part.m_partNameIndex++; + MxU8 partNameIndex = part.m_partNameIndices[part.m_partNameIndex]; - if (unk0x00 == 0xff) { - part.m_unk0x08 = 0; - unk0x00 = part.m_unk0x00[part.m_unk0x08]; + if (partNameIndex == 0xff) { + part.m_partNameIndex = 0; + partNameIndex = part.m_partNameIndices[part.m_partNameIndex]; } LegoROI* childROI = FindChildROI(p_roi, g_actorLODs[c_infohatLOD].m_name); @@ -818,14 +827,14 @@ MxBool LegoCharacterManager::SwitchVariant(LegoROI* p_roi) if (childROI != NULL) { char lodName[256]; - ViewLODList* lodList = GetViewLODListManager()->Lookup(part.m_unk0x04[unk0x00]); + ViewLODList* lodList = GetViewLODListManager()->Lookup(part.m_partName[partNameIndex]); MxS32 lodSize = lodList->Size(); - sprintf(lodName, "%s%d", p_roi->GetName(), g_unk0x100fc4ec++); + sprintf(lodName, "%s%d", p_roi->GetName(), g_infohatVariantCounter++); ViewLODList* dupLodList = GetViewLODListManager()->Create(lodName, lodSize); Tgl::Renderer* renderer = VideoManager()->GetRenderer(); LegoFloat red, green, blue, alpha; - LegoROI::GetRGBAColor(part.m_unk0x10[part.m_unk0x0c[part.m_unk0x14]], red, green, blue, alpha); + LegoROI::GetRGBAColor(part.m_names[part.m_nameIndices[part.m_nameIndex]], red, green, blue, alpha); for (MxS32 i = 0; i < lodSize; i++) { LegoLOD* lod = (LegoLOD*) (*lodList)[i]; @@ -929,11 +938,11 @@ MxU32 LegoCharacterManager::GetSoundId(LegoROI* p_roi, MxBool p_und) LegoActorInfo* info = GetActorInfo(p_roi); if (p_und) { - return info->m_mood + g_unk0x100fc4dc; + return info->m_mood + g_soundIdMoodOffset; } if (info != NULL) { - return info->m_sound + g_unk0x100fc4d8; + return info->m_sound + g_soundIdOffset; } else { return 0; @@ -998,14 +1007,14 @@ LegoROI* LegoCharacterManager::CreateAutoROI(const char* p_name, const char* p_l name = p_name; } else { - sprintf(buf, "autoROI_%d", g_unk0x100fc4f0++); + sprintf(buf, "autoROI_%d", g_autoRoiCounter++); name = buf; } roi->SetName(name); lodList->Release(); - if (roi != NULL && FUN_10085870(roi) != SUCCESS) { + if (roi != NULL && UpdateBoundingSphereAndBox(roi) != SUCCESS) { delete roi; roi = NULL; } @@ -1035,7 +1044,7 @@ LegoROI* LegoCharacterManager::CreateAutoROI(const char* p_name, const char* p_l } // FUNCTION: LEGO1 0x10085870 -MxResult LegoCharacterManager::FUN_10085870(LegoROI* p_roi) +MxResult LegoCharacterManager::UpdateBoundingSphereAndBox(LegoROI* p_roi) { MxResult result = FAILURE; diff --git a/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp b/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp index 7ba47ba1..0c3c81ea 100644 --- a/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp @@ -401,7 +401,7 @@ MxBool LegoPlantManager::SwitchColor(LegoEntity* p_entity) roi->SetLODList(lodList); lodList->Release(); - CharacterManager()->FUN_10085870(roi); + CharacterManager()->UpdateBoundingSphereAndBox(roi); return TRUE; } @@ -430,7 +430,7 @@ MxBool LegoPlantManager::SwitchVariant(LegoEntity* p_entity) roi->SetLODList(lodList); lodList->Release(); - CharacterManager()->FUN_10085870(roi); + CharacterManager()->UpdateBoundingSphereAndBox(roi); if (info->m_move != 0 && info->m_move >= g_maxMove[info->m_variant]) { info->m_move = g_maxMove[info->m_variant] - 1; diff --git a/LEGO1/lego/legoomni/src/video/legophonemepresenter.cpp b/LEGO1/lego/legoomni/src/video/legophonemepresenter.cpp index 7de88799..453d828b 100644 --- a/LEGO1/lego/legoomni/src/video/legophonemepresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legophonemepresenter.cpp @@ -66,7 +66,7 @@ void LegoPhonemePresenter::StartingTickle() if (!cursor.Find(phoneme)) { LegoTextureInfo* textureInfo = TextureContainer()->GetCached(m_textureInfo); - CharacterManager()->FUN_100849a0(entityROI, textureInfo); + CharacterManager()->SetHeadTexture(entityROI, textureInfo); phoneme->VTable0x0c(m_textureInfo); phoneme->VTable0x14(textureInfo); @@ -147,7 +147,7 @@ void LegoPhonemePresenter::EndAction() } if (roi != NULL) { - CharacterManager()->FUN_100849a0(roi, NULL); + CharacterManager()->SetHeadTexture(roi, NULL); } if (!m_unk0x84) { diff --git a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp index d8ef578c..0ab5ba06 100644 --- a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp +++ b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp @@ -473,6 +473,7 @@ void LegoVideoManager::DrawFPS() char buffer[32]; MxFloat time = (Timer()->GetTime() - m_unk0x54c) / 1000.0f; MxS32 nb = sprintf(buffer, "%.02f", m_unk0x550 / time); + SDL_Log("%.02f", m_unk0x550 / time); m_unk0x54c = Timer()->GetTime(); DDSURFACEDESC surfaceDesc; diff --git a/LEGO1/lego/sources/roi/legolod.cpp b/LEGO1/lego/sources/roi/legolod.cpp index f3a9092e..eb2402ef 100644 --- a/LEGO1/lego/sources/roi/legolod.cpp +++ b/LEGO1/lego/sources/roi/legolod.cpp @@ -225,7 +225,7 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text m_melems[meshIndex].m_tglMesh->SetColor(1.0F, 1.0F, 1.0F, 0.0F); LegoTextureInfo::SetGroupTexture(m_melems[meshIndex].m_tglMesh, textureInfo); - m_melems[meshIndex].m_unk0x04 = TRUE; + m_melems[meshIndex].m_textured = TRUE; } else { LegoFloat red = 1.0F; @@ -314,7 +314,7 @@ LegoLOD* LegoLOD::Clone(Tgl::Renderer* p_renderer) for (LegoU32 i = 0; i < m_numMeshes; i++) { dupLod->m_melems[i].m_tglMesh = m_melems[i].m_tglMesh->ShallowClone(dupLod->m_meshBuilder); - dupLod->m_melems[i].m_unk0x04 = m_melems[i].m_unk0x04; + dupLod->m_melems[i].m_textured = m_melems[i].m_textured; } dupLod->m_unk0x08 = m_unk0x08; @@ -330,7 +330,7 @@ LegoLOD* LegoLOD::Clone(Tgl::Renderer* p_renderer) LegoResult LegoLOD::SetColor(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha) { for (LegoU32 i = m_meshOffset; i < m_numMeshes; i++) { - if (!m_melems[i].m_unk0x04) { + if (!m_melems[i].m_textured) { m_melems[i].m_tglMesh->SetColor(p_red, p_green, p_blue, p_alpha); } } @@ -342,10 +342,10 @@ LegoResult LegoLOD::SetColor(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blu LegoResult LegoLOD::SetTextureInfo(LegoTextureInfo* p_textureInfo) { for (LegoU32 i = m_meshOffset; i < m_numMeshes; i++) { - if (m_melems[i].m_unk0x04) { + if (m_melems[i].m_textured) { LegoTextureInfo::SetGroupTexture(m_melems[i].m_tglMesh, p_textureInfo); m_melems[i].m_tglMesh->SetColor(1.0F, 1.0F, 1.0F, 0.0F); - m_melems[i].m_unk0x04 = TRUE; + m_melems[i].m_textured = TRUE; } } @@ -356,7 +356,7 @@ LegoResult LegoLOD::SetTextureInfo(LegoTextureInfo* p_textureInfo) LegoResult LegoLOD::FUN_100aad70(LegoTextureInfo* p_textureInfo) { for (LegoU32 i = m_meshOffset; i < m_numMeshes; i++) { - if (m_melems[i].m_unk0x04) { + if (m_melems[i].m_textured) { LegoTextureInfo::SetGroupTexture(m_melems[i].m_tglMesh, p_textureInfo); } } @@ -368,7 +368,7 @@ LegoResult LegoLOD::FUN_100aad70(LegoTextureInfo* p_textureInfo) LegoResult LegoLOD::GetTextureInfo(LegoTextureInfo*& p_textureInfo) { for (LegoU32 i = m_meshOffset; i < m_numMeshes; i++) { - if (m_melems[i].m_unk0x04) { + if (m_melems[i].m_textured) { if (LegoTextureInfo::GetGroupTexture(m_melems[i].m_tglMesh, p_textureInfo) == TRUE) { return SUCCESS; } diff --git a/LEGO1/lego/sources/roi/legolod.h b/LEGO1/lego/sources/roi/legolod.h index 8b3409b8..62ece564 100644 --- a/LEGO1/lego/sources/roi/legolod.h +++ b/LEGO1/lego/sources/roi/legolod.h @@ -15,7 +15,7 @@ class LegoLOD : public ViewLOD { // SIZE 0x08 struct Mesh { Tgl::Mesh* m_tglMesh; // 0x00 - BOOL m_unk0x04; // 0x04 + BOOL m_textured; // 0x04 }; LegoLOD(Tgl::Renderer*); diff --git a/miniwin/src/d3drm/d3drmviewport.cpp b/miniwin/src/d3drm/d3drmviewport.cpp index 3b9b6586..d1863e17 100644 --- a/miniwin/src/d3drm/d3drmviewport.cpp +++ b/miniwin/src/d3drm/d3drmviewport.cpp @@ -84,11 +84,8 @@ static void ComputeFrameWorldMatrix(IDirect3DRMFrame* frame, D3DRMMATRIX4D out) IDirect3DRMFrame* cur = frame; while (cur) { auto* impl = static_cast(cur); - D3DRMMATRIX4D local; - memcpy(local, impl->m_transform, sizeof(local)); - D3DRMMATRIX4D tmp; - D3DRMMatrixMultiply(tmp, local, acc); + D3DRMMatrixMultiply(tmp, impl->m_transform, acc); memcpy(acc, tmp, sizeof(acc)); if (cur == impl->m_parent) { @@ -99,243 +96,299 @@ static void ComputeFrameWorldMatrix(IDirect3DRMFrame* frame, D3DRMMATRIX4D out) memcpy(out, acc, sizeof(acc)); } +inline D3DVECTOR CrossProduct(const D3DVECTOR& a, const D3DVECTOR& b) +{ + return {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x}; +} + +inline D3DVECTOR Normalize(const D3DVECTOR& v) +{ + float len = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); + if (len > 0.0f) { + float invLen = 1.0f / len; + return {v.x * invLen, v.y * invLen, v.z * invLen}; + } + return {0, 0, 0}; +} + D3DVECTOR ComputeTriangleNormal(const D3DVECTOR& v0, const D3DVECTOR& v1, const D3DVECTOR& v2) { D3DVECTOR u = {v1.x - v0.x, v1.y - v0.y, v1.z - v0.z}; D3DVECTOR v = {v2.x - v0.x, v2.y - v0.y, v2.z - v0.z}; - D3DVECTOR normal = {u.y * v.z - u.z * v.y, u.z * v.x - u.x * v.z, u.x * v.y - u.y * v.x}; - float len = std::sqrt(normal.x * normal.x + normal.y * normal.y + normal.z * normal.z); - if (len > 0.0f) { - normal.x /= len; - normal.y /= len; - normal.z /= len; - } + D3DVECTOR normal = CrossProduct(u, v); + normal = Normalize(normal); return normal; } -HRESULT Direct3DRMViewportImpl::CollectSceneData() +inline D3DVECTOR TransformNormal(const D3DVECTOR& v, const Matrix3x3& m) +{ + return { + v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0], + v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1], + v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + }; +} + +inline D3DVECTOR TransformPoint(const D3DVECTOR& p, const D3DRMMATRIX4D& m) +{ + return { + p.x * m[0][0] + p.y * m[1][0] + p.z * m[2][0] + m[3][0], + p.x * m[0][1] + p.y * m[1][1] + p.z * m[2][1] + m[3][1], + p.x * m[0][2] + p.y * m[1][2] + p.z * m[2][2] + m[3][2] + }; +} + +void Direct3DRMViewportImpl::CollectLightsFromFrame( + IDirect3DRMFrame* frame, + D3DRMMATRIX4D parentToWorld, + std::vector& lights +) +{ + auto* frameImpl = static_cast(frame); + D3DRMMATRIX4D worldMatrix; + D3DRMMatrixMultiply(worldMatrix, parentToWorld, frameImpl->m_transform); + + IDirect3DRMLightArray* lightArray = nullptr; + frame->GetLights(&lightArray); + DWORD lightCount = lightArray->GetSize(); + for (DWORD li = 0; li < lightCount; ++li) { + IDirect3DRMLight* light = nullptr; + lightArray->GetElement(li, &light); + D3DCOLOR color = light->GetColor(); + SceneLight extracted; + extracted.color = { + ((color >> 0) & 0xFF) / 255.0f, + ((color >> 8) & 0xFF) / 255.0f, + ((color >> 16) & 0xFF) / 255.0f, + ((color >> 24) & 0xFF) / 255.0f + }; + + D3DRMLIGHTTYPE type = light->GetType(); + if (type == D3DRMLIGHT_POINT || type == D3DRMLIGHT_SPOT || type == D3DRMLIGHT_PARALLELPOINT) { + extracted.position = {worldMatrix[3][0], worldMatrix[3][1], worldMatrix[3][2]}; + extracted.positional = 1.f; + } + if (type == D3DRMLIGHT_DIRECTIONAL || type == D3DRMLIGHT_SPOT) { + extracted.direction = {worldMatrix[2][0], worldMatrix[2][1], worldMatrix[2][2]}; + extracted.directional = 1.f; + } + + lights.push_back(extracted); + light->Release(); + } + lightArray->Release(); + + IDirect3DRMFrameArray* children = nullptr; + frame->GetChildren(&children); + DWORD n = children->GetSize(); + for (DWORD i = 0; i < n; ++i) { + IDirect3DRMFrame* childFrame = nullptr; + children->GetElement(i, &childFrame); + CollectLightsFromFrame(childFrame, worldMatrix, lights); + childFrame->Release(); + } + children->Release(); +} + +struct Plane { + D3DVECTOR normal; + float d; +}; + +void NormalizePlane(Plane& plane) +{ + float len = + sqrtf(plane.normal.x * plane.normal.x + plane.normal.y * plane.normal.y + plane.normal.z * plane.normal.z); + if (len > 0.0f) { + float invLen = 1.0f / len; + plane.normal.x *= invLen; + plane.normal.y *= invLen; + plane.normal.z *= invLen; + plane.d *= invLen; + } +} + +Plane frustumPlanes[6]; + +void ExtractFrustumPlanes(const D3DRMMATRIX4D& m) +{ + static const int idx[][2] = {{0, 1}, {0, -1}, {1, 1}, {1, -1}, {2, 1}, {2, -1}}; + for (int i = 0; i < 6; ++i) { + int axis = idx[i][0], sign = idx[i][1]; + frustumPlanes[i] + .normal = {m[0][3] + sign * m[0][axis], m[1][3] + sign * m[1][axis], m[2][3] + sign * m[2][axis]}; + frustumPlanes[i].d = m[3][3] + sign * m[3][axis]; + NormalizePlane(frustumPlanes[i]); + } +} + +bool IsBoxInFrustum(const D3DVECTOR corners[8], const Plane planes[6]) +{ + for (int i = 0; i < 6; ++i) { + int out = 0; + for (int j = 0; j < 8; ++j) { + float dist = planes[i].normal.x * corners[j].x + planes[i].normal.y * corners[j].y + + planes[i].normal.z * corners[j].z + planes[i].d; + if (dist < 0.0f) { + ++out; + } + } + if (out == 8) { + return false; + } + } + return true; +} + +void Direct3DRMViewportImpl::CollectMeshesFromFrame( + IDirect3DRMFrame* frame, + D3DRMMATRIX4D parentMatrix, + std::vector& verts +) +{ + Direct3DRMFrameImpl* frameImpl = static_cast(frame); + D3DRMMATRIX4D localMatrix; + memcpy(localMatrix, frameImpl->m_transform, sizeof(D3DRMMATRIX4D)); + + D3DRMMATRIX4D worldMatrix; + D3DRMMatrixMultiply(worldMatrix, parentMatrix, localMatrix); + + Matrix3x3 worldMatrixInvert; + D3DRMMatrixInvertForNormal(worldMatrixInvert, worldMatrix); + + IDirect3DRMVisualArray* visuals = nullptr; + frame->GetVisuals(&visuals); + DWORD n = visuals->GetSize(); + for (DWORD i = 0; i < n; ++i) { + IDirect3DRMVisual* visual = nullptr; + visuals->GetElement(i, &visual); + + IDirect3DRMFrame* childFrame = nullptr; + visual->QueryInterface(IID_IDirect3DRMFrame, (void**) &childFrame); + if (childFrame) { + CollectMeshesFromFrame(childFrame, worldMatrix, verts); + childFrame->Release(); + visual->Release(); + continue; + } + + IDirect3DRMMesh* mesh = nullptr; + visual->QueryInterface(IID_IDirect3DRMMesh, (void**) &mesh); + if (!mesh) { + visual->Release(); + continue; + } + + D3DRMBOX box; + mesh->GetBox(&box); + D3DVECTOR boxCorners[8] = { + {box.min.x, box.min.y, box.min.z}, + {box.min.x, box.min.y, box.max.z}, + {box.min.x, box.max.y, box.min.z}, + {box.min.x, box.max.y, box.max.z}, + {box.max.x, box.min.y, box.min.z}, + {box.max.x, box.min.y, box.max.z}, + {box.max.x, box.max.y, box.min.z}, + {box.max.x, box.max.y, box.max.z}, + }; + for (D3DVECTOR& boxCorner : boxCorners) { + boxCorner = TransformPoint(boxCorner, worldMatrix); + } + if (!IsBoxInFrustum(boxCorners, frustumPlanes)) { + mesh->Release(); + visual->Release(); + continue; + } + + DWORD groupCount = mesh->GetGroupCount(); + for (DWORD gi = 0; gi < groupCount; ++gi) { + DWORD vtxCount, faceCount, vpf, dataSize; + mesh->GetGroup(gi, &vtxCount, &faceCount, &vpf, &dataSize, nullptr); + + std::vector d3dVerts(vtxCount); + std::vector faces(dataSize); + mesh->GetVertices(gi, 0, vtxCount, d3dVerts.data()); + mesh->GetGroup(gi, nullptr, nullptr, nullptr, nullptr, faces.data()); + + D3DCOLOR color = mesh->GetGroupColor(gi); + D3DRMRENDERQUALITY quality = mesh->GetGroupQuality(gi); + + IDirect3DRMTexture* texture = nullptr; + mesh->GetGroupTexture(gi, &texture); + Uint32 texId = NO_TEXTURE_ID; + if (texture) { + texId = m_renderer->GetTextureId(texture); + texture->Release(); + } + + IDirect3DRMMaterial* material = nullptr; + mesh->GetGroupMaterial(gi, &material); + float shininess = 0.0f; + if (material) { + shininess = material->GetPower(); + material->Release(); + } + + for (DWORD fi = 0; fi < faceCount; ++fi) { + D3DVECTOR norm; + if (quality == D3DRMRENDER_FLAT || quality == D3DRMRENDER_UNLITFLAT) { + D3DRMVERTEX& v0 = d3dVerts[faces[fi * vpf + 0]]; + D3DRMVERTEX& v1 = d3dVerts[faces[fi * vpf + 1]]; + D3DRMVERTEX& v2 = d3dVerts[faces[fi * vpf + 2]]; + norm = ComputeTriangleNormal(v0.position, v1.position, v2.position); + } + + for (DWORD idx = 0; idx < vpf; ++idx) { + D3DRMVERTEX& dv = d3dVerts[faces[fi * vpf + idx]]; + D3DVECTOR pos = dv.position; + if (quality == D3DRMRENDER_GOURAUD || quality == D3DRMRENDER_PHONG) { + norm = dv.normal; + } + + D3DVECTOR worldPos = TransformPoint(pos, worldMatrix); + D3DVECTOR viewNorm = TransformNormal(norm, worldMatrixInvert); + + verts.push_back( + {TransformPoint(worldPos, m_viewMatrix), + Normalize(viewNorm), + {static_cast((color >> 16) & 0xFF), + static_cast((color >> 8) & 0xFF), + static_cast((color >> 0) & 0xFF), + static_cast((color >> 24) & 0xFF)}, + texId, + {dv.tu, dv.tv}, + shininess} + ); + } + } + } + mesh->Release(); + visual->Release(); + } + visuals->Release(); +} + +void Direct3DRMViewportImpl::CollectSceneData() { m_backgroundColor = static_cast(m_rootFrame)->m_backgroundColor; - std::vector lights; - std::vector verts; - - // Compute camera matrix - D3DRMMATRIX4D cameraWorld; + // Compute view-projection matrix + D3DRMMATRIX4D cameraWorld, viewProj; ComputeFrameWorldMatrix(m_camera, cameraWorld); D3DRMMatrixInvertOrthogonal(m_viewMatrix, cameraWorld); - - std::function recurseFrame; - std::function recurseChildren; - - recurseChildren = [&](IDirect3DRMFrame* frame, D3DRMMATRIX4D parentMatrix) { - // Retrieve the current frame's transform - Direct3DRMFrameImpl* frameImpl = static_cast(frame); - D3DRMMATRIX4D localMatrix; - memcpy(localMatrix, frameImpl->m_transform, sizeof(D3DRMMATRIX4D)); - - // Compute combined world matrix: world = parent * local - D3DRMMATRIX4D worldMatrix; - D3DRMMatrixMultiply(worldMatrix, parentMatrix, localMatrix); - - // === Extract lights from the frame === - IDirect3DRMLightArray* lightArray = nullptr; - if (SUCCEEDED(frame->GetLights(&lightArray)) && lightArray) { - DWORD lightCount = lightArray->GetSize(); - for (DWORD li = 0; li < lightCount; ++li) { - IDirect3DRMLight* light = nullptr; - if (SUCCEEDED(lightArray->GetElement(li, &light)) && light) { - D3DCOLOR color = light->GetColor(); - D3DRMLIGHTTYPE type = light->GetType(); - - SceneLight extracted; - extracted.color.r = ((color >> 0) & 0xFF) / 255.0f; - extracted.color.g = ((color >> 8) & 0xFF) / 255.0f; - extracted.color.b = ((color >> 16) & 0xFF) / 255.0f; - extracted.color.a = ((color >> 24) & 0xFF) / 255.0f; - - if (type == D3DRMLIGHT_POINT || type == D3DRMLIGHT_SPOT || type == D3DRMLIGHT_PARALLELPOINT) { - extracted.position.x = worldMatrix[3][0]; - extracted.position.y = worldMatrix[3][1]; - extracted.position.z = worldMatrix[3][2]; - extracted.positional = 1.f; - } - - if (type == D3DRMLIGHT_DIRECTIONAL || type == D3DRMLIGHT_SPOT) { - extracted.direction.x = worldMatrix[2][0]; - extracted.direction.y = worldMatrix[2][1]; - extracted.direction.z = worldMatrix[2][2]; - extracted.directional = 1.f; - } - - lights.push_back(extracted); - - light->Release(); - } - } - lightArray->Release(); - } - - IDirect3DRMFrameArray* children = nullptr; - if (SUCCEEDED(frame->GetChildren(&children)) && children) { - DWORD n = children->GetSize(); - for (DWORD i = 0; i < n; ++i) { - IDirect3DRMFrame* childFrame = nullptr; - children->GetElement(i, &childFrame); - recurseChildren(childFrame, worldMatrix); - childFrame->Release(); - } - children->Release(); - } - }; - - recurseFrame = [&](IDirect3DRMFrame* frame, D3DRMMATRIX4D parentMatrix) { - // Retrieve the current frame's transform - Direct3DRMFrameImpl* frameImpl = static_cast(frame); - D3DRMMATRIX4D localMatrix; - memcpy(localMatrix, frameImpl->m_transform, sizeof(D3DRMMATRIX4D)); - - // Compute combined world matrix: world = parent * local - D3DRMMATRIX4D worldMatrix; - Matrix3x3 worldMatrixInvert; - D3DRMMatrixMultiply(worldMatrix, parentMatrix, localMatrix); - D3DRMMatrixInvertForNormal(worldMatrixInvert, worldMatrix); - - IDirect3DRMVisualArray* va = nullptr; - if (SUCCEEDED(frame->GetVisuals(&va)) && va) { - DWORD n = va->GetSize(); - for (DWORD i = 0; i < n; ++i) { - IDirect3DRMVisual* vis = nullptr; - va->GetElement(i, &vis); - if (!vis) { - continue; - } - - // Pull geometry from meshes - IDirect3DRMMesh* mesh = nullptr; - if (SUCCEEDED(vis->QueryInterface(IID_IDirect3DRMMesh, (void**) &mesh)) && mesh) { - DWORD groupCount = mesh->GetGroupCount(); - for (DWORD gi = 0; gi < groupCount; ++gi) { - DWORD vtxCount, faceCount, vpf, dataSize; - mesh->GetGroup(gi, &vtxCount, &faceCount, &vpf, &dataSize, nullptr); - - std::vector d3dVerts(vtxCount); - std::vector faces(dataSize); - mesh->GetVertices(gi, 0, vtxCount, d3dVerts.data()); - mesh->GetGroup(gi, nullptr, nullptr, nullptr, nullptr, faces.data()); - - D3DCOLOR color = mesh->GetGroupColor(gi); - D3DRMRENDERQUALITY quality = mesh->GetGroupQuality(gi); - IDirect3DRMTexture* texture = nullptr; - mesh->GetGroupTexture(gi, &texture); - IDirect3DRMMaterial* material = nullptr; - mesh->GetGroupMaterial(gi, &material); - Uint32 texId = NO_TEXTURE_ID; - if (texture) { - texId = m_renderer->GetTextureId(texture); - texture->Release(); - } - float shininess = 0.0f; - if (material) { - shininess = material->GetPower(); - material->Release(); - } - - for (DWORD fi = 0; fi < faceCount; ++fi) { - D3DVECTOR norm; - - if (quality == D3DRMRENDER_FLAT || quality == D3DRMRENDER_UNLITFLAT) { - // Discard normals and calculate flat ones - D3DRMVERTEX& v0 = d3dVerts[faces[fi * vpf + 0]]; - D3DRMVERTEX& v1 = d3dVerts[faces[fi * vpf + 1]]; - D3DRMVERTEX& v2 = d3dVerts[faces[fi * vpf + 2]]; - norm = ComputeTriangleNormal(v0.position, v1.position, v2.position); - } - for (int idx = 0; idx < vpf; ++idx) { - auto& dv = d3dVerts[faces[fi * vpf + idx]]; - - // Apply world transform to the vertex - D3DVECTOR pos = dv.position; - if (quality == D3DRMRENDER_GOURAUD || quality == D3DRMRENDER_PHONG) { - norm = dv.normal; - } - D3DVECTOR worldPos; - worldPos.x = pos.x * worldMatrix[0][0] + pos.y * worldMatrix[1][0] + - pos.z * worldMatrix[2][0] + worldMatrix[3][0]; - worldPos.y = pos.x * worldMatrix[0][1] + pos.y * worldMatrix[1][1] + - pos.z * worldMatrix[2][1] + worldMatrix[3][1]; - worldPos.z = pos.x * worldMatrix[0][2] + pos.y * worldMatrix[1][2] + - pos.z * worldMatrix[2][2] + worldMatrix[3][2]; - - // View transform - D3DVECTOR viewPos; - viewPos.x = worldPos.x * m_viewMatrix[0][0] + worldPos.y * m_viewMatrix[1][0] + - worldPos.z * m_viewMatrix[2][0] + m_viewMatrix[3][0]; - viewPos.y = worldPos.x * m_viewMatrix[0][1] + worldPos.y * m_viewMatrix[1][1] + - worldPos.z * m_viewMatrix[2][1] + m_viewMatrix[3][1]; - viewPos.z = worldPos.x * m_viewMatrix[0][2] + worldPos.y * m_viewMatrix[1][2] + - worldPos.z * m_viewMatrix[2][2] + m_viewMatrix[3][2]; - - // View transform - D3DVECTOR viewNorm; - viewNorm.x = norm.x * worldMatrixInvert[0][0] + norm.y * worldMatrixInvert[1][0] + - norm.z * worldMatrixInvert[2][0]; - viewNorm.y = norm.x * worldMatrixInvert[0][1] + norm.y * worldMatrixInvert[1][1] + - norm.z * worldMatrixInvert[2][1]; - viewNorm.z = norm.x * worldMatrixInvert[0][2] + norm.y * worldMatrixInvert[1][2] + - norm.z * worldMatrixInvert[2][2]; - - float len = - sqrtf(viewNorm.x * viewNorm.x + viewNorm.y * viewNorm.y + viewNorm.z * viewNorm.z); - if (len > 0.0f) { - float invLen = 1.0f / len; - viewNorm.x *= invLen; - viewNorm.y *= invLen; - viewNorm.z *= invLen; - } - - PositionColorVertex vtx; - vtx.position = viewPos; - vtx.normals = viewNorm; - vtx.colors = { - static_cast((color >> 16) & 0xFF), - static_cast((color >> 8) & 0xFF), - static_cast((color >> 0) & 0xFF), - static_cast((color >> 24) & 0xFF) - }; - vtx.shininess = shininess; - vtx.texId = texId; - vtx.texCoord = {dv.tu, dv.tv}; - verts.push_back(vtx); - } - } - } - mesh->Release(); - } - - // Recurse into sub frames - IDirect3DRMFrame* childFrame = nullptr; - if (SUCCEEDED(vis->QueryInterface(IID_IDirect3DRMFrame, (void**) &childFrame)) && childFrame) { - recurseFrame(childFrame, worldMatrix); - childFrame->Release(); - } - - vis->Release(); - } - va->Release(); - } - }; + D3DRMMatrixMultiply(viewProj, m_viewMatrix, m_projectionMatrix); D3DRMMATRIX4D identity = {{1.f, 0.f, 0.f, 0.f}, {0.f, 1.f, 0.f, 0.f}, {0.f, 0.f, 1.f, 0.f}, {0.f, 0.f, 0.f, 1.f}}; - recurseFrame(m_rootFrame, identity); - recurseChildren(m_rootFrame, identity); - + std::vector lights; + CollectLightsFromFrame(m_rootFrame, identity, lights); m_renderer->PushLights(lights.data(), lights.size()); - m_renderer->PushVertices(verts.data(), verts.size()); - return D3DRM_OK; + std::vector verts; + ExtractFrustumPlanes(viewProj); + CollectMeshesFromFrame(m_rootFrame, identity, verts); + m_renderer->PushVertices(verts.data(), verts.size()); } HRESULT Direct3DRMViewportImpl::Render(IDirect3DRMFrame* rootFrame) @@ -344,10 +397,7 @@ HRESULT Direct3DRMViewportImpl::Render(IDirect3DRMFrame* rootFrame) return DDERR_GENERIC; } m_rootFrame = rootFrame; - HRESULT success = CollectSceneData(); - if (success != DD_OK) { - return success; - } + CollectSceneData(); return m_renderer->Render(); } @@ -368,7 +418,8 @@ HRESULT Direct3DRMViewportImpl::Clear() uint8_t b = m_backgroundColor & 0xFF; Uint32 color = SDL_MapRGB(SDL_GetPixelFormatDetails(DDBackBuffer->format), nullptr, r, g, b); - SDL_FillSurfaceRect(DDBackBuffer, NULL, color); + SDL_FillSurfaceRect(DDBackBuffer, nullptr, color); + return DD_OK; } @@ -474,39 +525,39 @@ DWORD Direct3DRMViewportImpl::GetHeight() return m_height; } +inline float FromNDC(float ndcCoord, float dim) +{ + return (ndcCoord * 0.5f + 0.5f) * dim; +} + +inline void MultiplyMatrixVec4(D3DRMVECTOR4D& out, const D3DRMMATRIX4D& mat, const D3DRMVECTOR4D& vec) +{ + out.x = mat[0][0] * vec.x + mat[1][0] * vec.y + mat[2][0] * vec.z + mat[3][0] * vec.w; + out.y = mat[0][1] * vec.x + mat[1][1] * vec.y + mat[2][1] * vec.z + mat[3][1] * vec.w; + out.z = mat[0][2] * vec.x + mat[1][2] * vec.y + mat[2][2] * vec.z + mat[3][2] * vec.w; + out.w = mat[0][3] * vec.x + mat[1][3] * vec.y + mat[2][3] * vec.z + mat[3][3] * vec.w; +} + HRESULT Direct3DRMViewportImpl::Transform(D3DRMVECTOR4D* screen, D3DVECTOR* world) { D3DRMVECTOR4D worldVec = {world->x, world->y, world->z, 1.0f}; + D3DRMVECTOR4D viewVec, projVec; - D3DRMVECTOR4D viewVec; - viewVec.x = m_viewMatrix[0][0] * worldVec.x + m_viewMatrix[1][0] * worldVec.y + m_viewMatrix[2][0] * worldVec.z + - m_viewMatrix[3][0] * worldVec.w; - viewVec.y = m_viewMatrix[0][1] * worldVec.x + m_viewMatrix[1][1] * worldVec.y + m_viewMatrix[2][1] * worldVec.z + - m_viewMatrix[3][1] * worldVec.w; - viewVec.z = m_viewMatrix[0][2] * worldVec.x + m_viewMatrix[1][2] * worldVec.y + m_viewMatrix[2][2] * worldVec.z + - m_viewMatrix[3][2] * worldVec.w; - viewVec.w = m_viewMatrix[0][3] * worldVec.x + m_viewMatrix[1][3] * worldVec.y + m_viewMatrix[2][3] * worldVec.z + - m_viewMatrix[3][3] * worldVec.w; + MultiplyMatrixVec4(viewVec, m_viewMatrix, worldVec); + MultiplyMatrixVec4(projVec, m_projectionMatrix, viewVec); - screen->x = viewVec.x * m_projectionMatrix[0][0] + viewVec.y * m_projectionMatrix[1][0] + - viewVec.z * m_projectionMatrix[2][0] + viewVec.w * m_projectionMatrix[3][0]; - screen->y = viewVec.x * m_projectionMatrix[0][1] + viewVec.y * m_projectionMatrix[1][1] + - viewVec.z * m_projectionMatrix[2][1] + viewVec.w * m_projectionMatrix[3][1]; - screen->z = viewVec.x * m_projectionMatrix[0][2] + viewVec.y * m_projectionMatrix[1][2] + - viewVec.z * m_projectionMatrix[2][2] + viewVec.w * m_projectionMatrix[3][2]; - screen->w = viewVec.x * m_projectionMatrix[0][3] + viewVec.y * m_projectionMatrix[1][3] + - viewVec.z * m_projectionMatrix[2][3] + viewVec.w * m_projectionMatrix[3][3]; + *screen = projVec; - float invW = 1.0f / screen->w; - float ndcX = screen->x * invW; - float ndcY = screen->y * invW; + float invW = 1.0f / projVec.w; + float ndcX = projVec.x * invW; + float ndcY = projVec.y * invW; - screen->x = (ndcX * 0.5f + 0.5f) * m_width; - screen->y = (1.0f - (ndcY * 0.5f + 0.5f)) * m_height; + screen->x = FromNDC(ndcX, m_width); + screen->y = FromNDC(-ndcY, m_height); // Y-flip - // Undo perspective divide - screen->x *= screen->z; - screen->y *= screen->w; + // Undo perspective divide for screen-space coords + screen->x *= projVec.z; + screen->y *= projVec.w; return DD_OK; } @@ -521,35 +572,27 @@ HRESULT Direct3DRMViewportImpl::InverseTransform(D3DVECTOR* world, D3DRMVECTOR4D float ndcX = screenX / m_width * 2.0f - 1.0f; float ndcY = 1.0f - (screenY / m_height) * 2.0f; - float clipVec[4] = {ndcX * screen->w, ndcY * screen->w, screen->z, screen->w}; + D3DRMVECTOR4D clipVec = {ndcX * screen->w, ndcY * screen->w, screen->z, screen->w}; - float viewVec[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - viewVec[j] += m_inverseProjectionMatrix[i][j] * clipVec[i]; - } - } + D3DRMVECTOR4D viewVec; + MultiplyMatrixVec4(viewVec, m_inverseProjectionMatrix, clipVec); - float invViewMatrix[4][4]; - D3DRMMatrixInvertOrthogonal(invViewMatrix, m_viewMatrix); + D3DRMMATRIX4D inverseViewMatrix; + D3DRMMatrixInvertOrthogonal(inverseViewMatrix, m_viewMatrix); - float worldVec[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - worldVec[j] += invViewMatrix[i][j] * viewVec[i]; - } - } + D3DRMVECTOR4D worldVec; + MultiplyMatrixVec4(worldVec, inverseViewMatrix, viewVec); // Perspective divide - if (worldVec[3] != 0.0f) { - world->x = worldVec[0] / worldVec[3]; - world->y = worldVec[1] / worldVec[3]; - world->z = worldVec[2] / worldVec[3]; + if (worldVec.w != 0.0f) { + world->x = worldVec.x / worldVec.w; + world->y = worldVec.y / worldVec.w; + world->z = worldVec.z / worldVec.w; } else { - world->x = worldVec[0]; - world->y = worldVec[1]; - world->z = worldVec[2]; + world->x = worldVec.x; + world->y = worldVec.y; + world->z = worldVec.z; } return DD_OK; @@ -631,9 +674,7 @@ Ray BuildPickingRay( // Normalize ray direction float len = sqrt(DotProduct(rayDirView, rayDirView)); - rayDirView.x /= len; - rayDirView.y /= len; - rayDirView.z /= len; + rayDirView = Normalize(rayDirView); // Compute camera world matrix and invert it to get view->world D3DRMMATRIX4D cameraWorld; @@ -649,18 +690,11 @@ Ray BuildPickingRay( }; len = sqrt(rayDirWorld.x * rayDirWorld.x + rayDirWorld.y * rayDirWorld.y + rayDirWorld.z * rayDirWorld.z); - rayDirWorld.x /= len; - rayDirWorld.y /= len; - rayDirWorld.z /= len; + rayDirWorld = Normalize(rayDirWorld); return Ray{rayOriginWorld, rayDirWorld}; } -inline D3DVECTOR CrossProduct(const D3DVECTOR& a, const D3DVECTOR& b) -{ - return {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x}; -} - bool RayIntersectsTriangle( const Ray& ray, const D3DVECTOR& v0, @@ -731,12 +765,7 @@ bool RayIntersectsMeshTriangles( D3DVECTOR tri[3]; for (int j = 0; j < 3; ++j) { const D3DVECTOR& v = vertices[(j == 0 ? i0 : (j == 1 ? i1 : i2))].position; - tri[j].x = - v.x * worldMatrix[0][0] + v.y * worldMatrix[1][0] + v.z * worldMatrix[2][0] + worldMatrix[3][0]; - tri[j].y = - v.x * worldMatrix[0][1] + v.y * worldMatrix[1][1] + v.z * worldMatrix[2][1] + worldMatrix[3][1]; - tri[j].z = - v.x * worldMatrix[0][2] + v.y * worldMatrix[1][2] + v.z * worldMatrix[2][2] + worldMatrix[3][2]; + tri[j] = TransformPoint(v, worldMatrix); } float dist; @@ -751,6 +780,43 @@ bool RayIntersectsMeshTriangles( return false; } +inline D3DVECTOR TransformVector(const D3DRMMATRIX4D& mat, const D3DVECTOR& vec) +{ + return { + vec.x * mat[0][0] + vec.y * mat[1][0] + vec.z * mat[2][0] + mat[3][0], + vec.x * mat[0][1] + vec.y * mat[1][1] + vec.z * mat[2][1] + mat[3][1], + vec.x * mat[0][2] + vec.y * mat[1][2] + vec.z * mat[2][2] + mat[3][2] + }; +} + +D3DRMBOX ComputeTransformedAABB(const D3DRMBOX& box, const D3DRMMATRIX4D& mat) +{ + D3DVECTOR corners[8] = { + {box.min.x, box.min.y, box.min.z}, + {box.min.x, box.min.y, box.max.z}, + {box.min.x, box.max.y, box.min.z}, + {box.min.x, box.max.y, box.max.z}, + {box.max.x, box.min.y, box.min.z}, + {box.max.x, box.min.y, box.max.z}, + {box.max.x, box.max.y, box.min.z}, + {box.max.x, box.max.y, box.max.z} + }; + + D3DVECTOR transformed = TransformVector(mat, corners[0]); + D3DRMBOX worldBox = {transformed, transformed}; + + for (int i = 1; i < 8; ++i) { + D3DVECTOR v = TransformVector(mat, corners[i]); + worldBox.min.x = std::min(worldBox.min.x, v.x); + worldBox.min.y = std::min(worldBox.min.y, v.y); + worldBox.min.z = std::min(worldBox.min.z, v.z); + worldBox.max.x = std::max(worldBox.max.x, v.x); + worldBox.max.y = std::max(worldBox.max.y, v.y); + worldBox.max.z = std::max(worldBox.max.z, v.z); + } + return worldBox; +} + HRESULT Direct3DRMViewportImpl::Pick(float x, float y, LPDIRECT3DRMPICKEDARRAY* pickedArray) { if (!m_rootFrame) { @@ -773,107 +839,50 @@ HRESULT Direct3DRMViewportImpl::Pick(float x, float y, LPDIRECT3DRMPICKEDARRAY* std::function&)> recurse; recurse = [&](IDirect3DRMFrame* frame, std::vector& path) { - Direct3DRMFrameImpl* frameImpl = static_cast(frame); - path.push_back(frame); // Push current frame + path.push_back(frame); IDirect3DRMVisualArray* visuals = nullptr; - if (SUCCEEDED(frame->GetVisuals(&visuals)) && visuals) { - DWORD count = visuals->GetSize(); - for (DWORD i = 0; i < count; ++i) { - IDirect3DRMVisual* vis = nullptr; - visuals->GetElement(i, &vis); + frame->GetVisuals(&visuals); + DWORD count = visuals->GetSize(); + for (DWORD i = 0; i < count; ++i) { + IDirect3DRMVisual* visual = nullptr; + visuals->GetElement(i, &visual); - IDirect3DRMMesh* mesh = nullptr; - IDirect3DRMFrame* subFrame = nullptr; - - if (SUCCEEDED(vis->QueryInterface(IID_IDirect3DRMFrame, (void**) &subFrame)) && subFrame) { - recurse(subFrame, path); - subFrame->Release(); - } - else if (SUCCEEDED(vis->QueryInterface(IID_IDirect3DRMMesh, (void**) &mesh)) && mesh) { - D3DRMBOX box; - if (SUCCEEDED(mesh->GetBox(&box))) { - // Transform box corners to world space - D3DRMMATRIX4D worldMatrix; - ComputeFrameWorldMatrix(frame, worldMatrix); - - // Transform box min and max points - // Because axis-aligned box can become oriented box after transform, - // but we simplify by transforming all 8 corners and computing new AABB - - D3DVECTOR corners[8] = { - {box.min.x, box.min.y, box.min.z}, - {box.min.x, box.min.y, box.max.z}, - {box.min.x, box.max.y, box.min.z}, - {box.min.x, box.max.y, box.max.z}, - {box.max.x, box.min.y, box.min.z}, - {box.max.x, box.min.y, box.max.z}, - {box.max.x, box.max.y, box.min.z}, - {box.max.x, box.max.y, box.max.z}, - }; - - D3DRMBOX worldBox; - { - float x = corners[0].x * worldMatrix[0][0] + corners[0].y * worldMatrix[1][0] + - corners[0].z * worldMatrix[2][0] + worldMatrix[3][0]; - float y = corners[0].x * worldMatrix[0][1] + corners[0].y * worldMatrix[1][1] + - corners[0].z * worldMatrix[2][1] + worldMatrix[3][1]; - float z = corners[0].x * worldMatrix[0][2] + corners[0].y * worldMatrix[1][2] + - corners[0].z * worldMatrix[2][2] + worldMatrix[3][2]; - worldBox.min = {x, y, z}; - worldBox.max = {x, y, z}; - } - - for (int c = 1; c < 8; ++c) { - float x = corners[c].x * worldMatrix[0][0] + corners[c].y * worldMatrix[1][0] + - corners[c].z * worldMatrix[2][0] + worldMatrix[3][0]; - float y = corners[c].x * worldMatrix[0][1] + corners[c].y * worldMatrix[1][1] + - corners[c].z * worldMatrix[2][1] + worldMatrix[3][1]; - float z = corners[c].x * worldMatrix[0][2] + corners[c].y * worldMatrix[1][2] + - corners[c].z * worldMatrix[2][2] + worldMatrix[3][2]; - - if (x < worldBox.min.x) { - worldBox.min.x = x; - } - if (y < worldBox.min.y) { - worldBox.min.y = y; - } - if (z < worldBox.min.z) { - worldBox.min.z = z; - } - if (x > worldBox.max.x) { - worldBox.max.x = x; - } - if (y > worldBox.max.y) { - worldBox.max.y = y; - } - if (z > worldBox.max.z) { - worldBox.max.z = z; - } - } - - float distance = 0.0f; - if (RayIntersectsBox(pickRay, worldBox, distance)) { - if (RayIntersectsMeshTriangles(pickRay, mesh, worldMatrix, distance)) { - auto* arr = new Direct3DRMFrameArrayImpl(); - for (IDirect3DRMFrame* f : path) { - arr->AddElement(f); - } - - PickRecord rec; - rec.visual = vis; - rec.frameArray = arr; - rec.desc.dist = distance; - hits.push_back(rec); - } - } - } - mesh->Release(); - } - vis->Release(); + IDirect3DRMFrame* subFrame = nullptr; + visual->QueryInterface(IID_IDirect3DRMFrame, (void**) &subFrame); + if (subFrame) { + recurse(subFrame, path); + subFrame->Release(); + visual->Release(); + continue; } - visuals->Release(); + + IDirect3DRMMesh* mesh = nullptr; + visual->QueryInterface(IID_IDirect3DRMMesh, (void**) &mesh); + if (mesh) { + D3DRMBOX box; + mesh->GetBox(&box); + // Transform box corners to world space + D3DRMMATRIX4D worldMatrix; + ComputeFrameWorldMatrix(frame, worldMatrix); + D3DRMBOX worldBox = ComputeTransformedAABB(box, worldMatrix); + + float distance = FLT_MAX; + if (RayIntersectsBox(pickRay, worldBox, distance) && + RayIntersectsMeshTriangles(pickRay, mesh, worldMatrix, distance)) { + auto* arr = new Direct3DRMFrameArrayImpl(); + for (IDirect3DRMFrame* f : path) { + arr->AddElement(f); + } + + PickRecord rec = {visual, arr, {distance}}; + hits.push_back(rec); + } + mesh->Release(); + } + visual->Release(); } + visuals->Release(); path.pop_back(); // Pop after recursion }; diff --git a/miniwin/src/internal/d3drmviewport_impl.h b/miniwin/src/internal/d3drmviewport_impl.h index 162230d1..018b0858 100644 --- a/miniwin/src/internal/d3drmviewport_impl.h +++ b/miniwin/src/internal/d3drmviewport_impl.h @@ -35,7 +35,13 @@ struct Direct3DRMViewportImpl : public Direct3DRMObjectBaseImpl& lights); + void CollectMeshesFromFrame( + IDirect3DRMFrame* frame, + D3DRMMATRIX4D parentMatrix, + std::vector& verts + ); void UpdateProjectionMatrix(); Direct3DRMRenderer* m_renderer; D3DCOLOR m_backgroundColor = 0xFF000000;