From 866ed58727a29a1f957759b25bb79dca95462821 Mon Sep 17 00:00:00 2001 From: jonschz Date: Mon, 22 Jul 2024 13:06:28 +0200 Subject: [PATCH] Implement LegoRaceCar::VTable0x94 --- LEGO1/lego/legoomni/include/legoentity.h | 2 + LEGO1/lego/legoomni/include/legopathactor.h | 4 + LEGO1/lego/legoomni/include/legoracers.h | 13 +- LEGO1/lego/legoomni/src/race/legoracers.cpp | 130 +++++++++++++++++++- LEGO1/lego/sources/roi/legoroi.h | 1 + LEGO1/mxgeometry/mxmatrix.h | 1 + LEGO1/omni/include/mxtimer.h | 8 ++ LEGO1/realtime/orientableroi.h | 1 + 8 files changed, 153 insertions(+), 7 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legoentity.h b/LEGO1/lego/legoomni/include/legoentity.h index b5b4e880..fc4fe6ae 100644 --- a/LEGO1/lego/legoomni/include/legoentity.h +++ b/LEGO1/lego/legoomni/include/legoentity.h @@ -83,6 +83,8 @@ class LegoEntity : public MxEntity { MxBool GetFlagsIsSet(MxU8 p_flag) { return m_flags & p_flag; } MxU8 GetFlags() { return m_flags; } MxFloat GetWorldSpeed() { return m_worldSpeed; } + + // FUNCTION: BETA10 0x1000f2f0 LegoROI* GetROI() { return m_roi; } MxU8 GetType() { return m_type; } MxBool GetCameraFlag() { return m_cameraFlag; } diff --git a/LEGO1/lego/legoomni/include/legopathactor.h b/LEGO1/lego/legoomni/include/legopathactor.h index 70ee6950..96f753b8 100644 --- a/LEGO1/lego/legoomni/include/legopathactor.h +++ b/LEGO1/lego/legoomni/include/legopathactor.h @@ -124,11 +124,15 @@ class LegoPathActor : public LegoActor { virtual void VTable0xc8(MxU8 p_unk0x148) { m_unk0x148 = p_unk0x148; } // vtable+0xc8 LegoPathBoundary* GetBoundary() { return m_boundary; } + + // FUNCTION: BETA10 0x1001c860 MxU32 GetState() { return m_state; } LegoPathController* GetController() { return m_controller; } MxBool GetCollideBox() { return m_collideBox; } void SetBoundary(LegoPathBoundary* p_boundary) { m_boundary = p_boundary; } + + // FUNCTION: BETA10 0x10013430 void SetState(MxU32 p_state) { m_state = p_state; } void SetController(LegoPathController* p_controller) { m_controller = p_controller; } diff --git a/LEGO1/lego/legoomni/include/legoracers.h b/LEGO1/lego/legoomni/include/legoracers.h index f460a050..1a75cd91 100644 --- a/LEGO1/lego/legoomni/include/legoracers.h +++ b/LEGO1/lego/legoomni/include/legoracers.h @@ -88,11 +88,22 @@ class LegoRaceCar : public LegoCarRaceActor, public LegoRaceMap { static EdgeReference g_edgeReferences[]; static const SkeletonKickPhase g_skeletonKickPhases[]; - static const char* g_strSpeedCopy; + static const char* g_strSpeed; + static const char* g_srtsl18to29[]; + static const char* g_srtsl6to10[]; + static const char* g_emptySoundKeyList[]; + static const char* g_srtrh[]; static const char* g_srt001ra; static const char* g_soundSkel3; + static MxU32 g_srtsl18to29Index; + static MxU32 g_srtsl6to10Index; + static MxU32 g_emptySoundKeyListIndex; + static MxU32 g_srtrhIndex; + static MxLong g_timeLastSoundPlayed; static MxS32 g_unk0x100f0b88; static MxBool g_unk0x100f0b8c; + static MxLong g_unk0x100f3308; + static Mx3DPointFloat g_vector020; }; #endif // LEGORACERS_H diff --git a/LEGO1/lego/legoomni/src/race/legoracers.cpp b/LEGO1/lego/legoomni/src/race/legoracers.cpp index c5e227fa..71f1831f 100644 --- a/LEGO1/lego/legoomni/src/race/legoracers.cpp +++ b/LEGO1/lego/legoomni/src/race/legoracers.cpp @@ -12,6 +12,7 @@ #include "mxdebug.h" #include "mxmisc.h" #include "mxnotificationmanager.h" +#include "mxtimer.h" #include "mxutilities.h" #include "mxvariabletable.h" #include "raceskel.h" @@ -66,7 +67,32 @@ const SkeletonKickPhase LegoRaceCar::g_skeletonKickPhases[] = { // GLOBAL: LEGO1 0x100f0b10 // STRING: LEGO1 0x100f09cc -const char* LegoRaceCar::g_strSpeedCopy = "SPEED"; +const char* LegoRaceCar::g_strSpeed = "SPEED"; + +// GLOBAL: LEGO1 0x100f0b18 +const char* LegoRaceCar::g_srtsl18to29[] = { + "srt018sl", + "srt019sl", + "srt020sl", + "srt021sl", + "srt022sl", + "srt023sl", + "srt024sl", + "srt025sl", + "srt026sl", + "srt027sl", + "srt028sl", + "srt029sl" +}; + +// GLOBAL: LEGO1 0x100f0b48 +const char* LegoRaceCar::g_srtsl6to10[] = {"srt006sl", "srt007sl", "srt008sl", "srt009sl", "srt010sl"}; + +// GLOBAL: LEGO1 0x100f0b5c +const char* LegoRaceCar::g_emptySoundKeyList[] = {NULL}; + +// GLOBAL: LEGO1 0x100f0b60 +const char* LegoRaceCar::g_srtrh[] = {"srt004rh", "srt005rh", "srt006rh"}; // GLOBAL: LEGO1 0x100f0b6c // STRING: LEGO1 0x100f08c4 @@ -76,6 +102,21 @@ const char* LegoRaceCar::g_srt001ra = "srt001ra"; // STRING: LEGO1 0x100f08bc const char* LegoRaceCar::g_soundSkel3 = "skel3"; +// GLOBAL: LEGO1 0x100f0b74 +undefined4 LegoRaceCar::g_srtsl18to29Index = 0; + +// GLOBAL: LEGO1 0x100f0b78 +undefined4 LegoRaceCar::g_srtsl6to10Index = 0; + +// GLOBAL: LEGO1 0x100f0b7c +undefined4 LegoRaceCar::g_emptySoundKeyListIndex = 0; + +// GLOBAL: LEGO1 0x100f0b80 +MxU32 LegoRaceCar::g_srtrhIndex = 0; + +// GLOBAL: LEGO1 0x100f0b84 +MxLong LegoRaceCar::g_timeLastSoundPlayed = 0; + // GLOBAL: LEGO1 0x100f0b88 // GLOBAL: BETA10 0x101f5f94 MxS32 LegoRaceCar::g_unk0x100f0b88 = 0; @@ -84,6 +125,15 @@ MxS32 LegoRaceCar::g_unk0x100f0b88 = 0; // GLOBAL: BETA10 0x101f5f98 MxBool LegoRaceCar::g_unk0x100f0b8c = TRUE; +// Not sure why the next two are so far away from the rest in address space + +// GLOBAL: LEGO1 0x100f3308 +MxLong LegoRaceCar::g_unk0x100f3308 = 0; + +// Initialized at LEGO1 0x10012db0 +// GLOBAL: LEGO1 0x10102af0 +Mx3DPointFloat LegoRaceCar::g_vector020 = Mx3DPointFloat(0.0f, 2.0f, 0.0f); + // FUNCTION: LEGO1 0x10012950 LegoRaceCar::LegoRaceCar() { @@ -260,7 +310,6 @@ MxU32 LegoRaceCar::HandleSkeletonKicks(float p_param1) MxTrace( // STRING: BETA10 0x101f64c8 "Got kicked in boundary %s %d %g:%g %g\n", - // TODO: same as in above comparison m_boundary->GetName(), skeletonCurAnimPosition, skeletonCurAnimDuration, @@ -306,7 +355,7 @@ void LegoRaceCar::VTable0x70(float p_float) sprintf(buffer, "%g", absoluteSpeed / maximumSpeed); - VariableTable()->SetVariable(g_strSpeedCopy, buffer); + VariableTable()->SetVariable(g_strSpeed, buffer); if (m_sound) { // pitches up the engine sound based on the velocity @@ -332,11 +381,80 @@ void LegoRaceCar::VTable0x70(float p_float) } } -// STUB: LEGO1 0x100133c0 +// FUNCTION: LEGO1 0x100133c0 +// FUNCTION: BETA10 0x100cbb84 MxResult LegoRaceCar::VTable0x94(LegoPathActor* p_actor, MxBool p_bool) { - // TODO - return 0; + if (!p_actor->GetUserNavFlag()) { + if (p_actor->GetState()) { + return FAILURE; + } + + if (p_bool) { + LegoROI* roi = p_actor->GetROI(); // name verified by BETA10 0x100cbbf5 + assert(roi); + MxMatrix matr; + matr = roi->GetLocal2World(); + + Vector3(matr[3]).Add(g_vector020); + roi->FUN_100a58f0(matr); + + p_actor->SetState(2); + } + + if (m_userNavFlag) { + MxBool actorIsStuds = strcmpi(p_actor->GetROI()->GetName(), "studs") == 0; + MxBool actorIsRhoda = strcmpi(p_actor->GetROI()->GetName(), "rhoda") == 0; + MxTimer* timer = Timer(); + MxLong time = timer->GetTime(); + + const char* soundKey = NULL; + MxLong timeElapsed = time - g_timeLastSoundPlayed; + + if (timeElapsed > 3000) { + if (p_bool) { + if (actorIsStuds) { + soundKey = g_srtsl18to29[g_srtsl18to29Index++]; + if (g_srtsl18to29Index >= sizeOfArray(g_srtsl18to29)) { + g_srtsl18to29Index = 0; + } + } + else if (actorIsRhoda) { + soundKey = g_emptySoundKeyList[g_emptySoundKeyListIndex++]; + if (g_emptySoundKeyListIndex >= sizeOfArray(g_emptySoundKeyList)) { + g_emptySoundKeyListIndex = 0; + } + } + } + else { + if (actorIsStuds) { + soundKey = g_srtsl6to10[g_srtsl6to10Index++]; + if (g_srtsl6to10Index >= sizeOfArray(g_srtsl6to10)) { + g_srtsl6to10Index = 0; + } + } + else if (actorIsRhoda) { + soundKey = g_srtrh[g_srtrhIndex++]; + if (g_srtrhIndex >= sizeOfArray(g_srtrh)) { + g_srtrhIndex = 0; + } + } + } + + if (soundKey) { + SoundManager()->GetCacheSoundManager()->Play(soundKey, NULL, FALSE); + g_timeLastSoundPlayed = g_unk0x100f3308 = time; + } + } + + if (p_bool && m_worldSpeed != 0) { + return SUCCESS; + } + + return FAILURE; + } + } + return SUCCESS; } // STUB: LEGO1 0x10013600 diff --git a/LEGO1/lego/sources/roi/legoroi.h b/LEGO1/lego/sources/roi/legoroi.h index ef01fddf..188e4424 100644 --- a/LEGO1/lego/sources/roi/legoroi.h +++ b/LEGO1/lego/sources/roi/legoroi.h @@ -60,6 +60,7 @@ class LegoROI : public ViewROI { ); static LegoBool FUN_100a9cf0(const LegoChar* p_param, unsigned char* paletteEntries, LegoU32 p_numEntries); + // FUNCTION: BETA10 0x1000f320 const LegoChar* GetName() const { return m_name; } LegoEntity* GetEntity() { return m_entity; } diff --git a/LEGO1/mxgeometry/mxmatrix.h b/LEGO1/mxgeometry/mxmatrix.h index 1b8bbfbc..3b27e805 100644 --- a/LEGO1/mxgeometry/mxmatrix.h +++ b/LEGO1/mxgeometry/mxmatrix.h @@ -16,6 +16,7 @@ class MxMatrix : public Matrix4 { MxMatrix(const Matrix4& p_matrix) : Matrix4(m_elements) { Equals(p_matrix); } + // FUNCTION: BETA10 0x10010860 float* operator[](int idx) { return m_data[idx]; } const float* operator[](int idx) const { return m_data[idx]; } diff --git a/LEGO1/omni/include/mxtimer.h b/LEGO1/omni/include/mxtimer.h index 1e33d548..6f33d8b7 100644 --- a/LEGO1/omni/include/mxtimer.h +++ b/LEGO1/omni/include/mxtimer.h @@ -24,6 +24,14 @@ class MxTimer : public MxCore { } } + MxLong GetStartTime() { return m_startTime; } + MxBool IsRunning() { return m_isRunning; } + inline static MxLong GetLastTimeCalculated() { return g_lastTimeCalculated; } + inline static MxLong GetLastTimeTimerStarted() { return g_lastTimeTimerStarted; } + + // FUNCTION: BETA10 0x1000f320 + inline MxLong GetTimeElapsed() { return g_lastTimeCalculated - m_startTime; } + // SYNTHETIC: LEGO1 0x100ae0d0 // MxTimer::`scalar deleting destructor' diff --git a/LEGO1/realtime/orientableroi.h b/LEGO1/realtime/orientableroi.h index 25e09a5d..010deccd 100644 --- a/LEGO1/realtime/orientableroi.h +++ b/LEGO1/realtime/orientableroi.h @@ -39,6 +39,7 @@ class OrientableROI : public ROI { void FUN_100a58f0(const Matrix4& p_transform); void FUN_100a5a30(const Vector3& p_world_velocity); + // FUNCTION: BETA10 0x1000fbf0 const Matrix4& GetLocal2World() const { return m_local2world; } const float* GetWorldPosition() const { return m_local2world[3]; } const float* GetWorldDirection() const { return m_local2world[2]; }