diff --git a/LEGO1/lego/legoomni/include/carrace.h b/LEGO1/lego/legoomni/include/carrace.h index 5a43f420..954c1326 100644 --- a/LEGO1/lego/legoomni/include/carrace.h +++ b/LEGO1/lego/legoomni/include/carrace.h @@ -5,10 +5,12 @@ #include "legorace.h" // VTABLE: LEGO1 0x100d4b70 +// VTABLE: BETA10 0x101bd5f0 // SIZE 0x2c class CarRaceState : public RaceState { public: // FUNCTION: LEGO1 0x1000dd30 + // FUNCTION: BETA10 0x100a9100 const char* ClassName() const override // vtable+0x0c { // STRING: LEGO1 0x100f009c @@ -16,6 +18,7 @@ public: } // FUNCTION: LEGO1 0x1000dd40 + // FUNCTION: BETA10 0x100a9130 MxBool IsA(const char* p_name) const override // vtable+0x10 { return !strcmp(p_name, CarRaceState::ClassName()) || RaceState::IsA(p_name); @@ -26,12 +29,14 @@ public: }; // VTABLE: LEGO1 0x100d5e50 +// VTABLE: BETA10 0x101be290 // SIZE 0x154 class CarRace : public LegoRace { public: CarRace(); // FUNCTION: LEGO1 0x10016b20 + // FUNCTION: BETA10 0x100c9870 const char* ClassName() const override // vtable+0x0c { // STRING: LEGO1 0x100f0528 @@ -39,6 +44,7 @@ public: } // FUNCTION: LEGO1 0x10016b30 + // FUNCTION: BETA10 0x100c98a0 MxBool IsA(const char* p_name) const override // vtable+0x10 { return !strcmp(p_name, CarRace::ClassName()) || LegoRace::IsA(p_name); diff --git a/LEGO1/lego/legoomni/include/legojetskiraceactor.h b/LEGO1/lego/legoomni/include/legojetskiraceactor.h index 219ed51f..2f5b3d19 100644 --- a/LEGO1/lego/legoomni/include/legojetskiraceactor.h +++ b/LEGO1/lego/legoomni/include/legojetskiraceactor.h @@ -32,9 +32,9 @@ public: float p_f1, float p_f2, Vector3& p_v3 - ) override; // vtable+0x6c - void VTable0x70(float p_float) override; // vtable+0x70 - MxS32 VTable0x1c(undefined4 p_param1, LegoEdge* p_edge) override; // vtable+0x1c + ) override; // vtable+0x6c + void VTable0x70(float p_float) override; // vtable+0x70 + MxS32 VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edge) override; // vtable+0x1c // SYNTHETIC: LEGO1 0x10081d50 // LegoJetskiRaceActor::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/legoracespecial.h b/LEGO1/lego/legoomni/include/legoracespecial.h index 3db9838f..a85a967f 100644 --- a/LEGO1/lego/legoomni/include/legoracespecial.h +++ b/LEGO1/lego/legoomni/include/legoracespecial.h @@ -64,7 +64,7 @@ public: // FUNCTION: LEGO1 0x10012c00 virtual float FUN_10012c00() { return m_unk0x18; } - virtual MxS32 VTable0x1c(undefined4 p_param1, LegoEdge* p_edge); // vtable+0x1c + virtual MxS32 VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edge); // vtable+0x1c // SYNTHETIC: LEGO1 0x10012c30 // LegoCarRaceActor::`vbase destructor' diff --git a/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp b/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp index 6ebf975e..ae020f15 100644 --- a/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp +++ b/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp @@ -12,7 +12,7 @@ LegoJetskiRaceActor::LegoJetskiRaceActor() } // STUB: LEGO1 0x10081120 -MxS32 LegoJetskiRaceActor::VTable0x1c(undefined4 p_param1, LegoEdge* p_edge) +MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edge) { // TODO return 0; diff --git a/LEGO1/lego/legoomni/src/race/legoracespecial.cpp b/LEGO1/lego/legoomni/src/race/legoracespecial.cpp index 5e38bbaa..bd6e4330 100644 --- a/LEGO1/lego/legoomni/src/race/legoracespecial.cpp +++ b/LEGO1/lego/legoomni/src/race/legoracespecial.cpp @@ -8,14 +8,24 @@ #include "mxmisc.h" #include "mxvariabletable.h" +#include <vec.h> + // File name verified by BETA10 0x100cedf7 DECOMP_SIZE_ASSERT(LegoCarRaceActor, 0x1a0) +// GLOBAL: LEGO1 0x100f0c68 +// STRING: LEGO1 0x100f0c5c +const char* g_raceState = "RACE_STATE"; + // GLOBAL: LEGO1 0x100f7af0 // STRING: LEGO1 0x100f7ae4 const char* g_fuel = "FUEL"; +// GLOBAL: LEGO1 0x100f0c6c +// STRING: LEGO1 0x100f0c54 +const char* g_racing = "RACING"; + // GLOBAL: LEGO1 0x100f7aec MxFloat LegoCarRaceActor::g_unk0x100f7aec = 8.0f; @@ -93,7 +103,7 @@ void LegoCarRaceActor::FUN_10080590(float p_float) // FUNCTION: LEGO1 0x10080740 // FUNCTION: BETA10 0x100cece0 -MxS32 LegoCarRaceActor::VTable0x1c(undefined4 p_param1, LegoEdge* p_edge) +MxS32 LegoCarRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edge) { Mx3DPointFloat pointUnknown; Mx3DPointFloat destEdgeUnknownVector; @@ -148,9 +158,7 @@ MxS32 LegoCarRaceActor::VTable0x1c(undefined4 p_param1, LegoEdge* p_edge) 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; + LERP3(pointUnknown, *v1, *v2, m_unk0xe4); m_destEdge->FUN_1002ddc0(*m_boundary, destEdgeUnknownVector); @@ -200,20 +208,80 @@ void LegoCarRaceActor::SwitchBoundary(LegoPathBoundary*& p_boundary, LegoUnknown LegoPathActor::SwitchBoundary(m_boundary, m_destEdge, m_unk0xe4); } -// STUB: LEGO1 0x10080b70 +// FUNCTION: LEGO1 0x10080b70 +// FUNCTION: BETA10 0x1000366b void LegoCarRaceActor::VTable0x70(float p_float) { - // TODO + // m_unk0x0c is not an MxBool, there are places where it is set to 2 or higher + if (m_unk0x0c == 0) { + const char* value = VariableTable()->GetVariable(g_raceState); + + if (strcmpi(value, g_racing) == 0) { + m_unk0x0c = 1; + m_lastTime = p_float - 1.0f; + m_unk0x1c = p_float; + } + } + + if (m_unk0x0c == 1) { + LegoAnimActor::VTable0x70(p_float); + } } -// STUB: LEGO1 0x10080be0 +// FUNCTION: LEGO1 0x10080be0 +// FUNCTION: BETA10 0x100cdc54 MxResult LegoCarRaceActor::VTable0x9c() { - // TODO + LegoUnknown100db7f4* d = m_destEdge; + + if (VTable0x1c(m_boundary, m_destEdge)) { + LegoPathBoundary* b = m_boundary; + + SwitchBoundary(m_boundary, m_destEdge, m_unk0xe4); + assert(m_boundary && m_destEdge); + + // variable names verified by BETA10 + Vector3* v1 = m_destEdge->CWVertex(*m_boundary); + Vector3* v2 = m_destEdge->CCWVertex(*m_boundary); + assert(v1 && v2); + + Mx3DPointFloat point1; + LERP3(point1, *v1, *v2, m_unk0xe4); + + Mx3DPointFloat point2; + Mx3DPointFloat point3; + Mx3DPointFloat point4; + Mx3DPointFloat point5; + + d->FUN_1002ddc0(*b, point2); + m_destEdge->FUN_1002ddc0(*m_boundary, point3); + + point4.EqualsCross(&point2, m_boundary->GetUnknown0x14()); + point5.EqualsCross(m_boundary->GetUnknown0x14(), &point3); + + point4.Unitize(); + point5.Unitize(); + + ((Vector3*) &point4)->Mul(5.0f); + ((Vector3*) &point5)->Mul(5.0f); + + MxResult res = VTable0x80(m_roi->GetWorldPosition(), point4, point1, point5); + +#ifndef NDEBUG // BETA10 only + if (res) { + assert(0); + return -1; + } +#endif + + m_unk0x7c = 0; + } + return SUCCESS; } // STUB: LEGO1 0x10081840 +// FUNCTION: BETA10 0x100cf680 MxU32 LegoCarRaceActor::VTable0x6c( LegoPathBoundary* p_boundary, Vector3& p_v1, @@ -223,6 +291,11 @@ MxU32 LegoCarRaceActor::VTable0x6c( Vector3& p_v3 ) { + // LegoAnimPresenterSet& presenters = p_boundary->GetPresenters(); + + // Significant overlap with parent function -> Try to copy-paste LegoPathActor::VTable0x6c here + // and see by how much we diverge + // TODO return 0; } diff --git a/LEGO1/realtime/orientableroi.h b/LEGO1/realtime/orientableroi.h index ad84d9ed..61b61645 100644 --- a/LEGO1/realtime/orientableroi.h +++ b/LEGO1/realtime/orientableroi.h @@ -42,6 +42,7 @@ public: // FUNCTION: BETA10 0x1000fbf0 const Matrix4& GetLocal2World() const { return m_local2world; } + // FUNCTION: BETA10 0x10011750 const float* GetWorldPosition() const { return m_local2world[3]; } // FUNCTION: BETA10 0x10011780