diff --git a/config/us/pilotwings64.us.yaml b/config/us/pilotwings64.us.yaml index a332cc2..433be52 100644 --- a/config/us/pilotwings64.us.yaml +++ b/config/us/pilotwings64.us.yaml @@ -514,7 +514,8 @@ segments: - [0xD7AF0, data] - [0xD7B80, data] - [0xD7BC0, data] - - [0xD7D20, data] + - [0xD7D20, .data, app/thermals] + - [0xD7D30, data] - [0xD7E10, data] - [0xD7EF0, data] - [0xD7F40, .rodata, app/code_51E30] @@ -611,7 +612,9 @@ segments: - [0xDE640, .rodata, app/code_D4290] - [0xDE6B0, .rodata, app/wind_objects] - - { type: bss, start: 0xDE720, vram: 0x803571F0, name: app_bss } + - { type: bss, vram: 0x803571F0, name: app_bss_803571F0 } + - { type: .bss, vram: 0x8037AB50, name: app/thermals } + - { type: bss, vram: 0x8037ACE0, name: app_bss_8037ACD8 } - name: bin_DE720 type: bin diff --git a/config/us/sym/symbol_addrs_app.txt b/config/us/sym/symbol_addrs_app.txt index e083e0d..1215069 100644 --- a/config/us/sym/symbol_addrs_app.txt +++ b/config/us/sym/symbol_addrs_app.txt @@ -221,6 +221,13 @@ levelDataGetPHTS = 0x80345C3C; // type:func levelDataGetFALC = 0x80345C5C; // type:func levelDataGetHOPD = 0x80346474; // type:func +thermInit = 0x803465F0; // type:func +therm_8034662C = 0x8034662C; // type:func +therm_8034695C = 0x8034695C; // type:func +therm_80346B84 = 0x80346B84; // type:func +therm_80346C08 = 0x80346C08; // type:func +therm_80346E04 = 0x80346E04; // type:func + windObjectsInit = 0x8034E080; // type:func mem_get = 0x80312740; // type:func diff --git a/config/us/sym/symbol_addrs_kernel.txt b/config/us/sym/symbol_addrs_kernel.txt index ca6b680..f928383 100644 --- a/config/us/sym/symbol_addrs_kernel.txt +++ b/config/us/sym/symbol_addrs_kernel.txt @@ -494,6 +494,7 @@ gLevelClassU8 = 0x80350790; gLevelVehicleU8 = 0x80350794; gLevelTestU8 = 0x80350798; gMapLookup = 0x803507A8; +gThermShouldDisable = 0x803507F0; gTitleMenuDelay = 0x80356A68; @@ -510,8 +511,10 @@ gLevelClass = 0x8037AA78; gLevelTest = 0x8037AA7C; gLevelVehicle = 0x8037AA80; +gLevelTHER = 0x8037AB50; gThermalCount = 0x8037AB54; gThermals = 0x8037AB58; // size:0x180 +gThermReady = 0x8037ACD8; gLevelCurMap = 0x8034F40C; gLevelObjHeapPtr = 0x8034F840; diff --git a/docs/pilotwings64_file_system.md b/docs/pilotwings64_file_system.md index 0f79ec9..22a4a0e 100644 --- a/docs/pilotwings64_file_system.md +++ b/docs/pilotwings64_file_system.md @@ -287,8 +287,11 @@ Offset | Type | Description 0x8 | f32 | Z position 0xC | f32 | scale 0x10 | f32 | height -0x14 | ?? | TBD +0x14 | s32 | TBD 0x18 | f32 | TBD +0x1C | f32 | TBD +0x20 | f32 | TBD +0x24 | f32 | TBD 0x28 | | **Total length** ### TPAD / takeoff pad diff --git a/include/uv_level.h b/include/uv_level.h index f593599..e776ced 100644 --- a/include/uv_level.h +++ b/include/uv_level.h @@ -107,6 +107,16 @@ typedef struct { u8 pad1C[4]; } LevelHOPD; +typedef struct { + u8 countESND; + u8 countWOBJ; + u8 countLPAD; + u8 countTOYS; + u8 countTPTS; + u8 countAPTS; + u8 countBNUS; +} LevelLEVL; + typedef struct { f32 x; f32 y; @@ -114,6 +124,17 @@ typedef struct { f32 unkC; } LevelOBSV; +typedef struct { + Vec3F pos; + f32 scale; + f32 height; + s32 unk14; + f32 unk18; + f32 unk1C; + f32 unk20; + f32 unk24; +} LevelTHER; + typedef struct { u8 unk0; u8 unk1[3]; @@ -136,7 +157,7 @@ typedef struct { } LevelTOYS; typedef struct { - u8 unk0; + u8 countESND; u8 countWOBJ; u8 countLPAD; u8 countTOYS; @@ -192,7 +213,7 @@ typedef struct { void* dataNAME; // ptr NAME void* dataINFO; // ptr INFO void* dataJPTX; // ptr JPTX - void* dataTHER; // ptr THER + LevelTHER* dataTHER; // ptr THER void* dataLWIN; // ptr LWIN void* dataTPAD; // ptr TPAD void* dataLPAD; // ptr LPAD @@ -251,7 +272,7 @@ u8 levelGet_80346364(void); s32 level_80346370(s32 terra); void level_8034528C(void); u8 levelGet_80346468(void); -s32 levelDataGetTHER(void** data); +s32 levelDataGetTHER(LevelTHER** data); s32 levelDataGetLWIN(void** data); s32 levelDataGetTPAD(void** data); s32 levelDataGetCNTG(void** data); diff --git a/src/app/code_69BF0.h b/src/app/code_69BF0.h index b89b8a8..e066952 100644 --- a/src/app/code_69BF0.h +++ b/src/app/code_69BF0.h @@ -3,7 +3,23 @@ #include -void func_802E27A8(void*); +typedef struct { + Mtx4F unk0; + Vec3F unk40; + Vec3F unk4C; + s8 unk58; + u8 pad59[3]; + f32 unk5C; + f32 unk60; + s32 unk64; + f32 unk68; + f32 unk6C; + s8 unk70; + u8 pad71[3]; + s32 unk74; +} Unk802E27A8_Arg0; + +void func_802E27A8(Unk802E27A8_Arg0*); void func_802E344C(Unk80345464_Arg0*); #endif // APP_CODE_69BF0_H diff --git a/src/app/code_D4290.c b/src/app/code_D4290.c index f85b788..6e9e9f1 100644 --- a/src/app/code_D4290.c +++ b/src/app/code_D4290.c @@ -8,18 +8,6 @@ #include #include -// This is probably part of another struct but unsure which one it is -typedef struct { - s8 unk0; - f32 unk4; - f32 unk8; - s32 unkC; - f32 unk10; - f32 unk14; - s8 unk18; - s32 unk1C; -} WindRenderSPStruct; - // size: 0xA8 typedef struct { u16 unk0; @@ -60,23 +48,11 @@ static f32 func_8034DFC4(u8, f32); void func_8034CD60(void) { } -// wind_render has sp120/sp114 which are just assigned but never used -// this is probably related to WindRenderSPStruct assignments and will be resolved once -// the actual struct this is part of is resolved -#if defined(__GNUC__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Waddress" -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-but-set-variable" -#endif void wind_render(void) { s32 i; Unk8037F518* var_s1; Unk8037F510* temp_s0; - WindRenderSPStruct sp148; - Vec3F sp120; - Vec3F sp114; - Mtx4F spD4; + Unk802E27A8_Arg0 spD4; f32 temp_fs0; f32 var_fv1; Vec3F spC0; @@ -96,28 +72,24 @@ void wind_render(void) { return; } for (i = 0; i < D_8037F514; i++) { - // @fake to force correct s registers - if (&spA8) { } - if (&spC0) { } - if (&spB4) { } var_s1 = &D_8037F518[i]; temp_s0 = &D_8037F510[i]; uvMat4SetIdentity(&var_s1->unk4); - uvMat4SetIdentity(&spD4); - spD4.m[3][0] = temp_s0->unk0.f[0]; - spD4.m[3][1] = temp_s0->unk0.f[1]; - spD4.m[3][2] = temp_s0->unk0.f[2]; - sp148.unk0 = 0xB; - sp148.unk4 = 1.0f; - sp148.unkC = 0; - sp148.unk10 = temp_s0->unk4C; - sp148.unk14 = sp148.unk10; - sp148.unk18 = temp_s0->unk3C; - sp148.unk8 = uvSqrtF(SQ(temp_s0->unk40.x) + SQ(temp_s0->unk40.y) + SQ(temp_s0->unk40.z)) + 0.9f; - if (sp148.unk8 < 0.0f) { - sp148.unk8 = 0.0f; - } else if (sp148.unk8 > 1.0f) { - sp148.unk8 = 1.0f; + uvMat4SetIdentity(&spD4.unk0); + spD4.unk0.m[3][0] = temp_s0->unk0.f[0]; + spD4.unk0.m[3][1] = temp_s0->unk0.f[1]; + spD4.unk0.m[3][2] = temp_s0->unk0.f[2]; + spD4.unk58 = 0xB; + spD4.unk5C = 1.0f; + spD4.unk64 = 0; + spD4.unk68 = temp_s0->unk4C; + spD4.unk6C = spD4.unk68; + spD4.unk70 = temp_s0->unk3C; + spD4.unk60 = uvSqrtF(SQ(temp_s0->unk40.x) + SQ(temp_s0->unk40.y) + SQ(temp_s0->unk40.z)) + 0.9f; + if (spD4.unk60 < 0.0f) { + spD4.unk60 = 0.0f; + } else if (spD4.unk60 > 1.0f) { + spD4.unk60 = 1.0f; } s2 = &temp_s0->unkC; if (temp_s0->unk50 == 0) { @@ -130,9 +102,9 @@ void wind_render(void) { uvDobjPosm(var_s1->unk0, 0, &var_s1->unk4); uvDobjState(var_s1->unk0, 2U); uvDobjProps(var_s1->unk0, 3, temp_s0->unk4C, 0); - sp148.unk1C = 8; - sp114 = temp_s0->unk0; - sp120 = temp_s0->unkC; + spD4.unk74 = 8; + spD4.unk40 = temp_s0->unk0; + spD4.unk4C = temp_s0->unkC; } else if (temp_s0->unk50 == 1) { spB4.f[0] = s2->f[0] - temp_s0->unk0.f[0]; spB4.f[1] = s2->f[1] - temp_s0->unk0.f[1]; @@ -176,9 +148,9 @@ void wind_render(void) { var_fv1 = temp_fs0; } uvDobjProps(var_s1->unk0, 3, var_fv1, 0); - sp148.unk1C = 0xA; - sp114 = temp_s0->unk0; - sp120 = temp_s0->unkC; + spD4.unk74 = 0xA; + spD4.unk40 = temp_s0->unk0; + spD4.unk4C = temp_s0->unkC; } else if (temp_s0->unk50 == 2) { uvMat4RotateAxis(&var_s1->unk4, temp_s0->unk24.f[0] * 0.0174533f, 'z'); // almost DEG_TO_RAD(1) uvMat4RotateAxis(&var_s1->unk4, temp_s0->unk24.f[1] * 0.0174533f, 'x'); // almost DEG_TO_RAD(1) @@ -207,27 +179,22 @@ void wind_render(void) { var_fv1 = temp_s0->unk30.f[1]; } uvDobjProps(var_s1->unk0, 3, var_fv1, 0); - sp148.unk1C = 0xA; - sp114.f[0] = temp_s0->unk18.f[0]; - sp114.f[1] = temp_s0->unk18.f[1]; - sp114.f[2] = temp_s0->unk18.f[2]; - sp120.f[0] = temp_s0->unk30.f[0]; - sp120.f[1] = temp_s0->unk30.f[1]; - sp120.f[2] = temp_s0->unk30.f[2]; - sp148.unk14 = sp148.unk10 = uvSqrtF(SQ(temp_s0->unk30.x) + SQ(temp_s0->unk30.y) + SQ(temp_s0->unk30.z)) * 0.50; + spD4.unk74 = 0xA; + spD4.unk40.f[0] = temp_s0->unk18.f[0]; + spD4.unk40.f[1] = temp_s0->unk18.f[1]; + spD4.unk40.f[2] = temp_s0->unk18.f[2]; + spD4.unk4C.f[0] = temp_s0->unk30.f[0]; + spD4.unk4C.f[1] = temp_s0->unk30.f[1]; + spD4.unk4C.f[2] = temp_s0->unk30.f[2]; + spD4.unk6C = spD4.unk68 = uvSqrtF(SQ(temp_s0->unk30.x) + SQ(temp_s0->unk30.y) + SQ(temp_s0->unk30.z)) * 0.50; } else { _uvDebugPrintf("wind : unknown wind shape [%d]\n", temp_s0->unk50); return; } - // @fake to force stuff in this struct to be stored - if (&sp148) { } func_8034D6D4(temp_s0, var_s1); func_802E27A8(&spD4); } } -#if defined(__GNUC__) -#pragma GCC diagnostic pop -#endif void func_8034D4AC(void) { Unk8037F518* var_s0; diff --git a/src/app/level.c b/src/app/level.c index 45e3b77..7caf4d5 100644 --- a/src/app/level.c +++ b/src/app/level.c @@ -24,12 +24,6 @@ typedef struct { s32 unk0; } Unk8034F410; -typedef struct { - u8 unk0[7]; - u8 pad7; - u8 pad8[0x70]; -} Unk8030BDC8; - extern s32 D_8034F400; extern s32 D_8034F404; extern LevelObjects* D_8034F408; @@ -279,8 +273,8 @@ LevelObjects* levelLoadMapObjects(u8 mapIdx) { u32 size; // spBC u32 tag; u8* srcPtr; // spB4 - Unk8030BDC8 sp3C; - Unk8030BDC8* ptr; + Unk802E27A8_Arg0 sp3C; + LevelLEVL* ptr; LevelObjects* temp; u8 tmp8; @@ -297,7 +291,7 @@ LevelObjects* levelLoadMapObjects(u8 mapIdx) { while ((tag = uvFileReadBlock(idx, &size, (void**)&srcPtr, 1)) != 0) { switch (tag) { case 'ESND': // 0x45534E44 - for (i = 0; i < temp->unk0; i++) { + for (i = 0; i < temp->countESND; i++) { _uvMediaCopy(&sp3C, srcPtr, sizeof(sp3C)); srcPtr += sizeof(sp3C); func_802E27A8(&sp3C); @@ -322,46 +316,46 @@ LevelObjects* levelLoadMapObjects(u8 mapIdx) { _uvMediaCopy(temp->dataBNUS, srcPtr, size); break; case 'LEVL': // 0x4C45564C - ptr = (Unk8030BDC8*)srcPtr; - temp->unk0 = ptr->unk0[0]; - if (temp->unk0 >= 255) { - _uvAssertMsg("dst_level -> level . nenvsnds < NENV_SNDS", "level.c", 0x27F); + ptr = (LevelLEVL*)srcPtr; + temp->countESND = ptr->countESND; + if (temp->countESND >= 255) { + _uvAssertMsg("dst_level -> level . nenvsnds < NENV_SNDS", "level.c", 639); } - temp->countWOBJ = ptr->unk0[1]; + temp->countWOBJ = ptr->countWOBJ; if (temp->countWOBJ >= 16) { - _uvAssertMsg("dst_level -> level . nwobjs < LEVEL_NWOBJS", "level.c", 0x282); + _uvAssertMsg("dst_level -> level . nwobjs < LEVEL_NWOBJS", "level.c", 642); } if (temp->countWOBJ >= 17) { _uvDebugPrintf("level : too many wind objects defined in level [%d]\n", temp->countWOBJ); temp->countWOBJ = 0; } - temp->countLPAD = ptr->unk0[2]; + temp->countLPAD = ptr->countLPAD; if (temp->countLPAD >= 15) { _uvDebugPrintf("level : too many potential landing pads defined in level [%d]\n", temp->countLPAD); temp->countLPAD = 0; } - temp->countTOYS = ptr->unk0[3]; + temp->countTOYS = ptr->countTOYS; if (temp->countTOYS >= 17) { _uvDebugPrintf("level : too many toys in level [%d]\n", temp->countTOYS); temp->countTOYS = 0; } - temp->countTPTS = ptr->unk0[4]; + temp->countTPTS = ptr->countTPTS; if (temp->countTPTS >= 17) { _uvDebugPrintf("level : too many terra switch points in level [%d]\n", temp->countTPTS); temp->countTPTS = 0; } - temp->countAPTS = ptr->unk0[5]; + temp->countAPTS = ptr->countAPTS; if (temp->countAPTS >= 21) { _uvDebugPrintf("level : too many audio switch points in level [%d]\n", temp->countAPTS); temp->countAPTS = 0; } - temp->countBNUS = ptr->unk0[6]; + temp->countBNUS = ptr->countBNUS; if (temp->countBNUS >= 3) { _uvDebugPrintf("level : too many bonus objects level [%d]\n", temp->countBNUS); temp->countBNUS = 0; diff --git a/src/app/level_objects.c b/src/app/level_objects.c index 935acc5..f79dd95 100644 --- a/src/app/level_objects.c +++ b/src/app/level_objects.c @@ -77,7 +77,7 @@ void level_803449B0(void) { u8 sp88[0x28]; u8 sp60[0x28]; - func_803465F0(); + thermInit(); func_803232F0(); func_8034CD60(); func_802D22B0(); @@ -245,7 +245,7 @@ s32 level_80344FC8(s32 classIdx, s32 vehicle, s32 testIdx, u16* map, u16* arg4, break; } - func_803465F0(); + thermInit(); func_803232F0(); func_8034CD60(); func_802D22B0(); @@ -282,7 +282,7 @@ void level_8034528C(void) { sp1E = D_80362690->unk0[D_80362690->unk9C].unkC.unk2; D_8035079C = 1; wind_render(); - func_8034662C(); + therm_8034662C(); func_80316E40(); func_802E1278(); func_802EB598(); @@ -303,7 +303,7 @@ void level_8034528C(void) { void level_8034536C(void) { level_803453AC(); - func_80346B84(); + therm_80346B84(); func_8034D4AC(); func_8031776C(); func_802EB5E4(); @@ -336,7 +336,7 @@ s32 level_80345464(Unk80345464_Arg0* arg0, s32 arg1) { sp1E = D_80362690->unk0[D_80362690->unk9C].unkC.unk2; sp18 = 0; - func_8034695C(); + therm_8034695C(); func_8034D548(); func_802E15F0(); func_802CB3F8(); @@ -486,7 +486,7 @@ void level_80345A24(void) { func_802FAFF0(); } -s32 levelDataGetTHER(void** data) { +s32 levelDataGetTHER(LevelTHER** data) { *data = D_8035078C->dataTHER; return D_8035078C->comm.countTHER; } @@ -616,7 +616,7 @@ LevelCommObjects* levelLoadCommObj(u32 arg0) { dst->dataLSTP = mem_get(dst->comm.countLSTP * 0x24); dst->dataLWIN = mem_get(dst->comm.countLWIN * 0x54); dst->dataRNGS = mem_get(dst->comm.countRNGS * 0x84); - dst->dataTHER = mem_get(dst->comm.countTHER * 0x28); + dst->dataTHER = mem_get(dst->comm.countTHER * sizeof(LevelTHER)); dst->dataBALS = mem_get(dst->comm.countBALS * 0x68); dst->dataTARG = mem_get(dst->comm.countTARG * 0x20); dst->dataHPAD = mem_get(dst->comm.countHPAD * 0x40); @@ -626,7 +626,7 @@ LevelCommObjects* levelLoadCommObj(u32 arg0) { dst->dataCNTG = mem_get(dst->comm.countCNTG * 0x1C); dst->dataSDFM = mem_get(dst->comm.countSDFM * 0x4C); dst->dataHOPD = mem_get(dst->comm.countHOPD * 0x20); - dst->dataOBSV = (LevelOBSV*)mem_get(dst->comm.countOBSV * sizeof(LevelOBSV)); + dst->dataOBSV = mem_get(dst->comm.countOBSV * sizeof(LevelOBSV)); break; case 'THER': // 0x54484552 _uvMediaCopy(dst->dataTHER, data, size); diff --git a/src/app/thermals.c b/src/app/thermals.c index 2d26932..1439ff8 100644 --- a/src/app/thermals.c +++ b/src/app/thermals.c @@ -1,14 +1,228 @@ #include "common.h" +#include +#include +#include +#include "code_69BF0.h" +#include "code_9A960.h" +#include "hud.h" #include "thermals.h" -#pragma GLOBAL_ASM("asm/nonmatchings/app/thermals/func_803465F0.s") +#define THERM_ENABLE_DURATION (4 * 60) // 4 minutes in sec +#define THERM_WEAKEN_DURATION (10) +#define THERM_DISABLE_TIME (THERM_ENABLE_DURATION + THERM_WEAKEN_DURATION) -#pragma GLOBAL_ASM("asm/nonmatchings/app/thermals/func_8034662C.s") +s32 gThermShouldDisable = 0; // true when test disables thermals after THERM_ENABLE_DURATION -#pragma GLOBAL_ASM("asm/nonmatchings/app/thermals/func_8034695C.s") +static LevelTHER* gLevelTHER; +u8 gThermalCount; +Thermal gThermals[16]; +s8 gThermReady; -#pragma GLOBAL_ASM("asm/nonmatchings/app/thermals/func_80346B84.s") +// forward declarations +static void therm_80346E04(LevelTHER* therm, f32 x, f32 y, f32 z, f32 dist, Vec3F* dst); -#pragma GLOBAL_ASM("asm/nonmatchings/app/thermals/func_80346C08.s") +void thermInit(void) { + s32 i; + for (i = 0; i < ARRAY_COUNT(gThermals); i++) { + gThermals[i].unk0 = 0xFFFF; + } + gThermReady = 1; +} -#pragma GLOBAL_ASM("asm/nonmatchings/app/thermals/func_80346E04.s") +void therm_8034662C(void) { + Thermal* therm; + s32 pad; + Unk80362690_Unk0_UnkC* temp_v1_2; + LevelTHER* levlTher; + Unk802E27A8_Arg0 sp90; + f32 maxDim; + f32 ratio; + s32 i; + + if (D_80362690->unk0[D_80362690->unk9C].unkC.unk7B == 0) { + gThermalCount = levelDataGetTHER(&gLevelTHER); + if (gThermalCount > ARRAY_COUNT(gThermals)) { + _uvDebugPrintf("thermals : too many thermals defined in level [%d]\n", gThermalCount); + gThermalCount = 0; + return; + } + + if (gThermalCount != 0) { + uvLevelAppend(0x16); + + for (i = 0; i < gThermalCount; i++) { + levlTher = &gLevelTHER[i]; + therm = &gThermals[i]; + therm->unk0 = func_8021731C(); + uvDobjModel(therm->unk0, 0x101); + uvDobjState(therm->unk0, 2); + uvVec3Copy(&gThermals[i].pos, &levlTher->pos); + if (levlTher->height < levlTher->scale) { + maxDim = levlTher->scale; + } else { + maxDim = levlTher->height; + } + uvDobjProps(therm->unk0, 3, maxDim, 0); + therm->scale = levlTher->scale; + ratio = (f32)i / gThermalCount; + therm->height = 3.1415927f * ratio; + uvMat4SetIdentity(&sp90.unk0); + sp90.unk0.m[3][0] = 0.0f; + sp90.unk0.m[3][1] = 0.0f; + sp90.unk0.m[3][2] = 0.0f; + sp90.unk58 = 2; + sp90.unk5C = 1.0f; + sp90.unk64 = 0; + sp90.unk68 = maxDim; + sp90.unk6C = maxDim; + sp90.unk70 = (s8)levlTher->unk14; + sp90.unk60 = (levlTher->unk20 * 0.9f) + 0.9f; + sp90.unk74 = 10; + sp90.unk40.x = levlTher->pos.x; + sp90.unk40.y = levlTher->pos.y; + sp90.unk40.z = (f32)(levlTher->pos.z + (levlTher->height * 0.5)); + sp90.unk4C.x = levlTher->pos.x; + sp90.unk4C.y = levlTher->pos.y; + sp90.unk4C.z = (f32)(levlTher->pos.z - (levlTher->height * 0.5)); + func_802E27A8(&sp90); + } + gThermShouldDisable = 0; + temp_v1_2 = &D_80362690->unk0[D_80362690->unk9C].unkC; + if ((temp_v1_2->unk2 == 0) && (temp_v1_2->unk4 == 3) && (temp_v1_2->unk6 == 0)) { + gThermShouldDisable = 1; + } + } + } +} + +void therm_8034695C(void) { + f32 var_fs0; + Thermal* therm; + LevelTHER* levlTher; + Mtx4F sp74; + s32 i; + + var_fs0 = 1.0f; + // after 4 min, 10 sec, disable thermals, if the test calls for it + if ((D_8034F850 >= THERM_DISABLE_TIME) && (gThermalCount != 0) && gThermShouldDisable) { + therm_80346B84(); + gThermalCount = 0; + gThermReady = 0; + hudWarningText(0xF, 1.5f, 8.0f); + } + + for (i = 0; i < gThermalCount; i++) { + therm = &gThermals[i]; + levlTher = &gLevelTHER[i]; + // for the first 10 seconds after 4 minutes, reduce the scale of thermal, if test calls for it + if ((D_8034F850 >= THERM_ENABLE_DURATION) && (gThermalCount != 0) && gThermShouldDisable) { + var_fs0 = (f32)(1.0 - (f64)((D_8034F850 - THERM_ENABLE_DURATION) / THERM_WEAKEN_DURATION)); + } + therm->height += levlTher->unk20 * D_8034F854; + uvMat4SetIdentity(&sp74); + sp74.m[0][0] = levlTher->scale * var_fs0; + sp74.m[1][1] = levlTher->scale * var_fs0; + sp74.m[2][2] = levlTher->height; + uvMat4RotateAxis(&sp74, therm->height, 'z'); + sp74.m[3][0] = therm->pos.x; + sp74.m[3][1] = therm->pos.y; + sp74.m[3][2] = therm->pos.z; + if (therm->unk0 != 0xFFFF) { + uvDobjPosm(therm->unk0, 0, &sp74); + } + } +} + +void therm_80346B84(void) { + s32 i; + + for (i = 0; i < gThermalCount; i++) { + if (gThermals[i].unk0 != 0xFFFF) { + uvDobjModel(gThermals[i].unk0, 0xFFFF); + gThermals[i].unk0 = 0xFFFF; + } + } +} + +void therm_80346C08(f32 x, f32 y, f32 z, Vec3F* dst) { + f32 dz; + f32 dx; + f32 dy; + f32 dist; + LevelTHER* levlTher; + Thermal* therm; + Vec3F vec; + s32 i; + + dst->x = 0.0f; + dst->y = 0.0f; + dst->z = 0.0f; + + for (i = 0; i < gThermalCount; i++) { + therm = &gThermals[i]; + levlTher = &gLevelTHER[i]; + if (therm->unk0 == 0xFFFF) { + continue; + } + + dx = x - therm->pos.x; + dy = y - therm->pos.y; + dz = z - therm->pos.z; + dist = uvLength2D(dx, dy); + + if (levlTher->scale < dist) { + continue; + } + if (levlTher->height < dz) { + continue; + } + if (dz < 0.0f) { + continue; + } + + therm_80346E04(levlTher, dx, dy, dz, dist, &vec); + dst->x += vec.x; + dst->y += vec.y; + dst->z += vec.z; + + if (1) { } // fakematch + } +} + +void therm_80346E04(LevelTHER* therm, f32 x, f32 y, f32 z, f32 dist, Vec3F* dst) { + f32 temp_fv0; + f32 var_fa0; + f32 var_fv1; + + temp_fv0 = therm->scale * 0.5f; + if (dist > 1.0f) { + if (dist < temp_fv0) { + var_fa0 = temp_fv0 - dist; + } else { + var_fa0 = -(temp_fv0 - dist); + } + var_fv1 = 1.0f - ((2.0f * var_fa0) / therm->scale); + dst->x = therm->unk20 * var_fv1 * dist * (y / dist); + dst->y = -var_fv1 * therm->unk20 * dist * (x / dist); + } else { + dst->x = dst->y = 0.0f; + } + var_fv1 = uvSqrtF((therm->scale - dist) / therm->scale); + if (var_fv1 > 1.0f) { + var_fv1 = 1.0f; + } + if (var_fv1 < 0.0f) { + var_fv1 = 0.0f; + } + dst->z = therm->unk24 * var_fv1; + if (z < therm->unk18) { + var_fv1 = 1.0f - ((therm->unk18 - z) / therm->unk18); + } else if (therm->unk1C < z) { + var_fv1 = 1.0f - ((z - therm->unk1C) / (therm->height - therm->unk1C)); + } else { + var_fv1 = 1.0f; + } + dst->x *= var_fv1; + dst->y *= var_fv1; + dst->z *= var_fv1; +} diff --git a/src/app/thermals.h b/src/app/thermals.h index f9507bb..22d8eee 100644 --- a/src/app/thermals.h +++ b/src/app/thermals.h @@ -14,10 +14,12 @@ typedef struct { extern u8 gThermalCount; // count of gThermals extern Thermal gThermals[16]; // parsed thermal data, also parts copied to HUD +extern s8 gThermReady; -void func_803465F0(void); -void func_8034662C(void); -void func_8034695C(void); -void func_80346B84(void); +void thermInit(void); +void therm_8034662C(void); +void therm_8034695C(void); +void therm_80346B84(void); +void therm_80346C08(f32 x, f32 y, f32 z, Vec3F* dst); #endif // APP_THERMALS_H