Merge branch 'master_origin'

This commit is contained in:
Roman Masanin 2023-06-30 01:09:06 +02:00
commit c15b3667c7
338 changed files with 10596 additions and 1270 deletions

View File

@ -29,7 +29,7 @@ jobs:
if: steps.cache-dx5.outputs.cache-hit != 'true' if: steps.cache-dx5.outputs.cache-hit != 'true'
run: | run: |
cd dx5sdk 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 .\idx5sdk.exe
7z x .\DX5SDK.EXE 7z x .\DX5SDK.EXE
@ -55,13 +55,24 @@ jobs:
.\msvc420\bin\NMAKE.EXE /f isle.mak CFG="ISLE - Win32 Release" .\msvc420\bin\NMAKE.EXE /f isle.mak CFG="ISLE - Win32 Release"
- name: Summarize Accuracy - name: Summarize Accuracy
shell: cmd shell: bash
run: | run: |
C:\msys64\usr\bin\wget.exe https://legoisland.org/download/ISLE.EXE curl -fLOSs https://legoisland.org/download/ISLE.EXE
C:\msys64\usr\bin\wget.exe https://legoisland.org/download/LEGO1.DLL curl -fLOSs https://legoisland.org/download/LEGO1.DLL
pip install capstone pip install capstone
python3 tools/reccmp/reccmp.py -H ISLEPROGRESS.HTML ISLE.EXE Release/ISLE.EXE Release/ISLE.PDB . pip install colorama
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 . | tee ISLEPROGRESS.TXT
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 . | tee LEGO1PROGRESS.TXT
- name: Compare Accuracy With Current Master
shell: bash
run: |
# Compare with current master
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
diff -u ISLEPROGRESS-OLD.TXT ISLEPROGRESS.TXT || true
diff -u LEGO1PROGRESS-OLD.TXT LEGO1PROGRESS.TXT || true
- name: Upload Artifact - name: Upload Artifact
uses: actions/upload-artifact@master uses: actions/upload-artifact@master
@ -71,3 +82,31 @@ jobs:
Release Release
ISLEPROGRESS.HTML ISLEPROGRESS.HTML
LEGO1PROGRESS.HTML LEGO1PROGRESS.HTML
ISLEPROGRESS.SVG
LEGO1PROGRESS.SVG
- name: Upload Continuous Release
shell: bash
if: github.event_name == 'push'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# 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 512 ISLEPROGRESS.SVG -o ISLEPROGRESS.PNG
$INKSCAPE_DIR/bin/inkscape -w 512 LEGO1PROGRESS.SVG -o LEGO1PROGRESS.PNG
curl -fLOSs https://raw.githubusercontent.com/probonopd/uploadtool/master/upload.sh
./upload.sh \
Release/ISLE.EXE \
Release/LEGO1.DLL \
ISLEPROGRESS.HTML \
ISLEPROGRESS.TXT \
ISLEPROGRESS.SVG \
ISLEPROGRESS.PNG \
LEGO1PROGRESS.HTML \
LEGO1PROGRESS.TXT \
LEGO1PROGRESS.PNG \
LEGO1PROGRESS.SVG

View File

@ -6,13 +6,21 @@ Generally, decompilation is a fairly advanced skill. If you aren't already famil
## Ghidra Server ## 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 your changes back to the server (ask in the Matrix room).
To access the Ghidra repository, use the following details: To access the Ghidra repository, use the following details:
- Address: `server.mattkc.com` - Address: `server.mattkc.com`
- Port: `13100` - Port: `13100`
## General Guidelines
If you have contributions, feel free to create a pull request! Someone will review and merge it (or provide feedback) as soon as possible.
Please keep your pull requests small and understandable; you may be able to shoot ahead and make a lot of progress in a short amount of time, but this is a collaborative project, so you must allow others to catch up and follow along. Large pull requests become significantly more unwieldy to review, and as such make it exponentially more likely for a mistake or error to go undetected. They also make it harder to merge other pull requests because the more files you modify, the more likely it is for a merge conflict to occur. A general guideline is to keep submissions limited to one class at a time. Sometimes two or more classes may be too interlinked for this to be feasible, so this is not a hard rule, however if your PR is starting to modify more than 10 or so files, it's probably getting too big.
This repository currently has only one goal: accuracy to the original executables. We are byte/instruction matching as much as possible, which means the priority is making the original compiler (MSVC 4.20) produce code that matches the original game. As such, modernizations and bug fixes will probably be rejected for the time being.
## Code Style ## Code Style
In general, we're not exhaustively strict about coding style, but there are some preferable guidelines to follow that have been adopted from what we know about the original codebase: In general, we're not exhaustively strict about coding style, but there are some preferable guidelines to follow that have been adopted from what we know about the original codebase:
@ -21,10 +29,7 @@ In general, we're not exhaustively strict about coding style, but there are some
- `PascalCase` for classes and function names. - `PascalCase` for classes and function names.
- `m_camelCase` for member variables. - `m_camelCase` for member variables.
- `g_camelCase` for global variables. - `g_camelCase` for global variables.
- `p_camelCase` for function parameters.
## Kinds of Contributions
This repository has only one goal: accuracy to the original executables. As such, we are not likely to accept pull requests that attempt to modernize the code, or improve compatibility in a newer compiler that ends up reducing compatibility in MSVC 4.20. Essentially, accuracy is king, everything else is secondary. For modernizations and enhancements, it's recommended to create a fork downstream from this one instead.
## Questions? ## Questions?

View File

@ -1,7 +1,7 @@
#include "define.h" #include "define.h"
// 0x410030 // 0x410030
Isle *g_isle = 0; IsleApp *g_isle = 0;
// 0x410034 // 0x410034
unsigned char g_mousedown = 0; unsigned char g_mousedown = 0;
@ -28,7 +28,7 @@ int g_targetWidth = 640;
int g_targetHeight = 480; int g_targetHeight = 480;
// 0x410060 // 0x410060
unsigned int g_targetDepth = 16; int g_targetDepth = 16;
// 0x410064 // 0x410064
int g_reqEnableRMDevice = 0; int g_reqEnableRMDevice = 0;

View File

@ -1,11 +1,11 @@
#ifndef DEFINE_H #ifndef DEFINE_H
#define DEFINE_H #define DEFINE_H
#include "legoinc.h" #include <windows.h>
class Isle; class IsleApp;
extern Isle *g_isle; extern IsleApp *g_isle;
extern int g_closed; extern int g_closed;
// 0x4101c4 // 0x4101c4
#define WNDCLASS_NAME "Lego Island MainNoM App" #define WNDCLASS_NAME "Lego Island MainNoM App"
@ -18,7 +18,7 @@ extern int g_rmDisabled;
extern int g_waitingForTargetDepth; extern int g_waitingForTargetDepth;
extern int g_targetWidth; extern int g_targetWidth;
extern int g_targetHeight; extern int g_targetHeight;
extern unsigned int g_targetDepth; extern int g_targetDepth;
extern int g_reqEnableRMDevice; extern int g_reqEnableRMDevice;
extern int g_startupDelay; extern int g_startupDelay;
extern long g_lastFrameTime; extern long g_lastFrameTime;

View File

