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 IndentWidth: 4
InsertNewlineAtEOF: true InsertNewlineAtEOF: true
PointerAlignment: Left PointerAlignment: Left
QualifierAlignment: Custom
QualifierOrder:
- inline
- static
- friend
- const
- volatile
- type
SpaceAfterCStyleCast: true SpaceAfterCStyleCast: true
TabWidth: 4 TabWidth: 4
UseTab: ForContinuationAndIndentation UseTab: ForContinuationAndIndentation

View File

@ -163,12 +163,14 @@ add_library(lego1 SHARED
LEGO1/mxramstreamcontroller.cpp LEGO1/mxramstreamcontroller.cpp
LEGO1/mxramstreamprovider.cpp LEGO1/mxramstreamprovider.cpp
LEGO1/mxregion.cpp LEGO1/mxregion.cpp
LEGO1/mxregionlist.cpp
LEGO1/mxscheduler.cpp LEGO1/mxscheduler.cpp
LEGO1/mxsemaphore.cpp LEGO1/mxsemaphore.cpp
LEGO1/mxsmkpresenter.cpp LEGO1/mxsmkpresenter.cpp
LEGO1/mxsoundmanager.cpp LEGO1/mxsoundmanager.cpp
LEGO1/mxsoundpresenter.cpp LEGO1/mxsoundpresenter.cpp
LEGO1/mxstillpresenter.cpp LEGO1/mxstillpresenter.cpp
LEGO1/mxstreamchunklist.cpp
LEGO1/mxstreamcontroller.cpp LEGO1/mxstreamcontroller.cpp
LEGO1/mxstreamer.cpp LEGO1/mxstreamer.cpp
LEGO1/mxstreamprovider.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. - `m_camelCase` for member variables.
- `g_camelCase` for global variables. - `g_camelCase` for global variables.
- `p_camelCase` for function parameters. - `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? ## Questions?

View File

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

View File

@ -1,5 +1,15 @@
#include "define.h" #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 // 0x10101eac
const char* g_parseExtraTokens = ":;"; const char* g_parseExtraTokens = ":;";

View File

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

View File

@ -3,43 +3,49 @@
DECOMP_SIZE_ASSERT(LegoActor, 0x78) DECOMP_SIZE_ASSERT(LegoActor, 0x78)
// Probably in header // Probably in header
// OFFSET: LEGO1 0x10002cc0 STUB // OFFSET: LEGO1 0x10002cc0
void LegoActor::VTable0x50() MxFloat LegoActor::VTable0x50()
{ {
// TODO return m_unk68;
} }
// OFFSET: LEGO1 0x10002cd0 STUB // OFFSET: LEGO1 0x10002cd0
void LegoActor::VTable0x54() void LegoActor::VTable0x54(MxFloat p_unk)
{ {
// TODO m_unk68 = p_unk;
} }
// OFFSET: LEGO1 0x10002ce0 STUB // OFFSET: LEGO1 0x10002ce0
void LegoActor::VTable0x58() void LegoActor::VTable0x58(MxFloat p_unk)
{ {
// TODO m_unk70 = p_unk;
} }
// OFFSET: LEGO1 0x10002cf0 STUB // OFFSET: LEGO1 0x10002cf0
void LegoActor::VTable0x5c() MxFloat LegoActor::VTable0x5c()
{ {
// TODO return m_unk70;
} }
// OFFSET: LEGO1 0x10002d00 STUB // OFFSET: LEGO1 0x10002d00
void LegoActor::VTable0x60() undefined LegoActor::VTable0x60()
{ {
// TODO return m_unk74;
} }
// OFFSET: LEGO1 0x10002d10 STUB // OFFSET: LEGO1 0x10002d10
void LegoActor::VTable0x64() void LegoActor::VTable0x64(undefined p_unk)
{ {
// TODO m_unk74 = p_unk;
} }
// End header // End header
// OFFSET: LEGO1 0x1002d110
LegoActor::LegoActor() 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); return !strcmp(name, LegoActor::ClassName()) || LegoEntity::IsA(name);
} }
virtual void VTable0x50(); // vtable+0x50 virtual MxFloat VTable0x50(); // vtable+0x50
virtual void VTable0x54(); // vtable+0x54 virtual void VTable0x54(MxFloat p_unk); // vtable+0x54
virtual void VTable0x58(); // vtable+0x58 virtual void VTable0x58(MxFloat p_unk); // vtable+0x58
virtual void VTable0x5c(); // vtable+0x5c virtual MxFloat VTable0x5c(); // vtable+0x5c
virtual void VTable0x60(); // vtable+0x60 virtual undefined VTable0x60(); // vtable+0x60
virtual void VTable0x64(); // vtable+0x64 virtual void VTable0x64(undefined p_unk); // vtable+0x64
private: private:
undefined unk68[0x10]; MxFloat m_unk68;
undefined4 m_unk6c;
MxFloat m_unk70;
undefined m_unk74;
}; };
#endif // LEGOACTOR_H #endif // LEGOACTOR_H

View File

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

View File

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

View File

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

View File

@ -1,19 +1,47 @@
#include "legoentitypresenter.h" #include "legoentitypresenter.h"
#include "legoomni.h"
#include "legovideomanager.h"
DECOMP_SIZE_ASSERT(LegoEntityPresenter, 0x50);
// OFFSET: LEGO1 0x10053440 // OFFSET: LEGO1 0x10053440
LegoEntityPresenter::LegoEntityPresenter() LegoEntityPresenter::LegoEntityPresenter()
{ {
Init(); Init();
} }
// OFFSET: LEGO1 0x100535d0 STUB // OFFSET: LEGO1 0x100535c0
LegoEntityPresenter::~LegoEntityPresenter()
{
// TODO
}
// OFFSET: LEGO1 0x100535c0 STUB
void LegoEntityPresenter::Init() 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" #include "mxcompositepresenter.h"
// VTABLE 0x100d8398 // VTABLE 0x100d8398
// SIZE 0x50
class LegoEntityPresenter : public MxCompositePresenter { class LegoEntityPresenter : public MxCompositePresenter {
public: public:
LegoEntityPresenter(); LegoEntityPresenter();
@ -22,8 +23,14 @@ class LegoEntityPresenter : public MxCompositePresenter {
return !strcmp(name, LegoEntityPresenter::ClassName()) || MxCompositePresenter::IsA(name); 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: private:
void Init(); void Destroy(MxBool p_fromDestructor);
undefined4 m_unk4c;
}; };
#endif // LEGOENTITYPRESENTER_H #endif // LEGOENTITYPRESENTER_H

View File

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

View File

@ -7,16 +7,28 @@
// VTABLE 0x100d6aa0 // VTABLE 0x100d6aa0
class LegoEventNotificationParam : public MxNotificationParam { class LegoEventNotificationParam : public MxNotificationParam {
public: 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) virtual ~LegoEventNotificationParam() override {} // vtable+0x0 (scalar deleting destructor)
inline MxU8 GetKey() { return m_key; } inline MxU8 GetKey() const { return m_key; }
protected: protected:
MxU8 m_modifier; // 0x0c MxU8 m_modifier; // 0x0c
MxS32 m_x; // 0x10 MxS32 m_x; // 0x10
MxS32 m_y; // 0x14 MxS32 m_y; // 0x14
MxU8 m_key; // 0x18 MxU8 m_key; // 0x18
MxU32 m_unk1c; // 0x1c
}; };
#endif // LEGOEVENTNOTIFICATIONPARAM_H #endif // LEGOEVENTNOTIFICATIONPARAM_H

View File

@ -2,6 +2,7 @@
#include "infocenterstate.h" #include "infocenterstate.h"
#include "legoomni.h" #include "legoomni.h"
#include "legoroi.h"
#include "legostate.h" #include "legostate.h"
#include "legostream.h" #include "legostream.h"
#include "mxobjectfactory.h" #include "mxobjectfactory.h"
@ -43,6 +44,8 @@ extern const char* s_endOfVariables;
LegoGameState::LegoGameState() LegoGameState::LegoGameState()
{ {
// TODO // TODO
SetROIHandlerFunction();
m_stateCount = 0; m_stateCount = 0;
m_backgroundColor = new LegoBackgroundColor("backgroundcolor", "set 56 54 68"); m_backgroundColor = new LegoBackgroundColor("backgroundcolor", "set 56 54 68");
VariableTable()->SetVariable(m_backgroundColor); VariableTable()->SetVariable(m_backgroundColor);
@ -57,10 +60,22 @@ LegoGameState::LegoGameState()
SerializeScoreHistory(1); SerializeScoreHistory(1);
} }
// OFFSET: LEGO1 0x10039720 STUB // OFFSET: LEGO1 0x10039720
LegoGameState::~LegoGameState() 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 // OFFSET: LEGO1 0x10039c60 STUB
@ -149,6 +164,12 @@ void LegoGameState::SerializeScoreHistory(MxS16 p)
// TODO // TODO
} }
// OFFSET: LEGO1 0x1003cea0
void LegoGameState::SetSomeEnumState(undefined4 p_state)
{
m_unk10 = p_state;
}
// OFFSET: LEGO1 0x10039f00 // OFFSET: LEGO1 0x10039f00
void LegoGameState::SetSavePath(char* p_savePath) void LegoGameState::SetSavePath(char* p_savePath)
{ {
@ -163,6 +184,33 @@ void LegoGameState::SetSavePath(char* p_savePath)
m_savePath = NULL; 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 // OFFSET: LEGO1 0x1003bbb0
LegoState* LegoGameState::GetState(COMPAT_CONST char* p_stateName) LegoState* LegoGameState::GetState(COMPAT_CONST char* p_stateName)
{ {

View File

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

View File

@ -9,10 +9,10 @@ DECOMP_SIZE_ASSERT(LegoInputManager, 0x338);
// OFFSET: LEGO1 0x1005b790 // OFFSET: LEGO1 0x1005b790
LegoInputManager::LegoInputManager() LegoInputManager::LegoInputManager()
{ {
m_eventQueue = NULL; m_unk0x5c = NULL;
m_world = NULL; m_world = NULL;
m_camera = NULL; m_camera = NULL;
m_unk0x68 = NULL; m_eventQueue = NULL;
m_unk0x80 = 0; m_unk0x80 = 0;
m_timer = 0; m_timer = 0;
m_unk0x6c = 0; m_unk0x6c = 0;
@ -36,7 +36,7 @@ LegoInputManager::LegoInputManager()
// OFFSET: LEGO1 0x1005b8b0 STUB // OFFSET: LEGO1 0x1005b8b0 STUB
MxResult LegoInputManager::Tickle() MxResult LegoInputManager::Tickle()
{ {
// TODO ProcessEvents();
return SUCCESS; return SUCCESS;
} }
@ -46,19 +46,28 @@ LegoInputManager::~LegoInputManager()
Destroy(); Destroy();
} }
// OFFSET: LEGO1 0x1005b960
MxResult LegoInputManager::Create(HWND p_hwnd)
{
// TODO
if (m_eventQueue == NULL)
m_eventQueue = new LegoEventQueue();
return SUCCESS;
}
// OFFSET: LEGO1 0x1005bfe0 // OFFSET: LEGO1 0x1005bfe0
void LegoInputManager::Destroy() void LegoInputManager::Destroy()
{ {
ReleaseDX(); ReleaseDX();
if (m_unk0x5c)
delete m_unk0x5c;
m_unk0x5c = NULL;
if (m_eventQueue) if (m_eventQueue)
delete m_eventQueue; delete m_eventQueue;
m_eventQueue = NULL; m_eventQueue = NULL;
if (m_unk0x68)
delete m_unk0x68;
m_unk0x68 = NULL;
if (m_controlManager) if (m_controlManager)
delete m_controlManager; delete m_controlManager;
} }
@ -215,10 +224,34 @@ void LegoInputManager::ClearWorld()
m_world = NULL; m_world = NULL;
} }
// OFFSET: LEGO1 0x1005c740 STUB // OFFSET: LEGO1 0x1005c740
void LegoInputManager::QueueEvent(NotificationId id, unsigned char p2, MxLong p3, MxLong p4, unsigned char p5) 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 // TODO
return FALSE;
} }
// OFFSET: LEGO1 0x1005cfb0 // OFFSET: LEGO1 0x1005cfb0

View File

@ -6,21 +6,14 @@
#include "legoworld.h" #include "legoworld.h"
#include "mxlist.h" #include "mxlist.h"
#include "mxpresenter.h" #include "mxpresenter.h"
#include "mxqueue.h"
#include <dinput.h> #include <dinput.h>
enum NotificationId {
NONE = 0,
KEYDOWN = 7,
MOUSEUP = 8,
MOUSEDOWN = 9,
MOUSEMOVE = 10,
TIMER = 15
};
class LegoControlManager; 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 // VTABLE 0x100d8760
// SIZE 0x338 // SIZE 0x338
@ -29,12 +22,13 @@ class LegoInputManager : public MxPresenter {
LegoInputManager(); LegoInputManager();
virtual ~LegoInputManager() override; 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 Register(MxCore*);
__declspec(dllexport) void UnRegister(MxCore*); __declspec(dllexport) void UnRegister(MxCore*);
virtual MxResult Tickle() override; // vtable+0x8 virtual MxResult Tickle() override; // vtable+0x8
MxResult Create(HWND p_hwnd);
void Destroy(); void Destroy();
void CreateAndAcquireKeyboard(HWND hwnd); void CreateAndAcquireKeyboard(HWND hwnd);
void ReleaseDX(); void ReleaseDX();
@ -53,12 +47,15 @@ class LegoInputManager : public MxPresenter {
inline LegoControlManager* GetControlManager() { return m_controlManager; } inline LegoControlManager* GetControlManager() { return m_controlManager; }
inline LegoWorld* GetWorld() { return m_world; } inline LegoWorld* GetWorld() { return m_world; }
void ProcessEvents();
MxBool ProcessOneEvent(LegoEventNotificationParam& p_param);
// private: // private:
MxCriticalSection m_criticalSection; MxCriticalSection m_criticalSection;
LegoEventQueue* m_eventQueue; // list or hash table MxList<undefined4>* m_unk0x5c; // list or hash table
LegoCameraController* m_camera; LegoCameraController* m_camera;
LegoWorld* m_world; LegoWorld* m_world;
MxList<undefined4>* m_unk0x68; // list or hash table LegoEventQueue* m_eventQueue; // +0x68
undefined4 m_unk0x6c; undefined4 m_unk0x6c;
undefined4 m_unk0x70; undefined4 m_unk0x70;
undefined4 m_unk0x74; undefined4 m_unk0x74;
@ -83,4 +80,37 @@ class LegoInputManager : public MxPresenter {
MxBool m_unk0x336; 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 #endif // LEGOINPUTMANAGER_H

View File

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

View File

@ -37,7 +37,7 @@ class LegoNavController : public MxCore {
); );
LegoNavController(); LegoNavController();
// virtual ~LegoNavController(); // vtable+0x0 virtual ~LegoNavController() override; // vtable+0x0
// OFFSET: LEGO1 0x10054b80 // OFFSET: LEGO1 0x10054b80
inline const char* ClassName() const override // vtable+0xc 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) void LegoObjectFactory::Destroy(MxCore* p_object)
{ {
// TODO delete p_object;
} }

View File

@ -1,18 +1,110 @@
#include "legoomni.h" #include "legoomni.h"
#include "gifmanager.h"
#include "legoanimationmanager.h"
#include "legobuildingmanager.h"
#include "legogamestate.h" #include "legogamestate.h"
#include "legoinputmanager.h" #include "legoinputmanager.h"
#include "legoobjectfactory.h" #include "legoobjectfactory.h"
#include "legoplantmanager.h"
#include "legosoundmanager.h"
#include "legoutil.h" #include "legoutil.h"
#include "legovideomanager.h"
#include "legoworld.h" #include "legoworld.h"
#include "mxautolocker.h"
#include "mxbackgroundaudiomanager.h" #include "mxbackgroundaudiomanager.h"
#include "mxdsfile.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 // 0x100f4588
MxAtomId* g_nocdSourceName = NULL; MxAtomId* g_nocdSourceName = NULL;
// 0x100f456c // 0x100f6718
MxAtomId* g_jukeboxScript = NULL; const char* g_current = "current";
// 0x101020e8 // 0x101020e8
void (*g_omniUserMessage)(const char*, int); void (*g_omniUserMessage)(const char*, int);
@ -42,6 +134,13 @@ void LegoOmni::RemoveWorld(const MxAtomId& p1, MxLong p2)
// TODO // TODO
} }
// OFFSET: LEGO1 0x1005b0c0 STUB
LegoEntity* LegoOmni::FindByEntityIdOrAtomId(const MxAtomId& p_atom, MxS32 p_entityid)
{
// TODO
return NULL;
}
// OFFSET: LEGO1 0x1005b400 STUB // OFFSET: LEGO1 0x1005b400 STUB
int LegoOmni::GetCurrPathInfo(LegoPathBoundary**, int&) int LegoOmni::GetCurrPathInfo(LegoPathBoundary**, int&)
{ {
@ -212,12 +311,29 @@ GifManager* GetGifManager()
return LegoOmni::GetInstance()->GetGifManager(); return LegoOmni::GetInstance()->GetGifManager();
} }
// OFFSET: LEGO1 0x100158e0
MxDSAction& GetCurrentAction()
{
return LegoOmni::GetInstance()->GetCurrentAction();
}
// OFFSET: LEGO1 0x10015900 // OFFSET: LEGO1 0x10015900
MxTransitionManager* TransitionManager() MxTransitionManager* TransitionManager()
{ {
return LegoOmni::GetInstance()->GetTransitionManager(); 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 // OFFSET: LEGO1 0x100c0280
MxDSObject* CreateStreamObject(MxDSFile* p_file, MxS16 p_ofs) MxDSObject* CreateStreamObject(MxDSFile* p_file, MxS16 p_ofs)
{ {
@ -259,7 +375,7 @@ const char* GetNoCD_SourceName()
return g_nocdSourceName->GetInternal(); return g_nocdSourceName->GetInternal();
} }
// OFFSET: LEGO1 0x1005b5f0 // OFFSET: LEGO1 0x1005b5f0 STUB
MxLong LegoOmni::Notify(MxParam& p) MxLong LegoOmni::Notify(MxParam& p)
{ {
// TODO // TODO
@ -302,16 +418,83 @@ void LegoOmni::Init()
m_transitionManager = NULL; m_transitionManager = NULL;
} }
// OFFSET: LEGO1 0x10058e70 STUB // OFFSET: LEGO1 0x1001a700 STUB
void FUN_1001a700()
{
// TODO
}
// OFFSET: LEGO1 0x10058e70
MxResult LegoOmni::Create(MxOmniCreateParam& p) 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_objectFactory = new LegoObjectFactory();
m_gameState = new LegoGameState(); if (m_objectFactory == NULL)
m_bkgAudioManager = new MxBackgroundAudioManager(); 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 // OFFSET: LEGO1 0x10058c30 STUB
@ -337,18 +520,33 @@ MxResult LegoOmni::DeleteObject(MxDSAction& ds)
return FAILURE; return FAILURE;
} }
// OFFSET: LEGO1 0x1005b3c0 STUB // OFFSET: LEGO1 0x1005b3c0
MxBool LegoOmni::DoesEntityExist(MxDSAction& ds) MxBool LegoOmni::DoesEntityExist(MxDSAction& ds)
{ {
// TODO if (MxOmni::DoesEntityExist(ds)) {
return TRUE; if (FindByEntityIdOrAtomId(ds.GetAtomId(), ds.GetObjectId()) == NULL) {
return TRUE;
}
}
return FALSE;
} }
// OFFSET: LEGO1 0x1005b2f0 STUB // OFFSET: LEGO1 0x1005b2f0
int LegoOmni::Vtable0x30(char*, int, MxCore*) MxEntity* LegoOmni::FindWorld(const char* p_id, MxS32 p_entityId, MxPresenter* p_presenter)
{ {
// TODO LegoWorld* foundEntity = NULL;
return 0; 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 // OFFSET: LEGO1 0x1005b3a0
@ -371,3 +569,99 @@ void LegoOmni::StopTimer()
MxOmni::StopTimer(); MxOmni::StopTimer();
SetAppCursor(0); 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 MxDSFile;
class MxTransitionManager; 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 // VTABLE 0x100d8638
// SIZE: 0x140 // SIZE: 0x140
class LegoOmni : public MxOmni { class LegoOmni : public MxOmni {
@ -54,16 +83,18 @@ class LegoOmni : public MxOmni {
return !strcmp(name, LegoOmni::ClassName()) || MxOmni::IsA(name); return !strcmp(name, LegoOmni::ClassName()) || MxOmni::IsA(name);
} }
virtual void Init() override; // vtable+14 virtual void Init() override; // vtable+14
virtual MxResult Create(MxOmniCreateParam& p) override; // vtable+18 virtual MxResult Create(MxOmniCreateParam& p) override; // vtable+18
virtual void Destroy() override; // vtable+1c virtual void Destroy() override; // vtable+1c
virtual MxResult Start(MxDSAction* action) override; // vtable+20 virtual MxResult Start(MxDSAction* action) override; // vtable+20
virtual MxResult DeleteObject(MxDSAction& ds) override; // vtable+24 virtual MxResult DeleteObject(MxDSAction& ds) override; // vtable+24
virtual MxBool DoesEntityExist(MxDSAction& ds) override; // vtable+28 virtual MxBool DoesEntityExist(MxDSAction& ds) override; // vtable+28
virtual int Vtable0x30(char*, int, MxCore*) override; // vtable+30 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 NotifyCurrentEntity(MxNotificationParam* p_param) override; // vtable+34
virtual void StartTimer() override; // vtable+38 virtual void StartTimer() override; // vtable+38
virtual void StopTimer() override; // vtable+3c virtual void StopTimer() override; // vtable+3c
LegoEntity* FindByEntityIdOrAtomId(const MxAtomId& p_atom, MxS32 p_entityid);
LegoVideoManager* GetVideoManager() { return (LegoVideoManager*) m_videoManager; } LegoVideoManager* GetVideoManager() { return (LegoVideoManager*) m_videoManager; }
LegoSoundManager* GetSoundManager() { return (LegoSoundManager*) m_soundManager; } LegoSoundManager* GetSoundManager() { return (LegoSoundManager*) m_soundManager; }
@ -79,6 +110,7 @@ class LegoOmni : public MxOmni {
LegoGameState* GetGameState() { return m_gameState; } LegoGameState* GetGameState() { return m_gameState; }
MxBackgroundAudioManager* GetBackgroundAudioManager() { return m_bkgAudioManager; } MxBackgroundAudioManager* GetBackgroundAudioManager() { return m_bkgAudioManager; }
MxTransitionManager* GetTransitionManager() { return m_transitionManager; } MxTransitionManager* GetTransitionManager() { return m_transitionManager; }
MxDSAction& GetCurrentAction() { return m_action; }
private: private:
undefined4 m_unk68; undefined4 m_unk68;
@ -124,5 +156,9 @@ LegoPlantManager* PlantManager();
MxBool KeyValueStringParse(char*, const char*, const char*); MxBool KeyValueStringParse(char*, const char*, const char*);
LegoWorld* GetCurrentWorld(); LegoWorld* GetCurrentWorld();
GifManager* GetGifManager(); GifManager* GetGifManager();
MxDSAction& GetCurrentAction();
void RegisterScripts();
void UnregisterScripts();
#endif // LEGOOMNI_H #endif // LEGOOMNI_H

View File

@ -1,16 +1,96 @@
#include "legoroi.h" #include "legoroi.h"
// 0x10101368 #include <string.h>
int g_roiConfig = 100;
// OFFSET: LEGO1 0x100a9e10 // SIZE 0x14
void LegoROI::SetDisplayBB(int p_displayBB) typedef struct {
{ const char* m_name;
// Intentionally empty function 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 // OFFSET: LEGO1 0x100a81c0
void LegoROI::configureLegoROI(int p_roi) void LegoROI::configureLegoROI(MxS32 p_roi)
{ {
g_roiConfig = 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 #ifndef LEGOROI_H
#define LEGOROI_H #define LEGOROI_H
#include "mxtypes.h"
typedef MxBool (*ROIHandler)(char*, char*, MxU32);
class LegoROI { class LegoROI {
public: public:
__declspec(dllexport) void SetDisplayBB(int p_displayBB); __declspec(dllexport) void SetDisplayBB(MxS32 p_displayBB);
__declspec(dllexport) static void configureLegoROI(int p_roi); __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 #endif // LEGOROI_H

View File

@ -1,7 +1,17 @@
#include "legotexturepresenter.h" #include "legotexturepresenter.h"
// OFFSET: LEGO1 0x1004eb40 STUB #include "legoomni.h"
#include "legovideomanager.h"
// OFFSET: LEGO1 0x1004eb40
LegoTexturePresenter::~LegoTexturePresenter() 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); return !strcmp(name, LegoTexturePresenter::ClassName()) || MxMediaPresenter::IsA(name);
} }
virtual MxResult AddToManager() override; // vtable+0x34
}; };
#endif // LEGOTEXTUREPRESENTER_H #endif // LEGOTEXTUREPRESENTER_H

View File

@ -2,16 +2,57 @@
DECOMP_SIZE_ASSERT(LegoVideoManager, 0x590); DECOMP_SIZE_ASSERT(LegoVideoManager, 0x590);
// OFFSET: LEGO1 0x1007aa20 STUB // OFFSET: LEGO1 0x1007aa20
LegoVideoManager::LegoVideoManager() 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() 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 // OFFSET: LEGO1 0x1007c560 STUB

View File

@ -33,20 +33,42 @@ class LegoVideoManager : public MxVideoManager {
this->m_videoParam.GetPalette()->SetOverrideSkyColor(p_shouldOverride); this->m_videoParam.GetPalette()->SetOverrideSkyColor(p_shouldOverride);
} }
virtual void Destroy() override; // vtable+0x18
private: private:
undefined4 m_unk64; undefined4 m_unk64;
Lego3DManager* m_3dManager; Lego3DManager* m_3dManager; // 0x68
undefined4 m_unk6c; undefined4 m_unk6c;
undefined4 m_unk70; undefined4 m_unk70;
MxDirect3D* m_direct3d; MxDirect3D* m_direct3d; // 0x74
undefined m_pad0x78[0x6c]; undefined4 m_unk0x78[27];
MxBool m_unk0xe4; 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 MxBool m_cursorMoved; // 0x501
undefined m_pad0x502[0x8]; MxS32 m_cursorXCopy; // 0x504
MxS32 m_cursorX; // 0x50c MxS32 m_cursorYCopy; // 0x508
MxS32 m_cursorY; // 0x510 MxS32 m_cursorX; // 0x50c
undefined m_pad0x514[0x7c]; 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 #endif // LEGOVIDEOMANAGER_H

View File

@ -1,9 +1,12 @@
#include "legoworldpresenter.h" #include "legoworldpresenter.h"
// OFFSET: LEGO1 0x100665c0 STUB // 0x100f75d4
undefined4 g_LegoWorldPresenterQuality = 1;
// OFFSET: LEGO1 0x100665c0
LegoWorldPresenter::LegoWorldPresenter() LegoWorldPresenter::LegoWorldPresenter()
{ {
// TODO m_unk50 = 50000;
} }
// OFFSET: LEGO1 0x10066770 STUB // OFFSET: LEGO1 0x10066770 STUB
@ -12,8 +15,8 @@ LegoWorldPresenter::~LegoWorldPresenter()
// TODO // TODO
} }
// OFFSET: LEGO1 0x100665b0 STUB // OFFSET: LEGO1 0x100665b0
void LegoWorldPresenter::configureLegoWorldPresenter(int param_1) 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); return !strcmp(name, LegoWorldPresenter::ClassName()) || LegoEntityPresenter::IsA(name);
} }
private:
undefined4 m_unk50;
}; };
#endif // LEGOWORLDPRESENTER_H #endif // LEGOWORLDPRESENTER_H

View File

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

View File

@ -1,6 +1,10 @@
#include "mxbackgroundaudiomanager.h" #include "mxbackgroundaudiomanager.h"
#include "legoomni.h"
#include "mxcompositepresenter.h"
#include "mxdssound.h"
#include "mxomni.h" #include "mxomni.h"
#include "mxpresenter.h"
#include "mxstreamer.h" #include "mxstreamer.h"
#include "mxticklemanager.h" #include "mxticklemanager.h"
@ -14,7 +18,7 @@ MxBackgroundAudioManager::MxBackgroundAudioManager()
m_unk138 = 0; m_unk138 = 0;
m_unk13c = 0; m_unk13c = 0;
m_unk140 = 0; m_unk140 = 0;
m_unk144 = 0; m_targetVolume = 0;
m_unk148 = 0; m_unk148 = 0;
m_musicEnabled = FALSE; m_musicEnabled = FALSE;
} }
@ -47,6 +51,32 @@ void MxBackgroundAudioManager::Stop()
m_unk13c = 0; 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 // OFFSET: LEGO1 0x1007f5f0
void MxBackgroundAudioManager::Enable(MxBool p) void MxBackgroundAudioManager::Enable(MxBool p)
{ {
@ -106,3 +136,191 @@ void MxBackgroundAudioManager::DestroyMusic()
m_musicEnabled = FALSE; 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 #ifndef MXBACKGROUNDAUDIOMANAGER_H
#define MXBACKGROUNDAUDIOMANAGER_H #define MXBACKGROUNDAUDIOMANAGER_H
#include "mxaudiopresenter.h"
#include "mxcore.h" #include "mxcore.h"
#include "mxdsaction.h" #include "mxdsaction.h"
#include "mxnotificationmanager.h" #include "mxnotificationmanager.h"
#include "mxpresenter.h"
#include "mxtypes.h" #include "mxtypes.h"
// VTABLE 0x100d9fe8 // VTABLE 0x100d9fe8
@ -13,6 +15,9 @@ class MxBackgroundAudioManager : public MxCore {
MxBackgroundAudioManager(); MxBackgroundAudioManager();
virtual ~MxBackgroundAudioManager() override; virtual ~MxBackgroundAudioManager() override;
virtual MxLong Notify(MxParam& p) override; // vtable+0x04
virtual MxResult Tickle() override; // vtable+0x08
// OFFSET: LEGO1 0x1007eb70 // OFFSET: LEGO1 0x1007eb70
inline virtual const char* ClassName() const override // vtable+0x0c 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); 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); __declspec(dllexport) void Enable(unsigned char p);
virtual MxResult Create(MxAtomId& p_script, MxU32 p_frequencyMS); virtual MxResult Create(MxAtomId& p_script, MxU32 p_frequencyMS);
void Stop(); void Stop();
void LowerVolume();
void RaiseVolume();
private: private:
void Init(); void Init();
@ -38,12 +53,12 @@ class MxBackgroundAudioManager : public MxCore {
MxBool m_musicEnabled; // 0x8 MxBool m_musicEnabled; // 0x8
MxDSAction m_action1; // 0xc MxDSAction m_action1; // 0xc
MxS32 m_unka0; MxAudioPresenter* m_unka0;
MxDSAction m_action2; // 0xa4 MxDSAction m_action2; // 0xa4
MxS32 m_unk138; MxAudioPresenter* m_unk138;
MxS32 m_unk13c; MxS32 m_unk13c;
MxS32 m_unk140; MxS32 m_unk140;
MxS32 m_unk144; MxS32 m_targetVolume;
MxS16 m_unk148; MxS16 m_unk148;
MxAtomId m_script; 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); 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); 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; MxUnkList m_list;
}; };

View File

@ -1,5 +1,8 @@
#include "mxcontrolpresenter.h" #include "mxcontrolpresenter.h"
#include "legoomni.h"
#include "mxticklemanager.h"
DECOMP_SIZE_ASSERT(MxControlPresenter, 0x5c) DECOMP_SIZE_ASSERT(MxControlPresenter, 0x5c)
// OFFSET: LEGO1 0x10043f50 // OFFSET: LEGO1 0x10043f50
@ -12,3 +15,21 @@ MxControlPresenter::MxControlPresenter()
this->m_unk58 = 0; this->m_unk58 = 0;
this->m_unk54 = 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 { class MxControlPresenter : public MxCompositePresenter {
public: public:
MxControlPresenter(); MxControlPresenter();
virtual ~MxControlPresenter() override;
// OFFSET: LEGO1 0x10044000 // OFFSET: LEGO1 0x10044000
inline virtual const char* ClassName() const override // vtable+0x0c 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); return !strcmp(name, MxControlPresenter::ClassName()) || MxCompositePresenter::IsA(name);
} }
virtual void ReadyTickle() override; // vtable+0x18
private: private:
undefined2 m_unk4c; undefined2 m_unk4c;
MxS16 m_unk4e; MxS16 m_unk4e;
undefined m_unk50; undefined m_unk50;
undefined2 m_unk52; undefined2 m_unk52;
undefined2 m_unk54; undefined2 m_unk54;
undefined4 m_unk58; undefined4* m_unk58;
}; };
#endif // MXCONTROLPRESENTER_H #endif // MXCONTROLPRESENTER_H

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,13 +6,9 @@ DECOMP_SIZE_ASSERT(MxDSActionList, 0x1c);
DECOMP_SIZE_ASSERT(MxDSActionListCursor, 0x10); DECOMP_SIZE_ASSERT(MxDSActionListCursor, 0x10);
// OFFSET: LEGO1 0x100c9c90 // 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 p_a == p_b ? 0 : p_a < p_b ? -1 : 1;
return 0;
if (p_var1 <= p_var0)
return 1;
return -1;
} }
// OFFSET: LEGO1 0x100c9cb0 // OFFSET: LEGO1 0x100c9cb0

View File

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

View File

@ -1,5 +1,8 @@
#include "mxdsbuffer.h" #include "mxdsbuffer.h"
#include "mxomni.h"
#include "mxstreamer.h"
DECOMP_SIZE_ASSERT(MxDSBuffer, 0x34); DECOMP_SIZE_ASSERT(MxDSBuffer, 0x34);
// OFFSET: LEGO1 0x100c6470 // OFFSET: LEGO1 0x100c6470
@ -14,24 +17,112 @@ MxDSBuffer::MxDSBuffer()
m_unk1c = 0; m_unk1c = 0;
m_writeOffset = 0; m_writeOffset = 0;
m_bytesRemaining = 0; m_bytesRemaining = 0;
m_mode = 2; m_mode = MxDSBufferType_Preallocated;
m_unk30 = 0; m_unk30 = 0;
} }
// OFFSET: LEGO1 0x100c6530 // OFFSET: LEGO1 0x100c6530
MxDSBuffer::~MxDSBuffer() 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 // 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_pBuffer = (MxU8*) p_buffer;
m_pIntoBuffer = p_buffer; m_pIntoBuffer = (MxU8*) p_buffer;
m_pIntoBuffer2 = p_buffer; m_pIntoBuffer2 = (MxU8*) p_buffer;
m_bytesRemaining = p_size; m_bytesRemaining = p_size;
m_writeOffset = p_size; m_writeOffset = p_size;
m_mode = 2; m_mode = MxDSBufferType_Preallocated;
return SUCCESS; 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 "decomp.h"
#include "mxcore.h" #include "mxcore.h"
enum MxDSBufferType {
MxDSBufferType_Chunk = 0,
MxDSBufferType_Allocate = 1,
MxDSBufferType_Preallocated = 2,
MxDSBufferType_Unknown = 3,
};
// VTABLE 0x100dcca0 // VTABLE 0x100dcca0
// SIZE 0x34 // SIZE 0x34
class MxDSBuffer : public MxCore { class MxDSBuffer : public MxCore {
@ -18,20 +25,22 @@ class MxDSBuffer : public MxCore {
return "MxDSBuffer"; 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; } inline MxU32 GetWriteOffset() { return m_writeOffset; }
private: private:
void* m_pBuffer; MxU8* m_pBuffer;
void* m_pIntoBuffer; MxU8* m_pIntoBuffer;
void* m_pIntoBuffer2; MxU8* m_pIntoBuffer2;
undefined4 m_unk14; undefined4 m_unk14;
undefined4 m_unk18; undefined4 m_unk18;
undefined4 m_unk1c; undefined4 m_unk1c;
undefined2 m_unk20; undefined2 m_unk20;
undefined4 m_mode; MxDSBufferType m_mode;
MxU32 m_writeOffset; MxU32 m_writeOffset;
MxU32 m_bytesRemaining; MxU32 m_bytesRemaining;
undefined4 m_unk30; undefined4 m_unk30;

View File

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

View File

@ -1,12 +1,20 @@
#ifndef MXDSCHUNK_H #ifndef MXDSCHUNK_H
#define MXDSCHUNK_H #define MXDSCHUNK_H
#include "decomp.h"
#include "mxcore.h" #include "mxcore.h"
#include "mxtypes.h" #include "mxtypes.h"
// VTABLE 0x100dc7f8 // VTABLE 0x100dc7f8
// SIZE 0x1c
class MxDSChunk : public MxCore { class MxDSChunk : public MxCore {
public: public:
enum {
Flag_Bit1 = 0x01,
Flag_Bit2 = 0x02,
Flag_Bit3 = 0x04,
};
MxDSChunk(); MxDSChunk();
virtual ~MxDSChunk() override; virtual ~MxDSChunk() override;
@ -23,13 +31,27 @@ class MxDSChunk : public MxCore {
return !strcmp(name, MxDSChunk::ClassName()) || MxCore::IsA(name); 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: private:
MxS16 m_length; // 0x8 MxU16 m_flags; // 0x8
MxLong m_buffer; // 0xc undefined4 m_unk0c; // 0xc
MxLong m_unk10; // 0x10 MxLong m_time; // 0x10
MxLong m_unk14; // 0x14 MxU32 m_length; // 0x14
void* m_unk18; // 0x18 MxU8* m_data; // 0x18
void* m_unk1c; // 0x1c
}; };
#endif // MXDSCHUNK_H #endif // MXDSCHUNK_H

View File

@ -30,7 +30,7 @@ void MxDSSelectAction::CopyFrom(MxDSSelectAction& p_dsSelectAction)
MxStringListCursor cursor(p_dsSelectAction.m_unk0xac); MxStringListCursor cursor(p_dsSelectAction.m_unk0xac);
MxString string; MxString string;
while (cursor.Next(string)) while (cursor.Next(string))
this->m_unk0xac->OtherAppend(string); this->m_unk0xac->Append(string);
} }
// OFFSET: LEGO1 0x100cbd50 // OFFSET: LEGO1 0x100cbd50
@ -109,7 +109,7 @@ void MxDSSelectAction::Deserialize(char** p_source, MxS16 p_unk24)
if (!strcmp(string.GetData(), *p_source)) if (!strcmp(string.GetData(), *p_source))
index = i; index = i;
this->m_unk0xac->OtherAppend(*p_source); this->m_unk0xac->Append(*p_source);
*p_source += strlen(*p_source) + 1; *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 void Deserialize(char** p_source, MxS16 p_unk24) override; // vtable+1c;
virtual MxDSAction* Clone() override; // vtable+2c; virtual MxDSAction* Clone() override; // vtable+2c;
inline MxS32 GetVolume() const { return m_volume; }
private: private:
MxU32 m_sizeOnDisk; MxU32 m_sizeOnDisk;
MxS32 m_volume; // 0xbc MxS32 m_volume; // 0xbc

View File

@ -5,7 +5,7 @@
// OFFSET: LEGO1 0x100bffd0 // OFFSET: LEGO1 0x100bffd0
void MxDSSource::ReadToBuffer(MxDSBuffer* p_buffer) 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 // OFFSET: LEGO1 0x100bfff0

View File

@ -1,13 +1,42 @@
#include "mxdssubscriber.h" #include "mxdssubscriber.h"
// OFFSET: LEGO1 0x100b7bb0 DECOMP_SIZE_ASSERT(MxDSSubscriber, 0x4c);
// OFFSET: LEGO1 0x100b7bb0 STUB
MxDSSubscriber::MxDSSubscriber() MxDSSubscriber::MxDSSubscriber()
{ {
// TODO // TODO
} }
// OFFSET: LEGO1 0x100b7e00 // OFFSET: LEGO1 0x100b7e00 STUB
MxDSSubscriber::~MxDSSubscriber() MxDSSubscriber::~MxDSSubscriber()
{ {
// TODO // 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 #ifndef MXDSSUBSCRIBER_H
#define MXDSSUBSCRIBER_H #define MXDSSUBSCRIBER_H
#include "decomp.h"
#include "mxcore.h" #include "mxcore.h"
#include "mxdschunk.h"
#include "mxstreamchunk.h"
#include "mxstreamcontroller.h"
// VTABLE 0x100dc698 // VTABLE 0x100dc698
// SIZE 0x4c // SIZE 0x4c
@ -22,6 +26,14 @@ class MxDSSubscriber : public MxCore {
{ {
return !strcmp(name, MxDSSubscriber::ClassName()) || MxCore::IsA(name); 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 #endif // MXDSSUBSCRIBER_H

View File

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

View File

@ -24,7 +24,8 @@ class MxEventPresenter : public MxMediaPresenter {
return !strcmp(name, MxEventPresenter::ClassName()) || MxMediaPresenter::IsA(name); 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: private:
void Init(); void Init();

View File

@ -1,13 +1,11 @@
#ifndef MXHASHTABLE_H #ifndef MXHASHTABLE_H
#define MXHASHTABLE_H #define MXHASHTABLE_H
#include "mxcollection.h"
#include "mxcore.h" #include "mxcore.h"
#include "mxtypes.h" #include "mxtypes.h"
#define HASH_TABLE_INIT_SIZE 128 #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> template <class T>
class MxHashTableCursor; class MxHashTableCursor;
@ -15,8 +13,7 @@ class MxHashTableCursor;
template <class T> template <class T>
class MxHashTableNode { class MxHashTableNode {
public: public:
MxHashTableNode<T>() {} MxHashTableNode<T>(T p_obj, MxU32 p_hash)
MxHashTableNode<T>(T* p_obj, MxU32 p_hash)
{ {
m_obj = p_obj; m_obj = p_obj;
m_hash = p_hash; m_hash = p_hash;
@ -24,55 +21,39 @@ class MxHashTableNode {
m_next = NULL; m_next = NULL;
} }
// private: // DECOMP: Should use getter and setter methods here per the style guide.
T* m_obj; // However, LEGO1D (with no functions inlined) does not use them.
T m_obj;
MxU32 m_hash; MxU32 m_hash;
MxHashTableNode* m_prev; MxHashTableNode* m_prev;
MxHashTableNode* m_next; MxHashTableNode* m_next;
}; };
// See MxOmni::Create
// VTABLE 0x100dc1b0
template <class T> template <class T>
class HashTableParent : public MxCore { class MxHashTable : protected MxCollection<T> {
public: public:
HashTableParent() enum HashTableOpt {
{ HashTableOpt_NoExpand = 0,
m_numKeys = 0; HashTableOpt_ExpandAdd = 1,
m_customDestructor = Destroy; 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() MxHashTable()
{ {
m_numSlots = HASH_TABLE_INIT_SIZE; m_numSlots = HASH_TABLE_INIT_SIZE;
m_slots = new MxHashTableNode<T>*[HASH_TABLE_INIT_SIZE]; m_slots = new MxHashTableNode<T>*[HASH_TABLE_INIT_SIZE];
memset(m_slots, 0, sizeof(MxHashTableNode<T>*) * m_numSlots); 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 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>; friend class MxHashTableCursor<T>;
protected: protected:
@ -80,91 +61,108 @@ class MxHashTable : protected HashTableParent<T> {
MxHashTableNode<T>** m_slots; // +0x10 MxHashTableNode<T>** m_slots; // +0x10
MxU32 m_numSlots; // +0x14 MxU32 m_numSlots; // +0x14
MxU32 m_autoResizeRatio; MxU32 m_autoResizeRatio; // +0x18
int m_resizeOption; // +0x1c HashTableOpt m_resizeOption; // +0x1c
// FIXME: or FIXME? This qword is used as an integer or double depending // 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 // 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. // did it, but a simple cast in either direction doesn't match.
union { union {
MxU32 m_increaseAmount; MxU32 m_increaseAmount; // +0x20
double m_increaseFactor; double m_increaseFactor; // +0x20
}; };
}; };
template <class T> template <class T>
class MxHashTableCursor : public MxCore { class MxHashTableCursor : public MxCore {
public: public:
MxHashTableCursor(MxHashTable<T>* p_hashTable) MxHashTableCursor(MxHashTable<T>* p_table)
{ {
m_table = p_hashTable; m_table = p_table;
m_match = NULL; m_match = NULL;
} }
MxBool Find(T* p_obj) MxBool Find(T p_obj);
{ MxBool Current(T& p_obj);
MxU32 hash = m_table->Hash(p_obj); void DeleteMatch();
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--;
}
private: private:
MxHashTable<T>* m_table; MxHashTable<T>* m_table;
MxHashTableNode<T>* m_match; 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> template <class T>
MxHashTable<T>::~MxHashTable() 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]; MxHashTableNode<T>* t = m_slots[i];
while (t) { while (t) {
MxHashTableNode<T>* next = t->m_next; MxHashTableNode<T>* next = t->m_next;
this->m_customDestructor(t->m_obj); m_customDestructor(t->m_obj);
delete t; delete t;
t = next; t = next;
} }
} }
this->m_numKeys = 0; m_count = 0;
memset(m_slots, 0, sizeof(MxHashTableNode<T>*) * m_numSlots); memset(m_slots, 0, sizeof(MxHashTableNode<T>*) * m_numSlots);
delete[] m_slots; delete[] m_slots;
@ -179,21 +177,20 @@ inline void MxHashTable<T>::Resize()
MxHashTableNode<T>** old_table = m_slots; MxHashTableNode<T>** old_table = m_slots;
switch (m_resizeOption) { switch (m_resizeOption) {
case HASH_TABLE_OPT_EXPAND_ADD: case HashTableOpt_ExpandAdd:
m_numSlots += m_increaseAmount; m_numSlots += m_increaseAmount;
break; break;
case HASH_TABLE_OPT_EXPAND_MULTIPLY: case HashTableOpt_ExpandMultiply:
m_numSlots *= m_increaseFactor; m_numSlots *= m_increaseFactor;
break; break;
} }
MxHashTableNode<T>** new_table = new MxHashTableNode<T>*[m_numSlots]; MxHashTableNode<T>** new_table = new MxHashTableNode<T>*[m_numSlots];
// FIXME: order? m_numKeys set after `rep stosd`
m_slots = new_table; m_slots = new_table;
memset(m_slots, 0, sizeof(MxHashTableNode<T>*) * m_numSlots); 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]; MxHashTableNode<T>* t = old_table[i];
while (t) { while (t) {
@ -209,7 +206,7 @@ inline void MxHashTable<T>::Resize()
template <class T> template <class T>
inline void MxHashTable<T>::_NodeInsert(MxHashTableNode<T>* p_node) 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]; 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]->m_prev = p_node;
m_slots[bucket] = p_node; m_slots[bucket] = p_node;
this->m_numKeys++; m_count++;
} }
template <class T> 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(); MxHashTable<T>::Resize();
MxU32 hash = Hash(p_newobj); MxU32 hash = Hash(p_newobj);
@ -232,4 +229,6 @@ inline void MxHashTable<T>::Add(T* p_newobj)
MxHashTable<T>::_NodeInsert(node); MxHashTable<T>::_NodeInsert(node);
} }
#undef HASH_TABLE_INIT_SIZE
#endif // MXHASHTABLE_H #endif // MXHASHTABLE_H

View File

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

View File

@ -1,5 +1,12 @@
#include "mxmediapresenter.h" #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); DECOMP_SIZE_ASSERT(MxMediaPresenter, 0x50);
// OFFSET: LEGO1 0x1000c550 // OFFSET: LEGO1 0x1000c550
@ -8,38 +15,151 @@ MxMediaPresenter::~MxMediaPresenter()
Destroy(TRUE); Destroy(TRUE);
} }
// OFFSET: LEGO1 0x100b5d10 STUB // OFFSET: LEGO1 0x1000c5b0
MxResult MxMediaPresenter::Tickle() void MxMediaPresenter::Destroy()
{ {
// TODO Destroy(FALSE);
return SUCCESS;
} }
// OFFSET: LEGO1 0x100b54e0 // OFFSET: LEGO1 0x100b54e0
void MxMediaPresenter::Init() void MxMediaPresenter::Init()
{ {
this->m_unk40 = NULL; this->m_subscriber = NULL;
this->m_unk44 = NULL; this->m_chunks = NULL;
this->m_unk48 = NULL; this->m_cursor = NULL;
this->m_unk4c = NULL; this->m_currentChunk = NULL;
} }
// OFFSET: LEGO1 0x100b54f0 STUB // OFFSET: LEGO1 0x100b54f0
void MxMediaPresenter::Destroy(MxBool p_fromDestructor) 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() 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() 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 // OFFSET: LEGO1 0x100b5ef0
@ -50,32 +170,99 @@ void MxMediaPresenter::DoneTickle()
EndAction(); EndAction();
} }
// OFFSET: LEGO1 0x100b6030 STUB // OFFSET: LEGO1 0x100b6030
void MxMediaPresenter::Enable(MxBool p_enable) 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 // OFFSET: LEGO1 0x100b5700
void MxMediaPresenter::Destroy() 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 // OFFSET: LEGO1 0x100b5bc0
MxLong MxMediaPresenter::StartAction(MxStreamController* p_controller, MxDSAction* p_action)
{
return 0;
}
// OFFSET: LEGO1 0x100b5bc0 STUB
void MxMediaPresenter::EndAction() 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 // OFFSET: LEGO1 0x100b5f10
void MxMediaPresenter::VTable0x58() 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 #define MXMEDIAPRESENTER_H
#include "decomp.h" #include "decomp.h"
#include "mxdssubscriber.h"
#include "mxpresenter.h" #include "mxpresenter.h"
#include "mxstreamchunklist.h"
// VTABLE 0x100d4cd8 // VTABLE 0x100d4cd8
// SIZE 0x50
class MxMediaPresenter : public MxPresenter { class MxMediaPresenter : public MxPresenter {
public: public:
inline MxMediaPresenter() { Init(); } inline MxMediaPresenter() { Init(); }
virtual ~MxMediaPresenter() override; virtual ~MxMediaPresenter() override;
virtual MxResult Tickle() override; virtual MxResult Tickle() override; // vtable+0x8
// OFFSET: LEGO1 0x1000c5c0 // OFFSET: LEGO1 0x1000c5c0
inline virtual const char* ClassName() const override // vtable+0xc 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); return !strcmp(name, MxMediaPresenter::ClassName()) || MxPresenter::IsA(name);
} }
virtual void StreamingTickle() override; virtual void StreamingTickle() override; // vtable+0x20
virtual void RepeatingTickle() override; virtual void RepeatingTickle() override; // vtable+0x24
virtual void DoneTickle() override; virtual void DoneTickle() override; // vtable+0x2c
virtual void Destroy() override; virtual void Destroy() override; // vtable+0x38
virtual MxLong StartAction(MxStreamController*, MxDSAction*) override; virtual MxResult StartAction(MxStreamController*, MxDSAction*) override; // vtable+0x3c
virtual void EndAction() override; virtual void EndAction() override; // vtable+0x40
virtual void Enable(MxBool p_enable) override; virtual void Enable(MxBool p_enable) override; // vtable+0x54
virtual void VTable0x58(); virtual void AppendChunk(MxStreamChunk* p_chunk); // vtable+0x58
undefined4 m_unk40;
undefined4 m_unk44;
undefined4 m_unk48;
undefined4 m_unk4c;
protected: protected:
MxDSSubscriber* m_subscriber; // 0x40
MxStreamChunkList* m_chunks; // 0x44
MxStreamChunkListCursor* m_cursor; // 0x48
MxStreamChunk* m_currentChunk; // 0x4c
void Init(); void Init();
void Destroy(MxBool p_fromDestructor); void Destroy(MxBool p_fromDestructor);
MxStreamChunk* FUN_100b5650();
MxStreamChunk* NextChunk();
}; };
#endif // MXMEDIAPRESENTER_H #endif // MXMEDIAPRESENTER_H

View File

@ -4,6 +4,34 @@
#include "mxcore.h" #include "mxcore.h"
// VTABLE 0x100dc9a0 // 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 #endif // MXNEXTACTIONDATASTART_H

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,11 +6,7 @@ DECOMP_SIZE_ASSERT(MxPresenterList, 0x18);
DECOMP_SIZE_ASSERT(MxPresenterListCursor, 0x10); DECOMP_SIZE_ASSERT(MxPresenterListCursor, 0x10);
// OFFSET: LEGO1 0x1001cd00 // 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 p_a == p_b ? 0 : p_a < p_b ? -1 : 1;
return 0;
if (p_var1 <= p_var0)
return 1;
return -1;
} }

View File

@ -17,7 +17,7 @@ class MxPresenterListParent : public MxList<MxPresenter*> {
// SIZE 0x18 // SIZE 0x18
class MxPresenterList : public MxPresenterListParent { class MxPresenterList : public MxPresenterListParent {
public: public:
virtual MxS8 Compare(MxPresenter*, MxPresenter*); // +0x14 virtual MxS8 Compare(MxPresenter*, MxPresenter*) override; // +0x14
}; };
typedef MxListCursorChildChild<MxPresenter*> MxPresenterListCursor; 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)->GetBufferOfFileSize(),
((MxRAMStreamProvider*) m_provider)->GetFileSize() ((MxRAMStreamProvider*) m_provider)->GetFileSize()
); );
m_buffer.FUN_100c6780( m_buffer.SetBufferPointer(
((MxRAMStreamProvider*) m_provider)->GetBufferOfFileSize(), ((MxRAMStreamProvider*) m_provider)->GetBufferOfFileSize(),
((MxRAMStreamProvider*) m_provider)->GetFileSize() ((MxRAMStreamProvider*) m_provider)->GetFileSize()
); );

View File

@ -9,6 +9,19 @@ class MxRAMStreamProvider : public MxStreamProvider {
MxRAMStreamProvider(); MxRAMStreamProvider();
virtual ~MxRAMStreamProvider() override; 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 MxResult SetResourceToGet(MxStreamController* p_resource) override; // vtable+0x14
virtual MxU32 GetFileSize() override; // vtable+0x18 virtual MxU32 GetFileSize() override; // vtable+0x18
virtual MxU32 GetStreamBuffersNum() override; // vtable+0x1c virtual MxU32 GetStreamBuffersNum() override; // vtable+0x1c

View File

@ -1,6 +1,9 @@
#ifndef MXRECT32_H #ifndef MXRECT32_H
#define MXRECT32_H #define MXRECT32_H
#include "mxpoint32.h"
#include "mxsize32.h"
class MxRect32 { class MxRect32 {
public: public:
MxRect32() {} MxRect32() {}
@ -12,14 +15,72 @@ class MxRect32 {
this->m_bottom = p_bottom; 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_left;
MxS32 m_top; MxS32 m_top;
MxS32 m_right; MxS32 m_right;
MxS32 m_bottom; MxS32 m_bottom;
inline MxS32 GetWidth() { return (m_right - m_left) + 1; }
inline MxS32 GetHeight() { return (m_bottom - m_top) + 1; }
}; };
#endif // MXRECT32_H #endif // MXRECT32_H

View File

@ -1,40 +1,198 @@
#include "mxregion.h" #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() 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 // OFFSET: LEGO1 0x100c3660
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
MxBool MxRegion::vtable20() 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; return FALSE;
} }

View File

@ -4,6 +4,51 @@
#include "decomp.h" #include "decomp.h"
#include "mxcore.h" #include "mxcore.h"
#include "mxrect32.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 // VTABLE 0x100dcae8
// SIZE 0x1c // SIZE 0x1c
@ -14,15 +59,13 @@ class MxRegion : public MxCore {
virtual void Reset(); virtual void Reset();
virtual void vtable18(MxRect32& p_rect); virtual void vtable18(MxRect32& p_rect);
virtual void vtable1c(); virtual MxBool vtable1c(MxRect32& p_rect);
virtual MxBool vtable20(); virtual MxBool vtable20();
inline MxRect32& GetRect() { return this->m_rect; } inline MxRect32& GetRect() { return this->m_rect; }
private: private:
// A container (probably MxList) holding MxRect32 MxRegionList* m_list;
// MxList<MxRect32*> *m_rects;
undefined4 m_unk08;
MxRect32 m_rect; 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 "mxsmkpresenter.h"
#include "decomp.h" #include "decomp.h"
#include "mxvideomanager.h"
DECOMP_SIZE_ASSERT(MxSmkPresenter, 0x720); DECOMP_SIZE_ASSERT(MxSmkPresenter, 0x720);
@ -65,3 +66,48 @@ void MxSmkPresenter::FUN_100c5d40(MxSmack* p_mxSmack)
if (p_mxSmack->m_unk0x6b4) if (p_mxSmack->m_unk0x6b4)
delete 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(); MxSmkPresenter();
virtual ~MxSmkPresenter() override; 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 VTable0x60() override;
virtual void VTable0x68(undefined4 p_unknown1) override; // vtable+0x68
virtual void VTable0x70() override;
virtual MxU32 VTable0x88();
struct MxSmack { struct MxSmack {
Smack m_smack; Smack m_smack;

View File

@ -1,5 +1,6 @@
#include "mxsoundmanager.h" #include "mxsoundmanager.h"
#include "define.h"
#include "mxautolocker.h" #include "mxautolocker.h"
#include "mxomni.h" #include "mxomni.h"
#include "mxpresenter.h" #include "mxpresenter.h"
@ -127,6 +128,53 @@ MxResult MxSoundManager::Create(MxU32 p_frequencyMS, MxBool p_createThread)
return status; 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 // OFFSET: LEGO1 0x100aed10
void MxSoundManager::vtable0x34() void MxSoundManager::vtable0x34()
{ {
@ -152,25 +200,3 @@ void MxSoundManager::vtable0x38()
if (presenter->IsA("MxWavePresenter")) if (presenter->IsA("MxWavePresenter"))
((MxWavePresenter*) presenter)->VTable0x68(); ((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 #define MXSOUNDMANAGER_H
#include "decomp.h" #include "decomp.h"
#include "mxatomid.h"
#include "mxaudiomanager.h" #include "mxaudiomanager.h"
#include <dsound.h> #include <dsound.h>
@ -11,6 +12,9 @@
class MxSoundManager : public MxAudioManager { class MxSoundManager : public MxAudioManager {
public: public:
MxSoundManager(); MxSoundManager();
// OFFSET: LEGO1 0x100ae7b0 TEMPLATE
// MxSoundManager::`scalar deleting destructor'
virtual ~MxSoundManager() override; // vtable+0x0 virtual ~MxSoundManager() override; // vtable+0x0
virtual void Destroy() override; // vtable+18 virtual void Destroy() override; // vtable+18
@ -22,6 +26,8 @@ class MxSoundManager : public MxAudioManager {
private: private:
void Init(); void Init();
void Destroy(MxBool p_fromDestructor); 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 LPDIRECTSOUND m_directSound; // 0x30
LPDIRECTSOUNDBUFFER m_dsBuffer; // 0x34 LPDIRECTSOUNDBUFFER m_dsBuffer; // 0x34

View File

@ -8,6 +8,19 @@
// SIZE 0x6c // SIZE 0x6c
class MxStillPresenter : public MxVideoPresenter { class MxStillPresenter : public MxVideoPresenter {
public: 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 virtual void ParseExtra() override; // vtable+0x30
MxStillPresenter() { m_unk68 = 0; } MxStillPresenter() { m_unk68 = 0; }

View File

@ -4,6 +4,26 @@
#include "mxdschunk.h" #include "mxdschunk.h"
// VTABLE 0x100dc2a8 // 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 #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 "legoomni.h"
#include "mxautolocker.h" #include "mxautolocker.h"
#include "mxnextactiondatastart.h"
DECOMP_SIZE_ASSERT(MxNextActionDataStart, 0x14)
// OFFSET: LEGO1 0x100c0b90 STUB // OFFSET: LEGO1 0x100c0b90 STUB
MxStreamController::MxStreamController() MxStreamController::MxStreamController()
@ -74,16 +77,32 @@ MxResult MxStreamController::vtable0x24(undefined4 p_unknown)
return FAILURE; 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 // OFFSET: LEGO1 0x100b9420
MxResult MxStreamController::vtable0x28() MxResult MxStreamController::vtable0x28()
{ {
return SUCCESS; return SUCCESS;
} }
// OFFSET: LEGO1 0x100c1c10 STUB // OFFSET: LEGO1 0x100c1c10
MxResult MxStreamController::vtable0x2c(MxDSAction* p_action, MxU32 p_bufferval) 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 // OFFSET: LEGO1 0x100c1ce0 STUB
@ -91,3 +110,9 @@ MxResult MxStreamController::vtable0x30(undefined4 p_unknown)
{ {
return FAILURE; 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 vtable0x1C(undefined4 p_unknown, undefined4 p_unknown2); // vtable+0x1c
virtual MxResult vtable0x20(MxDSAction* p_action); // vtable+0x20 virtual MxResult vtable0x20(MxDSAction* p_action); // vtable+0x20
virtual MxResult vtable0x24(undefined4 p_unknown); // vtable+0x24 virtual MxResult vtable0x24(undefined4 p_unknown); // vtable+0x24
virtual MxResult vtable0x28(); // vtable+0x28 MxResult FUN_100c1800(MxDSAction* p_action, MxU32 p_val);
virtual MxResult vtable0x2c(MxDSAction* p_action, MxU32 p_bufferval); // vtable+0x2c virtual MxResult vtable0x28(); // vtable+0x28
virtual MxResult vtable0x30(undefined4 p_unknown); // vtable+0x30 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); MxBool FUN_100c20d0(MxDSObject& p_obj);
MxResult FUN_100c1a00(MxDSAction* p_action, MxU32 p_bufferval);
inline MxAtomId& GetAtom() { return atom; }; inline MxAtomId& GetAtom() { return atom; };

View File

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

View File

@ -18,6 +18,7 @@ class MxString : public MxCore {
MxString operator+(const char*); MxString operator+(const char*);
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; } inline const char* GetData() const { return m_data; }
private: private:

View File

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

View File

@ -468,7 +468,7 @@ void MxTransitionManager::SetWaitIndicator(MxVideoPresenter* p_waitIndicator)
{ {
// End current wait indicator // End current wait indicator
if (m_waitIndicator != NULL) { 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->EndAction();
m_waitIndicator = NULL; m_waitIndicator = NULL;
} }

View File

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

View File

@ -7,27 +7,51 @@
// VTABLE 0x100dc1c8 // VTABLE 0x100dc1c8
// SIZE 0x28 // SIZE 0x28
class MxVariableTable : public MxHashTable<MxVariable> { class MxVariableTable : public MxHashTable<MxVariable*> {
public: public:
MxVariableTable() { m_customDestructor = Destroy; } MxVariableTable() { m_customDestructor = Destroy; }
__declspec(dllexport) void SetVariable(const char* key, const char* value); __declspec(dllexport) void SetVariable(const char* p_key, const char* p_value);
__declspec(dllexport) void SetVariable(MxVariable* var); __declspec(dllexport) void SetVariable(MxVariable* p_var);
__declspec(dllexport) const char* GetVariable(const char* key); __declspec(dllexport) const char* GetVariable(const char* p_key);
// OFFSET: LEGO1 0x100afdb0 // OFFSET: LEGO1 0x100afdb0
static void Destroy(MxVariable* p_obj) { p_obj->Destroy(); } static void Destroy(MxVariable* p_obj) { p_obj->Destroy(); }
virtual MxS8 Compare(MxVariable*, MxVariable*); // +0x14 virtual MxS8 Compare(MxVariable*, MxVariable*) override; // +0x14
virtual MxU32 Hash(MxVariable*); // +0x18 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 // 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 // OFFSET: LEGO1 0x100b7ab0 TEMPLATE
// MxHashTable<MxVariable>::Resize // MxHashTable<MxVariable *>::Resize
// OFFSET: LEGO1 0x100b7b80 TEMPLATE // 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 #endif // MXVARIABLETABLE_H

View File

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

View File

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

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