This commit is contained in:
Christian Semmler 2024-08-08 13:07:47 -07:00
commit 03781da2ed
No known key found for this signature in database
GPG Key ID: 086DAA1360BEEE5C
38 changed files with 794 additions and 186 deletions

View File

@ -389,7 +389,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
@ -414,8 +413,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

View File

@ -139,3 +139,7 @@ const char* g_strBMP_ISMAP = "BMP_ISMAP";
// GLOBAL: LEGO1 0x101020e4
// STRING: LEGO1 0x10101eac
const char* g_parseExtraTokens = ":;";
// GLOBAL: LEGO1 0x100f0c14
// STRING: LEGO1 0x100f0c04
const char* g_strHIT_ACTOR_SOUND = "HIT_ACTOR_SOUND";

View File

@ -38,5 +38,6 @@ extern const char* g_strDB_CREATE;
extern const char* g_strPERMIT_NAVIGATE;
extern const char* g_strPATH;
extern const char* g_strCOLLIDEBOX;
extern const char* g_strHIT_ACTOR_SOUND;
#endif // DEFINE_H

View File

@ -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 @@ class CarRaceState : public RaceState {
}
// 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 @@ class CarRaceState : public RaceState {
};
// 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 @@ class CarRace : public LegoRace {
}
// 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);

View File

@ -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(LegoPathBoundary* p_boundary, LegoEdge* p_edge) override; // vtable+0x1c
// SYNTHETIC: LEGO1 0x10081d50
// LegoJetskiRaceActor::`scalar deleting destructor'

View File

@ -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; }

View File

@ -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

View File

@ -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

View File