@ -1,284 +0,0 @@
#include "isle.h"
// OFFSET: ISLE 0x401000
Isle::Isle()
{
m_hdPath = NULL;
m_cdPath = NULL;
m_deviceId = NULL;
m_savePath = NULL;
m_fullScreen = 1;
m_flipSurfaces = 0;
m_backBuffersInVram = 1;
m_using8bit = 0;
m_using16bit = 1;
m_unk24 = 0;
m_drawCursor = 0;
m_use3dSound = 1;
m_useMusic = 1;
m_useJoystick = 0;
m_joystickIndex = 0;
m_wideViewAngle = 1;
m_islandQuality = 1;
m_islandTexture = 1;
m_gameStarted = 0;
m_frameDelta = 10;
m_windowActive = 1;
m_videoParam = MxVideoParam(MxRect32(0, 0, 639, 479), NULL, 1, MxVideoParamFlags());
m_videoParam.flags().Set16Bit(MxDirectDraw::GetPrimaryBitDepth() == 16);
m_windowHandle = NULL;
m_cursorArrow = NULL;
m_cursorBusy = NULL;
m_cursorNo = NULL;
m_cursorCurrent = NULL;
LegoOmni::CreateInstance();
}
// OFFSET: ISLE 0x4011a0
Isle::~Isle()
{
if (LegoOmni::GetInstance()) {
Close();
MxOmni::DestroyInstance();
}
if (m_hdPath) {
delete [] m_hdPath;
}
if (m_cdPath) {
delete [] m_cdPath;
}
if (m_deviceId) {
delete [] m_deviceId;
}
if (m_savePath) {
delete [] m_savePath;
}
}
// OFFSET: ISLE 0x401260
void Isle::Close()
{
MxDSAction ds;
ds.SetUnknown24(-2);
if (Lego()) {
GameState()->Save(0);
if (InputManager()) {
InputManager()->QueueEvent(KEYDOWN, 0, 0, 0, 0x20);
}
VideoManager()->Get3DManager()->GetLego3DView()->GetViewManager()->RemoveAll(NULL);
Lego()->RemoveWorld(ds.GetAtomId(), ds.GetUnknown1c());
Lego()->vtable24(ds);
TransitionManager()->SetWaitIndicator(NULL);
Lego()->vtable3c();
long lVar8;
do {
lVar8 = Streamer()->Close(NULL);
} while (lVar8 == 0);
while (Lego()) {
if (Lego()->vtable28(ds) != MX_FALSE) {
break;
}
Timer()->GetRealTime();
TickleManager()->Tickle();
}
}
}
// OFFSET: ISLE 0x402740
BOOL Isle::ReadReg(LPCSTR name, LPSTR outValue, DWORD outSize)
{
HKEY hKey;
DWORD valueType;
BOOL out = FALSE;
unsigned long size = outSize;
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Mindscape\\LEGO Island", 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
if (RegQueryValueExA(hKey, name, NULL, &valueType, (LPBYTE) outValue, &size) == ERROR_SUCCESS) {
if (RegCloseKey(hKey) == ERROR_SUCCESS) {
out = TRUE;
}
}
}
return out;
}
// OFFSET: ISLE 0x4027b0
int Isle::ReadRegBool(LPCSTR name, BOOL *out)
{
char buffer[256];
BOOL read = ReadReg(name, buffer, sizeof(buffer));
if (read) {
if (strcmp("YES", buffer) == 0) {
*out = TRUE;
return read;
}
if (strcmp("NO", buffer) == 0) {
*out = FALSE;
return read;
}
read = FALSE;
}
return read;
}
// OFFSET: ISLE 0x402880
int Isle::ReadRegInt(LPCSTR name, int *out)
{
char buffer[256];
BOOL read = ReadReg(name, buffer, sizeof(buffer));
if (read) {
*out = atoi(buffer);
}
return read;
}
// OFFSET: ISLE 0x4028d0
void Isle::LoadConfig()
{
char buffer[1024];
if (!ReadReg("diskpath", buffer, sizeof(buffer))) {
strcpy(buffer, MxOmni::GetHD());
}
m_hdPath = new char[strlen(buffer) + 1];
strcpy(m_hdPath, buffer);
MxOmni::SetHD(m_hdPath);
if (!ReadReg("cdpath", buffer, sizeof(buffer))) {
strcpy(buffer, MxOmni::GetCD());
}
m_cdPath = new char[strlen(buffer) + 1];
strcpy(m_cdPath, buffer);
MxOmni::SetCD(m_cdPath);
ReadRegBool("Flip Surfaces", &m_flipSurfaces);
ReadRegBool("Full Screen", &m_fullScreen);
ReadRegBool("Wide View Angle", &m_wideViewAngle);
ReadRegBool("3DSound", &m_use3dSound);
ReadRegBool("Music", &m_useMusic);
ReadRegBool("UseJoystick", &m_useJoystick);
ReadRegInt("JoystickIndex", &m_joystickIndex);
ReadRegBool("Draw Cursor", &m_drawCursor);
int backBuffersInVRAM;
if (ReadRegBool("Back Buffers in Video RAM",&backBuffersInVRAM)) {
m_backBuffersInVram = !backBuffersInVRAM;
}
int bitDepth;
if (ReadRegInt("Display Bit Depth", &bitDepth)) {
if (bitDepth == 8) {
m_using8bit = TRUE;
} else if (bitDepth == 16) {
m_using16bit = TRUE;
}
}
if (!ReadReg("Island Quality", buffer, sizeof(buffer))) {
strcpy(buffer, "1");
}
m_islandQuality = atoi(buffer);
if (!ReadReg("Island Texture", buffer, sizeof(buffer))) {
strcpy(buffer, "1");
}
m_islandTexture = atoi(buffer);
if (ReadReg("3D Device ID", buffer, sizeof(buffer))) {
m_deviceId = new char[strlen(buffer) + 1];
strcpy(m_deviceId, buffer);
}
if (ReadReg("savepath", buffer, sizeof(buffer))) {
m_savePath = new char[strlen(buffer) + 1];
strcpy(m_savePath, buffer);
}
}
// 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);
}
}
// 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 0x402e80
void Isle::SetupCursor(WPARAM wParam)
{
switch (wParam) {
case 0:
m_cursorCurrent = m_cursorArrow;
break;
case 1:
m_cursorCurrent = m_cursorBusy;
break;
case 2:
m_cursorCurrent = m_cursorNo;
break;
case 0xB:
m_cursorCurrent = NULL;
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 0xA:
break;
}
SetCursor(m_cursorCurrent);
}

View File

