Implement/match LegoRaceCar::VTable0x94 ()

* Implement LegoRaceCar::VTable0x94

* Remove redundant inline modifiers

* Fix offsets

* Fix minor inconsistency

* Address review comments

* Address review comments, round 2

---------

Co-authored-by: jonschz <jonschz@users.noreply.github.com>
This commit is contained in:
jonschz 2024-07-26 19:53:09 +02:00 committed by GitHub
parent bc9abdc823
commit 0d385e27d0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 148 additions and 7 deletions
LEGO1
lego
mxgeometry
omni/include
realtime

View file

@ -83,7 +83,10 @@ public:
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; }

View file

@ -13,6 +13,8 @@ struct LegoPathEdgeContainer;
struct LegoUnknown100db7f4;
class LegoWEEdge;
extern MxLong g_unk0x100f3308;
// VTABLE: LEGO1 0x100d6e28
// SIZE 0x154
class LegoPathActor : public LegoActor {
@ -124,12 +126,18 @@ public:
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; }
// SYNTHETIC: LEGO1 0x1002d800

View file

@ -88,11 +88,21 @@ private:
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 Mx3DPointFloat g_unk0x10102af0;
};
#endif // LEGORACERS_H

View file

@ -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
MxU32 LegoRaceCar::g_srtsl18to29Index = 0;
// GLOBAL: LEGO1 0x100f0b78
MxU32 LegoRaceCar::g_srtsl6to10Index = 0;
// GLOBAL: LEGO1 0x100f0b7c
MxU32 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,10 @@ MxS32 LegoRaceCar::g_unk0x100f0b88 = 0;
// GLOBAL: BETA10 0x101f5f98
MxBool LegoRaceCar::g_unk0x100f0b8c = TRUE;
// Initialized at LEGO1 0x10012db0
// GLOBAL: LEGO1 0x10102af0
Mx3DPointFloat LegoRaceCar::g_unk0x10102af0 = Mx3DPointFloat(0.0f, 2.0f, 0.0f);
// FUNCTION: LEGO1 0x10012950
LegoRaceCar::LegoRaceCar()
{
@ -260,7 +305,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 +350,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 +376,79 @@ 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_unk0x10102af0);
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;
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

View file

@ -60,7 +60,9 @@ public:
);
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; }
void SetEntity(LegoEntity* p_entity) { m_entity = p_entity; }

View file

@ -16,7 +16,9 @@ public:
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]; }
// FUNCTION: LEGO1 0x10002850

View file

@ -14,8 +14,10 @@ public:
MxLong GetRealTime();
// FUNCTION: BETA10 0x10017810
MxLong GetTime()
{
// Note that the BETA10 implementation differs - it only consists of the second branch of this `if` call
if (this->m_isRunning) {
return g_lastTimeTimerStarted;
}

View file

@ -39,7 +39,9 @@ public:
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]; }
const float* GetWorldUp() const { return m_local2world[1]; }