@ -8,12 +8,16 @@ class Matrix4;
// VTABLE: LEGO1 0x100d5b78 LegoAnimActor
// VTABLE: LEGO1 0x100d5b88 LegoPathActor
// VTABLE: LEGO1 0x100d5c54 LegoRaceActor
// VTABLE: BETA10 0x101be380 LegoAnimActor
// VTABLE: BETA10 0x101be398 LegoPathActor
// VTABLE: BETA10 0x101be488 LegoRaceActor
// SIZE 0x180
class LegoRaceActor : public virtual LegoAnimActor {
public:
LegoRaceActor();
// FUNCTION: LEGO1 0x10014b00
// FUNCTION: BETA10 0x100aaae0
const char* ClassName() const override // vtable+0x0c
{
// STRING: LEGO1 0x100f0bf4
@ -26,9 +30,9 @@ class LegoRaceActor : public virtual LegoAnimActor {
return !strcmp(p_name, LegoRaceActor::ClassName()) || LegoAnimActor::IsA(p_name);
}
MxS32 VTable0x68(Vector3&, Vector3&, Vector3&) override; // vtable+0x68
MxU32 VTable0x90(float, Matrix4&) override; // vtable+0x90
MxResult VTable0x94(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94
MxS32 VTable0x68(Vector3& p_v1, Vector3& p_v2, Vector3& p_v3) override; // vtable+0x68
MxU32 VTable0x90(float p_float, Matrix4& p_matrix) override; // vtable+0x90
MxResult VTable0x94(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94
// FUNCTION: LEGO1 0x10014aa0
virtual MxResult FUN_10014aa0() { return SUCCESS; }
@ -40,7 +44,15 @@ class LegoRaceActor : public virtual LegoAnimActor {
// LegoRaceActor::`scalar deleting destructor'
private:
undefined4 m_unk0x08; // 0x08
MxFloat m_unk0x08; // 0x08
static Mx3DPointFloat g_unk0x10102b08;
};
// GLOBAL: LEGO1 0x100d5b68
// LegoRaceActor::`vbtable'{for `LegoRaceActor'}
// GLOBAL: LEGO1 0x100d5b60
// LegoRaceActor::`vbtable'{for `LegoAnimActor'}
#endif // LEGORACEACTOR_H

View File

@ -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

View File

@ -7,12 +7,17 @@
// VTABLE: LEGO1 0x100da0c8 LegoAnimActor
// VTABLE: LEGO1 0x100da0d8 LegoPathActor
// VTABLE: LEGO1 0x100da1a8 LegoCarRaceActor
// VTABLE: BETA10 0x101bea74 LegoRaceActor
// VTABLE: BETA10 0x101bea78 LegoAnimActor
// VTABLE: BETA10 0x101bea90 LegoPathActor
// VTABLE: BETA10 0x101beb80 LegoCarRaceActor
// SIZE 0x1a0
class LegoCarRaceActor : public virtual LegoRaceActor {
public:
LegoCarRaceActor();
// FUNCTION: LEGO1 0x10081660
// FUNCTION: BETA10 0x100aab10
const char* ClassName() const override // vtable+0x0c
{
// STRING: LEGO1 0x100f0568
@ -20,6 +25,7 @@ class LegoCarRaceActor : public virtual LegoRaceActor {
}
// FUNCTION: LEGO1 0x10081680
// FUNCTION: BETA10 0x100aa9e0
MxBool IsA(const char* p_name) const override // vtable+0x10
{
return !strcmp(p_name, LegoCarRaceActor::ClassName()) || LegoRaceActor::IsA(p_name);
@ -38,7 +44,7 @@ class LegoCarRaceActor : public virtual LegoRaceActor {
override; // vtable+0x98
MxResult VTable0x9c() override; // vtable+0x9c
virtual void FUN_10080590(float);
virtual void FUN_10080590(float p_float);
// FUNCTION: LEGO1 0x10012bb0
virtual void FUN_10012bb0(float p_unk0x14) { m_unk0x14 = p_unk0x14; }
@ -58,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(LegoPathBoundary* p_boundary, LegoEdge* p_edge); // vtable+0x1c
// SYNTHETIC: LEGO1 0x10012c30
// LegoCarRaceActor::`vbase destructor'
@ -67,12 +73,30 @@ class LegoCarRaceActor : public virtual LegoRaceActor {
// LegoCarRaceActor::`scalar deleting destructor'
protected:
float m_unk0x08; // 0x08
MxU8 m_unk0x0c; // 0x0c
float m_unk0x10; // 0x10
float m_unk0x14; // 0x14
float m_unk0x18; // 0x18
undefined4 m_unk0x1c; // 0x1c
MxFloat m_unk0x08; // 0x08
MxU8 m_unk0x0c; // 0x0c
// Could be a multiplier for the maximum speed when going straight
MxFloat m_unk0x10; // 0x10
// Could be the acceleration
MxFloat m_unk0x14; // 0x14
MxFloat m_unk0x18; // 0x18
// Could be the current timestamp for time-based movement
MxFloat m_unk0x1c; // 0x1c
static MxFloat g_unk0x100f7aec;
};
// GLOBAL: LEGO1 0x100da0b0
// LegoCarRaceActor::`vbtable'
// GLOBAL: LEGO1 0x100da0a8
// LegoCarRaceActor::`vbtable'{for `LegoAnimActor'}
// GLOBAL: LEGO1 0x100da098
// LegoCarRaceActor::`vbtable'{for `LegoRaceActor'}
#endif // LEGOCARRACEACTOR_H

View File

@ -5,6 +5,8 @@
#include "islepathactor.h"
#include "legostate.h"
class MxEndActionNotificationParam;
// VTABLE: LEGO1 0x100d7fd8
// SIZE 0x28
class TowTrackMissionState : public LegoState {
@ -48,7 +50,7 @@ class TowTrackMissionState : public LegoState {
// TowTrackMissionState::`scalar deleting destructor'
undefined4 m_unk0x08; // 0x08
MxS32 m_unk0x0c; // 0x0c
MxLong m_unk0x0c; // 0x0c
MxBool m_unk0x10; // 0x10
MxS16 m_unk0x12; // 0x12
MxS16 m_unk0x14; // 0x14
@ -90,29 +92,31 @@ class TowTrack : public IslePathActor {
MxLong HandleEndAnim(LegoEndAnimNotificationParam& p_param) override; // vtable+0xd8
MxLong HandlePathStruct(LegoPathStructNotificationParam& p_param) override; // vtable+0xdc
void Exit() override; // vtable+0xe4
virtual MxLong HandleEndAction(MxEndActionNotificationParam& p_param); // vtable+0xf0
void CreateState();
void FUN_1004dab0();
void FUN_1004dad0();
void FUN_1004db10();
void ActivateSceneActions();
void StopActions();
void FUN_1004dbe0();
// SYNTHETIC: LEGO1 0x1004c950
// TowTrack::`scalar deleting destructor'
private:
void FUN_1004dcf0(IsleScript::Script);
void Leave();
void PlayAction(IsleScript::Script p_objectId);
undefined4 m_unk0x160; // 0x160
TowTrackMissionState* m_state; // 0x164
MxS16 m_unk0x168; // 0x168
MxS16 m_unk0x16a; // 0x16a
MxS16 m_unk0x16c; // 0x16c
MxS16 m_unk0x16e; // 0x16e
MxS32 m_unk0x170; // 0x170
MxS32 m_unk0x174; // 0x174
MxFloat m_fuel; // 0x178
MxFloat m_time; // 0x17c
undefined4 m_unk0x160; // 0x160
TowTrackMissionState* m_state; // 0x164
MxS16 m_unk0x168; // 0x168
MxS16 m_actorId; // 0x16a
MxS16 m_unk0x16c; // 0x16c
MxS16 m_unk0x16e; // 0x16e
IsleScript::Script m_lastAction; // 0x170
MxS32 m_unk0x174; // 0x174
MxFloat m_fuel; // 0x178
MxFloat m_time; // 0x17c
};
#endif // TOWTRACK_H

View File

@ -1,27 +1,37 @@
#include "towtrack.h"
#include "isle.h"
#include "isle_actions.h"
#include "jukebox_actions.h"
#include "legoanimationmanager.h"
#include "legocontrolmanager.h"
#include "legogamestate.h"
#include "legonavcontroller.h"
#include "legoutils.h"
#include "legovariables.h"
#include "legoworld.h"
#include "misc.h"
#include "mxbackgroundaudiomanager.h"
#include "mxmisc.h"
#include "mxsoundpresenter.h"
#include "mxtimer.h"
#include "mxtransitionmanager.h"
#include "mxvariabletable.h"
DECOMP_SIZE_ASSERT(TowTrack, 0x180)
DECOMP_SIZE_ASSERT(TowTrackMissionState, 0x28)
// Flags used in isle.cpp
extern MxU32 g_isleFlags;
// FUNCTION: LEGO1 0x1004c720
TowTrack::TowTrack()
{
m_unk0x168 = 0;
m_unk0x16a = -1;
m_actorId = -1;
m_state = NULL;
m_unk0x16c = 0;
m_unk0x170 = -1;
m_lastAction = IsleScript::c_noneIsle;
m_unk0x16e = 0;
m_unk0x174 = -1;
m_maxLinearVel = 40.0;
@ -85,7 +95,7 @@ void TowTrack::VTable0x70(float p_time)
VariableTable()->SetVariable(g_varTOWFUEL, buf);
if (p_time - m_state->m_unk0x0c > 100000.0f && m_state->m_unk0x08 == 1 && !m_state->m_unk0x10) {
FUN_1004dcf0(IsleScript::c_Avo909In_PlayWav);
PlayAction(IsleScript::c_Avo909In_PlayWav);
m_state->m_unk0x10 = TRUE;
}
}
@ -100,15 +110,43 @@ void TowTrack::CreateState()
}
}
// STUB: LEGO1 0x1004cc80
// FUNCTION: LEGO1 0x1004cc80
MxLong TowTrack::Notify(MxParam& p_param)
{
// TODO
return 0;
MxLong result = 0;
switch (((MxNotificationParam&) p_param).GetNotification()) {
case c_notificationType0:
result = HandleNotification0();
break;
case c_notificationEndAction:
result = HandleEndAction((MxEndActionNotificationParam&) p_param);
break;
case c_notificationClick:
result = HandleClick();
break;
case c_notificationControl:
result = HandleControl((LegoControlManagerNotificationParam&) p_param);
break;
case c_notificationEndAnim:
result = HandleEndAnim((LegoEndAnimNotificationParam&) p_param);
break;
case c_notificationPathStruct:
result = HandlePathStruct((LegoPathStructNotificationParam&) p_param);
break;
}
return result;
}
// STUB: LEGO1 0x1004cd30
// FUNCTION: LEGO1 0x1004cd30
MxLong TowTrack::HandleEndAnim(LegoEndAnimNotificationParam& p_param)
{
return 1;
}
// STUB: LEGO1 0x1004cd40
MxLong TowTrack::HandleEndAction(MxEndActionNotificationParam& p_param)
{
// TODO
return 0;
@ -121,54 +159,176 @@ MxLong TowTrack::HandlePathStruct(LegoPathStructNotificationParam& p_param)
return 0;
}
// STUB: LEGO1 0x1004d690
// FUNCTION: LEGO1 0x1004d690
MxLong TowTrack::HandleClick()
{
// TODO
return 0;
if (((Act1State*) GameState()->GetState("Act1State"))->m_unk0x018 != 8) {
return 1;
}
if (m_state->m_unk0x08 == 3) {
return 1;
}
FUN_10015820(TRUE, 0);
((Isle*) CurrentWorld())->SetDestLocation(LegoGameState::e_towtrack);
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
if (UserActor()->GetActorId() != GameState()->GetActorId()) {
((IslePathActor*) UserActor())->Exit();
}
m_time = Timer()->GetTime();
m_actorId = UserActor()->GetActorId();
Enter();
InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_TowTrackDashboard, NULL);
ControlManager()->Register(this);
if (m_state->m_unk0x08 == 0) {
return 1;
}
if (m_state->m_unk0x08 == 2) {
SpawnPlayer(LegoGameState::e_unk52, TRUE, 0);
FindROI("rcred")->SetVisibility(FALSE);
}
else {
SpawnPlayer(LegoGameState::e_unk28, TRUE, 0);
m_lastAction = IsleScript::c_noneIsle;
m_unk0x174 = -1;
m_state->m_unk0x0c = Timer()->GetTime();
m_state->m_unk0x10 = FALSE;
InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_wns057rd_RunAnim, NULL);
InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_wns048p1_RunAnim, NULL);
InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_wns049p1_RunAnim, NULL);
InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_wns051bd_RunAnim, NULL);
InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_wns053pr_RunAnim, NULL);
InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_wns045di_RunAnim, NULL);
InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_pns123pr_RunAnim, NULL);
}
return 1;
}
// STUB: LEGO1 0x1004d8f0
// FUNCTION: LEGO1 0x1004d8f0
void TowTrack::Exit()
{
// TODO
GameState()->m_currentArea = LegoGameState::e_garageExterior;
StopActions();
FUN_1004dbe0();
Leave();
}
// STUB: LEGO1 0x1004d9e0
// FUNCTION: LEGO1 0x1004d920
void TowTrack::Leave()
{
IslePathActor::Exit();
CurrentWorld()->RemoveActor(this);
m_roi->SetVisibility(FALSE);
RemoveFromCurrentWorld(*g_isleScript, IsleScript::c_TowTrackDashboard_Bitmap);
RemoveFromCurrentWorld(*g_isleScript, IsleScript::c_TowTrackArms_Ctl);
RemoveFromCurrentWorld(*g_isleScript, IsleScript::c_TowHorn_Ctl);
RemoveFromCurrentWorld(*g_isleScript, IsleScript::c_TowHorn_Sound);
RemoveFromCurrentWorld(*g_isleScript, IsleScript::c_TowInfo_Ctl);
RemoveFromCurrentWorld(*g_isleScript, IsleScript::c_TowSpeedMeter);
RemoveFromCurrentWorld(*g_isleScript, IsleScript::c_TowFuelMeter);
ControlManager()->Unregister(this);
}
// FUNCTION: LEGO1 0x1004d9e0
MxLong TowTrack::HandleControl(LegoControlManagerNotificationParam& p_param)
{
// TODO
return 0;
MxLong result = 0;
if (p_param.GetUnknown0x28() == 1) {
switch (p_param.GetClickedObjectId()) {
case IsleScript::c_TowTrackArms_Ctl:
Exit();
GameState()->m_currentArea = LegoGameState::e_unk66;
result = 1;
break;
case IsleScript::c_TowInfo_Ctl:
((Isle*) CurrentWorld())->SetDestLocation(LegoGameState::e_infomain);
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
Exit();
GameState()->m_currentArea = LegoGameState::e_unk66;
result = 1;
break;
case IsleScript::c_TowHorn_Ctl:
MxSoundPresenter* presenter = (MxSoundPresenter*) CurrentWorld()->Find("MxSoundPresenter", "TowHorn_Sound");
presenter->Enable(p_param.GetUnknown0x28());
break;
}
}
return result;
}
// STUB: LEGO1 0x1004dab0
// FUNCTION: LEGO1 0x1004dab0
void TowTrack::FUN_1004dab0()
{
// TODO
m_state->m_unk0x08 = 1;
HandleClick();
}
// STUB: LEGO1 0x1004dad0
void TowTrack::FUN_1004dad0()
// FUNCTION: LEGO1 0x1004dad0
void TowTrack::ActivateSceneActions()
{
// TODO
PlayMusic(JukeboxScript::c_JBMusic2);
if (m_state->m_unk0x08 != 0) {
if (m_state->m_unk0x08 == 2) {
PlayAction(IsleScript::c_wrt082na_PlayWav);
}
else {
PlayAction(IsleScript::c_wgs032nu_PlayWav);
}
}
}
// STUB: LEGO1 0x1004db10
void TowTrack::FUN_1004db10()
// FUNCTION: LEGO1 0x1004db10
void TowTrack::StopActions()
{
// TODO
InvokeAction(Extra::e_stop, *g_isleScript, IsleScript::c_wns050p1_RunAnim, NULL);
InvokeAction(Extra::e_stop, *g_isleScript, IsleScript::c_wns046mg_RunAnim, NULL);
InvokeAction(Extra::e_stop, *g_isleScript, IsleScript::c_wns057rd_RunAnim, NULL);
InvokeAction(Extra::e_stop, *g_isleScript, IsleScript::c_wns048p1_RunAnim, NULL);
InvokeAction(Extra::e_stop, *g_isleScript, IsleScript::c_wns049p1_RunAnim, NULL);
InvokeAction(Extra::e_stop, *g_isleScript, IsleScript::c_wns051bd_RunAnim, NULL);
InvokeAction(Extra::e_stop, *g_isleScript, IsleScript::c_wns053pr_RunAnim, NULL);
InvokeAction(Extra::e_stop, *g_isleScript, IsleScript::c_wns045di_RunAnim, NULL);
InvokeAction(Extra::e_stop, *g_isleScript, IsleScript::c_pns123pr_RunAnim, NULL);
}
// STUB: LEGO1 0x1004dbe0
// FUNCTION: LEGO1 0x1004dbe0
void TowTrack::FUN_1004dbe0()
{
// TODO
if (m_lastAction != -1) {
InvokeAction(Extra::e_stop, *g_isleScript, m_lastAction, NULL);
}
((Act1State*) GameState()->GetState("Act1State"))->m_unk0x018 = 0;
m_state->m_unk0x08 = 0;
g_isleFlags |= Isle::c_playMusic;
AnimationManager()->EnableCamAnims(TRUE);
AnimationManager()->FUN_1005f6d0(TRUE);
m_state->m_unk0x0c = INT_MIN;
m_state->m_unk0x10 = FALSE;
m_state = NULL;
m_unk0x16c = 0;
m_unk0x16e = 0;
}
// STUB: LEGO1 0x1004dcf0
void TowTrack::FUN_1004dcf0(IsleScript::Script)
// FUNCTION: LEGO1 0x1004dcf0
void TowTrack::PlayAction(IsleScript::Script p_objectId)
{
// TODO
if (p_objectId != -1) {
InvokeAction(Extra::e_start, *g_isleScript, p_objectId, NULL);
}
m_lastAction = p_objectId;
BackgroundAudioManager()->LowerVolume();
}
// FUNCTION: LEGO1 0x1004dd30