@ -1,277 +0,0 @@
#ifndef ISLE_H
#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
{
public:
Isle();
~Isle();
void Close();
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 SetupCursor(WPARAM wParam);
// private:
// 0
LPSTR m_hdPath;
LPSTR m_cdPath;
LPSTR m_deviceId;
LPSTR m_savePath;
// 10
BOOL m_fullScreen;
BOOL m_flipSurfaces;
BOOL m_backBuffersInVram;
BOOL m_using8bit;
// 20
BOOL m_using16bit;
int m_unk24;
BOOL m_use3dSound;
BOOL m_useMusic;
// 30
BOOL m_useJoystick;
int m_joystickIndex;
BOOL m_wideViewAngle;
int m_islandQuality;
// 40
int m_islandTexture;
int m_gameStarted;
long m_frameDelta;
// 4c
MxVideoParam m_videoParam;
// 70
BOOL m_windowActive;
HWND m_windowHandle;
BOOL m_drawCursor;
HCURSOR m_cursorArrow;
// 80
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

781
ISLE/isleapp.cpp Normal file
View File

@ -0,0 +1,781 @@
#include "isleapp.h"
#include "define.h"
#include <dsound.h>
#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
IsleApp::IsleApp()
{
m_hdPath = NULL;
m_cdPath = NULL;
m_deviceId = NULL;
m_savePath = NULL;
m_fullScreen = 1;
m_flipSurfaces = 0;
m_backBuffersInVram = 1;
m_using8bit = 0;
m_using16bit = 1;
m_unk24 = 0;
m_drawCursor = 0;
m_use3dSound = 1;
m_useMusic = 1;
m_useJoystick = 0;
m_joystickIndex = 0;
m_wideViewAngle = 1;
m_islandQuality = 1;
m_islandTexture = 1;
m_gameStarted = 0;
m_frameDelta = 10;
m_windowActive = 1;
m_videoParam = MxVideoParam(MxRect32(0, 0, 639, 479), NULL, 1, MxVideoParamFlags());
m_videoParam.flags().Set16Bit(MxDirectDraw::GetPrimaryBitDepth() == 16);
m_windowHandle = NULL;
m_cursorArrow = NULL;
m_cursorBusy = NULL;
m_cursorNo = NULL;
m_cursorCurrent = NULL;
LegoOmni::CreateInstance();
}
// OFFSET: ISLE 0x4011a0
IsleApp::~IsleApp()
{
if (LegoOmni::GetInstance()) {
Close();
MxOmni::DestroyInstance();
}
if (m_hdPath) {
delete [] m_hdPath;
}
if (m_cdPath) {
delete [] m_cdPath;
}
if (m_deviceId) {
delete [] m_deviceId;
}
if (m_savePath) {
delete [] m_savePath;
}
}
// OFFSET: ISLE 0x401260
void IsleApp::Close()
{
MxDSAction ds;
ds.SetUnknown24(-2);
if (Lego()) {
GameState()->Save(0);
if (InputManager()) {
InputManager()->QueueEvent(KEYDOWN, 0, 0, 0, 0x20);
}
VideoManager()->Get3DManager()->GetLego3DView()->GetViewManager()->RemoveAll(NULL);
Lego()->RemoveWorld(ds.GetAtomId(), ds.GetUnknown1c());
Lego()->vtable24(ds);
TransitionManager()->SetWaitIndicator(NULL);
Lego()->vtable3c();
long lVar8;
do {
lVar8 = Streamer()->Close(NULL);
} while (lVar8 == 0);
while (Lego()) {
if (Lego()->vtable28(ds) != FALSE) {
break;
}
Timer()->GetRealTime();
TickleManager()->Tickle();
}
}
}
// OFFSET: ISLE 0x4013b0
BOOL IsleApp::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 IsleApp::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 IsleApp();
// 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 IsleApp::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 IsleApp::ReadReg(LPCSTR name, LPSTR outValue, DWORD outSize)
{
HKEY hKey;
DWORD valueType;
BOOL out = FALSE;
unsigned long size = outSize;
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Mindscape\\LEGO Island", 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
if (RegQueryValueExA(hKey, name, NULL, &valueType, (LPBYTE) outValue, &size) == ERROR_SUCCESS) {
if (RegCloseKey(hKey) == ERROR_SUCCESS) {
out = TRUE;
}
}
}
return out;
}
// OFFSET: ISLE 0x4027b0
int IsleApp::ReadRegBool(LPCSTR name, BOOL *out)
{
char buffer[256];
BOOL read = ReadReg(name, buffer, sizeof(buffer));
if (read) {
if (strcmp("YES", buffer) == 0) {
*out = TRUE;
return read;
}
if (strcmp("NO", buffer) == 0) {
*out = FALSE;
return read;
}
read = FALSE;
}
return read;
}
// OFFSET: ISLE 0x402880
int IsleApp::ReadRegInt(LPCSTR name, int *out)
{
char buffer[256];
BOOL read = ReadReg(name, buffer, sizeof(buffer));
if (read) {
*out = atoi(buffer);
}
return read;
}
// OFFSET: ISLE 0x4028d0
void IsleApp::LoadConfig()
{
char buffer[1024];
if (!ReadReg("diskpath", buffer, sizeof(buffer))) {
strcpy(buffer, MxOmni::GetHD());
}
m_hdPath = new char[strlen(buffer) + 1];
strcpy(m_hdPath, buffer);
MxOmni::SetHD(m_hdPath);
if (!ReadReg("cdpath", buffer, sizeof(buffer))) {
strcpy(buffer, MxOmni::GetCD());
}
m_cdPath = new char[strlen(buffer) + 1];
strcpy(m_cdPath, buffer);
MxOmni::SetCD(m_cdPath);
ReadRegBool("Flip Surfaces", &m_flipSurfaces);
ReadRegBool("Full Screen", &m_fullScreen);
ReadRegBool("Wide View Angle", &m_wideViewAngle);
ReadRegBool("3DSound", &m_use3dSound);
ReadRegBool("Music", &m_useMusic);
ReadRegBool("UseJoystick", &m_useJoystick);
ReadRegInt("JoystickIndex", &m_joystickIndex);
ReadRegBool("Draw Cursor", &m_drawCursor);
int backBuffersInVRAM;
if (ReadRegBool("Back Buffers in Video RAM",&backBuffersInVRAM)) {
m_backBuffersInVram = !backBuffersInVRAM;
}
int bitDepth;
if (ReadRegInt("Display Bit Depth", &bitDepth)) {
if (bitDepth == 8) {
m_using8bit = TRUE;
} else if (bitDepth == 16) {
m_using16bit = TRUE;
}
}
if (!ReadReg("Island Quality", buffer, sizeof(buffer))) {
strcpy(buffer, "1");
}
m_islandQuality = atoi(buffer);
if (!ReadReg("Island Texture", buffer, sizeof(buffer))) {
strcpy(buffer, "1");
}
m_islandTexture = atoi(buffer);
if (ReadReg("3D Device ID", buffer, sizeof(buffer))) {
m_deviceId = new char[strlen(buffer) + 1];
strcpy(m_deviceId, buffer);
}
if (ReadReg("savepath", buffer, sizeof(buffer))) {
m_savePath = new char[strlen(buffer) + 1];
strcpy(m_savePath, buffer);
}
}
// OFFSET: ISLE 0x402c20
inline void IsleApp::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);
}
// OFFSET: ISLE 0x402e80
void IsleApp::SetupCursor(WPARAM wParam)
{
switch (wParam) {
case 0:
m_cursorCurrent = m_cursorArrow;
break;
case 1:
m_cursorCurrent = m_cursorBusy;
break;
case 2:
m_cursorCurrent = m_cursorNo;
break;
case 0xB:
m_cursorCurrent = NULL;
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 0xA:
break;
}
SetCursor(m_cursorCurrent);
}

76
ISLE/isleapp.h Normal file
View File

@ -0,0 +1,76 @@
#ifndef ISLEAPP_H
#define ISLEAPP_H
#include <windows.h>
#include "mxtypes.h"
#include "mxvideoparam.h"
class IsleApp
{
public:
IsleApp();
~IsleApp();
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);
void LoadConfig();
void Tick(BOOL sleepIfNotNextFrame);
void SetupCursor(WPARAM wParam);
// private:
// 0
LPSTR m_hdPath;
LPSTR m_cdPath;
LPSTR m_deviceId;
LPSTR m_savePath;
// 10
BOOL m_fullScreen;
BOOL m_flipSurfaces;
BOOL m_backBuffersInVram;
BOOL m_using8bit;
// 20
BOOL m_using16bit;
int m_unk24;
BOOL m_use3dSound;
BOOL m_useMusic;
// 30
BOOL m_useJoystick;
int m_joystickIndex;
BOOL m_wideViewAngle;
int m_islandQuality;
// 40
int m_islandTexture;
int m_gameStarted;
long m_frameDelta;
// 4c
MxVideoParam m_videoParam;
// 70
BOOL m_windowActive;
HWND m_windowHandle;
BOOL m_drawCursor;
HCURSOR m_cursorArrow;
// 80
HCURSOR m_cursorBusy;
HCURSOR m_cursorNo;
HCURSOR m_cursorCurrent;
};
#endif // ISLEAPP_H

View File

@ -1,311 +0,0 @@
#include <dsound.h>
#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);
}

8
LEGO1/act1state.cpp Normal file
View File

@ -0,0 +1,8 @@
#include "act1state.h"
// OFFSET: LEGO1 0x100334b0 STUB
Act1State::Act1State()
{
// TODO
}

27
LEGO1/act1state.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef ACT1STATE_H
#define ACT1STATE_H
#include "legostate.h"
// VTABLE 0x100d7028
// SIZE 0x26c
class Act1State : public LegoState
{
public:
Act1State();
// OFFSET: LEGO1 0x100338a0
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f0154
return "Act1State";
};
// OFFSET: LEGO1 0x100338b0
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, Act1State::ClassName()) || LegoState::IsA(name);
};
};
#endif // ACT1STATE_H

