From f4646a70750295d20301efb07bf81e9a9476d65b Mon Sep 17 00:00:00 2001
From: Misha <106913236+MishaProductions@users.noreply.github.com>
Date: Sun, 29 Oct 2023 10:01:14 -0400
Subject: [PATCH] implement a few mxstream* methods (#252)

* commit code

* commit code

* Update mxdiskstreamprovider.cpp

* Update mxstreamprovider.h

* improve match + add html file to gitignore

* improve match of MxRAMStreamController::Open

* MxDiskStreamController::Open

* Match some functions, relocate m_target to `MxThread`

---------

Co-authored-by: Christian Semmler <mail@csemmler.com>
---
 .gitignore                       |  2 ++
 LEGO1/mxdiskstreamcontroller.cpp | 30 +++++++++++++++--
 LEGO1/mxdiskstreamprovider.cpp   | 56 +++++++++++++++++++++++++-------
 LEGO1/mxdiskstreamprovider.h     | 17 +++++-----
 LEGO1/mxdsfile.h                 |  3 ++
 LEGO1/mxramstreamcontroller.cpp  | 32 ++++++++++++++++--
 LEGO1/mxramstreamprovider.cpp    |  2 +-
 LEGO1/mxramstreamprovider.h      | 14 ++++----
 LEGO1/mxstreamprovider.cpp       |  2 +-
 LEGO1/mxstreamprovider.h         | 16 +++++----
 LEGO1/mxthread.cpp               |  7 ----
 LEGO1/mxthread.h                 | 11 +++----
 12 files changed, 139 insertions(+), 53 deletions(-)

diff --git a/.gitignore b/.gitignore
index ef90adb6..c41df18b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,3 +16,5 @@ ISLE.EXE
 LEGO1.DLL
 build/
 *.swp
+LEGO1PROGRESS.HTML
+LEGO1PROGRESS.SVG
diff --git a/LEGO1/mxdiskstreamcontroller.cpp b/LEGO1/mxdiskstreamcontroller.cpp
index 0bd3893e..95d6858c 100644
--- a/LEGO1/mxdiskstreamcontroller.cpp
+++ b/LEGO1/mxdiskstreamcontroller.cpp
@@ -1,5 +1,10 @@
 #include "mxdiskstreamcontroller.h"
 
+#include "mxautolocker.h"
+#include "mxdiskstreamprovider.h"
+#include "mxomni.h"
+#include "mxticklemanager.h"
+
 // OFFSET: LEGO1 0x100c7120 STUB
 MxDiskStreamController::MxDiskStreamController()
 {
@@ -19,11 +24,30 @@ MxResult MxDiskStreamController::Tickle()
 	return SUCCESS;
 }
 
-// OFFSET: LEGO1 0x100c7790 STUB
+// OFFSET: LEGO1 0x100c7790
 MxResult MxDiskStreamController::Open(const char* p_filename)
 {
-	// TODO
-	return FAILURE;
+	MxAutoLocker lock(&this->m_criticalSection);
+	MxResult result = MxStreamController::Open(p_filename);
+
+	if (result == SUCCESS) {
+		m_provider = new MxDiskStreamProvider();
+		if (m_provider == NULL) {
+			result = FAILURE;
+		}
+		else {
+			result = m_provider->SetResourceToGet(this);
+			if (result != SUCCESS) {
+				delete m_provider;
+				m_provider = NULL;
+			}
+			else {
+				TickleManager()->RegisterClient(this, 10);
+			}
+		}
+	}
+
+	return result;
 }
 
 // OFFSET: LEGO1 0x100c7880
diff --git a/LEGO1/mxdiskstreamprovider.cpp b/LEGO1/mxdiskstreamprovider.cpp
index 5ea03197..b5dabe4a 100644
--- a/LEGO1/mxdiskstreamprovider.cpp
+++ b/LEGO1/mxdiskstreamprovider.cpp
@@ -1,5 +1,8 @@
 #include "mxdiskstreamprovider.h"
 
+#include "mxomni.h"
+#include "mxstreamcontroller.h"
+#include "mxstring.h"
 #include "mxthread.h"
 
 DECOMP_SIZE_ASSERT(MxDiskStreamProvider, 0x60);
@@ -7,13 +10,20 @@ DECOMP_SIZE_ASSERT(MxDiskStreamProvider, 0x60);
 // OFFSET: LEGO1 0x100d0f30
 MxResult MxDiskStreamProviderThread::Run()
 {
-	if (m_target != NULL)
-		m_target->WaitForWorkToComplete();
+	if (m_target)
+		((MxDiskStreamProvider*) m_target)->WaitForWorkToComplete();
 	MxThread::Run();
 	// They should probably have writen "return MxThread::Run()" but they didn't.
 	return SUCCESS;
 }
 
+// OFFSET: LEGO1 0x100d0f50
+MxResult MxDiskStreamProviderThread::StartWithTarget(MxDiskStreamProvider* p_target)
+{
+	m_target = p_target;
+	return Start(0x1000, 0);
+}
+
 // OFFSET: LEGO1 0x100d0f70
 MxDiskStreamProvider::MxDiskStreamProvider()
 {
@@ -22,13 +32,44 @@ MxDiskStreamProvider::MxDiskStreamProvider()
 	this->m_unk35 = 0;
 }
 
-// OFFSET: LEGO1 0x100d1240
+// OFFSET: LEGO1 0x100d1240 STUB
 MxDiskStreamProvider::~MxDiskStreamProvider()
 {
 	// TODO
 }
 
-// Matching but with esi / edi swapped
+// OFFSET: LEGO1 0x100d13d0
+MxResult MxDiskStreamProvider::SetResourceToGet(MxStreamController* p_resource)
+{
+	MxResult result = FAILURE;
+	MxString path;
+	m_pLookup = p_resource;
+
+	path = (MxString(MxOmni::GetHD()) + p_resource->GetAtom().GetInternal() + ".si");
+
+	m_pFile = new MxDSFile(path.GetData(), 0);
+	if (m_pFile != NULL) {
+		if (m_pFile->Open(0) != 0) {
+			path = MxString(MxOmni::GetCD()) + p_resource->GetAtom().GetInternal() + ".si";
+			m_pFile->SetFileName(path.GetData());
+
+			if (m_pFile->Open(0) != 0)
+				goto done;
+		}
+
+		m_remainingWork = 1;
+		MxResult success = m_busySemaphore.Init(0, 100);
+		m_thread.StartWithTarget(this);
+
+		if (success == SUCCESS && p_resource != NULL) {
+			result = SUCCESS;
+		}
+	}
+
+done:
+	return result;
+}
+
 // OFFSET: LEGO1 0x100d1750
 MxResult MxDiskStreamProvider::WaitForWorkToComplete()
 {
@@ -46,13 +87,6 @@ void MxDiskStreamProvider::PerformWork()
 	// TODO
 }
 
-// OFFSET: LEGO1 0x100d13d0 STUB
-MxResult MxDiskStreamProvider::SetResourceToGet(void* p_resource)
-{
-	// TODO
-	return FAILURE;
-}
-
 // OFFSET: LEGO1 0x100d1e90
 MxU32 MxDiskStreamProvider::GetFileSize()
 {
diff --git a/LEGO1/mxdiskstreamprovider.h b/LEGO1/mxdiskstreamprovider.h
index 9cfa708c..9e6e3572 100644
--- a/LEGO1/mxdiskstreamprovider.h
+++ b/LEGO1/mxdiskstreamprovider.h
@@ -13,12 +13,11 @@ class MxDiskStreamProvider;
 class MxDiskStreamProviderThread : public MxThread {
 public:
 	// Only inlined, no offset
-	inline MxDiskStreamProviderThread() : MxThread(), m_target(NULL) {}
+	inline MxDiskStreamProviderThread() : MxThread() { m_target = NULL; }
 
 	MxResult Run() override;
 
-private:
-	MxDiskStreamProvider* m_target;
+	MxResult StartWithTarget(MxDiskStreamProvider* p_target);
 };
 
 // VTABLE 0x100dd138
@@ -45,12 +44,12 @@ public:
 
 	void PerformWork();
 
-	virtual MxResult SetResourceToGet(void* p_resource) override; // vtable+0x14
-	virtual MxU32 GetFileSize() override;                         // vtable+0x18
-	virtual MxU32 GetStreamBuffersNum() override;                 // vtable+0x1c
-	virtual void vtable0x20(undefined4 p_unknown1) override;      // vtable+0x20
-	virtual MxU32 GetLengthInDWords() override;                   // vtable+0x24
-	virtual MxU32* GetBufferForDWords() override;                 // vtable+0x28
+	virtual MxResult SetResourceToGet(MxStreamController* p_resource) override; // vtable+0x14
+	virtual MxU32 GetFileSize() override;                                       // vtable+0x18
+	virtual MxU32 GetStreamBuffersNum() override;                               // vtable+0x1c
+	virtual void vtable0x20(undefined4 p_unknown1) override;                    // vtable+0x20
+	virtual MxU32 GetLengthInDWords() override;                                 // vtable+0x24
+	virtual MxU32* GetBufferForDWords() override;                               // vtable+0x28
 
 private:
 	MxDiskStreamProviderThread m_thread; // 0x10
diff --git a/LEGO1/mxdsfile.h b/LEGO1/mxdsfile.h
index c9984aa4..477bcf74 100644
--- a/LEGO1/mxdsfile.h
+++ b/LEGO1/mxdsfile.h
@@ -31,6 +31,9 @@ public:
 	__declspec(dllexport) virtual MxLong Seek(MxLong, int);               // vtable+0x24
 	__declspec(dllexport) virtual MxULong GetBufferSize();                // vtable+0x28
 	__declspec(dllexport) virtual MxULong GetStreamBuffersNum();          // vtable+0x2c
+
+	inline void SetFileName(const char* p_filename) { m_filename = p_filename; }
+
 private:
 	MxLong ReadChunks();
 	struct ChunkHeader {
diff --git a/LEGO1/mxramstreamcontroller.cpp b/LEGO1/mxramstreamcontroller.cpp
index 1b75fd4f..ae3d9634 100644
--- a/LEGO1/mxramstreamcontroller.cpp
+++ b/LEGO1/mxramstreamcontroller.cpp
@@ -1,13 +1,41 @@
 #include "mxramstreamcontroller.h"
 
+#include "mxautolocker.h"
 #include "mxramstreamprovider.h"
 
 DECOMP_SIZE_ASSERT(MxRAMStreamController, 0x98);
 
-// OFFSET: LEGO1 0x100c6110 STUB
+// OFFSET: LEGO1 0x100d0d80 STUB
+undefined* __cdecl FUN_100d0d80(MxU32* p_fileSizeBuffer, MxU32 p_fileSize)
+{
+	return NULL;
+}
+
+// OFFSET: LEGO1 0x100c6110
 MxResult MxRAMStreamController::Open(const char* p_filename)
 {
-	// TODO STUB
+	MxAutoLocker locker(&m_criticalSection);
+	if (MxStreamController::Open(p_filename) != SUCCESS) {
+		return FAILURE;
+	}
+
+	m_provider = new MxRAMStreamProvider();
+	if (((MxRAMStreamProvider*) m_provider) != NULL) {
+		if (m_provider->SetResourceToGet(this) != SUCCESS) {
+			return FAILURE;
+		}
+
+		FUN_100d0d80(
+			((MxRAMStreamProvider*) m_provider)->GetBufferOfFileSize(),
+			((MxRAMStreamProvider*) m_provider)->GetFileSize()
+		);
+		m_buffer.FUN_100c6780(
+			((MxRAMStreamProvider*) m_provider)->GetBufferOfFileSize(),
+			((MxRAMStreamProvider*) m_provider)->GetFileSize()
+		);
+		return SUCCESS;
+	}
+
 	return FAILURE;
 }
 
diff --git a/LEGO1/mxramstreamprovider.cpp b/LEGO1/mxramstreamprovider.cpp
index 0cb5353d..795523c8 100644
--- a/LEGO1/mxramstreamprovider.cpp
+++ b/LEGO1/mxramstreamprovider.cpp
@@ -30,7 +30,7 @@ MxRAMStreamProvider::~MxRAMStreamProvider()
 }
 
 // OFFSET: LEGO1 0x100d0ae0 STUB
-MxResult MxRAMStreamProvider::SetResourceToGet(void* p_resource)
+MxResult MxRAMStreamProvider::SetResourceToGet(MxStreamController* p_resource)
 {
 	return FAILURE;
 }
diff --git a/LEGO1/mxramstreamprovider.h b/LEGO1/mxramstreamprovider.h
index 4b6d5a5c..ba32768a 100644
--- a/LEGO1/mxramstreamprovider.h
+++ b/LEGO1/mxramstreamprovider.h
@@ -9,16 +9,18 @@ public:
 	MxRAMStreamProvider();
 	virtual ~MxRAMStreamProvider() override;
 
-	virtual MxResult SetResourceToGet(void* p_resource) override; // vtable+0x14
-	virtual MxU32 GetFileSize() override;                         // vtable+0x18
-	virtual MxU32 GetStreamBuffersNum() override;                 // vtable+0x1c
-	virtual MxU32 GetLengthInDWords() override;                   // vtable+0x24
-	virtual MxU32* GetBufferForDWords() override;                 // vtable+0x28
+	virtual MxResult SetResourceToGet(MxStreamController* p_resource) override; // vtable+0x14
+	virtual MxU32 GetFileSize() override;                                       // vtable+0x18
+	virtual MxU32 GetStreamBuffersNum() override;                               // vtable+0x1c
+	virtual MxU32 GetLengthInDWords() override;                                 // vtable+0x24
+	virtual MxU32* GetBufferForDWords() override;                               // vtable+0x28
+
+	inline MxU32* GetBufferOfFileSize() { return m_pBufferOfFileSize; }
 
 protected:
 	MxU32 m_bufferSize;
 	MxU32 m_fileSize;
-	void* m_pBufferOfFileSize;
+	MxU32* m_pBufferOfFileSize;
 	MxU32 m_lengthInDWords;
 	MxU32* m_bufferForDWords;
 };
diff --git a/LEGO1/mxstreamprovider.cpp b/LEGO1/mxstreamprovider.cpp
index b7233690..c1ba84cd 100644
--- a/LEGO1/mxstreamprovider.cpp
+++ b/LEGO1/mxstreamprovider.cpp
@@ -5,7 +5,7 @@
 DECOMP_SIZE_ASSERT(MxStreamProvider, 0x10);
 
 // OFFSET: LEGO1 0x100d07c0
-MxResult MxStreamProvider::SetResourceToGet(void* p_resource)
+MxResult MxStreamProvider::SetResourceToGet(MxStreamController* p_resource)
 {
 	m_pLookup = p_resource;
 	return SUCCESS;
diff --git a/LEGO1/mxstreamprovider.h b/LEGO1/mxstreamprovider.h
index 384b373a..77d4fd89 100644
--- a/LEGO1/mxstreamprovider.h
+++ b/LEGO1/mxstreamprovider.h
@@ -5,6 +5,8 @@
 #include "mxcore.h"
 #include "mxdsfile.h"
 
+class MxStreamController;
+
 // VTABLE 0x100dd100
 // SIZE 0x10
 class MxStreamProvider : public MxCore {
@@ -23,15 +25,15 @@ public:
 		return !strcmp(name, MxStreamProvider::ClassName()) || MxCore::IsA(name);
 	}
 
-	virtual MxResult SetResourceToGet(void* p_resource); // vtable+0x14
-	virtual MxU32 GetFileSize() = 0;                     // vtable+0x18
-	virtual MxU32 GetStreamBuffersNum() = 0;             // vtable+0x1c
-	virtual void vtable0x20(undefined4 p_unknown1);      // vtable+0x20
-	virtual MxU32 GetLengthInDWords() = 0;               // vtable+0x24
-	virtual MxU32* GetBufferForDWords() = 0;             // vtable+0x28
+	virtual MxResult SetResourceToGet(MxStreamController* p_resource); // vtable+0x14
+	virtual MxU32 GetFileSize() = 0;                                   // vtable+0x18
+	virtual MxU32 GetStreamBuffersNum() = 0;                           // vtable+0x1c
+	virtual void vtable0x20(undefined4 p_unknown1);                    // vtable+0x20
+	virtual MxU32 GetLengthInDWords() = 0;                             // vtable+0x24
+	virtual MxU32* GetBufferForDWords() = 0;                           // vtable+0x28
 
 protected:
-	void* m_pLookup;
+	MxStreamController* m_pLookup;
 	MxDSFile* m_pFile;
 };
 
diff --git a/LEGO1/mxthread.cpp b/LEGO1/mxthread.cpp
index fd252799..7e445f7d 100644
--- a/LEGO1/mxthread.cpp
+++ b/LEGO1/mxthread.cpp
@@ -68,13 +68,6 @@ MxTickleThread::MxTickleThread(MxCore* p_target, int p_frequencyMS)
 	m_frequencyMS = p_frequencyMS;
 }
 
