diff --git a/src/melee/gr/forward.h b/src/melee/gr/forward.h index 41cb2f58f7..228fb3cb0e 100644 --- a/src/melee/gr/forward.h +++ b/src/melee/gr/forward.h @@ -7,6 +7,7 @@ struct grCorneria_GroundVars; typedef struct grDynamicAttr_UnkStruct grDynamicAttr_UnkStruct; typedef struct Ground Ground; +typedef struct IceMountainParams IceMountainParams; typedef struct StageInfo StageInfo; typedef struct UnkArchiveStruct UnkArchiveStruct; typedef struct UnkBgmStruct UnkBgmStruct; diff --git a/src/melee/gr/gricemt.c b/src/melee/gr/gricemt.c index 416141ff84..33d06db44c 100644 --- a/src/melee/gr/gricemt.c +++ b/src/melee/gr/gricemt.c @@ -8,6 +8,7 @@ #include "baselib/random.h" #include "cm/camera.h" #include "ef/efsync.h" +#include "gr/grdatfiles.h" #include "gr/grdisplay.h" #include "gr/grlib.h" #include "gr/grmaterial.h" @@ -22,6 +23,7 @@ #include "lb/lb_00B0.h" #include "mp/mplib.h" +#include #include #include @@ -64,7 +66,14 @@ HSD_GObj* grIm_804D69EC; HSD_GObj* grIm_804D69F0; IceMountainParams* grIm_804D69F4; -HSD_GObj* grIm_803E4068[6]; // This likely contains the ground segments +/// @brief Ice Mountain row data - 12 bytes each. +typedef struct IceMtRowData { + s32 id; // Row identifier, compared with xAC[i] values + u32 x4; + u32 x8; +} IceMtRowData; + +IceMtRowData grIm_803E4068[6]; S16Vec3 grIm_803E40B0[] = { { 0, 0, 0 }, { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 }, { 2, 0, 0 } @@ -108,17 +117,31 @@ StageData grIm_803E4800 = { 3, }; -const float grIm_804DB574 = 0.0; +const float grIm_804DB574 = 0.0F; +const float grIm_804DB5B0 = -1.0F; +const float grIm_804DB5B4 = 1.0F; +const float grIm_804DB5B8 = 6.0F; void grIceMt_801F6868(bool id) {} +#define ICEMT_FIELD_MAX 6 + /// #grIceMt_801F686C void grIceMt_801F686C(void) { - int iVar3; - u32 uVar4; - f32 dVar6; - f32 dVar7; + s32 field30; + s32 field29; + s32 field28; + u32 row_idx; + s16* xAC; + s32 id; + f32 y_pos; + f32 y_pos2; + f32 y_pos3; + f32 y_pos4; + HSD_GObj* gobj; + HSD_JObj* jobj; + grIm_804D69F4 = Ground_801C49F8(); stage_info.unk8C.b4 = true; stage_info.unk8C.b5 = false; @@ -130,47 +153,117 @@ void grIceMt_801F686C(void) Ground_801C3260(4); Ground_801C3260(5); Ground_801C3260(6); - iVar3 = Stage_80225194(); - if (iVar3 == 76) { // adventure mode - // foreach (uVar4 = 0; (uVar4 < 7) && (grIm_804D69F4->xAC == - // grIm_803E4068[uVar4]); uVar4++) { - //} - // uVar4 = 0; - if (grIm_804D69F4->xAC == grIm_803E4068[0]) { - uVar4 = 1; - if (grIm_804D69F4->xAC == grIm_803E4068[1]) { - uVar4 = 2; - if (grIm_804D69F4->xAC == grIm_803E4068[2]) { - uVar4 = 3; - if (grIm_804D69F4->xAC == grIm_803E4068[3]) { - uVar4 = 4; - if (grIm_804D69F4->xAC == grIm_803E4068[4]) { - uVar4 = 5; - if (grIm_804D69F4->xAC == grIm_803E4068[5]) { - uVar4 = 6; - } - } - } - } + if (Stage_80225194() == 76) { + // First loop: find row where neither xAC[0] nor xAC[1] matches + for (row_idx = 0; row_idx < ICEMT_FIELD_MAX; row_idx++) { + xAC = grIm_804D69F4->xAC; + id = grIm_803E4068[row_idx].id; + if (xAC[0] == id) { + continue; + } + if (xAC[1] == id) { + continue; } + field30 = grIm_803E4068[row_idx].id; + break; } - if (5 < uVar4) { - __assert("gricemt.c", 600, ""); + if (row_idx >= ICEMT_FIELD_MAX) { + __assert("gricemt.c", 0x258, ""); + } + + // Second loop: find row where xAC[0], xAC[1], and field30 don't match + for (row_idx = 0; row_idx < ICEMT_FIELD_MAX; row_idx++) { + xAC = grIm_804D69F4->xAC; + id = grIm_803E4068[row_idx].id; + if (xAC[0] == id) { + continue; + } + if (xAC[1] == id) { + continue; + } + if (field30 == id) { + continue; + } + field29 = grIm_803E4068[row_idx].id; + break; + } + if (row_idx >= ICEMT_FIELD_MAX) { + __assert("gricemt.c", 0x261, ""); + } + + // Third loop: find row where xAC[0], xAC[1], field30, and field29 + // don't match + for (row_idx = 0; row_idx < ICEMT_FIELD_MAX; row_idx++) { + xAC = grIm_804D69F4->xAC; + id = grIm_803E4068[row_idx].id; + if (xAC[0] == id) { + continue; + } + if (xAC[1] == id) { + continue; + } + if (field30 == id) { + continue; + } + if (field29 == id) { + continue; + } + field28 = grIm_803E4068[row_idx].id; + break; } - uVar4 = 0; - if (5 < uVar4) { + if (row_idx >= ICEMT_FIELD_MAX) { __assert("gricemt.c", 0x26B, ""); } - __assert("gricemt.c", 0xA37, "bg_gobj"); - __assert("gricemt.c", 0xA37, "bg_gobj"); - __assert("gricemt.c", 0xA37, "bg_gobj"); - __assert("gricemt.c", 0xA37, "bg_gobj"); - __assert("gricemt.c", 0xA37, "bg_gobj"); - dVar6 = Ground_801C0498(); - dVar7 = -20.0 * dVar6; - // dVar6 = grIceMt_801F993C(); - } else { // melee mode + + // Calculate Y positions for the 3 topi platforms + y_pos = Ground_801C0498(); + xAC = grIm_804D69F4->xAC; + y_pos = grIm_804DB570 * y_pos; + y_pos = y_pos + grIceMt_801F993C(grIm_803E4068[xAC[0]].id, + grIm_803E4068[xAC[1]].id); + y_pos2 = y_pos + grIceMt_801F993C(grIm_803E4068[xAC[1]].id, field30); + y_pos3 = y_pos2 + grIceMt_801F993C(field30, field29); + y_pos4 = y_pos3 + grIceMt_801F993C(field29, field28); + + // Set up first topi (grIm_804D69E8) + gobj = grIceMt_801F71E8(grIm_803E4068[xAC[2]].id); + if (gobj == NULL) { + __assert("gricemt.c", 0x27C, "bg_gobj"); + } + jobj = gobj->hsd_obj; + if (jobj == NULL) { + __assert("gricemt.c", 0x27D, "jobj"); + } + HSD_JObjSetTranslateY(jobj, y_pos2); + grIm_804D69E8 = gobj; + + // Set up second topi (grIm_804D69EC) + gobj = grIceMt_801F71E8(grIm_803E4068[xAC[3]].id); + if (gobj == NULL) { + __assert("gricemt.c", 0x281, "bg_gobj"); + } + jobj = gobj->hsd_obj; + if (jobj == NULL) { + __assert("gricemt.c", 0x282, "jobj"); + } + HSD_JObjSetTranslateY(jobj, y_pos3); + grIm_804D69EC = gobj; + + // Set up third topi (grIm_804D69F0) + gobj = grIceMt_801F71E8(grIm_803E4068[xAC[4]].id); + if (gobj == NULL) { + __assert("gricemt.c", 0x286, "bg_gobj"); + } + jobj = gobj->hsd_obj; + if (jobj == NULL) { + __assert("gricemt.c", 0x287, "jobj"); + } + HSD_JObjSetTranslateY(jobj, y_pos4); + grIm_804D69F0 = gobj; + + grIceMt_801F71E8(0xA); + } else { grIceMt_801F71E8(9); grIm_804D69E8 = NULL; grIm_804D69EC = NULL; @@ -179,6 +272,7 @@ void grIceMt_801F686C(void) Ground_801C39C0(); Ground_801C3BB4(); } + void grIceMt_801F7080(void) { // Ground_801C2BA4(5); @@ -344,24 +438,28 @@ void fn_801F75EC(HSD_GObj* arg0) } /// #grIceMt_801F75FC +/// @note This function treats xF4 area as s16 indices during initialization. +/// The same memory is later interpreted as pointers by other functions. void grIceMt_801F75FC(Ground_GObj* arg0) { u32 iVar1; + s16 val; Ground* gp = GET_GROUND(arg0); memzero(&gp->gv.icemt.xDC, 0x18); memzero(&gp->gv.icemt.xF4, 0x14); do { iVar1 = HSD_Randi(6); - } while (gp->gv.icemt.xF4[iVar1] != 0); - gp->gv.icemt.xF4[iVar1] = grIm_804D69F4; - gp->gv.icemt.xC4 = grIm_803E4068[iVar1]; + val = gp->gv.icemt.xF4[iVar1]; + } while (val != 0); + gp->gv.icemt.xF4[iVar1] = *(s16*) grIm_804D69F4; + gp->gv.icemt.xC4 = (s16) grIm_803E4068[iVar1].id; do { iVar1 = HSD_Randi(6); - } while (gp->gv.icemt.xF4[iVar1] != 0); - gp->gv.icemt.xF4[iVar1] = grIm_804D69F4; - // Ground_801C10B8(arg0,fn_801F75EC(arg0));grIm_803E4068 - gp->gv.icemt.xC6 = grIm_803E4068[iVar1]; - grIceMt_801FA0BC(gp->gv.icemt2.xC4); + val = gp->gv.icemt.xF4[iVar1]; + } while (val != 0); + gp->gv.icemt.xF4[iVar1] = *(s16*) grIm_804D69F4; + gp->gv.icemt.xC6 = (s16) grIm_803E4068[iVar1].id; + grIceMt_801FA0BC((int) &gp->gv.icemt.xC4); gp->gv.icemt.xDA = 0; gp->gv.icemt.xC8 = 0; gp->gv.icemt.xCE = 0; @@ -402,24 +500,38 @@ void fn_801F77B0(HSD_GObj* arg0) mpJointSetCb1(4, gp, grIceMt_801FA7F0); } -void grIceMt_801F785C(Ground_GObj* arg0) +/// #grIceMt_801F785C +void grIceMt_801F785C(Ground_GObj* gobj) { - Ground* gp = GET_GROUND(arg0); + Ground* gp = GET_GROUND(gobj); + + // Index into grIm_803E4068 using row indices from grIm_804D69F4->xAC + gp->gv.icemt.xC4 = (s16) grIm_803E4068[grIm_804D69F4->xAC[1]].id; + gp->gv.icemt.xC6 = (s16) grIm_803E4068[grIm_804D69F4->xAC[0]].id; + + grIceMt_801FA0BC((int) &gp->gv.icemt.xC4); + gp->gv.icemt.xDC = 0; - // gp->gv.icemt.xE0 = 2; + gp->gv.icemt.xE0 = 2; gp->gv.icemt.xDE = 0; - gp->gv.icemt.xDA = 0; - gp->gv.icemt.xE4 = 0.0; + ((UnkFlagStruct*) &gp->gv.icemt.xD8)->b1 = 0; + ((UnkFlagStruct*) &gp->gv.icemt.xD8)->b2 = 0; + ((UnkFlagStruct*) &gp->gv.icemt.xD8)->b3 = 0; + ((UnkFlagStruct*) &gp->gv.icemt.xD8)->b4 = 0; + gp->gv.icemt.xDA = 0; + gp->gv.icemt.xE4 = grIm_804DB574; gp->gv.icemt.xC8 = 0; gp->gv.icemt.xCE = 0; gp->gv.icemt.xCA = 0; gp->gv.icemt.xCC = 0; - gp->gv.icemt.xD0 = NULL; + gp->gv.icemt.xD0 = -1; gp->gv.icemt.xD4 = grIm_804DB574; - // gp->gv.icemt.xD8 = 1; - Ground_801C10B8(arg0, fn_801F77B0); + + ((UnkFlagStruct*) &gp->gv.icemt.xD8)->b7 = 1; + + Ground_801C10B8(gobj, fn_801F77B0); } /// #grIceMt_801F796C gricemt.c @@ -629,7 +741,13 @@ bool grIceMt_801F85BC(Ground_GObj* param1) } /// #grIceMt_801F85C4 - +void grIceMt_801F85C4(Ground_GObj* gobj) +{ + Ground* gp = gobj->user_data; + grIceMt_801F929C((HSD_GObj*) &gp->gv.icemt.xF8[4]); + grIceMt_801F98A8(gobj); + Ground_801C2FE0(gobj); +} /// #grIceMt_801F8608 void grIceMt_801F8608(Ground_GObj* arg0) { @@ -683,7 +801,19 @@ void grIceMt_801F87C8(Ground_GObj* param1) return; } -/// #grIceMt_801F87FC +/// @todo Rename: This is callback3 (destroy) for row 5 in grIm_803E4718. +/// Destroys HSD_GObj* stored in icemt.xF8[0-4]. +void grIceMt_801F87FC(Ground_GObj* gobj) +{ + Ground* gp = gobj->user_data; + int i; + for (i = 0; i < 5; i++) { + HSD_GObj* temp; + if ((temp = gp->gv.icemt.xF8[i]) != NULL) { + grMaterial_801C8CDC(temp); + } + } +} /// #grIceMt_801F8850 void grIceMt_801F8850(Ground_GObj* arg0) @@ -783,7 +913,60 @@ void fn_801F8C64(Item_GObj* gobj, Ground* u1, Vec3* u2, HSD_GObj* u3, f32 u4) Camera_80030E44(2, &pos); } -/// #grIceMt_801F8CDC +/// @brief Creates material items and attaches them to Entity05 platform JObjs. +/// @param gobj The Entity05 Ground_GObj +/// @param joint_indices Array of joint indices to get parent JObjs from +/// @param count Number of items to create (max 20) +/// @param output_array Array to store created Item_GObj pointers +void grIceMt_801F8CDC(Ground_GObj* gobj, s16* joint_indices, int count, + HSD_GObj** output_array) +{ + Ground* gp = gobj->user_data; + UnkArchiveStruct* archive; + void* jobj_desc; + HSD_JObj* parent_jobjs[20]; + HSD_JObj* parent_jobj; + HSD_JObj* child_jobj; + Item_GObj* item; + int i; + u8 unused[24]; + + archive = grDatFiles_801C6324(); + jobj_desc = archive->unk4->unk8[7].unk0; + + if (count > 20) { + __assert("gricemt.c", 0x7D4, "count <= 20"); + } + + for (i = 0; i < count; i++) { + parent_jobjs[i] = Ground_801C3FA4(gobj, joint_indices[i]); + } + + for (i = 0; i < count; i++) { + parent_jobj = parent_jobjs[i]; + if (parent_jobj == NULL) { + __assert("gricemt.c", 0x7E3, "parent_jobj"); + } + + child_jobj = HSD_JObjLoadJoint(jobj_desc); + if (child_jobj == NULL) { + __assert("gricemt.c", 0x7E6, "child_jobj"); + } + + HSD_JObjAddChild(parent_jobj, child_jobj); + + item = grMaterial_801C8CFC(8, 0, gp, parent_jobj, NULL, fn_801F8C64, + NULL); + if (item != NULL) { + grMaterial_801C8DE0(item, grIm_804DB574, grIm_804DB5B0, + grIm_804DB574, grIm_804DB574, grIm_804DB5B4, + grIm_804DB574, grIm_804DB5B8); + grMaterial_801C8E08(item); + grMaterial_801C8E68(item, 0); + } + output_array[i] = item; + } +} /// #fn_801F8E58 @@ -798,12 +981,15 @@ IceMountainParams* fn_801F9150(HSD_GObj* arg0) void fn_801F91A4(void) {} /// #fn_801F91A8 grIm_804D69F4 +/// @todo This function reads xAC[gp->xE0] and returns grIm_803E4068[index].id HSD_GObj* fn_801F91A8(HSD_GObj* arg0) { - HSD_GObj* iVar2 = grIm_804D69F4->xAC; - // if (iVar2 != -1) { - return iVar2; - //} + Ground* gp = GET_GROUND(arg0); + s16 index = grIm_804D69F4->xAC[gp->gv.icemt.xE0]; + if (index == -1) { + return (HSD_GObj*) (s32) index; + } + return (HSD_GObj*) grIm_803E4068[index].id; } /// #grIceMt_801F91EC @@ -911,28 +1097,28 @@ float grIceMt_801F96E0(float y) } /// #grIceMt_801F98A8 -int grIceMt_801F98A8(HSD_GObj* param1) +/// @note Checks bit 6 of icemt2.xC4 (as byte) - clears it and does cleanup. +int grIceMt_801F98A8(Ground_GObj* param1) { - Ground* gp = GET_GROUND(param1); - // gp->x8_callback = NULL; - // gp->xC_callback = NULL; - if (gp->gv.icemt2.xC8) { - Ground_801C2D0C(0, gp->gv.icemt2.xC8); - } - if (gp->gv.icemt2.xCC) { - Ground_801C2D0C(1, gp->gv.icemt2.xCC); - } - if (gp->gv.icemt2.xD0) { - Ground_801C2D0C(2, gp->gv.icemt2.xD0); - } - if (gp->gv.icemt2.xD4) { - Ground_801C2D0C(3, gp->gv.icemt2.xD4); + Ground* gp = param1->user_data; + u8 flags = *(u8*)&gp->gv.icemt2.xC4; + HSD_JObj** ptrs = &gp->gv.icemt2.xC8; + + if (flags & 0x40) { + *(u8*)&gp->gv.icemt2.xC4 = flags & ~0x40; + if (ptrs[0]) { + Ground_801C2D0C(0, ptrs[0]); + } + if (ptrs[1]) { + Ground_801C2D0C(1, ptrs[1]); + } + if (ptrs[2]) { + Ground_801C2D0C(2, ptrs[2]); + } + if (ptrs[3]) { + Ground_801C2D0C(3, ptrs[3]); + } } - - // Ground_801C2D0C(1); - // Ground_801C2D0C(2); - // Ground_801C2D0C(3); - // int bruh = Ground_801C2D0C(1, param1); return 0; } diff --git a/src/melee/gr/gricemt.h b/src/melee/gr/gricemt.h index 7b6e2dc652..481cf0f721 100644 --- a/src/melee/gr/gricemt.h +++ b/src/melee/gr/gricemt.h @@ -11,7 +11,7 @@ #include -typedef struct IceMountainParams { +struct IceMountainParams { float x0; int x4; float x8; @@ -56,7 +56,7 @@ typedef struct IceMountainParams { float xA0; float xA4; float xA8; - HSD_GObj* xAC; + s16* xAC; float xB0; float xB4; s16 xB8; @@ -65,7 +65,9 @@ typedef struct IceMountainParams { float xC4; float xC8; float xCC; -} IceMountainParams; +}; + +extern f32 grIm_804DB570; /* 1F6868 */ void grIceMt_801F6868(bool id); /* 1F686C */ void grIceMt_801F686C(void); @@ -116,34 +118,35 @@ typedef struct IceMountainParams { /* 1F8B10 */ void grIceMt_801F8B10(Ground_GObj*); /* 1F8C60 */ void grIceMt_801F8C60(Ground_GObj*); /* 1F8C64 */ // void fn_801F8C64(Item_GObj*, Ground*, Vec3*, HSD_GObj*, f32); -/* 1F8CDC */ UNK_RET grIceMt_801F8CDC(Ground_GObj*); +/* 1F8CDC */ void grIceMt_801F8CDC(Ground_GObj*, s16* joint_indices, int count, + HSD_GObj** output_array); /* 1F8E58 */ UNK_RET fn_801F8E58(Ground_GObj*); /* 1F9038 */ UNK_RET fn_801F9038(Ground_GObj*); /* 1F9150 */ IceMountainParams* fn_801F9150(HSD_GObj*); -/* 1F91A4 */ void fn_801F91A4(UNK_PARAMS); +/* 1F91A4 */ void fn_801F91A4(void); /* 1F91A8 */ HSD_GObj* fn_801F91A8(HSD_GObj*); /* 1F91EC */ UNK_RET grIceMt_801F91EC(HSD_GObj*); -/* 1F929C */ UNK_RET grIceMt_801F929C(HSD_GObj* arg0); -/* 1F9338 */ UNK_RET fn_801F9338(Ground*, int, CollData*, s32, - mpLib_GroundEnum, float); -/* 1F9448 */ UNK_RET fn_801F9448(Ground*, int, CollData*, s32, - mpLib_GroundEnum, float); -/* 1F9558 */ UNK_RET fn_801F9558(Ground*, int, CollData*, s32, - mpLib_GroundEnum, float); +/* 1F929C */ void grIceMt_801F929C(HSD_GObj* arg0); +/* 1F9338 */ void fn_801F9338(Ground*, int, CollData*, s32, mpLib_GroundEnum, + float); +/* 1F9448 */ void fn_801F9448(Ground*, int, CollData*, s32, mpLib_GroundEnum, + float); +/* 1F9558 */ void fn_801F9558(Ground*, int, CollData*, s32, mpLib_GroundEnum, + float); /* 1F9668 */ void grIceMt_801F9668(float); /* 1F96E0 */ float grIceMt_801F96E0(float); /* 1F98A8 */ bool grIceMt_801F98A8(HSD_GObj* param1); -/* 1F993C */ UNK_RET grIceMt_801F993C(UNK_PARAMS); -/* 1F9ACC */ UNK_RET grIceMt_801F9ACC(float); +/* 1F993C */ f32 grIceMt_801F993C(s32, s32); +/* 1F9ACC */ void grIceMt_801F9ACC(float); /* 1FA0BC */ UNK_RET grIceMt_801FA0BC(int); /* 1FA364 */ void grIceMt_801FA364(UNK_T, float*, HSD_GObjEvent, Ground_GObj*); /* 1FA4CC */ int fn_801FA4CC(int num); /* 1FA500 */ int grIceMt_801FA500(HSD_GObj*); -/* 1FA6D8 */ UNK_RET grIceMt_801FA6D8(Ground_GObj*); +/* 1FA6D8 */ void grIceMt_801FA6D8(HSD_GObj*); /* 1FA728 */ void grIceMt_801FA728(Vec3*); -/* 1FA7F0 */ UNK_RET grIceMt_801FA7F0(Ground*, s32, CollData*, s32, - mpLib_GroundEnum, float); -/* 1FA854 */ UNK_RET grIceMt_801FA854(void); +/* 1FA7F0 */ void grIceMt_801FA7F0(Ground*, s32, CollData*, s32, + mpLib_GroundEnum, float); +/* 1FA854 */ void grIceMt_801FA854(void); /* 1FA8F8 */ DynamicsDesc* grIceMt_801FA8F8(enum_t id); /* 1FA900 */ bool grIceMt_801FA900(Vec3* a, int id, HSD_JObj* jobj); diff --git a/src/melee/gr/types.h b/src/melee/gr/types.h index 7b1677d75a..857c36898f 100644 --- a/src/melee/gr/types.h +++ b/src/melee/gr/types.h @@ -350,8 +350,8 @@ struct grGreatBay_GroundVars { }; struct grIceMt_GroundVars { - /* +0 gp+C4 */ HSD_GObj* xC4; - /* +0 gp+C4 */ HSD_GObj* xC6; + /* +0 gp+C4 */ s16 xC4; + /* +0 gp+C4 */ s16 xC6; /* +0 gp+C4 */ s16 xC8; /* +0 gp+C4 */ s16 xCA; /* +0 gp+C4 */ s16 xCC; @@ -365,7 +365,11 @@ struct grIceMt_GroundVars { /* +0 gp+D8 */ s16 xDE; /* +0 gp+D8 */ s16 xE0; /* +0 gp+D8 */ f32 xE4; - /* +0 gp+D8 */ void* xF4[6]; + /* +0 gp+D8 */ u32 xE8; + /* +0 gp+D8 */ u32 xEC; + /* +0 gp+D8 */ u32 xF0; // padding + /* +0 gp+D8 */ s16 xF4[2]; + /* +0 gp+D8 */ HSD_GObj* xF8[5]; }; struct grIceMt_GroundVars2 { /* +0 gp+C4 */ f32 xC4;