29
LEGO1/act2brick.cpp Normal file
View File

@ -0,0 +1,29 @@
#include "act2brick.h"
// OFFSET: LEGO1 0x1007a2b0 STUB
Act2Brick::Act2Brick()
{
// TODO
}
// OFFSET: LEGO1 0x1007a470 STUB
Act2Brick::~Act2Brick()
{
// TODO
}
// STUB OFFSET: LEGO1 0x1007a8c0 STUB
long Act2Brick::Notify(MxParam &p)
{
// TODO
return 0;
}
// OFFSET: LEGO1 0x1007a7f0 STUB
long Act2Brick::Tickle()
{
// TODO
return 0;
}

32
LEGO1/act2brick.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef ACT2BRICK_H
#define ACT2BRICK_H
#include "legopathactor.h"
// VTABLE 0x100d9b60
// SIZE 0x194
class Act2Brick : public LegoPathActor
{
public:
Act2Brick();
virtual ~Act2Brick() override; // vtable+0x0
virtual long Notify(MxParam &p) override; // vtable+0x4
virtual long Tickle() override; // vtable+0x08
// OFFSET: LEGO1 0x1007a360
inline virtual const char *ClassName() override // vtable+0x0c
{
// 0x100f0438
return "Act2Brick";
}
// OFFSET: LEGO1 0x1007a370
inline virtual MxBool IsA(const char *name) override // vtable+0x10
{
return !strcmp(Act2Brick::ClassName(), name) || LegoEntity::IsA(name);
}
};
#endif // ACT2BRICK_H

View File

@ -0,0 +1,9 @@
#include "act2policestation.h"
// OFFSET: LEGO1 0x1004e0e0 STUB
long Act2PoliceStation::Notify(MxParam &p)
{
// TODO
return 0;
}

27
LEGO1/act2policestation.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef ACT2POLICESTATION_H
#define ACT2POLICESTATION_H
#include "legoentity.h"
// VTABLE 0x100d53a8
// SIZE 0x68
class Act2PoliceStation : public LegoEntity
{
public:
virtual long Notify(MxParam &p) override; // vtable+0x4
// OFFSET: LEGO1 0x1000e200
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f03fc
return "Act2PoliceStation";
}
// OFFSET: LEGO1 0x1000e210
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, Act2PoliceStation::ClassName()) || LegoEntity::IsA(name);
}
};
#endif // ACT2POLICESTATION_H

13
LEGO1/act3.cpp Normal file
View File

@ -0,0 +1,13 @@
#include "act3.h"
// OFFSET: LEGO1 0x10072270 STUB
Act3::Act3()
{
// TODO
}
// OFFSET: LEGO1 0x100726a0 STUB
Act3::~Act3()
{
// TODO
}

31
LEGO1/act3.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef ACT3_H
#define ACT3_H
#include "legoworld.h"
// VTABLE 0x100d9628
// SIZE 0x4274
class Act3 : public LegoWorld
{
public:
Act3();
virtual ~Act3() override; // vtable+00
// OFFSET: LEGO1 0x10072510
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f013c
return "Act3";
}
// OFFSET: LEGO1 0x10072520
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, Act3::ClassName()) || LegoWorld::IsA(name);
}
};
#endif // ACT3_H

18
LEGO1/act3actor.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef ACT3ACTOR_H
#define ACT3ACTOR_H
// FIXME: Uncertain location. There are three vtables which eventually call this
// class' ClassName() function, but none of them call it directly.
class Act3Actor
{
public:
// OFFSET: LEGO1 0x100431b0
inline virtual const char *ClassName() override
{
// 0x100f03ac
return "Act3Actor";
}
};
#endif // ACT3ACTOR_H

1
LEGO1/act3shark.cpp Normal file
View File

@ -0,0 +1 @@
#include "act3shark.h"

18
LEGO1/act3shark.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef ACT3SHARK_H
#define ACT3SHARK_H
#include "legoanimactor.h"
// VTABLE 0x100d7920
class Act3Shark : public LegoAnimActor
{
public:
// OFFSET: LEGO1 0x100430c0
inline virtual const char *ClassName() const override
{
// 0x100f03a0
return "Act3Shark";
}
};
#endif // ACT3SHARK_H

7
LEGO1/act3state.cpp Normal file
View File

@ -0,0 +1,7 @@
#include "act3state.h"
// OFFSET: LEGO1 0x1000e2f0
MxBool Act3State::VTable0x14()
{
return FALSE;
}

37
LEGO1/act3state.h Normal file
View File

@ -0,0 +1,37 @@
#ifndef ACT3STATE_H
#define ACT3STATE_H
#include "legostate.h"
// VTABLE 0x100d4fc8
// SIZE 0xc
class Act3State : public LegoState
{
public:
inline Act3State()
{
m_unk08 = 0;
}
// OFFSET: LEGO1 0x1000e300
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f03f0
return "Act3State";
}
// OFFSET: LEGO1 0x1000e310
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, Act3State::ClassName()) || LegoState::IsA(name);
}
virtual MxBool VTable0x14() override;
private:
// FIXME: May be part of LegoState? Uncertain...
MxU32 m_unk08;
};
#endif // ACT3STATE_H

7
LEGO1/ambulance.cpp Normal file
View File

@ -0,0 +1,7 @@
#include "ambulance.h"
// OFFSET: LEGO1 0x10035ee0 STUB
Ambulance::Ambulance()
{
// TODO
}

28
LEGO1/ambulance.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef AMBULANCE_H
#define AMBULANCE_H
#include "islepathactor.h"
// VTABLE 0x100d71a8
// SIZE 0x184
class Ambulance : public IslePathActor
{
public:
Ambulance();
// OFFSET: LEGO1 0x10035fa0
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f03c4
return "Ambulance";
}
// OFFSET: LEGO1 0x10035fb0
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, Ambulance::ClassName()) || IslePathActor::IsA(name);
}
};
#endif // AMBULANCE_H

View File

@ -0,0 +1,7 @@
#include "ambulancemissionstate.h"
// OFFSET: LEGO1 0x100373a0 STUB
AmbulanceMissionState::AmbulanceMissionState()
{
// TODO
}

View File

@ -0,0 +1,29 @@
#ifndef AMBULANCEMISSIONSTATE_H
#define AMBULANCEMISSIONSTATE_H
#include "legostate.h"
// VTABLE 0x100d72a0
// SIZE 0x24
class AmbulanceMissionState : public LegoState
{
public:
AmbulanceMissionState();
// OFFSET: LEGO1 0x10037600
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f00e8
return "AmbulanceMissionState";
}
// OFFSET: LEGO1 0x10037610
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, AmbulanceMissionState::ClassName()) || LegoState::IsA(name);
}
};
#endif // AMBULANCEMISSIONSTATE_H

13
LEGO1/animstate.cpp Normal file
View File

@ -0,0 +1,13 @@
#include "animstate.h"
// OFFSET: LEGO1 0x10064ff0 STUB
AnimState::AnimState()
{
// TODO
}
// OFFSET: LEGO1 0x10065150 STUB
AnimState::~AnimState()
{
// TODO
}

29
LEGO1/animstate.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef ANIMSTATE_H
#define ANIMSTATE_H
#include "legostate.h"
// VTABLE 0x100d8d80
// SIZE 0x1c
class AnimState : public LegoState
{
public:
AnimState();
virtual ~AnimState() override; // vtable+0x0
// OFFSET: LEGO1 0x10065070
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f0460
return "AnimState";
}
// OFFSET: LEGO1 0x10065080
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, AnimState::ClassName()) || LegoState::IsA(name);
}
};
#endif // ANIMSTATE_H

View File

