Merge branch 'isledecomp:master' into order-tool

This commit is contained in:
MS 2023-11-14 12:56:25 -05:00 committed by GitHub
commit 0fa6d207f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
109 changed files with 2874 additions and 789 deletions

View File

@ -21,6 +21,14 @@ IndentAccessModifiers: false
IndentWidth: 4
InsertNewlineAtEOF: true
PointerAlignment: Left
QualifierAlignment: Custom
QualifierOrder:
- inline
- static
- friend
- const
- volatile
- type
SpaceAfterCStyleCast: true
TabWidth: 4
UseTab: ForContinuationAndIndentation

View File

@ -163,12 +163,14 @@ add_library(lego1 SHARED
LEGO1/mxramstreamcontroller.cpp
LEGO1/mxramstreamprovider.cpp
LEGO1/mxregion.cpp
LEGO1/mxregionlist.cpp
LEGO1/mxscheduler.cpp
LEGO1/mxsemaphore.cpp
LEGO1/mxsmkpresenter.cpp
LEGO1/mxsoundmanager.cpp
LEGO1/mxsoundpresenter.cpp
LEGO1/mxstillpresenter.cpp
LEGO1/mxstreamchunklist.cpp
LEGO1/mxstreamcontroller.cpp
LEGO1/mxstreamer.cpp
LEGO1/mxstreamprovider.cpp

View File

@ -35,7 +35,7 @@ We are currently using [clang-format](https://clang.llvm.org/docs/ClangFormat.ht
- `m_camelCase` for member variables.
- `g_camelCase` for global variables.
- `p_camelCase` for function parameters.
- Instead of C++ primitives (e.g. `int`, `long`, etc.), use types in `mxtypes.h` instead. This will help us ensure that variables will be the correct size regardless of the underlying compiler/platform/architecture.
- Instead of C++ primitives (e.g. `int`, `long`, etc.), use types in [`mxtypes.h`](LEGO1/mxtypes.h) instead. This will help us ensure that variables will be the correct size regardless of the underlying compiler/platform/architecture.
## Questions?

View File

@ -95,7 +95,7 @@ void IsleApp::Close()
if (Lego()) {
GameState()->Save(0);
if (InputManager()) {
InputManager()->QueueEvent(KEYDOWN, 0, 0, 0, 0x20);
InputManager()->QueueEvent(c_notificationKeyPress, 0, 0, 0, 0x20);
}
VideoManager()->Get3DManager()->GetLego3DView()->GetViewManager()->RemoveAll(NULL);
@ -431,22 +431,22 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
}
keyCode = wParam;
type = KEYDOWN;
type = c_notificationKeyPress;
break;
case WM_MOUSEMOVE:
g_mousemoved = 1;
type = MOUSEMOVE;
type = c_notificationMouseMove;
break;
case WM_TIMER:
type = TIMER;
type = c_notificationTimer;
break;
case WM_LBUTTONDOWN:
g_mousedown = 1;
type = MOUSEDOWN;
type = c_notificationButtonDown;
break;
case WM_LBUTTONUP:
g_mousedown = 0;
type = MOUSEUP;
type = c_notificationButtonUp;
break;
case 0x5400:
if (g_isle) {
@ -462,7 +462,7 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (InputManager()) {
InputManager()->QueueEvent(type, wParam, LOWORD(lParam), HIWORD(lParam), keyCode);
}
if (g_isle && g_isle->m_drawCursor && type == MOUSEMOVE) {
if (g_isle && g_isle->m_drawCursor && type == c_notificationMouseMove) {
int x = LOWORD(lParam);
int y = HIWORD(lParam);
if (x >= 640) {

View File

@ -1,5 +1,15 @@
#include "define.h"
// 0x1010141c
MxU32 g_mxcoreCount[101] = {0, -6643, -5643, -5058, -4643, -4321, -4058, -3836, -3643, -3473, -3321, -3184, -3058,
-2943, -2836, -2736, -2643, -2556, -2473, -2395, -2321, -2251, -2184, -2120, -2058, -2000,
-1943, -1888, -1836, -1785, -1736, -1689, -1643, -1599, -1556, -1514, -1473, -1434, -1395,
-1358, -1321, -1286, -1251, -1217, -1184, -1152, -1120, -1089, -1058, -1029, -1000, -971,
-943, -915, -888, -862, -836, -810, -785, -761, -736, -713, -689, -666, -643,
-621, -599, -577, -556, -535, -514, -494, -473, -454, -434, -415, -395, -377,
-358, -340, -321, -304, -286, -268, -251, -234, -217, -200, -184, -168, -152,
-136, -120, -104, -89, -74, -58, -43, -29, -14, 0};
// 0x10101eac
const char* g_parseExtraTokens = ":;";

View File

@ -1,6 +1,9 @@
#ifndef DEFINE_H
#define DEFINE_H
#include "mxtypes.h"
extern MxU32 g_mxcoreCount[101];
extern const char* g_parseExtraTokens;
extern const char* g_strWORLD;
extern const char* g_strACTION;

View File

@ -3,43 +3,49 @@
DECOMP_SIZE_ASSERT(LegoActor, 0x78)
// Probably in header
// OFFSET: LEGO1 0x10002cc0 STUB
void LegoActor::VTable0x50()
// OFFSET: LEGO1 0x10002cc0
MxFloat LegoActor::VTable0x50()
{
// TODO
return m_unk68;
}
// OFFSET: LEGO1 0x10002cd0 STUB
void LegoActor::VTable0x54()
// OFFSET: LEGO1 0x10002cd0
void LegoActor::VTable0x54(MxFloat p_unk)
{
// TODO
m_unk68 = p_unk;
}
// OFFSET: LEGO1 0x10002ce0 STUB
void LegoActor::VTable0x58()
// OFFSET: LEGO1 0x10002ce0
void LegoActor::VTable0x58(MxFloat p_unk)
{
// TODO
m_unk70 = p_unk;
}
// OFFSET: LEGO1 0x10002cf0 STUB
void LegoActor::VTable0x5c()
// OFFSET: LEGO1 0x10002cf0
MxFloat LegoActor::VTable0x5c()
{
// TODO
return m_unk70;
}
// OFFSET: LEGO1 0x10002d00 STUB
void LegoActor::VTable0x60()
// OFFSET: LEGO1 0x10002d00
undefined LegoActor::VTable0x60()
{
// TODO
return m_unk74;
}
// OFFSET: LEGO1 0x10002d10 STUB
void LegoActor::VTable0x64()
// OFFSET: LEGO1 0x10002d10
void LegoActor::VTable0x64(undefined p_unk)
{
// TODO
m_unk74 = p_unk;
}
// End header
// OFFSET: LEGO1 0x1002d110
LegoActor::LegoActor()
{
m_unk68 = 0.0f;
m_unk6c = 0;
m_unk70 = 0.0f;
m_unk10 = 0;
m_unk74 = 0;
}

View File

@ -23,15 +23,18 @@ class LegoActor : public LegoEntity {
return !strcmp(name, LegoActor::ClassName()) || LegoEntity::IsA(name);
}
virtual void VTable0x50(); // vtable+0x50
virtual void VTable0x54(); // vtable+0x54
virtual void VTable0x58(); // vtable+0x58
virtual void VTable0x5c(); // vtable+0x5c
virtual void VTable0x60(); // vtable+0x60
virtual void VTable0x64(); // vtable+0x64
virtual MxFloat VTable0x50(); // vtable+0x50
virtual void VTable0x54(MxFloat p_unk); // vtable+0x54
virtual void VTable0x58(MxFloat p_unk); // vtable+0x58
virtual MxFloat VTable0x5c(); // vtable+0x5c
virtual undefined VTable0x60(); // vtable+0x60
virtual void VTable0x64(undefined p_unk); // vtable+0x64
private:
undefined unk68[0x10];
MxFloat m_unk68;
undefined4 m_unk6c;
MxFloat m_unk70;
undefined m_unk74;
};
#endif // LEGOACTOR_H

View File

@ -3,10 +3,10 @@
// 0x100f37cc
int g_buildingManagerConfig = 1;
// OFFSET: LEGO1 0x1002f8c0 STUB
// OFFSET: LEGO1 0x1002f8c0
LegoBuildingManager::LegoBuildingManager()
{
// TODO
Init();
}
// OFFSET: LEGO1 0x1002f960 STUB

View File

@ -3,6 +3,7 @@
#include "define.h"
#include "legoomni.h"
#include "legoutil.h"
#include "legoworld.h"
DECOMP_SIZE_ASSERT(LegoEntity, 0x68)
@ -60,12 +61,12 @@ void LegoEntity::Destroy(MxBool p_fromDestructor)
Init();
}
// OFFSET: LEGO1 0x10010880 STUB
// OFFSET: LEGO1 0x10010880
void LegoEntity::SetWorld()
{
LegoWorld* world = GetCurrentWorld();
if (world != NULL && world != (LegoWorld*) this) {
// TODO: world->AddEntity(this);
world->VTable0x58(this);
}
}

View File

@ -13,10 +13,7 @@
class LegoEntity : public MxEntity {
public:
// Inlined at 0x100853f7
inline LegoEntity()
{
// TODO
}
inline LegoEntity() { Init(); }
__declspec(dllexport) virtual ~LegoEntity() override; // vtable+0x0

View File

@ -1,19 +1,47 @@
#include "legoentitypresenter.h"
#include "legoomni.h"
#include "legovideomanager.h"
DECOMP_SIZE_ASSERT(LegoEntityPresenter, 0x50);
// OFFSET: LEGO1 0x10053440
LegoEntityPresenter::LegoEntityPresenter()
{
Init();
}
// OFFSET: LEGO1 0x100535d0 STUB
LegoEntityPresenter::~LegoEntityPresenter()
{
// TODO
}
// OFFSET: LEGO1 0x100535c0 STUB
// OFFSET: LEGO1 0x100535c0
void LegoEntityPresenter::Init()
{
// TODO
m_unk4c = 0;
}
// OFFSET: LEGO1 0x100535d0
LegoEntityPresenter::~LegoEntityPresenter()
{
Destroy(TRUE);
}
// OFFSET: LEGO1 0x10053630
undefined4 LegoEntityPresenter::vtable6c(undefined4 p_unknown)
{
m_unk4c = p_unknown;
return 0;
}
// OFFSET: LEGO1 0x10053640
void LegoEntityPresenter::Destroy(MxBool p_fromDestructor)
{
if (VideoManager()) {
VideoManager()->RemovePresenter(*this);
}
Init();
}
// OFFSET: LEGO1 0x10053670
void LegoEntityPresenter::Destroy()
{
Destroy(FALSE);
}

View File

@ -4,6 +4,7 @@
#include "mxcompositepresenter.h"
// VTABLE 0x100d8398
// SIZE 0x50
class LegoEntityPresenter : public MxCompositePresenter {
public:
LegoEntityPresenter();
@ -22,8 +23,14 @@ class LegoEntityPresenter : public MxCompositePresenter {
return !strcmp(name, LegoEntityPresenter::ClassName()) || MxCompositePresenter::IsA(name);
}
virtual void Destroy() override; // vtable+0x38
virtual void Init(); // vtable+0x68
virtual undefined4 vtable6c(undefined4 p_unknown); // vtable+0x6c
private:
void Init();
void Destroy(MxBool p_fromDestructor);
undefined4 m_unk4c;
};
#endif // LEGOENTITYPRESENTER_H

View File

@ -2,4 +2,4 @@
#include "decomp.h"
DECOMP_SIZE_ASSERT(LegoEventNotificationParam, 0x1c);
DECOMP_SIZE_ASSERT(LegoEventNotificationParam, 0x20);

View File

@ -7,16 +7,28 @@
// VTABLE 0x100d6aa0
class LegoEventNotificationParam : public MxNotificationParam {
public:
inline LegoEventNotificationParam() : MxNotificationParam((MxParamType) 0, NULL) {}
inline LegoEventNotificationParam() : MxNotificationParam(PARAM_NONE, NULL) {}
inline LegoEventNotificationParam(
NotificationId p_type,
MxCore* p_sender,
MxU8 p_modifier,
MxS32 p_x,
MxS32 p_y,
MxU8 p_key
)
: MxNotificationParam(p_type, p_sender), m_modifier(p_modifier), m_x(p_x), m_y(p_y), m_key(p_key), m_unk1c(0)
{
}
virtual ~LegoEventNotificationParam() override {} // vtable+0x0 (scalar deleting destructor)
inline MxU8 GetKey() { return m_key; }
inline MxU8 GetKey() const { return m_key; }
protected:
MxU8 m_modifier; // 0x0c
MxS32 m_x; // 0x10
MxS32 m_y; // 0x14
MxU8 m_key; // 0x18
MxU32 m_unk1c; // 0x1c
};
#endif // LEGOEVENTNOTIFICATIONPARAM_H

View File

@ -2,6 +2,7 @@
#include "infocenterstate.h"
#include "legoomni.h"
#include "legoroi.h"
#include "legostate.h"
#include "legostream.h"
#include "mxobjectfactory.h"
@ -43,6 +44,8 @@ extern const char* s_endOfVariables;
LegoGameState::LegoGameState()
{
// TODO
SetROIHandlerFunction();
m_stateCount = 0;
m_backgroundColor = new LegoBackgroundColor("backgroundcolor", "set 56 54 68");
VariableTable()->SetVariable(m_backgroundColor);
@ -57,10 +60,22 @@ LegoGameState::LegoGameState()
SerializeScoreHistory(1);
}
// OFFSET: LEGO1 0x10039720 STUB
// OFFSET: LEGO1 0x10039720
LegoGameState::~LegoGameState()
{
// TODO
LegoROI::SetSomeHandlerFunction(NULL);
if (m_stateCount) {
for (MxS16 i = 0; i < m_stateCount; i++) {
LegoState* state = m_stateArray[i];
if (state)
delete state;
}
delete[] m_stateArray;
}
delete[] m_savePath;
}
// OFFSET: LEGO1 0x10039c60 STUB
@ -149,6 +164,12 @@ void LegoGameState::SerializeScoreHistory(MxS16 p)
// TODO
}
// OFFSET: LEGO1 0x1003cea0
void LegoGameState::SetSomeEnumState(undefined4 p_state)
{
m_unk10 = p_state;
}
// OFFSET: LEGO1 0x10039f00
void LegoGameState::SetSavePath(char* p_savePath)
{
@ -163,6 +184,33 @@ void LegoGameState::SetSavePath(char* p_savePath)
m_savePath = NULL;
}
// OFFSET: LEGO1 0x1003bac0
void LegoGameState::SetROIHandlerFunction()
{
LegoROI::SetSomeHandlerFunction(&ROIHandlerFunction);
}
// OFFSET: LEGO1 0x1003bad0
MxBool ROIHandlerFunction(char* p_input, char* p_output, MxU32 p_copyLen)
{
if (p_output != NULL && p_copyLen != 0 &&
(strnicmp(p_input, "INDIR-F-", strlen("INDIR-F-")) == 0 ||
strnicmp(p_input, "INDIR-G-", strlen("INDIR-F-")) == 0)) {
char buf[256];
sprintf(buf, "c_%s", &p_input[strlen("INDIR-F-")]);
const char* value = VariableTable()->GetVariable(buf);
if (value != NULL) {
strncpy(p_output, value, p_copyLen);
p_output[p_copyLen - 1] = '\0';
return TRUE;
}
}
return FALSE;
}
// OFFSET: LEGO1 0x1003bbb0
LegoState* LegoGameState::GetState(COMPAT_CONST char* p_stateName)
{

View File

@ -37,9 +37,12 @@ class LegoGameState {
inline MxU32 GetUnknown10() { return m_unk10; }
inline void SetUnknown424(undefined4 p_unk424) { m_unk424 = p_unk424; }
void SetSomeEnumState(undefined4 p_state);
private:
void RegisterState(LegoState* p_state);
MxResult WriteEndOfVariables(LegoStream* p_stream);
void SetROIHandlerFunction();
private:
char* m_savePath; // 0x0
@ -58,4 +61,6 @@ class LegoGameState {
undefined4 m_unk42c;
};
MxBool ROIHandlerFunction(char* p_0, char* p_output, MxU32 p_copyLen);
#endif // LEGOGAMESTATE_H

View File

@ -9,10 +9,10 @@ DECOMP_SIZE_ASSERT(LegoInputManager, 0x338);
// OFFSET: LEGO1 0x1005b790
LegoInputManager::LegoInputManager()
{
m_eventQueue = NULL;
m_unk0x5c = NULL;
m_world = NULL;
m_camera = NULL;
m_unk0x68 = NULL;
m_eventQueue = NULL;
m_unk0x80 = 0;
m_timer = 0;
m_unk0x6c = 0;
@ -36,7 +36,7 @@ LegoInputManager::LegoInputManager()
// OFFSET: LEGO1 0x1005b8b0 STUB
MxResult LegoInputManager::Tickle()
{
// TODO
ProcessEvents();
return SUCCESS;
}
@ -46,19 +46,28 @@ LegoInputManager::~LegoInputManager()
Destroy();
}
// OFFSET: LEGO1 0x1005b960
MxResult LegoInputManager::Create(HWND p_hwnd)
{
// TODO
if (m_eventQueue == NULL)
m_eventQueue = new LegoEventQueue();
return SUCCESS;
}
// OFFSET: LEGO1 0x1005bfe0
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;
m_unk0x68 = NULL;
if (m_controlManager)
delete m_controlManager;
}
@ -215,10 +224,34 @@ void LegoInputManager::ClearWorld()
m_world = NULL;
}
// OFFSET: LEGO1 0x1005c740 STUB
void LegoInputManager::QueueEvent(NotificationId id, unsigned char p2, MxLong p3, MxLong p4, unsigned char p5)
// OFFSET: LEGO1 0x1005c740
void LegoInputManager::QueueEvent(NotificationId p_id, MxU8 p_modifier, MxLong p_x, MxLong p_y, MxU8 p_key)
{
LegoEventNotificationParam param = LegoEventNotificationParam(p_id, NULL, p_modifier, p_x, p_y, p_key);
if (((!m_unk0x88) || ((m_unk0x335 && (param.GetType() == c_notificationButtonDown)))) ||
((m_unk0x336 && (p_key == ' ')))) {
ProcessOneEvent(param);
}
}
// OFFSET: LEGO1 0x1005c820
void LegoInputManager::ProcessEvents()
{
MxAutoLocker lock(&m_criticalSection);
LegoEventNotificationParam event;
while (m_eventQueue->Dequeue(event)) {
if (ProcessOneEvent(event))
break;
}
}
// OFFSET: LEGO1 0x1005c9c0 STUB
MxBool LegoInputManager::ProcessOneEvent(LegoEventNotificationParam& p_param)
{
// TODO
return FALSE;
}
// OFFSET: LEGO1 0x1005cfb0

View File

@ -6,21 +6,14 @@
#include "legoworld.h"
#include "mxlist.h"
#include "mxpresenter.h"
#include "mxqueue.h"
#include <dinput.h>
enum NotificationId {
NONE = 0,
KEYDOWN = 7,
MOUSEUP = 8,
MOUSEDOWN = 9,
MOUSEMOVE = 10,
TIMER = 15
};
class LegoControlManager;
// TODO Really a MxQueue, but we don't have one of those
class LegoEventQueue : public MxList<LegoEventNotificationParam> {};
// VTABLE 0x100d8800
class LegoEventQueue : public MxQueue<LegoEventNotificationParam> {};
// VTABLE 0x100d8760
// SIZE 0x338
@ -29,12 +22,13 @@ class LegoInputManager : public MxPresenter {
LegoInputManager();
virtual ~LegoInputManager() override;
__declspec(dllexport) void QueueEvent(NotificationId id, unsigned char p2, MxLong p3, MxLong p4, unsigned char p5);
__declspec(dllexport) void QueueEvent(NotificationId p_id, MxU8 p_modifier, MxLong p_x, MxLong p_y, MxU8 p_key);
__declspec(dllexport) void Register(MxCore*);
__declspec(dllexport) void UnRegister(MxCore*);
virtual MxResult Tickle() override; // vtable+0x8
MxResult Create(HWND p_hwnd);
void Destroy();
void CreateAndAcquireKeyboard(HWND hwnd);
void ReleaseDX();
@ -53,12 +47,15 @@ class LegoInputManager : public MxPresenter {
inline LegoControlManager* GetControlManager() { return m_controlManager; }
inline LegoWorld* GetWorld() { return m_world; }
void ProcessEvents();
MxBool ProcessOneEvent(LegoEventNotificationParam& p_param);
// private:
MxCriticalSection m_criticalSection;
LegoEventQueue* m_eventQueue; // list or hash table
MxList<undefined4>* m_unk0x5c; // list or hash table
LegoCameraController* m_camera;
LegoWorld* m_world;
MxList<undefined4>* m_unk0x68; // list or hash table
LegoEventQueue* m_eventQueue; // +0x68
undefined4 m_unk0x6c;
undefined4 m_unk0x70;
undefined4 m_unk0x74;
@ -83,4 +80,37 @@ class LegoInputManager : public MxPresenter {
MxBool m_unk0x336;
};
// OFFSET: LEGO1 0x1005bb80 TEMPLATE
// MxListParent<LegoEventNotificationParam>::Compare
// OFFSET: LEGO1 0x1005bc30 TEMPLATE
// MxListParent<LegoEventNotificationParam>::Destroy
// OFFSET: LEGO1 0x1005bc80 TEMPLATE
// MxList<LegoEventNotificationParam>::~MxList<LegoEventNotificationParam>
// OFFSET: LEGO1 0x1005bd50 TEMPLATE
// MxListParent<LegoEventNotificationParam>::`scalar deleting destructor'
// OFFSET: LEGO1 0x1005bdc0 TEMPLATE
// MxList<LegoEventNotificationParam>::`scalar deleting destructor'
// OFFSET: LEGO1 0x1005beb0 TEMPLATE
// LegoEventQueue::`scalar deleting destructor'
// OFFSET: LEGO1 0x1005bf70 TEMPLATE
// MxQueue<LegoEventNotificationParam>::`scalar deleting destructor'
// OFFSET: LEGO1 0x1005d010 TEMPLATE
// MxListEntry<LegoEventNotificationParam>::GetValue
// VTABLE 0x100d87e8 TEMPLATE
// class MxQueue<LegoEventNotificationParam>
// VTABLE 0x100d87d0 TEMPLATE
// class MxList<LegoEventNotificationParam>
// VTABLE 0x100d87b8 TEMPLATE
// class MxListParent<LegoEventNotificationParam>
#endif // LEGOINPUTMANAGER_H

View File

@ -1,5 +1,6 @@
#include "legonavcontroller.h"
#include "legoinputmanager.h"
#include "legoomni.h"
#include "legoutil.h"
#include "legovideomanager.h"
@ -106,18 +107,14 @@ LegoNavController::LegoNavController()
MxTimer* timer = Timer();
this->m_time = timer->GetTime();
// TODO: InputManager()
// LegoInputManager* inputManager = InputManager();
// inputManager->Register(this);
InputManager()->Register(this);
}
// TODO: InputManager()
// OFFSET: LEGO1 0x10054c30
// LegoNavController::~LegoNavController()
// {
// LegoInputManager* inputManager = InputManager();
// inputManager->UnRegister(this);
// }
LegoNavController::~LegoNavController()
{
InputManager()->UnRegister(this);
}
// OFFSET: LEGO1 0x10054ca0
void LegoNavController::SetControlMax(int p_hMax, int p_vMax)

View File

@ -37,7 +37,7 @@ class LegoNavController : public MxCore {
);
LegoNavController();
// virtual ~LegoNavController(); // vtable+0x0
virtual ~LegoNavController() override; // vtable+0x0
// OFFSET: LEGO1 0x10054b80
inline const char* ClassName() const override // vtable+0xc

View File

@ -31,8 +31,8 @@ MxCore* LegoObjectFactory::Create(const char* p_name)
}
}
// OFFSET: LEGO1 0x1000fb30 STUB
// OFFSET: LEGO1 0x1000fb30
void LegoObjectFactory::Destroy(MxCore* p_object)
{
// TODO
delete p_object;
}

View File

@ -1,18 +1,110 @@
#include "legoomni.h"
#include "gifmanager.h"
#include "legoanimationmanager.h"
#include "legobuildingmanager.h"
#include "legogamestate.h"
#include "legoinputmanager.h"
#include "legoobjectfactory.h"
#include "legoplantmanager.h"
#include "legosoundmanager.h"
#include "legoutil.h"
#include "legovideomanager.h"
#include "legoworld.h"
#include "mxautolocker.h"
#include "mxbackgroundaudiomanager.h"
#include "mxdsfile.h"
#include "mxomnicreateflags.h"
#include "mxomnicreateparam.h"
#include "mxticklemanager.h"
#include "mxtransitionmanager.h"
// 0x100f451c
MxAtomId* g_copterScript = NULL;
// 0x100f4520
MxAtomId* g_dunecarScript = NULL;
// 0x100f4524
MxAtomId* g_jetskiScript = NULL;
// 0x100f4528
MxAtomId* g_racecarScript = NULL;
// 0x100f452c
MxAtomId* g_carraceScript = NULL;
// 0x100f4530
MxAtomId* g_carracerScript = NULL;
// 0x100f4534
MxAtomId* g_jetraceScript = NULL;
// 0x100f4538
MxAtomId* g_jetracerScript = NULL;
// 0x100f453c
MxAtomId* g_isleScript = NULL;
// 0x100f4540
MxAtomId* g_elevbottScript = NULL;
// 0x100f4544
MxAtomId* g_infodoorScript = NULL;
// 0x100f4548
MxAtomId* g_infomainScript = NULL;
// 0x100f454c
MxAtomId* g_infoscorScript = NULL;
// 0x100f4550
MxAtomId* g_regbookScript = NULL;
// 0x100f4554
MxAtomId* g_histbookScript = NULL;
// 0x100f4558
MxAtomId* g_hospitalScript = NULL;
// 0x100f455c
MxAtomId* g_policeScript = NULL;
// 0x100f4560
MxAtomId* g_garageScript = NULL;
// 0x100f4564
MxAtomId* g_act2mainScript = NULL;
// 0x100f4568
MxAtomId* g_act3Script = NULL;
// 0x100f456c
MxAtomId* g_jukeboxScript = NULL;
// 0x100f4570
MxAtomId* g_pz5Script = NULL;
// 0x100f4574
MxAtomId* g_introScript = NULL;
// 0x100f4578
MxAtomId* g_testScript = NULL;
// 0x100f457c
MxAtomId* g_jukeboxwScript = NULL;
// 0x100f4580c
MxAtomId* g_sndAnimScript = NULL;
// 0x100f4584
MxAtomId* g_creditsScript = NULL;
// 0x100f4588
MxAtomId* g_nocdSourceName = NULL;
// 0x100f456c
MxAtomId* g_jukeboxScript = NULL;
// 0x100f6718
const char* g_current = "current";
// 0x101020e8
void (*g_omniUserMessage)(const char*, int);
@ -42,6 +134,13 @@ void LegoOmni::RemoveWorld(const MxAtomId& p1, MxLong p2)
// TODO
}
// OFFSET: LEGO1 0x1005b0c0 STUB
LegoEntity* LegoOmni::FindByEntityIdOrAtomId(const MxAtomId& p_atom, MxS32 p_entityid)
{
// TODO
return NULL;
}
// OFFSET: LEGO1 0x1005b400 STUB
int LegoOmni::GetCurrPathInfo(LegoPathBoundary**, int&)
{
@ -212,12 +311,29 @@ GifManager* GetGifManager()
return LegoOmni::GetInstance()->GetGifManager();
}
// OFFSET: LEGO1 0x100158e0
MxDSAction& GetCurrentAction()
{
return LegoOmni::GetInstance()->GetCurrentAction();
}
// OFFSET: LEGO1 0x10015900
MxTransitionManager* TransitionManager()
{
return LegoOmni::GetInstance()->GetTransitionManager();
}
// OFFSET: LEGO1 0x10015910
void PlayMusic(MxU32 p_index)
{
// index is the entityid of the music in jukebox.si
MxDSAction action;
action.SetAtomId(*g_jukeboxScript);
action.SetObjectId(p_index);
LegoOmni::GetInstance()->GetBackgroundAudioManager()->PlayMusic(action, 5, 4);
}
// OFFSET: LEGO1 0x100c0280
MxDSObject* CreateStreamObject(MxDSFile* p_file, MxS16 p_ofs)
{
@ -259,7 +375,7 @@ const char* GetNoCD_SourceName()
return g_nocdSourceName->GetInternal();
}
// OFFSET: LEGO1 0x1005b5f0
// OFFSET: LEGO1 0x1005b5f0 STUB
MxLong LegoOmni::Notify(MxParam& p)
{
// TODO
@ -302,16 +418,83 @@ void LegoOmni::Init()
m_transitionManager = NULL;
}
// OFFSET: LEGO1 0x10058e70 STUB
// OFFSET: LEGO1 0x1001a700 STUB
void FUN_1001a700()
{
// TODO
}
// OFFSET: LEGO1 0x10058e70
MxResult LegoOmni::Create(MxOmniCreateParam& p)
{
MxOmni::Create(p);
MxResult result = FAILURE;
MxAutoLocker lock(&this->m_criticalsection);
p.CreateFlags().CreateObjectFactory(FALSE);
p.CreateFlags().CreateVideoManager(FALSE);
p.CreateFlags().CreateSoundManager(FALSE);
p.CreateFlags().CreateTickleManager(FALSE);
if (!(m_tickleManager = new MxTickleManager()))
return FAILURE;
if (MxOmni::Create(p) != SUCCESS)
return FAILURE;
m_objectFactory = new LegoObjectFactory();
m_gameState = new LegoGameState();
m_bkgAudioManager = new MxBackgroundAudioManager();
if (m_objectFactory == NULL)
return FAILURE;
return SUCCESS;
if (m_soundManager = new LegoSoundManager()) {
if (m_soundManager->Create(10, 0) != SUCCESS) {
delete m_soundManager;
m_soundManager = NULL;
return FAILURE;
}
}
if (m_videoManager = new LegoVideoManager()) {
if (m_videoManager->Create(p.GetVideoParam(), 100, 0) != SUCCESS) {
delete m_videoManager;
m_videoManager = NULL;
}
}
if (m_inputMgr = new LegoInputManager()) {
if (m_inputMgr->Create(p.GetWindowHandle()) != SUCCESS) {
delete m_inputMgr;
m_inputMgr = NULL;
}
}
// TODO: there are a few more classes here
m_gifManager = new GifManager();
m_plantManager = new LegoPlantManager();
m_animationManager = new LegoAnimationManager();
m_buildingManager = new LegoBuildingManager();
m_gameState = new LegoGameState();
// TODO: initialize list at m_unk78
if (m_unk6c && m_gifManager && m_unk78 && m_plantManager && m_animationManager && m_buildingManager) {
// TODO: initialize a bunch of MxVariables
RegisterScripts();
FUN_1001a700();
// todo: another function call. in legoomni maybe?
m_bkgAudioManager = new MxBackgroundAudioManager();
if (m_bkgAudioManager != NULL) {
m_transitionManager = new MxTransitionManager();
if (m_transitionManager != NULL) {
if (m_transitionManager->GetDDrawSurfaceFromVideoManager() == SUCCESS) {
m_notificationManager->Register(this);
SetAppCursor(1);
m_gameState->SetSomeEnumState(0);
return SUCCESS;
}
}
}
}
return FAILURE;
}
// OFFSET: LEGO1 0x10058c30 STUB
@ -337,18 +520,33 @@ MxResult LegoOmni::DeleteObject(MxDSAction& ds)
return FAILURE;
}
// OFFSET: LEGO1 0x1005b3c0 STUB
// OFFSET: LEGO1 0x1005b3c0
MxBool LegoOmni::DoesEntityExist(MxDSAction& ds)
{
// TODO
return TRUE;
if (MxOmni::DoesEntityExist(ds)) {
if (FindByEntityIdOrAtomId(ds.GetAtomId(), ds.GetObjectId()) == NULL) {
return TRUE;
}
}
return FALSE;
}
// OFFSET: LEGO1 0x1005b2f0 STUB
int LegoOmni::Vtable0x30(char*, int, MxCore*)
// OFFSET: LEGO1 0x1005b2f0
MxEntity* LegoOmni::FindWorld(const char* p_id, MxS32 p_entityId, MxPresenter* p_presenter)
{
// TODO
return 0;
LegoWorld* foundEntity = NULL;
if (strcmpi(p_id, g_current)) {
foundEntity = (LegoWorld*) FindByEntityIdOrAtomId(MxAtomId(p_id, LookupMode_LowerCase2), p_entityId);
}
else {
foundEntity = this->m_currentWorld;
}
if (foundEntity != NULL) {
foundEntity->VTable0x58(p_presenter);
}
return foundEntity;
}
// OFFSET: LEGO1 0x1005b3a0
@ -371,3 +569,99 @@ void LegoOmni::StopTimer()
MxOmni::StopTimer();
SetAppCursor(0);
}
// OFFSET: LEGO1 0x100528e0
void RegisterScripts()
{
g_copterScript = new MxAtomId("\\lego\\scripts\\build\\copter", LookupMode_LowerCase2);
g_dunecarScript = new MxAtomId("\\lego\\scripts\\build\\dunecar", LookupMode_LowerCase2);
g_jetskiScript = new MxAtomId("\\lego\\scripts\\build\\jetski", LookupMode_LowerCase2);
g_racecarScript = new MxAtomId("\\lego\\scripts\\build\\racecar", LookupMode_LowerCase2);
g_carraceScript = new MxAtomId("\\lego\\scripts\\race\\carrace", LookupMode_LowerCase2);
g_carracerScript = new MxAtomId("\\lego\\scripts\\race\\carracer", LookupMode_LowerCase2);
g_jetraceScript = new MxAtomId("\\lego\\scripts\\race\\jetrace", LookupMode_LowerCase2);
g_jetracerScript = new MxAtomId("\\lego\\scripts\\race\\jetracer", LookupMode_LowerCase2);
g_isleScript = new MxAtomId("\\lego\\scripts\\isle\\isle", LookupMode_LowerCase2);
g_elevbottScript = new MxAtomId("\\lego\\scripts\\infocntr\\elevbott", LookupMode_LowerCase2);
g_infodoorScript = new MxAtomId("\\lego\\scripts\\infocntr\\infodoor", LookupMode_LowerCase2);
g_infomainScript = new MxAtomId("\\lego\\scripts\\infocntr\\infomain", LookupMode_LowerCase2);
g_infoscorScript = new MxAtomId("\\lego\\scripts\\infocntr\\infoscor", LookupMode_LowerCase2);
g_regbookScript = new MxAtomId("\\lego\\scripts\\infocntr\\regbook", LookupMode_LowerCase2);
g_histbookScript = new MxAtomId("\\lego\\scripts\\infocntr\\histbook", LookupMode_LowerCase2);
g_hospitalScript = new MxAtomId("\\lego\\scripts\\hospital\\hospital", LookupMode_LowerCase2);
g_policeScript = new MxAtomId("\\lego\\scripts\\police\\police", LookupMode_LowerCase2);
g_garageScript = new MxAtomId("\\lego\\scripts\\garage\\garage", LookupMode_LowerCase2);
g_act2mainScript = new MxAtomId("\\lego\\scripts\\act2\\act2main", LookupMode_LowerCase2);
g_act3Script = new MxAtomId("\\lego\\scripts\\act3\\act3", LookupMode_LowerCase2);
g_jukeboxScript = new MxAtomId("\\lego\\scripts\\isle\\jukebox", LookupMode_LowerCase2);
g_pz5Script = new MxAtomId("\\lego\\scripts\\isle\\pz5", LookupMode_LowerCase2);
g_introScript = new MxAtomId("\\lego\\scripts\\intro", LookupMode_LowerCase2);
g_testScript = new MxAtomId("\\lego\\scripts\\test\\test", LookupMode_LowerCase2);
g_jukeboxwScript = new MxAtomId("\\lego\\scripts\\isle\\jukeboxw", LookupMode_LowerCase2);
g_sndAnimScript = new MxAtomId("\\lego\\scripts\\sndanim", LookupMode_LowerCase2);
g_creditsScript = new MxAtomId("\\lego\\scripts\\credits", LookupMode_LowerCase2);
g_nocdSourceName = new MxAtomId("\\lego\\scripts\\nocd", LookupMode_LowerCase2);
}
// OFFSET: LEGO1 0x100530c0
void UnregisterScripts()
{
delete g_copterScript;
delete g_dunecarScript;
delete g_jetskiScript;
delete g_racecarScript;
delete g_carraceScript;
delete g_carracerScript;
delete g_jetraceScript;
delete g_jetracerScript;
delete g_isleScript;
delete g_elevbottScript;
delete g_infodoorScript;
delete g_infomainScript;
delete g_infoscorScript;
delete g_regbookScript;
delete g_histbookScript;
delete g_hospitalScript;
delete g_policeScript;
delete g_garageScript;
delete g_act2mainScript;
delete g_act3Script;
delete g_jukeboxScript;
delete g_pz5Script;
delete g_introScript;
delete g_testScript;
delete g_jukeboxwScript;
delete g_sndAnimScript;
delete g_creditsScript;
delete g_nocdSourceName;
g_copterScript = NULL;
g_dunecarScript = NULL;
g_jetskiScript = NULL;
g_racecarScript = NULL;
g_carraceScript = NULL;
g_carracerScript = NULL;
g_jetraceScript = NULL;
g_jetracerScript = NULL;
g_isleScript = NULL;
g_elevbottScript = NULL;
g_infodoorScript = NULL;
g_infomainScript = NULL;
g_infoscorScript = NULL;
g_regbookScript = NULL;
g_histbookScript = NULL;
g_hospitalScript = NULL;
g_policeScript = NULL;
g_garageScript = NULL;
g_act2mainScript = NULL;
g_act3Script = NULL;
g_jukeboxScript = NULL;
g_pz5Script = NULL;
g_introScript = NULL;
g_testScript = NULL;
g_testScript = NULL;
g_jukeboxwScript = NULL;
g_sndAnimScript = NULL;
g_creditsScript = NULL;
g_nocdSourceName = NULL;
}

