From 6e8b93b07c818cfe15cc490428e7e762d6007494 Mon Sep 17 00:00:00 2001 From: MattKC <34096995+itsmattkc@users.noreply.github.com> Date: Tue, 27 Jun 2023 10:56:59 -0700 Subject: [PATCH 01/21] Update CONTRIBUTING.md --- CONTRIBUTING.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 331b5746..2c6519ce 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,7 +6,7 @@ Generally, decompilation is a fairly advanced skill. If you aren't already famil ## Ghidra Server -For documenting the original binaries and generating pseudocode that we decompile with, we primarily use [Ghidra](https://ghidra-sre.org/) (it's free and open source). To help with collaboration, we have a shared Ghidra repository with all of our current work. It is available to the public but read-only; to contribute to it yourself, you'll need approval from a current maintainer. +For documenting the original binaries and generating pseudocode that we decompile with, we primarily use [Ghidra](https://ghidra-sre.org/) (it's free and open source). To help with collaboration, we have a shared Ghidra repository with all of our current work. You are free to check it out and mess around with it locally, however to prevent sabotage, you will need to request permission before you can push back to the server (ask in the Matrix room). To access the Ghidra repository, use the following details: @@ -21,6 +21,7 @@ In general, we're not exhaustively strict about coding style, but there are some - `PascalCase` for classes and function names. - `m_camelCase` for member variables. - `g_camelCase` for global variables. +- `p_camelCase` for function parameters. ## Kinds of Contributions From 51ec2c97c60e107b27e15e06b4db8301add35966 Mon Sep 17 00:00:00 2001 From: Mark Langen Date: Tue, 27 Jun 2023 11:44:02 -0700 Subject: [PATCH 02/21] 100% Match of MxDSFile (#51) * 100% Match of MxDSFile * ...almost, MxDSFile::Open is still not quite matching but all of the other methods are 100% matching. * Turns out that most of the virtual methods and some of the members are actually on the MxDSSource base class, which I've pulled out as part of this. * In order to implement the methods I added the MXIOINFO class, which seems to be a thin wrapper around the MMIOINFO windows structure. We can tell this because MMIOINFO::~MMIOINFO was included in the DLL exports, and calls down to a function which deconstructs something looking exactly like MMIOINFO. * Add mxdssource.cpp * mattkc feedback * some accuracy improvements * Use FOURCC macro * Tirival solve in mxioinfo.cpp * Update mxdsfile.cpp 0xFFFFFFFF -> -1 --------- Co-authored-by: Christian Semmler --- LEGO1/mxdsfile.cpp | 126 ++++++++++++++++++++++++++++++++++++++++++- LEGO1/mxdsfile.h | 40 +++++++++++--- LEGO1/mxdssource.cpp | 14 +++++ LEGO1/mxdssource.h | 30 +++++++++++ LEGO1/mxioinfo.cpp | 49 +++++++++++++++++ LEGO1/mxioinfo.h | 12 +++++ LEGO1/mxstring.h | 2 + isle.mak | 83 ++++++++++++++++++++++++++++ isle.mdp | Bin 50176 -> 52224 bytes 9 files changed, 348 insertions(+), 8 deletions(-) create mode 100644 LEGO1/mxdssource.cpp create mode 100644 LEGO1/mxdssource.h create mode 100644 LEGO1/mxioinfo.cpp diff --git a/LEGO1/mxdsfile.cpp b/LEGO1/mxdsfile.cpp index 27d6668d..327fab46 100644 --- a/LEGO1/mxdsfile.cpp +++ b/LEGO1/mxdsfile.cpp @@ -1,6 +1,130 @@ #include "mxdsfile.h" +#include + +#define SI_MAJOR_VERSION 2 +#define SI_MINOR_VERSION 2 + +#define FOURCC(a, b, c, d) (((a) << 0) | ((b) << 8) | ((c) << 16) | ((d) << 24)) + +// OFFSET: LEGO1 0x100cc4b0 +MxDSFile::MxDSFile(const char *filename, unsigned long skipReadingChunks) +{ + m_filename = filename; + m_skipReadingChunks = skipReadingChunks; +} + +// OFFSET: LEGO1 0x100bfed0 +MxDSFile::~MxDSFile() +{ + Close(); +} + +// OFFSET: LEGO1 0x100cc590 +long MxDSFile::Open(unsigned long uStyle) +{ + // No idea what's stopping this one matching, but I'm pretty + // confident it has the correct behavior. + long longResult = 1; + memset(&m_io, 0, sizeof(MXIOINFO)); + + if (m_io.Open(m_filename.GetData(), uStyle) != 0) { + return -1; + } + + m_io.SetBuffer(NULL, 0, 0); + m_position = 0; + + if (m_skipReadingChunks == 0) { + longResult = ReadChunks(); + } + + if (longResult != 0) { + Close(); // vtable + 0x18 + } + else { + Seek(0, 0); // vtable + 0x24 + } + + return longResult; +} + +// OFFSET: LEGO1 0x100cc780 +long MxDSFile::Read(unsigned char *pch, unsigned long cch) +{ + if (m_io.Read((char*)pch, cch) != cch) + return -1; + + m_position += cch; + return 0; +} + +// OFFSET: LEGO1 0x100cc620 +long MxDSFile::ReadChunks() +{ + _MMCKINFO topChunk; + _MMCKINFO childChunk; + char tempBuffer[80]; + + topChunk.fccType = FOURCC('O', 'M', 'N', 'I'); + if (m_io.Descend(&topChunk, NULL, MMIO_FINDRIFF) != 0) { + return -1; + } + childChunk.ckid = FOURCC('M', 'x', 'H', 'd'); + if (m_io.Descend(&childChunk, &topChunk, 0) != 0) { + return -1; + } + + m_io.Read((char*)&m_header, 0xc); + if ((m_header.majorVersion == SI_MAJOR_VERSION) && (m_header.minorVersion == SI_MINOR_VERSION)) + { + childChunk.ckid = FOURCC('M', 'x', 'O', 'f'); + if (m_io.Descend(&childChunk, &topChunk, 0) != 0) { + return -1; + } + unsigned long* pLengthInDWords = &m_lengthInDWords; + m_io.Read((char *)pLengthInDWords, 4); + m_pBuffer = malloc(*pLengthInDWords * 4); + m_io.Read((char*)m_pBuffer, *pLengthInDWords * 4); + return 0; + } + else + { + sprintf(tempBuffer, "Wrong SI file version. %d.%d expected.", SI_MAJOR_VERSION, SI_MINOR_VERSION); + MessageBoxA(NULL, tempBuffer, NULL, MB_ICONERROR); + return -1; + } +} + +// OFFSET: LEGO1 0x100cc7b0 +long MxDSFile::Seek(long lOffset, int iOrigin) +{ + return (m_position = m_io.Seek(lOffset, iOrigin)) == -1 ? -1 : 0; +} + +// OFFSET: LEGO1 0x100cc7e0 unsigned long MxDSFile::GetBufferSize() { - return this->m_buffersize; + return m_header.bufferSize; +} + +// OFFSET: LEGO1 0x100cc7f0 +unsigned long MxDSFile::GetStreamBuffersNum() +{ + return m_header.streamBuffersNum; +} + +// OFFSET: LEGO1 0x100cc740 +long MxDSFile::Close() +{ + m_io.Close(0); + m_position = -1; + memset(&m_header, 0, sizeof(m_header)); + if (m_lengthInDWords != 0) + { + m_lengthInDWords = 0; + free(m_pBuffer); + m_pBuffer = NULL; + } + return 0; } diff --git a/LEGO1/mxdsfile.h b/LEGO1/mxdsfile.h index d28928dc..e1e170d4 100644 --- a/LEGO1/mxdsfile.h +++ b/LEGO1/mxdsfile.h @@ -1,20 +1,46 @@ #ifndef MXDSFILE_H #define MXDSFILE_H -class MxDSFile +#include "mxcore.h" +#include "mxstring.h" +#include "mxioinfo.h" +#include "mxdssource.h" +class MxDSFile : public MxDSSource { public: - __declspec(dllexport) MxDSFile(const char *,unsigned long); + __declspec(dllexport) MxDSFile(const char *filename, unsigned long skipReadingChunks); __declspec(dllexport) virtual ~MxDSFile(); - __declspec(dllexport) virtual long Close(); - __declspec(dllexport) virtual unsigned long GetBufferSize(); - __declspec(dllexport) virtual unsigned long GetStreamBuffersNum(); __declspec(dllexport) virtual long Open(unsigned long); + __declspec(dllexport) virtual long Close(); __declspec(dllexport) virtual long Read(unsigned char *,unsigned long); __declspec(dllexport) virtual long Seek(long,int); + __declspec(dllexport) virtual unsigned long GetBufferSize(); + __declspec(dllexport) virtual unsigned long GetStreamBuffersNum(); + private: - char m_unknown[0x70]; - unsigned long m_buffersize; + long ReadChunks(); + struct ChunkHeader { + ChunkHeader() + : majorVersion(0) + , minorVersion(0) + , bufferSize(0) + , streamBuffersNum(0) + {} + + unsigned short majorVersion; + unsigned short minorVersion; + unsigned long bufferSize; + short streamBuffersNum; + short reserved; + }; + + MxString m_filename; + MXIOINFO m_io; + ChunkHeader m_header; + + // If false, read chunks immediately on open, otherwise + // skip reading chunks until ReadChunks is explicitly called. + unsigned long m_skipReadingChunks; }; #endif // MXDSFILE_H diff --git a/LEGO1/mxdssource.cpp b/LEGO1/mxdssource.cpp new file mode 100644 index 00000000..8612c5c4 --- /dev/null +++ b/LEGO1/mxdssource.cpp @@ -0,0 +1,14 @@ +#include "mxdssource.h" + +// OFFSET: LEGO1 0x100bffd0 +void MxDSSource::SomethingWhichCallsRead(void* pUnknownObject) +{ + // TODO: Calls read, reading into a buffer somewhere in pUnknownObject. + Read(NULL, 0); +} + +// OFFSET: LEGO1 0x100bfff0 +long MxDSSource::GetLengthInDWords() +{ + return m_lengthInDWords; +} \ No newline at end of file diff --git a/LEGO1/mxdssource.h b/LEGO1/mxdssource.h new file mode 100644 index 00000000..7ee01490 --- /dev/null +++ b/LEGO1/mxdssource.h @@ -0,0 +1,30 @@ +#ifndef MXDSSOURCE_H +#define MXDSSOURCE_H + +#include "mxcore.h" + +class MxDSSource : public MxCore +{ +public: + MxDSSource() + : m_lengthInDWords(0) + , m_pBuffer(0) + , m_position(-1) + {} + + virtual long Open(unsigned long) = 0; + virtual long Close() = 0; + virtual void SomethingWhichCallsRead(void* pUnknownObject); + virtual long Read(unsigned char *, unsigned long) = 0; + virtual long Seek(long, int) = 0; + virtual unsigned long GetBufferSize() = 0; + virtual unsigned long GetStreamBuffersNum() = 0; + virtual long GetLengthInDWords(); + +protected: + unsigned long m_lengthInDWords; + void* m_pBuffer; + long m_position; +}; + +#endif // MXDSSOURCE_H \ No newline at end of file diff --git a/LEGO1/mxioinfo.cpp b/LEGO1/mxioinfo.cpp new file mode 100644 index 00000000..ebe2a480 --- /dev/null +++ b/LEGO1/mxioinfo.cpp @@ -0,0 +1,49 @@ +#include "mxioinfo.h" + +// OFFSET: LEGO1 0x100cc800 +MXIOINFO::MXIOINFO() +{ + memset(&m_info, 0, sizeof(MMIOINFO)); +} + +// OFFSET: LEGO1 0x100cc820 +MXIOINFO::~MXIOINFO() +{ + Close(0); +} + +// OFFSET: LEGO1 0x100cc830 +unsigned short MXIOINFO::Open(const char *filename, DWORD fdwOpen) +{ + return 0; +} + +// OFFSET: LEGO1 0x100cc8e0 +void MXIOINFO::Close(long arg) +{ + +} + +// OFFSET: LEGO1 0x100cc930 +unsigned long MXIOINFO::Read(HPSTR pch, LONG cch) +{ + return 0; +} + +// OFFSET: LEGO1 0x100cca00 +LONG MXIOINFO::Seek(LONG lOffset, int iOrigin) +{ + return 0; +} + +// OFFSET: LEGO1 0x100ccbc0 +void MXIOINFO::SetBuffer(LPSTR pchBuffer, LONG cchBuffer, LONG unk) +{ + +} + +// OFFSET: LEGO1 0x100cce60 +unsigned short MXIOINFO::Descend(LPMMCKINFO pmmcki, const MMCKINFO *pmmckiParent, UINT fuDescend) +{ + return 0; +} \ No newline at end of file diff --git a/LEGO1/mxioinfo.h b/LEGO1/mxioinfo.h index d3f2a40e..59ee3807 100644 --- a/LEGO1/mxioinfo.h +++ b/LEGO1/mxioinfo.h @@ -1,10 +1,22 @@ #ifndef MXIOINFO_H #define MXIOINFO_H +#include "legoinc.h" +#include "mmsystem.h" class MXIOINFO { public: + MXIOINFO(); __declspec(dllexport) ~MXIOINFO(); + + unsigned short Open(const char *filename, DWORD fdwOpen); + void Close(long arg); + LONG Seek(LONG lOffset, int iOrigin); + unsigned long Read(HPSTR pch, LONG cch); + void SetBuffer(LPSTR pchBuffer, LONG cchBuffer, LONG unk); + unsigned short Descend(LPMMCKINFO pmmcki, const MMCKINFO *pmmckiParent, UINT fuDescend); + + MMIOINFO m_info; }; #endif // MXIOINFO_H diff --git a/LEGO1/mxstring.h b/LEGO1/mxstring.h index 0f9ff9f3..a9a25ba1 100644 --- a/LEGO1/mxstring.h +++ b/LEGO1/mxstring.h @@ -16,6 +16,8 @@ class MxString : public MxCore void ToLowerCase(); const MxString &operator=(MxString *); + inline const char *GetData() const { return m_data; } + private: char *m_data; unsigned short m_length; diff --git a/isle.mak b/isle.mak index 59570097..7eaf3d48 100644 --- a/isle.mak +++ b/isle.mak @@ -61,7 +61,10 @@ CLEAN : -@erase "$(INTDIR)\mxautolocker.obj" -@erase "$(INTDIR)\mxcore.obj" -@erase "$(INTDIR)\mxcriticalsection.obj" + -@erase "$(INTDIR)\mxdsfile.obj" -@erase "$(INTDIR)\mxdsobject.obj" + -@erase "$(INTDIR)\mxdssource.obj" + -@erase "$(INTDIR)\mxioinfo.obj" -@erase "$(INTDIR)\mxomni.obj" -@erase "$(INTDIR)\mxomnicreateflags.obj" -@erase "$(INTDIR)\mxomnicreateparam.obj" @@ -138,7 +141,10 @@ LINK32_OBJS= \ "$(INTDIR)\mxautolocker.obj" \ "$(INTDIR)\mxcore.obj" \ "$(INTDIR)\mxcriticalsection.obj" \ + "$(INTDIR)\mxdsfile.obj" \ "$(INTDIR)\mxdsobject.obj" \ + "$(INTDIR)\mxdssource.obj" \ + "$(INTDIR)\mxioinfo.obj" \ "$(INTDIR)\mxomni.obj" \ "$(INTDIR)\mxomnicreateflags.obj" \ "$(INTDIR)\mxomnicreateparam.obj" \ @@ -181,7 +187,10 @@ CLEAN : -@erase "$(INTDIR)\mxautolocker.obj" -@erase "$(INTDIR)\mxcore.obj" -@erase "$(INTDIR)\mxcriticalsection.obj" + -@erase "$(INTDIR)\mxdsfile.obj" -@erase "$(INTDIR)\mxdsobject.obj" + -@erase "$(INTDIR)\mxdssource.obj" + -@erase "$(INTDIR)\mxioinfo.obj" -@erase "$(INTDIR)\mxomni.obj" -@erase "$(INTDIR)\mxomnicreateflags.obj" -@erase "$(INTDIR)\mxomnicreateparam.obj" @@ -260,7 +269,10 @@ LINK32_OBJS= \ "$(INTDIR)\mxautolocker.obj" \ "$(INTDIR)\mxcore.obj" \ "$(INTDIR)\mxcriticalsection.obj" \ + "$(INTDIR)\mxdsfile.obj" \ "$(INTDIR)\mxdsobject.obj" \ + "$(INTDIR)\mxdssource.obj" \ + "$(INTDIR)\mxioinfo.obj" \ "$(INTDIR)\mxomni.obj" \ "$(INTDIR)\mxomnicreateflags.obj" \ "$(INTDIR)\mxomnicreateparam.obj" \ @@ -524,7 +536,9 @@ DEP_CPP_LEGOO=\ ".\LEGO1\mxdsaction.h"\ ".\LEGO1\mxdsfile.h"\ ".\LEGO1\mxdsobject.h"\ + ".\LEGO1\mxdssource.h"\ ".\LEGO1\mxeventmanager.h"\ + ".\LEGO1\mxioinfo.h"\ ".\LEGO1\mxmusicmanager.h"\ ".\LEGO1\mxnotificationmanager.h"\ ".\LEGO1\mxobjectfactory.h"\ @@ -645,8 +659,11 @@ DEP_CPP_MXOMN=\ SOURCE=.\LEGO1\mxvideoparam.cpp DEP_CPP_MXVID=\ ".\LEGO1\legoinc.h"\ + ".\LEGO1\mxbool.h"\ + ".\LEGO1\mxcore.h"\ ".\LEGO1\mxpalette.h"\ ".\LEGO1\mxrect32.h"\ + ".\LEGO1\mxresult.h"\ ".\LEGO1\mxvariabletable.h"\ ".\LEGO1\mxvideoparam.h"\ ".\LEGO1\mxvideoparamflags.h"\ @@ -684,6 +701,7 @@ DEP_CPP_MXOMNI=\ ".\LEGO1\mxomnicreateparambase.h"\ ".\LEGO1\mxpalette.h"\ ".\LEGO1\mxrect32.h"\ + ".\LEGO1\mxresult.h"\ ".\LEGO1\mxstring.h"\ ".\LEGO1\mxvariabletable.h"\ ".\LEGO1\mxvideoparam.h"\ @@ -708,6 +726,7 @@ DEP_CPP_MXOMNIC=\ ".\LEGO1\mxomnicreateparambase.h"\ ".\LEGO1\mxpalette.h"\ ".\LEGO1\mxrect32.h"\ + ".\LEGO1\mxresult.h"\ ".\LEGO1\mxstring.h"\ ".\LEGO1\mxvariabletable.h"\ ".\LEGO1\mxvideoparam.h"\ @@ -773,7 +792,9 @@ DEP_CPP_LEGON=\ ".\LEGO1\mxdsaction.h"\ ".\LEGO1\mxdsfile.h"\ ".\LEGO1\mxdsobject.h"\ + ".\LEGO1\mxdssource.h"\ ".\LEGO1\mxeventmanager.h"\ + ".\LEGO1\mxioinfo.h"\ ".\LEGO1\mxmusicmanager.h"\ ".\LEGO1\mxnotificationmanager.h"\ ".\LEGO1\mxobjectfactory.h"\ @@ -842,6 +863,7 @@ DEP_CPP_MXUNK=\ ".\LEGO1\mxbool.h"\ ".\LEGO1\mxcore.h"\ ".\LEGO1\mxcriticalsection.h"\ + ".\LEGO1\mxresult.h"\ ".\LEGO1\mxunknown100dc6b0.h"\ @@ -861,6 +883,7 @@ DEP_CPP_MXVIDEO=\ ".\LEGO1\mxcriticalsection.h"\ ".\LEGO1\mxpalette.h"\ ".\LEGO1\mxrect32.h"\ + ".\LEGO1\mxresult.h"\ ".\LEGO1\mxunknown100dc6b0.h"\ ".\LEGO1\mxvariabletable.h"\ ".\LEGO1\mxvideomanager.h"\ @@ -878,13 +901,62 @@ DEP_CPP_MXVIDEO=\ SOURCE=.\LEGO1\mxpalette.cpp DEP_CPP_MXPAL=\ + ".\LEGO1\mxbool.h"\ + ".\LEGO1\mxcore.h"\ ".\LEGO1\mxpalette.h"\ + ".\LEGO1\mxresult.h"\ "$(INTDIR)\mxpalette.obj" : $(SOURCE) $(DEP_CPP_MXPAL) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\LEGO1\mxioinfo.cpp +DEP_CPP_MXIOI=\ + ".\LEGO1\mxioinfo.h"\ + + +"$(INTDIR)\mxioinfo.obj" : $(SOURCE) $(DEP_CPP_MXIOI) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\LEGO1\mxdsfile.cpp +DEP_CPP_MXDSF=\ + ".\LEGO1\mxbool.h"\ + ".\LEGO1\mxcore.h"\ + ".\LEGO1\mxdsfile.h"\ + ".\LEGO1\mxdssource.h"\ + ".\LEGO1\mxioinfo.h"\ + ".\LEGO1\mxstring.h"\ + + +"$(INTDIR)\mxdsfile.obj" : $(SOURCE) $(DEP_CPP_MXDSF) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\LEGO1\mxdssource.cpp +DEP_CPP_MXDSS=\ + ".\LEGO1\mxbool.h"\ + ".\LEGO1\mxcore.h"\ + ".\LEGO1\mxdssource.h"\ + + +"$(INTDIR)\mxdssource.obj" : $(SOURCE) $(DEP_CPP_MXDSS) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + # End Source File # End Target ################################################################################ @@ -944,7 +1016,9 @@ DEP_CPP_ISLE_=\ ".\LEGO1\mxdsaction.h"\ ".\LEGO1\mxdsfile.h"\ ".\LEGO1\mxdsobject.h"\ + ".\LEGO1\mxdssource.h"\ ".\LEGO1\mxeventmanager.h"\ + ".\LEGO1\mxioinfo.h"\ ".\LEGO1\mxmusicmanager.h"\ ".\LEGO1\mxnotificationmanager.h"\ ".\LEGO1\mxobjectfactory.h"\ @@ -982,25 +1056,34 @@ SOURCE=.\ISLE\main.cpp DEP_CPP_MAIN_=\ ".\ISLE\define.h"\ ".\ISLE\isle.h"\ + ".\ISLE\res\resource.h"\ ".\LEGO1\lego3dmanager.h"\ ".\LEGO1\lego3dview.h"\ + ".\LEGO1\legoanimationmanager.h"\ + ".\LEGO1\legobuildingmanager.h"\ ".\LEGO1\legoentity.h"\ ".\LEGO1\legogamestate.h"\ ".\LEGO1\legoinc.h"\ ".\LEGO1\legoinputmanager.h"\ + ".\LEGO1\legomodelpresenter.h"\ ".\LEGO1\legonavcontroller.h"\ ".\LEGO1\legoomni.h"\ + ".\LEGO1\legopartpresenter.h"\ ".\LEGO1\legoroi.h"\ ".\LEGO1\legovideomanager.h"\ + ".\LEGO1\legoworldpresenter.h"\ ".\LEGO1\mxatomid.h"\ ".\LEGO1\mxbackgroundaudiomanager.h"\ ".\LEGO1\mxbool.h"\ ".\LEGO1\mxcore.h"\ ".\LEGO1\mxcriticalsection.h"\ + ".\LEGO1\mxdirectdraw.h"\ ".\LEGO1\mxdsaction.h"\ ".\LEGO1\mxdsfile.h"\ ".\LEGO1\mxdsobject.h"\ + ".\LEGO1\mxdssource.h"\ ".\LEGO1\mxeventmanager.h"\ + ".\LEGO1\mxioinfo.h"\ ".\LEGO1\mxmusicmanager.h"\ ".\LEGO1\mxnotificationmanager.h"\ ".\LEGO1\mxobjectfactory.h"\ diff --git a/isle.mdp b/isle.mdp index 390064aa600f2bb5cc48156405e1040876938d6d..9449bd89ad80f94b71cded5a7863892a0bbb9186 100644 GIT binary patch literal 52224 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 l%ncu}wfH6?d2la(6J-hk&~VkBZg~GWIck%p zV+2mYH$)Sl*MtBeKnM^5ga9Ex2oM5<03kpK5CVh%Auz!RT$zTefBJk1{tkbJ(HD=W zK0O7{xz+t>;KqY)rx$yJ#IwTgM)WB3Bg+|dy@Bs`H}Bkif3+Ko`j+n|iQBgO{p$?r@<%tbO0}%p*03kpK5CVh%AwUQa0)zk|KnM^5gupQ)K>5Fung9D1d>g(4 z--YkN_u&WdBK+`}?U06lk_e>vKX%z~>E71noog>$d+3GhYu6sQzH1HK8EEA{s|SCo zpNZ%??v5AoP5`ae%bGl_mjHYG^f>~{3sa6Y%`sv(?OD){?N;mUgPGFS2EMx+S)mtL zi5G=gqk`UBChXfo&v)>H{yF!nCfvJL;0_Y(QPA$)GU4;W{xHdheA9$Ah#c4NBVKNp zU|WWs2Eqkctf@k~_lC)M*g_!@hSM;#Vz@ZM(Tsp8wVdb~0rMz|eMgw7HZZ|x+@SE0x~s`tT*5z302Rht&2u!6@+p zHa+c406AhS9C)QI#9*fTR_s~Z*kFhKGJ4dCPpBBUGe81T5wM~g_-TYzZgBh%r9ph5jmOsFUg*hC~|C+vKS;HjqBYO{x z#7xi3v^bXmq=l9Svn&=louvUl1#8~;sMRvyFFa=I^|-$8=mT8g-^P<_s)M#|L_mGe;%+!7~98ju#3rDja#fM8cJ?PJU)N zScO8oo(l3Th-5Ms3l$tO?;#--<}LUU3E{Nk;*u;uXT$Bgq2q@3XB|vbV>!`{#|A%# zg%e%{X~9{Mjv0JGlGZ)cB=by7FSOe|HO*N@v+iX1kp{{$DdoQBV%0<~kdtBA&PzUP zBIDx&ET1EPjx>N=C~9$PiI>&Y zH#O5@-A^?rc7_$FvWk{kC{8!4VX29@tZ`njVaRjA$lXWd&_D@EgWcKftT6|Lz;YtlyjaXx)mbg!^ROZx@(W;7CoSF=0IsPJp27PhKEA=+D z!1-)LZjiT(H1(RAS|*NPsiLWA5m8-d^0ZhhYjU_~b=8f&LA$4zo7Y%S99}r*GzjFb zc9?ir*;nh0bF60j8>naImNxD`q}>$H&9s~1cZxKa3hkz}oALmYc2nGZ+0_xX6QoLQo#xe z(gv%U;f|$+-Nv&bNRfmcCsuU=%JC;ma7wE5>@44N8VD9}Gl_<=jn`?_QjR=3dr`GD zsq|P@Y)mTpBTxV8B(aTB#7j)0`tGJu=qt!5bCI=uP&I)g&p&ej>N}une2fROkB+Df z^-ux!(NsC`C|)hjH9S$6uo6H0q1K49<90&Xar~f)+C(TjuH618JI<~%d{y~uI)11& zD>{B0T+pWDM|#$6|Mc-+|H<>f-OfS%+Nl5QB=mp%7=8u6hTlLJK7rrD@8HwPHF46c IhQK`h4@5i>LI3~& From 24ec7023bdfd3b455e58655570ab859f1e7e6b2e Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 27 Jun 2023 22:07:29 +0200 Subject: [PATCH 03/21] isle: match WndProc and re-arrange functions in `ISLE.EXE` (#45) * match WinProc * minor accuracy improvement * WndProc at 50% * fix WM_DISPLAYCHANGE branching * fix type * fix x/y comparison * WndProc 82% * 84% * 97% * rearrange functions to get close to the original * remove newline * inline no longer necessary * merge --- ISLE/define.cpp | 2 +- ISLE/define.h | 2 +- ISLE/isle.cpp | 563 +++++++++++++++++++++++++++++++++--- ISLE/isle.h | 217 +------------- ISLE/main.cpp | 311 -------------------- LEGO1/mxpalette.cpp | 0 LEGO1/mxunknown100dc6b0.cpp | 0 LEGO1/mxunknown100dc6b0.h | 0 LEGO1/mxvideomanager.cpp | 0 isle.mak | 122 ++------ isle.mdp | Bin 52224 -> 51200 bytes 11 files changed, 568 insertions(+), 649 deletions(-) delete mode 100644 ISLE/main.cpp mode change 100755 => 100644 LEGO1/mxpalette.cpp mode change 100755 => 100644 LEGO1/mxunknown100dc6b0.cpp mode change 100755 => 100644 LEGO1/mxunknown100dc6b0.h mode change 100755 => 100644 LEGO1/mxvideomanager.cpp diff --git a/ISLE/define.cpp b/ISLE/define.cpp index b5501b08..0a77efd9 100644 --- a/ISLE/define.cpp +++ b/ISLE/define.cpp @@ -28,7 +28,7 @@ int g_targetWidth = 640; int g_targetHeight = 480; // 0x410060 -unsigned int g_targetDepth = 16; +int g_targetDepth = 16; // 0x410064 int g_reqEnableRMDevice = 0; diff --git a/ISLE/define.h b/ISLE/define.h index 27a347b7..41f7de27 100644 --- a/ISLE/define.h +++ b/ISLE/define.h @@ -18,7 +18,7 @@ extern int g_rmDisabled; extern int g_waitingForTargetDepth; extern int g_targetWidth; extern int g_targetHeight; -extern unsigned int g_targetDepth; +extern int g_targetDepth; extern int g_reqEnableRMDevice; extern int g_startupDelay; extern long g_lastFrameTime; diff --git a/ISLE/isle.cpp b/ISLE/isle.cpp index 051572ef..efaa2564 100644 --- a/ISLE/isle.cpp +++ b/ISLE/isle.cpp @@ -1,4 +1,18 @@ #include "isle.h" +#include "define.h" + +#include + +#include "legoomni.h" +#include "legoanimationmanager.h" +#include "legobuildingmanager.h" +#include "legomodelpresenter.h" +#include "legopartpresenter.h" +#include "legoworldpresenter.h" +#include "mxdirectdraw.h" +#include "mxdsaction.h" + +#include "res/resource.h" // OFFSET: ISLE 0x401000 Isle::Isle() @@ -97,6 +111,459 @@ void Isle::Close() } } +// OFFSET: ISLE 0x4013b0 +BOOL Isle::SetupLegoOmni() +{ + BOOL result = FALSE; + char mediaPath[256]; + GetProfileStringA("LEGO Island", "MediaPath", "", mediaPath, sizeof(mediaPath)); + + BOOL failure = Lego()->Create(MxOmniCreateParam(mediaPath, (struct HWND__ *) m_windowHandle, m_videoParam, MxOmniCreateFlags())) == FAILURE; + if (!failure) { + VariableTable()->SetVariable("ACTOR_01", ""); + TickleManager()->vtable1c(VideoManager(), 10); + result = TRUE; + } + + return result; +} + +// OFFSET: ISLE 0x401560 +void Isle::SetupVideoFlags(BOOL fullScreen, BOOL flipSurfaces, BOOL backBuffers, + BOOL using8bit, BOOL using16bit, BOOL param_6, BOOL param_7, + BOOL wideViewAngle, char *deviceId) +{ + m_videoParam.flags().SetFullScreen(fullScreen); + m_videoParam.flags().SetFlipSurfaces(flipSurfaces); + m_videoParam.flags().SetBackBuffers(!backBuffers); + m_videoParam.flags().Set_f2bit0(!param_6); + m_videoParam.flags().Set_f1bit7(param_7); + m_videoParam.flags().SetWideViewAngle(wideViewAngle); + m_videoParam.flags().Set_f2bit1(1); + m_videoParam.SetDeviceName(deviceId); + if (using8bit) { + m_videoParam.flags().Set16Bit(0); + } + if (using16bit) { + m_videoParam.flags().Set16Bit(1); + } +} + +BOOL FindExistingInstance(void); +BOOL StartDirectSound(void); + +// OFFSET: ISLE 0x401610 +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) +{ + // Look for another instance, if we find one, bring it to the foreground instead + if (!FindExistingInstance()) { + return 0; + } + + // Attempt to create DirectSound instance + BOOL soundReady = FALSE; + for (int i = 0; i < 20; i++) { + if (StartDirectSound()) { + soundReady = TRUE; + break; + } + Sleep(500); + } + + // Throw error if sound unavailable + if (!soundReady) { + MessageBoxA(NULL, "\"LEGO\xAE Island\" is not detecting a DirectSound compatible sound card. Please quit all other applications and try again.", + "Lego Island Error", MB_OK); + return 0; + } + + // Create global app instance + g_isle = new Isle(); + + // Create window + if (g_isle->SetupWindow(hInstance, lpCmdLine) != SUCCESS) { + MessageBoxA(NULL, "\"LEGO\xAE Island\" failed to start. Please quit all other applications and try again.", "LEGO\xAE Island Error", MB_OK); + return 0; + } + + // Get reference to window + HWND window; + if (g_isle->m_windowHandle) { + window = g_isle->m_windowHandle; + } + + // Load accelerators (this call actually achieves nothing - there is no "AppAccel" resource in the original - but we'll keep this for authenticity) + // This line may actually be here because it's in DFVIEW, an example project that ships with + // MSVC420, and was such a clean example of a Win32 app, that it was later adapted + // into an "ExeSkeleton" sample for MSVC600. It's quite possible Mindscape derived + // this app from that example since they no longer had the luxury of the + // MFC AppWizard which we know they used for the frontend used during development (ISLEMFC.EXE, MAIN.EXE, et al.) + LoadAcceleratorsA(hInstance, "AppAccel"); + + MSG msg; + + while (!g_closed) { + while (!PeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE)) { + if (g_isle) { + g_isle->Tick(1); + } + } + + if (g_isle) { + g_isle->Tick(0); + } + + while (!g_closed) { + if (!PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) { + break; + } + + MSG nextMsg; + if (!g_isle + || !g_isle->m_windowHandle + || msg.message != WM_MOUSEMOVE + || !PeekMessageA(&nextMsg, NULL, 0, 0, PM_NOREMOVE) + || nextMsg.message != WM_MOUSEMOVE) { + TranslateMessage(&msg); + DispatchMessageA(&msg); + } + + if (g_reqEnableRMDevice) { + g_reqEnableRMDevice = 0; + VideoManager()->EnableRMDevice(); + g_rmDisabled = 0; + Lego()->vtable3c(); + } + + if (g_closed) { + break; + } + + if (g_mousedown == 0) { +LAB_00401bc7: + if (g_mousemoved) { + g_mousemoved = FALSE; + } + } else if (g_mousemoved) { + if (g_isle) { + g_isle->Tick(0); + } + goto LAB_00401bc7; + } + } + } + + DestroyWindow(window); + + return msg.wParam; +} + +// OFFSET: ISLE 0x401ca0 +BOOL FindExistingInstance(void) +{ + HWND hWnd = FindWindowA(WNDCLASS_NAME, WINDOW_TITLE); + if (hWnd) { + if (SetForegroundWindow(hWnd)) { + ShowWindow(hWnd, SW_RESTORE); + } + return 0; + } + return 1; +} + +// OFFSET: ISLE 0x401ce0 +BOOL StartDirectSound(void) +{ + LPDIRECTSOUND lpDS = NULL; + HRESULT ret = DirectSoundCreate(NULL, &lpDS, NULL); + if (ret == DS_OK && lpDS != NULL) { + lpDS->Release(); + return TRUE; + } + + return FALSE; +} + +// OFFSET: ISLE 0x401d20 +LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + NotificationId type; + unsigned char keyCode = 0; + + if (!g_isle) { + return DefWindowProcA(hWnd, uMsg, wParam, lParam); + } + + switch (uMsg) { + case WM_PAINT: + return DefWindowProcA(hWnd, uMsg, wParam, lParam); + case WM_ACTIVATE: + return DefWindowProcA(hWnd, uMsg, wParam, lParam); + case WM_ACTIVATEAPP: + if (g_isle) { + if ((wParam != 0) && (g_isle->m_fullScreen)) { + MoveWindow(hWnd, g_windowRect.left, g_windowRect.top, + (g_windowRect.right - g_windowRect.left) + 1, + (g_windowRect.bottom - g_windowRect.top) + 1, TRUE); + } + g_isle->m_windowActive = wParam; + } + return DefWindowProcA(hWnd,uMsg,wParam,lParam); + case WM_CLOSE: + if (!g_closed && g_isle) { + if (g_isle) { + delete g_isle; + } + g_isle = NULL; + g_closed = TRUE; + return 0; + } + return DefWindowProcA(hWnd,uMsg,wParam,lParam); + case WM_GETMINMAXINFO: + ((MINMAXINFO*) lParam)->ptMaxTrackSize.x = (g_windowRect.right - g_windowRect.left) + 1; + ((MINMAXINFO*) lParam)->ptMaxTrackSize.y = (g_windowRect.bottom - g_windowRect.top) + 1; + ((MINMAXINFO*) lParam)->ptMinTrackSize.x = (g_windowRect.right - g_windowRect.left) + 1; + ((MINMAXINFO*) lParam)->ptMinTrackSize.y = (g_windowRect.bottom - g_windowRect.top) + 1; + return 0; + case WM_ENTERMENULOOP: + return DefWindowProcA(hWnd,uMsg,wParam,lParam); + case WM_SYSCOMMAND: + if (wParam == SC_SCREENSAVE) { + return 0; + } + if (wParam == SC_CLOSE && g_closed == 0) { + if (g_isle) { + if (g_rmDisabled) { + ShowWindow(g_isle->m_windowHandle, SW_RESTORE); + } + PostMessageA(g_isle->m_windowHandle, WM_CLOSE, 0, 0); + return 0; + } + } else if (g_isle && g_isle->m_fullScreen && (wParam == SC_MOVE || wParam == SC_KEYMENU)) { + return 0; + } + return DefWindowProcA(hWnd,uMsg,wParam,lParam); + case WM_EXITMENULOOP: + return DefWindowProcA(hWnd, uMsg, wParam, lParam); + case WM_MOVING: + if (g_isle && g_isle->m_fullScreen) { + GetWindowRect(hWnd, (LPRECT) lParam); + return 0; + } + return DefWindowProcA(hWnd, uMsg, wParam, lParam); + case WM_NCPAINT: + if (g_isle && g_isle->m_fullScreen) { + return 0; + } + return DefWindowProcA(hWnd, uMsg, wParam, lParam); + case WM_DISPLAYCHANGE: + if (g_isle && VideoManager() && g_isle->m_fullScreen && VideoManager()->m_unk74 && VideoManager()->m_unk74[0x220]) { + int targetWidth = LOWORD(lParam); + int targetHeight = HIWORD(lParam); + int targetDepth = wParam; + + if (g_waitingForTargetDepth) { + g_waitingForTargetDepth = 0; + g_targetDepth = targetDepth; + } + else { + BOOL valid = FALSE; + if (targetWidth == g_targetWidth && targetHeight == g_targetHeight && g_targetDepth == targetDepth) { + valid = TRUE; + } + + if (g_rmDisabled) { + if (valid) { + g_reqEnableRMDevice = 1; + } + } + else if (!valid) { + g_rmDisabled = 1; + Lego()->vtable38(); + VideoManager()->DisableRMDevice(); + } + } + } + return DefWindowProcA(hWnd, uMsg, wParam, lParam); + case WM_SETCURSOR: + if (g_isle) { + HCURSOR hCursor = g_isle->m_cursorCurrent; + if (hCursor == g_isle->m_cursorBusy || hCursor == g_isle->m_cursorNo || !hCursor) { + SetCursor(hCursor); + return 0; + } + } + break; + case WM_KEYDOWN: + // While this probably should be (HIWORD(lParam) & KF_REPEAT), this seems + // to be what the assembly is actually doing + if (lParam & (KF_REPEAT << 16)) { + return DefWindowProcA(hWnd, uMsg, wParam, lParam); + } + keyCode = wParam; + type = KEYDOWN; + break; + case WM_MOUSEMOVE: + g_mousemoved = 1; + type = MOUSEMOVE; + break; + case WM_TIMER: + type = TIMER; + break; + case WM_LBUTTONDOWN: + g_mousedown = 1; + type = MOUSEDOWN; + break; + case WM_LBUTTONUP: + g_mousedown = 0; + type = MOUSEUP; + break; + case 0x5400: + if (g_isle) { + g_isle->SetupCursor(wParam); + return 0; + } + break; + default: + return DefWindowProcA(hWnd,uMsg,wParam,lParam); + } + + if (g_isle) { + if (InputManager()) { + InputManager()->QueueEvent(type, wParam, LOWORD(lParam), HIWORD(lParam), keyCode); + } + if (g_isle && g_isle->m_drawCursor && type == MOUSEMOVE) { + int x = LOWORD(lParam); + int y = HIWORD(lParam); + if (x >= 640) { + x = 639; + } + if (y >= 480) { + y = 479; + } + VideoManager()->MoveCursor(x,y); + } + } + + return 0; +} + +// OFFSET: ISLE 0x4023e0 +MxResult Isle::SetupWindow(HINSTANCE hInstance, LPSTR lpCmdLine) +{ + WNDCLASSA wndclass; + ZeroMemory(&wndclass, sizeof(WNDCLASSA)); + + LoadConfig(); + + SetupVideoFlags(m_fullScreen, m_flipSurfaces, m_backBuffersInVram, m_using8bit, + m_using16bit, m_unk24, FALSE, m_wideViewAngle, m_deviceId); + + MxOmni::SetSound3D(m_use3dSound); + + srand(timeGetTime() / 1000); + SystemParametersInfoA(SPI_SETMOUSETRAILS, 0, NULL, 0); + + ZeroMemory(&wndclass, sizeof(WNDCLASSA)); + + wndclass.cbClsExtra = 0; + wndclass.style = CS_HREDRAW | CS_VREDRAW; + wndclass.lpfnWndProc = WndProc; + wndclass.cbWndExtra = 0; + wndclass.hIcon = LoadIconA(hInstance, MAKEINTRESOURCEA(APP_ICON)); + wndclass.hCursor = m_cursorArrow = m_cursorCurrent = LoadCursorA(hInstance, MAKEINTRESOURCEA(ISLE_ARROW)); + m_cursorBusy = LoadCursorA(hInstance, MAKEINTRESOURCEA(ISLE_BUSY)); + m_cursorNo = LoadCursorA(hInstance, MAKEINTRESOURCEA(ISLE_NO)); + wndclass.hInstance = hInstance; + wndclass.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH); + wndclass.lpszClassName = WNDCLASS_NAME; + + if (!RegisterClassA(&wndclass)) { + return FAILURE; + } + + if (m_fullScreen) { + AdjustWindowRectEx(&g_windowRect, WS_CAPTION | WS_SYSMENU, 0, WS_EX_APPWINDOW); + + m_windowHandle = CreateWindowExA( + WS_EX_APPWINDOW, + WNDCLASS_NAME, + WINDOW_TITLE, + WS_CAPTION | WS_SYSMENU, + g_windowRect.left, + g_windowRect.top, + g_windowRect.right - g_windowRect.left + 1, + g_windowRect.bottom - g_windowRect.top + 1, + NULL, NULL, hInstance, NULL + ); + } else { + AdjustWindowRectEx(&g_windowRect, WS_CAPTION | WS_SYSMENU, 0, WS_EX_APPWINDOW); + + m_windowHandle = CreateWindowExA( + WS_EX_APPWINDOW, + WNDCLASS_NAME, + WINDOW_TITLE, + WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX, + CW_USEDEFAULT, + CW_USEDEFAULT, + g_windowRect.right - g_windowRect.left + 1, + g_windowRect.bottom - g_windowRect.top + 1, + NULL, NULL, hInstance, NULL + ); + } + + if (!m_windowHandle) { + return FAILURE; + } + + if (m_fullScreen) { + MoveWindow(m_windowHandle, g_windowRect.left, g_windowRect.top, (g_windowRect.right - g_windowRect.left) + 1, (g_windowRect.bottom - g_windowRect.top) + 1, TRUE); + } + + ShowWindow(m_windowHandle, SW_SHOWNORMAL); + UpdateWindow(m_windowHandle); + if (!SetupLegoOmni()) { + return FAILURE; + } + + GameState()->SetSavePath(m_savePath); + GameState()->SerializePlayersInfo(1); + GameState()->SerializeScoreHistory(1); + + int iVar10; + switch (m_islandQuality) { + case 0: + iVar10 = 1; + break; + case 1: + iVar10 = 2; + break; + default: + iVar10 = 100; + } + + int uVar1 = (m_islandTexture == 0); + LegoModelPresenter::configureLegoModelPresenter(uVar1); + LegoPartPresenter::configureLegoPartPresenter(uVar1,iVar10); + LegoWorldPresenter::configureLegoWorldPresenter(m_islandQuality); + LegoBuildingManager::configureLegoBuildingManager(m_islandQuality); + LegoROI::configureLegoROI(iVar10); + LegoAnimationManager::configureLegoAnimationManager(m_islandQuality); + if (LegoOmni::GetInstance()) { + if (LegoOmni::GetInstance()->GetInputManager()) { + LegoOmni::GetInstance()->GetInputManager()->m_useJoystick = m_useJoystick; + LegoOmni::GetInstance()->GetInputManager()->m_joystickIndex = m_joystickIndex; + } + } + if (m_fullScreen) { + MoveWindow(m_windowHandle, g_windowRect.left, g_windowRect.top, (g_windowRect.right - g_windowRect.left) + 1, (g_windowRect.bottom - g_windowRect.top) + 1, TRUE); + } + ShowWindow(m_windowHandle, SW_SHOWNORMAL); + UpdateWindow(m_windowHandle); + + return SUCCESS; +} + // OFFSET: ISLE 0x402740 BOOL Isle::ReadReg(LPCSTR name, LPSTR outValue, DWORD outSize) { @@ -216,42 +683,72 @@ void Isle::LoadConfig() } } -// OFFSET: ISLE 0x401560 -void Isle::SetupVideoFlags(BOOL fullScreen, BOOL flipSurfaces, BOOL backBuffers, - BOOL using8bit, BOOL using16bit, BOOL param_6, BOOL param_7, - BOOL wideViewAngle, char *deviceId) +// OFFSET: ISLE 0x402c20 +inline void Isle::Tick(BOOL sleepIfNotNextFrame) { - m_videoParam.flags().SetFullScreen(fullScreen); - m_videoParam.flags().SetFlipSurfaces(flipSurfaces); - m_videoParam.flags().SetBackBuffers(!backBuffers); - m_videoParam.flags().Set_f2bit0(!param_6); - m_videoParam.flags().Set_f1bit7(param_7); - m_videoParam.flags().SetWideViewAngle(wideViewAngle); - m_videoParam.flags().Set_f2bit1(1); - m_videoParam.SetDeviceName(deviceId); - if (using8bit) { - m_videoParam.flags().Set16Bit(0); - } - if (using16bit) { - m_videoParam.flags().Set16Bit(1); - } -} - -// OFFSET: ISLE 0x4013b0 -BOOL Isle::SetupLegoOmni() -{ - BOOL result = FALSE; - char mediaPath[256]; - GetProfileStringA("LEGO Island", "MediaPath", "", mediaPath, sizeof(mediaPath)); - - BOOL failure = Lego()->Create(MxOmniCreateParam(mediaPath, (struct HWND__ *) m_windowHandle, m_videoParam, MxOmniCreateFlags())) == FAILURE; - if (!failure) { - VariableTable()->SetVariable("ACTOR_01", ""); - TickleManager()->vtable1c(VideoManager(), 10); - result = TRUE; + if (!this->m_windowActive) { + Sleep(0); + return; } - return result; + if (!Lego()) return; + if (!TickleManager()) return; + if (!Timer()) return; + + long currentTime = Timer()->GetRealTime(); + if (currentTime < g_lastFrameTime) { + g_lastFrameTime = -this->m_frameDelta; + } + + if (this->m_frameDelta + g_lastFrameTime < currentTime) { + if (!Lego()->vtable40()) { + TickleManager()->Tickle(); + } + g_lastFrameTime = currentTime; + + if (g_startupDelay == 0) { + return; + } + + g_startupDelay--; + if (g_startupDelay != 0) { + return; + } + + LegoOmni::GetInstance()->CreateBackgroundAudio(); + BackgroundAudioManager()->Enable(this->m_useMusic); + + MxStreamController *stream = Streamer()->Open("\\lego\\scripts\\isle\\isle", 0); + MxDSAction ds; + + if (!stream) { + stream = Streamer()->Open("\\lego\\scripts\\nocd", 0); + if (!stream) { + return; + } + + ds.SetAtomId(stream->atom); + ds.SetUnknown24(-1); + ds.SetUnknown1c(0); + VideoManager()->EnableFullScreenMovie(TRUE, TRUE); + + if (Start(&ds) != SUCCESS) { + return; + } + } else { + ds.SetAtomId(stream->atom); + ds.SetUnknown24(-1); + ds.SetUnknown1c(0); + if (Start(&ds) != SUCCESS) { + return; + } + this->m_gameStarted = 1; + } + return; + } + + if (sleepIfNotNextFrame != 0) + Sleep(0); } // OFFSET: ISLE 0x402e80 diff --git a/ISLE/isle.h b/ISLE/isle.h index d899d037..d45d33a3 100644 --- a/ISLE/isle.h +++ b/ISLE/isle.h @@ -2,20 +2,9 @@ #define ISLE_H #include "legoinc.h" -#include "define.h" -#include "legoomni.h" -#include "legoanimationmanager.h" -#include "legobuildingmanager.h" -#include "legomodelpresenter.h" -#include "legopartpresenter.h" -#include "legoworldpresenter.h" #include "mxresult.h" #include "mxvideoparam.h" -#include "mxdirectdraw.h" -#include "mxdsaction.h" -#include "mxomni.h" -#include "res/resource.h" class Isle { @@ -25,24 +14,21 @@ class Isle void Close(); + BOOL SetupLegoOmni(); + void SetupVideoFlags(BOOL fullScreen, BOOL flipSurfaces, BOOL backBuffers, + BOOL using8bit, BOOL using16bit, BOOL param_6, BOOL param_7, + BOOL wideViewAngle, char *deviceId); + MxResult SetupWindow(HINSTANCE hInstance, LPSTR lpCmdLine); + BOOL ReadReg(LPCSTR name, LPSTR outValue, DWORD outSize); int ReadRegBool(LPCSTR name, BOOL *out); int ReadRegInt(LPCSTR name, int *out); - MxResult SetupWindow(HINSTANCE hInstance, LPSTR lpCmdLine); - - void Tick(BOOL sleepIfNotNextFrame); - - BOOL SetupLegoOmni(); void LoadConfig(); - void SetupVideoFlags(BOOL fullScreen, BOOL flipSurfaces, BOOL backBuffers, - BOOL using8bit, BOOL using16bit, BOOL param_6, BOOL param_7, - BOOL wideViewAngle, char *deviceId); - + void Tick(BOOL sleepIfNotNextFrame); void SetupCursor(WPARAM wParam); -// private: - + // private: // 0 LPSTR m_hdPath; LPSTR m_cdPath; @@ -85,193 +71,6 @@ class Isle HCURSOR m_cursorBusy; HCURSOR m_cursorNo; HCURSOR m_cursorCurrent; - }; -extern LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); - -// OFFSET: ISLE 0x4023e0 -inline MxResult Isle::SetupWindow(HINSTANCE hInstance, LPSTR lpCmdLine) -{ - WNDCLASSA wndclass; - ZeroMemory(&wndclass, sizeof(WNDCLASSA)); - - LoadConfig(); - - SetupVideoFlags(m_fullScreen, m_flipSurfaces, m_backBuffersInVram, m_using8bit, - m_using16bit, m_unk24, FALSE, m_wideViewAngle, m_deviceId); - - MxOmni::SetSound3D(m_use3dSound); - - srand(timeGetTime() / 1000); - SystemParametersInfoA(SPI_SETMOUSETRAILS, 0, NULL, 0); - - ZeroMemory(&wndclass, sizeof(WNDCLASSA)); - - wndclass.cbClsExtra = 0; - wndclass.style = CS_HREDRAW | CS_VREDRAW; - wndclass.lpfnWndProc = WndProc; - wndclass.cbWndExtra = 0; - wndclass.hIcon = LoadIconA(hInstance, MAKEINTRESOURCEA(APP_ICON)); - wndclass.hCursor = m_cursorArrow = m_cursorCurrent = LoadCursorA(hInstance, MAKEINTRESOURCEA(ISLE_ARROW)); - m_cursorBusy = LoadCursorA(hInstance, MAKEINTRESOURCEA(ISLE_BUSY)); - m_cursorNo = LoadCursorA(hInstance, MAKEINTRESOURCEA(ISLE_NO)); - wndclass.hInstance = hInstance; - wndclass.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH); - wndclass.lpszClassName = WNDCLASS_NAME; - - if (!RegisterClassA(&wndclass)) { - return FAILURE; - } - - if (m_fullScreen) { - AdjustWindowRectEx(&g_windowRect, WS_CAPTION | WS_SYSMENU, 0, WS_EX_APPWINDOW); - - m_windowHandle = CreateWindowExA( - WS_EX_APPWINDOW, - WNDCLASS_NAME, - WINDOW_TITLE, - WS_CAPTION | WS_SYSMENU, - g_windowRect.left, - g_windowRect.top, - g_windowRect.right - g_windowRect.left + 1, - g_windowRect.bottom - g_windowRect.top + 1, - NULL, NULL, hInstance, NULL - ); - } else { - AdjustWindowRectEx(&g_windowRect, WS_CAPTION | WS_SYSMENU, 0, WS_EX_APPWINDOW); - - m_windowHandle = CreateWindowExA( - WS_EX_APPWINDOW, - WNDCLASS_NAME, - WINDOW_TITLE, - WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX, - CW_USEDEFAULT, - CW_USEDEFAULT, - g_windowRect.right - g_windowRect.left + 1, - g_windowRect.bottom - g_windowRect.top + 1, - NULL, NULL, hInstance, NULL - ); - } - - if (!m_windowHandle) { - return FAILURE; - } - - if (m_fullScreen) { - MoveWindow(m_windowHandle, g_windowRect.left, g_windowRect.top, (g_windowRect.right - g_windowRect.left) + 1, (g_windowRect.bottom - g_windowRect.top) + 1, TRUE); - } - - ShowWindow(m_windowHandle, SW_SHOWNORMAL); - UpdateWindow(m_windowHandle); - if (!SetupLegoOmni()) { - return FAILURE; - } - - GameState()->SetSavePath(m_savePath); - GameState()->SerializePlayersInfo(1); - GameState()->SerializeScoreHistory(1); - - int iVar10; - switch (m_islandQuality) { - case 0: - iVar10 = 1; - break; - case 1: - iVar10 = 2; - break; - default: - iVar10 = 100; - } - - int uVar1 = (m_islandTexture == 0); - LegoModelPresenter::configureLegoModelPresenter(uVar1); - LegoPartPresenter::configureLegoPartPresenter(uVar1,iVar10); - LegoWorldPresenter::configureLegoWorldPresenter(m_islandQuality); - LegoBuildingManager::configureLegoBuildingManager(m_islandQuality); - LegoROI::configureLegoROI(iVar10); - LegoAnimationManager::configureLegoAnimationManager(m_islandQuality); - if (LegoOmni::GetInstance()) { - if (LegoOmni::GetInstance()->GetInputManager()) { - LegoOmni::GetInstance()->GetInputManager()->m_useJoystick = m_useJoystick; - LegoOmni::GetInstance()->GetInputManager()->m_joystickIndex = m_joystickIndex; - } - } - if (m_fullScreen) { - MoveWindow(m_windowHandle, g_windowRect.left, g_windowRect.top, (g_windowRect.right - g_windowRect.left) + 1, (g_windowRect.bottom - g_windowRect.top) + 1, TRUE); - } - ShowWindow(m_windowHandle, SW_SHOWNORMAL); - UpdateWindow(m_windowHandle); - - return SUCCESS; -} - -// OFFSET: ISLE 0x402c20 -inline void Isle::Tick(BOOL sleepIfNotNextFrame) -{ - if (!this->m_windowActive) { - Sleep(0); - return; - } - - if (!Lego()) return; - if (!TickleManager()) return; - if (!Timer()) return; - - long currentTime = Timer()->GetRealTime(); - if (currentTime < g_lastFrameTime) { - g_lastFrameTime = -this->m_frameDelta; - } - - if (this->m_frameDelta + g_lastFrameTime < currentTime) { - if (!Lego()->vtable40()) { - TickleManager()->Tickle(); - } - g_lastFrameTime = currentTime; - - if (g_startupDelay == 0) { - return; - } - - g_startupDelay--; - if (g_startupDelay != 0) { - return; - } - - LegoOmni::GetInstance()->CreateBackgroundAudio(); - BackgroundAudioManager()->Enable(this->m_useMusic); - - MxStreamController *stream = Streamer()->Open("\\lego\\scripts\\isle\\isle", 0); - MxDSAction ds; - - if (!stream) { - stream = Streamer()->Open("\\lego\\scripts\\nocd", 0); - if (!stream) { - return; - } - - ds.SetAtomId(stream->atom); - ds.SetUnknown24(-1); - ds.SetUnknown1c(0); - VideoManager()->EnableFullScreenMovie(TRUE, TRUE); - - if (Start(&ds) != SUCCESS) { - return; - } - } else { - ds.SetAtomId(stream->atom); - ds.SetUnknown24(-1); - ds.SetUnknown1c(0); - if (Start(&ds) != SUCCESS) { - return; - } - this->m_gameStarted = 1; - } - return; - } - - if (sleepIfNotNextFrame != 0) - Sleep(0); -} - #endif // ISLE_H diff --git a/ISLE/main.cpp b/ISLE/main.cpp deleted file mode 100644 index f45e9529..00000000 --- a/ISLE/main.cpp +++ /dev/null @@ -1,311 +0,0 @@ -#include - -#include "legoinc.h" -#include "define.h" - -#include "legoomni.h" -#include "isle.h" - -// OFFSET: ISLE 0x401ca0 -BOOL FindExistingInstance(void) -{ - HWND hWnd = FindWindowA(WNDCLASS_NAME, WINDOW_TITLE); - if (hWnd) { - if (SetForegroundWindow(hWnd)) { - ShowWindow(hWnd, SW_RESTORE); - } - return 0; - } - return 1; -} - -// OFFSET: ISLE 0x401ce0 -BOOL StartDirectSound(void) -{ - LPDIRECTSOUND lpDS = NULL; - HRESULT ret = DirectSoundCreate(NULL, &lpDS, NULL); - if (ret == DS_OK && lpDS != NULL) { - lpDS->Release(); - return TRUE; - } - - return FALSE; -} - -// OFFSET: ISLE 0x401610 -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) -{ - // Look for another instance, if we find one, bring it to the foreground instead - if (!FindExistingInstance()) { - return 0; - } - - // Attempt to create DirectSound instance - BOOL soundReady = FALSE; - for (int i = 0; i < 20; i++) { - if (StartDirectSound()) { - soundReady = TRUE; - break; - } - Sleep(500); - } - - // Throw error if sound unavailable - if (!soundReady) { - MessageBoxA(NULL, "\"LEGO\xAE Island\" is not detecting a DirectSound compatible sound card. Please quit all other applications and try again.", - "Lego Island Error", MB_OK); - return 0; - } - - // Create global app instance - g_isle = new Isle(); - - // Create window - if (g_isle->SetupWindow(hInstance, lpCmdLine) != SUCCESS) { - MessageBoxA(NULL, "\"LEGO\xAE Island\" failed to start. Please quit all other applications and try again.", "LEGO\xAE Island Error", MB_OK); - return 0; - } - - // Get reference to window - HWND window; - if (g_isle->m_windowHandle) { - window = g_isle->m_windowHandle; - } - - // Load accelerators (this call actually achieves nothing - there is no "AppAccel" resource in the original - but we'll keep this for authenticity) - // This line may actually be here because it's in DFVIEW, an example project that ships with - // MSVC420, and was such a clean example of a Win32 app, that it was later adapted - // into an "ExeSkeleton" sample for MSVC600. It's quite possible Mindscape derived - // this app from that example since they no longer had the luxury of the - // MFC AppWizard which we know they used for the frontend used during development (ISLEMFC.EXE, MAIN.EXE, et al.) - LoadAcceleratorsA(hInstance, "AppAccel"); - - MSG msg; - - while (!g_closed) { - while (!PeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE)) { - if (g_isle) { - g_isle->Tick(1); - } - } - - if (g_isle) { - g_isle->Tick(0); - } - - while (!g_closed) { - if (!PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) { - break; - } - - MSG nextMsg; - if (!g_isle - || !g_isle->m_windowHandle - || msg.message != WM_MOUSEMOVE - || !PeekMessageA(&nextMsg, NULL, 0, 0, PM_NOREMOVE) - || nextMsg.message != WM_MOUSEMOVE) { - TranslateMessage(&msg); - DispatchMessageA(&msg); - } - - if (g_reqEnableRMDevice) { - g_reqEnableRMDevice = 0; - VideoManager()->EnableRMDevice(); - g_rmDisabled = 0; - Lego()->vtable3c(); - } - - if (g_closed) { - break; - } - - if (g_mousedown == 0) { -LAB_00401bc7: - if (g_mousemoved) { - g_mousemoved = FALSE; - } - } else if (g_mousemoved) { - if (g_isle) { - g_isle->Tick(0); - } - goto LAB_00401bc7; - } - } - } - - DestroyWindow(window); - - return msg.wParam; -} - -// OFFSET: ISLE 0x401d20 -LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - if (!g_isle) { - return DefWindowProcA(hWnd, uMsg, wParam, lParam); - } - - switch (uMsg) { - case WM_PAINT: - return DefWindowProcA(hWnd, WM_PAINT, wParam, lParam); - case WM_ACTIVATE: - return DefWindowProcA(hWnd, WM_ACTIVATE, wParam, lParam); - case WM_ACTIVATEAPP: - if (g_isle) { - if ((wParam != 0) && (g_isle->m_fullScreen)) { - MoveWindow(hWnd, g_windowRect.left, g_windowRect.top, - (g_windowRect.right - g_windowRect.left) + 1, - (g_windowRect.bottom - g_windowRect.top) + 1, TRUE); - } - g_isle->m_windowActive = wParam; - } - return DefWindowProcA(hWnd,WM_ACTIVATEAPP,wParam,lParam); - case WM_CLOSE: - if (!g_closed && g_isle) { - if (g_isle) { - delete g_isle; - } - g_isle = NULL; - g_closed = TRUE; - return 0; - } - return DefWindowProcA(hWnd,WM_CLOSE,wParam,lParam); - case WM_GETMINMAXINFO: - { - MINMAXINFO *mmi = (MINMAXINFO *) lParam; - - mmi->ptMaxTrackSize.x = (g_windowRect.right - g_windowRect.left) + 1; - mmi->ptMaxTrackSize.y = (g_windowRect.bottom - g_windowRect.top) + 1; - mmi->ptMinTrackSize.x = (g_windowRect.right - g_windowRect.left) + 1; - mmi->ptMinTrackSize.y = (g_windowRect.bottom - g_windowRect.top) + 1; - - return 0; - } - case WM_ENTERMENULOOP: - return DefWindowProcA(hWnd,WM_ENTERMENULOOP,wParam,lParam); - case WM_SYSCOMMAND: - if (wParam == SC_SCREENSAVE) { - return 0; - } - if (wParam == SC_CLOSE && g_closed == 0) { - if (g_isle) { - if (g_rmDisabled) { - ShowWindow(g_isle->m_windowHandle, SW_RESTORE); - } - PostMessageA(g_isle->m_windowHandle, WM_CLOSE, 0, 0); - return 0; - } - } else if (g_isle && g_isle->m_fullScreen && (wParam == SC_MOVE || wParam == SC_KEYMENU)) { - return 0; - } - return DefWindowProcA(hWnd,WM_SYSCOMMAND,wParam,lParam); - case WM_EXITMENULOOP: - return DefWindowProcA(hWnd, WM_EXITMENULOOP, wParam, lParam); - case WM_MOVING: - if (g_isle && g_isle->m_fullScreen) { - GetWindowRect(hWnd, (LPRECT) lParam); - return 0; - } - return DefWindowProcA(hWnd, WM_MOVING, wParam, lParam); - case WM_NCPAINT: - if (g_isle && g_isle->m_fullScreen) { - return 0; - } - return DefWindowProcA(hWnd, WM_NCPAINT, wParam, lParam); - case WM_DISPLAYCHANGE: - if (g_isle && VideoManager() && g_isle->m_fullScreen && VideoManager()->m_unk74 && VideoManager()->m_unk74[0x220]) { - if (!g_waitingForTargetDepth) { - unsigned char valid = FALSE; - if (LOWORD(lParam) == g_targetWidth && HIWORD(lParam) == g_targetHeight && g_targetDepth == wParam) { - valid = TRUE; - } - if (!g_rmDisabled) { - if (!valid) { - g_rmDisabled = 1; - Lego()->vtable38(); - VideoManager()->DisableRMDevice(); - } - } else if (valid) { - g_reqEnableRMDevice = 1; - } - } else { - g_waitingForTargetDepth = 0; - g_targetDepth = wParam; - } - } - return DefWindowProcA(hWnd, WM_DISPLAYCHANGE, wParam, lParam); - case WM_SETCURSOR: - case WM_KEYDOWN: - case WM_MOUSEMOVE: - case WM_TIMER: - case WM_LBUTTONDOWN: - case WM_LBUTTONUP: - case 0x5400: - { - - NotificationId type = NONE; - unsigned char keyCode = 0; - - switch (uMsg) { - case WM_KEYDOWN: - // While this probably should be (HIWORD(lParam) & KF_REPEAT), this seems - // to be what the assembly is actually doing - if (lParam & (KF_REPEAT << 16)) { - return DefWindowProcA(hWnd, WM_KEYDOWN, wParam, lParam); - } - keyCode = wParam; - type = KEYDOWN; - break; - case WM_MOUSEMOVE: - g_mousemoved = 1; - type = MOUSEMOVE; - break; - case WM_TIMER: - type = TIMER; - break; - case WM_SETCURSOR: - if (g_isle) { - HCURSOR hCursor = g_isle->m_cursorCurrent; - if (hCursor == g_isle->m_cursorBusy || hCursor == g_isle->m_cursorNo || !hCursor) { - SetCursor(hCursor); - return 0; - } - } - break; - case WM_LBUTTONDOWN: - g_mousedown = 1; - type = MOUSEDOWN; - break; - case WM_LBUTTONUP: - g_mousedown = 0; - type = MOUSEUP; - break; - case 0x5400: - if (g_isle) { - g_isle->SetupCursor(wParam); - return 0; - } - } - - if (g_isle) { - if (InputManager()) { - InputManager()->QueueEvent(type, wParam, LOWORD(lParam), HIWORD(lParam), keyCode); - } - if (g_isle && g_isle->m_drawCursor && type == MOUSEMOVE) { - unsigned short x = LOWORD(lParam); - unsigned short y = HIWORD(lParam); - if (639 < x) { - x = 639; - } - if (479 < y) { - y = 479; - } - VideoManager()->MoveCursor(x,y); - } - } - return 0; - } - } - - return DefWindowProcA(hWnd,uMsg,wParam,lParam); -} \ No newline at end of file diff --git a/LEGO1/mxpalette.cpp b/LEGO1/mxpalette.cpp old mode 100755 new mode 100644 diff --git a/LEGO1/mxunknown100dc6b0.cpp b/LEGO1/mxunknown100dc6b0.cpp old mode 100755 new mode 100644 diff --git a/LEGO1/mxunknown100dc6b0.h b/LEGO1/mxunknown100dc6b0.h old mode 100755 new mode 100644 diff --git a/LEGO1/mxvideomanager.cpp b/LEGO1/mxvideomanager.cpp old mode 100755 new mode 100644 diff --git a/isle.mak b/isle.mak index 7eaf3d48..23583c29 100644 --- a/isle.mak +++ b/isle.mak @@ -311,7 +311,6 @@ CLEAN : -@erase "$(INTDIR)\define.obj" -@erase "$(INTDIR)\isle.obj" -@erase "$(INTDIR)\isle.res" - -@erase "$(INTDIR)\main.obj" -@erase "$(INTDIR)\vc40.pdb" -@erase ".\Release\ISLE.EXE" -@erase ".\Release\ISLE.PDB" @@ -372,7 +371,6 @@ LINK32_OBJS= \ "$(INTDIR)\define.obj" \ "$(INTDIR)\isle.obj" \ "$(INTDIR)\isle.res" \ - "$(INTDIR)\main.obj" \ ".\Release\LEGO1.LIB" ".\Release\ISLE.EXE" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) @@ -401,7 +399,6 @@ CLEAN : -@erase "$(INTDIR)\define.obj" -@erase "$(INTDIR)\isle.obj" -@erase "$(INTDIR)\isle.res" - -@erase "$(INTDIR)\main.obj" -@erase "$(INTDIR)\vc40.idb" -@erase "$(INTDIR)\vc40.pdb" -@erase ".\Debug\ISLE.EXE" @@ -464,7 +461,6 @@ LINK32_OBJS= \ "$(INTDIR)\define.obj" \ "$(INTDIR)\isle.obj" \ "$(INTDIR)\isle.res" \ - "$(INTDIR)\main.obj" \ ".\LEGO1\Debug\LEGO1.lib" ".\Debug\ISLE.EXE" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) @@ -917,6 +913,7 @@ DEP_CPP_MXPAL=\ SOURCE=.\LEGO1\mxioinfo.cpp DEP_CPP_MXIOI=\ + ".\LEGO1\legoinc.h"\ ".\LEGO1\mxioinfo.h"\ @@ -930,6 +927,7 @@ DEP_CPP_MXIOI=\ SOURCE=.\LEGO1\mxdsfile.cpp DEP_CPP_MXDSF=\ + ".\LEGO1\legoinc.h"\ ".\LEGO1\mxbool.h"\ ".\LEGO1\mxcore.h"\ ".\LEGO1\mxdsfile.h"\ @@ -974,19 +972,6 @@ DEP_CPP_MXDSS=\ ################################################################################ # Begin Source File -SOURCE=.\ISLE\define.cpp -DEP_CPP_DEFIN=\ - ".\ISLE\define.h"\ - - -"$(INTDIR)\define.obj" : $(SOURCE) $(DEP_CPP_DEFIN) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -# End Source File -################################################################################ -# Begin Source File - SOURCE=.\ISLE\isle.cpp DEP_CPP_ISLE_=\ ".\ISLE\define.h"\ @@ -1048,71 +1033,6 @@ DEP_CPP_ISLE_=\ $(CPP) $(CPP_PROJ) $(SOURCE) -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\ISLE\main.cpp -DEP_CPP_MAIN_=\ - ".\ISLE\define.h"\ - ".\ISLE\isle.h"\ - ".\ISLE\res\resource.h"\ - ".\LEGO1\lego3dmanager.h"\ - ".\LEGO1\lego3dview.h"\ - ".\LEGO1\legoanimationmanager.h"\ - ".\LEGO1\legobuildingmanager.h"\ - ".\LEGO1\legoentity.h"\ - ".\LEGO1\legogamestate.h"\ - ".\LEGO1\legoinc.h"\ - ".\LEGO1\legoinputmanager.h"\ - ".\LEGO1\legomodelpresenter.h"\ - ".\LEGO1\legonavcontroller.h"\ - ".\LEGO1\legoomni.h"\ - ".\LEGO1\legopartpresenter.h"\ - ".\LEGO1\legoroi.h"\ - ".\LEGO1\legovideomanager.h"\ - ".\LEGO1\legoworldpresenter.h"\ - ".\LEGO1\mxatomid.h"\ - ".\LEGO1\mxbackgroundaudiomanager.h"\ - ".\LEGO1\mxbool.h"\ - ".\LEGO1\mxcore.h"\ - ".\LEGO1\mxcriticalsection.h"\ - ".\LEGO1\mxdirectdraw.h"\ - ".\LEGO1\mxdsaction.h"\ - ".\LEGO1\mxdsfile.h"\ - ".\LEGO1\mxdsobject.h"\ - ".\LEGO1\mxdssource.h"\ - ".\LEGO1\mxeventmanager.h"\ - ".\LEGO1\mxioinfo.h"\ - ".\LEGO1\mxmusicmanager.h"\ - ".\LEGO1\mxnotificationmanager.h"\ - ".\LEGO1\mxobjectfactory.h"\ - ".\LEGO1\mxomni.h"\ - ".\LEGO1\mxomnicreateflags.h"\ - ".\LEGO1\mxomnicreateparam.h"\ - ".\LEGO1\mxomnicreateparambase.h"\ - ".\LEGO1\mxpalette.h"\ - ".\LEGO1\mxrect32.h"\ - ".\LEGO1\mxresult.h"\ - ".\LEGO1\mxsoundmanager.h"\ - ".\LEGO1\mxstreamcontroller.h"\ - ".\LEGO1\mxstreamer.h"\ - ".\LEGO1\mxstring.h"\ - ".\LEGO1\mxticklemanager.h"\ - ".\LEGO1\mxtimer.h"\ - ".\LEGO1\mxtransitionmanager.h"\ - ".\LEGO1\mxunknown100dc6b0.h"\ - ".\LEGO1\mxvariabletable.h"\ - ".\LEGO1\mxvideomanager.h"\ - ".\LEGO1\mxvideoparam.h"\ - ".\LEGO1\mxvideoparamflags.h"\ - ".\LEGO1\viewmanager.h"\ - - -"$(INTDIR)\main.obj" : $(SOURCE) $(DEP_CPP_MAIN_) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - # End Source File ################################################################################ # Begin Source File @@ -1262,18 +1182,6 @@ SOURCE=.\LEGO1\legoworldpresenter.h ################################################################################ # Begin Source File -SOURCE=.\LEGO1\mxatomid.h - -!IF "$(CFG)" == "ISLE - Win32 Release" - -!ELSEIF "$(CFG)" == "ISLE - Win32 Debug" - -!ENDIF - -# End Source File -################################################################################ -# Begin Source File - SOURCE=.\LEGO1\mxbackgroundaudiomanager.h !IF "$(CFG)" == "ISLE - Win32 Release" @@ -1553,6 +1461,32 @@ SOURCE=.\LEGO1\mxvideoparamflags.h !ENDIF # End Project Dependency +################################################################################ +# Begin Source File + +SOURCE=.\LEGO1\mxatomid.h + +!IF "$(CFG)" == "ISLE - Win32 Release" + +!ELSEIF "$(CFG)" == "ISLE - Win32 Debug" + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\ISLE\define.cpp +DEP_CPP_DEFIN=\ + ".\ISLE\define.h"\ + ".\LEGO1\legoinc.h"\ + + +"$(INTDIR)\define.obj" : $(SOURCE) $(DEP_CPP_DEFIN) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +# End Source File # End Target # End Project ################################################################################ diff --git a/isle.mdp b/isle.mdp index 9449bd89ad80f94b71cded5a7863892a0bbb9186..d9512305a07494826c1af13a85dc6a272fbd5283 100644 GIT binary patch literal 51200 zcmeHQTX!7A5w69OBgqC|B-vnY!nqLwi!R21xg=OJjvW!ef;b5x$?VKXJ7_LCv$OL0 zJr6qk4*mfTye4_gpWvA%{sF1(x%EtU&rS=+ilx#ymiEYBbyt5=eW|LR((R3#izi?L z9Dv7wzK$IOKhW2)X5ianJ$f4apW$V&;W9i4jEg7ucVgxEFd%Mt-yff0(?~N0Cg3Nc z3D9R^fEXYKhyh}N7$63S0b+m{AO?s5Vt^Pp!VG*f0bl?7iwXEA`~$wdxIcM$=JM*b z%})nzJlI_A$KD|EtZ;KJx)=J9BR)ft$E6VS6X?cv zr}OT3p|t9N?`}s{=ml2dMPXihp#P4EcyH+Wju&nh(yyCHZ(D&oNbtS>ZvUEzoEPp6 zlcLMFO+r7Pspz2 zy9t}*ttVSBV$82B8;T5ue$s7k_Q7b7U|EsCj>064e4nic2G2PaHd;h@kGNcR`){_V zFY)Xh-z}EA)=Nk*N?*5VzoMf=Y=r}_vL6^|x@X0n)x(F)z8Ot5zHnuh)p~u+s^)O9 z%%Tk}EUSFeZ^0+ul^u7>3*B^IhFQKT6r25;+Z%3+TfKoEd|BeVed{SDl(gw|T3amJ z?)jR*J8Qko2O~R1i?A(!fOC?qYh3<~_6A(7q|@oN9%pXBZO=k^F{N^p23iUxXi88i znwp`he7P{EQ-I6A*Ph^-d=Jl^=|gI58^ywOaMceobY_yFwI?jVynmBDdJy%#K)W;^ zZ&~=N(=nI}!*D0W3SLW#i;jJ@x0rU@`iv&m`Ra6DYyX_{jg*sQ@NCO!T?WfVaV9Z; zB!g%e+xb#?zTy^1DHZ-jujJaXmBPN<=GN_i^W>_&QB*fir|Lnxtt@stuFGt8G{DXVBX0)Po1jw~)&yZnS!w*W=6$pJ9DfZx~qxon`#=s^Z|vwmF(_ zNDb|u3P$--+JM4`kY||nopVr{Q`Up<$)kCMZPueXzE9Q?&iaj(i;0Te3n$Hn2KgdCOgy~aq96C<)ZE(byRc$Mjj<$-5$|>@V9(_t1m+pax4BhO zha#-OM5G(sDv66?Clw!9j_nm85Y~G2rnai-XT+xKx3g6OMT|{!g=ICK7TZP7LA-^n zYWAFn&zxtu)ym-N=S~@38C?B_wMvW2xfV^%wA@d@NqLi6)%sbX^(6ZFeHQyEk|ebIj`cEFbS!aJ4mLO@vXHf5YJrqbUW z1Is;58CIB6?imUf=kWX|3kckcuA~eU^eml88TM3ZK$1Htql+meIFvG~SdBC;r7R(6 zA-Rb%S}@hpsbj}w87f#!32m^NNuKcTVD0xjQBwv;<%CEXLX&$&s_OZ4g???kz3iHD zgFA4NXP6oQGq~lXH~1Pr4?GNeLAQbF;>q)x?MsJ$;BnqI(Q2bu@EjYFya(zA^gjq4 z^CqR;Qm4QJ4>WTEiF$oqXT=?wI!>UZZGW)#MU#5a!g2Wtw0=UFHr zyF_7d`@TR2g~5wdrN9b>!7*HV$YJpIfonR-==L-^%8bu~(@`e9sYOQ_ysjeb0sQnd z-oK%YzGvgh(Udo6%B)dFUwjv`!M8b@8U6GqBYtN$Wa*0-AO?s5Vt^PR28aP-;Ak`O zYhyh}N7$6211Ft|AUWG+if@N5NEASdzh1cN? zcoVL{Tktl#1Mk9b;J5G|T!&RygB$QZ+=So3Ew~N8hjsV>{s14sNANM+ferWsK7~KR zUHB7``$#bGGGN`uM?zClk{BQchyh}N7$63S0b+m{AO?s5Vt^PR27WvP{O>juxr0D9&HtGuVXB;ji#F_&Zq8`|+kkEj%&|Ov8Tx4SnN| literal 52224 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 l%ncu}wfH6?d Date: Tue, 27 Jun 2023 15:59:44 -0700 Subject: [PATCH 04/21] generate progress SVGs --- .github/workflows/build.yml | 6 ++- tools/reccmp/isle.png | Bin 0 -> 5448 bytes tools/reccmp/lego1.png | Bin 0 -> 5615 bytes tools/reccmp/reccmp.py | 60 ++++++++++++++++++++++++++++- tools/reccmp/template.svg | 74 ++++++++++++++++++++++++++++++++++++ 5 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 tools/reccmp/isle.png create mode 100755 tools/reccmp/lego1.png create mode 100644 tools/reccmp/template.svg diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index afa88865..295d88f3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -61,8 +61,8 @@ jobs: C:\msys64\usr\bin\wget.exe https://legoisland.org/download/LEGO1.DLL pip install capstone pip install colorama - python3 tools/reccmp/reccmp.py -H ISLEPROGRESS.HTML ISLE.EXE Release/ISLE.EXE Release/ISLE.PDB . - python3 tools/reccmp/reccmp.py -H LEGO1PROGRESS.HTML LEGO1.DLL Release/LEGO1.DLL Release/LEGO1.PDB . + python3 tools/reccmp/reccmp.py -S ISLEPROGRESS.SVG --svg-icon tools/reccmp/isle.png -H ISLEPROGRESS.HTML ISLE.EXE Release/ISLE.EXE Release/ISLE.PDB . + python3 tools/reccmp/reccmp.py -S LEGO1PROGRESS.SVG -T 1929 --svg-icon tools/reccmp/lego1.png -H LEGO1PROGRESS.HTML LEGO1.DLL Release/LEGO1.DLL Release/LEGO1.PDB . - name: Upload Artifact uses: actions/upload-artifact@master @@ -72,3 +72,5 @@ jobs: Release ISLEPROGRESS.HTML LEGO1PROGRESS.HTML + ISLEPROGRESS.SVG + LEGO1PROGRESS.SVG diff --git a/tools/reccmp/isle.png b/tools/reccmp/isle.png new file mode 100644 index 0000000000000000000000000000000000000000..cfa26a234f1eeb4d65808b0097e809eb5bfd6ba7 GIT binary patch literal 5448 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 literal 0 HcmV?d00001 diff --git a/tools/reccmp/lego1.png b/tools/reccmp/lego1.png new file mode 100755 index 0000000000000000000000000000000000000000..f76a54da16876d4bbb51cbff06e8a9c93df60aa6 GIT binary patch literal 5615 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 literal 0 HcmV?d00001 diff --git a/tools/reccmp/reccmp.py b/tools/reccmp/reccmp.py index 777cce2f..d50dc9ae 100755 --- a/tools/reccmp/reccmp.py +++ b/tools/reccmp/reccmp.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import argparse +import base64 from capstone import * import difflib import struct @@ -15,9 +16,12 @@ parser.add_argument('recompiled', metavar='recompiled-binary', help='The recompiled binary') parser.add_argument('pdb', metavar='recompiled-pdb', help='The PDB of the recompiled binary') parser.add_argument('decomp_dir', metavar='decomp-dir', help='The decompiled source tree') +parser.add_argument('--total', '-T', metavar='total-func-count', help='Total number of expected functions (improves total accuracy statistic)') parser.add_argument('--verbose', '-v', metavar='offset', help='Print assembly diff for specific function (original file\'s offset)') parser.add_argument('--html', '-H', metavar='output-file', help='Generate searchable HTML summary of status and diffs') parser.add_argument('--no-color', '-n', action='store_true', help='Do not color the output') +parser.add_argument('--svg', '-S', metavar='output-svg', help='Generate SVG graphic of progress') +parser.add_argument('--svg-icon', metavar='svg-icon', help='Icon to use in SVG (PNG)') args = parser.parse_args() @@ -50,6 +54,8 @@ if not os.path.isdir(source): parser.error('Source directory does not exist') +svg = args.svg + # Declare a class that can automatically convert virtual executable addresses # to file addresses class Bin: @@ -365,7 +371,8 @@ def parse_asm(file, addr, size): # If html, record the diffs to an HTML file if html: - htmlinsert.append('{address: "%s", name: "%s", matching: %s, diff: "%s"}' % (hex(addr), recinfo.name, str(ratio), '\\n'.join(udiff).replace('"', '\\"').replace('\n', '\\n'))) + escaped = '\\n'.join(udiff).replace('"', '\\"').replace('\n', '\\n').replace('<', '<').replace('>', '>') + htmlinsert.append('{address: "%s", name: "%s", matching: %s, diff: "%s"}' % (hex(addr), recinfo.name, str(ratio), escape)) except UnicodeDecodeError: break @@ -389,6 +396,49 @@ def gen_html(html, data): htmlfile.write(templatedata) htmlfile.close() +def gen_svg(svg, name, icon, implemented_funcs, total_funcs, raw_accuracy): + templatefile = open(get_file_in_script_dir('template.svg'), 'r') + if not templatefile: + print('Failed to find SVG template file, can\'t generate SVG summary') + return + + templatedata = templatefile.read() + templatefile.close() + + # Replace icon + if args.svg_icon: + iconfile = open(args.svg_icon, 'rb') + templatedata = templatedata.replace('{icon}', base64.b64encode(iconfile.read()).decode('utf-8'), 1) + iconfile.close() + + # Replace name + templatedata = templatedata.replace('{name}', name, 1) + + # Replace implemented statistic + templatedata = templatedata.replace('{implemented}', '%.2f%% (%i/%i)' % (implemented_funcs / total_funcs * 100, implemented_funcs, total_funcs), 1) + + # Replace accuracy statistic + templatedata = templatedata.replace('{accuracy}', '%.2f%%' % (raw_accuracy / implemented_funcs * 100), 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:] + + # Replace percentage statistic + templatedata = templatedata.replace('{percent}', '%.2f%%' % (total_statistic * 100), 1) + + svgfile = open(svg, 'w') + if not svgfile: + print('Failed to write to SVG file %s' % svg) + return + + svgfile.write(templatedata) + svgfile.close() + if html: gen_html(html, htmlinsert) @@ -396,5 +446,13 @@ def gen_html(html, data): if not found_verbose_target: print('Failed to find the function with address %s' % hex(verbose)) else: + implemented_funcs = function_count + + if args.total: + function_count = int(args.total) + if function_count > 0: print('\nTotal accuracy %.2f%% across %i functions' % (total_accuracy / function_count * 100, function_count)) + + if svg: + gen_svg(svg, os.path.basename(original), args.svg_icon, implemented_funcs, function_count, total_accuracy) diff --git a/tools/reccmp/template.svg b/tools/reccmp/template.svg new file mode 100644 index 00000000..cb37b94c --- /dev/null +++ b/tools/reccmp/template.svg @@ -0,0 +1,74 @@ + + + +{name}{percent}Implemented: {implemented}Accuracy: {accuracy} From 4a1e3a5b7e0c0d2ce85c9f27ea213884c25c636f Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue, 27 Jun 2023 16:01:49 -0700 Subject: [PATCH 05/21] reccmp: fixed typo --- tools/reccmp/reccmp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/reccmp/reccmp.py b/tools/reccmp/reccmp.py index d50dc9ae..3368bb72 100755 --- a/tools/reccmp/reccmp.py +++ b/tools/reccmp/reccmp.py @@ -372,7 +372,7 @@ def parse_asm(file, addr, size): # If html, record the diffs to an HTML file if html: escaped = '\\n'.join(udiff).replace('"', '\\"').replace('\n', '\\n').replace('<', '<').replace('>', '>') - htmlinsert.append('{address: "%s", name: "%s", matching: %s, diff: "%s"}' % (hex(addr), recinfo.name, str(ratio), escape)) + htmlinsert.append('{address: "%s", name: "%s", matching: %s, diff: "%s"}' % (hex(addr), recinfo.name, str(ratio), escaped)) except UnicodeDecodeError: break From f9e9723a67425abd3b296c3f49878b680d6d53bb Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue, 27 Jun 2023 16:12:04 -0700 Subject: [PATCH 06/21] reccmp: give svg template background color --- tools/reccmp/template.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/reccmp/template.svg b/tools/reccmp/template.svg index cb37b94c..6f7fac79 100644 --- a/tools/reccmp/template.svg +++ b/tools/reccmp/template.svg @@ -16,7 +16,7 @@ y="538.62568" width="480.69626" height="32.696293" - id="rect1277" /> Date: Tue, 27 Jun 2023 16:12:11 -0700 Subject: [PATCH 07/21] ci: upload release --- .github/workflows/build.yml | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 295d88f3..bd2884ba 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,7 +29,7 @@ jobs: if: steps.cache-dx5.outputs.cache-hit != 'true' run: | cd dx5sdk - C:\msys64\usr\bin\wget.exe https://archive.org/download/idx5sdk/idx5sdk.exe + curl -fLOSs https://archive.org/download/idx5sdk/idx5sdk.exe 7z x .\idx5sdk.exe 7z x .\DX5SDK.EXE @@ -57,8 +57,8 @@ jobs: - name: Summarize Accuracy shell: cmd run: | - C:\msys64\usr\bin\wget.exe https://legoisland.org/download/ISLE.EXE - C:\msys64\usr\bin\wget.exe https://legoisland.org/download/LEGO1.DLL + curl -fLOSs https://legoisland.org/download/ISLE.EXE + curl -fLOSs https://legoisland.org/download/LEGO1.DLL pip install capstone pip install colorama python3 tools/reccmp/reccmp.py -S ISLEPROGRESS.SVG --svg-icon tools/reccmp/isle.png -H ISLEPROGRESS.HTML ISLE.EXE Release/ISLE.EXE Release/ISLE.PDB . @@ -74,3 +74,15 @@ jobs: LEGO1PROGRESS.HTML ISLEPROGRESS.SVG LEGO1PROGRESS.SVG + + - name: Upload Continuous Release + shell: bash + run: | + curl -fLOSs https://raw.githubusercontent.com/probonopd/uploadtool/master/upload.sh + ./upload.sh \ + Release/ISLE.EXE \ + Release/LEGO1.DLL \ + Release/ISLEPROGRESS.HTML \ + Release/ISLEPROGRESS.SVG \ + Release/LEGO1PROGRESS.HTML \ + Release/LEGO1PROGRESS.SVG From b2bd8bc766f68c9651e6eae2a0d8038b518204ad Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue, 27 Jun 2023 16:15:38 -0700 Subject: [PATCH 08/21] ci: fix typo --- .github/workflows/build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bd2884ba..656fa600 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -82,7 +82,7 @@ jobs: ./upload.sh \ Release/ISLE.EXE \ Release/LEGO1.DLL \ - Release/ISLEPROGRESS.HTML \ - Release/ISLEPROGRESS.SVG \ - Release/LEGO1PROGRESS.HTML \ - Release/LEGO1PROGRESS.SVG + ISLEPROGRESS.HTML \ + ISLEPROGRESS.SVG \ + LEGO1PROGRESS.HTML \ + LEGO1PROGRESS.SVG From 883720941ac7a34d9dc403429c6e3822f8d87700 Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue, 27 Jun 2023 16:25:26 -0700 Subject: [PATCH 09/21] ci: provide GITHUB_TOKEN as env --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 656fa600..4fb71936 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -77,6 +77,8 @@ jobs: - name: Upload Continuous Release shell: bash + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | curl -fLOSs https://raw.githubusercontent.com/probonopd/uploadtool/master/upload.sh ./upload.sh \ From 066b7311ad57d40517caac9737fbf9b5ef1564d4 Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue, 27 Jun 2023 17:10:11 -0700 Subject: [PATCH 10/21] rename Isle to IsleApp --- ISLE/define.cpp | 2 +- ISLE/define.h | 4 ++-- ISLE/isle.cpp | 28 ++++++++++++++-------------- ISLE/isle.h | 6 +++--- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/ISLE/define.cpp b/ISLE/define.cpp index 0a77efd9..f236ea29 100644 --- a/ISLE/define.cpp +++ b/ISLE/define.cpp @@ -1,7 +1,7 @@ #include "define.h" // 0x410030 -Isle *g_isle = 0; +IsleApp *g_isle = 0; // 0x410034 unsigned char g_mousedown = 0; diff --git a/ISLE/define.h b/ISLE/define.h index 41f7de27..4da8666d 100644 --- a/ISLE/define.h +++ b/ISLE/define.h @@ -3,9 +3,9 @@ #include "legoinc.h" -class Isle; +class IsleApp; -extern Isle *g_isle; +extern IsleApp *g_isle; extern int g_closed; // 0x4101c4 #define WNDCLASS_NAME "Lego Island MainNoM App" diff --git a/ISLE/isle.cpp b/ISLE/isle.cpp index efaa2564..ab4d7efd 100644 --- a/ISLE/isle.cpp +++ b/ISLE/isle.cpp @@ -15,7 +15,7 @@ #include "res/resource.h" // OFFSET: ISLE 0x401000 -Isle::Isle() +IsleApp::IsleApp() { m_hdPath = NULL; m_cdPath = NULL; @@ -52,7 +52,7 @@ Isle::Isle() } // OFFSET: ISLE 0x4011a0 -Isle::~Isle() +IsleApp::~IsleApp() { if (LegoOmni::GetInstance()) { Close(); @@ -77,7 +77,7 @@ Isle::~Isle() } // OFFSET: ISLE 0x401260 -void Isle::Close() +void IsleApp::Close() { MxDSAction ds; ds.SetUnknown24(-2); @@ -112,7 +112,7 @@ void Isle::Close() } // OFFSET: ISLE 0x4013b0 -BOOL Isle::SetupLegoOmni() +BOOL IsleApp::SetupLegoOmni() { BOOL result = FALSE; char mediaPath[256]; @@ -129,7 +129,7 @@ BOOL Isle::SetupLegoOmni() } // OFFSET: ISLE 0x401560 -void Isle::SetupVideoFlags(BOOL fullScreen, BOOL flipSurfaces, BOOL backBuffers, +void IsleApp::SetupVideoFlags(BOOL fullScreen, BOOL flipSurfaces, BOOL backBuffers, BOOL using8bit, BOOL using16bit, BOOL param_6, BOOL param_7, BOOL wideViewAngle, char *deviceId) { @@ -178,7 +178,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine } // Create global app instance - g_isle = new Isle(); + g_isle = new IsleApp(); // Create window if (g_isle->SetupWindow(hInstance, lpCmdLine) != SUCCESS) { @@ -449,7 +449,7 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } // OFFSET: ISLE 0x4023e0 -MxResult Isle::SetupWindow(HINSTANCE hInstance, LPSTR lpCmdLine) +MxResult IsleApp::SetupWindow(HINSTANCE hInstance, LPSTR lpCmdLine) { WNDCLASSA wndclass; ZeroMemory(&wndclass, sizeof(WNDCLASSA)); @@ -565,7 +565,7 @@ MxResult Isle::SetupWindow(HINSTANCE hInstance, LPSTR lpCmdLine) } // OFFSET: ISLE 0x402740 -BOOL Isle::ReadReg(LPCSTR name, LPSTR outValue, DWORD outSize) +BOOL IsleApp::ReadReg(LPCSTR name, LPSTR outValue, DWORD outSize) { HKEY hKey; DWORD valueType; @@ -584,7 +584,7 @@ BOOL Isle::ReadReg(LPCSTR name, LPSTR outValue, DWORD outSize) } // OFFSET: ISLE 0x4027b0 -int Isle::ReadRegBool(LPCSTR name, BOOL *out) +int IsleApp::ReadRegBool(LPCSTR name, BOOL *out) { char buffer[256]; @@ -606,7 +606,7 @@ int Isle::ReadRegBool(LPCSTR name, BOOL *out) } // OFFSET: ISLE 0x402880 -int Isle::ReadRegInt(LPCSTR name, int *out) +int IsleApp::ReadRegInt(LPCSTR name, int *out) { char buffer[256]; @@ -619,7 +619,7 @@ int Isle::ReadRegInt(LPCSTR name, int *out) } // OFFSET: ISLE 0x4028d0 -void Isle::LoadConfig() +void IsleApp::LoadConfig() { char buffer[1024]; @@ -684,7 +684,7 @@ void Isle::LoadConfig() } // OFFSET: ISLE 0x402c20 -inline void Isle::Tick(BOOL sleepIfNotNextFrame) +inline void IsleApp::Tick(BOOL sleepIfNotNextFrame) { if (!this->m_windowActive) { Sleep(0); @@ -752,7 +752,7 @@ inline void Isle::Tick(BOOL sleepIfNotNextFrame) } // OFFSET: ISLE 0x402e80 -void Isle::SetupCursor(WPARAM wParam) +void IsleApp::SetupCursor(WPARAM wParam) { switch (wParam) { case 0: @@ -778,4 +778,4 @@ void Isle::SetupCursor(WPARAM wParam) } SetCursor(m_cursorCurrent); -} \ No newline at end of file +} diff --git a/ISLE/isle.h b/ISLE/isle.h index d45d33a3..1aad487f 100644 --- a/ISLE/isle.h +++ b/ISLE/isle.h @@ -6,11 +6,11 @@ #include "mxresult.h" #include "mxvideoparam.h" -class Isle +class IsleApp { public: - Isle(); - ~Isle(); + IsleApp(); + ~IsleApp(); void Close(); From 5915cc3ea26696f23ef0cdb0a87134ac1d614a79 Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue, 27 Jun 2023 17:17:26 -0700 Subject: [PATCH 11/21] ci: try converting SVG to PNG --- .github/workflows/build.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4fb71936..167b4561 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -63,6 +63,8 @@ jobs: pip install colorama python3 tools/reccmp/reccmp.py -S ISLEPROGRESS.SVG --svg-icon tools/reccmp/isle.png -H ISLEPROGRESS.HTML ISLE.EXE Release/ISLE.EXE Release/ISLE.PDB . python3 tools/reccmp/reccmp.py -S LEGO1PROGRESS.SVG -T 1929 --svg-icon tools/reccmp/lego1.png -H LEGO1PROGRESS.HTML LEGO1.DLL Release/LEGO1.DLL Release/LEGO1.PDB . + convert ISLEPROGRESS.SVG ISLEPROGRESS.PNG + convert LEGO1PROGRESS.SVG LEGO1PROGRESS.PNG - name: Upload Artifact uses: actions/upload-artifact@master @@ -74,6 +76,8 @@ jobs: LEGO1PROGRESS.HTML ISLEPROGRESS.SVG LEGO1PROGRESS.SVG + ISLEPROGRESS.PNG + LEGO1PROGRESS.PNG - name: Upload Continuous Release shell: bash @@ -86,5 +90,7 @@ jobs: Release/LEGO1.DLL \ ISLEPROGRESS.HTML \ ISLEPROGRESS.SVG \ + ISLEPROGRESS.PNG \ LEGO1PROGRESS.HTML \ + LEGO1PROGRESS.PNG \ LEGO1PROGRESS.SVG From 0191c6560beae0bb26a3cfc5499d096272772cbc Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue, 27 Jun 2023 17:26:30 -0700 Subject: [PATCH 12/21] ci: attempt to use inkscape to produce PNGs --- .github/workflows/build.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 167b4561..7e66cdcf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -63,8 +63,10 @@ jobs: pip install colorama python3 tools/reccmp/reccmp.py -S ISLEPROGRESS.SVG --svg-icon tools/reccmp/isle.png -H ISLEPROGRESS.HTML ISLE.EXE Release/ISLE.EXE Release/ISLE.PDB . python3 tools/reccmp/reccmp.py -S LEGO1PROGRESS.SVG -T 1929 --svg-icon tools/reccmp/lego1.png -H LEGO1PROGRESS.HTML LEGO1.DLL Release/LEGO1.DLL Release/LEGO1.PDB . - convert ISLEPROGRESS.SVG ISLEPROGRESS.PNG - convert LEGO1PROGRESS.SVG LEGO1PROGRESS.PNG + + #pacman -Sy mingw-w64-x86_64-inkscape + inkscape -w 1024 ISLEPROGRESS.SVG -o ISLEPROGRESS.PNG + inkscape -w 1024 LEGO1PROGRESS.SVG -o LEGO1PROGRESS.PNG - name: Upload Artifact uses: actions/upload-artifact@master From a3887f554d73f8655bdd4d552f3969ce282b62ab Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue, 27 Jun 2023 17:28:46 -0700 Subject: [PATCH 13/21] ci: attempt installing inkscape --- .github/workflows/build.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7e66cdcf..7f1b95ad 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -63,10 +63,6 @@ jobs: pip install colorama python3 tools/reccmp/reccmp.py -S ISLEPROGRESS.SVG --svg-icon tools/reccmp/isle.png -H ISLEPROGRESS.HTML ISLE.EXE Release/ISLE.EXE Release/ISLE.PDB . python3 tools/reccmp/reccmp.py -S LEGO1PROGRESS.SVG -T 1929 --svg-icon tools/reccmp/lego1.png -H LEGO1PROGRESS.HTML LEGO1.DLL Release/LEGO1.DLL Release/LEGO1.PDB . - - #pacman -Sy mingw-w64-x86_64-inkscape - inkscape -w 1024 ISLEPROGRESS.SVG -o ISLEPROGRESS.PNG - inkscape -w 1024 LEGO1PROGRESS.SVG -o LEGO1PROGRESS.PNG - name: Upload Artifact uses: actions/upload-artifact@master @@ -78,14 +74,16 @@ jobs: LEGO1PROGRESS.HTML ISLEPROGRESS.SVG LEGO1PROGRESS.SVG - ISLEPROGRESS.PNG - LEGO1PROGRESS.PNG - name: Upload Continuous Release shell: bash env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | + pacman -Sy mingw-w64-x86_64-inkscape + inkscape -w 1024 ISLEPROGRESS.SVG -o ISLEPROGRESS.PNG + inkscape -w 1024 LEGO1PROGRESS.SVG -o LEGO1PROGRESS.PNG + curl -fLOSs https://raw.githubusercontent.com/probonopd/uploadtool/master/upload.sh ./upload.sh \ Release/ISLE.EXE \ From dd3ce5ac613dea723c84dac94db3af0b32d10cf3 Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue, 27 Jun 2023 17:31:46 -0700 Subject: [PATCH 14/21] ci: attempt to install inkscape through msys2 --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7f1b95ad..df651c1b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -80,9 +80,9 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - pacman -Sy mingw-w64-x86_64-inkscape - inkscape -w 1024 ISLEPROGRESS.SVG -o ISLEPROGRESS.PNG - inkscape -w 1024 LEGO1PROGRESS.SVG -o LEGO1PROGRESS.PNG + /c/msys64/usr/bin/pacman -Sy mingw-w64-x86_64-inkscape + /c/msys64/mingw64/bin/inkscape -w 1024 ISLEPROGRESS.SVG -o ISLEPROGRESS.PNG + /c/msys64/mingw64/bin/inkscape -w 1024 LEGO1PROGRESS.SVG -o LEGO1PROGRESS.PNG curl -fLOSs https://raw.githubusercontent.com/probonopd/uploadtool/master/upload.sh ./upload.sh \ From 4ba4352058c21c09f850d71efb8126d3eb649901 Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue, 27 Jun 2023 17:38:37 -0700 Subject: [PATCH 15/21] ci: pacman noconfirm --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index df651c1b..bf64b158 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -80,7 +80,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - /c/msys64/usr/bin/pacman -Sy mingw-w64-x86_64-inkscape + /c/msys64/usr/bin/pacman -Sy --noconfirm mingw-w64-x86_64-inkscape /c/msys64/mingw64/bin/inkscape -w 1024 ISLEPROGRESS.SVG -o ISLEPROGRESS.PNG /c/msys64/mingw64/bin/inkscape -w 1024 LEGO1PROGRESS.SVG -o LEGO1PROGRESS.PNG From 40fdc5b2f56d96224813143dfdbb82b4c876ae44 Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue, 27 Jun 2023 17:42:07 -0700 Subject: [PATCH 16/21] ci: use alternative download --- .github/workflows/build.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bf64b158..a51b9395 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -80,9 +80,12 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - /c/msys64/usr/bin/pacman -Sy --noconfirm mingw-w64-x86_64-inkscape - /c/msys64/mingw64/bin/inkscape -w 1024 ISLEPROGRESS.SVG -o ISLEPROGRESS.PNG - /c/msys64/mingw64/bin/inkscape -w 1024 LEGO1PROGRESS.SVG -o LEGO1PROGRESS.PNG + # Convert SVGs to PNG + INKSCAPE_DIR=inkscape-1.2.2_2022-12-09_732a01da63-x64 + curl -fLOSs https://inkscape.org/gallery/item/37364/$INKSCAPE_DIR.7z + 7z x $INKSCAPE_DIR.7z + $INKSCAPE_DIR/bin/inkscape -w 1024 ISLEPROGRESS.SVG -o ISLEPROGRESS.PNG + $INKSCAPE_DIR/bin/inkscape -w 1024 LEGO1PROGRESS.SVG -o LEGO1PROGRESS.PNG curl -fLOSs https://raw.githubusercontent.com/probonopd/uploadtool/master/upload.sh ./upload.sh \ From f03cee6b6e1c200cc82f54abd3bb605fe079bf83 Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue, 27 Jun 2023 18:00:53 -0700 Subject: [PATCH 17/21] reccmp: improve progress bar text rendering --- tools/reccmp/reccmp.py | 2 +- tools/reccmp/template.svg | 40 ++++++++++++++++++++++++--------------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/tools/reccmp/reccmp.py b/tools/reccmp/reccmp.py index 3368bb72..a8d3cd07 100755 --- a/tools/reccmp/reccmp.py +++ b/tools/reccmp/reccmp.py @@ -429,7 +429,7 @@ def gen_svg(svg, name, icon, implemented_funcs, total_funcs, raw_accuracy): templatedata = templatedata[0:percentstart] + str(progwidth) + templatedata[percentend + 1:] # Replace percentage statistic - templatedata = templatedata.replace('{percent}', '%.2f%%' % (total_statistic * 100), 1) + templatedata = templatedata.replace('{percent}', '%.2f%%' % (total_statistic * 100), 2) svgfile = open(svg, 'w') if not svgfile: diff --git a/tools/reccmp/template.svg b/tools/reccmp/template.svg index 6f7fac79..091d721d 100644 --- a/tools/reccmp/template.svg +++ b/tools/reccmp/template.svg @@ -10,13 +10,12 @@ xml:space="preserve" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" - xmlns:svg="http://www.w3.org/2000/svg"> + + + + {percent}{percent} Date: Tue, 27 Jun 2023 18:04:30 -0700 Subject: [PATCH 18/21] reccmp: use entire canvas for progress images --- tools/reccmp/template.svg | 56 +++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/tools/reccmp/template.svg b/tools/reccmp/template.svg index 091d721d..a88ea83c 100644 --- a/tools/reccmp/template.svg +++ b/tools/reccmp/template.svg @@ -8,16 +8,50 @@ version="1.1" id="svg5" xml:space="preserve" + sodipodi:docname="template.svg" + inkscape:version="1.2.2 (b0a8486541, 2022-12-01)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" - xmlns:svg="http://www.w3.org/2000/svg"> - - + xmlns:svg="http://www.w3.org/2000/svg"> + + {percent}{percent}{percent} Date: Tue, 27 Jun 2023 18:10:36 -0700 Subject: [PATCH 19/21] reccmp: change svg canvas size --- tools/reccmp/template.svg | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tools/reccmp/template.svg b/tools/reccmp/template.svg index a88ea83c..cc5b774d 100644 --- a/tools/reccmp/template.svg +++ b/tools/reccmp/template.svg @@ -3,8 +3,8 @@ {name}{name}Implemented: {implemented}Implemented: {implemented}Accuracy: {accuracy} From 612730f6312305683526bc803c3386e96f98fa7f Mon Sep 17 00:00:00 2001 From: MattKC <34096995+itsmattkc@users.noreply.github.com> Date: Tue, 27 Jun 2023 18:12:52 -0700 Subject: [PATCH 20/21] readme: add progress images --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 14b0f424..f89f1f15 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This is a **work-in-progress** decompilation of LEGO Island version 1.1. It aims ## Status -*TODO: A progress bar showing the percentage progress of this decompilation.* + Currently `ISLE.EXE` is completely decompiled, however there are some known inaccuracies. It should work if you pair it with the original game's `LEGO1.DLL` (and other files), however small things may not work correctly yet. Work on decompiling `LEGO1.DLL` has only just started and currently it is too incomplete to be usable. From f7c84d719b008b1a55f551d5b4078a2f8e8c13ca Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Tue, 27 Jun 2023 18:25:23 -0700 Subject: [PATCH 21/21] reccmp: use bold font for easier readability --- tools/reccmp/template.svg | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/reccmp/template.svg b/tools/reccmp/template.svg index cc5b774d..1cded1e3 100644 --- a/tools/reccmp/template.svg +++ b/tools/reccmp/template.svg @@ -61,12 +61,12 @@ x="58.13345" y="51.967873" />{name}{percent}