@ -0,0 +1,9 @@
#include "beachhouseentity.h"
// OFFSET: LEGO1 0x100150a0 STUB
long BeachHouseEntity::Notify(MxParam &p)
{
// TODO
return 0;
}

27
LEGO1/beachhouseentity.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef BEACHHOUSEENTITY_H
#define BEACHHOUSEENTITY_H
#include "buildingentity.h"
// VTABLE 0x100d4a18
// SIZE 0x68
class BeachHouseEntity : public BuildingEntity
{
public:
virtual long Notify(MxParam &p) override; // vtable+04
// OFFSET: LEGO1 0x1000ee80
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f0314
return "BeachHouseEntity";
}
// OFFSET: LEGO1 0x1000ee90
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, BeachHouseEntity::ClassName()) || BuildingEntity::IsA(name);
}
};
#endif // BEACHHOUSEENTITY_H

8
LEGO1/bike.cpp Normal file
View File

@ -0,0 +1,8 @@
#include "bike.h"
// OFFSET: LEGO1 0x10076670 STUB
Bike::Bike()
{
// TODO
}

29
LEGO1/bike.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef BIKE_H
#define BIKE_H
#include "islepathactor.h"
// VTABLE 0x100d9808
// SIZE 0x164
class Bike : public IslePathActor
{
public:
Bike();
// OFFSET: LEGO1 0x100766f0
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f03d0
return "Bike";
}
// OFFSET: LEGO1 0x10076700
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, Bike::ClassName()) || IslePathActor::IsA(name);
}
};
#endif // BIKE_H

13
LEGO1/buildingentity.cpp Normal file
View File

@ -0,0 +1,13 @@
#include "buildingentity.h"
// OFFSET: LEGO1 0x10014e20 STUB
BuildingEntity::BuildingEntity()
{
// TODO
}
// OFFSET: LEGO1 0x10015030 STUB
BuildingEntity::~BuildingEntity()
{
// TODO
}

28
LEGO1/buildingentity.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef BUILDINGENTITY_H
#define BUILDINGENTITY_H
#include "legoentity.h"
// VTABLE 0x100d5c88
// SIZE <= 0x68, hard to tell because it's always constructed as a derivative
class BuildingEntity : public LegoEntity
{
public:
BuildingEntity();
virtual ~BuildingEntity() override; // vtable+0x0
// OFFSET: LEGO1 0x10014f20
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f07e8
return "BuildingEntity";
}
// OFFSET: LEGO1 0x10014f30
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, BuildingEntity::ClassName()) || LegoEntity::IsA(name);
}
};
#endif // BUILDINGENTITY_H

1
LEGO1/bumpbouy.cpp Normal file
View File

@ -0,0 +1 @@
#include "bumpbouy.h"

25
LEGO1/bumpbouy.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef BUMPBOUY_H
#define BUMPBOUY_H
#include "legoanimactor.h"
#include "mxtypes.h"
// VTABLE 0x100d6790
class BumpBouy : public LegoAnimActor
{
public:
// OFFSET: LEGO1 0x100274e0
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f0394
return "BumpBouy";
}
// OFFSET: LEGO1 0x10027500
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, BumpBouy::ClassName()) || LegoAnimActor::IsA(name);
}
};
#endif // BUMPBOUY_H

7
LEGO1/carrace.cpp Normal file
View File

@ -0,0 +1,7 @@
#include "carrace.h"
// OFFSET: LEGO1 0x10016a90 STUB
CarRace::CarRace()
{
// TODO
}

27
LEGO1/carrace.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef CARRACE_H
#define CARRACE_H
#include "legorace.h"
// VTABLE 0x100d5e50
// SIZE 0x154
class CarRace : public LegoRace
{
public:
CarRace();
// OFFSET: LEGO1 0x10016b20
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f0528
return "CarRace";
}
// OFFSET: LEGO1 0x10016b30
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, CarRace::ClassName()) || LegoRace::IsA(name);
}
};
#endif // CARRACE_H

25
LEGO1/carracestate.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef CARRACESTATE_H
#define CARRACESTATE_H
#include "racestate.h"
// VTABLE 0x100d4b70
// SIZE 0x2c
class CarRaceState : public RaceState
{
public:
// OFFSET: LEGO1 0x1000dd30
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f009c
return "CarRaceState";
}
// OFFSET: LEGO1 0x1000dd40
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, CarRaceState::ClassName()) || RaceState::IsA(name);
}
};
#endif // CARRACESTATE_H

View File

@ -1,4 +1,4 @@
#include "legoinc.h" #include <windows.h>
// OFFSET: LEGO1 0x10091ee0 // OFFSET: LEGO1 0x10091ee0
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)

26
LEGO1/doors.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef DOORS_H
#define DOORS_H
#include "legopathactor.h"
// VTABLE 0x100d4788
// SIZE 0x1f8
class Doors : public LegoPathActor
{
public:
// OFFSET: LEGO1 0x1000e430
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f03e8
return "Doors";
}
// OFFSET: LEGO1 0x1000e440
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, Doors::ClassName()) || LegoPathActor::IsA(name);
}
};
#endif // DOORS_H

7
LEGO1/dunebuggy.cpp Normal file
View File

@ -0,0 +1,7 @@
#include "dunebuggy.h"
// OFFSET: LEGO1 0x10067bb0 STUB
DuneBuggy::DuneBuggy()
{
// TODO
}

28
LEGO1/dunebuggy.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef DUNEBUGGY_H
#define DUNEBUGGY_H
#include "islepathactor.h"
// VTABLE 0x100d8f98
// SIZE 0x16c
class DuneBuggy : public IslePathActor
{
public:
DuneBuggy();
// OFFSET: LEGO1 0x10067c30
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f0410
return "DuneBuggy";
}
// OFFSET: LEGO1 0x10067c40
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, DuneBuggy::ClassName()) || IslePathActor::IsA(name);
}
};
#endif // DUNEBUGGY_H

21
LEGO1/elevatorbottom.cpp Normal file
View File

@ -0,0 +1,21 @@
#include "elevatorbottom.h"
// OFFSET: LEGO1 0x10017e90 STUB
ElevatorBottom::ElevatorBottom()
{
// TODO
}
// OFFSET: LEGO1 0x10018060 STUB
ElevatorBottom::~ElevatorBottom()
{
// TODO
}
// OFFSET: LEGO1 0x10018150 STUB
long ElevatorBottom::Notify(MxParam &p)
{
// TODO
return 0;
}

30
LEGO1/elevatorbottom.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef ELEVATORBOTTOM_H
#define ELEVATORBOTTOM_H
#include "legoworld.h"
// VTABLE 0x100d5f20
class ElevatorBottom : public LegoWorld
{
public:
ElevatorBottom();
virtual ~ElevatorBottom() override; // vtable+0x0
virtual long Notify(MxParam &p) override; // vtable+0x4
// OFFSET: LEGO1 0x10017f20
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f04ac
return "ElevatorBottom";
}
// OFFSET: LEGO1 0x10017f30
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, ElevatorBottom::ClassName()) || LegoWorld::IsA(name);
}
};
#endif // ELEVATORBOTTOM_H

29
LEGO1/gasstation.cpp Normal file
View File

@ -0,0 +1,29 @@
#include "gasstation.h"
// OFFSET: LEGO1 0x100046a0 STUB
GasStation::GasStation()
{
// TODO
}
// OFFSET: LEGO1 0x100048c0 STUB
GasStation::~GasStation()
{
// TODO
}
// OFFSET: LEGO1 0x10004a60 STUB
long GasStation::Notify(MxParam &p)
{
// TODO
return 0;
}
// OFFSET: LEGO1 0x10005c90 STUB
long GasStation::Tickle()
{
// TODO
return 0;
}

33
LEGO1/gasstation.h Normal file
View File