View File

@ -26,6 +26,35 @@ class MxBackgroundAudioManager;
class MxDSFile;
class MxTransitionManager;
extern MxAtomId* g_copterScript;
extern MxAtomId* g_dunecarScript;
extern MxAtomId* g_jetskiScript;
extern MxAtomId* g_racecarScript;
extern MxAtomId* g_carraceScript;
extern MxAtomId* g_carracerScript;
extern MxAtomId* g_jetraceScript;
extern MxAtomId* g_jetracerScript;
extern MxAtomId* g_isleScript;
extern MxAtomId* g_elevbottScript;
extern MxAtomId* g_infodoorScript;
extern MxAtomId* g_infomainScript;
extern MxAtomId* g_infoscorScript;
extern MxAtomId* g_regbookScript;
extern MxAtomId* g_histbookScript;
extern MxAtomId* g_hospitalScript;
extern MxAtomId* g_policeScript;
extern MxAtomId* g_garageScript;
extern MxAtomId* g_act2mainScript;
extern MxAtomId* g_act3Script;
extern MxAtomId* g_jukeboxScript;
extern MxAtomId* g_pz5Script;
extern MxAtomId* g_introScript;
extern MxAtomId* g_testScript;
extern MxAtomId* g_jukeboxwScript;
extern MxAtomId* g_sndAnimScript;
extern MxAtomId* g_creditsScript;
extern MxAtomId* g_nocdSourceName;
// VTABLE 0x100d8638
// SIZE: 0x140
class LegoOmni : public MxOmni {
@ -54,16 +83,18 @@ class LegoOmni : public MxOmni {
return !strcmp(name, LegoOmni::ClassName()) || MxOmni::IsA(name);
}
virtual void Init() override; // vtable+14
virtual MxResult Create(MxOmniCreateParam& p) override; // vtable+18
virtual void Destroy() override; // vtable+1c
virtual MxResult Start(MxDSAction* action) override; // vtable+20
virtual MxResult DeleteObject(MxDSAction& ds) override; // vtable+24
virtual MxBool DoesEntityExist(MxDSAction& ds) override; // vtable+28
virtual int Vtable0x30(char*, int, MxCore*) override; // vtable+30
virtual void NotifyCurrentEntity(MxNotificationParam* p_param) override; // vtable+34
virtual void StartTimer() override; // vtable+38
virtual void StopTimer() override; // vtable+3c
virtual void Init() override; // vtable+14
virtual MxResult Create(MxOmniCreateParam& p) override; // vtable+18
virtual void Destroy() override; // vtable+1c
virtual MxResult Start(MxDSAction* action) override; // vtable+20
virtual MxResult DeleteObject(MxDSAction& ds) override; // vtable+24
virtual MxBool DoesEntityExist(MxDSAction& ds) override; // vtable+28
virtual MxEntity* FindWorld(const char* p_id, MxS32 p_entityId, MxPresenter* p_presenter) override; // vtable+30
virtual void NotifyCurrentEntity(MxNotificationParam* p_param) override; // vtable+34
virtual void StartTimer() override; // vtable+38
virtual void StopTimer() override; // vtable+3c
LegoEntity* FindByEntityIdOrAtomId(const MxAtomId& p_atom, MxS32 p_entityid);
LegoVideoManager* GetVideoManager() { return (LegoVideoManager*) m_videoManager; }
LegoSoundManager* GetSoundManager() { return (LegoSoundManager*) m_soundManager; }
@ -79,6 +110,7 @@ class LegoOmni : public MxOmni {
LegoGameState* GetGameState() { return m_gameState; }
MxBackgroundAudioManager* GetBackgroundAudioManager() { return m_bkgAudioManager; }
MxTransitionManager* GetTransitionManager() { return m_transitionManager; }
MxDSAction& GetCurrentAction() { return m_action; }
private:
undefined4 m_unk68;
@ -124,5 +156,9 @@ LegoPlantManager* PlantManager();
MxBool KeyValueStringParse(char*, const char*, const char*);
LegoWorld* GetCurrentWorld();
GifManager* GetGifManager();
MxDSAction& GetCurrentAction();
void RegisterScripts();
void UnregisterScripts();
#endif // LEGOOMNI_H

View File

@ -1,16 +1,96 @@
#include "legoroi.h"
// 0x10101368
int g_roiConfig = 100;
#include <string.h>
// OFFSET: LEGO1 0x100a9e10
void LegoROI::SetDisplayBB(int p_displayBB)
{
// Intentionally empty function
}
// SIZE 0x14
typedef struct {
const char* m_name;
MxS32 m_red;
MxS32 m_green;
MxS32 m_blue;
MxS32 m_unk10;
} ROIColorAlias;
// 0x100dbe28
const double g_normalizeByteToFloat = 1.0 / 255;
// 0x101011b0
ROIColorAlias g_roiColorAliases[22] = {
{"lego black", 0x21, 0x21, 0x21, 0}, {"lego black f", 0x21, 0x21, 0x21, 0},
{"lego black flat", 0x21, 0x21, 0x21, 0}, {"lego blue", 0x00, 0x54, 0x8c, 0},
{"lego blue flat", 0x00, 0x54, 0x8c, 0}, {"lego brown", 0x4a, 0x23, 0x1a, 0},
{"lego brown flt", 0x4a, 0x23, 0x1a, 0}, {"lego brown flat", 0x4a, 0x23, 0x1a, 0},
{"lego drk grey", 0x40, 0x40, 0x40, 0}, {"lego drk grey flt", 0x40, 0x40, 0x40, 0},
{"lego dk grey flt", 0x40, 0x40, 0x40, 0}, {"lego green", 0x00, 0x78, 0x2d, 0},
{"lego green flat", 0x00, 0x78, 0x2d, 0}, {"lego lt grey", 0x82, 0x82, 0x82, 0},
{"lego lt grey flt", 0x82, 0x82, 0x82, 0}, {"lego lt grey fla", 0x82, 0x82, 0x82, 0},
{"lego red", 0xcb, 0x12, 0x20, 0}, {"lego red flat", 0xcb, 0x12, 0x20, 0},
{"lego white", 0xfa, 0xfa, 0xfa, 0}, {"lego white flat", 0xfa, 0xfa, 0xfa, 0},
{"lego yellow", 0xff, 0xb9, 0x00, 0}, {"lego yellow flat", 0xff, 0xb9, 0x00, 0},
};
// 0x10101368
MxS32 g_roiConfig = 100;
// 0x101013ac
ROIHandler g_someHandlerFunction = NULL;
// OFFSET: LEGO1 0x100a81c0
void LegoROI::configureLegoROI(int p_roi)
void LegoROI::configureLegoROI(MxS32 p_roi)
{
g_roiConfig = p_roi;
}
// OFFSET: LEGO1 0x100a9bf0
MxBool LegoROI::CallTheHandlerFunction(
char* p_param,
MxFloat& p_red,
MxFloat& p_green,
MxFloat& p_blue,
MxFloat& p_other
)
{
// TODO
if (p_param == NULL)
return FALSE;
if (g_someHandlerFunction) {
char buf[32];
if (g_someHandlerFunction(p_param, buf, 32))
p_param = buf;
}
return ColorAliasLookup(p_param, p_red, p_green, p_blue, p_other);
}
// OFFSET: LEGO1 0x100a9c50
MxBool LegoROI::ColorAliasLookup(char* p_param, MxFloat& p_red, MxFloat& p_green, MxFloat& p_blue, MxFloat& p_other)
{
// TODO: this seems awfully hacky for these devs. is there a dynamic way
// to represent `the end of this array` that would improve this?
MxU32 i = 0;
do {
if (strcmpi(g_roiColorAliases[i].m_name, p_param) == 0) {
p_red = g_roiColorAliases[i].m_red * g_normalizeByteToFloat;
p_green = g_roiColorAliases[i].m_green * g_normalizeByteToFloat;
p_blue = g_roiColorAliases[i].m_blue * g_normalizeByteToFloat;
p_other = g_roiColorAliases[i].m_unk10 * g_normalizeByteToFloat;
return TRUE;
}
i++;
} while ((MxS32*) &g_roiColorAliases[i] < &g_roiConfig);
return FALSE;
}
// OFFSET: LEGO1 0x100a9d30
void LegoROI::SetSomeHandlerFunction(ROIHandler p_func)
{
g_someHandlerFunction = p_func;
}
// OFFSET: LEGO1 0x100a9e10
void LegoROI::SetDisplayBB(MxS32 p_displayBB)
{
// Intentionally empty function
}

View File

@ -1,10 +1,24 @@
#ifndef LEGOROI_H
#define LEGOROI_H
#include "mxtypes.h"
typedef MxBool (*ROIHandler)(char*, char*, MxU32);
class LegoROI {
public:
__declspec(dllexport) void SetDisplayBB(int p_displayBB);
__declspec(dllexport) static void configureLegoROI(int p_roi);
__declspec(dllexport) void SetDisplayBB(MxS32 p_displayBB);
__declspec(dllexport) static void configureLegoROI(MxS32 p_roi);
static void SetSomeHandlerFunction(ROIHandler p_func);
static MxBool CallTheHandlerFunction(
char* p_param,
MxFloat& p_red,
MxFloat& p_green,
MxFloat& p_blue,
MxFloat& p_other
);
static MxBool ColorAliasLookup(char* p_param, MxFloat& p_red, MxFloat& p_green, MxFloat& p_blue, MxFloat& p_other);
};
#endif // LEGOROI_H

View File

@ -1,7 +1,17 @@
#include "legotexturepresenter.h"
// OFFSET: LEGO1 0x1004eb40 STUB
#include "legoomni.h"
#include "legovideomanager.h"
// OFFSET: LEGO1 0x1004eb40
LegoTexturePresenter::~LegoTexturePresenter()
{
// TODO
VideoManager()->RemovePresenter(*this);
}
// OFFSET: LEGO1 0x1004ebb0
MxResult LegoTexturePresenter::AddToManager()
{
VideoManager()->AddPresenter(*this);
return SUCCESS;
}

View File

@ -21,6 +21,8 @@ class LegoTexturePresenter : public MxMediaPresenter {
{
return !strcmp(name, LegoTexturePresenter::ClassName()) || MxMediaPresenter::IsA(name);
}
virtual MxResult AddToManager() override; // vtable+0x34
};
#endif // LEGOTEXTUREPRESENTER_H

View File

@ -2,16 +2,57 @@
DECOMP_SIZE_ASSERT(LegoVideoManager, 0x590);
// OFFSET: LEGO1 0x1007aa20 STUB
// OFFSET: LEGO1 0x1007aa20
LegoVideoManager::LegoVideoManager()
{
// TODO
m_unk64 = 0;
m_3dManager = NULL;
m_unk6c = 0;
m_direct3d = 0;
m_unk0xe6 = FALSE;
memset(m_unk0x78, 0, sizeof(m_unk0x78));
m_unk0x78[0] = 0x6c;
m_unk4e8 = 0;
m_isFullscreenMovie = FALSE;
m_palette = NULL;
m_prefCounter = NULL;
m_cursorMoved = FALSE;
m_cursorX = m_cursorY;
m_cursorYCopy = m_cursorY;
m_cursorXCopy = m_cursorY;
m_unk0x514 = 0;
m_unk0x500 = FALSE;
m_drawFPS = FALSE;
m_unk0x528 = 0;
m_arialFont = NULL;
m_unk0xe5 = FALSE;
m_unk0x554 = 0;
m_initialized = FALSE;
}
// OFFSET: LEGO1 0x1007ab40 STUB
// OFFSET: LEGO1 0x1007ab40
LegoVideoManager::~LegoVideoManager()
{
// TODO
Destroy();
delete m_palette;
}
// OFFSET: LEGO1 0x1007b5e0
void LegoVideoManager::Destroy()
{
// todo: delete m_unk0x512
// todo: delete m_unk0x258
if (m_arialFont != NULL) {
DeleteObject(m_arialFont);
m_arialFont = NULL;
}
// delete m_unk64; //TODO: delete d3drm
delete m_3dManager;
MxVideoManager::Destroy();
// todo: delete m_unk4e8
delete[] m_prefCounter;
}
// OFFSET: LEGO1 0x1007c560 STUB

View File

@ -33,20 +33,42 @@ class LegoVideoManager : public MxVideoManager {
this->m_videoParam.GetPalette()->SetOverrideSkyColor(p_shouldOverride);
}
virtual void Destroy() override; // vtable+0x18
private:
undefined4 m_unk64;
Lego3DManager* m_3dManager;
Lego3DManager* m_3dManager; // 0x68
undefined4 m_unk6c;
undefined4 m_unk70;
MxDirect3D* m_direct3d;
undefined m_pad0x78[0x6c];
MxDirect3D* m_direct3d; // 0x74
undefined4 m_unk0x78[27];
MxBool m_unk0xe4;
undefined m_pad0xe8[0x41c];
MxBool m_unk0xe5;
MxBool m_unk0xe6;
PALETTEENTRY m_paletteEntries[256]; // 0xe7
undefined m_padding0x4e7;
undefined4 m_unk4e8;
MxBool m_isFullscreenMovie; // 0x4ec
MxPalette* m_palette; // 0x4f0
LARGE_INTEGER* m_prefCounter; // 0x4f4
undefined m_padding0x4f4[8];
MxBool m_unk0x500;
MxBool m_cursorMoved; // 0x501
undefined m_pad0x502[0x8];
MxS32 m_cursorX; // 0x50c
MxS32 m_cursorY; // 0x510
undefined m_pad0x514[0x7c];
MxS32 m_cursorXCopy; // 0x504
MxS32 m_cursorYCopy; // 0x508
MxS32 m_cursorX; // 0x50c
MxS32 m_cursorY; // 0x510
undefined4 m_unk0x514;
undefined m_pad0x518[0x10];
undefined4 m_unk0x528;
MxBool m_drawFPS; // 0x52c
RECT m_fpsRect; // 0x530
HFONT m_arialFont; // 0x540
SIZE m_fpsSize; // 0x544
undefined m_pad0x54c[8];
undefined m_unk0x554;
MxBool m_initialized; // 0x555
undefined m_pad0x556[0x39];
};
#endif // LEGOVIDEOMANAGER_H

View File

@ -1,9 +1,12 @@
#include "legoworldpresenter.h"
// OFFSET: LEGO1 0x100665c0 STUB
// 0x100f75d4
undefined4 g_LegoWorldPresenterQuality = 1;
// OFFSET: LEGO1 0x100665c0
LegoWorldPresenter::LegoWorldPresenter()
{
// TODO
m_unk50 = 50000;
}
// OFFSET: LEGO1 0x10066770 STUB
@ -12,8 +15,8 @@ LegoWorldPresenter::~LegoWorldPresenter()
// TODO
}
// OFFSET: LEGO1 0x100665b0 STUB
void LegoWorldPresenter::configureLegoWorldPresenter(int param_1)
// OFFSET: LEGO1 0x100665b0
void LegoWorldPresenter::configureLegoWorldPresenter(int p_quality)
{
// TODO
g_LegoWorldPresenterQuality = p_quality;
}

