Reorganize sources and files (#414)

* Reorganize sources

* Refactor

* Remove relative paths

* Renames

* Fix gitignore

* Remove stuff

* Try fixing format script

* Fix format

* Fix format

* Fix naming script

* Test format

* Fix format
This commit is contained in:
Christian Semmler
2024-01-08 04:58:49 -05:00
committed by GitHub
parent 6a85e62406
commit c47206617d
447 changed files with 347 additions and 346 deletions

View File

@@ -0,0 +1,32 @@
#include "animstate.h"
DECOMP_SIZE_ASSERT(AnimState, 0x1c);
// FUNCTION: LEGO1 0x10064ff0
AnimState::AnimState()
{
m_unk0xc = 0;
m_unk0x10 = NULL;
m_unk0x14 = 0;
m_unk0x18 = NULL;
}
// STUB: LEGO1 0x10065150
AnimState::~AnimState()
{
// TODO
}
// STUB: LEGO1 0x100652d0
MxResult AnimState::VTable0x1c(LegoFileStream* p_legoFileStream)
{
// TODO
return FAILURE;
}
// STUB: LEGO1 0x100654f0
MxBool AnimState::SetFlag()
{
// TODO
return FALSE;
}

View File

@@ -0,0 +1,25 @@
#include "gifmanager.h"
DECOMP_SIZE_ASSERT(GifData, 0x14);
DECOMP_SIZE_ASSERT(GifMapEntry, 0x14);
DECOMP_SIZE_ASSERT(GifMap, 0x08);
DECOMP_SIZE_ASSERT(GifManagerBase, 0x14);
DECOMP_SIZE_ASSERT(GifManager, 0x30);
GifMapEntry* g_unk0x100f0100;
// FUNCTION: LEGO1 0x10001cc0
GifMapEntry* GifMap::FindNode(const char*& p_string)
{
GifMapEntry* ret = m_unk0x4;
GifMapEntry* current = ret->m_parent;
while (current != g_unk0x100f0100) {
if (strcmp(current->m_key, p_string) <= 0) {
ret = current;
current = current->m_right;
}
else
current = current->m_left;
}
return ret;
}

View File

@@ -0,0 +1,99 @@
#include "legoactioncontrolpresenter.h"
#include "define.h"
#include "extra.h"
#include "legoomni.h"
#include "legoutil.h"
#include "mxcompositepresenter.h"
#include "mxmediapresenter.h"
#include "mxomni.h"
#include "mxstreamchunk.h"
#include "mxticklemanager.h"
DECOMP_SIZE_ASSERT(LegoActionControlPresenter, 0x68)
// FUNCTION: LEGO1 0x10043ce0
void LegoActionControlPresenter::ReadyTickle()
{
MxStreamChunk* chunk = NextChunk();
if (chunk) {
ParseExtra();
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
m_currentTickleState = TickleState_Starting;
m_subscriber->FUN_100b8390(chunk);
if (m_compositePresenter) {
if (m_action->GetDuration() == -1 || m_action->GetFlags() & 1) {
m_compositePresenter->VTable0x60(this);
}
}
}
}
// FUNCTION: LEGO1 0x10043d40
void LegoActionControlPresenter::RepeatingTickle()
{
if (IsEnabled()) {
if (m_unk0x50 == 0) {
ParseExtra();
}
InvokeAction(m_unk0x50, MxAtomId(m_unk0x54.GetData(), LookupMode_LowerCase2), m_unk0x64, NULL);
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
m_currentTickleState = TickleState_Done;
}
}
// FUNCTION: LEGO1 0x10043df0
MxResult LegoActionControlPresenter::AddToManager()
{
MxResult result = FAILURE;
if (TickleManager()) {
result = SUCCESS;
TickleManager()->RegisterClient(this, 100);
}
return result;
}
// FUNCTION: LEGO1 0x10043e20
void LegoActionControlPresenter::Destroy(MxBool p_fromDestructor)
{
if (TickleManager()) {
TickleManager()->UnregisterClient(this);
}
if (!p_fromDestructor) {
MxMediaPresenter::Destroy(FALSE);
}
}
// FUNCTION: LEGO1 0x10043e50
void LegoActionControlPresenter::ParseExtra()
{
MxU32 len = m_action->GetExtraLength();
if (len == 0)
return;
len &= MAXWORD;
char buf[1024];
memcpy(buf, m_action->GetExtraData(), len);
buf[len] = '\0';
char output[1024];
if (KeyValueStringParse(output, g_strACTION, buf)) {
m_unk0x50 = MatchActionString(strtok(output, g_parseExtraTokens));
if (m_unk0x50 != ExtraActionType_exit) {
MakeSourceName(buf, strtok(NULL, g_parseExtraTokens));
m_unk0x54 = buf;
m_unk0x54.ToLowerCase();
if (m_unk0x50 != ExtraActionType_run) {
m_unk0x64 = atoi(strtok(NULL, g_parseExtraTokens));
}
}
}
}

View File

@@ -0,0 +1,56 @@
#include "legobackgroundcolor.h"
#include "decomp.h"
#include "legoomni.h"
#include "legoutil.h"
#include "legovideomanager.h"
DECOMP_SIZE_ASSERT(LegoBackgroundColor, 0x30)
const char* g_delimiter = "\t";
const char* g_set = "set";
const char* g_reset = "reset";
// FUNCTION: LEGO1 0x1003bfb0
LegoBackgroundColor::LegoBackgroundColor(const char* p_key, const char* p_value)
{
m_key = p_key;
m_key.ToUpperCase();
SetValue(p_value);
}
// FUNCTION: LEGO1 0x1003c070
void LegoBackgroundColor::SetValue(const char* p_colorString)
{
m_value = p_colorString;
m_value.ToLowerCase();
LegoVideoManager* videomanager = VideoManager();
if (!videomanager || !p_colorString)
return;
float convertedR, convertedG, convertedB;
char* colorStringCopy = strcpy(new char[strlen(p_colorString) + 1], p_colorString);
char* colorStringSplit = strtok(colorStringCopy, g_delimiter);
if (!strcmp(colorStringSplit, g_set)) {
colorStringSplit = strtok(0, g_delimiter);
if (colorStringSplit)
m_h = (float) (atoi(colorStringSplit) * 0.01);
colorStringSplit = strtok(0, g_delimiter);
if (colorStringSplit)
m_s = (float) (atoi(colorStringSplit) * 0.01);
colorStringSplit = strtok(0, g_delimiter);
if (colorStringSplit)
m_v = (float) (atoi(colorStringSplit) * 0.01);
ConvertHSVToRGB(m_h, m_s, m_v, &convertedR, &convertedG, &convertedB);
videomanager->SetSkyColor(convertedR, convertedG, convertedB);
}
else if (!strcmp(colorStringSplit, g_reset)) {
ConvertHSVToRGB(m_h, m_s, m_v, &convertedR, &convertedG, &convertedB);
videomanager->SetSkyColor(convertedR, convertedG, convertedB);
}
delete[] colorStringCopy;
}

View File

@@ -0,0 +1,47 @@
#include "legocameracontroller.h"
// STUB: LEGO1 0x10011d50
LegoCameraController::LegoCameraController()
{
// TODO
}
// STUB: LEGO1 0x10011f70
LegoCameraController::~LegoCameraController()
{
// TODO
}
// STUB: LEGO1 0x10012260
void LegoCameraController::LookAt(Vector3Impl& p_at, Vector3Impl& p_dir, Vector3Impl& p_up)
{
}
// STUB: LEGO1 0x100123e0
void LegoCameraController::FUN_100123e0(Matrix4Data& p_transform, MxU32)
{
}
// STUB: LEGO1 0x10012740
Vector3Data& LegoCameraController::FUN_10012740()
{
// Actually returns reference to a member
static Vector3Data g_v;
return g_v;
}
// STUB: LEGO1 0x100127f0
Vector3Data& LegoCameraController::FUN_100127f0()
{
// Actually returns reference to a member
static Vector3Data g_v;
return g_v;
}
// STUB: LEGO1 0x100128a0
Vector3Data& LegoCameraController::FUN_100128a0()
{
// Actually returns reference to a member
static Vector3Data g_v;
return g_v;
}

View File

@@ -0,0 +1,43 @@
#include "legofullscreenmovie.h"
#include "decomp.h"
#include "legoomni.h"
#include "legovideomanager.h"
#include "mxtypes.h"
DECOMP_SIZE_ASSERT(LegoFullScreenMovie, 0x24)
// GLOBAL: LEGO1 0x100f3be8
const char* g_strEnable = "enable";
// GLOBAL: LEGO1 0x100f3bf4
const char* g_strDisable = "disable";
// FUNCTION: LEGO1 0x1003c500
LegoFullScreenMovie::LegoFullScreenMovie(const char* p_key, const char* p_value)
{
m_key = p_key;
m_key.ToUpperCase();
SetValue(p_value);
}
// FUNCTION: LEGO1 0x1003c5c0
void LegoFullScreenMovie::SetValue(const char* p_option)
{
m_value = p_option;
m_value.ToLowerCase();
LegoVideoManager* videomanager = VideoManager();
if (videomanager) {
if (!strcmp(m_value.GetData(), g_strEnable)) {
videomanager->EnableFullScreenMovie(TRUE);
return;
}
if (!strcmp(m_value.GetData(), g_strDisable)) {
videomanager->EnableFullScreenMovie(FALSE);
return;
}
}
}

View File

@@ -0,0 +1,315 @@
#include "legogamestate.h"
#include "infocenterstate.h"
#include "legoomni.h"
#include "legostate.h"
#include "legostream.h"
#include "mxobjectfactory.h"
#include "mxstring.h"
#include "mxvariabletable.h"
#include "roi/legoroi.h"
#include <stdio.h>
// Based on the highest dword offset (0x42c) referenced in the constructor.
// There may be other members that come after.
DECOMP_SIZE_ASSERT(LegoGameState, 0x430)
// GLOBAL: LEGO1 0x100f3e24
const char* g_historyGSI = "History.gsi";
// GLOBAL: LEGO1 0x100f3e30
const char* g_playersGSI = "Players.gsi";
// GLOBAL: LEGO1 0x100f3e40
const char* g_fileExtensionGS = ".GS";
// GLOBAL: LEGO1 0x100f3e58
ColorStringStruct g_colorSaveData[43] = {
{"c_dbbkfny0", "lego red"}, {"c_dbbkxly0", "lego white"}, {"c_chbasey0", "lego black"},
{"c_chbacky0", "lego black"}, {"c_chdishy0", "lego white"}, {"c_chhorny0", "lego black"},
{"c_chljety1", "lego black"}, {"c_chrjety1", "lego black"}, {"c_chmidly0", "lego black"},
{"c_chmotry0", "lego blue"}, {"c_chsidly0", "lego black"}, {"c_chsidry0", "lego black"},
{"c_chstuty0", "lego black"}, {"c_chtaily0", "lego black"}, {"c_chwindy1", "lego black"},
{"c_dbfbrdy0", "lego red"}, {"c_dbflagy0", "lego yellow"}, {"c_dbfrfny4", "lego red"},
{"c_dbfrxly0", "lego white"}, {"c_dbhndly0", "lego white"}, {"c_dbltbry0", "lego white"},
{"c_jsdashy0", "lego white"}, {"c_jsexhy0", "lego black"}, {"c_jsfrnty5", "lego black"},
{"c_jshndly0", "lego red"}, {"c_jslsidy0", "lego black"}, {"c_jsrsidy0", "lego black"},
{"c_jsskiby0", "lego red"}, {"c_jswnshy5", "lego white"}, {"c_rcbacky6", "lego green"},
{"c_rcedgey0", "lego green"}, {"c_rcfrmey0", "lego red"}, {"c_rcfrnty6", "lego green"},
{"c_rcmotry0", "lego white"}, {"c_rcsidey0", "lego green"}, {"c_rcstery0", "lego white"},
{"c_rcstrpy0", "lego yellow"}, {"c_rctailya", "lego white"}, {"c_rcwhl1y0", "lego white"},
{"c_rcwhl2y0", "lego white"}, {"c_jsbasey0", "lego white"}, {"c_chblady0", "lego black"},
{"c_chseaty0", "lego white"},
};
// NOTE: This offset = the end of the variables table, the last entry
// in that table is a special entry, the string "END_OF_VARIABLES"
extern const char* g_endOfVariables;
// FUNCTION: LEGO1 0x10039550
LegoGameState::LegoGameState()
{
// TODO
SetROIHandlerFunction();
m_stateCount = 0;
m_backgroundColor = new LegoBackgroundColor("backgroundcolor", "set 56 54 68");
VariableTable()->SetVariable(m_backgroundColor);
m_tempBackgroundColor = new LegoBackgroundColor("tempBackgroundcolor", "set 56 54 68");
VariableTable()->SetVariable(m_tempBackgroundColor);
m_fullScreenMovie = new LegoFullScreenMovie("fsmovie", "disable");
VariableTable()->SetVariable(m_fullScreenMovie);
VariableTable()->SetVariable("lightposition", "2");
SerializeScoreHistory(1);
}
// FUNCTION: LEGO1 0x10039720
LegoGameState::~LegoGameState()
{
LegoROI::SetSomeHandlerFunction(NULL);
if (m_stateCount) {
for (MxS16 i = 0; i < m_stateCount; i++) {
LegoState* state = m_stateArray[i];
if (state)
delete state;
}
delete[] m_stateArray;
}
delete[] m_savePath;
}
// FUNCTION: LEGO1 0x10039980
MxResult LegoGameState::Save(MxULong p_slot)
{
MxResult result;
InfocenterState* infocenterState = (InfocenterState*) GameState()->GetState("InfocenterState");
if (!infocenterState || infocenterState->GetInfocenterBufferElement(0) == 0)
result = SUCCESS;
else {
result = FAILURE;
MxVariableTable* variableTable = VariableTable();
MxString savePath;
GetFileSavePath(&savePath, p_slot);
LegoFileStream fileStream;
if (fileStream.Open(savePath.GetData(), LegoStream::WriteBit) != FAILURE) {
MxU32 maybeVersion = 0x1000C;
fileStream.Write(&maybeVersion, 4);
fileStream.Write(&m_unk0x24, 2);
fileStream.Write(&m_unk0x10, 2);
fileStream.Write(&m_unk0xc, 1);
for (MxS32 i = 0; i < sizeof(g_colorSaveData) / sizeof(g_colorSaveData[0]); ++i) {
if (LegoStream::WriteVariable(&fileStream, variableTable, g_colorSaveData[i].m_targetName) == FAILURE)
return result;
}
if (LegoStream::WriteVariable(&fileStream, variableTable, "backgroundcolor") != FAILURE) {
if (LegoStream::WriteVariable(&fileStream, variableTable, "lightposition") != FAILURE) {
WriteEndOfVariables(&fileStream);
// TODO: Calls down to more aggregate writing functions
return SUCCESS;
}
}
}
}
return result;
}
// STUB: LEGO1 0x10039c60
MxResult LegoGameState::Load(MxULong)
{
// TODO
return 0;
}
// FUNCTION: LEGO1 0x10039f00
void LegoGameState::SetSavePath(char* p_savePath)
{
if (m_savePath != NULL)
delete[] m_savePath;
if (p_savePath) {
m_savePath = new char[strlen(p_savePath) + 1];
strcpy(m_savePath, p_savePath);
}
else
m_savePath = NULL;
}
// FUNCTION: LEGO1 0x1003a020
MxResult LegoGameState::WriteEndOfVariables(LegoStream* p_stream)
{
MxU8 len = strlen(g_endOfVariables);
if (p_stream->Write(&len, 1) == SUCCESS)
return p_stream->Write(g_endOfVariables, len);
return FAILURE;
}
// FUNCTION: LEGO1 0x1003a170
void LegoGameState::GetFileSavePath(MxString* p_outPath, MxULong p_slotn)
{
char baseForSlot[2] = "0";
char path[1024] = "";
// Save path base
if (m_savePath != NULL)
strcpy(path, m_savePath);
// Slot: "G0", "G1", ...
strcat(path, "G");
baseForSlot[0] += p_slotn;
strcat(path, baseForSlot);
// Extension: ".GS"
strcat(path, g_fileExtensionGS);
*p_outPath = MxString(path);
}
// STUB: LEGO1 0x1003a2e0
void LegoGameState::SerializePlayersInfo(MxS16)
{
// TODO
}
// STUB: LEGO1 0x1003a720
void LegoGameState::FUN_1003a720(MxU32)
{
// TODO
}
// STUB: LEGO1 0x1003b060
void LegoGameState::HandleAction(MxU32)
{
// TODO
}
// FUNCTION: LEGO1 0x1003bac0
void LegoGameState::SetROIHandlerFunction()
{
LegoROI::SetSomeHandlerFunction(&ROIHandlerFunction);
}
// FUNCTION: LEGO1 0x1003bad0
MxBool ROIHandlerFunction(char* p_input, char* p_output, MxU32 p_copyLen)
{
if (p_output != NULL && p_copyLen != 0 &&
(strnicmp(p_input, "INDIR-F-", strlen("INDIR-F-")) == 0 ||
strnicmp(p_input, "INDIR-G-", strlen("INDIR-F-")) == 0)) {
char buf[256];
sprintf(buf, "c_%s", &p_input[strlen("INDIR-F-")]);
const char* value = VariableTable()->GetVariable(buf);
if (value != NULL) {
strncpy(p_output, value, p_copyLen);
p_output[p_copyLen - 1] = '\0';
return TRUE;
}
}
return FALSE;
}
// FUNCTION: LEGO1 0x1003bbb0
LegoState* LegoGameState::GetState(const char* p_stateName)
{
for (MxS32 i = 0; i < m_stateCount; ++i)
if (m_stateArray[i]->IsA(p_stateName))
return m_stateArray[i];
return NULL;
}
// FUNCTION: LEGO1 0x1003bc00
LegoState* LegoGameState::CreateState(const char* p_stateName)
{
LegoState* newState = (LegoState*) ObjectFactory()->Create(p_stateName);
RegisterState(newState);
return newState;
}
// FUNCTION: LEGO1 0x1003bc30
void LegoGameState::RegisterState(LegoState* p_state)
{
MxS32 targetIndex;
for (targetIndex = 0; targetIndex < m_stateCount; ++targetIndex)
if (m_stateArray[targetIndex]->IsA(p_state->ClassName()))
break;
if (targetIndex == m_stateCount) {
LegoState** newBuffer = new LegoState*[m_stateCount + 1];
if (m_stateCount != 0) {
memcpy(newBuffer, m_stateArray, m_stateCount * sizeof(LegoState*));
delete[] m_stateArray;
}
newBuffer[m_stateCount++] = p_state;
m_stateArray = newBuffer;
return;
}
if (m_stateArray[targetIndex])
delete m_stateArray[targetIndex];
m_stateArray[targetIndex] = p_state;
}
// STUB: LEGO1 0x1003c870
void LegoGameState::ScoreStruct::WriteScoreHistory()
{
// TODO
}
// STUB: LEGO1 0x1003ccf0
void LegoGameState::ScoreStruct::FUN_1003ccf0(LegoFileStream&)
{
// TODO
}
// FUNCTION: LEGO1 0x1003cdd0
void LegoGameState::SerializeScoreHistory(MxS16 p_flags)
{
LegoFileStream stream;
MxString savePath(m_savePath);
savePath += "\\";
savePath += g_historyGSI;
if (p_flags == LegoStream::WriteBit) {
m_unk0xa6.WriteScoreHistory();
}
if (stream.Open(savePath.GetData(), (LegoStream::OpenFlags) p_flags) == SUCCESS) {
m_unk0xa6.FUN_1003ccf0(stream);
}
}
// FUNCTION: LEGO1 0x1003cea0
void LegoGameState::SetSomeEnumState(undefined4 p_state)
{
m_unk0x10 = p_state;
}
// FUNCTION: LEGO1 0x1003ceb0
void LegoGameState::FUN_1003ceb0()
{
if (FindEntityByAtomIdOrEntityId(*g_isleScript, 0)) {
m_currentAct = 0;
}
else if (FindEntityByAtomIdOrEntityId(*g_act2mainScript, 0)) {
m_currentAct = 1;
}
else if (FindEntityByAtomIdOrEntityId(*g_act3Script, 0)) {
m_currentAct = 2;
}
else {
m_currentAct = -1;
}
}

View File

@@ -0,0 +1,224 @@
#include "legonavcontroller.h"
#include "legoinputmanager.h"
#include "legoomni.h"
#include "legoutil.h"
#include "legovideomanager.h"
// GLOBAL: LEGO1 0x100f4c28
int g_mouseDeadzone = 40;
// GLOBAL: LEGO1 0x100f4c2c
float g_zeroThreshold = 0.001f;
// GLOBAL: LEGO1 0x100f4c30
float g_movementMaxSpeed = 40.0f;
// GLOBAL: LEGO1 0x100f4c34
float g_turnMaxSpeed = 20.0f;
// GLOBAL: LEGO1 0x100f4c38
float g_movementMaxAccel = 15.0f;
// GLOBAL: LEGO1 0x100f4c3c
float g_turnMaxAccel = 30.0f;
// GLOBAL: LEGO1 0x100f4c40
float g_movementMinAccel = 4.0f;
// GLOBAL: LEGO1 0x100f4c44
float g_turnMinAccel = 15.0f;
// GLOBAL: LEGO1 0x100f4c48
float g_movementDecel = 50.0f;
// GLOBAL: LEGO1 0x100f4c4c
float g_turnDecel = 50.0f;
// GLOBAL: LEGO1 0x100f4c50
float g_turnSensitivity = 0.4f;
// GLOBAL: LEGO1 0x100f4c54
MxBool g_turnUseVelocity = FALSE;
// FUNCTION: LEGO1 0x10054ac0
LegoNavController::LegoNavController()
{
ResetToDefault();
this->m_unk0x18 = 0.0f;
this->m_unk0x1c = 0.0f;
this->m_targetMovementSpeed = 0.0f;
this->m_targetTurnSpeed = 0.0f;
this->m_movementAccel = 0.0f;
this->m_turnAccel = 0.0f;
this->m_trackDefault = FALSE;
this->m_unk0x5d = FALSE;
this->m_unk0x6c = FALSE;
this->m_unk0x64 = 0;
this->m_unk0x68 = 0;
this->m_unk0x60 = 0;
MxTimer* timer = Timer();
this->m_time = timer->GetTime();
InputManager()->Register(this);
}
// FUNCTION: LEGO1 0x10054c30
LegoNavController::~LegoNavController()
{
InputManager()->UnRegister(this);
}
// FUNCTION: LEGO1 0x10054ca0
void LegoNavController::SetControlMax(int p_hMax, int p_vMax)
{
this->m_hMax = p_hMax;
this->m_vMax = p_vMax;
if (VideoManager()->GetVideoParam().Flags().GetFullScreen()) {
this->m_hMax = 640;
this->m_vMax = 480;
}
}
// FUNCTION: LEGO1 0x10054cd0
void LegoNavController::ResetToDefault()
{
this->m_mouseDeadzone = g_mouseDeadzone;
this->m_zeroThreshold = g_zeroThreshold;
this->m_turnMaxAccel = g_turnMaxAccel;
this->m_movementMaxAccel = g_movementMaxAccel;
this->m_turnMinAccel = g_turnMinAccel;
this->m_movementMinAccel = g_movementMinAccel;
this->m_turnDecel = g_turnDecel;
this->m_movementDecel = g_movementDecel;
this->m_turnMaxSpeed = g_turnMaxSpeed;
this->m_movementMaxSpeed = g_movementMaxSpeed;
this->m_turnUseVelocity = g_turnUseVelocity;
this->m_turnSensitivity = g_turnSensitivity;
}
// FUNCTION: LEGO1 0x10054d40
void LegoNavController::GetDefaults(
int* p_mouseDeadzone,
float* p_movementMaxSpeed,
float* p_turnMaxSpeed,
float* p_movementMaxAccel,
float* p_turnMaxAccel,
float* p_movementDecel,
float* p_turnDecel,
float* p_movementMinAccel,
float* p_turnMinAccel,
float* p_turnSensitivity,
MxBool* p_turnUseVelocity
)
{
*p_mouseDeadzone = g_mouseDeadzone;
*p_movementMaxSpeed = g_movementMaxSpeed;
*p_turnMaxSpeed = g_turnMaxSpeed;
*p_movementMaxAccel = g_movementMaxAccel;
*p_turnMaxAccel = g_turnMaxAccel;
*p_movementDecel = g_movementDecel;
*p_turnDecel = g_turnDecel;
*p_movementMinAccel = g_movementMinAccel;
*p_turnMinAccel = g_turnMinAccel;
*p_turnSensitivity = g_turnSensitivity;
*p_turnUseVelocity = g_turnUseVelocity;
}
// FUNCTION: LEGO1 0x10054dd0
void LegoNavController::SetDefaults(
int p_mouseDeadzone,
float p_movementMaxSpeed,
float p_turnMaxSpeed,
float p_movementMaxAccel,
float p_turnMaxAccel,
float p_movementDecel,
float p_turnDecel,
float p_movementMinAccel,
float p_turnMinAccel,
float p_turnSensitivity,
MxBool p_turnUseVelocity
)
{
g_mouseDeadzone = p_mouseDeadzone;
g_movementMaxSpeed = p_movementMaxSpeed;
g_turnMaxSpeed = p_turnMaxSpeed;
g_movementMaxAccel = p_movementMaxAccel;
g_turnMaxAccel = p_turnMaxAccel;
g_movementDecel = p_movementDecel;
g_turnDecel = p_turnDecel;
g_movementMinAccel = p_movementMinAccel;
g_turnMinAccel = p_turnMinAccel;
g_turnSensitivity = p_turnSensitivity;
g_turnUseVelocity = p_turnUseVelocity;
}
// FUNCTION: LEGO1 0x10054e40
void LegoNavController::SetTargets(int p_hPos, int p_vPos, MxBool p_accel)
{
if (this->m_trackDefault != FALSE)
ResetToDefault();
if (p_accel != FALSE) {
this->m_targetTurnSpeed = CalculateNewTargetSpeed(p_hPos, this->m_hMax / 2, this->m_turnMaxSpeed);
this->m_targetMovementSpeed =
CalculateNewTargetSpeed(this->m_vMax - p_vPos, this->m_vMax / 2, this->m_movementMaxSpeed);
this->m_turnAccel =
CalculateNewAccel(p_hPos, this->m_hMax / 2, this->m_turnMaxAccel, (int) this->m_turnMinAccel);
this->m_movementAccel = CalculateNewAccel(
this->m_vMax - p_vPos,
this->m_vMax / 2,
this->m_movementMaxAccel,
(int) this->m_movementMinAccel
);
}
else {
this->m_targetTurnSpeed = 0.0f;
this->m_targetMovementSpeed = 0.0f;
this->m_movementAccel = this->m_movementDecel;
this->m_turnAccel = this->m_turnDecel;
}
}
// FUNCTION: LEGO1 0x10054f10
float LegoNavController::CalculateNewTargetSpeed(int p_pos, int p_center, float p_maxSpeed)
{
float result;
int diff = p_pos - p_center;
if (diff > this->m_mouseDeadzone)
result = (diff - m_mouseDeadzone) * p_maxSpeed / (p_center - m_mouseDeadzone);
else if (diff < -m_mouseDeadzone)
result = (diff + m_mouseDeadzone) * p_maxSpeed / (p_center - m_mouseDeadzone);
else
result = 0.0f;
return result;
}
// FUNCTION: LEGO1 0x10054f90
float LegoNavController::CalculateNewAccel(int p_pos, int p_center, float p_maxAccel, int p_minAccel)
{
float result;
int diff = p_pos - p_center;
result = Abs(diff) * p_maxAccel / p_center;
if (result < p_minAccel)
result = (float) p_minAccel;
return result;
}
// FUNCTION: LEGO1 0x10054fe0
float LegoNavController::CalculateNewVel(float p_targetVel, float p_currentVel, float p_accel, float p_time)
{
float newVel = p_currentVel;
float velDiff = p_targetVel - p_currentVel;
int vSign = velDiff > 0 ? 1 : -1;
if (Abs(velDiff) > this->m_zeroThreshold) {
float deltaVel = p_accel * p_time;
newVel = p_currentVel + (deltaVel * vSign);
if (vSign > 0)
newVel = Min(newVel, p_targetVel);
else
newVel = Max(newVel, p_targetVel);
}
return newVel;
}

View File

@@ -0,0 +1,135 @@
#include "legoobjectfactory.h"
#include "carrace.h"
#include "decomp.h"
#include "dunebuggy.h"
#include "elevatorbottom.h"
#include "gasstation.h"
#include "gasstationstate.h"
#include "helicopter.h"
#include "helicopterstate.h"
#include "historybook.h"
#include "hospital.h"
#include "hospitalstate.h"
#include "infocenter.h"
#include "infocenterdoor.h"
#include "infocenterstate.h"
#include "isle.h"
#include "jetskirace.h"
#include "lego3dwavepresenter.h"
#include "legoact2.h"
#include "legoact2state.h"
#include "legoactioncontrolpresenter.h"
#include "legoactor.h"
#include "legoactorpresenter.h"
#include "legoanimactor.h"
#include "legoanimpresenter.h"
#include "legocarbuild.h"
#include "legocarbuildanimpresenter.h"
#include "legocarraceactor.h"
#include "legoentity.h"
#include "legoentitypresenter.h"
#include "legoflctexturepresenter.h"
#include "legohideanimpresenter.h"
#include "legojetski.h"
#include "legojetskiraceactor.h"
#include "legoloadcachesoundpresenter.h"
#include "legolocomotionanimpresenter.h"
#include "legoloopinganimpresenter.h"
#include "legomodelpresenter.h"
#include "legopalettepresenter.h"
#include "legopartpresenter.h"
#include "legopathactor.h"
#include "legopathpresenter.h"
#include "legophonemepresenter.h"
#include "legoracecar.h"
#include "legotexturepresenter.h"
#include "legoworld.h"
#include "legoworldpresenter.h"
#include "mxcontrolpresenter.h"
#include "mxvideopresenter.h"
#include "pizza.h"
#include "pizzamissionstate.h"
#include "police.h"
#include "policestate.h"
#include "registrationbook.h"
#include "score.h"
#include "scorestate.h"
#include "skateboard.h"
// #include "act2actor.h"
#include "act2brick.h"
// #include "act2genactor.h"
#include "act2policestation.h"
#include "act3.h"
#include "act3state.h"
#include "ambulance.h"
#include "ambulancemissionstate.h"
#include "bike.h"
#include "doors.h"
#include "jetski.h"
#include "legoanimmmpresenter.h"
#include "motorcycle.h"
#include "racecar.h"
#include "towtrack.h"
#include "towtrackmissionstate.h"
// #include "act3cop.h"
// #include "act3brickster.h"
#include "act1state.h"
#include "act3actor.h"
#include "act3shark.h"
#include "beachhouseentity.h"
#include "bumpbouy.h"
#include "carracestate.h"
#include "gasstationentity.h"
#include "hospitalentity.h"
#include "infocenterentity.h"
#include "jetskiracestate.h"
#include "jukeboxentity.h"
#include "pizzeria.h"
#include "pizzeriastate.h"
#include "policeentity.h"
#include "racestandsentity.h"
#include "radiostate.h"
// #include "caveentity.h"
// #include "jailentity.h"
#include "jukebox.h"
#include "jukeboxstate.h"
#include "mxcompositemediapresenter.h"
// #include "raceskel.h"
#include "animstate.h"
// TODO: Before HospitalState, add all of the different LegoVehicleBuildState's
// TODO: Uncomment once we have all the relevant types ready
// DECOMP_SIZE_ASSERT(LegoObjectFactory, 0x1c8);
// FUNCTION: LEGO1 0x10006e40
LegoObjectFactory::LegoObjectFactory()
{
#define X(V) this->m_id##V = MxAtomId(#V, LookupMode_Exact);
FOR_LEGOOBJECTFACTORY_OBJECTS(X)
#undef X
}
// FUNCTION: LEGO1 0x10009a90
MxCore* LegoObjectFactory::Create(const char* p_name)
{
MxAtomId atom(p_name, LookupMode_Exact);
#define X(V) \
if (this->m_id##V == atom) { \
return new V; \
} \
else
FOR_LEGOOBJECTFACTORY_OBJECTS(X)
#undef X
{
return MxObjectFactory::Create(p_name);
}
}
// FUNCTION: LEGO1 0x1000fb30
void LegoObjectFactory::Destroy(MxCore* p_object)
{
delete p_object;
}

View File

@@ -0,0 +1,27 @@
#include "legoplantmanager.h"
// FUNCTION: LEGO1 0x10026220
LegoPlantManager::LegoPlantManager()
{
Init();
}
// STUB: LEGO1 0x100262c0
LegoPlantManager::~LegoPlantManager()
{
// TODO
}
// STUB: LEGO1 0x10026330
void LegoPlantManager::Init()
{
// TODO
}
// STUB: LEGO1 0x10026e00
MxResult LegoPlantManager::Tickle()
{
// TODO
return 0;
}

View File

@@ -0,0 +1,42 @@
#include "legostate.h"
DECOMP_SIZE_ASSERT(LegoState, 0x08);
// FUNCTION: LEGO1 0x10005f40
LegoState::~LegoState()
{
}
// FUNCTION: LEGO1 0x10005f90
MxBool LegoState::VTable0x14()
{
return TRUE;
}
// FUNCTION: LEGO1 0x10005fa0
MxBool LegoState::SetFlag()
{
return FALSE;
}
// FUNCTION: LEGO1 0x10005fb0
MxResult LegoState::VTable0x1c(LegoFileStream* p_legoFileStream)
{
if (p_legoFileStream->IsWriteMode()) {
p_legoFileStream->FUN_10006030(this->ClassName());
}
return SUCCESS;
}
// FUNCTION: LEGO1 0x10006030
LegoFileStream* LegoFileStream::FUN_10006030(MxString p_str)
{
const char* data = p_str.GetData();
MxU32 fullLength = strlen(data);
MxU16 limitedLength = fullLength;
Write(&limitedLength, sizeof(limitedLength));
Write(data, (MxS16) fullLength);
return this;
}

View File

@@ -0,0 +1,200 @@
#include "legostream.h"
#include "mxvariabletable.h"
#include <cstdio>
#include <string>
// This is a pointer to the end of the global variable name table, which has
// the text "END_OF_VARIABLES" in it.
// TODO: make g_endOfVariables reference the actual end of the variable array.
// GLOBAL: LEGO1 0x100f3e50
const char* g_endOfVariables = "END_OF_VARIABLES";
// Very likely but not certain sizes.
// The classes are only used on the stack in functions we have not 100% matched
// yet, we can confirm the size once we have.
DECOMP_SIZE_ASSERT(LegoStream, 0x8);
DECOMP_SIZE_ASSERT(LegoFileStream, 0xC);
DECOMP_SIZE_ASSERT(LegoMemoryStream, 0x10);
// FUNCTION: LEGO1 0x10039f70
MxResult LegoStream::WriteVariable(LegoStream* p_stream, MxVariableTable* p_from, const char* p_variableName)
{
MxResult result = FAILURE;
const char* variableValue = p_from->GetVariable(p_variableName);
if (variableValue) {
MxU8 length = strlen(p_variableName);
if (p_stream->Write((char*) &length, 1) == SUCCESS) {
if (p_stream->Write(p_variableName, length) == SUCCESS) {
length = strlen(variableValue);
if (p_stream->Write((char*) &length, 1) == SUCCESS)
result = p_stream->Write((char*) variableValue, length);
}
}
}
return result;
}
// 95% match, just some instruction ordering differences on the call to
// MxVariableTable::SetVariable at the end.
// FUNCTION: LEGO1 0x1003a080
MxS32 LegoStream::ReadVariable(LegoStream* p_stream, MxVariableTable* p_to)
{
MxS32 result = 1;
MxU8 length;
if (p_stream->Read((char*) &length, 1) == SUCCESS) {
char nameBuffer[256];
if (p_stream->Read(nameBuffer, length) == SUCCESS) {
nameBuffer[length] = '\0';
if (strcmp(nameBuffer, g_endOfVariables) == 0)
// 2 -> "This was the last entry, done reading."
result = 2;
else {
if (p_stream->Read((char*) &length, 1) == SUCCESS) {
char valueBuffer[256];
if (p_stream->Read(valueBuffer, length) == SUCCESS) {
result = 0;
valueBuffer[length] = '\0';
p_to->SetVariable(nameBuffer, valueBuffer);
}
}
}
}
}
return result;
}
// FUNCTION: LEGO1 0x10045ae0
MxBool LegoStream::IsWriteMode()
{
return m_mode == LEGOSTREAM_MODE_WRITE;
}
// FUNCTION: LEGO1 0x10045af0
MxBool LegoStream::IsReadMode()
{
return m_mode == LEGOSTREAM_MODE_READ;
}
// FUNCTION: LEGO1 0x10099080
LegoMemoryStream::LegoMemoryStream(char* p_buffer) : LegoStream()
{
m_buffer = p_buffer;
m_offset = 0;
}
// FUNCTION: LEGO1 0x10099160
MxResult LegoMemoryStream::Read(void* p_buffer, MxU32 p_size)
{
memcpy(p_buffer, m_buffer + m_offset, p_size);
m_offset += p_size;
return SUCCESS;
}
// FUNCTION: LEGO1 0x10099190
MxResult LegoMemoryStream::Write(const void* p_buffer, MxU32 p_size)
{
memcpy(m_buffer + m_offset, p_buffer, p_size);
m_offset += p_size;
return SUCCESS;
}
// FUNCTION: LEGO1 0x100991c0
LegoFileStream::LegoFileStream() : LegoStream()
{
m_hFile = NULL;
}
// FUNCTION: LEGO1 0x10099250
LegoFileStream::~LegoFileStream()
{
if (m_hFile != NULL)
fclose(m_hFile);
}
// FUNCTION: LEGO1 0x100992c0
MxResult LegoFileStream::Read(void* p_buffer, MxU32 p_size)
{
if (m_hFile == NULL)
return FAILURE;
return (fread(p_buffer, 1, p_size, m_hFile) == p_size) ? SUCCESS : FAILURE;
}
// FUNCTION: LEGO1 0x10099300
MxResult LegoFileStream::Write(const void* p_buffer, MxU32 p_size)
{
if (m_hFile == NULL)
return FAILURE;
return (fwrite(p_buffer, 1, p_size, m_hFile) == p_size) ? SUCCESS : FAILURE;
}
// FUNCTION: LEGO1 0x10099340
MxResult LegoFileStream::Tell(MxU32* p_offset)
{
if (m_hFile == NULL)
return FAILURE;
int got = ftell(m_hFile);
if (got == -1)
return FAILURE;
*p_offset = got;
return SUCCESS;
}
// FUNCTION: LEGO1 0x10099370
MxResult LegoFileStream::Seek(MxU32 p_offset)
{
if (m_hFile == NULL)
return FAILURE;
return (fseek(m_hFile, p_offset, 0) == 0) ? SUCCESS : FAILURE;
}
// FUNCTION: LEGO1 0x100993a0
MxResult LegoFileStream::Open(const char* p_filename, OpenFlags p_mode)
{
char modeString[4];
if (m_hFile != NULL)
fclose(m_hFile);
modeString[0] = '\0';
if (p_mode & ReadBit) {
m_mode = LEGOSTREAM_MODE_READ;
strcat(modeString, "r");
}
if (p_mode & WriteBit) {
if (m_mode != LEGOSTREAM_MODE_READ)
m_mode = LEGOSTREAM_MODE_WRITE;
strcat(modeString, "w");
}
if ((p_mode & 4) != 0)
strcat(modeString, "b");
else
strcat(modeString, "t");
return (m_hFile = fopen(p_filename, modeString)) ? SUCCESS : FAILURE;
}
// FUNCTION: LEGO1 0x100994a0
MxResult LegoMemoryStream::Tell(MxU32* p_offset)
{
*p_offset = m_offset;
return SUCCESS;
}
// FUNCTION: LEGO1 0x100994b0
MxResult LegoMemoryStream::Seek(MxU32 p_offset)
{
m_offset = p_offset;
return SUCCESS;
}

View File

@@ -0,0 +1,49 @@
#include "legounksavedatawriter.h"
#include "legogamestate.h"
#include "legostream.h"
DECOMP_SIZE_ASSERT(LegoSaveDataEntry3, 0x108);
// GLOBAL: LEGO1 0x10104f20
LegoSaveDataEntry3 g_saveData3[66];
// FUNCTION: LEGO1 0x10083310
MxResult LegoUnkSaveDataWriter::WriteSaveData3(LegoStream* p_stream)
{
MxResult result = FAILURE;
// This should probably be a for loop but I can't figure out how to
// make it match as a for loop.
LegoSaveDataEntry3* entry = g_saveData3;
const LegoSaveDataEntry3* end = &g_saveData3[66];
while (TRUE) {
if (p_stream->Write(&entry->m_savePart1, 4) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart2, 4) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart3, 1) != SUCCESS)
break;
if (p_stream->Write(&entry->m_currentFrame, 1) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart5, 1) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart6, 1) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart7, 1) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart8, 1) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart9, 1) != SUCCESS)
break;
if (p_stream->Write(&entry->m_savePart10, 1) != SUCCESS)
break;
if (++entry >= end) {
result = SUCCESS;
break;
}
}
return result;
}