@ -0,0 +1,33 @@
#ifndef GASSTATION_H
#define GASSTATION_H
#include "legoworld.h"
// VTABLE 0x100d4650
// SIZE 0x128
// Radio variable at 0x46, in constructor
class GasStation : public LegoWorld
{
public:
GasStation();
virtual ~GasStation() override; // vtable+0x0
virtual long Notify(MxParam &p) override; // vtable+0x4
virtual long Tickle() override; // vtable+0x8
// OFFSET: LEGO1 0x10004780
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f0168
return "GasStation";
}
// OFFSET: LEGO1 0x10004790
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, GasStation::ClassName()) || LegoWorld::IsA(name);
}
};
#endif // GASSTATION_H

View File

@ -0,0 +1 @@
#include "gasstationentity.h"

25
LEGO1/gasstationentity.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef GASSTATIONENTITY_H
#define GASSTATIONENTITY_H
#include "buildingentity.h"
// VTABLE 0x100d5258
// SIZE 0x68
class GasStationEntity : public BuildingEntity
{
public:
// OFFSET: LEGO1 0x1000eb20
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f0348
return "GasStationEntity";
}
// OFFSET: LEGO1 0x1000eb30
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, GasStationEntity::ClassName()) || BuildingEntity::IsA(name);
}
};
#endif // GASSTATIONENTITY_H

View File

@ -0,0 +1,7 @@
#include "gasstationstate.h"
// OFFSET: LEGO1 0x10005eb0 STUB
GasStationState::GasStationState()
{
// TODO
}

28
LEGO1/gasstationstate.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef GASSTATIONSTATE_H
#define GASSTATIONSTATE_H
#include "legostate.h"
// VTABLE 0x100d46e0
// SIZE 0x24
class GasStationState : public LegoState
{
public:
GasStationState();
// OFFSET: LEGO1 0x100061d0
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f0174
return "GasStationState";
}
// OFFSET: LEGO1 0x100061e0
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, GasStationState::ClassName()) || LegoState::IsA(name);
}
};
#endif // GASSTATIONSTATE_H

13
LEGO1/helicopter.cpp Normal file
View File

@ -0,0 +1,13 @@
#include "helicopter.h"
// OFFSET: LEGO1 0x10001e60 STUB
Helicopter::Helicopter()
{
// TODO
}
// OFFSET: LEGO1 0x10003230 STUB
Helicopter::~Helicopter()
{
// TODO
}

29
LEGO1/helicopter.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef HELICOPTER_H
#define HELICOPTER_H
#include "islepathactor.h"
// VTABLE 0x100d40f8
// SIZE 0x230
class Helicopter : public IslePathActor
{
public:
Helicopter();
virtual ~Helicopter(); // vtable+0x0
// OFFSET: LEGO1 0x10003070
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f0130
return "Helicopter";
}
// OFFSET: LEGO1 0x10003080
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, Helicopter::ClassName()) || IslePathActor::IsA(name);
}
};
#endif // HELICOPTER_H

View File

@ -0,0 +1 @@
#include "helicopterstate.h"

25
LEGO1/helicopterstate.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef HELICOPTERSTATE_H
#define HELICOPTERSTATE_H
#include "legostate.h"
// VTABLE 0x100d5418
// SIZE 0xc
class HelicopterState : public LegoState
{
public:
// OFFSET: LEGO1 0x1000e0d0
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f0144
return "HelicopterState";
}
// OFFSET: LEGO1 0x1000e0e0
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, HelicopterState::ClassName()) || LegoState::IsA(name);
}
};
#endif // HELICOPTERSTATE_H

21
LEGO1/historybook.cpp Normal file
View File

@ -0,0 +1,21 @@
#include "historybook.h"
// OFFSET: LEGO1 0x100822f0 STUB
HistoryBook::HistoryBook()
{
// TODO
}
// OFFSET: LEGO1 0x100824d0 STUB
HistoryBook::~HistoryBook()
{
// TODO
}
// OFFSET: LEGO1 0x10082680 STUB
long HistoryBook::Notify(MxParam &p)
{
// TODO
return 0;
}

30
LEGO1/historybook.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef HISTORYBOOK_H
#define HISTORYBOOK_H
#include "legoworld.h"
// VTABLE 0x100da328
// SIZE 0x3e4
class HistoryBook : public LegoWorld
{
public:
HistoryBook();
virtual ~HistoryBook() override; // vtable+0x0
virtual long Notify(MxParam &p) override; // vtable+0x4
// OFFSET: LEGO1 0x10082390
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f04bc
return "HistoryBook";
}
// OFFSET: LEGO1 0x100823a0
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, HistoryBook::ClassName()) || LegoWorld::IsA(name);
}
};
#endif // HISTORYBOOK_H

21
LEGO1/hospital.cpp Normal file
View File

@ -0,0 +1,21 @@
#include "hospital.h"
// OFFSET: LEGO1 0x100745e0 STUB
Hospital::Hospital()
{
// TODO
}
// OFFSET: LEGO1 0x100747f0 STUB
Hospital::~Hospital()
{
// TODO
}
// OFFSET: LEGO1 0x10074990 STUB
long Hospital::Notify(MxParam &p)
{
// TODO
return 0;
}

31
LEGO1/hospital.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef HOSPITAL_H
#define HOSPITAL_H
#include "legoworld.h"
// VTABLE 0x100d9730
// SIZE 0x12c
class Hospital : public LegoWorld
{
public:
Hospital();
virtual ~Hospital() override; // vtable+0x0
virtual long Notify(MxParam &p) override; // vtable+0x04
// OFFSET: LEGO1 0x100746b0
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f0490
return "Hospital";
}
// OFFSET: LEGO1 0x100746c0
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, Hospital::ClassName()) || LegoWorld::IsA(name);
}
};
#endif // HOSPITAL_H

1
LEGO1/hospitalentity.cpp Normal file
View File

@ -0,0 +1 @@
#include "hospitalentity.h"

26
LEGO1/hospitalentity.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef HOSPITALENTITY_H
#define HOSPITALENTITY_H
#include "buildingentity.h"
// VTABLE 0x100d5068
// SIZE 0x68
class HospitalEntity : public BuildingEntity
{
public:
// OFFSET: LEGO1 0x1000ec40
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f0338
return "HospitalEntity";
}
// OFFSET: LEGO1 0x1000ec50
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, HospitalEntity::ClassName()) || BuildingEntity::IsA(name);
}
};
#endif // HOSPITALENTITY_H

7
LEGO1/hospitalstate.cpp Normal file
View File

@ -0,0 +1,7 @@
#include "hospitalstate.h"
// OFFSET: LEGO1 0x10076370 STUB
HospitalState::HospitalState()
{
// TODO
}

28
LEGO1/hospitalstate.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef HOSPITALSTATE_H
#define HOSPITALSTATE_H
#include "legostate.h"
// VTABLE 0x100d97a0
// SIZE 0x18
class HospitalState : public LegoState
{
public:
HospitalState();
// OFFSET: LEGO1 0x10076400
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f0480
return "HospitalState";
}
// OFFSET: LEGO1 0x10076410
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, HospitalState::ClassName()) || LegoState::IsA(name);
}
};
#endif // HOSPITALSTATE_H

29
LEGO1/infocenter.cpp Normal file
View File

@ -0,0 +1,29 @@
#include "infocenter.h"
// OFFSET: LEGO1 0x1006ea20 STUB
Infocenter::Infocenter()
{
// TODO
}
// OFFSET: LEGO1 0x1006ec90 STUB
Infocenter::~Infocenter()
{
// TODO
}
// OFFSET: LEGO1 0x1006ef10 STUB
long Infocenter::Notify(MxParam &p)
{
// TODO
return 0;
}
// OFFSET: LEGO1 0x10070af0 STUB
long Infocenter::Tickle()
{
// TODO
return 0;
}

