From 766d6001ff50c5bd43b2c1d985a3f519a73bac3b Mon Sep 17 00:00:00 2001 From: disinvite Date: Tue, 12 Sep 2023 16:47:46 -0400 Subject: [PATCH] MxPresenter::ParseExtra and surrounding functions --- LEGO1/legoomni.cpp | 36 +++++++++++++++++++++++++++ LEGO1/legoomni.h | 1 + LEGO1/mxdsaction.h | 3 +++ LEGO1/mxomni.cpp | 49 ++++++++++++++++++++++++++++++++++++ LEGO1/mxomni.h | 8 ++++++ LEGO1/mxpresenter.cpp | 58 ++++++++++++++++++++++++++++++++++++++++--- LEGO1/mxpresenter.h | 4 ++- 7 files changed, 155 insertions(+), 4 deletions(-) diff --git a/LEGO1/legoomni.cpp b/LEGO1/legoomni.cpp index b5cbca8e..e5574058 100644 --- a/LEGO1/legoomni.cpp +++ b/LEGO1/legoomni.cpp @@ -43,6 +43,42 @@ void MakeSourceName(char *, const char *) // TODO } +// OFFSET: LEGO1 0x100b7050 +MxBool KeyValueStringParse(char *p_outputValue, char *p_key, char *p_source) +{ + MxBool didMatch = FALSE; + + MxS16 len = strlen(p_source); + char *temp = new char[len + 1]; + strcpy(temp, p_source); + + char *token = strtok(temp, ", \t\r\n:"); + while (token) { + len -= (strlen(token) + 1); + + if (strcmpi(token, p_key) == 0) { + if (p_outputValue && len > 0) { + char *cur = &token[strlen(p_key)]; + cur++; + while (*cur != ',') { + if (*cur == ' ' || *cur == '\0' || *cur == '\t' || *cur == '\n' || *cur == '\r') + break; + *p_outputValue++ = *cur++; + } + *p_outputValue = '\0'; + } + + didMatch = TRUE; + break; + } + + token = strtok(NULL, ", \t\r\n:"); + } + + delete[] temp; + return didMatch; +} + // OFFSET: LEGO1 0x100b7210 void SetOmniUserMessage(void (*p_userMsg)(const char *,int)) { diff --git a/LEGO1/legoomni.h b/LEGO1/legoomni.h index 0ba27cf2..485da46c 100644 --- a/LEGO1/legoomni.h +++ b/LEGO1/legoomni.h @@ -113,5 +113,6 @@ __declspec(dllexport) MxLong Start(MxDSAction *a); LegoBuildingManager* BuildingManager(); Isle* GetIsle(); LegoPlantManager* PlantManager(); +MxBool KeyValueStringParse(char *, char *, char *); #endif // LEGOOMNI_H diff --git a/LEGO1/mxdsaction.h b/LEGO1/mxdsaction.h index a85e6494..205ae9a0 100644 --- a/LEGO1/mxdsaction.h +++ b/LEGO1/mxdsaction.h @@ -49,6 +49,9 @@ class MxDSAction : public MxDSObject inline MxU32 GetFlags() { return this->m_flags; } inline void SetFlags(MxU32 m_flags) { this->m_flags = m_flags; } + inline char *GetUnkData() { return m_unkData; } + inline MxU16 GetUnkLength() const { return m_unkLength; } + inline void SetOmni(MxOmni *p_omni) { m_omni = p_omni; } private: MxU32 m_sizeOnDisk; diff --git a/LEGO1/mxomni.cpp b/LEGO1/mxomni.cpp index 4048a0b5..446ac4f9 100644 --- a/LEGO1/mxomni.cpp +++ b/LEGO1/mxomni.cpp @@ -42,6 +42,55 @@ void MxOmni::Init() m_unk64 = NULL; } +// OFFSET: LEGO1 0x100b0090 STUB +void MxOmni::vtable0x20() +{ + // TODO +} + +// OFFSET: LEGO1 0x100b00c0 STUB +void MxOmni::DeleteObject() +{ + // TODO +} + +// OFFSET: LEGO1 0x100b09a0 STUB +void MxOmni::DoesEntityExist() +{ + // TODO +} + +// OFFSET: LEGO1 0x100b00e0 STUB +void MxOmni::vtable0x2c() +{ + // TODO +} + +// OFFSET: LEGO1 0x100aefb0 STUB +int MxOmni::vtable0x30(char*, int, MxCore*) +{ + // TODO + return 0; +} + +// OFFSET: LEGO1 0x100aefc0 STUB +void MxOmni::NotifyCurrentEntity() +{ + // TODO +} + +// OFFSET: LEGO1 0x100b09d0 STUB +void MxOmni::StartTimer() +{ + // TODO +} + +// OFFSET: LEGO1 0x100b0a00 STUB +void MxOmni::vtable0x3c() +{ + // TODO +} + // OFFSET: LEGO1 0x100b0690 void MxOmni::DestroyInstance() { diff --git a/LEGO1/mxomni.h b/LEGO1/mxomni.h index bbaf4cb0..8cacc5fc 100644 --- a/LEGO1/mxomni.h +++ b/LEGO1/mxomni.h @@ -37,6 +37,14 @@ class MxOmni : public MxCore virtual void Init(); // vtable+14 virtual MxResult Create(MxOmniCreateParam &p); // vtable+18 virtual void Destroy(); // vtable+1c + virtual void vtable0x20(); // vtable+20 + virtual void DeleteObject(); // vtable+24 + virtual void DoesEntityExist(); // vtable+28 + virtual void vtable0x2c(); // vtable+2c + virtual int vtable0x30(char*, int, MxCore*); // vtable+30 + virtual void NotifyCurrentEntity(); // vtable+34 + virtual void StartTimer(); // vtable+38 + virtual void vtable0x3c(); // vtable+3c static void SetInstance(MxOmni* instance); HWND GetWindowHandle() const { return this->m_windowHandle; } MxObjectFactory* GetObjectFactory() const { return this->m_objectFactory; } diff --git a/LEGO1/mxpresenter.cpp b/LEGO1/mxpresenter.cpp index 5fbdb8e4..d3847ecc 100644 --- a/LEGO1/mxpresenter.cpp +++ b/LEGO1/mxpresenter.cpp @@ -1,26 +1,78 @@ #include "mxpresenter.h" #include "mxautolocker.h" +#include "mxparam.h" +#include "legoomni.h" +#include #include "decomp.h" DECOMP_SIZE_ASSERT(MxPresenter, 0x40); +// 0x10101eac +char *g_parseExtraTokens = ":;"; + +// 0x10101edc +char *g_strWORLD = "WORLD"; + // OFFSET: LEGO1 0x100b4d50 void MxPresenter::Init() { m_currentTickleState = TickleState_Idle; m_action = NULL; m_unk0x18 = 0; - m_unk0x3c = 0; + m_unkPresenter = NULL; m_previousTickleStates = 0; m_unk0x10 = 0; m_unk0x14 = 0; } -// OFFSET: LEGO1 0x100b4fc0 STUB +// OFFSET: LEGO1 0x100b4fc0 void MxPresenter::ParseExtra() { - // TODO + + MxAutoLocker lock(&m_criticalSection); + MxU32 len = m_action->GetUnkLength(); + char *unk_data = m_action->GetUnkData(); + + if (len) { + len &= MAXWORD; + char t_actionData[512]; + memcpy(t_actionData, unk_data, len); + t_actionData[len] = '\0'; + + char t_worldValue[512]; + if (KeyValueStringParse(t_worldValue, g_strWORLD, t_actionData)) { + char *token = strtok(t_worldValue, g_parseExtraTokens); + char t_token[256]; + strcpy(t_token, token); + + token = strtok(NULL, g_parseExtraTokens); + int val = token ? atoi(token) : 0; + + int result = MxOmni::GetInstance()->vtable0x30(t_token, val, this); + + // TODO: magic number for flag + m_action->SetFlags(m_action->GetFlags() | 128); + + if (result) + SendTo_unkPresenter(MxOmni::GetInstance()); + + } + } +} + +// OFFSET: LEGO1 0x100b5120 +void MxPresenter::SendTo_unkPresenter(MxOmni *p_omni) +{ + if (m_unkPresenter) { + MxAutoLocker lock(&m_criticalSection); + + // TOOD: magic number used for notification type. replace with enum + NotificationManager()->Send(m_unkPresenter, &MxParam(5, this)); + + m_action->SetOmni(p_omni ? p_omni : MxOmni::GetInstance()); + m_unkPresenter = NULL; + } } // OFFSET: LEGO1 0x1000bf00 diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index 6f50984e..4b8659ec 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -4,6 +4,7 @@ #include "mxcore.h" #include "mxdsaction.h" #include "mxcriticalsection.h" +#include "mxomni.h" #include "decomp.h" @@ -68,6 +69,7 @@ class MxPresenter : public MxCore protected: __declspec(dllexport) void Init(); + void SendTo_unkPresenter(MxOmni *); private: MxS32 m_currentTickleState; // 0x8 @@ -77,7 +79,7 @@ class MxPresenter : public MxCore undefined4 m_unk0x18; MxDSAction* m_action; // 0 MxCriticalSection m_criticalSection; - undefined4 m_unk0x3c; + MxPresenter *m_unkPresenter; // 0x3c }; #endif // MXPRESENTER_H