Skip to content

Commit

Permalink
Complete LegoCarBuildAnimPresenter (#1114)
Browse files Browse the repository at this point in the history
* Complete `LegoCarBuildAnimPresenter`

* fix CI errors

* Drive-by BETA10 fixes

* Address review comments

---------

Co-authored-by: jonschz <[email protected]>
  • Loading branch information
jonschz and jonschz authored Oct 20, 2024
1 parent 91205be commit b5fee6b
Show file tree
Hide file tree
Showing 17 changed files with 188 additions and 25 deletions.
15 changes: 11 additions & 4 deletions LEGO1/lego/legoomni/include/legocarbuildpresenter.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
// SIZE 0x150
class LegoCarBuildAnimPresenter : public LegoAnimPresenter {
public:
enum {
c_bit1 = 0x01
};

// SIZE 0x0c
struct UnknownListEntry {
// FUNCTION: LEGO1 0x100795c0
Expand Down Expand Up @@ -67,7 +71,8 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter {
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 PartIsPlaced(const LegoChar* p_name);
void FUN_10079a90();
MxBool StringEqualsPlatform(const LegoChar* p_string);
MxBool StringEqualsShelf(const LegoChar* p_string);
MxBool FUN_10079cf0(const LegoChar* p_string);
Expand All @@ -84,7 +89,9 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter {
// LegoCarBuildAnimPresenter::`scalar deleting destructor'

private:
undefined2 m_unk0xbc; // 0xbc
void Beta10Inline0x100733d0();

MxU16 m_unk0xbc; // 0xbc

// variable name verified by BETA10 0x1007184f
MxS16 m_numberOfParts; // 0xbe
Expand All @@ -100,10 +107,10 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter {
UnknownListEntry* m_parts; // 0x128

MxFloat m_unk0x12c; // 0x12c
undefined4 m_unk0x130; // 0x130
MxFloat m_unk0x130; // 0x130
MxFloat m_unk0x134; // 0x134
MxFloat m_unk0x138; // 0x138
undefined4 m_unk0x13c; // 0x13c
MxLong m_unk0x13c; // 0x13c
LegoEntity* m_unk0x140; // 0x140
MxS32 m_unk0x144; // 0x144
MxS32 m_unk0x148; // 0x148
Expand Down
2 changes: 1 addition & 1 deletion LEGO1/lego/legoomni/include/legoextraactor.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions LEGO1/lego/legoomni/include/legoraceactor.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions LEGO1/lego/legoomni/src/build/legocarbuild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,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);
}
Expand Down Expand Up @@ -408,7 +408,7 @@ MxResult LegoCarBuild::Tickle()
}

if (m_unk0x110) {
if (m_unk0x258->FUN_10079ca0(m_unk0x110->GetName())) {
if (m_unk0x258->PartIsPlaced(m_unk0x110->GetName())) {
FUN_10022f30();
}
}
Expand Down Expand Up @@ -697,7 +697,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 {
Expand All @@ -706,7 +706,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];
Expand Down
140 changes: 127 additions & 13 deletions LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#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)
Expand Down Expand Up @@ -62,10 +64,75 @@ LegoCarBuildAnimPresenter::~LegoCarBuildAnimPresenter()
}
}

// 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();
}

// FUNCTION: LEGO1 0x100788c0
Expand Down Expand Up @@ -351,18 +418,42 @@ void LegoCarBuildAnimPresenter::FUN_10079160()
m_unk0xc8.SetRoot(destNode);
}

// STUB: LEGO1 0x100795d0
// STUB: BETA10 0x10071d96
// FUNCTION: LEGO1 0x100795d0
// FUNCTION: BETA10 0x10071d96
void LegoCarBuildAnimPresenter::FUN_100795d0(LegoChar* p_param)
{
// TODO
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;
}
}

// STUB: LEGO1 0x10079680
// STUB: BETA10 0x10071ec5
// FUNCTION: LEGO1 0x10079680
// FUNCTION: BETA10 0x10071ec5
void LegoCarBuildAnimPresenter::FUN_10079680(LegoChar* p_param)
{
// TODO
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
Expand Down Expand Up @@ -449,6 +540,25 @@ void LegoCarBuildAnimPresenter::RotateAroundYAxis(MxFloat p_angle)
}
}

// 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)
Expand Down Expand Up @@ -478,17 +588,21 @@ MxBool LegoCarBuildAnimPresenter::StringEqualsShelf(const LegoChar* p_string)
return strnicmp(p_string, "SHELF", strlen("SHELF")) == 0;
}

// STUB: LEGO1 0x10079c30
// STUB: BETA10 0x100726a6
// FUNCTION: LEGO1 0x10079c30
// FUNCTION: BETA10 0x100726a6
MxBool LegoCarBuildAnimPresenter::FUN_10079c30(const LegoChar* p_name)
{
// TODO
return FALSE;
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_placedPartCount; i++) {
if (strcmpi(p_name, m_parts[i].m_name) == 0) {
Expand Down
1 change: 1 addition & 0 deletions LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -904,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();
Expand Down
4 changes: 3 additions & 1 deletion LEGO1/lego/sources/anim/legoanim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -907,6 +908,7 @@ undefined4 LegoAnim::GetActorUnknown0x04(LegoU32 p_index)
}

// FUNCTION: LEGO1 0x100a0f60
// FUNCTION: BETA10 0x1018027c
LegoMorphKey::LegoMorphKey()
{
m_unk0x08 = 0;
Expand Down
22 changes: 21 additions & 1 deletion LEGO1/lego/sources/anim/legoanim.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ 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; }
Expand Down Expand Up @@ -120,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
};
Expand Down Expand Up @@ -186,6 +193,19 @@ class LegoAnimNodeData : public LegoTreeNodeData {
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; }

Expand Down
1 change: 1 addition & 0 deletions LEGO1/lego/sources/misc/legotree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ LegoTreeNode::LegoTreeNode()
}

// FUNCTION: LEGO1 0x10099da0
// FUNCTION: BETA10 0x10187e10
LegoTreeNode::~LegoTreeNode()
{
if (m_data) {
Expand Down
4 changes: 3 additions & 1 deletion LEGO1/lego/sources/misc/legotree.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
class LegoStorage;

// VTABLE: LEGO1 0x100db778
// VTABLE: BETA10 0x101c37f4
// SIZE 0x04
class LegoTreeNodeData {
public:
LegoTreeNodeData() {}

// FUNCTION: LEGO1 0x1009a0e0
virtual ~LegoTreeNodeData() {}

Expand All @@ -28,6 +28,7 @@ class LegoTreeNodeData {
};

// VTABLE: LEGO1 0x100db764
// VTABLE: BETA10 0x101c37f4
// SIZE 0x10
class LegoTreeNode {
public:
Expand Down Expand Up @@ -58,6 +59,7 @@ class LegoTreeNode {
void SetChildren(LegoTreeNode** p_children) { m_children = p_children; }

// SYNTHETIC: LEGO1 0x10099d80
// SYNTHETIC: BETA10 0x10188cb0
// LegoTreeNode::`scalar deleting destructor'

protected:
Expand Down
Loading

0 comments on commit b5fee6b

Please sign in to comment.