32
LEGO1/infocenter.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef INFOCENTER_H
#define INFOCENTER_H
#include "legoworld.h"
// VTABLE 0x100d9338
// SIZE 0x1d8
class Infocenter : public LegoWorld
{
public:
Infocenter();
virtual ~Infocenter() override;
virtual long Notify(MxParam &p) override; // vtable+0x4
virtual long Tickle() override; // vtable+0x8
// OFFSET: LEGO1 0x1006eb40
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f04ec
return "Infocenter";
}
// OFFSET: LEGO1 0x1006eb50
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, Infocenter::ClassName()) || LegoWorld::IsA(name);
}
};
#endif // INFOCENTER_H

21
LEGO1/infocenterdoor.cpp Normal file
View File

@ -0,0 +1,21 @@
#include "infocenterdoor.h"
// OFFSET: LEGO1 0x10037730 STUB
InfocenterDoor::InfocenterDoor()
{
// TODO
}
// OFFSET: LEGO1 0x100378f0 STUB
InfocenterDoor::~InfocenterDoor()
{
// TODO
}
// OFFSET: LEGO1 0x100379e0 STUB
long InfocenterDoor::Notify(MxParam &p)
{
// TODO
return 0;
}

31
LEGO1/infocenterdoor.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef INFOCENTERDOOR_H
#define INFOCENTERDOOR_H
#include "legoworld.h"
// VTABLE 0x100d72d8
// SIZE 0xfc
class InfocenterDoor : public LegoWorld
{
public:
InfocenterDoor();
virtual ~InfocenterDoor(); // vtable+0x0
virtual long Notify(MxParam &p) override; // vtable+0x4
// OFFSET: LEGO1 0x100377b0
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f049c
return "InfocenterDoor";
}
// OFFSET: LEGO1 0x100377c0
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, InfocenterDoor::ClassName()) || LegoWorld::IsA(name);
}
};
#endif // INFOCENTERDOOR_H

View File

@ -0,0 +1 @@
#include "infocenterentity.h"

26
LEGO1/infocenterentity.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef INFOCENTERENTITY_H
#define INFOCENTERENTITY_H
#include "buildingentity.h"
// VTABLE 0x100d4b90
// SIZE 0x68
class InfoCenterEntity : public BuildingEntity
{
public:
// OFFSET: LEGO1 0x1000ea00
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f035c
return "InfoCenterEntity";
}
// OFFSET: LEGO1 0x1000ea10
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, InfoCenterEntity::ClassName()) || BuildingEntity::IsA(name);
}
};
#endif // INFOCENTERENTITY_H

14
LEGO1/infocenterstate.cpp Normal file
View File

@ -0,0 +1,14 @@
#include "infocenterstate.h"
// OFFSET: LEGO1 0x10071600 STUB
InfocenterState::InfocenterState()
{
// TODO
}
// OFFSET: LEGO1 0x10071920 STUB
InfocenterState::~InfocenterState()
{
// TODO
}

28
LEGO1/infocenterstate.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef INFOCENTERSTATE_H
#define INFOCENTERSTATE_H
#include "legostate.h"
// VTABLE 0x100d93a8
// SIZE 0x94
class InfocenterState : public LegoState
{
public:
InfocenterState();
virtual ~InfocenterState();
// OFFSET: LEGO1 0x10071840
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f04dc
return "InfocenterState";
}
// OFFSET: LEGO1 0x10071850
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, InfocenterState::ClassName()) || LegoState::IsA(name);
}
};
#endif // INFOCENTERSTATE_H

7
LEGO1/isle.cpp Normal file
View File

@ -0,0 +1,7 @@
#include "isle.h"
// OFFSET: LEGO1 0x10030820 STUB
Isle::Isle()
{
// TODO
}

28
LEGO1/isle.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef ISLE_H
#define ISLE_H
#include "legoworld.h"
// VTABLE 0x100d6fb8
// SIZE 0x140
// Radio at 0x12c
class Isle : public LegoWorld
{
public:
Isle();
// OFFSET: LEGO1 0x10030910
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f0458
return "Isle";
}
// OFFSET: LEGO1 0x10030920
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, Isle::ClassName()) || LegoWorld::IsA(name);
}
};
#endif // ISLE_H

1
LEGO1/isleactor.cpp Normal file
View File

@ -0,0 +1 @@
#include "isleactor.h"

24
LEGO1/isleactor.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef ISLEACTOR_H
#define ISLEACTOR_H
#include "legoactor.h"
// VTABLE 0x100d5178
class IsleActor : public LegoActor
{
public:
// OFFSET: LEGO1 0x1000e660
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f07dc
return "IsleActor";
}
// OFFSET: LEGO1 0x1000e670
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, IsleActor::ClassName()) || LegoActor::IsA(name);
}
};
#endif // ISLEACTOR_H

1
LEGO1/islepathactor.cpp Normal file
View File

@ -0,0 +1 @@
#include "islepathactor.h"

25
LEGO1/islepathactor.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef ISLEPATHACTOR_H
#define ISLEPATHACTOR_H
#include "legopathactor.h"
// VTABLE 0x100d4398
// SIZE >= 0x230
class IslePathActor : public LegoPathActor
{
public:
// OFFSET: LEGO1 0x10002ea0
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f0104
return "IslePathActor";
}
// OFFSET: LEGO1 0x10002eb0
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, IslePathActor::ClassName()) || LegoPathActor::IsA(name);
}
};
#endif // ISLEPATHACTOR_H

7
LEGO1/jetski.cpp Normal file
View File

@ -0,0 +1,7 @@
#include "jetski.h"
// OFFSET: LEGO1 0x1007e3b0 STUB
Jetski::Jetski()
{
// TODO
}

29
LEGO1/jetski.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef JETSKI_H
#define JETSKI_H
#include "islepathactor.h"
// VTABLE 0x100d9ec8
// SIZE 0x164
class Jetski : public IslePathActor
{
public:
Jetski();
// OFFSET: LEGO1 0x1007e430
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f03d8
return "Jetski";
}
// OFFSET: LEGO1 0x1007e440
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, Jetski::ClassName()) || IslePathActor::IsA(name);
}
};
#endif // JETSKI_H

1
LEGO1/jetskirace.cpp Normal file
View File

@ -0,0 +1 @@
#include "jetskirace.h"

26
LEGO1/jetskirace.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef JETSKIRACE_H
#define JETSKIRACE_H
#include "legorace.h"
// VTABLE 0x100d4fe8
// SIZE 0x144
class JetskiRace : public LegoRace
{
public:
// OFFSET: LEGO1 0x1000daf0
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f0530
return "JetskiRace";
}
// OFFSET: LEGO1 0x1000db00
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, JetskiRace::ClassName()) || LegoRace::IsA(name);
}
};
#endif // JETSKIRACE_H

26
LEGO1/jetskiracestate.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef JETSKIRACESTATE_H
#define JETSKIRACESTATE_H
#include "racestate.h"
// VTABLE 0x100d4fa8
// SIZE 0x2c
class JetskiRaceState : public RaceState
{
public:
// OFFSET: LEGO1 0x1000dc40
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f00ac
return "JetskiRaceState";
}
// OFFSET: LEGO1 0x1000dc50
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, JetskiRaceState::ClassName()) || RaceState::IsA(name);
}
};
#endif // JETSKIRACESTATE_H

7
LEGO1/jukebox.cpp Normal file
View File

@ -0,0 +1,7 @@
#include "jukebox.h"
// OFFSET: LEGO1 0x1005d660 STUB
JukeBox::JukeBox()
{
// TODO
}

28
LEGO1/jukebox.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef JUKEBOX_H
#define JUKEBOX_H
#include "legoworld.h"
// VTABLE 0x100d8958
// SIZE 0x104
class JukeBox : public LegoWorld
{
public:
JukeBox();
// OFFSET: LEGO1 0x1005d6f0
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f02cc
return "JukeBox";
}
// OFFSET: LEGO1 0x1005d700
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, JukeBox::ClassName()) || LegoWorld::IsA(name);
}
};
#endif // JUKEBOX_H