View File

@ -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"

View File

@ -61,14 +61,18 @@ LegoAnimationManager* AnimationManager()
}
// FUNCTION: LEGO1 0x10015780
// FUNCTION: BETA10 0x100e49b8
LegoNavController* NavController()
{
assert(LegoOmni::GetInstance());
return LegoOmni::GetInstance()->GetNavController();
}
// FUNCTION: LEGO1 0x10015790
// FUNCTION: BETA10 0x100e49ff
LegoPathActor* UserActor()
{
assert(LegoOmni::GetInstance());
return LegoOmni::GetInstance()->GetUserActor();
}

View File

@ -1,71 +0,0 @@
#include "legocarraceactor.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
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");
}
// STUB: LEGO1 0x10080590
void LegoCarRaceActor::FUN_10080590(float)
{
}
// STUB: LEGO1 0x10080740
void LegoCarRaceActor::VTable0x1c()
{
}
// STUB: LEGO1 0x10080b40
void LegoCarRaceActor::SwitchBoundary(LegoPathBoundary*& p_boundary, LegoUnknown100db7f4*& p_edge, float& p_unk0xe4)
{
// TODO
}
// 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;
}

View File

@ -12,9 +12,10 @@ LegoJetskiRaceActor::LegoJetskiRaceActor()
}
// STUB: LEGO1 0x10081120
void LegoJetskiRaceActor::VTable0x1c()
MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edge)
{
// TODO
return 0;
}
// STUB: LEGO1 0x10081550

