From c626f18b03824091d6802aeda51cdc3b2104ee53 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 14 Nov 2023 15:10:43 -0500 Subject: [PATCH 01/10] Prepare MxMidiPresenter vtable and refactoring (#278) --- LEGO1/mxaudiopresenter.cpp | 8 ++--- LEGO1/mxaudiopresenter.h | 10 +++--- LEGO1/mxbackgroundaudiomanager.cpp | 26 ++++++++-------- LEGO1/mxmidipresenter.cpp | 49 ++++++++++++++++++++++++++++-- LEGO1/mxmidipresenter.h | 12 ++++++-- LEGO1/mxmusicpresenter.h | 6 ++-- LEGO1/mxsoundmanager.cpp | 2 +- LEGO1/mxsoundpresenter.cpp | 12 ++++---- LEGO1/mxsoundpresenter.h | 3 +- 9 files changed, 91 insertions(+), 37 deletions(-) diff --git a/LEGO1/mxaudiopresenter.cpp b/LEGO1/mxaudiopresenter.cpp index bd6a5c87..fcb8c0ea 100644 --- a/LEGO1/mxaudiopresenter.cpp +++ b/LEGO1/mxaudiopresenter.cpp @@ -5,13 +5,13 @@ DECOMP_SIZE_ASSERT(MxAudioPresenter, 0x54); // OFFSET: LEGO1 0x1000d260 -undefined4 MxAudioPresenter::vtable5c() +MxU32 MxAudioPresenter::GetVolume() { - return this->m_unk50; + return m_volume; } // OFFSET: LEGO1 0x1000d270 -void MxAudioPresenter::vtable60(undefined4 p_unk50) +void MxAudioPresenter::SetVolume(MxU32 p_volume) { - this->m_unk50 = p_unk50; + m_volume = p_volume; } diff --git a/LEGO1/mxaudiopresenter.h b/LEGO1/mxaudiopresenter.h index 717c8b4d..9fc92457 100644 --- a/LEGO1/mxaudiopresenter.h +++ b/LEGO1/mxaudiopresenter.h @@ -5,9 +5,10 @@ #include "mxmediapresenter.h" // VTABLE 0x100d4c70 +// SIZE 0x54 class MxAudioPresenter : public MxMediaPresenter { public: - MxAudioPresenter() { m_unk50 = 100; } + MxAudioPresenter() { m_volume = 100; } // OFFSET: LEGO1 0x1000d280 inline virtual const char* ClassName() const override // vtable+0x0c @@ -22,10 +23,11 @@ class MxAudioPresenter : public MxMediaPresenter { return !strcmp(name, MxAudioPresenter::ClassName()) || MxMediaPresenter::IsA(name); } - virtual undefined4 vtable5c(); - virtual void vtable60(undefined4); + virtual MxU32 GetVolume(); // vtable+0x5c + virtual void SetVolume(MxU32 p_volume); // vtable+0x60 - undefined4 m_unk50; +private: + MxU32 m_volume; }; #endif // MXAUDIOPRESENTER_H diff --git a/LEGO1/mxbackgroundaudiomanager.cpp b/LEGO1/mxbackgroundaudiomanager.cpp index 26d399f7..2099cbc4 100644 --- a/LEGO1/mxbackgroundaudiomanager.cpp +++ b/LEGO1/mxbackgroundaudiomanager.cpp @@ -159,7 +159,7 @@ void MxBackgroundAudioManager::StartAction(MxParam& p) m_action2.SetAtomId(m_unk138->GetAction()->GetAtomId()); m_action2.SetObjectId(m_unk138->GetAction()->GetObjectId()); m_targetVolume = ((MxDSSound*) (m_unk138->GetAction()))->GetVolume(); - m_unk138->vtable60(0); + m_unk138->SetVolume(0); } // OFFSET: LEGO1 0x1007f200 @@ -257,15 +257,15 @@ void MxBackgroundAudioManager::FUN_1007ef40() if (m_unk148 == 0) { compare = m_unk148; } - volume = m_unk138->vtable5c(); + volume = m_unk138->GetVolume(); if (volume < compare) { - if (m_unk140 + m_unk138->vtable5c() <= compare) { + if (m_unk140 + m_unk138->GetVolume() <= compare) { compare = m_unk140 + compare; } - m_unk138->vtable60(compare); + m_unk138->SetVolume(compare); } else { - m_unk138->vtable60(compare); + m_unk138->SetVolume(compare); m_unka0 = m_unk138; m_action1 = m_action2; m_unk138 = NULL; @@ -276,16 +276,16 @@ void MxBackgroundAudioManager::FUN_1007ef40() } } else if (m_unka0->GetAction() != NULL) { - if (m_unka0->vtable5c() == 0) { + if (m_unka0->GetVolume() == 0) { DeleteObject(*m_unka0->GetAction()); } else { - compare = m_unka0->vtable5c(); + compare = m_unka0->GetVolume(); volume = 0; if (compare != m_unk140 && -1 < compare - m_unk140) { - volume = m_unka0->vtable5c() - m_unk140; + volume = m_unka0->GetVolume() - m_unk140; } - m_unk138->vtable60(volume); + m_unk138->SetVolume(volume); } } } @@ -295,7 +295,7 @@ void MxBackgroundAudioManager::FadeInOrFadeOut() { // This function probably is the fade in/out routine if (m_unka0 != NULL) { - undefined4 volume = m_unka0->vtable5c(); + undefined4 volume = m_unka0->GetVolume(); MxU32 compare = 30; if (m_unk148 == 0) { compare = m_targetVolume; @@ -306,17 +306,17 @@ void MxBackgroundAudioManager::FadeInOrFadeOut() if (compare <= volume) { volume = compare; } - m_unka0->vtable60(volume); + m_unka0->SetVolume(volume); } else if (compare < volume) { volume = volume - m_unk140; if (volume <= compare) { volume = compare; } - m_unka0->vtable60(volume); + m_unka0->SetVolume(volume); } else { - m_unka0->vtable60(volume); + m_unka0->SetVolume(volume); m_unk13c = 0; } } diff --git a/LEGO1/mxmidipresenter.cpp b/LEGO1/mxmidipresenter.cpp index 59e30fa3..37b6ea9c 100644 --- a/LEGO1/mxmidipresenter.cpp +++ b/LEGO1/mxmidipresenter.cpp @@ -6,6 +6,13 @@ DECOMP_SIZE_ASSERT(MxMIDIPresenter, 0x58); +// OFFSET: LEGO1 0x100c25a0 STUB +MxResult MxMIDIPresenter::AddToManager() +{ + // TODO + return SUCCESS; +} + // OFFSET: LEGO1 0x100c25e0 MxMIDIPresenter::MxMIDIPresenter() { @@ -30,10 +37,46 @@ void MxMIDIPresenter::Destroy(MxBool p_fromDestructor) // TODO } +// OFFSET: LEGO1 0x100c2890 STUB +void MxMIDIPresenter::ReadyTickle() +{ + // TODO +} + +// OFFSET: LEGO1 0x100c28d0 STUB +void MxMIDIPresenter::StartingTickle() +{ + // TODO +} + +// OFFSET: LEGO1 0x100c2910 STUB +void MxMIDIPresenter::StreamingTickle() +{ + // TODO +} + // OFFSET: LEGO1 0x100c2940 void MxMIDIPresenter::DoneTickle() { - if (!MusicManager()->GetMIDIInitialized()) { - this->EndAction(); - } + if (!MusicManager()->GetMIDIInitialized()) + EndAction(); +} + +// OFFSET: LEGO1 0x100c2960 STUB +void MxMIDIPresenter::Destroy() +{ + // TODO +} + +// OFFSET: LEGO1 0x100c2970 STUB +undefined4 MxMIDIPresenter::PutData() +{ + // TODO + return 0; +} + +// OFFSET: LEGO1 0x100c29e0 STUB +void MxMIDIPresenter::EndAction() +{ + // TODO } diff --git a/LEGO1/mxmidipresenter.h b/LEGO1/mxmidipresenter.h index 675f79b5..245adb34 100644 --- a/LEGO1/mxmidipresenter.h +++ b/LEGO1/mxmidipresenter.h @@ -4,6 +4,7 @@ #include "mxmusicpresenter.h" // VTABLE 0x100dca20 +// SIZE 0x58 class MxMIDIPresenter : public MxMusicPresenter { public: MxMIDIPresenter(); @@ -22,11 +23,18 @@ class MxMIDIPresenter : public MxMusicPresenter { return !strcmp(name, MxMIDIPresenter::ClassName()) || MxMusicPresenter::IsA(name); } - virtual void DoneTickle() override; // vtable+0x2c + virtual void ReadyTickle() override; // vtable+0x18 + virtual void StartingTickle() override; // vtable+0x1c + virtual void StreamingTickle() override; // vtable+0x20 + virtual void DoneTickle() override; // vtable+0x2c + virtual MxResult AddToManager() override; // vtable+0x34 + virtual void Destroy() override; // vtable+0x38 + virtual void EndAction() override; // vtable+0x40 + virtual undefined4 PutData() override; // vtable+0x4c private: void Init(); - void Destroy(MxBool); + void Destroy(MxBool p_fromDestructor); undefined4 m_unk54; }; diff --git a/LEGO1/mxmusicpresenter.h b/LEGO1/mxmusicpresenter.h index 02edf1a5..2f96d64e 100644 --- a/LEGO1/mxmusicpresenter.h +++ b/LEGO1/mxmusicpresenter.h @@ -7,6 +7,9 @@ // SIZE 0x54 class MxMusicPresenter : public MxAudioPresenter { public: + MxMusicPresenter(); + virtual ~MxMusicPresenter() override; + // OFFSET: LEGO1 0x100c23a0 inline virtual const char* ClassName() const override // vtable+0xc { @@ -20,9 +23,6 @@ class MxMusicPresenter : public MxAudioPresenter { return !strcmp(name, MxMusicPresenter::ClassName()) || MxAudioPresenter::IsA(name); } - MxMusicPresenter(); - virtual ~MxMusicPresenter() override; - virtual MxResult AddToManager() override; // vtable+0x34 virtual void Destroy() override; // vtable+0x38 diff --git a/LEGO1/mxsoundmanager.cpp b/LEGO1/mxsoundmanager.cpp index a57672d3..8e32345e 100644 --- a/LEGO1/mxsoundmanager.cpp +++ b/LEGO1/mxsoundmanager.cpp @@ -145,7 +145,7 @@ void MxSoundManager::SetVolume(MxS32 p_volume) MxPresenterListCursor cursor(m_presenters); while (cursor.Next(presenter)) - ((MxAudioPresenter*) presenter)->vtable60(((MxAudioPresenter*) presenter)->vtable5c()); + ((MxAudioPresenter*) presenter)->SetVolume(((MxAudioPresenter*) presenter)->GetVolume()); m_criticalSection.Leave(); } diff --git a/LEGO1/mxsoundpresenter.cpp b/LEGO1/mxsoundpresenter.cpp index 3935a97c..540dcbac 100644 --- a/LEGO1/mxsoundpresenter.cpp +++ b/LEGO1/mxsoundpresenter.cpp @@ -11,6 +11,12 @@ MxSoundPresenter::~MxSoundPresenter() Destroy(TRUE); } +// OFFSET: LEGO1 0x1000d490 +void MxSoundPresenter::Destroy() +{ + Destroy(FALSE); +} + // OFFSET: LEGO1 0x100b1a50 void MxSoundPresenter::Destroy(MxBool p_fromDestructor) { @@ -37,9 +43,3 @@ MxResult MxSoundPresenter::AddToManager() return ret; } - -// OFFSET: LEGO1 0x1000d490 -void MxSoundPresenter::Destroy() -{ - Destroy(FALSE); -} diff --git a/LEGO1/mxsoundpresenter.h b/LEGO1/mxsoundpresenter.h index 57997646..408dbe88 100644 --- a/LEGO1/mxsoundpresenter.h +++ b/LEGO1/mxsoundpresenter.h @@ -5,6 +5,7 @@ #include "mxomni.h" // VTABLE 0x100d4b08 +// SIZE 0x54 class MxSoundPresenter : public MxAudioPresenter { public: virtual ~MxSoundPresenter() override; @@ -26,7 +27,7 @@ class MxSoundPresenter : public MxAudioPresenter { virtual void Destroy() override; // vtable+0x38 private: - void Destroy(MxBool); + void Destroy(MxBool p_fromDestructor); }; #endif // MXSOUNDPRESENTER_H From d8bf4aebf4358523cf5f611ce63fd07bd4442be7 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 14 Nov 2023 15:25:14 -0500 Subject: [PATCH 02/10] Implement/match most of MxVideoPresenter (#280) * Bootstrap MxMediaPresenter * Implement/match MxMediaPresenter::Tickle and related * Implement AppendChunk and Enable * Implement/match most of MxVideoPresenter * Add missing offset --- LEGO1/mxdsaction.h | 34 +++---- LEGO1/mxdsmediaaction.h | 16 ++-- LEGO1/mxmediapresenter.cpp | 6 +- LEGO1/mxvideopresenter.cpp | 189 ++++++++++++++++++++++++++++++++++++- LEGO1/mxvideopresenter.h | 33 ++++--- 5 files changed, 232 insertions(+), 46 deletions(-) diff --git a/LEGO1/mxdsaction.h b/LEGO1/mxdsaction.h index e986438f..01e4af51 100644 --- a/LEGO1/mxdsaction.h +++ b/LEGO1/mxdsaction.h @@ -70,27 +70,21 @@ class MxDSAction : public MxDSObject { inline MxBool IsLooping() const { return m_flags & Flag_Looping; } inline MxBool IsBit3() const { return m_flags & Flag_Bit3; } -private: - MxU32 m_sizeOnDisk; - MxU32 m_flags; - MxLong m_startTime; - protected: - MxLong m_duration; - MxS32 m_loopCount; - -private: - MxVector3Data m_location; - MxVector3Data m_direction; - MxVector3Data m_up; - char* m_extraData; - MxU16 m_extraLength; - MxCore* m_unk84; - undefined4 m_unk88; - MxCore* m_unk8c; - -protected: - MxLong m_unkTimingField; // 0x90 + MxU32 m_sizeOnDisk; // 0x2c + MxU32 m_flags; // 0x30 + MxLong m_startTime; // 0x34 + MxLong m_duration; // 0x38 + MxS32 m_loopCount; // 0x3c + MxVector3Data m_location; // 0x40 + MxVector3Data m_direction; // 0x54 + MxVector3Data m_up; // 0x68 + char* m_extraData; // 0x7c + MxU16 m_extraLength; // 0x80 + MxCore* m_unk84; // 0x84 + undefined4 m_unk88; // 0x88 + MxCore* m_unk8c; // 0x8c + MxLong m_unkTimingField; // 0x90 }; #endif // MXDSACTION_H diff --git a/LEGO1/mxdsmediaaction.h b/LEGO1/mxdsmediaaction.h index f987e8f9..adeb049e 100644 --- a/LEGO1/mxdsmediaaction.h +++ b/LEGO1/mxdsmediaaction.h @@ -37,17 +37,17 @@ class MxDSMediaAction : public MxDSAction { inline MxLong GetSustainTime() const { return this->m_sustainTime; } private: - MxU32 m_sizeOnDisk; - char* m_mediaSrcPath; + MxU32 m_sizeOnDisk; // 0x94 + char* m_mediaSrcPath; // 0x98 struct { undefined4 m_unk00; undefined4 m_unk04; - } m_unk9c; - MxS32 m_framesPerSecond; - MxS32 m_mediaFormat; - MxS32 m_paletteManagement; - MxLong m_sustainTime; - undefined4 m_unkb4; + } m_unk9c; // 0x9c + MxS32 m_framesPerSecond; // 0xa4 + MxS32 m_mediaFormat; // 0xa8 + MxS32 m_paletteManagement; // 0xac + MxLong m_sustainTime; // 0xb0 + undefined4 m_unkb4; // 0xb4 }; #endif // MXDSMEDIAACTION_H diff --git a/LEGO1/mxmediapresenter.cpp b/LEGO1/mxmediapresenter.cpp index 919b1fa8..0a4d691a 100644 --- a/LEGO1/mxmediapresenter.cpp +++ b/LEGO1/mxmediapresenter.cpp @@ -129,7 +129,7 @@ void MxMediaPresenter::StreamingTickle() else if (m_action->GetFlags() & MxDSAction::Flag_Looping) { AppendChunk(m_currentChunk); - if (!MxPresenter::IsEnabled()) { + if (!IsEnabled()) { m_subscriber->FUN_100b8390(m_currentChunk); m_currentChunk = NULL; } @@ -141,7 +141,7 @@ void MxMediaPresenter::StreamingTickle() // OFFSET: LEGO1 0x100b5e10 void MxMediaPresenter::RepeatingTickle() { - if (MxPresenter::IsEnabled() && !m_currentChunk) { + if (IsEnabled() && !m_currentChunk) { if (m_cursor) if (!m_cursor->Next(m_currentChunk)) m_cursor->Next(m_currentChunk); @@ -173,7 +173,7 @@ void MxMediaPresenter::DoneTickle() // OFFSET: LEGO1 0x100b6030 void MxMediaPresenter::Enable(MxBool p_enable) { - if (MxPresenter::IsEnabled() != p_enable) { + if (IsEnabled() != p_enable) { MxPresenter::Enable(p_enable); if (p_enable) { diff --git a/LEGO1/mxvideopresenter.cpp b/LEGO1/mxvideopresenter.cpp index e39a92bf..25a2d850 100644 --- a/LEGO1/mxvideopresenter.cpp +++ b/LEGO1/mxvideopresenter.cpp @@ -1,12 +1,14 @@ #include "mxvideopresenter.h" +#include "mxautolocker.h" +#include "mxdsmediaaction.h" #include "mxvideomanager.h" DECOMP_SIZE_ASSERT(MxVideoPresenter, 0x64); DECOMP_SIZE_ASSERT(MxVideoPresenter::AlphaMask, 0xc); // OFFSET: LEGO1 0x1000c700 -void MxVideoPresenter::VTable0x5c(undefined4 p_unknown1) +void MxVideoPresenter::VTable0x5c(MxStreamChunk* p_chunk) { // Empty } @@ -18,7 +20,7 @@ void MxVideoPresenter::VTable0x60() } // OFFSET: LEGO1 0x1000c720 -void MxVideoPresenter::VTable0x68(undefined4 p_unknown1) +void MxVideoPresenter::VTable0x68(MxStreamChunk* p_chunk) { // Empty } @@ -232,10 +234,20 @@ void MxVideoPresenter::Destroy(MxBool p_fromDestructor) MxMediaPresenter::Destroy(FALSE); } -// OFFSET: LEGO1 0x100b28b0 STUB +// OFFSET: LEGO1 0x100b28b0 void MxVideoPresenter::VTable0x64() { - // TODO + MxStreamChunk* chunk = NextChunk(); + + if (chunk->GetFlags() & MxStreamChunk::Flag_Bit2) { + m_subscriber->FUN_100b8390(chunk); + m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState; + m_currentTickleState = TickleState_Repeating; + } + else { + VTable0x68(chunk); + m_subscriber->FUN_100b8390(chunk); + } } // OFFSET: LEGO1 0x100b2900 @@ -306,6 +318,175 @@ void MxVideoPresenter::VTable0x6c() // TODO } +// OFFSET: LEGO1 0x100b2f60 +void MxVideoPresenter::ReadyTickle() +{ + MxStreamChunk* chunk = NextChunk(); + + if (chunk) { + VTable0x5c(chunk); + m_subscriber->FUN_100b8390(chunk); + ParseExtra(); + m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState; + m_currentTickleState = TickleState_Starting; + } +} + +// OFFSET: LEGO1 0x100b2fa0 +void MxVideoPresenter::StartingTickle() +{ + MxStreamChunk* chunk = FUN_100b5650(); + + if (chunk && m_action->GetElapsedTime() >= chunk->GetTime()) { + VTable0x60(); + m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState; + m_currentTickleState = TickleState_Streaming; + } +} + +// OFFSET: LEGO1 0x100b2fe0 +void MxVideoPresenter::StreamingTickle() +{ + if (m_action->GetFlags() & MxDSAction::Flag_Bit9) { + if (!m_currentChunk) + MxMediaPresenter::StreamingTickle(); + + if (m_currentChunk) { + VTable0x68(m_currentChunk); + m_currentChunk = NULL; + } + } + else { + for (MxS16 i = 0; i < m_unk5c; i++) { + if (!m_currentChunk) { + MxMediaPresenter::StreamingTickle(); + + if (!m_currentChunk) + break; + } + + if (m_action->GetElapsedTime() < m_currentChunk->GetTime()) + break; + + VTable0x68(m_currentChunk); + m_subscriber->FUN_100b8390(m_currentChunk); + m_currentChunk = NULL; + m_flags |= Flag_Bit1; + + if (m_currentTickleState != TickleState_Streaming) + break; + } + + if (m_flags & Flag_Bit1) + m_unk5c = 5; + } +} + +// OFFSET: LEGO1 0x100b3080 +void MxVideoPresenter::RepeatingTickle() +{ + if (IsEnabled()) { + if (m_action->GetFlags() & MxDSAction::Flag_Bit9) { + if (!m_currentChunk) + MxMediaPresenter::RepeatingTickle(); + + if (m_currentChunk) { + VTable0x68(m_currentChunk); + m_currentChunk = NULL; + } + } + else { + for (MxS16 i = 0; i < m_unk5c; i++) { + if (!m_currentChunk) { + MxMediaPresenter::RepeatingTickle(); + + if (!m_currentChunk) + break; + } + + if (m_action->GetElapsedTime() % m_action->GetLoopCount() < m_currentChunk->GetTime()) + break; + + VTable0x68(m_currentChunk); + m_currentChunk = NULL; + m_flags |= Flag_Bit1; + + if (m_currentTickleState != TickleState_Repeating) + break; + } + + if (m_flags & Flag_Bit1) + m_unk5c = 5; + } + } +} + +// OFFSET: LEGO1 0x100b3130 +void MxVideoPresenter::Unk5Tickle() +{ + MxLong sustainTime = ((MxDSMediaAction*) m_action)->GetSustainTime(); + + if (sustainTime != -1) { + if (sustainTime) { + if (m_unk60 == -1) + m_unk60 = m_action->GetElapsedTime(); + + if (m_action->GetElapsedTime() >= m_unk60 + ((MxDSMediaAction*) m_action)->GetSustainTime()) { + m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState; + m_currentTickleState = TickleState_Done; + } + } + else { + m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState; + m_currentTickleState = TickleState_Done; + } + } +} + +// OFFSET: LEGO1 0x100b31a0 +MxResult MxVideoPresenter::AddToManager() +{ + MxResult result = FAILURE; + + if (MVideoManager()) { + result = SUCCESS; + MVideoManager()->AddPresenter(*this); + } + + return result; +} + +// OFFSET: LEGO1 0x100b31d0 +void MxVideoPresenter::EndAction() +{ + if (m_action) { + MxMediaPresenter::EndAction(); + MxAutoLocker lock(&m_criticalSection); + + if (m_bitmap) { + MxLong height = m_bitmap->GetBmiHeightAbs(); + MxLong width = m_bitmap->GetBmiWidth(); + MxS32 x = m_location.m_x; + MxS32 y = m_location.m_y; + + MxRect32 rect(x, y, x + width, y + height); + + MVideoManager()->InvalidateRect(rect); + } + } +} + +// OFFSET: LEGO1 0x100b3280 +undefined4 MxVideoPresenter::PutData() +{ + MxAutoLocker lock(&m_criticalSection); + + if (IsEnabled() && m_currentTickleState >= TickleState_Streaming && m_currentTickleState <= TickleState_unk5) + VTable0x6c(); + + return 0; +} + // OFFSET: LEGO1 0x100b3300 undefined MxVideoPresenter::VTable0x74() { diff --git a/LEGO1/mxvideopresenter.h b/LEGO1/mxvideopresenter.h index 14ad2d78..34406255 100644 --- a/LEGO1/mxvideopresenter.h +++ b/LEGO1/mxvideopresenter.h @@ -6,10 +6,14 @@ #include "mxmediapresenter.h" // VTABLE 0x100d4be8 +// SIZE 0x64 class MxVideoPresenter : public MxMediaPresenter { public: - MxVideoPresenter() { Init(); } + enum { + Flag_Bit1 = 0x01, + }; + MxVideoPresenter() { Init(); } virtual ~MxVideoPresenter() override; // vtable+0x0 // OFFSET: LEGO1 0x1000c820 @@ -28,13 +32,20 @@ class MxVideoPresenter : public MxMediaPresenter { void Init(); void Destroy(MxBool p_fromDestructor); - virtual void Destroy() override; // vtable+0x38 - + virtual void ReadyTickle() override; // vtable+0x18 + virtual void StartingTickle() override; // vtable+0x1c + virtual void StreamingTickle() override; // vtable+0x20 + virtual void RepeatingTickle() override; // vtable+0x24 + virtual void Unk5Tickle() override; // vtable+0x28 + virtual MxResult AddToManager() override; // vtable+0x34 + virtual void Destroy() override; // vtable+0x38 + virtual void EndAction() override; // vtable+0x40 + virtual undefined4 PutData() override; // vtable+0x4c virtual MxBool IsHit(MxS32 p_x, MxS32 p_y) override; // vtable+0x50 - virtual void VTable0x5c(undefined4 p_unknown1); // vtable+0x5c + virtual void VTable0x5c(MxStreamChunk* p_chunk); // vtable+0x5c virtual void VTable0x60(); // vtable+0x60 virtual void VTable0x64(); // vtable+0x64 - virtual void VTable0x68(undefined4 p_unknown1); // vtable+0x68 + virtual void VTable0x68(MxStreamChunk* p_chunk); // vtable+0x68 virtual void VTable0x6c(); // vtable+0x6c virtual void VTable0x70(); // vtable+0x70 virtual undefined VTable0x74(); // vtable+0x74 @@ -56,12 +67,12 @@ class MxVideoPresenter : public MxMediaPresenter { MxS32 IsHit(MxU32 p_x, MxU32 p_y); }; - MxBitmap* m_bitmap; - AlphaMask* m_alpha; - LPDIRECTDRAWSURFACE m_unk58; - undefined2 m_unk5c; - unsigned char m_flags; // 0x5e - MxLong m_unk60; + MxBitmap* m_bitmap; // 0x50 + AlphaMask* m_alpha; // 0x54 + LPDIRECTDRAWSURFACE m_unk58; // 0x58 + MxS16 m_unk5c; // 0x5c + MxU8 m_flags; // 0x5e + MxLong m_unk60; // 0x60 }; #endif // MXVIDEOPRESENTER_H From eee80250c0006a3927736aed21865f400d3828d9 Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Fri, 17 Nov 2023 15:01:27 -0500 Subject: [PATCH 03/10] LegoPalettePresenter - destroy function and destructor (#288) * LegoPalettePresenter - destroy function and destructor * Update legopalettepresenter.h --------- Co-authored-by: Christian Semmler --- LEGO1/legopalettepresenter.cpp | 26 +++++++++++++++++++++++--- LEGO1/legopalettepresenter.h | 7 +++++-- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/LEGO1/legopalettepresenter.cpp b/LEGO1/legopalettepresenter.cpp index 86b99b0a..6b3981a7 100644 --- a/LEGO1/legopalettepresenter.cpp +++ b/LEGO1/legopalettepresenter.cpp @@ -8,14 +8,34 @@ LegoPalettePresenter::LegoPalettePresenter() Init(); } -// OFFSET: LEGO1 0x1007a070 STUB +// OFFSET: LEGO1 0x1007a070 LegoPalettePresenter::~LegoPalettePresenter() { - // TODO + Destroy(TRUE); } // OFFSET: LEGO1 0x1007a0d0 void LegoPalettePresenter::Init() { - this->m_unk64 = 0; + m_palette = NULL; +} + +// OFFSET: LEGO1 0x1007a0e0 +void LegoPalettePresenter::Destroy(MxBool p_fromDestructor) +{ + m_criticalSection.Enter(); + if (m_palette) { + delete m_palette; + } + Init(); + m_criticalSection.Leave(); + if (!p_fromDestructor) { + MxVideoPresenter::Destroy(FALSE); + } +} + +// OFFSET: LEGO1 0x1007a120 +void LegoPalettePresenter::Destroy() +{ + Destroy(FALSE); } diff --git a/LEGO1/legopalettepresenter.h b/LEGO1/legopalettepresenter.h index 7688d0af..9d500e08 100644 --- a/LEGO1/legopalettepresenter.h +++ b/LEGO1/legopalettepresenter.h @@ -2,6 +2,7 @@ #define LEGOPALETTEPRESENTER_H #include "decomp.h" +#include "mxpalette.h" #include "mxvideopresenter.h" // VTABLE 0x100d9aa0 @@ -9,7 +10,7 @@ class LegoPalettePresenter : public MxVideoPresenter { public: LegoPalettePresenter(); - virtual ~LegoPalettePresenter(); // vtable+0x0 + virtual ~LegoPalettePresenter() override; // vtable+0x0 // OFFSET: LEGO1 0x10079f30 inline const char* ClassName() const override // vtable+0xc @@ -24,10 +25,12 @@ class LegoPalettePresenter : public MxVideoPresenter { return !strcmp(name, ClassName()) || MxVideoPresenter::IsA(name); } + virtual void Destroy() override; // vtable+0x38 private: void Init(); + void Destroy(MxBool p_fromDestructor); - undefined4 m_unk64; + MxPalette* m_palette; }; #endif // LEGOPALETTEPRESENTER_H From 93eb4dc82d6ba3b83aa3ec0c81eeb94f32ad9568 Mon Sep 17 00:00:00 2001 From: Nathan M Gilbert Date: Sat, 18 Nov 2023 10:08:49 -0500 Subject: [PATCH 04/10] Create (#289) * Align name of Create method with known source Fix name in Score for reccmp * Also update MxEntity::Vtable0x14 --- LEGO1/helicopter.cpp | 4 ++-- LEGO1/helicopter.h | 2 +- LEGO1/islepathactor.cpp | 4 ++-- LEGO1/islepathactor.h | 20 ++++++++++---------- LEGO1/legoentity.cpp | 2 +- LEGO1/legoentity.h | 2 +- LEGO1/mxentity.cpp | 2 +- LEGO1/mxentity.h | 4 ++-- LEGO1/score.cpp | 2 +- LEGO1/score.h | 12 ++++++------ 10 files changed, 27 insertions(+), 27 deletions(-) diff --git a/LEGO1/helicopter.cpp b/LEGO1/helicopter.cpp index 005d9b56..6e159a26 100644 --- a/LEGO1/helicopter.cpp +++ b/LEGO1/helicopter.cpp @@ -24,9 +24,9 @@ Helicopter::~Helicopter() } // OFFSET: LEGO1 0x100032c0 -MxResult Helicopter::InitFromMxDSObject(MxDSObject& p_dsObject) +MxResult Helicopter::Create(MxDSObject& p_dsObject) { - MxResult result = IslePathActor::InitFromMxDSObject(p_dsObject); + MxResult result = IslePathActor::Create(p_dsObject); LegoWorld* world = GetCurrentWorld(); SetWorld(world); if (world->IsA("Act3")) { diff --git a/LEGO1/helicopter.h b/LEGO1/helicopter.h index d9de2854..cc47b082 100644 --- a/LEGO1/helicopter.h +++ b/LEGO1/helicopter.h @@ -24,7 +24,7 @@ class Helicopter : public IslePathActor { return !strcmp(name, Helicopter::ClassName()) || IslePathActor::IsA(name); } - virtual MxResult InitFromMxDSObject(MxDSObject& p_dsObject) override; // vtable+0x18 + virtual MxResult Create(MxDSObject& p_dsObject) override; // vtable+0x18 virtual void VTable0xe4() override; // OFFSET: LEGO1 0x10003210 TEMPLATE diff --git a/LEGO1/islepathactor.cpp b/LEGO1/islepathactor.cpp index 9aca029b..21fca59a 100644 --- a/LEGO1/islepathactor.cpp +++ b/LEGO1/islepathactor.cpp @@ -44,9 +44,9 @@ IslePathActor::IslePathActor() } // OFFSET: LEGO1 0x1001a280 -MxResult IslePathActor::InitFromMxDSObject(MxDSObject& p_dsObject) +MxResult IslePathActor::Create(MxDSObject& p_dsObject) { - return MxEntity::InitFromMxDSObject(p_dsObject); + return MxEntity::Create(p_dsObject); } // OFFSET: LEGO1 0x1001a350 STUB diff --git a/LEGO1/islepathactor.h b/LEGO1/islepathactor.h index c0222047..7885fbb2 100644 --- a/LEGO1/islepathactor.h +++ b/LEGO1/islepathactor.h @@ -28,16 +28,16 @@ class IslePathActor : public LegoPathActor { // IslePathActor::`scalar deleting destructor' inline virtual ~IslePathActor() override { IslePathActor::Destroy(TRUE); } - virtual MxResult InitFromMxDSObject(MxDSObject& p_dsObject) override; // vtable+0x18 - virtual void VTable0xcc(); // vtable+0xcc - virtual void VTable0xd0(); // vtable+0xd0 - virtual void VTable0xd4(); // vtable+0xd4 - virtual void VTable0xd8(); // vtable+0xd8 - virtual void VTable0xdc(); // vtable+0xdc - virtual void VTable0xe0(); // vtable+0xe0 - virtual void VTable0xe4(); // vtable+0xe4 - virtual void VTable0xe8(MxU32 p_1, MxBool p_2, MxU8 p_3); // vtable+0xe8 - virtual void VTable0xec(); // vtable+0xec + virtual MxResult Create(MxDSObject& p_dsObject) override; // vtable+0x18 + virtual void VTable0xcc(); // vtable+0xcc + virtual void VTable0xd0(); // vtable+0xd0 + virtual void VTable0xd4(); // vtable+0xd4 + virtual void VTable0xd8(); // vtable+0xd8 + virtual void VTable0xdc(); // vtable+0xdc + virtual void VTable0xe0(); // vtable+0xe0 + virtual void VTable0xe4(); // vtable+0xe4 + virtual void VTable0xe8(MxU32 p_1, MxBool p_2, MxU8 p_3); // vtable+0xe8 + virtual void VTable0xec(); // vtable+0xec inline void SetWorld(LegoWorld* p_world) { m_pLegoWorld = p_world; } inline LegoWorld* GetWorld() { return m_pLegoWorld; } diff --git a/LEGO1/legoentity.cpp b/LEGO1/legoentity.cpp index 2a9b4b76..2ea9cee4 100644 --- a/LEGO1/legoentity.cpp +++ b/LEGO1/legoentity.cpp @@ -42,7 +42,7 @@ void LegoEntity::SetWorldTransform(MxVector3& p_loc, MxVector3& p_dir, MxVector3 } // OFFSET: LEGO1 0x100107e0 -MxResult LegoEntity::InitFromMxDSObject(MxDSObject& p_dsObject) +MxResult LegoEntity::Create(MxDSObject& p_dsObject) { m_mxEntityId = p_dsObject.GetObjectId(); m_atom = p_dsObject.GetAtomId(); diff --git a/LEGO1/legoentity.h b/LEGO1/legoentity.h index c0a16c32..7fe9c59b 100644 --- a/LEGO1/legoentity.h +++ b/LEGO1/legoentity.h @@ -32,7 +32,7 @@ class LegoEntity : public MxEntity { return !strcmp(name, LegoEntity::ClassName()) || MxEntity::IsA(name); } - virtual MxResult InitFromMxDSObject(MxDSObject& p_dsObject); // vtable+0x18 + virtual MxResult Create(MxDSObject& p_dsObject); // vtable+0x18 virtual void Destroy(MxBool p_fromDestructor); // vtable+0x1c virtual void ParseAction(char*); // vtable+0x20 virtual void SetROI(LegoROI* p_roi, MxBool p_bool1, MxBool p_bool2); // vtable+0x24 diff --git a/LEGO1/mxentity.cpp b/LEGO1/mxentity.cpp index 27067e37..524bb293 100644 --- a/LEGO1/mxentity.cpp +++ b/LEGO1/mxentity.cpp @@ -14,7 +14,7 @@ MxEntity::~MxEntity() } // OFFSET: LEGO1 0x10001070 -MxResult MxEntity::SetEntityId(MxS32 p_id, const MxAtomId& p_atom) +MxResult MxEntity::Create(MxS32 p_id, const MxAtomId& p_atom) { this->m_mxEntityId = p_id; this->m_atom = p_atom; diff --git a/LEGO1/mxentity.h b/LEGO1/mxentity.h index 4ec82f1c..aa8df045 100644 --- a/LEGO1/mxentity.h +++ b/LEGO1/mxentity.h @@ -27,8 +27,8 @@ class MxEntity : public MxCore { return !strcmp(name, MxEntity::ClassName()) || MxCore::IsA(name); } - virtual MxResult SetEntityId(MxS32 p_id, const MxAtomId& p_atom); // vtable+0x14 - inline MxResult InitFromMxDSObject(MxDSObject& p_dsObject) + virtual MxResult Create(MxS32 p_id, const MxAtomId& p_atom); // vtable+0x14 + inline MxResult Create(MxDSObject& p_dsObject) { m_mxEntityId = p_dsObject.GetObjectId(); m_atom = p_dsObject.GetAtomId(); diff --git a/LEGO1/score.cpp b/LEGO1/score.cpp index 1c122482..2b7f2d95 100644 --- a/LEGO1/score.cpp +++ b/LEGO1/score.cpp @@ -74,7 +74,7 @@ MxBool Score::VTable0x5c() } // OFFSET: LEGO1 0x100012a0 -MxResult Score::InitFromMxDSObject(MxDSObject& p_dsObject) +MxResult Score::Create(MxDSObject& p_dsObject) { MxResult result = SetAsCurrentWorld(p_dsObject); diff --git a/LEGO1/score.h b/LEGO1/score.h index 612bba4c..756ba089 100644 --- a/LEGO1/score.h +++ b/LEGO1/score.h @@ -29,13 +29,13 @@ class Score : public LegoWorld { } // OFFSET: LEGO1 0x100011e0 TEMPLATE - // Helicopter::`scalar deleting destructor' + // Score::`scalar deleting destructor' - virtual MxResult InitFromMxDSObject(MxDSObject& p_dsObject) override; // vtable+18 - virtual void Stop() override; // vtable+50 - virtual MxBool VTable0x5c() override; // vtable+5c - virtual MxBool VTable0x64() override; // vtable+64 - virtual void VTable0x68(MxBool p_add) override; // vtable+68 + virtual MxResult Create(MxDSObject& p_dsObject) override; // vtable+18 + virtual void Stop() override; // vtable+50 + virtual MxBool VTable0x5c() override; // vtable+5c + virtual MxBool VTable0x64() override; // vtable+64 + virtual void VTable0x68(MxBool p_add) override; // vtable+68 void Paint(); MxLong FUN_10001510(MxEndActionNotificationParam& p); From 0bb3ea6a0304e6c31f9ea62ba0ccddb3cf6d8c30 Mon Sep 17 00:00:00 2001 From: MS Date: Sun, 19 Nov 2023 07:23:30 -0500 Subject: [PATCH 05/10] MxList refactor (#290) * MxList refactor * Reorder LegoPathControllerList::Destroy * MxPtrList custom destructor and more offsets Co-authored-by: Christian Semmler * Fix member offset comments in collection classes * Fix template annotations --------- Co-authored-by: Christian Semmler --- CMakeLists.txt | 1 + LEGO1/legoinputmanager.cpp | 25 ++++++++++++++ LEGO1/legoinputmanager.h | 43 ++++++----------------- LEGO1/legopathcontrollerlist.cpp | 42 +++++++++++++++++++++++ LEGO1/legopathcontrollerlist.h | 26 ++++++++++++++ LEGO1/legoworld.h | 11 ++++-- LEGO1/mxcollection.h | 4 +-- LEGO1/mxdsactionlist.cpp | 15 ++++++++ LEGO1/mxdsactionlist.h | 17 ++++----- LEGO1/mxhashtable.h | 22 ++++++------ LEGO1/mxlist.h | 33 ++++++------------ LEGO1/mxpresenterlist.cpp | 24 +++++++++++++ LEGO1/mxpresenterlist.h | 24 +++++-------- LEGO1/mxregion.h | 2 +- LEGO1/mxregionlist.cpp | 49 ++++++++++++++++++++++++-- LEGO1/mxregionlist.h | 59 ++++++++++++++------------------ LEGO1/mxstreamchunklist.cpp | 15 ++++++++ LEGO1/mxstreamchunklist.h | 20 ++++------- LEGO1/mxstringlist.cpp | 21 ++++++++++++ LEGO1/mxstringlist.h | 21 ------------ LEGO1/mxvariabletable.h | 4 +-- 21 files changed, 308 insertions(+), 170 deletions(-) create mode 100644 LEGO1/legopathcontrollerlist.cpp create mode 100644 LEGO1/legopathcontrollerlist.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a297f7f4..d5bc8ae3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,6 +83,7 @@ add_library(lego1 SHARED LEGO1/legopartpresenter.cpp LEGO1/legopathactor.cpp LEGO1/legopathcontroller.cpp + LEGO1/legopathcontrollerlist.cpp LEGO1/legopathpresenter.cpp LEGO1/legophonemepresenter.cpp LEGO1/legoplantmanager.cpp diff --git a/LEGO1/legoinputmanager.cpp b/LEGO1/legoinputmanager.cpp index e9a82cc6..fb0fc079 100644 --- a/LEGO1/legoinputmanager.cpp +++ b/LEGO1/legoinputmanager.cpp @@ -5,6 +5,7 @@ #include "mxautolocker.h" DECOMP_SIZE_ASSERT(LegoInputManager, 0x338); +DECOMP_SIZE_ASSERT(LegoEventQueue, 0x18); // OFFSET: LEGO1 0x1005b790 LegoInputManager::LegoInputManager() @@ -55,6 +56,27 @@ MxResult LegoInputManager::Create(HWND p_hwnd) return SUCCESS; } +// OFFSET: LEGO1 0x1005bb80 TEMPLATE +// MxCollection::Compare + +// OFFSET: LEGO1 0x1005bc30 TEMPLATE +// MxCollection::Destroy + +// OFFSET: LEGO1 0x1005bc80 TEMPLATE +// MxList::~MxList + +// OFFSET: LEGO1 0x1005bd50 TEMPLATE +// MxCollection::`scalar deleting destructor' + +// OFFSET: LEGO1 0x1005bdc0 TEMPLATE +// MxList::`scalar deleting destructor' + +// OFFSET: LEGO1 0x1005beb0 TEMPLATE +// LegoEventQueue::`scalar deleting destructor' + +// OFFSET: LEGO1 0x1005bf70 TEMPLATE +// MxQueue::`scalar deleting destructor' + // OFFSET: LEGO1 0x1005bfe0 void LegoInputManager::Destroy() { @@ -270,3 +292,6 @@ void LegoInputManager::KillTimer() ::KillTimer(omni->GetWindowHandle(), m_timer); } } + +// OFFSET: LEGO1 0x1005d010 TEMPLATE +// MxListEntry::GetValue diff --git a/LEGO1/legoinputmanager.h b/LEGO1/legoinputmanager.h index c583a64a..542bd02d 100644 --- a/LEGO1/legoinputmanager.h +++ b/LEGO1/legoinputmanager.h @@ -12,7 +12,17 @@ class LegoControlManager; +// VTABLE 0x100d87b8 TEMPLATE +// class MxCollection + +// VTABLE 0x100d87d0 TEMPLATE +// class MxList + +// VTABLE 0x100d87e8 TEMPLATE +// class MxQueue + // VTABLE 0x100d8800 +// SIZE 0x18 class LegoEventQueue : public MxQueue {}; // VTABLE 0x100d8760 @@ -80,37 +90,4 @@ class LegoInputManager : public MxPresenter { MxBool m_unk0x336; }; -// OFFSET: LEGO1 0x1005bb80 TEMPLATE -// MxListParent::Compare - -// OFFSET: LEGO1 0x1005bc30 TEMPLATE -// MxListParent::Destroy - -// OFFSET: LEGO1 0x1005bc80 TEMPLATE -// MxList::~MxList - -// OFFSET: LEGO1 0x1005bd50 TEMPLATE -// MxListParent::`scalar deleting destructor' - -// OFFSET: LEGO1 0x1005bdc0 TEMPLATE -// MxList::`scalar deleting destructor' - -// OFFSET: LEGO1 0x1005beb0 TEMPLATE -// LegoEventQueue::`scalar deleting destructor' - -// OFFSET: LEGO1 0x1005bf70 TEMPLATE -// MxQueue::`scalar deleting destructor' - -// OFFSET: LEGO1 0x1005d010 TEMPLATE -// MxListEntry::GetValue - -// VTABLE 0x100d87e8 TEMPLATE -// class MxQueue - -// VTABLE 0x100d87d0 TEMPLATE -// class MxList - -// VTABLE 0x100d87b8 TEMPLATE -// class MxListParent - #endif // LEGOINPUTMANAGER_H diff --git a/LEGO1/legopathcontrollerlist.cpp b/LEGO1/legopathcontrollerlist.cpp new file mode 100644 index 00000000..762217c0 --- /dev/null +++ b/LEGO1/legopathcontrollerlist.cpp @@ -0,0 +1,42 @@ +#include "legopathcontrollerlist.h" + +#include "decomp.h" +#include "legopathcontroller.h" + +DECOMP_SIZE_ASSERT(LegoPathControllerList, 0x18); + +// OFFSET: LEGO1 0x1001d210 +MxS8 LegoPathControllerList::Compare(LegoPathController* p_a, LegoPathController* p_b) +{ + return p_a == p_b ? 0 : p_a < p_b ? -1 : 1; +} + +// OFFSET: LEGO1 0x1001d230 TEMPLATE +// MxCollection::Compare + +// OFFSET: LEGO1 0x1001d240 TEMPLATE +// MxList::MxList + +// OFFSET: LEGO1 0x1001d2d0 TEMPLATE +// MxCollection::~MxCollection + +// OFFSET: LEGO1 0x1001d320 TEMPLATE +// MxCollection::Destroy + +// OFFSET: LEGO1 0x1001d330 TEMPLATE +// MxList::~MxList + +// OFFSET: LEGO1 0x1001d3c0 +void LegoPathControllerList::Destroy(LegoPathController* p_controller) +{ + delete p_controller; +} + +// OFFSET: LEGO1 0x1001d490 TEMPLATE +// MxCollection::`scalar deleting destructor' + +// OFFSET: LEGO1 0x1001d500 TEMPLATE +// MxList::`scalar deleting destructor' + +// OFFSET: LEGO1 0x1001d5b0 TEMPLATE +// MxPtrList::`scalar deleting destructor' diff --git a/LEGO1/legopathcontrollerlist.h b/LEGO1/legopathcontrollerlist.h new file mode 100644 index 00000000..f69472d6 --- /dev/null +++ b/LEGO1/legopathcontrollerlist.h @@ -0,0 +1,26 @@ +#ifndef LEGOPATHCONTROLLERLIST_H +#define LEGOPATHCONTROLLERLIST_H + +#include "legopathcontroller.h" +#include "mxlist.h" +#include "mxtypes.h" + +// VTABLE 0x100d6320 TEMPLATE +// class MxPtrList + +// VTABLE 0x100d6338 +// SIZE 0x18 +class LegoPathControllerList : public MxPtrList { +public: + LegoPathControllerList() : MxPtrList(Destroy) {} + virtual MxS8 Compare(LegoPathController*, LegoPathController*) override; // vtable+0x14 + static void Destroy(LegoPathController*); +}; + +// VTABLE 0x100d6380 TEMPLATE +// class MxCollection + +// VTABLE 0x100d6398 TEMPLATE +// class MxList + +#endif // LEGOPATHCONTROLLERLIST_H diff --git a/LEGO1/legoworld.h b/LEGO1/legoworld.h index b2ad8793..7f46ff58 100644 --- a/LEGO1/legoworld.h +++ b/LEGO1/legoworld.h @@ -3,7 +3,9 @@ #include "legocameracontroller.h" #include "legoentity.h" +#include "legopathcontrollerlist.h" #include "mxpresenter.h" +#include "mxpresenterlist.h" // VTABLE 0x100d6280 // SIZE 0xf8 @@ -39,9 +41,12 @@ class LegoWorld : public LegoEntity { void EndAction(MxPresenter* p_presenter); protected: - undefined m_unk68[0x30]; - LegoCameraController* m_camera; - undefined m_unk9c[0x5a]; + LegoPathControllerList m_list0x68; // 0x68 + MxPresenterList m_list0x80; // 0x80 + LegoCameraController* m_camera; // 0x98 + undefined m_unk9c[0x1c]; + MxPresenterList m_list0xb8; // 0xb8 + undefined m_unkd0[0x26]; undefined m_unkf6; undefined m_unkf7; }; diff --git a/LEGO1/mxcollection.h b/LEGO1/mxcollection.h index 0f32a064..903ba8bd 100644 --- a/LEGO1/mxcollection.h +++ b/LEGO1/mxcollection.h @@ -18,8 +18,8 @@ class MxCollection : public MxCore { virtual MxS8 Compare(T, T) { return 0; } protected: - MxU32 m_count; // +0x8 - void (*m_customDestructor)(T); // +0xc + MxU32 m_count; // 0x8 + void (*m_customDestructor)(T); // 0xc }; #endif // MXCOLLECTION_H diff --git a/LEGO1/mxdsactionlist.cpp b/LEGO1/mxdsactionlist.cpp index 2959ffcd..123a38eb 100644 --- a/LEGO1/mxdsactionlist.cpp +++ b/LEGO1/mxdsactionlist.cpp @@ -17,3 +17,18 @@ void MxDSActionList::Destroy(MxDSAction* p_action) if (p_action) delete p_action; } + +// OFFSET: LEGO1 0x100c9cc0 TEMPLATE +// MxCollection::Compare + +// OFFSET: LEGO1 0x100c9d20 TEMPLATE +// MxCollection::Destroy + +// OFFSET: LEGO1 0x100c9d30 TEMPLATE +// MxList::~MxList + +// OFFSET: LEGO1 0x100c9e30 TEMPLATE +// MxCollection::`scalar deleting destructor' + +// OFFSET: LEGO1 0x100c9ea0 TEMPLATE +// MxList::`scalar deleting destructor' diff --git a/LEGO1/mxdsactionlist.h b/LEGO1/mxdsactionlist.h index d3bafbbb..b6ca0c11 100644 --- a/LEGO1/mxdsactionlist.h +++ b/LEGO1/mxdsactionlist.h @@ -6,13 +6,19 @@ class MxDSAction; +// VTABLE 0x100dcea8 TEMPLATE +// class MxCollection + +// VTABLE 0x100dcec0 TEMPLATE +// class MxList + // VTABLE 0x100dced8 // SIZE 0x1c class MxDSActionList : public MxList { public: MxDSActionList() { this->m_unk18 = 0; } - virtual MxS8 Compare(MxDSAction*, MxDSAction*) override; // +0x14 + virtual MxS8 Compare(MxDSAction*, MxDSAction*) override; // vtable+0x14 static void Destroy(MxDSAction* p_action); @@ -22,13 +28,4 @@ class MxDSActionList : public MxList { typedef MxListCursorChild MxDSActionListCursor; -// OFFSET: LEGO1 0x100c9cc0 TEMPLATE -// MxListParent::Compare - -// OFFSET: LEGO1 0x100c9d20 TEMPLATE -// MxListParent::Destroy - -// OFFSET: LEGO1 0x100c9d30 TEMPLATE -// MxList::~MxList - #endif // MXDSACTIONLIST_H diff --git a/LEGO1/mxhashtable.h b/LEGO1/mxhashtable.h index a276cfd8..b09bf28c 100644 --- a/LEGO1/mxhashtable.h +++ b/LEGO1/mxhashtable.h @@ -59,16 +59,16 @@ class MxHashTable : protected MxCollection { protected: void _NodeInsert(MxHashTableNode*); - MxHashTableNode** m_slots; // +0x10 - MxU32 m_numSlots; // +0x14 - MxU32 m_autoResizeRatio; // +0x18 - HashTableOpt m_resizeOption; // +0x1c + MxHashTableNode** m_slots; // 0x10 + MxU32 m_numSlots; // 0x14 + MxU32 m_autoResizeRatio; // 0x18 + HashTableOpt m_resizeOption; // 0x1c // FIXME: or FIXME? This qword is used as an integer or double depending // on the value of m_resizeOption. Hard to say whether this is how the devs // did it, but a simple cast in either direction doesn't match. union { - MxU32 m_increaseAmount; // +0x20 - double m_increaseFactor; // +0x20 + MxU32 m_increaseAmount; // 0x20 + double m_increaseFactor; // 0x20 }; }; @@ -156,13 +156,13 @@ void MxHashTable::DeleteAll() while (t) { MxHashTableNode* next = t->m_next; - m_customDestructor(t->m_obj); + this->m_customDestructor(t->m_obj); delete t; t = next; } } - m_count = 0; + this->m_count = 0; memset(m_slots, 0, sizeof(MxHashTableNode*) * m_numSlots); delete[] m_slots; @@ -188,7 +188,7 @@ inline void MxHashTable::Resize() MxHashTableNode** new_table = new MxHashTableNode*[m_numSlots]; m_slots = new_table; memset(m_slots, 0, sizeof(MxHashTableNode*) * m_numSlots); - m_count = 0; + this->m_count = 0; for (MxS32 i = 0; i != old_size; i++) { MxHashTableNode* t = old_table[i]; @@ -214,13 +214,13 @@ inline void MxHashTable::_NodeInsert(MxHashTableNode* p_node) m_slots[bucket]->m_prev = p_node; m_slots[bucket] = p_node; - m_count++; + this->m_count++; } template inline void MxHashTable::Add(T p_newobj) { - if (m_resizeOption && ((m_count + 1) / m_numSlots) > m_autoResizeRatio) + if (m_resizeOption && ((this->m_count + 1) / m_numSlots) > m_autoResizeRatio) MxHashTable::Resize(); MxU32 hash = Hash(p_newobj); diff --git a/LEGO1/mxlist.h b/LEGO1/mxlist.h index 11f0e8ba..d44d6c8f 100644 --- a/LEGO1/mxlist.h +++ b/LEGO1/mxlist.h @@ -1,6 +1,7 @@ #ifndef MXLIST_H #define MXLIST_H +#include "mxcollection.h" #include "mxcore.h" #include "mxtypes.h" @@ -9,6 +10,12 @@ class MxList; template class MxListCursor; +template +class MxPtrList : public MxList { +public: + MxPtrList(void (*p_destroy)(T*) = Destroy) { m_customDestructor = p_destroy; } +}; + template class MxListEntry { public: @@ -40,29 +47,9 @@ class MxListEntry { MxListEntry* m_next; }; -// SIZE 0x10 -template -class MxListParent : public MxCore { -public: - MxListParent() - { - m_count = 0; - m_customDestructor = Destroy; - } - - virtual ~MxListParent() {} - virtual MxS8 Compare(T, T) { return 0; }; - - static void Destroy(T){}; - -protected: - MxU32 m_count; // +0x8 - void (*m_customDestructor)(T); // +0xc -}; - // SIZE 0x18 template -class MxList : protected MxListParent { +class MxList : protected MxCollection { public: MxList() { @@ -80,8 +67,8 @@ class MxList : protected MxListParent { friend class MxListCursor; protected: - MxListEntry* m_first; // +0x10 - MxListEntry* m_last; // +0x14 + MxListEntry* m_first; // 0x10 + MxListEntry* m_last; // 0x14 void _DeleteEntry(MxListEntry* match); MxListEntry* _InsertEntry(T, MxListEntry*, MxListEntry*); diff --git a/LEGO1/mxpresenterlist.cpp b/LEGO1/mxpresenterlist.cpp index f6ed6594..da625f24 100644 --- a/LEGO1/mxpresenterlist.cpp +++ b/LEGO1/mxpresenterlist.cpp @@ -10,3 +10,27 @@ MxS8 MxPresenterList::Compare(MxPresenter* p_a, MxPresenter* p_b) { return p_a == p_b ? 0 : p_a < p_b ? -1 : 1; } + +// OFFSET: LEGO1 0x1001cd20 TEMPLATE +// MxCollection::Compare + +// OFFSET: LEGO1 0x1001cd30 TEMPLATE +// MxCollection::Destroy + +// OFFSET: LEGO1 0x1001cd40 TEMPLATE +// MxList::MxList + +// OFFSET: LEGO1 0x1001cdd0 TEMPLATE +// MxCollection::~MxCollection + +// OFFSET: LEGO1 0x1001ce20 TEMPLATE +// MxList::~MxList + +// OFFSET: LEGO1 0x1001cf70 TEMPLATE +// MxCollection::`scalar deleting destructor' + +// OFFSET: LEGO1 0x1001cfe0 TEMPLATE +// MxList::`scalar deleting destructor' + +// OFFSET: LEGO1 0x1001d090 TEMPLATE +// MxPtrList::`scalar deleting destructor' diff --git a/LEGO1/mxpresenterlist.h b/LEGO1/mxpresenterlist.h index 350d6c17..b8c95950 100644 --- a/LEGO1/mxpresenterlist.h +++ b/LEGO1/mxpresenterlist.h @@ -5,30 +5,22 @@ class MxPresenter; -// Unclear what the purpose of this class is -// VTABLE 0x100d62f0 -// SIZE 0x18 -class MxPresenterListParent : public MxList { -public: - MxPresenterListParent() { m_customDestructor = Destroy; } -}; +// VTABLE 0x100d62f0 TEMPLATE +// class MxPtrList // VTABLE 0x100d6308 // SIZE 0x18 -class MxPresenterList : public MxPresenterListParent { +class MxPresenterList : public MxPtrList { public: - virtual MxS8 Compare(MxPresenter*, MxPresenter*) override; // +0x14 + virtual MxS8 Compare(MxPresenter*, MxPresenter*) override; // vtable+0x14 }; typedef MxListCursorChildChild MxPresenterListCursor; -// OFFSET: LEGO1 0x1001cd20 TEMPLATE -// MxListParent::Compare +// VTABLE 0x100d6350 TEMPLATE +// class MxCollection -// OFFSET: LEGO1 0x1001cd30 TEMPLATE -// MxListParent::Destroy - -// OFFSET: LEGO1 0x1001ce20 TEMPLATE -// MxList::~MxList +// VTABLE 0x100d6368 TEMPLATE +// class MxList #endif // MXPRESENTERLIST_H diff --git a/LEGO1/mxregion.h b/LEGO1/mxregion.h index ac6acd5e..a0fa7475 100644 --- a/LEGO1/mxregion.h +++ b/LEGO1/mxregion.h @@ -21,7 +21,7 @@ struct MxRegionTopBottom { inline void SetTop(MxS32 p_top) { m_top = p_top; } inline void SetBottom(MxS32 p_bottom) { m_bottom = p_bottom; } - friend class MxRegionListParent; + friend class MxRegionList; private: MxS32 m_top; diff --git a/LEGO1/mxregionlist.cpp b/LEGO1/mxregionlist.cpp index a33d78b7..74e5739a 100644 --- a/LEGO1/mxregionlist.cpp +++ b/LEGO1/mxregionlist.cpp @@ -3,7 +3,7 @@ #include "mxregion.h" // OFFSET: LEGO1 0x100c33e0 -void MxRegionListParent::Destroy(MxRegionTopBottom* p_topBottom) +void MxRegionList::Destroy(MxRegionTopBottom* p_topBottom) { if (p_topBottom) { if (p_topBottom->m_leftRightList) @@ -13,7 +13,52 @@ void MxRegionListParent::Destroy(MxRegionTopBottom* p_topBottom) } // OFFSET: LEGO1 0x100c4e80 -void MxRegionLeftRightListParent::Destroy(MxRegionLeftRight* p_leftRight) +void MxRegionLeftRightList::Destroy(MxRegionLeftRight* p_leftRight) { delete p_leftRight; } + +// OFFSET: LEGO1 0x100c32e0 TEMPLATE +// MxCollection::Compare + +// OFFSET: LEGO1 0x100c3340 TEMPLATE +// MxCollection::Destroy + +// OFFSET: LEGO1 0x100c34d0 TEMPLATE +// MxCollection::`scalar deleting destructor' + +// OFFSET: LEGO1 0x100c3540 TEMPLATE +// MxList::`scalar deleting destructor' + +// OFFSET: LEGO1 0x100c35f0 TEMPLATE +// MxPtrList::`scalar deleting destructor' + +// OFFSET: LEGO1 0x100c4d80 TEMPLATE +// MxCollection::Compare + +// OFFSET: LEGO1 0x100c4de0 TEMPLATE +// MxCollection::Destroy + +// OFFSET: LEGO1 0x100c4f50 TEMPLATE +// MxCollection::`scalar deleting destructor' + +// OFFSET: LEGO1 0x100c4fc0 TEMPLATE +// MxList::`scalar deleting destructor' + +// OFFSET: LEGO1 0x100c5070 TEMPLATE +// MxPtrList::`scalar deleting destructor' + +// OFFSET: LEGO1 0x100c54f0 TEMPLATE +// MxListCursor::MxListCursor + +// OFFSET: LEGO1 0x100c58c0 TEMPLATE +// MxList::_InsertEntry + +// OFFSET: LEGO1 0x100c5970 TEMPLATE +// MxList::_InsertEntry + +// OFFSET: LEGO1 0x100c5a20 TEMPLATE +// MxListEntry::MxListEntry + +// OFFSET: LEGO1 0x100c5a40 TEMPLATE +// MxList::_DeleteEntry diff --git a/LEGO1/mxregionlist.h b/LEGO1/mxregionlist.h index 52336d38..c3a5d2ef 100644 --- a/LEGO1/mxregionlist.h +++ b/LEGO1/mxregionlist.h @@ -6,51 +6,44 @@ struct MxRegionTopBottom; struct MxRegionLeftRight; -// VTABLE 0x100dcb40 -// SIZE 0x18 -class MxRegionListParent : public MxList { -public: - static void Destroy(MxRegionTopBottom* p_topBottom); +// VTABLE 0x100dcb10 TEMPLATE +// class MxCollection - MxRegionListParent() { m_customDestructor = Destroy; } -}; +// VTABLE 0x100dcb28 TEMPLATE +// class MxList + +// VTABLE 0x100dcb40 TEMPLATE +// class MxPtrList // VTABLE 0x100dcb58 // SIZE 0x18 -class MxRegionList : public MxRegionListParent {}; +class MxRegionList : public MxPtrList { +public: + MxRegionList() : MxPtrList(Destroy) {} + static void Destroy(MxRegionTopBottom*); +}; // VTABLE 0x100dcb88 typedef MxListCursorChildChild MxRegionListCursor; -// OFFSET: LEGO1 0x100c5970 TEMPLATE -// MxList::_InsertEntry - -// OFFSET: LEGO1 0x100c5a20 TEMPLATE -// MxListEntry::MxListEntry - -// VTABLE 0x100dcc70 -// SIZE 0x18 -class MxRegionLeftRightListParent : public MxList { -public: - static void Destroy(MxRegionLeftRight* p_leftRight); - - MxRegionLeftRightListParent() { m_customDestructor = Destroy; } -}; - -// VTABLE 0x100dcc88 -// SIZE 0x18 -class MxRegionLeftRightList : public MxRegionLeftRightListParent {}; - // VTABLE 0x100dcc10 typedef MxListCursorChildChild MxRegionLeftRightListCursor; -// OFFSET: LEGO1 0x100c54f0 TEMPLATE -// MxListCursor::MxListCursor +// VTABLE 0x100dcc40 TEMPLATE +// class MxCollection -// OFFSET: LEGO1 0x100c58c0 TEMPLATE -// MxList::_InsertEntry +// VTABLE 0x100dcc58 TEMPLATE +// class MxList -// OFFSET: LEGO1 0x100c5a40 TEMPLATE -// MxList::_DeleteEntry +// VTABLE 0x100dcc70 TEMPLATE +// class MxPtrList + +// VTABLE 0x100dcc88 +// SIZE 0x18 +class MxRegionLeftRightList : public MxPtrList { +public: + MxRegionLeftRightList() : MxPtrList(Destroy) {} + static void Destroy(MxRegionLeftRight*); +}; #endif // MXREGIONLIST_H diff --git a/LEGO1/mxstreamchunklist.cpp b/LEGO1/mxstreamchunklist.cpp index 8c76452e..46a610ad 100644 --- a/LEGO1/mxstreamchunklist.cpp +++ b/LEGO1/mxstreamchunklist.cpp @@ -17,3 +17,18 @@ void MxStreamChunkList::Destroy(MxStreamChunk* p_chunk) if (p_chunk) delete p_chunk; } + +// OFFSET: LEGO1 0x100b5930 TEMPLATE +// MxCollection::Compare + +// OFFSET: LEGO1 0x100b5990 TEMPLATE +// MxCollection::Destroy + +// OFFSET: LEGO1 0x100b59a0 TEMPLATE +// MxList::~MxList + +// OFFSET: LEGO1 0x100b5aa0 TEMPLATE +// MxCollection::`scalar deleting destructor' + +// OFFSET: LEGO1 0x100b5b10 TEMPLATE +// MxList::`scalar deleting destructor' diff --git a/LEGO1/mxstreamchunklist.h b/LEGO1/mxstreamchunklist.h index 3a19950b..9a84e572 100644 --- a/LEGO1/mxstreamchunklist.h +++ b/LEGO1/mxstreamchunklist.h @@ -6,29 +6,23 @@ class MxStreamChunk; +// VTABLE 0x100dc5d0 TEMPLATE +// class MxCollection + +// VTABLE 0x100dc5e8 TEMPLATE +// class MxList + // VTABLE 0x100dc600 // SIZE 0x18 class MxStreamChunkList : public MxList { public: MxStreamChunkList() { m_customDestructor = Destroy; } - virtual MxS8 Compare(MxStreamChunk*, MxStreamChunk*) override; // +0x14 + virtual MxS8 Compare(MxStreamChunk*, MxStreamChunk*) override; // vtable+0x14 static void Destroy(MxStreamChunk* p_chunk); }; typedef MxListCursorChild MxStreamChunkListCursor; -// OFFSET: LEGO1 0x100b5930 TEMPLATE -// MxListParent::Compare - -// OFFSET: LEGO1 0x100b5990 TEMPLATE -// MxListParent::Destroy - -// OFFSET: LEGO1 0x100b59a0 TEMPLATE -// MxList::~MxList - -// OFFSET: LEGO1 0x100b5b10 TEMPLATE -// MxList::`scalar deleting destructor' - #endif // MXSTREAMCHUNKLIST_H diff --git a/LEGO1/mxstringlist.cpp b/LEGO1/mxstringlist.cpp index 8a0a2ddc..9279e8cf 100644 --- a/LEGO1/mxstringlist.cpp +++ b/LEGO1/mxstringlist.cpp @@ -3,3 +3,24 @@ #include "decomp.h" DECOMP_SIZE_ASSERT(MxListEntry, 0x18) + +// OFFSET: LEGO1 0x100cb3c0 TEMPLATE +// MxCollection::Compare + +// OFFSET: LEGO1 0x100cb470 TEMPLATE +// MxCollection::Destroy + +// OFFSET: LEGO1 0x100cb4c0 TEMPLATE +// MxList::~MxList + +// OFFSET: LEGO1 0x100cbb40 TEMPLATE +// MxList::Append + +// OFFSET: LEGO1 0x100cc2d0 TEMPLATE +// MxList::_InsertEntry + +// OFFSET: LEGO1 0x100cc3c0 TEMPLATE +// MxListEntry::MxListEntry + +// OFFSET: LEGO1 0x100cc450 TEMPLATE +// MxListEntry::GetValue diff --git a/LEGO1/mxstringlist.h b/LEGO1/mxstringlist.h index d80c4777..f397fbf7 100644 --- a/LEGO1/mxstringlist.h +++ b/LEGO1/mxstringlist.h @@ -11,25 +11,4 @@ class MxStringList : public MxList {}; // VTABLE 0x100dd058 typedef MxListCursorChild MxStringListCursor; -// OFFSET: LEGO1 0x100cb3c0 TEMPLATE -// MxListParent::Compare - -// OFFSET: LEGO1 0x100cb470 TEMPLATE -// MxListParent::Destroy - -// OFFSET: LEGO1 0x100cb4c0 TEMPLATE -// MxList::~MxList - -// OFFSET: LEGO1 0x100cbb40 TEMPLATE -// MxList::Append - -// OFFSET: LEGO1 0x100cc2d0 TEMPLATE -// MxList::_InsertEntry - -// OFFSET: LEGO1 0x100cc3c0 TEMPLATE -// MxListEntry::MxListEntry - -// OFFSET: LEGO1 0x100cc450 TEMPLATE -// MxListEntry::GetValue - #endif // MXSTRINGLIST_H diff --git a/LEGO1/mxvariabletable.h b/LEGO1/mxvariabletable.h index 872aa49f..1df02204 100644 --- a/LEGO1/mxvariabletable.h +++ b/LEGO1/mxvariabletable.h @@ -17,8 +17,8 @@ class MxVariableTable : public MxHashTable { // OFFSET: LEGO1 0x100afdb0 static void Destroy(MxVariable* p_obj) { p_obj->Destroy(); } - virtual MxS8 Compare(MxVariable*, MxVariable*) override; // +0x14 - virtual MxU32 Hash(MxVariable*) override; // +0x18 + virtual MxS8 Compare(MxVariable*, MxVariable*) override; // vtable+0x14 + virtual MxU32 Hash(MxVariable*) override; // vtable+0x18 }; // OFFSET: LEGO1 0x100afcd0 TEMPLATE From 0b0a9a6d6fba71a1ee169b8443a8fd5192febccb Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Sun, 19 Nov 2023 07:28:06 -0500 Subject: [PATCH 06/10] MxFlcPresenter: vtable70 (#291) * MxFlcPresenter: vtable70 * Fix function --------- Co-authored-by: Christian Semmler --- LEGO1/mxflcpresenter.cpp | 14 ++++++++++++++ LEGO1/mxflcpresenter.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/LEGO1/mxflcpresenter.cpp b/LEGO1/mxflcpresenter.cpp index 5c8c23a5..991e0bbe 100644 --- a/LEGO1/mxflcpresenter.cpp +++ b/LEGO1/mxflcpresenter.cpp @@ -1,6 +1,10 @@ #include "mxflcpresenter.h" #include "decomp.h" +#include "mxbitmap.h" +#include "mxomni.h" +#include "mxpalette.h" +#include "mxvideomanager.h" DECOMP_SIZE_ASSERT(MxFlcPresenter, 0x68); @@ -19,3 +23,13 @@ MxFlcPresenter::~MxFlcPresenter() delete this->m_unk64; } } + +// OFFSET: LEGO1 0x100b3620 +void MxFlcPresenter::VTable0x70() +{ + MxPalette* pal = m_bitmap->CreatePalette(); + MVideoManager()->RealizePalette(pal); + + if (pal) + delete pal; +} diff --git a/LEGO1/mxflcpresenter.h b/LEGO1/mxflcpresenter.h index 99035172..6fcf8973 100644 --- a/LEGO1/mxflcpresenter.h +++ b/LEGO1/mxflcpresenter.h @@ -24,6 +24,8 @@ class MxFlcPresenter : public MxVideoPresenter { return !strcmp(name, MxFlcPresenter::ClassName()) || MxVideoPresenter::IsA(name); } + virtual void VTable0x70() override; // vtable+0x70 + undefined4* m_unk64; }; From dff410d87a40917ad2bcca9d05bf8b55922d11a3 Mon Sep 17 00:00:00 2001 From: Thomas Phillips Date: Mon, 20 Nov 2023 01:55:01 +1300 Subject: [PATCH 07/10] Use templates instead of replacing (#292) * Use templates instead of replacing * Use Renderer to avoid loading templates ourselves --------- Co-authored-by: Thomas Phillips --- tools/reccmp/reccmp.py | 65 +++++++++++++++-------------------- tools/reccmp/requirements.txt | 3 +- tools/reccmp/template.html | 2 +- tools/reccmp/template.svg | 14 ++++---- 4 files changed, 37 insertions(+), 47 deletions(-) diff --git a/tools/reccmp/reccmp.py b/tools/reccmp/reccmp.py index 565fddef..debc25a3 100755 --- a/tools/reccmp/reccmp.py +++ b/tools/reccmp/reccmp.py @@ -12,6 +12,7 @@ import colorama import html import re +from pystache import Renderer parser = argparse.ArgumentParser(allow_abbrev=False, description='Recompilation Compare: compare an original EXE with a recompiled EXE + PDB.') @@ -552,50 +553,38 @@ def can_resolve_register_differences(original_asm, new_asm): except UnicodeDecodeError: break -def gen_html(html_path, data): - templatedata = None - with open(get_file_in_script_dir('template.html')) as templatefile: - templatedata = templatefile.read() +def gen_html(html_file, data): + output_data = Renderer().render_path(get_file_in_script_dir('template.html'), + { + "data": ','.join(data) + } + ) - templatedata = templatedata.replace('/* INSERT DATA HERE */', ','.join(data), 1) - - with open(html_path, 'w') as htmlfile: - htmlfile.write(templatedata) + with open(html_file, 'w') as htmlfile: + htmlfile.write(output_data) -def gen_svg(svg, name, icon, implemented_funcs, total_funcs, raw_accuracy): - templatedata = None - with open(get_file_in_script_dir('template.svg')) as templatefile: - templatedata = templatefile.read() +def gen_svg(svg_file, name_svg, icon, svg_implemented_funcs, total_funcs, raw_accuracy): + icon_data = None + if icon: + with open(icon, 'rb') as iconfile: + icon_data = base64.b64encode(iconfile.read()).decode('utf-8') - # TODO: Use templating engine (e.g. pystache) - # Replace icon - if args.svg_icon: - with open(args.svg_icon, 'rb') as iconfile: - templatedata = templatedata.replace('{icon}', base64.b64encode(iconfile.read()).decode('utf-8'), 1) - - # Replace name - templatedata = templatedata.replace('{name}', name, 1) - - # Replace implemented statistic - templatedata = templatedata.replace('{implemented}', f'{(implemented_funcs / total_funcs * 100):.2f}% ({implemented_funcs}/{total_funcs})', 1) - - # Replace accuracy statistic - templatedata = templatedata.replace('{accuracy}', f'{(raw_accuracy / implemented_funcs * 100):.2f}%', 1) - - # Generate progress bar width total_statistic = raw_accuracy / total_funcs - percenttemplate = '{progbar' - percentstart = templatedata.index(percenttemplate) - percentend = templatedata.index('}', percentstart) - progwidth = float(templatedata[percentstart + len(percenttemplate) + 1:percentend]) * total_statistic - templatedata = templatedata[0:percentstart] + str(progwidth) + templatedata[percentend + 1:] + full_percentbar_width = 127.18422 + output_data = Renderer().render_path(get_file_in_script_dir('template.svg'), + { + "name": name_svg, + "icon": icon_data, + "implemented": f'{(svg_implemented_funcs / total_funcs * 100):.2f}% ({svg_implemented_funcs}/{total_funcs})', + "accuracy": f'{(raw_accuracy / svg_implemented_funcs * 100):.2f}%', + "progbar": total_statistic * full_percentbar_width, + "percent": f'{(total_statistic * 100):.2f}%', + } + ) + with open(svg_file, 'w') as svgfile: + svgfile.write(output_data) - # Replace percentage statistic - templatedata = templatedata.replace('{percent}', f'{(total_statistic * 100):.2f}%', 2) - - with open(svg, 'w') as svgfile: - svgfile.write(templatedata) if html_path: gen_html(html_path, htmlinsert) diff --git a/tools/reccmp/requirements.txt b/tools/reccmp/requirements.txt index 31469c4c..b4f969a7 100644 --- a/tools/reccmp/requirements.txt +++ b/tools/reccmp/requirements.txt @@ -1,2 +1,3 @@ +capstone colorama -capstone \ No newline at end of file +pystache diff --git a/tools/reccmp/template.html b/tools/reccmp/template.html index f3087688..25de983a 100644 --- a/tools/reccmp/template.html +++ b/tools/reccmp/template.html @@ -75,7 +75,7 @@ }