13
LEGO1/jukeboxentity.cpp Normal file
View File

@ -0,0 +1,13 @@
#include "jukeboxentity.h"
// OFFSET: LEGO1 0x10085bc0 STUB
JukeBoxEntity::JukeBoxEntity()
{
// TODO
}
// OFFSET: LEGO1 0x10085dd0 STUB
JukeBoxEntity::~JukeBoxEntity()
{
// TODO
}

29
LEGO1/jukeboxentity.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef JUKEBOXENTITY_H
#define JUKEBOXENTITY_H
#include "legoentity.h"
// VTABLE 0x100da8a0
// SIZE 0x6c
class JukeBoxEntity : public LegoEntity
{
public:
JukeBoxEntity();
virtual ~JukeBoxEntity() override; // vtable+0x0
// OFFSET: LEGO1 0x10085cc0
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f02f0
return "JukeBoxEntity";
}
// OFFSET: LEGO1 0x10085cd0
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, JukeBoxEntity::ClassName()) || LegoEntity::IsA(name);
}
};
#endif // JUKEBOXENTITY_H

1
LEGO1/jukeboxstate.cpp Normal file
View File

@ -0,0 +1 @@
#include "jukeboxstate.h"

26
LEGO1/jukeboxstate.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef JUKEBOXSTATE_H
#define JUKEBOXSTATE_H
#include "legostate.h"
// VTABLE 0x100d4a90
// SIZE 0x10
class JukeBoxState : public LegoState
{
public:
// OFFSET: LEGO1 0x1000f310
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f02bc
return "JukeBoxState";
}
// OFFSET: LEGO1 0x1000f320
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, JukeBoxState::ClassName()) || LegoState::IsA(name);
}
};
#endif // JUKEBOXSTATE_H

View File

@ -0,0 +1,25 @@
#ifndef LEGO3DWAVEPRESENTER_H
#define LEGO3DWAVEPRESENTER_H
#include "legowavepresenter.h"
// VTABLE 0x100d52b0
// SIZE 0xa0
class Lego3DWavePresenter : public LegoWavePresenter
{
public:
// OFFSET: LEGO1 0x1000d890
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f058c
return "Lego3DWavePresenter";
}
// OFFSET: LEGO1 0x1000d8a0
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, Lego3DWavePresenter::ClassName()) || MxWavePresenter::IsA(name);
}
};
#endif // LEGO3DWAVEPRESENTER_H

1
LEGO1/legoact2state.cpp Normal file
View File

@ -0,0 +1 @@
#include "legoact2state.h"

26
LEGO1/legoact2state.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef LEGOACT2STATE_H
#define LEGOACT2STATE_H
#include "legostate.h"
// VTABLE 0x100d4a70
// SIZE 0x10
class LegoAct2State : public LegoState
{
public:
// OFFSET: LEGO1 0x1000df80
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f0428
return "LegoAct2State";
}
// OFFSET: LEGO1 0x1000df90
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, LegoAct2State::ClassName()) || LegoState::IsA(name);
}
};
#endif // LEGOACT2STATE_H

View File

@ -0,0 +1 @@
#include "legoactioncontrolpresenter.h"

View File

@ -0,0 +1,25 @@
#ifndef LEGOACTIONCONTROLPRESENTER_H
#define LEGOACTIONCONTROLPRESENTER_H
#include "mxmediapresenter.h"
// VTABLE 0x100d5118
// SIZE 0x68
class LegoActionControlPresenter : public MxMediaPresenter
{
public:
// OFFSET: LEGO1 0x1000d0e0
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f05bc
return "LegoActionControlPresenter";
}
// OFFSET: LEGO1 0x1000d0f0
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, LegoActionControlPresenter::ClassName()) || MxMediaPresenter::IsA(name);
}
};
#endif // LEGOACTIONCONTROLPRESENTER_H

25
LEGO1/legoactor.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef LEGOACTOR_H
#define LEGOACTOR_H
#include "legoentity.h"
// VTABLE 0x100d6d68
// SIZE 0x78
class LegoActor : public LegoEntity
{
public:
// OFFSET: LEGO1 0x1002d210
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f0124
return "LegoActor";
}
// OFFSET: LEGO1 0x1002d220
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, LegoActor::ClassName()) || LegoEntity::IsA(name);
}
};
#endif // LEGOACTOR_H

View File

@ -0,0 +1,25 @@
#ifndef LEGOACTORPRESENTER_H
#define LEGOACTORPRESENTER_H
#include "legoentitypresenter.h"
// VTABLE 0x100d5320
// SIZE 0x50
class LegoActorPresenter : public LegoEntityPresenter
{
public:
// OFFSET: LEGO1 0x1000cb10
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f06a4
return "LegoActorPresenter";
}
// OFFSET: LEGO1 0x1000cb20
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, LegoActorPresenter::ClassName()) || LegoEntityPresenter::IsA(name);
}
};
#endif // LEGOACTORPRESENTER_H

1
LEGO1/legoanimactor.cpp Normal file
View File

@ -0,0 +1 @@
#include "legoanimactor.h"

11
LEGO1/legoanimactor.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef LEGOANIMACTOR_H
#define LEGOANIMACTOR_H
#include "legopathactor.h"
class LegoAnimActor : public LegoPathActor
{
public:
};
#endif // LEGOANIMACTOR_H

View File

@ -0,0 +1,34 @@
#include "legoanimationmanager.h"
// OFFSET: LEGO1 0x1005eb60 STUB
LegoAnimationManager::LegoAnimationManager()
{
}
// OFFSET: LEGO1 0x1005ed30 STUB
LegoAnimationManager::~LegoAnimationManager()
{
// TODO
}
// OFFSET: LEGO1 0x100619f0 STUB
long LegoAnimationManager::Notify(MxParam &p)
{
// TODO
return 0;
}
// OFFSET: LEGO1 0x10061cc0 STUB
long LegoAnimationManager::Tickle()
{
// TODO
return 0;
}
// OFFSET: LEGO1 0x1005f130 STUB
void LegoAnimationManager::Init()
{
// TODO
}

View File

@ -1,10 +1,37 @@
#ifndef LEGOANIMATIONMANAGER_H #ifndef LEGOANIMATIONMANAGER_H
#define LEGOANIMATIONMANAGER_H #define LEGOANIMATIONMANAGER_H
class LegoAnimationManager #include "mxcore.h"
// VTABLE 0x100d8c18
// SIZE 0x500
class LegoAnimationManager : public MxCore
{ {
public: public:
LegoAnimationManager();
virtual ~LegoAnimationManager() override; // vtable+0x0
virtual long Notify(MxParam &p) override; // vtable+0x4
virtual long Tickle() override; // vtable+0x8
// OFFSET: LEGO1 0x1005ec80
inline virtual const char *ClassName() const override // vtable+0x0c
{
// 0x100f7508
return "LegoAnimationManager";
}
// OFFSET: LEGO1 0x1005ec90
inline virtual MxBool IsA(const char *name) const override // vtable+0x10
{
return !strcmp(name, ClassName()) || MxCore::IsA(name);
}
__declspec(dllexport) static void configureLegoAnimationManager(int param_1); __declspec(dllexport) static void configureLegoAnimationManager(int param_1);
private:
void Init();
}; };
#endif // LEGOANIMATIONMANAGER_H #endif // LEGOANIMATIONMANAGER_H

View File

@ -0,0 +1,7 @@
#include "legoanimmmpresenter.h"
// OFFSET: LEGO1 0x1004a8d0 STUB
LegoAnimMMPresenter::LegoAnimMMPresenter()
{
// TODO
}

Some files were not shown because too many files have changed in this diff Show More