-// OFFSET: LEGO1 0x100d0f50
-MxResult MxTickleThread::StartWithTarget(MxCore* p_target)
-{
-	m_target = p_target;
-	return Start(0x1000, 0);
-}
-
 // Match except for register allocation
 // OFFSET: LEGO1 0x100b8c90
 MxResult MxTickleThread::Run()
diff --git a/LEGO1/mxthread.h b/LEGO1/mxthread.h
index 72a61d95..59b31554 100644
--- a/LEGO1/mxthread.h
+++ b/LEGO1/mxthread.h
@@ -7,6 +7,7 @@
 
 class MxCore;
 
+// VTABLE 0x100dc860
 class MxThread {
 public:
 	// Note: Comes before virtual destructor
@@ -34,24 +35,22 @@ private:
 	MxU32 m_threadId;
 	MxBool m_running;
 	MxSemaphore m_semaphore;
+
+protected:
+	MxCore* m_target;
 };
 
+// VTABLE 0x100dc6d8
 class MxTickleThread : public MxThread {
 public:
 	MxTickleThread(MxCore* p_target, int p_frequencyMS);
 
-	// Unclear at this time whether this function and the m_target field are
-	// actually a general "userdata" pointer in the base MxThread, but it seems
-	// like the only usage is with an MxTickleThread.
-	MxResult StartWithTarget(MxCore* p_target);
-
 	// Only inlined, no offset
 	virtual ~MxTickleThread() {}
 
 	MxResult Run() override;
 
 private:
-	MxCore* m_target;
 	MxS32 m_frequencyMS;
 };