diff --git a/CMakeLists.txt b/CMakeLists.txt index a775dc2e..54d4b76b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -350,7 +350,6 @@ add_library(lego1 SHARED LEGO1/lego/legoomni/src/entity/legoactor.cpp LEGO1/lego/legoomni/src/entity/legoactorpresenter.cpp LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp - LEGO1/lego/legoomni/src/entity/legocarraceactor.cpp LEGO1/lego/legoomni/src/entity/legoentity.cpp LEGO1/lego/legoomni/src/entity/legoentitypresenter.cpp LEGO1/lego/legoomni/src/entity/legojetski.cpp @@ -375,8 +374,9 @@ add_library(lego1 SHARED LEGO1/lego/legoomni/src/race/jetskirace.cpp LEGO1/lego/legoomni/src/race/legorace.cpp LEGO1/lego/legoomni/src/race/legoraceactor.cpp - LEGO1/lego/legoomni/src/race/legoracers.cpp LEGO1/lego/legoomni/src/race/legoracemap.cpp + LEGO1/lego/legoomni/src/race/legoracers.cpp + LEGO1/lego/legoomni/src/race/legoracespecial.cpp LEGO1/lego/legoomni/src/race/raceskel.cpp LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp LEGO1/lego/legoomni/src/video/legoflctexturepresenter.cpp diff --git a/LEGO1/lego/legoomni/include/legojetskiraceactor.h b/LEGO1/lego/legoomni/include/legojetskiraceactor.h index c844a186..219ed51f 100644 --- a/LEGO1/lego/legoomni/include/legojetskiraceactor.h +++ b/LEGO1/lego/legoomni/include/legojetskiraceactor.h @@ -1,7 +1,7 @@ #ifndef LEGOJETSKIRACEACTOR_H #define LEGOJETSKIRACEACTOR_H -#include "legocarraceactor.h" +#include "legoracespecial.h" // VTABLE: LEGO1 0x100da208 LegoCarRaceActor // VTABLE: LEGO1 0x100da228 LegoRaceActor @@ -32,9 +32,9 @@ class LegoJetskiRaceActor : public virtual LegoCarRaceActor { float p_f1, float p_f2, Vector3& p_v3 - ) override; // vtable+0x6c - void VTable0x70(float p_float) override; // vtable+0x70 - void VTable0x1c() override; // vtable+0x1c + ) override; // vtable+0x6c + void VTable0x70(float p_float) override; // vtable+0x70 + MxS32 VTable0x1c(undefined4 p_param1, LegoEdge* p_edge) override; // vtable+0x1c // SYNTHETIC: LEGO1 0x10081d50 // LegoJetskiRaceActor::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/legonavcontroller.h b/LEGO1/lego/legoomni/include/legonavcontroller.h index 8cd891dc..216b7b89 100644 --- a/LEGO1/lego/legoomni/include/legonavcontroller.h +++ b/LEGO1/lego/legoomni/include/legonavcontroller.h @@ -13,6 +13,7 @@ class Vector3; // LegoMouseController // VTABLE: LEGO1 0x100d85b8 +// VTABLE: BETA10 0x101bcc80 // SIZE 0x70 class LegoNavController : public MxCore { public: @@ -22,6 +23,7 @@ class LegoNavController : public MxCore { MxLong Notify(MxParam& p_param) override; // vtable+0x04 // FUNCTION: LEGO1 0x10054b80 + // FUNCTION: BETA10 0x1009e5f0 const char* ClassName() const override // vtable+0x0c { // STRING: LEGO1 0x100f66d8 @@ -77,7 +79,9 @@ class LegoNavController : public MxCore { static MxS32 GetNumLocations(); static LegoLocation* GetLocation(MxU32 p_location); + // FUNCTION: BETA10 0x100b0f40 void SetLinearVel(MxFloat p_linearVel) { m_linearVel = p_linearVel; } + MxFloat GetLinearVel() { return m_linearVel; } MxFloat GetRotationalVel() { return m_rotationalVel; } MxFloat GetMaxLinearVel() { return m_maxLinearVel; } diff --git a/LEGO1/lego/legoomni/include/legopathactor.h b/LEGO1/lego/legoomni/include/legopathactor.h index 5110c8ee..242d46b6 100644 --- a/LEGO1/lego/legoomni/include/legopathactor.h +++ b/LEGO1/lego/legoomni/include/legopathactor.h @@ -59,7 +59,7 @@ class LegoPathActor : public LegoActor { virtual MxBool GetUserNavFlag() { return m_userNavFlag; } // vtable+0x7c virtual MxResult VTable0x80( - Vector3& p_point1, + const Vector3& p_point1, Vector3& p_point2, Vector3& p_point3, Vector3& p_point4 @@ -165,7 +165,7 @@ class LegoPathActor : public LegoActor { LegoUnknown100db7f4* m_destEdge; // 0xe0 MxFloat m_unk0xe4; // 0xe4 MxBool m_collideBox; // 0xe8 - undefined m_unk0xe9; // 0xe9 + MxBool m_unk0xe9; // 0xe9 MxBool m_userNavFlag; // 0xea MxMatrix m_unk0xec; // 0xec LegoPathEdgeContainer* m_grec; // 0x134 diff --git a/LEGO1/lego/legoomni/include/legopathcontroller.h b/LEGO1/lego/legoomni/include/legopathcontroller.h index 3722df2b..ad0b5791 100644 --- a/LEGO1/lego/legoomni/include/legopathcontroller.h +++ b/LEGO1/lego/legoomni/include/legopathcontroller.h @@ -60,7 +60,7 @@ class LegoPathController : public MxCore { } LegoPathController* m_controller; // 0x00 - LegoEdge* m_edge; // 0x04 + LegoUnknown100db7f4* m_edge; // 0x04 }; LegoPathController(); @@ -121,6 +121,16 @@ class LegoPathController : public MxCore { static MxResult Init(); static MxResult Reset(); + // FUNCTION: BETA10 0x100cf580 + static LegoUnknown100db7f4* GetControlEdgeA(MxS32 p_index) { return g_ctrlEdgesA[p_index].m_edge; } + + // FUNCTION: BETA10 0x100cf5b0 + static LegoPathBoundary* GetControlBoundaryA(MxS32 p_index) { return g_ctrlBoundariesA[p_index].m_boundary; } + + // These two are an educated guess because BETA10 does not have the g_ctrl.*B globals + static LegoUnknown100db7f4* GetControlEdgeB(MxS32 p_index) { return g_ctrlEdgesB[p_index].m_edge; } + static LegoPathBoundary* GetControlBoundaryB(MxS32 p_index) { return g_ctrlBoundariesB[p_index].m_boundary; } + private: void FUN_10046970(); MxResult Read(LegoStorage* p_storage); @@ -140,6 +150,15 @@ class LegoPathController : public MxCore { MxU16 m_numT; // 0x1e LegoPathCtrlEdgeSet m_pfsE; // 0x20 LegoPathActorSet m_actors; // 0x30 + + // Names verified by BETA10 + static CtrlBoundary* g_ctrlBoundariesA; + static CtrlEdge* g_ctrlEdgesA; + + static const char* g_unk0x100f42f0[]; + static const char* g_unk0x100f4330[]; + static CtrlBoundary* g_ctrlBoundariesB; + static CtrlEdge* g_ctrlEdgesB; }; // clang-format off diff --git a/LEGO1/lego/legoomni/include/legoracers.h b/LEGO1/lego/legoomni/include/legoracers.h index d20de8a7..7e207ef8 100644 --- a/LEGO1/lego/legoomni/include/legoracers.h +++ b/LEGO1/lego/legoomni/include/legoracers.h @@ -1,8 +1,8 @@ #ifndef LEGORACERS_H #define LEGORACERS_H -#include "legocarraceactor.h" #include "legoracemap.h" +#include "legoracespecial.h" #define LEGORACECAR_UNKNOWN_0 0 #define LEGORACECAR_UNKNOWN_1 1 diff --git a/LEGO1/lego/legoomni/include/legocarraceactor.h b/LEGO1/lego/legoomni/include/legoracespecial.h similarity index 95% rename from LEGO1/lego/legoomni/include/legocarraceactor.h rename to LEGO1/lego/legoomni/include/legoracespecial.h index e1d41dce..3db9838f 100644 --- a/LEGO1/lego/legoomni/include/legocarraceactor.h +++ b/LEGO1/lego/legoomni/include/legoracespecial.h @@ -64,7 +64,7 @@ class LegoCarRaceActor : public virtual LegoRaceActor { // FUNCTION: LEGO1 0x10012c00 virtual float FUN_10012c00() { return m_unk0x18; } - virtual void VTable0x1c(); // vtable+0x1c + virtual MxS32 VTable0x1c(undefined4 p_param1, LegoEdge* p_edge); // vtable+0x1c // SYNTHETIC: LEGO1 0x10012c30 // LegoCarRaceActor::`vbase destructor' @@ -86,6 +86,8 @@ class LegoCarRaceActor : public virtual LegoRaceActor { // Could be the current timestamp for time-based movement MxFloat m_unk0x1c; // 0x1c + + static MxFloat g_unk0x100f7aec; }; // GLOBAL: LEGO1 0x100da0b0 diff --git a/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp b/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp index 6bbae1fa..4eebe624 100644 --- a/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp +++ b/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp @@ -40,7 +40,6 @@ #include "legoanimpresenter.h" #include "legocarbuild.h" #include "legocarbuildpresenter.h" -#include "legocarraceactor.h" #include "legoentity.h" #include "legoentitypresenter.h" #include "legoflctexturepresenter.h" @@ -58,6 +57,7 @@ #include "legopathpresenter.h" #include "legophonemepresenter.h" #include "legoracers.h" +#include "legoracespecial.h" #include "legotexturepresenter.h" #include "legoworld.h" #include "legoworldpresenter.h" diff --git a/LEGO1/lego/legoomni/src/common/misc.cpp b/LEGO1/lego/legoomni/src/common/misc.cpp index 901810d0..05dcf678 100644 --- a/LEGO1/lego/legoomni/src/common/misc.cpp +++ b/LEGO1/lego/legoomni/src/common/misc.cpp @@ -61,8 +61,10 @@ LegoAnimationManager* AnimationManager() } // FUNCTION: LEGO1 0x10015780 +// FUNCTION: BETA10 0x100e49b8 LegoNavController* NavController() { + assert(LegoOmni::GetInstance()); return LegoOmni::GetInstance()->GetNavController(); } diff --git a/LEGO1/lego/legoomni/src/entity/legocarraceactor.cpp b/LEGO1/lego/legoomni/src/entity/legocarraceactor.cpp deleted file mode 100644 index 3dd009da..00000000 --- a/LEGO1/lego/legoomni/src/entity/legocarraceactor.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include "legocarraceactor.h" - -#include "geom/legounkown100db7f4.h" -#include "legopathboundary.h" -#include "misc.h" -#include "mxmisc.h" -#include "mxvariabletable.h" - -DECOMP_SIZE_ASSERT(LegoCarRaceActor, 0x1a0) - -// GLOBAL: LEGO1 0x100f7af0 -// STRING: LEGO1 0x100f7ae4 -const char* g_fuel = "FUEL"; - -// FUNCTION: LEGO1 0x10080350 -// FUNCTION: BETA10 0x100cd6b0 -LegoCarRaceActor::LegoCarRaceActor() -{ - m_unk0x08 = 1.0f; - m_unk0x70 = 0.0f; - m_unk0x0c = 0; - m_maxLinearVel = 0.0f; - m_frequencyFactor = 1.0f; - m_unk0x1c = 0; - m_unk0x10 = 0.65f; - m_unk0x14 = 0.03f; - m_unk0x18 = 0.6f; - m_unk0x140 = 0.1f; - m_unk0x150 = -5.0f; - m_unk0x148 = 1; - VariableTable()->SetVariable(g_fuel, "0.8"); -} - -// FUNCTION: LEGO1 0x10080590 -// FUNCTION: BETA10 0x100cd8cf -void LegoCarRaceActor::FUN_10080590(float p_float) -{ - MxFloat maxSpeed = m_maxLinearVel; - Mx3DPointFloat destEdgeUnknownVector; - Mx3DPointFloat worldDirection = Mx3DPointFloat(m_roi->GetWorldDirection()); - - m_destEdge->FUN_1002ddc0(*m_boundary, destEdgeUnknownVector); - - if (abs(destEdgeUnknownVector.Dot(destEdgeUnknownVector.GetData(), worldDirection.GetData())) > 0.5) { - maxSpeed *= m_unk0x10; - } - - MxS32 deltaUnk0x70; - LegoPathActor* userActor = UserActor(); - - if (userActor) { - // All known implementations of LegoPathActor->VTable0x5c() return LegoPathActor::m_unk0x70 - deltaUnk0x70 = m_unk0x70 - userActor->VTable0x5c(); - } - else { - deltaUnk0x70 = 0; - } - - if (deltaUnk0x70 > 1) { - if (deltaUnk0x70 > 3) { - deltaUnk0x70 = 3; - } - - maxSpeed *= (m_unk0x18 * (--deltaUnk0x70) * -0.25f + 1.0f); - } - else if (deltaUnk0x70 < -1) { - maxSpeed *= 1.3; - } - - MxFloat deltaSpeed = maxSpeed - m_worldSpeed; - MxFloat changeInSpeed = (p_float - m_unk0x1c) * m_unk0x14; - m_unk0x1c = p_float; - - if (deltaSpeed < 0.0f) { - changeInSpeed = -changeInSpeed; - } - - MxFloat newWorldSpeed = changeInSpeed + m_worldSpeed; - - if (newWorldSpeed > maxSpeed) { - newWorldSpeed = maxSpeed; - } - - SetWorldSpeed(newWorldSpeed); -} - -// STUB: LEGO1 0x10080740 -void LegoCarRaceActor::VTable0x1c() -{ -} - -// FUNCTION: LEGO1 0x10080b40 -// FUNCTION: BETA10 0x100cdb3c -void LegoCarRaceActor::SwitchBoundary(LegoPathBoundary*& p_boundary, LegoUnknown100db7f4*& p_edge, float& p_unk0xe4) -{ - LegoPathActor::SwitchBoundary(m_boundary, m_destEdge, m_unk0xe4); -} - -// STUB: LEGO1 0x10080b70 -void LegoCarRaceActor::VTable0x70(float p_float) -{ - // TODO -} - -// STUB: LEGO1 0x10080be0 -MxResult LegoCarRaceActor::VTable0x9c() -{ - // TODO - return SUCCESS; -} - -// STUB: LEGO1 0x10081840 -MxU32 LegoCarRaceActor::VTable0x6c( - LegoPathBoundary* p_boundary, - Vector3& p_v1, - Vector3& p_v2, - float p_f1, - float p_f2, - Vector3& p_v3 -) -{ - // TODO - return 0; -} diff --git a/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp b/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp index 18a4f3d9..6ebf975e 100644 --- a/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp +++ b/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp @@ -12,9 +12,10 @@ LegoJetskiRaceActor::LegoJetskiRaceActor() } // STUB: LEGO1 0x10081120 -void LegoJetskiRaceActor::VTable0x1c() +MxS32 LegoJetskiRaceActor::VTable0x1c(undefined4 p_param1, LegoEdge* p_edge) { // TODO + return 0; } // STUB: LEGO1 0x10081550 diff --git a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp index 239f704f..9aa817c3 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp @@ -64,7 +64,7 @@ LegoPathActor::~LegoPathActor() } // FUNCTION: LEGO1 0x1002d8d0 -MxResult LegoPathActor::VTable0x80(Vector3& p_point1, Vector3& p_point2, Vector3& p_point3, Vector3& p_point4) +MxResult LegoPathActor::VTable0x80(const Vector3& p_point1, Vector3& p_point2, Vector3& p_point3, Vector3& p_point4) { Mx3DPointFloat p1, p2, p3; diff --git a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp index ddfe66ec..480b43ec 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathcontroller.cpp @@ -19,13 +19,15 @@ MxU32 g_unk0x100d7cc8[] = {2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 0}; MxU32 g_unk0x100d7d08[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // GLOBAL: LEGO1 0x100f42e8 -LegoPathController::CtrlBoundary* g_ctrlBoundariesA = NULL; +// GLOBAL: BETA10 0x101f25f0 +LegoPathController::CtrlBoundary* LegoPathController::g_ctrlBoundariesA = NULL; // GLOBAL: LEGO1 0x100f42ec -LegoPathController::CtrlEdge* g_ctrlEdgesA = NULL; +// GLOBAL: BETA10 0x101f25f4 +LegoPathController::CtrlEdge* LegoPathController::g_ctrlEdgesA = NULL; // GLOBAL: LEGO1 0x100f42f0 -const char* g_unk0x100f42f0[] = { +const char* LegoPathController::g_unk0x100f42f0[] = { "edg03_21", "edg03_23", "edg03_30", @@ -45,7 +47,7 @@ const char* g_unk0x100f42f0[] = { }; // GLOBAL: LEGO1 0x100f4330 -const char* g_unk0x100f4330[] = { +const char* LegoPathController::g_unk0x100f4330[] = { "edg03_06", "edg03_21", "edg03_30", @@ -59,10 +61,10 @@ const char* g_unk0x100f4330[] = { }; // GLOBAL: LEGO1 0x100f4358 -LegoPathController::CtrlBoundary* g_ctrlBoundariesB = NULL; +LegoPathController::CtrlBoundary* LegoPathController::g_ctrlBoundariesB = NULL; // GLOBAL: LEGO1 0x100f435c -LegoPathController::CtrlEdge* g_ctrlEdgesB = NULL; +LegoPathController::CtrlEdge* LegoPathController::g_ctrlEdgesB = NULL; // FUNCTION: LEGO1 0x10044f40 // FUNCTION: BETA10 0x100b6860 @@ -620,7 +622,7 @@ MxResult LegoPathController::ReadBoundaries(LegoStorage* p_storage) boundary.m_edgeNormals = new Mx4DPointFloat[numE]; - LegoEdge** edges = new LegoEdge*[numE]; + LegoUnknown100db7f4** edges = new LegoUnknown100db7f4*[numE]; boundary.SetEdges(edges, numE); for (j = 0; j < numE; j++) { diff --git a/LEGO1/lego/legoomni/src/race/legoracers.cpp b/LEGO1/lego/legoomni/src/race/legoracers.cpp index 16963723..d9f15050 100644 --- a/LEGO1/lego/legoomni/src/race/legoracers.cpp +++ b/LEGO1/lego/legoomni/src/race/legoracers.cpp @@ -266,13 +266,13 @@ void LegoRaceCar::FUN_10012ff0(float p_param) if (a->GetDuration() <= deltaTime || deltaTime < 0.0) { if (m_userState == LEGORACECAR_KICK1) { - LegoEdge** edges = m_kick1B->GetEdges(); - m_destEdge = (LegoUnknown100db7f4*) (edges[2]); + LegoUnknown100db7f4** edges = m_kick1B->GetEdges(); + m_destEdge = edges[2]; m_boundary = m_kick1B; } else { - LegoEdge** edges = m_kick1B->GetEdges(); - m_destEdge = (LegoUnknown100db7f4*) (edges[1]); + LegoUnknown100db7f4** edges = m_kick1B->GetEdges(); + m_destEdge = edges[1]; m_boundary = m_kick2B; } diff --git a/LEGO1/lego/legoomni/src/race/legoracespecial.cpp b/LEGO1/lego/legoomni/src/race/legoracespecial.cpp new file mode 100644 index 00000000..5e38bbaa --- /dev/null +++ b/LEGO1/lego/legoomni/src/race/legoracespecial.cpp @@ -0,0 +1,228 @@ +#include "legoracespecial.h" + +#include "geom/legounkown100db7f4.h" +#include "legonavcontroller.h" +#include "legopathboundary.h" +#include "legopathcontroller.h" +#include "misc.h" +#include "mxmisc.h" +#include "mxvariabletable.h" + +// File name verified by BETA10 0x100cedf7 + +DECOMP_SIZE_ASSERT(LegoCarRaceActor, 0x1a0) + +// GLOBAL: LEGO1 0x100f7af0 +// STRING: LEGO1 0x100f7ae4 +const char* g_fuel = "FUEL"; + +// GLOBAL: LEGO1 0x100f7aec +MxFloat LegoCarRaceActor::g_unk0x100f7aec = 8.0f; + +// FUNCTION: LEGO1 0x10080350 +// FUNCTION: BETA10 0x100cd6b0 +LegoCarRaceActor::LegoCarRaceActor() +{ + m_unk0x08 = 1.0f; + m_unk0x70 = 0.0f; + m_unk0x0c = 0; + m_maxLinearVel = 0.0f; + m_frequencyFactor = 1.0f; + m_unk0x1c = 0; + m_unk0x10 = 0.65f; + m_unk0x14 = 0.03f; + m_unk0x18 = 0.6f; + m_unk0x140 = 0.1f; + m_unk0x150 = -5.0f; + m_unk0x148 = 1; + VariableTable()->SetVariable(g_fuel, "0.8"); +} + +// FUNCTION: LEGO1 0x10080590 +// FUNCTION: BETA10 0x100cd8cf +void LegoCarRaceActor::FUN_10080590(float p_float) +{ + MxFloat maxSpeed = m_maxLinearVel; + Mx3DPointFloat destEdgeUnknownVector; + Mx3DPointFloat worldDirection = Mx3DPointFloat(m_roi->GetWorldDirection()); + + m_destEdge->FUN_1002ddc0(*m_boundary, destEdgeUnknownVector); + + if (abs(destEdgeUnknownVector.Dot(destEdgeUnknownVector.GetData(), worldDirection.GetData())) > 0.5) { + maxSpeed *= m_unk0x10; + } + + MxS32 deltaUnk0x70; + LegoPathActor* userActor = UserActor(); + + if (userActor) { + // All known implementations of LegoPathActor->VTable0x5c() return LegoPathActor::m_unk0x70 + deltaUnk0x70 = m_unk0x70 - userActor->VTable0x5c(); + } + else { + deltaUnk0x70 = 0; + } + + if (deltaUnk0x70 > 1) { + if (deltaUnk0x70 > 3) { + deltaUnk0x70 = 3; + } + + maxSpeed *= (m_unk0x18 * (--deltaUnk0x70) * -0.25f + 1.0f); + } + else if (deltaUnk0x70 < -1) { + maxSpeed *= 1.3; + } + + MxFloat deltaSpeed = maxSpeed - m_worldSpeed; + MxFloat changeInSpeed = (p_float - m_unk0x1c) * m_unk0x14; + m_unk0x1c = p_float; + + if (deltaSpeed < 0.0f) { + changeInSpeed = -changeInSpeed; + } + + MxFloat newWorldSpeed = changeInSpeed + m_worldSpeed; + + if (newWorldSpeed > maxSpeed) { + newWorldSpeed = maxSpeed; + } + + SetWorldSpeed(newWorldSpeed); +} + +// FUNCTION: LEGO1 0x10080740 +// FUNCTION: BETA10 0x100cece0 +MxS32 LegoCarRaceActor::VTable0x1c(undefined4 p_param1, LegoEdge* p_edge) +{ + Mx3DPointFloat pointUnknown; + Mx3DPointFloat destEdgeUnknownVector; + Mx3DPointFloat crossProduct; + + if (m_state == 1) { + m_boundary = NULL; + + // Not sure where the upper bound of 11 comes from, the underlying array has a size of 16 + for (MxS32 i = 0; i < 11; i += 2) { + if (LegoPathController::GetControlEdgeA(i + 1) == m_destEdge) { + m_boundary = LegoPathController::GetControlBoundaryA(i + 1); + break; + } + } + + assert(m_boundary); + + m_state = 0; + m_unk0x7c = 0; + + if (m_userNavFlag) { + NavController()->SetLinearVel(m_worldSpeed); + return 0; + } + else { + return 1; + } + } + else { + for (MxS32 i = 0; i < 11; i += 2) { + if (LegoPathController::GetControlEdgeA(i) == p_edge) { + m_state = 1; + + if (m_worldSpeed < g_unk0x100f7aec) { + m_worldSpeed = g_unk0x100f7aec; + } + + m_destEdge = LegoPathController::GetControlEdgeA(i + 1); + m_boundary = LegoPathController::GetControlBoundaryA(i + 1); + break; + } + } + + if (m_state == 1) { + if (m_userNavFlag) { + m_unk0xe4 = 0.5f; + } + + // variable names verified by BETA10 + Vector3* v1 = m_destEdge->CCWVertex(*m_boundary); + Vector3* v2 = m_destEdge->CWVertex(*m_boundary); + assert(v1 && v2); + + pointUnknown[0] = (*v1)[0] + ((*v2)[0] - (*v1)[0]) * m_unk0xe4; + pointUnknown[1] = (*v1)[1] + ((*v2)[1] - (*v1)[1]) * m_unk0xe4; + pointUnknown[2] = (*v1)[2] + ((*v2)[2] - (*v1)[2]) * m_unk0xe4; + + m_destEdge->FUN_1002ddc0(*m_boundary, destEdgeUnknownVector); + + crossProduct.EqualsCross(m_boundary->GetUnknown0x14(), &destEdgeUnknownVector); + crossProduct.Unitize(); + + Mx3DPointFloat worldDirection(Vector3(m_roi->GetWorldDirection())); + + if (!m_userNavFlag) { + ((Vector3*) &worldDirection)->Mul(-1.0f); + } + + ((Vector3*) &worldDirection)->Mul(5.0f); + ((Vector3*) &crossProduct)->Mul(5.0f); + + MxResult callResult = + VTable0x80(Vector3(m_roi->GetWorldPosition()), worldDirection, pointUnknown, crossProduct); + + if (callResult) { + m_unk0x7c = 0; + return 0; + } + else { + m_unk0x7c = 0; + assert(0); + return 0; // BETA10 returns -1 here + } + } + else { + // This `for` loop does not exist in BETA10 + for (MxS32 i = 0; i < 10; i++) { + if (LegoPathController::GetControlEdgeB(i) == p_edge && + LegoPathController::GetControlBoundaryB(i) == m_boundary) { + return 0; + } + } + + return 1; + } + } +} + +// FUNCTION: LEGO1 0x10080b40 +// FUNCTION: BETA10 0x100cdb3c +void LegoCarRaceActor::SwitchBoundary(LegoPathBoundary*& p_boundary, LegoUnknown100db7f4*& p_edge, float& p_unk0xe4) +{ + LegoPathActor::SwitchBoundary(m_boundary, m_destEdge, m_unk0xe4); +} + +// STUB: LEGO1 0x10080b70 +void LegoCarRaceActor::VTable0x70(float p_float) +{ + // TODO +} + +// STUB: LEGO1 0x10080be0 +MxResult LegoCarRaceActor::VTable0x9c() +{ + // TODO + return SUCCESS; +} + +// STUB: LEGO1 0x10081840 +MxU32 LegoCarRaceActor::VTable0x6c( + LegoPathBoundary* p_boundary, + Vector3& p_v1, + Vector3& p_v2, + float p_f1, + float p_f2, + Vector3& p_v3 +) +{ + // TODO + return 0; +} diff --git a/LEGO1/lego/sources/geom/legoedge.cpp b/LEGO1/lego/sources/geom/legoedge.cpp index 7606d6a1..d1a810d6 100644 --- a/LEGO1/lego/sources/geom/legoedge.cpp +++ b/LEGO1/lego/sources/geom/legoedge.cpp @@ -1,5 +1,6 @@ #include "legoedge.h" +#include "assert.h" #include "decomp.h" DECOMP_SIZE_ASSERT(LegoEdge, 0x24) @@ -51,13 +52,27 @@ LegoEdge* LegoEdge::GetCounterclockwiseEdge(LegoWEEdge& p_face) } // FUNCTION: LEGO1 0x1009a510 +// FUNCTION: BETA10 0x10182433 Vector3* LegoEdge::CWVertex(LegoWEEdge& p_face) { - return &p_face == m_faceA ? m_pointB : m_pointA; + if (m_faceA == &p_face) { + return m_pointB; + } + else { + assert(m_faceB == &p_face); + return m_pointA; + } } // FUNCTION: LEGO1 0x1009a530 +// FUNCTION: BETA10 0x10182498 Vector3* LegoEdge::CCWVertex(LegoWEEdge& p_face) { - return &p_face == m_faceB ? m_pointB : m_pointA; + if (m_faceB == &p_face) { + return m_pointB; + } + else { + assert(m_faceA == &p_face); + return m_pointA; + } } diff --git a/LEGO1/lego/sources/geom/legoweedge.cpp b/LEGO1/lego/sources/geom/legoweedge.cpp index c03a5e3f..a87072e9 100644 --- a/LEGO1/lego/sources/geom/legoweedge.cpp +++ b/LEGO1/lego/sources/geom/legoweedge.cpp @@ -1,5 +1,7 @@ #include "legoweedge.h" +#include "legounkown100db7f4.h" + DECOMP_SIZE_ASSERT(LegoWEEdge, 0x0c) // FUNCTION: LEGO1 0x1009a550 @@ -21,8 +23,8 @@ LegoWEEdge::~LegoWEEdge() LegoResult LegoWEEdge::VTable0x04() { for (LegoS32 i = 0; i < m_numEdges; i++) { - LegoEdge* e1 = m_edges[i]; - LegoEdge* e2 = (m_numEdges - i) == 1 ? m_edges[0] : m_edges[i + 1]; + LegoUnknown100db7f4* e1 = m_edges[i]; + LegoUnknown100db7f4* e2 = (m_numEdges - i) == 1 ? m_edges[0] : m_edges[i + 1]; if (e2->m_pointA == e1->m_pointA) { e1->m_faceA = this; diff --git a/LEGO1/lego/sources/geom/legoweedge.h b/LEGO1/lego/sources/geom/legoweedge.h index 6e5f4548..a63eb50e 100644 --- a/LEGO1/lego/sources/geom/legoweedge.h +++ b/LEGO1/lego/sources/geom/legoweedge.h @@ -2,9 +2,10 @@ #define __LEGOWEEDGE_H #include "decomp.h" -#include "legoedge.h" #include "misc/legotypes.h" +struct LegoUnknown100db7f4; + // might be a struct with public members // VTABLE: LEGO1 0x100db7c0 // SIZE 0x0c @@ -18,13 +19,13 @@ class LegoWEEdge { LegoU8 GetNumEdges() { return m_numEdges; } // FUNCTION: BETA10 0x1001cc30 - LegoEdge** GetEdges() { return m_edges; } + LegoUnknown100db7f4** GetEdges() { return m_edges; } // TODO: The assertion at BETA10 0x10037352 suggests that this function might take a pointer instead of a reference // FUNCTION: BETA10 0x100373f0 LegoU32 IsEqual(LegoWEEdge& p_other) { return this == &p_other; } - void SetEdges(LegoEdge** p_edges, LegoU8 p_numEdges) + void SetEdges(LegoUnknown100db7f4** p_edges, LegoU8 p_numEdges) { m_edges = p_edges; m_numEdges = p_numEdges; @@ -34,8 +35,8 @@ class LegoWEEdge { // LegoWEEdge::`scalar deleting destructor' protected: - LegoU8 m_numEdges; // 0x04 - LegoEdge** m_edges; // 0x08 + LegoU8 m_numEdges; // 0x04 + LegoUnknown100db7f4** m_edges; // 0x08 }; #endif // __LEGOWEEDGE_H diff --git a/LEGO1/lego/sources/geom/legowegedge.h b/LEGO1/lego/sources/geom/legowegedge.h index 23bdf340..1e774abf 100644 --- a/LEGO1/lego/sources/geom/legowegedge.h +++ b/LEGO1/lego/sources/geom/legowegedge.h @@ -41,7 +41,10 @@ class LegoWEGEdge : public LegoWEEdge { LegoResult VTable0x04() override; // vtable+0x04 LegoU32 GetFlag0x10() { return m_flags & c_bit5 ? FALSE : TRUE; } + + // FUNCTION: BETA10 0x1001ff80 Mx4DPointFloat* GetUnknown0x14() { return &m_unk0x14; } + Mx4DPointFloat* GetEdgeNormal(int index) { return &m_edgeNormals[index]; } // FUNCTION: BETA10 0x1001c9b0 diff --git a/LEGO1/lego/sources/misc/legounknown.cpp b/LEGO1/lego/sources/misc/legounknown.cpp index b3976b51..67e1423c 100644 --- a/LEGO1/lego/sources/misc/legounknown.cpp +++ b/LEGO1/lego/sources/misc/legounknown.cpp @@ -16,7 +16,7 @@ LegoUnknown::~LegoUnknown() } // FUNCTION: LEGO1 0x1009a140 -void LegoUnknown::FUN_1009a140(Vector3& p_point1, Vector3& p_point2, Vector3& p_point3, Vector3& p_point4) +void LegoUnknown::FUN_1009a140(const Vector3& p_point1, Vector3& p_point2, Vector3& p_point3, Vector3& p_point4) { m_unk0x00[0] = p_point1; m_unk0x00[1] = p_point2; diff --git a/LEGO1/lego/sources/misc/legounknown.h b/LEGO1/lego/sources/misc/legounknown.h index 1d0d1aef..cc7a467b 100644 --- a/LEGO1/lego/sources/misc/legounknown.h +++ b/LEGO1/lego/sources/misc/legounknown.h @@ -12,7 +12,7 @@ class LegoUnknown { LegoUnknown(); ~LegoUnknown(); - void FUN_1009a140(Vector3& p_point1, Vector3& p_point2, Vector3& p_point3, Vector3& p_point4); + void FUN_1009a140(const Vector3& p_point1, Vector3& p_point2, Vector3& p_point3, Vector3& p_point4); LegoResult FUN_1009a1e0(float p_f1, Matrix4& p_mat, Vector3& p_v, LegoU32 p_und); private: diff --git a/LEGO1/mxgeometry/mxgeometry3d.h b/LEGO1/mxgeometry/mxgeometry3d.h index 20946865..f675a350 100644 --- a/LEGO1/mxgeometry/mxgeometry3d.h +++ b/LEGO1/mxgeometry/mxgeometry3d.h @@ -18,6 +18,7 @@ class Mx3DPointFloat : public Vector3 { } // FUNCTION: LEGO1 0x100343a0 + // FUNCTION: BETA10 0x10011600 Mx3DPointFloat(const Mx3DPointFloat& p_other) : Vector3(m_elements) { EqualsImpl(p_other.m_data); } Mx3DPointFloat(const Vector3& p_other) : Vector3(m_elements) { EqualsImpl(p_other.m_data); } diff --git a/LEGO1/realtime/vector.h b/LEGO1/realtime/vector.h index 920b24b1..9c73f31f 100644 --- a/LEGO1/realtime/vector.h +++ b/LEGO1/realtime/vector.h @@ -10,10 +10,12 @@ // The class needs to undergo a very careful refactoring to fix that (no matches should break). // VTABLE: LEGO1 0x100d4288 +// VTABLE: BETA10 0x101b8440 // SIZE 0x08 class Vector2 { public: // FUNCTION: LEGO1 0x1000c0f0 + // FUNCTION: BETA10 0x100116a0 Vector2(float* p_data) { SetData(p_data); } // Note: virtual function overloads appear in the virtual table @@ -68,6 +70,7 @@ class Vector2 { virtual float DotImpl(float* p_a, float* p_b) const { return p_b[0] * p_a[0] + p_b[1] * p_a[1]; } // vtable+0x18 // FUNCTION: LEGO1 0x10002060 + // FUNCTION: BETA10 0x10010c90 virtual void SetData(float* p_data) { m_data = p_data; } // vtable+0x1c // FUNCTION: LEGO1 0x10002070 @@ -86,6 +89,7 @@ class Vector2 { virtual float Dot(float* p_a, float* p_b) const { return DotImpl(p_a, p_b); } // vtable+0x3c // FUNCTION: LEGO1 0x100020f0 + // FUNCTION: BETA10 0x100028f6 virtual float Dot(Vector2* p_a, Vector2* p_b) const { return DotImpl(p_a->m_data, p_b->m_data); } // vtable+0x38 // FUNCTION: LEGO1 0x10002110 @@ -98,6 +102,7 @@ class Vector2 { virtual float LenSquared() const { return m_data[0] * m_data[0] + m_data[1] * m_data[1]; } // vtable+0x40 // FUNCTION: LEGO1 0x10002160 + // FUNCTION: BETA10 0x10010900 virtual int Unitize() { float sq = LenSquared(); @@ -154,7 +159,11 @@ class Vector2 { Vector2::SetVector(&p_other); return *this; } + + // FUNCTION: BETA10 0x10013460 float& operator[](int idx) { return m_data[idx]; } + + // FUNCTION: BETA10 0x1001d140 const float& operator[](int idx) const { return m_data[idx]; } protected: @@ -188,6 +197,7 @@ class Vector3 : public Vector2 { } // vtable+0x74 // FUNCTION: LEGO1 0x100022c0 + // FUNCTION: BETA10 0x10011430 virtual void EqualsCross(Vector3* p_a, Vector3* p_b) { EqualsCrossImpl(p_a->m_data, p_b->m_data); } // vtable+0x80 // FUNCTION: LEGO1 0x100022e0 @@ -261,10 +271,11 @@ class Vector3 : public Vector2 { } // vtable+0x18 // FUNCTION: LEGO1 0x10003ba0 + // FUNCTION: BETA10 0x100113f0 void EqualsImpl(float* p_data) override { memcpy(m_data, p_data, sizeof(float) * 3); } // vtable+0x20 // FUNCTION: LEGO1 0x10003bc0 - // FUNCTION: BETA10 0x101b84fc + // FUNCTION: BETA10 0x1000132a void Clear() override { memset(m_data, 0, sizeof(float) * 3); } // vtable+0x2c // FUNCTION: LEGO1 0x10003bd0