merge from isledecomp/isle

This commit is contained in:
Christian Semmler 2024-10-26 08:06:31 -07:00
commit bf5379992e
No known key found for this signature in database
GPG key ID: 086DAA1360BEEE5C
54 changed files with 1133 additions and 159 deletions

2
.gitignore vendored
View file

@ -1,3 +1,5 @@
reccmp-user.yml
reccmp-build.yml
Debug/
Release/
*.ncb

View file

@ -16,6 +16,14 @@ class MxActionNotificationParam;
// SIZE 0x50
class LegoVehicleBuildState : public LegoState {
public:
enum AnimationState {
e_unknown0 = 0,
e_entering = 1,
e_unknown2 = 2,
e_cutscene = 3,
e_exiting = 6
};
LegoVehicleBuildState(const char* p_classType);
// FUNCTION: LEGO1 0x10025ff0
@ -46,11 +54,7 @@ class LegoVehicleBuildState : public LegoState {
// * LegoJetskiBuildState
MxString m_className; // 0x38
// Known States:
// * 1 == enter(ing) build screen
// * 3 == cutscene/dialogue
// * 6 == exit(ing) build screen
MxU32 m_animationState; // 0x48
AnimationState m_animationState; // 0x48
undefined m_unk0x4c; // 0x4c
MxBool m_unk0x4d; // 0x4d
MxBool m_unk0x4e; // 0x4e
@ -103,6 +107,7 @@ class LegoCarBuild : public LegoWorld {
MxFloat p_param4[2]
); // vtable+0x80
MxS16 GetPlacedPartCount();
void InitPresenters();
void FUN_10022f30();
void FUN_10023130(MxLong p_x, MxLong p_y);
@ -113,7 +118,7 @@ class LegoCarBuild : public LegoWorld {
undefined4 FUN_100246e0(MxLong p_x, MxLong p_y);
MxS32 FUN_10024850(MxLong p_x, MxLong p_y);
undefined4 FUN_10024890(LegoEventNotificationParam* p_param);
void FUN_10024c20(LegoEventNotificationParam* p_param);
undefined4 FUN_10024c20(LegoEventNotificationParam* p_param);
void FUN_10024ef0();
void FUN_10024f50();
void FUN_10024f70(MxBool p_enabled);
@ -127,6 +132,9 @@ class LegoCarBuild : public LegoWorld {
void FUN_10025e40();
MxS32 FUN_10025ee0(undefined4 p_param1);
// FUNCTION: BETA10 0x100735b0
void SetUnknown0x258(LegoCarBuildAnimPresenter* p_unk0x258) { m_unk0x258 = p_unk0x258; }
// SYNTHETIC: LEGO1 0x10022a60
// LegoCarBuild::`scalar deleting destructor'
@ -194,7 +202,7 @@ class LegoCarBuild : public LegoWorld {
// variable name verified by BETA10 0x1006cba7
LegoGameState::Area m_destLocation; // 0x334
undefined4 m_unk0x338; // 0x338
MxPresenter* m_unk0x338; // 0x338
MxControlPresenter* m_unk0x33c; // 0x33c
undefined4 m_unk0x340; // 0x340
undefined4 m_unk0x344; // 0x344
@ -202,7 +210,7 @@ class LegoCarBuild : public LegoWorld {
static MxS16 g_unk0x100f11cc;
static MxFloat g_unk0x100d65a4;
static MxFloat g_unk0x100d65a8;
static MxFloat g_rotationAngleStepYAxis;
};
#endif // LEGOCARBUILD_H

View file

@ -9,11 +9,28 @@
// SIZE 0x150
class LegoCarBuildAnimPresenter : public LegoAnimPresenter {
public:
enum {
c_bit1 = 0x01
};
// SIZE 0x0c
struct UnknownListEntry {
LegoChar* m_unk0x00; // 0x00
LegoChar* m_unk0x04; // 0x04
undefined m_unk0x08[4]; // 0x08
// FUNCTION: LEGO1 0x100795c0
// FUNCTION: BETA10 0x10073850
UnknownListEntry()
{
m_name = NULL;
m_wiredName = NULL;
m_unk0x08 = 0;
}
// variable name verified by BETA10 0x10071b56
LegoChar* m_name; // 0x00
// variable name verified by BETA10 0x100719f0
LegoChar* m_wiredName; // 0x04
undefined2 m_unk0x08; // 0x08
};
LegoCarBuildAnimPresenter();
@ -45,14 +62,26 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter {
void EndAction() override; // vtable+0x40
void PutFrame() override; // vtable+0x6c
void FUN_10079920(float p_param1);
void FUN_10079050(MxS16 p_index);
void SwapNodesByName(LegoChar* p_param1, LegoChar* p_param2);
void FUN_10079160();
void FUN_100795d0(LegoChar* p_param);
void FUN_10079680(LegoChar* p_param);
LegoAnimNodeData* FindNodeDataByName(LegoTreeNode* p_treeNode, const LegoChar* p_name);
LegoTreeNode* FindNodeByName(LegoTreeNode* p_treeNode, const LegoChar* p_name);
void RotateAroundYAxis(MxFloat p_angle);
MxBool FUN_10079c30(const LegoChar* p_name);
MxBool FUN_10079ca0(const LegoChar* p_name);
MxBool FUN_10079cf0(const LegoChar* p_string);
MxBool PartIsPlaced(const LegoChar* p_name);
void FUN_10079a90();
MxBool StringEqualsPlatform(const LegoChar* p_string);
MxBool StringEqualsShelf(const LegoChar* p_string);
MxBool StringEndsOnY(const LegoChar* p_string);
MxBool StringEndsOnZero(const LegoChar* p_string);
// FUNCTION: BETA10 0x10070180
void SetUnknown0xbc(undefined2 p_unk0xbc) { m_unk0xbc = p_unk0xbc; }
MxBool StringEndsOnW(LegoChar* p_param);
MxBool StringEndsOnYOrN(const LegoChar* p_string);
const BoundingSphere& FUN_10079e20();
@ -61,22 +90,36 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter {
// LegoCarBuildAnimPresenter::`scalar deleting destructor'
private:
undefined2 m_unk0xbc; // 0xbc
MxS16 m_unk0xbe; // 0xbe
MxS16 m_unk0xc0; // 0xc0
undefined4 m_unk0xc4; // 0xc4
void Beta10Inline0x100733d0();
MxU16 m_unk0xbc; // 0xbc
// variable name verified by BETA10 0x1007184f
MxS16 m_numberOfParts; // 0xbe
// name derived from LegoVehicleBuildState, field 0x4f
MxS16 m_placedPartCount; // 0xc0
LegoAnimNodeData* m_unk0xc4; // 0xc4
LegoAnim m_unk0xc8; // 0xc8
MxMatrix m_unk0xe0; // 0xe0
UnknownListEntry* m_unk0x128; // 0x128
undefined4 m_unk0x12c; // 0x12c
undefined4 m_unk0x130; // 0x130
undefined4 m_unk0x134; // 0x134
undefined4 m_unk0x138; // 0x138
undefined4 m_unk0x13c; // 0x13c
// variable name verified by BETA10 0x100719f0
UnknownListEntry* m_parts; // 0x128
MxFloat m_unk0x12c; // 0x12c
MxFloat m_unk0x130; // 0x130
MxFloat m_unk0x134; // 0x134
MxFloat m_unk0x138; // 0x138
MxLong m_unk0x13c; // 0x13c
LegoEntity* m_unk0x140; // 0x140
MxS32 m_unk0x144; // 0x144
MxS32 m_unk0x148; // 0x148
undefined* m_unk0x14c; // 0x14c
// name verified by BETA10 0x10070d63
LegoChar* m_mainSourceId; // 0x14c
friend class LegoCarBuild;
};
#endif // LEGOCARBUILDPRESENTER_H

View file

@ -6,7 +6,7 @@
// VTABLE: LEGO1 0x100d6c00 LegoAnimActor
// VTABLE: LEGO1 0x100d6c10 LegoPathActor
// VTABLE: LEGO1 0x100d6cdc LegoExtraActor
// VTABLE: BETA10 0x101bc2b8 LegoAnimActor
// VTABLE: BETA10 0x101bc2b8 LegoPathActor
// SIZE 0x1dc
class LegoExtraActor : public virtual LegoAnimActor {
public:

View file

@ -134,7 +134,10 @@ class LegoOmni : public MxOmni {
LegoPlantManager* GetPlantManager() { return m_plantManager; }
LegoAnimationManager* GetAnimationManager() { return m_animationManager; }
LegoBuildingManager* GetBuildingManager() { return m_buildingManager; }
// FUNCTION: BETA10 0x100e52b0
LegoGameState* GetGameState() { return m_gameState; }
MxBackgroundAudioManager* GetBackgroundAudioManager() { return m_bkgAudioManager; }
MxTransitionManager* GetTransitionManager() { return m_transitionManager; }
MxDSAction& GetCurrentAction() { return m_action; }

View file

@ -9,6 +9,7 @@ class LegoEntity;
class MxDSChunk;
// VTABLE: LEGO1 0x100d4e50
// VTABLE: BETA10 0x101bcd88
// SIZE 0x6c
class LegoModelPresenter : public MxVideoPresenter {
public:

View file

@ -35,6 +35,7 @@ class LegoRaceActor : public virtual LegoAnimActor {
MxResult VTable0x94(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94
// FUNCTION: LEGO1 0x10014aa0
// FUNCTION: BETA10 0x100ca038
virtual MxResult FUN_10014aa0() { return SUCCESS; }
// SYNTHETIC: LEGO1 0x10012c10

View file

@ -43,6 +43,7 @@ void FUN_1003dde0(LegoROI* p_param1, MxFloat p_param2);
MxBool FUN_1003ded0(MxFloat p_param1[2], MxFloat p_param2[3], MxFloat p_param3[3]);
MxBool TransformWorldToScreen(const MxFloat p_world[3], MxFloat p_screen[4]);
MxS16 CountTotalTreeNodes(LegoTreeNode* p_node);
LegoTreeNode* GetTreeNode(LegoTreeNode* p_node, MxU32 p_index);
void FUN_1003e050(LegoAnimPresenter* p_presenter);
Extra::ActionType MatchActionString(const char*);
void InvokeAction(Extra::ActionType p_actionId, const MxAtomId& p_pAtom, MxS32 p_targetEntityId, LegoEntity* p_sender);

View file

@ -53,7 +53,9 @@ class LegoVideoManager : public MxVideoManager {
// FUNCTION: BETA10 0x100117e0
Lego3DManager* Get3DManager() { return m_3dManager; }
// FUNCTION: BETA10 0x1003a380
LegoROI* GetViewROI() { return m_viewROI; }
MxDirect3D* GetDirect3D() { return m_direct3d; }
MxBool GetRender3D() { return m_render3d; }
double GetElapsedSeconds() { return m_elapsedSeconds; }

View file

@ -3,6 +3,7 @@
#include "mxcore.h"
#include "mxdsaction.h"
#include "mxpresenter.h"
#include "mxtypes.h"
class MxAudioPresenter;
@ -34,7 +35,7 @@ class MxBackgroundAudioManager : public MxCore {
void StartAction(MxParam& p_param);
void StopAction(MxParam& p_param);
MxResult PlayMusic(MxDSAction& p_action, undefined4 p_unk0x140, undefined4 p_unk0x13c);
MxResult PlayMusic(MxDSAction& p_action, undefined4 p_unk0x140, MxPresenter::TickleState p_tickleState);
void FUN_1007ee70();
void FUN_1007ef40();
@ -47,6 +48,7 @@ class MxBackgroundAudioManager : public MxCore {
void Stop();
void LowerVolume();
void RaiseVolume();
undefined4 FUN_1007f610(MxPresenter* p_unk0x138, MxS32 p_unk0x140, MxPresenter::TickleState p_tickleState);
// SYNTHETIC: LEGO1 0x1007ec00
// MxBackgroundAudioManager::`scalar deleting destructor'
@ -60,7 +62,10 @@ class MxBackgroundAudioManager : public MxCore {
MxAudioPresenter* m_unk0xa0; // 0xa0
MxDSAction m_action2; // 0xa4
MxAudioPresenter* m_unk0x138; // 0x138
MxS32 m_unk0x13c; // 0x13c
// name is inferred from context
MxPresenter::TickleState m_tickleState; // 0x13c
MxS32 m_unk0x140; // 0x140
MxS32 m_targetVolume; // 0x144
MxS16 m_unk0x148; // 0x148

View file

@ -38,8 +38,7 @@ class PizzaMissionState : public LegoState {
undefined m_unk0x03[3]; // 0x03
MxS16 m_unk0x06; // 0x06
undefined m_unk0x08[8]; // 0x08
MxS16 m_unk0x10; // 0x10
MxS16 m_unk0x12; // 0x12
undefined4 m_unk0x10; // 0x10
MxS16 m_unk0x14; // 0x14
MxS16 m_unk0x16; // 0x16
MxS16 m_score; // 0x18
@ -107,6 +106,7 @@ class Pizza : public IsleActor {
void FUN_10038220(MxU32 p_objectId);
void FUN_100382b0();
void FUN_10038380();
void FUN_10038fe0(MxU32 p_objectId, MxBool);
void SetSkateboard(SkateBoard* p_skateboard) { m_skateboard = p_skateboard; }
@ -115,7 +115,7 @@ class Pizza : public IsleActor {
private:
PizzaMissionState* m_state; // 0x7c
undefined4 m_unk0x80; // 0x80
PizzaMissionState::Entry* m_entry; // 0x80
SkateBoard* m_skateboard; // 0x84
Act1State* m_act1state; // 0x88
undefined4 m_unk0x8c; // 0x8c

View file

@ -600,7 +600,7 @@ void IslePathActor::SpawnPlayer(LegoGameState::Area p_area, MxBool p_enter, MxU8
MxDSAction action;
action.SetAtomId(*g_jukeboxScript);
action.SetObjectId(g_spawnLocations[i].m_music);
BackgroundAudioManager()->PlayMusic(action, 5, 4);
BackgroundAudioManager()->PlayMusic(action, 5, MxPresenter::e_repeating);
}
}
}

View file

@ -92,7 +92,7 @@ void JukeBoxEntity::StartAction()
BackgroundAudioManager()->Enable(TRUE);
}
BackgroundAudioManager()->PlayMusic(action, 5, 4);
BackgroundAudioManager()->PlayMusic(action, 5, MxPresenter::e_repeating);
}
// FUNCTION: LEGO1 0x100860f0

View file

@ -1,6 +1,8 @@
#include "pizza.h"
#include "isle.h"
#include "isle_actions.h"
#include "legoanimationmanager.h"
#include "legogamestate.h"
#include "legoworld.h"
#include "misc.h"
@ -11,11 +13,14 @@ DECOMP_SIZE_ASSERT(Pizza, 0x9c)
DECOMP_SIZE_ASSERT(PizzaMissionState, 0xb4)
DECOMP_SIZE_ASSERT(PizzaMissionState::Entry, 0x20)
// Flags used in isle.cpp
extern MxU32 g_isleFlags;
// FUNCTION: LEGO1 0x10037ef0
Pizza::Pizza()
{
m_state = NULL;
m_unk0x80 = 0;
m_entry = NULL;
m_skateboard = NULL;
m_act1state = NULL;
m_unk0x8c = -1;
@ -56,9 +61,19 @@ void Pizza::CreateState()
}
}
// STUB: LEGO1 0x10038220
// FUNCTION: LEGO1 0x10038220
void Pizza::FUN_10038220(MxU32 p_objectId)
{
AnimationManager()->FUN_10064740(NULL);
m_entry = m_state->GetState(GameState()->GetActorId());
m_state->m_unk0x0c = 1;
m_act1state->m_unk0x018 = 3;
m_entry->m_unk0x10 = 0x80000000;
g_isleFlags &= ~Isle::c_playMusic;
AnimationManager()->EnableCamAnims(FALSE);
AnimationManager()->FUN_1005f6d0(FALSE);
FUN_10038fe0(p_objectId, FALSE);
m_unk0x8c = -1;
}
// STUB: LEGO1 0x100382b0
@ -99,6 +114,12 @@ MxLong Pizza::HandleEndAction(MxEndActionNotificationParam&)
return 0;
}
// STUB: LEGO1 0x10038fe0
void Pizza::FUN_10038fe0(MxU32 p_objectId, MxBool)
{
// TODO
}
// STUB: LEGO1 0x10039030
PizzaMissionState::PizzaMissionState()
{

View file

@ -115,7 +115,7 @@ void Radio::Play()
BackgroundAudioManager()->Enable(TRUE);
}
BackgroundAudioManager()->PlayMusic(action, 3, 4);
BackgroundAudioManager()->PlayMusic(action, 3, MxPresenter::e_repeating);
m_state->SetActive(TRUE);
}
}
@ -178,7 +178,7 @@ MxLong Radio::HandleEndAction(MxEndActionNotificationParam& p_param)
action.SetObjectId(m_state->FUN_1002d090());
action.SetLoopCount(1);
BackgroundAudioManager()->PlayMusic(action, 3, 4);
BackgroundAudioManager()->PlayMusic(action, 3, MxPresenter::e_repeating);
return 1;
}

View file

@ -20,7 +20,7 @@ MxBackgroundAudioManager::MxBackgroundAudioManager()
NotificationManager()->Register(this);
m_unk0xa0 = 0;
m_unk0x138 = 0;
m_unk0x13c = 0;
m_tickleState = MxPresenter::e_idle;
m_unk0x140 = 0;
m_targetVolume = 0;
m_unk0x148 = 0;
@ -81,7 +81,7 @@ void MxBackgroundAudioManager::DestroyMusic()
// FUNCTION: LEGO1 0x1007ee40
MxResult MxBackgroundAudioManager::Tickle()
{
switch (m_unk0x13c) {
switch (m_tickleState) {
case MxPresenter::e_starting:
FadeInOrFadeOut();
break;
@ -108,7 +108,7 @@ void MxBackgroundAudioManager::FUN_1007ee70()
m_unk0x138 = NULL;
m_action2.SetObjectId(-1);
m_action2.SetAtomId(MxAtomId());
m_unk0x13c = 0;
m_tickleState = MxPresenter::e_idle;
}
}
@ -141,7 +141,7 @@ void MxBackgroundAudioManager::FUN_1007ef40()
m_unk0x138 = NULL;
m_action2.SetObjectId(-1);
m_action2.SetAtomId(MxAtomId());
m_unk0x13c = 0;
m_tickleState = MxPresenter::e_idle;
}
}
}
@ -187,11 +187,11 @@ void MxBackgroundAudioManager::FadeInOrFadeOut()
}
else {
m_unk0xa0->SetVolume(volume);
m_unk0x13c = 0;
m_tickleState = MxPresenter::e_idle;
}
}
else {
m_unk0x13c = 0;
m_tickleState = MxPresenter::e_idle;
}
}
@ -238,7 +238,11 @@ void MxBackgroundAudioManager::StopAction(MxParam& p_param)
}
// FUNCTION: LEGO1 0x1007f2f0
MxResult MxBackgroundAudioManager::PlayMusic(MxDSAction& p_action, undefined4 p_unk0x140, undefined4 p_unk0x13c)
MxResult MxBackgroundAudioManager::PlayMusic(
MxDSAction& p_action,
undefined4 p_unk0x140,
MxPresenter::TickleState p_tickleState
)
{
if (!m_enabled) {
return SUCCESS;
@ -262,7 +266,7 @@ MxResult MxBackgroundAudioManager::PlayMusic(MxDSAction& p_action, undefined4 p_
GetCurrentAction().SetUnknown24(action.GetUnknown24());
if (result == SUCCESS) {
m_unk0x13c = p_unk0x13c;
m_tickleState = p_tickleState;
m_unk0x140 = p_unk0x140;
}
@ -292,15 +296,15 @@ void MxBackgroundAudioManager::Stop()
m_action1.SetAtomId(MxAtomId());
m_unk0x148 = 0;
m_action1.SetObjectId(-1);
m_unk0x13c = 0;
m_tickleState = MxPresenter::e_idle;
}
// FUNCTION: LEGO1 0x1007f570
void MxBackgroundAudioManager::LowerVolume()
{
if (m_unk0x148 == 0) {
if (m_unk0x13c == 0) {
m_unk0x13c = 2;
if (m_tickleState == 0) {
m_tickleState = MxPresenter::e_starting;
}
m_unk0x140 = 20;
}
@ -313,8 +317,8 @@ void MxBackgroundAudioManager::RaiseVolume()
if (m_unk0x148 != 0) {
m_unk0x148--;
if (m_unk0x148 == 0) {
if (m_unk0x13c == 0) {
m_unk0x13c = 2;
if (m_tickleState == 0) {
m_tickleState = MxPresenter::e_starting;
}
m_unk0x140 = 10;
}
@ -333,9 +337,28 @@ void MxBackgroundAudioManager::Enable(MxBool p_enable)
}
}
// FUNCTION: LEGO1 0x1007f610
// FUNCTION: BETA10 0x100e95ee
undefined4 MxBackgroundAudioManager::FUN_1007f610(
MxPresenter* p_unk0x138,
MxS32 p_unk0x140,
MxPresenter::TickleState p_tickleState
)
{
m_unk0x138 = (MxAudioPresenter*) p_unk0x138;
m_targetVolume = ((MxDSSound*) m_unk0x138->GetAction())->GetVolume();
((MxCompositePresenter*) m_unk0x138)->VTable0x60(NULL);
m_unk0x140 = p_unk0x140;
m_tickleState = p_tickleState;
return 0;
}
// FUNCTION: LEGO1 0x1007f650
void MxBackgroundAudioManager::Init()
{
this->m_unk0xa0 = 0;
this->m_unk0x13c = 0;
this->m_tickleState = MxPresenter::e_idle;
}

View file

@ -1,9 +1,14 @@
#include "legocarbuild.h"
#include "dunebuggy.h"
#include "helicopter.h"
#include "jetski.h"
#include "jukebox_actions.h"
#include "legocarbuildpresenter.h"
#include "legocontrolmanager.h"
#include "legogamestate.h"
#include "legoinputmanager.h"
#include "legosoundmanager.h"
#include "legoutils.h"
#include "misc.h"
#include "mxactionnotificationparam.h"
@ -15,8 +20,10 @@
#include "mxstillpresenter.h"
#include "mxticklemanager.h"
#include "mxtransitionmanager.h"
#include "racecar.h"
#include "scripts.h"
#include <isle.h>
#include <vec.h>
DECOMP_SIZE_ASSERT(LegoCarBuild, 0x34c)
@ -26,7 +33,7 @@ DECOMP_SIZE_ASSERT(LegoVehicleBuildState, 0x50)
MxFloat LegoCarBuild::g_unk0x100d65a4 = -0.1f;
// GLOBAL: LEGO1 0x100d65a8
MxFloat LegoCarBuild::g_unk0x100d65a8 = 0.07;
MxFloat LegoCarBuild::g_rotationAngleStepYAxis = 0.07;
// GLOBAL: LEGO1 0x100f11cc
MxS16 LegoCarBuild::g_unk0x100f11cc = -1;
@ -141,7 +148,7 @@ MxResult LegoCarBuild::Create(MxDSAction& p_dsAction)
GameState()->StopArea(LegoGameState::e_previousArea);
m_buildState->m_animationState = 1;
m_buildState->m_animationState = LegoVehicleBuildState::e_entering;
m_unk0x100 = 0;
BackgroundAudioManager()->Stop();
@ -153,6 +160,17 @@ MxResult LegoCarBuild::Create(MxDSAction& p_dsAction)
return result;
}
// FUNCTION: LEGO1 0x10022cd0
MxS16 LegoCarBuild::GetPlacedPartCount()
{
if (m_buildState) {
return m_buildState->m_placedPartCount;
}
else {
return 0;
}
}
// FUNCTION: LEGO1 0x10022d10
// FUNCTION: BETA10 0x1006b27a
void LegoCarBuild::InitPresenters()
@ -207,7 +225,7 @@ void LegoCarBuild::FUN_10022f30()
FUN_10024f70(FALSE);
FUN_100250e0(FALSE);
if (m_unk0x258->FUN_10079ca0(m_unk0x110->GetName())) {
if (m_unk0x258->PartIsPlaced(m_unk0x110->GetName())) {
m_PlaceBrick_Sound->Enable(FALSE);
m_PlaceBrick_Sound->Enable(TRUE);
}
@ -397,7 +415,7 @@ MxResult LegoCarBuild::Tickle()
}
if (m_unk0x110) {
if (m_unk0x258->FUN_10079ca0(m_unk0x110->GetName())) {
if (m_unk0x258->PartIsPlaced(m_unk0x110->GetName())) {
FUN_10022f30();
}
}
@ -537,7 +555,7 @@ MxLong LegoCarBuild::Notify(MxParam& p_param)
assert(m_buildState);
if (((m_buildState->m_animationState != 4) && (m_buildState->m_animationState != 6)) &&
(m_buildState->m_animationState != 2)) {
m_buildState->m_animationState = 0;
m_buildState->m_animationState = LegoVehicleBuildState::e_unknown0;
result = FUN_100244e0(
((LegoEventNotificationParam&) p_param).GetX(),
((LegoEventNotificationParam&) p_param).GetY()
@ -607,7 +625,7 @@ void LegoCarBuild::ReadyWorld()
if (BackgroundAudioManager()->GetEnabled()) {
InvokeAction(Extra::ActionType::e_start, *g_jukeboxScript, FUN_10025ee0(m_unk0x330), NULL);
m_buildState->m_animationState = 2;
m_buildState->m_animationState = LegoVehicleBuildState::e_unknown2;
NotificationManager()->Send(this, MxNotificationParam());
}
else {
@ -652,7 +670,7 @@ undefined4 LegoCarBuild::FUN_10024480(MxActionNotificationParam* p_param)
switch (m_buildState->m_animationState) {
case 3:
BackgroundAudioManager()->RaiseVolume();
m_buildState->m_animationState = 0;
m_buildState->m_animationState = LegoVehicleBuildState::e_unknown0;
result = 1;
break;
case 6:
@ -686,7 +704,7 @@ undefined4 LegoCarBuild::FUN_100244e0(MxLong p_x, MxLong p_y)
FUN_100250e0(TRUE);
}
if (m_unk0x100 == 5 && m_unk0x258->FUN_10079ca0(m_unk0x110->GetName())) {
if (m_unk0x100 == 5 && m_unk0x258->PartIsPlaced(m_unk0x110->GetName())) {
m_unk0x2d4 = TRUE;
}
else {
@ -695,7 +713,7 @@ undefined4 LegoCarBuild::FUN_100244e0(MxLong p_x, MxLong p_y)
FUN_10025450();
VTable0x70();
if (m_unk0x258->FUN_10079ca0(m_unk0x110->GetName())) {
if (m_unk0x258->PartIsPlaced(m_unk0x110->GetName())) {
if (m_unk0x100 != 5) {
m_unk0x250[0] += m_unk0x290[0] - m_unk0x298[0];
m_unk0x250[1] += m_unk0x290[1] - m_unk0x298[1];
@ -761,18 +779,115 @@ undefined4 LegoCarBuild::FUN_10024890(LegoEventNotificationParam* p_param)
return 0;
}
// STUB: LEGO1 0x10024c20
// STUB: BETA10 0x1006db21
void LegoCarBuild::FUN_10024c20(LegoEventNotificationParam* p_param)
// FUNCTION: LEGO1 0x10024c20
// FUNCTION: BETA10 0x1006db21
undefined4 LegoCarBuild::FUN_10024c20(LegoEventNotificationParam* p_param)
{
// TODO
LegoEntity* entity;
assert(m_buildState);
switch (m_buildState->m_animationState) {
case 4:
entity = (LegoEntity*) Find(m_atomId, m_unk0x330);
if (entity && entity->GetROI()) {
// This function was changed between BETA10 and LEGO1.
// These lines looks like a relic from older code.
LegoWorld* destWorld = NULL;
destWorld = FindWorld(*g_isleScript, 0);
Act1State* gameState = (Act1State*) GameState()->GetState("Act1State");
switch (GameState()->GetCurrentArea()) {
case LegoGameState::e_copterbuild:
if (gameState->m_helicopter) {
delete gameState->m_helicopter;
}
gameState->m_helicopter = (Helicopter*) entity;
gameState->m_unk0x108.SetName("");
break;
case LegoGameState::e_dunecarbuild:
if (gameState->m_dunebuggy) {
delete gameState->m_dunebuggy;
}
gameState->m_dunebuggy = (DuneBuggy*) entity;
gameState->m_unk0x1bc.SetName("");
break;
case LegoGameState::e_jetskibuild:
if (gameState->m_jetski) {
delete gameState->m_jetski;
}
gameState->m_jetski = (Jetski*) entity;
gameState->m_unk0x164.SetName("");
break;
case LegoGameState::e_racecarbuild:
if (gameState->m_racecar) {
delete gameState->m_racecar;
}
gameState->m_racecar = (RaceCar*) entity;
gameState->m_unk0x210.SetName("");
break;
}
assert(destWorld);
m_buildState->m_animationState = LegoVehicleBuildState::e_exiting;
if (m_unk0x258->m_numberOfParts != m_unk0x258->m_placedPartCount) {
FUN_100243a0();
}
else {
FUN_10025720(5);
}
}
else {
MxNotificationParam param;
NotificationManager()->Send(this, param);
}
break;
case 2:
MxU32 jukeboxScript;
switch (m_unk0x330) {
case 1:
jukeboxScript = JukeboxScript::c_HelicopterBuild_Music;
break;
case 2:
jukeboxScript = JukeboxScript::c_DuneCarBuild_Music;
break;
case 3:
jukeboxScript = JukeboxScript::c_JetskiBuild_Music;
break;
case 4:
jukeboxScript = JukeboxScript::c_RaceCarBuild_Music;
}
m_unk0x338 = SoundManager()->FUN_100aebd0(*g_jukeboxScript, jukeboxScript);
if (m_unk0x338) {
BackgroundAudioManager()->FUN_1007f610(m_unk0x338, 5, MxPresenter::e_repeating);
FUN_10024ef0();
}
else {
MxNotificationParam p;
// In BETA10, NotificationManager->Send() also takes __FILE__ and __LINE__ arguments
NotificationManager()->Send(this, p);
}
break;
}
return 1;
}
// FUNCTION: LEGO1 0x10024ef0
void LegoCarBuild::FUN_10024ef0()
{
FUN_1003eda0();
m_buildState->m_animationState = 3;
m_buildState->m_animationState = LegoVehicleBuildState::e_cutscene;
FUN_10025720(FUN_10025d70());
m_buildState->m_unk0x4c += 1;
FUN_10015820(FALSE, 7);
@ -783,14 +898,14 @@ void LegoCarBuild::FUN_10024ef0()
void LegoCarBuild::FUN_10024f50()
{
m_unk0x2d4 = FALSE;
m_unk0x258->FUN_10079920(g_unk0x100d65a8);
m_unk0x258->RotateAroundYAxis(g_rotationAngleStepYAxis);
}
// FUNCTION: LEGO1 0x10024f70
// FUNCTION: BETA10 0x1006e002
void LegoCarBuild::FUN_10024f70(MxBool p_enabled)
{
if (m_unk0x258->FUN_10079cf0(m_unk0x110->GetName())) {
if (m_unk0x258->StringEndsOnY(m_unk0x110->GetName())) {
SetPresentersEnabled(p_enabled);
}
}
@ -821,11 +936,41 @@ void LegoCarBuild::TogglePresentersEnabled()
m_Black_Ctl->Enable(!m_Black_Ctl->IsEnabled());
}
// STUB: LEGO1 0x100250e0
// STUB: BETA10 0x1006e124
// FUNCTION: LEGO1 0x100250e0
// FUNCTION: BETA10 0x1006e124
void LegoCarBuild::FUN_100250e0(MxBool p_enabled)
{
// TODO
if (m_unk0x258->StringEndsOnZero(m_unk0x110->GetName()) && m_Decals_Ctl) {
if (strnicmp(m_unk0x110->GetName(), "JSFRNT", strlen("JSFRNT")) == 0) {
m_Decal_Bitmap->Enable(p_enabled);
m_Decals_Ctl->Enable(p_enabled);
m_Decals_Ctl1->Enable(p_enabled);
m_Decals_Ctl2->Enable(p_enabled);
m_Decals_Ctl3->Enable(p_enabled);
}
else if (strnicmp(m_unk0x110->GetName(), "JSWNSH", strlen("JSWNSH")) == 0) {
m_Decal_Bitmap->Enable(p_enabled);
m_Decals_Ctl4->Enable(p_enabled);
m_Decals_Ctl5->Enable(p_enabled);
m_Decals_Ctl6->Enable(p_enabled);
m_Decals_Ctl7->Enable(p_enabled);
}
else if (strnicmp(m_unk0x110->GetName(), "RCBACK", strlen("RCBACK")) == 0) {
m_Decals_Ctl1->Enable(p_enabled);
}
else if (strnicmp(m_unk0x110->GetName(), "RCTAIL", strlen("RCTAIL")) == 0) {
m_Decals_Ctl2->Enable(p_enabled);
}
else if (m_Decals_Ctl1 && strnicmp(m_unk0x110->GetName(), "chljety", strlen("chljety")) == 0) {
m_Decals_Ctl1->Enable(p_enabled);
}
else if (m_Decals_Ctl2 && strnicmp(m_unk0x110->GetName(), "chrjety", strlen("chrjety")) == 0) {
m_Decals_Ctl2->Enable(p_enabled);
}
else if (m_Decals_Ctl) {
m_Decals_Ctl->Enable(p_enabled);
}
}
}
// STUB: LEGO1 0x10025450
@ -916,7 +1061,7 @@ MxBool LegoCarBuild::Escape()
InvokeAction(Extra::ActionType::e_stop, *g_jukeboxScript, targetEntityId, NULL);
DeleteObjects(&m_atomId, 500, 999);
m_buildState->m_animationState = 0;
m_buildState->m_animationState = LegoVehicleBuildState::e_unknown0;
m_destLocation = LegoGameState::e_infomain;
return TRUE;
}

View file

@ -1,7 +1,19 @@
#include "legocarbuildpresenter.h"
#include "3dmanager/lego3dmanager.h"
#include "legocarbuild.h"
#include "legoentity.h"
#include "legogamestate.h"
#include "legomain.h"
#include "legoutils.h"
#include "legovideomanager.h"
#include "legoworld.h"
#include "misc.h"
#include "mxautolock.h"
#include "mxcompositepresenter.h"
#include "mxmisc.h"
#include "mxtimer.h"
#include "realtime/realtime.h"
DECOMP_SIZE_ASSERT(LegoCarBuildAnimPresenter::UnknownListEntry, 0x0c)
DECOMP_SIZE_ASSERT(LegoCarBuildAnimPresenter, 0x150)
@ -11,10 +23,10 @@ DECOMP_SIZE_ASSERT(LegoCarBuildAnimPresenter, 0x150)
LegoCarBuildAnimPresenter::LegoCarBuildAnimPresenter()
{
m_unk0xbc = 0;
m_unk0xbe = 0;
m_unk0xc0 = 0;
m_unk0x128 = NULL;
m_unk0xc4 = 0;
m_numberOfParts = 0;
m_placedPartCount = 0;
m_parts = NULL;
m_unk0xc4 = NULL;
m_unk0x130 = 0;
m_unk0x12c = 0;
m_unk0x134 = 0;
@ -23,7 +35,7 @@ LegoCarBuildAnimPresenter::LegoCarBuildAnimPresenter()
m_unk0x140 = NULL;
m_unk0x144 = -1;
m_unk0x148 = -1;
m_unk0x14c = NULL;
m_mainSourceId = NULL;
}
// FUNCTION: LEGO1 0x10078500
@ -36,40 +48,238 @@ void LegoCarBuildAnimPresenter::RepeatingTickle()
// FUNCTION: BETA10 0x1007091e
LegoCarBuildAnimPresenter::~LegoCarBuildAnimPresenter()
{
if (m_unk0x128) {
for (MxS16 i = 0; i < m_unk0xbe; i++) {
delete m_unk0x128[i].m_unk0x00;
delete m_unk0x128[i].m_unk0x04;
if (m_parts) {
for (MxS16 i = 0; i < m_numberOfParts; i++) {
delete m_parts[i].m_name;
delete m_parts[i].m_wiredName;
}
delete[] m_unk0x128;
delete[] m_parts;
}
m_unk0xc8.GetRoot()->SetNumChildren(0);
*m_unk0xc8.GetRoot()->GetChildren() = NULL;
if (m_unk0x14c) {
delete m_unk0x14c;
if (m_mainSourceId) {
delete[] m_mainSourceId;
}
}
// STUB: LEGO1 0x10078790
// FUNCTION: BETA10 0x100733d0
inline void LegoCarBuildAnimPresenter::Beta10Inline0x100733d0()
{
MxLong time = Timer()->GetTime();
MxLong bvar5;
if (m_unk0x13c < time) {
bvar5 = FALSE;
// I have no idea why this conditional is so convoluted
if (m_unk0x13c & c_bit1) {
bvar5 = TRUE;
m_unk0x13c = time + 400;
}
else {
m_unk0x13c = time + 200;
}
if (bvar5) {
m_unk0x13c &= ~c_bit1;
}
else {
m_unk0x13c |= c_bit1;
}
if (m_placedPartCount < m_numberOfParts) {
const LegoChar* wiredName = m_parts[m_placedPartCount].m_wiredName;
if (wiredName) {
for (MxS32 i = 1; i <= m_roiMapSize; i++) {
LegoROI* roi = m_roiMap[i];
if (roi) {
const LegoChar* name = roi->GetName();
if (name && stricmp(wiredName, name) == 0) {
if (bvar5) {
roi->SetVisibility(TRUE);
}
else {
roi->SetVisibility(FALSE);
}
}
}
}
}
}
}
}
// FUNCTION: LEGO1 0x10078790
// FUNCTION: BETA10 0x10070ab1
void LegoCarBuildAnimPresenter::PutFrame()
{
// TODO
switch (m_unk0xbc) {
case 0:
break;
case 2:
FUN_10079a90();
case 1:
if (m_unk0x140->GetROI()) {
FUN_1006b9a0(m_anim, m_unk0x12c, NULL);
}
default:
break;
}
Beta10Inline0x100733d0();
}
// STUB: LEGO1 0x100788c0
// STUB: BETA10 0x10070b56
// FUNCTION: LEGO1 0x100788c0
// FUNCTION: BETA10 0x10070b56
void LegoCarBuildAnimPresenter::ReadyTickle()
{
// TODO
if (!m_anim) {
LegoAnimPresenter::ReadyTickle();
if (!m_currentWorld) {
return;
}
#ifdef NDEBUG
if (!m_anim) {
return;
}
#else
assert(m_anim);
#endif
}
m_unk0x140 = (LegoEntity*) m_currentWorld->Find("MxEntity", "Dunebld");
if (!m_unk0x140) {
m_unk0x140 = (LegoEntity*) m_currentWorld->Find("MxEntity", "Chptrbld");
}
if (!m_unk0x140) {
m_unk0x140 = (LegoEntity*) m_currentWorld->Find("MxEntity", "Jetbld");
}
if (!m_unk0x140) {
m_unk0x140 = (LegoEntity*) m_currentWorld->Find("MxEntity", "bldrace");
}
if (m_unk0x140) {
((LegoCarBuild*) m_currentWorld)->SetUnknown0x258(this);
m_placedPartCount = ((LegoCarBuild*) m_currentWorld)->GetPlacedPartCount();
SetUnknown0xbc(1);
m_previousTickleStates |= 1 << m_currentTickleState;
m_currentTickleState = e_starting;
m_compositePresenter->SendToCompositePresenter(Lego());
}
else {
m_previousTickleStates |= 1 << m_currentTickleState;
m_currentTickleState = e_ready;
}
}
// STUB: LEGO1 0x100789e0
// STUB: BETA10 0x10070cdd
// FUNCTION: LEGO1 0x100789e0
// FUNCTION: BETA10 0x10070cdd
void LegoCarBuildAnimPresenter::StreamingTickle()
{
// TODO
if (!m_unk0x140->GetROI()) {
return;
}
m_mainSourceId = new LegoChar[strlen(m_action->GetAtomId().GetInternal()) + 1];
assert(m_mainSourceId);
strcpy(m_mainSourceId, m_action->GetAtomId().GetInternal());
m_mainSourceId[strlen(m_mainSourceId) - 1] = 'M';
FUN_10079160();
if (GameState()->GetCurrentAct() == LegoGameState::e_act2) {
m_placedPartCount = 10;
}
MxS16 i;
for (i = 0; i < m_numberOfParts; i++) {
if (m_placedPartCount == i) {
FUN_10079680(m_parts[i].m_wiredName);
}
else {
FUN_100795d0(m_parts[i].m_wiredName);
}
if (i < m_placedPartCount) {
FUN_10079050(i);
FUN_10079680(m_parts[i].m_name);
}
LegoChar* name = m_parts[i].m_wiredName;
if (name) {
for (MxS32 j = 0; j <= m_roiMapSize; j++) {
LegoROI* roi = m_roiMap[j];
if (roi && roi->GetName() && (strcmpi(name, roi->GetName()) == 0)) {
roi->FUN_100a9dd0();
roi->FUN_100a9350("lego red");
}
}
}
}
LegoVideoManager* videoManager = VideoManager();
assert(videoManager); // verifies variable name 'videoManager'
Lego3DView* lego3dview = videoManager->Get3DManager()->GetLego3DView();
LegoROI* videoManagerROI = videoManager->GetViewROI();
LegoROI* local60 = m_unk0x140->GetROI();
LegoROI* camera = NULL;
MxFloat fov;
MxS16 totalNodes = CountTotalTreeNodes(m_anim->GetRoot());
for (i = 0; i < totalNodes; i++) {
LegoAnimNodeData* animNodeData = (LegoAnimNodeData*) GetTreeNode(m_anim->GetRoot(), i)->GetData();
if (strnicmp(animNodeData->GetName(), "CAM", strlen("CAM")) == 0) {
camera = local60->FindChildROI(animNodeData->GetName(), local60);
fov = atof(&animNodeData->GetName()[strlen(animNodeData->GetName()) - 2]);
break;
}
}
assert(camera); // verifies variable name 'camera'
LegoROI* targetROI = local60->FindChildROI("TARGET", local60);
Mx3DPointFloat dirVec;
Vector3 cameraPosition(camera->GetWorldPosition());
Vector3 upVec(camera->GetWorldUp());
Vector3 targetPosition(targetROI->GetWorldPosition());
MxMatrix localTransform;
dirVec[0] = targetPosition[0] - cameraPosition[0];
dirVec[1] = targetPosition[1] - cameraPosition[1];
dirVec[2] = targetPosition[2] - cameraPosition[2];
dirVec.Unitize();
CalcLocalTransform(cameraPosition, dirVec, upVec, localTransform);
videoManagerROI->WrappedSetLocalTransform(localTransform);
lego3dview->Moved(*videoManagerROI);
videoManager->Get3DManager()->SetFrustrum(fov, 0.1, 250.0);
m_unk0xe0 = local60->FindChildROI("VIEW", local60)->GetLocal2World();
m_previousTickleStates |= 1 << m_currentTickleState;
m_currentTickleState = e_repeating;
}
// FUNCTION: LEGO1 0x10078db0
@ -83,11 +293,284 @@ void LegoCarBuildAnimPresenter::EndAction()
}
}
// STUB: LEGO1 0x10079920
// STUB: BETA10 0x1007225d
void LegoCarBuildAnimPresenter::FUN_10079920(float p_param1)
// FUNCTION: LEGO1 0x10079050
// FUNCTION: BETA10 0x1007151e
void LegoCarBuildAnimPresenter::FUN_10079050(MxS16 p_index)
{
// TODO
SwapNodesByName(m_parts[p_index].m_wiredName, m_parts[p_index].m_name);
FUN_100795d0(m_parts[p_index].m_wiredName);
}
// FUNCTION: LEGO1 0x10079090
// FUNCTION: BETA10 0x10071584
void LegoCarBuildAnimPresenter::SwapNodesByName(LegoChar* p_name1, LegoChar* p_name2)
{
char buffer[40];
if (stricmp(p_name1, p_name2) != 0) {
LegoAnimNodeData* node1 = FindNodeDataByName(m_anim->GetRoot(), p_name1);
LegoAnimNodeData* node2 = FindNodeDataByName(m_anim->GetRoot(), p_name2);
strcpy(buffer, node1->GetName());
strcpy(node1->GetName(), node2->GetName());
strcpy(node2->GetName(), buffer);
LegoU16 val1 = node1->GetUnknown0x20();
node1->SetUnknown0x20(node2->GetUnknown0x20());
node2->SetUnknown0x20(val1);
}
}
// FUNCTION: LEGO1 0x10079160
// FUNCTION: BETA10 0x1007165d
void LegoCarBuildAnimPresenter::FUN_10079160()
{
LegoTreeNode* root;
LegoAnimNodeData* data2;
MxS16 i;
MxS16 totalNodes = CountTotalTreeNodes(m_anim->GetRoot());
LegoChar* name;
LegoTreeNode* destNode;
LegoAnimNodeData* destData;
LegoTreeNode** children;
for (i = 0; i < totalNodes; i++) {
LegoAnimNodeData* data = (LegoAnimNodeData*) GetTreeNode(m_anim->GetRoot(), i)->GetData();
name = data->GetName();
if (StringEqualsPlatform(name)) {
m_unk0xc4 = data;
if (m_unk0xc4->GetNumRotationKeys() == 0) {
LegoRotationKey* key = new LegoRotationKey();
m_unk0xc4->SetNumRotationKeys(1);
m_unk0xc4->SetRotationKeys(key);
}
}
else {
if (StringEndsOnYOrN(name)) {
m_numberOfParts++;
}
else {
if (m_unk0x134 == 0.0f && StringEqualsShelf(name)) {
m_unk0x134 = m_anim->GetDuration();
m_unk0x138 = m_unk0x134 / (data->GetNumTranslationKeys() - 1);
}
}
}
}
assert(m_numberOfParts);
m_parts = new UnknownListEntry[m_numberOfParts];
assert(m_parts);
for (i = 0; i < totalNodes; i++) {
name = ((LegoAnimNodeData*) GetTreeNode(m_anim->GetRoot(), i)->GetData())->GetName();
strupr(name);
if (StringEndsOnW(name)) {
m_parts[name[strlen(name) - 1] - 'A'].m_wiredName = new LegoChar[strlen(name) + 1];
// clang-format off
assert(m_parts[name[strlen(name)-1] - 'A'].m_wiredName);
// clang-format on
strcpy(m_parts[name[strlen(name) - 1] - 'A'].m_wiredName, name);
}
}
MxS16 counter = 0;
for (i = 0; i < totalNodes; i++) {
name = ((LegoAnimNodeData*) GetTreeNode(m_anim->GetRoot(), i)->GetData())->GetName();
if (StringEndsOnYOrN(name)) {
for (MxS16 ii = 0; ii < m_numberOfParts; ii++) {
if (strnicmp(m_parts[ii].m_wiredName, name, strlen(name) - 2) == 0) {
m_parts[ii].m_name = new LegoChar[strlen(name) + 1];
assert(m_parts[ii].m_name);
strcpy(m_parts[ii].m_name, name);
counter++;
if (m_numberOfParts == counter) {
break;
}
}
}
}
}
destNode = new LegoTreeNode();
assert(destNode);
destData = new LegoAnimNodeData();
assert(destData);
destNode->SetData(destData);
root = m_anim->GetRoot();
data2 = (LegoAnimNodeData*) root->GetData();
destData->FUN_100a0360(data2->GetName());
destNode->SetNumChildren(1);
children = new LegoTreeNode*;
assert(children);
*children = FindNodeByName(m_anim->GetRoot(), "PLATFORM");
destNode->SetChildren(children);
m_unk0xc8.SetRoot(destNode);
}
// FUNCTION: LEGO1 0x100795d0
// FUNCTION: BETA10 0x10071d96
void LegoCarBuildAnimPresenter::FUN_100795d0(LegoChar* p_param)
{
LegoAnimNodeData* data = FindNodeDataByName(m_anim->GetRoot(), p_param);
if (data) {
LegoMorphKey* oldMorphKeys = data->GetMorphKeys();
LegoMorphKey* newHideKey = new LegoMorphKey();
assert(newHideKey);
newHideKey->SetTime(0);
newHideKey->SetUnknown0x08(FALSE);
data->SetNumMorphKeys(1);
data->SetMorphKeys(newHideKey);
delete oldMorphKeys;
}
}
// FUNCTION: LEGO1 0x10079680
// FUNCTION: BETA10 0x10071ec5
void LegoCarBuildAnimPresenter::FUN_10079680(LegoChar* p_param)
{
LegoAnimNodeData* data = FindNodeDataByName(m_anim->GetRoot(), p_param);
if (data) {
LegoMorphKey* oldMorphKeys = data->GetMorphKeys();
data->SetNumMorphKeys(0);
data->SetMorphKeys(NULL);
delete oldMorphKeys;
}
}
// FUNCTION: LEGO1 0x100796b0
// FUNCTION: BETA10 0x10071f3c
LegoAnimNodeData* LegoCarBuildAnimPresenter::FindNodeDataByName(LegoTreeNode* p_treeNode, const LegoChar* p_name)
{
LegoAnimNodeData* data = NULL;
if (p_treeNode) {
data = (LegoAnimNodeData*) p_treeNode->GetData();
if (stricmp(data->GetName(), p_name) == 0) {
return data;
}
for (MxS32 i = 0; i < p_treeNode->GetNumChildren(); i++) {
data = FindNodeDataByName(p_treeNode->GetChildren()[i], p_name);
if (data) {
return data;
}
}
}
return NULL;
}
// FUNCTION: LEGO1 0x10079720
// FUNCTION: BETA10 0x10071fec
LegoTreeNode* LegoCarBuildAnimPresenter::FindNodeByName(LegoTreeNode* p_treeNode, const LegoChar* p_name)
{
LegoAnimNodeData* data = NULL;
LegoTreeNode* node = NULL;
if (p_treeNode) {
data = (LegoAnimNodeData*) p_treeNode->GetData();
if (stricmp(data->GetName(), p_name) == 0) {
return p_treeNode;
}
for (MxS32 i = 0; i < p_treeNode->GetNumChildren(); i++) {
node = FindNodeByName(p_treeNode->GetChildren()[i], p_name);
if (node) {
return node;
}
}
}
return NULL;
}
// FUNCTION: LEGO1 0x10079920
// FUNCTION: BETA10 0x1007225d
void LegoCarBuildAnimPresenter::RotateAroundYAxis(MxFloat p_angle)
{
if (m_unk0xc4) {
LegoRotationKey* rotationKey = m_unk0xc4->GetRotationKey(0);
Mx4DPointFloat
currentRotation(rotationKey->GetX(), rotationKey->GetY(), rotationKey->GetZ(), rotationKey->GetAngle());
Mx4DPointFloat additionalRotation(0.0f, 1.0f, 0.0f, -p_angle);
Mx4DPointFloat newRotation;
additionalRotation.NormalizeQuaternion();
newRotation.EqualsHamiltonProduct(&currentRotation, &additionalRotation);
if (newRotation[3] < 0.9999) {
rotationKey->FUN_100739a0(TRUE);
}
else {
rotationKey->FUN_100739a0(FALSE);
}
m_unk0xc4->GetRotationKey(0)->SetX(newRotation[0]);
m_unk0xc4->GetRotationKey(0)->SetY(newRotation[1]);
m_unk0xc4->GetRotationKey(0)->SetZ(newRotation[2]);
m_unk0xc4->GetRotationKey(0)->SetAngle(newRotation[3]);
if (m_unk0x140->GetROI()) {
FUN_1006b9a0(&m_unk0xc8, m_unk0x12c, NULL);
}
}
}
// FUNCTION: LEGO1 0x10079a90
// FUNCTION: BETA10 0x10072412
void LegoCarBuildAnimPresenter::FUN_10079a90()
{
if (m_unk0x12c >= m_unk0x134) {
m_unk0x130 = 0.0;
m_unk0x12c = m_unk0x130;
m_unk0xbc = 1;
}
else if (m_unk0x12c >= m_unk0x138 + m_unk0x130) {
m_unk0x130 = m_unk0x138 + m_unk0x130;
m_unk0x12c = m_unk0x130;
m_unk0xbc = 1;
}
else {
m_unk0x12c = m_unk0x138 / 10.0f + m_unk0x12c;
}
}
// FUNCTION: LEGO1 0x10079b20
// FUNCTION: BETA10 0x100724fa
MxBool LegoCarBuildAnimPresenter::StringEqualsPlatform(const LegoChar* p_string)
{
return stricmp(p_string, "PLATFORM") == 0;
}
// FUNCTION: LEGO1 0x10079b40
// FUNCTION: BETA10 0x10072534
MxBool LegoCarBuildAnimPresenter::StringEndsOnW(LegoChar* p_param)
{
return (p_param[strlen(p_param) - 2] == 'W') || (p_param[strlen(p_param) - 2] == 'w');
}
// FUNCTION: LEGO1 0x10079b80
@ -98,20 +581,31 @@ MxBool LegoCarBuildAnimPresenter::StringEndsOnYOrN(const LegoChar* p_string)
(p_string[strlen(p_string) - 2] == 'Y') || (p_string[strlen(p_string) - 2] == 'y');
}
// STUB: LEGO1 0x10079c30
// STUB: BETA10 0x100726a6
// FUNCTION: LEGO1 0x10079bf0
// FUNCTION: BETA10 0x10072624
MxBool LegoCarBuildAnimPresenter::StringEqualsShelf(const LegoChar* p_string)
{
return strnicmp(p_string, "SHELF", strlen("SHELF")) == 0;
}
// FUNCTION: LEGO1 0x10079c30
// FUNCTION: BETA10 0x100726a6
MxBool LegoCarBuildAnimPresenter::FUN_10079c30(const LegoChar* p_name)
{
// TODO
if (PartIsPlaced(p_name)) {
return FALSE;
}
return m_placedPartCount < m_numberOfParts &&
strnicmp(p_name, m_parts[m_placedPartCount].m_name, strlen(p_name) - 3) == 0;
}
// FUNCTION: LEGO1 0x10079ca0
// FUNCTION: BETA10 0x10072740
MxBool LegoCarBuildAnimPresenter::FUN_10079ca0(const LegoChar* p_name)
MxBool LegoCarBuildAnimPresenter::PartIsPlaced(const LegoChar* p_name)
{
for (MxS16 i = 0; i < m_unk0xc0; i++) {
if (strcmpi(p_name, m_unk0x128[i].m_unk0x00) == 0) {
for (MxS16 i = 0; i < m_placedPartCount; i++) {
if (strcmpi(p_name, m_parts[i].m_name) == 0) {
return TRUE;
}
}
@ -121,15 +615,22 @@ MxBool LegoCarBuildAnimPresenter::FUN_10079ca0(const LegoChar* p_name)
// FUNCTION: LEGO1 0x10079cf0
// FUNCTION: BETA10 0x100727b3
MxBool LegoCarBuildAnimPresenter::FUN_10079cf0(const LegoChar* p_string)
MxBool LegoCarBuildAnimPresenter::StringEndsOnY(const LegoChar* p_string)
{
return (p_string[strlen(p_string) - 2] == 'Y') || (p_string[strlen(p_string) - 2] == 'y');
}
// FUNCTION: LEGO1 0x10079d30
// FUNCTION: BETA10 0x1007280e
MxBool LegoCarBuildAnimPresenter::StringEndsOnZero(const LegoChar* p_string)
{
return (p_string[strlen(p_string) - 2] != '0');
}
// FUNCTION: LEGO1 0x10079e20
// FUNCTION: BETA10 0x10072959
const BoundingSphere& LegoCarBuildAnimPresenter::FUN_10079e20()
{
LegoROI* roi = m_unk0x140->GetROI();
return roi->FindChildROI(m_unk0x128[m_unk0xc0].m_unk0x04, roi)->GetWorldBoundingSphere();
return roi->FindChildROI(m_parts[m_placedPartCount].m_wiredName, roi)->GetWorldBoundingSphere();
}

View file

@ -107,6 +107,7 @@ MxBool TransformWorldToScreen(const MxFloat p_world[3], MxFloat p_screen[4])
}
// FUNCTION: LEGO1 0x1003df90
// FUNCTION: BETA10 0x100d39a3
MxS16 CountTotalTreeNodes(LegoTreeNode* p_node)
{
MxS16 result = 1;
@ -119,6 +120,7 @@ MxS16 CountTotalTreeNodes(LegoTreeNode* p_node)
}
// FUNCTION: LEGO1 0x1003dfd0
// FUNCTION: BETA10 0x100d3a09
LegoTreeNode* GetTreeNode(LegoTreeNode* p_node, MxU32 p_index)
{
LegoTreeNode* result = NULL;

View file

@ -53,8 +53,10 @@ LegoControlManager* ControlManager()
}
// FUNCTION: LEGO1 0x10015760
// FUNCTION: BETA10 0x100e492a
LegoGameState* GameState()
{
assert(LegoOmni::GetInstance());
return LegoOmni::GetInstance()->GetGameState();
}
@ -166,8 +168,10 @@ void DeleteAction()
}
// FUNCTION: LEGO1 0x100158c0
// FUNCTION: BETA10 0x100e4e18
LegoWorld* FindWorld(const MxAtomId& p_atom, MxS32 p_entityid)
{
assert(LegoOmni::GetInstance());
return LegoOmni::GetInstance()->FindWorld(p_atom, p_entityid);
}
@ -196,7 +200,7 @@ void PlayMusic(JukeboxScript::Script p_script)
action.SetAtomId(*g_jukeboxScript);
action.SetObjectId(p_script);
LegoOmni::GetInstance()->GetBackgroundAudioManager()->PlayMusic(action, 5, 4);
LegoOmni::GetInstance()->GetBackgroundAudioManager()->PlayMusic(action, 5, MxPresenter::e_repeating);
}
// FUNCTION: LEGO1 0x100159c0

View file

@ -213,6 +213,7 @@ Mx3DPointFloat LegoEntity::GetWorldUp()
}
// FUNCTION: LEGO1 0x10010d80
// FUNCTION: BETA10 0x1007ebbe
Mx3DPointFloat LegoEntity::GetWorldPosition()
{
if (m_roi != NULL) {

View file

@ -380,6 +380,7 @@ void LegoWorld::AddPath(LegoPathController* p_controller)
}
// FUNCTION: LEGO1 0x10020020
// FUNCTION: BETA10 0x100da77c
LegoPathBoundary* LegoWorld::FindPathBoundary(const char* p_name)
{
LegoPathControllerListCursor cursor(&m_list0x68);

View file

@ -357,6 +357,7 @@ void LegoOmni::RemoveWorld(const MxAtomId& p_atom, MxLong p_objectId)
}
// FUNCTION: LEGO1 0x1005b0c0
// FUNCTION: BETA10 0x1008e827
LegoWorld* LegoOmni::FindWorld(const MxAtomId& p_atom, MxS32 p_entityid)
{
if (m_worldList) {

View file

@ -27,6 +27,7 @@ MxAtomId* g_jetraceScript = NULL;
MxAtomId* g_jetracerScript = NULL;
// GLOBAL: LEGO1 0x100f453c
// GLOBAL: BETA10 0x10211534
MxAtomId* g_isleScript = NULL;
// GLOBAL: LEGO1 0x100f4540

View file

@ -161,6 +161,6 @@ void LegoPathStruct::PlayMusic(MxBool p_direction, MxU32 p_data)
}
if (action.GetObjectId() != -1) {
BackgroundAudioManager()->PlayMusic(action, 5, 4);
BackgroundAudioManager()->PlayMusic(action, 5, MxPresenter::e_repeating);
}
}

View file

@ -750,6 +750,7 @@ MxResult LegoAnimPresenter::FUN_1006b140(LegoROI* p_roi)
}
// FUNCTION: LEGO1 0x1006b550
// FUNCTION: BETA10 0x10050a9c
void LegoAnimPresenter::ReadyTickle()
{
m_currentWorld = CurrentWorld();
@ -789,9 +790,9 @@ void LegoAnimPresenter::StartingTickle()
FUN_1006c8a0(TRUE);
if (m_unk0x78 == NULL) {
if (fabs(m_action->GetDirection().GetX()) >= 0.00000047683716F ||
fabs(m_action->GetDirection().GetY()) >= 0.00000047683716F ||
fabs(m_action->GetDirection().GetZ()) >= 0.00000047683716F) {
if (fabs(m_action->GetDirection()[0]) >= 0.00000047683716F ||
fabs(m_action->GetDirection()[1]) >= 0.00000047683716F ||
fabs(m_action->GetDirection()[2]) >= 0.00000047683716F) {
m_unk0x78 = new MxMatrix();
CalcLocalTransform(m_action->GetLocation(), m_action->GetDirection(), m_action->GetUp(), *m_unk0x78);
}
@ -903,6 +904,7 @@ void LegoAnimPresenter::FUN_1006b900(LegoAnim* p_anim, MxLong p_time, Matrix4* p
}
// FUNCTION: LEGO1 0x1006b9a0
// FUNCTION: BETA10 0x1005118b
void LegoAnimPresenter::FUN_1006b9a0(LegoAnim* p_anim, MxLong p_time, Matrix4* p_matrix)
{
LegoTreeNode* root = p_anim->GetRoot();

View file

@ -50,6 +50,7 @@ void LegoModelPresenter::Destroy(MxBool p_fromDestructor)
}
// FUNCTION: LEGO1 0x1007f6b0
// FUNCTION: BETA10 0x1009845e
MxResult LegoModelPresenter::CreateROI(MxDSChunk* p_chunk)
{
MxResult result = FAILURE;
@ -171,13 +172,9 @@ MxResult LegoModelPresenter::CreateROI(MxDSChunk* p_chunk)
// Get scripted location, direction and up vectors
CalcLocalTransform(
Mx3DPointFloat(m_action->GetLocation().GetX(), m_action->GetLocation().GetY(), m_action->GetLocation().GetZ()),
Mx3DPointFloat(
m_action->GetDirection().GetX(),
m_action->GetDirection().GetY(),
m_action->GetDirection().GetZ()
),
Mx3DPointFloat(m_action->GetUp().GetX(), m_action->GetUp().GetY(), m_action->GetUp().GetZ()),
Mx3DPointFloat(m_action->GetLocation()[0], m_action->GetLocation()[1], m_action->GetLocation()[2]),
Mx3DPointFloat(m_action->GetDirection()[0], m_action->GetDirection()[1], m_action->GetDirection()[2]),
Mx3DPointFloat(m_action->GetUp()[0], m_action->GetUp()[1], m_action->GetUp()[2]),
mat
);
m_roi->UpdateTransformationRelativeToParent(mat);
@ -234,6 +231,7 @@ MxResult LegoModelPresenter::FUN_1007ff70(
}
// FUNCTION: LEGO1 0x10080050
// FUNCTION: BETA10 0x100991c2
void LegoModelPresenter::ReadyTickle()
{
if (m_compositePresenter != NULL && m_compositePresenter->IsA("LegoEntityPresenter") &&

View file

@ -97,6 +97,7 @@ double Lego3DManager::Render(double p_und)
}
// FUNCTION: LEGO1 0x100ab4d0
// FUNCTION: BETA10 0x1017baeb
int Lego3DManager::SetFrustrum(float p_fov, float p_front, float p_back)
{
m_pLego3DView->GetView()->SetFrustrum(p_front, p_back, p_fov);

View file

@ -119,6 +119,7 @@ BOOL Lego3DView::SetPointOfView(ViewROI& rROI)
}
// FUNCTION: LEGO1 0x100ab210
// FUNCTION: BETA10 0x1017d230
BOOL Lego3DView::Moved(ViewROI& rROI)
{
assert(m_pViewManager);

View file

@ -221,10 +221,11 @@ LegoResult LegoAnimScene::FUN_1009f490(LegoFloat p_time, Matrix4& p_matrix)
}
// FUNCTION: LEGO1 0x1009f900
// FUNCTION: BETA10 0x1017df90
LegoAnimKey::LegoAnimKey()
{
m_flags = 0;
m_time = 0;
m_flags = 0;
}
// FUNCTION: LEGO1 0x1009f910
@ -279,6 +280,7 @@ LegoResult LegoTranslationKey::Read(LegoStorage* p_storage)
}
// FUNCTION: LEGO1 0x1009faa0
// FUNCTION: BETA10 0x1017e2b3
LegoRotationKey::LegoRotationKey()
{
m_angle = 1.0F;
@ -356,6 +358,7 @@ LegoResult LegoScaleKey::Read(LegoStorage* p_storage)
}
// FUNCTION: LEGO1 0x1009fcf0
// FUNCTION: BETA10 0x1017e71a
LegoAnimNodeData::LegoAnimNodeData()
{
m_numTranslationKeys = 0;
@ -494,6 +497,13 @@ LegoResult LegoAnimNodeData::Write(LegoStorage* p_storage)
return SUCCESS;
}
// STUB: LEGO1 0x100a0360
// STUB: BETA10 0x1017f1e5
void LegoAnimNodeData::FUN_100a0360(LegoChar* p_param)
{
// TODO
}
// FUNCTION: LEGO1 0x100a03c0
LegoResult LegoAnimNodeData::CreateLocalTransform(LegoFloat p_time, Matrix4& p_matrix)
{
@ -898,6 +908,7 @@ undefined4 LegoAnim::GetActorUnknown0x04(LegoU32 p_index)
}
// FUNCTION: LEGO1 0x100a0f60
// FUNCTION: BETA10 0x1018027c
LegoMorphKey::LegoMorphKey()
{
m_unk0x08 = 0;

View file

@ -19,11 +19,26 @@ class LegoAnimKey {
LegoAnimKey();
LegoResult Read(LegoStorage* p_storage);
LegoFloat GetTime() { return m_time; }
void SetTime(LegoFloat p_time) { m_time = p_time; }
// The different types (LegoFloat vs. MxS32) are correct according to BETA10
// FUNCTION: BETA10 0x100738a0
void SetTime(MxS32 p_time) { m_time = p_time; }
LegoU32 TestBit1() { return m_flags & c_bit1; }
LegoU32 TestBit2() { return m_flags & c_bit2; }
LegoU32 TestBit3() { return m_flags & c_bit3; }
// FUNCTION: BETA10 0x100739a0
void FUN_100739a0(MxS32 p_param)
{
if (p_param) {
m_flags |= c_bit1;
}
else {
m_flags &= ~c_bit1;
}
}
protected:
LegoU8 m_flags; // 0x00
LegoFloat m_time; // 0x04
@ -52,13 +67,29 @@ class LegoRotationKey : public LegoAnimKey {
public:
LegoRotationKey();
LegoResult Read(LegoStorage* p_storage);
// FUNCTION: BETA10 0x10073a00
LegoFloat GetAngle() { return m_angle; }
// FUNCTION: BETA10 0x10073a30
void SetAngle(LegoFloat p_angle) { m_angle = p_angle; }
// FUNCTION: BETA10 0x10073a60
LegoFloat GetX() { return m_x; }
// FUNCTION: BETA10 0x10073a90
void SetX(LegoFloat p_x) { m_x = p_x; }
// FUNCTION: BETA10 0x10073ac0
LegoFloat GetY() { return m_y; }
// FUNCTION: BETA10 0x10073af0
void SetY(LegoFloat p_y) { m_y = p_y; }
// FUNCTION: BETA10 0x10073b20
LegoFloat GetZ() { return m_z; }
// FUNCTION: BETA10 0x10073b50
void SetZ(LegoFloat p_z) { m_z = p_z; }
protected:
@ -93,6 +124,9 @@ class LegoMorphKey : public LegoAnimKey {
LegoResult Read(LegoStorage* p_storage);
LegoBool GetUnknown0x08() { return m_unk0x08; }
// FUNCTION: BETA10 0x100738d0
void SetUnknown0x08(LegoBool p_unk0x08) { m_unk0x08 = p_unk0x08; }
protected:
LegoBool m_unk0x08; // 0x08
};
@ -118,22 +152,64 @@ class LegoAnimNodeData : public LegoTreeNodeData {
LegoResult Read(LegoStorage* p_storage) override; // vtable+0x04
LegoResult Write(LegoStorage* p_storage) override; // vtable+0x08
void FUN_100a0360(LegoChar* p_param);
LegoResult CreateLocalTransform(LegoFloat p_time, Matrix4& p_matrix);
LegoBool FUN_100a0990(LegoFloat p_time);
const LegoChar* GetName() { return m_name; }
// FUNCTION: BETA10 0x100595d0
LegoChar* GetName() { return m_name; }
// FUNCTION: BETA10 0x10073780
LegoU16 GetNumTranslationKeys() { return m_numTranslationKeys; }
// FUNCTION: BETA10 0x100737b0
LegoU16 GetNumRotationKeys() { return m_numRotationKeys; }
// FUNCTION: BETA10 0x100737e0
void SetNumRotationKeys(LegoU16 p_numRotationKeys) { m_numRotationKeys = p_numRotationKeys; }
// FUNCTION: BETA10 0x10073810
void SetRotationKeys(LegoRotationKey* p_keys)
{
m_rotationKeys = p_keys;
m_rotationIndex = 0;
}
LegoU32 GetTranslationIndex() { return m_translationIndex; }
LegoU32 GetRotationIndex() { return m_rotationIndex; }
LegoU32 GetScaleIndex() { return m_scaleIndex; }
LegoU32 GetMorphIndex() { return m_morphIndex; }
// FUNCTION: BETA10 0x1005abc0
LegoU16 GetUnknown0x20() { return m_unk0x20; }
LegoU16 GetUnknown0x22() { return m_unk0x22; }
// FUNCTION: BETA10 0x10073b80
LegoRotationKey* GetRotationKey(MxS32 index) { return &m_rotationKeys[index]; }
void SetTranslationIndex(LegoU32 p_translationIndex) { m_translationIndex = p_translationIndex; }
void SetRotationIndex(LegoU32 p_rotationIndex) { m_rotationIndex = p_rotationIndex; }
void SetScaleIndex(LegoU32 p_scaleIndex) { m_scaleIndex = p_scaleIndex; }
void SetMorphIndex(LegoU32 p_morphIndex) { m_morphIndex = p_morphIndex; }
// FUNCTION: BETA10 0x10073930
LegoMorphKey* GetMorphKeys() { return m_morphKeys; }
// FUNCTION: BETA10 0x10073960
void SetMorphKeys(LegoMorphKey* p_morphKeys)
{
m_morphKeys = p_morphKeys;
m_morphIndex = 0;
}
// FUNCTION: BETA10 0x10073900
void SetNumMorphKeys(LegoU16 p_numMorphKeys) { m_numMorphKeys = p_numMorphKeys; }
// FUNCTION: BETA10 0x10059600
void SetUnknown0x20(LegoU16 p_unk0x20) { m_unk0x20 = p_unk0x20; }
// FUNCTION: BETA10 0x1005f2e0
void SetUnknown0x22(LegoU16 p_unk0x22) { m_unk0x22 = p_unk0x22; }
LegoResult CreateLocalTransform(LegoTime p_time, Matrix4& p_matrix)

View file

@ -25,9 +25,9 @@ struct LegoUnknown100db7f4 : public LegoEdge {
LegoResult FUN_1002ddc0(LegoWEEdge& p_f, Vector3& p_point)
{
if (p_f.IsEqual(*m_faceA)) {
p_point[0] = -m_unk0x28[0];
p_point[1] = -m_unk0x28[1];
p_point[2] = -m_unk0x28[2];
p_point[0] = -m_unk0x28.index_operator(0);
p_point[1] = -m_unk0x28.index_operator(1);
p_point[2] = -m_unk0x28.index_operator(2);
}
else {
// clang-format off

View file

@ -8,6 +8,7 @@ DECOMP_SIZE_ASSERT(LegoTreeNode, 0x010)
DECOMP_SIZE_ASSERT(LegoTree, 0x08)
// FUNCTION: LEGO1 0x10099d60
// FUNCTION: BETA10 0x10187dd0
LegoTreeNode::LegoTreeNode()
{
m_data = NULL;
@ -16,6 +17,7 @@ LegoTreeNode::LegoTreeNode()
}
// FUNCTION: LEGO1 0x10099da0
// FUNCTION: BETA10 0x10187e10
LegoTreeNode::~LegoTreeNode()
{
if (m_data) {

View file

@ -13,6 +13,7 @@ class LegoStorage;
class LegoTreeNodeData {
public:
LegoTreeNodeData() {}
// FUNCTION: LEGO1 0x1009a0e0
virtual ~LegoTreeNodeData() {}
@ -27,27 +28,38 @@ class LegoTreeNodeData {
};
// VTABLE: LEGO1 0x100db764
// VTABLE: BETA10 0x101c37f4
// SIZE 0x10
class LegoTreeNode {
public:
LegoTreeNode();
virtual ~LegoTreeNode();
// FUNCTION: BETA10 0x100595a0
LegoTreeNodeData* GetData() { return m_data; }
// FUNCTION: BETA10 0x100736f0
void SetData(LegoTreeNodeData* p_data) { m_data = p_data; }
// FUNCTION: BETA10 0x10012150
LegoU32 GetNumChildren() { return m_numChildren; }
// FUNCTION: BETA10 0x10073370
void SetNumChildren(LegoU32 p_numChildren) { m_numChildren = p_numChildren; }
// FUNCTION: BETA10 0x10012180
LegoTreeNode* GetChild(LegoU32 p_i) { return m_children[p_i]; }
void SetChild(LegoU32 p_i, LegoTreeNode* p_child) { m_children[p_i] = p_child; }
// FUNCTION: BETA10 0x100733a0
LegoTreeNode** GetChildren() { return m_children; }
// FUNCTION: BETA10 0x10073720
void SetChildren(LegoTreeNode** p_children) { m_children = p_children; }
// SYNTHETIC: LEGO1 0x10099d80
// SYNTHETIC: BETA10 0x10188cb0
// LegoTreeNode::`scalar deleting destructor'
protected:
@ -66,7 +78,9 @@ class LegoTree {
// FUNCTION: BETA10 0x100121b0
LegoTreeNode* GetRoot() { return m_root; }
// FUNCTION: BETA10 0x10073750
void SetRoot(LegoTreeNode* p_root) { m_root = p_root; }
virtual LegoResult Read(LegoStorage* p_storage); // vtable+0x04
virtual LegoResult Write(LegoStorage* p_storage); // vtable+0x08

View file

@ -341,6 +341,7 @@ LegoResult LegoROI::FUN_100a8cb0(LegoAnimNodeData* p_data, LegoTime p_time, Matr
}
// FUNCTION: LEGO1 0x100a8ce0
// FUNCTION: BETA10 0x1018a815
LegoROI* LegoROI::FindChildROI(const LegoChar* p_name, LegoROI* p_roi)
{
CompoundObject::iterator it;
@ -551,6 +552,18 @@ LegoResult LegoROI::GetTexture(LegoTextureInfo*& p_textureInfo)
return FAILURE;
}
// FUNCTION: LEGO1 0x100a9350
// FUNCTION: BETA10 0x1018b25c
LegoResult LegoROI::FUN_100a9350(const LegoChar* p_color)
{
MxFloat red, green, blue, alpha;
if (ColorAliasLookup(p_color, red, green, blue, alpha)) {
return FUN_100a9170(red, green, blue, alpha);
}
return SUCCESS;
}
// FUNCTION: LEGO1 0x100a9410
// FUNCTION: BETA10 0x1018b324
LegoU32 LegoROI::FUN_100a9410(
@ -778,6 +791,13 @@ void LegoROI::SetName(const LegoChar* p_name)
}
}
// STUB: LEGO1 0x100a9dd0
// STUB: BETA10 0x1018bfdb
void LegoROI::FUN_100a9dd0()
{
// TODO
}
// FUNCTION: LEGO1 0x100a9e10
void LegoROI::SetDisplayBB(int p_displayBB)
{

View file

@ -38,12 +38,14 @@ class LegoROI : public ViewROI {
LegoResult FUN_100a9170(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha);
LegoResult FUN_100a9210(LegoTextureInfo* p_textureInfo);
LegoResult GetTexture(LegoTextureInfo*& p_textureInfo);
LegoResult FUN_100a9350(const LegoChar* p_color);
LegoU32 FUN_100a9410(Vector3& p_v1, Vector3& p_v2, float p_f1, float p_f2, Vector3& p_v3, LegoBool p_collideBox);
void SetName(const LegoChar* p_name);
float IntrinsicImportance() const override; // vtable+0x04
void UpdateWorldBoundingVolumes() override; // vtable+0x18
void FUN_100a9dd0();
void SetDisplayBB(int p_displayBB);
static LegoResult FUN_100a8cb0(LegoAnimNodeData* p_data, LegoTime p_time, Matrix4& p_matrix);

View file

@ -482,6 +482,7 @@
// __setmode_lk
// LIBRARY: LEGO1 0x100d1ed0
// LIBRARY: BETA10 0x1018ec70
// _strnicmp
// LIBRARY: LEGO1 0x100d1fd0
@ -682,6 +683,9 @@
// LIBRARY: BETA10 0x100f9780
// strlen
// LIBRARY: BETA10 0x100fa200
// strcpy
// LIBRARY: BETA10 0x100f8a88
// operator new
@ -703,7 +707,31 @@
// LIBRARY: BETA10 0x100fe5a0
// abort
// LIBRARY: BETA10 0x100fa0e0
// atof
// LIBRARY: BETA10 0x1005a9c0
// fabs
// LIBRARY: BETA10 0x1005a9f0
// fabsf
// LIBRARY: BETA10 0x100f9bb0
// _fabs
// LIBRARY: BETA10 0x100f9570
// memset
// LIBRARY: BETA10 0x100ff82b
// __ctrandisp1
// LIBRARY: BETA10 0x100f8a92
// operator delete
// LIBRARY: BETA10 0x1018ed70
// _strupr
// LIBRARY: BETA10 0x1001d1a0
// `vector constructor iterator'
#endif

View file

@ -6,10 +6,15 @@
#include "realtime/vector.h"
// VTABLE: LEGO1 0x100d4488
// VTABLE: BETA10 0x101b84d0
// SIZE 0x14
class Mx3DPointFloat : public Vector3 {
public:
// FUNCTION: LEGO1 0x1001d170
// FUNCTION: BETA10 0x10011990
Mx3DPointFloat() : Vector3(m_elements) {}
// FUNCTION: BETA10 0x10011870
Mx3DPointFloat(float p_x, float p_y, float p_z) : Vector3(m_elements)
{
m_elements[0] = p_x;
@ -24,18 +29,18 @@ class Mx3DPointFloat : public Vector3 {
// FUNCTION: BETA10 0x100151e0
Mx3DPointFloat(const Vector3& p_other) : Vector3(m_elements) { EqualsImpl(p_other.m_data); }
// SYNTHETIC: LEGO1 0x1001d170
// Mx3DPointFloat::Mx3DPointFloat
// FUNCTION: LEGO1 0x10003c10
virtual void operator=(const Vector3& p_impl) { EqualsImpl(p_impl.m_data); } // vtable+0x88
float GetX() { return m_data[0]; }
float GetY() { return m_data[1]; }
float GetZ() { return m_data[2]; }
// FUNCTION: BETA10 0x10013460
float& operator[](int idx) { return m_data[idx]; }
const float& operator[](int idx) const { return m_data[idx]; }
// According to the PDB, BETA10 will not link this one if it is never used
// const float& operator[](int idx) const { return m_data[idx]; }
// only used by LegoUnknown100db7f4::FUN_1002ddc0() for some unknown reason
// FUNCTION: BETA10 0x100373c0
float& index_operator(int idx) { return m_data[idx]; }
// SYNTHETIC: LEGO1 0x10010c00
// Mx3DPointFloat::operator=
@ -50,6 +55,7 @@ class Mx3DPointFloat : public Vector3 {
class Mx4DPointFloat : public Vector4 {
public:
// FUNCTION: LEGO1 0x10048290
// FUNCTION: BETA10 0x100484c0
Mx4DPointFloat() : Vector4(m_elements) {}
// FUNCTION: BETA10 0x10073bb0

View file

@ -86,13 +86,13 @@ class MxDSAction : public MxDSObject {
void SetLoopCount(MxS32 p_loopCount) { m_loopCount = p_loopCount; }
// FUNCTION: BETA10 0x1003db50
Mx3DPointFloat& GetLocation() { return m_location; }
Vector3& GetLocation() { return m_location; }
// FUNCTION: BETA10 0x1003db80
Mx3DPointFloat& GetDirection() { return m_direction; }
Vector3& GetDirection() { return m_direction; }
// FUNCTION: BETA10 0x1003dbb0
Mx3DPointFloat& GetUp() { return m_up; }
Vector3& GetUp() { return m_up; }
void SetLocation(const Vector3& p_location) { m_location = p_location; }
void SetDirection(const Vector3& p_direction) { m_direction = p_direction; }

View file

@ -69,7 +69,9 @@ class MxDSObject : public MxCore {
// FUNCTION: BETA10 0x10017910
MxU32 GetObjectId() { return m_objectId; }
// FUNCTION: BETA10 0x10017940
const MxAtomId& GetAtomId() { return m_atomId; }
MxS16 GetUnknown24() { return m_unk0x24; }
MxPresenter* GetUnknown28() { return m_unk0x28; }

View file

@ -30,6 +30,7 @@ class MxDSSound : public MxDSMediaAction {
void Deserialize(MxU8*& p_source, MxS16 p_unk0x24) override; // vtable+1c;
MxDSAction* Clone() override; // vtable+2c;
// FUNCTION: BETA10 0x1008d060
MxS32 GetVolume() const { return m_volume; }
// SYNTHETIC: LEGO1 0x100c9450

View file

@ -39,6 +39,7 @@ enum NotificationId {
// SIZE 0x0c
class MxNotificationParam : public MxParam {
public:
// FUNCTION: BETA10 0x100702d0
MxNotificationParam() : m_type(c_notificationType0), m_sender(NULL) {}
// FUNCTION: BETA10 0x10013490

View file

@ -98,6 +98,7 @@ class MxPresenter : public MxCore {
virtual void EndAction(); // vtable+0x40
// FUNCTION: LEGO1 0x1000bf90
// FUNCTION: BETA10 0x10054a50
virtual void SetTickleState(TickleState p_tickleState) { ProgressTickleState(p_tickleState); } // vtable+0x44
// FUNCTION: LEGO1 0x1000bfb0

View file

@ -25,10 +25,11 @@ class MxSoundManager : public MxAudioManager {
float GetAttenuation(MxU32 p_volume);
MxPresenter* FUN_100aebd0(const MxAtomId& p_atomId, MxU32 p_objectId);
protected:
void Init();
void Destroy(MxBool p_fromDestructor);
MxPresenter* FUN_100aebd0(const MxAtomId& p_atomId, MxU32 p_objectId);
// [library:audio]
// Upscaling everything to 44.1KHz, since we have various sample rates throughout the game.

View file

@ -7,10 +7,13 @@ class MxDSBuffer;
class MxStreamListMxDSSubscriber;
// VTABLE: LEGO1 0x100dc2a8
// VTABLE: BETA10 0x101c1d20
// SIZE 0x20
class MxStreamChunk : public MxDSChunk {
public:
// FUNCTION: BETA10 0x10134420
MxStreamChunk() : m_buffer(NULL) {}
~MxStreamChunk() override;
// FUNCTION: LEGO1 0x100b1fe0

View file

@ -52,14 +52,17 @@ class MxVideoPresenter : public MxMediaPresenter {
MxBool IsHit(MxS32 p_x, MxS32 p_y) override; // vtable+0x50
// FUNCTION: LEGO1 0x1000c700
// FUNCTION: BETA10 0x10054a80
virtual void LoadHeader(MxStreamChunk* p_chunk) {} // vtable+0x5c
// FUNCTION: LEGO1 0x1000c710
// FUNCTION: BETA10 0x10054aa0
virtual void CreateBitmap() {} // vtable+0x60
virtual void NextFrame(); // vtable+0x64
// FUNCTION: LEGO1 0x1000c720
// FUNCTION: BETA10 0x10054ac0
virtual void LoadFrame(MxStreamChunk* p_chunk) {} // vtable+0x68
virtual void PutFrame(); // vtable+0x6c

View file

@ -229,6 +229,7 @@ void MxMediaPresenter::DoneTickle()
}
// FUNCTION: LEGO1 0x100b5f10
// FUNCTION: BETA10 0x101366e9
void MxMediaPresenter::LoopChunk(MxStreamChunk* p_chunk)
{
MxStreamChunk* chunk = new MxStreamChunk;
@ -243,6 +244,7 @@ void MxMediaPresenter::LoopChunk(MxStreamChunk* p_chunk)
}
// FUNCTION: LEGO1 0x100b6030
// FUNCTION: BETA10 0x10136814
void MxMediaPresenter::Enable(MxBool p_enable)
{
if (IsEnabled() != p_enable) {

View file

@ -110,6 +110,7 @@ void MxPresenter::ParseExtra()
}
// FUNCTION: LEGO1 0x100b5120
// FUNCTION: BETA10 0x1012e5d8
void MxPresenter::SendToCompositePresenter(MxOmni* p_omni)
{
if (m_compositePresenter) {
@ -260,6 +261,7 @@ MxEntity* MxPresenter::CreateEntity(const char* p_defaultName)
}
// FUNCTION: LEGO1 0x100b54c0
// FUNCTION: BETA10 0x1012ebaf
MxBool MxPresenter::IsEnabled()
{
return this->m_action && this->m_action->GetFlags() & MxDSAction::c_enabled;

View file

@ -176,6 +176,7 @@ void MxVideoPresenter::Destroy(MxBool p_fromDestructor)
}
// FUNCTION: LEGO1 0x100b28b0
// FUNCTION: BETA10 0x101389c1
void MxVideoPresenter::NextFrame()
{
MxStreamChunk* chunk = NextChunk();
@ -191,6 +192,7 @@ void MxVideoPresenter::NextFrame()
}
// FUNCTION: LEGO1 0x100b2900
// FUNCTION: BETA10 0x10138a3a
MxBool MxVideoPresenter::IsHit(MxS32 p_x, MxS32 p_y)
{
MxDSAction* action = GetAction();
@ -563,6 +565,7 @@ void MxVideoPresenter::EndAction()
}
// FUNCTION: LEGO1 0x100b3280
// FUNCTION: BETA10 0x101397c0
MxResult MxVideoPresenter::PutData()
{
AUTOLOCK(m_criticalSection);

View file

@ -25,6 +25,7 @@ class Matrix4 {
// in reverse order of appearance.
// FUNCTION: LEGO1 0x10002320
// FUNCTION: BETA10 0x1000fcb0
virtual void Equals(float (*p_data)[4]) { memcpy(m_data, p_data, sizeof(float) * 4 * 4); } // vtable+0x04
// FUNCTION: LEGO1 0x10002340
@ -35,27 +36,35 @@ class Matrix4 {
} // vtable+0x00
// FUNCTION: LEGO1 0x10002360
// FUNCTION: BETA10 0x1000fd30
virtual void SetData(float (*p_data)[4]) { m_data = p_data; } // vtable+0x0c
// FUNCTION: LEGO1 0x10002370
// FUNCTION: BETA10 0x1000fd60
virtual void SetData(UnknownMatrixType& p_matrix) { m_data = p_matrix.m_data; } // vtable+0x08
// FUNCTION: LEGO1 0x10002380
// FUNCTION: BETA10 0x1000fd90
virtual float (*GetData())[4] { return m_data; } // vtable+0x14
// FUNCTION: LEGO1 0x10002390
// FUNCTION: BETA10 0x1000fdc0
virtual float (*GetData() const)[4] { return m_data; } // vtable+0x10
// FUNCTION: LEGO1 0x100023a0
// FUNCTION: BETA10 0x1000fdf0
virtual float* Element(int p_row, int p_col) { return &m_data[p_row][p_col]; } // vtable+0x1c
// FUNCTION: LEGO1 0x100023c0
// FUNCTION: BETA10 0x1000fe30
virtual const float* Element(int p_row, int p_col) const { return &m_data[p_row][p_col]; } // vtable+0x18
// FUNCTION: LEGO1 0x100023e0
// FUNCTION: BETA10 0x1000fe70
virtual void Clear() { memset(m_data, 0, 16 * sizeof(float)); } // vtable+0x20
// FUNCTION: LEGO1 0x100023f0
// FUNCTION: BETA10 0x1000feb0
virtual void SetIdentity()
{
Clear();
@ -66,9 +75,11 @@ class Matrix4 {
} // vtable+0x24
// FUNCTION: LEGO1 0x10002420
// FUNCTION: BETA10 0x1000ff20
virtual void operator=(const Matrix4& p_matrix) { Equals(p_matrix); } // vtable+0x28
// FUNCTION: LEGO1 0x10002430
// FUNCTION: BETA10 0x1000ff50
virtual Matrix4& operator+=(float (*p_data)[4])
{
for (int i = 0; i < 16; i++) {
@ -78,6 +89,7 @@ class Matrix4 {
} // vtable+0x2c
// FUNCTION: LEGO1 0x10002460
// FUNCTION: BETA10 0x1000ffc0
virtual void TranslateBy(const float& p_x, const float& p_y, const float& p_z)
{
m_data[3][0] += p_x;
@ -86,6 +98,7 @@ class Matrix4 {
} // vtable+0x30
// FUNCTION: LEGO1 0x100024a0
// FUNCTION: BETA10 0x10010040
virtual void SetTranslation(const float& p_x, const float& p_y, const float& p_z)
{
m_data[3][0] = p_x;
@ -94,6 +107,7 @@ class Matrix4 {
} // vtable+0x34
// FUNCTION: LEGO1 0x100024d0
// FUNCTION: BETA10 0x100100a0
virtual void Product(float (*p_a)[4], float (*p_b)[4])
{
float* cur = (float*) m_data;
@ -109,6 +123,7 @@ class Matrix4 {
} // vtable+0x3c
// FUNCTION: LEGO1 0x10002530
// FUNCTION: BETA10 0x10010180
virtual void Product(const Matrix4& p_a, const Matrix4& p_b) { Product(p_a.m_data, p_b.m_data); } // vtable+0x38
inline virtual void ToQuaternion(Vector4& p_resultQuat); // vtable+0x40
@ -183,6 +198,7 @@ class Matrix4 {
};
// FUNCTION: LEGO1 0x10002550
// FUNCTION: BETA10 0x100101c0
inline void Matrix4::ToQuaternion(Vector4& p_outQuat)
{
float trace = m_data[0][0] + m_data[1][1] + m_data[2][2];
@ -223,6 +239,7 @@ inline void Matrix4::ToQuaternion(Vector4& p_outQuat)
}
// FUNCTION: LEGO1 0x10002710
// FUNCTION: BETA10 0x10010550
inline int Matrix4::FromQuaternion(const Vector4& p_vec)
{
float len = p_vec.LenSquared();

View file

@ -48,7 +48,9 @@ class OrientableROI : public ROI {
// FUNCTION: BETA10 0x10011780
const float* GetWorldDirection() const { return m_local2world[2]; }
// FUNCTION: BETA10 0x1004aa70
const float* GetWorldUp() const { return m_local2world[1]; }
OrientableROI* GetParentROI() const { return m_parentROI; }
void SetParentROI(OrientableROI* p_parentROI) { m_parentROI = p_parentROI; }

View file

@ -3,6 +3,7 @@
#include <vec.h>
// FUNCTION: LEGO1 0x100a5b40
// FUNCTION: BETA10 0x10168127
void CalcLocalTransform(const Vector3& p_posVec, const Vector3& p_dirVec, const Vector3& p_upVec, Matrix4& p_outMatrix)
{
float x_axis[3], y_axis[3], z_axis[3];

View file

@ -118,6 +118,8 @@ class ROI {
const CompoundObject* GetComp() const { return comp; }
unsigned char GetVisibility() { return m_visible; }
// FUNCTION: BETA10 0x10011720
void SetVisibility(unsigned char p_visible) { m_visible = p_visible; }
// SYNTHETIC: LEGO1 0x100a5d60

View file

@ -163,13 +163,10 @@ class Vector2 {
return *this;
}
// SYNTHETIC: BETA10 0x10013460
// Vector3::operator[]
// FUNCTION: BETA10 0x10010890
// FUNCTION: BETA10 0x1001d140
float& operator[](int idx) { return m_data[idx]; }
// FUNCTION: BETA10 0x1001d140
// FUNCTION: BETA10 0x1001d170
const float& operator[](int idx) const { return m_data[idx]; }
protected:
@ -182,12 +179,15 @@ class Vector2 {
class Vector3 : public Vector2 {
public:
// FUNCTION: LEGO1 0x1001d150
// FUNCTION: BETA10 0x10011660
Vector3(float* p_data) : Vector2(p_data) {}
// Hack: Some code initializes a Vector3 from a (most likely) const float* source.
// Example: LegoCameraController::GetWorldUp
// Vector3 however is a class that can mutate its underlying source, making
// initialization with a const source fundamentally incompatible.
// FUNCTION: BETA10 0x100109a0
Vector3(const float* p_data) : Vector2((float*) p_data) {}
// Note: virtual function overloads appear in the virtual table
@ -298,6 +298,7 @@ class Vector3 : public Vector2 {
// SIZE 0x08
class Vector4 : public Vector3 {
public:
// FUNCTION: BETA10 0x10048780
Vector4(float* p_data) : Vector3(p_data) {}
// Hack: Some code initializes a Vector4 from a (most likely) const float* source.
@ -407,6 +408,11 @@ class Vector4 : public Vector3 {
m_data[3] = p_value;
} // vtable+0x84
float& operator[](int idx) { return m_data[idx]; }
// FUNCTION: BETA10 0x10010890
const float& operator[](int idx) const { return m_data[idx]; }
friend class Mx4DPointFloat;
};