Merge remote-tracking branch 'upstream/master' into impl/legoomni-create

This commit is contained in:
Misha 2023-11-05 15:22:34 -05:00
commit b6c5977858
No known key found for this signature in database
GPG Key ID: 8441D12AEF33FED8
47 changed files with 1346 additions and 120 deletions

View File

@ -163,6 +163,7 @@ add_library(lego1 SHARED
LEGO1/mxramstreamcontroller.cpp
LEGO1/mxramstreamprovider.cpp
LEGO1/mxregion.cpp
LEGO1/mxregionlist.cpp
LEGO1/mxscheduler.cpp
LEGO1/mxsemaphore.cpp
LEGO1/mxsmkpresenter.cpp

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -40,6 +40,7 @@ class LegoGameState {
private:
void RegisterState(LegoState* p_state);
MxResult WriteEndOfVariables(LegoStream* p_stream);
void SetROIHandlerFunction();
private:
char* m_savePath; // 0x0
@ -58,4 +59,6 @@ class LegoGameState {
undefined4 m_unk42c;
};
MxBool ROIHandlerFunction(char* p_0, char* p_output, MxU32 p_copyLen);
#endif // LEGOGAMESTATE_H

View File

@ -16,12 +16,90 @@
const char* g_current = "current";
// 0x100f4588
MxAtomId* g_nocdSourceName = NULL;
// 0x100f451c
MxAtomId* g_copterScript = NULL;
// 0x100f4520
MxAtomId* g_dunecarScript = NULL;
// 0x100f4524
MxAtomId* g_jetskiScript = NULL;
// 0x100f4528
MxAtomId* g_racecarScript = NULL;
// 0x100f452c
MxAtomId* g_carraceScript = NULL;
// 0x100f4530
MxAtomId* g_carracerScript = NULL;
// 0x100f4534
MxAtomId* g_jetraceScript = NULL;
// 0x100f4538
MxAtomId* g_jetracerScript = NULL;
// 0x100f453c
MxAtomId* g_isleScript = NULL;
// 0x100f4540
MxAtomId* g_elevbottScript = NULL;
// 0x100f4544
MxAtomId* g_infodoorScript = NULL;
// 0x100f4548
MxAtomId* g_infomainScript = NULL;
// 0x100f454c
MxAtomId* g_infoscorScript = NULL;
// 0x100f4550
MxAtomId* g_regbookScript = NULL;
// 0x100f4554
MxAtomId* g_histbookScript = NULL;
// 0x100f4558
MxAtomId* g_hospitalScript = NULL;
// 0x100f455c
MxAtomId* g_policeScript = NULL;
// 0x100f4560
MxAtomId* g_garageScript = NULL;
// 0x100f4564
MxAtomId* g_act2mainScript = NULL;
// 0x100f4568
MxAtomId* g_act3Script = NULL;
// 0x100f456c
MxAtomId* g_jukeboxScript = NULL;
// 0x100f4570
MxAtomId* g_pz5Script = NULL;
// 0x100f4574
MxAtomId* g_introScript = NULL;
// 0x100f4578
MxAtomId* g_testScript = NULL;
// 0x100f457c
MxAtomId* g_jukeboxwScript = NULL;
// 0x100f4580c
MxAtomId* g_sndAnimScript = NULL;
// 0x100f4584
MxAtomId* g_creditsScript = NULL;
// 0x100f4588
MxAtomId* g_nocdSourceName = NULL;
// 0x101020e8
void (*g_omniUserMessage)(const char*, int);
@ -227,12 +305,29 @@ GifManager* GetGifManager()
return LegoOmni::GetInstance()->GetGifManager();
}
// OFFSET: LEGO1 0x100158e0
MxDSAction& GetCurrentAction()
{
return LegoOmni::GetInstance()->GetCurrentAction();
}
// OFFSET: LEGO1 0x10015900
MxTransitionManager* TransitionManager()
{
return LegoOmni::GetInstance()->GetTransitionManager();
}
// OFFSET: LEGO1 0x10015910
void PlayMusic(MxU32 p_index)
{
// index is the entityid of the music in jukebox.si
MxDSAction action;
action.SetAtomId(*g_jukeboxScript);
action.SetObjectId(p_index);
LegoOmni::GetInstance()->GetBackgroundAudioManager()->PlayMusic(action, 5, 4);
}
// OFFSET: LEGO1 0x100c0280
MxDSObject* CreateStreamObject(MxDSFile* p_file, MxS16 p_ofs)
{
@ -364,9 +459,8 @@ MxResult LegoOmni::Create(MxOmniCreateParam& p)
m_bkgAudioManager = new MxBackgroundAudioManager();
SetAppCursor(1);
result = SUCCESS;
return result;
RegisterScripts();
return SUCCESS;
}
// OFFSET: LEGO1 0x10058c30 STUB
@ -441,3 +535,99 @@ void LegoOmni::StopTimer()
MxOmni::StopTimer();
SetAppCursor(0);
}
// OFFSET: LEGO1 0x100528e0
void RegisterScripts()
{
g_copterScript = new MxAtomId("\\lego\\scripts\\build\\copter", LookupMode_LowerCase2);
g_dunecarScript = new MxAtomId("\\lego\\scripts\\build\\dunecar", LookupMode_LowerCase2);
g_jetskiScript = new MxAtomId("\\lego\\scripts\\build\\jetski", LookupMode_LowerCase2);
g_racecarScript = new MxAtomId("\\lego\\scripts\\build\\racecar", LookupMode_LowerCase2);
g_carraceScript = new MxAtomId("\\lego\\scripts\\race\\carrace", LookupMode_LowerCase2);
g_carracerScript = new MxAtomId("\\lego\\scripts\\race\\carracer", LookupMode_LowerCase2);
g_jetraceScript = new MxAtomId("\\lego\\scripts\\race\\jetrace", LookupMode_LowerCase2);
g_jetracerScript = new MxAtomId("\\lego\\scripts\\race\\jetracer", LookupMode_LowerCase2);
g_isleScript = new MxAtomId("\\lego\\scripts\\isle\\isle", LookupMode_LowerCase2);
g_elevbottScript = new MxAtomId("\\lego\\scripts\\infocntr\\elevbott", LookupMode_LowerCase2);
g_infodoorScript = new MxAtomId("\\lego\\scripts\\infocntr\\infodoor", LookupMode_LowerCase2);
g_infomainScript = new MxAtomId("\\lego\\scripts\\infocntr\\infomain", LookupMode_LowerCase2);
g_infoscorScript = new MxAtomId("\\lego\\scripts\\infocntr\\infoscor", LookupMode_LowerCase2);
g_regbookScript = new MxAtomId("\\lego\\scripts\\infocntr\\regbook", LookupMode_LowerCase2);
g_histbookScript = new MxAtomId("\\lego\\scripts\\infocntr\\histbook", LookupMode_LowerCase2);
g_hospitalScript = new MxAtomId("\\lego\\scripts\\hospital\\hospital", LookupMode_LowerCase2);
g_policeScript = new MxAtomId("\\lego\\scripts\\police\\police", LookupMode_LowerCase2);
g_garageScript = new MxAtomId("\\lego\\scripts\\garage\\garage", LookupMode_LowerCase2);
g_act2mainScript = new MxAtomId("\\lego\\scripts\\act2\\act2main", LookupMode_LowerCase2);
g_act3Script = new MxAtomId("\\lego\\scripts\\act3\\act3", LookupMode_LowerCase2);
g_jukeboxScript = new MxAtomId("\\lego\\scripts\\isle\\jukebox", LookupMode_LowerCase2);
g_pz5Script = new MxAtomId("\\lego\\scripts\\isle\\pz5", LookupMode_LowerCase2);
g_introScript = new MxAtomId("\\lego\\scripts\\intro", LookupMode_LowerCase2);
g_testScript = new MxAtomId("\\lego\\scripts\\test\\test", LookupMode_LowerCase2);
g_jukeboxwScript = new MxAtomId("\\lego\\scripts\\isle\\jukeboxw", LookupMode_LowerCase2);
g_sndAnimScript = new MxAtomId("\\lego\\scripts\\sndanim", LookupMode_LowerCase2);
g_creditsScript = new MxAtomId("\\lego\\scripts\\credits", LookupMode_LowerCase2);
g_nocdSourceName = new MxAtomId("\\lego\\scripts\\nocd", LookupMode_LowerCase2);
}
// OFFSET: LEGO1 0x100530c0
void UnregisterScripts()
{
delete g_copterScript;
delete g_dunecarScript;
delete g_jetskiScript;
delete g_racecarScript;
delete g_carraceScript;
delete g_carracerScript;
delete g_jetraceScript;
delete g_jetracerScript;
delete g_isleScript;
delete g_elevbottScript;
delete g_infodoorScript;
delete g_infomainScript;
delete g_infoscorScript;
delete g_regbookScript;
delete g_histbookScript;
delete g_hospitalScript;
delete g_policeScript;
delete g_garageScript;
delete g_act2mainScript;
delete g_act3Script;
delete g_jukeboxScript;
delete g_pz5Script;
delete g_introScript;
delete g_testScript;
delete g_jukeboxwScript;
delete g_sndAnimScript;
delete g_creditsScript;
delete g_nocdSourceName;
g_copterScript = NULL;
g_dunecarScript = NULL;
g_jetskiScript = NULL;
g_racecarScript = NULL;
g_carraceScript = NULL;
g_carracerScript = NULL;
g_jetraceScript = NULL;
g_jetracerScript = NULL;
g_isleScript = NULL;
g_elevbottScript = NULL;
g_infodoorScript = NULL;
g_infomainScript = NULL;
g_infoscorScript = NULL;
g_regbookScript = NULL;
g_histbookScript = NULL;
g_hospitalScript = NULL;
g_policeScript = NULL;
g_garageScript = NULL;
g_act2mainScript = NULL;
g_act3Script = NULL;
g_jukeboxScript = NULL;
g_pz5Script = NULL;
g_introScript = NULL;
g_testScript = NULL;
g_testScript = NULL;
g_jukeboxwScript = NULL;
g_sndAnimScript = NULL;
g_creditsScript = NULL;
g_nocdSourceName = NULL;
}

