mirror of
https://github.com/isledecomp/isle.git
synced 2026-01-28 18:51:16 +00:00
Merge branch 'master' of https://github.com/tahg/isletahg into extra
This commit is contained in:
commit
8fc00ea7dd
7
.github/workflows/build.yml
vendored
7
.github/workflows/build.yml
vendored
@ -156,6 +156,13 @@ jobs:
|
|||||||
python3 tools/vtable/vtable.py legobin/ISLE.EXE build/ISLE.EXE build/ISLE.PDB .
|
python3 tools/vtable/vtable.py legobin/ISLE.EXE build/ISLE.EXE build/ISLE.PDB .
|
||||||
python3 tools/vtable/vtable.py legobin/LEGO1.DLL build/LEGO1.DLL build/LEGO1.PDB .
|
python3 tools/vtable/vtable.py legobin/LEGO1.DLL build/LEGO1.DLL build/LEGO1.PDB .
|
||||||
|
|
||||||
|
- name: Check Variables
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
python3 tools/datacmp.py legobin/CONFIG.EXE build/CONFIG.EXE build/CONFIG.PDB .
|
||||||
|
python3 tools/datacmp.py legobin/ISLE.EXE build/ISLE.EXE build/ISLE.PDB .
|
||||||
|
python3 tools/datacmp.py legobin/LEGO1.DLL build/LEGO1.DLL build/LEGO1.PDB .
|
||||||
|
|
||||||
- name: Upload Artifact
|
- name: Upload Artifact
|
||||||
uses: actions/upload-artifact@master
|
uses: actions/upload-artifact@master
|
||||||
with:
|
with:
|
||||||
|
|||||||
@ -297,7 +297,7 @@
|
|||||||
// GLOBAL: ISLE 0x4105b0
|
// GLOBAL: ISLE 0x4105b0
|
||||||
// __shi_TaskRecord
|
// __shi_TaskRecord
|
||||||
|
|
||||||
// GLOBAL: ISLE 0x4125f8
|
// ~GLOBAL: ISLE 0x4125f8
|
||||||
// ?_pnhHeap@@3P6AHI@ZA
|
// ?_pnhHeap@@3P6AHI@ZA
|
||||||
|
|
||||||
// GLOBAL: ISLE 0x412830
|
// GLOBAL: ISLE 0x412830
|
||||||
|
|||||||
@ -35,8 +35,8 @@ class Act3 : public LegoWorld {
|
|||||||
MxBool VTable0x64() override; // vtable+0x64
|
MxBool VTable0x64() override; // vtable+0x64
|
||||||
void Enable(MxBool p_enable) override; // vtable+0x68
|
void Enable(MxBool p_enable) override; // vtable+0x68
|
||||||
|
|
||||||
inline void SetUnkown420c(MxEntity* p_entity) { m_unk0x420c = p_entity; }
|
inline void SetUnknown420c(MxEntity* p_entity) { m_unk0x420c = p_entity; }
|
||||||
inline void SetUnkown4270(MxU32 p_unk0x4270) { m_unk0x4270 = p_unk0x4270; }
|
inline void SetUnknown4270(MxU32 p_unk0x4270) { m_unk0x4270 = p_unk0x4270; }
|
||||||
|
|
||||||
// SYNTHETIC: LEGO1 0x10072630
|
// SYNTHETIC: LEGO1 0x10072630
|
||||||
// Act3::`scalar deleting destructor'
|
// Act3::`scalar deleting destructor'
|
||||||
|
|||||||
@ -20,8 +20,7 @@ class BeachHouseEntity : public BuildingEntity {
|
|||||||
return !strcmp(p_name, BeachHouseEntity::ClassName()) || BuildingEntity::IsA(p_name);
|
return !strcmp(p_name, BeachHouseEntity::ClassName()) || BuildingEntity::IsA(p_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x100153b0
|
MxLong VTable0x50(MxParam& p_param) override;
|
||||||
MxLong VTable0x50(MxParam& p_param) override { return 0; }
|
|
||||||
|
|
||||||
// SYNTHETIC: LEGO1 0x1000f970
|
// SYNTHETIC: LEGO1 0x1000f970
|
||||||
// BeachHouseEntity::`scalar deleting destructor'
|
// BeachHouseEntity::`scalar deleting destructor'
|
||||||
|
|||||||
@ -20,8 +20,7 @@ class GasStationEntity : public BuildingEntity {
|
|||||||
return !strcmp(p_name, GasStationEntity::ClassName()) || BuildingEntity::IsA(p_name);
|
return !strcmp(p_name, GasStationEntity::ClassName()) || BuildingEntity::IsA(p_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x100151d0
|
MxLong VTable0x50(MxParam& p_param) override;
|
||||||
MxLong VTable0x50(MxParam& p_param) override { return 0; }
|
|
||||||
|
|
||||||
// SYNTHETIC: LEGO1 0x1000f890
|
// SYNTHETIC: LEGO1 0x1000f890
|
||||||
// GasStationEntity::`scalar deleting destructor'
|
// GasStationEntity::`scalar deleting destructor'
|
||||||
|
|||||||
@ -20,8 +20,7 @@ class InfoCenterEntity : public BuildingEntity {
|
|||||||
return !strcmp(p_name, InfoCenterEntity::ClassName()) || BuildingEntity::IsA(p_name);
|
return !strcmp(p_name, InfoCenterEntity::ClassName()) || BuildingEntity::IsA(p_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x100150c0
|
MxLong VTable0x50(MxParam& p_param) override; // vtable+0x50
|
||||||
MxLong VTable0x50(MxParam& p_param) override { return 0; }
|
|
||||||
|
|
||||||
// SYNTHETIC: LEGO1 0x1000f7b0
|
// SYNTHETIC: LEGO1 0x1000f7b0
|
||||||
// InfoCenterEntity::`scalar deleting destructor'
|
// InfoCenterEntity::`scalar deleting destructor'
|
||||||
|
|||||||
@ -69,6 +69,7 @@ class Isle : public LegoWorld {
|
|||||||
void FUN_10031590();
|
void FUN_10031590();
|
||||||
void FUN_10032620();
|
void FUN_10032620();
|
||||||
void FUN_100330e0();
|
void FUN_100330e0();
|
||||||
|
void FUN_10033350();
|
||||||
void FUN_10032d30(
|
void FUN_10032d30(
|
||||||
IsleScript::Script p_script,
|
IsleScript::Script p_script,
|
||||||
JukeboxScript::Script p_music,
|
JukeboxScript::Script p_music,
|
||||||
|
|||||||
@ -19,6 +19,8 @@ class LegoAct2 : public LegoWorld {
|
|||||||
MxBool VTable0x64() override; // vtable+0x64
|
MxBool VTable0x64() override; // vtable+0x64
|
||||||
void Enable(MxBool p_enable) override; // vtable+0x68
|
void Enable(MxBool p_enable) override; // vtable+0x68
|
||||||
|
|
||||||
|
inline void SetUnknown0x1150(undefined4 p_unk0x1150) { m_unk0x1150 = p_unk0x1150; }
|
||||||
|
|
||||||
// SYNTHETIC: LEGO1 0x1004fe20
|
// SYNTHETIC: LEGO1 0x1004fe20
|
||||||
// LegoAct2::`scalar deleting destructor'
|
// LegoAct2::`scalar deleting destructor'
|
||||||
|
|
||||||
|
|||||||
@ -28,10 +28,11 @@ class LegoAct2State : public LegoState {
|
|||||||
// LegoAct2State::`scalar deleting destructor'
|
// LegoAct2State::`scalar deleting destructor'
|
||||||
|
|
||||||
inline undefined4 GetUnknown0x08() { return m_unk0x08; }
|
inline undefined4 GetUnknown0x08() { return m_unk0x08; }
|
||||||
|
inline void SetUnknown0x0c(undefined p_unk0x0c) { m_unk0x0c = p_unk0x0c; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
undefined4 m_unk0x08; // 0x08
|
undefined4 m_unk0x08; // 0x08
|
||||||
undefined4 m_unk0x0c; // 0x0c
|
undefined m_unk0x0c; // 0x0c
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LEGOACT2STATE_H
|
#endif // LEGOACT2STATE_H
|
||||||
|
|||||||
@ -10,13 +10,18 @@
|
|||||||
|
|
||||||
// SIZE 0x18
|
// SIZE 0x18
|
||||||
struct Character {
|
struct Character {
|
||||||
char* m_name; // 0x00
|
char* m_name; // 0x00
|
||||||
undefined m_unk0x04; // 0x04
|
MxBool m_unk0x04; // 0x04
|
||||||
MxS8 m_vehicleId; // 0x05
|
MxS8 m_vehicleId; // 0x05
|
||||||
undefined m_unk0x06; // 0x06
|
undefined m_unk0x06; // 0x06 (unused?)
|
||||||
MxBool m_unk0x07; // 0x07
|
MxBool m_unk0x07; // 0x07
|
||||||
undefined m_unk0x08[12]; // 0x08
|
MxBool m_unk0x08; // 0x08
|
||||||
MxBool m_active; // 0x14
|
MxBool m_unk0x09; // 0x09
|
||||||
|
MxU32 m_unk0x0c; // 0x0c
|
||||||
|
MxU32 m_unk0x10; // 0x10
|
||||||
|
MxBool m_active; // 0x14
|
||||||
|
MxU8 m_unk0x15; // 0x15
|
||||||
|
MxU8 m_unk0x16; // 0x16
|
||||||
};
|
};
|
||||||
|
|
||||||
// SIZE 0x08
|
// SIZE 0x08
|
||||||
@ -62,10 +67,10 @@ class LegoAnimationManager : public MxCore {
|
|||||||
void FUN_1005f6d0(MxBool);
|
void FUN_1005f6d0(MxBool);
|
||||||
void FUN_1005f700(MxBool);
|
void FUN_1005f700(MxBool);
|
||||||
MxResult LoadScriptInfo(MxS32 p_scriptIndex);
|
MxResult LoadScriptInfo(MxS32 p_scriptIndex);
|
||||||
MxBool FUN_10060140(char* p_name, MxU32& p_index);
|
MxBool FindVehicle(const char* p_name, MxU32& p_index);
|
||||||
MxResult ReadAnimInfo(LegoFile* p_file, AnimInfo* p_info);
|
MxResult ReadAnimInfo(LegoFile* p_file, AnimInfo* p_info);
|
||||||
MxResult ReadModelInfo(LegoFile* p_file, ModelInfo* p_info);
|
MxResult ReadModelInfo(LegoFile* p_file, ModelInfo* p_info);
|
||||||
void FUN_100603c0();
|
void DeleteAnimations();
|
||||||
MxResult StartEntityAction(MxDSAction& p_dsAction, LegoEntity* p_entity);
|
MxResult StartEntityAction(MxDSAction& p_dsAction, LegoEntity* p_entity);
|
||||||
void FUN_10060570(MxBool);
|
void FUN_10060570(MxBool);
|
||||||
undefined4 FUN_10060dc0(
|
undefined4 FUN_10060dc0(
|
||||||
|
|||||||
@ -10,8 +10,8 @@ class LegoBackgroundColor : public MxVariable {
|
|||||||
LegoBackgroundColor(const char* p_key, const char* p_value);
|
LegoBackgroundColor(const char* p_key, const char* p_value);
|
||||||
|
|
||||||
void SetValue(const char* p_colorString) override;
|
void SetValue(const char* p_colorString) override;
|
||||||
void SetLights(float p_r, float p_g, float p_b);
|
void SetLightColor(float p_r, float p_g, float p_b);
|
||||||
void SetLights();
|
void SetLightColor();
|
||||||
void ToggleDayNight(MxBool);
|
void ToggleDayNight(MxBool);
|
||||||
void ToggleSkyColor();
|
void ToggleSkyColor();
|
||||||
|
|
||||||
|
|||||||
@ -47,17 +47,19 @@ class LegoCharacterManager {
|
|||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
static void SetCustomizeAnimFile(const char* p_value);
|
static void SetCustomizeAnimFile(const char* p_value);
|
||||||
static MxBool FUN_10084c00(const LegoChar*);
|
static MxBool Exists(const char* p_key);
|
||||||
|
|
||||||
void FUN_100832a0();
|
void FUN_100832a0();
|
||||||
|
MxU32 GetRefCount(LegoROI* p_roi);
|
||||||
void FUN_10083db0(LegoROI* p_roi);
|
void FUN_10083db0(LegoROI* p_roi);
|
||||||
void FUN_10083f10(LegoROI* p_roi);
|
void FUN_10083f10(LegoROI* p_roi);
|
||||||
LegoExtraActor* FUN_10084c40(const LegoChar*);
|
LegoExtraActor* GetActor(const char* p_key);
|
||||||
LegoCharacterData* Find(const char* p_key);
|
LegoCharacterData* GetData(const char* p_key);
|
||||||
|
LegoCharacterData* GetData(LegoROI* p_roi);
|
||||||
MxBool FUN_10084ec0(LegoROI* p_roi);
|
MxBool FUN_10084ec0(LegoROI* p_roi);
|
||||||
MxU32 FUN_10085140(LegoROI*, MxBool);
|
MxU32 FUN_10085140(LegoROI* p_roi, MxBool p_und);
|
||||||
LegoROI* FUN_10085210(const LegoChar*, LegoChar*, undefined);
|
LegoROI* FUN_10085210(const char*, char*, undefined);
|
||||||
LegoROI* FUN_10085a80(LegoChar* p_und1, LegoChar* p_und2, undefined p_und3);
|
LegoROI* FUN_10085a80(char* p_und1, char* p_und2, undefined p_und3);
|
||||||
|
|
||||||
static const char* GetCustomizeAnimFile() { return g_customizeAnimFile; }
|
static const char* GetCustomizeAnimFile() { return g_customizeAnimFile; }
|
||||||
|
|
||||||
|
|||||||
@ -25,8 +25,8 @@ void FUN_1003ef00(MxBool);
|
|||||||
void SetAppCursor(WPARAM p_wparam);
|
void SetAppCursor(WPARAM p_wparam);
|
||||||
MxBool FUN_1003ef60();
|
MxBool FUN_1003ef60();
|
||||||
MxBool RemoveFromWorld(MxAtomId& p_entityAtom, MxS32 p_entityId, MxAtomId& p_worldAtom, MxS32 p_worldEntityId);
|
MxBool RemoveFromWorld(MxAtomId& p_entityAtom, MxS32 p_entityId, MxAtomId& p_worldAtom, MxS32 p_worldEntityId);
|
||||||
MxS32 FUN_1003f050(MxS32);
|
MxS32 UpdateLightPosition(MxS32 p_increase);
|
||||||
void SetLightPosition(MxU32);
|
void SetLightPosition(MxS32 p_index);
|
||||||
LegoNamedTexture* ReadNamedTexture(LegoFile* p_file);
|
LegoNamedTexture* ReadNamedTexture(LegoFile* p_file);
|
||||||
void FUN_1003f540(LegoFile* p_file, const char* p_filename);
|
void FUN_1003f540(LegoFile* p_file, const char* p_filename);
|
||||||
void WriteNamedTexture(LegoFile* p_file, LegoNamedTexture* p_texture);
|
void WriteNamedTexture(LegoFile* p_file, LegoNamedTexture* p_texture);
|
||||||
|
|||||||
@ -20,7 +20,7 @@ class PoliceEntity : public BuildingEntity {
|
|||||||
return !strcmp(p_name, PoliceEntity::ClassName()) || BuildingEntity::IsA(p_name);
|
return !strcmp(p_name, PoliceEntity::ClassName()) || BuildingEntity::IsA(p_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
MxLong VTable0x50(MxParam& p_param) override;
|
MxLong VTable0x50(MxParam& p_param) override; // vtable+0x50
|
||||||
|
|
||||||
// SYNTHETIC: LEGO1 0x1000f900
|
// SYNTHETIC: LEGO1 0x1000f900
|
||||||
// PoliceEntity::`scalar deleting destructor'
|
// PoliceEntity::`scalar deleting destructor'
|
||||||
|
|||||||
@ -19,8 +19,7 @@ class RaceStandsEntity : public BuildingEntity {
|
|||||||
return !strcmp(p_name, RaceStandsEntity::ClassName()) || BuildingEntity::IsA(p_name);
|
return !strcmp(p_name, RaceStandsEntity::ClassName()) || BuildingEntity::IsA(p_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x10015450
|
MxLong VTable0x50(MxParam& p_param) override;
|
||||||
MxLong VTable0x50(MxParam& p_param) override { return 0; }
|
|
||||||
|
|
||||||
// SYNTHETIC: LEGO1 0x1000f9e0
|
// SYNTHETIC: LEGO1 0x1000f9e0
|
||||||
// RaceStandsEntity::`scalar deleting destructor'
|
// RaceStandsEntity::`scalar deleting destructor'
|
||||||
|
|||||||
@ -41,7 +41,7 @@ MxResult Helicopter::Create(MxDSAction& p_dsAction)
|
|||||||
LegoWorld* world = CurrentWorld();
|
LegoWorld* world = CurrentWorld();
|
||||||
SetWorld(world);
|
SetWorld(world);
|
||||||
if (world->IsA("Act3")) {
|
if (world->IsA("Act3")) {
|
||||||
((Act3*) GetWorld())->SetUnkown420c(this);
|
((Act3*) GetWorld())->SetUnknown420c(this);
|
||||||
}
|
}
|
||||||
world = GetWorld();
|
world = GetWorld();
|
||||||
if (world) {
|
if (world) {
|
||||||
@ -160,7 +160,7 @@ MxU32 Helicopter::VTable0xd4(LegoControlManagerEvent& p_param)
|
|||||||
switch (p_param.GetClickedObjectId()) {
|
switch (p_param.GetClickedObjectId()) {
|
||||||
case IsleScript::c_HelicopterArms_Ctl:
|
case IsleScript::c_HelicopterArms_Ctl:
|
||||||
if (*g_act3Script == script) {
|
if (*g_act3Script == script) {
|
||||||
((Act3*) CurrentWorld())->SetUnkown4270(2);
|
((Act3*) CurrentWorld())->SetUnknown4270(2);
|
||||||
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
||||||
}
|
}
|
||||||
else if (m_state->GetUnkown8() != 0) {
|
else if (m_state->GetUnkown8() != 0) {
|
||||||
|
|||||||
@ -15,11 +15,66 @@ DECOMP_SIZE_ASSERT(Vehicle, 0x8)
|
|||||||
DECOMP_SIZE_ASSERT(Unknown0x3c, 0x18)
|
DECOMP_SIZE_ASSERT(Unknown0x3c, 0x18)
|
||||||
|
|
||||||
// GLOBAL: LEGO1 0x100f6d20
|
// GLOBAL: LEGO1 0x100f6d20
|
||||||
Vehicle g_vehicles[] = {"bikebd", 0, FALSE, "bikepg", 0, FALSE, "bikerd", 0, FALSE, "bikesy", 0,
|
Vehicle g_vehicles[] = {
|
||||||
FALSE, "motoni", 0, FALSE, "motola", 0, FALSE, "board", 0, FALSE};
|
{"bikebd", 0, FALSE},
|
||||||
|
{"bikepg", 0, FALSE},
|
||||||
|
{"bikerd", 0, FALSE},
|
||||||
|
{"bikesy", 0, FALSE},
|
||||||
|
{"motoni", 0, FALSE},
|
||||||
|
{"motola", 0, FALSE},
|
||||||
|
{"board", 0, FALSE}
|
||||||
|
};
|
||||||
|
|
||||||
// GLOBAL: LEGO1 0x100f7048
|
// GLOBAL: LEGO1 0x100f7048
|
||||||
Character g_characters[47]; // TODO: Initialize this
|
Character g_characters[47] = {
|
||||||
|
{"pepper", FALSE, 6, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 50, 1},
|
||||||
|
{"mama", FALSE, -1, 0, FALSE, FALSE, FALSE, 1500, 20000, FALSE, 0, 2},
|
||||||
|
{"papa", FALSE, -1, 0, FALSE, FALSE, FALSE, 1500, 20000, FALSE, 0, 3},
|
||||||
|
{"nick", FALSE, 4, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 20, 4},
|
||||||
|
{"laura", FALSE, 5, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 20, 5},
|
||||||
|
{"brickstr", FALSE, -1, 0, FALSE, FALSE, FALSE, 1000, 20000, FALSE, 0, 6},
|
||||||
|
{"studs", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"rhoda", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"valerie", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"snap", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"pt", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"mg", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"bu", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"ml", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"nu", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"na", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"cl", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"en", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"re", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"ro", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"d1", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"d2", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"d3", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"d4", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"l1", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"l2", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"l3", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"l4", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"l5", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"l6", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"b1", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"b2", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"b3", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"b4", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"cm", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"gd", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"rd", FALSE, 2, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 50, 9},
|
||||||
|
{"pg", FALSE, 1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 50, 8},
|
||||||
|
{"bd", FALSE, 0, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 100, 7},
|
||||||
|
{"sy", FALSE, 3, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 100, 10},
|
||||||
|
{"gn", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"df", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"bs", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"lt", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"st", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"bm", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0},
|
||||||
|
{"jk", FALSE, -1, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
// GLOBAL: LEGO1 0x100f74f8
|
// GLOBAL: LEGO1 0x100f74f8
|
||||||
MxS32 g_legoAnimationManagerConfig = 1;
|
MxS32 g_legoAnimationManagerConfig = 1;
|
||||||
@ -118,7 +173,7 @@ MxResult LegoAnimationManager::LoadScriptInfo(MxS32 p_scriptIndex)
|
|||||||
m_animState->FUN_10065240(m_animCount, m_anims, m_unk0x3fc);
|
m_animState->FUN_10065240(m_animCount, m_anims, m_unk0x3fc);
|
||||||
}
|
}
|
||||||
|
|
||||||
FUN_100603c0();
|
DeleteAnimations();
|
||||||
|
|
||||||
LegoFile file;
|
LegoFile file;
|
||||||
|
|
||||||
@ -199,7 +254,7 @@ MxResult LegoAnimationManager::LoadScriptInfo(MxS32 p_scriptIndex)
|
|||||||
for (MxS32 m = 0; m < m_anims[j].m_modelCount; m++) {
|
for (MxS32 m = 0; m < m_anims[j].m_modelCount; m++) {
|
||||||
MxU32 n;
|
MxU32 n;
|
||||||
|
|
||||||
if (FUN_10060140(m_anims[j].m_models[m].m_modelName, n) && m_anims[j].m_models[m].m_unk0x2c) {
|
if (FindVehicle(m_anims[j].m_models[m].m_modelName, n) && m_anims[j].m_models[m].m_unk0x2c) {
|
||||||
m_anims[j].m_unk0x2a[count++] = n;
|
m_anims[j].m_unk0x2a[count++] = n;
|
||||||
if (count > 3) {
|
if (count > 3) {
|
||||||
break;
|
break;
|
||||||
@ -233,16 +288,22 @@ MxResult LegoAnimationManager::LoadScriptInfo(MxS32 p_scriptIndex)
|
|||||||
|
|
||||||
done:
|
done:
|
||||||
if (result == FAILURE) {
|
if (result == FAILURE) {
|
||||||
FUN_100603c0();
|
DeleteAnimations();
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x10060140
|
// FUNCTION: LEGO1 0x10060140
|
||||||
MxBool LegoAnimationManager::FUN_10060140(char* p_name, MxU32& p_index)
|
MxBool LegoAnimationManager::FindVehicle(const char* p_name, MxU32& p_index)
|
||||||
{
|
{
|
||||||
// TODO
|
for (MxS32 i = 0; i < _countof(g_vehicles); i++) {
|
||||||
|
if (!strcmpi(p_name, g_vehicles[i].m_name)) {
|
||||||
|
p_index = i;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,10 +408,29 @@ MxResult LegoAnimationManager::ReadModelInfo(LegoFile* p_file, ModelInfo* p_info
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x100603c0
|
// FUNCTION: LEGO1 0x100603c0
|
||||||
void LegoAnimationManager::FUN_100603c0()
|
void LegoAnimationManager::DeleteAnimations()
|
||||||
{
|
{
|
||||||
// TODO
|
undefined unk0x42b = m_unk0x42b;
|
||||||
|
|
||||||
|
if (m_anims != NULL) {
|
||||||
|
for (MxS32 i = 0; i < m_animCount; i++) {
|
||||||
|
delete m_anims[i].m_animName;
|
||||||
|
|
||||||
|
if (m_anims[i].m_models != NULL) {
|
||||||
|
for (MxS32 j = 0; j < m_anims[i].m_modelCount; j++) {
|
||||||
|
delete m_anims[i].m_models[j].m_modelName;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete m_anims[i].m_models;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete m_anims;
|
||||||
|
}
|
||||||
|
|
||||||
|
Init();
|
||||||
|
m_unk0x42b = unk0x42b;
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x10060570
|
// STUB: LEGO1 0x10060570
|
||||||
@ -366,7 +446,7 @@ MxResult LegoAnimationManager::StartEntityAction(MxDSAction& p_dsAction, LegoEnt
|
|||||||
LegoROI* roi = p_entity->GetROI();
|
LegoROI* roi = p_entity->GetROI();
|
||||||
|
|
||||||
if (p_entity->GetUnknown0x59() == 0) {
|
if (p_entity->GetUnknown0x59() == 0) {
|
||||||
LegoPathActor* actor = CharacterManager()->FUN_10084c40(roi->GetName());
|
LegoPathActor* actor = CharacterManager()->GetActor(roi->GetName());
|
||||||
|
|
||||||
if (actor) {
|
if (actor) {
|
||||||
LegoPathController* controller = actor->GetController();
|
LegoPathController* controller = actor->GetController();
|
||||||
|
|||||||
@ -91,7 +91,7 @@ void LegoBackgroundColor::ToggleDayNight(MxBool p_sun)
|
|||||||
float convertedR, convertedG, convertedB;
|
float convertedR, convertedG, convertedB;
|
||||||
ConvertHSVToRGB(m_h, m_s, m_v, &convertedR, &convertedG, &convertedB);
|
ConvertHSVToRGB(m_h, m_s, m_v, &convertedR, &convertedG, &convertedB);
|
||||||
VideoManager()->SetSkyColor(convertedR, convertedG, convertedB);
|
VideoManager()->SetSkyColor(convertedR, convertedG, convertedB);
|
||||||
SetLights(convertedR, convertedG, convertedB);
|
SetLightColor(convertedR, convertedG, convertedB);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x1003c330
|
// FUNCTION: LEGO1 0x1003c330
|
||||||
@ -110,18 +110,39 @@ void LegoBackgroundColor::ToggleSkyColor()
|
|||||||
float convertedR, convertedG, convertedB;
|
float convertedR, convertedG, convertedB;
|
||||||
ConvertHSVToRGB(m_h, m_s, m_v, &convertedR, &convertedG, &convertedB);
|
ConvertHSVToRGB(m_h, m_s, m_v, &convertedR, &convertedG, &convertedB);
|
||||||
VideoManager()->SetSkyColor(convertedR, convertedG, convertedB);
|
VideoManager()->SetSkyColor(convertedR, convertedG, convertedB);
|
||||||
SetLights(convertedR, convertedG, convertedB);
|
SetLightColor(convertedR, convertedG, convertedB);
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x1003c400
|
// FUNCTION: LEGO1 0x1003c400
|
||||||
void LegoBackgroundColor::SetLights(float p_r, float p_g, float p_b)
|
void LegoBackgroundColor::SetLightColor(float p_r, float p_g, float p_b)
|
||||||
{
|
{
|
||||||
|
if (!VideoManager()->GetVideoParam().Flags().GetF2bit0()) {
|
||||||
|
// TODO: Computed constants based on what?
|
||||||
|
p_r *= 4.3478260869565215;
|
||||||
|
p_g *= 1.5873015873015872;
|
||||||
|
p_b *= 1.1764705882352942;
|
||||||
|
|
||||||
|
if (p_r > 1.0) {
|
||||||
|
p_r = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_g > 1.0) {
|
||||||
|
p_g = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_b > 1.0) {
|
||||||
|
p_b = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
VideoManager()->Get3DManager()->GetLego3DView()->SetLightColor(FALSE, p_r, p_g, p_b);
|
||||||
|
VideoManager()->Get3DManager()->GetLego3DView()->SetLightColor(TRUE, p_r, p_g, p_b);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x1003c4b0
|
// FUNCTION: LEGO1 0x1003c4b0
|
||||||
void LegoBackgroundColor::SetLights()
|
void LegoBackgroundColor::SetLightColor()
|
||||||
{
|
{
|
||||||
float convertedR, convertedG, convertedB;
|
float convertedR, convertedG, convertedB;
|
||||||
ConvertHSVToRGB(m_h, m_s, m_v, &convertedR, &convertedG, &convertedB);
|
ConvertHSVToRGB(m_h, m_s, m_v, &convertedR, &convertedG, &convertedB);
|
||||||
SetLights(convertedR, convertedG, convertedB);
|
SetLightColor(convertedR, convertedG, convertedB);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,6 +17,12 @@ DECOMP_SIZE_ASSERT(LegoCharacterManager, 0x08)
|
|||||||
// GLOBAL: LEGO1 0x100fc4e4
|
// GLOBAL: LEGO1 0x100fc4e4
|
||||||
char* LegoCharacterManager::g_customizeAnimFile = NULL;
|
char* LegoCharacterManager::g_customizeAnimFile = NULL;
|
||||||
|
|
||||||
|
// GLOBAL: LEGO1 0x100fc4d8
|
||||||
|
MxU32 g_unk0x100fc4d8 = 50;
|
||||||
|
|
||||||
|
// GLOBAL: LEGO1 0x100fc4dc
|
||||||
|
MxU32 g_unk0x100fc4dc = 66;
|
||||||
|
|
||||||
// GLOBAL: LEGO1 0x10104f20
|
// GLOBAL: LEGO1 0x10104f20
|
||||||
LegoCharacterData g_characterData[66];
|
LegoCharacterData g_characterData[66];
|
||||||
|
|
||||||
@ -38,10 +44,26 @@ void LegoCharacterManager::Init()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x100832a0
|
// FUNCTION: LEGO1 0x100832a0
|
||||||
void LegoCharacterManager::FUN_100832a0()
|
void LegoCharacterManager::FUN_100832a0()
|
||||||
{
|
{
|
||||||
// TODO
|
for (MxS32 i = 0; i < _countof(g_characterData); i++) {
|
||||||
|
LegoCharacterData* data = GetData(g_characterData[i].m_name);
|
||||||
|
|
||||||
|
if (data != NULL) {
|
||||||
|
LegoExtraActor* actor = data->m_actor;
|
||||||
|
|
||||||
|
if (actor != NULL && actor->IsA("LegoExtraActor")) {
|
||||||
|
LegoROI* roi = g_characterData[i].m_roi;
|
||||||
|
MxU32 refCount = GetRefCount(roi);
|
||||||
|
|
||||||
|
while (refCount != 0) {
|
||||||
|
FUN_10083db0(roi);
|
||||||
|
refCount = GetRefCount(roi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x10083310
|
// FUNCTION: LEGO1 0x10083310
|
||||||
@ -49,7 +71,7 @@ MxResult LegoCharacterManager::Write(LegoStorage* p_storage)
|
|||||||
{
|
{
|
||||||
MxResult result = FAILURE;
|
MxResult result = FAILURE;
|
||||||
|
|
||||||
for (MxS32 i = 0; i < _countof(g_characterData) - 1; i++) {
|
for (MxS32 i = 0; i < _countof(g_characterData); i++) {
|
||||||
LegoCharacterData* data = &g_characterData[i];
|
LegoCharacterData* data = &g_characterData[i];
|
||||||
|
|
||||||
if (p_storage->Write(&data->m_unk0x0c, sizeof(data->m_unk0x0c)) != SUCCESS) {
|
if (p_storage->Write(&data->m_unk0x0c, sizeof(data->m_unk0x0c)) != SUCCESS) {
|
||||||
@ -95,7 +117,7 @@ MxResult LegoCharacterManager::Read(LegoStorage* p_storage)
|
|||||||
{
|
{
|
||||||
MxResult result = FAILURE;
|
MxResult result = FAILURE;
|
||||||
|
|
||||||
for (MxS32 i = 0; i < _countof(g_characterData) - 1; i++) {
|
for (MxS32 i = 0; i < _countof(g_characterData); i++) {
|
||||||
LegoCharacterData* data = &g_characterData[i];
|
LegoCharacterData* data = &g_characterData[i];
|
||||||
|
|
||||||
if (p_storage->Read(&data->m_unk0x0c, sizeof(data->m_unk0x0c)) != SUCCESS) {
|
if (p_storage->Read(&data->m_unk0x0c, sizeof(data->m_unk0x0c)) != SUCCESS) {
|
||||||
@ -180,7 +202,7 @@ LegoROI* LegoCharacterManager::GetROI(const char* p_key, MxBool p_createEntity)
|
|||||||
actor->SetROI(character->m_roi, FALSE, FALSE);
|
actor->SetROI(character->m_roi, FALSE, FALSE);
|
||||||
actor->FUN_100114e0(0);
|
actor->FUN_100114e0(0);
|
||||||
actor->SetFlag(LegoActor::c_bit2);
|
actor->SetFlag(LegoActor::c_bit2);
|
||||||
Find(p_key)->m_actor = actor;
|
GetData(p_key)->m_actor = actor;
|
||||||
}
|
}
|
||||||
|
|
||||||
return character->m_roi;
|
return character->m_roi;
|
||||||
@ -189,6 +211,23 @@ LegoROI* LegoCharacterManager::GetROI(const char* p_key, MxBool p_createEntity)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FUNCTION: LEGO1 0x10083bc0
|
||||||
|
MxU32 LegoCharacterManager::GetRefCount(LegoROI* p_roi)
|
||||||
|
{
|
||||||
|
LegoCharacterMap::iterator it;
|
||||||
|
|
||||||
|
for (it = m_characters->begin(); it != m_characters->end(); it++) {
|
||||||
|
LegoCharacter* character = (*it).second;
|
||||||
|
LegoROI* roi = character->m_roi;
|
||||||
|
|
||||||
|
if (roi == p_roi) {
|
||||||
|
return character->m_refCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x10083db0
|
// STUB: LEGO1 0x10083db0
|
||||||
void LegoCharacterManager::FUN_10083db0(LegoROI* p_roi)
|
void LegoCharacterManager::FUN_10083db0(LegoROI* p_roi)
|
||||||
{
|
{
|
||||||
@ -215,21 +254,21 @@ LegoROI* LegoCharacterManager::CreateROI(const char* p_key)
|
|||||||
Tgl::Renderer* renderer = VideoManager()->GetRenderer();
|
Tgl::Renderer* renderer = VideoManager()->GetRenderer();
|
||||||
ViewLODListManager* lodManager = GetViewLODListManager();
|
ViewLODListManager* lodManager = GetViewLODListManager();
|
||||||
LegoTextureContainer* textureContainer = TextureContainer();
|
LegoTextureContainer* textureContainer = TextureContainer();
|
||||||
LegoCharacterData* characterData = Find(p_key);
|
LegoCharacterData* data = GetData(p_key);
|
||||||
|
|
||||||
if (characterData == NULL) {
|
if (data == NULL) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmpi(p_key, "pep")) {
|
if (!strcmpi(p_key, "pep")) {
|
||||||
LegoCharacterData* pepper = Find("pepper");
|
LegoCharacterData* pepper = GetData("pepper");
|
||||||
|
|
||||||
characterData->m_unk0x0c = pepper->m_unk0x0c;
|
data->m_unk0x0c = pepper->m_unk0x0c;
|
||||||
characterData->m_unk0x10 = pepper->m_unk0x10;
|
data->m_unk0x10 = pepper->m_unk0x10;
|
||||||
characterData->m_unk0x14 = pepper->m_unk0x14;
|
data->m_unk0x14 = pepper->m_unk0x14;
|
||||||
|
|
||||||
for (i = 0; i < _countof(characterData->m_parts); i++) {
|
for (i = 0; i < _countof(data->m_parts); i++) {
|
||||||
characterData->m_parts[i] = pepper->m_parts[i];
|
data->m_parts[i] = pepper->m_parts[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,7 +299,7 @@ LegoROI* LegoCharacterManager::CreateROI(const char* p_key)
|
|||||||
const char* parentName;
|
const char* parentName;
|
||||||
char lodName[64];
|
char lodName[64];
|
||||||
|
|
||||||
LegoCharacterData::Part& part = characterData->m_parts[i];
|
LegoCharacterData::Part& part = data->m_parts[i];
|
||||||
|
|
||||||
if (i == 0 || i == 1) {
|
if (i == 0 || i == 1) {
|
||||||
parentName = part.m_unk0x04[part.m_unk0x00[part.m_unk0x08]];
|
parentName = part.m_unk0x04[part.m_unk0x00[part.m_unk0x08]];
|
||||||
@ -338,7 +377,7 @@ LegoROI* LegoCharacterManager::CreateROI(const char* p_key)
|
|||||||
);
|
);
|
||||||
roi->WrappedSetLocalTransform(mat);
|
roi->WrappedSetLocalTransform(mat);
|
||||||
|
|
||||||
characterData->m_roi = roi;
|
data->m_roi = roi;
|
||||||
success = TRUE;
|
success = TRUE;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
@ -350,25 +389,36 @@ LegoROI* LegoCharacterManager::CreateROI(const char* p_key)
|
|||||||
return roi;
|
return roi;
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x10084c00
|
// FUNCTION: LEGO1 0x10084c00
|
||||||
MxBool LegoCharacterManager::FUN_10084c00(const LegoChar*)
|
MxBool LegoCharacterManager::Exists(const char* p_key)
|
||||||
{
|
{
|
||||||
// TODO
|
for (MxU32 i = 0; i < _countof(g_characterData); i++) {
|
||||||
|
if (!strcmpi(g_characterData[i].m_name, p_key)) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x10084c40
|
// FUNCTION: LEGO1 0x10084c40
|
||||||
LegoExtraActor* LegoCharacterManager::FUN_10084c40(const LegoChar*)
|
LegoExtraActor* LegoCharacterManager::GetActor(const char* p_key)
|
||||||
{
|
{
|
||||||
|
LegoCharacterData* data = GetData(p_key);
|
||||||
|
|
||||||
|
if (data != NULL) {
|
||||||
|
return data->m_actor;
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x10084c60
|
// FUNCTION: LEGO1 0x10084c60
|
||||||
LegoCharacterData* LegoCharacterManager::Find(const char* p_key)
|
LegoCharacterData* LegoCharacterManager::GetData(const char* p_key)
|
||||||
{
|
{
|
||||||
MxU32 i;
|
MxU32 i;
|
||||||
|
|
||||||
for (i = 0; i < _countof(g_characterData) - 1; i++) {
|
for (i = 0; i < _countof(g_characterData); i++) {
|
||||||
if (!strcmpi(g_characterData[i].m_name, p_key)) {
|
if (!strcmpi(g_characterData[i].m_name, p_key)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -381,6 +431,24 @@ LegoCharacterData* LegoCharacterManager::Find(const char* p_key)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FUNCTION: LEGO1 0x10084cb0
|
||||||
|
LegoCharacterData* LegoCharacterManager::GetData(LegoROI* p_roi)
|
||||||
|
{
|
||||||
|
MxU32 i;
|
||||||
|
|
||||||
|
for (i = 0; i < _countof(g_characterData); i++) {
|
||||||
|
if (g_characterData[i].m_roi == p_roi) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < _countof(g_characterData)) {
|
||||||
|
return &g_characterData[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x10084ec0
|
// STUB: LEGO1 0x10084ec0
|
||||||
MxBool LegoCharacterManager::FUN_10084ec0(LegoROI* p_roi)
|
MxBool LegoCharacterManager::FUN_10084ec0(LegoROI* p_roi)
|
||||||
{
|
{
|
||||||
@ -388,10 +456,19 @@ MxBool LegoCharacterManager::FUN_10084ec0(LegoROI* p_roi)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x10085140
|
// FUNCTION: LEGO1 0x10085140
|
||||||
MxU32 LegoCharacterManager::FUN_10085140(LegoROI*, MxBool)
|
MxU32 LegoCharacterManager::FUN_10085140(LegoROI* p_roi, MxBool p_und)
|
||||||
{
|
{
|
||||||
// TODO
|
LegoCharacterData* data = GetData(p_roi);
|
||||||
|
|
||||||
|
if (p_und) {
|
||||||
|
return data->m_unk0x14 + g_unk0x100fc4dc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data != NULL) {
|
||||||
|
return data->m_unk0x0c + g_unk0x100fc4d8;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,13 +492,13 @@ void LegoCharacterManager::SetCustomizeAnimFile(const char* p_value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x10085210
|
// STUB: LEGO1 0x10085210
|
||||||
LegoROI* LegoCharacterManager::FUN_10085210(const LegoChar*, LegoChar*, undefined)
|
LegoROI* LegoCharacterManager::FUN_10085210(const char*, char*, undefined)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x10085a80
|
// FUNCTION: LEGO1 0x10085a80
|
||||||
LegoROI* LegoCharacterManager::FUN_10085a80(LegoChar* p_und1, LegoChar* p_und2, undefined p_und3)
|
LegoROI* LegoCharacterManager::FUN_10085a80(char* p_und1, char* p_und2, undefined p_und3)
|
||||||
{
|
{
|
||||||
return FUN_10085210(p_und1, p_und2, p_und3);
|
return FUN_10085210(p_und1, p_und2, p_und3);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -350,7 +350,7 @@ MxResult LegoGameState::Load(MxULong p_slot)
|
|||||||
}
|
}
|
||||||
} while (status != 2);
|
} while (status != 2);
|
||||||
|
|
||||||
m_backgroundColor->SetLights();
|
m_backgroundColor->SetLightColor();
|
||||||
lightPosition = VariableTable()->GetVariable("lightposition");
|
lightPosition = VariableTable()->GetVariable("lightposition");
|
||||||
|
|
||||||
if (lightPosition) {
|
if (lightPosition) {
|
||||||
@ -1072,7 +1072,7 @@ void LegoGameState::RegisterState(LegoState* p_state)
|
|||||||
void LegoGameState::Init()
|
void LegoGameState::Init()
|
||||||
{
|
{
|
||||||
m_backgroundColor->SetValue("set 56 54 68");
|
m_backgroundColor->SetValue("set 56 54 68");
|
||||||
m_backgroundColor->SetLights();
|
m_backgroundColor->SetLightColor();
|
||||||
m_tempBackgroundColor->SetValue("set 56 54 68");
|
m_tempBackgroundColor->SetValue("set 56 54 68");
|
||||||
VariableTable()->SetVariable("lightposition", "2");
|
VariableTable()->SetVariable("lightposition", "2");
|
||||||
SetLightPosition(2);
|
SetLightPosition(2);
|
||||||
|
|||||||
@ -14,9 +14,11 @@
|
|||||||
#include "mxnotificationmanager.h"
|
#include "mxnotificationmanager.h"
|
||||||
#include "mxstreamer.h"
|
#include "mxstreamer.h"
|
||||||
#include "mxtypes.h"
|
#include "mxtypes.h"
|
||||||
|
#include "realtime/realtime.h"
|
||||||
|
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <vec.h>
|
||||||
|
|
||||||
// STUB: LEGO1 0x1003e050
|
// STUB: LEGO1 0x1003e050
|
||||||
void FUN_1003e050(LegoAnimPresenter* p_presenter)
|
void FUN_1003e050(LegoAnimPresenter* p_presenter)
|
||||||
@ -339,22 +341,95 @@ MxBool FUN_1003ef60()
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x1003f050
|
// FUNCTION: LEGO1 0x1003f050
|
||||||
MxS32 FUN_1003f050(MxS32)
|
MxS32 UpdateLightPosition(MxS32 p_increase)
|
||||||
{
|
{
|
||||||
// TODO
|
MxS32 lightPosition = atoi(VariableTable()->GetVariable("lightposition"));
|
||||||
return 0;
|
|
||||||
|
// Only ever increases by 1 irrespective of p_increase
|
||||||
|
if (p_increase > 0) {
|
||||||
|
lightPosition += 1;
|
||||||
|
if (lightPosition > 5) {
|
||||||
|
lightPosition = 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lightPosition -= 1;
|
||||||
|
if (lightPosition < 0) {
|
||||||
|
lightPosition = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetLightPosition(lightPosition);
|
||||||
|
|
||||||
|
char lightPositionBuffer[32];
|
||||||
|
sprintf(lightPositionBuffer, "%d", lightPosition);
|
||||||
|
|
||||||
|
VariableTable()->SetVariable("lightposition", lightPositionBuffer);
|
||||||
|
|
||||||
|
return lightPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x1003f0d0
|
// FUNCTION: LEGO1 0x1003f0d0
|
||||||
void SetLightPosition(MxU32)
|
void SetLightPosition(MxS32 p_index)
|
||||||
{
|
{
|
||||||
|
float lights[6][6] = {
|
||||||
|
{1.0, 0.0, 0.0, -150.0, 50.0, -50.0},
|
||||||
|
{0.809, -0.588, 0.0, -75.0, 50.0, -50.0},
|
||||||
|
{0.0, -1.0, 0.0, 0.0, 150.0, -150.0},
|
||||||
|
{-0.309, -0.951, 0.0, 25.0, 50.0, -50.0},
|
||||||
|
{-0.809, -0.588, 0.0, 75.0, 50.0, -50.0},
|
||||||
|
{-1.0, 0.0, 0.0, 150.0, 50.0, -50.0}
|
||||||
|
};
|
||||||
|
|
||||||
|
Mx3DPointFloat up(1.0, 0.0, 0.0);
|
||||||
|
Mx3DPointFloat direction;
|
||||||
|
Mx3DPointFloat position;
|
||||||
|
|
||||||
|
Tgl::FloatMatrix4 matrix;
|
||||||
|
Matrix4 in(matrix);
|
||||||
|
MxMatrix transform;
|
||||||
|
|
||||||
|
if (p_index < 0) {
|
||||||
|
p_index = 0;
|
||||||
|
}
|
||||||
|
else if (p_index > 5) {
|
||||||
|
p_index = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
direction = lights[p_index];
|
||||||
|
position = &lights[p_index][3];
|
||||||
|
|
||||||
|
CalcLocalTransform(position, direction, up, transform);
|
||||||
|
SETMAT4(in, transform);
|
||||||
|
|
||||||
|
VideoManager()->Get3DManager()->GetLego3DView()->SetLightTransform(FALSE, matrix);
|
||||||
|
VideoManager()->Get3DManager()->GetLego3DView()->SetLightTransform(TRUE, matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x1003f3b0
|
// FUNCTION: LEGO1 0x1003f3b0
|
||||||
LegoNamedTexture* ReadNamedTexture(LegoFile* p_file)
|
LegoNamedTexture* ReadNamedTexture(LegoFile* p_file)
|
||||||
{
|
{
|
||||||
return NULL;
|
LegoTexture* texture = NULL;
|
||||||
|
LegoNamedTexture* namedTexture = NULL;
|
||||||
|
MxString string;
|
||||||
|
|
||||||
|
p_file->ReadString(string);
|
||||||
|
|
||||||
|
texture = new LegoTexture();
|
||||||
|
if (texture != NULL) {
|
||||||
|
if (texture->Read(p_file, 0) != SUCCESS) {
|
||||||
|
delete texture;
|
||||||
|
return namedTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
namedTexture = new LegoNamedTexture(string.GetData(), texture);
|
||||||
|
if (namedTexture == NULL) {
|
||||||
|
delete texture;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return namedTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
// STUB: LEGO1 0x1003f540
|
// STUB: LEGO1 0x1003f540
|
||||||
|
|||||||
@ -1,3 +1,39 @@
|
|||||||
#include "gasstationentity.h"
|
#include "gasstationentity.h"
|
||||||
|
|
||||||
|
#include "act1state.h"
|
||||||
|
#include "isle.h"
|
||||||
|
#include "isle_actions.h"
|
||||||
|
#include "islepathactor.h"
|
||||||
|
#include "legoanimationmanager.h"
|
||||||
|
#include "legogamestate.h"
|
||||||
|
#include "legoomni.h"
|
||||||
|
#include "legoutils.h"
|
||||||
|
#include "legoworld.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "mxtransitionmanager.h"
|
||||||
|
|
||||||
DECOMP_SIZE_ASSERT(GasStationEntity, 0x68)
|
DECOMP_SIZE_ASSERT(GasStationEntity, 0x68)
|
||||||
|
|
||||||
|
// FUNCTION: LEGO1 0x100151d0
|
||||||
|
MxLong GasStationEntity::VTable0x50(MxParam& p_param)
|
||||||
|
{
|
||||||
|
if (FUN_1003ef60()) {
|
||||||
|
Act1State* state = (Act1State*) GameState()->GetState("Act1State");
|
||||||
|
|
||||||
|
if (state->GetUnknown18() != 8) {
|
||||||
|
state->SetUnknown18(0);
|
||||||
|
|
||||||
|
if (CurrentActor()->GetActorId() != GameState()->GetActorId()) {
|
||||||
|
CurrentActor()->VTable0xe4();
|
||||||
|
}
|
||||||
|
|
||||||
|
Isle* isle = (Isle*) FindWorld(*g_isleScript, IsleScript::c__Isle);
|
||||||
|
isle->SetDestLocation(LegoGameState::Area::e_garage);
|
||||||
|
|
||||||
|
AnimationManager()->FUN_10061010(0);
|
||||||
|
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|||||||
@ -30,7 +30,7 @@ MxLong HospitalEntity::VTable0x50(MxParam& p_param)
|
|||||||
Isle* isle = (Isle*) FindWorld(*g_isleScript, IsleScript::c__Isle);
|
Isle* isle = (Isle*) FindWorld(*g_isleScript, IsleScript::c__Isle);
|
||||||
isle->SetDestLocation(LegoGameState::Area::e_hospital);
|
isle->SetDestLocation(LegoGameState::Area::e_hospital);
|
||||||
|
|
||||||
AnimationManager()->FUN_10061010(NULL);
|
AnimationManager()->FUN_10061010(0);
|
||||||
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,60 @@
|
|||||||
#include "infocenterentity.h"
|
#include "infocenterentity.h"
|
||||||
|
|
||||||
|
#include "act1state.h"
|
||||||
|
#include "act2main_actions.h"
|
||||||
|
#include "act3.h"
|
||||||
|
#include "act3_actions.h"
|
||||||
|
#include "act3state.h"
|
||||||
|
#include "isle.h"
|
||||||
|
#include "isle_actions.h"
|
||||||
|
#include "islepathactor.h"
|
||||||
|
#include "legoact2.h"
|
||||||
|
#include "legoact2state.h"
|
||||||
|
#include "legoanimationmanager.h"
|
||||||
|
#include "legogamestate.h"
|
||||||
|
#include "legoomni.h"
|
||||||
|
#include "legoutils.h"
|
||||||
|
#include "legoworld.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "mxtransitionmanager.h"
|
||||||
|
|
||||||
DECOMP_SIZE_ASSERT(InfoCenterEntity, 0x68)
|
DECOMP_SIZE_ASSERT(InfoCenterEntity, 0x68)
|
||||||
|
|
||||||
|
// FUNCTION: LEGO1 0x100150c0
|
||||||
|
MxLong InfoCenterEntity::VTable0x50(MxParam& p_param)
|
||||||
|
{
|
||||||
|
switch (GameState()->GetCurrentAct()) {
|
||||||
|
case LegoGameState::Act::e_act1: {
|
||||||
|
if (CurrentActor()->GetActorId() != GameState()->GetActorId()) {
|
||||||
|
CurrentActor()->VTable0xe4();
|
||||||
|
}
|
||||||
|
|
||||||
|
Isle* isle = (Isle*) FindWorld(*g_isleScript, IsleScript::c__Isle);
|
||||||
|
isle->FUN_10033350();
|
||||||
|
isle->SetDestLocation(LegoGameState::Area::e_infomain);
|
||||||
|
|
||||||
|
Act1State* act1state = (Act1State*) GameState()->GetState("Act1State");
|
||||||
|
act1state->SetUnknown18(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LegoGameState::Act::e_act2: {
|
||||||
|
LegoAct2* act2 = (LegoAct2*) FindWorld(*g_act2mainScript, Act2mainScript::c__Act2Main);
|
||||||
|
act2->SetUnknown0x1150(2);
|
||||||
|
|
||||||
|
LegoAct2State* act2state = (LegoAct2State*) GameState()->GetState("LegoAct2State");
|
||||||
|
if (act2state) {
|
||||||
|
act2state->SetUnknown0x0c(0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case LegoGameState::Act::e_act3:
|
||||||
|
Act3* act3 = (Act3*) FindWorld(*g_act3Script, Act3Script::c__Act3);
|
||||||
|
act3->SetUnknown4270(2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimationManager()->FUN_10061010(0);
|
||||||
|
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|||||||
@ -1,3 +1,36 @@
|
|||||||
#include "beachhouseentity.h"
|
#include "beachhouseentity.h"
|
||||||
|
|
||||||
|
#include "act1state.h"
|
||||||
|
#include "isle.h"
|
||||||
|
#include "isle_actions.h"
|
||||||
|
#include "islepathactor.h"
|
||||||
|
#include "legoanimationmanager.h"
|
||||||
|
#include "legogamestate.h"
|
||||||
|
#include "legoomni.h"
|
||||||
|
#include "legoutils.h"
|
||||||
|
#include "legoworld.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "mxtransitionmanager.h"
|
||||||
|
|
||||||
DECOMP_SIZE_ASSERT(BeachHouseEntity, 0x68)
|
DECOMP_SIZE_ASSERT(BeachHouseEntity, 0x68)
|
||||||
|
|
||||||
|
// FUNCTION: LEGO1 0x100153b0
|
||||||
|
MxLong BeachHouseEntity::VTable0x50(MxParam& p_param)
|
||||||
|
{
|
||||||
|
if (FUN_1003ef60()) {
|
||||||
|
Act1State* state = (Act1State*) GameState()->GetState("Act1State");
|
||||||
|
state->SetUnknown18(0);
|
||||||
|
|
||||||
|
if (CurrentActor()->GetActorId() != GameState()->GetActorId()) {
|
||||||
|
CurrentActor()->VTable0xe4();
|
||||||
|
}
|
||||||
|
|
||||||
|
Isle* isle = (Isle*) FindWorld(*g_isleScript, IsleScript::c__Isle);
|
||||||
|
isle->SetDestLocation(LegoGameState::Area::e_jetskibuild);
|
||||||
|
|
||||||
|
AnimationManager()->FUN_10061010(0);
|
||||||
|
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|||||||
@ -30,7 +30,7 @@ MxLong PoliceEntity::VTable0x50(MxParam& p_param)
|
|||||||
Isle* isle = (Isle*) FindWorld(*g_isleScript, IsleScript::c__Isle);
|
Isle* isle = (Isle*) FindWorld(*g_isleScript, IsleScript::c__Isle);
|
||||||
isle->SetDestLocation(LegoGameState::Area::e_police);
|
isle->SetDestLocation(LegoGameState::Area::e_police);
|
||||||
|
|
||||||
AnimationManager()->FUN_10061010(NULL);
|
AnimationManager()->FUN_10061010(0);
|
||||||
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,36 @@
|
|||||||
#include "racestandsentity.h"
|
#include "racestandsentity.h"
|
||||||
|
|
||||||
|
#include "act1state.h"
|
||||||
|
#include "isle.h"
|
||||||
|
#include "isle_actions.h"
|
||||||
|
#include "islepathactor.h"
|
||||||
|
#include "legoanimationmanager.h"
|
||||||
|
#include "legogamestate.h"
|
||||||
|
#include "legoomni.h"
|
||||||
|
#include "legoutils.h"
|
||||||
|
#include "legoworld.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "mxtransitionmanager.h"
|
||||||
|
|
||||||
DECOMP_SIZE_ASSERT(RaceStandsEntity, 0x68)
|
DECOMP_SIZE_ASSERT(RaceStandsEntity, 0x68)
|
||||||
|
|
||||||
|
// FUNCTION: LEGO1 0x10015450
|
||||||
|
MxLong RaceStandsEntity::VTable0x50(MxParam& p_param)
|
||||||
|
{
|
||||||
|
if (FUN_1003ef60()) {
|
||||||
|
Act1State* state = (Act1State*) GameState()->GetState("Act1State");
|
||||||
|
state->SetUnknown18(0);
|
||||||
|
|
||||||
|
if (CurrentActor()->GetActorId() != GameState()->GetActorId()) {
|
||||||
|
CurrentActor()->VTable0xe4();
|
||||||
|
}
|
||||||
|
|
||||||
|
Isle* isle = (Isle*) FindWorld(*g_isleScript, IsleScript::c__Isle);
|
||||||
|
isle->SetDestLocation(LegoGameState::Area::e_racecarbuild);
|
||||||
|
|
||||||
|
AnimationManager()->FUN_10061010(0);
|
||||||
|
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|||||||
@ -115,7 +115,7 @@ LegoChar* LegoAnimPresenter::FUN_10069150(const LegoChar* p_und1)
|
|||||||
{
|
{
|
||||||
LegoChar* str;
|
LegoChar* str;
|
||||||
|
|
||||||
if (LegoCharacterManager::FUN_10084c00(p_und1 + 1)) {
|
if (LegoCharacterManager::Exists(p_und1 + 1)) {
|
||||||
str = new LegoChar[strlen(p_und1)];
|
str = new LegoChar[strlen(p_und1)];
|
||||||
|
|
||||||
if (str != NULL) {
|
if (str != NULL) {
|
||||||
|
|||||||
@ -399,11 +399,11 @@ MxLong Isle::HandleClick(LegoControlManagerEvent& p_param)
|
|||||||
FUN_10031590();
|
FUN_10031590();
|
||||||
break;
|
break;
|
||||||
case IsleScript::c_Observe_GlobeLArrow_Ctl:
|
case IsleScript::c_Observe_GlobeLArrow_Ctl:
|
||||||
FUN_1003f050(-1);
|
UpdateLightPosition(-1);
|
||||||
FUN_10031590();
|
FUN_10031590();
|
||||||
break;
|
break;
|
||||||
case IsleScript::c_Observe_GlobeRArrow_Ctl:
|
case IsleScript::c_Observe_GlobeRArrow_Ctl:
|
||||||
FUN_1003f050(1);
|
UpdateLightPosition(1);
|
||||||
FUN_10031590();
|
FUN_10031590();
|
||||||
break;
|
break;
|
||||||
case IsleScript::c_Observe_Draw1_Ctl:
|
case IsleScript::c_Observe_Draw1_Ctl:
|
||||||
@ -1115,3 +1115,9 @@ MxBool Isle::VTable0x64()
|
|||||||
// TODO
|
// TODO
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// STUB: LEGO1 0x10033350
|
||||||
|
void Isle::FUN_10033350()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|||||||
@ -182,3 +182,45 @@ void LegoView1::Destroy()
|
|||||||
|
|
||||||
LegoView::Destroy();
|
LegoView::Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FUNCTION: LEGO1 0x100abb60
|
||||||
|
void LegoView1::SetLightTransform(BOOL bDirectionalLight, Tgl::FloatMatrix4& rMatrix)
|
||||||
|
{
|
||||||
|
Tgl::Light* pLight;
|
||||||
|
|
||||||
|
if (bDirectionalLight == FALSE) {
|
||||||
|
pLight = m_pSunLight;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pLight = m_pDirectionalLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetLightTransform(pLight, rMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FUNCTION: LEGO1 0x100abb80
|
||||||
|
void LegoView1::SetLightTransform(Tgl::Light* pLight, Tgl::FloatMatrix4& rMatrix)
|
||||||
|
{
|
||||||
|
pLight->SetTransformation(rMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FUNCTION: LEGO1 0x100abba0
|
||||||
|
void LegoView1::SetLightColor(BOOL bDirectionalLight, float red, float green, float blue)
|
||||||
|
{
|
||||||
|
Tgl::Light* pLight;
|
||||||
|
|
||||||
|
if (bDirectionalLight == FALSE) {
|
||||||
|
pLight = m_pSunLight;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pLight = m_pDirectionalLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetLightColor(pLight, red, green, blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FUNCTION: LEGO1 0x100abbd0
|
||||||
|
void LegoView1::SetLightColor(Tgl::Light* pLight, float red, float green, float blue)
|
||||||
|
{
|
||||||
|
pLight->SetColor(red, green, blue);
|
||||||
|
}
|
||||||
|
|||||||
@ -8,7 +8,8 @@
|
|||||||
namespace Tgl
|
namespace Tgl
|
||||||
{
|
{
|
||||||
class Camera;
|
class Camera;
|
||||||
}
|
class Light;
|
||||||
|
} // namespace Tgl
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// LegoView
|
// LegoView
|
||||||
@ -64,7 +65,13 @@ class LegoView1 : public LegoView {
|
|||||||
BOOL Create(const TglSurface::CreateStruct&, Tgl::Renderer*);
|
BOOL Create(const TglSurface::CreateStruct&, Tgl::Renderer*);
|
||||||
void Destroy() override; // vtable+0x08
|
void Destroy() override; // vtable+0x08
|
||||||
|
|
||||||
|
void SetLightTransform(BOOL bDirectionalLight, Tgl::FloatMatrix4& rMatrix);
|
||||||
|
void SetLightColor(BOOL bDirectionalLight, float red, float green, float blue);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void SetLightTransform(Tgl::Light* pLight, Tgl::FloatMatrix4& rMatrix);
|
||||||
|
void SetLightColor(Tgl::Light* pLight, float red, float green, float blue);
|
||||||
|
|
||||||
Tgl::Light* m_pSunLight; // 0x78
|
Tgl::Light* m_pSunLight; // 0x78
|
||||||
Tgl::Light* m_pDirectionalLight; // 0x7c
|
Tgl::Light* m_pDirectionalLight; // 0x7c
|
||||||
Tgl::Light* m_pAmbientLight; // 0x80
|
Tgl::Light* m_pAmbientLight; // 0x80
|
||||||
|
|||||||
@ -23,9 +23,6 @@ typedef struct {
|
|||||||
int m_alpha;
|
int m_alpha;
|
||||||
} ROIColorAlias;
|
} ROIColorAlias;
|
||||||
|
|
||||||
// GLOBAL: LEGO1 0x100dbe28
|
|
||||||
const double g_normalizeByteToFloat = 1.0 / 255;
|
|
||||||
|
|
||||||
// GLOBAL: LEGO1 0x101011b0
|
// GLOBAL: LEGO1 0x101011b0
|
||||||
ROIColorAlias g_roiColorAliases[22] = {
|
ROIColorAlias g_roiColorAliases[22] = {
|
||||||
{"lego black", 0x21, 0x21, 0x21, 0}, {"lego black f", 0x21, 0x21, 0x21, 0},
|
{"lego black", 0x21, 0x21, 0x21, 0}, {"lego black f", 0x21, 0x21, 0x21, 0},
|
||||||
@ -529,19 +526,15 @@ LegoBool LegoROI::FUN_100a9bf0(const LegoChar* p_param, float& p_red, float& p_g
|
|||||||
// FUNCTION: LEGO1 0x100a9c50
|
// FUNCTION: LEGO1 0x100a9c50
|
||||||
LegoBool LegoROI::ColorAliasLookup(const LegoChar* p_param, float& p_red, float& p_green, float& p_blue, float& p_alpha)
|
LegoBool LegoROI::ColorAliasLookup(const LegoChar* p_param, float& p_red, float& p_green, float& p_blue, float& p_alpha)
|
||||||
{
|
{
|
||||||
// TODO: this seems awfully hacky for these devs. is there a dynamic way
|
for (MxU32 i = 0; i < _countof(g_roiColorAliases); i++) {
|
||||||
// to represent `the end of this array` that would improve this?
|
|
||||||
unsigned int i = 0;
|
|
||||||
do {
|
|
||||||
if (strcmpi(g_roiColorAliases[i].m_name, p_param) == 0) {
|
if (strcmpi(g_roiColorAliases[i].m_name, p_param) == 0) {
|
||||||
p_red = g_roiColorAliases[i].m_red * g_normalizeByteToFloat;
|
p_red = g_roiColorAliases[i].m_red / 255.0;
|
||||||
p_green = g_roiColorAliases[i].m_green * g_normalizeByteToFloat;
|
p_green = g_roiColorAliases[i].m_green / 255.0;
|
||||||
p_blue = g_roiColorAliases[i].m_blue * g_normalizeByteToFloat;
|
p_blue = g_roiColorAliases[i].m_blue / 255.0;
|
||||||
p_alpha = g_roiColorAliases[i].m_alpha * g_normalizeByteToFloat;
|
p_alpha = g_roiColorAliases[i].m_alpha / 255.0;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
i++;
|
}
|
||||||
} while ((int*) &g_roiColorAliases[i] < &g_roiConfig);
|
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,6 +47,13 @@ def parse_args() -> argparse.Namespace:
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--no-color", "-n", action="store_true", help="Do not color the output"
|
"--no-color", "-n", action="store_true", help="Do not color the output"
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--all",
|
||||||
|
"-a",
|
||||||
|
dest="show_all",
|
||||||
|
action="store_true",
|
||||||
|
help="Only show variables with a problem",
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--print-rec-addr",
|
"--print-rec-addr",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
@ -236,7 +243,7 @@ def do_the_comparison(args: argparse.Namespace) -> Iterable[ComparisonItem]:
|
|||||||
|
|
||||||
# If we are here, we can do the type-aware comparison.
|
# If we are here, we can do the type-aware comparison.
|
||||||
compared = []
|
compared = []
|
||||||
compare_items = mini_cvdump.types.get_scalars(type_name)
|
compare_items = mini_cvdump.types.get_scalars_gapless(type_name)
|
||||||
format_str = mini_cvdump.types.get_format_string(type_name)
|
format_str = mini_cvdump.types.get_format_string(type_name)
|
||||||
|
|
||||||
orig_data = unpack(format_str, orig_raw)
|
orig_data = unpack(format_str, orig_raw)
|
||||||
@ -308,8 +315,15 @@ def display_match(result: CompareResult) -> str:
|
|||||||
)
|
)
|
||||||
return f"{match_color}{result.name}{colorama.Style.RESET_ALL}"
|
return f"{match_color}{result.name}{colorama.Style.RESET_ALL}"
|
||||||
|
|
||||||
|
var_count = 0
|
||||||
|
problems = 0
|
||||||
|
|
||||||
for item in do_the_comparison(args):
|
for item in do_the_comparison(args):
|
||||||
if not args.verbose and item.result == CompareResult.MATCH:
|
var_count += 1
|
||||||
|
if item.result in (CompareResult.DIFF, CompareResult.ERROR):
|
||||||
|
problems += 1
|
||||||
|
|
||||||
|
if not args.show_all and item.result == CompareResult.MATCH:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
address_display = (
|
address_display = (
|
||||||
@ -334,8 +348,14 @@ def display_match(result: CompareResult) -> str:
|
|||||||
f" {c.offset:5} {value_get(c.name, '(value)'):30} {value_a} : {value_b}"
|
f" {c.offset:5} {value_get(c.name, '(value)'):30} {value_a} : {value_b}"
|
||||||
)
|
)
|
||||||
|
|
||||||
print()
|
if args.verbose:
|
||||||
|
print()
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"{os.path.basename(args.original)} - Variables: {var_count}. Issues: {problems}"
|
||||||
|
)
|
||||||
|
return 0 if problems == 0 else 1
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
raise SystemExit(main())
|
||||||
|
|||||||
@ -69,14 +69,16 @@ def float_replace(self, addr: int, data_size: int) -> Optional[str]:
|
|||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def lookup(self, addr: int) -> Optional[str]:
|
def lookup(self, addr: int, use_cache: bool = True) -> Optional[str]:
|
||||||
"""Return a replacement name for this address if we find one."""
|
"""Return a replacement name for this address if we find one."""
|
||||||
if (cached := self.replacements.get(addr, None)) is not None:
|
if use_cache and (cached := self.replacements.get(addr, None)) is not None:
|
||||||
return cached
|
return cached
|
||||||
|
|
||||||
if callable(self.name_lookup):
|
if callable(self.name_lookup):
|
||||||
if (name := self.name_lookup(addr)) is not None:
|
if (name := self.name_lookup(addr)) is not None:
|
||||||
self.replacements[addr] = name
|
if use_cache:
|
||||||
|
self.replacements[addr] = name
|
||||||
|
|
||||||
return name
|
return name
|
||||||
|
|
||||||
return None
|
return None
|
||||||
@ -110,6 +112,16 @@ def hex_replace_relocated(self, match: re.Match) -> str:
|
|||||||
|
|
||||||
return match.group(0)
|
return match.group(0)
|
||||||
|
|
||||||
|
def hex_replace_annotated(self, match: re.Match) -> str:
|
||||||
|
"""For replacing immediate value operands. Here we replace the value
|
||||||
|
only if the name lookup returns something. Do not use a placeholder."""
|
||||||
|
value = int(match.group(1), 16)
|
||||||
|
placeholder = self.lookup(value, use_cache=False)
|
||||||
|
if placeholder is not None:
|
||||||
|
return match.group(0).replace(match.group(1), placeholder)
|
||||||
|
|
||||||
|
return match.group(0)
|
||||||
|
|
||||||
def hex_replace_float(self, match: re.Match) -> str:
|
def hex_replace_float(self, match: re.Match) -> str:
|
||||||
"""Special case for replacements on float instructions.
|
"""Special case for replacements on float instructions.
|
||||||
If the pointer is a float constant, read it from the binary."""
|
If the pointer is a float constant, read it from the binary."""
|
||||||
@ -178,7 +190,13 @@ def sanitize(self, inst: DisasmLiteInst) -> Tuple[str, str]:
|
|||||||
# vtable call, or this->member access.
|
# vtable call, or this->member access.
|
||||||
op_str = displace_replace_regex.sub(self.hex_replace_relocated, op_str)
|
op_str = displace_replace_regex.sub(self.hex_replace_relocated, op_str)
|
||||||
|
|
||||||
op_str = immediate_replace_regex.sub(self.hex_replace_relocated, op_str)
|
# In the event of pointer comparison, only replace the immediate value
|
||||||
|
# if it is a known address.
|
||||||
|
if inst.mnemonic == "cmp":
|
||||||
|
op_str = immediate_replace_regex.sub(self.hex_replace_annotated, op_str)
|
||||||
|
else:
|
||||||
|
op_str = immediate_replace_regex.sub(self.hex_replace_relocated, op_str)
|
||||||
|
|
||||||
return (inst.mnemonic, op_str)
|
return (inst.mnemonic, op_str)
|
||||||
|
|
||||||
def parse_asm(self, data: bytes, start_addr: Optional[int] = 0) -> List[str]:
|
def parse_asm(self, data: bytes, start_addr: Optional[int] = 0) -> List[str]:
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import re
|
import re
|
||||||
from typing import Dict, Iterator, List, NamedTuple, Optional
|
from typing import Dict, List, NamedTuple, Optional
|
||||||
|
|
||||||
|
|
||||||
class CvdumpTypeError(Exception):
|
class CvdumpTypeError(Exception):
|
||||||
@ -109,38 +109,10 @@ def scalar_type_format_char(type_name: str) -> str:
|
|||||||
return char if scalar_type_signed(type_name) else char.upper()
|
return char if scalar_type_signed(type_name) else char.upper()
|
||||||
|
|
||||||
|
|
||||||
def member_string_iter(
|
def member_list_to_struct_string(members: List[ScalarType]) -> str:
|
||||||
members: List[ScalarType], size: Optional[int] = None
|
"""Create a string for use with struct.unpack"""
|
||||||
) -> Iterator[str]:
|
|
||||||
if len(members) == 0:
|
|
||||||
yield "x" * (size or 0)
|
|
||||||
|
|
||||||
last_offset = 0
|
format_string = "".join(m.format_char for m in members)
|
||||||
last_size = 0
|
|
||||||
for m in members:
|
|
||||||
padding = m.offset - last_offset - last_size
|
|
||||||
if padding > 0:
|
|
||||||
yield "x" * padding
|
|
||||||
|
|
||||||
yield m.format_char
|
|
||||||
last_offset = m.offset
|
|
||||||
last_size = m.size
|
|
||||||
|
|
||||||
if size is not None:
|
|
||||||
padding = size - (last_offset + last_size)
|
|
||||||
if padding > 0:
|
|
||||||
yield "x" * padding
|
|
||||||
|
|
||||||
|
|
||||||
def member_list_to_struct_string(
|
|
||||||
members: List[ScalarType], size: Optional[int] = None
|
|
||||||
) -> str:
|
|
||||||
"""Create a string for use with struct.unpack
|
|
||||||
Will pad to `size` bytes if present."""
|
|
||||||
if len(members) == 0:
|
|
||||||
return "x" * (size or 0)
|
|
||||||
|
|
||||||
format_string = "".join(list(member_string_iter(members, size)))
|
|
||||||
if len(format_string) > 0:
|
if len(format_string) > 0:
|
||||||
return "<" + format_string
|
return "<" + format_string
|
||||||
|
|
||||||
@ -372,11 +344,43 @@ def get_scalars(self, type_key: str) -> List[ScalarType]:
|
|||||||
for cm in self.get_scalars(m.type)
|
for cm in self.get_scalars(m.type)
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_format_string(self, type_key: str) -> str:
|
def get_scalars_gapless(self, type_key: str) -> List[ScalarType]:
|
||||||
|
"""Reduce the given type to a list of scalars so we can
|
||||||
|
compare each component value."""
|
||||||
|
|
||||||
obj = self.get(type_key)
|
obj = self.get(type_key)
|
||||||
members = self.get_scalars(type_key)
|
total_size = obj.size
|
||||||
# We need both to pad the data to size
|
|
||||||
return member_list_to_struct_string(members, obj.size)
|
scalars = self.get_scalars(type_key)
|
||||||
|
|
||||||
|
output = []
|
||||||
|
last_extent = total_size
|
||||||
|
|
||||||
|
# Walk the scalar list in reverse; we assume a gap could not
|
||||||
|
# come at the start of the struct.
|
||||||
|
for scalar in scalars[::-1]:
|
||||||
|
this_extent = scalar.offset + scalar_type_size(scalar.type)
|
||||||
|
size_diff = last_extent - this_extent
|
||||||
|
# We need to add the gap fillers in reverse here
|
||||||
|
for i in range(size_diff - 1, -1, -1):
|
||||||
|
# Push to front
|
||||||
|
output.insert(
|
||||||
|
0,
|
||||||
|
ScalarType(
|
||||||
|
offset=this_extent + i,
|
||||||
|
name="(padding)",
|
||||||
|
type="T_UCHAR",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
output.insert(0, scalar)
|
||||||
|
last_extent = scalar.offset
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
def get_format_string(self, type_key: str) -> str:
|
||||||
|
members = self.get_scalars_gapless(type_key)
|
||||||
|
return member_list_to_struct_string(members)
|
||||||
|
|
||||||
def read_line(self, line: str):
|
def read_line(self, line: str):
|
||||||
if (match := self.INDEX_RE.match(line)) is not None:
|
if (match := self.INDEX_RE.match(line)) is not None:
|
||||||
|
|||||||
@ -313,14 +313,27 @@ def test_struct(parser):
|
|||||||
|
|
||||||
|
|
||||||
def test_struct_padding(parser):
|
def test_struct_padding(parser):
|
||||||
"""Struct format string should insert padding characters 'x'
|
"""For data comparison purposes, make sure we have no gaps in the
|
||||||
where a value is padded to alignment size (probably 4 bytes)"""
|
list of scalar types. Any gap is filled by an unsigned char."""
|
||||||
|
|
||||||
|
# MxString, padded to 16 bytes. 4 actual members. 2 bytes of padding.
|
||||||
|
assert len(parser.get_scalars("0x4db6")) == 4
|
||||||
|
assert len(parser.get_scalars_gapless("0x4db6")) == 6
|
||||||
|
|
||||||
|
# MxVariable, with two MxStrings (and a vtable)
|
||||||
|
# Fill in the middle gap and the outer gap.
|
||||||
|
assert len(parser.get_scalars("0x22d5")) == 9
|
||||||
|
assert len(parser.get_scalars_gapless("0x22d5")) == 13
|
||||||
|
|
||||||
|
|
||||||
|
def test_struct_format_string(parser):
|
||||||
|
"""Generate the struct.unpack format string using the
|
||||||
|
list of scalars with padding filled in."""
|
||||||
# MxString, padded to 16 bytes.
|
# MxString, padded to 16 bytes.
|
||||||
assert parser.get_format_string("0x4db6") == "<LLLHxx"
|
assert parser.get_format_string("0x4db6") == "<LLLHBB"
|
||||||
|
|
||||||
# MxVariable, with two MxString members.
|
# MxVariable, with two MxString members.
|
||||||
assert parser.get_format_string("0x22d5") == "<LLLLHxxLLLHxx"
|
assert parser.get_format_string("0x22d5") == "<LLLLHBBLLLHBB"
|
||||||
|
|
||||||
|
|
||||||
def test_array(parser):
|
def test_array(parser):
|
||||||
|
|||||||
@ -221,3 +221,38 @@ def substitute_float(_: int, __: int) -> str:
|
|||||||
inst = DisasmLiteInst(0x1000, 6, "fld", "dword ptr [0x1234]")
|
inst = DisasmLiteInst(0x1000, 6, "fld", "dword ptr [0x1234]")
|
||||||
(_, op_str) = p.sanitize(inst)
|
(_, op_str) = p.sanitize(inst)
|
||||||
assert op_str == "dword ptr [g_myFloatVariable]"
|
assert op_str == "dword ptr [g_myFloatVariable]"
|
||||||
|
|
||||||
|
|
||||||
|
def test_pointer_compare():
|
||||||
|
"""A loop on an array could get optimized into comparing on the address
|
||||||
|
that immediately follows the array. This may or may not be a valid address
|
||||||
|
and it may or may not be annotated. To avoid a situation where an
|
||||||
|
erroneous address value would get replaced with a placeholder and silently
|
||||||
|
pass the comparison check, we will only replace an immediate value on the
|
||||||
|
CMP instruction if it is a known address."""
|
||||||
|
|
||||||
|
# 0x1234 and 0x5555 are relocated and so are considered to be addresses.
|
||||||
|
def relocate_lookup(addr: int) -> bool:
|
||||||
|
return addr in (0x1234, 0x5555)
|
||||||
|
|
||||||
|
# Only 0x5555 is a "known" address
|
||||||
|
def name_lookup(addr: int) -> Optional[str]:
|
||||||
|
return "hello" if addr == 0x5555 else None
|
||||||
|
|
||||||
|
p = ParseAsm(relocate_lookup=relocate_lookup, name_lookup=name_lookup)
|
||||||
|
|
||||||
|
# Will always replace on MOV instruction
|
||||||
|
(_, op_str) = p.sanitize(mock_inst("mov", "eax, 0x1234"))
|
||||||
|
assert op_str == "eax, <OFFSET1>"
|
||||||
|
(_, op_str) = p.sanitize(mock_inst("mov", "eax, 0x5555"))
|
||||||
|
assert op_str == "eax, hello"
|
||||||
|
|
||||||
|
# n.b. We have already cached the replacement for 0x1234, but the
|
||||||
|
# special handling for CMP should skip the cache and not use it.
|
||||||
|
|
||||||
|
# Do not replace here
|
||||||
|
(_, op_str) = p.sanitize(mock_inst("cmp", "eax, 0x1234"))
|
||||||
|
assert op_str == "eax, 0x1234"
|
||||||
|
# Should replace here
|
||||||
|
(_, op_str) = p.sanitize(mock_inst("cmp", "eax, 0x5555"))
|
||||||
|
assert op_str == "eax, hello"
|
||||||
|
|||||||
@ -107,7 +107,7 @@ def print_match_verbose(match, show_both_addrs: bool = False, is_plain: bool = F
|
|||||||
print(f"{addrs}: {match.name} 100% match.\n\n{ok_text}\n\n")
|
print(f"{addrs}: {match.name} 100% match.\n\n{ok_text}\n\n")
|
||||||
else:
|
else:
|
||||||
print(
|
print(
|
||||||
f"{addrs}: {match.name} Effective 100%% match. (Differs in register allocation only)\n\n{ok_text} (still differs in register allocation)\n\n"
|
f"{addrs}: {match.name} Effective 100% match. (Differs in register allocation only)\n\n{ok_text} (still differs in register allocation)\n\n"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
print_combined_diff(match.udiff, is_plain, show_both_addrs)
|
print_combined_diff(match.udiff, is_plain, show_both_addrs)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user