View File

@@ -0,0 +1,208 @@
#include "legoutil.h"
#include "legoomni.h"
#include "legoworld.h"
#include "mxdsaction.h"
#include "mxomni.h"
#include "mxstreamer.h"
#include "mxtypes.h"
#include <process.h>
#include <string.h>
// FUNCTION: LEGO1 0x1003e300
ExtraActionType MatchActionString(const char* p_str)
{
ExtraActionType result = ExtraActionType_unknown;
if (!strcmpi("openram", p_str))
result = ExtraActionType_openram;
else if (!strcmpi("opendisk", p_str))
result = ExtraActionType_opendisk;
else if (!strcmpi("close", p_str))
result = ExtraActionType_close;
else if (!strcmpi("start", p_str))
result = ExtraActionType_start;
else if (!strcmpi("stop", p_str))
result = ExtraActionType_stop;
else if (!strcmpi("run", p_str))
result = ExtraActionType_run;
else if (!strcmpi("exit", p_str))
result = ExtraActionType_exit;
else if (!strcmpi("enable", p_str))
result = ExtraActionType_enable;
else if (!strcmpi("disable", p_str))
result = ExtraActionType_disable;
else if (!strcmpi("notify", p_str))
result = ExtraActionType_notify;
return result;
}
MxBool CheckIfEntityExists(MxBool p_enable, const char* p_filename, MxS32 p_entityId);
void NotifyEntity(const char* p_filename, MxS32 p_entityId, LegoEntity* p_sender);
// FUNCTION: LEGO1 0x1003e430
void InvokeAction(ExtraActionType p_actionId, MxAtomId& p_pAtom, int p_targetEntityId, LegoEntity* p_sender)
{
MxDSAction action;
action.SetAtomId(p_pAtom);
action.SetObjectId(p_targetEntityId);
switch (p_actionId) {
case ExtraActionType_opendisk:
if (!CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_targetEntityId)) {
Streamer()->Open(p_pAtom.GetInternal(), MxStreamer::e_DiskStream);
Start(&action);
}
break;
case ExtraActionType_openram:
if (!CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_targetEntityId)) {
Streamer()->Open(p_pAtom.GetInternal(), MxStreamer::e_RAMStream);
Start(&action);
}
break;
case ExtraActionType_close:
action.SetUnknown24(-2);
DeleteObject(action);
Streamer()->Close(p_pAtom.GetInternal());
break;
case ExtraActionType_start:
if (!CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_targetEntityId)) {
Start(&action);
}
break;
case ExtraActionType_stop:
action.SetUnknown24(-2);
if (!FUN_1003ee00(p_pAtom, p_targetEntityId)) {
DeleteObject(action);
}
break;
case ExtraActionType_run:
_spawnl(0, "\\lego\\sources\\main\\main.exe", "\\lego\\sources\\main\\main.exe", "/script", &p_pAtom, 0);
break;
case ExtraActionType_exit:
Lego()->SetExit(TRUE);
break;
case ExtraActionType_enable:
CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_targetEntityId);
break;
case ExtraActionType_disable:
CheckIfEntityExists(FALSE, p_pAtom.GetInternal(), p_targetEntityId);
break;
case ExtraActionType_notify:
NotifyEntity(p_pAtom.GetInternal(), p_targetEntityId, p_sender);
break;
}
}
// FUNCTION: LEGO1 0x1003e670
MxBool CheckIfEntityExists(MxBool p_enable, const char* p_filename, MxS32 p_entityId)
{
LegoWorld* world =
(LegoWorld*) FindEntityByAtomIdOrEntityId(MxAtomId(p_filename, LookupMode_LowerCase2), p_entityId);
if (world) {
world->VTable0x68(p_enable);
return TRUE;
}
else {
return FALSE;
}
}
// STUB: LEGO1 0x1003e700
void NotifyEntity(const char* p_filename, MxS32 p_entityId, LegoEntity* p_sender)
{
}
// FUNCTION: LEGO1 0x1003eae0
void ConvertHSVToRGB(float p_h, float p_s, float p_v, float* p_rOut, float* p_bOut, float* p_gOut)
{
double calc;
double p;
MxLong hueIndex;
double v9;
double v12;
double v13;
double sDbl = p_s;
if (p_s > 0.5f)
calc = (1.0f - p_v) * p_s + p_v;
else
calc = (p_v + 1.0) * sDbl;
if (calc <= 0.0) {
*p_gOut = 0.0f;
*p_bOut = 0.0f;
*p_rOut = 0.0f;
return;
}
p = p_s * 2.0f - calc;
hueIndex = p_h * 6.0;
v9 = (p_h * 6.0 - (float) hueIndex) * ((calc - p) / calc) * calc;
v12 = p + v9;
v13 = calc - v9;
switch (hueIndex) {
case 0:
*p_rOut = calc;
*p_bOut = v12;
*p_gOut = p;
break;
case 1:
*p_rOut = v13;
*p_bOut = calc;
*p_gOut = p;
break;
case 2:
*p_rOut = p;
*p_bOut = calc;
*p_gOut = v12;
break;
case 3:
*p_rOut = p;
*p_bOut = v13;
*p_gOut = calc;
break;
case 4:
*p_rOut = v12;
*p_bOut = p;
*p_gOut = calc;
break;
case 5:
*p_rOut = calc;
*p_bOut = p;
*p_gOut = v13;
break;
case 6:
*p_rOut = calc;
*p_bOut = p;
*p_gOut = v13;
break;
default:
return;
}
}
// STUB: LEGO1 0x1003ee00
MxBool FUN_1003ee00(MxAtomId& p_atomId, MxS32 p_id)
{
return TRUE;
}
// STUB: LEGO1 0x1003ef00
void FUN_1003ef00(MxBool)
{
// TODO (something related to animation manager)
}
// FUNCTION: LEGO1 0x1003ef40
void SetAppCursor(WPARAM p_wparam)
{
PostMessageA(MxOmni::GetInstance()->GetWindowHandle(), 0x5400, p_wparam, 0);
}
// STUB: LEGO1 0x1003ef60
MxBool FUN_1003ef60()
{
return TRUE;
}