summaryrefslogtreecommitdiff
path: root/src/code
diff options
context:
space:
mode:
Diffstat (limited to 'src/code')
-rw-r--r--src/code/audio/audio_load.c2
-rw-r--r--src/code/graph.c2
-rw-r--r--src/code/z_actor.c2
-rw-r--r--src/code/z_bgcheck.c4
-rw-r--r--src/code/z_demo.c1
-rw-r--r--src/code/z_eff_blure.c3
-rw-r--r--src/code/z_en_hy_code.c4
-rw-r--r--src/code/z_lights.c2
-rw-r--r--src/code/z_quake.c2
-rw-r--r--src/code/z_scene.c6
-rw-r--r--src/code/z_scene_proc.c2
-rw-r--r--src/code/z_skelanime.c20
-rw-r--r--src/code/z_sram_NES.c2
-rw-r--r--src/code/z_sub_s.c289
14 files changed, 305 insertions, 36 deletions
diff --git a/src/code/audio/audio_load.c b/src/code/audio/audio_load.c
index b63f8192b..8faf565ea 100644
--- a/src/code/audio/audio_load.c
+++ b/src/code/audio/audio_load.c
@@ -459,6 +459,7 @@ s32 AudioLoad_SyncLoadInstrument(s32 fontId, s32 instId, s32 drumId) {
if (instrument->normalRangeHi != 0x7F) {
return AudioLoad_SyncLoadSample(instrument->highNotesSound.sample, fontId);
}
+ // TODO: is this missing return UB?
} else if (instId == 0x7F) {
Drum* drum = AudioPlayback_GetDrum(fontId, drumId);
@@ -468,6 +469,7 @@ s32 AudioLoad_SyncLoadInstrument(s32 fontId, s32 instId, s32 drumId) {
AudioLoad_SyncLoadSample(drum->sound.sample, fontId);
return 0;
}
+ // TODO: is this missing return UB?
}
void AudioLoad_AsyncLoad(s32 tableType, s32 id, s32 nChunks, s32 retData, OSMesgQueue* retQueue) {
diff --git a/src/code/graph.c b/src/code/graph.c
index 04ab72057..28327c35f 100644
--- a/src/code/graph.c
+++ b/src/code/graph.c
@@ -12,7 +12,7 @@ GfxMasterList* gGfxMasterDL;
CfbInfo sGraphCfbInfos[3];
OSTime sGraphTaskStartTime;
-void* Graph_FaultClient(void) {
+void Graph_FaultClient(void) {
FaultDrawer_DrawText(30, 100, "ShowFrameBuffer PAGE 0/1");
osViSwapBuffer(SysCfb_GetFbPtr(0));
osViSetMode(D_801FBB88);
diff --git a/src/code/z_actor.c b/src/code/z_actor.c
index 93eeeddc7..24bc91a17 100644
--- a/src/code/z_actor.c
+++ b/src/code/z_actor.c
@@ -240,7 +240,7 @@ void ActorShadow_DrawFeet(Actor* actor, Lights* mapper, GlobalContext* globalCtx
}
actor->shape.unk_17 &= ~spB8;
- if (!mapper->l.l) {} // POSSIBLE FAKE MATCH
+ if ((uintptr_t)mapper->l.l) {} // POSSIBLE FAKE MATCH
}
}
diff --git a/src/code/z_bgcheck.c b/src/code/z_bgcheck.c
index b2891de90..028f68011 100644
--- a/src/code/z_bgcheck.c
+++ b/src/code/z_bgcheck.c
@@ -4441,11 +4441,13 @@ s32 WaterBox_GetSurfaceImpl(GlobalContext* globalCtx, CollisionContext* colCtx,
return false;
}
+// boolean
s32 WaterBox_GetSurface1(GlobalContext* globalCtx, CollisionContext* colCtx, f32 x, f32 z, f32* ySurface,
WaterBox** outWaterBox) {
- WaterBox_GetSurface1_2(globalCtx, colCtx, x, z, ySurface, outWaterBox);
+ return WaterBox_GetSurface1_2(globalCtx, colCtx, x, z, ySurface, outWaterBox);
}
+// boolean
s32 WaterBox_GetSurface1_2(GlobalContext* globalCtx, CollisionContext* colCtx, f32 x, f32 z, f32* ySurface,
WaterBox** outWaterBox) {
s32 bgId;
diff --git a/src/code/z_demo.c b/src/code/z_demo.c
index 0af7dfb4d..762be4538 100644
--- a/src/code/z_demo.c
+++ b/src/code/z_demo.c
@@ -1418,6 +1418,7 @@ void Cutscene_ProcessCommands(GlobalContext* globalCtx, CutsceneContext* csCtx,
}
}
#else
+void Cutscene_ProcessCommands(GlobalContext* globalCtx, CutsceneContext* csCtx, u8* cutscenePtr);
#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/Cutscene_ProcessCommands.s")
#endif
diff --git a/src/code/z_eff_blure.c b/src/code/z_eff_blure.c
index b17799aff..6ab70f1ef 100644
--- a/src/code/z_eff_blure.c
+++ b/src/code/z_eff_blure.c
@@ -309,6 +309,7 @@ void EffectBlure_GetComputedValues(EffectBlure* this, s32 index, f32 ratio, Vec3
Vec3s sp30;
f32 mode4Param;
EffectBlureElement* elem = &this->elements[index];
+ Vec3s* unusedPtr = &sp30; // Optimized out but seems necessary to match stack usage
switch (this->calcMode) {
case 1:
@@ -367,8 +368,6 @@ void EffectBlure_GetComputedValues(EffectBlure* this, s32 index, f32 ratio, Vec3
break;
}
- sp30 = sp30; // Optimized out but seems necessary to match stack usage
-
if (this->flags & 0x10) {
color1->r = color1->g = color1->b = color1->a = 255;
color2->r = color2->g = color2->b = color2->a = 255;
diff --git a/src/code/z_en_hy_code.c b/src/code/z_en_hy_code.c
index 6b16cc91c..28c177068 100644
--- a/src/code/z_en_hy_code.c
+++ b/src/code/z_en_hy_code.c
@@ -37,9 +37,9 @@ static AnimationInfoS sAnimations[] = {
s8 gEnHyBodyParts[] = { -1, 1, 12, 13, 14, 9, 10, 11, 0, 6, 7, 8, 3, 4, 5, 2 };
-s8 gEnHyBodyPartsIndex[] = { 0, 0, 0, 0, 3, 4, 0, 6, 7, 0, 9, 10, 0, 12, 13 };
+s8 gEnHyParentBodyParts[] = { 0, 0, 0, 0, 3, 4, 0, 6, 7, 0, 9, 10, 0, 12, 13 };
-u8 gEnHyShadowSize[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+u8 gEnHyShadowSizes[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
s32 EnHy_ChangeAnim(SkelAnime* skelAnime, s16 animIndex) {
s16 frameCount;
diff --git a/src/code/z_lights.c b/src/code/z_lights.c
index 2b0db8ad4..5d47b4153 100644
--- a/src/code/z_lights.c
+++ b/src/code/z_lights.c
@@ -216,7 +216,7 @@ void Lights_BindAll(Lights* lights, LightNode* listHead, Vec3f* refPos, GlobalCo
}
}
-LightNode* Lights_FindBufSlot() {
+LightNode* Lights_FindBufSlot(void) {
LightNode* ret;
if (sLightsBuffer.numOccupied >= LIGHTS_BUFFER_SIZE) {
diff --git a/src/code/z_quake.c b/src/code/z_quake.c
index ee4fa3a6d..d57dc8e54 100644
--- a/src/code/z_quake.c
+++ b/src/code/z_quake.c
@@ -638,7 +638,7 @@ void Distortion_Update(void) {
sDistortionContext.countdown = 2;
player = GET_PLAYER(globalCtx);
- if (&player->actor != NULL) {
+ if (player != NULL) {
Actor_GetWorldPosShapeRot(&playerPosRot, &player->actor);
}
diff --git a/src/code/z_scene.c b/src/code/z_scene.c
index 8a9bdd4e7..b03990702 100644
--- a/src/code/z_scene.c
+++ b/src/code/z_scene.c
@@ -341,7 +341,7 @@ void Scene_HeaderCmdEnvLightSettings(GlobalContext* globalCtx, SceneCmd* cmd) {
* Loads different texture files for each region of the world.
* These later are stored in segment 0x06, and used in maps.
*/
-s32 Scene_LoadAreaTextures(GlobalContext* globalCtx, s32 fileIndex) {
+void Scene_LoadAreaTextures(GlobalContext* globalCtx, s32 fileIndex) {
static RomFile sceneTextureFiles[9] = {
{ 0, 0 }, // Default
{ SEGMENT_ROM_START(scene_texture_01), SEGMENT_ROM_END(scene_texture_01) },
@@ -358,10 +358,8 @@ s32 Scene_LoadAreaTextures(GlobalContext* globalCtx, s32 fileIndex) {
if (size != 0) {
globalCtx->roomCtx.unk74 = THA_AllocEndAlign16(&globalCtx->state.heap, size);
- return DmaMgr_SendRequest0(globalCtx->roomCtx.unk74, vromStart, size);
+ DmaMgr_SendRequest0(globalCtx->roomCtx.unk74, vromStart, size);
}
-
- // UB: Undefined behaviour to not have a return statement here, but it breaks matching to add one.
}
// SceneTableEntry Header Command 0x11: Skybox Settings
diff --git a/src/code/z_scene_proc.c b/src/code/z_scene_proc.c
index f7f71a2dd..8f369008f 100644
--- a/src/code/z_scene_proc.c
+++ b/src/code/z_scene_proc.c
@@ -234,7 +234,7 @@ f32 Scene_LagrangeInterp(s32 n, f32 x[], f32 fx[], f32 xp) {
s32 i;
s32 j;
- for (i = 0, weightsPtr = weights, xPtr1 = x, fxPtr = fx, weightsPtr = weightsPtr; i < n; i++) {
+ for (i = 0, xPtr1 = x, fxPtr = fx, weightsPtr = weights; i < n; i++) {
for (xVal = *xPtr1, m = 1.0f, j = 0, xPtr2 = x; j < n; j++) {
if (j != i) {
m *= xVal - (*xPtr2);
diff --git a/src/code/z_skelanime.c b/src/code/z_skelanime.c
index 8ad36c891..6563eecfc 100644
--- a/src/code/z_skelanime.c
+++ b/src/code/z_skelanime.c
@@ -1238,9 +1238,9 @@ void SkelAnime_InitLink(GlobalContext* globalCtx, SkelAnime* skelAnime, FlexSkel
*/
void LinkAnimation_SetUpdateFunction(SkelAnime* skelAnime) {
if (skelAnime->mode <= ANIMMODE_LOOP_INTERP) {
- skelAnime->update = LinkAnimation_Loop;
+ skelAnime->update.link = LinkAnimation_Loop;
} else {
- skelAnime->update = LinkAnimation_Once;
+ skelAnime->update.link = LinkAnimation_Once;
}
skelAnime->morphWeight = 0.0f;
}
@@ -1250,7 +1250,7 @@ void LinkAnimation_SetUpdateFunction(SkelAnime* skelAnime) {
* finishes.
*/
s32 LinkAnimation_Update(GlobalContext* globalCtx, SkelAnime* skelAnime) {
- return skelAnime->update(globalCtx, skelAnime);
+ return skelAnime->update.link(globalCtx, skelAnime);
}
/**
@@ -1355,7 +1355,7 @@ void LinkAnimation_Change(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAn
SkelAnime_CopyFrameTable(skelAnime, skelAnime->morphTable, skelAnime->jointTable);
morphFrames = -morphFrames;
} else {
- skelAnime->update = LinkAnimation_Morph;
+ skelAnime->update.link = LinkAnimation_Morph;
AnimationContext_SetLoadFrame(globalCtx, animation, (s32)startFrame, skelAnime->limbCount,
skelAnime->morphTable);
}
@@ -1599,11 +1599,11 @@ void SkelAnime_InitSkin(GameState* gameState, SkelAnime* skelAnime, SkeletonHead
*/
void SkelAnime_SetUpdate(SkelAnime* skelAnime) {
if (skelAnime->mode <= ANIMMODE_LOOP_INTERP) {
- skelAnime->update = SkelAnime_LoopFull;
+ skelAnime->update.normal = SkelAnime_LoopFull;
} else if (skelAnime->mode <= ANIMMODE_ONCE_INTERP) {
- skelAnime->update = SkelAnime_Once;
+ skelAnime->update.normal = SkelAnime_Once;
} else {
- skelAnime->update = SkelAnime_LoopPartial;
+ skelAnime->update.normal = SkelAnime_LoopPartial;
}
}
@@ -1612,7 +1612,7 @@ void SkelAnime_SetUpdate(SkelAnime* skelAnime) {
* finishes.
*/
s32 SkelAnime_Update(SkelAnime* skelAnime) {
- return skelAnime->update(skelAnime);
+ return skelAnime->update.normal(skelAnime);
}
/**
@@ -1774,10 +1774,10 @@ void Animation_ChangeImpl(SkelAnime* skelAnime, AnimationHeader* animation, f32
morphFrames = -morphFrames;
} else {
if (taper != ANIMTAPER_NONE) {
- skelAnime->update = SkelAnime_MorphTaper;
+ skelAnime->update.normal = SkelAnime_MorphTaper;
skelAnime->taper = taper;
} else {
- skelAnime->update = SkelAnime_Morph;
+ skelAnime->update.normal = SkelAnime_Morph;
}
SkelAnime_GetFrameData(animation, startFrame, skelAnime->limbCount, skelAnime->morphTable);
}
diff --git a/src/code/z_sram_NES.c b/src/code/z_sram_NES.c
index 63c3a1571..05078382b 100644
--- a/src/code/z_sram_NES.c
+++ b/src/code/z_sram_NES.c
@@ -1494,7 +1494,7 @@ void func_80146DF8(SramContext* sramCtx) {
}
void Sram_InitSram(GameState* gameState, SramContext* sramCtx) {
- if (&gSaveContext.save) {}
+ if (gSaveContext.save.entranceIndex) {} // Required to match
func_801A3D98(gSaveContext.options.audioSetting);
}
diff --git a/src/code/z_sub_s.c b/src/code/z_sub_s.c
index c36365d48..b51de4897 100644
--- a/src/code/z_sub_s.c
+++ b/src/code/z_sub_s.c
@@ -10,7 +10,7 @@ s16 sPathDayFlags[] = { 0x40, 0x20, 0x10, 8, 4, 2, 1, 0 };
#include "code/sub_s/sub_s.c"
-Vec3f D_801C5DB0 = { 1.0f, 1.0f, 1.0f };
+Vec3f gOneVec3f = { 1.0f, 1.0f, 1.0f };
s32 D_801C5DBC[] = { 0, 1 }; // Unused
@@ -158,7 +158,15 @@ Gfx* SubS_DrawTransformFlex(GlobalContext* globalCtx, void** skeleton, Vec3s* jo
return gfx;
}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013AD6C.s")
+s32 SubS_InCsMode(GlobalContext* globalCtx) {
+ s32 inCsMode = false;
+
+ if (Play_InCsMode(globalCtx)) {
+ inCsMode = true;
+ }
+
+ return inCsMode;
+}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013AD9C.s")
@@ -333,13 +341,189 @@ s32 SubS_CopyPointFromPathCheckBounds(Path* path, s32 pointIndex, Vec3f* dst) {
return true;
}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013C964.s")
+//! TODO: Needs docs with func_800B8500
+s32 func_8013C964(Actor* actor, GlobalContext* globalCtx, f32 xzRange, f32 yRange, s32 itemId, s32 type) {
+ s32 ret = false;
+ s16 x;
+ s16 y;
+ f32 xzDistToPlayerTemp;
+
+ Actor_GetScreenPos(globalCtx, actor, &x, &y);
+
+ switch (type) {
+ case 1:
+ yRange = fabsf(actor->playerHeightRel) + 1.0f;
+ xzRange = actor->xzDistToPlayer + 1.0f;
+ ret = Actor_PickUp(actor, globalCtx, itemId, xzRange, yRange);
+ break;
+ case 2:
+ if ((fabsf(actor->playerHeightRel) <= yRange) && (actor->xzDistToPlayer <= xzRange)) {
+ ret = func_800B8500(actor, globalCtx, xzRange, yRange, itemId);
+ }
+ break;
+ case 3:
+ //! @bug: Both x and y conditionals are always true, || should be an &&
+ if (((x >= 0) || (x < SCREEN_WIDTH)) && ((y >= 0) || (y < SCREEN_HEIGHT))) {
+ ret = func_800B8500(actor, globalCtx, xzRange, yRange, itemId);
+ }
+ break;
+ case 4:
+ yRange = fabsf(actor->playerHeightRel) + 1.0f;
+ xzRange = actor->xzDistToPlayer + 1.0f;
+ xzDistToPlayerTemp = actor->xzDistToPlayer;
+ actor->xzDistToPlayer = 0.0f;
+ actor->flags |= 0x10000;
+ ret = func_800B8500(actor, globalCtx, xzRange, yRange, itemId);
+ actor->xzDistToPlayer = xzDistToPlayerTemp;
+ break;
+ case 5:
+ //! @bug: Both x and y conditionals are always true, || should be an &&
+ if (((x >= 0) || (x < SCREEN_WIDTH)) && ((y >= 0) || (y < SCREEN_HEIGHT)) &&
+ (fabsf(actor->playerHeightRel) <= yRange) && (actor->xzDistToPlayer <= xzRange) && actor->isTargeted) {
+ actor->flags |= 0x10000;
+ ret = func_800B8500(actor, globalCtx, xzRange, yRange, itemId);
+ }
+ break;
+ case 6:
+ //! @bug: Both x and y conditionals are always true, || should be an &&
+ if (((x >= 0) || (x < SCREEN_WIDTH)) && ((y >= 0) || (y < SCREEN_HEIGHT)) &&
+ (fabsf(actor->playerHeightRel) <= yRange) && (actor->xzDistToPlayer <= xzRange)) {
+ actor->flags |= 0x10000;
+ ret = func_800B8500(actor, globalCtx, xzRange, yRange, itemId);
+ }
+ break;
+ }
+ return ret;
+}
+
+const u8 sShadowMaps[4][12][12] = {
+ {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ },
+ {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
+ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
+ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ },
+ {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
+ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
+ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
+ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ },
+ {
+ { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 },
+ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
+ { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
+ { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
+ { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
+ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 },
+ },
+};
+
+void SubS_FillShadowTex(s32 startCol, s32 startRow, u8* tex, s32 size) {
+ s32 i;
+ s32 j;
+ s32 start;
+
+ for (i = 0; i < 12; i++) {
+ start = ((startRow + i) * 64) + startCol - 390;
+ for (j = 0; j < 12; j++) {
+ if (sShadowMaps[size][i][j] != 0) {
+ if ((start + j >= 0) && (start + j < SUBS_SHADOW_TEX_SIZE)) {
+ tex[start + j] = 255;
+ }
+ }
+ }
+ }
+}
+
+void SubS_GenShadowTex(Vec3f bodyPartsPos[], Vec3f* worldPos, u8* tex, f32 tween, u8 bodyPartsNum, u8 sizes[],
+ s8 parentBodyParts[]) {
+ Vec3f pos;
+ Vec3f startVec;
+ s32 i;
+ s32 parentBodyPart;
+ Vec3f* bodyPartPos;
+ s32 startCol;
+ s32 startRow;
+
+ for (i = 0; i < bodyPartsNum; i++) {
+ if (parentBodyParts[i] >= 0) {
+ parentBodyPart = parentBodyParts[i];
+ bodyPartPos = &bodyPartsPos[i];
+
+ pos.x = (bodyPartsPos[parentBodyPart].x - bodyPartPos->x) * tween + (bodyPartPos->x - worldPos->x);
+ pos.y = (bodyPartsPos[parentBodyPart].y - bodyPartPos->y) * tween + (bodyPartPos->y - worldPos->y);
+ pos.z = (bodyPartsPos[parentBodyPart].z - bodyPartPos->z) * tween + (bodyPartPos->z - worldPos->z);
+ } else {
+ bodyPartPos = &bodyPartsPos[i];
+
+ pos.x = bodyPartPos->x - worldPos->x;
+ pos.y = bodyPartPos->y - worldPos->y;
+ pos.z = bodyPartPos->z - worldPos->z;
+ }
+
+ Matrix_MultiplyVector3fByState(&pos, &startVec);
+ startCol = 64.0f + startVec.x;
+ startRow = 64.0f - startVec.z;
+ SubS_FillShadowTex(startCol >> 1, startRow >> 1, tex, sizes[i]);
+ }
+}
+
+void SubS_DrawShadowTex(Actor* actor, GameState* gameState, u8* tex) {
+ s32 pad;
+ GraphicsContext* gfxCtx = gameState->gfxCtx;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013CC2C.s")
+ OPEN_DISPS(gfxCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013CD64.s")
+ func_8012C28C(gfxCtx);
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 0, 100);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 0);
+ Matrix_InsertTranslation(actor->world.pos.x, 0.0f, actor->world.pos.z, MTXMODE_NEW);
+ Matrix_Scale(0.6f, 1.0f, 0.6f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gShadowDL);
+ gDPLoadTextureBlock(POLY_OPA_DISP++, tex, G_IM_FMT_I, G_IM_SIZ_8b, SUBS_SHADOW_TEX_WIDTH, SUBS_SHADOW_TEX_HEIGHT, 0,
+ G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD);
+ gSPDisplayList(POLY_OPA_DISP++, gShadowVtxDL);
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013CF04.s")
+ CLOSE_DISPS(gfxCtx);
+}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013D0E0.s")
@@ -688,9 +872,58 @@ s32 SubS_FillCutscenesList(Actor* actor, s16 cutscenes[], s16 numCutscenes) {
return i;
}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E4B0.s")
+/**
+ * Computes a plane based on a point on the plane, a unit vector and two angles
+ *
+ * @param[in] point a point on the plane
+ * @param[in] unitVec the unit vector rotated that becomes the plane's normal
+ * @param[in] rot the angles to rotate with, uses just the x and y components
+ * @param[out] plane the computed plane
+ *
+ * Notes:
+ * The unit input vector is expected to already be normalized (only uses are with the z unit vector)
+ *
+ */
+void SubS_ConstructPlane(Vec3f* point, Vec3f* unitVec, Vec3s* rot, Plane* plane) {
+ f32 sin;
+ f32 cos;
+ f32 temp;
+ f32 unitVecZ;
+ f32 normY;
+ f32 unitVecYX;
+
+ sin = Math_SinS(-rot->x);
+ cos = Math_CosS(-rot->x);
+ unitVecZ = unitVec->z;
+ unitVecYX = unitVec->y;
+
+ // Apply a rotation by -x about the X axis
+ temp = (unitVecZ * cos) - (unitVecYX * sin);
+ normY = (unitVecZ * sin) + (unitVecYX * cos);
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E5CC.s")
+ sin = Math_SinS(rot->y);
+ cos = Math_CosS(rot->y);
+ unitVecYX = unitVec->x;
+ plane->normal.y = normY;
+
+ // Apply a rotation by y about the Y axis
+ plane->normal.z = (temp * cos) - (unitVecYX * sin);
+ plane->normal.x = (temp * sin) + (unitVecYX * cos);
+
+ plane->originDist = -((point->x * plane->normal.x) + (plane->normal.y * point->y) + (plane->normal.z * point->z));
+}
+
+s32 SubS_LineSegVsPlane(Vec3f* point, Vec3s* rot, Vec3f* unitVec, Vec3f* linePointA, Vec3f* linePointB,
+ Vec3f* intersect) {
+ s32 lineSegVsPlane;
+ Plane plane;
+
+ SubS_ConstructPlane(point, unitVec, rot, &plane);
+ lineSegVsPlane = Math3D_LineSegVsPlane(plane.normal.x, plane.normal.y, plane.normal.z, plane.originDist, linePointA,
+ linePointB, intersect, false);
+
+ return lineSegVsPlane ? true : false;
+}
/**
* Finds the first actor instance of a specified Id and category verified with a custom callback.
@@ -714,10 +947,44 @@ Actor* SubS_FindActorCustom(GlobalContext* globalCtx, Actor* actor, Actor* actor
return actorIter;
}
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E748.s")
+//! TODO: Needs docs with func_800B8500
+s32 func_8013E748(Actor* actor, GlobalContext* globalCtx, f32 xzRange, f32 yRange, s32 exchangeItemId, void* data,
+ func_8013E748_VerifyFunc verifyFunc) {
+ s32 ret = false;
+
+ if ((verifyFunc == NULL) || ((verifyFunc != NULL) && verifyFunc(globalCtx, actor, data))) {
+ ret = func_800B8500(actor, globalCtx, xzRange, yRange, exchangeItemId);
+ }
+ return ret;
+}
+
+s32 SubS_ActorAndPlayerFaceEachOther(GlobalContext* globalCtx, Actor* actor, void* data) {
+ Player* player = GET_PLAYER(globalCtx);
+ Vec3s* yawTols = (Vec3s*)data;
+ s16 playerYaw = ABS(BINANG_SUB(Actor_YawBetweenActors(&player->actor, actor), player->actor.shape.rot.y));
+ s16 actorYaw = ABS(BINANG_SUB(actor->yawTowardsPlayer, actor->shape.rot.y));
+ s32 areFacing = false;
+ s32 actorYawTol = ABS(yawTols->y);
+ s32 playerYawTol;
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E7C0.s")
+ if (actorYaw < (s16)actorYawTol) {
+ playerYawTol = ABS(yawTols->x);
+ if (playerYaw < (s16)playerYawTol) {
+ areFacing = true;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E8F8.s")
+ return areFacing;
+}
+
+//! TODO: Needs docs with func_800B8500
+s32 func_8013E8F8(Actor* actor, GlobalContext* globalCtx, f32 xzRange, f32 yRange, s32 exhangeItemId, s16 playerYawTol,
+ s16 actorYawTol) {
+ Vec3s yawTols;
+
+ yawTols.x = playerYawTol;
+ yawTols.y = actorYawTol;
+ return func_8013E748(actor, globalCtx, xzRange, yRange, exhangeItemId, &yawTols, SubS_ActorAndPlayerFaceEachOther);
+}
#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E950.s")