diff --git a/LEGO1/lego/legoomni/include/legobuildingmanager.h b/LEGO1/lego/legoomni/include/legobuildingmanager.h index 2c50c027..d11a384f 100644 --- a/LEGO1/lego/legoomni/include/legobuildingmanager.h +++ b/LEGO1/lego/legoomni/include/legobuildingmanager.h @@ -24,6 +24,7 @@ class LegoBuildingManager : public MxCore { static void configureLegoBuildingManager(MxS32); static void SetCustomizeAnimFile(const char* p_value); + void Init(); void FUN_1002fa00(); void FUN_1002fb30(); MxResult Save(LegoStorage* p_storage); @@ -36,8 +37,6 @@ class LegoBuildingManager : public MxCore { private: static char* g_customizeAnimFile; - void Init(); - undefined m_unk0x08[0x28]; // 0x08 }; diff --git a/LEGO1/lego/legoomni/include/legogamestate.h b/LEGO1/lego/legoomni/include/legogamestate.h index d35c0764..7358df5f 100644 --- a/LEGO1/lego/legoomni/include/legogamestate.h +++ b/LEGO1/lego/legoomni/include/legogamestate.h @@ -90,8 +90,11 @@ class LegoGameState { // SIZE 0x0c struct Username { Username(); + inline Username(Username& p_other) { Set(p_other); } + inline void Set(Username& p_other) { memcpy(m_letters, p_other.m_letters, sizeof(m_letters)); } + MxResult ReadWrite(LegoStorage* p_storage); - Username* operator=(const Username* p_other); + Username& operator=(const Username& p_other); MxS16 m_letters[7]; // 0x00 }; @@ -120,19 +123,29 @@ class LegoGameState { LegoGameState(); ~LegoGameState(); + void SetActor(MxU8 p_actorId); + void RemoveActor(); + void ResetROI(); + MxResult Save(MxULong); MxResult DeleteState(); MxResult Load(MxULong); - void SerializePlayersInfo(MxS16); + + void SerializePlayersInfo(MxS16 p_flags); + MxResult AddPlayer(Username& p_player); + void SwitchPlayer(MxS16 p_playerId); + MxS16 FindPlayer(Username& p_player); + void SerializeScoreHistory(MxS16 p_flags); void SetSavePath(char*); LegoState* GetState(const char* p_stateName); LegoState* CreateState(const char* p_stateName); - void GetFileSavePath(MxString* p_outPath, MxULong p_slotn); + void GetFileSavePath(MxString* p_outPath, MxU8 p_slotn); void StopArea(Area p_area); void SwitchArea(Area p_area); + void Init(); inline MxU8 GetActorId() { return m_actorId; } inline Act GetCurrentAct() { return m_currentAct; } @@ -152,8 +165,6 @@ class LegoGameState { void SetCurrentAct(Act p_currentAct); void FindLoadedAct(); - void SetActor(MxU8 p_actorId); - void ResetROI(); private: void RegisterState(LegoState* p_state); @@ -173,7 +184,7 @@ class LegoGameState { LegoBackgroundColor* m_tempBackgroundColor; // 0x1c LegoFullScreenMovie* m_fullScreenMovie; // 0x20 MxU16 m_unk0x24; // 0x24 - undefined2 m_unk0x26; // 0x26 + MxS16 m_playerCount; // 0x26 Username m_players[9]; // 0x28 History m_history; // 0xa6 undefined2 m_unk0x41a; // 0x41a diff --git a/LEGO1/lego/legoomni/include/legoplantmanager.h b/LEGO1/lego/legoomni/include/legoplantmanager.h index 622eb500..0f2577cc 100644 --- a/LEGO1/lego/legoomni/include/legoplantmanager.h +++ b/LEGO1/lego/legoomni/include/legoplantmanager.h @@ -21,6 +21,7 @@ class LegoPlantManager : public MxCore { return "LegoPlantManager"; } + void Init(); void FUN_10026360(MxS32 p_scriptIndex); void FUN_100263a0(undefined4 p_und); void Save(LegoStorage* p_storage); @@ -35,8 +36,6 @@ class LegoPlantManager : public MxCore { private: static char* g_customizeAnimFile; - void Init(); - undefined m_unk0x08[0x24]; // 0x08 }; diff --git a/LEGO1/lego/legoomni/include/legounksavedatawriter.h b/LEGO1/lego/legoomni/include/legounksavedatawriter.h index 482ecd9e..9f3d1235 100644 --- a/LEGO1/lego/legoomni/include/legounksavedatawriter.h +++ b/LEGO1/lego/legoomni/include/legounksavedatawriter.h @@ -59,7 +59,7 @@ class LegoUnkSaveDataWriter { MxResult ReadSaveData3(LegoStorage* p_storage); LegoROI* FUN_10083500(const char*, MxBool); - static void InitSaveData(); + void InitSaveData(); static void SetCustomizeAnimFile(const char* p_value); static MxBool FUN_10084c00(const LegoChar*); diff --git a/LEGO1/lego/legoomni/src/common/legogamestate.cpp b/LEGO1/lego/legoomni/src/common/legogamestate.cpp index 9c794f97..375938b4 100644 --- a/LEGO1/lego/legoomni/src/common/legogamestate.cpp +++ b/LEGO1/lego/legoomni/src/common/legogamestate.cpp @@ -2,8 +2,12 @@ #include "act1state.h" #include "define.h" +#include "dunebuggy.h" +#include "helicopter.h" #include "infocenterstate.h" +#include "isle.h" #include "islepathactor.h" +#include "jetski.h" #include "legoanimationmanager.h" #include "legobuildingmanager.h" #include "legonavcontroller.h" @@ -18,6 +22,7 @@ #include "mxobjectfactory.h" #include "mxstring.h" #include "mxvariabletable.h" +#include "racecar.h" #include "roi/legoroi.h" #include @@ -90,7 +95,7 @@ LegoGameState::LegoGameState() m_currentArea = e_noArea; m_previousArea = e_noArea; m_unk0x42c = e_noArea; - m_unk0x26 = 0; + m_playerCount = 0; m_isDirty = FALSE; m_loadedAct = e_actNotFound; SetCurrentAct(e_act1); @@ -158,6 +163,15 @@ void LegoGameState::SetActor(MxU8 p_actorId) SetCurrentActor(newActor); } +// FUNCTION: LEGO1 0x10039910 +void LegoGameState::RemoveActor() +{ + IslePathActor* actor = CurrentActor(); + SetCurrentActor(NULL); + delete actor; + m_actorId = 0; +} + // FUNCTION: LEGO1 0x10039940 void LegoGameState::ResetROI() { @@ -422,8 +436,6 @@ MxResult LegoGameState::WriteEndOfVariables(LegoStorage* p_storage) return FAILURE; } -// 95% match, just some instruction ordering differences on the call to -// MxVariableTable::SetVariable at the end. // FUNCTION: LEGO1 0x1003a080 MxS32 LegoGameState::ReadVariable(LegoStorage* p_storage, MxVariableTable* p_to) { @@ -442,9 +454,9 @@ MxS32 LegoGameState::ReadVariable(LegoStorage* p_storage, MxVariableTable* p_to) if (p_storage->Read((char*) &length, 1) == SUCCESS) { char valueBuffer[256]; if (p_storage->Read(valueBuffer, length) == SUCCESS) { - result = 0; valueBuffer[length] = '\0'; p_to->SetVariable(nameBuffer, valueBuffer); + result = SUCCESS; } } } @@ -455,7 +467,7 @@ MxS32 LegoGameState::ReadVariable(LegoStorage* p_storage, MxVariableTable* p_to) } // FUNCTION: LEGO1 0x1003a170 -void LegoGameState::GetFileSavePath(MxString* p_outPath, MxULong p_slotn) +void LegoGameState::GetFileSavePath(MxString* p_outPath, MxU8 p_slotn) { char baseForSlot[2] = "0"; char path[1024] = ""; @@ -475,10 +487,83 @@ void LegoGameState::GetFileSavePath(MxString* p_outPath, MxULong p_slotn) *p_outPath = MxString(path); } -// STUB: LEGO1 0x1003a2e0 -void LegoGameState::SerializePlayersInfo(MxS16) +// FUNCTION: LEGO1 0x1003a2e0 +void LegoGameState::SerializePlayersInfo(MxS16 p_flags) { - // TODO + LegoFile fileStream; + MxString playersGSI = MxString(m_savePath); + playersGSI += "\\"; + playersGSI += g_playersGSI; + if (fileStream.Open(playersGSI.GetData(), p_flags) == SUCCESS) { + if (fileStream.IsReadMode()) { + Read(&fileStream, &m_playerCount); + } + else if (fileStream.IsWriteMode()) { + Write(&fileStream, m_playerCount); + } + for (MxS16 i = 0; i < m_playerCount; i++) { + m_players[i].ReadWrite(&fileStream); + } + } +} + +// FUNCTION: LEGO1 0x1003a3f0 +MxResult LegoGameState::AddPlayer(Username& p_player) +{ + MxString from, to; + if (m_playerCount == 9) { + GetFileSavePath(&from, 8); + DeleteFile(from.GetData()); + m_playerCount--; + } + for (MxS16 i = m_playerCount; i > 0; i--) { + m_players[i] = m_players[i - 1]; + GetFileSavePath(&from, i - 1); + GetFileSavePath(&to, i); + MoveFile(from.GetData(), to.GetData()); + } + m_playerCount++; + m_players[0].Set(p_player); + m_unk0x24 = m_history.m_unk0x372; + m_history.m_unk0x372 = m_unk0x24 + 1; + m_history.WriteScoreHistory(); + SetCurrentAct(e_act1); + return DeleteState(); +} + +// FUNCTION: LEGO1 0x1003a540 +void LegoGameState::SwitchPlayer(MxS16 p_playerId) +{ + if (p_playerId > 0) { + MxString from, temp, to; + GetFileSavePath(&from, p_playerId); + GetFileSavePath(&temp, 36); + Username selectedName(m_players[p_playerId]); + MoveFile(from.GetData(), temp.GetData()); + for (MxS16 i = p_playerId; i > 0; i--) { + m_players[i] = m_players[i - 1]; + GetFileSavePath(&from, i - 1); + GetFileSavePath(&to, i); + MoveFile(from.GetData(), to.GetData()); + } + m_players[0] = selectedName; + GetFileSavePath(&from, 0); + MoveFile(temp.GetData(), from.GetData()); + } + if (Load(0) != SUCCESS) { + Init(); + } +} + +// FUNCTION: LEGO1 0x1003a6e0 +MxS16 LegoGameState::FindPlayer(Username& p_player) +{ + for (MxS16 i = 0; i < m_playerCount; i++) { + if (memcmp(&m_players[i], &p_player, sizeof(Username)) == 0) { + return i; + } + } + return -1; } // FUNCTION: LEGO1 0x1003a720 @@ -939,6 +1024,54 @@ void LegoGameState::RegisterState(LegoState* p_state) m_stateArray[targetIndex] = p_state; } +// FUNCTION: LEGO1 0x1003bd00 +void LegoGameState::Init() +{ + m_backgroundColor->SetValue("set 56 54 68"); + m_backgroundColor->SetLights(); + m_tempBackgroundColor->SetValue("set 56 54 68"); + VariableTable()->SetVariable("lightposition", "2"); + SetLightPosition(2); + PlantManager()->Init(); + BuildingManager()->Init(); + UnkSaveDataWriter()->InitSaveData(); + AnimationManager()->FUN_1005ee80(TRUE); + SetColors(); + RemoveActor(); + DeleteState(); + m_isDirty = FALSE; + FindLoadedAct(); + SetCurrentAct(e_act1); + if (m_loadedAct == e_act1) { + Isle* isle = (Isle*) FindWorld(*g_isleScript, 0); + Helicopter* copter = (Helicopter*) isle->Find(*g_copterScript, 1); + if (copter) { + isle->FUN_1001fc80(copter); + isle->VTable0x6c(copter); + delete copter; + } + DuneBuggy* dunebuggy = (DuneBuggy*) isle->Find(*g_dunecarScript, 2); + if (dunebuggy) { + isle->FUN_1001fc80(dunebuggy); + isle->VTable0x6c(dunebuggy); + delete dunebuggy; + } + Jetski* jetski = (Jetski*) isle->Find(*g_jetskiScript, 3); + if (jetski) { + isle->FUN_1001fc80(jetski); + isle->VTable0x6c(jetski); + delete jetski; + } + RaceCar* racecar = (RaceCar*) isle->Find(*g_racecarScript, 4); + if (racecar) { + isle->FUN_1001fc80(racecar); + isle->VTable0x6c(racecar); + delete racecar; + } + } + m_unk0x42c = e_noArea; +} + // FUNCTION: LEGO1 0x1003c670 LegoGameState::Username::Username() { @@ -964,10 +1097,10 @@ MxResult LegoGameState::Username::ReadWrite(LegoStorage* p_storage) } // FUNCTION: LEGO1 0x1003c710 -LegoGameState::Username* LegoGameState::Username::operator=(const Username* p_other) +LegoGameState::Username& LegoGameState::Username::operator=(const Username& p_other) { - memcpy(m_letters, p_other->m_letters, sizeof(m_letters)); - return this; + memcpy(m_letters, p_other.m_letters, sizeof(m_letters)); + return *this; } // FUNCTION: LEGO1 0x1003c830