View File

@ -24,6 +24,9 @@ class LegoWorldPresenter : public LegoEntityPresenter {
{
return !strcmp(name, LegoWorldPresenter::ClassName()) || LegoEntityPresenter::IsA(name);
}
private:
undefined4 m_unk50;
};
#endif // LEGOWORLDPRESENTER_H

View File

@ -8,7 +8,12 @@
// SIZE 0x14
class MxActionNotificationParam : public MxNotificationParam {
public:
inline MxActionNotificationParam(MxParamType p_type, MxCore* p_sender, MxDSAction* p_action, MxBool p_reallocAction)
inline MxActionNotificationParam(
NotificationId p_type,
MxCore* p_sender,
MxDSAction* p_action,
MxBool p_reallocAction
)
: MxNotificationParam(p_type, p_sender)
{
MxDSAction* oldAction = p_action;
@ -50,7 +55,7 @@ class MxActionNotificationParam : public MxNotificationParam {
class MxEndActionNotificationParam : public MxActionNotificationParam {
public:
inline MxEndActionNotificationParam(
MxParamType p_type,
NotificationId p_type,
MxCore* p_sender,
MxDSAction* p_action,
MxBool p_reallocAction

View File

@ -1,6 +1,10 @@
#include "mxbackgroundaudiomanager.h"
#include "legoomni.h"
#include "mxcompositepresenter.h"
#include "mxdssound.h"
#include "mxomni.h"
#include "mxpresenter.h"
#include "mxstreamer.h"
#include "mxticklemanager.h"
@ -14,7 +18,7 @@ MxBackgroundAudioManager::MxBackgroundAudioManager()
m_unk138 = 0;
m_unk13c = 0;
m_unk140 = 0;
m_unk144 = 0;
m_targetVolume = 0;
m_unk148 = 0;
m_musicEnabled = FALSE;
}
@ -47,6 +51,32 @@ void MxBackgroundAudioManager::Stop()
m_unk13c = 0;
}
// OFFSET: LEGO1 0x1007f570
void MxBackgroundAudioManager::LowerVolume()
{
if (m_unk148 == 0) {
if (m_unk13c == 0) {
m_unk13c = 2;
}
m_unk140 = 20;
}
m_unk148++;
}
// OFFSET: LEGO1 0x1007f5b0
void MxBackgroundAudioManager::RaiseVolume()
{
if (m_unk148 != 0) {
m_unk148--;
if (m_unk148 == 0) {
if (m_unk13c == 0) {
m_unk13c = 2;
}
m_unk140 = 10;
}
}
}
// OFFSET: LEGO1 0x1007f5f0
void MxBackgroundAudioManager::Enable(MxBool p)
{
@ -106,3 +136,191 @@ void MxBackgroundAudioManager::DestroyMusic()
m_musicEnabled = FALSE;
}
}
// OFFSET: LEGO1 0x1007f170
MxLong MxBackgroundAudioManager::Notify(MxParam& p)
{
switch (((MxNotificationParam&) p).GetNotification()) {
case c_notificationStartAction:
StartAction(p);
return 1;
case c_notificationEndAction:
StopAction(p);
return 1;
}
return 0;
}
// OFFSET: LEGO1 0x1007f1b0
void MxBackgroundAudioManager::StartAction(MxParam& p)
{
// TODO: the sender is most likely a MxAudioPresenter?
m_unk138 = (MxAudioPresenter*) ((MxNotificationParam&) p).GetSender();
m_action2.SetAtomId(m_unk138->GetAction()->GetAtomId());
m_action2.SetObjectId(m_unk138->GetAction()->GetObjectId());
m_targetVolume = ((MxDSSound*) (m_unk138->GetAction()))->GetVolume();
m_unk138->vtable60(0);
}
// OFFSET: LEGO1 0x1007f200
void MxBackgroundAudioManager::StopAction(MxParam& p)
{
if (((MxNotificationParam&) p).GetSender() == m_unka0) {
m_unka0 = NULL;
m_action1.SetAtomId(MxAtomId());
m_action1.SetObjectId(-1);
}
else if (((MxNotificationParam&) p).GetSender() == m_unk138) {
m_unk138 = NULL;
m_action2.SetAtomId(MxAtomId());
m_action2.SetObjectId(-1);
}
Lego()->HandleNotificationType2(p);
}
// OFFSET: LEGO1 0x1007f2f0
MxResult MxBackgroundAudioManager::PlayMusic(MxDSAction& p_action, undefined4 p_unknown, undefined4 p_unknown2)
{
if (!m_musicEnabled) {
return SUCCESS;
}
if (m_action2.GetObjectId() == -1 && m_action1.GetObjectId() != p_action.GetObjectId()) {
MxDSAction action;
action.SetAtomId(GetCurrentAction().GetAtomId());
action.SetObjectId(GetCurrentAction().GetObjectId());
action.SetUnknown24(GetCurrentAction().GetUnknown24());
m_action2.SetAtomId(p_action.GetAtomId());
m_action2.SetObjectId(p_action.GetObjectId());
m_action2.SetUnknown84(this);
m_action2.SetUnknown8c(this);
MxResult result = Start(&m_action2);
GetCurrentAction().SetAtomId(action.GetAtomId());
GetCurrentAction().SetObjectId(action.GetObjectId());
GetCurrentAction().SetUnknown24(action.GetUnknown24());
if (result == SUCCESS) {
m_unk13c = p_unknown2;
m_unk140 = p_unknown;
}
return result;
}
return FAILURE;
}
// OFFSET: LEGO1 0x1007ee40
MxResult MxBackgroundAudioManager::Tickle()
{
switch (m_unk13c) {
case MxPresenter::TickleState_Starting:
FadeInOrFadeOut();
return SUCCESS;
case MxPresenter::TickleState_Streaming:
FUN_1007ee70();
return SUCCESS;
case MxPresenter::TickleState_Repeating:
FUN_1007ef40();
return SUCCESS;
default:
return SUCCESS;
}
}
// OFFSET: LEGO1 0x1007ee70
void MxBackgroundAudioManager::FUN_1007ee70()
{
if (m_unka0 && m_unka0->GetAction()) {
DeleteObject(*m_unk138->GetAction());
}
if (m_unk138) {
m_unka0 = m_unk138;
m_action1 = m_action2;
m_unk138 = NULL;
m_action2.SetObjectId(-1);
m_action2.SetAtomId(MxAtomId());
m_unk13c = NULL;
}
}
// OFFSET: LEGO1 0x1007ef40
void MxBackgroundAudioManager::FUN_1007ef40()
{
MxU32 compare;
MxU32 volume;
if (m_unka0 == NULL) {
if (m_unk138) {
compare = 30;
if (m_unk148 == 0) {
compare = m_unk148;
}
volume = m_unk138->vtable5c();
if (volume < compare) {
if (m_unk140 + m_unk138->vtable5c() <= compare) {
compare = m_unk140 + compare;
}
m_unk138->vtable60(compare);
}
else {
m_unk138->vtable60(compare);
m_unka0 = m_unk138;
m_action1 = m_action2;
m_unk138 = NULL;
m_action2.SetObjectId(-1);
m_action2.SetAtomId(MxAtomId());
m_unk13c = NULL;
}
}
}
else if (m_unka0->GetAction() != NULL) {
if (m_unka0->vtable5c() == 0) {
DeleteObject(*m_unka0->GetAction());
}
else {
compare = m_unka0->vtable5c();
volume = 0;
if (compare != m_unk140 && -1 < compare - m_unk140) {
volume = m_unka0->vtable5c() - m_unk140;
}
m_unk138->vtable60(volume);
}
}
}
// OFFSET: LEGO1 0x1007f0e0
void MxBackgroundAudioManager::FadeInOrFadeOut()
{
// This function probably is the fade in/out routine
if (m_unka0 != NULL) {
undefined4 volume = m_unka0->vtable5c();
MxU32 compare = 30;
if (m_unk148 == 0) {
compare = m_targetVolume;
}
if (volume < compare) {
volume = m_unk140 + volume;
if (compare <= volume) {
volume = compare;
}
m_unka0->vtable60(volume);
}
else if (compare < volume) {
volume = volume - m_unk140;
if (volume <= compare) {
volume = compare;
}
m_unka0->vtable60(volume);
}
else {
m_unka0->vtable60(volume);
m_unk13c = 0;
}
}
else {
m_unk13c = 0;
}
}

View File

@ -1,9 +1,11 @@
#ifndef MXBACKGROUNDAUDIOMANAGER_H
#define MXBACKGROUNDAUDIOMANAGER_H
#include "mxaudiopresenter.h"
#include "mxcore.h"
#include "mxdsaction.h"
#include "mxnotificationmanager.h"
#include "mxpresenter.h"
#include "mxtypes.h"
// VTABLE 0x100d9fe8
@ -13,6 +15,9 @@ class MxBackgroundAudioManager : public MxCore {
MxBackgroundAudioManager();
virtual ~MxBackgroundAudioManager() override;
virtual MxLong Notify(MxParam& p) override; // vtable+0x04
virtual MxResult Tickle() override; // vtable+0x08
// OFFSET: LEGO1 0x1007eb70
inline virtual const char* ClassName() const override // vtable+0x0c
{
@ -26,10 +31,20 @@ class MxBackgroundAudioManager : public MxCore {
return !strcmp(name, MxBackgroundAudioManager::ClassName()) || MxCore::IsA(name);
}
void StartAction(MxParam& p);
void StopAction(MxParam& p);
MxResult PlayMusic(MxDSAction& p_action, undefined4 p_unknown, undefined4 p_unknown2);
void FUN_1007ee70();
void FUN_1007ef40();
void FadeInOrFadeOut();
__declspec(dllexport) void Enable(unsigned char p);
virtual MxResult Create(MxAtomId& p_script, MxU32 p_frequencyMS);
void Stop();
void LowerVolume();
void RaiseVolume();
private:
void Init();
@ -38,12 +53,12 @@ class MxBackgroundAudioManager : public MxCore {
MxBool m_musicEnabled; // 0x8
MxDSAction m_action1; // 0xc
MxS32 m_unka0;
MxAudioPresenter* m_unka0;
MxDSAction m_action2; // 0xa4
MxS32 m_unk138;
MxAudioPresenter* m_unk138;
MxS32 m_unk13c;
MxS32 m_unk140;
MxS32 m_unk144;
MxS32 m_targetVolume;
MxS16 m_unk148;
MxAtomId m_script;
};

25
LEGO1/mxcollection.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef MXCOLLECTION_H
#define MXCOLLECTION_H
#include "mxcore.h"
template <class T>
class MxCollection : public MxCore {
public:
MxCollection()
{
m_count = 0;
m_customDestructor = Destroy;
}
virtual ~MxCollection() {}
static void Destroy(T){};
virtual MxS8 Compare(T, T) { return 0; }
protected:
MxU32 m_count; // +0x8
void (*m_customDestructor)(T); // +0xc
};
#endif // MXCOLLECTION_H

View File

@ -16,3 +16,29 @@ MxCompositePresenter::~MxCompositePresenter()
{
NotificationManager()->Unregister(this);
}
// OFFSET: LEGO1 0x100b67f0 STUB
void MxCompositePresenter::VTable0x58()
{
// TODO
}
// OFFSET: LEGO1 0x100b69b0 STUB
void MxCompositePresenter::VTable0x5c()
{
// TODO
}
// OFFSET: LEGO1 0x100b6b40 STUB
void MxCompositePresenter::VTable0x60(undefined4 p_unknown)
{
// TODO
}
// OFFSET: LEGO1 0x1000caf0
MxBool MxCompositePresenter::VTable0x64(undefined4 p_unknown)
{
if (m_compositePresenter)
return m_compositePresenter->VTable0x64(p_unknown);
return TRUE;
}

View File

@ -24,6 +24,12 @@ class MxCompositePresenter : public MxPresenter {
return !strcmp(name, MxCompositePresenter::ClassName()) || MxPresenter::IsA(name);
}
virtual void VTable0x58();
virtual void VTable0x5c();
virtual void VTable0x60(undefined4 p_unknown);
virtual MxBool VTable0x64(undefined4 p_unknown);
private:
MxUnkList m_list;
};

View File

@ -1,5 +1,8 @@
#include "mxcontrolpresenter.h"
#include "legoomni.h"
#include "mxticklemanager.h"
DECOMP_SIZE_ASSERT(MxControlPresenter, 0x5c)
// OFFSET: LEGO1 0x10043f50
@ -12,3 +15,21 @@ MxControlPresenter::MxControlPresenter()
this->m_unk58 = 0;
this->m_unk54 = 0;
}
// OFFSET: LEGO1 0x10044110
MxControlPresenter::~MxControlPresenter()
{
if (this->m_unk58) {
delete this->m_unk58;
}
}
// OFFSET: LEGO1 0x10044610
void MxControlPresenter::ReadyTickle()
{
MxPresenter::ParseExtra();
TickleManager()->UnregisterClient(this);
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
m_currentTickleState = TickleState_Repeating;
}

View File

@ -9,6 +9,7 @@
class MxControlPresenter : public MxCompositePresenter {
public:
MxControlPresenter();
virtual ~MxControlPresenter() override;
// OFFSET: LEGO1 0x10044000
inline virtual const char* ClassName() const override // vtable+0x0c
@ -23,13 +24,15 @@ class MxControlPresenter : public MxCompositePresenter {
return !strcmp(name, MxControlPresenter::ClassName()) || MxCompositePresenter::IsA(name);
}
virtual void ReadyTickle() override; // vtable+0x18
private:
undefined2 m_unk4c;
MxS16 m_unk4e;
undefined m_unk50;
undefined2 m_unk52;
undefined2 m_unk54;
undefined4 m_unk58;
undefined4* m_unk58;
};
#endif // MXCONTROLPRESENTER_H

View File

@ -1,13 +1,12 @@
#include "mxcore.h"
// 0x1010141c
unsigned int g_mxcoreCount = 0;
#include "define.h"
// OFFSET: LEGO1 0x100ae1a0
MxCore::MxCore()
{
m_id = g_mxcoreCount;
g_mxcoreCount++;
m_id = g_mxcoreCount[0];
g_mxcoreCount[0]++;
}
// OFFSET: LEGO1 0x100ae1e0

View File

@ -13,9 +13,9 @@ class MxParam;
class MxCore {
public:
__declspec(dllexport) MxCore();
__declspec(dllexport) virtual ~MxCore(); // vtable+00
__declspec(dllexport) virtual MxResult Notify(MxParam& p); // vtable+04
virtual MxResult Tickle(); // vtable+08
__declspec(dllexport) virtual ~MxCore(); // vtable+00
__declspec(dllexport) virtual MxLong Notify(MxParam& p); // vtable+04
virtual MxResult Tickle(); // vtable+08
// OFFSET: LEGO1 0x100144c0
inline virtual const char* ClassName() const // vtable+0c

View File

@ -81,7 +81,7 @@ MxResult MxDiskStreamProvider::WaitForWorkToComplete()
return SUCCESS;
}
// OFFSET: LEGO1 0x100d1760 STUB
// OFFSET: LEGO1 0x100d18f0 STUB
void MxDiskStreamProvider::PerformWork()
{
// TODO

View File

@ -82,8 +82,8 @@ MxResult MxDisplaySurface::Create(MxVideoParam& p_videoParam)
}
if (this->m_videoParam.flags().GetFullScreen()) {
MxS32 width = this->m_videoParam.GetRect().m_right - this->m_videoParam.GetRect().m_left + 1;
MxS32 height = this->m_videoParam.GetRect().m_bottom - this->m_videoParam.GetRect().m_top + 1;
MxS32 width = this->m_videoParam.GetRect().GetWidth();
MxS32 height = this->m_videoParam.GetRect().GetHeight();
if (lpDirectDraw->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN))
goto done;
@ -129,8 +129,8 @@ MxResult MxDisplaySurface::Create(MxVideoParam& p_videoParam)
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH | DDSD_CAPS;
ddsd.dwWidth = this->m_videoParam.GetRect().m_right - this->m_videoParam.GetRect().m_left + 1;
ddsd.dwHeight = this->m_videoParam.GetRect().m_bottom - this->m_videoParam.GetRect().m_top + 1;
ddsd.dwWidth = this->m_videoParam.GetRect().GetWidth();
ddsd.dwHeight = this->m_videoParam.GetRect().GetHeight();
ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_3DDEVICE | DDSCAPS_OFFSCREENPLAIN;
if (!this->m_videoParam.flags().GetBackBuffers())

View File

@ -28,7 +28,7 @@ MxDSAction::MxDSAction()
this->m_up.Fill(FLT_MAX);
this->m_unk84 = NULL;
this->m_unk88 = 0;
this->m_omni = NULL;
this->m_unk8c = NULL;
this->m_unkTimingField = INT_MIN;
}
@ -54,7 +54,7 @@ void MxDSAction::CopyFrom(MxDSAction& p_dsAction)
AppendData(p_dsAction.m_extraLength, p_dsAction.m_extraData);
this->m_unk84 = p_dsAction.m_unk84;
this->m_unk88 = p_dsAction.m_unk88;
this->m_omni = p_dsAction.m_omni;
this->m_unk8c = p_dsAction.m_unk8c;
this->m_unkTimingField = p_dsAction.m_unkTimingField;
}
@ -196,11 +196,8 @@ MxLong MxDSAction::GetUnkTimingField()
return this->m_unkTimingField;
}
// Win32 defines GetCurrentTime to GetTickCount
#undef GetCurrentTime
// OFFSET: LEGO1 0x100adcd0
MxLong MxDSAction::GetCurrentTime()
MxLong MxDSAction::GetElapsedTime()
{
return Timer()->GetTime() - this->m_unkTimingField;
}

View File

@ -17,7 +17,8 @@ class MxDSAction : public MxDSObject {
Flag_Bit4 = 0x08,
Flag_Bit5 = 0x10,
Flag_Enabled = 0x20,
Flag_Parsed = 0x80,
Flag_Bit7 = 0x40,
Flag_World = 0x80,
Flag_Bit9 = 0x200,
Flag_Bit10 = 0x400,
};
@ -50,7 +51,7 @@ class MxDSAction : public MxDSObject {
virtual MxBool HasId(MxU32 p_objectId); // vtable+34;
virtual void SetUnkTimingField(MxLong p_unkTimingField); // vtable+38;
virtual MxLong GetUnkTimingField(); // vtable+3c;
virtual MxLong GetCurrentTime(); // vtable+40;
virtual MxLong GetElapsedTime(); // vtable+40;
void AppendData(MxU16 p_extraLength, const char* p_extraData);
@ -63,7 +64,8 @@ class MxDSAction : public MxDSObject {
inline void SetLoopCount(MxS32 p_loopCount) { m_loopCount = p_loopCount; }
inline const MxVector3Data& GetLocation() const { return m_location; }
inline void SetUnknown84(MxCore* p_unk84) { m_unk84 = p_unk84; }
inline void SetOmni(MxOmni* p_omni) { m_omni = p_omni; }
inline MxCore* GetUnknown8c() { return m_unk8c; }
inline void SetUnknown8c(MxCore* p_unk8c) { m_unk8c = p_unk8c; }
inline MxBool IsLooping() const { return m_flags & Flag_Looping; }
inline MxBool IsBit3() const { return m_flags & Flag_Bit3; }
@ -85,7 +87,7 @@ class MxDSAction : public MxDSObject {
MxU16 m_extraLength;
MxCore* m_unk84;
undefined4 m_unk88;
MxOmni* m_omni; // 0x8c
MxCore* m_unk8c;
protected:
MxLong m_unkTimingField; // 0x90

View File

@ -6,13 +6,9 @@ DECOMP_SIZE_ASSERT(MxDSActionList, 0x1c);
DECOMP_SIZE_ASSERT(MxDSActionListCursor, 0x10);
// OFFSET: LEGO1 0x100c9c90
MxS8 MxDSActionList::Compare(MxDSAction* p_var0, MxDSAction* p_var1)
MxS8 MxDSActionList::Compare(MxDSAction* p_a, MxDSAction* p_b)
{
if (p_var1 == p_var0)
return 0;
if (p_var1 <= p_var0)
return 1;
return -1;
return p_a == p_b ? 0 : p_a < p_b ? -1 : 1;
}
// OFFSET: LEGO1 0x100c9cb0

View File

@ -12,7 +12,7 @@ class MxDSActionList : public MxList<MxDSAction*> {
public:
MxDSActionList() { this->m_unk18 = 0; }
virtual MxS8 Compare(MxDSAction*, MxDSAction*); // +0x14
virtual MxS8 Compare(MxDSAction*, MxDSAction*) override; // +0x14
static void Destroy(MxDSAction* p_action);

View File

@ -1,5 +1,8 @@
#include "mxdsbuffer.h"
#include "mxomni.h"
#include "mxstreamer.h"
DECOMP_SIZE_ASSERT(MxDSBuffer, 0x34);
// OFFSET: LEGO1 0x100c6470
@ -14,24 +17,112 @@ MxDSBuffer::MxDSBuffer()
m_unk1c = 0;
m_writeOffset = 0;
m_bytesRemaining = 0;
m_mode = 2;
m_mode = MxDSBufferType_Preallocated;
m_unk30 = 0;
}
// OFFSET: LEGO1 0x100c6530
MxDSBuffer::~MxDSBuffer()
{
// TODO
if (m_pBuffer != NULL) {
if (m_mode == MxDSBufferType_Chunk) {
// TODO
}
else if (m_mode == MxDSBufferType_Allocate || m_mode == MxDSBufferType_Unknown) {
delete[] m_pBuffer;
}
}
m_unk14 = 0;
m_unk1c = 0;
}
// OFFSET: LEGO1 0x100c6640
MxResult MxDSBuffer::AllocateBuffer(MxU32 p_bufferSize, MxDSBufferType p_mode)
{
MxResult result = FAILURE;
MxU32 i = 0;
if (p_mode == MxDSBufferType_Allocate) {
m_pBuffer = new MxU8[p_bufferSize];
}
else if (p_mode == MxDSBufferType_Chunk) {
MxStreamer* streamer = Streamer();
// I have no clue as to what this does, or even if its correct. Maybe it's related to storing chunks in
// MxRamStreamController?
if (p_bufferSize >> 10 == 0x40) {
i = 0;
while (i < 22) {
if ((*(MxU32*) ((streamer->GetSubclass1().GetUnk08() + ((i & 0xffffffe7) >> 3)) & 1 << ((MxU8) i & 0x1f)
)) == 0) {
MxU32* ptr = (MxU32*) ((streamer->GetSubclass1().GetUnk08() + ((i & 0xffffffe7) >> 3)) &
1 << ((MxU8) i & 0x1f));
// mark it as used?
*ptr = *ptr ^ 1 << (i & 0x1f);
m_pBuffer =
(MxU8*) (streamer->GetSubclass1().GetSize() * i * 0x400 + streamer->GetSubclass1().GetBuffer());
break;
}
i++;
}
m_pBuffer = NULL;
}
else if (p_bufferSize >> 10 == 0x80) {
i = 0;
// Same thing as above but it uses subclass2
while (i < 22) {
if ((*(MxU32*) ((streamer->GetSubclass2().GetUnk08() + ((i & 0xffffffe7) >> 3)) & 1 << ((MxU8) i & 0x1f)
)) == 0) {
MxU32* ptr = (MxU32*) ((streamer->GetSubclass2().GetUnk08() + ((i & 0xffffffe7) >> 3)) &
1 << ((MxU8) i & 0x1f));
// mark it as used?
*ptr = *ptr ^ 1 << (i & 0x1f);
m_pBuffer =
(MxU8*) (streamer->GetSubclass2().GetSize() * i * 0x400 + streamer->GetSubclass2().GetBuffer());
break;
}
i++;
}
m_pBuffer = NULL;
}
else {
m_pIntoBuffer = NULL;
}
}
m_pIntoBuffer = m_pBuffer;
m_pIntoBuffer2 = m_pBuffer;
if (m_pBuffer != NULL) {
m_mode = p_mode;
m_bytesRemaining = p_bufferSize;
m_writeOffset = p_bufferSize;
result = SUCCESS;
}
return result;
}
// OFFSET: LEGO1 0x100c6780
MxResult MxDSBuffer::FUN_100c6780(void* p_buffer, MxU32 p_size)
MxResult MxDSBuffer::SetBufferPointer(MxU32* p_buffer, MxU32 p_size)
{
m_pBuffer = p_buffer;
m_pIntoBuffer = p_buffer;
m_pIntoBuffer2 = p_buffer;
m_pBuffer = (MxU8*) p_buffer;
m_pIntoBuffer = (MxU8*) p_buffer;
m_pIntoBuffer2 = (MxU8*) p_buffer;
m_bytesRemaining = p_size;
m_writeOffset = p_size;
m_mode = 2;
m_mode = MxDSBufferType_Preallocated;
return SUCCESS;
}
// OFFSET: LEGO1 0x100c6f80
void MxDSBuffer::FUN_100c6f80(MxU32 p_unk)
{
if (p_unk < m_writeOffset) {
m_pIntoBuffer2 = m_pBuffer + p_unk;
m_pIntoBuffer = m_pBuffer + p_unk;
}
}

View File

@ -4,6 +4,13 @@
#include "decomp.h"
#include "mxcore.h"
enum MxDSBufferType {
MxDSBufferType_Chunk = 0,
MxDSBufferType_Allocate = 1,
MxDSBufferType_Preallocated = 2,
MxDSBufferType_Unknown = 3,
};
// VTABLE 0x100dcca0
// SIZE 0x34
class MxDSBuffer : public MxCore {
@ -18,20 +25,22 @@ class MxDSBuffer : public MxCore {
return "MxDSBuffer";
}
MxResult FUN_100c6780(void* p_buffer, MxU32 p_size);
MxResult AllocateBuffer(MxU32 p_bufferSize, MxDSBufferType p_mode);
MxResult SetBufferPointer(MxU32* p_buffer, MxU32 p_size);
void FUN_100c6f80(MxU32 p_unk);
inline void* GetBuffer() { return m_pBuffer; }
inline MxU8* GetBuffer() { return m_pBuffer; }
inline MxU32 GetWriteOffset() { return m_writeOffset; }
private:
void* m_pBuffer;
void* m_pIntoBuffer;
void* m_pIntoBuffer2;
MxU8* m_pBuffer;
MxU8* m_pIntoBuffer;
MxU8* m_pIntoBuffer2;
undefined4 m_unk14;
undefined4 m_unk18;
undefined4 m_unk1c;
undefined2 m_unk20;
undefined4 m_mode;
MxDSBufferType m_mode;
MxU32 m_writeOffset;
MxU32 m_bytesRemaining;
undefined4 m_unk30;

View File

@ -1,19 +1,21 @@
#include "mxdschunk.h"
DECOMP_SIZE_ASSERT(MxDSChunk, 0x1c);
// OFFSET: LEGO1 0x100be050
MxDSChunk::MxDSChunk()
{
this->m_length = 0;
this->m_unk18 = NULL;
this->m_buffer = -1;
this->m_unk10 = 0;
this->m_unk14 = 0;
m_flags = 0;
m_data = NULL;
m_unk0c = -1;
m_time = 0;
m_length = 0;
}
// OFFSET: LEGO1 0x100be170
MxDSChunk::~MxDSChunk()
{
if ((this->m_length & 1) != 0) {
delete this->m_unk18;
if (m_flags & Flag_Bit1) {
delete[] m_data;
}
}

View File

@ -1,12 +1,20 @@
#ifndef MXDSCHUNK_H
#define MXDSCHUNK_H
#include "decomp.h"
#include "mxcore.h"
#include "mxtypes.h"
// VTABLE 0x100dc7f8
// SIZE 0x1c
class MxDSChunk : public MxCore {
public:
enum {
Flag_Bit1 = 0x01,
Flag_Bit2 = 0x02,
Flag_Bit3 = 0x04,
};
MxDSChunk();
virtual ~MxDSChunk() override;
@ -23,13 +31,27 @@ class MxDSChunk : public MxCore {
return !strcmp(name, MxDSChunk::ClassName()) || MxCore::IsA(name);
}
inline void SetTime(MxLong p_time) { m_time = p_time; }
inline void SetLength(MxU32 p_length) { m_length = p_length; }
inline void SetData(MxU8* p_data) { m_data = p_data; }
inline MxU16 GetFlags() { return m_flags; }
inline MxLong GetTime() { return m_time; }
inline MxU32 GetLength() { return m_length; }
inline MxU8* GetData() { return m_data; }
inline void Release()
{
if (m_data)
delete[] m_data;
}
private:
MxS16 m_length; // 0x8
MxLong m_buffer; // 0xc
MxLong m_unk10; // 0x10
MxLong m_unk14; // 0x14
void* m_unk18; // 0x18
void* m_unk1c; // 0x1c
MxU16 m_flags; // 0x8
undefined4 m_unk0c; // 0xc
MxLong m_time; // 0x10
MxU32 m_length; // 0x14
MxU8* m_data; // 0x18
};
#endif // MXDSCHUNK_H

View File

@ -30,7 +30,7 @@ void MxDSSelectAction::CopyFrom(MxDSSelectAction& p_dsSelectAction)
MxStringListCursor cursor(p_dsSelectAction.m_unk0xac);
MxString string;
while (cursor.Next(string))
this->m_unk0xac->OtherAppend(string);
this->m_unk0xac->Append(string);
}
// OFFSET: LEGO1 0x100cbd50
@ -109,7 +109,7 @@ void MxDSSelectAction::Deserialize(char** p_source, MxS16 p_unk24)
if (!strcmp(string.GetData(), *p_source))
index = i;
this->m_unk0xac->OtherAppend(*p_source);
this->m_unk0xac->Append(*p_source);
*p_source += strlen(*p_source) + 1;
}

View File

@ -30,6 +30,8 @@ class MxDSSound : public MxDSMediaAction {
virtual void Deserialize(char** p_source, MxS16 p_unk24) override; // vtable+1c;
virtual MxDSAction* Clone() override; // vtable+2c;
inline MxS32 GetVolume() const { return m_volume; }
private:
MxU32 m_sizeOnDisk;
MxS32 m_volume; // 0xbc

View File

@ -5,7 +5,7 @@
// OFFSET: LEGO1 0x100bffd0
void MxDSSource::ReadToBuffer(MxDSBuffer* p_buffer)
{
Read((unsigned char*) p_buffer->GetBuffer(), p_buffer->GetWriteOffset());
Read(p_buffer->GetBuffer(), p_buffer->GetWriteOffset());
}
// OFFSET: LEGO1 0x100bfff0

View File

@ -1,13 +1,42 @@
#include "mxdssubscriber.h"
// OFFSET: LEGO1 0x100b7bb0
DECOMP_SIZE_ASSERT(MxDSSubscriber, 0x4c);
// OFFSET: LEGO1 0x100b7bb0 STUB
MxDSSubscriber::MxDSSubscriber()
{
// TODO
}
// OFFSET: LEGO1 0x100b7e00
// OFFSET: LEGO1 0x100b7e00 STUB
MxDSSubscriber::~MxDSSubscriber()
{
// TODO
}
// OFFSET: LEGO1 0x100b7ed0 STUB
MxResult MxDSSubscriber::FUN_100b7ed0(MxStreamController*, MxU32, MxS16)
{
// TODO
return SUCCESS;
}
// OFFSET: LEGO1 0x100b8250 STUB
MxStreamChunk* MxDSSubscriber::FUN_100b8250()
{
// TODO
return NULL;
}
// OFFSET: LEGO1 0x100b8360 STUB
MxStreamChunk* MxDSSubscriber::FUN_100b8360()
{
// TODO
return NULL;
}
// OFFSET: LEGO1 0x100b8390 STUB
void MxDSSubscriber::FUN_100b8390(MxStreamChunk*)
{
// TODO
}

View File

@ -1,7 +1,11 @@
#ifndef MXDSSUBSCRIBER_H
#define MXDSSUBSCRIBER_H
#include "decomp.h"
#include "mxcore.h"
#include "mxdschunk.h"
#include "mxstreamchunk.h"
#include "mxstreamcontroller.h"
// VTABLE 0x100dc698
// SIZE 0x4c
@ -22,6 +26,14 @@ class MxDSSubscriber : public MxCore {
{
return !strcmp(name, MxDSSubscriber::ClassName()) || MxCore::IsA(name);
}
MxResult FUN_100b7ed0(MxStreamController*, MxU32, MxS16);
MxStreamChunk* FUN_100b8250();
MxStreamChunk* FUN_100b8360();
void FUN_100b8390(MxStreamChunk*);
private:
undefined m_pad[0x44]; // 0x8
};
#endif // MXDSSUBSCRIBER_H

View File

@ -24,11 +24,22 @@ void MxEventPresenter::Init()
m_unk50 = NULL;
}
// OFFSET: LEGO1 0x100c2db0
MxResult MxEventPresenter::AddToManager()
{
MxResult ret = FAILURE;
if (EventManager()) {
ret = SUCCESS;
EventManager()->AddPresenter(*this);
}
return ret;
}
// OFFSET: LEGO1 0x100c2de0
void MxEventPresenter::Destroy()
{
MxEventManager* eventManager = EventManager();
if (eventManager)
if (EventManager())
EventManager()->RemovePresenter(*this);
m_criticalSection.Enter();

View File

@ -24,7 +24,8 @@ class MxEventPresenter : public MxMediaPresenter {
return !strcmp(name, MxEventPresenter::ClassName()) || MxMediaPresenter::IsA(name);
}
virtual void Destroy() override; // vtable+0x38
virtual MxResult AddToManager() override; // vtable+0x34
virtual void Destroy() override; // vtable+0x38
private:
void Init();

View File

@ -1,13 +1,11 @@
#ifndef MXHASHTABLE_H
#define MXHASHTABLE_H
#include "mxcollection.h"
#include "mxcore.h"
#include "mxtypes.h"
#define HASH_TABLE_INIT_SIZE 128
#define HASH_TABLE_OPT_NO_EXPAND 0
#define HASH_TABLE_OPT_EXPAND_ADD 1
#define HASH_TABLE_OPT_EXPAND_MULTIPLY 2
template <class T>
class MxHashTableCursor;
@ -15,8 +13,7 @@ class MxHashTableCursor;
template <class T>
class MxHashTableNode {
public:
MxHashTableNode<T>() {}
MxHashTableNode<T>(T* p_obj, MxU32 p_hash)
MxHashTableNode<T>(T p_obj, MxU32 p_hash)
{
m_obj = p_obj;
m_hash = p_hash;
@ -24,55 +21,39 @@ class MxHashTableNode {
m_next = NULL;
}
// private:
T* m_obj;
// DECOMP: Should use getter and setter methods here per the style guide.
// However, LEGO1D (with no functions inlined) does not use them.
T m_obj;
MxU32 m_hash;
MxHashTableNode* m_prev;
MxHashTableNode* m_next;
};
// See MxOmni::Create
// VTABLE 0x100dc1b0
template <class T>
class HashTableParent : public MxCore {
class MxHashTable : protected MxCollection<T> {
public:
HashTableParent()
{
m_numKeys = 0;
m_customDestructor = Destroy;
}
enum HashTableOpt {
HashTableOpt_NoExpand = 0,
HashTableOpt_ExpandAdd = 1,
HashTableOpt_ExpandMultiply = 2,
};
static void Destroy(T*){};
virtual MxS8 Compare(T*, T*) = 0;
protected:
MxU32 m_numKeys; // +0x8
void (*m_customDestructor)(T*); // +0xc
};
// VTABLE 0x100dc1e8
template <class T>
class MxHashTable : protected HashTableParent<T> {
public:
MxHashTable()
{
m_numSlots = HASH_TABLE_INIT_SIZE;
m_slots = new MxHashTableNode<T>*[HASH_TABLE_INIT_SIZE];
memset(m_slots, 0, sizeof(MxHashTableNode<T>*) * m_numSlots);
m_resizeOption = HASH_TABLE_OPT_NO_EXPAND;
m_resizeOption = HashTableOpt_NoExpand;
}
virtual ~MxHashTable();
virtual ~MxHashTable() override;
void Resize();
void Add(T*);
void Add(T);
void DeleteAll();
virtual MxS8 Compare(T*, T*) = 0;
virtual MxU32 Hash(T) { return 0; }
virtual MxU32 Hash(T*) = 0;
// FIXME: use of friend here?
friend class MxHashTableCursor<T>;
protected:
@ -80,91 +61,108 @@ class MxHashTable : protected HashTableParent<T> {
MxHashTableNode<T>** m_slots; // +0x10
MxU32 m_numSlots; // +0x14
MxU32 m_autoResizeRatio;
int m_resizeOption; // +0x1c
MxU32 m_autoResizeRatio; // +0x18
HashTableOpt m_resizeOption; // +0x1c
// FIXME: or FIXME? This qword is used as an integer or double depending
// on the value of m_resizeOption. Hard to say whether this is how the devs
// did it, but a simple cast in either direction doesn't match.
union {
MxU32 m_increaseAmount;
double m_increaseFactor;
MxU32 m_increaseAmount; // +0x20
double m_increaseFactor; // +0x20
};
};
template <class T>
class MxHashTableCursor : public MxCore {
public:
MxHashTableCursor(MxHashTable<T>* p_hashTable)
MxHashTableCursor(MxHashTable<T>* p_table)
{
m_table = p_hashTable;
m_table = p_table;
m_match = NULL;
}
MxBool Find(T* p_obj)
{
MxU32 hash = m_table->Hash(p_obj);
int bucket = hash % m_table->m_numSlots;
MxHashTableNode<T>* t = m_table->m_slots[bucket];
while (t) {
if (t->m_hash == hash && !m_table->Compare(t->m_obj, p_obj))
m_match = t;
t = t->m_next;
}
return m_match != NULL;
}
void GetMatch(T*& p_obj)
{
if (m_match) {
p_obj = m_match->m_obj;
}
}
void DeleteMatch()
{
// Cut the matching node out of the linked list
// by updating pointer references.
if (m_match->m_prev) {
m_match->m_prev->m_next = m_match->m_next;
}
else {
// No "prev" node, so move "next" to the head of the list.
int bucket = m_match->m_hash % m_table->m_numSlots;
m_table->m_slots[bucket] = m_match->m_next;
}
if (m_match->m_next)
m_match->m_next->m_prev = m_match->m_prev;
m_table->m_customDestructor(m_match->m_obj);
delete m_match;
m_table->m_numKeys--;
}
MxBool Find(T p_obj);
MxBool Current(T& p_obj);
void DeleteMatch();
private:
MxHashTable<T>* m_table;
MxHashTableNode<T>* m_match;
};
template <class T>
MxBool MxHashTableCursor<T>::Find(T p_obj)
{
MxU32 hash = m_table->Hash(p_obj);
MxS32 bucket = hash % m_table->m_numSlots;
MxHashTableNode<T>* t = m_table->m_slots[bucket];
while (t) {
if (t->m_hash == hash && !m_table->Compare(t->m_obj, p_obj))
m_match = t;
t = t->m_next;
}
return m_match != NULL;
}
template <class T>
MxBool MxHashTableCursor<T>::Current(T& p_obj)
{
if (m_match) {
p_obj = m_match->m_obj;
}
return m_match != NULL;
}
template <class T>
void MxHashTableCursor<T>::DeleteMatch()
{
// Cut the matching node out of the linked list
// by updating pointer references.
if (m_match == NULL)
return;
if (m_match->m_prev) {
m_match->m_prev->m_next = m_match->m_next;
}
else {
// No "prev" node, so move "next" to the head of the list.
MxS32 bucket = m_match->m_hash % m_table->m_numSlots;
m_table->m_slots[bucket] = m_match->m_next;
}
if (m_match->m_next)
m_match->m_next->m_prev = m_match->m_prev;
m_table->m_customDestructor(m_match->m_obj);
delete m_match;
m_table->m_count--;
}
template <class T>
MxHashTable<T>::~MxHashTable()
{
for (int i = 0; i < m_numSlots; i++) {
DeleteAll();
}
template <class T>
void MxHashTable<T>::DeleteAll()
{
for (MxS32 i = 0; i < m_numSlots; i++) {
MxHashTableNode<T>* t = m_slots[i];
while (t) {
MxHashTableNode<T>* next = t->m_next;
this->m_customDestructor(t->m_obj);
m_customDestructor(t->m_obj);
delete t;
t = next;
}
}
this->m_numKeys = 0;
m_count = 0;
memset(m_slots, 0, sizeof(MxHashTableNode<T>*) * m_numSlots);
delete[] m_slots;
@ -179,21 +177,20 @@ inline void MxHashTable<T>::Resize()
MxHashTableNode<T>** old_table = m_slots;
switch (m_resizeOption) {
case HASH_TABLE_OPT_EXPAND_ADD:
case HashTableOpt_ExpandAdd:
m_numSlots += m_increaseAmount;
break;
case HASH_TABLE_OPT_EXPAND_MULTIPLY:
case HashTableOpt_ExpandMultiply:
m_numSlots *= m_increaseFactor;
break;
}
MxHashTableNode<T>** new_table = new MxHashTableNode<T>*[m_numSlots];
// FIXME: order? m_numKeys set after `rep stosd`
m_slots = new_table;
memset(m_slots, 0, sizeof(MxHashTableNode<T>*) * m_numSlots);
this->m_numKeys = 0;
m_count = 0;
for (int i = 0; i != old_size; i++) {
for (MxS32 i = 0; i != old_size; i++) {
MxHashTableNode<T>* t = old_table[i];
while (t) {
@ -209,7 +206,7 @@ inline void MxHashTable<T>::Resize()
template <class T>
inline void MxHashTable<T>::_NodeInsert(MxHashTableNode<T>* p_node)
{
int bucket = p_node->m_hash % m_numSlots;
MxS32 bucket = p_node->m_hash % m_numSlots;
p_node->m_next = m_slots[bucket];
@ -217,13 +214,13 @@ inline void MxHashTable<T>::_NodeInsert(MxHashTableNode<T>* p_node)
m_slots[bucket]->m_prev = p_node;
m_slots[bucket] = p_node;
this->m_numKeys++;
m_count++;
}
template <class T>
inline void MxHashTable<T>::Add(T* p_newobj)
inline void MxHashTable<T>::Add(T p_newobj)
{
if (m_resizeOption && ((this->m_numKeys + 1) / m_numSlots) > m_autoResizeRatio)
if (m_resizeOption && ((m_count + 1) / m_numSlots) > m_autoResizeRatio)
MxHashTable<T>::Resize();
MxU32 hash = Hash(p_newobj);
@ -232,4 +229,6 @@ inline void MxHashTable<T>::Add(T* p_newobj)
MxHashTable<T>::_NodeInsert(node);
}
#undef HASH_TABLE_INIT_SIZE
#endif // MXHASHTABLE_H

View File

@ -27,9 +27,12 @@ class MxListEntry {
}
T GetValue() { return this->m_obj; }
MxListEntry* GetNext() { return m_next; }
MxListEntry* GetPrev() { return m_prev; }
friend class MxList<T>;
friend class MxListCursor<T>;
void SetValue(T p_obj) { m_obj = p_obj; }
void SetNext(MxListEntry* p_next) { m_next = p_next; }
void SetPrev(MxListEntry* p_prev) { m_prev = p_prev; }
private:
T m_obj;
@ -67,10 +70,9 @@ class MxList : protected MxListParent<T> {
m_first = NULL;
}
virtual ~MxList();
virtual ~MxList() override;
void Append(T);
void OtherAppend(T p_obj) { _InsertEntry(p_obj, this->m_last, NULL); };
void Append(T p_obj) { _InsertEntry(p_obj, this->m_last, NULL); };
void DeleteAll();
MxU32 GetCount() { return this->m_count; }
void SetDestroy(void (*p_customDestructor)(T)) { this->m_customDestructor = p_customDestructor; }
@ -81,7 +83,6 @@ class MxList : protected MxListParent<T> {
MxListEntry<T>* m_first; // +0x10
MxListEntry<T>* m_last; // +0x14
private:
void _DeleteEntry(MxListEntry<T>* match);
MxListEntry<T>* _InsertEntry(T, MxListEntry<T>*, MxListEntry<T>*);
};
@ -97,10 +98,15 @@ class MxListCursor : public MxCore {
MxBool Find(T p_obj);
void Detach();
void Destroy();
MxBool Next(T& p_obj);
MxBool Current(T& p_obj);
MxBool Advance();
MxBool HasMatch() { return m_match != NULL; }
void SetValue(T p_obj);
void Head() { m_match = m_list->m_first; }
void Reset() { m_match = NULL; }
void Prepend(T p_newobj);
private:
MxList<T>* m_list;
@ -134,7 +140,7 @@ inline void MxList<T>::DeleteAll()
if (!t)
break;
MxListEntry<T>* next = t->m_next;
MxListEntry<T>* next = t->GetNext();
this->m_customDestructor(t->GetValue());
delete t;
t = next;
@ -145,33 +151,18 @@ inline void MxList<T>::DeleteAll()
m_first = NULL;
}
template <class T>
inline void MxList<T>::Append(T p_newobj)
{
MxListEntry<T>* currentLast = this->m_last;
MxListEntry<T>* newEntry = new MxListEntry<T>(p_newobj, currentLast);
if (currentLast)
currentLast->m_next = newEntry;
else
this->m_first = newEntry;
this->m_last = newEntry;
this->m_count++;
}
template <class T>
inline MxListEntry<T>* MxList<T>::_InsertEntry(T p_newobj, MxListEntry<T>* p_prev, MxListEntry<T>* p_next)
{
MxListEntry<T>* newEntry = new MxListEntry<T>(p_newobj, p_prev, p_next);
if (p_prev)
p_prev->m_next = newEntry;
p_prev->SetNext(newEntry);
else
this->m_first = newEntry;
if (p_next)
p_next->m_prev = newEntry;
p_next->SetPrev(newEntry);
else
this->m_last = newEntry;
@ -182,18 +173,15 @@ inline MxListEntry<T>* MxList<T>::_InsertEntry(T p_newobj, MxListEntry<T>* p_pre
template <class T>
inline void MxList<T>::_DeleteEntry(MxListEntry<T>* match)
{
MxListEntry<T>** pPrev = &match->m_prev;
MxListEntry<T>** pNext = &match->m_next;
if (match->m_prev)
match->m_prev->m_next = *pNext;
if (match->GetPrev())
match->GetPrev()->SetNext(match->GetNext());
else
m_first = *pNext;
m_first = match->GetNext();
if (*pNext)
(*pNext)->m_prev = *pPrev;
if (match->GetNext())
match->GetNext()->SetPrev(match->GetPrev());
else
m_last = *pPrev;
m_last = match->GetPrev();
delete match;
this->m_count--;
@ -202,7 +190,8 @@ inline void MxList<T>::_DeleteEntry(MxListEntry<T>* match)
template <class T>
inline MxBool MxListCursor<T>::Find(T p_obj)
{
for (m_match = m_list->m_first; m_match && m_list->Compare(m_match->m_obj, p_obj); m_match = m_match->m_next)
for (m_match = m_list->m_first; m_match && m_list->Compare(m_match->GetValue(), p_obj);
m_match = m_match->GetNext())
;
return m_match != NULL;
@ -215,13 +204,22 @@ inline void MxListCursor<T>::Detach()
m_match = NULL;
}
template <class T>
inline void MxListCursor<T>::Destroy()
{
if (m_match) {
m_list->m_customDestructor(m_match->GetValue());
Detach();
}
}
template <class T>
inline MxBool MxListCursor<T>::Next(T& p_obj)
{
if (!m_match)
m_match = m_list->m_first;
else
m_match = m_match->m_next;
m_match = m_match->GetNext();
if (m_match)
p_obj = m_match->GetValue();
@ -229,11 +227,38 @@ inline MxBool MxListCursor<T>::Next(T& p_obj)
return m_match != NULL;
}
template <class T>
inline MxBool MxListCursor<T>::Current(T& p_obj)
{
if (m_match)
p_obj = m_match->GetValue();
return m_match != NULL;
}
template <class T>
inline MxBool MxListCursor<T>::Advance()
{
if (!m_match)
m_match = m_list->m_first;
else
m_match = m_match->GetNext();
return m_match != NULL;
}
template <class T>
inline void MxListCursor<T>::SetValue(T p_obj)
{
if (m_match)
m_match->m_obj = p_obj;
m_match->SetValue(p_obj);
}
template <class T>
inline void MxListCursor<T>::Prepend(T p_newobj)
{
if (m_match)
m_list->_InsertEntry(p_newobj, m_match->GetPrev(), m_match);
}
#endif // MXLIST_H

View File

@ -1,5 +1,12 @@
#include "mxmediapresenter.h"
#include "mxactionnotificationparam.h"
#include "mxautolocker.h"
#include "mxcompositepresenter.h"
#include "mxnotificationmanager.h"
#include "mxstreamchunk.h"
#include "mxtimer.h"
DECOMP_SIZE_ASSERT(MxMediaPresenter, 0x50);
// OFFSET: LEGO1 0x1000c550
@ -8,38 +15,151 @@ MxMediaPresenter::~MxMediaPresenter()
Destroy(TRUE);
}
// OFFSET: LEGO1 0x100b5d10 STUB
MxResult MxMediaPresenter::Tickle()
// OFFSET: LEGO1 0x1000c5b0
void MxMediaPresenter::Destroy()
{
// TODO
return SUCCESS;
Destroy(FALSE);
}
// OFFSET: LEGO1 0x100b54e0
void MxMediaPresenter::Init()
{
this->m_unk40 = NULL;
this->m_unk44 = NULL;
this->m_unk48 = NULL;
this->m_unk4c = NULL;
this->m_subscriber = NULL;
this->m_chunks = NULL;
this->m_cursor = NULL;
this->m_currentChunk = NULL;
}
// OFFSET: LEGO1 0x100b54f0 STUB
// OFFSET: LEGO1 0x100b54f0
void MxMediaPresenter::Destroy(MxBool p_fromDestructor)
{
// TODO
{
MxAutoLocker lock(&m_criticalSection);
if (m_currentChunk && m_subscriber)
m_subscriber->FUN_100b8390(m_currentChunk);
if (m_subscriber)
delete m_subscriber;
if (m_cursor)
delete m_cursor;
if (m_chunks) {
MxStreamChunkListCursor cursor(m_chunks);
MxStreamChunk* chunk;
while (cursor.Next(chunk))
chunk->Release();
delete m_chunks;
}
Init();
}
if (!p_fromDestructor)
MxPresenter::Destroy();
}
// OFFSET: LEGO1 0x100b5d90 STUB
// OFFSET: LEGO1 0x100b5650
MxStreamChunk* MxMediaPresenter::FUN_100b5650()
{
MxStreamChunk* result = NULL;
if (m_subscriber) {
result = m_subscriber->FUN_100b8360();
if (result && result->GetFlags() & MxDSChunk::Flag_Bit3) {
m_action->SetFlags(m_action->GetFlags() | MxDSAction::Flag_Bit7);
m_subscriber->FUN_100b8250();
m_subscriber->FUN_100b8390(result);
result = NULL;
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
m_currentTickleState = TickleState_Done;
}
}
return result;
}
// OFFSET: LEGO1 0x100b56b0
MxStreamChunk* MxMediaPresenter::NextChunk()
{
MxStreamChunk* result = NULL;
if (m_subscriber) {
result = m_subscriber->FUN_100b8250();
if (result && result->GetFlags() & MxDSChunk::Flag_Bit3) {
m_action->SetFlags(m_action->GetFlags() | MxDSAction::Flag_Bit7);
m_subscriber->FUN_100b8390(result);
result = NULL;
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
m_currentTickleState = TickleState_Done;
}
}
return result;
}
// OFFSET: LEGO1 0x100b5d10
MxResult MxMediaPresenter::Tickle()
{
MxAutoLocker lock(&m_criticalSection);
FUN_100b5650();
return MxPresenter::Tickle();
}
// OFFSET: LEGO1 0x100b5d90
void MxMediaPresenter::StreamingTickle()
{
// TODO
if (!m_currentChunk) {
m_currentChunk = NextChunk();
if (m_currentChunk) {
if (m_currentChunk->GetFlags() & MxDSChunk::Flag_Bit2) {
m_subscriber->FUN_100b8390(m_currentChunk);
m_currentChunk = NULL;
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
m_currentTickleState = TickleState_Repeating;
}
else if (m_action->GetFlags() & MxDSAction::Flag_Looping) {
AppendChunk(m_currentChunk);
if (!MxPresenter::IsEnabled()) {
m_subscriber->FUN_100b8390(m_currentChunk);
m_currentChunk = NULL;
}
}
}
}
}
// OFFSET: LEGO1 0x100b5e10 STUB
// OFFSET: LEGO1 0x100b5e10
void MxMediaPresenter::RepeatingTickle()
{
// TODO
if (MxPresenter::IsEnabled() && !m_currentChunk) {
if (m_cursor)
if (!m_cursor->Next(m_currentChunk))
m_cursor->Next(m_currentChunk);
if (m_currentChunk) {
MxLong time = m_currentChunk->GetTime();
if (time <= m_action->GetElapsedTime() % m_action->GetLoopCount()) {
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
m_currentTickleState = TickleState_unk5;
}
}
else {
if (m_action->GetElapsedTime() <= m_action->GetStartTime() + m_action->GetDuration()) {
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
m_currentTickleState = TickleState_unk5;
}
}
}
}
// OFFSET: LEGO1 0x100b5ef0
@ -50,32 +170,99 @@ void MxMediaPresenter::DoneTickle()
EndAction();
}
// OFFSET: LEGO1 0x100b6030 STUB
// OFFSET: LEGO1 0x100b6030
void MxMediaPresenter::Enable(MxBool p_enable)
{
// TODO
if (MxPresenter::IsEnabled() != p_enable) {
MxPresenter::Enable(p_enable);
if (p_enable) {
MxLong time = Timer()->GetTime();
m_action->SetUnkTimingField(time);
SetTickleState(TickleState_Repeating);
}
else {
if (m_cursor)
m_cursor->Reset();
m_currentChunk = NULL;
SetTickleState(TickleState_Done);
}
}
}
// OFFSET: LEGO1 0x1000c5b0
void MxMediaPresenter::Destroy()
// OFFSET: LEGO1 0x100b5700
MxResult MxMediaPresenter::StartAction(MxStreamController* p_controller, MxDSAction* p_action)
{
Destroy(FALSE);
MxResult result = FAILURE;
MxAutoLocker lock(&m_criticalSection);
if (MxPresenter::StartAction(p_controller, p_action) == SUCCESS) {
if (m_action->GetFlags() & MxDSAction::Flag_Looping) {
m_chunks = new MxStreamChunkList;
m_cursor = new MxStreamChunkListCursor(m_chunks);
if (!m_chunks && !m_cursor)
goto done;
}
if (p_controller) {
m_subscriber = new MxDSSubscriber;
if (!m_subscriber ||
m_subscriber->FUN_100b7ed0(p_controller, p_action->GetObjectId(), p_action->GetUnknown24()) != SUCCESS)
goto done;
}
result = SUCCESS;
}
done:
return result;
}
// OFFSET: LEGO1 0x100b5700 STUB
MxLong MxMediaPresenter::StartAction(MxStreamController* p_controller, MxDSAction* p_action)
{
return 0;
}
// OFFSET: LEGO1 0x100b5bc0 STUB
// OFFSET: LEGO1 0x100b5bc0
void MxMediaPresenter::EndAction()
{
// TODO
MxAutoLocker lock(&m_criticalSection);
if (!m_action)
return;
m_currentChunk = NULL;
if (m_action->GetFlags() & MxDSAction::Flag_World &&
(!m_compositePresenter || !m_compositePresenter->VTable0x64(2))) {
MxPresenter::Enable(FALSE);
SetTickleState(TickleState_Idle);
}
else {
MxDSAction* action = m_action;
MxPresenter::EndAction();
if (m_subscriber) {
delete m_subscriber;
m_subscriber = NULL;
}
if (action && action->GetUnknown8c()) {
NotificationManager()->Send(
action->GetUnknown8c(),
&MxEndActionNotificationParam(c_notificationEndAction, this, action, FALSE)
);
}
}
}
// OFFSET: LEGO1 0x100b5f10 STUB
void MxMediaPresenter::VTable0x58()
// OFFSET: LEGO1 0x100b5f10
void MxMediaPresenter::AppendChunk(MxStreamChunk* p_chunk)
{
// TODO
MxStreamChunk* chunk = new MxStreamChunk;
MxU32 length = p_chunk->GetLength();
chunk->SetLength(length);
chunk->SetData(new MxU8[length]);
chunk->SetTime(p_chunk->GetTime());
memcpy(chunk->GetData(), p_chunk->GetData(), chunk->GetLength());
m_chunks->Append(chunk);
}

View File

@ -2,15 +2,18 @@
#define MXMEDIAPRESENTER_H
#include "decomp.h"
#include "mxdssubscriber.h"
#include "mxpresenter.h"
#include "mxstreamchunklist.h"
// VTABLE 0x100d4cd8
// SIZE 0x50
class MxMediaPresenter : public MxPresenter {
public:
inline MxMediaPresenter() { Init(); }
virtual ~MxMediaPresenter() override;
virtual MxResult Tickle() override;
virtual MxResult Tickle() override; // vtable+0x8
// OFFSET: LEGO1 0x1000c5c0
inline virtual const char* ClassName() const override // vtable+0xc
@ -25,23 +28,25 @@ class MxMediaPresenter : public MxPresenter {
return !strcmp(name, MxMediaPresenter::ClassName()) || MxPresenter::IsA(name);
}
virtual void StreamingTickle() override;
virtual void RepeatingTickle() override;
virtual void DoneTickle() override;
virtual void Destroy() override;
virtual MxLong StartAction(MxStreamController*, MxDSAction*) override;
virtual void EndAction() override;
virtual void Enable(MxBool p_enable) override;
virtual void VTable0x58();
undefined4 m_unk40;
undefined4 m_unk44;
undefined4 m_unk48;
undefined4 m_unk4c;
virtual void StreamingTickle() override; // vtable+0x20
virtual void RepeatingTickle() override; // vtable+0x24
virtual void DoneTickle() override; // vtable+0x2c
virtual void Destroy() override; // vtable+0x38
virtual MxResult StartAction(MxStreamController*, MxDSAction*) override; // vtable+0x3c
virtual void EndAction() override; // vtable+0x40
virtual void Enable(MxBool p_enable) override; // vtable+0x54
virtual void AppendChunk(MxStreamChunk* p_chunk); // vtable+0x58
protected:
MxDSSubscriber* m_subscriber; // 0x40
MxStreamChunkList* m_chunks; // 0x44
MxStreamChunkListCursor* m_cursor; // 0x48
MxStreamChunk* m_currentChunk; // 0x4c
void Init();
void Destroy(MxBool p_fromDestructor);
MxStreamChunk* FUN_100b5650();
MxStreamChunk* NextChunk();
};
#endif // MXMEDIAPRESENTER_H

View File

@ -4,6 +4,34 @@
#include "mxcore.h"
// VTABLE 0x100dc9a0
class MxNextActionDataStart : public MxCore {};
// SIZE 0x14
class MxNextActionDataStart : public MxCore {
public:
// inlined constructor at 0x100c1847
inline MxNextActionDataStart(MxU32 p_objectId, MxS16 p_unk24val, MxU32 p_data)
{
m_objectId = p_objectId;
m_unk24val = p_unk24val;
m_data = p_data;
}
// OFFSET: LEGO1 0x100c1900
inline virtual const char* ClassName() const override // vtable+0xc
{
// 0x101025a0
return "MxNextActionDataStart";
}
// OFFSET: LEGO1 0x100c1910
inline virtual MxBool IsA(const char* name) const override // vtable+0x10
{
return !strcmp(name, MxNextActionDataStart::ClassName()) || MxCore::IsA(name);
}
private:
MxU32 m_objectId;
MxS16 m_unk24val;
MxU32 m_data;
};
#endif // MXNEXTACTIONDATASTART_H

View File

@ -7,11 +7,11 @@
class MxCore;
enum MxParamType {
enum NotificationId {
PARAM_NONE = 0,
PAINT = 1, // 100dc210:100d8350
c_notificationEndAction = 2, // 100d8358:100d8350
TYPE4 = 4, // 100dc208:100d8350
c_notificationStartAction = 1, // 100dc210:100d8350
c_notificationEndAction = 2, // 100d8358:100d8350
TYPE4 = 4, // 100dc208:100d8350
MXPRESENTER_NOTIFICATION = 5,
MXSTREAMER_DELETE_NOTIFY = 6, // 100dc760
c_notificationKeyPress = 7, // 100d6aa0
@ -36,17 +36,20 @@ enum MxParamType {
// VTABLE 0x100d56e0
class MxNotificationParam : public MxParam {
public:
inline MxNotificationParam(MxParamType p_type, MxCore* p_sender) : MxParam(), m_type(p_type), m_sender(p_sender) {}
inline MxNotificationParam(NotificationId p_type, MxCore* p_sender) : MxParam(), m_type(p_type), m_sender(p_sender)
{
}
virtual ~MxNotificationParam() override {} // vtable+0x0 (scalar deleting destructor)
virtual MxNotificationParam* Clone(); // vtable+0x4
inline MxParamType GetNotification() const { return m_type; }
inline NotificationId GetNotification() const { return m_type; }
inline MxCore* GetSender() const { return m_sender; }
inline NotificationId GetType() const { return m_type; }
protected:
MxParamType m_type; // 0x4
MxCore* m_sender; // 0x8
NotificationId m_type; // 0x4
MxCore* m_sender; // 0x8
};
#endif // MXNOTIFICATIONPARAM_H

View File

@ -91,11 +91,10 @@ void MxOmni::Vtable0x2c()
// TODO
}
// OFFSET: LEGO1 0x100aefb0 STUB
int MxOmni::Vtable0x30(char*, int, MxCore*)
// OFFSET: LEGO1 0x100aefb0
MxEntity* MxOmni::FindWorld(const char*, MxS32, MxPresenter*)
{
// TODO
return 0;
return NULL;
}
// OFFSET: LEGO1 0x100aefc0

View File

@ -14,12 +14,14 @@ class MxNotificationManager;
class MxNotificationParam;
class MxObjectFactory;
class MxOmniCreateParam;
class MxPresenter;
class MxSoundManager;
class MxStreamer;
class MxTickleManager;
class MxTimer;
class MxVariableTable;
class MxVideoManager;
class MxEntity;
// VTABLE 0x100dc168
// SIZE 0x68
@ -45,7 +47,7 @@ class MxOmni : public MxCore {
virtual MxResult DeleteObject(MxDSAction& p_dsAction); // vtable+24
virtual MxBool DoesEntityExist(MxDSAction& p_dsAction); // vtable+28
virtual void Vtable0x2c(); // vtable+2c
virtual int Vtable0x30(char*, int, MxCore*); // vtable+30
virtual MxEntity* FindWorld(const char*, MxS32, MxPresenter*); // vtable+30
virtual void NotifyCurrentEntity(MxNotificationParam* p_param); // vtable+34
virtual void StartTimer(); // vtable+38
virtual void StopTimer(); // vtable+3c

View File

@ -23,17 +23,17 @@ class MxOmniCreateFlags {
__declspec(dllexport) MxOmniCreateFlags();
const inline MxBool CreateObjectFactory() const { return this->m_flags1 & Flag_CreateObjectFactory; }
const inline MxBool CreateVariableTable() const { return this->m_flags1 & Flag_CreateVariableTable; }
const inline MxBool CreateTickleManager() const { return this->m_flags1 & Flag_CreateTickleManager; }
const inline MxBool CreateNotificationManager() const { return this->m_flags1 & Flag_CreateNotificationManager; }
const inline MxBool CreateVideoManager() const { return this->m_flags1 & Flag_CreateVideoManager; }
const inline MxBool CreateSoundManager() const { return this->m_flags1 & Flag_CreateSoundManager; }
const inline MxBool CreateMusicManager() const { return this->m_flags1 & Flag_CreateMusicManager; }
const inline MxBool CreateEventManager() const { return this->m_flags1 & Flag_CreateEventManager; }
inline const MxBool CreateObjectFactory() const { return this->m_flags1 & Flag_CreateObjectFactory; }
inline const MxBool CreateVariableTable() const { return this->m_flags1 & Flag_CreateVariableTable; }
inline const MxBool CreateTickleManager() const { return this->m_flags1 & Flag_CreateTickleManager; }
inline const MxBool CreateNotificationManager() const { return this->m_flags1 & Flag_CreateNotificationManager; }
inline const MxBool CreateVideoManager() const { return this->m_flags1 & Flag_CreateVideoManager; }
inline const MxBool CreateSoundManager() const { return this->m_flags1 & Flag_CreateSoundManager; }
inline const MxBool CreateMusicManager() const { return this->m_flags1 & Flag_CreateMusicManager; }
inline const MxBool CreateEventManager() const { return this->m_flags1 & Flag_CreateEventManager; }
const inline MxBool CreateTimer() const { return this->m_flags2 & Flag_CreateTimer; }
const inline MxBool CreateStreamer() const { return this->m_flags2 & Flag_CreateStreamer; }
inline const MxBool CreateTimer() const { return this->m_flags2 & Flag_CreateTimer; }
inline const MxBool CreateStreamer() const { return this->m_flags2 & Flag_CreateStreamer; }
inline void CreateObjectFactory(MxBool b)
{

View File

@ -17,7 +17,7 @@ class MxOmniCreateParam : public MxParam {
MxOmniCreateFlags flags
);
const MxOmniCreateFlags& CreateFlags() const { return this->m_createFlags; }
MxOmniCreateFlags& CreateFlags() { return this->m_createFlags; }
const MxString& GetMediaPath() const { return m_mediaPath; }
const HWND GetWindowHandle() const { return m_windowHandle; }
MxVideoParam& GetVideoParam() { return m_videoParam; }

View File

@ -5,6 +5,7 @@
#include "legoomni.h"
#include "mxactionnotificationparam.h"
#include "mxautolocker.h"
#include "mxcompositepresenter.h"
#include "mxdsanim.h"
#include "mxdssound.h"
#include "mxnotificationmanager.h"
@ -22,7 +23,7 @@ void MxPresenter::Init()
m_action = NULL;
m_location = MxPoint32(0, 0);
m_displayZ = 0;
m_unkPresenter = NULL;
m_compositePresenter = NULL;
m_previousTickleStates = 0;
}
@ -47,26 +48,26 @@ void MxPresenter::ParseExtra()
token = strtok(NULL, g_parseExtraTokens);
MxS32 val = token ? atoi(token) : 0;
MxS32 result = MxOmni::GetInstance()->Vtable0x30(t_token, val, this);
MxEntity* result = MxOmni::GetInstance()->FindWorld(t_token, val, this);
m_action->SetFlags(m_action->GetFlags() | MxDSAction::Flag_Parsed);
m_action->SetFlags(m_action->GetFlags() | MxDSAction::Flag_World);
if (result)
SendTo_unkPresenter(MxOmni::GetInstance());
SendToCompositePresenter(MxOmni::GetInstance());
}
}
}
// OFFSET: LEGO1 0x100b5120
void MxPresenter::SendTo_unkPresenter(MxOmni* p_omni)
void MxPresenter::SendToCompositePresenter(MxOmni* p_omni)
{
if (m_unkPresenter) {
if (m_compositePresenter) {
MxAutoLocker lock(&m_criticalSection);
NotificationManager()->Send(m_unkPresenter, &MxNotificationParam(MXPRESENTER_NOTIFICATION, this));
NotificationManager()->Send(m_compositePresenter, &MxNotificationParam(MXPRESENTER_NOTIFICATION, this));
m_action->SetOmni(p_omni ? p_omni : MxOmni::GetInstance());
m_unkPresenter = NULL;
m_action->SetUnknown8c(p_omni ? p_omni : MxOmni::GetInstance());
m_compositePresenter = NULL;
}
}
@ -116,7 +117,7 @@ MxResult MxPresenter::Tickle()
}
// OFFSET: LEGO1 0x100b4d80
MxLong MxPresenter::StartAction(MxStreamController*, MxDSAction* p_action)
MxResult MxPresenter::StartAction(MxStreamController*, MxDSAction* p_action)
{
MxAutoLocker lock(&this->m_criticalSection);
@ -138,8 +139,10 @@ void MxPresenter::EndAction()
{
if (this->m_action == FALSE)
return;
MxAutoLocker lock(&this->m_criticalSection);
if (!this->m_unkPresenter) {
if (!this->m_compositePresenter) {
MxOmni::GetInstance()->NotifyCurrentEntity(
&MxEndActionNotificationParam(c_notificationEndAction, NULL, this->m_action, TRUE)
);

View File

@ -8,9 +8,11 @@
#include "mxomni.h"
#include "mxpoint32.h"
class MxCompositePresenter;
class MxStreamController;
// VTABLE 0x100d4d38
// SIZE 0x40
class MxPresenter : public MxCore {
public:
enum TickleState {
@ -53,15 +55,15 @@ class MxPresenter : public MxCore {
__declspec(dllexport) virtual void ParseExtra(); // vtable+0x30
public:
virtual MxResult AddToManager(); // vtable+0x34
virtual void Destroy(); // vtable+0x38
__declspec(dllexport) virtual MxLong StartAction(MxStreamController*, MxDSAction*); // vtable+0x3c
__declspec(dllexport) virtual void EndAction(); // vtable+0x40
virtual void SetTickleState(TickleState p_tickleState); // vtable+0x44
virtual MxBool HasTickleStatePassed(TickleState p_tickleState); // vtable+0x48
virtual undefined4 PutData(); // vtable+0x4c
virtual MxBool IsHit(MxS32 p_x, MxS32 p_y); // vtable+0x50
__declspec(dllexport) virtual void Enable(MxBool p_enable); // vtable+0x54
virtual MxResult AddToManager(); // vtable+0x34
virtual void Destroy(); // vtable+0x38
__declspec(dllexport) virtual MxResult StartAction(MxStreamController*, MxDSAction*); // vtable+0x3c
__declspec(dllexport) virtual void EndAction(); // vtable+0x40
virtual void SetTickleState(TickleState p_tickleState); // vtable+0x44
virtual MxBool HasTickleStatePassed(TickleState p_tickleState); // vtable+0x48
virtual undefined4 PutData(); // vtable+0x4c
virtual MxBool IsHit(MxS32 p_x, MxS32 p_y); // vtable+0x50
__declspec(dllexport) virtual void Enable(MxBool p_enable); // vtable+0x54
MxBool IsEnabled();
@ -74,14 +76,15 @@ class MxPresenter : public MxCore {
protected:
__declspec(dllexport) void Init();
void SendTo_unkPresenter(MxOmni*);
TickleState m_currentTickleState; // 0x8
MxU32 m_previousTickleStates; // 0x0c
MxPoint32 m_location; // 0x10
MxS32 m_displayZ; // 0x18
MxDSAction* m_action; // 0x1c
MxCriticalSection m_criticalSection; // 0x20
MxPresenter* m_unkPresenter; // 0x3c
void SendToCompositePresenter(MxOmni*);
TickleState m_currentTickleState; // 0x8
MxU32 m_previousTickleStates; // 0x0c
MxPoint32 m_location; // 0x10
MxS32 m_displayZ; // 0x18
MxDSAction* m_action; // 0x1c
MxCriticalSection m_criticalSection; // 0x20
MxCompositePresenter* m_compositePresenter; // 0x3c
};
const char* PresenterNameDispatch(const MxDSAction&);

View File

@ -6,11 +6,7 @@ DECOMP_SIZE_ASSERT(MxPresenterList, 0x18);
DECOMP_SIZE_ASSERT(MxPresenterListCursor, 0x10);
// OFFSET: LEGO1 0x1001cd00
MxS8 MxPresenterList::Compare(MxPresenter* p_var0, MxPresenter* p_var1)
MxS8 MxPresenterList::Compare(MxPresenter* p_a, MxPresenter* p_b)
{
if (p_var1 == p_var0)
return 0;
if (p_var1 <= p_var0)
return 1;
return -1;
return p_a == p_b ? 0 : p_a < p_b ? -1 : 1;
}

View File

@ -17,7 +17,7 @@ class MxPresenterListParent : public MxList<MxPresenter*> {
// SIZE 0x18
class MxPresenterList : public MxPresenterListParent {
public:
virtual MxS8 Compare(MxPresenter*, MxPresenter*); // +0x14
virtual MxS8 Compare(MxPresenter*, MxPresenter*) override; // +0x14
};
typedef MxListCursorChildChild<MxPresenter*> MxPresenterListCursor;

26
LEGO1/mxqueue.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef MXQUEUE_H
#define MXQUEUE_H
#include "mxlist.h"
template <class T>
class MxQueue : public MxList<T> {
public:
void Enqueue(T& p_obj)
{
// TODO
}
MxBool Dequeue(T& p_obj)
{
MxBool has_next = (m_first != NULL);
if (m_first) {
p_obj = m_first->GetValue();
_DeleteEntry(m_first);
}
return has_next;
}
};
#endif // MXQUEUE_H

View File

@ -29,7 +29,7 @@ MxResult MxRAMStreamController::Open(const char* p_filename)
((MxRAMStreamProvider*) m_provider)->GetBufferOfFileSize(),
((MxRAMStreamProvider*) m_provider)->GetFileSize()
);
m_buffer.FUN_100c6780(
m_buffer.SetBufferPointer(
((MxRAMStreamProvider*) m_provider)->GetBufferOfFileSize(),
((MxRAMStreamProvider*) m_provider)->GetFileSize()
);

View File

@ -9,6 +9,19 @@ class MxRAMStreamProvider : public MxStreamProvider {
MxRAMStreamProvider();
virtual ~MxRAMStreamProvider() override;
// OFFSET: LEGO1 0x100d0970
inline virtual const char* ClassName() const override // vtable+0xc
{
// 0x10102864
return "MxRAMStreamProvider";
}
// OFFSET: LEGO1 0x100d0980
inline virtual MxBool IsA(const char* name) const override // vtable+0x10
{
return !strcmp(name, MxRAMStreamProvider::ClassName()) || MxStreamProvider::IsA(name);
}
virtual MxResult SetResourceToGet(MxStreamController* p_resource) override; // vtable+0x14
virtual MxU32 GetFileSize() override; // vtable+0x18
virtual MxU32 GetStreamBuffersNum() override; // vtable+0x1c

View File

@ -1,6 +1,9 @@
#ifndef MXRECT32_H
#define MXRECT32_H
#include "mxpoint32.h"
#include "mxsize32.h"
class MxRect32 {
public:
MxRect32() {}
@ -12,14 +15,72 @@ class MxRect32 {
this->m_bottom = p_bottom;
}
MxRect32(const MxPoint32& p_point, const MxSize32& p_size)
{
this->m_left = p_point.m_x;
this->m_top = p_point.m_y;
this->m_right = p_size.m_width;
this->m_bottom = p_size.m_height;
}
MxRect32(const MxRect32& p_a, const MxRect32& p_b)
{
m_left = Max(p_a.m_left, p_b.m_left);
m_top = Max(p_a.m_top, p_b.m_top);
m_right = Min(p_a.m_right, p_b.m_right);
m_bottom = Min(p_a.m_bottom, p_b.m_bottom);
}
inline void SetPoint(const MxPoint32& p_point)
{
this->m_left = p_point.m_x;
this->m_top = p_point.m_y;
}
inline void SetSize(const MxSize32& p_size)
{
this->m_right = p_size.m_width;
this->m_bottom = p_size.m_height;
}
inline MxBool IsValid() { return m_left < m_right && m_top < m_bottom; }
inline MxBool IntersectsWith(const MxRect32& p_rect)
{
return m_left < p_rect.m_right && p_rect.m_left < m_right && m_top < p_rect.m_bottom && p_rect.m_top < m_bottom;
}
inline void UpdateBounds(const MxRect32& p_rect)
{
m_left = Min(m_left, p_rect.m_left);
m_top = Min(m_top, p_rect.m_top);
m_right = Max(m_right, p_rect.m_right);
m_bottom = Max(m_bottom, p_rect.m_bottom);
}
inline MxS32 GetWidth() { return (m_right - m_left) + 1; }
inline MxS32 GetHeight() { return (m_bottom - m_top) + 1; }
inline MxPoint32 GetPoint() { return MxPoint32(this->m_left, this->m_top); }
inline MxSize32 GetSize() { return MxSize32(this->m_right, this->m_bottom); }
inline MxS32 GetLeft() { return m_left; }
inline MxS32 GetTop() { return m_top; }
inline MxS32 GetRight() { return m_right; }
inline MxS32 GetBottom() { return m_bottom; }
inline void SetLeft(MxS32 p_left) { m_left = p_left; }
inline void SetTop(MxS32 p_top) { m_top = p_top; }
inline void SetRight(MxS32 p_right) { m_right = p_right; }
inline void SetBottom(MxS32 p_bottom) { m_bottom = p_bottom; }
private:
inline static MxS32 Min(MxS32 a, MxS32 b) { return a <= b ? a : b; };
inline static MxS32 Max(MxS32 a, MxS32 b) { return a <= b ? b : a; };
MxS32 m_left;
MxS32 m_top;
MxS32 m_right;
MxS32 m_bottom;
inline MxS32 GetWidth() { return (m_right - m_left) + 1; }
inline MxS32 GetHeight() { return (m_bottom - m_top) + 1; }
};
#endif // MXRECT32_H

View File

@ -1,40 +1,198 @@
#include "mxregion.h"
DECOMP_SIZE_ASSERT(MxRegion, 0x1c);
#include <limits.h>
// OFFSET: LEGO1 0x100c31c0 STUB
DECOMP_SIZE_ASSERT(MxRegion, 0x1c);
DECOMP_SIZE_ASSERT(MxRegionTopBottom, 0x0c);
DECOMP_SIZE_ASSERT(MxRegionLeftRight, 0x08);
// OFFSET: LEGO1 0x100c31c0
MxRegion::MxRegion()
{
// TODO
m_list = new MxRegionList;
m_rect.SetPoint(MxPoint32(INT_MAX, INT_MAX));
m_rect.SetSize(MxSize32(-1, -1));
}
// OFFSET: LEGO1 0x100c3690 STUB
MxRegion::~MxRegion()
{
// TODO
}
// OFFSET: LEGO1 0x100c3700 STUB
void MxRegion::Reset()
{
// TODO
}
// OFFSET: LEGO1 0x100c3750 STUB
void MxRegion::vtable18(MxRect32& p_rect)
{
// TODO
}
// OFFSET: LEGO1 0x100c3e20 STUB
void MxRegion::vtable1c()
{
// TODO
}
// OFFSET: LEGO1 0x100c3660 STUB
// OFFSET: LEGO1 0x100c3660
MxBool MxRegion::vtable20()
{
// TODO
return m_list->GetCount() == 0;
}
// OFFSET: LEGO1 0x100c3690
MxRegion::~MxRegion()
{
if (m_list)
delete m_list;
}
// OFFSET: LEGO1 0x100c3700
void MxRegion::Reset()
{
m_list->DeleteAll();
m_rect.SetPoint(MxPoint32(INT_MAX, INT_MAX));
m_rect.SetSize(MxSize32(-1, -1));
}
// OFFSET: LEGO1 0x100c3750
void MxRegion::vtable18(MxRect32& p_rect)
{
MxRect32 rect(p_rect.GetPoint(), MxSize32(p_rect.GetRight(), p_rect.GetBottom()));
MxRegionListCursor cursor(m_list);
MxRegionTopBottom* topBottom;
while (rect.IsValid() && cursor.Next(topBottom)) {
if (topBottom->GetTop() >= rect.GetBottom()) {
MxRegionTopBottom* newTopBottom = new MxRegionTopBottom(rect);
cursor.Prepend(newTopBottom);
rect.SetTop(rect.GetBottom());
}
else if (rect.GetTop() < topBottom->GetBottom()) {
if (rect.GetTop() < topBottom->GetTop()) {
MxRect32 newRect(rect);
newRect.SetBottom(topBottom->GetTop());
MxRegionTopBottom* newTopBottom = new MxRegionTopBottom(newRect);
cursor.Prepend(newTopBottom);
rect.SetTop(topBottom->GetTop());
}
else if (topBottom->GetTop() < rect.GetTop()) {
MxRegionTopBottom* newTopBottom = topBottom->Clone();
newTopBottom->SetBottom(rect.GetTop());
topBottom->SetTop(rect.GetTop());
cursor.Prepend(newTopBottom);
}
if (rect.GetBottom() < topBottom->GetBottom()) {
MxRegionTopBottom* newTopBottom = topBottom->Clone();
newTopBottom->SetBottom(rect.GetBottom());
topBottom->SetTop(rect.GetBottom());
newTopBottom->FUN_100c5280(rect.GetLeft(), rect.GetRight());
cursor.Prepend(newTopBottom);
rect.SetTop(rect.GetBottom());
}
else {
topBottom->FUN_100c5280(rect.GetLeft(), rect.GetRight());
rect.SetTop(topBottom->GetBottom());
}
}
}
if (rect.IsValid()) {
MxRegionTopBottom* newTopBottom = new MxRegionTopBottom(rect);
m_list->Append(newTopBottom);
}
m_rect.UpdateBounds(p_rect);
}
// OFFSET: LEGO1 0x100c3e20
MxBool MxRegion::vtable1c(MxRect32& p_rect)
{
if (!m_rect.IntersectsWith(p_rect))
return FALSE;
MxRegionListCursor cursor(m_list);
MxRegionTopBottom* topBottom;
while (cursor.Next(topBottom)) {
if (topBottom->GetTop() >= p_rect.GetBottom())
return FALSE;
if (topBottom->GetBottom() > p_rect.GetTop() && topBottom->FUN_100c57b0(p_rect))
return TRUE;
}
return FALSE;
}
// OFFSET: LEGO1 0x100c4c90
MxRegionTopBottom::MxRegionTopBottom(MxS32 p_top, MxS32 p_bottom)
{
m_top = p_top;
m_bottom = p_bottom;
m_leftRightList = new MxRegionLeftRightList;
}
// OFFSET: LEGO1 0x100c50e0
MxRegionTopBottom::MxRegionTopBottom(MxRect32& p_rect)
{
m_top = p_rect.GetTop();
m_bottom = p_rect.GetBottom();
m_leftRightList = new MxRegionLeftRightList;
MxRegionLeftRight* leftRight = new MxRegionLeftRight(p_rect.GetLeft(), p_rect.GetRight());
m_leftRightList->Append(leftRight);
}
// OFFSET: LEGO1 0x100c5280
void MxRegionTopBottom::FUN_100c5280(MxS32 p_left, MxS32 p_right)
{
MxRegionLeftRightListCursor a(m_leftRightList);
MxRegionLeftRightListCursor b(m_leftRightList);
MxRegionLeftRight* leftRight;
while (a.Next(leftRight) && leftRight->GetRight() < p_left)
;
if (!a.HasMatch()) {
MxRegionLeftRight* copy = new MxRegionLeftRight(p_left, p_right);
m_leftRightList->Append(copy);
}
else {
if (p_left > leftRight->GetLeft())
p_left = leftRight->GetLeft();
while (leftRight->GetLeft() < p_right) {
if (p_right < leftRight->GetRight())
p_right = leftRight->GetRight();
b = a;
b.Advance();
a.Destroy();
if (!b.Current(leftRight))
break;
a = b;
}
if (a.HasMatch()) {
MxRegionLeftRight* copy = new MxRegionLeftRight(p_left, p_right);
a.Prepend(copy);
}
else {
MxRegionLeftRight* copy = new MxRegionLeftRight(p_left, p_right);
m_leftRightList->Append(copy);
}
}
}
// OFFSET: LEGO1 0x100c55d0
MxRegionTopBottom* MxRegionTopBottom::Clone()
{
MxRegionTopBottom* clone = new MxRegionTopBottom(m_top, m_bottom);
MxRegionLeftRightListCursor cursor(m_leftRightList);
MxRegionLeftRight* leftRight;
while (cursor.Next(leftRight))
clone->m_leftRightList->Append(leftRight->Clone());
return clone;
}
// OFFSET: LEGO1 0x100c57b0
MxBool MxRegionTopBottom::FUN_100c57b0(MxRect32& p_rect)
{
MxRegionLeftRightListCursor cursor(m_leftRightList);
MxRegionLeftRight* leftRight;
while (cursor.Next(leftRight)) {
if (p_rect.GetRight() <= leftRight->GetLeft())
return FALSE;
if (leftRight->GetRight() > p_rect.GetLeft())
return TRUE;
}
return FALSE;
}

View File

@ -4,6 +4,51 @@
#include "decomp.h"
#include "mxcore.h"
#include "mxrect32.h"
#include "mxregionlist.h"
// SIZE 0x0c
struct MxRegionTopBottom {
MxRegionTopBottom(MxRect32& p_rect);
MxRegionTopBottom(MxS32 m_top, MxS32 m_bottom);
MxRegionTopBottom* Clone();
void FUN_100c5280(MxS32 p_left, MxS32 p_right);
MxBool FUN_100c57b0(MxRect32& p_rect);
inline MxS32 GetTop() { return m_top; }
inline MxS32 GetBottom() { return m_bottom; }
inline void SetTop(MxS32 p_top) { m_top = p_top; }
inline void SetBottom(MxS32 p_bottom) { m_bottom = p_bottom; }
friend class MxRegionListParent;
private:
MxS32 m_top;
MxS32 m_bottom;
MxRegionLeftRightList* m_leftRightList;
};
// SIZE 0x08
struct MxRegionLeftRight {
MxRegionLeftRight(MxS32 p_left, MxS32 p_right)
{
m_left = p_left;
m_right = p_right;
}
MxRegionLeftRight* Clone() { return new MxRegionLeftRight(m_left, m_right); }
inline MxS32 GetLeft() { return m_left; }
inline MxS32 GetRight() { return m_right; }
inline void SetLeft(MxS32 p_left) { m_left = p_left; }
inline void SetRight(MxS32 p_right) { m_right = p_right; }
private:
MxS32 m_left;
MxS32 m_right;
};
// VTABLE 0x100dcae8
// SIZE 0x1c
@ -14,15 +59,13 @@ class MxRegion : public MxCore {
virtual void Reset();
virtual void vtable18(MxRect32& p_rect);
virtual void vtable1c();
virtual MxBool vtable1c(MxRect32& p_rect);
virtual MxBool vtable20();
inline MxRect32& GetRect() { return this->m_rect; }
private:
// A container (probably MxList) holding MxRect32
// MxList<MxRect32*> *m_rects;
undefined4 m_unk08;
MxRegionList* m_list;
MxRect32 m_rect;
};

19
LEGO1/mxregionlist.cpp Normal file
View File

@ -0,0 +1,19 @@
#include "mxregionlist.h"
#include "mxregion.h"
// OFFSET: LEGO1 0x100c33e0
void MxRegionListParent::Destroy(MxRegionTopBottom* p_topBottom)
{
if (p_topBottom) {
if (p_topBottom->m_leftRightList)
delete p_topBottom->m_leftRightList;
delete p_topBottom;
}
}
// OFFSET: LEGO1 0x100c4e80
void MxRegionLeftRightListParent::Destroy(MxRegionLeftRight* p_leftRight)
{
delete p_leftRight;
}

56
LEGO1/mxregionlist.h Normal file
View File

@ -0,0 +1,56 @@
#ifndef MXREGIONLIST_H
#define MXREGIONLIST_H
#include "mxlist.h"
struct MxRegionTopBottom;
struct MxRegionLeftRight;
// VTABLE 0x100dcb40
// SIZE 0x18
class MxRegionListParent : public MxList<MxRegionTopBottom*> {
public:
static void Destroy(MxRegionTopBottom* p_topBottom);
MxRegionListParent() { m_customDestructor = Destroy; }
};
// VTABLE 0x100dcb58
// SIZE 0x18
class MxRegionList : public MxRegionListParent {};
// VTABLE 0x100dcb88
typedef MxListCursorChildChild<MxRegionTopBottom*> MxRegionListCursor;
// OFFSET: LEGO1 0x100c5970 TEMPLATE
// MxList<MxRegionTopBottom *>::_InsertEntry
// OFFSET: LEGO1 0x100c5a20 TEMPLATE
// MxListEntry<MxRegionTopBottom *>::MxListEntry<MxRegionTopBottom *>
// VTABLE 0x100dcc70
// SIZE 0x18
class MxRegionLeftRightListParent : public MxList<MxRegionLeftRight*> {
public:
static void Destroy(MxRegionLeftRight* p_leftRight);
MxRegionLeftRightListParent() { m_customDestructor = Destroy; }
};
// VTABLE 0x100dcc88
// SIZE 0x18
class MxRegionLeftRightList : public MxRegionLeftRightListParent {};
// VTABLE 0x100dcc10
typedef MxListCursorChildChild<MxRegionLeftRight*> MxRegionLeftRightListCursor;
// OFFSET: LEGO1 0x100c54f0 TEMPLATE
// MxListCursor<MxRegionLeftRight *>::MxListCursor<MxRegionLeftRight *>
// OFFSET: LEGO1 0x100c58c0 TEMPLATE
// MxList<MxRegionLeftRight *>::_InsertEntry
// OFFSET: LEGO1 0x100c5a40 TEMPLATE
// MxList<MxRegionLeftRight *>::_DeleteEntry
#endif // MXREGIONLIST_H

19
LEGO1/mxsize32.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef MXSIZE32_H
#define MXSIZE32_H
#include "mxtypes.h"
class MxSize32 {
public:
MxSize32() {}
MxSize32(MxS32 p_width, MxS32 p_height)
{
this->m_width = p_width;
this->m_height = p_height;
}
MxS32 m_width;
MxS32 m_height;
};
#endif // MXSIZE32_H

View File

@ -1,6 +1,7 @@
#include "mxsmkpresenter.h"
#include "decomp.h"
#include "mxvideomanager.h"
DECOMP_SIZE_ASSERT(MxSmkPresenter, 0x720);
@ -65,3 +66,48 @@ void MxSmkPresenter::FUN_100c5d40(MxSmack* p_mxSmack)
if (p_mxSmack->m_unk0x6b4)
delete p_mxSmack->m_unk0x6b4;
}
// OFFSET: LEGO1 0x100b4300
void MxSmkPresenter::Destroy()
{
Destroy(FALSE);
}
// OFFSET: LEGO1 0x100b3940 STUB
void MxSmkPresenter::VTable0x5c(undefined4 p_unknown1)
{
}
// OFFSET: LEGO1 0x100b3a00 STUB
void MxSmkPresenter::VTable0x68(undefined4 p_unknown1)
{
}
// OFFSET: LEGO1 0x100b42c0
void MxSmkPresenter::VTable0x70()
{
MxPalette* palette = m_bitmap->CreatePalette();
MVideoManager()->RealizePalette(palette);
delete palette;
}
// OFFSET: LEGO1 0x100b4260
MxU32 MxSmkPresenter::VTable0x88()
{
MxU32 result = m_unk0x71c;
if ((m_mxSmack.m_smack.m_smkType & 1) != 0) {
result = m_unk0x71c / m_mxSmack.m_smack.m_frames;
if (1 < m_unk0x71c && (m_unk0x71c % m_mxSmack.m_smack.m_frames) == 1) {
m_unk0x71c = 1;
}
return result;
}
else {
if (m_mxSmack.m_smack.m_frames == result) {
m_unk0x71c = 0;
result = 0;
memset(m_mxSmack.m_smack.m_palette, 0, sizeof(m_mxSmack.m_smack.m_palette));
}
return result;
}
}

View File

@ -13,7 +13,25 @@ class MxSmkPresenter : public MxVideoPresenter {
MxSmkPresenter();
virtual ~MxSmkPresenter() override;
// OFFSET: LEGO1 0x100b3730
inline virtual const char* ClassName() const override // vtable+0xc
{
// 0x10101e38
return "MxSmkPresenter";
}
// OFFSET: LEGO1 0x100b3740
inline virtual MxBool IsA(const char* name) const override // vtable+0x10
{
return !strcmp(name, MxSmkPresenter::ClassName()) || MxVideoPresenter::IsA(name);
}
virtual void Destroy() override;
virtual void VTable0x5c(undefined4 p_unknown1) override;
virtual void VTable0x60() override;
virtual void VTable0x68(undefined4 p_unknown1) override; // vtable+0x68
virtual void VTable0x70() override;
virtual MxU32 VTable0x88();
struct MxSmack {
Smack m_smack;

View File

@ -1,5 +1,6 @@
#include "mxsoundmanager.h"
#include "define.h"
#include "mxautolocker.h"
#include "mxomni.h"
#include "mxpresenter.h"
@ -127,6 +128,53 @@ MxResult MxSoundManager::Create(MxU32 p_frequencyMS, MxBool p_createThread)
return status;
}
// OFFSET: LEGO1 0x100aeab0
void MxSoundManager::Destroy()
{
Destroy(FALSE);
}
// OFFSET: LEGO1 0x100aeac0
void MxSoundManager::SetVolume(MxS32 p_volume)
{
MxAudioManager::SetVolume(p_volume);
m_criticalSection.Enter();
MxPresenter* presenter;
MxPresenterListCursor cursor(m_presenters);
while (cursor.Next(presenter))
((MxAudioPresenter*) presenter)->vtable60(((MxAudioPresenter*) presenter)->vtable5c());
m_criticalSection.Leave();
}
// OFFSET: LEGO1 0x100aebd0
MxPresenter* MxSoundManager::FUN_100aebd0(const MxAtomId& p_atomId, MxU32 p_objectId)
{
MxAutoLocker lock(&m_criticalSection);
MxPresenter* presenter;
MxPresenterListCursor cursor(m_presenters);
while (cursor.Next(presenter)) {
if (presenter->GetAction()->GetAtomId().GetInternal() == p_atomId.GetInternal() &&
presenter->GetAction()->GetObjectId() == p_objectId)
return presenter;
}
return NULL;
}
// OFFSET: LEGO1 0x100aecf0
MxS32 MxSoundManager::FUN_100aecf0(MxU32 p_unk)
{
if (!p_unk)
return -10000;
return g_mxcoreCount[p_unk];
}
// OFFSET: LEGO1 0x100aed10
void MxSoundManager::vtable0x34()
{
@ -152,25 +200,3 @@ void MxSoundManager::vtable0x38()
if (presenter->IsA("MxWavePresenter"))
((MxWavePresenter*) presenter)->VTable0x68();
}
// OFFSET: LEGO1 0x100aeab0
void MxSoundManager::Destroy()
{
Destroy(FALSE);
}
// OFFSET: LEGO1 0x100aeac0
void MxSoundManager::SetVolume(MxS32 p_volume)
{
MxAudioManager::SetVolume(p_volume);
m_criticalSection.Enter();
MxPresenter* presenter;
MxPresenterListCursor cursor(m_presenters);
while (cursor.Next(presenter))
((MxAudioPresenter*) presenter)->vtable60(((MxAudioPresenter*) presenter)->vtable5c());
m_criticalSection.Leave();
}

View File

@ -2,6 +2,7 @@
#define MXSOUNDMANAGER_H
#include "decomp.h"
#include "mxatomid.h"
#include "mxaudiomanager.h"
#include <dsound.h>
@ -11,6 +12,9 @@
class MxSoundManager : public MxAudioManager {
public:
MxSoundManager();
// OFFSET: LEGO1 0x100ae7b0 TEMPLATE
// MxSoundManager::`scalar deleting destructor'
virtual ~MxSoundManager() override; // vtable+0x0
virtual void Destroy() override; // vtable+18
@ -22,6 +26,8 @@ class MxSoundManager : public MxAudioManager {
private:
void Init();
void Destroy(MxBool p_fromDestructor);
MxPresenter* FUN_100aebd0(const MxAtomId& p_atomId, MxU32 p_objectId);
MxS32 FUN_100aecf0(MxU32 p_unk);
LPDIRECTSOUND m_directSound; // 0x30
LPDIRECTSOUNDBUFFER m_dsBuffer; // 0x34

View File

@ -8,6 +8,19 @@
// SIZE 0x6c
class MxStillPresenter : public MxVideoPresenter {
public:
// OFFSET: LEGO1 0x100435c0
inline virtual const char* ClassName() const override // vtable+0xc
{
// 0x100f0184
return "MxStillPresenter";
}
// OFFSET: LEGO1 0x100435d0
inline virtual MxBool IsA(const char* name) const override // vtable+0x10
{
return !strcmp(name, MxStillPresenter::ClassName()) || MxVideoPresenter::IsA(name);
}
virtual void ParseExtra() override; // vtable+0x30
MxStillPresenter() { m_unk68 = 0; }

View File

@ -4,6 +4,26 @@
#include "mxdschunk.h"
// VTABLE 0x100dc2a8
class MxStreamChunk : public MxDSChunk {};
// SIZE 0x20
class MxStreamChunk : public MxDSChunk {
public:
inline MxStreamChunk() : m_unk1c(NULL) {}
// OFFSET: LEGO1 0x100b1fe0
inline virtual const char* ClassName() const override // vtable+0xc
{
// 0x10101e5c
return "MxStreamChunk";
}
// OFFSET: LEGO1 0x100b1ff0
inline virtual MxBool IsA(const char* name) const override // vtable+0x10
{
return !strcmp(name, MxStreamChunk::ClassName()) || MxDSChunk::IsA(name);
}
private:
void* m_unk1c; // 0x1c
};
#endif // MXSTREAMCHUNK_H

View File

@ -0,0 +1,19 @@
#include "mxstreamchunklist.h"
#include "mxstreamchunk.h"
DECOMP_SIZE_ASSERT(MxStreamChunkList, 0x18);
DECOMP_SIZE_ASSERT(MxStreamChunkListCursor, 0x10);
// OFFSET: LEGO1 0x100b5900
MxS8 MxStreamChunkList::Compare(MxStreamChunk* p_a, MxStreamChunk* p_b)
{
return p_a == p_b ? 0 : p_a < p_b ? -1 : 1;
}
// OFFSET: LEGO1 0x100b5920
void MxStreamChunkList::Destroy(MxStreamChunk* p_chunk)
{
if (p_chunk)
delete p_chunk;
}

34
LEGO1/mxstreamchunklist.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef MXSTREAMCHUNKLIST_H
#define MXSTREAMCHUNKLIST_H
#include "decomp.h"
#include "mxlist.h"
class MxStreamChunk;
// VTABLE 0x100dc600
// SIZE 0x18
class MxStreamChunkList : public MxList<MxStreamChunk*> {
public:
MxStreamChunkList() { m_customDestructor = Destroy; }
virtual MxS8 Compare(MxStreamChunk*, MxStreamChunk*) override; // +0x14
static void Destroy(MxStreamChunk* p_chunk);
};
typedef MxListCursorChild<MxStreamChunk*> MxStreamChunkListCursor;
// OFFSET: LEGO1 0x100b5930 TEMPLATE
// MxListParent<MxStreamChunk *>::Compare
// OFFSET: LEGO1 0x100b5990 TEMPLATE
// MxListParent<MxStreamChunk *>::Destroy
// OFFSET: LEGO1 0x100b59a0 TEMPLATE
// MxList<MxStreamChunk *>::~MxList<MxStreamChunk *>
// OFFSET: LEGO1 0x100b5b10 TEMPLATE
// MxList<MxStreamChunk *>::`scalar deleting destructor'
#endif // MXSTREAMCHUNKLIST_H

View File

@ -2,6 +2,9 @@
#include "legoomni.h"
#include "mxautolocker.h"
#include "mxnextactiondatastart.h"
DECOMP_SIZE_ASSERT(MxNextActionDataStart, 0x14)
// OFFSET: LEGO1 0x100c0b90 STUB
MxStreamController::MxStreamController()
@ -74,16 +77,32 @@ MxResult MxStreamController::vtable0x24(undefined4 p_unknown)
return FAILURE;
}
// OFFSET: LEGO1 0x100c1800 STUB
MxResult MxStreamController::FUN_100c1800(MxDSAction* p_action, MxU32 p_val)
{
MxNextActionDataStart* dataActionStart =
new MxNextActionDataStart(p_action->GetObjectId(), p_action->GetUnknown24(), p_val);
if (dataActionStart == NULL) {
return FAILURE;
}
// TODO: insert dataActionStart to a list
return FAILURE;
}
// OFFSET: LEGO1 0x100b9420
MxResult MxStreamController::vtable0x28()
{
return SUCCESS;
}
// OFFSET: LEGO1 0x100c1c10 STUB
// OFFSET: LEGO1 0x100c1c10
MxResult MxStreamController::vtable0x2c(MxDSAction* p_action, MxU32 p_bufferval)
{
return FAILURE;
MxAutoLocker locker(&m_criticalSection);
if (FUN_100c1a00(p_action, p_bufferval) != SUCCESS) {
return FAILURE;
}
return FUN_100c1800(p_action, (p_bufferval / m_provider->GetFileSize()) * m_provider->GetFileSize());
}
// OFFSET: LEGO1 0x100c1ce0 STUB
@ -91,3 +110,9 @@ MxResult MxStreamController::vtable0x30(undefined4 p_unknown)
{
return FAILURE;
}
// OFFSET: LEGO1 0x100c1a00 STUB
MxResult MxStreamController::FUN_100c1a00(MxDSAction* p_action, MxU32 p_bufferval)
{
return FAILURE;
}

View File

@ -35,11 +35,13 @@ class MxStreamController : public MxCore {
virtual MxResult vtable0x1C(undefined4 p_unknown, undefined4 p_unknown2); // vtable+0x1c
virtual MxResult vtable0x20(MxDSAction* p_action); // vtable+0x20
virtual MxResult vtable0x24(undefined4 p_unknown); // vtable+0x24
virtual MxResult vtable0x28(); // vtable+0x28
virtual MxResult vtable0x2c(MxDSAction* p_action, MxU32 p_bufferval); // vtable+0x2c
virtual MxResult vtable0x30(undefined4 p_unknown); // vtable+0x30
MxResult FUN_100c1800(MxDSAction* p_action, MxU32 p_val);
virtual MxResult vtable0x28(); // vtable+0x28
virtual MxResult vtable0x2c(MxDSAction* p_action, MxU32 p_bufferval); // vtable+0x2c
virtual MxResult vtable0x30(undefined4 p_unknown); // vtable+0x30
MxBool FUN_100c20d0(MxDSObject& p_obj);
MxResult FUN_100c1a00(MxDSAction* p_action, MxU32 p_bufferval);
inline MxAtomId& GetAtom() { return atom; };

View File

@ -18,9 +18,11 @@ class MxStreamerSubClass1 {
~MxStreamerSubClass1() { delete[] m_buffer; }
undefined4 GetSize() { return m_size; }
undefined4 GetSize() const { return m_size; }
void SetBuffer(undefined* p_buf) { m_buffer = p_buf; }
inline undefined* GetBuffer() const { return m_buffer; }
inline undefined4 GetUnk08() const { return m_unk08; }
private:
undefined* m_buffer;
@ -40,7 +42,7 @@ class MxStreamerSubClass3 : public MxStreamerSubClass1 {
class MxStreamerNotification : public MxNotificationParam {
public:
inline MxStreamerNotification(MxParamType p_type, MxCore* p_sender, MxStreamController* p_ctrlr)
inline MxStreamerNotification(NotificationId p_type, MxCore* p_sender, MxStreamController* p_ctrlr)
: MxNotificationParam(p_type, p_sender)
{
m_controller = p_ctrlr;
@ -93,6 +95,9 @@ class MxStreamer : public MxCore {
MxResult AddStreamControllerToOpenList(MxStreamController* p_stream);
MxResult FUN_100b99b0(MxDSAction* p_action);
inline const MxStreamerSubClass2& GetSubclass1() { return m_subclass1; }
inline const MxStreamerSubClass3& GetSubclass2() { return m_subclass2; }
private:
list<MxStreamController*> m_openStreams; // 0x8
MxStreamerSubClass2 m_subclass1; // 0x14

View File

@ -18,6 +18,7 @@ class MxString : public MxCore {
MxString operator+(const char*);
MxString& operator+=(const char*);
inline MxS8 Compare(const MxString& p_str) const { return strcmp(m_data, p_str.m_data); }
inline const char* GetData() const { return m_data; }
private:

View File

@ -21,7 +21,7 @@ typedef MxListCursorChild<MxString> MxStringListCursor;
// MxList<MxString>::~MxList<MxString>
// OFFSET: LEGO1 0x100cbb40 TEMPLATE
// MxList<MxString>::OtherAppend
// MxList<MxString>::Append
// OFFSET: LEGO1 0x100cc2d0 TEMPLATE
// MxList<MxString>::_InsertEntry

View File

@ -468,7 +468,7 @@ void MxTransitionManager::SetWaitIndicator(MxVideoPresenter* p_waitIndicator)
{
// End current wait indicator
if (m_waitIndicator != NULL) {
m_waitIndicator->GetAction()->SetFlags(m_waitIndicator->GetAction()->GetFlags() & ~MxDSAction::Flag_Parsed);
m_waitIndicator->GetAction()->SetFlags(m_waitIndicator->GetAction()->GetFlags() & ~MxDSAction::Flag_World);
m_waitIndicator->EndAction();
m_waitIndicator = NULL;
}

View File

@ -3,7 +3,7 @@
// OFFSET: LEGO1 0x100b7330
MxS8 MxVariableTable::Compare(MxVariable* p_var0, MxVariable* p_var1)
{
return strcmp(p_var0->GetKey()->GetData(), p_var1->GetKey()->GetData());
return p_var0->GetKey()->Compare(*p_var1->GetKey());
}
// OFFSET: LEGO1 0x100b7370
@ -22,43 +22,43 @@ MxU32 MxVariableTable::Hash(MxVariable* p_var)
// OFFSET: LEGO1 0x100b73a0
void MxVariableTable::SetVariable(const char* p_key, const char* p_value)
{
MxHashTableCursor<MxVariable> cursor(this);
MxHashTableCursor<MxVariable*> cursor(this);
MxVariable* var = new MxVariable(p_key, p_value);
if (cursor.Find(var)) {
delete var;
cursor.GetMatch(var);
cursor.Current(var);
var->SetValue(p_value);
}
else {
MxHashTable<MxVariable>::Add(var);
MxHashTable<MxVariable*>::Add(var);
}
}
// OFFSET: LEGO1 0x100b7740
void MxVariableTable::SetVariable(MxVariable* var)
void MxVariableTable::SetVariable(MxVariable* p_var)
{
MxHashTableCursor<MxVariable> cursor(this);
MxBool found = cursor.Find(var);
MxHashTableCursor<MxVariable*> cursor(this);
MxBool found = cursor.Find(p_var);
if (found)
cursor.DeleteMatch();
MxHashTable<MxVariable>::Add(var);
MxHashTable<MxVariable*>::Add(p_var);
}
// OFFSET: LEGO1 0x100b78f0
const char* MxVariableTable::GetVariable(const char* p_key)
{
const char* value = "";
MxHashTableCursor<MxVariable> cursor(this);
MxHashTableCursor<MxVariable*> cursor(this);
MxVariable* var = new MxVariable(p_key);
MxBool found = cursor.Find(var);
delete var;
if (found) {
cursor.GetMatch(var);
cursor.Current(var);
value = var->GetValue()->GetData();
}

View File

@ -7,27 +7,51 @@
// VTABLE 0x100dc1c8
// SIZE 0x28
class MxVariableTable : public MxHashTable<MxVariable> {
class MxVariableTable : public MxHashTable<MxVariable*> {
public:
MxVariableTable() { m_customDestructor = Destroy; }
__declspec(dllexport) void SetVariable(const char* key, const char* value);
__declspec(dllexport) void SetVariable(MxVariable* var);
__declspec(dllexport) const char* GetVariable(const char* key);
__declspec(dllexport) void SetVariable(const char* p_key, const char* p_value);
__declspec(dllexport) void SetVariable(MxVariable* p_var);
__declspec(dllexport) const char* GetVariable(const char* p_key);
// OFFSET: LEGO1 0x100afdb0
static void Destroy(MxVariable* p_obj) { p_obj->Destroy(); }
virtual MxS8 Compare(MxVariable*, MxVariable*); // +0x14
virtual MxU32 Hash(MxVariable*); // +0x18
virtual MxS8 Compare(MxVariable*, MxVariable*) override; // +0x14
virtual MxU32 Hash(MxVariable*) override; // +0x18
};
// OFFSET: LEGO1 0x100afcd0 TEMPLATE
// MxCollection<MxVariable *>::Compare
// OFFSET: LEGO1 0x100afce0 TEMPLATE
// MxCollection<MxVariable *>::~MxCollection<MxVariable *>
// OFFSET: LEGO1 0x100afd30 TEMPLATE
// MxCollection<MxVariable *>::Destroy
// OFFSET: LEGO1 0x100afd40 TEMPLATE
// MxCollection<MxVariable *>::`scalar deleting destructor'
// OFFSET: LEGO1 0x100afdc0 TEMPLATE
// MxHashTable<MxVariable *>::Hash
// OFFSET: LEGO1 0x100b0bd0 TEMPLATE
// MxHashTable<MxVariable>::~MxHashTable<MxVariable>
// MxHashTable<MxVariable *>::~MxHashTable<MxVariable *>
// OFFSET: LEGO1 0x100b0ca0 TEMPLATE
// MxHashTable<MxVariable *>::`scalar deleting destructor'
// OFFSET: LEGO1 0x100b7ab0 TEMPLATE
// MxHashTable<MxVariable>::Resize
// MxHashTable<MxVariable *>::Resize
// OFFSET: LEGO1 0x100b7b80 TEMPLATE
// MxHashTable<MxVariable>::_NodeInsert
// MxHashTable<MxVariable *>::_NodeInsert
// VTABLE 0x100dc1b0 TEMPLATE
// class MxCollection<MxVariable *>
// VTABLE 0x100dc1e8 TEMPLATE
// class MxHashTable<MxVariable *>
#endif // MXVARIABLETABLE_H

View File

@ -75,26 +75,9 @@ void MxVideoManager::Destroy(MxBool p_fromDestructor)
void MxVideoManager::UpdateRegion()
{
if (m_region->vtable20() == FALSE) {
MxS32 left, top, right, bottom;
MxRect32& regionRect = m_region->GetRect();
left = m_videoParam.GetRect().m_left;
if (left <= regionRect.m_left)
left = regionRect.m_left;
top = regionRect.m_top;
if (top <= m_videoParam.GetRect().m_top)
top = m_videoParam.GetRect().m_top;
right = regionRect.m_right;
if (right >= m_videoParam.GetRect().m_right)
right = m_videoParam.GetRect().m_right;
bottom = m_videoParam.GetRect().m_bottom;
if (bottom >= regionRect.m_bottom)
bottom = regionRect.m_bottom;
m_displaySurface->Display(left, top, left, top, right - left + 1, bottom - top + 1);
MxRect32 rect(m_region->GetRect(), m_videoParam.GetRect());
m_displaySurface
->Display(rect.GetLeft(), rect.GetTop(), rect.GetLeft(), rect.GetTop(), rect.GetWidth(), rect.GetHeight());
}
}

View File

@ -6,14 +6,14 @@
// 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_rect.SetRight(640);
this->m_rect.SetBottom(480);
this->m_rect.SetLeft(0);
this->m_rect.SetTop(0);
this->m_palette = NULL;
this->m_backBuffers = 0;
this->m_unk1c = 0;
this->m_deviceId = 0;
this->m_deviceId = NULL;
}
// OFFSET: LEGO1 0x100beca0
@ -24,10 +24,7 @@ MxVideoParam::MxVideoParam(
COMPAT_CONST 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_rect = p_rect;
this->m_palette = p_pal;
this->m_backBuffers = p_backBuffers;
this->m_flags = p_flags;
@ -38,10 +35,7 @@ MxVideoParam::MxVideoParam(
// 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_rect = p_videoParam.m_rect;
this->m_palette = p_videoParam.m_palette;
this->m_backBuffers = p_videoParam.m_backBuffers;
this->m_flags = p_videoParam.m_flags;
@ -53,10 +47,7 @@ MxVideoParam::MxVideoParam(MxVideoParam& p_videoParam)
// 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_rect = p_videoParam.m_rect;
this->m_palette = p_videoParam.m_palette;
this->m_backBuffers = p_videoParam.m_backBuffers;
this->m_flags = p_videoParam.m_flags;
@ -69,24 +60,24 @@ MxVideoParam& MxVideoParam::operator=(const MxVideoParam& p_videoParam)
// OFFSET: LEGO1 0x100bed70
void MxVideoParam::SetDeviceName(char* id)
{
if (this->m_deviceId != 0)
if (this->m_deviceId != NULL)
delete[] this->m_deviceId;
if (id != 0) {
this->m_deviceId = new char[strlen(id) + 1];
if (this->m_deviceId != 0) {
if (this->m_deviceId != NULL) {
strcpy(this->m_deviceId, id);
}
}
else {
this->m_deviceId = 0;
this->m_deviceId = NULL;
}
}
// OFFSET: LEGO1 0x100bed50
MxVideoParam::~MxVideoParam()
{
if (this->m_deviceId != 0)
if (this->m_deviceId != NULL)
delete[] this->m_deviceId;
}

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