Merge remote-tracking branch 'isle/master'

This commit is contained in:
Christian Semmler 2025-06-22 08:57:16 -07:00
commit 67a89f2d78
No known key found for this signature in database
GPG Key ID: 086DAA1360BEEE5C
15 changed files with 247 additions and 121 deletions

View File

@ -157,7 +157,18 @@ class LegoGameState {
MxS16 m_totalScore; // 0x00 MxS16 m_totalScore; // 0x00
MxU8 m_scores[5][5]; // 0x02 MxU8 m_scores[5][5]; // 0x02
Username m_name; // 0x1c Username m_name; // 0x1c
MxS16 m_unk0x2a; // 0x2a MxS16 m_playerId; // 0x2a
ScoreItem& operator=(const ScoreItem& p_other)
{
// MSVC auto-generates an operator=, but LegoGameState::WriteScoreHistory() has a much better match
// with a manual implementation.
m_totalScore = p_other.m_totalScore;
memcpy(m_scores, p_other.m_scores, sizeof(m_scores));
m_name = p_other.m_name;
m_playerId = p_other.m_playerId;
return *this;
}
}; };
// SIZE 0x372 // SIZE 0x372
@ -165,7 +176,7 @@ class LegoGameState {
History(); History();
void WriteScoreHistory(); void WriteScoreHistory();
MxResult Serialize(LegoStorage* p_storage); MxResult Serialize(LegoStorage* p_storage);
ScoreItem* FUN_1003cc90(Username* p_player, MxS16 p_unk0x24, MxS32& p_unk0x2c); ScoreItem* FindPlayerInScoreHistory(Username* p_player, MxS16 p_unk0x24, MxS32& p_unk0x2c);
// FUNCTION: BETA10 0x1002c2b0 // FUNCTION: BETA10 0x1002c2b0
MxS16 GetCount() { return m_count; } MxS16 GetCount() { return m_count; }
@ -174,9 +185,12 @@ class LegoGameState {
// FUNCTION: BETA10 0x1002c540 // FUNCTION: BETA10 0x1002c540
ScoreItem* GetScore(MxS32 p_index) { return p_index >= m_count ? NULL : &m_scores[p_index]; } ScoreItem* GetScore(MxS32 p_index) { return p_index >= m_count ? NULL : &m_scores[p_index]; }
MxS16 m_count; // 0x00 MxS16 m_count; // 0x00
ScoreItem m_scores[20]; // 0x02 #ifdef BETA10
MxS16 m_unk0x372; // 0x372 MxS16 m_indices[20]; // 0x02
#endif
ScoreItem m_scores[20]; // 0x02 (0x22 for BETA10)
MxS16 m_nextPlayerId; // 0x372 (0x392 for BETA10)
}; };
LEGO1_EXPORT LegoGameState(); LEGO1_EXPORT LegoGameState();
@ -252,7 +266,7 @@ class LegoGameState {
// TODO: Most likely getters/setters are not used according to BETA for the following members: // TODO: Most likely getters/setters are not used according to BETA for the following members:
public: public:
MxS16 m_unk0x24; // 0x24 MxS16 m_currentPlayerId; // 0x24
MxS16 m_playerCount; // 0x26 MxS16 m_playerCount; // 0x26
Username m_players[9]; // 0x28 Username m_players[9]; // 0x28
History m_history; // 0xa6 History m_history; // 0xa6

View File

@ -579,10 +579,10 @@ void LegoCarBuildAnimPresenter::RotateAroundYAxis(MxFloat p_angle)
newRotation.EqualsHamiltonProduct(currentRotation, additionalRotation); newRotation.EqualsHamiltonProduct(currentRotation, additionalRotation);
if (newRotation[3] < 0.9999) { if (newRotation[3] < 0.9999) {
rotationKey->FUN_100739a0(TRUE); rotationKey->SetActive(TRUE);
} }
else { else {
rotationKey->FUN_100739a0(FALSE); rotationKey->SetActive(FALSE);
} }
m_platformAnimNodeData->GetRotationKey(0)->SetX(newRotation[0]); m_platformAnimNodeData->GetRotationKey(0)->SetX(newRotation[0]);

View File

@ -290,7 +290,7 @@ MxResult LegoGameState::Save(MxULong p_slot)
} }
storage.WriteS32(0x1000c); storage.WriteS32(0x1000c);
storage.WriteS16(m_unk0x24); storage.WriteS16(m_currentPlayerId);
storage.WriteU16(m_currentAct); storage.WriteU16(m_currentAct);
storage.WriteU8(m_actorId); storage.WriteU8(m_actorId);
@ -386,7 +386,7 @@ MxResult LegoGameState::Load(MxULong p_slot)
goto done; goto done;
} }
storage.ReadS16(m_unk0x24); storage.ReadS16(m_currentPlayerId);
storage.ReadS16(actArea); storage.ReadS16(actArea);
SetCurrentAct((Act) actArea); SetCurrentAct((Act) actArea);
@ -630,8 +630,8 @@ MxResult LegoGameState::AddPlayer(Username& p_player)
m_playerCount++; m_playerCount++;
m_players[0].Set(p_player); m_players[0].Set(p_player);
m_unk0x24 = m_history.m_unk0x372; m_currentPlayerId = m_history.m_nextPlayerId;
m_history.m_unk0x372 = m_unk0x24 + 1; m_history.m_nextPlayerId = m_currentPlayerId + 1;
m_history.WriteScoreHistory(); m_history.WriteScoreHistory();
SetCurrentAct(e_act1); SetCurrentAct(e_act1);
@ -1422,7 +1422,7 @@ MxResult LegoGameState::ScoreItem::Serialize(LegoStorage* p_storage)
} }
m_name.Serialize(p_storage); m_name.Serialize(p_storage);
p_storage->ReadS16(m_unk0x2a); p_storage->ReadS16(m_playerId);
} }
else if (p_storage->IsWriteMode()) { else if (p_storage->IsWriteMode()) {
p_storage->WriteS16(m_totalScore); p_storage->WriteS16(m_totalScore);
@ -1434,7 +1434,7 @@ MxResult LegoGameState::ScoreItem::Serialize(LegoStorage* p_storage)
} }
m_name.Serialize(p_storage); m_name.Serialize(p_storage);
p_storage->WriteS16(m_unk0x2a); p_storage->WriteS16(m_playerId);
} }
return SUCCESS; return SUCCESS;
@ -1445,7 +1445,7 @@ MxResult LegoGameState::ScoreItem::Serialize(LegoStorage* p_storage)
LegoGameState::History::History() LegoGameState::History::History()
{ {
m_count = 0; m_count = 0;
m_unk0x372 = 0; m_nextPlayerId = 0;
} }
// FUNCTION: LEGO1 0x1003c870 // FUNCTION: LEGO1 0x1003c870
@ -1456,83 +1456,130 @@ void LegoGameState::History::WriteScoreHistory()
MxU8 scores[5][5]; MxU8 scores[5][5];
InfocenterState* state = (InfocenterState*) GameState()->GetState("InfocenterState"); InfocenterState* state = (InfocenterState*) GameState()->GetState("InfocenterState");
if (state->m_letters[0]) {
JetskiRaceState* jetskiRaceState = (JetskiRaceState*) GameState()->GetState("JetskiRaceState");
CarRaceState* carRaceState = (CarRaceState*) GameState()->GetState("CarRaceState");
TowTrackMissionState* towTrackMissionState =
(TowTrackMissionState*) GameState()->GetState("TowTrackMissionState");
PizzaMissionState* pizzaMissionState = (PizzaMissionState*) GameState()->GetState("PizzaMissionState");
AmbulanceMissionState* ambulanceMissionState =
(AmbulanceMissionState*) GameState()->GetState("AmbulanceMissionState");
for (MxS32 actor = 1; actor <= 5; actor++) { if (!state->m_letters[0]) {
scores[0][actor - 1] = carRaceState ? carRaceState->GetState(actor)->GetHighScore() : 0; return;
totalScore += scores[0][actor - 1]; }
scores[1][actor - 1] = jetskiRaceState ? jetskiRaceState->GetState(actor)->GetHighScore() : 0; JetskiRaceState* jetskiRaceState = (JetskiRaceState*) GameState()->GetState("JetskiRaceState");
totalScore += scores[1][actor - 1]; CarRaceState* carRaceState = (CarRaceState*) GameState()->GetState("CarRaceState");
TowTrackMissionState* towTrackMissionState = (TowTrackMissionState*) GameState()->GetState("TowTrackMissionState");
PizzaMissionState* pizzaMissionState = (PizzaMissionState*) GameState()->GetState("PizzaMissionState");
AmbulanceMissionState* ambulanceMissionState =
(AmbulanceMissionState*) GameState()->GetState("AmbulanceMissionState");
scores[2][actor - 1] = pizzaMissionState ? pizzaMissionState->GetHighScore(actor) : 0; for (MxS32 actor = 1; actor <= 5; actor++) {
totalScore += scores[2][actor - 1]; scores[0][actor - 1] = carRaceState ? carRaceState->GetState(actor)->GetHighScore() : 0;
totalScore += scores[0][actor - 1];
scores[3][actor - 1] = towTrackMissionState ? towTrackMissionState->GetHighScore(actor) : 0; #ifdef BETA10
totalScore += scores[3][actor - 1]; // likely a bug in BETA10
scores[1][actor - 1] = carRaceState ? carRaceState->GetState(actor)->GetHighScore() : 0;
#else
scores[1][actor - 1] = jetskiRaceState ? jetskiRaceState->GetState(actor)->GetHighScore() : 0;
#endif
totalScore += scores[1][actor - 1];
scores[4][actor - 1] = ambulanceMissionState ? ambulanceMissionState->GetHighScore(actor) : 0; scores[2][actor - 1] = pizzaMissionState ? pizzaMissionState->GetHighScore(actor) : 0;
totalScore += scores[4][actor - 1]; totalScore += scores[2][actor - 1];
}
MxS32 unk0x2c; scores[3][actor - 1] = towTrackMissionState ? towTrackMissionState->GetHighScore(actor) : 0;
ScoreItem* p_scorehist = FUN_1003cc90(&GameState()->m_players[0], GameState()->m_unk0x24, unk0x2c); totalScore += scores[3][actor - 1];
if (p_scorehist != NULL) { scores[4][actor - 1] = ambulanceMissionState ? ambulanceMissionState->GetHighScore(actor) : 0;
p_scorehist->m_totalScore = totalScore; totalScore += scores[4][actor - 1];
memcpy(p_scorehist->m_scores, scores, sizeof(p_scorehist->m_scores)); }
}
else { MxS32 playerScoreHistoryIndex;
if (m_count < (MxS16) sizeOfArray(m_scores)) { ScoreItem* p_scorehist =
m_scores[m_count].m_totalScore = totalScore; FindPlayerInScoreHistory(GameState()->m_players, GameState()->m_currentPlayerId, playerScoreHistoryIndex);
memcpy(m_scores[m_count].m_scores, scores, sizeof(m_scores[m_count].m_scores));
m_scores[m_count].m_name = GameState()->m_players[0]; #ifdef BETA10
m_scores[m_count].m_unk0x2a = GameState()->m_unk0x24; if (!p_scorehist) {
m_count++; MxS32 playerScoreRank;
} // LINE: BETA10 0x100870ee
else if (m_scores[19].m_totalScore <= totalScore) { for (playerScoreRank = 0; playerScoreRank < m_count; playerScoreRank++) {
m_scores[19].m_totalScore = totalScore; if (totalScore > m_scores[m_indices[playerScoreRank]].m_totalScore) {
memcpy(m_scores[19].m_scores, scores, sizeof(m_scores[19].m_scores)); break;
m_scores[19].m_name = GameState()->m_players[0];
m_scores[19].m_unk0x2a = GameState()->m_unk0x24;
} }
} }
// LINE: BETA10 0x1008713f
if (playerScoreRank < m_count) {
if (m_count < 20) {
playerScoreHistoryIndex = m_count++;
}
else {
playerScoreHistoryIndex = m_indices[19];
}
MxU8 tmpScores[5][5]; MxS32 max = m_count - 1;
Username tmpPlayer; for (MxS32 j = max; playerScoreRank < j; j--) {
MxS16 tmpUnk0x2a; m_indices[j - 1] = m_indices[j - 2];
}
// TODO: Match bubble sort loops m_indices[playerScoreRank] = playerScoreHistoryIndex;
for (MxS32 i = m_count - 1; i > 0; i--) { p_scorehist = &m_scores[playerScoreHistoryIndex];
for (MxS32 j = 1; j <= i; j++) { }
if (m_scores[j - 1].m_totalScore < m_scores[j].m_totalScore) { else if (playerScoreRank < 20) {
memcpy(tmpScores, m_scores[j - 1].m_scores, sizeof(tmpScores)); m_indices[m_count] = m_count;
tmpPlayer = m_scores[j - 1].m_name; p_scorehist = &m_scores[m_count++];
tmpUnk0x2a = m_scores[j - 1].m_unk0x2a; }
}
else if (p_scorehist->m_totalScore != totalScore) {
assert(totalScore > p_scorehist->m_totalScore);
memcpy(m_scores[j - 1].m_scores, m_scores[j].m_scores, sizeof(m_scores[j - 1].m_scores)); for (MxS32 i = playerScoreHistoryIndex; i > 0 && m_indices[i - 1] < m_indices[i]; i--) {
m_scores[j - 1].m_name = m_scores[j].m_name; MxU8 tmp = m_indices[i - 1];
m_scores[j - 1].m_unk0x2a = m_scores[j].m_unk0x2a; m_indices[i - 1] = m_indices[i];
m_indices[i] = tmp;
}
}
if (p_scorehist) {
p_scorehist->m_totalScore = totalScore;
memcpy(p_scorehist->m_scores[0], scores[0], sizeof(scores));
p_scorehist->m_name = GameState()->m_players[0];
p_scorehist->m_playerId = GameState()->m_currentPlayerId;
}
#else
if (p_scorehist != NULL) {
p_scorehist->m_totalScore = totalScore;
memcpy(p_scorehist->m_scores, scores, sizeof(p_scorehist->m_scores));
}
else {
if (m_count < (MxS16) sizeOfArray(m_scores)) {
assert(totalScore > p_scorehist->m_totalScore);
memcpy(m_scores[j].m_scores, tmpScores, sizeof(m_scores[j].m_scores)); m_scores[m_count].m_totalScore = totalScore;
m_scores[j].m_name = tmpPlayer; memcpy(m_scores[m_count].m_scores, scores, sizeof(m_scores[m_count].m_scores));
m_scores[j].m_unk0x2a = tmpUnk0x2a; m_scores[m_count].m_name = GameState()->m_players[0];
} m_scores[m_count].m_playerId = GameState()->m_currentPlayerId;
m_count++;
}
else if (m_scores[19].m_totalScore <= totalScore) {
m_scores[19].m_totalScore = totalScore;
memcpy(m_scores[19].m_scores, scores, sizeof(m_scores[19].m_scores));
m_scores[19].m_name = GameState()->m_players[0];
m_scores[19].m_playerId = GameState()->m_currentPlayerId;
}
}
ScoreItem tmpItem;
for (MxS32 i = m_count - 1; i >= 0; i--) {
for (MxS32 j = 1; j <= i; j++) {
if (m_scores[j].m_totalScore > m_scores[j - 1].m_totalScore) {
tmpItem = m_scores[j - 1];
m_scores[j - 1] = m_scores[j];
m_scores[j] = tmpItem;
} }
} }
} }
#endif
} }
// FUNCTION: LEGO1 0x1003cc90 // FUNCTION: LEGO1 0x1003cc90
// FUNCTION: BETA10 0x1008732a // FUNCTION: BETA10 0x1008732a
LegoGameState::ScoreItem* LegoGameState::History::FUN_1003cc90( LegoGameState::ScoreItem* LegoGameState::History::FindPlayerInScoreHistory(
LegoGameState::Username* p_player, LegoGameState::Username* p_player,
MxS16 p_unk0x24, MxS16 p_unk0x24,
MxS32& p_unk0x2c MxS32& p_unk0x2c
@ -1540,7 +1587,7 @@ LegoGameState::ScoreItem* LegoGameState::History::FUN_1003cc90(
{ {
MxS32 i = 0; MxS32 i = 0;
for (; i < m_count; i++) { for (; i < m_count; i++) {
if (!memcmp(p_player, &m_scores[i].m_name, sizeof(*p_player)) && m_scores[i].m_unk0x2a == p_unk0x24) { if (!memcmp(p_player, &m_scores[i].m_name, sizeof(*p_player)) && m_scores[i].m_playerId == p_unk0x24) {
break; break;
} }
} }
@ -1559,7 +1606,7 @@ LegoGameState::ScoreItem* LegoGameState::History::FUN_1003cc90(
MxResult LegoGameState::History::Serialize(LegoStorage* p_storage) MxResult LegoGameState::History::Serialize(LegoStorage* p_storage)
{ {
if (p_storage->IsReadMode()) { if (p_storage->IsReadMode()) {
p_storage->ReadS16(m_unk0x372); p_storage->ReadS16(m_nextPlayerId);
p_storage->ReadS16(m_count); p_storage->ReadS16(m_count);
for (MxS16 i = 0; i < m_count; i++) { for (MxS16 i = 0; i < m_count; i++) {
@ -1569,7 +1616,7 @@ MxResult LegoGameState::History::Serialize(LegoStorage* p_storage)
} }
} }
else if (p_storage->IsWriteMode()) { else if (p_storage->IsWriteMode()) {
p_storage->WriteS16(m_unk0x372); p_storage->WriteS16(m_nextPlayerId);
p_storage->WriteS16(m_count); p_storage->WriteS16(m_count);
for (MxS16 i = 0; i < m_count; i++) { for (MxS16 i = 0; i < m_count; i++) {

View File

@ -1,6 +1,7 @@
#include "legovariables.h" #include "legovariables.h"
#include "3dmanager/lego3dmanager.h" #include "3dmanager/lego3dmanager.h"
#include "legoactor.h"
#include "legogamestate.h" #include "legogamestate.h"
#include "legonavcontroller.h" #include "legonavcontroller.h"
#include "legovideomanager.h" #include "legovideomanager.h"
@ -159,18 +160,18 @@ void WhoAmIVariable::SetValue(const char* p_value)
MxVariable::SetValue(p_value); MxVariable::SetValue(p_value);
if (!SDL_strcasecmp(p_value, g_papa)) { if (!SDL_strcasecmp(p_value, g_papa)) {
GameState()->SetActorId(3); GameState()->SetActorId(LegoActor::c_papa);
} }
else if (!SDL_strcasecmp(p_value, g_mama)) { else if (!SDL_strcasecmp(p_value, g_mama)) {
GameState()->SetActorId(2); GameState()->SetActorId(LegoActor::c_mama);
} }
else if (!SDL_strcasecmp(p_value, g_pepper)) { else if (!SDL_strcasecmp(p_value, g_pepper)) {
GameState()->SetActorId(1); GameState()->SetActorId(LegoActor::c_pepper);
} }
else if (!SDL_strcasecmp(p_value, g_nick)) { else if (!SDL_strcasecmp(p_value, g_nick)) {
GameState()->SetActorId(4); GameState()->SetActorId(LegoActor::c_nick);
} }
else if (!SDL_strcasecmp(p_value, g_laura)) { else if (!SDL_strcasecmp(p_value, g_laura)) {
GameState()->SetActorId(5); GameState()->SetActorId(LegoActor::c_laura);
} }
} }

View File

@ -224,10 +224,10 @@ void LegoAnimPresenter::FUN_100692b0()
for (LegoU32 i = 0; i < numActors; i++) { for (LegoU32 i = 0; i < numActors; i++) {
LegoChar* str = GetVariableOrIdentity(m_anim->GetActorName(i), NULL); LegoChar* str = GetVariableOrIdentity(m_anim->GetActorName(i), NULL);
undefined4 unk0x04 = m_anim->GetActorUnknown0x04(i); LegoU32 actorType = m_anim->GetActorType(i);
LegoROI* roi = NULL; LegoROI* roi = NULL;
if (unk0x04 == 2) { if (actorType == LegoAnimActorEntry::e_actorType2) {
LegoChar* src; LegoChar* src;
if (str[0] == '*') { if (str[0] == '*') {
src = str + 1; src = str + 1;
@ -242,7 +242,7 @@ void LegoAnimPresenter::FUN_100692b0()
roi->SetVisibility(FALSE); roi->SetVisibility(FALSE);
} }
} }
else if (unk0x04 == 4) { else if (actorType == LegoAnimActorEntry::e_actorType4) {
LegoChar* baseName = new LegoChar[strlen(str)]; LegoChar* baseName = new LegoChar[strlen(str)];
strcpy(baseName, str + 1); strcpy(baseName, str + 1);
SDL_strlwr(baseName); SDL_strlwr(baseName);
@ -257,7 +257,7 @@ void LegoAnimPresenter::FUN_100692b0()
delete[] baseName; delete[] baseName;
delete[] und; delete[] und;
} }
else if (unk0x04 == 3) { else if (actorType == LegoAnimActorEntry::e_actorType3) {
LegoChar* lodName = new LegoChar[strlen(str)]; LegoChar* lodName = new LegoChar[strlen(str)];
strcpy(lodName, str + 1); strcpy(lodName, str + 1);
@ -303,9 +303,9 @@ void LegoAnimPresenter::FUN_100695c0()
for (LegoU32 i = 0; i < numActors; i++) { for (LegoU32 i = 0; i < numActors; i++) {
if (FUN_100698b0(rois, m_anim->GetActorName(i)) == FALSE) { if (FUN_100698b0(rois, m_anim->GetActorName(i)) == FALSE) {
undefined4 unk0x04 = m_anim->GetActorUnknown0x04(i); LegoU32 actorType = m_anim->GetActorType(i);
if (unk0x04 == 5 || unk0x04 == 6) { if (actorType == LegoAnimActorEntry::e_actorType5 || actorType == LegoAnimActorEntry::e_actorType6) {
LegoChar lodName[256]; LegoChar lodName[256];
const LegoChar* actorName = m_anim->GetActorName(i); const LegoChar* actorName = m_anim->GetActorName(i);

View File

@ -725,6 +725,7 @@ void LegoAnimNodeData::SetName(LegoChar* p_name)
} }
// FUNCTION: LEGO1 0x100a03c0 // FUNCTION: LEGO1 0x100a03c0
// FUNCTION: BETA10 0x1017f254
LegoResult LegoAnimNodeData::CreateLocalTransform(LegoFloat p_time, Matrix4& p_matrix) LegoResult LegoAnimNodeData::CreateLocalTransform(LegoFloat p_time, Matrix4& p_matrix)
{ {
LegoU32 index; LegoU32 index;
@ -1062,7 +1063,7 @@ LegoResult LegoAnim::Read(LegoStorage* p_storage, LegoS32 p_parseScene)
m_modelList[i].m_name[length] = '\0'; m_modelList[i].m_name[length] = '\0';
if (p_storage->Read(&m_modelList[i].m_unk0x04, sizeof(undefined4)) != SUCCESS) { if (p_storage->Read(&m_modelList[i].m_type, sizeof(LegoU32)) != SUCCESS) {
goto done; goto done;
} }
} }
@ -1123,7 +1124,7 @@ LegoResult LegoAnim::Write(LegoStorage* p_storage)
goto done; goto done;
} }
if (p_storage->Write(&m_modelList[i].m_unk0x04, sizeof(m_modelList[i].m_unk0x04)) != SUCCESS) { if (p_storage->Write(&m_modelList[i].m_type, sizeof(m_modelList[i].m_type)) != SUCCESS) {
goto done; goto done;
} }
} }
@ -1158,10 +1159,10 @@ const LegoChar* LegoAnim::GetActorName(LegoU32 p_index)
// FUNCTION: LEGO1 0x100a0f40 // FUNCTION: LEGO1 0x100a0f40
// FUNCTION: BETA10 0x1018023c // FUNCTION: BETA10 0x1018023c
undefined4 LegoAnim::GetActorUnknown0x04(LegoU32 p_index) LegoU32 LegoAnim::GetActorType(LegoU32 p_index)
{ {
if (p_index < m_numActors) { if (p_index < m_numActors) {
return m_modelList[p_index].m_unk0x04; return m_modelList[p_index].m_type;
} }
return 0; return 0;

View File

@ -30,9 +30,9 @@ class LegoAnimKey {
LegoU32 ShouldSkipInterpolation() { return m_flags & c_skipInterpolation; } LegoU32 ShouldSkipInterpolation() { return m_flags & c_skipInterpolation; }
// FUNCTION: BETA10 0x100739a0 // FUNCTION: BETA10 0x100739a0
void FUN_100739a0(MxS32 p_param) void SetActive(MxS32 p_active)
{ {
if (p_param) { if (p_active) {
m_flags |= c_active; m_flags |= c_active;
} }
else { else {
@ -289,8 +289,16 @@ class LegoAnimNodeData : public LegoTreeNodeData {
// SIZE 0x08 // SIZE 0x08
struct LegoAnimActorEntry { struct LegoAnimActorEntry {
LegoChar* m_name; // 0x00 enum {
undefined4 m_unk0x04; // 0x04 e_actorType2 = 2,
e_actorType3 = 3,
e_actorType4 = 4,
e_actorType5 = 5,
e_actorType6 = 6,
};
LegoChar* m_name; // 0x00
LegoU32 m_type; // 0x04
}; };
// TODO: Possibly called `LegoCameraAnim(ation)`? // TODO: Possibly called `LegoCameraAnim(ation)`?
@ -338,7 +346,7 @@ class LegoAnim : public LegoTree {
virtual LegoResult Read(LegoStorage* p_storage, LegoS32 p_parseScene); // vtable+0x10 virtual LegoResult Read(LegoStorage* p_storage, LegoS32 p_parseScene); // vtable+0x10
const LegoChar* GetActorName(LegoU32 p_index); const LegoChar* GetActorName(LegoU32 p_index);
undefined4 GetActorUnknown0x04(LegoU32 p_index); LegoU32 GetActorType(LegoU32 p_index);
// FUNCTION: BETA10 0x1005abf0 // FUNCTION: BETA10 0x1005abf0
LegoAnimScene* GetCamAnim() { return m_camAnim; } LegoAnimScene* GetCamAnim() { return m_camAnim; }

View File

@ -59,8 +59,12 @@ ColorOverride g_colorOverride = NULL;
TextureHandler g_textureHandler = NULL; TextureHandler g_textureHandler = NULL;
// FUNCTION: LEGO1 0x100a81b0 // FUNCTION: LEGO1 0x100a81b0
void LegoROI::FUN_100a81b0(const LegoChar* p_error, const LegoChar* p_name) // FUNCTION: BETA10 0x101898c0
// FUNCTION: ALPHA 0x100bb1c0
void LegoROI::FUN_100a81b0(const LegoChar* p_error, ...)
{ {
// Probably a printf-like debug function that was removed early.
// No known implementation in any of the binaries.
} }
// FUNCTION: LEGO1 0x100a81c0 // FUNCTION: LEGO1 0x100a81c0
@ -70,6 +74,7 @@ void LegoROI::configureLegoROI(int p_roiConfig)
} }
// FUNCTION: LEGO1 0x100a81d0 // FUNCTION: LEGO1 0x100a81d0
// FUNCTION: BETA10 0x101898e8
LegoROI::LegoROI(Tgl::Renderer* p_renderer) : ViewROI(p_renderer, NULL) LegoROI::LegoROI(Tgl::Renderer* p_renderer) : ViewROI(p_renderer, NULL)
{ {
m_parentROI = NULL; m_parentROI = NULL;
@ -78,6 +83,7 @@ LegoROI::LegoROI(Tgl::Renderer* p_renderer) : ViewROI(p_renderer, NULL)
} }
// FUNCTION: LEGO1 0x100a82d0 // FUNCTION: LEGO1 0x100a82d0
// FUNCTION: BETA10 0x10189994
LegoROI::LegoROI(Tgl::Renderer* p_renderer, ViewLODList* p_lodList) : ViewROI(p_renderer, p_lodList) LegoROI::LegoROI(Tgl::Renderer* p_renderer, ViewLODList* p_lodList) : ViewROI(p_renderer, p_lodList)
{ {
m_parentROI = NULL; m_parentROI = NULL;
@ -86,6 +92,7 @@ LegoROI::LegoROI(Tgl::Renderer* p_renderer, ViewLODList* p_lodList) : ViewROI(p_
} }
// FUNCTION: LEGO1 0x100a83c0 // FUNCTION: LEGO1 0x100a83c0
// FUNCTION: BETA10 0x10189a42
LegoROI::~LegoROI() LegoROI::~LegoROI()
{ {
if (comp) { if (comp) {
@ -106,6 +113,7 @@ LegoROI::~LegoROI()
} }
// FUNCTION: LEGO1 0x100a84a0 // FUNCTION: LEGO1 0x100a84a0
// FUNCTION: BETA10 0x10189b99
LegoResult LegoROI::Read( LegoResult LegoROI::Read(
OrientableROI* p_unk0xd4, OrientableROI* p_unk0xd4,
Tgl::Renderer* p_renderer, Tgl::Renderer* p_renderer,
@ -338,6 +346,7 @@ LegoResult LegoROI::Read(
} }
// FUNCTION: LEGO1 0x100a8cb0 // FUNCTION: LEGO1 0x100a8cb0
// FUNCTION: BETA10 0x1018a7e8
LegoResult LegoROI::CreateLocalTransform(LegoAnimNodeData* p_data, LegoTime p_time, Matrix4& p_matrix) LegoResult LegoROI::CreateLocalTransform(LegoAnimNodeData* p_data, LegoTime p_time, Matrix4& p_matrix)
{ {
p_matrix.SetIdentity(); p_matrix.SetIdentity();
@ -380,6 +389,7 @@ LegoROI* LegoROI::FindChildROI(const LegoChar* p_name, LegoROI* p_roi)
} }
// FUNCTION: LEGO1 0x100a8da0 // FUNCTION: LEGO1 0x100a8da0
// FUNCTION: BETA10 0x1018a9fb
LegoResult LegoROI::ApplyAnimationTransformation( LegoResult LegoROI::ApplyAnimationTransformation(
LegoTreeNode* p_node, LegoTreeNode* p_node,
const Matrix4& p_matrix, const Matrix4& p_matrix,
@ -474,6 +484,7 @@ void LegoROI::FUN_100a8fd0(LegoTreeNode* p_node, Matrix4& p_matrix, LegoTime p_t
} }
// FUNCTION: LEGO1 0x100a90f0 // FUNCTION: LEGO1 0x100a90f0
// FUNCTION: BETA10 0x1018ada8
LegoResult LegoROI::SetFrame(LegoAnim* p_anim, LegoTime p_time) LegoResult LegoROI::SetFrame(LegoAnim* p_anim, LegoTime p_time)
{ {
LegoTreeNode* root = p_anim->GetRoot(); LegoTreeNode* root = p_anim->GetRoot();
@ -513,6 +524,7 @@ LegoResult LegoROI::SetLodColor(LegoFloat p_red, LegoFloat p_green, LegoFloat p_
} }
// FUNCTION: LEGO1 0x100a9210 // FUNCTION: LEGO1 0x100a9210
// FUNCTION: BETA10 0x1018af25
LegoResult LegoROI::SetTextureInfo(LegoTextureInfo* p_textureInfo) LegoResult LegoROI::SetTextureInfo(LegoTextureInfo* p_textureInfo)
{ {
LegoResult result = SUCCESS; LegoResult result = SUCCESS;
@ -736,6 +748,7 @@ LegoU32 LegoROI::FUN_100a9410(
} }
// FUNCTION: LEGO1 0x100a9a50 // FUNCTION: LEGO1 0x100a9a50
// FUNCTION: BETA10 0x1018bb6b
TimeROI::TimeROI(Tgl::Renderer* p_renderer, ViewLODList* p_lodList, LegoTime p_time) : LegoROI(p_renderer, p_lodList) TimeROI::TimeROI(Tgl::Renderer* p_renderer, ViewLODList* p_lodList, LegoTime p_time) : LegoROI(p_renderer, p_lodList)
{ {
m_time = p_time; m_time = p_time;
@ -761,6 +774,7 @@ void TimeROI::FUN_100a9b40(Matrix4& p_matrix, LegoTime p_time)
} }
// FUNCTION: LEGO1 0x100a9bf0 // FUNCTION: LEGO1 0x100a9bf0
// FUNCTION: BETA10 0x1018bc93
LegoBool LegoROI::GetRGBAColor(const LegoChar* p_name, float& p_red, float& p_green, float& p_blue, float& p_alpha) LegoBool LegoROI::GetRGBAColor(const LegoChar* p_name, float& p_red, float& p_green, float& p_blue, float& p_alpha)
{ {
if (p_name == NULL) { if (p_name == NULL) {
@ -851,12 +865,14 @@ void LegoROI::SetDisplayBB(int p_displayBB)
} }
// FUNCTION: LEGO1 0x100aa340 // FUNCTION: LEGO1 0x100aa340
// FUNCTION: BETA10 0x1018cca0
float LegoROI::IntrinsicImportance() const float LegoROI::IntrinsicImportance() const
{ {
return .5; return .5;
} }
// FUNCTION: LEGO1 0x100aa350 // FUNCTION: LEGO1 0x100aa350
// FUNCTION: BETA10 0x1018ccc0
void LegoROI::UpdateWorldBoundingVolumes() void LegoROI::UpdateWorldBoundingVolumes()
{ {
CalcWorldBoundingVolumes(m_sphere, m_local2world, m_world_bounding_box, m_world_bounding_sphere); CalcWorldBoundingVolumes(m_sphere, m_local2world, m_world_bounding_box, m_world_bounding_sphere);

View File

@ -18,6 +18,7 @@ class LegoTreeNode;
struct LegoAnimActorEntry; struct LegoAnimActorEntry;
// VTABLE: LEGO1 0x100dbe38 // VTABLE: LEGO1 0x100dbe38
// VTABLE: BETA10 0x101c3898
// SIZE 0x108 // SIZE 0x108
class LegoROI : public ViewROI { class LegoROI : public ViewROI {
public: public:
@ -58,7 +59,7 @@ class LegoROI : public ViewROI {
void SetDisplayBB(int p_displayBB); void SetDisplayBB(int p_displayBB);
static LegoResult CreateLocalTransform(LegoAnimNodeData* p_data, LegoTime p_time, Matrix4& p_matrix); static LegoResult CreateLocalTransform(LegoAnimNodeData* p_data, LegoTime p_time, Matrix4& p_matrix);
static void FUN_100a81b0(const LegoChar* p_error, const LegoChar* p_name); static void FUN_100a81b0(const LegoChar* p_error, ...);
LEGO1_EXPORT static void configureLegoROI(int p_roi); LEGO1_EXPORT static void configureLegoROI(int p_roi);
static void SetColorOverride(ColorOverride p_colorOverride); static void SetColorOverride(ColorOverride p_colorOverride);
static LegoBool GetRGBAColor(const LegoChar* p_name, float& p_red, float& p_green, float& p_blue, float& p_alpha); static LegoBool GetRGBAColor(const LegoChar* p_name, float& p_red, float& p_green, float& p_blue, float& p_alpha);
@ -87,6 +88,7 @@ class LegoROI : public ViewROI {
void SetBoundingBox(const BoundingBox& p_box) { m_bounding_box = p_box; } void SetBoundingBox(const BoundingBox& p_box) { m_bounding_box = p_box; }
// SYNTHETIC: LEGO1 0x100a82b0 // SYNTHETIC: LEGO1 0x100a82b0
// SYNTHETIC: BETA10 0x1018c490
// LegoROI::`scalar deleting destructor' // LegoROI::`scalar deleting destructor'
private: private:
@ -99,15 +101,20 @@ class LegoROI : public ViewROI {
}; };
// VTABLE: LEGO1 0x100dbea8 // VTABLE: LEGO1 0x100dbea8
// VTABLE: BETA10 0x101c38d0
// SIZE 0x10c // SIZE 0x10c
class TimeROI : public LegoROI { class TimeROI : public LegoROI {
public: public:
TimeROI(Tgl::Renderer* p_renderer, ViewLODList* p_lodList, LegoTime p_time); TimeROI(Tgl::Renderer* p_renderer, ViewLODList* p_lodList, LegoTime p_time);
void FUN_100a9b40(Matrix4& p_matrix, LegoTime p_time);
// SYNTHETIC: LEGO1 0x100a9ad0 // SYNTHETIC: LEGO1 0x100a9ad0
// SYNTHETIC: BETA10 0x1018c540
// TimeROI::`scalar deleting destructor' // TimeROI::`scalar deleting destructor'
void FUN_100a9b40(Matrix4& p_matrix, LegoTime p_time); // SYNTHETIC: BETA10 0x1018c580
// TimeROI::~TimeROI
private: private:
LegoTime m_time; // 0x108 LegoTime m_time; // 0x108

View File

@ -289,7 +289,7 @@ void DecodeBrun(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData, BYTE* p_da
while (--line >= 0) { while (--line >= 0) {
short column = 0; short column = 0;
data++; data++;
char count = 0; signed char count = 0;
while ((column += count) < width2) { while ((column += count) < width2) {
count = *data++; count = *data++;
@ -332,7 +332,7 @@ void DecodeLC(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData, BYTE* p_data
while (packets > 0) { while (packets > 0) {
column += *data++; // skip byte column += *data++; // skip byte
char type = *((char*) data++); signed char type = *((signed char*) data++);
if (type < 0) { if (type < 0) {
type = -type; type = -type;
@ -418,7 +418,7 @@ void DecodeSS2(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData, BYTE* p_dat
// LINE: BETA10 0x1013e726 // LINE: BETA10 0x1013e726
column += *data.byte++; column += *data.byte++;
// LINE: BETA10 0x1013e73a // LINE: BETA10 0x1013e73a
short type = *(char*) data.byte++; short type = *(signed char*) data.byte++;
type += type; type += type;
if (type >= 0) { if (type >= 0) {

View File

@ -108,6 +108,7 @@ void OrientableROI::SetLocal2World(const Matrix4& p_local2world)
} }
// FUNCTION: LEGO1 0x100a5910 // FUNCTION: LEGO1 0x100a5910
// FUNCTION: BETA10 0x10167bac
void OrientableROI::UpdateWorldData() void OrientableROI::UpdateWorldData()
{ {
UpdateWorldBoundingVolumes(); UpdateWorldBoundingVolumes();
@ -115,6 +116,7 @@ void OrientableROI::UpdateWorldData()
} }
// FUNCTION: LEGO1 0x100a5930 // FUNCTION: LEGO1 0x100a5930
// FUNCTION: BETA10 0x10167bd8
void OrientableROI::SetLocal2WorldWithWorldDataUpdate(const Matrix4& p_transform) void OrientableROI::SetLocal2WorldWithWorldDataUpdate(const Matrix4& p_transform)
{ {
m_local2world = p_transform; m_local2world = p_transform;
@ -123,6 +125,7 @@ void OrientableROI::SetLocal2WorldWithWorldDataUpdate(const Matrix4& p_transform
} }
// FUNCTION: LEGO1 0x100a5960 // FUNCTION: LEGO1 0x100a5960
// FUNCTION: BETA10 0x10167c19
void OrientableROI::UpdateWorldDataWithTransform(const Matrix4& p_transform) void OrientableROI::UpdateWorldDataWithTransform(const Matrix4& p_transform)
{ {
MxMatrix l_matrix(m_local2world); MxMatrix l_matrix(m_local2world);
@ -132,6 +135,7 @@ void OrientableROI::UpdateWorldDataWithTransform(const Matrix4& p_transform)
} }
// FUNCTION: LEGO1 0x100a59b0 // FUNCTION: LEGO1 0x100a59b0
// FUNCTION: BETA10 0x10167c6d
void OrientableROI::UpdateWorldDataWithTransformAndChildren(const Matrix4& p_transform) void OrientableROI::UpdateWorldDataWithTransformAndChildren(const Matrix4& p_transform)
{ {
MxMatrix l_matrix(m_local2world); MxMatrix l_matrix(m_local2world);
@ -155,11 +159,13 @@ void OrientableROI::SetWorldVelocity(const Vector3& p_world_velocity)
} }
// FUNCTION: LEGO1 0x100a5a50 // FUNCTION: LEGO1 0x100a5a50
// FUNCTION: BETA10 0x10167d65
void OrientableROI::UpdateWorldVelocity() void OrientableROI::UpdateWorldVelocity()
{ {
} }
// FUNCTION: LEGO1 0x100a5a60 // FUNCTION: LEGO1 0x100a5a60
// FUNCTION: BETA10 0x10167d7b
void CalcWorldBoundingVolumes( void CalcWorldBoundingVolumes(
const BoundingSphere& modelling_sphere, const BoundingSphere& modelling_sphere,
const Matrix4& local2world, const Matrix4& local2world,
@ -186,18 +192,21 @@ void CalcWorldBoundingVolumes(
} }
// FUNCTION: LEGO1 0x100a5d80 // FUNCTION: LEGO1 0x100a5d80
// FUNCTION: BETA10 0x10168760
const float* OrientableROI::GetWorldVelocity() const const float* OrientableROI::GetWorldVelocity() const
{ {
return m_world_velocity.GetData(); return m_world_velocity.GetData();
} }
// FUNCTION: LEGO1 0x100a5d90 // FUNCTION: LEGO1 0x100a5d90
// FUNCTION: BETA10 0x10168790
const BoundingBox& OrientableROI::GetWorldBoundingBox() const const BoundingBox& OrientableROI::GetWorldBoundingBox() const
{ {
return m_world_bounding_box; return m_world_bounding_box;
} }
// FUNCTION: LEGO1 0x100a5da0 // FUNCTION: LEGO1 0x100a5da0
// FUNCTION: BETA10 0x101687b0
const BoundingSphere& OrientableROI::GetWorldBoundingSphere() const const BoundingSphere& OrientableROI::GetWorldBoundingSphere() const
{ {
return m_world_bounding_sphere; return m_world_bounding_sphere;

View File

@ -27,6 +27,7 @@ class OrientableROI : public ROI {
const BoundingSphere& GetWorldBoundingSphere() const override; // vtable+0x10 const BoundingSphere& GetWorldBoundingSphere() const override; // vtable+0x10
// FUNCTION: LEGO1 0x100a5db0 // FUNCTION: LEGO1 0x100a5db0
// FUNCTION: BETA10 0x101687d0
virtual void WrappedUpdateWorldData() { UpdateWorldData(); } // vtable+0x14 virtual void WrappedUpdateWorldData() { UpdateWorldData(); } // vtable+0x14
virtual void UpdateWorldBoundingVolumes() = 0; // vtable+0x18 virtual void UpdateWorldBoundingVolumes() = 0; // vtable+0x18
@ -85,6 +86,7 @@ class OrientableROI : public ROI {
// OrientableROI::`scalar deleting destructor' // OrientableROI::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100aa2f0 // SYNTHETIC: LEGO1 0x100aa2f0
// SYNTHETIC: BETA10 0x10168600
// OrientableROI::~OrientableROI // OrientableROI::~OrientableROI
#endif // ORIENTABLEROI_H #endif // ORIENTABLEROI_H

View File

@ -15,9 +15,16 @@
// SIZE 0x28 // SIZE 0x28
class BoundingBox { class BoundingBox {
public: public:
// The BETA10 matches may reference the wrong version
// FUNCTION: BETA10 0x1004a7a0
const Vector3& Min() const { return min; } const Vector3& Min() const { return min; }
Vector3& Min() { return min; } Vector3& Min() { return min; }
// FUNCTION: BETA10 0x1004a7c0
const Vector3& Max() const { return max; } const Vector3& Max() const { return max; }
Vector3& Max() { return max; } Vector3& Max() { return max; }
private: private:
@ -31,14 +38,26 @@ class BoundingBox {
// SIZE 0x18 // SIZE 0x18
class BoundingSphere { class BoundingSphere {
public: public:
// The BETA10 matches may reference the wrong version
// FUNCTION: BETA10 0x1001fac0
const Vector3& Center() const { return center; } const Vector3& Center() const { return center; }
// FUNCTION: BETA10 0x100d55a0
Vector3& Center() { return center; } Vector3& Center() { return center; }
// FUNCTION: BETA10 0x1001fd30
const float& Radius() const { return radius; } const float& Radius() const { return radius; }
// FUNCTION: BETA10 0x1001fae0
float& Radius() { return radius; } float& Radius() { return radius; }
// SYNTHETIC: BETA10 0x1001fb90 // SYNTHETIC: BETA10 0x1001fb90
// BoundingSphere::operator= // BoundingSphere::operator=
// SYNTHETIC: BETA10 0x1001fc50
// BoundingSphere::BoundingSphere
private: private:
Mx3DPointFloat center; // 0x00 Mx3DPointFloat center; // 0x00
float radius; // 0x14 float radius; // 0x14
@ -136,6 +155,7 @@ class ROI {
// list<ROI *,allocator<ROI *> >::~list<ROI *,allocator<ROI *> > // list<ROI *,allocator<ROI *> >::~list<ROI *,allocator<ROI *> >
// SYNTHETIC: LEGO1 0x100a5d50 // SYNTHETIC: LEGO1 0x100a5d50
// SYNTHETIC: BETA10 0x101686a0
// ROI::~ROI // ROI::~ROI
#endif // ROI_H #endif // ROI_H

View File

@ -16,65 +16,60 @@ float ViewROI::IntrinsicImportance() const
} // for now } // for now
// FUNCTION: LEGO1 0x100a9ec0 // FUNCTION: LEGO1 0x100a9ec0
// FUNCTION: BETA10 0x1018c740
Tgl::Group* ViewROI::GetGeometry() Tgl::Group* ViewROI::GetGeometry()
{ {
return geometry; return geometry;
} }
// FUNCTION: LEGO1 0x100a9ed0 // FUNCTION: LEGO1 0x100a9ed0
// FUNCTION: BETA10 0x1018c760
const Tgl::Group* ViewROI::GetGeometry() const const Tgl::Group* ViewROI::GetGeometry() const
{ {
return geometry; return geometry;
} }
// FUNCTION: LEGO1 0x100a9ee0 // FUNCTION: LEGO1 0x100a9ee0
// FUNCTION: BETA10 0x1018c780
void ViewROI::UpdateWorldDataWithTransformAndChildren(const Matrix4& parent2world) void ViewROI::UpdateWorldDataWithTransformAndChildren(const Matrix4& parent2world)
{ {
OrientableROI::UpdateWorldDataWithTransformAndChildren(parent2world); OrientableROI::UpdateWorldDataWithTransformAndChildren(parent2world);
SetGeometryTransformation();
}
// FUNCTION: BETA10 0x1018c7b0
inline void ViewROI::SetGeometryTransformation()
{
if (geometry) { if (geometry) {
Tgl::FloatMatrix4 matrix; Tgl::FloatMatrix4 matrix;
Matrix4 in(matrix); Matrix4 in(matrix);
SETMAT4(in, m_local2world); SETMAT4(in, m_local2world);
Tgl::Result result = geometry->SetTransformation(matrix); geometry->SetTransformation(matrix);
// assert(Tgl::Succeeded(result));
} }
} }
// FUNCTION: LEGO1 0x100a9fc0 // FUNCTION: LEGO1 0x100a9fc0
// FUNCTION: BETA10 0x1018cad0
void ViewROI::UpdateWorldDataWithTransform(const Matrix4& p_transform) void ViewROI::UpdateWorldDataWithTransform(const Matrix4& p_transform)
{ {
OrientableROI::UpdateWorldDataWithTransform(p_transform); OrientableROI::UpdateWorldDataWithTransform(p_transform);
if (geometry) { SetGeometryTransformation();
Tgl::FloatMatrix4 matrix;
Matrix4 in(matrix);
SETMAT4(in, m_local2world);
geometry->SetTransformation(matrix);
}
} }
// FUNCTION: LEGO1 0x100aa0a0 // FUNCTION: LEGO1 0x100aa0a0
// FUNCTION: BETA10 0x1018cb00
void ViewROI::SetLocal2WorldWithWorldDataUpdate(const Matrix4& p_transform) void ViewROI::SetLocal2WorldWithWorldDataUpdate(const Matrix4& p_transform)
{ {
OrientableROI::SetLocal2WorldWithWorldDataUpdate(p_transform); OrientableROI::SetLocal2WorldWithWorldDataUpdate(p_transform);
if (geometry) { SetGeometryTransformation();
Tgl::FloatMatrix4 matrix;
Matrix4 in(matrix);
SETMAT4(in, m_local2world);
geometry->SetTransformation(matrix);
}
} }
// FUNCTION: LEGO1 0x100aa180 // FUNCTION: LEGO1 0x100aa180
// FUNCTION: BETA10 0x1018cb30
void ViewROI::UpdateWorldData() void ViewROI::UpdateWorldData()
{ {
OrientableROI::UpdateWorldData(); OrientableROI::UpdateWorldData();
if (geometry) { SetGeometryTransformation();
Tgl::FloatMatrix4 matrix;
Matrix4 in(matrix);
SETMAT4(in, m_local2world);
geometry->SetTransformation(matrix);
}
} }
// FUNCTION: LEGO1 0x100aa500 // FUNCTION: LEGO1 0x100aa500

View File

@ -13,6 +13,7 @@
*/ */
// VTABLE: LEGO1 0x100dbe70 // VTABLE: LEGO1 0x100dbe70
// VTABLE: BETA10 0x101c3908
// SIZE 0xe4 // SIZE 0xe4
class ViewROI : public OrientableROI { class ViewROI : public OrientableROI {
public: public:
@ -21,6 +22,7 @@ class ViewROI : public OrientableROI {
c_lodLevelInvisible = -2, c_lodLevelInvisible = -2,
}; };
// FUNCTION: BETA10 0x1018c5e0
ViewROI(Tgl::Renderer* pRenderer, ViewLODList* lodList) ViewROI(Tgl::Renderer* pRenderer, ViewLODList* lodList)
{ {
SetLODList(lodList); SetLODList(lodList);
@ -29,6 +31,7 @@ class ViewROI : public OrientableROI {
} }
// FUNCTION: LEGO1 0x100a9e20 // FUNCTION: LEGO1 0x100a9e20
// FUNCTION: BETA10 0x1018c680
~ViewROI() override ~ViewROI() override
{ {
// SetLODList() will decrease refCount of LODList // SetLODList() will decrease refCount of LODList
@ -36,6 +39,7 @@ class ViewROI : public OrientableROI {
delete geometry; delete geometry;
} }
// FUNCTION: BETA10 0x1007b540
void SetLODList(ViewLODList* lodList) void SetLODList(ViewLODList* lodList)
{ {
// ??? inherently type unsafe - kind of... because, now, ROI // ??? inherently type unsafe - kind of... because, now, ROI
@ -69,6 +73,8 @@ class ViewROI : public OrientableROI {
protected: protected:
void UpdateWorldDataWithTransformAndChildren(const Matrix4& parent2world) override; // vtable+0x28 void UpdateWorldDataWithTransformAndChildren(const Matrix4& parent2world) override; // vtable+0x28
void SetGeometryTransformation();
Tgl::Group* geometry; // 0xdc Tgl::Group* geometry; // 0xdc
int m_lodLevel; // 0xe0 int m_lodLevel; // 0xe0
}; };