mirror of
https://github.com/isledecomp/isle.git
synced 2026-01-20 23:01:16 +00:00
merge master
This commit is contained in:
commit
5a90ca6422
7
.gitattributes
vendored
Normal file
7
.gitattributes
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
*.MD text eol=lf diff=markdown
|
||||
*.cpp text eol=lf diff=cpp
|
||||
*.h text eol=lf diff=cpp
|
||||
*.py text eol=lf diff=python
|
||||
*.html text eol=lf diff=html
|
||||
*.mdp binary
|
||||
*.mak text eol=crlf
|
||||
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -60,8 +60,8 @@ jobs:
|
||||
C:\msys64\usr\bin\wget.exe https://legoisland.org/download/ISLE.EXE
|
||||
C:\msys64\usr\bin\wget.exe https://legoisland.org/download/LEGO1.DLL
|
||||
pip install capstone
|
||||
python3 tools/reccomp/reccomp.py -h ISLEPROGRESS.HTML ISLE.EXE Release/ISLE.EXE Release/ISLE.PDB ISLE
|
||||
python3 tools/reccomp/reccomp.py -h LEGO1PROGRESS.HTML LEGO1.DLL Release/LEGO1.DLL Release/LEGO1.PDB LEGO1
|
||||
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 .
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@master
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,3 +2,5 @@ Debug/
|
||||
Release/
|
||||
*.ncb
|
||||
/.vs
|
||||
ISLE.EXE
|
||||
LEGO1.DLL
|
||||
|
||||
@ -38,6 +38,3 @@ int g_startupDelay = 200;
|
||||
|
||||
// 0x4101c0
|
||||
long g_lastFrameTime = 0;
|
||||
|
||||
// 0x4101dc
|
||||
const char *WINDOW_TITLE = "LEGO\xAE";
|
||||
|
||||
@ -1,14 +1,16 @@
|
||||
#ifndef DEFINE_H
|
||||
#define DEFINE_H
|
||||
|
||||
#include <Windows.h>
|
||||
#include "legoinc.h"
|
||||
|
||||
class Isle;
|
||||
|
||||
extern Isle *g_isle;
|
||||
extern int g_closed;
|
||||
// 0x4101c4
|
||||
#define WNDCLASS_NAME "Lego Island MainNoM App"
|
||||
extern const char *WINDOW_TITLE;
|
||||
// 0x4101dc
|
||||
#define WINDOW_TITLE "LEGO\xAE"
|
||||
extern unsigned char g_mousedown;
|
||||
extern unsigned char g_mousemoved;
|
||||
extern RECT g_windowRect;
|
||||
|
||||
384
ISLE/isle.cpp
384
ISLE/isle.cpp
@ -1,17 +1,5 @@
|
||||
#include "isle.h"
|
||||
|
||||
#include "define.h"
|
||||
#include "legoanimationmanager.h"
|
||||
#include "legobuildingmanager.h"
|
||||
#include "legomodelpresenter.h"
|
||||
#include "legoomni.h"
|
||||
#include "legopartpresenter.h"
|
||||
#include "legoworldpresenter.h"
|
||||
#include "mxdirectdraw.h"
|
||||
#include "mxdsaction.h"
|
||||
#include "mxomni.h"
|
||||
#include "res/resource.h"
|
||||
|
||||
// OFFSET: ISLE 0x401000
|
||||
Isle::Isle()
|
||||
{
|
||||
@ -38,7 +26,7 @@ Isle::Isle()
|
||||
m_windowActive = 1;
|
||||
|
||||
m_videoParam = MxVideoParam(MxRect32(0, 0, 639, 479), NULL, 1, MxVideoParamFlags());
|
||||
m_videoParam.flags().Enable16Bit(MxDirectDraw::GetPrimaryBitDepth() == 16);
|
||||
m_videoParam.flags().Set16Bit(MxDirectDraw::GetPrimaryBitDepth() == 16);
|
||||
|
||||
m_windowHandle = NULL;
|
||||
m_cursorArrow = NULL;
|
||||
@ -78,7 +66,7 @@ Isle::~Isle()
|
||||
void Isle::Close()
|
||||
{
|
||||
MxDSAction ds;
|
||||
ds.SetUnknown24(0xFFFE);
|
||||
ds.SetUnknown24(-2);
|
||||
|
||||
if (Lego()) {
|
||||
GameState()->Save(0);
|
||||
@ -230,22 +218,22 @@ void Isle::LoadConfig()
|
||||
|
||||
// OFFSET: ISLE 0x401560
|
||||
void Isle::SetupVideoFlags(BOOL fullScreen, BOOL flipSurfaces, BOOL backBuffers,
|
||||
BOOL using8bit, BOOL m_using16bit, BOOL param_6, BOOL param_7,
|
||||
BOOL using8bit, BOOL using16bit, BOOL param_6, BOOL param_7,
|
||||
BOOL wideViewAngle, char *deviceId)
|
||||
{
|
||||
m_videoParam.flags().EnableFullScreen(fullScreen);
|
||||
m_videoParam.flags().EnableFlipSurfaces(flipSurfaces);
|
||||
m_videoParam.flags().EnableBackBuffers(backBuffers);
|
||||
m_videoParam.flags().EnableUnknown1(param_6);
|
||||
m_videoParam.flags().SetUnknown3(param_7);
|
||||
m_videoParam.flags().EnableWideViewAngle(wideViewAngle);
|
||||
m_videoParam.flags().EnableUnknown2();
|
||||
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().Set8Bit();
|
||||
m_videoParam.flags().Set16Bit(0);
|
||||
}
|
||||
if (m_using16bit) {
|
||||
m_videoParam.flags().Set16Bit();
|
||||
if (using16bit) {
|
||||
m_videoParam.flags().Set16Bit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -293,348 +281,4 @@ void Isle::SetupCursor(WPARAM wParam)
|
||||
}
|
||||
|
||||
SetCursor(m_cursorCurrent);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// OFFSET: ISLE 0x4023e0
|
||||
MxResult Isle::SetupWindow(HINSTANCE hInstance)
|
||||
{
|
||||
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, MAKEINTRESOURCE(APP_ICON));
|
||||
wndclass.hCursor = LoadCursorA(hInstance, MAKEINTRESOURCE(ISLE_ARROW));
|
||||
m_cursorCurrent = wndclass.hCursor;
|
||||
m_cursorArrow = wndclass.hCursor;
|
||||
m_cursorBusy = LoadCursorA(hInstance, MAKEINTRESOURCE(ISLE_BUSY));
|
||||
m_cursorNo = LoadCursorA(hInstance, MAKEINTRESOURCE(ISLE_NO));
|
||||
wndclass.hInstance = hInstance;
|
||||
wndclass.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
|
||||
wndclass.lpszClassName = WNDCLASS_NAME;
|
||||
|
||||
if (!RegisterClassA(&wndclass)) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
DWORD dwStyle;
|
||||
int x, y, width, height;
|
||||
|
||||
if (!m_fullScreen) {
|
||||
AdjustWindowRectEx(&g_windowRect, WS_CAPTION | WS_SYSMENU, 0, WS_EX_APPWINDOW);
|
||||
|
||||
height = g_windowRect.bottom - g_windowRect.top;
|
||||
width = g_windowRect.right - g_windowRect.left;
|
||||
|
||||
y = CW_USEDEFAULT;
|
||||
x = CW_USEDEFAULT;
|
||||
dwStyle = WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
|
||||
} else {
|
||||
AdjustWindowRectEx(&g_windowRect, WS_CAPTION | WS_SYSMENU, 0, WS_EX_APPWINDOW);
|
||||
height = g_windowRect.bottom - g_windowRect.top;
|
||||
width = g_windowRect.right - g_windowRect.left;
|
||||
dwStyle = WS_CAPTION | WS_SYSMENU;
|
||||
x = g_windowRect.left;
|
||||
y = g_windowRect.top;
|
||||
}
|
||||
|
||||
m_windowHandle = CreateWindowExA(WS_EX_APPWINDOW, WNDCLASS_NAME, WINDOW_TITLE, dwStyle,
|
||||
x, y, width + 1, height + 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;
|
||||
if (m_islandQuality == 0) {
|
||||
iVar10 = 1;
|
||||
} else if (m_islandQuality == 1) {
|
||||
iVar10 = 2;
|
||||
} else {
|
||||
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_unk00[0xCD] = m_useJoystick;
|
||||
LegoOmni::GetInstance()->GetInputManager()->m_unk00[0x67] = 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
|
||||
void Isle::Tick(BOOL sleepIfNotNextFrame)
|
||||
{
|
||||
if (this->m_windowActive) {
|
||||
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(0xFFFF);
|
||||
ds.SetUnknown1c(0);
|
||||
VideoManager()->EnableFullScreenMovie(TRUE, TRUE);
|
||||
|
||||
if (Start(&ds) != SUCCESS) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
ds.SetAtomId(stream->atom);
|
||||
ds.SetUnknown24(0xFFFF);
|
||||
ds.SetUnknown1c(0);
|
||||
if (Start(&ds) != SUCCESS) {
|
||||
return;
|
||||
}
|
||||
this->m_gameStarted = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (sleepIfNotNextFrame == 0) return;
|
||||
}
|
||||
|
||||
Sleep(0);
|
||||
}
|
||||
}
|
||||
203
ISLE/isle.h
203
ISLE/isle.h
@ -1,10 +1,21 @@
|
||||
#ifndef ISLE_H
|
||||
#define ISLE_H
|
||||
|
||||
#include <windows.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
|
||||
{
|
||||
@ -18,14 +29,14 @@ class Isle
|
||||
int ReadRegBool(LPCSTR name, BOOL *out);
|
||||
int ReadRegInt(LPCSTR name, int *out);
|
||||
|
||||
MxResult SetupWindow(HINSTANCE hInstance);
|
||||
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 m_using16bit, BOOL param_6, BOOL param_7,
|
||||
BOOL using8bit, BOOL using16bit, BOOL param_6, BOOL param_7,
|
||||
BOOL wideViewAngle, char *deviceId);
|
||||
|
||||
void SetupCursor(WPARAM wParam);
|
||||
@ -77,4 +88,190 @@ class Isle
|
||||
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
189
ISLE/main.cpp
189
ISLE/main.cpp
@ -1,9 +1,10 @@
|
||||
#include <dsound.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "legoinc.h"
|
||||
#include "define.h"
|
||||
#include "isle.h"
|
||||
|
||||
#include "legoomni.h"
|
||||
#include "isle.h"
|
||||
|
||||
// OFFSET: ISLE 0x401ca0
|
||||
BOOL FindExistingInstance(void)
|
||||
@ -60,7 +61,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
g_isle = new Isle();
|
||||
|
||||
// Create window
|
||||
if (g_isle->SetupWindow(hInstance) != SUCCESS) {
|
||||
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;
|
||||
}
|
||||
@ -89,14 +90,10 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
}
|
||||
|
||||
if (g_isle) {
|
||||
g_isle->Tick(1);
|
||||
g_isle->Tick(0);
|
||||
}
|
||||
|
||||
if (g_closed) {
|
||||
break;
|
||||
}
|
||||
|
||||
do {
|
||||
while (!g_closed) {
|
||||
if (!PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
break;
|
||||
}
|
||||
@ -133,10 +130,182 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
}
|
||||
goto LAB_00401bc7;
|
||||
}
|
||||
} while (!g_closed);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
#include "mxdsobject.h"
|
||||
|
||||
// OFFSET: ISLE 0x00401c40
|
||||
void MxDSObject::SetAtomId(MxAtomId p_atomId)
|
||||
{
|
||||
this->m_atomId = p_atomId;
|
||||
}
|
||||
@ -20,7 +20,10 @@ class LegoInputManager
|
||||
__declspec(dllexport) void Register(MxCore *);
|
||||
__declspec(dllexport) void UnRegister(MxCore *);
|
||||
|
||||
int m_unk00[0x400];
|
||||
char m_pad00[0x19C];
|
||||
int m_joystickIndex;
|
||||
char m_pad200[0x194];
|
||||
MxBool m_useJoystick;
|
||||
};
|
||||
|
||||
#endif // LEGOINPUTMANAGER_H
|
||||
|
||||
@ -100,22 +100,18 @@ LegoNavController::LegoNavController()
|
||||
// inputManager->UnRegister(this);
|
||||
// }
|
||||
|
||||
// TODO: VideoManager()
|
||||
// OFFSET: LEGO1 0x10054ca0
|
||||
// void LegoNavController::SetControlMax(int p_hMax, int p_vMax)
|
||||
// {
|
||||
// LegoVideoManager* videoManager = VideoManager();
|
||||
void LegoNavController::SetControlMax(int p_hMax, int p_vMax)
|
||||
{
|
||||
this->m_hMax = p_hMax;
|
||||
this->m_vMax = p_vMax;
|
||||
|
||||
// this->m_hMax = p_hMax;
|
||||
// this->m_vMax = p_vMax;
|
||||
|
||||
// Probably checks for MxVideoParamFlags: FULL_SCREEN
|
||||
// if ((videoManager->m_unk44 & 0x01) != 0)
|
||||
// {
|
||||
// this->m_hMax = 640;
|
||||
// this->m_vMax = 480;
|
||||
// }
|
||||
// }
|
||||
if (VideoManager()->GetVideoParam().flags().GetFullScreen())
|
||||
{
|
||||
this->m_hMax = 640;
|
||||
this->m_vMax = 480;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10054cd0
|
||||
void LegoNavController::ResetToDefault()
|
||||
|
||||
@ -20,7 +20,7 @@ class LegoNavController : public MxCore
|
||||
LegoNavController();
|
||||
// virtual ~LegoNavController();
|
||||
|
||||
// void SetControlMax(int p_hMax, int p_vMax);
|
||||
void SetControlMax(int p_hMax, int p_vMax);
|
||||
void ResetToDefault();
|
||||
void SetTargets(int p_hPos, int p_vPos, MxBool p_accel);
|
||||
float CalculateNewTargetSpeed(int p_pos, int p_center, float p_maxSpeed);
|
||||
|
||||
@ -24,12 +24,43 @@ LegoOmni *Lego()
|
||||
return (LegoOmni *) MxOmni::GetInstance();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10015710
|
||||
LegoSoundManager *SoundManager()
|
||||
{
|
||||
return LegoOmni::GetInstance()->GetSoundManager();
|
||||
}
|
||||
|
||||
|
||||
// OFFSET: LEGO1 0x10015720
|
||||
LegoVideoManager *VideoManager()
|
||||
{
|
||||
return LegoOmni::GetInstance()->GetVideoManager();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10015730
|
||||
MxBackgroundAudioManager *BackgroundAudioManager()
|
||||
{
|
||||
return LegoOmni::GetInstance()->GetBackgroundAudioManager();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10015740
|
||||
LegoInputManager *InputManager()
|
||||
{
|
||||
return LegoOmni::GetInstance()->GetInputManager();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10015760
|
||||
LegoGameState *GameState()
|
||||
{
|
||||
return LegoOmni::GetInstance()->GetGameState();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10015780
|
||||
LegoNavController *NavController()
|
||||
{
|
||||
return LegoOmni::GetInstance()->GetNavController();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005b5f0
|
||||
long LegoOmni::Notify(MxParam &p)
|
||||
{
|
||||
|
||||
@ -46,7 +46,11 @@ class LegoOmni : public MxOmni
|
||||
virtual unsigned char vtable40();
|
||||
|
||||
LegoVideoManager *GetVideoManager() { return (LegoVideoManager *) m_videoManager; }
|
||||
LegoSoundManager *GetSoundManager() { return (LegoSoundManager *)m_soundManager;}
|
||||
MxBackgroundAudioManager *GetBackgroundAudioManager() { return m_bkgAudioManager; }
|
||||
LegoInputManager *GetInputManager() { return m_inputMgr; }
|
||||
LegoGameState *GetGameState() { return m_gameState; }
|
||||
LegoNavController *GetNavController() { return m_navController; }
|
||||
|
||||
private:
|
||||
int m_unk68;
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
#ifndef LEGOVIDEOMANAGER_H
|
||||
#define LEGOVIDEOMANAGER_H
|
||||
|
||||
#include "mxvideomanager.h"
|
||||
#include "lego3dmanager.h"
|
||||
|
||||
// class LegoVideoManager : public MxVideoManager
|
||||
class LegoVideoManager
|
||||
class LegoVideoManager : public MxVideoManager
|
||||
{
|
||||
public:
|
||||
__declspec(dllexport) int EnableRMDevice();
|
||||
@ -14,31 +14,6 @@ class LegoVideoManager
|
||||
|
||||
inline Lego3DManager *Get3DManager() { return this->m_3dManager; }
|
||||
|
||||
int m_unk00;
|
||||
int m_unk04;
|
||||
int m_unk08;
|
||||
int m_unk0c;
|
||||
int m_unk10;
|
||||
int m_unk14;
|
||||
int m_unk18;
|
||||
int m_unk1c;
|
||||
int m_unk20;
|
||||
int m_unk24;
|
||||
int m_unk28;
|
||||
int m_unk2c;
|
||||
int m_unk30;
|
||||
int m_unk34;
|
||||
int m_unk38;
|
||||
int m_unk3c;
|
||||
int m_unk40;
|
||||
int m_unk44;
|
||||
int m_unk48;
|
||||
int m_unk4c;
|
||||
int m_unk50;
|
||||
int m_unk54;
|
||||
int m_unk58;
|
||||
int m_unk5c;
|
||||
int m_unk60;
|
||||
int m_unk64;
|
||||
Lego3DManager *m_3dManager;
|
||||
int m_unk6c;
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
#include "mxautolocker.h"
|
||||
|
||||
// OFFSET: LEGO1 0x100b8ed0
|
||||
MxAutoLocker::MxAutoLocker(MxCriticalSection *critsect)
|
||||
{
|
||||
this->m_criticalSection = critsect;
|
||||
if (this->m_criticalSection != 0)
|
||||
this->m_criticalSection->Enter();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b8ef0
|
||||
MxAutoLocker::~MxAutoLocker()
|
||||
{
|
||||
if (this->m_criticalSection != 0)
|
||||
this->m_criticalSection->Leave();
|
||||
}
|
||||
#include "mxautolocker.h"
|
||||
|
||||
// OFFSET: LEGO1 0x100b8ed0
|
||||
MxAutoLocker::MxAutoLocker(MxCriticalSection *critsect)
|
||||
{
|
||||
this->m_criticalSection = critsect;
|
||||
if (this->m_criticalSection != 0)
|
||||
this->m_criticalSection->Enter();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b8ef0
|
||||
MxAutoLocker::~MxAutoLocker()
|
||||
{
|
||||
if (this->m_criticalSection != 0)
|
||||
this->m_criticalSection->Leave();
|
||||
}
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
#ifndef MXAUTOLOCKER_H
|
||||
#define MXAUTOLOCKER_H
|
||||
|
||||
#include "mxcriticalsection.h"
|
||||
|
||||
class MxAutoLocker
|
||||
{
|
||||
public:
|
||||
MxAutoLocker(MxCriticalSection* cs);
|
||||
virtual ~MxAutoLocker();
|
||||
private:
|
||||
MxCriticalSection* m_criticalSection;
|
||||
};
|
||||
|
||||
#endif // MXAUTOLOCKER_H
|
||||
#ifndef MXAUTOLOCKER_H
|
||||
#define MXAUTOLOCKER_H
|
||||
|
||||
#include "mxcriticalsection.h"
|
||||
|
||||
class MxAutoLocker
|
||||
{
|
||||
public:
|
||||
MxAutoLocker(MxCriticalSection* cs);
|
||||
virtual ~MxAutoLocker();
|
||||
private:
|
||||
MxCriticalSection* m_criticalSection;
|
||||
};
|
||||
|
||||
#endif // MXAUTOLOCKER_H
|
||||
|
||||
@ -6,14 +6,11 @@
|
||||
// OFFSET: LEGO1 0x100bf6a0
|
||||
MxDSObject::MxDSObject()
|
||||
{
|
||||
// The following code yields 100% matching assembly if m_unk24 is declared as (signed) short.
|
||||
// However, in other areas m_unk24 (notably, ISLE.EXE) is treated as unsigned short.
|
||||
// Since we don't have a proper solution yet, we are using a union to work around this discrepancy.
|
||||
this->m_unk0c = 0;
|
||||
this->m_unk10 = 0;
|
||||
this->m_unk14 = 0;
|
||||
this->m_name = NULL;
|
||||
this->m_unk24signed = -1;
|
||||
this->m_unk24 = -1;
|
||||
this->m_unk1c = -1;
|
||||
this->m_unk28 = 0;
|
||||
}
|
||||
@ -37,9 +34,3 @@ void MxDSObject::SetObjectName(const char *p_name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10005530
|
||||
void MxDSObject::SetAtomId(MxAtomId p_atomId)
|
||||
{
|
||||
this->m_atomId = p_atomId;
|
||||
}
|
||||
|
||||
@ -15,9 +15,11 @@ class MxDSObject : public MxCore
|
||||
inline int GetUnknown1c() { return this->m_unk1c; }
|
||||
|
||||
inline void SetUnknown1c(int p_unk1c) { this->m_unk1c = p_unk1c; }
|
||||
inline void SetUnknown24(unsigned short p_unk24) { this->m_unk24 = p_unk24; }
|
||||
inline void SetUnknown24(short p_unk24) { this->m_unk24 = p_unk24; }
|
||||
|
||||
void SetAtomId(MxAtomId p_atomId);
|
||||
// OFFSET: ISLE 0x401c40
|
||||
// OFFSET: LEGO1 0x10005530
|
||||
inline void SetAtomId(MxAtomId p_atomId) { this->m_atomId = p_atomId; }
|
||||
|
||||
private:
|
||||
int m_unk08;
|
||||
@ -27,13 +29,7 @@ class MxDSObject : public MxCore
|
||||
char *m_name;
|
||||
int m_unk1c;
|
||||
MxAtomId m_atomId;
|
||||
// So far, implementing MxDSObject::MxDSObject correctly required that m_unk24 is declared a (signed) short.
|
||||
// Most of the other game's code appears to treat it as unsigned short, however.
|
||||
// This union is a workaround until we have figured this out.
|
||||
union {
|
||||
unsigned short m_unk24;
|
||||
short m_unk24signed;
|
||||
};
|
||||
short m_unk24;
|
||||
unsigned short m_unk26;
|
||||
int m_unk28;
|
||||
};
|
||||
|
||||
@ -1,17 +1,17 @@
|
||||
#include "mxomnicreateflags.h"
|
||||
|
||||
// OFFSET: LEGO1 0x100b0a30
|
||||
MxOmniCreateFlags::MxOmniCreateFlags()
|
||||
{
|
||||
this->CreateObjectFactory(MX_TRUE);
|
||||
this->CreateVariableTable(MX_TRUE);
|
||||
this->CreateTickleManager(MX_TRUE);
|
||||
this->CreateNotificationManager(MX_TRUE);
|
||||
this->CreateVideoManager(MX_TRUE);
|
||||
this->CreateSoundManager(MX_TRUE);
|
||||
this->CreateMusicManager(MX_TRUE);
|
||||
this->CreateEventManager(MX_TRUE);
|
||||
|
||||
this->CreateTimer(MX_TRUE);
|
||||
this->CreateStreamer(MX_TRUE);
|
||||
}
|
||||
#include "mxomnicreateflags.h"
|
||||
|
||||
// OFFSET: LEGO1 0x100b0a30
|
||||
MxOmniCreateFlags::MxOmniCreateFlags()
|
||||
{
|
||||
this->CreateObjectFactory(MX_TRUE);
|
||||
this->CreateVariableTable(MX_TRUE);
|
||||
this->CreateTickleManager(MX_TRUE);
|
||||
this->CreateNotificationManager(MX_TRUE);
|
||||
this->CreateVideoManager(MX_TRUE);
|
||||
this->CreateSoundManager(MX_TRUE);
|
||||
this->CreateMusicManager(MX_TRUE);
|
||||
this->CreateEventManager(MX_TRUE);
|
||||
|
||||
this->CreateTimer(MX_TRUE);
|
||||
this->CreateStreamer(MX_TRUE);
|
||||
}
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
#include "mxomnicreateparam.h"
|
||||
|
||||
// OFFSET: LEGO1 0x100b0b00
|
||||
MxOmniCreateParam::MxOmniCreateParam(const char *mediaPath, struct HWND__ *windowHandle, MxVideoParam &vparam, MxOmniCreateFlags flags)
|
||||
{
|
||||
this->m_mediaPath = mediaPath;
|
||||
this->m_windowHandle = (HWND) windowHandle;
|
||||
this->m_videoParam = vparam;
|
||||
this->m_createFlags = flags;
|
||||
}
|
||||
#include "mxomnicreateparam.h"
|
||||
|
||||
// OFFSET: LEGO1 0x100b0b00
|
||||
MxOmniCreateParam::MxOmniCreateParam(const char *mediaPath, struct HWND__ *windowHandle, MxVideoParam &vparam, MxOmniCreateFlags flags)
|
||||
{
|
||||
this->m_mediaPath = mediaPath;
|
||||
this->m_windowHandle = (HWND) windowHandle;
|
||||
this->m_videoParam = vparam;
|
||||
this->m_createFlags = flags;
|
||||
}
|
||||
|
||||
8
LEGO1/mxpalette.cpp
Executable file
8
LEGO1/mxpalette.cpp
Executable file
@ -0,0 +1,8 @@
|
||||
#include "mxpalette.h"
|
||||
|
||||
// OFFSET: LEGO1 0x100bf150
|
||||
MxResult MxPalette::GetEntries(LPPALETTEENTRY p_entries)
|
||||
{
|
||||
memcpy(p_entries, this->m_entries, sizeof(this->m_entries));
|
||||
return SUCCESS;
|
||||
}
|
||||
@ -1,11 +1,23 @@
|
||||
#ifndef MXPALETTE_H
|
||||
#define MXPALETTE_H
|
||||
|
||||
class MxPalette
|
||||
#include <ddraw.h>
|
||||
|
||||
#include "mxcore.h"
|
||||
#include "mxresult.h"
|
||||
|
||||
class MxPalette : public MxCore
|
||||
{
|
||||
public:
|
||||
__declspec(dllexport) unsigned char operator==(MxPalette &);
|
||||
__declspec(dllexport) void Detach();
|
||||
|
||||
MxResult GetEntries(LPPALETTEENTRY p_entries);
|
||||
|
||||
private:
|
||||
LPDIRECTDRAWPALETTE m_pDirectDrawPalette;
|
||||
PALETTEENTRY m_entries[256];
|
||||
// there's a bit more here
|
||||
};
|
||||
|
||||
#endif // MXPALETTE_H
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
class MxRect32
|
||||
{
|
||||
public:
|
||||
MxRect32() { }
|
||||
MxRect32(int p_left, int p_top, int p_right, int p_bottom)
|
||||
{
|
||||
this->m_left = p_left;
|
||||
|
||||
@ -1,81 +1,81 @@
|
||||
#include "mxstring.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// OFFSET: LEGO1 0x100ae200
|
||||
MxString::MxString()
|
||||
{
|
||||
// Set string to one char in length and set that char to null terminator
|
||||
this->m_data = (char *)malloc(1);
|
||||
this->m_data[0] = 0;
|
||||
this->m_length = 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ae2a0
|
||||
MxString::MxString(const MxString &str)
|
||||
{
|
||||
this->m_length = str.m_length;
|
||||
this->m_data = (char *)malloc(this->m_length + 1);
|
||||
strcpy(this->m_data, str.m_data);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ae350
|
||||
MxString::MxString(const char *str)
|
||||
{
|
||||
if (str) {
|
||||
this->m_length = strlen(str);
|
||||
this->m_data = (char *)malloc(this->m_length + 1);
|
||||
strcpy(this->m_data, str);
|
||||
} else {
|
||||
this->m_data = (char *)malloc(1);
|
||||
this->m_data[0] = 0;
|
||||
this->m_length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ae420
|
||||
MxString::~MxString()
|
||||
{
|
||||
free(this->m_data);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ae490
|
||||
void MxString::ToUpperCase()
|
||||
{
|
||||
strupr(this->m_data);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ae4a0
|
||||
void MxString::ToLowerCase()
|
||||
{
|
||||
strlwr(this->m_data);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ae4b0
|
||||
const MxString &MxString::operator=(MxString *param)
|
||||
{
|
||||
if (this->m_data != param->m_data)
|
||||
{
|
||||
free(this->m_data);
|
||||
this->m_length = param->m_length;
|
||||
this->m_data = (char *)malloc(this->m_length + 1);
|
||||
strcpy(this->m_data, param->m_data);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// TODO: this *mostly* matches, again weird with the comparison
|
||||
// OFFSET: LEGO1 0x100ae510
|
||||
const MxString &MxString::operator=(const char *param)
|
||||
{
|
||||
if (this->m_data != param)
|
||||
{
|
||||
free(this->m_data);
|
||||
this->m_length = strlen(param);
|
||||
this->m_data = (char *)malloc(this->m_length + 1);
|
||||
strcpy(this->m_data, param);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
#include "mxstring.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// OFFSET: LEGO1 0x100ae200
|
||||
MxString::MxString()
|
||||
{
|
||||
// Set string to one char in length and set that char to null terminator
|
||||
this->m_data = (char *)malloc(1);
|
||||
this->m_data[0] = 0;
|
||||
this->m_length = 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ae2a0
|
||||
MxString::MxString(const MxString &str)
|
||||
{
|
||||
this->m_length = str.m_length;
|
||||
this->m_data = (char *)malloc(this->m_length + 1);
|
||||
strcpy(this->m_data, str.m_data);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ae350
|
||||
MxString::MxString(const char *str)
|
||||
{
|
||||
if (str) {
|
||||
this->m_length = strlen(str);
|
||||
this->m_data = (char *)malloc(this->m_length + 1);
|
||||
strcpy(this->m_data, str);
|
||||
} else {
|
||||
this->m_data = (char *)malloc(1);
|
||||
this->m_data[0] = 0;
|
||||
this->m_length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ae420
|
||||
MxString::~MxString()
|
||||
{
|
||||
free(this->m_data);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ae490
|
||||
void MxString::ToUpperCase()
|
||||
{
|
||||
strupr(this->m_data);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ae4a0
|
||||
void MxString::ToLowerCase()
|
||||
{
|
||||
strlwr(this->m_data);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ae4b0
|
||||
const MxString &MxString::operator=(MxString *param)
|
||||
{
|
||||
if (this->m_data != param->m_data)
|
||||
{
|
||||
free(this->m_data);
|
||||
this->m_length = param->m_length;
|
||||
this->m_data = (char *)malloc(this->m_length + 1);
|
||||
strcpy(this->m_data, param->m_data);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// TODO: this *mostly* matches, again weird with the comparison
|
||||
// OFFSET: LEGO1 0x100ae510
|
||||
const MxString &MxString::operator=(const char *param)
|
||||
{
|
||||
if (this->m_data != param)
|
||||
{
|
||||
free(this->m_data);
|
||||
this->m_length = strlen(param);
|
||||
this->m_data = (char *)malloc(this->m_length + 1);
|
||||
strcpy(this->m_data, param);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -1,42 +1,42 @@
|
||||
#include "mxtimer.h"
|
||||
|
||||
#include "legoinc.h"
|
||||
|
||||
// 0x10101414
|
||||
long MxTimer::s_LastTimeCalculated = 0;
|
||||
|
||||
// 0x10101418
|
||||
long MxTimer::s_LastTimeTimerStarted = 0;
|
||||
|
||||
// OFFSET: LEGO1 0x100ae060
|
||||
MxTimer::MxTimer()
|
||||
#include "mxtimer.h"
|
||||
|
||||
#include "legoinc.h"
|
||||
|
||||
// 0x10101414
|
||||
long MxTimer::s_LastTimeCalculated = 0;
|
||||
|
||||
// 0x10101418
|
||||
long MxTimer::s_LastTimeTimerStarted = 0;
|
||||
|
||||
// OFFSET: LEGO1 0x100ae060
|
||||
MxTimer::MxTimer()
|
||||
{
|
||||
this->m_isRunning = MX_FALSE;
|
||||
m_startTime = timeGetTime();
|
||||
// yeah this is somehow what the asm is
|
||||
s_LastTimeCalculated = m_startTime;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ae160
|
||||
void MxTimer::Start()
|
||||
{
|
||||
s_LastTimeCalculated = m_startTime;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ae160
|
||||
void MxTimer::Start()
|
||||
{
|
||||
s_LastTimeTimerStarted = this->GetRealTime();
|
||||
this->m_isRunning = MX_TRUE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ae180
|
||||
void MxTimer::Stop()
|
||||
{
|
||||
long elapsed = this->GetRealTime();
|
||||
long startTime = elapsed - MxTimer::s_LastTimeTimerStarted;
|
||||
this->m_isRunning = MX_FALSE;
|
||||
// this feels very stupid but it's what the assembly does
|
||||
this->m_startTime = this->m_startTime + startTime - 5;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ae140
|
||||
long MxTimer::GetRealTime()
|
||||
{
|
||||
MxTimer::s_LastTimeCalculated = timeGetTime();
|
||||
return MxTimer::s_LastTimeCalculated - this->m_startTime;
|
||||
}
|
||||
this->m_isRunning = MX_TRUE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ae180
|
||||
void MxTimer::Stop()
|
||||
{
|
||||
long elapsed = this->GetRealTime();
|
||||
long startTime = elapsed - MxTimer::s_LastTimeTimerStarted;
|
||||
this->m_isRunning = MX_FALSE;
|
||||
// this feels very stupid but it's what the assembly does
|
||||
this->m_startTime = this->m_startTime + startTime - 5;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ae140
|
||||
long MxTimer::GetRealTime()
|
||||
{
|
||||
MxTimer::s_LastTimeCalculated = timeGetTime();
|
||||
return MxTimer::s_LastTimeCalculated - this->m_startTime;
|
||||
}
|
||||
|
||||
15
LEGO1/mxunknown100dc6b0.cpp
Executable file
15
LEGO1/mxunknown100dc6b0.cpp
Executable file
@ -0,0 +1,15 @@
|
||||
#include "mxunknown100dc6b0.h"
|
||||
|
||||
// OFFSET: LEGO1 0x100b84c0
|
||||
MxUnknown100dc6b0::MxUnknown100dc6b0()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b85d0
|
||||
MxResult MxUnknown100dc6b0::Init()
|
||||
{
|
||||
this->m_unk08 = 0;
|
||||
this->m_unk0c = 0;
|
||||
return SUCCESS;
|
||||
}
|
||||
23
LEGO1/mxunknown100dc6b0.h
Executable file
23
LEGO1/mxunknown100dc6b0.h
Executable file
@ -0,0 +1,23 @@
|
||||
#ifndef MXUNKNOWN100DC6B0_H
|
||||
#define MXUNKNOWN100DC6B0_H
|
||||
|
||||
#include "mxcore.h"
|
||||
#include "mxresult.h"
|
||||
#include "mxcriticalsection.h"
|
||||
|
||||
class MxUnknown100dc6b0 : public MxCore
|
||||
{
|
||||
public:
|
||||
MxUnknown100dc6b0();
|
||||
|
||||
MxResult Init();
|
||||
|
||||
private:
|
||||
int m_unk08;
|
||||
int m_unk0c;
|
||||
|
||||
protected:
|
||||
MxCriticalSection m_criticalSection;
|
||||
};
|
||||
|
||||
#endif // MXUNKNOWN100DC6B0_H
|
||||
36
LEGO1/mxvideomanager.cpp
Executable file
36
LEGO1/mxvideomanager.cpp
Executable file
@ -0,0 +1,36 @@
|
||||
#include "mxvideomanager.h"
|
||||
|
||||
// OFFSET: LEGO1 0x100be1f0
|
||||
MxVideoManager::MxVideoManager()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100be320
|
||||
int MxVideoManager::Init()
|
||||
{
|
||||
this->m_unk50 = 0;
|
||||
this->m_unk54 = NULL;
|
||||
this->m_unk58 = NULL;
|
||||
this->m_unk5c = 0;
|
||||
this->m_videoParam.SetPalette(NULL);
|
||||
this->m_unk60 = MX_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bebe0
|
||||
long MxVideoManager::RealizePalette(MxPalette *p_palette)
|
||||
{
|
||||
PALETTEENTRY paletteEntries[256];
|
||||
|
||||
this->m_criticalSection.Enter();
|
||||
|
||||
if (p_palette && this->m_videoParam.GetPalette())
|
||||
{
|
||||
p_palette->GetEntries(paletteEntries);
|
||||
// TODO
|
||||
}
|
||||
|
||||
this->m_criticalSection.Leave();
|
||||
return 0;
|
||||
}
|
||||
@ -1,11 +1,28 @@
|
||||
#ifndef MXVIDEOMANAGER_H
|
||||
#define MXVIDEOMANAGER_H
|
||||
|
||||
class MxVideoManager
|
||||
#include "mxunknown100dc6b0.h"
|
||||
#include "mxvideoparam.h"
|
||||
|
||||
class MxVideoManager : public MxUnknown100dc6b0
|
||||
{
|
||||
public:
|
||||
__declspec(dllexport) void InvalidateRect(MxRect32 &);
|
||||
__declspec(dllexport) virtual long RealizePalette(MxPalette *);
|
||||
|
||||
MxVideoManager();
|
||||
|
||||
int Init();
|
||||
|
||||
inline MxVideoParam& GetVideoParam() { return this->m_videoParam; }
|
||||
|
||||
private:
|
||||
MxVideoParam m_videoParam;
|
||||
int m_unk50;
|
||||
LPDIRECTDRAWSURFACE m_unk54;
|
||||
void* m_unk58;
|
||||
int m_unk5c;
|
||||
MxBool m_unk60;
|
||||
};
|
||||
|
||||
#endif // MXVIDEOMANAGER_H
|
||||
|
||||
@ -1,62 +1,88 @@
|
||||
#include "mxvideoparam.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// OFFSET: LEGO1 0x100bec70
|
||||
MxVideoParam::MxVideoParam()
|
||||
{
|
||||
this->m_flags = MxVideoParamFlags();
|
||||
this->m_right = 640;
|
||||
this->m_bottom = 480;
|
||||
this->m_left = 0;
|
||||
this->m_top = 0;
|
||||
this->m_palette = 0;
|
||||
this->m_backBuffers = 0;
|
||||
this->m_unk1c = 0;
|
||||
this->m_deviceId = 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100becf0
|
||||
MxVideoParam &MxVideoParam::operator=(const MxVideoParam &other)
|
||||
{
|
||||
m_flags = MxVideoParamFlags();
|
||||
m_left = other.m_left;
|
||||
m_top = other.m_top;
|
||||
m_right = other.m_right;
|
||||
m_bottom = other.m_bottom;
|
||||
m_palette = other.m_palette;
|
||||
m_backBuffers = other.m_backBuffers;
|
||||
m_flags = other.m_flags;
|
||||
m_unk1c = other.m_unk1c;
|
||||
m_deviceId = other.m_deviceId;
|
||||
SetDeviceName(other.m_deviceId);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bed70
|
||||
void MxVideoParam::SetDeviceName(char *id)
|
||||
{
|
||||
if (this->m_deviceId != 0)
|
||||
free(this->m_deviceId);
|
||||
|
||||
if (id != 0)
|
||||
{
|
||||
this->m_deviceId = (char *)malloc(strlen(id) + 1);
|
||||
|
||||
if (this->m_deviceId != 0) {
|
||||
strcpy(this->m_deviceId, id);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this->m_deviceId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bed50
|
||||
MxVideoParam::~MxVideoParam()
|
||||
{
|
||||
if (this->m_deviceId != 0)
|
||||
free(this->m_deviceId);
|
||||
}
|
||||
#include "mxvideoparam.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// OFFSET: LEGO1 0x100bec70
|
||||
MxVideoParam::MxVideoParam()
|
||||
{
|
||||
this->m_rect.m_right = 640;
|
||||
this->m_rect.m_bottom = 480;
|
||||
this->m_rect.m_left = 0;
|
||||
this->m_rect.m_top = 0;
|
||||
this->m_palette = 0;
|
||||
this->m_backBuffers = 0;
|
||||
this->m_unk1c = 0;
|
||||
this->m_deviceId = 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100beca0
|
||||
MxVideoParam::MxVideoParam(MxRect32 &p_rect, MxPalette *p_pal, unsigned long p_backBuffers, MxVideoParamFlags &p_flags)
|
||||
{
|
||||
this->m_rect.m_left = p_rect.m_left;
|
||||
this->m_rect.m_top = p_rect.m_top;
|
||||
this->m_rect.m_right = p_rect.m_right;
|
||||
this->m_rect.m_bottom = p_rect.m_bottom;
|
||||
this->m_palette = p_pal;
|
||||
this->m_backBuffers = p_backBuffers;
|
||||
this->m_flags = p_flags;
|
||||
this->m_unk1c = 0;
|
||||
this->m_deviceId = NULL;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100becf0
|
||||
MxVideoParam::MxVideoParam(MxVideoParam &p_videoParam)
|
||||
{
|
||||
this->m_rect.m_left = p_videoParam.m_rect.m_left;
|
||||
this->m_rect.m_top = p_videoParam.m_rect.m_top;
|
||||
this->m_rect.m_right = p_videoParam.m_rect.m_right;
|
||||
this->m_rect.m_bottom = p_videoParam.m_rect.m_bottom;
|
||||
this->m_palette = p_videoParam.m_palette;
|
||||
this->m_backBuffers = p_videoParam.m_backBuffers;
|
||||
this->m_flags = p_videoParam.m_flags;
|
||||
this->m_unk1c = p_videoParam.m_unk1c;
|
||||
this->m_deviceId = NULL;
|
||||
SetDeviceName(p_videoParam.m_deviceId);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bede0
|
||||
MxVideoParam &MxVideoParam::operator=(const MxVideoParam &p_videoParam)
|
||||
{
|
||||
this->m_rect.m_left = p_videoParam.m_rect.m_left;
|
||||
this->m_rect.m_top = p_videoParam.m_rect.m_top;
|
||||
this->m_rect.m_right = p_videoParam.m_rect.m_right;
|
||||
this->m_rect.m_bottom = p_videoParam.m_rect.m_bottom;
|
||||
this->m_palette = p_videoParam.m_palette;
|
||||
this->m_backBuffers = p_videoParam.m_backBuffers;
|
||||
this->m_flags = p_videoParam.m_flags;
|
||||
this->m_unk1c = p_videoParam.m_unk1c;
|
||||
SetDeviceName(p_videoParam.m_deviceId);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bed70
|
||||
void MxVideoParam::SetDeviceName(char *id)
|
||||
{
|
||||
if (this->m_deviceId != 0)
|
||||
free(this->m_deviceId);
|
||||
|
||||
if (id != 0)
|
||||
{
|
||||
this->m_deviceId = (char *)malloc(strlen(id) + 1);
|
||||
|
||||
if (this->m_deviceId != 0) {
|
||||
strcpy(this->m_deviceId, id);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this->m_deviceId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bed50
|
||||
MxVideoParam::~MxVideoParam()
|
||||
{
|
||||
if (this->m_deviceId != 0)
|
||||
free(this->m_deviceId);
|
||||
}
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
#ifndef MXVIDEOPARAM_H
|
||||
#define MXVIDEOPARAM_H
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
#include "mxpalette.h"
|
||||
#include "mxbool.h"
|
||||
#include "mxrect32.h"
|
||||
#include "mxvariabletable.h"
|
||||
#include "mxvideoparamflags.h"
|
||||
@ -19,17 +22,16 @@ class MxVideoParam
|
||||
|
||||
inline MxVideoParamFlags &flags() { return m_flags; }
|
||||
|
||||
inline void SetPalette(MxPalette *p_palette) { this->m_palette = p_palette; }
|
||||
inline MxPalette *GetPalette() { return this->m_palette; }
|
||||
|
||||
private:
|
||||
int m_left;
|
||||
int m_top;
|
||||
int m_right;
|
||||
int m_bottom;
|
||||
MxRect32 m_rect;
|
||||
MxPalette *m_palette;
|
||||
int m_backBuffers;
|
||||
unsigned int m_backBuffers;
|
||||
MxVideoParamFlags m_flags;
|
||||
int m_unk1c;
|
||||
char *m_deviceId;
|
||||
|
||||
};
|
||||
|
||||
#endif // MXVIDEOPARAM_H
|
||||
|
||||
@ -1,17 +1,15 @@
|
||||
#include "mxvideoparamflags.h"
|
||||
|
||||
// OFFSET: LEGO1 0x100bec40
|
||||
MxVideoParamFlags::MxVideoParamFlags()
|
||||
{
|
||||
// TODO: convert to EnableXXX function calls
|
||||
unsigned char bVar1 = this->m_flags1;
|
||||
this->m_flags1 = bVar1 & 0xfe;
|
||||
this->m_flags1 = bVar1 & 0xfc;
|
||||
this->m_flags1 = bVar1 & 0xf8;
|
||||
this->m_flags1 = bVar1 & 0xf0;
|
||||
this->m_flags1 = bVar1 & 0xe0;
|
||||
this->m_flags2 = this->m_flags2 | 2;
|
||||
this->m_flags1 = bVar1 & 0xc0;
|
||||
this->m_flags1 = bVar1 & 0xc0 | 0x40;
|
||||
this->m_flags1 = 0xc0;
|
||||
}
|
||||
#include "mxvideoparamflags.h"
|
||||
|
||||
// OFFSET: LEGO1 0x100bec40
|
||||
MxVideoParamFlags::MxVideoParamFlags()
|
||||
{
|
||||
this->SetFullScreen(0);
|
||||
this->SetFlipSurfaces(0);
|
||||
this->SetBackBuffers(0);
|
||||
this->Set_f1bit3(0);
|
||||
this->Set_f1bit4(0);
|
||||
this->Set16Bit(0);
|
||||
this->SetWideViewAngle(1);
|
||||
this->Set_f1bit7(1);
|
||||
this->Set_f2bit1(1);
|
||||
}
|
||||
|
||||
@ -3,85 +3,63 @@
|
||||
|
||||
#include "legoinc.h"
|
||||
|
||||
// Must be union with struct for match.
|
||||
typedef union {
|
||||
struct {
|
||||
BYTE bit0: 1;
|
||||
BYTE bit1: 1;
|
||||
BYTE bit2: 1;
|
||||
BYTE bit3: 1;
|
||||
BYTE bit4: 1;
|
||||
BYTE bit5: 1;
|
||||
BYTE bit6: 1;
|
||||
BYTE bit7: 1;
|
||||
};
|
||||
// BYTE all; // ?
|
||||
} flag_bitfield;
|
||||
|
||||
class MxVideoParamFlags
|
||||
{
|
||||
public:
|
||||
enum LowFlags
|
||||
{
|
||||
FULL_SCREEN = 0x1,
|
||||
FLIP_SURFACES = 0x2,
|
||||
BACK_BUFFERS = 0x4,
|
||||
ENABLE_16BIT = 0x20,
|
||||
WIDE_VIEW_ANGLE = 0x40,
|
||||
UNKNOWN3 = 0x80
|
||||
};
|
||||
|
||||
enum HighFlags
|
||||
{
|
||||
UNKNOWN1 = 0x1,
|
||||
UNKNOWN2 = 0x2
|
||||
};
|
||||
|
||||
__declspec(dllexport) MxVideoParamFlags();
|
||||
|
||||
inline void EnableFullScreen(BOOL e)
|
||||
{
|
||||
m_flags1 = (m_flags1 ^ (e << 0)) & FULL_SCREEN ^ m_flags1;
|
||||
}
|
||||
inline void SetFullScreen(BOOL e) { m_flags1.bit0 = e; }
|
||||
inline void SetFlipSurfaces(BOOL e) { m_flags1.bit1 = e; }
|
||||
inline void SetBackBuffers(BOOL e) { m_flags1.bit2 = e; }
|
||||
inline void Set_f1bit3(BOOL e) { m_flags1.bit3 = e; }
|
||||
inline void Set_f1bit4(BOOL e) { m_flags1.bit4 = e; }
|
||||
inline void Set16Bit(BYTE e) { m_flags1.bit5 = e; }
|
||||
inline void SetWideViewAngle(BOOL e) { m_flags1.bit6 = e; }
|
||||
inline void Set_f1bit7(BOOL e) { m_flags1.bit7 = e; }
|
||||
inline void Set_f2bit0(BOOL e) { m_flags2.bit0 = e; }
|
||||
inline void Set_f2bit1(BOOL e) { m_flags2.bit1 = e; }
|
||||
inline void Set_f2bit2(BOOL e) { m_flags2.bit2 = e; }
|
||||
inline void Set_f2bit3(BOOL e) { m_flags2.bit3 = e; }
|
||||
inline void Set_f2bit4(BOOL e) { m_flags2.bit4 = e; }
|
||||
inline void Set_f2bit5(BOOL e) { m_flags2.bit5 = e; }
|
||||
inline void Set_f2bit6(BOOL e) { m_flags2.bit6 = e; }
|
||||
inline void Set_f2bit7(BOOL e) { m_flags2.bit7 = e; }
|
||||
|
||||
inline void EnableFlipSurfaces(BOOL e)
|
||||
{
|
||||
m_flags1 = (m_flags1 ^ (e << 1)) & FLIP_SURFACES ^ m_flags1;
|
||||
}
|
||||
|
||||
inline void EnableBackBuffers(BOOL e)
|
||||
{
|
||||
m_flags1 = (m_flags1 ^ ((!e) << 2)) & BACK_BUFFERS ^ m_flags1;
|
||||
}
|
||||
|
||||
inline void SetUnknown3(BOOL e)
|
||||
{
|
||||
m_flags1 = (m_flags1 ^ (e << 7)) & UNKNOWN3 ^ m_flags1;
|
||||
}
|
||||
|
||||
inline void Set8Bit()
|
||||
{
|
||||
m_flags1 &= ~ENABLE_16BIT;
|
||||
}
|
||||
|
||||
inline void Set16Bit()
|
||||
{
|
||||
m_flags1 |= ENABLE_16BIT;
|
||||
}
|
||||
|
||||
inline void Enable16Bit(unsigned char e)
|
||||
{
|
||||
m_flags1 = ((e << 5) ^ m_flags1) & ENABLE_16BIT ^ m_flags1;
|
||||
}
|
||||
|
||||
inline void EnableWideViewAngle(BOOL e)
|
||||
{
|
||||
m_flags1 = (m_flags1 ^ (e << 6)) & WIDE_VIEW_ANGLE ^ m_flags1;
|
||||
}
|
||||
|
||||
inline void EnableUnknown1(BOOL e)
|
||||
{
|
||||
m_flags2 = (m_flags2 ^ ((!e) << 0)) & UNKNOWN1 ^ m_flags2;
|
||||
}
|
||||
|
||||
inline void EnableUnknown2(BOOL e)
|
||||
{
|
||||
m_flags2 = (m_flags2 ^ (e << 1)) & UNKNOWN2 ^ m_flags2;
|
||||
}
|
||||
|
||||
inline void EnableUnknown2()
|
||||
{
|
||||
m_flags2 |= UNKNOWN2;
|
||||
}
|
||||
inline BYTE GetFullScreen() { return m_flags1.bit0; }
|
||||
inline BYTE GetFlipSurfaces() { return m_flags1.bit1; }
|
||||
inline BYTE GetBackBuffers() { return m_flags1.bit2; }
|
||||
inline BYTE Get_f1bit3() { return m_flags1.bit3; }
|
||||
inline BYTE Get_f1bit4() { return m_flags1.bit4; }
|
||||
inline BYTE Get16Bit() { return m_flags1.bit5; }
|
||||
inline BYTE GetWideViewAngle() { return m_flags1.bit6; }
|
||||
inline BYTE Get_f1bit7() { return m_flags1.bit7; }
|
||||
inline BYTE Get_f2bit0() { return m_flags2.bit0; }
|
||||
inline BYTE Get_f2bit1() { return m_flags2.bit1; }
|
||||
inline BYTE Get_f2bit2() { return m_flags2.bit2; }
|
||||
inline BYTE Get_f2bit3() { return m_flags2.bit3; }
|
||||
inline BYTE Get_f2bit4() { return m_flags2.bit4; }
|
||||
inline BYTE Get_f2bit5() { return m_flags2.bit5; }
|
||||
inline BYTE Get_f2bit6() { return m_flags2.bit6; }
|
||||
inline BYTE Get_f2bit7() { return m_flags2.bit7; }
|
||||
|
||||
private:
|
||||
unsigned char m_flags1;
|
||||
unsigned char m_flags2;
|
||||
flag_bitfield m_flags1;
|
||||
flag_bitfield m_flags2;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
from capstone import *
|
||||
import difflib
|
||||
import struct
|
||||
@ -7,60 +8,40 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
def print_usage():
|
||||
print('Usage: %s [options] <original-binary> <recompiled-binary> <recompiled-pdb> <decomp-dir>\n' % sys.argv[0])
|
||||
print('\t-v, --verbose <offset>\t\t\tPrint assembly diff for specific function (original file\'s offset)')
|
||||
print('\t-h, --html <output-file>\t\t\tGenerate searchable HTML summary of status and diffs')
|
||||
sys.exit(1)
|
||||
parser = argparse.ArgumentParser(allow_abbrev=False,
|
||||
description='Recompilation Compare: compare an original EXE with a recompiled EXE + PDB.')
|
||||
parser.add_argument('original', metavar='original-binary', help='The original binary')
|
||||
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('--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')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
positional_args = []
|
||||
verbose = None
|
||||
skip = False
|
||||
html = None
|
||||
if args.verbose:
|
||||
try:
|
||||
verbose = int(args.verbose, 16)
|
||||
except ValueError:
|
||||
parser.error('invalid verbose argument')
|
||||
html = args.html
|
||||
|
||||
for i, arg in enumerate(sys.argv):
|
||||
if skip:
|
||||
skip = False
|
||||
continue
|
||||
|
||||
if arg.startswith('-'):
|
||||
# A flag rather than a positional arg
|
||||
flag = arg[1:]
|
||||
|
||||
if flag == 'v' or flag == '-verbose':
|
||||
verbose = int(sys.argv[i + 1], 16)
|
||||
skip = True
|
||||
elif flag == 'h' or flag == '-html':
|
||||
html = sys.argv[i + 1]
|
||||
skip = True
|
||||
else:
|
||||
print('Unknown flag: %s' % arg)
|
||||
print_usage()
|
||||
else:
|
||||
positional_args.append(arg)
|
||||
|
||||
if len(positional_args) != 5:
|
||||
print_usage()
|
||||
|
||||
original = positional_args[1]
|
||||
original = args.original
|
||||
if not os.path.isfile(original):
|
||||
print('Invalid input: Original binary does not exist')
|
||||
sys.exit(1)
|
||||
parser.error('Original binary does not exist')
|
||||
|
||||
recomp = positional_args[2]
|
||||
recomp = args.recompiled
|
||||
if not os.path.isfile(recomp):
|
||||
print('Invalid input: Recompiled binary does not exist')
|
||||
sys.exit(1)
|
||||
parser.error('Recompiled binary does not exist')
|
||||
|
||||
syms = positional_args[3]
|
||||
syms = args.pdb
|
||||
if not os.path.isfile(syms):
|
||||
print('Invalid input: Symbols PDB does not exist')
|
||||
sys.exit(1)
|
||||
parser.error('Symbols PDB does not exist')
|
||||
|
||||
source = positional_args[4]
|
||||
source = args.decomp_dir
|
||||
if not os.path.isdir(source):
|
||||
print('Invalid input: Source directory does not exist')
|
||||
sys.exit(1)
|
||||
parser.error('Source directory does not exist')
|
||||
|
||||
# Declare a class that can automatically convert virtual executable addresses
|
||||
# to file addresses
|
||||
@ -137,14 +118,23 @@ def __init__(self, pdb, file):
|
||||
if current_section == 'SYMBOLS' and 'S_GPROC32' in line:
|
||||
addr = int(line[26:34], 16)
|
||||
|
||||
debug_offs = line_dump[i + 2]
|
||||
debug_start = int(debug_offs[22:30], 16)
|
||||
debug_end = int(debug_offs[43:], 16)
|
||||
|
||||
|
||||
info = RecompiledInfo()
|
||||
info.addr = addr + recompfile.imagebase + recompfile.textvirt
|
||||
info.start = debug_start
|
||||
info.size = debug_end - debug_start
|
||||
|
||||
use_dbg_offs = False
|
||||
if use_dbg_offs:
|
||||
debug_offs = line_dump[i + 2]
|
||||
debug_start = int(debug_offs[22:30], 16)
|
||||
debug_end = int(debug_offs[43:], 16)
|
||||
|
||||
info.start = debug_start
|
||||
info.size = debug_end - debug_start
|
||||
else:
|
||||
info.start = 0
|
||||
info.size = int(line[41:49], 16)
|
||||
|
||||
info.name = line[77:]
|
||||
|
||||
self.funcs[addr] = info
|
||||
@ -208,7 +198,14 @@ def get_recompiled_address(self, filename, line):
|
||||
def sanitize(file, mnemonic, op_str):
|
||||
offsetplaceholder = '<OFFSET>'
|
||||
|
||||
if mnemonic == 'call' or mnemonic == 'jmp':
|
||||
op_str_is_number = False
|
||||
try:
|
||||
int(op_str, 16)
|
||||
op_str_is_number = True
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
if (mnemonic == 'call' or mnemonic == 'jmp') and op_str_is_number:
|
||||
# Filter out "calls" because the offsets we're not currently trying to
|
||||
# match offsets. As long as there's a call in the right place, it's
|
||||
# probably accurate.
|
||||
@ -262,6 +259,10 @@ def parse_asm(file, addr, size):
|
||||
total_accuracy = 0
|
||||
htmlinsert = []
|
||||
|
||||
# Generate basename of original file, used in locating OFFSET lines
|
||||
basename = os.path.basename(os.path.splitext(original)[0])
|
||||
pattern = '// OFFSET:'
|
||||
|
||||
for subdir, dirs, files in os.walk(source):
|
||||
for file in files:
|
||||
srcfilename = os.path.join(os.path.abspath(subdir), file)
|
||||
@ -276,9 +277,14 @@ def parse_asm(file, addr, size):
|
||||
if not line:
|
||||
break
|
||||
|
||||
if line.startswith('// OFFSET:'):
|
||||
par = line[10:].strip().split()
|
||||
line = line.strip()
|
||||
|
||||
if line.startswith(pattern):
|
||||
par = line[len(pattern):].strip().split()
|
||||
module = par[0]
|
||||
if module != basename:
|
||||
continue
|
||||
|
||||
addr = int(par[1], 16)
|
||||
|
||||
find_open_bracket = line
|
||||
@ -67,6 +67,12 @@
|
||||
#sortind {
|
||||
margin: 0 0.5em;
|
||||
}
|
||||
|
||||
.filters {
|
||||
font-size: 10pt;
|
||||
text-align: center;
|
||||
margin: 0.5em 0 1em 0;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
var data = [/* INSERT DATA HERE */];
|
||||
@ -115,18 +121,25 @@
|
||||
}
|
||||
}
|
||||
|
||||
function filter(text) {
|
||||
const filterOptions = { text: '', hidePerfect: false };
|
||||
|
||||
function filter() {
|
||||
closeAllDiffs();
|
||||
|
||||
var ltext = text.toLowerCase();
|
||||
var ltext = filterOptions.text.toLowerCase();
|
||||
|
||||
const collection = document.getElementsByClassName("funcrow");
|
||||
var searchCount = 0;
|
||||
for (var ele of collection) {
|
||||
var eledata = data[ele.dataset.index];
|
||||
if (text == ''
|
||||
|
||||
const textOk = (ltext == ''
|
||||
|| eledata.address.toLowerCase().includes(ltext)
|
||||
|| eledata.name.toLowerCase().includes(ltext)) {
|
||||
|| eledata.name.toLowerCase().includes(ltext));
|
||||
|
||||
const perfOk = (!filterOptions.hidePerfect || (eledata.matching < 1));
|
||||
|
||||
if (textOk && perfOk) {
|
||||
ele.style.display = '';
|
||||
searchCount++;
|
||||
} else {
|
||||
@ -219,9 +232,16 @@
|
||||
|
||||
var search = document.getElementById('search');
|
||||
search.addEventListener('input', function (evt) {
|
||||
filter(search.value);
|
||||
filterOptions.text = search.value;
|
||||
filter();
|
||||
});
|
||||
|
||||
const cbHidePerfect = document.getElementById('cbHidePerfect');
|
||||
cbHidePerfect.addEventListener('change', evt => {
|
||||
filterOptions.hidePerfect = evt.target.checked;
|
||||
filter();
|
||||
})
|
||||
|
||||
sortByColumn(0);
|
||||
});
|
||||
</script>
|
||||
@ -230,8 +250,10 @@
|
||||
<div class="main">
|
||||
<h1>Decompilation Status</h1>
|
||||
<input id="search" type="search" placeholder="Search for offset or function name...">
|
||||
<br>
|
||||
<br>
|
||||
<div class="filters">
|
||||
<label for="cbHidePerfect">Hide 100% match</label>
|
||||
<input type="checkbox" id="cbHidePerfect" />
|
||||
</div>
|
||||
<table id="listing">
|
||||
<tr id='listingheader'><th style='width: 20%'>Address</th><th style="width:60%">Name</th><th style='width: 20%'>Matching</th></tr>
|
||||
</table>
|
||||
Loading…
Reference in New Issue
Block a user