Implement/match LegoAnimActor (#730)

* Implement/match LegoAnimActor

* Name changes (deviation from original source)

* Attempt to fix modern build

* Add missing override

* Match LegoAnimActor::SetWorldSpeed

* Remove junk

* Style changes and implement WEEdge

* Add override

* Match LegoAnimActor::FUN_1001c1f0, style

* Style

* Add missing annotations, STUB LegoPathBoundary

* Style

---------

Co-authored-by: Christian Semmler <mail@csemmler.com>
This commit is contained in:
Nathan M Gilbert
2024-03-26 13:51:52 -04:00
committed by GitHub
parent 43ce89224a
commit 1e3ca11886
25 changed files with 534 additions and 94 deletions

View File

@@ -2,36 +2,12 @@
DECOMP_SIZE_ASSERT(BumpBouy, 0x174)
// STUB: LEGO1 0x1000fd00
void BumpBouy::ParseAction(char*)
{
// TODO
}
// STUB: LEGO1 0x1000fd10
void BumpBouy::SetWorldSpeed(MxFloat p_worldSpeed)
{
// TODO
}
// STUB: LEGO1 0x1000fd20
void BumpBouy::VTable0x70(float p_float)
{
// TODO
}
// STUB: LEGO1 0x1000fd30
void BumpBouy::VTable0x74(Matrix4& p_transform)
{
// TODO
}
// STUB: LEGO1 0x10027220
BumpBouy::BumpBouy()
{
}
// STUB: LEGO1 0x100274d0
// STUB: LEGO1 0x10027400
MxLong BumpBouy::Notify(MxParam& p_param)
{
// TODO

View File

@@ -311,7 +311,7 @@ MxU32 Helicopter::VTable0xd8(MxType18NotificationParam& p_param)
// FUNCTION: LEGO1 0x10003e90
void Helicopter::VTable0x74(Matrix4& p_transform)
{
if (m_unk0xea != 0) {
if (m_userNavFlag) {
m_roi->FUN_100a46b0(p_transform);
FUN_10010c30();
}

View File

@@ -72,7 +72,7 @@ void IslePathActor::VTable0xe8(LegoGameState::Area, MxBool, MxU8)
}
// STUB: LEGO1 0x1001b5b0
void IslePathActor::VTable0xec(MxMatrix, MxU32, MxBool)
void IslePathActor::VTable0xec(MxMatrix, LegoPathBoundary*, MxBool)
{
// TODO
}

View File

@@ -181,7 +181,7 @@ void LegoGameState::SetActor(MxU8 p_actorId)
if (oldActor) {
newActor->GetROI()->FUN_100a58f0(oldActor->GetROI()->GetLocal2World());
newActor->SetUnknown88(oldActor->GetUnknown88());
newActor->SetBoundary(oldActor->GetBoundary());
delete oldActor;
}

View File

@@ -1,27 +1,218 @@
#include "legoanimactor.h"
#include "define.h"
#include "legoanimpresenter.h"
#include "legoworld.h"
#include "misc.h"
#include "mxutilities.h"
DECOMP_SIZE_ASSERT(LegoAnimActor, 0x174)
DECOMP_SIZE_ASSERT(LegoAnimActorStruct, 0x20)
// STUB: LEGO1 0x1001c1f0
MxResult LegoAnimActor::FUN_1001c1f0(float& p_out)
// FUNCTION: LEGO1 0x1001bf80
LegoAnimActorStruct::LegoAnimActorStruct(float p_unk0x00, LegoAnim* p_AnimTreePtr, LegoROI** p_roiMap, MxU32 p_numROIs)
{
// TODO
m_unk0x00 = p_unk0x00;
m_AnimTreePtr = p_AnimTreePtr;
m_roiMap = p_roiMap;
m_numROIs = p_numROIs;
}
// FUNCTION: LEGO1 0x1001c0a0
LegoAnimActorStruct::~LegoAnimActorStruct()
{
for (MxU16 i = 0; i < m_unk0x10.size(); i++) {
delete m_unk0x10[i];
}
}
// FUNCTION: LEGO1 0x1001c130
float LegoAnimActorStruct::GetDuration()
{
return m_AnimTreePtr->GetDuration();
}
// FUNCTION: LEGO1 0x1001c140
LegoAnimActor::~LegoAnimActor()
{
for (MxS32 i = 0; i < m_animMaps.size(); i++) {
if (m_animMaps[i]) {
delete m_animMaps[i];
}
}
}
// FUNCTION: LEGO1 0x1001c1f0
MxResult LegoAnimActor::FUN_1001c1f0(float& p_und)
{
float duration = (float) m_animMaps[m_curAnim]->m_AnimTreePtr->GetDuration();
p_und = m_unk0x80 - duration * ((MxS32) (m_unk0x80 / duration));
return SUCCESS;
}
// STUB: LEGO1 0x1001c360
MxResult LegoAnimActor::FUN_1001c360(float, undefined4)
// FUNCTION: LEGO1 0x1001c240
void LegoAnimActor::VTable0x74(Matrix4& p_transform)
{
return FAILURE;
float und;
LegoPathActor::VTable0x74(p_transform);
if (m_curAnim >= 0) {
FUN_1001c1f0(und);
FUN_1001c360(und, p_transform);
}
}
// STUB: LEGO1 0x1001c450
MxResult LegoAnimActor::FUN_1001c450(undefined4, undefined4, undefined4, undefined4)
// FUNCTION: LEGO1 0x1001c290
void LegoAnimActor::VTable0x70(float p_float)
{
if (m_unk0x84 == 0) {
m_unk0x84 = p_float - 1.0f;
}
if (m_unk0xdc == 0 && !m_userNavFlag && m_worldSpeed <= 0) {
if (m_curAnim >= 0) {
MxMatrix matrix(m_unk0xec);
float f;
FUN_1001c1f0(f);
FUN_1001c360(f, matrix);
}
m_unk0x84 = m_unk0x80 = p_float;
}
else {
LegoPathActor::VTable0x70(p_float);
}
}
// FUNCTION: LEGO1 0x1001c360
MxResult LegoAnimActor::FUN_1001c360(float p_und, Matrix4& p_transform)
{
if (p_und >= 0) {
LegoROI** roiMap = m_animMaps[m_curAnim]->m_roiMap;
MxU32 numROIs = m_animMaps[m_curAnim]->m_numROIs;
if (!m_boundary->GetFlag0x10()) {
MxU32 i;
m_roi->SetVisibility(FALSE);
for (i = 0; i < numROIs; i++) {
LegoROI* roi = roiMap[i];
if (roi != NULL && m_roi != roi) {
roi->SetVisibility(FALSE);
}
}
}
else {
MxU32 i;
LegoTreeNode* root = m_animMaps[m_curAnim]->m_AnimTreePtr->GetRoot();
m_roi->SetVisibility(TRUE);
for (i = 0; i < numROIs; i++) {
LegoROI* roi = roiMap[i];
if (roi != NULL && m_roi != roi) {
roi->SetVisibility(TRUE);
}
}
for (i = 0; i < root->GetNumChildren(); i++) {
LegoROI::FUN_100a8e80(root->GetChild(i), p_transform, p_und, roiMap);
}
if (m_cameraFlag) {
FUN_10010c30();
}
}
return SUCCESS;
}
else {
return FAILURE;
}
}
// FUNCTION: LEGO1 0x1001c450
MxResult LegoAnimActor::FUN_1001c450(LegoAnim* p_animTreePtr, float p_unk0x00, LegoROI** p_roiMap, MxU32 p_numROIs)
{
LegoAnimActorStruct* laas = new LegoAnimActorStruct(p_unk0x00, p_animTreePtr, p_roiMap, p_numROIs);
for (vector<LegoAnimActorStruct*>::iterator it = m_animMaps.begin(); it != m_animMaps.end(); it++) {
if (p_unk0x00 < (*it)->m_unk0x00) {
m_animMaps.insert(it, laas);
SetWorldSpeed(m_worldSpeed);
return SUCCESS;
}
}
m_animMaps.push_back(laas);
SetWorldSpeed(m_worldSpeed);
return SUCCESS;
}
// STUB: LEGO1 0x1001c800
void LegoAnimActor::FUN_1001c800()
// FUNCTION: LEGO1 0x1001c800
void LegoAnimActor::ClearMaps()
{
for (MxU32 i = 0; i < m_animMaps.size(); i++) {
delete m_animMaps[i];
}
m_animMaps.clear();
m_curAnim = -1;
}
// FUNCTION: LEGO1 0x1001c870
void LegoAnimActor::SetWorldSpeed(MxFloat p_worldSpeed)
{
if (p_worldSpeed < 0) {
m_worldSpeed = 0;
}
else {
m_worldSpeed = p_worldSpeed;
}
if (m_animMaps.size() > 0) {
m_curAnim = 0;
if (m_worldSpeed >= m_animMaps[m_animMaps.size() - 1]->m_unk0x00) {
m_curAnim = m_animMaps.size() - 1;
}
else {
for (MxU32 i = 0; i < m_animMaps.size(); i++) {
if (m_worldSpeed <= m_animMaps[i]->m_unk0x00) {
m_curAnim = i;
break;
}
}
}
}
}
// FUNCTION: LEGO1 0x1001c920
void LegoAnimActor::ParseAction(char* p_extra)
{
LegoPathActor::ParseAction(p_extra);
LegoWorld* world = CurrentWorld();
char value[256];
if (world) {
if (KeyValueStringParse(value, g_strANIMATION, p_extra)) {
char* token = strtok(value, g_parseExtraTokens);
while (token) {
LegoAnimPresenter* presenter = (LegoAnimPresenter*) world->Find("LegoAnimPresenter", token);
if (presenter != NULL) {
token = strtok(NULL, g_parseExtraTokens);
if (token) {
presenter->FUN_1006d680(this, atof(token));
}
}
token = strtok(NULL, g_parseExtraTokens);
}
}
}
}

View File

@@ -0,0 +1,10 @@
#include "legopathboundary.h"
#include "decomp.h"
DECOMP_SIZE_ASSERT(LegoPathBoundary, 0x74)
// STUB: LEGO1 0x10056a70
LegoPathBoundary::LegoPathBoundary()
{
}

View File

@@ -517,3 +517,9 @@ void LegoAnimPresenter::VTable0x98()
{
// TODO
}
// STUB: LEGO1 0x1006d680
void LegoAnimPresenter::FUN_1006d680(LegoAnimActor* p_actor, MxFloat p_value)
{
// TODO
}

View File

@@ -796,8 +796,8 @@ void Isle::FUN_10032620()
switch (GameState()->m_currentArea) {
case LegoGameState::e_unk66: {
MxMatrix mat(CurrentActor()->GetROI()->GetLocal2World());
MxU32 unk0x88 = CurrentActor()->GetUnknown88();
CurrentActor()->VTable0xec(mat, unk0x88, TRUE);
LegoPathBoundary* boundary = CurrentActor()->GetBoundary();
CurrentActor()->VTable0xec(mat, boundary, TRUE);
break;
}
case LegoGameState::e_unk4: