Merge branch 'isledecomp:master' into ioinfo2

This commit is contained in:
MS 2023-07-15 17:33:15 -04:00 committed by GitHub
commit 9ad8eb6430
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 621 additions and 67 deletions

View File

@ -45,8 +45,8 @@ jobs:
- name: Setup cmake - name: Setup cmake
uses: jwlawson/actions-setup-cmake@v1.13 uses: jwlawson/actions-setup-cmake@v1.13
with: with:
# Use 2.8 for maximum backwards compatibility # Use minimum supported version
cmake-version: '2.8.x' cmake-version: '3.0.x'
- name: Build - name: Build
shell: cmd shell: cmd
@ -112,8 +112,8 @@ jobs:
curl -fLSs -o ISLEPROGRESS-OLD.TXT https://github.com/isledecomp/isle/releases/download/continuous/ISLEPROGRESS.TXT curl -fLSs -o ISLEPROGRESS-OLD.TXT https://github.com/isledecomp/isle/releases/download/continuous/ISLEPROGRESS.TXT
curl -fLSs -o LEGO1PROGRESS-OLD.TXT https://github.com/isledecomp/isle/releases/download/continuous/LEGO1PROGRESS.TXT curl -fLSs -o LEGO1PROGRESS-OLD.TXT https://github.com/isledecomp/isle/releases/download/continuous/LEGO1PROGRESS.TXT
diff -u ISLEPROGRESS-OLD.TXT ISLEPROGRESS.TXT || true diff -u0 ISLEPROGRESS-OLD.TXT ISLEPROGRESS.TXT || true
diff -u LEGO1PROGRESS-OLD.TXT LEGO1PROGRESS.TXT || true diff -u0 LEGO1PROGRESS-OLD.TXT LEGO1PROGRESS.TXT || true
- name: Test Exports - name: Test Exports
shell: bash shell: bash

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 2.8...3.5 FATAL_ERROR) cmake_minimum_required(VERSION 3.0...3.5 FATAL_ERROR)
project(isle CXX) project(isle CXX)
@ -80,6 +80,7 @@ add_library(lego1 SHARED
LEGO1/legoroi.cpp LEGO1/legoroi.cpp
LEGO1/legosoundmanager.cpp LEGO1/legosoundmanager.cpp
LEGO1/legostate.cpp LEGO1/legostate.cpp
LEGO1/legostream.cpp
LEGO1/legotexturepresenter.cpp LEGO1/legotexturepresenter.cpp
LEGO1/legoutil.cpp LEGO1/legoutil.cpp
LEGO1/legovideomanager.cpp LEGO1/legovideomanager.cpp
@ -135,6 +136,7 @@ add_library(lego1 SHARED
LEGO1/mxpalette.cpp LEGO1/mxpalette.cpp
LEGO1/mxpresenter.cpp LEGO1/mxpresenter.cpp
LEGO1/mxscheduler.cpp LEGO1/mxscheduler.cpp
LEGO1/mxsemaphore.cpp
LEGO1/mxsmkpresenter.cpp LEGO1/mxsmkpresenter.cpp
LEGO1/mxsoundmanager.cpp LEGO1/mxsoundmanager.cpp
LEGO1/mxsoundpresenter.cpp LEGO1/mxsoundpresenter.cpp
@ -142,6 +144,7 @@ add_library(lego1 SHARED
LEGO1/mxstreamer.cpp LEGO1/mxstreamer.cpp
LEGO1/mxstring.cpp LEGO1/mxstring.cpp
LEGO1/mxstringvariable.cpp LEGO1/mxstringvariable.cpp
LEGO1/mxthread.cpp
LEGO1/mxtimer.cpp LEGO1/mxtimer.cpp
LEGO1/mxtransitionmanager.cpp LEGO1/mxtransitionmanager.cpp
LEGO1/mxunknown100dc6b0.cpp LEGO1/mxunknown100dc6b0.cpp

View File

@ -11,4 +11,11 @@
#define COMPAT_CONST #define COMPAT_CONST
#endif #endif
// We use `override` so newer compilers can tell us our vtables are valid,
// however this keyword was added in C++11, so we define it as empty for
// compatibility with older compilers.
#if defined(_MSC_VER) && _MSC_VER <= 1200 // 1200 corresponds to VC6.0 but "override" was probably added even later
#define override
#endif
#endif // ISLECOMPAT_H #endif // ISLECOMPAT_H

View File

@ -1,4 +1,5 @@
#include "legogamestate.h" #include "legogamestate.h"
#include "legoomni.h"
// OFFSET: LEGO1 0x10039550 // OFFSET: LEGO1 0x10039550
LegoGameState::LegoGameState() LegoGameState::LegoGameState()
@ -39,7 +40,19 @@ void LegoGameState::SerializeScoreHistory(MxS16 p)
} }
// OFFSET: LEGO1 0x10039f00 // OFFSET: LEGO1 0x10039f00
void LegoGameState::SetSavePath(char *p) void LegoGameState::SetSavePath(char *p_savePath)
{ {
// TODO 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;
}
} }

View File

@ -13,6 +13,9 @@ class LegoGameState
__declspec(dllexport) void SerializePlayersInfo(MxS16 p); __declspec(dllexport) void SerializePlayersInfo(MxS16 p);
__declspec(dllexport) void SerializeScoreHistory(MxS16 p); __declspec(dllexport) void SerializeScoreHistory(MxS16 p);
__declspec(dllexport) void SetSavePath(char *p); __declspec(dllexport) void SetSavePath(char *p);
private:
char *m_savePath;
}; };
#endif // LEGOGAMESTATE_H #endif // LEGOGAMESTATE_H

149
LEGO1/legostream.cpp Normal file
View File

@ -0,0 +1,149 @@
#include "legostream.h"
#include <cstdio>
#include <string>
// 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);
// OFFSET: LEGO1 0x10045ae0
MxBool LegoStream::IsWriteMode()
{
return m_mode == LEGOSTREAM_MODE_WRITE;
}
// OFFSET: LEGO1 0x10045af0
MxBool LegoStream::IsReadMode()
{
return m_mode == LEGOSTREAM_MODE_READ;
}
// OFFSET: LEGO1 0x100991c0
LegoFileStream::LegoFileStream()
: LegoStream()
{
m_hFile = NULL;
}
// OFFSET: LEGO1 0x10099250
LegoFileStream::~LegoFileStream()
{
if (m_hFile != NULL)
fclose(m_hFile);
}
// OFFSET: LEGO1 0x100992c0
MxResult LegoFileStream::Read(char* p_buffer, MxU32 p_size)
{
if (m_hFile == NULL)
return FAILURE;
return (fread(p_buffer, 1, p_size, m_hFile) == p_size) ? SUCCESS : FAILURE;
}
// OFFSET: LEGO1 0x10099300
MxResult LegoFileStream::Write(char* p_buffer, MxU32 p_size)
{
if (m_hFile == NULL)
return FAILURE;
return (fwrite(p_buffer, 1, p_size, m_hFile) == p_size) ? SUCCESS : FAILURE;
}
// OFFSET: 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;
}
// OFFSET: LEGO1 0x10099370
MxResult LegoFileStream::Seek(MxU32 p_offset)
{
if (m_hFile == NULL)
return FAILURE;
return (fseek(m_hFile, p_offset, 0) == 0) ? SUCCESS : FAILURE;
}
// OFFSET: 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;
}
// OFFSET: LEGO1 0x10099080
LegoMemoryStream::LegoMemoryStream(char* p_buffer)
: LegoStream()
{
m_buffer = p_buffer;
m_offset = 0;
}
// OFFSET: LEGO1 0x10099160
MxResult LegoMemoryStream::Read(char* p_buffer, MxU32 p_size)
{
memcpy(p_buffer, m_buffer + m_offset, p_size);
m_offset += p_size;
return SUCCESS;
}
// OFFSET: LEGO1 0x10099190
MxResult LegoMemoryStream::Write(char* p_buffer, MxU32 p_size)
{
memcpy(m_buffer + m_offset, p_buffer, p_size);
m_offset += p_size;
return SUCCESS;
}
// OFFSET: LEGO1 0x100994a0
MxResult LegoMemoryStream::Tell(MxU32* p_offset)
{
*p_offset = m_offset;
return SUCCESS;
}
// OFFSET: LEGO1 0x100994b0
MxResult LegoMemoryStream::Seek(MxU32 p_offset)
{
m_offset = p_offset;
return SUCCESS;
}

74
LEGO1/legostream.h Normal file
View File

@ -0,0 +1,74 @@
#ifndef LEGOSTREAM_H
#define LEGOSTREAM_H
#include "compat.h"
#include "decomp.h"
#include "mxtypes.h"
#include <iosfwd>
#define LEGOSTREAM_MODE_READ 1
#define LEGOSTREAM_MODE_WRITE 2
// VTABLE 0x100d7d80
class LegoStream
{
public:
LegoStream() : m_mode(0) {}
inline virtual ~LegoStream() {};
virtual MxResult Read(char* p_buffer, MxU32 p_size) = 0;
virtual MxResult Write(char* p_buffer, MxU32 p_size) = 0;
virtual MxResult Tell(MxU32* p_offset) = 0;
virtual MxResult Seek(MxU32 p_offset) = 0;
virtual MxBool IsWriteMode();
virtual MxBool IsReadMode();
enum OpenFlags
{
ReadBit = 1,
WriteBit = 2,
BinaryBit = 4,
};
protected:
MxU8 m_mode;
};
// VTABLE 0x100db730
class LegoFileStream : public LegoStream
{
public:
LegoFileStream();
virtual ~LegoFileStream();
MxResult Read(char* p_buffer, MxU32 p_size) override;
MxResult Write(char* p_buffer, MxU32 p_size) override;
MxResult Tell(MxU32* p_offset) override;
MxResult Seek(MxU32 p_offset) override;
MxResult Open(const char* p_filename, OpenFlags p_mode);
private:
FILE *m_hFile;
};
// VTABLE 0x100db710
class LegoMemoryStream : public LegoStream
{
public:
LegoMemoryStream(char* p_buffer);
~LegoMemoryStream() {}
MxResult Read(char* p_buffer, MxU32 p_size) override;
MxResult Write(char* p_buffer, MxU32 p_size) override;
MxResult Tell(MxU32* p_offset) override;
MxResult Seek(MxU32 p_offset) override;
private:
char *m_buffer;
MxU32 m_offset;
};
#endif // LEGOSTREAM_H

View File

@ -5,10 +5,10 @@
enum LookupMode enum LookupMode
{ {
LookupMode_Exact = 0, LookupMode_Exact = 0,
LookupMode_LowerCase = 1, LookupMode_LowerCase = 1,
LookupMode_UpperCase = 2, LookupMode_UpperCase = 2,
LookupMode_LowerCase2 = 3 LookupMode_LowerCase2 = 3
}; };
class MxAtomId class MxAtomId

View File

@ -3,6 +3,7 @@
#include <string.h> #include <string.h>
#include "compat.h"
#include "mxtypes.h" #include "mxtypes.h"
class MxParam; class MxParam;
@ -14,8 +15,8 @@ class MxCore
public: public:
__declspec(dllexport) MxCore(); __declspec(dllexport) MxCore();
__declspec(dllexport) virtual ~MxCore(); // vtable+00 __declspec(dllexport) virtual ~MxCore(); // vtable+00
__declspec(dllexport) virtual MxLong Notify(MxParam &p); // vtable+04 __declspec(dllexport) virtual MxResult Notify(MxParam &p); // vtable+04
virtual MxLong Tickle(); // vtable+08 virtual MxResult Tickle(); // vtable+08
// OFFSET: LEGO1 0x100144c0 // OFFSET: LEGO1 0x100144c0
inline virtual const char *ClassName() const // vtable+0c inline virtual const char *ClassName() const // vtable+0c

View File

@ -1,5 +1,17 @@
#include "mxdiskstreamprovider.h" #include "mxdiskstreamprovider.h"
#include "mxthread.h"
// OFFSET: LEGO1 0x100d0f30
MxResult MxDiskStreamProviderThread::Run()
{
if (m_target != NULL)
m_target->WaitForWorkToComplete();
MxThread::Run();
// They should probably have writen "return MxThread::Run()" but they didn't.
return SUCCESS;
}
// OFFSET: LEGO1 0x100d0f70 // OFFSET: LEGO1 0x100d0f70
MxDiskStreamProvider::MxDiskStreamProvider() MxDiskStreamProvider::MxDiskStreamProvider()
{ {
@ -11,3 +23,22 @@ MxDiskStreamProvider::~MxDiskStreamProvider()
{ {
// TODO // TODO
} }
// Matching but with esi / edi swapped
// OFFSET: LEGO1 0x100d1750
MxResult MxDiskStreamProvider::WaitForWorkToComplete()
{
while (m_remainingWork != 0)
{
m_busySemaphore.Wait(INFINITE);
if (m_unk1 != 0)
PerformWork();
}
return SUCCESS;
}
// OFFSET: LEGO1 0x100d1760 STUB
void MxDiskStreamProvider::PerformWork()
{
// TODO
}

View File

@ -2,6 +2,25 @@
#define MXDISKSTREAMPROVIDER_H #define MXDISKSTREAMPROVIDER_H
#include "mxstreamprovider.h" #include "mxstreamprovider.h"
#include "mxthread.h"
#include "mxcriticalsection.h"
class MxDiskStreamProvider;
// VTABLE 0x100dd130
class MxDiskStreamProviderThread : public MxThread
{
public:
// Only inlined, no offset
inline MxDiskStreamProviderThread()
: MxThread()
, m_target(NULL) {}
MxResult Run() override;
private:
MxDiskStreamProvider *m_target;
};
// VTABLE 0x100dd138 // VTABLE 0x100dd138
class MxDiskStreamProvider : public MxStreamProvider class MxDiskStreamProvider : public MxStreamProvider
@ -23,6 +42,20 @@ class MxDiskStreamProvider : public MxStreamProvider
{ {
return !strcmp(name, MxDiskStreamProvider::ClassName()) || MxStreamProvider::IsA(name); return !strcmp(name, MxDiskStreamProvider::ClassName()) || MxStreamProvider::IsA(name);
} }
MxResult WaitForWorkToComplete();
void PerformWork();
private:
MxDiskStreamProviderThread m_thread;
MxSemaphore m_busySemaphore;
byte m_remainingWork;
byte m_unk1;
MxCriticalSection m_criticalSection;
byte unk2[4];
void* unk3;
void *unk4;
}; };
#endif // MXDISKSTREAMPROVIDER_H #endif // MXDISKSTREAMPROVIDER_H

View File