View File

@ -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;

View File

@ -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++) {

View File

@ -1,7 +1,20 @@
#include "legoraceactor.h"
#include "define.h"
#include "legocachesoundmanager.h"
#include "legosoundmanager.h"
#include "misc.h"
#include "mxmisc.h"
#include "mxtimer.h"
#include "mxvariabletable.h"
#include "roi/legoroi.h"
DECOMP_SIZE_ASSERT(LegoRaceActor, 0x180)
// Initialized at LEGO1 0x100145a0
// GLOBAL: LEGO1 0x10102b08
Mx3DPointFloat LegoRaceActor::g_unk0x10102b08 = Mx3DPointFloat(0.0, 2.0, 0.0);
// FUNCTION: LEGO1 0x100145d0
LegoRaceActor::LegoRaceActor()
{
@ -9,23 +22,98 @@ LegoRaceActor::LegoRaceActor()
m_unk0x08 = 0;
}
// STUB: LEGO1 0x10014750
MxS32 LegoRaceActor::VTable0x68(Vector3&, Vector3&, Vector3&)
// FUNCTION: LEGO1 0x10014750
// FUNCTION: BETA10 0x100c9bba
MxS32 LegoRaceActor::VTable0x68(Vector3& p_v1, Vector3& p_v2, Vector3& p_v3)
{
// TODO
MxS32 result = LegoPathActor::VTable0x68(p_v1, p_v2, p_v3);
if (m_userNavFlag && result) {
MxLong time = Timer()->GetTime();
if (time - g_unk0x100f3308 > 1000) {
g_unk0x100f3308 = time;
const char* soundKey = VariableTable()->GetVariable(g_strHIT_ACTOR_SOUND);
if (soundKey && *soundKey) {
SoundManager()->GetCacheSoundManager()->Play(soundKey, NULL, FALSE);
}
}
}
return result;
}
// FUNCTION: LEGO1 0x100147f0
// FUNCTION: BETA10 0x100c9c93
MxU32 LegoRaceActor::VTable0x90(float p_float, Matrix4& p_transform)
{
// Note: Code duplication with LegoExtraActor::VTable0x90
switch (m_state) {
case 0:
case 1:
return 1;
case 2:
m_unk0x08 = p_float + 2000.0f;
m_state = 3;
m_actorTime += (p_float - m_lastTime) * m_worldSpeed;
m_lastTime = p_float;
return 0;
case 3:
assert(!m_userNavFlag);
Vector3 positionRef(p_transform[3]);
p_transform = m_roi->GetLocal2World();
if (m_unk0x08 > p_float) {
Mx3DPointFloat position;
position = positionRef;
positionRef.Clear();
p_transform.RotateX(0.6);
positionRef = position;
m_actorTime += (p_float - m_lastTime) * m_worldSpeed;
m_lastTime = p_float;
VTable0x74(p_transform);
return 0;
}
else {
m_state = 0;
m_unk0x08 = 0;
((Vector3&) positionRef).Sub(g_unk0x10102b08);
m_roi->FUN_100a58f0(p_transform);
return 1;
}
}
return 0;
}
// STUB: LEGO1 0x100147f0
MxU32 LegoRaceActor::VTable0x90(float, Matrix4&)
{
// TODO
return 0;
}
// STUB: LEGO1 0x10014a00
// FUNCTION: LEGO1 0x10014a00
// FUNCTION: BETA10 0x100c9f5c
MxResult LegoRaceActor::VTable0x94(LegoPathActor* p_actor, MxBool p_bool)
{
// TODO
if (!p_actor->GetUserNavFlag()) {
if (p_actor->GetState()) {
return FAILURE;
}
if (p_bool) {
LegoROI* roi = p_actor->GetROI(); // name verified by BETA10 0x100c9fcf
assert(roi);
MxMatrix matr;
matr = roi->GetLocal2World();
Vector3(matr[3]).Add(g_unk0x10102b08);
roi->FUN_100a58f0(matr);
p_actor->SetState(2);
}
}
return 0;
}

View File

@ -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;
}
@ -405,6 +405,7 @@ void LegoRaceCar::VTable0x70(float p_float)
// FUNCTION: BETA10 0x100cbb84
MxResult LegoRaceCar::VTable0x94(LegoPathActor* p_actor, MxBool p_bool)
{
// Note: Code duplication with LegoRaceActor::VTable0x94
if (!p_actor->GetUserNavFlag()) {
if (p_actor->GetState()) {
return FAILURE;

View File

@ -0,0 +1,301 @@
#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"
#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;
// 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(LegoPathBoundary* p_boundary, 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);
LERP3(pointUnknown, *v1, *v2, 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);
}
// FUNCTION: LEGO1 0x10080b70
// FUNCTION: BETA10 0x1000366b
void LegoCarRaceActor::VTable0x70(float p_float)
{
// 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);
}
}
// FUNCTION: LEGO1 0x10080be0
// FUNCTION: BETA10 0x100cdc54
MxResult LegoCarRaceActor::VTable0x9c()
{
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,
Vector3& p_v2,
float p_f1,
float p_f2,
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;
}

View File

@ -1,6 +1,6 @@
#include "raceskel.h"
#include <cassert>
#include <assert.h>
DECOMP_SIZE_ASSERT(RaceSkel, 0x178)

View File

@ -1036,7 +1036,7 @@ MxLong Isle::HandleTransitionEnd()
FUN_10032d30(IsleScript::c_TowFuelMeter, JukeboxScript::c_MusicTheme1, NULL, TRUE);
if (!m_act1state->m_unk0x01f) {
m_towtrack->FUN_1004dad0();
m_towtrack->ActivateSceneActions();
}
break;
case LegoGameState::e_jetski:
@ -1196,7 +1196,7 @@ MxBool Isle::Escape()
break;
case 8:
if (UserActor() != NULL && !UserActor()->IsA("TowTrack")) {
m_towtrack->FUN_1004db10();
m_towtrack->StopActions();
m_towtrack->FUN_1004dbe0();
}
break;
@ -1250,7 +1250,7 @@ void Isle::FUN_10033350()
if (m_act1state->m_unk0x018 == 8) {
if (UserActor() != NULL && !UserActor()->IsA("TowTrack")) {
m_towtrack->FUN_1004db10();
m_towtrack->StopActions();
m_towtrack->FUN_1004dbe0();
}
}

View File

@ -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;
}
}

