Merge branch 'master' into mxregion

This commit is contained in:
Christian Semmler
2023-10-25 16:55:26 -04:00
committed by GitHub
70 changed files with 257 additions and 186 deletions

View File

@@ -19,6 +19,7 @@ ContinuationIndentWidth: 4
IncludeBlocks: Regroup
IndentAccessModifiers: false
IndentWidth: 4
InsertNewlineAtEOF: true
PointerAlignment: Left
SpaceAfterCStyleCast: true
TabWidth: 4

9
.gitignore vendored
View File

@@ -3,6 +3,15 @@ Release/
*.ncb
/.vs
/.vscode
/.idea
.env
.venv
env/
venv/
ENV/
VENV/
env.bak/
venv.bak/
ISLE.EXE
LEGO1.DLL
build/

View File

@@ -65,6 +65,7 @@ add_library(lego1 SHARED
LEGO1/legocontrolmanager.cpp
LEGO1/legoentity.cpp
LEGO1/legoentitypresenter.cpp
LEGO1/legoeventnotificationparam.cpp
LEGO1/legoflctexturepresenter.cpp
LEGO1/legofullscreenmovie.cpp
LEGO1/legogamestate.cpp
@@ -99,7 +100,6 @@ add_library(lego1 SHARED
LEGO1/legoworldpresenter.cpp
LEGO1/motorcycle.cpp
LEGO1/mxactionnotificationparam.cpp
LEGO1/mxappnotificationparam.cpp
LEGO1/mxatomid.cpp
LEGO1/mxatomidcounter.cpp
LEGO1/mxaudiomanager.cpp

View File

@@ -25,7 +25,12 @@ This repository currently has only one goal: accuracy to the original executable
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:
- Indent: 2 spaces
### Formatting
We are currently using [clang-format](https://clang.llvm.org/docs/ClangFormat.html) with a configuration file that aims to replicate the code formatting employed by the original developers. There are [integrations](https://clang.llvm.org/docs/ClangFormat.html#vim-integration) available for most editors and IDEs. The required `clang-format` version is `17.x`.
### Naming conventions
- `PascalCase` for classes, function names, and enumerations.
- `m_camelCase` for member variables.
- `g_camelCase` for global variables.

View File

@@ -12,22 +12,14 @@ LegoEntity::~LegoEntity()
Destroy(TRUE);
}
// OFFSET: LEGO1 0x100114f0 STUB
MxLong LegoEntity::Notify(MxParam& p)
{
// TODO
return 0;
}
// OFFSET: LEGO1 0x100105f0
void LegoEntity::Reset()
void LegoEntity::Init()
{
m_vec1.Fill(0);
m_vec2.Fill(0);
m_unk50 = 0;
m_unk54 = 0;
m_unk58 = 0;
m_worldLocation.Fill(0);
m_worldDirection.Fill(0);
m_worldSpeed = 0;
m_roi = NULL;
m_cameraFlag = 0;
m_actionArgString = NULL;
m_unk10 = 0;
m_unk11 = 0;
@@ -36,35 +28,53 @@ void LegoEntity::Reset()
m_unk59 = 4;
}
// OFFSET: LEGO1 0x10010650 STUB
void LegoEntity::ResetWorldTransform(MxBool p_inVehicle)
{
// TODO
}
// OFFSET: LEGO1 0x10010790 STUB
void LegoEntity::SetWorldTransform(MxVector3& p_loc, MxVector3& p_dir, MxVector3& p_up)
{
// TODO
}
// OFFSET: LEGO1 0x100107e0
MxResult LegoEntity::InitFromMxDSObject(MxDSObject& p_dsObject)
{
m_mxEntityId = p_dsObject.GetObjectId();
m_atom = p_dsObject.GetAtomId();
AddToCurrentWorld();
Init();
return SUCCESS;
}
// OFFSET: LEGO1 0x10010810 STUB
void LegoEntity::Destroy(MxBool p_fromDestructor)
{
if (m_unk54) {
if (m_roi) {
// TODO
}
delete[] m_actionArgString;
Reset();
Init();
}
// OFFSET: LEGO1 0x10010880 STUB
void LegoEntity::AddToCurrentWorld()
void LegoEntity::SetWorld()
{
LegoWorld* world = GetCurrentWorld();
if (world != NULL && world != (LegoWorld*) this) {
// TODO: world->vtable58(this);
// TODO: world->AddEntity(this);
}
}
// OFFSET: LEGO1 0x100108a0 STUB
void LegoEntity::SetROI(LegoROI* p_roi, MxBool p_bool1, MxBool p_bool2)
{
// TODO
}
// OFFSET: LEGO1 0x10010e10
void LegoEntity::ParseAction(char* p_extra)
{
@@ -88,24 +98,6 @@ void LegoEntity::ParseAction(char* p_extra)
}
}
// OFFSET: LEGO1 0x100108a0 STUB
void LegoEntity::VTable0x24()
{
// TODO
}
// OFFSET: LEGO1 0x10010790 STUB
void LegoEntity::VTable0x28()
{
// TODO
}
// OFFSET: LEGO1 0x10010650 STUB
void LegoEntity::VTable0x2c()
{
// TODO
}
// OFFSET: LEGO1 0x10010f10 STUB
void LegoEntity::VTable0x34()
{
@@ -147,3 +139,11 @@ void LegoEntity::VTable0x4c()
{
// TODO
}
// OFFSET: LEGO1 0x100114f0 STUB
MxLong LegoEntity::Notify(MxParam& p)
{
// TODO
return 0;
}

View File

@@ -3,6 +3,7 @@
#include "decomp.h"
#include "extra.h"
#include "legoroi.h"
#include "mxdsobject.h"
#include "mxentity.h"
#include "mxvector.h"
@@ -37,11 +38,11 @@ public:
virtual MxResult InitFromMxDSObject(MxDSObject& p_dsObject); // vtable+0x18
virtual void Destroy(MxBool p_fromDestructor); // vtable+0x1c
virtual void ParseAction(char*); // vtable+0x20
virtual void VTable0x24(); // vtable+0x24
virtual void VTable0x28(); // vtable+0x28
virtual void VTable0x2c(); // vtable+0x2c
virtual void SetROI(LegoROI* p_roi, MxBool p_bool1, MxBool p_bool2); // vtable+0x24
virtual void SetWorldTransform(MxVector3& p_loc, MxVector3& p_dir, MxVector3& p_up); // vtable+0x28
virtual void ResetWorldTransform(MxBool p_inVehicle); // vtable+0x2c
// OFFSET: LEGO1 0x10001090
virtual void VTable0x30(undefined4 p_unk50) { m_unk50 = p_unk50; } // vtable+0x30
virtual void SetWorldSpeed(MxFloat p_worldSpeed) { m_worldSpeed = p_worldSpeed; } // vtable+0x30
virtual void VTable0x34(); // vtable+0x34
virtual void VTable0x38(); // vtable+0x38
virtual void VTable0x3c(); // vtable+0x3c
@@ -51,17 +52,17 @@ public:
virtual void VTable0x4c(); // vtable+0x4c
protected:
void Reset();
void AddToCurrentWorld();
void Init();
void SetWorld();
undefined m_unk10;
undefined m_unk11;
MxVector3Data m_vec1; // 0x14
MxVector3Data m_vec2; // 0x28
MxVector3Data m_vec3; // 0x3c
undefined4 m_unk50;
undefined4 m_unk54;
undefined m_unk58;
MxVector3Data m_worldLocation; // 0x14
MxVector3Data m_worldDirection; // 0x28
MxVector3Data m_worldUp; // 0x3c
MxFloat m_worldSpeed; // 0x50
LegoROI* m_roi; // 0x54
MxBool m_cameraFlag; // 0x58
undefined m_unk59;
// For tokens from the extra string that look like this:
// "Action:openram;\lego\scripts\Race\CarRaceR;0"

View File

@@ -0,0 +1,5 @@
#include "legoeventnotificationparam.h"
#include "decomp.h"
DECOMP_SIZE_ASSERT(LegoEventNotificationParam, 0x1c);

View File

@@ -0,0 +1,22 @@
#ifndef LEGOEVENTNOTIFICATIONPARAM_H
#define LEGOEVENTNOTIFICATIONPARAM_H
#include "mxnotificationparam.h"
#include "mxtypes.h"
// VTABLE 0x100d6aa0
class LegoEventNotificationParam : public MxNotificationParam {
public:
inline LegoEventNotificationParam() : MxNotificationParam((MxParamType) 0, NULL) {}
virtual ~LegoEventNotificationParam() override {} // vtable+0x0 (scalar deleting destructor)
inline MxU8 GetKey() { return m_key; }
protected:
MxU8 m_modifier; // 0x0c
MxS32 m_x; // 0x10
MxS32 m_y; // 0x14
MxU8 m_key; // 0x18
};
#endif // LEGOEVENTNOTIFICATIONPARAM_H

View File

@@ -9,7 +9,7 @@ DECOMP_SIZE_ASSERT(LegoInputManager, 0x338);
// OFFSET: LEGO1 0x1005b790
LegoInputManager::LegoInputManager()
{
m_unk0x5c = NULL;
m_eventQueue = NULL;
m_world = NULL;
m_camera = NULL;
m_unk0x68 = NULL;
@@ -51,9 +51,9 @@ void LegoInputManager::Destroy()
{
ReleaseDX();
if (m_unk0x5c)
delete m_unk0x5c;
m_unk0x5c = NULL;
if (m_eventQueue)
delete m_eventQueue;
m_eventQueue = NULL;
if (m_unk0x68)
delete m_unk0x68;

View File

@@ -2,6 +2,7 @@
#define LEGOINPUTMANAGER_H
#include "decomp.h"
#include "legoeventnotificationparam.h"
#include "legoworld.h"
#include "mxlist.h"
#include "mxpresenter.h"
@@ -18,6 +19,8 @@ enum NotificationId {
};
class LegoControlManager;
// TODO Really a MxQueue, but we don't have one of those
class LegoEventQueue : public MxList<LegoEventNotificationParam> {};
// VTABLE 0x100d8760
// SIZE 0x338
@@ -52,7 +55,7 @@ public:
// private:
MxCriticalSection m_criticalSection;
MxList<undefined4>* m_unk0x5c; // list or hash table
LegoEventQueue* m_eventQueue; // list or hash table
LegoCameraController* m_camera;
LegoWorld* m_world;
MxList<undefined4>* m_unk0x68; // list or hash table

View File

@@ -2,12 +2,20 @@
#include "legoinputmanager.h"
#include "legoomni.h"
#include "mxactionnotificationparam.h"
#include "mxnotificationparam.h"
#include "mxomni.h"
#include "mxticklemanager.h"
DECOMP_SIZE_ASSERT(LegoWorld, 0xf8);
MxBool g_isWorldActive;
// OFFSET: LEGO1 0x100010a0
void LegoWorld::VTable0x60()
{
}
// OFFSET: LEGO1 0x1001ca40 STUB
LegoWorld::LegoWorld()
{
@@ -26,12 +34,35 @@ void LegoWorld::Stop()
TickleManager()->UnregisterClient(this);
}
// OFFSET: LEGO1 0x1001f5e0
MxLong LegoWorld::Notify(MxParam& p_param)
{
MxLong ret = 0;
switch (((MxNotificationParam&) p_param).GetNotification()) {
case c_notificationEndAction: {
MxPresenter* presenter = (MxPresenter*) ((MxEndActionNotificationParam&) p_param).GetSender();
EndAction(presenter);
ret = 1;
break;
}
case c_notificationNewPresenter:
TickleManager()->RegisterClient(this, 100);
break;
}
return ret;
}
// OFFSET: LEGO1 0x1001f630 STUB
void LegoWorld::VTable0x54()
{
// TODO
}
// OFFSET: LEGO1 0x10020f10 STUB
void LegoWorld::EndAction(MxPresenter* p_presenter)
{
}
// OFFSET: LEGO1 0x10020220 STUB
void LegoWorld::VTable0x58(MxCore* p_object)
{
@@ -44,11 +75,6 @@ MxBool LegoWorld::VTable0x5c()
return FALSE;
}
// OFFSET: LEGO1 0x100010a0
void LegoWorld::VTable0x60()
{
}
// OFFSET: LEGO1 0x1001d680
MxBool LegoWorld::VTable0x64()
{

View File

@@ -3,6 +3,7 @@
#include "legocameracontroller.h"
#include "legoentity.h"
#include "mxpresenter.h"
// VTABLE 0x100d6280
// SIZE 0xf8
@@ -11,6 +12,8 @@ public:
__declspec(dllexport) LegoWorld();
__declspec(dllexport) virtual ~LegoWorld(); // vtable+0x0
virtual MxLong Notify(MxParam& p) override; // vtable+0x4
// OFFSET: LEGO1 0x1001d690
inline virtual const char* ClassName() const override // vtable+0x0c
{
@@ -33,6 +36,7 @@ public:
virtual void VTable0x68(MxBool p_add); // vtable+68
MxResult SetAsCurrentWorld(MxDSObject& p_dsObject);
void EndAction(MxPresenter* p_presenter);
protected:
undefined m_unk68[0x30];

View File

@@ -12,5 +12,5 @@ MxNotificationParam* MxActionNotificationParam::Clone()
// OFFSET: LEGO1 0x10051270
MxNotificationParam* MxEndActionNotificationParam::Clone()
{
return new MxEndActionNotificationParam(MXSTREAMER_UNKNOWN, this->m_sender, this->m_action, this->m_realloc);
return new MxEndActionNotificationParam(c_notificationEndAction, this->m_sender, this->m_action, this->m_realloc);
}

View File

@@ -1,3 +0,0 @@
#include "mxappnotificationparam.h"
DECOMP_SIZE_ASSERT(MxAppNotificationParam, 0x1c)

View File

@@ -1,20 +0,0 @@
#ifndef MXAPPNOTIFICATIONPARAM_H
#define MXAPPNOTIFICATIONPARAM_H
#include "decomp.h"
#include "mxnotificationparam.h"
// VTABLE 0x100d6aa0
class MxAppNotificationParam : public MxNotificationParam {
public:
inline MxAppNotificationParam() : MxNotificationParam((MxParamType) 0, NULL) {}
virtual ~MxAppNotificationParam() override {} // vtable+0x0 (scalar deleting destructor)
inline MxU8 GetUnknown18() { return m_unk18; }
protected:
undefined m_unkc[0xc];
MxU8 m_unk18;
};
#endif // MXAPPNOTIFICATIONPARAM_H

View File

@@ -42,10 +42,8 @@ public:
m_customDestructor = Destroy;
}
// OFFSET: LEGO1 0x100afd30
static void Destroy(T*){};
// OFFSET: LEGO1 0x100afcd0
virtual MxS8 Compare(T*, T*) = 0;
protected:
@@ -72,7 +70,6 @@ public:
virtual MxS8 Compare(T*, T*) = 0;
// OFFSET: LEGO1 0x100afdc0
virtual MxU32 Hash(T*) = 0;
// FIXME: use of friend here?
@@ -154,7 +151,6 @@ private:
};
template <class T>
// OFFSET: LEGO1 0x100b0bd0
MxHashTable<T>::~MxHashTable()
{
for (int i = 0; i < m_numSlots; i++) {
@@ -175,7 +171,6 @@ MxHashTable<T>::~MxHashTable()
}
template <class T>
// OFFSET: LEGO1 0x100b7ab0
inline void MxHashTable<T>::Resize()
{
// Save a reference to the current table
@@ -185,10 +180,10 @@ inline void MxHashTable<T>::Resize()
switch (m_resizeOption) {
case HASH_TABLE_OPT_EXPAND_ADD:
m_numSlots = old_size + m_increaseAmount;
m_numSlots += m_increaseAmount;
break;
case HASH_TABLE_OPT_EXPAND_MULTIPLY:
m_numSlots = old_size * m_increaseFactor;
m_numSlots *= m_increaseFactor;
break;
}
@@ -212,7 +207,6 @@ inline void MxHashTable<T>::Resize()
}
template <class T>
// OFFSET: LEGO1 0x100b7b80
inline void MxHashTable<T>::_NodeInsert(MxHashTableNode<T>* p_node)
{
int bucket = p_node->m_hash % m_numSlots;

View File

@@ -54,7 +54,10 @@ MxResult MxNotificationManager::Tickle()
else {
{
MxAutoLocker lock(&m_lock);
swap(m_queue, m_sendList);
MxNotificationPtrList* temp1 = m_queue;
MxNotificationPtrList* temp2 = m_sendList;
m_queue = temp2;
m_sendList = temp1;
}
while (m_sendList->size() != 0) {

View File

@@ -46,6 +46,7 @@ public:
MxResult Send(MxCore* p_listener, MxNotificationParam* p_param);
inline MxNotificationPtrList* GetQueue() { return m_queue; }
inline void SetActive(MxBool p_active) { m_active = p_active; }
private:
void FlushPending(MxCore* p_listener);

View File

@@ -10,21 +10,24 @@ class MxCore;
enum MxParamType {
PARAM_NONE = 0,
PAINT = 1, // 100dc210:100d8350
MXSTREAMER_UNKNOWN = 2, // 100d8358:100d8350
c_notificationEndAction = 2, // 100d8358:100d8350
TYPE4 = 4, // 100dc208:100d8350
MXPRESENTER_NOTIFICATION = 5,
MXSTREAMER_DELETE_NOTIFY = 6, // 100dc760
APP_MESSAGE = 7, // 100d6aa0
MOUSE_RELEASE = 8, // 100d6aa0
MOUSE_PRESS = 9, // 100d6aa0
MOUSE_MOVE = 10, // 100d6aa0
c_notificationKeyPress = 7, // 100d6aa0
c_notificationButtonUp = 8, // 100d6aa0
c_notificationButtonDown = 9, // 100d6aa0
c_notificationMouseMove = 10, // 100d6aa0
TYPE11 = 11, // 100d6aa0
PARAM_TIMER = 15, // 100d6aa0
c_notificationDragEnd = 12,
c_notificationDragStart = 13,
c_notificationDrag = 14,
c_notificationTimer = 15, // 100d6aa0
TYPE17 = 17,
TYPE18 = 18, // 100d7e80
TYPE19 = 19, // 100d6230
TYPE20 = 20,
TYPE21 = 21,
c_notificationNewPresenter = 21,
TYPE22 = 22,
TYPE23 = 23,
MXTRANSITIONMANAGER_TRANSITIONENDED = 24
@@ -38,7 +41,7 @@ public:
virtual ~MxNotificationParam() override {} // vtable+0x0 (scalar deleting destructor)
virtual MxNotificationParam* Clone(); // vtable+0x4
inline MxParamType GetType() const { return m_type; }
inline MxParamType GetNotification() const { return m_type; }
inline MxCore* GetSender() const { return m_sender; }
protected:

View File

@@ -278,18 +278,23 @@ done:
// OFFSET: LEGO1 0x100afe90
void MxOmni::Destroy()
{
// FIXME: Stub
{
MxDSAction action;
action.SetObjectId(-1);
action.SetUnknown24(-2);
DeleteObject(action);
}
/*
// TODO: private members
if (m_notificationManager) {
while (m_notificationManager->m_queue->size()) {
while (m_notificationManager->GetQueue()) {
if (m_notificationManager->GetQueue()->size() == 0)
break;
m_notificationManager->Tickle();
}
}
m_notificationManager->m_active = 0;
*/
m_notificationManager->SetActive(FALSE);
}
delete m_eventManager;
delete m_soundManager;
@@ -313,6 +318,7 @@ void MxOmni::Destroy()
}
delete m_atomIdCounterSet;
}
Init();
}
// OFFSET: LEGO1 0x100b07f0
@@ -320,7 +326,7 @@ MxLong MxOmni::Notify(MxParam& p)
{
MxAutoLocker lock(&this->m_criticalsection);
if (((MxNotificationParam&) p).GetType() != MXSTREAMER_UNKNOWN)
if (((MxNotificationParam&) p).GetNotification() != c_notificationEndAction)
return 0;
return HandleNotificationType2(p);

View File

@@ -69,7 +69,7 @@ protected:
static MxOmni* g_instance;
MxString m_mediaPath; // 0x8
HWND m_windowHandle; // 0x18;
HWND m_windowHandle; // 0x18
MxObjectFactory* m_objectFactory; // 0x1C
MxVariableTable* m_variableTable; // 0x20
MxTickleManager* m_tickleManager; // 0x24
@@ -96,7 +96,6 @@ __declspec(dllexport) MxMusicManager* MusicManager();
__declspec(dllexport) MxEventManager* EventManager();
__declspec(dllexport) MxNotificationManager* NotificationManager();
MxResult DeleteObject(MxDSAction& p_dsAction);
MxVideoManager* MVideoManager();
MxAtomIdCounterSet* AtomIdCounterSet();
MxObjectFactory* ObjectFactory();

View File

@@ -30,11 +30,11 @@ void MxPresenter::Init()
void MxPresenter::ParseExtra()
{
MxAutoLocker lock(&m_criticalSection);
MxU32 len = m_action->GetExtraLength();
MxU16 len = m_action->GetExtraLength();
char* extraData = m_action->GetExtraData();
if (len) {
len &= MAXWORD;
// len &= MAXWORD;
char extraCopy[512];
memcpy(extraCopy, extraData, len);
extraCopy[len] = '\0';
@@ -141,7 +141,7 @@ void MxPresenter::EndAction()
MxAutoLocker lock(&this->m_criticalSection);
if (!this->m_unkPresenter) {
MxOmni::GetInstance()->NotifyCurrentEntity(
&MxEndActionNotificationParam(MXSTREAMER_UNKNOWN, NULL, this->m_action, TRUE)
&MxEndActionNotificationParam(c_notificationEndAction, NULL, this->m_action, TRUE)
);
}

View File

@@ -156,7 +156,7 @@ MxBool MxStreamer::FUN_100b9b30(MxDSObject& p_dsObject)
// OFFSET: LEGO1 0x100b9b60
MxLong MxStreamer::Notify(MxParam& p)
{
if (((MxNotificationParam&) p).GetType() == MXSTREAMER_DELETE_NOTIFY) {
if (((MxNotificationParam&) p).GetNotification() == MXSTREAMER_DELETE_NOTIFY) {
MxDSAction ds;
ds.SetUnknown24(-2);

View File

@@ -21,4 +21,13 @@ public:
virtual MxU32 Hash(MxVariable*); // +0x18
};
// OFFSET: LEGO1 0x100b0bd0 TEMPLATE
// MxHashTable<MxVariable>::~MxHashTable<MxVariable>
// OFFSET: LEGO1 0x100b7ab0 TEMPLATE
// MxHashTable<MxVariable>::Resize
// OFFSET: LEGO1 0x100b7b80 TEMPLATE
// MxHashTable<MxVariable>::_NodeInsert
#endif // MXVARIABLETABLE_H

View File

@@ -40,16 +40,16 @@ MxLong Score::Notify(MxParam& p)
MxLong ret = 0;
LegoWorld::Notify(p);
if (m_unkf6) {
switch (((MxNotificationParam&) p).GetType()) {
switch (((MxNotificationParam&) p).GetNotification()) {
case PAINT:
ret = 1;
Paint();
break;
case MXSTREAMER_UNKNOWN:
case c_notificationEndAction:
ret = FUN_10001510((MxEndActionNotificationParam&) p);
break;
case APP_MESSAGE:
if (((MxAppNotificationParam&) p).GetUnknown18() == 0x20)
case c_notificationKeyPress:
if (((LegoEventNotificationParam&) p).GetKey() == 0x20)
DeleteScript(); // Shutting down
ret = 1;
break;

View File

@@ -1,9 +1,9 @@
#ifndef SCORE_H
#define SCORE_H
#include "legoeventnotificationparam.h"
#include "legoworld.h"
#include "mxactionnotificationparam.h"
#include "mxappnotificationparam.h"
#include "mxtype17notificationparam.h"
#include "scorestate.h"
@@ -28,6 +28,9 @@ public:
return !strcmp(name, Score::ClassName()) || LegoWorld::IsA(name);
}
// OFFSET: LEGO1 0x100011e0 TEMPLATE
// Helicopter::`scalar deleting destructor'
virtual MxResult InitFromMxDSObject(MxDSObject& p_dsObject) override; // vtable+18
virtual void Stop() override; // vtable+50
virtual MxBool VTable0x5c() override; // vtable+5c