Implement/match Act3Brickster::FUN_10042300 (#1238)

* Implement/match `Act3Brickster::FUN_10042300`

* Add comment about assignment operator

* Add another comment

* Fix

* add back BETA annotation
This commit is contained in:
Christian Semmler 2024-12-17 15:16:00 -07:00 committed by GitHub
parent 66e3c9a2e1
commit 90c687bde0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 188 additions and 68 deletions

View file

@ -22,9 +22,7 @@ class Vector3;
// VTABLE: LEGO1 0x100d7da8 // VTABLE: LEGO1 0x100d7da8
// SIZE 0x40 // SIZE 0x40
struct LegoPathCtrlEdge : public LegoUnknown100db7f4 { struct LegoPathCtrlEdge : public LegoUnknown100db7f4 {};
inline MxU32 FUN_10048c40(const Vector3& p_position);
};
struct LegoPathCtrlEdgeCompare { struct LegoPathCtrlEdgeCompare {
MxU32 operator()(const LegoPathCtrlEdge* p_lhs, const LegoPathCtrlEdge* p_rhs) const MxU32 operator()(const LegoPathCtrlEdge* p_lhs, const LegoPathCtrlEdge* p_rhs) const

View file

@ -613,11 +613,105 @@ MxResult Act3Brickster::FUN_100417c0()
return SUCCESS; return SUCCESS;
} }
// STUB: LEGO1 0x10042300 // FUNCTION: LEGO1 0x10042300
// STUB: BETA10 0x1001b017 // FUNCTION: BETA10 0x1001b017
MxS32 Act3Brickster::FUN_10042300() MxS32 Act3Brickster::FUN_10042300()
{ {
// TODO // TODO: Has poor inlining, can be fixed by changing the assignment operator in vector.h
// See extended comment in vector.h for operator=
Act3* a3 = (Act3*) m_world;
assert(a3 && a3->m_cop1 && a3->m_cop2);
assert(a3->m_cop1->GetROI() && a3->m_cop2->GetROI() && GetROI());
Mx3DPointFloat local64[2];
Mx3DPointFloat local38;
Mx3DPointFloat local18;
MxS32 local1c = 0;
float local24[2];
local64[0] = a3->m_cop1->GetROI()->GetLocal2World()[3];
local64[1] = a3->m_cop2->GetROI()->GetLocal2World()[3];
local38 = GetROI()->GetLocal2World()[3];
local18 = local64[0];
local18 -= local38;
local24[0] = local18.LenSquared();
local18 = local64[1];
local18 -= local38;
local24[1] = local18.LenSquared();
if (local24[1] < local24[0]) {
local1c = 1;
}
if (local24[local1c] < 225.0f) {
m_unk0x38 = 8;
if (m_grec != NULL) {
delete m_grec;
m_grec = NULL;
}
if (m_pInfo != NULL) {
m_pInfo = NULL;
}
assert(m_boundary && m_destEdge && m_roi);
LegoPathBoundary* boundaries[2];
LegoUnknown100db7f4* maxE = NULL;
boundaries[0] = m_boundary;
if (m_destEdge->FUN_10048c40(local38)) {
boundaries[1] = (LegoPathBoundary*) m_destEdge->OtherFace(m_boundary);
}
else {
boundaries[1] = NULL;
}
float local78, local98;
for (MxS32 i = 0; i < (MxS32) sizeOfArray(boundaries); i++) {
if (boundaries[i] != NULL) {
for (MxS32 j = 0; j < boundaries[i]->GetNumEdges(); j++) {
LegoUnknown100db7f4* e = boundaries[i]->GetEdges()[j];
if (e->GetMask0x03()) {
Mx3DPointFloat local94(*e->GetPointA());
local94 += *e->GetPointB();
local94 /= 2.0f;
local18 = local94;
local18 -= local64[local1c];
local98 = local18.LenSquared();
local94 -= local38;
local18 = local64[local1c];
local18 -= local38;
if (maxE == NULL || (local18.Dot(&local94, &local18) < 0.0f && local78 < local98)) {
maxE = e;
m_boundary = boundaries[i];
local78 = local98;
}
}
}
}
}
assert(maxE);
m_destEdge = maxE;
if (m_boundary != boundaries[0]) {
m_unk0xe4 = 1.0 - m_unk0xe4;
}
VTable0x9c();
}
return -1; return -1;
} }

View file

@ -920,68 +920,6 @@ MxResult LegoPathController::FUN_10048310(
return FAILURE; return FAILURE;
} }
// FUNCTION: LEGO1 0x10048c40
// FUNCTION: BETA10 0x1001cc90
inline MxU32 LegoPathCtrlEdge::FUN_10048c40(const Vector3& p_position)
{
MxFloat localc, local10;
MxU32 result = FALSE;
if (m_unk0x28[0] > 0.001 || m_unk0x28[0] < -0.001) {
localc = (p_position[0] - (*m_pointA)[0]) / m_unk0x28[0];
if (localc < 0 || localc > 1) {
return FALSE;
}
result = TRUE;
}
else {
if (p_position[0] > (*m_pointA)[0] + 0.001 || p_position[0] < (*m_pointA)[0] - 0.001) {
return FALSE;
}
}
if (m_unk0x28[1] > 0.001 || m_unk0x28[1] < -0.001) {
local10 = (p_position[1] - (*m_pointA)[1]) / m_unk0x28[1];
if (result) {
if (localc > local10 + 0.001 || localc < local10 - 0.001) {
return FALSE;
}
}
else {
result = TRUE;
localc = local10;
}
}
else {
if (p_position[1] > (*m_pointA)[1] + 0.001 || p_position[1] < (*m_pointA)[1] - 0.001) {
return FALSE;
}
}
if (m_unk0x28[2] > 0.001 || m_unk0x28[2] < -0.001) {
local10 = (p_position[2] - (*m_pointA)[2]) / m_unk0x28[2];
if (result) {
if (localc > local10 + 0.001 || localc < local10 - 0.001) {
return FALSE;
}
}
else {
return TRUE;
}
}
else {
if (p_position[2] > (*m_pointA)[2] + 0.001 || p_position[2] < (*m_pointA)[2] - 0.001) {
return FALSE;
}
}
return TRUE;
}
// FUNCTION: LEGO1 0x1004a240 // FUNCTION: LEGO1 0x1004a240
// FUNCTION: BETA10 0x100b9160 // FUNCTION: BETA10 0x100b9160
MxS32 LegoPathController::FUN_1004a240( MxS32 LegoPathController::FUN_1004a240(

View file

@ -19,6 +19,12 @@ struct LegoEdge {
LegoResult FUN_1002ddc0(LegoWEEdge& p_face, Vector3& p_point); LegoResult FUN_1002ddc0(LegoWEEdge& p_face, Vector3& p_point);
// FUNCTION: BETA10 0x1001cb80
Vector3* GetPointA() { return m_pointA; }
// FUNCTION: BETA10 0x1001cbb0
Vector3* GetPointB() { return m_pointB; }
// SYNTHETIC: LEGO1 0x1009a4a0 // SYNTHETIC: LEGO1 0x1009a4a0
// LegoEdge::`scalar deleting destructor' // LegoEdge::`scalar deleting destructor'

View file

@ -93,6 +93,8 @@ struct LegoUnknown100db7f4 : public LegoEdge {
// FUNCTION: BETA10 0x1001cc60 // FUNCTION: BETA10 0x1001cc60
LegoU32 GetMask0x03() { return m_flags & (c_bit1 | c_bit2); } LegoU32 GetMask0x03() { return m_flags & (c_bit1 | c_bit2); }
inline LegoU32 FUN_10048c40(const Vector3& p_position);
// SYNTHETIC: LEGO1 0x1009a6c0 // SYNTHETIC: LEGO1 0x1009a6c0
// LegoUnknown100db7f4::`scalar deleting destructor' // LegoUnknown100db7f4::`scalar deleting destructor'
@ -101,4 +103,66 @@ struct LegoUnknown100db7f4 : public LegoEdge {
float m_unk0x3c; // 0x3c float m_unk0x3c; // 0x3c
}; };
// FUNCTION: LEGO1 0x10048c40
// FUNCTION: BETA10 0x1001cc90
inline LegoU32 LegoUnknown100db7f4::FUN_10048c40(const Vector3& p_position)
{
LegoFloat localc, local10;
LegoU32 result = FALSE;
if (m_unk0x28[0] > 0.001 || m_unk0x28[0] < -0.001) {
localc = (p_position[0] - (*m_pointA)[0]) / m_unk0x28[0];
if (localc < 0 || localc > 1) {
return FALSE;
}
result = TRUE;
}
else {
if (p_position[0] > (*m_pointA)[0] + 0.001 || p_position[0] < (*m_pointA)[0] - 0.001) {
return FALSE;
}
}
if (m_unk0x28[1] > 0.001 || m_unk0x28[1] < -0.001) {
local10 = (p_position[1] - (*m_pointA)[1]) / m_unk0x28[1];
if (result) {
if (localc > local10 + 0.001 || localc < local10 - 0.001) {
return FALSE;
}
}
else {
result = TRUE;
localc = local10;
}
}
else {
if (p_position[1] > (*m_pointA)[1] + 0.001 || p_position[1] < (*m_pointA)[1] - 0.001) {
return FALSE;
}
}
if (m_unk0x28[2] > 0.001 || m_unk0x28[2] < -0.001) {
local10 = (p_position[2] - (*m_pointA)[2]) / m_unk0x28[2];
if (result) {
if (localc > local10 + 0.001 || localc < local10 - 0.001) {
return FALSE;
}
}
else {
return TRUE;
}
}
else {
if (p_position[2] > (*m_pointA)[2] + 0.001 || p_position[2] < (*m_pointA)[2] - 0.001) {
return FALSE;
}
}
return TRUE;
}
#endif // __LEGOUNKNOWN100DB7F4_H #endif // __LEGOUNKNOWN100DB7F4_H

View file

@ -33,6 +33,9 @@ class Mx3DPointFloat : public Vector3 {
// FUNCTION: LEGO1 0x10003c10 // FUNCTION: LEGO1 0x10003c10
virtual void operator=(const Vector3& p_impl) { EqualsImpl(p_impl.m_data); } // vtable+0x88 virtual void operator=(const Vector3& p_impl) { EqualsImpl(p_impl.m_data); } // vtable+0x88
// FUNCTION: BETA10 0x10015240
// ??4Mx3DPointFloat@@QAEAAV0@ABV0@@Z
// FUNCTION: BETA10 0x10013460 // FUNCTION: BETA10 0x10013460
float& operator[](int idx) { return m_data[idx]; } float& operator[](int idx) { return m_data[idx]; }

View file

@ -151,8 +151,25 @@ class Vector2 {
virtual void SetVector(float* p_other) { EqualsImpl(p_other); } // vtable+0x70 virtual void SetVector(float* p_other) { EqualsImpl(p_other); } // vtable+0x70
// FUNCTION: LEGO1 0x10002260 // FUNCTION: LEGO1 0x10002260
// FUNCTION: BETA10 0x100110c0
virtual void SetVector(const Vector2* p_other) { EqualsImpl(p_other->m_data); } // vtable+0x6c virtual void SetVector(const Vector2* p_other) { EqualsImpl(p_other->m_data); } // vtable+0x6c
// Note: it's unclear whether Vector3::operator= has been defined explicitly
// with the same function body as Vector2& operator=. The BETA indicates that;
// however, it makes LEGO1 0x10010be0 disappear and worsens matches in
// at least these functions:
// LEGO1 0x100109b0
// LEGO1 0x10023130
// LEGO1 0x1002de10
// LEGO1 0x10050a80
// LEGO1 0x10053980
// LEGO1 0x100648f0
// LEGO1 0x10064b50
// LEGO1 0x10084030
// LEGO1 0x100a9410
// However, defining it as in the BETA improves at least these functions:
// LEGO1 0x10042300
// SYNTHETIC: LEGO1 0x10010be0 // SYNTHETIC: LEGO1 0x10010be0
// SYNTHETIC: BETA10 0x100121e0 // SYNTHETIC: BETA10 0x100121e0
// Vector3::operator= // Vector3::operator=