View File

@ -5,6 +5,8 @@
#include "legowegedge.h"
#include "mxgeometry/mxgeometry3d.h"
#include <assert.h>
// VTABLE: LEGO1 0x100db7f4
// SIZE 0x40
struct LegoUnknown100db7f4 : public LegoEdge {
@ -28,6 +30,10 @@ struct LegoUnknown100db7f4 : public LegoEdge {
p_point[2] = -m_unk0x28[2];
}
else {
// clang-format off
// FIXME: There is no * dereference in the original assertion
assert(p_f.IsEqual( *m_faceB ));
// clang-format on
p_point = m_unk0x28;
}

View File

@ -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;

View File

@ -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,11 +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;
@ -32,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

View File

@ -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

View File

@ -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;

View File

@ -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:

View File

@ -1,18 +1,23 @@
#ifdef 0
// LIBRARY: LEGO1 0x100cd782
// LIBRARY: BETA10 0x1015fb82
// _SmackGetSizeTables
// LIBRARY: LEGO1 0x100cd7e8
// LIBRARY: BETA10 0x1015fbe8
// _SmackDoTables
// LIBRARY: LEGO1 0x100cda83
// LIBRARY: BETA10 0x1015fe83
// _SmackDoFrameToBuffer
// LIBRARY: LEGO1 0x100d052c
// LIBRARY: BETA10 0x1016292c
// _SmackGetSizeDeltas
// LIBRARY: LEGO1 0x100d0543
// LIBRARY: BETA10 0x10162943
// _SmackGetRect
#endif

View File

@ -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); }