View File

@ -26,6 +26,35 @@ class MxBackgroundAudioManager;
class MxDSFile;
class MxTransitionManager;
extern MxAtomId* g_copterScript;
extern MxAtomId* g_dunecarScript;
extern MxAtomId* g_jetskiScript;
extern MxAtomId* g_racecarScript;
extern MxAtomId* g_carraceScript;
extern MxAtomId* g_carracerScript;
extern MxAtomId* g_jetraceScript;
extern MxAtomId* g_jetracerScript;
extern MxAtomId* g_isleScript;
extern MxAtomId* g_elevbottScript;
extern MxAtomId* g_infodoorScript;
extern MxAtomId* g_infomainScript;
extern MxAtomId* g_infoscorScript;
extern MxAtomId* g_regbookScript;
extern MxAtomId* g_histbookScript;
extern MxAtomId* g_hospitalScript;
extern MxAtomId* g_policeScript;
extern MxAtomId* g_garageScript;
extern MxAtomId* g_act2mainScript;
extern MxAtomId* g_act3Script;
extern MxAtomId* g_jukeboxScript;
extern MxAtomId* g_pz5Script;
extern MxAtomId* g_introScript;
extern MxAtomId* g_testScript;
extern MxAtomId* g_jukeboxwScript;
extern MxAtomId* g_sndAnimScript;
extern MxAtomId* g_creditsScript;
extern MxAtomId* g_nocdSourceName;
// VTABLE 0x100d8638
// SIZE: 0x140
class LegoOmni : public MxOmni {
@ -81,6 +110,7 @@ class LegoOmni : public MxOmni {
LegoGameState* GetGameState() { return m_gameState; }
MxBackgroundAudioManager* GetBackgroundAudioManager() { return m_bkgAudioManager; }
MxTransitionManager* GetTransitionManager() { return m_transitionManager; }
MxDSAction& GetCurrentAction() { return m_action; }
private:
undefined4 m_unk68;
@ -126,5 +156,9 @@ LegoPlantManager* PlantManager();
MxBool KeyValueStringParse(char*, const char*, const char*);
LegoWorld* GetCurrentWorld();
GifManager* GetGifManager();
MxDSAction& GetCurrentAction();
void RegisterScripts();
void UnregisterScripts();
#endif // LEGOOMNI_H

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -14,7 +14,7 @@ class MxCore {
public:
__declspec(dllexport) MxCore();
__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
// OFFSET: LEGO1 0x100144c0

View File

@ -28,7 +28,7 @@ MxDSAction::MxDSAction()
this->m_up.Fill(FLT_MAX);
this->m_unk84 = NULL;
this->m_unk88 = 0;
this->m_omni = NULL;
this->m_unk8c = NULL;
this->m_unkTimingField = INT_MIN;
}
@ -54,7 +54,7 @@ void MxDSAction::CopyFrom(MxDSAction& p_dsAction)
AppendData(p_dsAction.m_extraLength, p_dsAction.m_extraData);
this->m_unk84 = p_dsAction.m_unk84;
this->m_unk88 = p_dsAction.m_unk88;
this->m_omni = p_dsAction.m_omni;
this->m_unk8c = p_dsAction.m_unk8c;
this->m_unkTimingField = p_dsAction.m_unkTimingField;
}

View File

@ -63,7 +63,7 @@ class MxDSAction : public MxDSObject {
inline void SetLoopCount(MxS32 p_loopCount) { m_loopCount = p_loopCount; }
inline const MxVector3Data& GetLocation() const { return m_location; }
inline void SetUnknown84(MxCore* p_unk84) { m_unk84 = p_unk84; }
inline void SetOmni(MxOmni* p_omni) { m_omni = p_omni; }
inline void SetUnknown8c(MxCore* p_unk8c) { m_unk8c = p_unk8c; }
inline MxBool IsLooping() const { return m_flags & Flag_Looping; }
inline MxBool IsBit3() const { return m_flags & Flag_Bit3; }
@ -85,7 +85,7 @@ class MxDSAction : public MxDSObject {
MxU16 m_extraLength;
MxCore* m_unk84;
undefined4 m_unk88;
MxOmni* m_omni; // 0x8c
MxCore* m_unk8c;
protected:
MxLong m_unkTimingField; // 0x90

View File

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

View File

@ -97,10 +97,15 @@ class MxListCursor : public MxCore {
MxBool Find(T p_obj);
void Detach();
void Destroy();
MxBool Next(T& p_obj);
MxBool Current(T& p_obj);
void Advance();
MxBool HasMatch() { return m_match != NULL; }
void SetValue(T p_obj);
void Head() { m_match = m_list->m_first; }
void Reset() { m_match = NULL; }
void Prepend(T p_newobj);
private:
MxList<T>* m_list;
@ -215,6 +220,12 @@ inline void MxListCursor<T>::Detach()
m_match = NULL;
}
template <class T>
inline void MxListCursor<T>::Destroy()
{
m_list->m_customDestructor(m_match->GetValue());
}
template <class T>
inline MxBool MxListCursor<T>::Next(T& p_obj)
{
@ -229,6 +240,24 @@ inline MxBool MxListCursor<T>::Next(T& p_obj)
return m_match != NULL;
}
template <class T>
inline MxBool MxListCursor<T>::Current(T& p_obj)
{
if (m_match)
p_obj = m_match->GetValue();
return m_match != NULL;
}
template <class T>
inline void MxListCursor<T>::Advance()
{
if (!m_match)
m_match = m_list->m_first;
else
m_match = m_match->m_next;
}
template <class T>
inline void MxListCursor<T>::SetValue(T p_obj)
{
@ -236,4 +265,11 @@ inline void MxListCursor<T>::SetValue(T p_obj)
m_match->m_obj = p_obj;
}
template <class T>
inline void MxListCursor<T>::Prepend(T p_newobj)
{
if (m_match)
m_list->_InsertEntry(p_newobj, m_match->m_prev, m_match);
}
#endif // MXLIST_H

View File

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

View File

@ -9,7 +9,7 @@ class MxCore;
enum MxParamType {
PARAM_NONE = 0,
PAINT = 1, // 100dc210:100d8350
c_notificationStartAction = 1, // 100dc210:100d8350
c_notificationEndAction = 2, // 100d8358:100d8350
TYPE4 = 4, // 100dc208:100d8350
MXPRESENTER_NOTIFICATION = 5,

View File

@ -65,7 +65,7 @@ void MxPresenter::SendTo_unkPresenter(MxOmni* p_omni)
NotificationManager()->Send(m_unkPresenter, &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;
}
}

View File

@ -11,6 +11,7 @@
class MxStreamController;
// VTABLE 0x100d4d38
// SIZE 0x40
class MxPresenter : public MxCore {
public:
enum TickleState {

View File

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

View File

@ -1,6 +1,9 @@
#ifndef MXRECT32_H
#define MXRECT32_H
#include "mxpoint32.h"
#include "mxsize32.h"
class MxRect32 {
public:
MxRect32() {}
@ -12,14 +15,35 @@ class MxRect32 {
this->m_bottom = p_bottom;
}
MxRect32(const MxPoint32& p_point, const MxSize32& p_size)
{
this->m_left = p_point.m_x;
this->m_top = p_point.m_y;
this->m_right = p_size.m_width;
this->m_bottom = p_size.m_height;
}
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 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); }
MxS32 m_left;
MxS32 m_top;
MxS32 m_right;
MxS32 m_bottom;
inline MxS32 GetWidth() { return (m_right - m_left) + 1; }
inline MxS32 GetHeight() { return (m_bottom - m_top) + 1; }
};
#endif // MXRECT32_H

View File

@ -1,40 +1,214 @@
#include "mxregion.h"
DECOMP_SIZE_ASSERT(MxRegion, 0x1c);
#include <limits.h>
// OFFSET: LEGO1 0x100c31c0 STUB
DECOMP_SIZE_ASSERT(MxRegion, 0x1c);
DECOMP_SIZE_ASSERT(MxRegionTopBottom, 0x0c);
DECOMP_SIZE_ASSERT(MxRegionLeftRight, 0x08);
// OFFSET: LEGO1 0x100c31c0
MxRegion::MxRegion()
{
// TODO
m_list = new MxRegionList;
m_rect.SetPoint(MxPoint32(INT_MAX, INT_MAX));
m_rect.SetSize(MxSize32(-1, -1));
}
// OFFSET: LEGO1 0x100c3690 STUB
MxRegion::~MxRegion()
{
// TODO
}
// OFFSET: LEGO1 0x100c3700 STUB
void MxRegion::Reset()
{
// TODO
}
// OFFSET: LEGO1 0x100c3750 STUB
void MxRegion::vtable18(MxRect32& p_rect)
{
// TODO
}
// OFFSET: LEGO1 0x100c3e20 STUB
void MxRegion::vtable1c()
{
// TODO
}
// OFFSET: LEGO1 0x100c3660 STUB
// OFFSET: LEGO1 0x100c3660
MxBool MxRegion::vtable20()
{
// TODO
return m_list->GetCount() == 0;
}
// OFFSET: LEGO1 0x100c3690
MxRegion::~MxRegion()
{
if (m_list)
delete m_list;
}
// OFFSET: LEGO1 0x100c3700
void MxRegion::Reset()
{
m_list->DeleteAll();
m_rect.SetPoint(MxPoint32(INT_MAX, INT_MAX));
m_rect.SetSize(MxSize32(-1, -1));
}
// OFFSET: LEGO1 0x100c3750
void MxRegion::vtable18(MxRect32& p_rect)
{
MxRect32 rectCopy(p_rect.GetPoint(), MxSize32(p_rect.m_right, p_rect.m_bottom));
MxRegionListCursor cursor(m_list);
if (rectCopy.m_left < rectCopy.m_right) {
while (rectCopy.m_top < rectCopy.m_bottom) {
MxRegionTopBottom* topBottom;
if (!cursor.Next(topBottom))
break;
if (topBottom->m_top >= rectCopy.m_bottom) {
cursor.Prepend(new MxRegionTopBottom(rectCopy));
rectCopy.m_top = rectCopy.m_bottom;
}
else if (rectCopy.m_top < topBottom->m_bottom) {
if (rectCopy.m_top < topBottom->m_top) {
MxRect32 topBottomRect(rectCopy.GetPoint(), MxSize32(rectCopy.m_right, topBottom->m_top));
cursor.Prepend(new MxRegionTopBottom(topBottomRect));
rectCopy.m_top = topBottom->m_top;
}
else if (topBottom->m_top < rectCopy.m_top) {
MxRegionTopBottom* newTopBottom = topBottom->Clone();
newTopBottom->m_bottom = rectCopy.m_top;
topBottom->m_top = rectCopy.m_top;
cursor.Prepend(newTopBottom);
}
if (rectCopy.m_bottom < topBottom->m_bottom) {
MxRegionTopBottom* newTopBottom = topBottom->Clone();
newTopBottom->m_bottom = rectCopy.m_bottom;
topBottom->m_top = rectCopy.m_bottom;
newTopBottom->FUN_100c5280(rectCopy.m_left, rectCopy.m_right);
// TODO: _InsertEntry currently inlined, shouldn't be
cursor.Prepend(newTopBottom);
rectCopy.m_top = rectCopy.m_bottom;
}
else {
topBottom->FUN_100c5280(rectCopy.m_left, rectCopy.m_right);
rectCopy.m_top = topBottom->m_bottom;
}
}
if (rectCopy.m_right <= rectCopy.m_left)
break;
}
}
if (rectCopy.m_left < rectCopy.m_right && rectCopy.m_top < rectCopy.m_bottom) {
MxRegionTopBottom* newTopBottom = new MxRegionTopBottom(rectCopy);
m_list->OtherAppend(newTopBottom);
}
m_rect.m_left = m_rect.m_left <= p_rect.m_left ? m_rect.m_left : p_rect.m_left;
m_rect.m_top = m_rect.m_top <= p_rect.m_top ? m_rect.m_top : p_rect.m_top;
m_rect.m_right = m_rect.m_right <= p_rect.m_right ? p_rect.m_right : m_rect.m_right;
m_rect.m_bottom = m_rect.m_bottom <= p_rect.m_bottom ? p_rect.m_bottom : m_rect.m_bottom;
}
// OFFSET: LEGO1 0x100c3e20
MxBool MxRegion::vtable1c(MxRect32& p_rect)
{
if (m_rect.m_left >= p_rect.m_right || p_rect.m_left >= m_rect.m_right || m_rect.m_top >= p_rect.m_bottom ||
p_rect.m_top >= m_rect.m_bottom)
return FALSE;
MxRegionListCursor cursor(m_list);
MxRegionTopBottom* topBottom;
while (cursor.Next(topBottom)) {
if (topBottom->m_top >= p_rect.m_bottom)
return FALSE;
if (topBottom->m_bottom > p_rect.m_top && 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.m_top;
m_bottom = p_rect.m_bottom;
m_leftRightList = new MxRegionLeftRightList;
MxRegionLeftRight* leftRight = new MxRegionLeftRight(p_rect.m_left, p_rect.m_right);
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->m_right < p_left)
;
if (!a.HasMatch()) {
MxRegionLeftRight* copy = new MxRegionLeftRight(p_left, p_right);
m_leftRightList->OtherAppend(copy);
}
else {
if (p_left > leftRight->m_left)
p_left = leftRight->m_left;
while (leftRight->m_left < p_right) {
if (p_right < leftRight->m_right)
p_right = leftRight->m_right;
// TODO: Currently inlined, shouldn't be
b = a;
b.Advance();
if (a.HasMatch()) {
a.Destroy();
a.Detach();
}
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->OtherAppend(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.m_right <= leftRight->m_left)
return FALSE;
if (leftRight->m_right > p_rect.m_left)
return TRUE;
}
return FALSE;
}

View File

@ -4,6 +4,35 @@
#include "decomp.h"
#include "mxcore.h"
#include "mxrect32.h"
#include "mxregionlist.h"
// SIZE 0x0c
struct MxRegionTopBottom {
MxRegionTopBottom(MxRect32& p_rect);
MxRegionTopBottom(MxS32 m_top, MxS32 m_bottom);
MxRegionTopBottom* Clone();
void FUN_100c5280(MxS32 p_left, MxS32 p_right);
MxBool FUN_100c57b0(MxRect32& p_rect);
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); }
MxS32 m_left;
MxS32 m_right;
};
// VTABLE 0x100dcae8
// SIZE 0x1c
@ -14,15 +43,13 @@ class MxRegion : public MxCore {
virtual void Reset();
virtual void vtable18(MxRect32& p_rect);
virtual void vtable1c();
virtual MxBool vtable1c(MxRect32& p_rect);
virtual MxBool vtable20();
inline MxRect32& GetRect() { return this->m_rect; }
private:
// A container (probably MxList) holding MxRect32
// MxList<MxRect32*> *m_rects;
undefined4 m_unk08;
MxRegionList* m_list;
MxRect32 m_rect;
};

19
LEGO1/mxregionlist.cpp Normal file
View File

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

56
LEGO1/mxregionlist.h Normal file
View File

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

19
LEGO1/mxsize32.h Normal file
View File

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

View File

@ -13,6 +13,19 @@ class MxSmkPresenter : public MxVideoPresenter {
MxSmkPresenter();
virtual ~MxSmkPresenter() override;
// OFFSET: LEGO1 0x100b3730
inline virtual const char* ClassName() const override // vtable+0xc
{
// 0x10101e38
return "MxSmkPresenter";
}
// OFFSET: LEGO1 0x100b3740
inline virtual MxBool IsA(const char* name) const override // vtable+0x10
{
return !strcmp(name, MxSmkPresenter::ClassName()) || MxVideoPresenter::IsA(name);
}
virtual void Destroy() override;
virtual void VTable0x5c(undefined4 p_unknown1) override;
virtual void VTable0x60() override;

View File

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

View File

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

View File

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

View File

@ -4,6 +4,19 @@
#include "mxdschunk.h"
// VTABLE 0x100dc2a8
class MxStreamChunk : public MxDSChunk {};
class MxStreamChunk : public MxDSChunk {
// 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);
}
};
#endif // MXSTREAMCHUNK_H

View File

@ -2,6 +2,9 @@
#include "legoomni.h"
#include "mxautolocker.h"
#include "mxnextactiondatastart.h"
DECOMP_SIZE_ASSERT(MxNextActionDataStart, 0x14)
// OFFSET: LEGO1 0x100c0b90 STUB
MxStreamController::MxStreamController()
@ -74,20 +77,42 @@ MxResult MxStreamController::vtable0x24(undefined4 p_unknown)
return FAILURE;
}
// OFFSET: LEGO1 0x100c1800 STUB
MxResult MxStreamController::FUN_100c1800(MxDSAction* p_action, MxU32 p_val)
{
MxNextActionDataStart* dataActionStart =
new MxNextActionDataStart(p_action->GetObjectId(), p_action->GetUnknown24(), p_val);
if (dataActionStart == NULL) {
return FAILURE;
}
// TODO: insert dataActionStart to a list
return FAILURE;
}
// OFFSET: LEGO1 0x100b9420
MxResult MxStreamController::vtable0x28()
{
return SUCCESS;
}
// OFFSET: LEGO1 0x100c1c10 STUB
// OFFSET: LEGO1 0x100c1c10
MxResult MxStreamController::vtable0x2c(MxDSAction* p_action, MxU32 p_bufferval)
{
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
MxResult MxStreamController::vtable0x30(undefined4 p_unknown)
{
return FAILURE;
}
// OFFSET: LEGO1 0x100c1a00 STUB
MxResult MxStreamController::FUN_100c1a00(MxDSAction* p_action, MxU32 p_bufferval)
{
return FAILURE;
}

View File

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

View File

@ -7,6 +7,18 @@
// SIZE 0x84
class Pizzeria : public IsleActor {
public:
// OFFSET: LEGO1 0x1000e780
inline virtual const char* ClassName() const override // vtable+0x0c
{
// 0x100f0380
return "Pizzeria";
}
// OFFSET: LEGO1 0x1000e790
inline virtual MxBool IsA(const char* name) const override // vtable+0x10
{
return !strcmp(name, Pizzeria::ClassName()) || IsleActor::IsA(name);
}
};
#endif // PIZZERIASTATE_H

View File

@ -8,6 +8,19 @@
class PizzeriaState : public LegoState {
public:
PizzeriaState();
// OFFSET: LEGO1 0x10017c20
inline virtual const char* ClassName() const override // vtable+0x0c
{
// 0x100f0370
return "PizzeriaState";
}
// OFFSET: LEGO1 0x10017c30
inline virtual MxBool IsA(const char* name) const override // vtable+0x10
{
return !strcmp(name, PizzeriaState::ClassName()) || LegoState::IsA(name);
}
};
#endif // PIZZERIASTATE_H

View File

@ -7,6 +7,19 @@
class Radio : public MxCore {
public:
virtual ~Radio() override;
// OFFSET: LEGO1 0x1002c8e0
inline virtual const char* ClassName() const override // vtable+0x0c
{
// 0x100f328c
return "Radio";
}
// OFFSET: LEGO1 0x1002c8f0
inline virtual MxBool IsA(const char* name) const override // vtable+0x10
{
return !strcmp(name, Radio::ClassName()) || MxCore::IsA(name);
}
};
#endif // RADIO_H

View File

@ -11,6 +11,19 @@ class RegistrationBook : public LegoWorld {
virtual ~RegistrationBook() override; // vtable+0x0
virtual MxLong Notify(MxParam& p) override; // vtable+0x4
// OFFSET: LEGO1 0x10076e10
inline virtual const char* ClassName() const override // vtable+0x0c
{
// 0x100f04c8
return "RegistrationBook";
}
// OFFSET: LEGO1 0x10076e20
inline virtual MxBool IsA(const char* name) const override // vtable+0x10
{
return !strcmp(name, RegistrationBook::ClassName()) || LegoWorld::IsA(name);
}
};
#endif // REGISTRATIONBOOK_H

View File

@ -15,8 +15,6 @@
DECOMP_SIZE_ASSERT(Score, 0x104)
MxAtomId* g_infoscorScript;
// OFFSET: LEGO1 0x10001000
Score::Score()
{
@ -41,7 +39,7 @@ MxLong Score::Notify(MxParam& p)
LegoWorld::Notify(p);
if (m_unkf6) {
switch (((MxNotificationParam&) p).GetNotification()) {
case PAINT:
case c_notificationStartAction:
ret = 1;
Paint();
break;