@ -4,9 +4,10 @@
MxDSAction::MxDSAction() MxDSAction::MxDSAction()
{ {
// TODO // TODO
this->SetType(MxDSType_Action);
} }
// OFFSET: LEGO1 0x100ada80 // OFFSET: LEGO1 0x100ada80 STUB
MxDSAction::~MxDSAction() MxDSAction::~MxDSAction()
{ {
// TODO // TODO

View File

@ -3,11 +3,10 @@
// OFFSET: LEGO1 0x100c8ff0 // OFFSET: LEGO1 0x100c8ff0
MxDSAnim::MxDSAnim() MxDSAnim::MxDSAnim()
{ {
// TODO this->SetType(MxDSType_Anim);
} }
// OFFSET: LEGO1 0x100c91a0 // OFFSET: LEGO1 0x100c91a0
MxDSAnim::~MxDSAnim() MxDSAnim::~MxDSAnim()
{ {
// TODO
} }

View File

@ -1,13 +1,12 @@
#include "mxdsevent.h" #include "mxdsevent.h"
// OFFSET: LEGO1 0x100c95f0 STUB // OFFSET: LEGO1 0x100c95f0
MxDSEvent::MxDSEvent() MxDSEvent::MxDSEvent()
{ {
// TODO this->SetType(MxDSType_Event);
} }
// OFFSET: LEGO1 0x100c97a0 STUB // OFFSET: LEGO1 0x100c97a0
MxDSEvent::~MxDSEvent() MxDSEvent::~MxDSEvent()
{ {
// TODO
} }

View File

@ -4,9 +4,10 @@
MxDSMediaAction::MxDSMediaAction() MxDSMediaAction::MxDSMediaAction()
{ {
// TODO // TODO
this->SetType(MxDSType_MediaAction);
} }
// OFFSET: LEGO1 0x100c8cf0 // OFFSET: LEGO1 0x100c8cf0 STUB
MxDSMediaAction::~MxDSMediaAction() MxDSMediaAction::~MxDSMediaAction()
{ {
// TODO // TODO

View File

@ -3,11 +3,12 @@
// OFFSET: LEGO1 0x100c9b90 // OFFSET: LEGO1 0x100c9b90
MxDSMultiAction::MxDSMultiAction() MxDSMultiAction::MxDSMultiAction()
{ {
// TODO
this->SetType(MxDSType_MultiAction);
} }
// OFFSET: LEGO1 0x100ca060 // OFFSET: LEGO1 0x100ca060 STUB
MxDSMultiAction::~MxDSMultiAction() MxDSMultiAction::~MxDSMultiAction()
{ {
// TODO
} }

View File

@ -3,10 +3,12 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
DECOMP_SIZE_ASSERT(MxDSObject, 0x2c);
// OFFSET: LEGO1 0x100bf6a0 // OFFSET: LEGO1 0x100bf6a0
MxDSObject::MxDSObject() MxDSObject::MxDSObject()
{ {
this->m_unk0c = 0; this->SetType(MxDSType_Object);
this->m_sourceName = NULL; this->m_sourceName = NULL;
this->m_unk14 = 0; this->m_unk14 = 0;
this->m_objectName = NULL; this->m_objectName = NULL;
@ -83,15 +85,15 @@ void MxDSObject::SetSourceName(const char *p_sourceName)
} }
// OFFSET: LEGO1 0x100bf9c0 // OFFSET: LEGO1 0x100bf9c0
int MxDSObject::unk14() undefined4 MxDSObject::unk14()
{ {
return 10; return 10;
} }
// OFFSET: LEGO1 0x100bf9d0 // OFFSET: LEGO1 0x100bf9d0
unsigned int MxDSObject::CalculateUnk08() MxU32 MxDSObject::CalculateUnk08()
{ {
unsigned int unk08; MxU32 unk08;
if (this->m_sourceName) if (this->m_sourceName)
unk08 = strlen(this->m_sourceName) + 3; unk08 = strlen(this->m_sourceName) + 3;
@ -111,16 +113,16 @@ unsigned int MxDSObject::CalculateUnk08()
} }
// OFFSET: LEGO1 0x100bfa20 // OFFSET: LEGO1 0x100bfa20
void MxDSObject::Parse(char **p_source, MxU16 p_unk24) void MxDSObject::Parse(char **p_source, MxS16 p_unk24)
{ {
this->SetSourceName(*p_source); this->SetSourceName(*p_source);
*p_source += strlen(this->m_sourceName) + 1; *p_source += strlen(this->m_sourceName) + 1;
this->m_unk14 = *(int*) *p_source; this->m_unk14 = *(undefined4*) *p_source;
*p_source += 4; *p_source += 4;
this->SetObjectName(*p_source); this->SetObjectName(*p_source);
*p_source += strlen(this->m_objectName) + 1; *p_source += strlen(this->m_objectName) + 1;
this->m_unk1c = *(int*) *p_source; this->m_unk1c = *(undefined4*) *p_source;
*p_source += 4; *p_source += 4;
this->m_unk24 = p_unk24; this->m_unk24 = p_unk24;

View File

@ -1,55 +1,59 @@
#ifndef MXDSOBJECT_H #ifndef MXDSOBJECT_H
#define MXDSOBJECT_H #define MXDSOBJECT_H
#include "decomp.h"
#include "mxcore.h" #include "mxcore.h"
#include "mxatomid.h" #include "mxatomid.h"
#include "mxdstypes.h"
// VTABLE 0x100dc868 // VTABLE 0x100dc868
// SIZE 0x2c // SIZE 0x2c
class MxDSObject : public MxCore class MxDSObject : public MxCore
{ {
public: public:
__declspec(dllexport) void SetObjectName(const char *p_objectName);
MxDSObject(); MxDSObject();
virtual ~MxDSObject() override; virtual ~MxDSObject() override;
MxDSObject &operator=(MxDSObject &p_dsObject);
void CopyFrom(MxDSObject &p_dsObject); void CopyFrom(MxDSObject &p_dsObject);
MxDSObject &operator=(MxDSObject &p_dsObject);
// OFFSET: LEGO1 0x100bf730 __declspec(dllexport) void SetObjectName(const char *p_objectName);
void SetSourceName(const char *p_sourceName);
// OFFSET: LEGO1 0x100bf730
inline virtual const char *ClassName() const override { return "MxDSObject"; }; // vtable+0c inline virtual const char *ClassName() const override { return "MxDSObject"; }; // vtable+0c
// OFFSET: LEGO1 0x100bf740 // OFFSET: LEGO1 0x100bf740
inline virtual MxBool IsA(const char *name) const override { return !strcmp(name, MxDSObject::ClassName()) || MxCore::IsA(name); }; // vtable+10; inline virtual MxBool IsA(const char *name) const override { return !strcmp(name, MxDSObject::ClassName()) || MxCore::IsA(name); }; // vtable+10;
virtual int unk14(); // vtable+14; virtual undefined4 unk14(); // vtable+14;
virtual unsigned int CalculateUnk08(); // vtable+18; virtual MxU32 CalculateUnk08(); // vtable+18;
virtual void Parse(char **p_source, MxU16 p_unk24); // vtable+1c; virtual void Parse(char **p_source, MxS16 p_unk24); // vtable+1c;
void SetSourceName(const char *p_sourceName);
inline const MxAtomId& GetAtomId() { return this->m_atomId; } inline const MxAtomId& GetAtomId() { return this->m_atomId; }
inline int GetUnknown1c() { return this->m_unk1c; } inline undefined4 GetUnknown1c() { return this->m_unk1c; }
inline void SetUnknown1c(int p_unk1c) { this->m_unk1c = p_unk1c; } inline void SetUnknown1c(undefined4 p_unk1c) { this->m_unk1c = p_unk1c; }
inline void SetUnknown24(MxS16 p_unk24) { this->m_unk24 = p_unk24; } inline void SetUnknown24(MxS16 p_unk24) { this->m_unk24 = p_unk24; }
// OFFSET: ISLE 0x401c40 // OFFSET: ISLE 0x401c40
// OFFSET: LEGO1 0x10005530 // OFFSET: LEGO1 0x10005530
inline void SetAtomId(MxAtomId p_atomId) { this->m_atomId = p_atomId; } inline void SetAtomId(MxAtomId p_atomId) { this->m_atomId = p_atomId; }
protected:
inline void SetType(MxDSType p_type) { this->m_type = p_type; }
private: private:
unsigned int m_unk08; MxU32 m_unk08;
MxS16 m_unk0c; MxU16 m_type;
char* m_sourceName; char* m_sourceName;
int m_unk14; undefined4 m_unk14;
char *m_objectName; char *m_objectName;
int m_unk1c; undefined4 m_unk1c;
MxAtomId m_atomId; MxAtomId m_atomId;
MxS16 m_unk24; MxS16 m_unk24;
MxU16 m_unk26; undefined4 m_unk28;
int m_unk28;
}; };
#endif // MXDSOBJECT_H #endif // MXDSOBJECT_H

View File

@ -3,11 +3,10 @@
// OFFSET: LEGO1 0x100c8870 // OFFSET: LEGO1 0x100c8870
MxDSObjectAction::MxDSObjectAction() MxDSObjectAction::MxDSObjectAction()
{ {
// TODO this->SetType(MxDSType_ObjectAction);
} }
// OFFSET: LEGO1 0x100c8a20 // OFFSET: LEGO1 0x100c8a20
MxDSObjectAction::~MxDSObjectAction() MxDSObjectAction::~MxDSObjectAction()
{ {
// TODO
} }

View File

@ -3,11 +3,10 @@
// OFFSET: LEGO1 0x100cae80 // OFFSET: LEGO1 0x100cae80
MxDSParallelAction::MxDSParallelAction() MxDSParallelAction::MxDSParallelAction()
{ {
this->SetType(MxDSType_ParallelAction);
} }
// OFFSET: LEGO1 0x100cb040 // OFFSET: LEGO1 0x100cb040
MxDSParallelAction::~MxDSParallelAction() MxDSParallelAction::~MxDSParallelAction()
{ {
} }

View File

@ -3,11 +3,12 @@
// OFFSET: LEGO1 0x100cb2b0 // OFFSET: LEGO1 0x100cb2b0
MxDSSelectAction::MxDSSelectAction() MxDSSelectAction::MxDSSelectAction()
{ {
// TODO
this->SetType(MxDSType_SelectAction);
} }
// OFFSET: LEGO1 0x100cb8d0 // OFFSET: LEGO1 0x100cb8d0 STUB
MxDSSelectAction::~MxDSSelectAction() MxDSSelectAction::~MxDSSelectAction()
{ {
// TODO
} }

View File

@ -3,11 +3,12 @@
// OFFSET: LEGO1 0x100ca9d0 // OFFSET: LEGO1 0x100ca9d0
MxDSSerialAction::MxDSSerialAction() MxDSSerialAction::MxDSSerialAction()
{ {
// TODO
this->SetType(MxDSType_SerialAction);
} }
// OFFSET: LEGO1 0x100cac10 // OFFSET: LEGO1 0x100cac10 STUB
MxDSSerialAction::~MxDSSerialAction() MxDSSerialAction::~MxDSSerialAction()
{ {
// TODO
} }

View File

@ -4,10 +4,10 @@
MxDSSound::MxDSSound() MxDSSound::MxDSSound()
{ {
// TODO // TODO
this->SetType(MxDSType_Sound);
} }
// OFFSET: LEGO1 0x100c9470 // OFFSET: LEGO1 0x100c9470
MxDSSound::~MxDSSound() MxDSSound::~MxDSSound()
{ {
// TODO
} }

View File

@ -3,11 +3,10 @@
// OFFSET: LEGO1 0x100c98c0 // OFFSET: LEGO1 0x100c98c0
MxDSStill::MxDSStill() MxDSStill::MxDSStill()
{ {
// TODO this->SetType(MxDSType_Still);
} }
// OFFSET: LEGO1 0x100c9a70 // OFFSET: LEGO1 0x100c9a70
MxDSStill::~MxDSStill() MxDSStill::~MxDSStill()
{ {
// TODO
} }

20
LEGO1/mxdstypes.h Executable file
View File

@ -0,0 +1,20 @@
#ifndef MXDSTYPES_H
#define MXDSTYPES_H
enum MxDSType
{
MxDSType_Object = 0,
MxDSType_Action = 1,
MxDSType_MediaAction = 2,
MxDSType_Anim = 3,
MxDSType_Sound = 4,
MxDSType_MultiAction = 5,
MxDSType_SerialAction = 6,
MxDSType_ParallelAction = 7,
MxDSType_Event = 8,
MxDSType_SelectAction = 9,
MxDSType_Still = 10,
MxDSType_ObjectAction = 11,
};
#endif // MXDSTYPES_H

29
LEGO1/mxsemaphore.cpp Normal file
View File

@ -0,0 +1,29 @@
#include "mxsemaphore.h"
// OFFSET: LEGO1 0x100c87d0
MxSemaphore::MxSemaphore()
{
m_hSemaphore = NULL;
}
// OFFSET: LEGO1 0x100c8800
MxResult MxSemaphore::Init(MxU32 p_initialCount, MxU32 p_maxCount)
{
MxResult result = FAILURE;
if (m_hSemaphore = CreateSemaphoreA(NULL, p_initialCount, p_maxCount, NULL))
result = SUCCESS;
return result;
}
// OFFSET: LEGO1 0x100c8830
void MxSemaphore::Wait(MxU32 p_timeoutMS)
{
WaitForSingleObject(m_hSemaphore, p_timeoutMS);
}
// OFFSET: LEGO1 0x100c8850
void MxSemaphore::Release(MxU32 p_releaseCount)
{
ReleaseSemaphore(m_hSemaphore, p_releaseCount, NULL);
}

27
LEGO1/mxsemaphore.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef MX_SEMAPHORE_H
#define MX_SEMAPHORE_H
#include "mxtypes.h"
#include <windows.h>
class MxSemaphore
{
public:
MxSemaphore();
// Inlined only, no offset
~MxSemaphore()
{
CloseHandle(m_hSemaphore);
}
virtual MxResult Init(MxU32 p_initialCount, MxU32 p_maxCount);
void Wait(MxU32 p_timeoutMS);
void Release(MxU32 p_releaseCount);
private:
HANDLE m_hSemaphore;
};
#endif // MX_SEMAPHORE_H

View File

@ -2,6 +2,7 @@
#define MXSTREAMPROVIDER_H #define MXSTREAMPROVIDER_H
#include "mxcore.h" #include "mxcore.h"
#include "mxdsfile.h"
// VTABLE 0x100dd100 // VTABLE 0x100dd100
class MxStreamProvider : public MxCore class MxStreamProvider : public MxCore
@ -18,6 +19,10 @@ class MxStreamProvider : public MxCore
{ {
return !strcmp(name, MxStreamProvider::ClassName()) || MxCore::IsA(name); return !strcmp(name, MxStreamProvider::ClassName()) || MxCore::IsA(name);
} }
private:
void *m_pLookup;
MxDSFile* m_pFile;
}; };
#endif // MXSTREAMPROVIDER_H #endif // MXSTREAMPROVIDER_H

99
LEGO1/mxthread.cpp Normal file
View File

@ -0,0 +1,99 @@
#include "mxthread.h"
#include <process.h>
#include "mxomni.h"
// OFFSET: LEGO1 0x100bf690
MxResult MxThread::Run()
{
m_semaphore.Release(1);
return SUCCESS;
}
// OFFSET: LEGO1 0x100bf510
MxThread::MxThread()
{
m_hThread = NULL;
m_running = TRUE;
m_threadId = 0;
}
// OFFSET: LEGO1 0x100bf5a0
MxThread::~MxThread()
{
if (m_hThread)
CloseHandle((HANDLE)m_hThread);
}
typedef unsigned(__stdcall *ThreadFunc)(void *);
// OFFSET: LEGO1 0x100bf610
MxResult MxThread::Start(int p_stack, int p_flag)
{
MxResult result = FAILURE;
if (m_semaphore.Init(0, 1) == SUCCESS)
{
if (m_hThread = _beginthreadex(NULL, p_stack << 2, (ThreadFunc)&MxThread::ThreadProc, this, p_flag, &m_threadId))
result = SUCCESS;
}
return result;
}
// OFFSET: LEGO1 0x100bf670
void MxThread::Terminate()
{
m_running = FALSE;
m_semaphore.Wait(INFINITE);
}
// OFFSET: LEGO1 0x100bf680
unsigned MxThread::ThreadProc(void *p_thread)
{
return static_cast<MxThread*>(p_thread)->Run();
}
// OFFSET: LEGO1 0x100bf660
void MxThread::Sleep(MxS32 p_milliseconds)
{
::Sleep(p_milliseconds);
}
// OFFSET: LEGO1 0x100b8bb0
MxTickleThread::MxTickleThread(MxCore *p_target, int p_frequencyMS)
{
m_target = p_target;
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()
{
MxTimer* timer = Timer();
int lastTickled = -m_frequencyMS;
while (IsRunning())
{
int currentTime = timer->GetTime();
if (currentTime < lastTickled) {
lastTickled = -m_frequencyMS;
}
int timeRemainingMS = (m_frequencyMS - currentTime) + lastTickled;
if (timeRemainingMS <= 0) {
m_target->Tickle();
timeRemainingMS = 0;
lastTickled = currentTime;
}
Sleep(timeRemainingMS);
}
return MxThread::Run();
}

58
LEGO1/mxthread.h Normal file
View File

@ -0,0 +1,58 @@
#ifndef MXTHREAD_H
#define MXTHREAD_H
#include "compat.h"
#include "mxtypes.h"
#include "mxsemaphore.h"
class MxCore;
class MxThread
{
public:
// Note: Comes before virtual destructor
virtual MxResult Run();
MxResult Start(int p_stack, int p_flag);
void Terminate();
void Sleep(MxS32 p_milliseconds);
// Inferred, not in DLL
inline MxBool IsRunning() { return m_running; }
protected:
MxThread();
virtual ~MxThread();
private:
static unsigned ThreadProc(void *p_thread);
MxULong m_hThread;
MxU32 m_threadId;
MxBool m_running;
MxSemaphore m_semaphore;
};
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;
};
#endif // MXTHREAD_H

View File

@ -18,7 +18,7 @@ class MxTimer : public MxCore
inline MxLong GetTime() inline MxLong GetTime()
{ {
if (this->m_isRunning) if (this->m_isRunning)
return s_LastTimeCalculated; return s_LastTimeTimerStarted;
else else
return s_LastTimeCalculated - this->m_startTime; return s_LastTimeCalculated - this->m_startTime;
} }

View File

@ -39,8 +39,4 @@ typedef MxU8 MxBool;
#define FALSE 0 #define FALSE 0
#endif #endif
#if defined(_MSC_VER) && _MSC_VER <= 1200 // 1200 corresponds to VC6.0 but "override" was probably added even later
#define override
#endif
#endif // MXTYPE_H #endif // MXTYPE_H