summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAetias <aetias@outlook.com>2025-02-16 16:07:22 +0100
committerAetias <aetias@outlook.com>2025-02-16 16:07:22 +0100
commit83bdfdb8925d84d85b36ffbe69f256cc87da8116 (patch)
tree9ad569a2300e9d7e0d7f09f01bf9a2e7ba84e1ce
parentd057996378f1235c67d93014595e9fd929a4efb6 (diff)
PlayerControl: Decomp 68%
-rw-r--r--config/eur/arm9/overlays/ov000/symbols.txt4
-rw-r--r--config/eur/arm9/symbols.txt2
-rw-r--r--config/usa/arm9/overlays/ov000/symbols.txt6
-rw-r--r--config/usa/arm9/symbols.txt2
-rw-r--r--include/DTCM/UnkStruct_027e05f8.hpp2
-rw-r--r--include/DTCM/UnkStruct_027e0f64.hpp15
-rw-r--r--include/Player/PlayerBase.hpp2
-rw-r--r--include/Player/PlayerControl.hpp8
-rw-r--r--include/Player/TouchGesture.hpp3
-rw-r--r--libs/nds/include/nds/math.h3
-rw-r--r--src/00_Core/Player/PlayerControl.cpp439
11 files changed, 449 insertions, 37 deletions
diff --git a/config/eur/arm9/overlays/ov000/symbols.txt b/config/eur/arm9/overlays/ov000/symbols.txt
index 394c8faf..db19cea9 100644
--- a/config/eur/arm9/overlays/ov000/symbols.txt
+++ b/config/eur/arm9/overlays/ov000/symbols.txt
@@ -2184,7 +2184,7 @@ _ZN13PlayerControl18func_ov00_020aeef8Ev kind:function(arm,size=0x38) addr:0x20a
_ZN13PlayerControl18func_ov00_020aef30Ev kind:function(thumb,size=0x38) addr:0x20aef30
_ZN13PlayerControl9UpdateAimEv kind:function(thumb,size=0x94) addr:0x20aef68
_ZN13PlayerControl14GetFollowActorEv kind:function(arm,size=0x20) addr:0x20aeffc
-_ZN13PlayerControl18func_ov00_020af01cEPc kind:function(arm,size=0x28) addr:0x20af01c
+_ZN13PlayerControl18func_ov00_020af01cEP5Vec2b kind:function(arm,size=0x28) addr:0x20af01c
_ZN13PlayerControl9SetUnk_80Ev kind:function(arm,size=0xc) addr:0x20af044
_ZN13PlayerControl13StopFollowingEv kind:function(arm,size=0x1c) addr:0x20af050
_ZN13PlayerControl18func_ov00_020af06cEv kind:function(arm,size=0x22c) addr:0x20af06c
@@ -2212,7 +2212,7 @@ _ZN13PlayerControl18func_ov00_020b034cEv kind:function(arm,size=0xcc) addr:0x20b
_ZN13PlayerControl18func_ov00_020b0418Ev kind:function(arm,size=0x84) addr:0x20b0418
_ZN13PlayerControl18func_ov00_020b049cEP5Vec3pb kind:function(arm,size=0x14c) addr:0x20b049c
_ZN13PlayerControl18func_ov00_020b05e8EP5Vec3p kind:function(arm,size=0x190) addr:0x20b05e8
-_ZN13PlayerControl18func_ov00_020b0778EP5Vec3pji kind:function(arm,size=0x33c) addr:0x20b0778
+_ZN13PlayerControl18func_ov00_020b0778EP5Vec3pjPi kind:function(arm,size=0x33c) addr:0x20b0778
_ZN13PlayerControl16CheckNotTouchingEv kind:function(arm,size=0x1c) addr:0x20b0ab4
_ZN13PlayerControl18func_ov00_020b0ad0EP5Actor kind:function(arm,size=0x3c) addr:0x20b0ad0
_ZN13PlayerControl18func_ov00_020b0b0cEPsPiS1_Pb kind:function(arm,size=0x2dc) addr:0x20b0b0c
diff --git a/config/eur/arm9/symbols.txt b/config/eur/arm9/symbols.txt
index 58c20b43..b19d655b 100644
--- a/config/eur/arm9/symbols.txt
+++ b/config/eur/arm9/symbols.txt
@@ -56,7 +56,7 @@ func_020029fc kind:function(arm,size=0x1b0) addr:0x20029fc
func_02002bac kind:function(arm,size=0xc) addr:0x2002bac
func_02002bb8 kind:function(arm,size=0x3c) addr:0x2002bb8
func_02002bf4 kind:function(arm,size=0x20) addr:0x2002bf4
-SoftDivideMod kind:function(arm,size=0x20c) addr:0x2002c14
+_s32_div_f kind:function(arm,size=0x20c) addr:0x2002c14
SoftDivide kind:function(arm,size=0x1e4) addr:0x2002e20
_02002e28 kind:label(arm) addr:0x2002e28
func_0200301c kind:function(arm,size=0x544) addr:0x200301c
diff --git a/config/usa/arm9/overlays/ov000/symbols.txt b/config/usa/arm9/overlays/ov000/symbols.txt
index 96a0dcfe..31a2ea13 100644
--- a/config/usa/arm9/overlays/ov000/symbols.txt
+++ b/config/usa/arm9/overlays/ov000/symbols.txt
@@ -2179,12 +2179,12 @@ _ZN13LinkStateRoll8vfunc_20Ei kind:function(arm,size=0x180) addr:0x20aebb0
_ZN13LinkStateRoll8vfunc_24Ei kind:function(arm,size=0xc8) addr:0x20aed30
_ZN13LinkStateRoll18func_ov00_020aee58Est kind:function(arm,size=0x2c) addr:0x20aedf8
_ZN13LinkStateRoll18func_ov00_020aee84Ev kind:function(arm,size=0x28) addr:0x20aee24
-_ZN13PlayerControl18_ZN13PlayerControl18func_ov00_020aeeacEvEv kind:function(arm,size=0x4c) addr:0x20aee4c
+_ZN13PlayerControl18func_ov00_020aeeacEv kind:function(arm,size=0x4c) addr:0x20aee4c
_ZN13PlayerControl18func_ov00_020aeef8Ev kind:function(arm,size=0x38) addr:0x20aee98
_ZN13PlayerControl18func_ov00_020aef30Ev kind:function(thumb,size=0x38) addr:0x20aeed0
_ZN13PlayerControl9UpdateAimEv kind:function(thumb,size=0x94) addr:0x20aef08
_ZN13PlayerControl14GetFollowActorEv kind:function(arm,size=0x20) addr:0x20aef9c
-_ZN13PlayerControl18func_ov00_020af01cEPc kind:function(arm,size=0x28) addr:0x20aefbc
+_ZN13PlayerControl18func_ov00_020af01cEP5Vec2b kind:function(arm,size=0x28) addr:0x20aefbc
_ZN13PlayerControl9SetUnk_80Ev kind:function(arm,size=0xc) addr:0x20aefe4
_ZN13PlayerControl13StopFollowingEv kind:function(arm,size=0x1c) addr:0x20aeff0
_ZN13PlayerControl18func_ov00_020af06cEv kind:function(arm,size=0x22c) addr:0x20af00c
@@ -2212,7 +2212,7 @@ _ZN13PlayerControl18func_ov00_020b034cEv kind:function(arm,size=0xcc) addr:0x20b
_ZN13PlayerControl18func_ov00_020b0418Ev kind:function(arm,size=0x84) addr:0x20b03b8
_ZN13PlayerControl18func_ov00_020b049cEP5Vec3pb kind:function(arm,size=0x14c) addr:0x20b043c
_ZN13PlayerControl18func_ov00_020b05e8EP5Vec3p kind:function(arm,size=0x190) addr:0x20b0588
-_ZN13PlayerControl18func_ov00_020b0778EP5Vec3pji kind:function(arm,size=0x33c) addr:0x20b0718
+_ZN13PlayerControl18func_ov00_020b0778EP5Vec3pjPi kind:function(arm,size=0x33c) addr:0x20b0718
_ZN13PlayerControl16CheckNotTouchingEv kind:function(arm,size=0x1c) addr:0x20b0a54
_ZN13PlayerControl18func_ov00_020b0ad0EP5Actor kind:function(arm,size=0x3c) addr:0x20b0a70
_ZN13PlayerControl18func_ov00_020b0b0cEPsPiS1_Pb kind:function(arm,size=0x2dc) addr:0x20b0aac
diff --git a/config/usa/arm9/symbols.txt b/config/usa/arm9/symbols.txt
index 07dd55c6..61783c9d 100644
--- a/config/usa/arm9/symbols.txt
+++ b/config/usa/arm9/symbols.txt
@@ -56,7 +56,7 @@ func_020029fc kind:function(arm,size=0x1b0) addr:0x20029fc
func_02002bac kind:function(arm,size=0xc) addr:0x2002bac
func_02002bb8 kind:function(arm,size=0x3c) addr:0x2002bb8
func_02002bf4 kind:function(arm,size=0x20) addr:0x2002bf4
-SoftDivideMod kind:function(arm,size=0x20c) addr:0x2002c14
+_s32_div_f kind:function(arm,size=0x20c) addr:0x2002c14
SoftDivide kind:function(arm,size=0x1e4) addr:0x2002e20
_02002e28 kind:label(arm) addr:0x2002e28
func_0200301c kind:function(arm,size=0x544) addr:0x200301c
diff --git a/include/DTCM/UnkStruct_027e05f8.hpp b/include/DTCM/UnkStruct_027e05f8.hpp
index 7270ade1..a5bc24d6 100644
--- a/include/DTCM/UnkStruct_027e05f8.hpp
+++ b/include/DTCM/UnkStruct_027e05f8.hpp
@@ -5,7 +5,7 @@
struct UnkStruct_027e05f8 {
/* 0 */ u16 mUnk_0;
- /* 2 */ unk16 mUnk_2;
+ /* 2 */ u16 mUnk_2;
/* 4 */ unk16 mUnk_4;
/* 6 */
diff --git a/include/DTCM/UnkStruct_027e0f64.hpp b/include/DTCM/UnkStruct_027e0f64.hpp
new file mode 100644
index 00000000..33728a7e
--- /dev/null
+++ b/include/DTCM/UnkStruct_027e0f64.hpp
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "global.h"
+#include "types.h"
+
+struct UnkStruct_027e0f64 {
+ /* 0 */ DebugHierarchyBase *mUnk_0;
+ /* 4 */ void *mUnk_4;
+ /* 8 */ void *mUnk_8;
+ /* c */
+
+ unk32 func_ov000_0208b180();
+};
+
+extern UnkStruct_027e0f64 *data_027e0f64;
diff --git a/include/Player/PlayerBase.hpp b/include/Player/PlayerBase.hpp
index 354e1078..b08e71a4 100644
--- a/include/Player/PlayerBase.hpp
+++ b/include/Player/PlayerBase.hpp
@@ -64,4 +64,4 @@ public:
extern PlayerBase *gPlayer;
extern Vec3p gPlayerPos;
extern Vec3p gPlayerVel;
-extern s16 gPlayerAngle;
+extern u16 gPlayerAngle;
diff --git a/include/Player/PlayerControl.hpp b/include/Player/PlayerControl.hpp
index c11ad0ce..962a3fe0 100644
--- a/include/Player/PlayerControl.hpp
+++ b/include/Player/PlayerControl.hpp
@@ -11,7 +11,7 @@
#include "Player/TouchControl.hpp"
#include "Player/TouchGesture.hpp"
-typedef u16 TouchEdge;
+typedef s16 TouchEdge;
enum TouchEdge_ {
TouchEdge_Right = 0,
TouchEdge_Left = 1,
@@ -52,7 +52,7 @@ public:
/* 7f */ bool mUnk_7f;
/* 80 */ bool mUnk_80;
/* 81 */ bool mFollowing;
- /* 82 */ unk8 mUnk_82;
+ /* 82 */ bool mUnk_82;
/* 83 */ bool mUnk_83;
/* 84 */ ActorRef mFollowRef;
/* 8c */ ActorRef mNextFollowRef;
@@ -106,13 +106,13 @@ public:
s32 func_ov00_020b0418();
bool func_ov00_020b049c(Vec3p *param1, bool param2);
bool func_ov00_020b05e8(Vec3p *param1);
- bool func_ov00_020b0778(Vec3p *param1, u32 param2, unk32 param3);
+ bool func_ov00_020b0778(Vec3p *param1, u32 param2, unk32 *param3);
bool CheckNotTouching();
bool func_ov00_020b0ad0(Actor *actor);
bool func_ov00_020b0b0c(s16 *pAngle, ItemFlag *pEquipId, unk32 *pCardinal, bool *pFast);
bool func_ov00_020b0de8(Vec3p *param1);
bool func_ov00_020b0e54(Vec3p *param1, Vec3p *param2);
- bool func_ov00_020b0f88(Vec3p *param1, unk32 param2, Vec3p *param3);
+ bool func_ov00_020b0f88(Vec3p *param1, unk32 scale, Vec3p *param3);
bool func_ov00_020b1058(Vec3p *param1, unk32 param2, Vec3p *param3, Vec3p *param4);
bool IsUntouchedNow();
bool IsNotUntouchedNow();
diff --git a/include/Player/TouchGesture.hpp b/include/Player/TouchGesture.hpp
index 5009525e..0ed897a7 100644
--- a/include/Player/TouchGesture.hpp
+++ b/include/Player/TouchGesture.hpp
@@ -22,7 +22,8 @@ public:
class TouchGesture : public TouchGestureBase {
public:
/* 00 (base) */
- /* 05 */ unk8 mUnk_05[7];
+ /* 05 */ unk8 mUnk_05[3];
+ /* 08 */ s32 mUnk_08;
/* 0c */ u16 mIndex;
/* 0e */ unk16 mUnk_0e;
/* 10 */ u16 mUnk_10[GESTURE_BUFFER_LENGTH];
diff --git a/libs/nds/include/nds/math.h b/libs/nds/include/nds/math.h
index aaaf52fe..6cb1d524 100644
--- a/libs/nds/include/nds/math.h
+++ b/libs/nds/include/nds/math.h
@@ -8,6 +8,8 @@
extern "C" {
#endif
+#define ABS(x) ((x) < 0 ? -(x) : (x))
+
// Q20.12 fixed point number
typedef s32 q20;
// Q4.12 fixed point number
@@ -19,6 +21,7 @@ typedef s16 q4;
#define FLOAT_TO_Q19(n) ((s32) (((n) * 8192 + 1)))
#define ROUND_Q20(n) (((s32) (n) + 0x800) >> 12)
#define MUL_Q20(a, b) (q20)((((s64) (a)) * ((s64) (b)) + 0x800) >> 12)
+#define DIV_Q20(a, b) (((a) << 12) / (b))
#define DEG_TO_ANG(n) ((n) * 0x10000 / 360)
#define SIN(n) (gSinCosTable[2 * ((n) >> 4)])
diff --git a/src/00_Core/Player/PlayerControl.cpp b/src/00_Core/Player/PlayerControl.cpp
index 0cf8d23a..b2ccb8a5 100644
--- a/src/00_Core/Player/PlayerControl.cpp
+++ b/src/00_Core/Player/PlayerControl.cpp
@@ -6,6 +6,7 @@
#include "DTCM/UnkStruct_027e0c68.hpp"
#include "DTCM/UnkStruct_027e0d38.hpp"
#include "DTCM/UnkStruct_027e0e2c.hpp"
+#include "DTCM/UnkStruct_027e0f64.hpp"
#include "DTCM/UnkStruct_027e0ffc.hpp"
#include "DTCM/UnkStruct_027e103c.hpp"
#include "Item/ItemManager.hpp"
@@ -540,13 +541,12 @@ ARM void PlayerControl::func_ov00_020affec(Vec3p *param1, s32 y, s32 param3, Vec
}
extern u32 data_ov000_020ee198;
-extern u32 data_027e0f64;
ARM void PlayerControl::func_ov00_020b014c(Vec3p *param1) {
if ((data_ov000_020ee198 & 1) == 0) {
data_ov000_020ee198 |= 1;
}
- if (*(s32 *) (*(s32 *) (data_027e0f64 + 0x4) + 0x15c) == 0x16) {
+ if (*(s32 *) ((s32) data_027e0f64->mUnk_4 + 0x15c) == 0x16) {
return;
}
if (!this->func_ov00_020aeef8()) {
@@ -598,7 +598,7 @@ ARM s16 PlayerControl::GetTouchAngle() {
return mUnk_ac;
}
-const q20 data_ov000_020e6144 = FLOAT_TO_Q20(80.0);
+static q20 data_ov000_020e6144 = FLOAT_TO_Q20(80.0);
ARM u32 PlayerControl::func_ov00_020b034c() {
if (mTouchDuration >= 0 && this->func_ov00_020af2d4(1, true)) {
@@ -621,23 +621,416 @@ ARM u32 PlayerControl::func_ov00_020b034c() {
return 0;
}
-s32 PlayerControl::func_ov00_020b0418() {}
-bool PlayerControl::func_ov00_020b049c(Vec3p *param1, bool param2) {}
-bool PlayerControl::func_ov00_020b05e8(Vec3p *param1) {}
-bool PlayerControl::func_ov00_020b0778(Vec3p *param1, u32 param2, unk32 param3) {}
-bool PlayerControl::CheckNotTouching() {}
-bool PlayerControl::func_ov00_020b0ad0(Actor *actor) {}
-bool PlayerControl::func_ov00_020b0b0c(s16 *pAngle, ItemFlag *pEquipId, unk32 *pCardinal, bool *pFast) {}
-bool PlayerControl::func_ov00_020b0de8(Vec3p *param1) {}
-bool PlayerControl::func_ov00_020b0e54(Vec3p *param1, Vec3p *param2) {}
-bool PlayerControl::func_ov00_020b0f88(Vec3p *param1, unk32 param2, Vec3p *param3) {}
-bool PlayerControl::func_ov00_020b1058(Vec3p *param1, unk32 param2, Vec3p *param3, Vec3p *param4) {}
-bool PlayerControl::IsUntouchedNow() {}
-bool PlayerControl::IsNotUntouchedNow() {}
-bool PlayerControl::func_ov00_020b1248(unk32 *param1) {}
-bool PlayerControl::func_ov00_020b129c() {}
-bool PlayerControl::func_ov00_020b12d0(s16 *pAngle) {}
-bool PlayerControl::IsNotTouching() {}
-bool PlayerControl::IsTouchingFast() {}
-bool PlayerControl::IsTappedNow() {}
-bool PlayerControl::func_ov00_020b13c4() {}
+ARM s32 PlayerControl::func_ov00_020b0418() {}
+
+extern "C" void func_0202d95c(Vec3p *param1, q20 param2);
+ARM bool PlayerControl::func_ov00_020b049c(Vec3p *param1, bool param2) {
+ if (this->CheckUntouchedNow(1) && mTouchDuration >= 0 && mTouchDuration < 21) {
+ this->ApplyTouchWorld(param1, FLOAT_TO_Q20(0.25));
+ Vec3p_Sub(param1, &gPlayerPos, param1);
+ q20 length = Vec3p_Length(param1);
+ if (length >= FLOAT_TO_Q20(1.25)) {
+ return true;
+ }
+ if (param2) {
+ if (length < FLOAT_TO_Q20(0.25)) {
+ *param1 = gVec3p_ZERO;
+ param1->x += MUL_Q20(SIN(gPlayerAngle), FLOAT_TO_Q20(1.25));
+ param1->z += MUL_Q20(COS(gPlayerAngle), FLOAT_TO_Q20(1.25));
+ } else {
+ func_0202d95c(param1, FLOAT_TO_Q20(1.25));
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+ARM bool PlayerControl::func_ov00_020b05e8(Vec3p *param1) {
+ if (this->CheckUntouchedNow(1) && mTouchDuration >= 0 && mTouchDuration < 21) {
+ Vec3p *playerPos = &gPlayerPos;
+
+ Vec3p VStack_1c;
+ this->ApplyTouchWorld(&VStack_1c, FLOAT_TO_Q20(0.2));
+ VStack_1c.y = gPlayerPos.y;
+
+ q20 distance = Vec3p_Distance(&VStack_1c, playerPos);
+ if (distance > FLOAT_TO_Q20(1.25)) {
+ return false;
+ }
+
+ if (distance < FLOAT_TO_Q20(0.25)) {
+ VStack_1c.y = playerPos->y;
+ VStack_1c.x = playerPos->x + MUL_Q20(SIN(gPlayerAngle), FLOAT_TO_Q20(0.25));
+ VStack_1c.z = playerPos->z + MUL_Q20(COS(gPlayerAngle), FLOAT_TO_Q20(0.25));
+ }
+
+ Vec2b VStack_20;
+ MapManager::func_ov00_02083a1c(&VStack_20, gMapManager, &VStack_1c);
+ VStack_1c.x += (gMapManager->func_ov00_02083c24(VStack_20.x) - VStack_1c.x) / 2;
+ VStack_1c.z += (gMapManager->func_ov00_02083c50(VStack_20.y) - VStack_1c.z) / 2;
+ Vec3p_Sub(&VStack_1c, playerPos, param1);
+ return true;
+ }
+ return false;
+}
+
+extern "C" bool func_01ffe468(unk32 param1, Vec3p *param2, s32 *param3, s32 *param4, bool param5);
+
+ARM bool PlayerControl::func_ov00_020b0778(Vec3p *param1, u32 angle, unk32 *param3) {
+ static const sThreshold = FLOAT_TO_Q20(0.0059);
+
+ *param3 = 0;
+ Vec3p local_2c = *param1;
+
+ s32 unk2X, unk2Y;
+ unk32 uVar2 = data_027e0f64->func_ov000_0208b180();
+ if (!func_01ffe468(uVar2, &local_2c, &unk2X, &unk2Y, false)) {
+ return false;
+ }
+
+ q20 dirX = MUL_Q20(SIN(angle), 2 * sThreshold);
+ q20 dirY = MUL_Q20(COS(angle), 2 * sThreshold);
+
+ q20 x = mTouchX - unk2X;
+ q20 y = mTouchY - unk2Y;
+
+ q20 unk1X, unk1Y;
+ bool bVar1, bVar8, bVar7;
+ if (this->CheckTouchedNow(1)) {
+ unk1X = dirX - sThreshold;
+ if (unk1X <= x) {
+ unk1X = dirX + sThreshold;
+ }
+ if (unk1X == x) {
+ unk1Y = dirY - sThreshold;
+ if (unk1Y <= y) {
+ unk1Y = dirY + sThreshold;
+ if (unk1Y == y) {
+ *param3 = FLOAT_TO_Q20(1.0);
+ return true;
+ }
+ }
+ }
+ unk1X = -sThreshold - dirX;
+ if (unk1X <= x) {
+ unk1X = sThreshold - dirX;
+ }
+ if (unk1X == x) {
+ unk1Y = -sThreshold - dirY;
+ if (unk1Y == y) {
+ unk1Y = sThreshold - dirY;
+ if (y == unk1Y) {
+ *param3 = -FLOAT_TO_Q20(1.0);
+ return true;
+ }
+ }
+ }
+ if (ABS(dirX) - sThreshold <= x && x <= ABS(dirX) + sThreshold) {
+ if (ABS(dirY) - sThreshold <= y && y <= ABS(dirY) + sThreshold) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ unk1Y = this->CheckTouching(1);
+ if (unk1Y) {
+ bVar1 = dirX < 0;
+ if (dirX < 0) {
+ unk1Y = dirX + sThreshold;
+ bVar1 = x - unk1Y < 0;
+ }
+ if (bVar1 == (dirX < 0 && (x < unk1Y))) {
+ bVar1 = dirX == 0;
+ unk1X = dirX;
+ if (0 < dirX) {
+ unk1Y = dirX - sThreshold;
+ unk1X = x - unk1Y;
+ bVar1 = x == unk1Y;
+ }
+ if (bVar1 || unk1X < 0 != (0 < dirX && (x < unk1Y))) {
+ bVar7 = dirY < 0;
+ bVar1 = bVar7;
+ if (bVar7) {
+ unk1Y = dirY + sThreshold;
+ bVar1 = y - unk1Y < 0;
+ }
+ if (bVar1 == (bVar7 && (y < unk1Y))) {
+ bVar1 = dirY == 0;
+ unk1X = dirY;
+ if (0 < dirY) {
+ unk1Y = dirY - sThreshold;
+ unk1X = y - unk1Y;
+ bVar1 = y == unk1Y;
+ }
+ if (bVar1 || unk1X < 0 != (0 < dirY && (y < unk1Y))) {
+ if ((0 < dirX && dirX < sThreshold - x) || (0 > dirX && dirX > -sThreshold - x) ||
+ (0 < dirY && dirY < sThreshold - y) || (0 > dirY && dirY > -sThreshold - y))
+ {
+ *param3 = -FLOAT_TO_Q20(1.0);
+ }
+ return true;
+ }
+ }
+ }
+ }
+ *param3 = FLOAT_TO_Q20(1.0);
+ return true;
+ }
+
+ if (this->CheckUntouchedNow(1)) {
+ unk2X = mTouchPrevX - unk2X;
+ unk2Y = mTouchPrevY - unk2Y;
+ if (sThreshold < ABS(dirX) && ABS(dirX) < ABS(unk2X) + sThreshold) {
+ return false;
+ }
+ if (sThreshold < ABS(dirY) && ABS(dirY) < ABS(unk2Y) + sThreshold) {
+ return false;
+ }
+ }
+ return true;
+}
+
+ARM bool PlayerControl::CheckNotTouching() {
+ return !this->CheckTouching(1);
+}
+
+ARM bool PlayerControl::func_ov00_020b0ad0(Actor *actor) {
+ if (actor != NULL && actor->mRef.id == mLastFollowRef.id) {
+ return mTouchDuration >= 15 && mTouchDuration < 30;
+ }
+ return false;
+}
+
+ARM bool PlayerControl::func_ov00_020b0b0c(s16 *pAngle, ItemFlag *pEquipId, unk32 *pCardinal, bool *pFast) {
+ if (mUsingEquipItem && gItemManager->func_ov00_020ad790(1)) {
+ ItemFlag equipId = gItemManager->GetEquippedItem();
+ *pEquipId = equipId;
+ data_027e103c->func_ov000_020cf330();
+ return *pEquipId != ItemFlag_None;
+ }
+
+ *pEquipId = ItemFlag_OshusSword;
+ if (this->func_ov00_020b1248(pCardinal)) {
+ *pEquipId = ItemFlag_OshusSword;
+ return true;
+ }
+
+ if ((this->CheckUntouchedNow(1) && mTouchDuration >= 0 && mTouchDuration < 21) ||
+ (this->CheckTouchFast(1) && mTouchSlowDuration > 21))
+ {
+ s32 dx = mTouchLastX - mTouchFastX;
+ s32 dy = mTouchLastY - mTouchFastY;
+ Vec3p local_20;
+ local_20.x = INT_TO_Q20(dx);
+ local_20.y = 0;
+ local_20.z = INT_TO_Q20(dy);
+ q20 length = Vec3p_Length(&local_20);
+ if (length < FLOAT_TO_Q20(10.0)) {
+ return false;
+ }
+ if (mUnk_82 && length < FLOAT_TO_Q20(20.0)) {
+ return false;
+ }
+
+ *pEquipId = ItemFlag_OshusSword;
+ *pAngle = mTouchAngle + ((mTouchFastAngle - mTouchAngle) << 16 >> 16) / 2;
+
+ if (mTouchSpeed > FLOAT_TO_Q20(0.5)) {
+ q20 touchMoveAngle = Atan2(mTouchSpeedX, mTouchSpeedY);
+ if (pFast != NULL) {
+ *pFast = true;
+ }
+ *pCardinal = ((mTouchFastAngle - mTouchAngle) * 0x10000 >> 0x10) ? 2 : 1;
+ return true;
+ }
+
+ s32 unkAngle = Atan2(local_20.x, local_20.z);
+
+ Vec3p VStack_2c;
+ VStack_2c.x = INT_TO_Q20(mTouchFastX);
+ VStack_2c.y = INT_TO_Q20(mTouchFastY);
+ VStack_2c.z = 0;
+
+ Vec3p VStack_38;
+ VStack_38.x = INT_TO_Q20(mTouchLastX);
+ VStack_38.y = INT_TO_Q20(mTouchLastY);
+ VStack_38.z = 0;
+
+ s32 unkAngle2 = (unkAngle - *pAngle) * 0x10000 >> 0x10;
+ Vec3p_Sub(&VStack_38, &VStack_2c, &VStack_38);
+ if (mTouchDist > FLOAT_TO_Q20(10.0)) {
+ if (unkAngle2 >= 0x6000 || unkAngle2 <= -0x6000) {
+ *pCardinal = 0;
+ } else if (unkAngle2 >= 0x2000) {
+ *pCardinal = 1;
+ } else if (unkAngle2 >= -0x2000) {
+ *pCardinal = 3;
+ } else {
+ *pCardinal = 4;
+ }
+ return true;
+ }
+ *pCardinal = 0;
+ *pAngle = mTouchFastAngle;
+ return true;
+ }
+
+ return false;
+}
+
+ARM bool PlayerControl::func_ov00_020b0de8(Vec3p *param1) {
+ if (!this->CheckTouching(1)) {
+ return false;
+ }
+ q20 z = (mTouchLastY - 96) * 0xaa00;
+ param1->x = (mTouchLastX - 128) * 0xaa;
+ param1->y = 0;
+ param1->z = z / 6;
+ return true;
+}
+
+ARM bool PlayerControl::func_ov00_020b0e54(Vec3p *param1, Vec3p *param2) {
+ Vec3p local_20;
+ if (mTouchDuration >= 16 && this->func_ov00_020b0de8(&local_20)) {
+ this->ApplyTouchWorld(param1, FLOAT_TO_Q20(0.5));
+ q20 length = Vec3p_Length(&local_20);
+ if (length > FLOAT_TO_Q20(4.0)) {
+ local_20.x = DIV_Q20(local_20.x * 4, length);
+ local_20.z = DIV_Q20(local_20.z * 4, length);
+ }
+ mAim = local_20;
+ *param2 = local_20;
+ return true;
+ }
+
+ if (mTouchDuration >= 0 && this->func_ov00_020af2d4(1, true)) {
+ if (mTouchDist > FLOAT_TO_Q20(24.0)) {
+ this->ApplyTouchWorld(param1, FLOAT_TO_Q20(0.5));
+ } else {
+ *param1 = gPlayerPos;
+ }
+ return true;
+ }
+
+ return false;
+}
+
+extern "C" bool func_0202b2e8(Vec3p *param1, Vec3p *param2, q20 param3);
+ARM bool PlayerControl::func_ov00_020b0f88(Vec3p *param1, unk32 scale, Vec3p *param3) {
+ Vec3p local_20;
+ if (this->func_ov00_020b0de8(&local_20)) {
+ this->ApplyTouchWorld(param1, scale);
+ q20 length = Vec3p_Length(&local_20);
+ if (length > FLOAT_TO_Q20(4.0)) {
+ local_20.x = DIV_Q20(local_20.x * 4, length);
+ local_20.z = DIV_Q20(local_20.z * 4, length);
+ }
+ q20 touchSpeed = CoSqrt((mTouchDiffX * mTouchDiffX + mTouchDiffY * mTouchDiffY + 4) * 0x10);
+ func_0202b2e8(param3, &local_20, touchSpeed);
+ mAim = local_20;
+ return true;
+ }
+ return false;
+}
+
+ARM bool PlayerControl::func_ov00_020b1058(Vec3p *param1, unk32 param2, Vec3p *param3, Vec3p *param4) {
+ Vec3p local_24;
+ if (this->func_ov00_020b0de8(&local_24)) {
+ this->ApplyTouchWorld(param1, param2);
+ if (param4 != NULL) {
+ Vec3p local_30;
+ Vec3p_Sub(param4, &gPlayerPos, &local_30);
+ local_30.x = MUL_Q20(local_30.x, FLOAT_TO_Q20(0.5));
+ local_30.y = MUL_Q20(local_30.y, FLOAT_TO_Q20(0.5));
+ local_30.z = MUL_Q20(local_30.z, FLOAT_TO_Q20(0.5));
+ func_0202b2e8(&local_30, &local_24, FLOAT_TO_Q20(2.5));
+ local_24 = local_30;
+ }
+ q20 length = Vec3p_Length(&local_24);
+ if (length > FLOAT_TO_Q20(4.0)) {
+ local_24.x = DIV_Q20(local_24.x * 4, length);
+ local_24.z = DIV_Q20(local_24.z * 4, length);
+ }
+ q20 touchSpeed = CoSqrt((mTouchDiffX * mTouchDiffX + mTouchDiffY * mTouchDiffY + 4) * 0x10);
+ func_0202b2e8(param3, &local_24, touchSpeed);
+ mAim = *param3;
+ return true;
+ }
+ return false;
+}
+
+ARM bool PlayerControl::IsUntouchedNow() {
+ return this->CheckUntouchedNow(7) && data_027e103c->mUnk_1c == 0;
+}
+
+ARM bool PlayerControl::IsNotUntouchedNow() {
+ if (!this->CheckUntouchedNow(7)) {
+ return (data_027e05f8.mUnk_2 & 3) != 0;
+ }
+ return true;
+}
+
+ARM bool PlayerControl::func_ov00_020b1248(unk32 *param1) {
+ if (*this->mTouchGesture != NULL && (*this->mTouchGesture)->mUnk_4) {
+ *param1 = (*this->mTouchGesture)->mUnk_08 == 0 ? 5 : 6;
+ (*this->mTouchGesture)->ResetTouchHistory();
+ return true;
+ }
+ return false;
+}
+
+ARM bool PlayerControl::func_ov00_020b129c() {
+ return mTouchDuration < 2 || mTouchDuration > 10 || mTouchDuration != mTimeSinceTouch;
+}
+
+ARM bool PlayerControl::func_ov00_020b12d0(s16 *pAngle) {
+ if (!this->func_ov00_020af2d4(1, true)) {
+ return false;
+ }
+ if (mTouchSlowDuration <= 15 && this->func_ov000_020b7d6c() && mTouchEdge == mTouchLastEdge) {
+ *pAngle = mTouchAngle;
+ return true;
+ }
+ return false;
+}
+
+ARM bool PlayerControl::IsNotTouching() {
+ return !mTouch;
+}
+
+extern u32 data_ov000_020eec9c[];
+extern "C" void func_ov000_020d77e4(u32 *param1, u32 param2);
+ARM bool PlayerControl::IsTouchingFast() {
+ if (this->CheckTouchFast(1)) {
+ func_ov000_020d77e4(data_ov000_020eec9c, 0x17);
+ return true;
+ }
+ return false;
+}
+
+ARM bool PlayerControl::IsTappedNow() {
+ return mTouchDuration < 10 && this->func_ov00_020af2d4(1, true) && this->CheckUntouchedNow(1);
+}
+
+ARM bool PlayerControl::func_ov00_020b13c4() {
+ if (!this->CheckTouching(1)) {
+ return false;
+ }
+ func_01ff992c(data_ov000_020e6144);
+ q20 touchDist = mTouchDist;
+ s32 iVar2 = mTouchDuration;
+ if (mTouchFastTime > 0 && mTouchFastTime < iVar2) {
+ iVar2 = (iVar2 - mTouchFastTime) << 16 >> 16;
+ }
+ if (touchDist >= FLOAT_TO_Q20(80.0)) {
+ return iVar2 >= 2;
+ }
+ if (mTouchDist < FLOAT_TO_Q20(16.0)) {
+ return false;
+ }
+ q20 uVar4 = CoReciprocal(FLOAT_TO_Q20(64.0));
+ q20 unk1 = MUL_Q20(mTouchDist - FLOAT_TO_Q20(16.0), uVar4);
+ return iVar2 >= MUL_Q20(FLOAT_TO_Q20(1.0) - unk1, FLOAT_TO_Q20(0.0058)) + 2;
+}