View File

@ -90,7 +90,7 @@ class MxBitmap : public MxCore {
// DECOMP: This could be a free function. It is static here because it has no
// reference to "this". In the beta it is called in two places:
// 1. GetBmiHeightAbs
// 2. at 0x101523b9, in reference to BITMAPINFOHEADER.biHeight
// 2. MxSmack::LoadFrame
// FUNCTION: BETA10 0x1002c690
static MxLong HeightAbs(MxLong p_value) { return p_value > 0 ? p_value : -p_value; }

View File

@ -8,6 +8,7 @@ DECOMP_SIZE_ASSERT(SmackTag, 0x390);
DECOMP_SIZE_ASSERT(MxSmack, 0x6b8);
// FUNCTION: LEGO1 0x100c5a90
// FUNCTION: BETA10 0x10151e70
MxResult MxSmack::LoadHeader(MxU8* p_data, MxU32 p_length, MxSmack* p_mxSmack)
{
p_mxSmack->m_smk = smk_open_memory_stream(p_data, p_length);
@ -21,6 +22,7 @@ MxResult MxSmack::LoadHeader(MxU8* p_data, MxU32 p_length, MxSmack* p_mxSmack)
}
// FUNCTION: LEGO1 0x100c5d40
// FUNCTION: BETA10 0x10152298
void MxSmack::Destroy(MxSmack* p_mxSmack)
{
if (p_mxSmack->m_smk != NULL) {
@ -28,13 +30,8 @@ void MxSmack::Destroy(MxSmack* p_mxSmack)
}
}
// This should be refactored to somewhere else
inline MxLong AbsFlipped(MxLong p_value)
{
return p_value > 0 ? p_value : -p_value;
}
// FUNCTION: LEGO1 0x100c5db0
// FUNCTION: BETA10 0x10152391
MxResult MxSmack::LoadFrame(
MxBITMAPINFO* p_bitmapInfo,
MxU8* p_bitmapData,
@ -45,7 +42,7 @@ MxResult MxSmack::LoadFrame(
MxRectList* p_list
)
{
p_bitmapInfo->m_bmiHeader.biHeight = -AbsFlipped(p_bitmapInfo->m_bmiHeader.biHeight);
p_bitmapInfo->m_bmiHeader.biHeight = -MxBitmap::HeightAbs(p_bitmapInfo->m_bmiHeader.biHeight);
unsigned long w, h;
smk_info_video(p_mxSmack->m_smk, &w, &h, NULL);
@ -58,8 +55,6 @@ MxResult MxSmack::LoadFrame(
smk_next(p_mxSmack->m_smk);
}
memcpy(p_bitmapData, smk_get_video(p_mxSmack->m_smk), w * h);
unsigned char frameType;
smk_info_all(p_mxSmack->m_smk, NULL, NULL, &frameType, NULL);
p_paletteChanged = frameType & 1;

View File

@ -122,6 +122,7 @@ class Matrix4 {
}
}
// FUNCTION: BETA10 0x1001c6a0
void RotateX(const float& p_angle)
{
float s = sin(p_angle);

View File

@ -42,8 +42,12 @@ class OrientableROI : public ROI {
// FUNCTION: BETA10 0x1000fbf0
const Matrix4& GetLocal2World() const { return m_local2world; }
// FUNCTION: BETA10 0x10011750
const float* GetWorldPosition() const { return m_local2world[3]; }
// FUNCTION: BETA10 0x10011780
const float* GetWorldDirection() const { return m_local2world[2]; }
const float* GetWorldUp() const { return m_local2world[1]; }
OrientableROI* GetParentROI() const { return m_parentROI; }

View File

@ -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:
@ -162,6 +171,7 @@ class Vector2 {
};
// VTABLE: LEGO1 0x100d4518
// VTABLE: BETA10 0x101b8398
// SIZE 0x08
class Vector3 : public Vector2 {
public:
@ -187,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
@ -260,9 +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 0x1000132a
void Clear() override { memset(m_data, 0, sizeof(float) * 3); } // vtable+0x2c
// FUNCTION: LEGO1 0x10003bd0