mirror of
https://github.com/isledecomp/isle-portable.git
synced 2024-11-29 10:55:42 -05:00
Checkorder tool to keep functions in original binary order (#228)
* First commit of order tool * More flexible match on module name. Bugfix on blank_or_comment * Report inexact offset comments in verbose mode. Bugfix for exact regex * Refactor checkorder into reusable isledecomp module * Find bad comments in one pass, add awareness of TEMPLATE * Refactor of state machine to prepare for reccmp integration * Use isledecomp lib in reccmp * Build isledecomp in GH actions, fix mypy complaint * Ensure unit test cpp files will be ignored by reccmp * Allow multiple offset markers, pep8 cleanup * Remove unused variable * Code style, remove unneeded module and TODO * Final renaming and type hints * Fix checkorder issues, add GH action and enforce (#2) * Fix checkorder issues * Add GH action * Test error case * Works * Fixes --------- Co-authored-by: Christian Semmler <mail@csemmler.com>
This commit is contained in:
parent
714d36b57d
commit
1ae3b07dc2
84 changed files with 4021 additions and 3209 deletions
5
.github/workflows/build.yml
vendored
5
.github/workflows/build.yml
vendored
|
@ -70,6 +70,11 @@ jobs:
|
|||
path: legobin
|
||||
key: legobin
|
||||
|
||||
- name: Build isledecomp library
|
||||
shell: bash
|
||||
run: |
|
||||
pip install tools/isledecomp
|
||||
|
||||
- name: Summarize Accuracy
|
||||
shell: bash
|
||||
run: |
|
||||
|
|
20
.github/workflows/order.yml
vendored
Normal file
20
.github/workflows/order.yml
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
name: Check order
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
checkorder:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Build isledecomp library
|
||||
run: |
|
||||
pip install tools/isledecomp
|
||||
|
||||
- name: Run checkorder.py
|
||||
run: |
|
||||
pip install -r tools/checkorder/requirements.txt
|
||||
python3 tools/checkorder/checkorder.py --verbose --enforce ISLE
|
||||
python3 tools/checkorder/checkorder.py --verbose --enforce LEGO1
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -18,3 +18,4 @@ build/
|
|||
*.swp
|
||||
LEGO1PROGRESS.HTML
|
||||
LEGO1PROGRESS.SVG
|
||||
*.pyc
|
||||
|
|
|
@ -281,6 +281,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
|||
return msg.wParam;
|
||||
}
|
||||
|
||||
// OFFSET: ISLE 0x401c40 TEMPLATE
|
||||
// MxDSObject::SetAtomId
|
||||
|
||||
// OFFSET: ISLE 0x401ca0
|
||||
BOOL FindExistingInstance(void)
|
||||
{
|
||||
|
|
|
@ -3,6 +3,12 @@
|
|||
// 0x100f37cc
|
||||
int g_buildingManagerConfig = 1;
|
||||
|
||||
// OFFSET: LEGO1 0x1002f8b0
|
||||
void LegoBuildingManager::configureLegoBuildingManager(int param_1)
|
||||
{
|
||||
g_buildingManagerConfig = param_1;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1002f8c0
|
||||
LegoBuildingManager::LegoBuildingManager()
|
||||
{
|
||||
|
@ -20,9 +26,3 @@ void LegoBuildingManager::Init()
|
|||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1002f8b0
|
||||
void LegoBuildingManager::configureLegoBuildingManager(int param_1)
|
||||
{
|
||||
g_buildingManagerConfig = param_1;
|
||||
}
|
||||
|
|
|
@ -12,14 +12,6 @@ LegoCarBuild::~LegoCarBuild()
|
|||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10024050 STUB
|
||||
MxLong LegoCarBuild::Notify(MxParam& p)
|
||||
{
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100238b0 STUB
|
||||
MxResult LegoCarBuild::Tickle()
|
||||
{
|
||||
|
@ -27,3 +19,11 @@ MxResult LegoCarBuild::Tickle()
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10024050 STUB
|
||||
MxLong LegoCarBuild::Notify(MxParam& p)
|
||||
{
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -12,14 +12,6 @@ LegoControlManager::~LegoControlManager()
|
|||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10029600 STUB
|
||||
MxResult LegoControlManager::Tickle()
|
||||
{
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10028e10 STUB
|
||||
void LegoControlManager::Register(MxCore* p_listener)
|
||||
{
|
||||
|
@ -31,3 +23,11 @@ void LegoControlManager::Unregister(MxCore* p_listener)
|
|||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10029600 STUB
|
||||
MxResult LegoControlManager::Tickle()
|
||||
{
|
||||
// TODO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
|
||||
DECOMP_SIZE_ASSERT(LegoEntity, 0x68)
|
||||
|
||||
// OFFSET: LEGO1 0x10001090 TEMPLATE
|
||||
// LegoEntity::SetWorldSpeed
|
||||
|
||||
// OFFSET: LEGO1 0x1000c290
|
||||
LegoEntity::~LegoEntity()
|
||||
{
|
||||
|
|
|
@ -38,15 +38,14 @@ class LegoEntity : public MxEntity {
|
|||
virtual void SetROI(LegoROI* p_roi, MxBool p_bool1, MxBool p_bool2); // vtable+0x24
|
||||
virtual void SetWorldTransform(Vector3Impl& p_loc, Vector3Impl& p_dir, Vector3Impl& p_up); // vtable+0x28
|
||||
virtual void ResetWorldTransform(MxBool p_inVehicle); // vtable+0x2c
|
||||
// OFFSET: LEGO1 0x10001090
|
||||
virtual void SetWorldSpeed(MxFloat p_worldSpeed) { m_worldSpeed = p_worldSpeed; } // vtable+0x30
|
||||
virtual void VTable0x34(); // vtable+0x34
|
||||
virtual void VTable0x38(); // vtable+0x38
|
||||
virtual void VTable0x3c(); // vtable+0x3c
|
||||
virtual void VTable0x40(); // vtable+0x40
|
||||
virtual void VTable0x44(); // vtable+0x44
|
||||
virtual void VTable0x48(); // vtable+0x48
|
||||
virtual void VTable0x4c(); // vtable+0x4c
|
||||
virtual void SetWorldSpeed(MxFloat p_worldSpeed) { m_worldSpeed = p_worldSpeed; } // vtable+0x30
|
||||
virtual void VTable0x34(); // vtable+0x34
|
||||
virtual void VTable0x38(); // vtable+0x38
|
||||
virtual void VTable0x3c(); // vtable+0x3c
|
||||
virtual void VTable0x40(); // vtable+0x40
|
||||
virtual void VTable0x44(); // vtable+0x44
|
||||
virtual void VTable0x48(); // vtable+0x48
|
||||
virtual void VTable0x4c(); // vtable+0x4c
|
||||
|
||||
protected:
|
||||
void Init();
|
||||
|
|
|
@ -78,42 +78,6 @@ LegoGameState::~LegoGameState()
|
|||
delete[] m_savePath;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10039c60 STUB
|
||||
MxResult LegoGameState::Load(MxULong)
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1003a170
|
||||
void LegoGameState::GetFileSavePath(MxString* p_outPath, MxULong p_slotn)
|
||||
{
|
||||
char baseForSlot[2] = "0";
|
||||
char path[1024] = "";
|
||||
|
||||
// Save path base
|
||||
if (m_savePath != NULL)
|
||||
strcpy(path, m_savePath);
|
||||
|
||||
// Slot: "G0", "G1", ...
|
||||
strcat(path, "G");
|
||||
baseForSlot[0] += p_slotn;
|
||||
strcat(path, baseForSlot);
|
||||
|
||||
// Extension: ".GS"
|
||||
strcat(path, g_fileExtensionGS);
|
||||
*p_outPath = MxString(path);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1003a020
|
||||
MxResult LegoGameState::WriteEndOfVariables(LegoStream* p_stream)
|
||||
{
|
||||
MxU8 len = strlen(s_endOfVariables);
|
||||
if (p_stream->Write(&len, 1) == SUCCESS)
|
||||
return p_stream->Write(s_endOfVariables, len);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10039980
|
||||
MxResult LegoGameState::Save(MxULong p_slot)
|
||||
{
|
||||
|
@ -152,22 +116,11 @@ MxResult LegoGameState::Save(MxULong p_slot)
|
|||
return result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1003a2e0 STUB
|
||||
void LegoGameState::SerializePlayersInfo(MxS16 p)
|
||||
// OFFSET: LEGO1 0x10039c60 STUB
|
||||
MxResult LegoGameState::Load(MxULong)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1003cdd0 STUB
|
||||
void LegoGameState::SerializeScoreHistory(MxS16 p)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1003cea0
|
||||
void LegoGameState::SetSomeEnumState(undefined4 p_state)
|
||||
{
|
||||
m_unk10 = p_state;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10039f00
|
||||
|
@ -184,6 +137,53 @@ void LegoGameState::SetSavePath(char* p_savePath)
|
|||
m_savePath = NULL;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1003a020
|
||||
MxResult LegoGameState::WriteEndOfVariables(LegoStream* p_stream)
|
||||
{
|
||||
MxU8 len = strlen(s_endOfVariables);
|
||||
if (p_stream->Write(&len, 1) == SUCCESS)
|
||||
return p_stream->Write(s_endOfVariables, len);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1003a170
|
||||
void LegoGameState::GetFileSavePath(MxString* p_outPath, MxULong p_slotn)
|
||||
{
|
||||
char baseForSlot[2] = "0";
|
||||
char path[1024] = "";
|
||||
|
||||
// Save path base
|
||||
if (m_savePath != NULL)
|
||||
strcpy(path, m_savePath);
|
||||
|
||||
// Slot: "G0", "G1", ...
|
||||
strcat(path, "G");
|
||||
baseForSlot[0] += p_slotn;
|
||||
strcat(path, baseForSlot);
|
||||
|
||||
// Extension: ".GS"
|
||||
strcat(path, g_fileExtensionGS);
|
||||
*p_outPath = MxString(path);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1003a2e0 STUB
|
||||
void LegoGameState::SerializePlayersInfo(MxS16 p)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1003a720 STUB
|
||||
void LegoGameState::FUN_1003a720(MxU32 p_unk)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1003b060 STUB
|
||||
void LegoGameState::HandleAction(MxU32 p_unk)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1003bac0
|
||||
void LegoGameState::SetROIHandlerFunction()
|
||||
{
|
||||
|
@ -255,14 +255,14 @@ void LegoGameState::RegisterState(LegoState* p_state)
|
|||
m_stateArray[targetIndex] = p_state;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1003a720 STUB
|
||||
void LegoGameState::FUN_1003a720(MxU32 p_unk)
|
||||
// OFFSET: LEGO1 0x1003cdd0 STUB
|
||||
void LegoGameState::SerializeScoreHistory(MxS16 p)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1003b060 STUB
|
||||
void LegoGameState::HandleAction(MxU32 p_unk)
|
||||
// OFFSET: LEGO1 0x1003cea0
|
||||
void LegoGameState::SetSomeEnumState(undefined4 p_state)
|
||||
{
|
||||
// TODO
|
||||
m_unk10 = p_state;
|
||||
}
|
||||
|
|
|
@ -30,62 +30,6 @@ float g_turnSensitivity = 0.4f;
|
|||
// 0x100f4c54
|
||||
MxBool g_turnUseVelocity = FALSE;
|
||||
|
||||
// OFFSET: LEGO1 0x10054d40
|
||||
void LegoNavController::GetDefaults(
|
||||
int* p_mouseDeadzone,
|
||||
float* p_movementMaxSpeed,
|
||||
float* p_turnMaxSpeed,
|
||||
float* p_movementMaxAccel,
|
||||
float* p_turnMaxAccel,
|
||||
float* p_movementDecel,
|
||||
float* p_turnDecel,
|
||||
float* p_movementMinAccel,
|
||||
float* p_turnMinAccel,
|
||||
float* p_turnSensitivity,
|
||||
MxBool* p_turnUseVelocity
|
||||
)
|
||||
{
|
||||
*p_mouseDeadzone = g_mouseDeadzone;
|
||||
*p_movementMaxSpeed = g_movementMaxSpeed;
|
||||
*p_turnMaxSpeed = g_turnMaxSpeed;
|
||||
*p_movementMaxAccel = g_movementMaxAccel;
|
||||
*p_turnMaxAccel = g_turnMaxAccel;
|
||||
*p_movementDecel = g_movementDecel;
|
||||
*p_turnDecel = g_turnDecel;
|
||||
*p_movementMinAccel = g_movementMinAccel;
|
||||
*p_turnMinAccel = g_turnMinAccel;
|
||||
*p_turnSensitivity = g_turnSensitivity;
|
||||
*p_turnUseVelocity = g_turnUseVelocity;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10054dd0
|
||||
void LegoNavController::SetDefaults(
|
||||
int p_mouseDeadzone,
|
||||
float p_movementMaxSpeed,
|
||||
float p_turnMaxSpeed,
|
||||
float p_movementMaxAccel,
|
||||
float p_turnMaxAccel,
|
||||
float p_movementDecel,
|
||||
float p_turnDecel,
|
||||
float p_movementMinAccel,
|
||||
float p_turnMinAccel,
|
||||
float p_turnSensitivity,
|
||||
MxBool p_turnUseVelocity
|
||||
)
|
||||
{
|
||||
g_mouseDeadzone = p_mouseDeadzone;
|
||||
g_movementMaxSpeed = p_movementMaxSpeed;
|
||||
g_turnMaxSpeed = p_turnMaxSpeed;
|
||||
g_movementMaxAccel = p_movementMaxAccel;
|
||||
g_turnMaxAccel = p_turnMaxAccel;
|
||||
g_movementDecel = p_movementDecel;
|
||||
g_turnDecel = p_turnDecel;
|
||||
g_movementMinAccel = p_movementMinAccel;
|
||||
g_turnMinAccel = p_turnMinAccel;
|
||||
g_turnSensitivity = p_turnSensitivity;
|
||||
g_turnUseVelocity = p_turnUseVelocity;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10054ac0
|
||||
LegoNavController::LegoNavController()
|
||||
{
|
||||
|
@ -145,6 +89,62 @@ void LegoNavController::ResetToDefault()
|
|||
this->m_turnSensitivity = g_turnSensitivity;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10054d40
|
||||
void LegoNavController::GetDefaults(
|
||||
int* p_mouseDeadzone,
|
||||
float* p_movementMaxSpeed,
|
||||
float* p_turnMaxSpeed,
|
||||
float* p_movementMaxAccel,
|
||||
float* p_turnMaxAccel,
|
||||
float* p_movementDecel,
|
||||
float* p_turnDecel,
|
||||
float* p_movementMinAccel,
|
||||
float* p_turnMinAccel,
|
||||
float* p_turnSensitivity,
|
||||
MxBool* p_turnUseVelocity
|
||||
)
|
||||
{
|
||||
*p_mouseDeadzone = g_mouseDeadzone;
|
||||
*p_movementMaxSpeed = g_movementMaxSpeed;
|
||||
*p_turnMaxSpeed = g_turnMaxSpeed;
|
||||
*p_movementMaxAccel = g_movementMaxAccel;
|
||||
*p_turnMaxAccel = g_turnMaxAccel;
|
||||
*p_movementDecel = g_movementDecel;
|
||||
*p_turnDecel = g_turnDecel;
|
||||
*p_movementMinAccel = g_movementMinAccel;
|
||||
*p_turnMinAccel = g_turnMinAccel;
|
||||
*p_turnSensitivity = g_turnSensitivity;
|
||||
*p_turnUseVelocity = g_turnUseVelocity;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10054dd0
|
||||
void LegoNavController::SetDefaults(
|
||||
int p_mouseDeadzone,
|
||||
float p_movementMaxSpeed,
|
||||
float p_turnMaxSpeed,
|
||||
float p_movementMaxAccel,
|
||||
float p_turnMaxAccel,
|
||||
float p_movementDecel,
|
||||
float p_turnDecel,
|
||||
float p_movementMinAccel,
|
||||
float p_turnMinAccel,
|
||||
float p_turnSensitivity,
|
||||
MxBool p_turnUseVelocity
|
||||
)
|
||||
{
|
||||
g_mouseDeadzone = p_mouseDeadzone;
|
||||
g_movementMaxSpeed = p_movementMaxSpeed;
|
||||
g_turnMaxSpeed = p_turnMaxSpeed;
|
||||
g_movementMaxAccel = p_movementMaxAccel;
|
||||
g_turnMaxAccel = p_turnMaxAccel;
|
||||
g_movementDecel = p_movementDecel;
|
||||
g_turnDecel = p_turnDecel;
|
||||
g_movementMinAccel = p_movementMinAccel;
|
||||
g_turnMinAccel = p_turnMinAccel;
|
||||
g_turnSensitivity = p_turnSensitivity;
|
||||
g_turnUseVelocity = p_turnUseVelocity;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10054e40
|
||||
void LegoNavController::SetTargets(int p_hPos, int p_vPos, MxBool p_accel)
|
||||
{
|
||||
|
|
|
@ -109,124 +109,6 @@ const char* g_current = "current";
|
|||
// 0x101020e8
|
||||
void (*g_omniUserMessage)(const char*, int);
|
||||
|
||||
// OFFSET: LEGO1 0x10058a00
|
||||
LegoOmni::LegoOmni()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10058b50
|
||||
LegoOmni::~LegoOmni()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005b560
|
||||
void LegoOmni::CreateBackgroundAudio()
|
||||
{
|
||||
if (m_bkgAudioManager)
|
||||
m_bkgAudioManager->Create(*g_jukeboxScript, 100);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005af10 STUB
|
||||
void LegoOmni::RemoveWorld(const MxAtomId& p1, MxLong p2)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005b0c0 STUB
|
||||
LegoEntity* LegoOmni::FindByEntityIdOrAtomId(const MxAtomId& p_atom, MxS32 p_entityid)
|
||||
{
|
||||
// TODO
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005b400 STUB
|
||||
int LegoOmni::GetCurrPathInfo(LegoPathBoundary**, int&)
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b6ff0
|
||||
void MakeSourceName(char* p_output, const char* p_input)
|
||||
{
|
||||
const char* cln = strchr(p_input, ':');
|
||||
if (cln) {
|
||||
p_input = cln + 1;
|
||||
}
|
||||
|
||||
strcpy(p_output, p_input);
|
||||
|
||||
strlwr(p_output);
|
||||
|
||||
char* extLoc = strstr(p_output, ".si");
|
||||
if (extLoc) {
|
||||
*extLoc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b7050
|
||||
MxBool KeyValueStringParse(char* p_outputValue, const char* p_key, const char* p_source)
|
||||
{
|
||||
MxBool didMatch = FALSE;
|
||||
|
||||
MxS16 len = strlen(p_source);
|
||||
char* temp = new char[len + 1];
|
||||
strcpy(temp, p_source);
|
||||
|
||||
char* token = strtok(temp, ", \t\r\n:");
|
||||
while (token) {
|
||||
len -= (strlen(token) + 1);
|
||||
|
||||
if (strcmpi(token, p_key) == 0) {
|
||||
if (p_outputValue && len > 0) {
|
||||
char* cur = &token[strlen(p_key)];
|
||||
cur++;
|
||||
while (*cur != ',') {
|
||||
if (*cur == ' ' || *cur == '\0' || *cur == '\t' || *cur == '\n' || *cur == '\r')
|
||||
break;
|
||||
*p_outputValue++ = *cur++;
|
||||
}
|
||||
*p_outputValue = '\0';
|
||||
}
|
||||
|
||||
didMatch = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
token = strtok(NULL, ", \t\r\n:");
|
||||
}
|
||||
|
||||
delete[] temp;
|
||||
return didMatch;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b7210
|
||||
void SetOmniUserMessage(void (*p_userMsg)(const char*, int))
|
||||
{
|
||||
g_omniUserMessage = p_userMsg;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acf50
|
||||
MxResult Start(MxDSAction* p_dsAction)
|
||||
{
|
||||
return MxOmni::GetInstance()->Start(p_dsAction);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005ad10
|
||||
LegoOmni* LegoOmni::GetInstance()
|
||||
{
|
||||
return (LegoOmni*) MxOmni::GetInstance();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005ac90
|
||||
void LegoOmni::CreateInstance()
|
||||
{
|
||||
MxOmni::DestroyInstance();
|
||||
MxOmni::SetInstance(new LegoOmni());
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10015700
|
||||
LegoOmni* Lego()
|
||||
{
|
||||
|
@ -334,52 +216,10 @@ void PlayMusic(MxU32 p_index)
|
|||
LegoOmni::GetInstance()->GetBackgroundAudioManager()->PlayMusic(action, 5, 4);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c0280
|
||||
MxDSObject* CreateStreamObject(MxDSFile* p_file, MxS16 p_ofs)
|
||||
{
|
||||
char* buf;
|
||||
_MMCKINFO tmp_chunk;
|
||||
|
||||
if (p_file->Seek(((MxLong*) p_file->GetBuffer())[p_ofs], 0)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (p_file->Read((MxU8*) &tmp_chunk.ckid, 8) == 0 && tmp_chunk.ckid == FOURCC('M', 'x', 'S', 't')) {
|
||||
if (p_file->Read((MxU8*) &tmp_chunk.ckid, 8) == 0 && tmp_chunk.ckid == FOURCC('M', 'x', 'O', 'b')) {
|
||||
|
||||
buf = new char[tmp_chunk.cksize];
|
||||
if (!buf) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (p_file->Read((MxU8*) buf, tmp_chunk.cksize) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Save a copy so we can clean up properly, because
|
||||
// this function will alter the pointer value.
|
||||
char* copy = buf;
|
||||
MxDSObject* obj = DeserializeDSObjectDispatch(&buf, -1);
|
||||
delete[] copy;
|
||||
return obj;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10053430
|
||||
const char* GetNoCD_SourceName()
|
||||
{
|
||||
return g_nocdSourceName->GetInternal();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005b5f0 STUB
|
||||
MxLong LegoOmni::Notify(MxParam& p)
|
||||
// OFFSET: LEGO1 0x1001a700 STUB
|
||||
void FUN_1001a700()
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1003dd70 STUB
|
||||
|
@ -396,180 +236,6 @@ LegoEntity* PickEntity(MxLong, MxLong)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10058bd0
|
||||
void LegoOmni::Init()
|
||||
{
|
||||
MxOmni::Init();
|
||||
m_unk68 = 0;
|
||||
m_inputMgr = NULL;
|
||||
m_unk6c = 0;
|
||||
m_gifManager = NULL;
|
||||
m_unk78 = 0;
|
||||
m_currentWorld = NULL;
|
||||
m_unk80 = FALSE;
|
||||
m_currentVehicle = NULL;
|
||||
m_unkLegoSaveDataWriter = NULL;
|
||||
m_plantManager = NULL;
|
||||
m_gameState = NULL;
|
||||
m_animationManager = NULL;
|
||||
m_buildingManager = NULL;
|
||||
m_bkgAudioManager = NULL;
|
||||
m_unk13c = TRUE;
|
||||
m_transitionManager = NULL;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1001a700 STUB
|
||||
void FUN_1001a700()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10058e70
|
||||
MxResult LegoOmni::Create(MxOmniCreateParam& 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();
|
||||
if (m_objectFactory == NULL)
|
||||
return FAILURE;
|
||||
|
||||
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
|
||||
void LegoOmni::Destroy()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005b580
|
||||
MxResult LegoOmni::Start(MxDSAction* action)
|
||||
{
|
||||
MxResult result = MxOmni::Start(action);
|
||||
this->m_action.SetAtomId(action->GetAtomId());
|
||||
this->m_action.SetObjectId(action->GetObjectId());
|
||||
this->m_action.SetUnknown24(action->GetUnknown24());
|
||||
return result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005b1d0 STUB
|
||||
MxResult LegoOmni::DeleteObject(MxDSAction& ds)
|
||||
{
|
||||
// TODO
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005b3c0
|
||||
MxBool LegoOmni::DoesEntityExist(MxDSAction& ds)
|
||||
{
|
||||
if (MxOmni::DoesEntityExist(ds)) {
|
||||
if (FindByEntityIdOrAtomId(ds.GetAtomId(), ds.GetObjectId()) == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005b2f0
|
||||
MxEntity* LegoOmni::FindWorld(const char* p_id, MxS32 p_entityId, MxPresenter* p_presenter)
|
||||
{
|
||||
LegoWorld* foundEntity = NULL;
|
||||
if (strcmpi(p_id, g_current)) {
|
||||
foundEntity = (LegoWorld*) FindByEntityIdOrAtomId(MxAtomId(p_id, LookupMode_LowerCase2), p_entityId);
|
||||
}
|
||||
else {
|
||||
foundEntity = this->m_currentWorld;
|
||||
}
|
||||
|
||||
if (foundEntity != NULL) {
|
||||
foundEntity->VTable0x58(p_presenter);
|
||||
}
|
||||
|
||||
return foundEntity;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005b3a0
|
||||
void LegoOmni::NotifyCurrentEntity(MxNotificationParam* p_param)
|
||||
{
|
||||
if (m_currentWorld)
|
||||
NotificationManager()->Send(m_currentWorld, p_param);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005b640
|
||||
void LegoOmni::StartTimer()
|
||||
{
|
||||
MxOmni::StartTimer();
|
||||
SetAppCursor(2);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005b650
|
||||
void LegoOmni::StopTimer()
|
||||
{
|
||||
MxOmni::StopTimer();
|
||||
SetAppCursor(0);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100528e0
|
||||
void RegisterScripts()
|
||||
{
|
||||
|
@ -665,3 +331,337 @@ void UnregisterScripts()
|
|||
g_creditsScript = NULL;
|
||||
g_nocdSourceName = NULL;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10053430
|
||||
const char* GetNoCD_SourceName()
|
||||
{
|
||||
return g_nocdSourceName->GetInternal();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10058a00
|
||||
LegoOmni::LegoOmni()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10058b50
|
||||
LegoOmni::~LegoOmni()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10058bd0
|
||||
void LegoOmni::Init()
|
||||
{
|
||||
MxOmni::Init();
|
||||
m_unk68 = 0;
|
||||
m_inputMgr = NULL;
|
||||
m_unk6c = 0;
|
||||
m_gifManager = NULL;
|
||||
m_unk78 = 0;
|
||||
m_currentWorld = NULL;
|
||||
m_unk80 = FALSE;
|
||||
m_currentVehicle = NULL;
|
||||
m_unkLegoSaveDataWriter = NULL;
|
||||
m_plantManager = NULL;
|
||||
m_gameState = NULL;
|
||||
m_animationManager = NULL;
|
||||
m_buildingManager = NULL;
|
||||
m_bkgAudioManager = NULL;
|
||||
m_unk13c = TRUE;
|
||||
m_transitionManager = NULL;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10058c30 STUB
|
||||
void LegoOmni::Destroy()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10058e70
|
||||
MxResult LegoOmni::Create(MxOmniCreateParam& 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();
|
||||
if (m_objectFactory == NULL)
|
||||
return FAILURE;
|
||||
|
||||
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 0x1005ac90
|
||||
void LegoOmni::CreateInstance()
|
||||
{
|
||||
MxOmni::DestroyInstance();
|
||||
MxOmni::SetInstance(new LegoOmni());
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005ad10
|
||||
LegoOmni* LegoOmni::GetInstance()
|
||||
{
|
||||
return (LegoOmni*) MxOmni::GetInstance();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005af10 STUB
|
||||
void LegoOmni::RemoveWorld(const MxAtomId& p1, MxLong p2)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005b0c0 STUB
|
||||
LegoEntity* LegoOmni::FindByEntityIdOrAtomId(const MxAtomId& p_atom, MxS32 p_entityid)
|
||||
{
|
||||
// TODO
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005b1d0 STUB
|
||||
MxResult LegoOmni::DeleteObject(MxDSAction& ds)
|
||||
{
|
||||
// TODO
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005b2f0
|
||||
MxEntity* LegoOmni::FindWorld(const char* p_id, MxS32 p_entityId, MxPresenter* p_presenter)
|
||||
{
|
||||
LegoWorld* foundEntity = NULL;
|
||||
if (strcmpi(p_id, g_current)) {
|
||||
foundEntity = (LegoWorld*) FindByEntityIdOrAtomId(MxAtomId(p_id, LookupMode_LowerCase2), p_entityId);
|
||||
}
|
||||
else {
|
||||
foundEntity = this->m_currentWorld;
|
||||
}
|
||||
|
||||
if (foundEntity != NULL) {
|
||||
foundEntity->VTable0x58(p_presenter);
|
||||
}
|
||||
|
||||
return foundEntity;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005b3a0
|
||||
void LegoOmni::NotifyCurrentEntity(MxNotificationParam* p_param)
|
||||
{
|
||||
if (m_currentWorld)
|
||||
NotificationManager()->Send(m_currentWorld, p_param);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005b3c0
|
||||
MxBool LegoOmni::DoesEntityExist(MxDSAction& ds)
|
||||
{
|
||||
if (MxOmni::DoesEntityExist(ds)) {
|
||||
if (FindByEntityIdOrAtomId(ds.GetAtomId(), ds.GetObjectId()) == NULL) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005b400 STUB
|
||||
int LegoOmni::GetCurrPathInfo(LegoPathBoundary**, int&)
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005b560
|
||||
void LegoOmni::CreateBackgroundAudio()
|
||||
{
|
||||
if (m_bkgAudioManager)
|
||||
m_bkgAudioManager->Create(*g_jukeboxScript, 100);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005b580
|
||||
MxResult LegoOmni::Start(MxDSAction* action)
|
||||
{
|
||||
MxResult result = MxOmni::Start(action);
|
||||
this->m_action.SetAtomId(action->GetAtomId());
|
||||
this->m_action.SetObjectId(action->GetObjectId());
|
||||
this->m_action.SetUnknown24(action->GetUnknown24());
|
||||
return result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005b5f0 STUB
|
||||
MxLong LegoOmni::Notify(MxParam& p)
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005b640
|
||||
void LegoOmni::StartTimer()
|
||||
{
|
||||
MxOmni::StartTimer();
|
||||
SetAppCursor(2);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1005b650
|
||||
void LegoOmni::StopTimer()
|
||||
{
|
||||
MxOmni::StopTimer();
|
||||
SetAppCursor(0);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acf50
|
||||
MxResult Start(MxDSAction* p_dsAction)
|
||||
{
|
||||
return MxOmni::GetInstance()->Start(p_dsAction);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b6ff0
|
||||
void MakeSourceName(char* p_output, const char* p_input)
|
||||
{
|
||||
const char* cln = strchr(p_input, ':');
|
||||
if (cln) {
|
||||
p_input = cln + 1;
|
||||
}
|
||||
|
||||
strcpy(p_output, p_input);
|
||||
|
||||
strlwr(p_output);
|
||||
|
||||
char* extLoc = strstr(p_output, ".si");
|
||||
if (extLoc) {
|
||||
*extLoc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b7050
|
||||
MxBool KeyValueStringParse(char* p_outputValue, const char* p_key, const char* p_source)
|
||||
{
|
||||
MxBool didMatch = FALSE;
|
||||
|
||||
MxS16 len = strlen(p_source);
|
||||
char* temp = new char[len + 1];
|
||||
strcpy(temp, p_source);
|
||||
|
||||
char* token = strtok(temp, ", \t\r\n:");
|
||||
while (token) {
|
||||
len -= (strlen(token) + 1);
|
||||
|
||||
if (strcmpi(token, p_key) == 0) {
|
||||
if (p_outputValue && len > 0) {
|
||||
char* cur = &token[strlen(p_key)];
|
||||
cur++;
|
||||
while (*cur != ',') {
|
||||
if (*cur == ' ' || *cur == '\0' || *cur == '\t' || *cur == '\n' || *cur == '\r')
|
||||
break;
|
||||
*p_outputValue++ = *cur++;
|
||||
}
|
||||
*p_outputValue = '\0';
|
||||
}
|
||||
|
||||
didMatch = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
token = strtok(NULL, ", \t\r\n:");
|
||||
}
|
||||
|
||||
delete[] temp;
|
||||
return didMatch;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b7210
|
||||
void SetOmniUserMessage(void (*p_userMsg)(const char*, int))
|
||||
{
|
||||
g_omniUserMessage = p_userMsg;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c0280
|
||||
MxDSObject* CreateStreamObject(MxDSFile* p_file, MxS16 p_ofs)
|
||||
{
|
||||
char* buf;
|
||||
_MMCKINFO tmp_chunk;
|
||||
|
||||
if (p_file->Seek(((MxLong*) p_file->GetBuffer())[p_ofs], 0)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (p_file->Read((MxU8*) &tmp_chunk.ckid, 8) == 0 && tmp_chunk.ckid == FOURCC('M', 'x', 'S', 't')) {
|
||||
if (p_file->Read((MxU8*) &tmp_chunk.ckid, 8) == 0 && tmp_chunk.ckid == FOURCC('M', 'x', 'O', 'b')) {
|
||||
|
||||
buf = new char[tmp_chunk.cksize];
|
||||
if (!buf) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (p_file->Read((MxU8*) buf, tmp_chunk.cksize) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Save a copy so we can clean up properly, because
|
||||
// this function will alter the pointer value.
|
||||
char* copy = buf;
|
||||
MxDSObject* obj = DeserializeDSObjectDispatch(&buf, -1);
|
||||
delete[] copy;
|
||||
return obj;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,11 @@ LegoPhonemePresenter::LegoPhonemePresenter()
|
|||
Init();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1004e340
|
||||
LegoPhonemePresenter::~LegoPhonemePresenter()
|
||||
{
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1004e3b0
|
||||
void LegoPhonemePresenter::Init()
|
||||
{
|
||||
|
@ -16,8 +21,3 @@ void LegoPhonemePresenter::Init()
|
|||
m_unk70 = 0;
|
||||
m_unk84 = 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1004e340
|
||||
LegoPhonemePresenter::~LegoPhonemePresenter()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -12,6 +12,12 @@ LegoPlantManager::~LegoPlantManager()
|
|||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10026330 STUB
|
||||
void LegoPlantManager::Init()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10026e00 STUB
|
||||
MxResult LegoPlantManager::Tickle()
|
||||
{
|
||||
|
@ -19,9 +25,3 @@ MxResult LegoPlantManager::Tickle()
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10026330 STUB
|
||||
void LegoPlantManager::Init()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
|
|
@ -14,10 +14,11 @@ LegoSoundManager::~LegoSoundManager()
|
|||
Destroy(TRUE);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1002a390
|
||||
void LegoSoundManager::Destroy()
|
||||
// OFFSET: LEGO1 0x100299a0
|
||||
void LegoSoundManager::Init()
|
||||
{
|
||||
Destroy(FALSE);
|
||||
unk0x40 = 0;
|
||||
unk0x3c = 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100299b0 STUB
|
||||
|
@ -31,11 +32,10 @@ MxResult LegoSoundManager::Create(MxU32 p_frequencyMS, MxBool p_createThread)
|
|||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100299a0
|
||||
void LegoSoundManager::Init()
|
||||
// OFFSET: LEGO1 0x1002a390
|
||||
void LegoSoundManager::Destroy()
|
||||
{
|
||||
unk0x40 = 0;
|
||||
unk0x3c = 0;
|
||||
Destroy(FALSE);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1002a3a0 STUB
|
||||
|
|
|
@ -19,6 +19,55 @@ DECOMP_SIZE_ASSERT(LegoStream, 0x8);
|
|||
DECOMP_SIZE_ASSERT(LegoFileStream, 0xC);
|
||||
DECOMP_SIZE_ASSERT(LegoMemoryStream, 0x10);
|
||||
|
||||
// OFFSET: LEGO1 0x10039f70
|
||||
MxResult LegoStream::WriteVariable(LegoStream* p_stream, MxVariableTable* p_from, const char* p_variableName)
|
||||
{
|
||||
MxResult result = FAILURE;
|
||||
const char* variableValue = p_from->GetVariable(p_variableName);
|
||||
|
||||
if (variableValue) {
|
||||
MxU8 length = strlen(p_variableName);
|
||||
if (p_stream->Write((char*) &length, 1) == SUCCESS) {
|
||||
if (p_stream->Write(p_variableName, length) == SUCCESS) {
|
||||
length = strlen(variableValue);
|
||||
if (p_stream->Write((char*) &length, 1) == SUCCESS)
|
||||
result = p_stream->Write((char*) variableValue, length);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// 95% match, just some instruction ordering differences on the call to
|
||||
// MxVariableTable::SetVariable at the end.
|
||||
// OFFSET: LEGO1 0x1003a080
|
||||
MxS32 LegoStream::ReadVariable(LegoStream* p_stream, MxVariableTable* p_to)
|
||||
{
|
||||
MxS32 result = 1;
|
||||
MxU8 length;
|
||||
|
||||
if (p_stream->Read((char*) &length, 1) == SUCCESS) {
|
||||
char nameBuffer[256];
|
||||
if (p_stream->Read(nameBuffer, length) == SUCCESS) {
|
||||
nameBuffer[length] = '\0';
|
||||
if (strcmp(nameBuffer, s_endOfVariables) == 0)
|
||||
// 2 -> "This was the last entry, done reading."
|
||||
result = 2;
|
||||
else {
|
||||
if (p_stream->Read((char*) &length, 1) == SUCCESS) {
|
||||
char valueBuffer[256];
|
||||
if (p_stream->Read(valueBuffer, length) == SUCCESS) {
|
||||
result = 0;
|
||||
valueBuffer[length] = '\0';
|
||||
p_to->SetVariable(nameBuffer, valueBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10045ae0
|
||||
MxBool LegoStream::IsWriteMode()
|
||||
{
|
||||
|
@ -31,6 +80,29 @@ MxBool LegoStream::IsReadMode()
|
|||
return m_mode == LEGOSTREAM_MODE_READ;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10099080
|
||||
LegoMemoryStream::LegoMemoryStream(char* p_buffer) : LegoStream()
|
||||
{
|
||||
m_buffer = p_buffer;
|
||||
m_offset = 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10099160
|
||||
MxResult LegoMemoryStream::Read(void* p_buffer, MxU32 p_size)
|
||||
{
|
||||
memcpy(p_buffer, m_buffer + m_offset, p_size);
|
||||
m_offset += p_size;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10099190
|
||||
MxResult LegoMemoryStream::Write(const void* p_buffer, MxU32 p_size)
|
||||
{
|
||||
memcpy(m_buffer + m_offset, p_buffer, p_size);
|
||||
m_offset += p_size;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100991c0
|
||||
LegoFileStream::LegoFileStream() : LegoStream()
|
||||
{
|
||||
|
@ -113,29 +185,6 @@ MxResult LegoFileStream::Open(const char* p_filename, OpenFlags p_mode)
|
|||
return (m_hFile = fopen(p_filename, modeString)) ? SUCCESS : FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10099080
|
||||
LegoMemoryStream::LegoMemoryStream(char* p_buffer) : LegoStream()
|
||||
{
|
||||
m_buffer = p_buffer;
|
||||
m_offset = 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10099160
|
||||
MxResult LegoMemoryStream::Read(void* p_buffer, MxU32 p_size)
|
||||
{
|
||||
memcpy(p_buffer, m_buffer + m_offset, p_size);
|
||||
m_offset += p_size;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10099190
|
||||
MxResult LegoMemoryStream::Write(const void* p_buffer, MxU32 p_size)
|
||||
{
|
||||
memcpy(m_buffer + m_offset, p_buffer, p_size);
|
||||
m_offset += p_size;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100994a0
|
||||
MxResult LegoMemoryStream::Tell(MxU32* p_offset)
|
||||
{
|
||||
|
@ -149,52 +198,3 @@ MxResult LegoMemoryStream::Seek(MxU32 p_offset)
|
|||
m_offset = p_offset;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10039f70
|
||||
MxResult LegoStream::WriteVariable(LegoStream* p_stream, MxVariableTable* p_from, const char* p_variableName)
|
||||
{
|
||||
MxResult result = FAILURE;
|
||||
const char* variableValue = p_from->GetVariable(p_variableName);
|
||||
|
||||
if (variableValue) {
|
||||
MxU8 length = strlen(p_variableName);
|
||||
if (p_stream->Write((char*) &length, 1) == SUCCESS) {
|
||||
if (p_stream->Write(p_variableName, length) == SUCCESS) {
|
||||
length = strlen(variableValue);
|
||||
if (p_stream->Write((char*) &length, 1) == SUCCESS)
|
||||
result = p_stream->Write((char*) variableValue, length);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// 95% match, just some instruction ordering differences on the call to
|
||||
// MxVariableTable::SetVariable at the end.
|
||||
// OFFSET: LEGO1 0x1003a080
|
||||
MxS32 LegoStream::ReadVariable(LegoStream* p_stream, MxVariableTable* p_to)
|
||||
{
|
||||
MxS32 result = 1;
|
||||
MxU8 length;
|
||||
|
||||
if (p_stream->Read((char*) &length, 1) == SUCCESS) {
|
||||
char nameBuffer[256];
|
||||
if (p_stream->Read(nameBuffer, length) == SUCCESS) {
|
||||
nameBuffer[length] = '\0';
|
||||
if (strcmp(nameBuffer, s_endOfVariables) == 0)
|
||||
// 2 -> "This was the last entry, done reading."
|
||||
result = 2;
|
||||
else {
|
||||
if (p_stream->Read((char*) &length, 1) == SUCCESS) {
|
||||
char valueBuffer[256];
|
||||
if (p_stream->Read(valueBuffer, length) == SUCCESS) {
|
||||
result = 0;
|
||||
valueBuffer[length] = '\0';
|
||||
p_to->SetVariable(nameBuffer, valueBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,15 @@
|
|||
DECOMP_SIZE_ASSERT(LegoVehicleBuildState, 0x50); // 1000acd7
|
||||
DECOMP_SIZE_ASSERT(LegoVehicleBuildState::UnkStruct, 0xc);
|
||||
|
||||
// OFFSET: LEGO1 0x10017c00
|
||||
LegoVehicleBuildState::UnkStruct::UnkStruct()
|
||||
{
|
||||
m_unk04 = 0;
|
||||
m_unk00 = 0;
|
||||
m_unk06 = 0;
|
||||
m_unk08 = 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10025f30
|
||||
LegoVehicleBuildState::LegoVehicleBuildState(char* p_classType)
|
||||
{
|
||||
|
@ -14,12 +23,3 @@ LegoVehicleBuildState::LegoVehicleBuildState(char* p_classType)
|
|||
this->m_unk4e = 0;
|
||||
this->m_placedPartCount = 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 10017c00
|
||||
LegoVehicleBuildState::UnkStruct::UnkStruct()
|
||||
{
|
||||
m_unk04 = 0;
|
||||
m_unk00 = 0;
|
||||
m_unk06 = 0;
|
||||
m_unk08 = 0;
|
||||
}
|
||||
|
|
|
@ -55,32 +55,6 @@ void LegoVideoManager::Destroy()
|
|||
delete[] m_prefCounter;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1007c560 STUB
|
||||
int LegoVideoManager::EnableRMDevice()
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1007c740 STUB
|
||||
int LegoVideoManager::DisableRMDevice()
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1007c300
|
||||
void LegoVideoManager::EnableFullScreenMovie(MxBool p_enable)
|
||||
{
|
||||
EnableFullScreenMovie(p_enable, TRUE);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1007c310 STUB
|
||||
void LegoVideoManager::EnableFullScreenMovie(MxBool p_enable, MxBool p_scale)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1007b6a0
|
||||
void LegoVideoManager::MoveCursor(MxS32 p_cursorX, MxS32 p_cursorY)
|
||||
{
|
||||
|
@ -95,6 +69,18 @@ void LegoVideoManager::MoveCursor(MxS32 p_cursorX, MxS32 p_cursorY)
|
|||
m_cursorY = 463;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1007c300
|
||||
void LegoVideoManager::EnableFullScreenMovie(MxBool p_enable)
|
||||
{
|
||||
EnableFullScreenMovie(p_enable, TRUE);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1007c310 STUB
|
||||
void LegoVideoManager::EnableFullScreenMovie(MxBool p_enable, MxBool p_scale)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1007c440
|
||||
void LegoVideoManager::SetSkyColor(float p_red, float p_green, float p_blue)
|
||||
{
|
||||
|
@ -110,3 +96,17 @@ void LegoVideoManager::SetSkyColor(float p_red, float p_green, float p_blue)
|
|||
// TODO 3d manager
|
||||
// m_3dManager->m_pViewport->vtable1c(red, green, blue)
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1007c560 STUB
|
||||
int LegoVideoManager::EnableRMDevice()
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1007c740 STUB
|
||||
int LegoVideoManager::DisableRMDevice()
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -16,22 +16,55 @@ void LegoWorld::VTable0x60()
|
|||
{
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10015820 STUB
|
||||
void FUN_10015820(MxU32 p_unk1, MxU32 p_unk2)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10015910 STUB
|
||||
void FUN_10015910(MxU32 p_unk1)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100159c0
|
||||
void SetIsWorldActive(MxBool p_isWorldActive)
|
||||
{
|
||||
if (!p_isWorldActive)
|
||||
LegoOmni::GetInstance()->GetInputManager()->SetCamera(NULL);
|
||||
g_isWorldActive = p_isWorldActive;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1001ca40 STUB
|
||||
LegoWorld::LegoWorld()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1001d670
|
||||
MxBool LegoWorld::VTable0x5c()
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1001d680
|
||||
MxBool LegoWorld::VTable0x64()
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1001dfa0 STUB
|
||||
LegoWorld::~LegoWorld()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10022340
|
||||
void LegoWorld::Stop()
|
||||
// OFFSET: LEGO1 0x1001e0b0 STUB
|
||||
MxResult LegoWorld::SetAsCurrentWorld(MxDSObject& p_dsObject)
|
||||
{
|
||||
TickleManager()->UnregisterClient(this);
|
||||
// TODO
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1001f5e0
|
||||
|
@ -58,27 +91,15 @@ void LegoWorld::VTable0x54()
|
|||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10020f10 STUB
|
||||
void LegoWorld::EndAction(MxPresenter* p_presenter)
|
||||
{
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10020220 STUB
|
||||
void LegoWorld::VTable0x58(MxCore* p_object)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1001d670
|
||||
MxBool LegoWorld::VTable0x5c()
|
||||
// OFFSET: LEGO1 0x10020f10 STUB
|
||||
void LegoWorld::EndAction(MxPresenter* p_presenter)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1001d680
|
||||
MxBool LegoWorld::VTable0x64()
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10021a70 STUB
|
||||
|
@ -87,29 +108,8 @@ void LegoWorld::VTable0x68(MxBool p_add)
|
|||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1001e0b0 STUB
|
||||
MxResult LegoWorld::SetAsCurrentWorld(MxDSObject& p_dsObject)
|
||||
// OFFSET: LEGO1 0x10022340
|
||||
void LegoWorld::Stop()
|
||||
{
|
||||
// TODO
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10015820 STUB
|
||||
void FUN_10015820(MxU32 p_unk1, MxU32 p_unk2)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10015910 STUB
|
||||
void FUN_10015910(MxU32 p_unk1)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100159c0
|
||||
void SetIsWorldActive(MxBool p_isWorldActive)
|
||||
{
|
||||
if (!p_isWorldActive)
|
||||
LegoOmni::GetInstance()->GetInputManager()->SetCamera(NULL);
|
||||
g_isWorldActive = p_isWorldActive;
|
||||
TickleManager()->UnregisterClient(this);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,12 @@
|
|||
// 0x100f75d4
|
||||
undefined4 g_LegoWorldPresenterQuality = 1;
|
||||
|
||||
// OFFSET: LEGO1 0x100665b0
|
||||
void LegoWorldPresenter::configureLegoWorldPresenter(int p_quality)
|
||||
{
|
||||
g_LegoWorldPresenterQuality = p_quality;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100665c0
|
||||
LegoWorldPresenter::LegoWorldPresenter()
|
||||
{
|
||||
|
@ -14,9 +20,3 @@ LegoWorldPresenter::~LegoWorldPresenter()
|
|||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100665b0
|
||||
void LegoWorldPresenter::configureLegoWorldPresenter(int p_quality)
|
||||
{
|
||||
g_LegoWorldPresenterQuality = p_quality;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,12 @@ DECOMP_SIZE_ASSERT(MxAudioManager, 0x30);
|
|||
// GLOBAL: LEGO1 0x10102108
|
||||
MxS32 MxAudioManager::g_unkCount = 0;
|
||||
|
||||
// OFFSET: LEGO1 0x10029910
|
||||
MxS32 MxAudioManager::GetVolume()
|
||||
{
|
||||
return this->m_volume;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b8d00
|
||||
MxAudioManager::MxAudioManager()
|
||||
{
|
||||
|
@ -23,20 +29,6 @@ void MxAudioManager::Init()
|
|||
this->m_volume = 100;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10029910
|
||||
MxS32 MxAudioManager::GetVolume()
|
||||
{
|
||||
return this->m_volume;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b8ea0
|
||||
void MxAudioManager::SetVolume(MxS32 p_volume)
|
||||
{
|
||||
this->m_criticalSection.Enter();
|
||||
this->m_volume = p_volume;
|
||||
this->m_criticalSection.Leave();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b8e00
|
||||
void MxAudioManager::Destroy(MxBool p_fromDestructor)
|
||||
{
|
||||
|
@ -76,3 +68,11 @@ void MxAudioManager::Destroy()
|
|||
{
|
||||
Destroy(FALSE);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b8ea0
|
||||
void MxAudioManager::SetVolume(MxS32 p_volume)
|
||||
{
|
||||
this->m_criticalSection.Enter();
|
||||
this->m_volume = p_volume;
|
||||
this->m_criticalSection.Leave();
|
||||
}
|
||||
|
|
|
@ -31,70 +31,6 @@ MxBackgroundAudioManager::~MxBackgroundAudioManager()
|
|||
DestroyMusic();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1007f470
|
||||
void MxBackgroundAudioManager::Stop()
|
||||
{
|
||||
if (m_action2.GetObjectId() != -1)
|
||||
DeleteObject(m_action2);
|
||||
|
||||
m_unk138 = 0;
|
||||
m_action2.SetAtomId(MxAtomId());
|
||||
m_action2.SetObjectId(-1);
|
||||
|
||||
if (m_action1.GetObjectId() != -1)
|
||||
DeleteObject(m_action1);
|
||||
|
||||
m_unka0 = 0;
|
||||
m_action1.SetAtomId(MxAtomId());
|
||||
m_unk148 = 0;
|
||||
m_action1.SetObjectId(-1);
|
||||
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)
|
||||
{
|
||||
if (this->m_musicEnabled != p) {
|
||||
this->m_musicEnabled = p;
|
||||
if (!p) {
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1007f650
|
||||
void MxBackgroundAudioManager::Init()
|
||||
{
|
||||
this->m_unka0 = 0;
|
||||
this->m_unk13c = 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1007ece0
|
||||
MxResult MxBackgroundAudioManager::Create(MxAtomId& p_script, MxU32 p_frequencyMS)
|
||||
{
|
||||
|
@ -137,80 +73,6 @@ void MxBackgroundAudioManager::DestroyMusic()
|
|||
}
|
||||
}
|
||||
|
||||
// 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->SetVolume(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()
|
||||
{
|
||||
|
@ -324,3 +186,141 @@ void MxBackgroundAudioManager::FadeInOrFadeOut()
|
|||
m_unk13c = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 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->SetVolume(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 0x1007f470
|
||||
void MxBackgroundAudioManager::Stop()
|
||||
{
|
||||
if (m_action2.GetObjectId() != -1)
|
||||
DeleteObject(m_action2);
|
||||
|
||||
m_unk138 = 0;
|
||||
m_action2.SetAtomId(MxAtomId());
|
||||
m_action2.SetObjectId(-1);
|
||||
|
||||
if (m_action1.GetObjectId() != -1)
|
||||
DeleteObject(m_action1);
|
||||
|
||||
m_unka0 = 0;
|
||||
m_action1.SetAtomId(MxAtomId());
|
||||
m_unk148 = 0;
|
||||
m_action1.SetObjectId(-1);
|
||||
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)
|
||||
{
|
||||
if (this->m_musicEnabled != p) {
|
||||
this->m_musicEnabled = p;
|
||||
if (!p) {
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1007f650
|
||||
void MxBackgroundAudioManager::Init()
|
||||
{
|
||||
this->m_unka0 = 0;
|
||||
this->m_unk13c = 0;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,28 @@ DECOMP_SIZE_ASSERT(MxBITMAPINFO, 0x428);
|
|||
// (1998) GLOBAL: LEGO1 0x10102184
|
||||
MxU16 g_bitmapSignature = TWOCC('B', 'M');
|
||||
|
||||
// Bit mask trick to round up to the nearest multiple of four.
|
||||
// Pixel data may be stored with padding.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/medfound/image-stride
|
||||
inline MxLong AlignToFourByte(MxLong p_value)
|
||||
{
|
||||
return (p_value + 3) & -4;
|
||||
}
|
||||
|
||||
// Same as the one from legoutil.h, but flipped the other way
|
||||
// TODO: While it's not outside the realm of possibility that they
|
||||
// reimplemented Abs for only this file, that seems odd, right?
|
||||
inline MxLong _Abs(MxLong p_value)
|
||||
{
|
||||
return p_value > 0 ? p_value : -p_value;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1004e0d0
|
||||
int MxBitmap::vtable28(int)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bc980
|
||||
MxBitmap::MxBitmap()
|
||||
{
|
||||
|
@ -32,118 +54,6 @@ MxBitmap::~MxBitmap()
|
|||
delete m_palette;
|
||||
}
|
||||
|
||||
// Bit mask trick to round up to the nearest multiple of four.
|
||||
// Pixel data may be stored with padding.
|
||||
// https://learn.microsoft.com/en-us/windows/win32/medfound/image-stride
|
||||
inline MxLong AlignToFourByte(MxLong p_value)
|
||||
{
|
||||
return (p_value + 3) & -4;
|
||||
}
|
||||
|
||||
// Same as the one from legoutil.h, but flipped the other way
|
||||
// TODO: While it's not outside the realm of possibility that they
|
||||
// reimplemented Abs for only this file, that seems odd, right?
|
||||
inline MxLong _Abs(MxLong p_value)
|
||||
{
|
||||
return p_value > 0 ? p_value : -p_value;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bcc40
|
||||
MxResult MxBitmap::ImportBitmap(MxBitmap* p_bitmap)
|
||||
{
|
||||
MxResult result = FAILURE;
|
||||
|
||||
this->m_info = new MxBITMAPINFO;
|
||||
if (this->m_info) {
|
||||
MxLong height = _Abs(p_bitmap->m_bmiHeader->biHeight);
|
||||
this->m_data = new MxU8[AlignToFourByte(p_bitmap->m_bmiHeader->biWidth) * height];
|
||||
if (this->m_data) {
|
||||
memcpy(this->m_info, p_bitmap->m_info, sizeof(*this->m_info));
|
||||
height = _Abs(p_bitmap->m_bmiHeader->biHeight);
|
||||
memcpy(this->m_data, p_bitmap->m_data, AlignToFourByte(p_bitmap->m_bmiHeader->biWidth) * height);
|
||||
|
||||
result = SUCCESS;
|
||||
this->m_bmiHeader = &this->m_info->bmiHeader;
|
||||
this->m_paletteData = this->m_info->bmiColors;
|
||||
}
|
||||
}
|
||||
|
||||
if (result != SUCCESS) {
|
||||
if (this->m_info) {
|
||||
delete this->m_info;
|
||||
this->m_info = NULL;
|
||||
}
|
||||
|
||||
if (this->m_data) {
|
||||
delete this->m_data;
|
||||
this->m_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bcba0
|
||||
MxResult MxBitmap::ImportBitmapInfo(MxBITMAPINFO* p_info)
|
||||
{
|
||||
MxResult result = FAILURE;
|
||||
MxLong width = p_info->bmiHeader.biWidth;
|
||||
MxLong height = p_info->bmiHeader.biHeight;
|
||||
MxLong size = AlignToFourByte(width) * height;
|
||||
|
||||
this->m_info = new MxBITMAPINFO;
|
||||
if (this->m_info) {
|
||||
this->m_data = new MxU8[size];
|
||||
if (this->m_data) {
|
||||
memcpy(this->m_info, p_info, sizeof(*this->m_info));
|
||||
this->m_bmiHeader = &this->m_info->bmiHeader;
|
||||
this->m_paletteData = this->m_info->bmiColors;
|
||||
result = SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (result != SUCCESS) {
|
||||
if (this->m_info) {
|
||||
delete this->m_info;
|
||||
this->m_info = NULL;
|
||||
}
|
||||
|
||||
if (this->m_data) {
|
||||
delete this->m_data;
|
||||
this->m_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bd450
|
||||
MxResult MxBitmap::ImportColorsToPalette(RGBQUAD* p_rgbquad, MxPalette* p_palette)
|
||||
{
|
||||
MxResult ret = FAILURE;
|
||||
PALETTEENTRY entries[256];
|
||||
|
||||
if (p_palette) {
|
||||
if (p_palette->GetEntries(entries))
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
MxPalette local_pal;
|
||||
if (local_pal.GetEntries(entries))
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (MxS32 i = 0; i < 256; i++) {
|
||||
p_rgbquad[i].rgbRed = entries[i].peRed;
|
||||
p_rgbquad[i].rgbGreen = entries[i].peGreen;
|
||||
p_rgbquad[i].rgbBlue = entries[i].peBlue;
|
||||
p_rgbquad[i].rgbReserved = 0;
|
||||
}
|
||||
|
||||
ret = SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bcaa0
|
||||
MxResult MxBitmap::SetSize(MxS32 p_width, MxS32 p_height, MxPalette* p_palette, MxBool p_isHighColor)
|
||||
{
|
||||
|
@ -189,6 +99,91 @@ MxResult MxBitmap::SetSize(MxS32 p_width, MxS32 p_height, MxPalette* p_palette,
|
|||
return ret;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bcba0
|
||||
MxResult MxBitmap::ImportBitmapInfo(MxBITMAPINFO* p_info)
|
||||
{
|
||||
MxResult result = FAILURE;
|
||||
MxLong width = p_info->bmiHeader.biWidth;
|
||||
MxLong height = p_info->bmiHeader.biHeight;
|
||||
MxLong size = AlignToFourByte(width) * height;
|
||||
|
||||
this->m_info = new MxBITMAPINFO;
|
||||
if (this->m_info) {
|
||||
this->m_data = new MxU8[size];
|
||||
if (this->m_data) {
|
||||
memcpy(this->m_info, p_info, sizeof(*this->m_info));
|
||||
this->m_bmiHeader = &this->m_info->bmiHeader;
|
||||
this->m_paletteData = this->m_info->bmiColors;
|
||||
result = SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (result != SUCCESS) {
|
||||
if (this->m_info) {
|
||||
delete this->m_info;
|
||||
this->m_info = NULL;
|
||||
}
|
||||
|
||||
if (this->m_data) {
|
||||
delete this->m_data;
|
||||
this->m_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bcc40
|
||||
MxResult MxBitmap::ImportBitmap(MxBitmap* p_bitmap)
|
||||
{
|
||||
MxResult result = FAILURE;
|
||||
|
||||
this->m_info = new MxBITMAPINFO;
|
||||
if (this->m_info) {
|
||||
MxLong height = _Abs(p_bitmap->m_bmiHeader->biHeight);
|
||||
this->m_data = new MxU8[AlignToFourByte(p_bitmap->m_bmiHeader->biWidth) * height];
|
||||
if (this->m_data) {
|
||||
memcpy(this->m_info, p_bitmap->m_info, sizeof(*this->m_info));
|
||||
height = _Abs(p_bitmap->m_bmiHeader->biHeight);
|
||||
memcpy(this->m_data, p_bitmap->m_data, AlignToFourByte(p_bitmap->m_bmiHeader->biWidth) * height);
|
||||
|
||||
result = SUCCESS;
|
||||
this->m_bmiHeader = &this->m_info->bmiHeader;
|
||||
this->m_paletteData = this->m_info->bmiColors;
|
||||
}
|
||||
}
|
||||
|
||||
if (result != SUCCESS) {
|
||||
if (this->m_info) {
|
||||
delete this->m_info;
|
||||
this->m_info = NULL;
|
||||
}
|
||||
|
||||
if (this->m_data) {
|
||||
delete this->m_data;
|
||||
this->m_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bcd10
|
||||
MxLong MxBitmap::Read(const char* p_filename)
|
||||
{
|
||||
MxResult result = FAILURE;
|
||||
HANDLE handle =
|
||||
CreateFileA(p_filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (handle != INVALID_HANDLE_VALUE && !LoadFile(handle))
|
||||
result = SUCCESS;
|
||||
|
||||
if (handle)
|
||||
CloseHandle(handle);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bcd60
|
||||
MxResult MxBitmap::LoadFile(HANDLE p_handle)
|
||||
{
|
||||
|
@ -236,28 +231,6 @@ MxResult MxBitmap::LoadFile(HANDLE p_handle)
|
|||
return result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bcd10
|
||||
MxLong MxBitmap::Read(const char* p_filename)
|
||||
{
|
||||
MxResult result = FAILURE;
|
||||
HANDLE handle =
|
||||
CreateFileA(p_filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (handle != INVALID_HANDLE_VALUE && !LoadFile(handle))
|
||||
result = SUCCESS;
|
||||
|
||||
if (handle)
|
||||
CloseHandle(handle);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1004e0d0
|
||||
int MxBitmap::vtable28(int)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bce70 STUB
|
||||
void MxBitmap::vtable2c(int, int, int, int, int, int, int)
|
||||
{
|
||||
|
@ -393,3 +366,30 @@ MxResult MxBitmap::StretchBits(
|
|||
SRCCOPY
|
||||
);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bd450
|
||||
MxResult MxBitmap::ImportColorsToPalette(RGBQUAD* p_rgbquad, MxPalette* p_palette)
|
||||
{
|
||||
MxResult ret = FAILURE;
|
||||
PALETTEENTRY entries[256];
|
||||
|
||||
if (p_palette) {
|
||||
if (p_palette->GetEntries(entries))
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
MxPalette local_pal;
|
||||
if (local_pal.GetEntries(entries))
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (MxS32 i = 0; i < 256; i++) {
|
||||
p_rgbquad[i].rgbRed = entries[i].peRed;
|
||||
p_rgbquad[i].rgbGreen = entries[i].peGreen;
|
||||
p_rgbquad[i].rgbBlue = entries[i].peBlue;
|
||||
p_rgbquad[i].rgbReserved = 0;
|
||||
}
|
||||
|
||||
ret = SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,14 @@
|
|||
|
||||
DECOMP_SIZE_ASSERT(MxCompositePresenter, 0x4c);
|
||||
|
||||
// OFFSET: LEGO1 0x1000caf0
|
||||
MxBool MxCompositePresenter::VTable0x64(undefined4 p_unknown)
|
||||
{
|
||||
if (m_compositePresenter)
|
||||
return m_compositePresenter->VTable0x64(p_unknown);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b60b0
|
||||
MxCompositePresenter::MxCompositePresenter()
|
||||
{
|
||||
|
@ -34,11 +42,3 @@ 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;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,12 @@
|
|||
|
||||
#include "define.h"
|
||||
|
||||
// OFFSET: LEGO1 0x10001f70
|
||||
MxResult MxCore::Tickle()
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ae1a0
|
||||
MxCore::MxCore()
|
||||
{
|
||||
|
@ -19,9 +25,3 @@ MxLong MxCore::Notify(MxParam& p)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10001f70
|
||||
MxResult MxCore::Tickle()
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,13 @@
|
|||
|
||||
class MxParam;
|
||||
|
||||
// TODO: Find proper compilation unit to put these
|
||||
// OFFSET: LEGO1 0x100140d0 TEMPLATE
|
||||
// MxCore::IsA
|
||||
|
||||
// OFFSET: LEGO1 0x100144c0 TEMPLATE
|
||||
// MxCore::ClassName
|
||||
|
||||
// VTABLE 0x100dc0f8
|
||||
// SIZE 0x8
|
||||
class MxCore {
|
||||
|
@ -17,14 +24,12 @@ class MxCore {
|
|||
__declspec(dllexport) virtual MxLong Notify(MxParam& p); // vtable+04
|
||||
virtual MxResult Tickle(); // vtable+08
|
||||
|
||||
// OFFSET: LEGO1 0x100144c0
|
||||
inline virtual const char* ClassName() const // vtable+0c
|
||||
{
|
||||
// 0x100f007c
|
||||
return "MxCore";
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100140d0
|
||||
inline virtual MxBool IsA(const char* name) const // vtable+10
|
||||
{
|
||||
return !strcmp(name, MxCore::ClassName());
|
||||
|
|
|
@ -31,12 +31,6 @@ MxCriticalSection::~MxCriticalSection()
|
|||
DeleteCriticalSection(&this->m_criticalSection);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b6e00
|
||||
void MxCriticalSection::SetDoMutex()
|
||||
{
|
||||
g_useMutex = 1;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b6d80
|
||||
void MxCriticalSection::Enter()
|
||||
{
|
||||
|
@ -70,3 +64,9 @@ void MxCriticalSection::Leave()
|
|||
|
||||
LeaveCriticalSection(&this->m_criticalSection);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b6e00
|
||||
void MxCriticalSection::SetDoMutex()
|
||||
{
|
||||
g_useMutex = 1;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -17,13 +17,6 @@ MxDiskStreamController::~MxDiskStreamController()
|
|||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c8640 STUB
|
||||
MxResult MxDiskStreamController::Tickle()
|
||||
{
|
||||
// TODO
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c7790
|
||||
MxResult MxDiskStreamController::Open(const char* p_filename)
|
||||
{
|
||||
|
@ -56,17 +49,9 @@ MxResult MxDiskStreamController::vtable0x18(undefined4 p_unknown, undefined4 p_u
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c7ff0 STUB
|
||||
MxResult MxDiskStreamController::vtable0x20(MxDSAction* p_action)
|
||||
// OFFSET: LEGO1 0x100c7960
|
||||
MxResult MxDiskStreamController::vtable0x34(undefined4 p_unknown)
|
||||
{
|
||||
// TODO
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c8160 STUB
|
||||
MxResult MxDiskStreamController::vtable0x24(undefined4 p_unknown)
|
||||
{
|
||||
// TODO
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
|
@ -84,8 +69,23 @@ MxResult MxDiskStreamController::vtable0x30(undefined4 p_unknown)
|
|||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c7960
|
||||
MxResult MxDiskStreamController::vtable0x34(undefined4 p_unknown)
|
||||
// OFFSET: LEGO1 0x100c7ff0 STUB
|
||||
MxResult MxDiskStreamController::vtable0x20(MxDSAction* p_action)
|
||||
{
|
||||
// TODO
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c8160 STUB
|
||||
MxResult MxDiskStreamController::vtable0x24(undefined4 p_unknown)
|
||||
{
|
||||
// TODO
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c8640 STUB
|
||||
MxResult MxDiskStreamController::Tickle()
|
||||
{
|
||||
// TODO
|
||||
return SUCCESS;
|
||||
}
|
||||
|
|
|
@ -70,6 +70,12 @@ MxResult MxDiskStreamProvider::SetResourceToGet(MxStreamController* p_resource)
|
|||
return result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100d15e0 STUB
|
||||
void MxDiskStreamProvider::vtable0x20(undefined4 p_unknown1)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100d1750
|
||||
MxResult MxDiskStreamProvider::WaitForWorkToComplete()
|
||||
{
|
||||
|
@ -99,12 +105,6 @@ MxU32 MxDiskStreamProvider::GetStreamBuffersNum()
|
|||
return m_pFile->GetStreamBuffersNum();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100d15e0 STUB
|
||||
void MxDiskStreamProvider::vtable0x20(undefined4 p_unknown1)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100d1eb0
|
||||
MxU32 MxDiskStreamProvider::GetLengthInDWords()
|
||||
{
|
||||
|
|
|
@ -28,6 +28,12 @@ void MxDisplaySurface::Reset()
|
|||
memset(&this->m_surfaceDesc, 0, sizeof(this->m_surfaceDesc));
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ba640 STUB
|
||||
void MxDisplaySurface::FUN_100ba640()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ba790
|
||||
MxResult MxDisplaySurface::Init(
|
||||
MxVideoParam& p_videoParam,
|
||||
|
@ -178,33 +184,12 @@ void MxDisplaySurface::SetPalette(MxPalette* p_palette)
|
|||
{
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bc200 STUB
|
||||
void MxDisplaySurface::vtable24(
|
||||
LPDDSURFACEDESC,
|
||||
MxBitmap*,
|
||||
undefined4,
|
||||
undefined4,
|
||||
undefined4,
|
||||
undefined4,
|
||||
undefined4,
|
||||
undefined4
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bacc0 STUB
|
||||
MxBool MxDisplaySurface::vtable28(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bc630 STUB
|
||||
MxBool MxDisplaySurface::
|
||||
vtable2c(LPDDSURFACEDESC, MxBitmap*, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bb1d0 STUB
|
||||
MxBool MxDisplaySurface::vtable30(
|
||||
undefined4,
|
||||
|
@ -253,8 +238,23 @@ undefined4 MxDisplaySurface::vtable44(undefined4, undefined4*, undefined4, undef
|
|||
return 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ba640 STUB
|
||||
void MxDisplaySurface::FUN_100ba640()
|
||||
// OFFSET: LEGO1 0x100bc200 STUB
|
||||
void MxDisplaySurface::vtable24(
|
||||
LPDDSURFACEDESC,
|
||||
MxBitmap*,
|
||||
undefined4,
|
||||
undefined4,
|
||||
undefined4,
|
||||
undefined4,
|
||||
undefined4,
|
||||
undefined4
|
||||
)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bc630 STUB
|
||||
MxBool MxDisplaySurface::
|
||||
vtable2c(LPDDSURFACEDESC, MxBitmap*, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,36 @@ MxDSAction::MxDSAction()
|
|||
this->m_unkTimingField = INT_MIN;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ad940
|
||||
MxLong MxDSAction::GetDuration()
|
||||
{
|
||||
return this->m_duration;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ad950
|
||||
void MxDSAction::SetDuration(MxLong p_duration)
|
||||
{
|
||||
this->m_duration = p_duration;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ad960
|
||||
MxBool MxDSAction::HasId(MxU32 p_objectId)
|
||||
{
|
||||
return this->GetObjectId() == p_objectId;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ada40
|
||||
void MxDSAction::SetUnkTimingField(MxLong p_unkTimingField)
|
||||
{
|
||||
this->m_unkTimingField = p_unkTimingField;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ada50
|
||||
MxLong MxDSAction::GetUnkTimingField()
|
||||
{
|
||||
return this->m_unkTimingField;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ada80
|
||||
MxDSAction::~MxDSAction()
|
||||
{
|
||||
|
@ -58,17 +88,6 @@ void MxDSAction::CopyFrom(MxDSAction& p_dsAction)
|
|||
this->m_unkTimingField = p_dsAction.m_unkTimingField;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100adc10
|
||||
MxDSAction& MxDSAction::operator=(MxDSAction& p_dsAction)
|
||||
{
|
||||
if (this == &p_dsAction)
|
||||
return *this;
|
||||
|
||||
MxDSObject::operator=(p_dsAction);
|
||||
this->CopyFrom(p_dsAction);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100adbe0
|
||||
MxU32 MxDSAction::GetSizeOnDisk()
|
||||
{
|
||||
|
@ -80,42 +99,15 @@ MxU32 MxDSAction::GetSizeOnDisk()
|
|||
return totalSizeOnDisk;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100adf70
|
||||
void MxDSAction::Deserialize(char** p_source, MxS16 p_unk24)
|
||||
// OFFSET: LEGO1 0x100adc10
|
||||
MxDSAction& MxDSAction::operator=(MxDSAction& p_dsAction)
|
||||
{
|
||||
MxDSObject::Deserialize(p_source, p_unk24);
|
||||
if (this == &p_dsAction)
|
||||
return *this;
|
||||
|
||||
GetScalar(p_source, this->m_flags);
|
||||
GetScalar(p_source, this->m_startTime);
|
||||
GetScalar(p_source, this->m_duration);
|
||||
GetScalar(p_source, this->m_loopCount);
|
||||
GetDouble(p_source, this->m_location[0]);
|
||||
GetDouble(p_source, this->m_location[1]);
|
||||
GetDouble(p_source, this->m_location[2]);
|
||||
GetDouble(p_source, this->m_direction[0]);
|
||||
GetDouble(p_source, this->m_direction[1]);
|
||||
GetDouble(p_source, this->m_direction[2]);
|
||||
GetDouble(p_source, this->m_up[0]);
|
||||
GetDouble(p_source, this->m_up[1]);
|
||||
GetDouble(p_source, this->m_up[2]);
|
||||
|
||||
MxU16 extraLength = GetScalar((MxU16**) p_source);
|
||||
if (extraLength) {
|
||||
AppendData(extraLength, *p_source);
|
||||
*p_source += extraLength;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ad940
|
||||
MxLong MxDSAction::GetDuration()
|
||||
{
|
||||
return this->m_duration;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ad950
|
||||
void MxDSAction::SetDuration(MxLong p_duration)
|
||||
{
|
||||
this->m_duration = p_duration;
|
||||
MxDSObject::operator=(p_dsAction);
|
||||
this->CopyFrom(p_dsAction);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100adc40
|
||||
|
@ -129,6 +121,12 @@ MxDSAction* MxDSAction::Clone()
|
|||
return clone;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100adcd0
|
||||
MxLong MxDSAction::GetElapsedTime()
|
||||
{
|
||||
return Timer()->GetTime() - this->m_unkTimingField;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100add00
|
||||
void MxDSAction::MergeFrom(MxDSAction& p_dsAction)
|
||||
{
|
||||
|
@ -178,30 +176,6 @@ void MxDSAction::MergeFrom(MxDSAction& p_dsAction)
|
|||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ad960
|
||||
MxBool MxDSAction::HasId(MxU32 p_objectId)
|
||||
{
|
||||
return this->GetObjectId() == p_objectId;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ada40
|
||||
void MxDSAction::SetUnkTimingField(MxLong p_unkTimingField)
|
||||
{
|
||||
this->m_unkTimingField = p_unkTimingField;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ada50
|
||||
MxLong MxDSAction::GetUnkTimingField()
|
||||
{
|
||||
return this->m_unkTimingField;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100adcd0
|
||||
MxLong MxDSAction::GetElapsedTime()
|
||||
{
|
||||
return Timer()->GetTime() - this->m_unkTimingField;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ade60
|
||||
void MxDSAction::AppendData(MxU16 p_extraLength, const char* p_extraData)
|
||||
{
|
||||
|
@ -229,3 +203,29 @@ void MxDSAction::AppendData(MxU16 p_extraLength, const char* p_extraData)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100adf70
|
||||
void MxDSAction::Deserialize(char** p_source, MxS16 p_unk24)
|
||||
{
|
||||
MxDSObject::Deserialize(p_source, p_unk24);
|
||||
|
||||
GetScalar(p_source, this->m_flags);
|
||||
GetScalar(p_source, this->m_startTime);
|
||||
GetScalar(p_source, this->m_duration);
|
||||
GetScalar(p_source, this->m_loopCount);
|
||||
GetDouble(p_source, this->m_location[0]);
|
||||
GetDouble(p_source, this->m_location[1]);
|
||||
GetDouble(p_source, this->m_location[2]);
|
||||
GetDouble(p_source, this->m_direction[0]);
|
||||
GetDouble(p_source, this->m_direction[1]);
|
||||
GetDouble(p_source, this->m_direction[2]);
|
||||
GetDouble(p_source, this->m_up[0]);
|
||||
GetDouble(p_source, this->m_up[1]);
|
||||
GetDouble(p_source, this->m_up[2]);
|
||||
|
||||
MxU16 extraLength = GetScalar((MxU16**) p_source);
|
||||
if (extraLength) {
|
||||
AppendData(extraLength, *p_source);
|
||||
*p_source += extraLength;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,12 @@
|
|||
#define SI_MAJOR_VERSION 2
|
||||
#define SI_MINOR_VERSION 2
|
||||
|
||||
// OFFSET: LEGO1 0x100bfed0
|
||||
MxDSFile::~MxDSFile()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100cc4b0
|
||||
MxDSFile::MxDSFile(const char* filename, MxULong skipReadingChunks)
|
||||
{
|
||||
|
@ -12,12 +18,6 @@ MxDSFile::MxDSFile(const char* filename, MxULong skipReadingChunks)
|
|||
m_skipReadingChunks = skipReadingChunks;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bfed0
|
||||
MxDSFile::~MxDSFile()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100cc590
|
||||
MxLong MxDSFile::Open(MxULong uStyle)
|
||||
{
|
||||
|
@ -46,16 +46,6 @@ MxLong MxDSFile::Open(MxULong uStyle)
|
|||
return longResult;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100cc780
|
||||
MxResult MxDSFile::Read(unsigned char* p_buf, MxULong p_nbytes)
|
||||
{
|
||||
if (m_io.Read(p_buf, p_nbytes) != p_nbytes)
|
||||
return FAILURE;
|
||||
|
||||
m_position += p_nbytes;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100cc620
|
||||
MxLong MxDSFile::ReadChunks()
|
||||
{
|
||||
|
@ -91,6 +81,30 @@ MxLong MxDSFile::ReadChunks()
|
|||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100cc740
|
||||
MxLong MxDSFile::Close()
|
||||
{
|
||||
m_io.Close(0);
|
||||
m_position = -1;
|
||||
memset(&m_header, 0, sizeof(m_header));
|
||||
if (m_lengthInDWords != 0) {
|
||||
m_lengthInDWords = 0;
|
||||
delete[] m_pBuffer;
|
||||
m_pBuffer = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100cc780
|
||||
MxResult MxDSFile::Read(unsigned char* p_buf, MxULong p_nbytes)
|
||||
{
|
||||
if (m_io.Read(p_buf, p_nbytes) != p_nbytes)
|
||||
return FAILURE;
|
||||
|
||||
m_position += p_nbytes;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100cc7b0
|
||||
MxLong MxDSFile::Seek(MxLong lOffset, int iOrigin)
|
||||
{
|
||||
|
@ -108,17 +122,3 @@ MxULong MxDSFile::GetStreamBuffersNum()
|
|||
{
|
||||
return m_header.streamBuffersNum;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100cc740
|
||||
MxLong MxDSFile::Close()
|
||||
{
|
||||
m_io.Close(0);
|
||||
m_position = -1;
|
||||
memset(&m_header, 0, sizeof(m_header));
|
||||
if (m_lengthInDWords != 0) {
|
||||
m_lengthInDWords = 0;
|
||||
delete[] m_pBuffer;
|
||||
m_pBuffer = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -47,6 +47,23 @@ MxDSMediaAction& MxDSMediaAction::operator=(MxDSMediaAction& p_dsMediaAction)
|
|||
return *this;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c8e80
|
||||
void MxDSMediaAction::CopyMediaSrcPath(const char* p_mediaSrcPath)
|
||||
{
|
||||
if (this->m_mediaSrcPath == p_mediaSrcPath)
|
||||
return;
|
||||
|
||||
delete[] this->m_mediaSrcPath;
|
||||
|
||||
if (p_mediaSrcPath) {
|
||||
this->m_mediaSrcPath = new char[strlen(p_mediaSrcPath) + 1];
|
||||
if (this->m_mediaSrcPath)
|
||||
strcpy(this->m_mediaSrcPath, p_mediaSrcPath);
|
||||
}
|
||||
else
|
||||
this->m_mediaSrcPath = NULL;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c8f10
|
||||
MxU32 MxDSMediaAction::GetSizeOnDisk()
|
||||
{
|
||||
|
@ -75,20 +92,3 @@ void MxDSMediaAction::Deserialize(char** p_source, MxS16 p_unk24)
|
|||
GetScalar(p_source, this->m_paletteManagement);
|
||||
GetScalar(p_source, this->m_sustainTime);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c8e80
|
||||
void MxDSMediaAction::CopyMediaSrcPath(const char* p_mediaSrcPath)
|
||||
{
|
||||
if (this->m_mediaSrcPath == p_mediaSrcPath)
|
||||
return;
|
||||
|
||||
delete[] this->m_mediaSrcPath;
|
||||
|
||||
if (p_mediaSrcPath) {
|
||||
this->m_mediaSrcPath = new char[strlen(p_mediaSrcPath) + 1];
|
||||
if (this->m_mediaSrcPath)
|
||||
strcpy(this->m_mediaSrcPath, p_mediaSrcPath);
|
||||
}
|
||||
else
|
||||
this->m_mediaSrcPath = NULL;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
#include "mxcore.h"
|
||||
#include "mxdstypes.h"
|
||||
|
||||
// TODO: Find proper compilation unit to put this
|
||||
// OFFSET: LEGO1 0x10005530 TEMPLATE
|
||||
// MxDSObject::SetAtomId
|
||||
|
||||
// VTABLE 0x100dc868
|
||||
// SIZE 0x2c
|
||||
class MxDSObject : public MxCore {
|
||||
|
@ -28,11 +32,9 @@ class MxDSObject : public MxCore {
|
|||
return !strcmp(name, MxDSObject::ClassName()) || MxCore::IsA(name);
|
||||
}; // vtable+10;
|
||||
|
||||
virtual undefined4 unk14(); // vtable+14;
|
||||
virtual MxU32 GetSizeOnDisk(); // vtable+18;
|
||||
virtual void Deserialize(char** p_source, MxS16 p_unk24); // vtable+1c;
|
||||
// OFFSET: ISLE 0x401c40
|
||||
// OFFSET: LEGO1 0x10005530
|
||||
virtual undefined4 unk14(); // vtable+14;
|
||||
virtual MxU32 GetSizeOnDisk(); // vtable+18;
|
||||
virtual void Deserialize(char** p_source, MxS16 p_unk24); // vtable+1c;
|
||||
inline virtual void SetAtomId(MxAtomId p_atomId) { this->m_atomId = p_atomId; } // vtable+20;
|
||||
|
||||
inline const MxAtomId& GetAtomId() { return this->m_atomId; }
|
||||
|
|
|
@ -34,23 +34,6 @@ MxDSSound& MxDSSound::operator=(MxDSSound& p_dsSound)
|
|||
return *this;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c95d0
|
||||
MxU32 MxDSSound::GetSizeOnDisk()
|
||||
{
|
||||
MxU32 totalSizeOnDisk = MxDSMediaAction::GetSizeOnDisk();
|
||||
|
||||
this->m_sizeOnDisk = sizeof(this->m_volume);
|
||||
return totalSizeOnDisk + 4;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c95a0
|
||||
void MxDSSound::Deserialize(char** p_source, MxS16 p_unk24)
|
||||
{
|
||||
MxDSMediaAction::Deserialize(p_source, p_unk24);
|
||||
|
||||
GetScalar(p_source, this->m_volume);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c9510
|
||||
MxDSAction* MxDSSound::Clone()
|
||||
{
|
||||
|
@ -61,3 +44,20 @@ MxDSAction* MxDSSound::Clone()
|
|||
|
||||
return clone;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c95a0
|
||||
void MxDSSound::Deserialize(char** p_source, MxS16 p_unk24)
|
||||
{
|
||||
MxDSMediaAction::Deserialize(p_source, p_unk24);
|
||||
|
||||
GetScalar(p_source, this->m_volume);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c95d0
|
||||
MxU32 MxDSSound::GetSizeOnDisk()
|
||||
{
|
||||
MxU32 totalSizeOnDisk = MxDSMediaAction::GetSizeOnDisk();
|
||||
|
||||
this->m_sizeOnDisk = sizeof(this->m_volume);
|
||||
return totalSizeOnDisk + 4;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,14 @@ MxDSStreamingAction::MxDSStreamingAction(MxDSAction& p_dsAction, MxU32 p_offset)
|
|||
this->m_bufferOffset = p_offset;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100cd090
|
||||
MxBool MxDSStreamingAction::HasId(MxU32 p_objectId)
|
||||
{
|
||||
if (this->m_internalAction)
|
||||
return this->m_internalAction->HasId(p_objectId);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100cd0d0
|
||||
MxDSStreamingAction::MxDSStreamingAction(MxDSStreamingAction& p_dsStreamingAction)
|
||||
{
|
||||
|
@ -32,6 +40,20 @@ MxDSStreamingAction::~MxDSStreamingAction()
|
|||
delete this->m_internalAction;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100cd1e0
|
||||
MxResult MxDSStreamingAction::Init()
|
||||
{
|
||||
this->m_unk94 = 0;
|
||||
this->m_bufferOffset = 0;
|
||||
this->m_unk9c = 0;
|
||||
this->m_unka0 = NULL;
|
||||
this->m_unka4 = NULL;
|
||||
this->m_unka8 = 0;
|
||||
this->m_unkac = 2;
|
||||
this->m_internalAction = NULL;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100cd220
|
||||
MxDSStreamingAction* MxDSStreamingAction::CopyFrom(MxDSStreamingAction& p_dsStreamingAction)
|
||||
{
|
||||
|
@ -48,28 +70,6 @@ MxDSStreamingAction* MxDSStreamingAction::CopyFrom(MxDSStreamingAction& p_dsStre
|
|||
return this;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100cd090
|
||||
MxBool MxDSStreamingAction::HasId(MxU32 p_objectId)
|
||||
{
|
||||
if (this->m_internalAction)
|
||||
return this->m_internalAction->HasId(p_objectId);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100cd1e0
|
||||
MxResult MxDSStreamingAction::Init()
|
||||
{
|
||||
this->m_unk94 = 0;
|
||||
this->m_bufferOffset = 0;
|
||||
this->m_unk9c = 0;
|
||||
this->m_unka0 = NULL;
|
||||
this->m_unka4 = NULL;
|
||||
this->m_unka8 = 0;
|
||||
this->m_unkac = 2;
|
||||
this->m_internalAction = NULL;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100cd2a0
|
||||
void MxDSStreamingAction::SetInternalAction(MxDSAction* p_dsAction)
|
||||
{
|
||||
|
|
|
@ -2,17 +2,6 @@
|
|||
|
||||
DECOMP_SIZE_ASSERT(MxEntity, 0x10)
|
||||
|
||||
// OFFSET: LEGO1 0x1001d190
|
||||
MxEntity::MxEntity()
|
||||
{
|
||||
this->m_mxEntityId = -1;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000c110
|
||||
MxEntity::~MxEntity()
|
||||
{
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10001070
|
||||
MxResult MxEntity::Create(MxS32 p_id, const MxAtomId& p_atom)
|
||||
{
|
||||
|
@ -20,3 +9,14 @@ MxResult MxEntity::Create(MxS32 p_id, const MxAtomId& p_atom)
|
|||
this->m_atom = p_atom;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000c110
|
||||
MxEntity::~MxEntity()
|
||||
{
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1001d190
|
||||
MxEntity::MxEntity()
|
||||
{
|
||||
this->m_mxEntityId = -1;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,12 @@ class MxFlcPresenter : public MxVideoPresenter {
|
|||
MxFlcPresenter();
|
||||
virtual ~MxFlcPresenter() override;
|
||||
|
||||
// OFFSET: LEGO1 0x1004e200
|
||||
inline virtual MxBool IsA(const char* name) const override // vtable+0x10
|
||||
{
|
||||
return !strcmp(name, MxFlcPresenter::ClassName()) || MxVideoPresenter::IsA(name);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b33f0
|
||||
inline virtual const char* ClassName() const override // vtable+0xc
|
||||
{
|
||||
|
@ -18,12 +24,6 @@ class MxFlcPresenter : public MxVideoPresenter {
|
|||
return "MxFlcPresenter";
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1004e200
|
||||
inline virtual MxBool IsA(const char* name) const override // vtable+0x10
|
||||
{
|
||||
return !strcmp(name, MxFlcPresenter::ClassName()) || MxVideoPresenter::IsA(name);
|
||||
}
|
||||
|
||||
virtual void VTable0x70() override; // vtable+0x70
|
||||
|
||||
undefined4* m_unk64;
|
||||
|
|
|
@ -28,24 +28,6 @@ MxResult MxMediaManager::Init()
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b8790
|
||||
MxResult MxMediaManager::Tickle()
|
||||
{
|
||||
MxAutoLocker lock(&this->m_criticalSection);
|
||||
MxPresenter* presenter;
|
||||
MxPresenterListCursor cursor(this->m_presenters);
|
||||
|
||||
while (cursor.Next(presenter))
|
||||
presenter->Tickle();
|
||||
|
||||
cursor.Reset();
|
||||
|
||||
while (cursor.Next(presenter))
|
||||
presenter->PutData();
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b85e0
|
||||
MxResult MxMediaManager::InitPresenters()
|
||||
{
|
||||
|
@ -72,6 +54,24 @@ void MxMediaManager::Destroy()
|
|||
Init();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b8790
|
||||
MxResult MxMediaManager::Tickle()
|
||||
{
|
||||
MxAutoLocker lock(&this->m_criticalSection);
|
||||
MxPresenter* presenter;
|
||||
MxPresenterListCursor cursor(this->m_presenters);
|
||||
|
||||
while (cursor.Next(presenter))
|
||||
presenter->Tickle();
|
||||
|
||||
cursor.Reset();
|
||||
|
||||
while (cursor.Next(presenter))
|
||||
presenter->PutData();
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b88c0
|
||||
void MxMediaManager::AddPresenter(MxPresenter& p_presenter)
|
||||
{
|
||||
|
|
|
@ -103,6 +103,69 @@ MxStreamChunk* MxMediaPresenter::NextChunk()
|
|||
return result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b5700
|
||||
MxResult MxMediaPresenter::StartAction(MxStreamController* p_controller, MxDSAction* p_action)
|
||||
{
|
||||
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 0x100b5bc0
|
||||
void MxMediaPresenter::EndAction()
|
||||
{
|
||||
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 0x100b5d10
|
||||
MxResult MxMediaPresenter::Tickle()
|
||||
{
|
||||
|
@ -170,6 +233,20 @@ void MxMediaPresenter::DoneTickle()
|
|||
EndAction();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b5f10
|
||||
void MxMediaPresenter::AppendChunk(MxStreamChunk* p_chunk)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b6030
|
||||
void MxMediaPresenter::Enable(MxBool p_enable)
|
||||
{
|
||||
|
@ -189,80 +266,3 @@ void MxMediaPresenter::Enable(MxBool p_enable)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b5700
|
||||
MxResult MxMediaPresenter::StartAction(MxStreamController* p_controller, MxDSAction* p_action)
|
||||
{
|
||||
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 0x100b5bc0
|
||||
void MxMediaPresenter::EndAction()
|
||||
{
|
||||
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
|
||||
void MxMediaPresenter::AppendChunk(MxStreamChunk* p_chunk)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -19,24 +19,6 @@ MxMusicManager::~MxMusicManager()
|
|||
Destroy(TRUE);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c0b20
|
||||
void MxMusicManager::DeinitializeMIDI()
|
||||
{
|
||||
m_criticalSection.Enter();
|
||||
|
||||
if (m_MIDIInitialized) {
|
||||
m_MIDIInitialized = FALSE;
|
||||
midiStreamStop(m_MIDIStreamH);
|
||||
midiOutUnprepareHeader((HMIDIOUT) m_MIDIStreamH, m_MIDIHdrP, sizeof(MIDIHDR));
|
||||
midiOutSetVolume((HMIDIOUT) m_MIDIStreamH, m_MIDIVolume);
|
||||
midiStreamClose(m_MIDIStreamH);
|
||||
delete m_MIDIHdrP;
|
||||
InitData();
|
||||
}
|
||||
|
||||
m_criticalSection.Leave();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c0690
|
||||
void MxMusicManager::Init()
|
||||
{
|
||||
|
@ -80,19 +62,6 @@ void MxMusicManager::Destroy(MxBool p_fromDestructor)
|
|||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c0930
|
||||
void MxMusicManager::Destroy()
|
||||
{
|
||||
Destroy(FALSE);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c09a0
|
||||
MxS32 MxMusicManager::CalculateVolume(MxS32 p_volume)
|
||||
{
|
||||
MxS32 result = (p_volume * 0xffff) / 100;
|
||||
return (result << 0x10) | result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c07f0
|
||||
void MxMusicManager::SetMIDIVolume()
|
||||
{
|
||||
|
@ -105,15 +74,6 @@ void MxMusicManager::SetMIDIVolume()
|
|||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c0940
|
||||
void MxMusicManager::SetVolume(MxS32 p_volume)
|
||||
{
|
||||
MxAudioManager::SetVolume(p_volume);
|
||||
m_criticalSection.Enter();
|
||||
SetMIDIVolume();
|
||||
m_criticalSection.Leave();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c0840
|
||||
MxResult MxMusicManager::Create(MxU32 p_frequencyMS, MxBool p_createThread)
|
||||
{
|
||||
|
@ -144,3 +104,43 @@ MxResult MxMusicManager::Create(MxU32 p_frequencyMS, MxBool p_createThread)
|
|||
|
||||
return status;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c0930
|
||||
void MxMusicManager::Destroy()
|
||||
{
|
||||
Destroy(FALSE);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c0940
|
||||
void MxMusicManager::SetVolume(MxS32 p_volume)
|
||||
{
|
||||
MxAudioManager::SetVolume(p_volume);
|
||||
m_criticalSection.Enter();
|
||||
SetMIDIVolume();
|
||||
m_criticalSection.Leave();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c09a0
|
||||
MxS32 MxMusicManager::CalculateVolume(MxS32 p_volume)
|
||||
{
|
||||
MxS32 result = (p_volume * 0xffff) / 100;
|
||||
return (result << 0x10) | result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c0b20
|
||||
void MxMusicManager::DeinitializeMIDI()
|
||||
{
|
||||
m_criticalSection.Enter();
|
||||
|
||||
if (m_MIDIInitialized) {
|
||||
m_MIDIInitialized = FALSE;
|
||||
midiStreamStop(m_MIDIStreamH);
|
||||
midiOutUnprepareHeader((HMIDIOUT) m_MIDIStreamH, m_MIDIHdrP, sizeof(MIDIHDR));
|
||||
midiOutSetVolume((HMIDIOUT) m_MIDIStreamH, m_MIDIVolume);
|
||||
midiStreamClose(m_MIDIStreamH);
|
||||
delete m_MIDIHdrP;
|
||||
InitData();
|
||||
}
|
||||
|
||||
m_criticalSection.Leave();
|
||||
}
|
||||
|
|
|
@ -44,6 +44,47 @@ MxNotificationManager::~MxNotificationManager()
|
|||
TickleManager()->UnregisterClient(this);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ac600
|
||||
MxResult MxNotificationManager::Create(MxU32 p_frequencyMS, MxBool p_createThread)
|
||||
{
|
||||
MxResult result = SUCCESS;
|
||||
m_queue = new MxNotificationPtrList();
|
||||
|
||||
if (m_queue == NULL) {
|
||||
result = FAILURE;
|
||||
}
|
||||
else {
|
||||
TickleManager()->RegisterClient(this, 10);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ac6c0
|
||||
MxResult MxNotificationManager::Send(MxCore* p_listener, MxNotificationParam* p_param)
|
||||
{
|
||||
MxAutoLocker lock(&m_lock);
|
||||
|
||||
if (m_active == FALSE) {
|
||||
return FAILURE;
|
||||
}
|
||||
else {
|
||||
MxIdList::iterator it = find(m_listenerIds.begin(), m_listenerIds.end(), p_listener->GetId());
|
||||
if (it == m_listenerIds.end()) {
|
||||
return FAILURE;
|
||||
}
|
||||
else {
|
||||
MxNotification* notif = new MxNotification(p_listener, p_param);
|
||||
if (notif != NULL) {
|
||||
m_queue->push_back(notif);
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ac800
|
||||
MxResult MxNotificationManager::Tickle()
|
||||
{
|
||||
|
@ -73,47 +114,6 @@ MxResult MxNotificationManager::Tickle()
|
|||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ac600
|
||||
MxResult MxNotificationManager::Create(MxU32 p_frequencyMS, MxBool p_createThread)
|
||||
{
|
||||
MxResult result = SUCCESS;
|
||||
m_queue = new MxNotificationPtrList();
|
||||
|
||||
if (m_queue == NULL) {
|
||||
result = FAILURE;
|
||||
}
|
||||
else {
|
||||
TickleManager()->RegisterClient(this, 10);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acd20
|
||||
void MxNotificationManager::Register(MxCore* p_listener)
|
||||
{
|
||||
MxAutoLocker lock(&m_lock);
|
||||
|
||||
MxIdList::iterator it = find(m_listenerIds.begin(), m_listenerIds.end(), p_listener->GetId());
|
||||
if (it != m_listenerIds.end())
|
||||
return;
|
||||
|
||||
m_listenerIds.push_back(p_listener->GetId());
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acdf0
|
||||
void MxNotificationManager::Unregister(MxCore* p_listener)
|
||||
{
|
||||
MxAutoLocker lock(&m_lock);
|
||||
|
||||
MxIdList::iterator it = find(m_listenerIds.begin(), m_listenerIds.end(), p_listener->GetId());
|
||||
|
||||
if (it != m_listenerIds.end()) {
|
||||
m_listenerIds.erase(it);
|
||||
FlushPending(p_listener);
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ac990
|
||||
void MxNotificationManager::FlushPending(MxCore* p_listener)
|
||||
{
|
||||
|
@ -163,27 +163,27 @@ void MxNotificationManager::FlushPending(MxCore* p_listener)
|
|||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ac6c0
|
||||
MxResult MxNotificationManager::Send(MxCore* p_listener, MxNotificationParam* p_param)
|
||||
// OFFSET: LEGO1 0x100acd20
|
||||
void MxNotificationManager::Register(MxCore* p_listener)
|
||||
{
|
||||
MxAutoLocker lock(&m_lock);
|
||||
|
||||
if (m_active == FALSE) {
|
||||
return FAILURE;
|
||||
}
|
||||
else {
|
||||
MxIdList::iterator it = find(m_listenerIds.begin(), m_listenerIds.end(), p_listener->GetId());
|
||||
if (it == m_listenerIds.end()) {
|
||||
return FAILURE;
|
||||
}
|
||||
else {
|
||||
MxNotification* notif = new MxNotification(p_listener, p_param);
|
||||
if (notif != NULL) {
|
||||
m_queue->push_back(notif);
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
MxIdList::iterator it = find(m_listenerIds.begin(), m_listenerIds.end(), p_listener->GetId());
|
||||
if (it != m_listenerIds.end())
|
||||
return;
|
||||
|
||||
return FAILURE;
|
||||
m_listenerIds.push_back(p_listener->GetId());
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acdf0
|
||||
void MxNotificationManager::Unregister(MxCore* p_listener)
|
||||
{
|
||||
MxAutoLocker lock(&m_lock);
|
||||
|
||||
MxIdList::iterator it = find(m_listenerIds.begin(), m_listenerIds.end(), p_listener->GetId());
|
||||
|
||||
if (it != m_listenerIds.end()) {
|
||||
m_listenerIds.erase(it);
|
||||
FlushPending(p_listener);
|
||||
}
|
||||
}
|
||||
|
|
370
LEGO1/mxomni.cpp
370
LEGO1/mxomni.cpp
|
@ -25,12 +25,115 @@ MxBool g_use3dSound;
|
|||
// 0x101015b0
|
||||
MxOmni* MxOmni::g_instance = NULL;
|
||||
|
||||
// OFFSET: LEGO1 0x100159e0
|
||||
void DeleteObjects(MxAtomId* p_id, MxS32 p_first, MxS32 p_last)
|
||||
{
|
||||
MxDSAction action;
|
||||
|
||||
action.SetAtomId(*p_id);
|
||||
action.SetUnknown24(-2);
|
||||
|
||||
for (MxS32 l_first = p_first, l_last = p_last; l_first <= l_last; l_first++) {
|
||||
action.SetObjectId(l_first);
|
||||
DeleteObject(action);
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10058a90
|
||||
MxBool MxOmni::IsTimerRunning()
|
||||
{
|
||||
return m_timerRunning;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acea0
|
||||
MxObjectFactory* ObjectFactory()
|
||||
{
|
||||
return MxOmni::GetInstance()->GetObjectFactory();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100aceb0
|
||||
MxNotificationManager* NotificationManager()
|
||||
{
|
||||
return MxOmni::GetInstance()->GetNotificationManager();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acec0
|
||||
MxTickleManager* TickleManager()
|
||||
{
|
||||
return MxOmni::GetInstance()->GetTickleManager();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100aced0
|
||||
MxTimer* Timer()
|
||||
{
|
||||
return MxOmni::GetInstance()->GetTimer();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acee0
|
||||
MxAtomIdCounterSet* AtomIdCounterSet()
|
||||
{
|
||||
return MxOmni::GetInstance()->GetAtomIdCounterSet();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acef0
|
||||
MxStreamer* Streamer()
|
||||
{
|
||||
return MxOmni::GetInstance()->GetStreamer();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acf00
|
||||
MxSoundManager* MSoundManager()
|
||||
{
|
||||
return MxOmni::GetInstance()->GetSoundManager();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acf10
|
||||
MxVideoManager* MVideoManager()
|
||||
{
|
||||
return MxOmni::GetInstance()->GetVideoManager();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acf20
|
||||
MxVariableTable* VariableTable()
|
||||
{
|
||||
return MxOmni::GetInstance()->GetVariableTable();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acf30
|
||||
MxMusicManager* MusicManager()
|
||||
{
|
||||
return MxOmni::GetInstance()->GetMusicManager();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acf40
|
||||
MxEventManager* EventManager()
|
||||
{
|
||||
return MxOmni::GetInstance()->GetEventManager();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acf70
|
||||
MxResult DeleteObject(MxDSAction& p_dsAction)
|
||||
{
|
||||
return MxOmni::GetInstance()->DeleteObject(p_dsAction);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100aef10
|
||||
MxOmni::MxOmni()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100aefb0
|
||||
MxEntity* MxOmni::FindWorld(const char*, MxS32, MxPresenter*)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100aefc0
|
||||
void MxOmni::NotifyCurrentEntity(MxNotificationParam* p_param)
|
||||
{
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100aeff0
|
||||
MxOmni::~MxOmni()
|
||||
{
|
||||
|
@ -55,130 +158,6 @@ void MxOmni::Init()
|
|||
m_timerRunning = NULL;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b0090
|
||||
MxResult MxOmni::Start(MxDSAction* p_dsAction)
|
||||
{
|
||||
MxResult result = FAILURE;
|
||||
if (p_dsAction->GetAtomId().GetInternal() != NULL && p_dsAction->GetObjectId() != -1 && m_streamer != NULL) {
|
||||
result = m_streamer->FUN_100b99b0(p_dsAction);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b00c0 STUB
|
||||
MxResult MxOmni::DeleteObject(MxDSAction& p_dsAction)
|
||||
{
|
||||
// TODO
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b09a0
|
||||
MxBool MxOmni::DoesEntityExist(MxDSAction& p_dsAction)
|
||||
{
|
||||
if (m_streamer->FUN_100b9b30(p_dsAction)) {
|
||||
MxNotificationPtrList* queue = m_notificationManager->GetQueue();
|
||||
|
||||
if (!queue || queue->size() == 0)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b00e0 STUB
|
||||
void MxOmni::Vtable0x2c()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100aefb0
|
||||
MxEntity* MxOmni::FindWorld(const char*, MxS32, MxPresenter*)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100aefc0
|
||||
void MxOmni::NotifyCurrentEntity(MxNotificationParam* p_param)
|
||||
{
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b09d0
|
||||
void MxOmni::StartTimer()
|
||||
{
|
||||
if (m_timerRunning == FALSE && m_timer != NULL && m_soundManager != NULL) {
|
||||
m_timer->Start();
|
||||
m_soundManager->vtable0x34();
|
||||
m_timerRunning = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b0a00
|
||||
void MxOmni::StopTimer()
|
||||
{
|
||||
if (m_timerRunning != FALSE && m_timer != NULL && m_soundManager != NULL) {
|
||||
m_timer->Stop();
|
||||
m_soundManager->vtable0x38();
|
||||
m_timerRunning = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10058a90
|
||||
MxBool MxOmni::IsTimerRunning()
|
||||
{
|
||||
return m_timerRunning;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b0690
|
||||
void MxOmni::DestroyInstance()
|
||||
{
|
||||
if (g_instance != NULL) {
|
||||
delete g_instance;
|
||||
g_instance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b0900
|
||||
const char* MxOmni::GetHD()
|
||||
{
|
||||
return g_hdPath;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b0940
|
||||
const char* MxOmni::GetCD()
|
||||
{
|
||||
return g_cdPath;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b0980
|
||||
MxBool MxOmni::IsSound3D()
|
||||
{
|
||||
return g_use3dSound;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b0910
|
||||
void MxOmni::SetHD(const char* p_hd)
|
||||
{
|
||||
strcpy(g_hdPath, p_hd);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b0950
|
||||
void MxOmni::SetCD(const char* p_cd)
|
||||
{
|
||||
strcpy(g_cdPath, p_cd);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b0990
|
||||
void MxOmni::SetSound3D(MxBool p_3dsound)
|
||||
{
|
||||
g_use3dSound = p_3dsound;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b0680
|
||||
MxOmni* MxOmni::GetInstance()
|
||||
{
|
||||
return g_instance;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100af0b0
|
||||
void MxOmni::SetInstance(MxOmni* instance)
|
||||
{
|
||||
|
@ -320,6 +299,45 @@ void MxOmni::Destroy()
|
|||
Init();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b0090
|
||||
MxResult MxOmni::Start(MxDSAction* p_dsAction)
|
||||
{
|
||||
MxResult result = FAILURE;
|
||||
if (p_dsAction->GetAtomId().GetInternal() != NULL && p_dsAction->GetObjectId() != -1 && m_streamer != NULL) {
|
||||
result = m_streamer->FUN_100b99b0(p_dsAction);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b00c0 STUB
|
||||
MxResult MxOmni::DeleteObject(MxDSAction& p_dsAction)
|
||||
{
|
||||
// TODO
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b00e0 STUB
|
||||
void MxOmni::Vtable0x2c()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b0680
|
||||
MxOmni* MxOmni::GetInstance()
|
||||
{
|
||||
return g_instance;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b0690
|
||||
void MxOmni::DestroyInstance()
|
||||
{
|
||||
if (g_instance != NULL) {
|
||||
delete g_instance;
|
||||
g_instance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b07f0
|
||||
MxLong MxOmni::Notify(MxParam& p)
|
||||
{
|
||||
|
@ -338,88 +356,70 @@ MxResult MxOmni::HandleNotificationType2(MxParam& p_param)
|
|||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acea0
|
||||
MxObjectFactory* ObjectFactory()
|
||||
// OFFSET: LEGO1 0x100b0900
|
||||
const char* MxOmni::GetHD()
|
||||
{
|
||||
return MxOmni::GetInstance()->GetObjectFactory();
|
||||
return g_hdPath;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100aceb0
|
||||
MxNotificationManager* NotificationManager()
|
||||
// OFFSET: LEGO1 0x100b0910
|
||||
void MxOmni::SetHD(const char* p_hd)
|
||||
{
|
||||
return MxOmni::GetInstance()->GetNotificationManager();
|
||||
strcpy(g_hdPath, p_hd);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acec0
|
||||
MxTickleManager* TickleManager()
|
||||
// OFFSET: LEGO1 0x100b0940
|
||||
const char* MxOmni::GetCD()
|
||||
{
|
||||
return MxOmni::GetInstance()->GetTickleManager();
|
||||
return g_cdPath;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100aced0
|
||||
MxTimer* Timer()
|
||||
// OFFSET: LEGO1 0x100b0950
|
||||
void MxOmni::SetCD(const char* p_cd)
|
||||
{
|
||||
return MxOmni::GetInstance()->GetTimer();
|
||||
strcpy(g_cdPath, p_cd);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acee0
|
||||
MxAtomIdCounterSet* AtomIdCounterSet()
|
||||
// OFFSET: LEGO1 0x100b0980
|
||||
MxBool MxOmni::IsSound3D()
|
||||
{
|
||||
return MxOmni::GetInstance()->GetAtomIdCounterSet();
|
||||
return g_use3dSound;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acef0
|
||||
MxStreamer* Streamer()
|
||||
// OFFSET: LEGO1 0x100b0990
|
||||
void MxOmni::SetSound3D(MxBool p_3dsound)
|
||||
{
|
||||
return MxOmni::GetInstance()->GetStreamer();
|
||||
g_use3dSound = p_3dsound;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acf00
|
||||
MxSoundManager* MSoundManager()
|
||||
// OFFSET: LEGO1 0x100b09a0
|
||||
MxBool MxOmni::DoesEntityExist(MxDSAction& p_dsAction)
|
||||
{
|
||||
return MxOmni::GetInstance()->GetSoundManager();
|
||||
if (m_streamer->FUN_100b9b30(p_dsAction)) {
|
||||
MxNotificationPtrList* queue = m_notificationManager->GetQueue();
|
||||
|
||||
if (!queue || queue->size() == 0)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acf10
|
||||
MxVideoManager* MVideoManager()
|
||||
// OFFSET: LEGO1 0x100b09d0
|
||||
void MxOmni::StartTimer()
|
||||
{
|
||||
return MxOmni::GetInstance()->GetVideoManager();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acf20
|
||||
MxVariableTable* VariableTable()
|
||||
{
|
||||
return MxOmni::GetInstance()->GetVariableTable();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acf30
|
||||
MxMusicManager* MusicManager()
|
||||
{
|
||||
return MxOmni::GetInstance()->GetMusicManager();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acf40
|
||||
MxEventManager* EventManager()
|
||||
{
|
||||
return MxOmni::GetInstance()->GetEventManager();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100acf70
|
||||
MxResult DeleteObject(MxDSAction& p_dsAction)
|
||||
{
|
||||
return MxOmni::GetInstance()->DeleteObject(p_dsAction);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100159e0
|
||||
void DeleteObjects(MxAtomId* p_id, MxS32 p_first, MxS32 p_last)
|
||||
{
|
||||
MxDSAction action;
|
||||
|
||||
action.SetAtomId(*p_id);
|
||||
action.SetUnknown24(-2);
|
||||
|
||||
for (MxS32 l_first = p_first, l_last = p_last; l_first <= l_last; l_first++) {
|
||||
action.SetObjectId(l_first);
|
||||
DeleteObject(action);
|
||||
if (m_timerRunning == FALSE && m_timer != NULL && m_soundManager != NULL) {
|
||||
m_timer->Start();
|
||||
m_soundManager->vtable0x34();
|
||||
m_timerRunning = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b0a00
|
||||
void MxOmni::StopTimer()
|
||||
{
|
||||
if (m_timerRunning != FALSE && m_timer != NULL && m_soundManager != NULL) {
|
||||
m_timer->Stop();
|
||||
m_soundManager->vtable0x38();
|
||||
m_timerRunning = FALSE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ MxPalette::MxPalette()
|
|||
this->m_skyColor = this->m_entries[141];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100BEED0
|
||||
// OFFSET: LEGO1 0x100beed0
|
||||
MxPalette::MxPalette(const RGBQUAD* p_colors)
|
||||
{
|
||||
this->m_overrideSkyColor = FALSE;
|
||||
|
@ -97,7 +97,7 @@ MxPalette::MxPalette(const RGBQUAD* p_colors)
|
|||
this->m_skyColor = this->m_entries[141];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 100bef90
|
||||
// OFFSET: LEGO1 0x100bef90
|
||||
MxPalette::~MxPalette()
|
||||
{
|
||||
if (m_palette) {
|
||||
|
@ -105,21 +105,30 @@ MxPalette::~MxPalette()
|
|||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bf390
|
||||
void MxPalette::ApplySystemEntriesToPalette(LPPALETTEENTRY p_entries)
|
||||
// OFFSET: LEGO1 0x100bf000
|
||||
LPDIRECTDRAWPALETTE MxPalette::CreateNativePalette()
|
||||
{
|
||||
HDC hdc;
|
||||
MxS32 i;
|
||||
if (this->m_palette == NULL) {
|
||||
for (i = 0; i < 10; i++)
|
||||
this->m_entries[i].peFlags = 0x80;
|
||||
for (i = 10; i < 136; i++)
|
||||
this->m_entries[i].peFlags = 0x44;
|
||||
for (i = 136; i < 140; i++)
|
||||
this->m_entries[i].peFlags = 0x84;
|
||||
this->m_entries[140].peFlags = 0x84;
|
||||
this->m_entries[141].peFlags = 0x44;
|
||||
for (i = 142; i < 246; i++)
|
||||
this->m_entries[i].peFlags = 0x84;
|
||||
for (i = 246; i < 256; i++)
|
||||
this->m_entries[i].peFlags = 0x80;
|
||||
|
||||
hdc = GetDC(0);
|
||||
if ((GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) != 0 && GetDeviceCaps(hdc, SIZEPALETTE) == 256) {
|
||||
GetSystemPaletteEntries(hdc, 0, 10, p_entries);
|
||||
GetSystemPaletteEntries(hdc, 246, 10, &p_entries[246]);
|
||||
if (MVideoManager() && MVideoManager()->GetDirectDraw()) {
|
||||
MVideoManager()->GetDirectDraw()->CreatePalette(4, this->m_entries, &this->m_palette, NULL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
memcpy(p_entries, g_defaultPaletteEntries, sizeof(PALETTEENTRY) * 10);
|
||||
memcpy(&p_entries[246], &g_defaultPaletteEntries[246], sizeof(PALETTEENTRY) * 10);
|
||||
}
|
||||
ReleaseDC(0, hdc);
|
||||
|
||||
return this->m_palette;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bf0b0
|
||||
|
@ -131,23 +140,6 @@ MxPalette* MxPalette::Clone()
|
|||
return result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bf420
|
||||
void MxPalette::GetDefaultPalette(LPPALETTEENTRY p_entries)
|
||||
{
|
||||
HDC hdc;
|
||||
|
||||
hdc = GetDC(0);
|
||||
if ((GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) != 0 && GetDeviceCaps(hdc, SIZEPALETTE) == 256) {
|
||||
GetSystemPaletteEntries(hdc, 0, 256, p_entries);
|
||||
memcpy(&p_entries[10], &g_defaultPaletteEntries[10], sizeof(PALETTEENTRY) * 236);
|
||||
}
|
||||
else {
|
||||
memcpy(p_entries, g_defaultPaletteEntries, sizeof(PALETTEENTRY) * 256);
|
||||
}
|
||||
|
||||
ReleaseDC(0, hdc);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bf150
|
||||
MxResult MxPalette::GetEntries(LPPALETTEENTRY p_entries)
|
||||
{
|
||||
|
@ -155,26 +147,6 @@ MxResult MxPalette::GetEntries(LPPALETTEENTRY p_entries)
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bf340
|
||||
MxBool MxPalette::operator==(MxPalette& other)
|
||||
{
|
||||
for (MxS32 i = 0; i < 256; i++) {
|
||||
if (this->m_entries[i].peRed != other.m_entries[i].peRed)
|
||||
return FALSE;
|
||||
if (this->m_entries[i].peGreen != other.m_entries[i].peGreen)
|
||||
return FALSE;
|
||||
if (this->m_entries[i].peBlue != other.m_entries[i].peBlue)
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bf330
|
||||
void MxPalette::Detach()
|
||||
{
|
||||
this->m_palette = NULL;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bf170
|
||||
MxResult MxPalette::SetEntries(LPPALETTEENTRY p_entries)
|
||||
{
|
||||
|
@ -240,7 +212,61 @@ MxResult MxPalette::SetSkyColor(LPPALETTEENTRY p_sky_color)
|
|||
return status;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100BF490
|
||||
// OFFSET: LEGO1 0x100bf330
|
||||
void MxPalette::Detach()
|
||||
{
|
||||
this->m_palette = NULL;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bf340
|
||||
MxBool MxPalette::operator==(MxPalette& other)
|
||||
{
|
||||
for (MxS32 i = 0; i < 256; i++) {
|
||||
if (this->m_entries[i].peRed != other.m_entries[i].peRed)
|
||||
return FALSE;
|
||||
if (this->m_entries[i].peGreen != other.m_entries[i].peGreen)
|
||||
return FALSE;
|
||||
if (this->m_entries[i].peBlue != other.m_entries[i].peBlue)
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bf390
|
||||
void MxPalette::ApplySystemEntriesToPalette(LPPALETTEENTRY p_entries)
|
||||
{
|
||||
HDC hdc;
|
||||
|
||||
hdc = GetDC(0);
|
||||
if ((GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) != 0 && GetDeviceCaps(hdc, SIZEPALETTE) == 256) {
|
||||
GetSystemPaletteEntries(hdc, 0, 10, p_entries);
|
||||
GetSystemPaletteEntries(hdc, 246, 10, &p_entries[246]);
|
||||
}
|
||||
else {
|
||||
memcpy(p_entries, g_defaultPaletteEntries, sizeof(PALETTEENTRY) * 10);
|
||||
memcpy(&p_entries[246], &g_defaultPaletteEntries[246], sizeof(PALETTEENTRY) * 10);
|
||||
}
|
||||
ReleaseDC(0, hdc);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bf420
|
||||
void MxPalette::GetDefaultPalette(LPPALETTEENTRY p_entries)
|
||||
{
|
||||
HDC hdc;
|
||||
|
||||
hdc = GetDC(0);
|
||||
if ((GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) != 0 && GetDeviceCaps(hdc, SIZEPALETTE) == 256) {
|
||||
GetSystemPaletteEntries(hdc, 0, 256, p_entries);
|
||||
memcpy(&p_entries[10], &g_defaultPaletteEntries[10], sizeof(PALETTEENTRY) * 236);
|
||||
}
|
||||
else {
|
||||
memcpy(p_entries, g_defaultPaletteEntries, sizeof(PALETTEENTRY) * 256);
|
||||
}
|
||||
|
||||
ReleaseDC(0, hdc);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bf490
|
||||
void MxPalette::Reset(MxBool p_ignoreSkyColor)
|
||||
{
|
||||
if (this->m_palette != NULL) {
|
||||
|
@ -252,29 +278,3 @@ void MxPalette::Reset(MxBool p_ignoreSkyColor)
|
|||
this->m_palette->SetEntries(0, 0, 256, this->m_entries);
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100BF000
|
||||
LPDIRECTDRAWPALETTE MxPalette::CreateNativePalette()
|
||||
{
|
||||
MxS32 i;
|
||||
if (this->m_palette == NULL) {
|
||||
for (i = 0; i < 10; i++)
|
||||
this->m_entries[i].peFlags = 0x80;
|
||||
for (i = 10; i < 136; i++)
|
||||
this->m_entries[i].peFlags = 0x44;
|
||||
for (i = 136; i < 140; i++)
|
||||
this->m_entries[i].peFlags = 0x84;
|
||||
this->m_entries[140].peFlags = 0x84;
|
||||
this->m_entries[141].peFlags = 0x44;
|
||||
for (i = 142; i < 246; i++)
|
||||
this->m_entries[i].peFlags = 0x84;
|
||||
for (i = 246; i < 256; i++)
|
||||
this->m_entries[i].peFlags = 0x80;
|
||||
|
||||
if (MVideoManager() && MVideoManager()->GetDirectDraw()) {
|
||||
MVideoManager()->GetDirectDraw()->CreatePalette(4, this->m_entries, &this->m_palette, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return this->m_palette;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,97 @@
|
|||
|
||||
DECOMP_SIZE_ASSERT(MxPresenter, 0x40);
|
||||
|
||||
// OFFSET: LEGO1 0x1000be30
|
||||
void MxPresenter::VTable0x14()
|
||||
{
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000be40
|
||||
void MxPresenter::ReadyTickle()
|
||||
{
|
||||
ParseExtra();
|
||||
|
||||
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
|
||||
m_currentTickleState = TickleState_Starting;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000be60
|
||||
void MxPresenter::StartingTickle()
|
||||
{
|
||||
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
|
||||
m_currentTickleState = TickleState_Streaming;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000be80
|
||||
void MxPresenter::StreamingTickle()
|
||||
{
|
||||
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
|
||||
m_currentTickleState = TickleState_Repeating;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000bea0
|
||||
void MxPresenter::RepeatingTickle()
|
||||
{
|
||||
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
|
||||
m_currentTickleState = TickleState_unk5;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000bec0
|
||||
void MxPresenter::Unk5Tickle()
|
||||
{
|
||||
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
|
||||
m_currentTickleState = TickleState_Done;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000bee0
|
||||
void MxPresenter::DoneTickle()
|
||||
{
|
||||
m_previousTickleStates |= 1 << m_currentTickleState;
|
||||
m_currentTickleState = TickleState_Idle;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000bf00
|
||||
MxPresenter::~MxPresenter()
|
||||
{
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000bf70
|
||||
MxResult MxPresenter::AddToManager()
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000bf80
|
||||
void MxPresenter::Destroy()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000bf90
|
||||
void MxPresenter::SetTickleState(TickleState p_tickleState)
|
||||
{
|
||||
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
|
||||
m_currentTickleState = p_tickleState;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000bfb0
|
||||
MxBool MxPresenter::HasTickleStatePassed(TickleState p_tickleState)
|
||||
{
|
||||
return m_previousTickleStates & (1 << (unsigned char) p_tickleState);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000bfc0
|
||||
undefined4 MxPresenter::PutData()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000bfd0
|
||||
MxBool MxPresenter::IsHit(MxS32 p_x, MxS32 p_y)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b4d50
|
||||
void MxPresenter::Init()
|
||||
{
|
||||
|
@ -27,6 +118,44 @@ void MxPresenter::Init()
|
|||
m_previousTickleStates = 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b4d80
|
||||
MxResult MxPresenter::StartAction(MxStreamController*, MxDSAction* p_action)
|
||||
{
|
||||
MxAutoLocker lock(&this->m_criticalSection);
|
||||
|
||||
this->m_action = p_action;
|
||||
|
||||
const Vector3Data& location = this->m_action->GetLocation();
|
||||
MxS32 previousTickleState = this->m_currentTickleState;
|
||||
|
||||
this->m_location = MxPoint32(this->m_action->GetLocation()[0], this->m_action->GetLocation()[1]);
|
||||
this->m_displayZ = this->m_action->GetLocation()[2];
|
||||
this->m_previousTickleStates |= 1 << (unsigned char) previousTickleState;
|
||||
this->m_currentTickleState = TickleState_Ready;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b4e40
|
||||
void MxPresenter::EndAction()
|
||||
{
|
||||
if (this->m_action == FALSE)
|
||||
return;
|
||||
|
||||
MxAutoLocker lock(&this->m_criticalSection);
|
||||
|
||||
if (!this->m_compositePresenter) {
|
||||
MxOmni::GetInstance()->NotifyCurrentEntity(
|
||||
&MxEndActionNotificationParam(c_notificationEndAction, NULL, this->m_action, TRUE)
|
||||
);
|
||||
}
|
||||
|
||||
this->m_action = FALSE;
|
||||
MxS32 previousTickleState = 1 << m_currentTickleState;
|
||||
this->m_previousTickleStates |= previousTickleState;
|
||||
this->m_currentTickleState = TickleState_Idle;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b4fc0
|
||||
void MxPresenter::ParseExtra()
|
||||
{
|
||||
|
@ -71,11 +200,6 @@ void MxPresenter::SendToCompositePresenter(MxOmni* p_omni)
|
|||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000bf00
|
||||
MxPresenter::~MxPresenter()
|
||||
{
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b5200
|
||||
MxResult MxPresenter::Tickle()
|
||||
{
|
||||
|
@ -116,44 +240,6 @@ MxResult MxPresenter::Tickle()
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b4d80
|
||||
MxResult MxPresenter::StartAction(MxStreamController*, MxDSAction* p_action)
|
||||
{
|
||||
MxAutoLocker lock(&this->m_criticalSection);
|
||||
|
||||
this->m_action = p_action;
|
||||
|
||||
const Vector3Data& location = this->m_action->GetLocation();
|
||||
MxS32 previousTickleState = this->m_currentTickleState;
|
||||
|
||||
this->m_location = MxPoint32(this->m_action->GetLocation()[0], this->m_action->GetLocation()[1]);
|
||||
this->m_displayZ = this->m_action->GetLocation()[2];
|
||||
this->m_previousTickleStates |= 1 << (unsigned char) previousTickleState;
|
||||
this->m_currentTickleState = TickleState_Ready;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b4e40
|
||||
void MxPresenter::EndAction()
|
||||
{
|
||||
if (this->m_action == FALSE)
|
||||
return;
|
||||
|
||||
MxAutoLocker lock(&this->m_criticalSection);
|
||||
|
||||
if (!this->m_compositePresenter) {
|
||||
MxOmni::GetInstance()->NotifyCurrentEntity(
|
||||
&MxEndActionNotificationParam(c_notificationEndAction, NULL, this->m_action, TRUE)
|
||||
);
|
||||
}
|
||||
|
||||
this->m_action = FALSE;
|
||||
MxS32 previousTickleState = 1 << m_currentTickleState;
|
||||
this->m_previousTickleStates |= previousTickleState;
|
||||
this->m_currentTickleState = TickleState_Idle;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b52d0
|
||||
void MxPresenter::Enable(MxBool p_enable)
|
||||
{
|
||||
|
@ -223,89 +309,3 @@ MxBool MxPresenter::IsEnabled()
|
|||
{
|
||||
return this->m_action && this->m_action->GetFlags() & MxDSAction::Flag_Enabled;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000be30
|
||||
void MxPresenter::VTable0x14()
|
||||
{
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000be40
|
||||
void MxPresenter::ReadyTickle()
|
||||
{
|
||||
ParseExtra();
|
||||
|
||||
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
|
||||
m_currentTickleState = TickleState_Starting;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000be60
|
||||
void MxPresenter::StartingTickle()
|
||||
{
|
||||
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
|
||||
m_currentTickleState = TickleState_Streaming;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000be80
|
||||
void MxPresenter::StreamingTickle()
|
||||
{
|
||||
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
|
||||
m_currentTickleState = TickleState_Repeating;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000bea0
|
||||
void MxPresenter::RepeatingTickle()
|
||||
{
|
||||
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
|
||||
m_currentTickleState = TickleState_unk5;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000bec0
|
||||
void MxPresenter::Unk5Tickle()
|
||||
{
|
||||
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
|
||||
m_currentTickleState = TickleState_Done;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000bee0
|
||||
void MxPresenter::DoneTickle()
|
||||
{
|
||||
m_previousTickleStates |= 1 << m_currentTickleState;
|
||||
m_currentTickleState = TickleState_Idle;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000bf70
|
||||
MxResult MxPresenter::AddToManager()
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000bf80
|
||||
void MxPresenter::Destroy()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000bf90
|
||||
void MxPresenter::SetTickleState(TickleState p_tickleState)
|
||||
{
|
||||
m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState;
|
||||
m_currentTickleState = p_tickleState;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000bfb0
|
||||
MxBool MxPresenter::HasTickleStatePassed(TickleState p_tickleState)
|
||||
{
|
||||
return m_previousTickleStates & (1 << (unsigned char) p_tickleState);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000bfc0
|
||||
undefined4 MxPresenter::PutData()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1000bfd0
|
||||
MxBool MxPresenter::IsHit(MxS32 p_x, MxS32 p_y)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -5,11 +5,7 @@
|
|||
|
||||
DECOMP_SIZE_ASSERT(MxRAMStreamController, 0x98);
|
||||
|
||||
// OFFSET: LEGO1 0x100d0d80 STUB
|
||||
undefined* __cdecl FUN_100d0d80(MxU32* p_fileSizeBuffer, MxU32 p_fileSize)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
undefined* __cdecl FUN_100d0d80(MxU32* p_fileSizeBuffer, MxU32 p_fileSize);
|
||||
|
||||
// OFFSET: LEGO1 0x100c6110
|
||||
MxResult MxRAMStreamController::Open(const char* p_filename)
|
||||
|
@ -52,3 +48,9 @@ MxResult MxRAMStreamController::vtable0x24(undefined4 p_unknown)
|
|||
// TODO STUB
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100d0d80 STUB
|
||||
undefined* __cdecl FUN_100d0d80(MxU32* p_fileSizeBuffer, MxU32 p_fileSize)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -14,27 +14,6 @@ MxRAMStreamProvider::MxRAMStreamProvider()
|
|||
m_bufferForDWords = NULL;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100d0a50
|
||||
MxRAMStreamProvider::~MxRAMStreamProvider()
|
||||
{
|
||||
m_bufferSize = 0;
|
||||
m_fileSize = 0;
|
||||
|
||||
free(m_pBufferOfFileSize);
|
||||
m_pBufferOfFileSize = NULL;
|
||||
|
||||
m_lengthInDWords = 0;
|
||||
|
||||
free(m_bufferForDWords);
|
||||
m_bufferForDWords = NULL;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100d0ae0 STUB
|
||||
MxResult MxRAMStreamProvider::SetResourceToGet(MxStreamController* p_resource)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100d0930
|
||||
MxU32 MxRAMStreamProvider::GetFileSize()
|
||||
{
|
||||
|
@ -58,3 +37,24 @@ MxU32* MxRAMStreamProvider::GetBufferForDWords()
|
|||
{
|
||||
return m_bufferForDWords;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100d0a50
|
||||
MxRAMStreamProvider::~MxRAMStreamProvider()
|
||||
{
|
||||
m_bufferSize = 0;
|
||||
m_fileSize = 0;
|
||||
|
||||
free(m_pBufferOfFileSize);
|
||||
m_pBufferOfFileSize = NULL;
|
||||
|
||||
m_lengthInDWords = 0;
|
||||
|
||||
free(m_bufferForDWords);
|
||||
m_bufferForDWords = NULL;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100d0ae0 STUB
|
||||
MxResult MxRAMStreamProvider::SetResourceToGet(MxStreamController* p_resource)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,12 @@
|
|||
|
||||
#include "mxregion.h"
|
||||
|
||||
// OFFSET: LEGO1 0x100c32e0 TEMPLATE
|
||||
// MxCollection<MxRegionTopBottom *>::Compare
|
||||
|
||||
// OFFSET: LEGO1 0x100c3340 TEMPLATE
|
||||
// MxCollection<MxRegionTopBottom *>::Destroy
|
||||
|
||||
// OFFSET: LEGO1 0x100c33e0
|
||||
void MxRegionList::Destroy(MxRegionTopBottom* p_topBottom)
|
||||
{
|
||||
|
@ -12,18 +18,6 @@ void MxRegionList::Destroy(MxRegionTopBottom* p_topBottom)
|
|||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c4e80
|
||||
void MxRegionLeftRightList::Destroy(MxRegionLeftRight* p_leftRight)
|
||||
{
|
||||
delete p_leftRight;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c32e0 TEMPLATE
|
||||
// MxCollection<MxRegionTopBottom *>::Compare
|
||||
|
||||
// OFFSET: LEGO1 0x100c3340 TEMPLATE
|
||||
// MxCollection<MxRegionTopBottom *>::Destroy
|
||||
|
||||
// OFFSET: LEGO1 0x100c34d0 TEMPLATE
|
||||
// MxCollection<MxRegionTopBottom *>::`scalar deleting destructor'
|
||||
|
||||
|
@ -39,6 +33,12 @@ void MxRegionLeftRightList::Destroy(MxRegionLeftRight* p_leftRight)
|
|||
// OFFSET: LEGO1 0x100c4de0 TEMPLATE
|
||||
// MxCollection<MxRegionLeftRight *>::Destroy
|
||||
|
||||
// OFFSET: LEGO1 0x100c4e80
|
||||
void MxRegionLeftRightList::Destroy(MxRegionLeftRight* p_leftRight)
|
||||
{
|
||||
delete p_leftRight;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c4f50 TEMPLATE
|
||||
// MxCollection<MxRegionLeftRight *>::`scalar deleting destructor'
|
||||
|
||||
|
|
|
@ -41,6 +41,11 @@ void MxSmkPresenter::Destroy(MxBool p_fromDestructor)
|
|||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b3940 STUB
|
||||
void MxSmkPresenter::VTable0x5c(undefined4 p_unknown1)
|
||||
{
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b3960
|
||||
void MxSmkPresenter::VTable0x60()
|
||||
{
|
||||
|
@ -52,45 +57,11 @@ void MxSmkPresenter::VTable0x60()
|
|||
m_bitmap->SetSize(m_mxSmack.m_smack.m_width, m_mxSmack.m_smack.m_height, NULL, FALSE);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c5d40
|
||||
void MxSmkPresenter::FUN_100c5d40(MxSmack* p_mxSmack)
|
||||
{
|
||||
if (p_mxSmack->m_unk0x6a0)
|
||||
delete p_mxSmack->m_unk0x6a0;
|
||||
if (p_mxSmack->m_unk0x6a4)
|
||||
delete p_mxSmack->m_unk0x6a4;
|
||||
if (p_mxSmack->m_unk0x6a8)
|
||||
delete p_mxSmack->m_unk0x6a8;
|
||||
if (p_mxSmack->m_unk0x6ac)
|
||||
delete p_mxSmack->m_unk0x6ac;
|
||||
if (p_mxSmack->m_unk0x6b4)
|
||||
delete p_mxSmack->m_unk0x6b4;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b4300
|
||||
void MxSmkPresenter::Destroy()
|
||||
{
|
||||
Destroy(FALSE);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b3940 STUB
|
||||
void MxSmkPresenter::VTable0x5c(undefined4 p_unknown1)
|
||||
{
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b3a00 STUB
|
||||
void MxSmkPresenter::VTable0x68(undefined4 p_unknown1)
|
||||
{
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b42c0
|
||||
void MxSmkPresenter::VTable0x70()
|
||||
{
|
||||
MxPalette* palette = m_bitmap->CreatePalette();
|
||||
MVideoManager()->RealizePalette(palette);
|
||||
delete palette;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b4260
|
||||
MxU32 MxSmkPresenter::VTable0x88()
|
||||
{
|
||||
|
@ -111,3 +82,32 @@ MxU32 MxSmkPresenter::VTable0x88()
|
|||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b42c0
|
||||
void MxSmkPresenter::VTable0x70()
|
||||
{
|
||||
MxPalette* palette = m_bitmap->CreatePalette();
|
||||
MVideoManager()->RealizePalette(palette);
|
||||
delete palette;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b4300
|
||||
void MxSmkPresenter::Destroy()
|
||||
{
|
||||
Destroy(FALSE);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c5d40
|
||||
void MxSmkPresenter::FUN_100c5d40(MxSmack* p_mxSmack)
|
||||
{
|
||||
if (p_mxSmack->m_unk0x6a0)
|
||||
delete p_mxSmack->m_unk0x6a0;
|
||||
if (p_mxSmack->m_unk0x6a4)
|
||||
delete p_mxSmack->m_unk0x6a4;
|
||||
if (p_mxSmack->m_unk0x6a8)
|
||||
delete p_mxSmack->m_unk0x6a8;
|
||||
if (p_mxSmack->m_unk0x6ac)
|
||||
delete p_mxSmack->m_unk0x6ac;
|
||||
if (p_mxSmack->m_unk0x6b4)
|
||||
delete p_mxSmack->m_unk0x6b4;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,24 @@
|
|||
|
||||
DECOMP_SIZE_ASSERT(MxNextActionDataStart, 0x14)
|
||||
|
||||
// OFFSET: LEGO1 0x100b9400
|
||||
MxResult MxStreamController::vtable0x18(undefined4 p_unknown, undefined4 p_unknown2)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b9410
|
||||
MxResult MxStreamController::vtable0x1C(undefined4 p_unknown, undefined4 p_unknown2)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b9420
|
||||
MxResult MxStreamController::vtable0x28()
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c0b90 STUB
|
||||
MxStreamController::MxStreamController()
|
||||
{
|
||||
|
@ -18,13 +36,6 @@ MxStreamController::~MxStreamController()
|
|||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c20d0 STUB
|
||||
MxBool MxStreamController::FUN_100c20d0(MxDSObject& p_obj)
|
||||
{
|
||||
// TODO
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c1520
|
||||
MxResult MxStreamController::Open(const char* p_filename)
|
||||
{
|
||||
|
@ -36,18 +47,6 @@ MxResult MxStreamController::Open(const char* p_filename)
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b9400
|
||||
MxResult MxStreamController::vtable0x18(undefined4 p_unknown, undefined4 p_unknown2)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b9410
|
||||
MxResult MxStreamController::vtable0x1C(undefined4 p_unknown, undefined4 p_unknown2)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c1690
|
||||
MxResult MxStreamController::vtable0x20(MxDSAction* p_action)
|
||||
{
|
||||
|
@ -89,10 +88,10 @@ MxResult MxStreamController::FUN_100c1800(MxDSAction* p_action, MxU32 p_val)
|
|||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b9420
|
||||
MxResult MxStreamController::vtable0x28()
|
||||
// OFFSET: LEGO1 0x100c1a00 STUB
|
||||
MxResult MxStreamController::FUN_100c1a00(MxDSAction* p_action, MxU32 p_bufferval)
|
||||
{
|
||||
return SUCCESS;
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c1c10
|
||||
|
@ -111,8 +110,9 @@ MxResult MxStreamController::vtable0x30(undefined4 p_unknown)
|
|||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100c1a00 STUB
|
||||
MxResult MxStreamController::FUN_100c1a00(MxDSAction* p_action, MxU32 p_bufferval)
|
||||
// OFFSET: LEGO1 0x100c20d0 STUB
|
||||
MxBool MxStreamController::FUN_100c20d0(MxDSObject& p_obj)
|
||||
{
|
||||
return FAILURE;
|
||||
// TODO
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -6,11 +6,34 @@
|
|||
|
||||
#include <process.h>
|
||||
|
||||
// OFFSET: LEGO1 0x100bf690
|
||||
MxResult MxThread::Run()
|
||||
// OFFSET: LEGO1 0x100b8bb0
|
||||
MxTickleThread::MxTickleThread(MxCore* p_target, int p_frequencyMS)
|
||||
{
|
||||
m_semaphore.Release(1);
|
||||
return SUCCESS;
|
||||
m_target = p_target;
|
||||
m_frequencyMS = p_frequencyMS;
|
||||
}
|
||||
|
||||
// Match except for register allocation
|
||||
// OFFSET: LEGO1 0x100b8c90
|
||||
MxResult MxTickleThread::Run()
|
||||
{
|
||||
MxTimer* timer = Timer();
|
||||
int lastTickled = -m_frequencyMS;
|
||||
while (IsRunning()) {
|
||||
int currentTime = timer->GetTime();
|
||||
|
||||
if (currentTime < lastTickled) {
|
||||
lastTickled = -m_frequencyMS;
|
||||
}
|
||||
int timeRemainingMS = (m_frequencyMS - currentTime) + lastTickled;
|
||||
if (timeRemainingMS <= 0) {
|
||||
m_target->Tickle();
|
||||
timeRemainingMS = 0;
|
||||
lastTickled = currentTime;
|
||||
}
|
||||
Sleep(timeRemainingMS);
|
||||
}
|
||||
return MxThread::Run();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bf510
|
||||
|
@ -42,6 +65,12 @@ MxResult MxThread::Start(int p_stack, int p_flag)
|
|||
return result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bf660
|
||||
void MxThread::Sleep(MxS32 p_milliseconds)
|
||||
{
|
||||
::Sleep(p_milliseconds);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bf670
|
||||
void MxThread::Terminate()
|
||||
{
|
||||
|
@ -55,38 +84,9 @@ unsigned MxThread::ThreadProc(void* p_thread)
|
|||
return static_cast<MxThread*>(p_thread)->Run();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bf660
|
||||
void MxThread::Sleep(MxS32 p_milliseconds)
|
||||
// OFFSET: LEGO1 0x100bf690
|
||||
MxResult MxThread::Run()
|
||||
{
|
||||
::Sleep(p_milliseconds);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b8bb0
|
||||
MxTickleThread::MxTickleThread(MxCore* p_target, int p_frequencyMS)
|
||||
{
|
||||
m_target = p_target;
|
||||
m_frequencyMS = p_frequencyMS;
|
||||
}
|
||||
|
||||
// Match except for register allocation
|
||||
// OFFSET: LEGO1 0x100b8c90
|
||||
MxResult MxTickleThread::Run()
|
||||
{
|
||||
MxTimer* timer = Timer();
|
||||
int lastTickled = -m_frequencyMS;
|
||||
while (IsRunning()) {
|
||||
int currentTime = timer->GetTime();
|
||||
|
||||
if (currentTime < lastTickled) {
|
||||
lastTickled = -m_frequencyMS;
|
||||
}
|
||||
int timeRemainingMS = (m_frequencyMS - currentTime) + lastTickled;
|
||||
if (timeRemainingMS <= 0) {
|
||||
m_target->Tickle();
|
||||
timeRemainingMS = 0;
|
||||
lastTickled = currentTime;
|
||||
}
|
||||
Sleep(timeRemainingMS);
|
||||
}
|
||||
return MxThread::Run();
|
||||
m_semaphore.Release(1);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,13 @@ MxTimer::MxTimer()
|
|||
s_LastTimeCalculated = m_startTime;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ae140
|
||||
MxLong MxTimer::GetRealTime()
|
||||
{
|
||||
MxTimer::s_LastTimeCalculated = timeGetTime();
|
||||
return MxTimer::s_LastTimeCalculated - this->m_startTime;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ae160
|
||||
void MxTimer::Start()
|
||||
{
|
||||
|
@ -33,10 +40,3 @@ void MxTimer::Stop()
|
|||
// this feels very stupid but it's what the assembly does
|
||||
this->m_startTime = this->m_startTime + startTime - 5;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100ae140
|
||||
MxLong MxTimer::GetRealTime()
|
||||
{
|
||||
MxTimer::s_LastTimeCalculated = timeGetTime();
|
||||
return MxTimer::s_LastTimeCalculated - this->m_startTime;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,14 @@ MxTransitionManager::~MxTransitionManager()
|
|||
TickleManager()->UnregisterClient(this);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1004baa0
|
||||
MxResult MxTransitionManager::GetDDrawSurfaceFromVideoManager() // vtable+0x14
|
||||
{
|
||||
LegoVideoManager* videoManager = VideoManager();
|
||||
this->m_ddSurface = videoManager->GetDisplaySurface()->GetDirectDrawSurface2();
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1004bac0
|
||||
MxResult MxTransitionManager::Tickle()
|
||||
{
|
||||
|
@ -71,6 +79,53 @@ MxResult MxTransitionManager::Tickle()
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1004bb70
|
||||
MxResult MxTransitionManager::StartTransition(
|
||||
TransitionType p_animationType,
|
||||
MxS32 p_speed,
|
||||
MxBool p_doCopy,
|
||||
MxBool p_playMusicInAnim
|
||||
)
|
||||
{
|
||||
if (this->m_transitionType == NOT_TRANSITIONING) {
|
||||
if (!p_playMusicInAnim) {
|
||||
MxBackgroundAudioManager* backgroundAudioManager = BackgroundAudioManager();
|
||||
backgroundAudioManager->Stop();
|
||||
}
|
||||
|
||||
this->m_transitionType = p_animationType;
|
||||
|
||||
m_copyFlags.bit0 = p_doCopy;
|
||||
|
||||
if (m_copyFlags.bit0 && m_waitIndicator != NULL) {
|
||||
m_waitIndicator->Enable(TRUE);
|
||||
|
||||
MxDSAction* action = m_waitIndicator->GetAction();
|
||||
action->SetLoopCount(10000);
|
||||
action->SetFlags(action->GetFlags() | MxDSAction::Flag_Bit9);
|
||||
}
|
||||
|
||||
MxU32 time = timeGetTime();
|
||||
this->m_systemTime = time;
|
||||
|
||||
this->m_animationSpeed = p_speed;
|
||||
|
||||
MxTickleManager* tickleManager = TickleManager();
|
||||
tickleManager->RegisterClient(this, p_speed);
|
||||
|
||||
LegoInputManager* inputManager = InputManager();
|
||||
inputManager->m_unk0x88 = TRUE;
|
||||
inputManager->m_unk0x336 = FALSE;
|
||||
|
||||
LegoVideoManager* videoManager = VideoManager();
|
||||
videoManager->SetUnkE4(FALSE);
|
||||
|
||||
SetAppCursor(1);
|
||||
return SUCCESS;
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1004bc30
|
||||
void MxTransitionManager::EndTransition(MxBool p_notifyWorld)
|
||||
{
|
||||
|
@ -91,6 +146,14 @@ void MxTransitionManager::EndTransition(MxBool p_notifyWorld)
|
|||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1004bcf0
|
||||
void MxTransitionManager::Transition_None()
|
||||
{
|
||||
LegoVideoManager* videoManager = VideoManager();
|
||||
videoManager->GetDisplaySurface()->FUN_100ba640();
|
||||
EndTransition(TRUE);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1004bd10
|
||||
void MxTransitionManager::Transition_Dissolve()
|
||||
{
|
||||
|
@ -173,69 +236,6 @@ void MxTransitionManager::Transition_Dissolve()
|
|||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1004baa0
|
||||
MxResult MxTransitionManager::GetDDrawSurfaceFromVideoManager() // vtable+0x14
|
||||
{
|
||||
LegoVideoManager* videoManager = VideoManager();
|
||||
this->m_ddSurface = videoManager->GetDisplaySurface()->GetDirectDrawSurface2();
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1004bb70
|
||||
MxResult MxTransitionManager::StartTransition(
|
||||
TransitionType p_animationType,
|
||||
MxS32 p_speed,
|
||||
MxBool p_doCopy,
|
||||
MxBool p_playMusicInAnim
|
||||
)
|
||||
{
|
||||
if (this->m_transitionType == NOT_TRANSITIONING) {
|
||||
if (!p_playMusicInAnim) {
|
||||
MxBackgroundAudioManager* backgroundAudioManager = BackgroundAudioManager();
|
||||
backgroundAudioManager->Stop();
|
||||
}
|
||||
|
||||
this->m_transitionType = p_animationType;
|
||||
|
||||
m_copyFlags.bit0 = p_doCopy;
|
||||
|
||||
if (m_copyFlags.bit0 && m_waitIndicator != NULL) {
|
||||
m_waitIndicator->Enable(TRUE);
|
||||
|
||||
MxDSAction* action = m_waitIndicator->GetAction();
|
||||
action->SetLoopCount(10000);
|
||||
action->SetFlags(action->GetFlags() | MxDSAction::Flag_Bit9);
|
||||
}
|
||||
|
||||
MxU32 time = timeGetTime();
|
||||
this->m_systemTime = time;
|
||||
|
||||
this->m_animationSpeed = p_speed;
|
||||
|
||||
MxTickleManager* tickleManager = TickleManager();
|
||||
tickleManager->RegisterClient(this, p_speed);
|
||||
|
||||
LegoInputManager* inputManager = InputManager();
|
||||
inputManager->m_unk0x88 = TRUE;
|
||||
inputManager->m_unk0x336 = FALSE;
|
||||
|
||||
LegoVideoManager* videoManager = VideoManager();
|
||||
videoManager->SetUnkE4(FALSE);
|
||||
|
||||
SetAppCursor(1);
|
||||
return SUCCESS;
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1004bcf0
|
||||
void MxTransitionManager::Transition_None()
|
||||
{
|
||||
LegoVideoManager* videoManager = VideoManager();
|
||||
videoManager->GetDisplaySurface()->FUN_100ba640();
|
||||
EndTransition(TRUE);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1004bed0
|
||||
void MxTransitionManager::Transition_Pixelation()
|
||||
{
|
||||
|
@ -353,6 +353,45 @@ void MxTransitionManager::Transition_Pixelation()
|
|||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1004c170
|
||||
void MxTransitionManager::Transition_Wipe()
|
||||
{
|
||||
// If the animation is finished
|
||||
if (m_animationTimer == 240) {
|
||||
m_animationTimer = 0;
|
||||
EndTransition(TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
DDSURFACEDESC ddsd;
|
||||
memset(&ddsd, 0, sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
|
||||
HRESULT res = m_ddSurface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
|
||||
if (res == DDERR_SURFACELOST) {
|
||||
m_ddSurface->Restore();
|
||||
res = m_ddSurface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
|
||||
}
|
||||
|
||||
if (res == DD_OK) {
|
||||
SubmitCopyRect(&ddsd);
|
||||
|
||||
// For each of the 240 animation ticks, blank out two scanlines
|
||||
// starting at the top of the screen.
|
||||
// (dwRGBBitCount / 8) will tell how many bytes are used per pixel.
|
||||
MxU8* line = (MxU8*) ddsd.lpSurface + 2 * ddsd.lPitch * m_animationTimer;
|
||||
memset(line, 0, 640 * ddsd.ddpfPixelFormat.dwRGBBitCount / 8);
|
||||
|
||||
line += ddsd.lPitch;
|
||||
memset(line, 0, 640 * ddsd.ddpfPixelFormat.dwRGBBitCount / 8);
|
||||
|
||||
SetupCopyRect(&ddsd);
|
||||
m_ddSurface->Unlock(ddsd.lpSurface);
|
||||
|
||||
m_animationTimer++;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1004c270
|
||||
void MxTransitionManager::Transition_Windows()
|
||||
{
|
||||
|
@ -424,45 +463,6 @@ void MxTransitionManager::Transition_Broken()
|
|||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1004c170
|
||||
void MxTransitionManager::Transition_Wipe()
|
||||
{
|
||||
// If the animation is finished
|
||||
if (m_animationTimer == 240) {
|
||||
m_animationTimer = 0;
|
||||
EndTransition(TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
DDSURFACEDESC ddsd;
|
||||
memset(&ddsd, 0, sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
|
||||
HRESULT res = m_ddSurface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
|
||||
if (res == DDERR_SURFACELOST) {
|
||||
m_ddSurface->Restore();
|
||||
res = m_ddSurface->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
|
||||
}
|
||||
|
||||
if (res == DD_OK) {
|
||||
SubmitCopyRect(&ddsd);
|
||||
|
||||
// For each of the 240 animation ticks, blank out two scanlines
|
||||
// starting at the top of the screen.
|
||||
// (dwRGBBitCount / 8) will tell how many bytes are used per pixel.
|
||||
MxU8* line = (MxU8*) ddsd.lpSurface + 2 * ddsd.lPitch * m_animationTimer;
|
||||
memset(line, 0, 640 * ddsd.ddpfPixelFormat.dwRGBBitCount / 8);
|
||||
|
||||
line += ddsd.lPitch;
|
||||
memset(line, 0, 640 * ddsd.ddpfPixelFormat.dwRGBBitCount / 8);
|
||||
|
||||
SetupCopyRect(&ddsd);
|
||||
m_ddSurface->Unlock(ddsd.lpSurface);
|
||||
|
||||
m_animationTimer++;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x1004c470
|
||||
void MxTransitionManager::SetWaitIndicator(MxVideoPresenter* p_waitIndicator)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,29 @@
|
|||
#include "mxvariabletable.h"
|
||||
|
||||
// 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 0x100afdb0 TEMPLATE
|
||||
// MxVariableTable::Destroy
|
||||
|
||||
// OFFSET: LEGO1 0x100afdc0 TEMPLATE
|
||||
// MxHashTable<MxVariable *>::Hash
|
||||
|
||||
// OFFSET: LEGO1 0x100b0bd0 TEMPLATE
|
||||
// MxHashTable<MxVariable *>::~MxHashTable<MxVariable *>
|
||||
|
||||
// OFFSET: LEGO1 0x100b0ca0 TEMPLATE
|
||||
// MxHashTable<MxVariable *>::`scalar deleting destructor'
|
||||
|
||||
// OFFSET: LEGO1 0x100b7330
|
||||
MxS8 MxVariableTable::Compare(MxVariable* p_var0, MxVariable* p_var1)
|
||||
{
|
||||
|
@ -64,3 +88,9 @@ const char* MxVariableTable::GetVariable(const char* p_key)
|
|||
|
||||
return value;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100b7ab0 TEMPLATE
|
||||
// MxHashTable<MxVariable *>::Resize
|
||||
|
||||
// OFFSET: LEGO1 0x100b7b80 TEMPLATE
|
||||
// MxHashTable<MxVariable *>::_NodeInsert
|
||||
|
|
|
@ -14,40 +14,12 @@ class MxVariableTable : public MxHashTable<MxVariable*> {
|
|||
__declspec(dllexport) void SetVariable(MxVariable* p_var);
|
||||
__declspec(dllexport) const char* GetVariable(const char* p_key);
|
||||
|
||||
// OFFSET: LEGO1 0x100afdb0
|
||||
static void Destroy(MxVariable* p_obj) { p_obj->Destroy(); }
|
||||
|
||||
virtual MxS8 Compare(MxVariable*, MxVariable*) override; // vtable+0x14
|
||||
virtual MxU32 Hash(MxVariable*) override; // vtable+0x18
|
||||
};
|
||||
|
||||
// OFFSET: LEGO1 0x100afcd0 TEMPLATE
|
||||
// MxCollection<MxVariable *>::Compare
|
||||
|
||||
// OFFSET: LEGO1 0x100afce0 TEMPLATE
|
||||
// MxCollection<MxVariable *>::~MxCollection<MxVariable *>
|
||||
|
||||
// OFFSET: LEGO1 0x100afd30 TEMPLATE
|
||||
// MxCollection<MxVariable *>::Destroy
|
||||
|
||||
// OFFSET: LEGO1 0x100afd40 TEMPLATE
|
||||
// MxCollection<MxVariable *>::`scalar deleting destructor'
|
||||
|
||||
// OFFSET: LEGO1 0x100afdc0 TEMPLATE
|
||||
// MxHashTable<MxVariable *>::Hash
|
||||
|
||||
// OFFSET: LEGO1 0x100b0bd0 TEMPLATE
|
||||
// MxHashTable<MxVariable *>::~MxHashTable<MxVariable *>
|
||||
|
||||
// OFFSET: LEGO1 0x100b0ca0 TEMPLATE
|
||||
// MxHashTable<MxVariable *>::`scalar deleting destructor'
|
||||
|
||||
// OFFSET: LEGO1 0x100b7ab0 TEMPLATE
|
||||
// MxHashTable<MxVariable *>::Resize
|
||||
|
||||
// OFFSET: LEGO1 0x100b7b80 TEMPLATE
|
||||
// MxHashTable<MxVariable *>::_NodeInsert
|
||||
|
||||
// VTABLE 0x100dc1b0 TEMPLATE
|
||||
// class MxCollection<MxVariable *>
|
||||
|
||||
|
|
|
@ -44,17 +44,11 @@ MxVideoParam::MxVideoParam(MxVideoParam& p_videoParam)
|
|||
SetDeviceName(p_videoParam.m_deviceId);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bede0
|
||||
MxVideoParam& MxVideoParam::operator=(const MxVideoParam& p_videoParam)
|
||||
// OFFSET: LEGO1 0x100bed50
|
||||
MxVideoParam::~MxVideoParam()
|
||||
{
|
||||
this->m_rect = p_videoParam.m_rect;
|
||||
this->m_palette = p_videoParam.m_palette;
|
||||
this->m_backBuffers = p_videoParam.m_backBuffers;
|
||||
this->m_flags = p_videoParam.m_flags;
|
||||
this->m_unk1c = p_videoParam.m_unk1c;
|
||||
SetDeviceName(p_videoParam.m_deviceId);
|
||||
|
||||
return *this;
|
||||
if (this->m_deviceId != NULL)
|
||||
delete[] this->m_deviceId;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bed70
|
||||
|
@ -75,9 +69,15 @@ void MxVideoParam::SetDeviceName(char* id)
|
|||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100bed50
|
||||
MxVideoParam::~MxVideoParam()
|
||||
// OFFSET: LEGO1 0x100bede0
|
||||
MxVideoParam& MxVideoParam::operator=(const MxVideoParam& p_videoParam)
|
||||
{
|
||||
if (this->m_deviceId != NULL)
|
||||
delete[] this->m_deviceId;
|
||||
this->m_rect = p_videoParam.m_rect;
|
||||
this->m_palette = p_videoParam.m_palette;
|
||||
this->m_backBuffers = p_videoParam.m_backBuffers;
|
||||
this->m_flags = p_videoParam.m_flags;
|
||||
this->m_unk1c = p_videoParam.m_unk1c;
|
||||
SetDeviceName(p_videoParam.m_deviceId);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ void Matrix4Impl::ToQuaternion(Vector4Impl* p_outQuat)
|
|||
return;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100d4090
|
||||
// 0x100d4090
|
||||
static int rotateIndex[] = {1, 2, 0};
|
||||
|
||||
// Largest element along the trace
|
||||
|
|
|
@ -14,6 +14,19 @@ float g_userMaxLod = 3.6f;
|
|||
// 0x1010104c
|
||||
float g_partsThreshold = 1000.0f;
|
||||
|
||||
// OFFSET: LEGO1 0x100a5de0
|
||||
void RealtimeView::SetUserMaxLOD(float p_lod)
|
||||
{
|
||||
g_userMaxLod = p_lod;
|
||||
UpdateMaxLOD();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100a5df0
|
||||
void RealtimeView::SetPartsThreshold(float p_threshold)
|
||||
{
|
||||
g_partsThreshold = p_threshold;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100a5e00
|
||||
float RealtimeView::GetUserMaxLOD()
|
||||
{
|
||||
|
@ -27,21 +40,8 @@ float RealtimeView::GetPartsThreshold()
|
|||
return g_partsThreshold;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 100a5e20
|
||||
// OFFSET: LEGO1 0x100a5e20
|
||||
void RealtimeView::UpdateMaxLOD()
|
||||
{
|
||||
g_userMaxLodPower = pow(g_userMaxBase, -g_userMaxLod);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100a5de0
|
||||
void RealtimeView::SetUserMaxLOD(float p_lod)
|
||||
{
|
||||
g_userMaxLod = p_lod;
|
||||
UpdateMaxLOD();
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100a5df0
|
||||
void RealtimeView::SetPartsThreshold(float p_threshold)
|
||||
{
|
||||
g_partsThreshold = p_threshold;
|
||||
}
|
||||
|
|
|
@ -12,10 +12,63 @@ DECOMP_SIZE_ASSERT(Vector4Impl, 0x8);
|
|||
DECOMP_SIZE_ASSERT(Vector3Data, 0x14);
|
||||
DECOMP_SIZE_ASSERT(Vector4Data, 0x18);
|
||||
|
||||
// OFFSET: LEGO1 0x100020a0
|
||||
const float* Vector2Impl::GetData() const
|
||||
// OFFSET: LEGO1 0x10001f80
|
||||
void Vector2Impl::AddVectorImpl(float* p_value)
|
||||
{
|
||||
return m_data;
|
||||
m_data[0] += p_value[0];
|
||||
m_data[1] += p_value[1];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10001fa0
|
||||
void Vector2Impl::AddScalarImpl(float p_value)
|
||||
{
|
||||
m_data[0] += p_value;
|
||||
m_data[1] += p_value;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10001fc0
|
||||
void Vector2Impl::SubVectorImpl(float* p_value)
|
||||
{
|
||||
m_data[0] -= p_value[0];
|
||||
m_data[1] -= p_value[1];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10001fe0
|
||||
void Vector2Impl::MullVectorImpl(float* p_value)
|
||||
{
|
||||
m_data[0] *= p_value[0];
|
||||
m_data[1] *= p_value[1];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002000
|
||||
void Vector2Impl::MullScalarImpl(float* p_value)
|
||||
{
|
||||
m_data[0] *= *p_value;
|
||||
m_data[1] *= *p_value;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002020
|
||||
void Vector2Impl::DivScalarImpl(float* p_value)
|
||||
{
|
||||
m_data[0] /= *p_value;
|
||||
m_data[1] /= *p_value;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002040
|
||||
float Vector2Impl::DotImpl(float* p_a, float* p_b) const
|
||||
{
|
||||
return p_b[0] * p_a[0] + p_b[1] * p_a[1];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002060 TEMPLATE
|
||||
// Vector2Impl::SetData
|
||||
|
||||
// OFFSET: LEGO1 0x10002070
|
||||
void Vector2Impl::EqualsImpl(float* p_data)
|
||||
{
|
||||
float* vec = m_data;
|
||||
vec[0] = p_data[0];
|
||||
vec[1] = p_data[1];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002090
|
||||
|
@ -24,16 +77,24 @@ float* Vector2Impl::GetData()
|
|||
return m_data;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002130
|
||||
float Vector2Impl::Dot(Vector2Impl* p_a, float* p_b) const
|
||||
// OFFSET: LEGO1 0x100020a0
|
||||
const float* Vector2Impl::GetData() const
|
||||
{
|
||||
return DotImpl(p_a->m_data, p_b);
|
||||
return m_data;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002110
|
||||
float Vector2Impl::Dot(float* p_a, Vector2Impl* p_b) const
|
||||
// OFFSET: LEGO1 0x100020b0
|
||||
void Vector2Impl::Clear()
|
||||
{
|
||||
return DotImpl(p_a, p_b->m_data);
|
||||
float* vec = m_data;
|
||||
vec[0] = 0.0f;
|
||||
vec[1] = 0.0f;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100020d0
|
||||
float Vector2Impl::Dot(float* p_a, float* p_b) const
|
||||
{
|
||||
return DotImpl(p_a, p_b);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100020f0
|
||||
|
@ -42,10 +103,22 @@ float Vector2Impl::Dot(Vector2Impl* p_a, Vector2Impl* p_b) const
|
|||
return DotImpl(p_a->m_data, p_b->m_data);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100020d0
|
||||
float Vector2Impl::Dot(float* p_a, float* p_b) const
|
||||
// OFFSET: LEGO1 0x10002110
|
||||
float Vector2Impl::Dot(float* p_a, Vector2Impl* p_b) const
|
||||
{
|
||||
return DotImpl(p_a, p_b);
|
||||
return DotImpl(p_a, p_b->m_data);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002130
|
||||
float Vector2Impl::Dot(Vector2Impl* p_a, float* p_b) const
|
||||
{
|
||||
return DotImpl(p_a->m_data, p_b);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002150
|
||||
float Vector2Impl::LenSquared() const
|
||||
{
|
||||
return m_data[0] * m_data[0] + m_data[1] * m_data[1];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002160
|
||||
|
@ -62,10 +135,10 @@ int Vector2Impl::Unitize()
|
|||
return -1;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100021e0
|
||||
void Vector2Impl::AddVector(Vector2Impl* p_other)
|
||||
// OFFSET: LEGO1 0x100021c0
|
||||
void Vector2Impl::AddScalar(float p_value)
|
||||
{
|
||||
AddVectorImpl(p_other->m_data);
|
||||
AddScalarImpl(p_value);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100021d0
|
||||
|
@ -74,16 +147,10 @@ void Vector2Impl::AddVector(float* p_other)
|
|||
AddVectorImpl(p_other);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100021c0
|
||||
void Vector2Impl::AddScalar(float p_value)
|
||||
// OFFSET: LEGO1 0x100021e0
|
||||
void Vector2Impl::AddVector(Vector2Impl* p_other)
|
||||
{
|
||||
AddScalarImpl(p_value);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002200
|
||||
void Vector2Impl::SubVector(Vector2Impl* p_other)
|
||||
{
|
||||
SubVectorImpl(p_other->m_data);
|
||||
AddVectorImpl(p_other->m_data);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100021f0
|
||||
|
@ -92,16 +159,10 @@ void Vector2Impl::SubVector(float* p_other)
|
|||
SubVectorImpl(p_other);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002230
|
||||
void Vector2Impl::MullScalar(float* p_value)
|
||||
// OFFSET: LEGO1 0x10002200
|
||||
void Vector2Impl::SubVector(Vector2Impl* p_other)
|
||||
{
|
||||
MullScalarImpl(p_value);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002220
|
||||
void Vector2Impl::MullVector(Vector2Impl* p_other)
|
||||
{
|
||||
MullVectorImpl(p_other->m_data);
|
||||
SubVectorImpl(p_other->m_data);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002210
|
||||
|
@ -110,100 +171,206 @@ void Vector2Impl::MullVector(float* p_other)
|
|||
MullVectorImpl(p_other);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002220
|
||||
void Vector2Impl::MullVector(Vector2Impl* p_other)
|
||||
{
|
||||
MullVectorImpl(p_other->m_data);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002230
|
||||
void Vector2Impl::MullScalar(float* p_value)
|
||||
{
|
||||
MullScalarImpl(p_value);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002240
|
||||
void Vector2Impl::DivScalar(float* p_value)
|
||||
{
|
||||
DivScalarImpl(p_value);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002260
|
||||
void Vector2Impl::SetVector(Vector2Impl* p_other)
|
||||
{
|
||||
EqualsImpl(p_other->m_data);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002250
|
||||
void Vector2Impl::SetVector(float* p_other)
|
||||
{
|
||||
EqualsImpl(p_other);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10001fa0
|
||||
void Vector2Impl::AddScalarImpl(float p_value)
|
||||
// OFFSET: LEGO1 0x10002260
|
||||
void Vector2Impl::SetVector(Vector2Impl* p_other)
|
||||
{
|
||||
m_data[0] += p_value;
|
||||
m_data[1] += p_value;
|
||||
EqualsImpl(p_other->m_data);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10001f80
|
||||
void Vector2Impl::AddVectorImpl(float* p_value)
|
||||
// OFFSET: LEGO1 0x10002270
|
||||
void Vector3Impl::EqualsCrossImpl(float* p_a, float* p_b)
|
||||
{
|
||||
m_data[0] = p_a[1] * p_b[2] - p_a[2] * p_b[1];
|
||||
m_data[1] = p_a[2] * p_b[0] - p_a[0] * p_b[2];
|
||||
m_data[2] = p_a[0] * p_b[1] - p_a[1] * p_b[0];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100022c0
|
||||
void Vector3Impl::EqualsCross(Vector3Impl* p_a, Vector3Impl* p_b)
|
||||
{
|
||||
EqualsCrossImpl(p_a->m_data, p_b->m_data);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100022e0
|
||||
void Vector3Impl::EqualsCross(Vector3Impl* p_a, float* p_b)
|
||||
{
|
||||
EqualsCrossImpl(p_a->m_data, p_b);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002300
|
||||
void Vector3Impl::EqualsCross(float* p_a, Vector3Impl* p_b)
|
||||
{
|
||||
EqualsCrossImpl(p_a, p_b->m_data);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002870
|
||||
void Vector4Impl::AddVectorImpl(float* p_value)
|
||||
{
|
||||
m_data[0] += p_value[0];
|
||||
m_data[1] += p_value[1];
|
||||
m_data[2] += p_value[2];
|
||||
m_data[3] += p_value[3];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10001fc0
|
||||
void Vector2Impl::SubVectorImpl(float* p_value)
|
||||
{
|
||||
m_data[0] -= p_value[0];
|
||||
m_data[1] -= p_value[1];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002000
|
||||
void Vector2Impl::MullScalarImpl(float* p_value)
|
||||
{
|
||||
m_data[0] *= *p_value;
|
||||
m_data[1] *= *p_value;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10001fe0
|
||||
void Vector2Impl::MullVectorImpl(float* p_value)
|
||||
{
|
||||
m_data[0] *= p_value[0];
|
||||
m_data[1] *= p_value[1];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002020
|
||||
void Vector2Impl::DivScalarImpl(float* p_value)
|
||||
{
|
||||
m_data[0] /= *p_value;
|
||||
m_data[1] /= *p_value;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002040
|
||||
float Vector2Impl::DotImpl(float* p_a, float* p_b) const
|
||||
{
|
||||
return p_b[0] * p_a[0] + p_b[1] * p_a[1];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002070
|
||||
void Vector2Impl::EqualsImpl(float* p_data)
|
||||
{
|
||||
float* vec = m_data;
|
||||
vec[0] = p_data[0];
|
||||
vec[1] = p_data[1];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100020b0
|
||||
void Vector2Impl::Clear()
|
||||
{
|
||||
float* vec = m_data;
|
||||
vec[0] = 0.0f;
|
||||
vec[1] = 0.0f;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002150
|
||||
float Vector2Impl::LenSquared() const
|
||||
{
|
||||
return m_data[0] * m_data[0] + m_data[1] * m_data[1];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10003a90
|
||||
void Vector3Impl::AddScalarImpl(float p_value)
|
||||
// OFFSET: LEGO1 0x100028b0
|
||||
void Vector4Impl::AddScalarImpl(float p_value)
|
||||
{
|
||||
m_data[0] += p_value;
|
||||
m_data[1] += p_value;
|
||||
m_data[2] += p_value;
|
||||
m_data[3] += p_value;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100028f0
|
||||
void Vector4Impl::SubVectorImpl(float* p_value)
|
||||
{
|
||||
m_data[0] -= p_value[0];
|
||||
m_data[1] -= p_value[1];
|
||||
m_data[2] -= p_value[2];
|
||||
m_data[3] -= p_value[3];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002930
|
||||
void Vector4Impl::MullVectorImpl(float* p_value)
|
||||
{
|
||||
m_data[0] *= p_value[0];
|
||||
m_data[1] *= p_value[1];
|
||||
m_data[2] *= p_value[2];
|
||||
m_data[3] *= p_value[3];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002970
|
||||
void Vector4Impl::MullScalarImpl(float* p_value)
|
||||
{
|
||||
m_data[0] *= *p_value;
|
||||
m_data[1] *= *p_value;
|
||||
m_data[2] *= *p_value;
|
||||
m_data[3] *= *p_value;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100029b0
|
||||
void Vector4Impl::DivScalarImpl(float* p_value)
|
||||
{
|
||||
m_data[0] /= *p_value;
|
||||
m_data[1] /= *p_value;
|
||||
m_data[2] /= *p_value;
|
||||
m_data[3] /= *p_value;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100029f0
|
||||
float Vector4Impl::DotImpl(float* p_a, float* p_b) const
|
||||
{
|
||||
return p_a[0] * p_b[0] + p_a[2] * p_b[2] + (p_a[1] * p_b[1] + p_a[3] * p_b[3]);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002a20
|
||||
void Vector4Impl::EqualsImpl(float* p_data)
|
||||
{
|
||||
float* vec = m_data;
|
||||
vec[0] = p_data[0];
|
||||
vec[1] = p_data[1];
|
||||
vec[2] = p_data[2];
|
||||
vec[3] = p_data[3];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002a40
|
||||
void Vector4Impl::SetMatrixProductImpl(float* p_vec, float* p_mat)
|
||||
{
|
||||
m_data[0] = p_vec[0] * p_mat[0] + p_vec[1] * p_mat[4] + p_vec[2] * p_mat[8] + p_vec[3] * p_mat[12];
|
||||
m_data[1] = p_vec[0] * p_mat[1] + p_vec[1] * p_mat[5] + p_vec[2] * p_mat[9] + p_vec[4] * p_mat[13];
|
||||
m_data[2] = p_vec[0] * p_mat[2] + p_vec[1] * p_mat[6] + p_vec[2] * p_mat[10] + p_vec[4] * p_mat[14];
|
||||
m_data[3] = p_vec[0] * p_mat[3] + p_vec[1] * p_mat[7] + p_vec[2] * p_mat[11] + p_vec[4] * p_mat[15];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002ae0
|
||||
void Vector4Impl::SetMatrixProduct(Vector4Impl* p_a, float* p_b)
|
||||
{
|
||||
SetMatrixProductImpl(p_a->m_data, p_b);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002b00
|
||||
void Vector4Impl::Clear()
|
||||
{
|
||||
float* vec = m_data;
|
||||
vec[0] = 0.0f;
|
||||
vec[1] = 0.0f;
|
||||
vec[2] = 0.0f;
|
||||
vec[3] = 0.0f;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002b20
|
||||
float Vector4Impl::LenSquared() const
|
||||
{
|
||||
return m_data[1] * m_data[1] + m_data[0] * m_data[0] + m_data[2] * m_data[2] + m_data[3] * m_data[3];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002b40
|
||||
void Vector4Impl::EqualsScalar(float* p_value)
|
||||
{
|
||||
m_data[0] = *p_value;
|
||||
m_data[1] = *p_value;
|
||||
m_data[2] = *p_value;
|
||||
m_data[3] = *p_value;
|
||||
}
|
||||
|
||||
// Note close yet, included because I'm at least confident I know what operation
|
||||
// it's trying to do.
|
||||
// OFFSET: LEGO1 0x10002b70 STUB
|
||||
int Vector4Impl::NormalizeQuaternion()
|
||||
{
|
||||
float* v = m_data;
|
||||
float magnitude = v[1] * v[1] + v[2] * v[2] + v[0] * v[0];
|
||||
if (magnitude > 0.0f) {
|
||||
float theta = v[3] * 0.5f;
|
||||
v[3] = cos(theta);
|
||||
float frac = sin(theta);
|
||||
magnitude = frac / sqrt(magnitude);
|
||||
v[0] *= magnitude;
|
||||
v[1] *= magnitude;
|
||||
v[2] *= magnitude;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002bf0
|
||||
void Vector4Impl::UnknownQuaternionOp(Vector4Impl* p_a, Vector4Impl* p_b)
|
||||
{
|
||||
float* bDat = p_b->m_data;
|
||||
float* aDat = p_a->m_data;
|
||||
|
||||
this->m_data[3] = aDat[3] * bDat[3] - (bDat[0] * aDat[0] + aDat[2] * bDat[2] + aDat[1] * aDat[1]);
|
||||
this->m_data[0] = bDat[2] * aDat[1] - bDat[1] * aDat[2];
|
||||
this->m_data[1] = aDat[2] * bDat[0] - bDat[2] * aDat[0];
|
||||
this->m_data[2] = bDat[1] * aDat[0] - aDat[1] * bDat[0];
|
||||
|
||||
m_data[0] = p_b->m_data[3] * p_a->m_data[0] + p_a->m_data[3] * p_b->m_data[0] + m_data[0];
|
||||
m_data[1] = p_b->m_data[1] * p_a->m_data[3] + p_a->m_data[1] * p_b->m_data[3] + m_data[1];
|
||||
m_data[2] = p_b->m_data[2] * p_a->m_data[3] + p_a->m_data[2] * p_b->m_data[3] + m_data[2];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10003a60
|
||||
|
@ -214,6 +381,14 @@ void Vector3Impl::AddVectorImpl(float* p_value)
|
|||
m_data[2] += p_value[2];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10003a90
|
||||
void Vector3Impl::AddScalarImpl(float p_value)
|
||||
{
|
||||
m_data[0] += p_value;
|
||||
m_data[1] += p_value;
|
||||
m_data[2] += p_value;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10003ac0
|
||||
void Vector3Impl::SubVectorImpl(float* p_value)
|
||||
{
|
||||
|
@ -222,14 +397,6 @@ void Vector3Impl::SubVectorImpl(float* p_value)
|
|||
m_data[2] -= p_value[2];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10003b20
|
||||
void Vector3Impl::MullScalarImpl(float* p_value)
|
||||
{
|
||||
m_data[0] *= *p_value;
|
||||
m_data[1] *= *p_value;
|
||||
m_data[2] *= *p_value;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10003af0
|
||||
void Vector3Impl::MullVectorImpl(float* p_value)
|
||||
{
|
||||
|
@ -238,6 +405,14 @@ void Vector3Impl::MullVectorImpl(float* p_value)
|
|||
m_data[2] *= p_value[2];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10003b20
|
||||
void Vector3Impl::MullScalarImpl(float* p_value)
|
||||
{
|
||||
m_data[0] *= *p_value;
|
||||
m_data[1] *= *p_value;
|
||||
m_data[2] *= *p_value;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10003b50
|
||||
void Vector3Impl::DivScalarImpl(float* p_value)
|
||||
{
|
||||
|
@ -276,32 +451,6 @@ float Vector3Impl::LenSquared() const
|
|||
return m_data[1] * m_data[1] + m_data[0] * m_data[0] + m_data[2] * m_data[2];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002270
|
||||
void Vector3Impl::EqualsCrossImpl(float* p_a, float* p_b)
|
||||
{
|
||||
m_data[0] = p_a[1] * p_b[2] - p_a[2] * p_b[1];
|
||||
m_data[1] = p_a[2] * p_b[0] - p_a[0] * p_b[2];
|
||||
m_data[2] = p_a[0] * p_b[1] - p_a[1] * p_b[0];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002300
|
||||
void Vector3Impl::EqualsCross(float* p_a, Vector3Impl* p_b)
|
||||
{
|
||||
EqualsCrossImpl(p_a, p_b->m_data);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100022e0
|
||||
void Vector3Impl::EqualsCross(Vector3Impl* p_a, float* p_b)
|
||||
{
|
||||
EqualsCrossImpl(p_a->m_data, p_b);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100022c0
|
||||
void Vector3Impl::EqualsCross(Vector3Impl* p_a, Vector3Impl* p_b)
|
||||
{
|
||||
EqualsCrossImpl(p_a->m_data, p_b->m_data);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10003bf0
|
||||
void Vector3Impl::EqualsScalar(float* p_value)
|
||||
{
|
||||
|
@ -309,149 +458,3 @@ void Vector3Impl::EqualsScalar(float* p_value)
|
|||
m_data[1] = *p_value;
|
||||
m_data[2] = *p_value;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100028b0
|
||||
void Vector4Impl::AddScalarImpl(float p_value)
|
||||
{
|
||||
m_data[0] += p_value;
|
||||
m_data[1] += p_value;
|
||||
m_data[2] += p_value;
|
||||
m_data[3] += p_value;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002870
|
||||
void Vector4Impl::AddVectorImpl(float* p_value)
|
||||
{
|
||||
m_data[0] += p_value[0];
|
||||
m_data[1] += p_value[1];
|
||||
m_data[2] += p_value[2];
|
||||
m_data[3] += p_value[3];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100028f0
|
||||
void Vector4Impl::SubVectorImpl(float* p_value)
|
||||
{
|
||||
m_data[0] -= p_value[0];
|
||||
m_data[1] -= p_value[1];
|
||||
m_data[2] -= p_value[2];
|
||||
m_data[3] -= p_value[3];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002970
|
||||
void Vector4Impl::MullScalarImpl(float* p_value)
|
||||
{
|
||||
m_data[0] *= *p_value;
|
||||
m_data[1] *= *p_value;
|
||||
m_data[2] *= *p_value;
|
||||
m_data[3] *= *p_value;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002930
|
||||
void Vector4Impl::MullVectorImpl(float* p_value)
|
||||
{
|
||||
m_data[0] *= p_value[0];
|
||||
m_data[1] *= p_value[1];
|
||||
m_data[2] *= p_value[2];
|
||||
m_data[3] *= p_value[3];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100029b0
|
||||
void Vector4Impl::DivScalarImpl(float* p_value)
|
||||
{
|
||||
m_data[0] /= *p_value;
|
||||
m_data[1] /= *p_value;
|
||||
m_data[2] /= *p_value;
|
||||
m_data[3] /= *p_value;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100029f0
|
||||
float Vector4Impl::DotImpl(float* p_a, float* p_b) const
|
||||
{
|
||||
return p_a[0] * p_b[0] + p_a[2] * p_b[2] + (p_a[1] * p_b[1] + p_a[3] * p_b[3]);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002a20
|
||||
void Vector4Impl::EqualsImpl(float* p_data)
|
||||
{
|
||||
float* vec = m_data;
|
||||
vec[0] = p_data[0];
|
||||
vec[1] = p_data[1];
|
||||
vec[2] = p_data[2];
|
||||
vec[3] = p_data[3];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002b00
|
||||
void Vector4Impl::Clear()
|
||||
{
|
||||
float* vec = m_data;
|
||||
vec[0] = 0.0f;
|
||||
vec[1] = 0.0f;
|
||||
vec[2] = 0.0f;
|
||||
vec[3] = 0.0f;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002b20
|
||||
float Vector4Impl::LenSquared() const
|
||||
{
|
||||
return m_data[1] * m_data[1] + m_data[0] * m_data[0] + m_data[2] * m_data[2] + m_data[3] * m_data[3];
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002b40
|
||||
void Vector4Impl::EqualsScalar(float* p_value)
|
||||
{
|
||||
m_data[0] = *p_value;
|
||||
m_data[1] = *p_value;
|
||||
m_data[2] = *p_value;
|
||||
m_data[3] = *p_value;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002ae0
|
||||
void Vector4Impl::SetMatrixProduct(Vector4Impl* p_a, float* p_b)
|
||||
{
|
||||
SetMatrixProductImpl(p_a->m_data, p_b);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002a40
|
||||
void Vector4Impl::SetMatrixProductImpl(float* p_vec, float* p_mat)
|
||||
{
|
||||
m_data[0] = p_vec[0] * p_mat[0] + p_vec[1] * p_mat[4] + p_vec[2] * p_mat[8] + p_vec[3] * p_mat[12];
|
||||
m_data[1] = p_vec[0] * p_mat[1] + p_vec[1] * p_mat[5] + p_vec[2] * p_mat[9] + p_vec[4] * p_mat[13];
|
||||
m_data[2] = p_vec[0] * p_mat[2] + p_vec[1] * p_mat[6] + p_vec[2] * p_mat[10] + p_vec[4] * p_mat[14];
|
||||
m_data[3] = p_vec[0] * p_mat[3] + p_vec[1] * p_mat[7] + p_vec[2] * p_mat[11] + p_vec[4] * p_mat[15];
|
||||
}
|
||||
|
||||
// Note close yet, included because I'm at least confident I know what operation
|
||||
// it's trying to do.
|
||||
// OFFSET: LEGO1 0x10002b70 STUB
|
||||
int Vector4Impl::NormalizeQuaternion()
|
||||
{
|
||||
float* v = m_data;
|
||||
float magnitude = v[1] * v[1] + v[2] * v[2] + v[0] * v[0];
|
||||
if (magnitude > 0.0f) {
|
||||
float theta = v[3] * 0.5f;
|
||||
v[3] = cos(theta);
|
||||
float frac = sin(theta);
|
||||
magnitude = frac / sqrt(magnitude);
|
||||
v[0] *= magnitude;
|
||||
v[1] *= magnitude;
|
||||
v[2] *= magnitude;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10002bf0
|
||||
void Vector4Impl::UnknownQuaternionOp(Vector4Impl* p_a, Vector4Impl* p_b)
|
||||
{
|
||||
float* bDat = p_b->m_data;
|
||||
float* aDat = p_a->m_data;
|
||||
|
||||
this->m_data[3] = aDat[3] * bDat[3] - (bDat[0] * aDat[0] + aDat[2] * bDat[2] + aDat[1] * aDat[1]);
|
||||
this->m_data[0] = bDat[2] * aDat[1] - bDat[1] * aDat[2];
|
||||
this->m_data[1] = aDat[2] * bDat[0] - bDat[2] * aDat[0];
|
||||
this->m_data[2] = bDat[1] * aDat[0] - aDat[1] * bDat[0];
|
||||
|
||||
m_data[0] = p_b->m_data[3] * p_a->m_data[0] + p_a->m_data[3] * p_b->m_data[0] + m_data[0];
|
||||
m_data[1] = p_b->m_data[1] * p_a->m_data[3] + p_a->m_data[1] * p_b->m_data[3] + m_data[1];
|
||||
m_data[2] = p_b->m_data[2] * p_a->m_data[3] + p_a->m_data[2] * p_b->m_data[3] + m_data[2];
|
||||
}
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
|
||||
#include <vec.h>
|
||||
|
||||
// TODO: Find proper compilation unit to put this
|
||||
// OFFSET: LEGO1 0x1000c0f0 TEMPLATE
|
||||
// Vector2Impl::Vector2Impl
|
||||
|
||||
/*
|
||||
* A simple array of three floats that can be indexed into.
|
||||
*/
|
||||
|
@ -60,7 +64,6 @@ struct Vector4 {
|
|||
// SIZE 0x8
|
||||
class Vector2Impl {
|
||||
public:
|
||||
// OFFSET: LEGO1 0x1000c0f0
|
||||
inline Vector2Impl(float* p_data) { this->SetData(p_data); }
|
||||
|
||||
// vtable + 0x00 (no virtual destructor)
|
||||
|
@ -73,8 +76,6 @@ class Vector2Impl {
|
|||
virtual void MullVectorImpl(float* p_value) = 0;
|
||||
virtual void DivScalarImpl(float* p_value) = 0;
|
||||
virtual float DotImpl(float* p_a, float* p_b) const = 0;
|
||||
|
||||
// OFFSET: LEGO1 0x10002060
|
||||
virtual void SetData(float* p_data) { this->m_data = p_data; }
|
||||
|
||||
// vtable + 0x20
|
||||
|
|
|
@ -22,6 +22,12 @@ Score::Score()
|
|||
NotificationManager()->Register(this);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100010b0
|
||||
MxBool Score::VTable0x5c()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10001200
|
||||
Score::~Score()
|
||||
{
|
||||
|
@ -32,6 +38,39 @@ Score::~Score()
|
|||
NotificationManager()->Unregister(this);
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100012a0
|
||||
MxResult Score::Create(MxDSObject& p_dsObject)
|
||||
{
|
||||
MxResult result = SetAsCurrentWorld(p_dsObject);
|
||||
|
||||
if (result == SUCCESS) {
|
||||
InputManager()->SetWorld(this);
|
||||
ControlManager()->Register(this);
|
||||
InputManager()->Register(this);
|
||||
SetIsWorldActive(FALSE);
|
||||
LegoGameState* gs = GameState();
|
||||
ScoreState* state = (ScoreState*) gs->GetState("ScoreState");
|
||||
m_state = state ? state : (ScoreState*) gs->CreateState("ScoreState");
|
||||
GameState()->SetUnknown424(0xd);
|
||||
GameState()->FUN_1003a720(0);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10001340
|
||||
void Score::DeleteScript()
|
||||
{
|
||||
if (m_state->GetTutorialFlag()) {
|
||||
MxDSAction action;
|
||||
action.SetObjectId(0x1f5);
|
||||
action.SetAtomId(*g_infoscorScript);
|
||||
action.SetUnknown24(-2);
|
||||
DeleteObject(action);
|
||||
m_state->SetTutorialFlag(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10001410
|
||||
MxLong Score::Notify(MxParam& p)
|
||||
{
|
||||
|
@ -67,45 +106,6 @@ MxLong Score::Notify(MxParam& p)
|
|||
return ret;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100010b0
|
||||
MxBool Score::VTable0x5c()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x100012a0
|
||||
MxResult Score::Create(MxDSObject& p_dsObject)
|
||||
{
|
||||
MxResult result = SetAsCurrentWorld(p_dsObject);
|
||||
|
||||
if (result == SUCCESS) {
|
||||
InputManager()->SetWorld(this);
|
||||
ControlManager()->Register(this);
|
||||
InputManager()->Register(this);
|
||||
SetIsWorldActive(FALSE);
|
||||
LegoGameState* gs = GameState();
|
||||
ScoreState* state = (ScoreState*) gs->GetState("ScoreState");
|
||||
m_state = state ? state : (ScoreState*) gs->CreateState("ScoreState");
|
||||
GameState()->SetUnknown424(0xd);
|
||||
GameState()->FUN_1003a720(0);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10001340
|
||||
void Score::DeleteScript()
|
||||
{
|
||||
if (m_state->GetTutorialFlag()) {
|
||||
MxDSAction action;
|
||||
action.SetObjectId(0x1f5);
|
||||
action.SetAtomId(*g_infoscorScript);
|
||||
action.SetUnknown24(-2);
|
||||
DeleteObject(action);
|
||||
m_state->SetTutorialFlag(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: LEGO1 0x10001510
|
||||
MxLong Score::FUN_10001510(MxEndActionNotificationParam& p)
|
||||
{
|
||||
|
|
120
tools/checkorder/checkorder.py
Normal file
120
tools/checkorder/checkorder.py
Normal file
|
@ -0,0 +1,120 @@
|
|||
import os
|
||||
import sys
|
||||
import argparse
|
||||
from isledecomp.dir import (
|
||||
walk_source_dir,
|
||||
is_file_cpp
|
||||
)
|
||||
from isledecomp.parser import find_code_blocks
|
||||
from isledecomp.parser.util import (
|
||||
is_exact_offset_comment
|
||||
)
|
||||
|
||||
|
||||
def sig_truncate(sig: str) -> str:
|
||||
"""Helper to truncate function names to 50 chars and append ellipsis
|
||||
if needed. Goal is to stay under 80 columns for tool output."""
|
||||
return f"{sig[:47]}{'...' if len(sig) >= 50 else ''}"
|
||||
|
||||
|
||||
def check_file(filename: str, verbose: bool = False) -> bool:
|
||||
"""Open and read the given file, then check whether the code blocks
|
||||
are in order. If verbose, print each block."""
|
||||
|
||||
with open(filename, 'r') as f:
|
||||
code_blocks = find_code_blocks(f)
|
||||
|
||||
bad_comments = [(block.start_line, block.offset_comment)
|
||||
for block in code_blocks
|
||||
if not is_exact_offset_comment(block.offset_comment)]
|
||||
|
||||
just_offsets = [block.offset for block in code_blocks]
|
||||
sorted_offsets = sorted(just_offsets)
|
||||
file_out_of_order = just_offsets != sorted_offsets
|
||||
|
||||
# If we detect inexact comments, don't print anything unless we are
|
||||
# in verbose mode. If the file is out of order, we always print the
|
||||
# file name.
|
||||
should_report = ((len(bad_comments) > 0 and verbose)
|
||||
or file_out_of_order)
|
||||
|
||||
if not should_report and not file_out_of_order:
|
||||
return False
|
||||
|
||||
# Else: we are alerting to some problem in this file
|
||||
print(filename)
|
||||
if verbose:
|
||||
if file_out_of_order:
|
||||
order_lookup = {k: i for i, k in enumerate(sorted_offsets)}
|
||||
prev_offset = 0
|
||||
|
||||
for block in code_blocks:
|
||||
msg = ' '.join([
|
||||
' ' if block.offset > prev_offset else '!',
|
||||
f'{block.offset:08x}',
|
||||
f'{block.end_line - block.start_line:4} lines',
|
||||
f'{order_lookup[block.offset]:3}',
|
||||
' ',
|
||||
sig_truncate(block.signature),
|
||||
])
|
||||
print(msg)
|
||||
prev_offset = block.offset
|
||||
|
||||
for (line_no, line) in bad_comments:
|
||||
print(f'* line {line_no:3} bad offset comment ({line})')
|
||||
|
||||
print()
|
||||
|
||||
return file_out_of_order
|
||||
|
||||
|
||||
def parse_args(test_args: list | None = None) -> dict:
|
||||
p = argparse.ArgumentParser()
|
||||
p.add_argument('target', help='The file or directory to check.')
|
||||
p.add_argument('--enforce', action=argparse.BooleanOptionalAction,
|
||||
default=False,
|
||||
help='Fail with error code if target is out of order.')
|
||||
p.add_argument('--verbose', action=argparse.BooleanOptionalAction,
|
||||
default=False,
|
||||
help=('Display each code block in the file and show '
|
||||
'where each consecutive run of blocks is broken.'))
|
||||
|
||||
if test_args is None:
|
||||
args = p.parse_args()
|
||||
else:
|
||||
args = p.parse_args(test_args)
|
||||
|
||||
return vars(args)
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
|
||||
if os.path.isdir(args['target']):
|
||||
files_to_check = list(walk_source_dir(args['target']))
|
||||
elif os.path.isfile(args['target']) and is_file_cpp(args['target']):
|
||||
files_to_check = [args['target']]
|
||||
else:
|
||||
sys.exit('Invalid target')
|
||||
|
||||
files_out_of_order = 0
|
||||
|
||||
for file in files_to_check:
|
||||
is_jumbled = check_file(file, args['verbose'])
|
||||
if is_jumbled:
|
||||
files_out_of_order += 1
|
||||
|
||||
if files_out_of_order > 0:
|
||||
error_message = ' '.join([
|
||||
str(files_out_of_order),
|
||||
'files are' if files_out_of_order > 1 else 'file is',
|
||||
'out of order'
|
||||
])
|
||||
print(error_message)
|
||||
|
||||
if files_out_of_order > 0 and args['enforce']:
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
1
tools/checkorder/requirements.txt
Normal file
1
tools/checkorder/requirements.txt
Normal file
|
@ -0,0 +1 @@
|
|||
isledecomp
|
1
tools/isledecomp/.gitignore
vendored
Normal file
1
tools/isledecomp/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
isledecomp.egg-info/
|
0
tools/isledecomp/isledecomp/__init__.py
Normal file
0
tools/isledecomp/isledecomp/__init__.py
Normal file
21
tools/isledecomp/isledecomp/dir.py
Normal file
21
tools/isledecomp/isledecomp/dir.py
Normal file
|
@ -0,0 +1,21 @@
|
|||
import os
|
||||
from typing import Iterator
|
||||
|
||||
|
||||
def is_file_cpp(filename: str) -> bool:
|
||||
(basefile, ext) = os.path.splitext(filename)
|
||||
return ext.lower() in ('.h', '.cpp')
|
||||
|
||||
|
||||
def walk_source_dir(source: str, recursive: bool = True) -> Iterator[str]:
|
||||
"""Generator to walk the given directory recursively and return
|
||||
any C++ files found."""
|
||||
|
||||
source = os.path.abspath(source)
|
||||
for subdir, dirs, files in os.walk(source):
|
||||
for file in files:
|
||||
if is_file_cpp(file):
|
||||
yield os.path.join(subdir, file)
|
||||
|
||||
if not recursive:
|
||||
break
|
1
tools/isledecomp/isledecomp/parser/__init__.py
Normal file
1
tools/isledecomp/isledecomp/parser/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
from .parser import find_code_blocks
|
142
tools/isledecomp/isledecomp/parser/parser.py
Normal file
142
tools/isledecomp/isledecomp/parser/parser.py
Normal file
|
@ -0,0 +1,142 @@
|
|||
# C++ file parser
|
||||
|
||||
from typing import List, TextIO
|
||||
from enum import Enum
|
||||
from .util import (
|
||||
CodeBlock,
|
||||
OffsetMatch,
|
||||
is_blank_or_comment,
|
||||
match_offset_comment,
|
||||
is_exact_offset_comment,
|
||||
get_template_function_name,
|
||||
remove_trailing_comment,
|
||||
distinct_by_module,
|
||||
)
|
||||
|
||||
|
||||
class ReaderState(Enum):
|
||||
WANT_OFFSET = 0
|
||||
WANT_SIG = 1
|
||||
IN_FUNC = 2
|
||||
IN_TEMPLATE = 3
|
||||
WANT_CURLY = 4
|
||||
FUNCTION_DONE = 5
|
||||
|
||||
|
||||
def find_code_blocks(stream: TextIO) -> List[CodeBlock]:
|
||||
"""Read the IO stream (file) line-by-line and give the following report:
|
||||
Foreach code block (function) in the file, what are its starting and
|
||||
ending line numbers, and what is the given offset in the original
|
||||
binary. We expect the result to be ordered by line number because we
|
||||
are reading the file from start to finish."""
|
||||
|
||||
blocks: List[CodeBlock] = []
|
||||
|
||||
offset_matches: List[OffsetMatch] = []
|
||||
|
||||
function_sig = None
|
||||
start_line = None
|
||||
end_line = None
|
||||
state = ReaderState.WANT_OFFSET
|
||||
|
||||
# 1-based to match cvdump and your text editor
|
||||
# I know it says 0, but we will increment before each readline()
|
||||
line_no = 0
|
||||
can_seek = True
|
||||
|
||||
while True:
|
||||
# Do this before reading again so that an EOF will not
|
||||
# cause us to miss the last function of the file.
|
||||
if state == ReaderState.FUNCTION_DONE:
|
||||
# Our list of offset marks could have duplicates on
|
||||
# module name, so we'll eliminate those now.
|
||||
for offset_match in distinct_by_module(offset_matches):
|
||||
block = CodeBlock(offset=offset_match.address,
|
||||
signature=function_sig,
|
||||
start_line=start_line,
|
||||
end_line=end_line,
|
||||
offset_comment=offset_match.comment,
|
||||
module=offset_match.module,
|
||||
is_template=offset_match.is_template,
|
||||
is_stub=offset_match.is_stub)
|
||||
blocks.append(block)
|
||||
offset_matches = []
|
||||
state = ReaderState.WANT_OFFSET
|
||||
|
||||
if can_seek:
|
||||
line_no += 1
|
||||
line = stream.readline()
|
||||
if line == '':
|
||||
break
|
||||
|
||||
new_match = match_offset_comment(line)
|
||||
if new_match is not None:
|
||||
# We will allow multiple offsets if we have just begun
|
||||
# the code block, but not after we hit the curly brace.
|
||||
if state in (ReaderState.WANT_OFFSET, ReaderState.IN_TEMPLATE,
|
||||
ReaderState.WANT_SIG):
|
||||
# If we detected an offset marker unexpectedly,
|
||||
# we are handling it here so we can continue seeking.
|
||||
can_seek = True
|
||||
|
||||
offset_matches.append(new_match)
|
||||
|
||||
if new_match.is_template:
|
||||
state = ReaderState.IN_TEMPLATE
|
||||
else:
|
||||
state = ReaderState.WANT_SIG
|
||||
else:
|
||||
# We hit another offset unexpectedly.
|
||||
# We can recover easily by just ending the function here.
|
||||
end_line = line_no - 1
|
||||
state = ReaderState.FUNCTION_DONE
|
||||
|
||||
# Pause reading here so we handle the offset marker
|
||||
# on the next loop iteration
|
||||
can_seek = False
|
||||
|
||||
elif state == ReaderState.IN_TEMPLATE:
|
||||
# TEMPLATE functions are a special case. The signature is
|
||||
# given on the next line (in a // comment)
|
||||
function_sig = get_template_function_name(line)
|
||||
start_line = line_no
|
||||
end_line = line_no
|
||||
state = ReaderState.FUNCTION_DONE
|
||||
|
||||
elif state == ReaderState.WANT_SIG:
|
||||
# Skip blank lines or comments that come after the offset
|
||||
# marker. There is not a formal procedure for this, so just
|
||||
# assume the next "code line" is the function signature
|
||||
if not is_blank_or_comment(line):
|
||||
# Inline functions may end with a comment. Strip that out
|
||||
# to help parsing.
|
||||
function_sig = remove_trailing_comment(line.strip())
|
||||
|
||||
# Now check to see if the opening curly bracket is on the
|
||||
# same line. clang-format should prevent this (BraceWrapping)
|
||||
# but it is easy to detect.
|
||||
# If the entire function is on one line, handle that too.
|
||||
if function_sig.endswith('{'):
|
||||
start_line = line_no
|
||||
state = ReaderState.IN_FUNC
|
||||
elif (function_sig.endswith('}') or
|
||||
function_sig.endswith('};')):
|
||||
start_line = line_no
|
||||
end_line = line_no
|
||||
state = ReaderState.FUNCTION_DONE
|
||||
else:
|
||||
state = ReaderState.WANT_CURLY
|
||||
|
||||
elif state == ReaderState.WANT_CURLY:
|
||||
if line.strip() == '{':
|
||||
start_line = line_no
|
||||
state = ReaderState.IN_FUNC
|
||||
|
||||
elif state == ReaderState.IN_FUNC:
|
||||
# Naive but reasonable assumption that functions will end with
|
||||
# a curly brace on its own line with no prepended spaces.
|
||||
if line.startswith('}'):
|
||||
end_line = line_no
|
||||
state = ReaderState.FUNCTION_DONE
|
||||
|
||||
return blocks
|
97
tools/isledecomp/isledecomp/parser/util.py
Normal file
97
tools/isledecomp/isledecomp/parser/util.py
Normal file
|
@ -0,0 +1,97 @@
|
|||
# C++ Parser utility functions and data structures
|
||||
from __future__ import annotations # python <3.10 compatibility
|
||||
import re
|
||||
from typing import List
|
||||
from collections import namedtuple
|
||||
|
||||
|
||||
CodeBlock = namedtuple('CodeBlock',
|
||||
['offset', 'signature', 'start_line', 'end_line',
|
||||
'offset_comment', 'module', 'is_template', 'is_stub'])
|
||||
|
||||
OffsetMatch = namedtuple('OffsetMatch', ['module', 'address', 'is_template',
|
||||
'is_stub', 'comment'])
|
||||
|
||||
# This has not been formally established, but considering that "STUB"
|
||||
# is a temporary state for a function, we assume it will appear last,
|
||||
# after any other modifiers (i.e. TEMPLATE)
|
||||
|
||||
# To match a reasonable variance of formatting for the offset comment
|
||||
offsetCommentRegex = re.compile(r'\s*//\s*OFFSET:\s*(\w+)\s+(?:0x)?([a-f0-9]+)(\s+TEMPLATE)?(\s+STUB)?', # nopep8
|
||||
flags=re.I)
|
||||
|
||||
# To match the exact syntax (text upper case, hex lower case, with spaces)
|
||||
# that is used in most places
|
||||
offsetCommentExactRegex = re.compile(r'^// OFFSET: [A-Z0-9]+ (0x[a-f0-9]+)( TEMPLATE)?( STUB)?$') # nopep8
|
||||
|
||||
|
||||
# The goal here is to just read whatever is on the next line, so some
|
||||
# flexibility in the formatting seems OK
|
||||
templateCommentRegex = re.compile(r'\s*//\s+(.*)')
|
||||
|
||||
|
||||
# To remove any comment (//) or block comment (/*) and its leading spaces
|
||||
# from the end of a code line
|
||||
trailingCommentRegex = re.compile(r'(\s*(?://|/\*).*)$')
|
||||
|
||||
|
||||
def get_template_function_name(line: str) -> str:
|
||||
"""Parse function signature for special TEMPLATE functions"""
|
||||
template_match = templateCommentRegex.match(line)
|
||||
|
||||
# If we don't match, you get whatever is on the line as the signature
|
||||
if template_match is not None:
|
||||
return template_match.group(1)
|
||||
|
||||
return line
|
||||
|
||||
|
||||
def remove_trailing_comment(line: str) -> str:
|
||||
return trailingCommentRegex.sub('', line)
|
||||
|
||||
|
||||
def is_blank_or_comment(line: str) -> bool:
|
||||
"""Helper to read ahead after the offset comment is matched.
|
||||
There could be blank lines or other comments before the
|
||||
function signature, and we want to skip those."""
|
||||
line_strip = line.strip()
|
||||
return (len(line_strip) == 0
|
||||
or line_strip.startswith('//')
|
||||
or line_strip.startswith('/*')
|
||||
or line_strip.endswith('*/'))
|
||||
|
||||
|
||||
def is_exact_offset_comment(line: str) -> bool:
|
||||
"""If the offset comment does not match our (unofficial) syntax
|
||||
we may want to alert the user to fix it for style points."""
|
||||
return offsetCommentExactRegex.match(line) is not None
|
||||
|
||||
|
||||
def match_offset_comment(line: str) -> OffsetMatch | None:
|
||||
match = offsetCommentRegex.match(line)
|
||||
if match is None:
|
||||
return None
|
||||
|
||||
return OffsetMatch(module=match.group(1),
|
||||
address=int(match.group(2), 16),
|
||||
is_template=match.group(3) is not None,
|
||||
is_stub=match.group(4) is not None,
|
||||
comment=line.strip())
|
||||
|
||||
|
||||
def distinct_by_module(offsets: List) -> List:
|
||||
"""Given a list of offset markers, return a list with distinct
|
||||
module names. If module names (case-insensitive) are repeated,
|
||||
choose the offset that appears first."""
|
||||
|
||||
if len(offsets) < 2:
|
||||
return offsets
|
||||
|
||||
# Dict maintains insertion order in python >=3.7
|
||||
offsets_dict = {}
|
||||
for offset in offsets:
|
||||
module_upper = offset.module.upper()
|
||||
if module_upper not in offsets_dict:
|
||||
offsets_dict[module_upper] = offset
|
||||
|
||||
return list(offsets_dict.values())
|
9
tools/isledecomp/setup.py
Normal file
9
tools/isledecomp/setup.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
from setuptools import setup, find_packages
|
||||
|
||||
setup(
|
||||
name='isledecomp',
|
||||
version='0.1.0',
|
||||
description='Python tools for the isledecomp project',
|
||||
packages=find_packages(),
|
||||
tests_require=['pytest'],
|
||||
)
|
0
tools/isledecomp/tests/__init__.py
Normal file
0
tools/isledecomp/tests/__init__.py
Normal file
29
tools/isledecomp/tests/samples/basic_class.cpp
Normal file
29
tools/isledecomp/tests/samples/basic_class.cpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
// Sample for python unit tests
|
||||
// Not part of the decomp
|
||||
|
||||
// A very simple class
|
||||
|
||||
class TestClass {
|
||||
public:
|
||||
TestClass();
|
||||
virtual ~TestClass() override;
|
||||
|
||||
virtual MxResult Tickle() override; // vtable+08
|
||||
|
||||
// OFFSET: TEST 0x12345678
|
||||
inline const char* ClassName() const // vtable+0c
|
||||
{
|
||||
// 0xabcd1234
|
||||
return "TestClass";
|
||||
}
|
||||
|
||||
// OFFSET: TEST 0xdeadbeef
|
||||
inline MxBool IsA(const char* name) const override // vtable+10
|
||||
{
|
||||
return !strcmp(name, TestClass::ClassName());
|
||||
}
|
||||
|
||||
private:
|
||||
int m_hello;
|
||||
int m_hiThere;
|
||||
};
|
22
tools/isledecomp/tests/samples/basic_file.cpp
Normal file
22
tools/isledecomp/tests/samples/basic_file.cpp
Normal file
|
@ -0,0 +1,22 @@
|
|||
// Sample for python unit tests
|
||||
// Not part of the decomp
|
||||
|
||||
// A very simple well-formed code file
|
||||
|
||||
// OFFSET: TEST 0x1234
|
||||
void function01()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: TEST 0x2345
|
||||
void function02()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: TEST 0x3456
|
||||
void function03()
|
||||
{
|
||||
// TODO
|
||||
}
|
8
tools/isledecomp/tests/samples/inline.cpp
Normal file
8
tools/isledecomp/tests/samples/inline.cpp
Normal file
|
@ -0,0 +1,8 @@
|
|||
// Sample for python unit tests
|
||||
// Not part of the decomp
|
||||
|
||||
// OFFSET: TEST 0x10000001
|
||||
inline const char* OneLineWithComment() const { return "MxDSObject"; }; // hi there
|
||||
|
||||
// OFFSET: TEST 0x10000002
|
||||
inline const char* OneLine() const { return "MxDSObject"; };
|
16
tools/isledecomp/tests/samples/missing_offset.cpp
Normal file
16
tools/isledecomp/tests/samples/missing_offset.cpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
// Sample for python unit tests
|
||||
// Not part of the decomp
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int no_offset_comment()
|
||||
{
|
||||
static int dummy = 123;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// OFFSET: TEST 0xdeadbeef
|
||||
void regular_ole_function()
|
||||
{
|
||||
printf("hi there");
|
||||
}
|
25
tools/isledecomp/tests/samples/multiple_offsets.cpp
Normal file
25
tools/isledecomp/tests/samples/multiple_offsets.cpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Sample for python unit tests
|
||||
// Not part of the decomp
|
||||
|
||||
// Handling multiple offset markers
|
||||
|
||||
// OFFSET: TEST 0x1234
|
||||
// OFFSET: HELLO 0x5555
|
||||
void different_modules()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: TEST 0x2345
|
||||
// OFFSET: TEST 0x1234
|
||||
void same_module()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: TEST 0x2002
|
||||
// OFFSET: test 0x1001
|
||||
void same_case_insensitive()
|
||||
{
|
||||
// TODO
|
||||
}
|
12
tools/isledecomp/tests/samples/oneline_function.cpp
Normal file
12
tools/isledecomp/tests/samples/oneline_function.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
// Sample for python unit tests
|
||||
// Not part of the decomp
|
||||
|
||||
// OFFSET: TEST 0x1234
|
||||
void short_function() { static char* msg = "oneliner"; }
|
||||
|
||||
// OFFSET: TEST 0x5555
|
||||
void function_after_one_liner()
|
||||
{
|
||||
// This function comes after the previous that is on a single line.
|
||||
// Do we report the offset for this one correctly?
|
||||
}
|
20
tools/isledecomp/tests/samples/out_of_order.cpp
Normal file
20
tools/isledecomp/tests/samples/out_of_order.cpp
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Sample for python unit tests
|
||||
// Not part of the decomp
|
||||
|
||||
// OFFSET: TEST 0x1001
|
||||
void function_order01()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: TEST 0x1003
|
||||
void function_order03()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// OFFSET: TEST 0x1002
|
||||
void function_order02()
|
||||
{
|
||||
// TODO
|
||||
}
|
23
tools/isledecomp/tests/samples/poorly_formatted.cpp
Normal file
23
tools/isledecomp/tests/samples/poorly_formatted.cpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Sample for python unit tests
|
||||
// Not part of the decomp
|
||||
|
||||
// While it's reasonable to expect a well-formed file (and clang-format
|
||||
// will make sure we get one), this will put the parser through its paces.
|
||||
|
||||
// OFFSET: TEST 0x1234
|
||||
void curly_with_spaces()
|
||||
{
|
||||
static char* msg = "hello";
|
||||
}
|
||||
|
||||
// OFFSET: TEST 0x5555
|
||||
void weird_closing_curly()
|
||||
{
|
||||
int x = 123; }
|
||||
|
||||
// OFFSET: HELLO 0x5656
|
||||
void bad_indenting() {
|
||||
if (0)
|
||||
{
|
||||
int y = 5;
|
||||
}}
|
128
tools/isledecomp/tests/test_parser.py
Normal file
128
tools/isledecomp/tests/test_parser.py
Normal file
|
@ -0,0 +1,128 @@
|
|||
import os
|
||||
import pytest
|
||||
from typing import List, TextIO
|
||||
from isledecomp.parser import find_code_blocks
|
||||
from isledecomp.parser.util import CodeBlock
|
||||
|
||||
SAMPLE_DIR = os.path.join(os.path.dirname(__file__), 'samples')
|
||||
|
||||
|
||||
def sample_file(filename: str) -> TextIO:
|
||||
"""Wrapper for opening the samples from the directory that does not
|
||||
depend on the cwd where we run the test"""
|
||||
full_path = os.path.join(SAMPLE_DIR, filename)
|
||||
return open(full_path, 'r')
|
||||
|
||||
|
||||
def code_blocks_are_sorted(blocks: List[CodeBlock]) -> bool:
|
||||
"""Helper to make this more idiomatic"""
|
||||
just_offsets = [block.offset for block in blocks]
|
||||
return just_offsets == sorted(just_offsets)
|
||||
|
||||
|
||||
# Tests are below #
|
||||
|
||||
|
||||
def test_sanity():
|
||||
"""Read a very basic file"""
|
||||
with sample_file('basic_file.cpp') as f:
|
||||
blocks = find_code_blocks(f)
|
||||
|
||||
assert len(blocks) == 3
|
||||
assert code_blocks_are_sorted(blocks) is True
|
||||
# n.b. The parser returns line numbers as 1-based
|
||||
# Function starts when we see the opening curly brace
|
||||
assert blocks[0].start_line == 8
|
||||
assert blocks[0].end_line == 10
|
||||
|
||||
|
||||
def test_oneline():
|
||||
"""(Assuming clang-format permits this) This sample has a function
|
||||
on a single line. This will test the end-of-function detection"""
|
||||
with sample_file('oneline_function.cpp') as f:
|
||||
blocks = find_code_blocks(f)
|
||||
|
||||
assert len(blocks) == 2
|
||||
assert blocks[0].start_line == 5
|
||||
assert blocks[0].end_line == 5
|
||||
|
||||
|
||||
def test_missing_offset():
|
||||
"""What if the function doesn't have an offset comment?"""
|
||||
with sample_file('missing_offset.cpp') as f:
|
||||
blocks = find_code_blocks(f)
|
||||
|
||||
# TODO: For now, the function without the offset will just be ignored.
|
||||
# Would be the same outcome if the comment was present but mangled and
|
||||
# we failed to match it. We should detect these cases in the future.
|
||||
assert len(blocks) == 1
|
||||
|
||||
|
||||
def test_jumbled_case():
|
||||
"""The parser just reports what it sees. It is the responsibility of
|
||||
the downstream tools to do something about a jumbled file.
|
||||
Just verify that we are reading it correctly."""
|
||||
with sample_file('out_of_order.cpp') as f:
|
||||
blocks = find_code_blocks(f)
|
||||
|
||||
assert len(blocks) == 3
|
||||
assert code_blocks_are_sorted(blocks) is False
|
||||
|
||||
|
||||
def test_bad_file():
|
||||
with sample_file('poorly_formatted.cpp') as f:
|
||||
blocks = find_code_blocks(f)
|
||||
|
||||
assert len(blocks) == 3
|
||||
|
||||
|
||||
def test_indented():
|
||||
"""Offsets for functions inside of a class will probably be indented."""
|
||||
with sample_file('basic_class.cpp') as f:
|
||||
blocks = find_code_blocks(f)
|
||||
|
||||
# TODO: We don't properly detect the end of these functions
|
||||
# because the closing brace is indented. However... knowing where each
|
||||
# function ends is less important (for now) than capturing
|
||||
# all the functions that are there.
|
||||
|
||||
assert len(blocks) == 2
|
||||
assert blocks[0].offset == int('0x12345678', 16)
|
||||
assert blocks[0].start_line == 15
|
||||
# assert blocks[0].end_line == 18
|
||||
|
||||
assert blocks[1].offset == int('0xdeadbeef', 16)
|
||||
assert blocks[1].start_line == 22
|
||||
# assert blocks[1].end_line == 24
|
||||
|
||||
|
||||
def test_inline():
|
||||
with sample_file('inline.cpp') as f:
|
||||
blocks = find_code_blocks(f)
|
||||
|
||||
assert len(blocks) == 2
|
||||
for block in blocks:
|
||||
assert block.start_line is not None
|
||||
assert block.start_line == block.end_line
|
||||
|
||||
|
||||
def test_multiple_offsets():
|
||||
"""If multiple offset marks appear before for a code block, take them
|
||||
all but ensure module name (case-insensitive) is distinct.
|
||||
Use first module occurrence in case of duplicates."""
|
||||
with sample_file('multiple_offsets.cpp') as f:
|
||||
blocks = find_code_blocks(f)
|
||||
|
||||
assert len(blocks) == 4
|
||||
assert blocks[0].module == 'TEST'
|
||||
assert blocks[0].start_line == 9
|
||||
|
||||
assert blocks[1].module == 'HELLO'
|
||||
assert blocks[1].start_line == 9
|
||||
|
||||
# Duplicate modules are ignored
|
||||
assert blocks[2].start_line == 16
|
||||
assert blocks[2].offset == 0x2345
|
||||
|
||||
assert blocks[3].module == 'TEST'
|
||||
assert blocks[3].offset == 0x2002
|
113
tools/isledecomp/tests/test_parser_util.py
Normal file
113
tools/isledecomp/tests/test_parser_util.py
Normal file
|
@ -0,0 +1,113 @@
|
|||
import pytest
|
||||
from collections import namedtuple
|
||||
from typing import List
|
||||
from isledecomp.parser.util import (
|
||||
is_blank_or_comment,
|
||||
match_offset_comment,
|
||||
is_exact_offset_comment,
|
||||
distinct_by_module,
|
||||
)
|
||||
|
||||
|
||||
blank_or_comment_param = [
|
||||
(True, ''),
|
||||
(True, '\t'),
|
||||
(True, ' '),
|
||||
(False, '\tint abc=123;'),
|
||||
(True, '// OFFSET: LEGO1 0xdeadbeef'),
|
||||
(True, ' /* Block comment beginning'),
|
||||
(True, 'Block comment ending */ '),
|
||||
|
||||
# TODO: does clang-format have anything to say about these cases?
|
||||
(False, 'x++; // Comment folows'),
|
||||
(False, 'x++; /* Block comment begins'),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize('expected, line', blank_or_comment_param)
|
||||
def test_is_blank_or_comment(line: str, expected: bool):
|
||||
assert is_blank_or_comment(line) is expected
|
||||
|
||||
|
||||
offset_comment_samples = [
|
||||
# (can_parse: bool, exact_match: bool, line: str)
|
||||
# Should match both expected modules with optional STUB marker
|
||||
(True, True, '// OFFSET: LEGO1 0xdeadbeef'),
|
||||
(True, True, '// OFFSET: LEGO1 0xdeadbeef STUB'),
|
||||
(True, True, '// OFFSET: ISLE 0x12345678'),
|
||||
(True, True, '// OFFSET: ISLE 0x12345678 STUB'),
|
||||
|
||||
# No trailing spaces allowed
|
||||
(True, False, '// OFFSET: LEGO1 0xdeadbeef '),
|
||||
(True, False, '// OFFSET: LEGO1 0xdeadbeef STUB '),
|
||||
|
||||
# Must have exactly one space between elements
|
||||
(True, False, '//OFFSET: ISLE 0xdeadbeef'),
|
||||
(True, False, '// OFFSET:ISLE 0xdeadbeef'),
|
||||
(True, False, '// OFFSET: ISLE 0xdeadbeef'),
|
||||
(True, False, '// OFFSET: ISLE 0xdeadbeef'),
|
||||
(True, False, '// OFFSET: ISLE 0xdeadbeef'),
|
||||
(True, False, '// OFFSET: ISLE 0xdeadbeef STUB'),
|
||||
|
||||
# Must have 0x prefix for hex number
|
||||
(True, False, '// OFFSET: ISLE deadbeef'),
|
||||
|
||||
# Offset, module name, and STUB must be uppercase
|
||||
(True, False, '// offset: ISLE 0xdeadbeef'),
|
||||
(True, False, '// offset: isle 0xdeadbeef'),
|
||||
(True, False, '// OFFSET: LEGO1 0xdeadbeef stub'),
|
||||
|
||||
# Hex string must be lowercase
|
||||
(True, False, '// OFFSET: ISLE 0xDEADBEEF'),
|
||||
|
||||
# TODO: How flexible should we be with matching the module name?
|
||||
(True, True, '// OFFSET: OMNI 0x12345678'),
|
||||
(True, True, '// OFFSET: LEG01 0x12345678'),
|
||||
(True, False, '// OFFSET: hello 0x12345678'),
|
||||
|
||||
# Not close enough to match
|
||||
(False, False, '// OFFSET: ISLE0x12345678'),
|
||||
(False, False, '// OFFSET: 0x12345678'),
|
||||
(False, False, '// LEGO1: 0x12345678'),
|
||||
|
||||
# Hex string shorter than 8 characters
|
||||
(True, True, '// OFFSET: LEGO1 0x1234'),
|
||||
|
||||
# TODO: These match but shouldn't.
|
||||
# (False, False, '// OFFSET: LEGO1 0'),
|
||||
# (False, False, '// OFFSET: LEGO1 0x'),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize('match, exact, line', offset_comment_samples)
|
||||
def test_offset_match(line: str, match: bool, exact):
|
||||
did_match = match_offset_comment(line) is not None
|
||||
assert did_match is match
|
||||
|
||||
|
||||
@pytest.mark.parametrize('match, exact, line', offset_comment_samples)
|
||||
def test_exact_offset_comment(line: str, exact: bool, match):
|
||||
assert is_exact_offset_comment(line) is exact
|
||||
|
||||
|
||||
# Helper for the next test: cut down version of OffsetMatch
|
||||
MiniOfs = namedtuple('MiniOfs', ['module', 'value'])
|
||||
|
||||
distinct_by_module_samples = [
|
||||
# empty set
|
||||
([], []),
|
||||
# same module name
|
||||
([MiniOfs('TEST', 123), MiniOfs('TEST', 555)],
|
||||
[MiniOfs('TEST', 123)]),
|
||||
# same module name, case-insensitive
|
||||
([MiniOfs('test', 123), MiniOfs('TEST', 555)],
|
||||
[MiniOfs('test', 123)]),
|
||||
# duplicates, non-consecutive
|
||||
([MiniOfs('test', 123), MiniOfs('abc', 111), MiniOfs('TEST', 555)],
|
||||
[MiniOfs('test', 123), MiniOfs('abc', 111)]),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize('sample, expected', distinct_by_module_samples)
|
||||
def test_distinct_by_module(sample: List[MiniOfs], expected: List[MiniOfs]):
|
||||
assert distinct_by_module(sample) == expected
|
|
@ -12,6 +12,8 @@
|
|||
import colorama
|
||||
import html
|
||||
import re
|
||||
from isledecomp.dir import walk_source_dir
|
||||
from isledecomp.parser import find_code_blocks
|
||||
from pystache import Renderer
|
||||
|
||||
parser = argparse.ArgumentParser(allow_abbrev=False,
|
||||
|
@ -413,145 +415,120 @@ def can_resolve_register_differences(original_asm, new_asm):
|
|||
|
||||
# Generate basename of original file, used in locating OFFSET lines
|
||||
basename = os.path.basename(os.path.splitext(original)[0])
|
||||
pattern = '// OFFSET:'
|
||||
|
||||
for subdir, dirs, files in os.walk(source):
|
||||
for file in files:
|
||||
srcfilename = os.path.join(os.path.abspath(subdir), file)
|
||||
with open(srcfilename, 'r') as srcfile:
|
||||
line_no = 0
|
||||
for srcfilename in walk_source_dir(source):
|
||||
with open(srcfilename, 'r') as srcfile:
|
||||
blocks = find_code_blocks(srcfile)
|
||||
|
||||
while True:
|
||||
try:
|
||||
line = srcfile.readline()
|
||||
line_no += 1
|
||||
for block in blocks:
|
||||
if block.is_stub:
|
||||
continue
|
||||
|
||||
if not line:
|
||||
break
|
||||
if block.module != basename:
|
||||
continue
|
||||
|
||||
line = line.strip()
|
||||
addr = block.offset
|
||||
# Verbose flag handling
|
||||
if verbose:
|
||||
if addr == verbose:
|
||||
found_verbose_target = True
|
||||
else:
|
||||
continue
|
||||
|
||||
if line.startswith(pattern) and not line.endswith('STUB'):
|
||||
par = line[len(pattern):].strip().split()
|
||||
module = par[0]
|
||||
if module != basename:
|
||||
continue
|
||||
if block.is_template:
|
||||
recinfo = syminfo.get_recompiled_address_from_name(block.signature)
|
||||
if not recinfo:
|
||||
continue
|
||||
else:
|
||||
recinfo = syminfo.get_recompiled_address(srcfilename, block.start_line)
|
||||
if not recinfo:
|
||||
continue
|
||||
|
||||
addr = int(par[1], 16)
|
||||
# The effective_ratio is the ratio when ignoring differing register
|
||||
# allocation vs the ratio is the true ratio.
|
||||
ratio = 0.0
|
||||
effective_ratio = 0.0
|
||||
if recinfo.size:
|
||||
origasm = parse_asm(origfile, addr + recinfo.start, recinfo.size)
|
||||
recompasm = parse_asm(recompfile, recinfo.addr + recinfo.start, recinfo.size)
|
||||
|
||||
# Verbose flag handling
|
||||
if verbose:
|
||||
if addr == verbose:
|
||||
found_verbose_target = True
|
||||
else:
|
||||
continue
|
||||
diff = difflib.SequenceMatcher(None, origasm, recompasm)
|
||||
ratio = diff.ratio()
|
||||
effective_ratio = ratio
|
||||
|
||||
if line.endswith('TEMPLATE'):
|
||||
line = srcfile.readline()
|
||||
line_no += 1
|
||||
# Name comes after // comment
|
||||
name = line.strip()[2:].strip()
|
||||
if ratio != 1.0:
|
||||
# Check whether we can resolve register swaps which are actually
|
||||
# perfect matches modulo compiler entropy.
|
||||
if can_resolve_register_differences(origasm, recompasm):
|
||||
effective_ratio = 1.0
|
||||
else:
|
||||
ratio = 0
|
||||
|
||||
recinfo = syminfo.get_recompiled_address_from_name(name)
|
||||
if not recinfo:
|
||||
continue
|
||||
else:
|
||||
find_open_bracket = line
|
||||
while '{' not in find_open_bracket:
|
||||
find_open_bracket = srcfile.readline()
|
||||
line_no += 1
|
||||
percenttext = f'{(effective_ratio * 100):.2f}%'
|
||||
if not plain:
|
||||
if effective_ratio == 1.0:
|
||||
percenttext = colorama.Fore.GREEN + percenttext + colorama.Style.RESET_ALL
|
||||
elif effective_ratio > 0.8:
|
||||
percenttext = colorama.Fore.YELLOW + percenttext + colorama.Style.RESET_ALL
|
||||
else:
|
||||
percenttext = colorama.Fore.RED + percenttext + colorama.Style.RESET_ALL
|
||||
|
||||
recinfo = syminfo.get_recompiled_address(srcfilename, line_no)
|
||||
if not recinfo:
|
||||
continue
|
||||
if effective_ratio == 1.0 and ratio != 1.0:
|
||||
if plain:
|
||||
percenttext += '*'
|
||||
else:
|
||||
percenttext += colorama.Fore.RED + '*' + colorama.Style.RESET_ALL
|
||||
|
||||
# The effective_ratio is the ratio when ignoring differing register
|
||||
# allocation vs the ratio is the true ratio.
|
||||
ratio = 0.0
|
||||
effective_ratio = 0.0
|
||||
if recinfo.size:
|
||||
origasm = parse_asm(origfile, addr + recinfo.start, recinfo.size)
|
||||
recompasm = parse_asm(recompfile, recinfo.addr + recinfo.start, recinfo.size)
|
||||
if args.print_rec_addr:
|
||||
addrs = f'0x{addr:x} / 0x{recinfo.addr:x}'
|
||||
else:
|
||||
addrs = hex(addr)
|
||||
|
||||
diff = difflib.SequenceMatcher(None, origasm, recompasm)
|
||||
ratio = diff.ratio()
|
||||
effective_ratio = ratio
|
||||
if not verbose:
|
||||
print(f' {recinfo.name} ({addrs}) is {percenttext} similar to the original')
|
||||
|
||||
if ratio != 1.0:
|
||||
# Check whether we can resolve register swaps which are actually
|
||||
# perfect matches modulo compiler entropy.
|
||||
if can_resolve_register_differences(origasm, recompasm):
|
||||
effective_ratio = 1.0
|
||||
else:
|
||||
ratio = 0
|
||||
function_count += 1
|
||||
total_accuracy += ratio
|
||||
total_effective_accuracy += effective_ratio
|
||||
|
||||
percenttext = f'{(effective_ratio * 100):.2f}%'
|
||||
if not plain:
|
||||
if effective_ratio == 1.0:
|
||||
percenttext = colorama.Fore.GREEN + percenttext + colorama.Style.RESET_ALL
|
||||
elif effective_ratio > 0.8:
|
||||
percenttext = colorama.Fore.YELLOW + percenttext + colorama.Style.RESET_ALL
|
||||
else:
|
||||
percenttext = colorama.Fore.RED + percenttext + colorama.Style.RESET_ALL
|
||||
if recinfo.size:
|
||||
udiff = difflib.unified_diff(origasm, recompasm, n=10)
|
||||
|
||||
if effective_ratio == 1.0 and ratio != 1.0:
|
||||
# If verbose, print the diff for that function to the output
|
||||
if verbose:
|
||||
if effective_ratio == 1.0:
|
||||
ok_text = 'OK!' if plain else (colorama.Fore.GREEN + '✨ OK! ✨' + colorama.Style.RESET_ALL)
|
||||
if ratio == 1.0:
|
||||
print(f'{addrs}: {recinfo.name} 100% match.\n\n{ok_text}\n\n')
|
||||
else:
|
||||
print(f'{addrs}: {recinfo.name} Effective 100%% match. (Differs in register allocation only)\n\n{ok_text} (still differs in register allocation)\n\n')
|
||||
else:
|
||||
for line in udiff:
|
||||
if line.startswith('++') or line.startswith('@@') or line.startswith('--'):
|
||||
# Skip unneeded parts of the diff for the brief view
|
||||
pass
|
||||
elif line.startswith('+'):
|
||||
if plain:
|
||||
percenttext += '*'
|
||||
print(line)
|
||||
else:
|
||||
percenttext += colorama.Fore.RED + '*' + colorama.Style.RESET_ALL
|
||||
|
||||
if args.print_rec_addr:
|
||||
addrs = f'0x{addr:x} / 0x{recinfo.addr:x}'
|
||||
print(colorama.Fore.GREEN + line)
|
||||
elif line.startswith('-'):
|
||||
if plain:
|
||||
print(line)
|
||||
else:
|
||||
print(colorama.Fore.RED + line)
|
||||
else:
|
||||
addrs = hex(addr)
|
||||
print(line)
|
||||
if not plain:
|
||||
print(colorama.Style.RESET_ALL, end='')
|
||||
|
||||
if not verbose:
|
||||
print(f' {recinfo.name} ({addrs}) is {percenttext} similar to the original')
|
||||
print(f'\n{recinfo.name} is only {percenttext} similar to the original, diff above')
|
||||
|
||||
function_count += 1
|
||||
total_accuracy += ratio
|
||||
total_effective_accuracy += effective_ratio
|
||||
# If html, record the diffs to an HTML file
|
||||
if html_path:
|
||||
escaped = html.escape('\\n'.join(udiff).replace('"', '\\"').replace('\n', '\\n'))
|
||||
htmlinsert.append(f'{{address: "0x{addr:x}", name: "{html.escape(recinfo.name)}", matching: {effective_ratio}, diff: "{escaped}"}}')
|
||||
|
||||
if recinfo.size:
|
||||
udiff = difflib.unified_diff(origasm, recompasm, n=10)
|
||||
|
||||
# If verbose, print the diff for that function to the output
|
||||
if verbose:
|
||||
if effective_ratio == 1.0:
|
||||
ok_text = 'OK!' if plain else (colorama.Fore.GREEN + '✨ OK! ✨' + colorama.Style.RESET_ALL)
|
||||
if ratio == 1.0:
|
||||
print(f'{addrs}: {recinfo.name} 100% match.\n\n{ok_text}\n\n')
|
||||
else:
|
||||
print(f'{addrs}: {recinfo.name} Effective 100%% match. (Differs in register allocation only)\n\n{ok_text} (still differs in register allocation)\n\n')
|
||||
else:
|
||||
for line in udiff:
|
||||
if line.startswith('++') or line.startswith('@@') or line.startswith('--'):
|
||||
# Skip unneeded parts of the diff for the brief view
|
||||
pass
|
||||
elif line.startswith('+'):
|
||||
if plain:
|
||||
print(line)
|
||||
else:
|
||||
print(colorama.Fore.GREEN + line)
|
||||
elif line.startswith('-'):
|
||||
if plain:
|
||||
print(line)
|
||||
else:
|
||||
print(colorama.Fore.RED + line)
|
||||
else:
|
||||
print(line)
|
||||
if not plain:
|
||||
print(colorama.Style.RESET_ALL, end='')
|
||||
|
||||
print(f'\n{recinfo.name} is only {percenttext} similar to the original, diff above')
|
||||
|
||||
# If html, record the diffs to an HTML file
|
||||
if html_path:
|
||||
escaped = html.escape('\\n'.join(udiff).replace('"', '\\"').replace('\n', '\\n'))
|
||||
htmlinsert.append(f'{{address: "0x{addr:x}", name: "{html.escape(recinfo.name)}", matching: {effective_ratio}, diff: "{escaped}"}}')
|
||||
|
||||
except UnicodeDecodeError:
|
||||
break
|
||||
|
||||
def gen_html(html_file, data):
|
||||
output_data = Renderer().render_path(get_file_in_script_dir('template.html'),
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
capstone
|
||||
colorama
|
||||
pystache
|
||||
isledecomp
|
||||
pystache
|
Loading…
Reference in a new issue