mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-05-01 18:13:57 +00:00
Merge pull request #782 from foxtacles/master
Some checks failed
CI / clang-format (push) Has been cancelled
CI / ${{ matrix.name }} (false, --toolchain /usr/local/vitasdk/share/vita.toolchain.cmake, false, false, Ninja, Vita, ubuntu-latest, true, true) (push) Has been cancelled
CI / ${{ matrix.name }} (false, -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0.26100.0, false, false, Visual Studio 17 2022, true, Xbox One, windows-latest, amd64, false, true) (push) Has been cancelled
CI / ${{ matrix.name }} (false, -DCMAKE_TOOLCHAIN_FILE=/opt/devkitpro/cmake/3DS.cmake, false, devkitpro/devkitarm:latest, false, Ninja, true, Nintendo 3DS, ubuntu-latest, true) (push) Has been cancelled
CI / ${{ matrix.name }} (false, -DCMAKE_TOOLCHAIN_FILE=/opt/devkitpro/cmake/Switch.cmake, false, devkitpro/devkita64:latest, false, Ninja, Nintendo Switch, true, ubuntu-latest, true) (push) Has been cancelled
CI / ${{ matrix.name }} (false, emcmake, false, false, true, Ninja, Emscripten, ubuntu-latest, true) (push) Has been cancelled
CI / ${{ matrix.name }} (false, false, false, Ninja, true, MSVC (arm64), windows-latest, amd64_arm64, false) (push) Has been cancelled
CI / ${{ matrix.name }} (false, false, true, Ninja, true, MSVC (x86), windows-latest, amd64_x86, false) (push) Has been cancelled
CI / ${{ matrix.name }} (false, true, false, Ninja, true, MSVC (x64), windows-latest, amd64, false) (push) Has been cancelled
CI / ${{ matrix.name }} (false, true, true, false, Ninja, true, MSVC (x64 Debug), windows-latest, amd64, false) (push) Has been cancelled
CI / ${{ matrix.name }} (true, false, -DCMAKE_SYSTEM_NAME=iOS, false, false, Xcode, true, iOS, macos-15, true) (push) Has been cancelled
CI / ${{ matrix.name }} (true, false, false, Ninja, true, mingw-w64-i686, mingw32, msys2 mingw32, windows-latest, msys2 {0}, true) (push) Has been cancelled
CI / ${{ matrix.name }} (true, false, false, false, Ninja, Android, ubuntu-latest, true) (push) Has been cancelled
CI / ${{ matrix.name }} (true, false, true, false, Ninja, macOS, macos-latest, true) (push) Has been cancelled
CI / ${{ matrix.name }} (true, true, false, Ninja, true, mingw-w64-x86_64, mingw64, msys2 mingw64, windows-latest, msys2 {0}, true) (push) Has been cancelled
CI / ${{ matrix.name }} (true, true, true, false, Ninja, true, Linux (Debug), ubuntu-latest, true) (push) Has been cancelled
CI / ${{ matrix.name }} (true, true, true, false, Ninja, true, Linux, ubuntu-latest, true) (push) Has been cancelled
CI / Flatpak (${{ matrix.arch }}) (aarch64, ubuntu-22.04-arm) (push) Has been cancelled
CI / Flatpak (${{ matrix.arch }}) (x86_64, ubuntu-latest) (push) Has been cancelled
CI / C++ (push) Has been cancelled
Docker / Publish web port (push) Has been cancelled
CI / Release (push) Has been cancelled
Some checks failed
CI / clang-format (push) Has been cancelled
CI / ${{ matrix.name }} (false, --toolchain /usr/local/vitasdk/share/vita.toolchain.cmake, false, false, Ninja, Vita, ubuntu-latest, true, true) (push) Has been cancelled
CI / ${{ matrix.name }} (false, -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0.26100.0, false, false, Visual Studio 17 2022, true, Xbox One, windows-latest, amd64, false, true) (push) Has been cancelled
CI / ${{ matrix.name }} (false, -DCMAKE_TOOLCHAIN_FILE=/opt/devkitpro/cmake/3DS.cmake, false, devkitpro/devkitarm:latest, false, Ninja, true, Nintendo 3DS, ubuntu-latest, true) (push) Has been cancelled
CI / ${{ matrix.name }} (false, -DCMAKE_TOOLCHAIN_FILE=/opt/devkitpro/cmake/Switch.cmake, false, devkitpro/devkita64:latest, false, Ninja, Nintendo Switch, true, ubuntu-latest, true) (push) Has been cancelled
CI / ${{ matrix.name }} (false, emcmake, false, false, true, Ninja, Emscripten, ubuntu-latest, true) (push) Has been cancelled
CI / ${{ matrix.name }} (false, false, false, Ninja, true, MSVC (arm64), windows-latest, amd64_arm64, false) (push) Has been cancelled
CI / ${{ matrix.name }} (false, false, true, Ninja, true, MSVC (x86), windows-latest, amd64_x86, false) (push) Has been cancelled
CI / ${{ matrix.name }} (false, true, false, Ninja, true, MSVC (x64), windows-latest, amd64, false) (push) Has been cancelled
CI / ${{ matrix.name }} (false, true, true, false, Ninja, true, MSVC (x64 Debug), windows-latest, amd64, false) (push) Has been cancelled
CI / ${{ matrix.name }} (true, false, -DCMAKE_SYSTEM_NAME=iOS, false, false, Xcode, true, iOS, macos-15, true) (push) Has been cancelled
CI / ${{ matrix.name }} (true, false, false, Ninja, true, mingw-w64-i686, mingw32, msys2 mingw32, windows-latest, msys2 {0}, true) (push) Has been cancelled
CI / ${{ matrix.name }} (true, false, false, false, Ninja, Android, ubuntu-latest, true) (push) Has been cancelled
CI / ${{ matrix.name }} (true, false, true, false, Ninja, macOS, macos-latest, true) (push) Has been cancelled
CI / ${{ matrix.name }} (true, true, false, Ninja, true, mingw-w64-x86_64, mingw64, msys2 mingw64, windows-latest, msys2 {0}, true) (push) Has been cancelled
CI / ${{ matrix.name }} (true, true, true, false, Ninja, true, Linux (Debug), ubuntu-latest, true) (push) Has been cancelled
CI / ${{ matrix.name }} (true, true, true, false, Ninja, true, Linux, ubuntu-latest, true) (push) Has been cancelled
CI / Flatpak (${{ matrix.arch }}) (aarch64, ubuntu-22.04-arm) (push) Has been cancelled
CI / Flatpak (${{ matrix.arch }}) (x86_64, ubuntu-latest) (push) Has been cancelled
CI / C++ (push) Has been cancelled
Docker / Publish web port (push) Has been cancelled
CI / Release (push) Has been cancelled
Updates from isledecomp/isle
This commit is contained in:
commit
e739cf6ba6
@ -143,15 +143,15 @@ class Act3 : public LegoWorld {
|
||||
MxResult ShootPizza(LegoPathController* p_controller, Vector3& p_location, Vector3& p_direction, Vector3& p_up);
|
||||
MxResult ShootDonut(LegoPathController* p_controller, Vector3& p_location, Vector3& p_direction, Vector3& p_up);
|
||||
void TriggerHitSound(undefined4 p_param1);
|
||||
MxResult FUN_10073360(Act3Ammo& p_ammo, const Vector3& p_param2);
|
||||
MxResult FUN_10073390(Act3Ammo& p_ammo, const Vector3& p_param2);
|
||||
MxResult HitBrickster(Act3Ammo& p_ammo, const Vector3& p_param2);
|
||||
MxResult HitCop(Act3Ammo& p_ammo, const Vector3& p_param2);
|
||||
void SetBrickster(Act3Brickster* p_brickster);
|
||||
void AddCop(Act3Cop* p_cop);
|
||||
void FUN_10073400();
|
||||
void FUN_10073430();
|
||||
void TransitionToGoodEnding();
|
||||
void TransitionToBadEnding();
|
||||
void GoodEnding(const Matrix4& p_destination);
|
||||
void BadEnding(const Matrix4& p_destination);
|
||||
void FUN_10073a60();
|
||||
void DisableHelicopterDot();
|
||||
|
||||
// BETA indicates that the following classes access certain members directly.
|
||||
friend class Act3Ammo;
|
||||
@ -171,27 +171,27 @@ class Act3 : public LegoWorld {
|
||||
const MxQuaternionTransformer& p_quatTransform
|
||||
);
|
||||
|
||||
Act3State* m_state; // 0xf8
|
||||
Act3Ammo m_pizzas[MAX_PIZZAS]; // 0xfc
|
||||
Act3Ammo m_donuts[MAX_DONUTS]; // 0x217c
|
||||
undefined m_unk0x41fc; // 0x41fc
|
||||
Act3Cop* m_cop1; // 0x4200
|
||||
Act3Cop* m_cop2; // 0x4204
|
||||
Act3Brickster* m_brickster; // 0x4208
|
||||
Helicopter* m_copter; // 0x420c
|
||||
Act3Shark* m_shark; // 0x4210
|
||||
MxFloat m_time; // 0x4214
|
||||
MxU8 m_pizzaHitSound; // 0x4218
|
||||
MxU8 m_pizzaMissSound; // 0x4219
|
||||
MxU8 m_copDonutSound; // 0x421a
|
||||
MxU8 m_donutMissSound; // 0x421b
|
||||
MxU8 m_islanderSound; // 0x421c
|
||||
MxU8 m_bricksterDonutSound; // 0x421d
|
||||
undefined m_unk0x421e; // 0x421e
|
||||
Act3List m_unk0x4220; // 0x4220
|
||||
MxPresenter* m_helicopterDots[15]; // 0x4230
|
||||
Act3Script::Script m_unk0x426c; // 0x426c
|
||||
LegoGameState::Area m_destLocation; // 0x4270
|
||||
Act3State* m_state; // 0xf8
|
||||
Act3Ammo m_pizzas[MAX_PIZZAS]; // 0xfc
|
||||
Act3Ammo m_donuts[MAX_DONUTS]; // 0x217c
|
||||
undefined m_unk0x41fc; // 0x41fc
|
||||
Act3Cop* m_cop1; // 0x4200
|
||||
Act3Cop* m_cop2; // 0x4204
|
||||
Act3Brickster* m_brickster; // 0x4208
|
||||
Helicopter* m_copter; // 0x420c
|
||||
Act3Shark* m_shark; // 0x4210
|
||||
MxFloat m_time; // 0x4214
|
||||
MxU8 m_pizzaHitSound; // 0x4218
|
||||
MxU8 m_pizzaMissSound; // 0x4219
|
||||
MxU8 m_copDonutSound; // 0x421a
|
||||
MxU8 m_donutMissSound; // 0x421b
|
||||
MxU8 m_islanderSound; // 0x421c
|
||||
MxU8 m_bricksterDonutSound; // 0x421d
|
||||
undefined m_helicopterDotCount; // 0x421e
|
||||
Act3List m_soundList; // 0x4220
|
||||
MxPresenter* m_helicopterDots[15]; // 0x4230
|
||||
Act3Script::Script m_explanationAnimation; // 0x426c
|
||||
LegoGameState::Area m_destLocation; // 0x4270
|
||||
};
|
||||
|
||||
// TEMPLATE: LEGO1 0x10071f10
|
||||
|
||||
@ -77,19 +77,19 @@ class LegoAct2 : public LegoWorld {
|
||||
MxBool Escape() override; // vtable+0x64
|
||||
void Enable(MxBool p_enable) override; // vtable+0x68
|
||||
|
||||
void SetUnknown0x1138(Act2Actor* p_unk0x1138) { m_unk0x1138 = p_unk0x1138; }
|
||||
void SetAmbulanceActor(Act2Actor* p_ambulanceActor) { m_ambulanceActor = p_ambulanceActor; }
|
||||
void SetDestLocation(LegoGameState::Area p_destLocation) { m_destLocation = p_destLocation; }
|
||||
|
||||
MxResult CreateBrick();
|
||||
void FUN_100517b0();
|
||||
MxResult CreateDroppingBrick();
|
||||
void CreateBrick();
|
||||
MxResult BadEnding();
|
||||
MxResult StartAction(
|
||||
Act2mainScript::Script p_objectId,
|
||||
MxBool p_param2,
|
||||
MxBool p_param3,
|
||||
MxBool p_isAnimation,
|
||||
MxBool p_ignoreCurrentAction,
|
||||
Mx3DPointFloat* p_location,
|
||||
Mx3DPointFloat* p_direction,
|
||||
Mx3DPointFloat* p_param6
|
||||
Mx3DPointFloat* p_up
|
||||
);
|
||||
|
||||
// SYNTHETIC: LEGO1 0x1004fe20
|
||||
@ -117,7 +117,7 @@ class LegoAct2 : public LegoWorld {
|
||||
MxLong HandleTransitionEnd();
|
||||
MxLong HandlePathStruct(LegoPathStructNotificationParam& p_param);
|
||||
void PlayMusic(JukeboxScript::Script p_objectId);
|
||||
void FUN_10051900();
|
||||
void DisableAnimations();
|
||||
void HideMaPaInfo();
|
||||
void InitBricks();
|
||||
void UninitBricks();
|
||||
@ -145,7 +145,7 @@ class LegoAct2 : public LegoWorld {
|
||||
undefined4 m_unk0x112c; // 0x112c
|
||||
undefined4 m_unk0x1130; // 0x1130
|
||||
undefined4 m_unk0x1134; // 0x1134
|
||||
Act2Actor* m_unk0x1138; // 0x1138
|
||||
Act2Actor* m_ambulanceActor; // 0x1138
|
||||
undefined m_unk0x113c; // 0x113c
|
||||
Act2mainScript::Script m_currentAction; // 0x1140
|
||||
Act2mainScript::Script m_infomanDirecting; // 0x1144
|
||||
|
||||
@ -114,21 +114,21 @@ class LegoGameState {
|
||||
e_jetskibuild,
|
||||
e_racecarbuild,
|
||||
e_helicopterSpawn,
|
||||
e_unk41,
|
||||
e_unk42,
|
||||
e_helicopterLanded,
|
||||
e_helicopterTakenOff,
|
||||
e_dunebuggySpawn,
|
||||
e_racecarSpawn,
|
||||
e_jetskiSpawn,
|
||||
e_act2main,
|
||||
e_act3script,
|
||||
e_unk48,
|
||||
e_unk49,
|
||||
e_unk50,
|
||||
e_helicopterLandedAct3,
|
||||
e_helicopterTakenOffAct3,
|
||||
e_pepperSpawnAct2,
|
||||
e_unk51,
|
||||
e_towTrackHookedUp,
|
||||
e_jukeboxw,
|
||||
e_jukeboxExterior,
|
||||
e_unk55,
|
||||
e_helicopterExited,
|
||||
e_histbook,
|
||||
e_bike,
|
||||
e_dunecar,
|
||||
|
||||
@ -222,9 +222,6 @@ class LegoPathActor : public LegoActor {
|
||||
MxFloat m_linearRotationRatio; // 0x150
|
||||
};
|
||||
|
||||
// FUNCTION: LEGO1 0x1002edd0
|
||||
// LegoPathActor::CheckIntersectionBothFaces
|
||||
|
||||
// TEMPLATE: LEGO1 0x10018b70
|
||||
// List<LegoBoundaryEdge>::~List<LegoBoundaryEdge>
|
||||
|
||||
|
||||
@ -73,13 +73,13 @@ class LegoPathStruct : public LegoPathStructBase {
|
||||
public:
|
||||
enum Trigger {
|
||||
c_camAnim = 'C',
|
||||
c_d = 'D',
|
||||
c_e = 'E',
|
||||
c_g = 'G',
|
||||
c_h = 'H',
|
||||
c_waypoint = 'D',
|
||||
c_deleteAction = 'E',
|
||||
c_nothing = 'G',
|
||||
c_hideAnim = 'H',
|
||||
c_music = 'M',
|
||||
c_s = 'S',
|
||||
c_w = 'W'
|
||||
c_specialMissionWaypointAndAction = 'S',
|
||||
c_missionFinalWaypoint = 'W'
|
||||
};
|
||||
|
||||
// FUNCTION: LEGO1 0x100473a0
|
||||
@ -94,8 +94,8 @@ class LegoPathStruct : public LegoPathStructBase {
|
||||
void SetAtomId(const MxAtomId& p_atomId) { m_atomId = p_atomId; }
|
||||
|
||||
private:
|
||||
MxBool HandleTrigger(LegoPathActor* p_actor, MxBool p_direction, MxU32 p_data, MxBool p_bool);
|
||||
void FUN_1001bc40(const char* p_name, MxU32 p_data, MxBool p_bool);
|
||||
MxBool HandleTrigger(LegoPathActor* p_actor, MxBool p_direction, MxU32 p_data, MxBool p_invertDirection);
|
||||
void HandleAction(const char* p_name, MxU32 p_data, MxBool p_start);
|
||||
void PlayMusic(MxBool p_direction, MxU32 p_data);
|
||||
|
||||
LegoWorld* m_world; // 0x0c
|
||||
|
||||
@ -53,27 +53,33 @@ class LegoCarRaceActor : public virtual LegoRaceActor {
|
||||
|
||||
// LegoCarRaceActor vtable
|
||||
|
||||
virtual void FUN_10080590(float p_time); // vtable+0x00
|
||||
virtual void UpdateWorldSpeed(float p_time); // vtable+0x00
|
||||
|
||||
// FUNCTION: LEGO1 0x10012bb0
|
||||
virtual void FUN_10012bb0(float p_unk0x14) { m_unk0x14 = p_unk0x14; } // vtable+0x04
|
||||
virtual void SetAcceleration(float p_acceleration) { m_acceleration = p_acceleration; } // vtable+0x04
|
||||
|
||||
// FUNCTION: LEGO1 0x10012bc0
|
||||
virtual float FUN_10012bc0() { return m_unk0x14; } // vtable+0x08
|
||||
virtual float GetAcceleration() { return m_acceleration; } // vtable+0x08
|
||||
|
||||
// FUNCTION: LEGO1 0x10012bd0
|
||||
virtual void FUN_10012bd0(float p_unk0x10) { m_unk0x10 = p_unk0x10; } // vtable+0x0c
|
||||
virtual void SetCurveSpeedFactor(float p_curveSpeedFactor)
|
||||
{
|
||||
m_curveSpeedFactor = p_curveSpeedFactor;
|
||||
} // vtable+0x0c
|
||||
|
||||
// FUNCTION: LEGO1 0x10012be0
|
||||
virtual float FUN_10012be0() { return m_unk0x10; } // vtable+0x10
|
||||
virtual float GetCurveSpeedFactor() { return m_curveSpeedFactor; } // vtable+0x10
|
||||
|
||||
// FUNCTION: LEGO1 0x10012bf0
|
||||
virtual void FUN_10012bf0(float p_unk0x18) { m_unk0x18 = p_unk0x18; } // vtable+0x14
|
||||
virtual void SetRubberBandFactor(float p_rubberBandFactor)
|
||||
{
|
||||
m_rubberBandFactor = p_rubberBandFactor;
|
||||
} // vtable+0x14
|
||||
|
||||
// FUNCTION: LEGO1 0x10012c00
|
||||
virtual float FUN_10012c00() { return m_unk0x18; } // vtable+0x18
|
||||
virtual float GetRubberBandFactor() { return m_rubberBandFactor; } // vtable+0x18
|
||||
|
||||
virtual MxS32 VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edge); // vtable+0x1c
|
||||
virtual MxS32 HandleJump(LegoPathBoundary* p_boundary, LegoEdge* p_edge); // vtable+0x1c
|
||||
|
||||
// SYNTHETIC: LEGO1 0x10012c30
|
||||
// LegoCarRaceActor::`vbase destructor'
|
||||
@ -88,18 +94,18 @@ class LegoCarRaceActor : public virtual LegoRaceActor {
|
||||
MxFloat m_unk0x08; // 0x08
|
||||
MxU8 m_animState; // 0x0c
|
||||
|
||||
// Could be a multiplier for the maximum speed when going straight
|
||||
MxFloat m_unk0x10; // 0x10
|
||||
// A multiplier for the maximum speed when going around a curve
|
||||
MxFloat m_curveSpeedFactor; // 0x10
|
||||
|
||||
// Could be the acceleration
|
||||
MxFloat m_unk0x14; // 0x14
|
||||
MxFloat m_acceleration; // 0x14
|
||||
|
||||
MxFloat m_unk0x18; // 0x18
|
||||
MxFloat m_rubberBandFactor; // 0x18
|
||||
|
||||
// Could be the current timestamp for time-based movement
|
||||
MxFloat m_unk0x1c; // 0x1c
|
||||
MxFloat m_lastAcceleration; // 0x1c
|
||||
|
||||
static MxFloat g_unk0x100f7aec;
|
||||
static MxFloat g_maxSpeed;
|
||||
};
|
||||
|
||||
// VTABLE: LEGO1 0x100da208 LegoCarRaceActor
|
||||
@ -139,7 +145,7 @@ class LegoJetskiRaceActor : public virtual LegoCarRaceActor {
|
||||
Vector3& p_intersectionPoint
|
||||
) override; // vtable+0x6c
|
||||
void Animate(float p_time) override; // vtable+0x70
|
||||
MxS32 VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edge) override; // vtable+0x1c
|
||||
MxS32 HandleJump(LegoPathBoundary* p_boundary, LegoEdge* p_edge) override; // vtable+0x1c
|
||||
|
||||
// SYNTHETIC: LEGO1 0x10013a80
|
||||
// LegoJetskiRaceActor::`vbase destructor'
|
||||
|
||||
@ -65,7 +65,7 @@ void CalculateViewFromAnimation(LegoAnimPresenter* p_presenter);
|
||||
Extra::ActionType MatchActionString(const char*);
|
||||
void InvokeAction(Extra::ActionType p_actionId, const MxAtomId& p_pAtom, MxS32 p_streamId, LegoEntity* p_sender);
|
||||
void SetCameraControllerFromIsle();
|
||||
void ConvertHSVToRGB(float p_h, float p_s, float p_v, float* p_rOut, float* p_bOut, float* p_gOut);
|
||||
void ConvertHSVToRGB(float p_h, float p_s, float p_v, float* p_rOut, float* p_gOut, float* p_bOut);
|
||||
void PlayCamAnim(LegoPathActor* p_actor, MxBool p_unused, MxU32 p_location, MxBool p_bool);
|
||||
void ResetViewVelocity();
|
||||
MxBool RemoveFromCurrentWorld(const MxAtomId& p_atomId, MxS32 p_id);
|
||||
|
||||
@ -287,7 +287,7 @@ void Act2Actor::Animate(float p_time)
|
||||
}
|
||||
|
||||
SetWorldSpeed(0.0f);
|
||||
((LegoAct2*) CurrentWorld())->FUN_100517b0();
|
||||
((LegoAct2*) CurrentWorld())->CreateBrick();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@ -355,7 +355,7 @@ void Act2Actor::Animate(float p_time)
|
||||
m_state = e_createdBrick;
|
||||
m_createBrickTime = p_time;
|
||||
|
||||
if (((LegoAct2*) CurrentWorld())->CreateBrick() == SUCCESS) {
|
||||
if (((LegoAct2*) CurrentWorld())->CreateDroppingBrick() == SUCCESS) {
|
||||
PlayNextVoiceOver(VoiceOver::e_behind);
|
||||
}
|
||||
#ifndef BETA10
|
||||
|
||||
@ -649,7 +649,7 @@ void Act3Brickster::Animate(float p_time)
|
||||
assert(m_shootAnim && m_bInfo);
|
||||
|
||||
if (m_unk0x50 < p_time) {
|
||||
((Act3*) m_world)->FUN_10073a60();
|
||||
((Act3*) m_world)->DisableHelicopterDot();
|
||||
m_unk0x58 = 0;
|
||||
assert(SoundManager()->GetCacheSoundManager());
|
||||
SoundManager()->GetCacheSoundManager()->Play("thpt", NULL, FALSE);
|
||||
|
||||
@ -483,10 +483,10 @@ void Act3Ammo::Animate(float p_time)
|
||||
|
||||
if (!annihilated) {
|
||||
if (IsPizza()) {
|
||||
m_world->FUN_10073360(*this, position);
|
||||
m_world->HitBrickster(*this, position);
|
||||
}
|
||||
else {
|
||||
m_world->FUN_10073390(*this, position);
|
||||
m_world->HitCop(*this, position);
|
||||
}
|
||||
|
||||
m_worldSpeed = -1.0f;
|
||||
|
||||
@ -318,7 +318,7 @@ MxLong Ambulance::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
||||
PlayAction(IsleScript::c_Avo915In_PlayWav);
|
||||
}
|
||||
}
|
||||
else if (p_param.GetTrigger() == LegoPathStruct::c_s && p_param.GetData() == 0x131 && m_atBeachTask == 0) {
|
||||
else if (p_param.GetTrigger() == LegoPathStruct::c_specialMissionWaypointAndAction && p_param.GetData() == 0x131 && m_atBeachTask == 0) {
|
||||
m_atBeachTask = 1;
|
||||
m_taskState = Ambulance::e_waiting;
|
||||
|
||||
|
||||
@ -95,7 +95,7 @@ void Helicopter::Exit()
|
||||
if (UserActor() && UserActor()->IsA("IslePathActor")) {
|
||||
((IslePathActor*) UserActor())
|
||||
->SpawnPlayer(
|
||||
LegoGameState::e_unk55,
|
||||
LegoGameState::e_helicopterExited,
|
||||
TRUE,
|
||||
IslePathActor::c_spawnBit1 | IslePathActor::c_playMusic | IslePathActor::c_spawnBit3
|
||||
);
|
||||
@ -143,7 +143,7 @@ MxLong Helicopter::HandleClick()
|
||||
m_script = *g_isleScript;
|
||||
AnimationManager()->FUN_10064670(NULL);
|
||||
SpawnPlayer(
|
||||
LegoGameState::e_unk41,
|
||||
LegoGameState::e_helicopterLanded,
|
||||
TRUE,
|
||||
IslePathActor::c_spawnBit1 | IslePathActor::c_playMusic | IslePathActor::c_spawnBit3
|
||||
);
|
||||
@ -320,14 +320,14 @@ MxLong Helicopter::HandleEndAnim(LegoEndAnimNotificationParam& p_param)
|
||||
assert(act1State);
|
||||
act1State->m_state = Act1State::e_helicopter;
|
||||
SpawnPlayer(
|
||||
LegoGameState::e_unk42,
|
||||
LegoGameState::e_helicopterTakenOff,
|
||||
TRUE,
|
||||
IslePathActor::c_spawnBit1 | IslePathActor::c_playMusic | IslePathActor::c_spawnBit3
|
||||
);
|
||||
}
|
||||
else {
|
||||
SpawnPlayer(
|
||||
LegoGameState::e_unk49,
|
||||
LegoGameState::e_helicopterTakenOffAct3,
|
||||
TRUE,
|
||||
IslePathActor::c_spawnBit1 | IslePathActor::c_playMusic | IslePathActor::c_spawnBit3
|
||||
);
|
||||
@ -361,14 +361,14 @@ MxLong Helicopter::HandleEndAnim(LegoEndAnimNotificationParam& p_param)
|
||||
assert(act1State);
|
||||
act1State->m_state = Act1State::e_none;
|
||||
SpawnPlayer(
|
||||
LegoGameState::e_unk41,
|
||||
LegoGameState::e_helicopterLanded,
|
||||
TRUE,
|
||||
IslePathActor::c_spawnBit1 | IslePathActor::c_playMusic | IslePathActor::c_spawnBit3
|
||||
);
|
||||
}
|
||||
else {
|
||||
SpawnPlayer(
|
||||
LegoGameState::e_unk48,
|
||||
LegoGameState::e_helicopterLandedAct3,
|
||||
TRUE,
|
||||
IslePathActor::c_spawnBit1 | IslePathActor::c_playMusic | IslePathActor::c_spawnBit3
|
||||
);
|
||||
@ -430,10 +430,10 @@ void Helicopter::Animate(float p_time)
|
||||
}
|
||||
else {
|
||||
if (m_state->m_unk0x08 == 4) {
|
||||
((Act3*) m_world)->FUN_10073400();
|
||||
((Act3*) m_world)->TransitionToGoodEnding();
|
||||
}
|
||||
else {
|
||||
((Act3*) m_world)->FUN_10073430();
|
||||
((Act3*) m_world)->TransitionToBadEnding();
|
||||
}
|
||||
|
||||
SetActorState(c_disabled);
|
||||
|
||||
@ -367,7 +367,7 @@ void IslePathActor::RegisterSpawnLocations()
|
||||
JukeboxScript::c_noneJukebox
|
||||
);
|
||||
g_spawnLocations[17] = SpawnLocation(
|
||||
LegoGameState::e_unk41,
|
||||
LegoGameState::e_helicopterLanded,
|
||||
g_isleScript,
|
||||
0,
|
||||
"edg02_51",
|
||||
@ -415,7 +415,7 @@ void IslePathActor::RegisterSpawnLocations()
|
||||
JukeboxScript::c_noneJukebox
|
||||
);
|
||||
g_spawnLocations[21] = SpawnLocation(
|
||||
LegoGameState::e_unk42,
|
||||
LegoGameState::e_helicopterTakenOff,
|
||||
g_isleScript,
|
||||
0,
|
||||
"inv_05",
|
||||
@ -427,7 +427,7 @@ void IslePathActor::RegisterSpawnLocations()
|
||||
JukeboxScript::c_noneJukebox
|
||||
);
|
||||
g_spawnLocations[22] = SpawnLocation(
|
||||
LegoGameState::e_unk48,
|
||||
LegoGameState::e_helicopterLandedAct3,
|
||||
g_act3Script,
|
||||
0,
|
||||
"edg02_51",
|
||||
@ -439,7 +439,7 @@ void IslePathActor::RegisterSpawnLocations()
|
||||
JukeboxScript::c_noneJukebox
|
||||
);
|
||||
g_spawnLocations[23] = SpawnLocation(
|
||||
LegoGameState::e_unk49,
|
||||
LegoGameState::e_helicopterTakenOffAct3,
|
||||
g_act3Script,
|
||||
0,
|
||||
"inv_05",
|
||||
@ -451,7 +451,7 @@ void IslePathActor::RegisterSpawnLocations()
|
||||
JukeboxScript::c_noneJukebox
|
||||
);
|
||||
g_spawnLocations[24] = SpawnLocation(
|
||||
LegoGameState::e_unk50,
|
||||
LegoGameState::e_pepperSpawnAct2,
|
||||
g_act2mainScript,
|
||||
0,
|
||||
"EDG02_51",
|
||||
@ -499,7 +499,7 @@ void IslePathActor::RegisterSpawnLocations()
|
||||
JukeboxScript::c_noneJukebox
|
||||
);
|
||||
g_spawnLocations[28] = SpawnLocation(
|
||||
LegoGameState::e_unk55,
|
||||
LegoGameState::e_helicopterExited,
|
||||
g_isleScript,
|
||||
0,
|
||||
"edg02_50",
|
||||
|
||||
@ -281,7 +281,7 @@ MxLong Pizza::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
||||
if (m_state->m_state == PizzaMissionState::e_delivering) {
|
||||
MxLong time = Timer()->GetTime() - m_mission->m_startTime;
|
||||
|
||||
if (p_param.GetTrigger() == LegoPathStruct::c_s && p_param.GetData() == 0x12e &&
|
||||
if (p_param.GetTrigger() == LegoPathStruct::c_specialMissionWaypointAndAction && p_param.GetData() == 0x12e &&
|
||||
GameState()->GetActorId() == LegoActor::c_pepper) {
|
||||
m_state->m_state = PizzaMissionState::e_arrivedAtDestination;
|
||||
m_state->SetPlayedAction(SndanimScript::c_TRS302_OpenJailDoor);
|
||||
@ -303,7 +303,7 @@ MxLong Pizza::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
||||
(p_param.GetData() == 0x33 && GameState()->GetActorId() == LegoActor::c_papa) ||
|
||||
((p_param.GetData() == 0x08 || p_param.GetData() == 0x09) && GameState()->GetActorId() == LegoActor::c_nick) ||
|
||||
(p_param.GetData() == 0x0b && GameState()->GetActorId() == LegoActor::c_laura)
|
||||
)) || (p_param.GetTrigger() == LegoPathStruct::c_w && p_param.GetData() == 0x169 && GameState()->GetActorId() == LegoActor::c_nick)) {
|
||||
)) || (p_param.GetTrigger() == LegoPathStruct::c_missionFinalWaypoint && p_param.GetData() == 0x169 && GameState()->GetActorId() == LegoActor::c_nick)) {
|
||||
IsleScript::Script action;
|
||||
|
||||
if (time < m_mission->GetRedFinishTime()) {
|
||||
@ -353,7 +353,7 @@ MxLong Pizza::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
||||
|
||||
MxTrace("Pizza mission: ending\n");
|
||||
}
|
||||
else if (p_param.GetTrigger() == LegoPathStruct::c_w) {
|
||||
else if (p_param.GetTrigger() == LegoPathStruct::c_missionFinalWaypoint) {
|
||||
if (p_param.GetData() == 0x15e && GameState()->GetActorId() == LegoActor::c_pepper) {
|
||||
if (!m_playedLocationAnimation) {
|
||||
m_playedLocationAnimation = TRUE;
|
||||
|
||||
@ -302,7 +302,7 @@ MxLong TowTrack::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
||||
|
||||
if (m_state->m_state == TowTrackMissionState::e_hookedUp &&
|
||||
((p_param.GetTrigger() == LegoPathStruct::c_camAnim && (p_param.GetData() == 9 || p_param.GetData() == 8)) ||
|
||||
(p_param.GetTrigger() == LegoPathStruct::c_w && p_param.GetData() == 0x169))) {
|
||||
(p_param.GetTrigger() == LegoPathStruct::c_missionFinalWaypoint && p_param.GetData() == 0x169))) {
|
||||
m_state->m_state = TowTrackMissionState::e_none;
|
||||
|
||||
MxLong time = Timer()->GetTime() - m_state->m_startTime;
|
||||
@ -329,7 +329,7 @@ MxLong TowTrack::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
||||
Leave();
|
||||
PlayFinalAnimation(IsleScript::c_wrt060bm_RunAnim);
|
||||
}
|
||||
else if (p_param.GetTrigger() == LegoPathStruct::c_w && m_state->m_state == TowTrackMissionState::e_started) {
|
||||
else if (p_param.GetTrigger() == LegoPathStruct::c_missionFinalWaypoint && m_state->m_state == TowTrackMissionState::e_started) {
|
||||
if (p_param.GetData() == 0x15f) {
|
||||
if (m_treeBlockageTriggered == 0) {
|
||||
m_treeBlockageTriggered = 1;
|
||||
|
||||
@ -1684,8 +1684,7 @@ void LegoCarBuild::HandleEndAnim()
|
||||
MxBool LegoCarBuild::Escape()
|
||||
{
|
||||
BackgroundAudioManager()->Init();
|
||||
MxS32 targetEntityId = GetBuildMovieId(m_carId);
|
||||
InvokeAction(Extra::ActionType::e_stop, *g_jukeboxScript, targetEntityId, NULL);
|
||||
InvokeAction(Extra::ActionType::e_stop, *g_jukeboxScript, GetBuildMovieId(m_carId), NULL);
|
||||
DeleteObjects(&m_atomId, 500, 999);
|
||||
|
||||
m_buildState->m_animationState = LegoVehicleBuildState::e_none;
|
||||
|
||||
@ -389,7 +389,7 @@ MxCore* LegoObjectFactory::Create(const char* p_name)
|
||||
}
|
||||
else if (m_idAct2Actor == atom) {
|
||||
Act2Actor* actor = new Act2Actor();
|
||||
((LegoAct2*) CurrentWorld())->SetUnknown0x1138(actor);
|
||||
((LegoAct2*) CurrentWorld())->SetAmbulanceActor(actor);
|
||||
object = actor;
|
||||
}
|
||||
else if (m_idAct2Brick == atom) {
|
||||
|
||||
@ -96,11 +96,13 @@ void RotateY(LegoROI* p_roi, MxFloat p_angle)
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1003de80
|
||||
// FUNCTION: BETA10 0x100d3684
|
||||
MxBool SpheresIntersect(const BoundingSphere& p_sphere1, const BoundingSphere& p_sphere2)
|
||||
{
|
||||
// This doesn't look clean, but it matches.
|
||||
// p_sphere1.Center().GetData() doesn't work out
|
||||
return sqrt(DISTSQRD3(&p_sphere1.Center()[0], &p_sphere2.Center()[0])) < p_sphere1.Radius() + p_sphere2.Radius();
|
||||
float distance = DISTSQRD3(p_sphere1.Center(), p_sphere2.Center());
|
||||
return sqrt(distance) < p_sphere1.Radius() + p_sphere2.Radius();
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1003ded0
|
||||
@ -392,7 +394,7 @@ void SetCameraControllerFromIsle()
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1003eae0
|
||||
void ConvertHSVToRGB(float p_h, float p_s, float p_v, float* p_rOut, float* p_bOut, float* p_gOut)
|
||||
void ConvertHSVToRGB(float p_h, float p_s, float p_v, float* p_rOut, float* p_gOut, float* p_bOut)
|
||||
{
|
||||
double calc;
|
||||
double p;
|
||||
@ -410,8 +412,8 @@ void ConvertHSVToRGB(float p_h, float p_s, float p_v, float* p_rOut, float* p_bO
|
||||
calc = (p_v + 1.0) * sDbl;
|
||||
}
|
||||
if (calc <= 0.0) {
|
||||
*p_gOut = 0.0f;
|
||||
*p_bOut = 0.0f;
|
||||
*p_gOut = 0.0f;
|
||||
*p_rOut = 0.0f;
|
||||
return;
|
||||
}
|
||||
@ -423,38 +425,38 @@ void ConvertHSVToRGB(float p_h, float p_s, float p_v, float* p_rOut, float* p_bO
|
||||
switch (hueIndex) {
|
||||
case 0:
|
||||
*p_rOut = calc;
|
||||
*p_bOut = v12;
|
||||
*p_gOut = p;
|
||||
*p_gOut = v12;
|
||||
*p_bOut = p;
|
||||
break;
|
||||
case 1:
|
||||
*p_rOut = v13;
|
||||
*p_bOut = calc;
|
||||
*p_gOut = p;
|
||||
*p_gOut = calc;
|
||||
*p_bOut = p;
|
||||
break;
|
||||
case 2:
|
||||
*p_rOut = p;
|
||||
*p_bOut = calc;
|
||||
*p_gOut = v12;
|
||||
*p_gOut = calc;
|
||||
*p_bOut = v12;
|
||||
break;
|
||||
case 3:
|
||||
*p_rOut = p;
|
||||
*p_bOut = v13;
|
||||
*p_gOut = calc;
|
||||
*p_gOut = v13;
|
||||
*p_bOut = calc;
|
||||
break;
|
||||
case 4:
|
||||
*p_rOut = v12;
|
||||
*p_bOut = p;
|
||||
*p_gOut = calc;
|
||||
*p_gOut = p;
|
||||
*p_bOut = calc;
|
||||
break;
|
||||
case 5:
|
||||
*p_rOut = calc;
|
||||
*p_bOut = p;
|
||||
*p_gOut = v13;
|
||||
*p_gOut = p;
|
||||
*p_bOut = v13;
|
||||
break;
|
||||
case 6:
|
||||
*p_rOut = calc;
|
||||
*p_bOut = p;
|
||||
*p_gOut = v13;
|
||||
*p_gOut = p;
|
||||
*p_bOut = v13;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
|
||||
@ -190,6 +190,7 @@ void LegoCameraController::TransformPointOfView(const Matrix4& p_transform, MxU3
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10012740
|
||||
// FUNCTION: BETA10 0x10069c35
|
||||
Mx3DPointFloat LegoCameraController::GetWorldUp()
|
||||
{
|
||||
if (m_lego3DView && m_lego3DView->GetPointOfView()) {
|
||||
@ -203,6 +204,7 @@ Mx3DPointFloat LegoCameraController::GetWorldUp()
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100127f0
|
||||
// FUNCTION: BETA10 0x10069cea
|
||||
Mx3DPointFloat LegoCameraController::GetWorldLocation()
|
||||
{
|
||||
if (m_lego3DView && m_lego3DView->GetPointOfView()) {
|
||||
@ -216,6 +218,7 @@ Mx3DPointFloat LegoCameraController::GetWorldLocation()
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100128a0
|
||||
// FUNCTION: BETA10 0x10069daa
|
||||
Mx3DPointFloat LegoCameraController::GetWorldDirection()
|
||||
{
|
||||
if (m_lego3DView && m_lego3DView->GetPointOfView()) {
|
||||
|
||||
@ -197,16 +197,18 @@ void LegoEntity::SetLocation(
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10010c30
|
||||
// FUNCTION: BETA10 0x1007ea5a
|
||||
void LegoEntity::TransformPointOfView()
|
||||
{
|
||||
LegoWorld* world = CurrentWorld();
|
||||
|
||||
if (m_cameraFlag && world && world->GetCameraController() && m_roi) {
|
||||
if (GetCameraFlag() && world && world->GetCameraController() && m_roi) {
|
||||
world->GetCameraController()->TransformPointOfView(m_roi->GetLocal2World(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10010c60
|
||||
// FUNCTION: BETA10 0x1007ead0
|
||||
Mx3DPointFloat LegoEntity::GetWorldDirection()
|
||||
{
|
||||
if (m_roi != NULL) {
|
||||
@ -218,6 +220,7 @@ Mx3DPointFloat LegoEntity::GetWorldDirection()
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10010cf0
|
||||
// FUNCTION: BETA10 0x1007eb47
|
||||
Mx3DPointFloat LegoEntity::GetWorldUp()
|
||||
{
|
||||
if (m_roi != NULL) {
|
||||
|
||||
@ -189,23 +189,31 @@ MxResult LegoPathActor::SetTransformAndDestinationFromPoints(
|
||||
assert(p_destEdge);
|
||||
|
||||
Vector3* v3 = p_destEdge->CWVertex(*p_boundary);
|
||||
// LINE: LEGO1 0x1002de35
|
||||
Vector3* v4 = p_destEdge->CCWVertex(*p_boundary);
|
||||
|
||||
assert(v3 && v4);
|
||||
|
||||
Mx3DPointFloat end, destNormal, endDirection;
|
||||
|
||||
// LINE: LEGO1 0x1002de8f
|
||||
end = *v4;
|
||||
end -= *v3;
|
||||
end *= p_destScale;
|
||||
// LINE: LEGO1 0x1002deae
|
||||
end += *v3;
|
||||
|
||||
// LINE: LEGO1 0x1002deba
|
||||
m_boundary = p_boundary;
|
||||
// LINE: LEGO1 0x1002dece
|
||||
m_destEdge = p_destEdge;
|
||||
// LINE: LEGO1 0x1002ded4
|
||||
m_destScale = p_destScale;
|
||||
m_traveledDistance = 0;
|
||||
m_transformTime = p_time;
|
||||
m_actorTime = p_time;
|
||||
// TODO: this one fails to inline
|
||||
// LINE: LEGO1 0x1002deed
|
||||
p_destEdge->GetFaceNormal(*p_boundary, destNormal);
|
||||
|
||||
MxMatrix matrix;
|
||||
@ -516,6 +524,95 @@ MxU32 LegoPathActor::CheckPresenterAndActorIntersections(
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef BETA10
|
||||
// FUNCTION: BETA10 0x100af35e
|
||||
MxS32 LegoPathActor::CheckIntersections(Vector3& p_rayOrigin, Vector3& p_rayEnd, Vector3& p_intersectionPoint)
|
||||
{
|
||||
assert(m_boundary && m_roi);
|
||||
|
||||
Mx3DPointFloat rayDirection(p_rayEnd);
|
||||
rayDirection -= p_rayOrigin;
|
||||
|
||||
float len = rayDirection.LenSquared();
|
||||
|
||||
if (len <= 0.001) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = sqrt((double) len);
|
||||
rayDirection /= len;
|
||||
|
||||
float radius = m_roi->GetWorldBoundingSphere().Radius();
|
||||
LegoPathBoundary* b = m_boundary;
|
||||
LegoOrientedEdge* local14 = *m_boundary->GetEdges();
|
||||
LegoOrientedEdge* local18 = NULL;
|
||||
|
||||
while (1) {
|
||||
assert(b);
|
||||
|
||||
MxU32 result =
|
||||
CheckPresenterAndActorIntersections(b, p_rayOrigin, rayDirection, len, radius, p_intersectionPoint);
|
||||
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (local18 == NULL) {
|
||||
local18 = (LegoOrientedEdge*) local14->GetCounterclockwiseEdge(*m_boundary);
|
||||
b = (LegoPathBoundary*) local14->OtherFace(m_boundary);
|
||||
}
|
||||
else {
|
||||
b = NULL;
|
||||
}
|
||||
|
||||
while (!b) {
|
||||
if (local18 == local14) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
b = (LegoPathBoundary*) local18->OtherFace(m_boundary);
|
||||
local18 = (LegoOrientedEdge*) local18->GetCounterclockwiseEdge(*m_boundary);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
// FUNCTION: LEGO1 0x1002ebe0
|
||||
MxS32 LegoPathActor::CheckIntersections(Vector3& p_rayOrigin, Vector3& p_rayEnd, Vector3& p_intersectionPoint)
|
||||
{
|
||||
assert(m_boundary && m_roi);
|
||||
|
||||
Mx3DPointFloat rayDirection(p_rayEnd);
|
||||
rayDirection -= p_rayOrigin;
|
||||
|
||||
float len = rayDirection.LenSquared();
|
||||
|
||||
if (len <= 0.001) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = sqrt((double) len);
|
||||
rayDirection /= len;
|
||||
|
||||
float radius = m_roi->GetWorldBoundingSphere().Radius();
|
||||
list<LegoPathBoundary*> boundaries;
|
||||
// This function is inlined once. The recursion calls into the actual function.
|
||||
// Matching `CheckIntersectionBothFaces` will likely match `CheckIntersections` as well.
|
||||
return CheckIntersectionBothFaces(
|
||||
boundaries,
|
||||
m_boundary,
|
||||
p_rayOrigin,
|
||||
rayDirection,
|
||||
len,
|
||||
radius,
|
||||
p_intersectionPoint,
|
||||
0
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
// FUNCTION: LEGO1 0x1002edd0
|
||||
inline MxU32 LegoPathActor::CheckIntersectionBothFaces(
|
||||
list<LegoPathBoundary*>& p_checkedBoundaries,
|
||||
LegoPathBoundary* p_boundary,
|
||||
@ -549,17 +646,22 @@ inline MxU32 LegoPathActor::CheckIntersectionBothFaces(
|
||||
LegoS32 numEdges = p_boundary->GetNumEdges();
|
||||
for (MxS32 i = 0; i < numEdges; i++) {
|
||||
LegoOrientedEdge* edge = p_boundary->GetEdges()[i];
|
||||
// LINE: LEGO1 0x1002ee8c
|
||||
LegoPathBoundary* boundary = (LegoPathBoundary*) edge->OtherFace(p_boundary);
|
||||
|
||||
// LINE: LEGO1 0x1002ee9f
|
||||
if (boundary != NULL) {
|
||||
list<LegoPathBoundary*>::const_iterator it;
|
||||
|
||||
// LINE: LEGO1 0x1002eead
|
||||
for (it = p_checkedBoundaries.begin(); !(it == p_checkedBoundaries.end()); it++) {
|
||||
// LINE: LEGO1 0x1002eeb3
|
||||
if ((*it) == boundary) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// LINE: LEGO1 0x1002eec4
|
||||
if (it == p_checkedBoundaries.end()) {
|
||||
result = CheckIntersectionBothFaces(
|
||||
p_checkedBoundaries,
|
||||
@ -582,39 +684,6 @@ inline MxU32 LegoPathActor::CheckIntersectionBothFaces(
|
||||
return 0;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1002ebe0
|
||||
// FUNCTION: BETA10 0x100af35e
|
||||
MxS32 LegoPathActor::CheckIntersections(Vector3& p_rayOrigin, Vector3& p_rayEnd, Vector3& p_intersectionPoint)
|
||||
{
|
||||
assert(m_boundary && m_roi);
|
||||
|
||||
Mx3DPointFloat rayDirection(p_rayEnd);
|
||||
rayDirection -= p_rayOrigin;
|
||||
|
||||
float len = rayDirection.LenSquared();
|
||||
|
||||
if (len <= 0.001) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = sqrt((double) len);
|
||||
rayDirection /= len;
|
||||
|
||||
float radius = m_roi->GetWorldBoundingSphere().Radius();
|
||||
list<LegoPathBoundary*> boundaries;
|
||||
|
||||
return CheckIntersectionBothFaces(
|
||||
boundaries,
|
||||
m_boundary,
|
||||
p_rayOrigin,
|
||||
rayDirection,
|
||||
len,
|
||||
radius,
|
||||
p_intersectionPoint,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1002f020
|
||||
// FUNCTION: BETA10 0x100af54a
|
||||
void LegoPathActor::ParseAction(char* p_extra)
|
||||
|
||||
@ -19,24 +19,24 @@ DECOMP_SIZE_ASSERT(LegoPathStruct, 0x14)
|
||||
extern MxU32 g_isleFlags;
|
||||
|
||||
// GLOBAL: LEGO1 0x100f119c
|
||||
MxBool g_unk0x100f119c = FALSE;
|
||||
MxBool g_triggerHandlingIgnoreDirection = FALSE;
|
||||
|
||||
// FUNCTION: LEGO1 0x1001b700
|
||||
void LegoPathStruct::HandleTrigger(LegoPathActor* p_actor, MxBool p_direction, MxU32 p_data)
|
||||
{
|
||||
if (!HandleTrigger(p_actor, p_direction, p_data, FALSE) && g_unk0x100f119c) {
|
||||
if (!HandleTrigger(p_actor, p_direction, p_data, FALSE) && g_triggerHandlingIgnoreDirection) {
|
||||
HandleTrigger(p_actor, p_direction, p_data, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1001b740
|
||||
// FUNCTION: BETA10 0x100c26c5
|
||||
MxBool LegoPathStruct::HandleTrigger(LegoPathActor* p_actor, MxBool p_direction, MxU32 p_data, MxBool p_bool)
|
||||
MxBool LegoPathStruct::HandleTrigger(LegoPathActor* p_actor, MxBool p_direction, MxU32 p_data, MxBool p_invertDirection)
|
||||
{
|
||||
MxBool triggered = FALSE;
|
||||
MxBool bool2 = p_bool ? !p_direction : p_direction;
|
||||
MxBool actualDirection = p_invertDirection ? !p_direction : p_direction;
|
||||
|
||||
MxU32 flags = bool2 ? c_bit5 : c_bit6;
|
||||
MxU32 flags = actualDirection ? c_bit5 : c_bit6;
|
||||
flags |= p_actor->GetCameraFlag() ? c_bit1 : (c_bit2 | c_bit3 | c_bit4);
|
||||
|
||||
if ((m_flags & flags & (c_bit5 | c_bit6 | c_bit7)) && (m_flags & flags & (c_bit1 | c_bit2 | c_bit3 | c_bit4))) {
|
||||
@ -45,10 +45,10 @@ MxBool LegoPathStruct::HandleTrigger(LegoPathActor* p_actor, MxBool p_direction,
|
||||
switch (m_name[2]) {
|
||||
case c_camAnim:
|
||||
if (g_isleFlags & Isle::c_playCamAnims) {
|
||||
PlayCamAnim(p_actor, bool2, p_data, TRUE);
|
||||
PlayCamAnim(p_actor, actualDirection, p_data, TRUE);
|
||||
}
|
||||
break;
|
||||
case c_d: {
|
||||
case c_waypoint: {
|
||||
p_actor->SetLastPathStruct(p_data);
|
||||
|
||||
LegoPathStructNotificationParam param(c_notificationPathStruct, p_actor, m_name[2], p_data);
|
||||
@ -60,12 +60,12 @@ MxBool LegoPathStruct::HandleTrigger(LegoPathActor* p_actor, MxBool p_direction,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case c_e:
|
||||
FUN_1001bc40(m_name, p_data, !(p_bool == FALSE));
|
||||
case c_deleteAction:
|
||||
HandleAction(m_name, p_data, !(p_invertDirection == FALSE));
|
||||
break;
|
||||
case c_g:
|
||||
case c_nothing:
|
||||
break;
|
||||
case c_h: {
|
||||
case c_hideAnim: {
|
||||
LegoHideAnimPresenter* presenter = m_world->GetHideAnimPresenter();
|
||||
if (presenter != NULL) {
|
||||
presenter->ApplyVisibility(p_data * 100);
|
||||
@ -77,7 +77,7 @@ MxBool LegoPathStruct::HandleTrigger(LegoPathActor* p_actor, MxBool p_direction,
|
||||
PlayMusic(p_direction, p_data);
|
||||
}
|
||||
break;
|
||||
case c_s: {
|
||||
case c_specialMissionWaypointAndAction: {
|
||||
LegoWorld* world = CurrentWorld();
|
||||
if (world != NULL) {
|
||||
LegoPathStructNotificationParam param(c_notificationPathStruct, p_actor, m_name[2], p_data);
|
||||
@ -87,10 +87,10 @@ MxBool LegoPathStruct::HandleTrigger(LegoPathActor* p_actor, MxBool p_direction,
|
||||
}
|
||||
}
|
||||
|
||||
FUN_1001bc40(m_name, p_data, p_bool == FALSE);
|
||||
HandleAction(m_name, p_data, p_invertDirection == FALSE);
|
||||
break;
|
||||
}
|
||||
case c_w: {
|
||||
case c_missionFinalWaypoint: {
|
||||
LegoWorld* world = CurrentWorld();
|
||||
if (world != NULL) {
|
||||
LegoPathStructNotificationParam param(c_notificationPathStruct, p_actor, m_name[2], p_data);
|
||||
@ -106,13 +106,13 @@ MxBool LegoPathStruct::HandleTrigger(LegoPathActor* p_actor, MxBool p_direction,
|
||||
|
||||
// FUNCTION: LEGO1 0x1001bc40
|
||||
// FUNCTION: BETA10 0x100c2a6c
|
||||
void LegoPathStruct::FUN_1001bc40(const char* p_name, MxU32 p_data, MxBool p_bool)
|
||||
void LegoPathStruct::HandleAction(const char* p_name, MxU32 p_data, MxBool p_start)
|
||||
{
|
||||
MxDSAction action;
|
||||
action.SetObjectId(p_data);
|
||||
action.SetAtomId(m_atomId);
|
||||
|
||||
if (p_bool) {
|
||||
if (p_start) {
|
||||
action.SetUnknown24(-1);
|
||||
Start(&action);
|
||||
}
|
||||
|
||||
@ -191,7 +191,7 @@ MxLong CarRace::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
||||
{
|
||||
MxLong result = 0;
|
||||
|
||||
if (p_param.GetTrigger() == LegoPathStruct::c_d) {
|
||||
if (p_param.GetTrigger() == LegoPathStruct::c_waypoint) {
|
||||
MxEntity* sender = (MxEntity*) p_param.GetSender();
|
||||
MxS32 paramData = p_param.GetData();
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
// Defined in legopathstruct.cpp
|
||||
extern MxBool g_unk0x100f119c;
|
||||
extern MxBool g_triggerHandlingIgnoreDirection;
|
||||
|
||||
// Defined in jetski.cpp
|
||||
extern const char* g_varJSFRNTY5;
|
||||
@ -72,7 +72,7 @@ MxResult JetskiRace::Create(MxDSAction& p_dsAction)
|
||||
InvokeAction(Extra::e_start, m_atomId, raceCarDashboardStreamId, NULL);
|
||||
InvokeAction(Extra::e_start, m_atomId, JetraceScript::c_JetskiDashboard, NULL);
|
||||
|
||||
g_unk0x100f119c = TRUE;
|
||||
g_triggerHandlingIgnoreDirection = TRUE;
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -160,7 +160,7 @@ MxLong JetskiRace::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
||||
MxLong result = 0;
|
||||
MxEntity* sender = (MxEntity*) p_param.GetSender();
|
||||
|
||||
if (p_param.GetTrigger() == LegoPathStruct::c_d) {
|
||||
if (p_param.GetTrigger() == LegoPathStruct::c_waypoint) {
|
||||
MxS32 paramData = p_param.GetData();
|
||||
|
||||
switch (sender->GetEntityId()) {
|
||||
|
||||
@ -12,7 +12,7 @@ DECOMP_SIZE_ASSERT(RaceState::Entry, 0x06)
|
||||
DECOMP_SIZE_ASSERT(RaceState, 0x2c)
|
||||
|
||||
// Defined in legopathstruct.cpp
|
||||
extern MxBool g_unk0x100f119c;
|
||||
extern MxBool g_triggerHandlingIgnoreDirection;
|
||||
|
||||
// FUNCTION: LEGO1 0x10015aa0
|
||||
LegoRace::LegoRace()
|
||||
@ -56,7 +56,7 @@ MxResult LegoRace::Create(MxDSAction& p_dsAction)
|
||||
// FUNCTION: BETA10 0x100c7ab5
|
||||
LegoRace::~LegoRace()
|
||||
{
|
||||
g_unk0x100f119c = FALSE;
|
||||
g_triggerHandlingIgnoreDirection = FALSE;
|
||||
if (m_pathActor) {
|
||||
SetUserActor(m_pathActor);
|
||||
NavController()->ResetMaxLinearVel(m_pathActor->GetMaxLinearVel());
|
||||
|
||||
@ -418,7 +418,7 @@ void LegoRaceCar::Animate(float p_time)
|
||||
UpdateMapLocatorPosition();
|
||||
|
||||
if (!m_userNavFlag) {
|
||||
FUN_10080590(p_time);
|
||||
UpdateWorldSpeed(p_time);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -620,7 +620,7 @@ void LegoJetski::Animate(float p_time)
|
||||
UpdateMapLocatorPosition();
|
||||
|
||||
if (!m_userNavFlag) {
|
||||
FUN_10080590(p_time);
|
||||
UpdateWorldSpeed(p_time);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -33,11 +33,11 @@ const char* g_fuel = "FUEL";
|
||||
const char* g_racing = "RACING";
|
||||
|
||||
// GLOBAL: LEGO1 0x100f7aec
|
||||
MxFloat LegoCarRaceActor::g_unk0x100f7aec = 8.0f;
|
||||
MxFloat LegoCarRaceActor::g_maxSpeed = 8.0f;
|
||||
|
||||
// GLOBAL: LEGO1 0x100da044
|
||||
// GLOBAL: BETA10 0x101be9fc
|
||||
MxFloat g_unk0x100da044 = 8.0f;
|
||||
MxFloat g_maxWorldSpeed = 8.0f;
|
||||
|
||||
// FUNCTION: LEGO1 0x10080350
|
||||
// FUNCTION: BETA10 0x100cd6b0
|
||||
@ -48,10 +48,10 @@ LegoCarRaceActor::LegoCarRaceActor()
|
||||
m_animState = 0;
|
||||
m_maxLinearVel = 0.0f;
|
||||
m_frequencyFactor = 1.0f;
|
||||
m_unk0x1c = 0;
|
||||
m_unk0x10 = 0.65f;
|
||||
m_unk0x14 = 0.03f;
|
||||
m_unk0x18 = 0.6f;
|
||||
m_lastAcceleration = 0;
|
||||
m_curveSpeedFactor = 0.65f;
|
||||
m_acceleration = 0.03f;
|
||||
m_rubberBandFactor = 0.6f;
|
||||
m_wallHitDirectionFactor = 0.1f;
|
||||
m_linearRotationRatio = -5.0f;
|
||||
m_canRotate = 1;
|
||||
@ -60,43 +60,43 @@ LegoCarRaceActor::LegoCarRaceActor()
|
||||
|
||||
// FUNCTION: LEGO1 0x10080590
|
||||
// FUNCTION: BETA10 0x100cd8cf
|
||||
void LegoCarRaceActor::FUN_10080590(float p_time)
|
||||
void LegoCarRaceActor::UpdateWorldSpeed(float p_time)
|
||||
{
|
||||
MxFloat maxSpeed = m_maxLinearVel;
|
||||
Mx3DPointFloat destEdgeUnknownVector;
|
||||
Mx3DPointFloat edgeNormal;
|
||||
Mx3DPointFloat worldDirection = Mx3DPointFloat(m_roi->GetWorldDirection());
|
||||
|
||||
m_destEdge->GetFaceNormal(*m_boundary, destEdgeUnknownVector);
|
||||
m_destEdge->GetFaceNormal(*m_boundary, edgeNormal);
|
||||
|
||||
if (abs(destEdgeUnknownVector.Dot(destEdgeUnknownVector.GetData(), worldDirection.GetData())) > 0.5) {
|
||||
maxSpeed *= m_unk0x10;
|
||||
if (abs(edgeNormal.Dot(edgeNormal.GetData(), worldDirection.GetData())) > 0.5) {
|
||||
maxSpeed *= m_curveSpeedFactor;
|
||||
}
|
||||
|
||||
MxS32 deltaUnk0x70;
|
||||
MxS32 deltaPathStructs;
|
||||
LegoPathActor* userActor = UserActor();
|
||||
|
||||
if (userActor) {
|
||||
// All known implementations of LegoPathActor->GetLastPathStruct() return LegoPathActor::m_lastPathStruct
|
||||
deltaUnk0x70 = m_lastPathStruct - userActor->GetLastPathStruct();
|
||||
deltaPathStructs = m_lastPathStruct - userActor->GetLastPathStruct();
|
||||
}
|
||||
else {
|
||||
deltaUnk0x70 = 0;
|
||||
deltaPathStructs = 0;
|
||||
}
|
||||
|
||||
if (deltaUnk0x70 > 1) {
|
||||
if (deltaUnk0x70 > 3) {
|
||||
deltaUnk0x70 = 3;
|
||||
if (deltaPathStructs > 1) {
|
||||
if (deltaPathStructs > 3) {
|
||||
deltaPathStructs = 3;
|
||||
}
|
||||
|
||||
maxSpeed *= (m_unk0x18 * (--deltaUnk0x70) * -0.25f + 1.0f);
|
||||
maxSpeed *= (m_rubberBandFactor * (--deltaPathStructs) * -0.25f + 1.0f);
|
||||
}
|
||||
else if (deltaUnk0x70 < -1) {
|
||||
else if (deltaPathStructs < -1) {
|
||||
maxSpeed *= 1.3;
|
||||
}
|
||||
|
||||
MxFloat deltaSpeed = maxSpeed - m_worldSpeed;
|
||||
MxFloat changeInSpeed = (p_time - m_unk0x1c) * m_unk0x14;
|
||||
m_unk0x1c = p_time;
|
||||
MxFloat changeInSpeed = (p_time - m_lastAcceleration) * m_acceleration;
|
||||
m_lastAcceleration = p_time;
|
||||
|
||||
if (deltaSpeed < 0.0f) {
|
||||
changeInSpeed = -changeInSpeed;
|
||||
@ -113,16 +113,17 @@ void LegoCarRaceActor::FUN_10080590(float p_time)
|
||||
|
||||
// FUNCTION: LEGO1 0x10080740
|
||||
// FUNCTION: BETA10 0x100cece0
|
||||
MxS32 LegoCarRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edge)
|
||||
MxS32 LegoCarRaceActor::HandleJump(LegoPathBoundary* p_boundary, LegoEdge* p_edge)
|
||||
{
|
||||
Mx3DPointFloat pointUnknown;
|
||||
Mx3DPointFloat targetPosition;
|
||||
Mx3DPointFloat destEdgeUnknownVector;
|
||||
Mx3DPointFloat crossProduct;
|
||||
Mx3DPointFloat targetDirection;
|
||||
|
||||
if (m_actorState == c_ready) {
|
||||
m_boundary = NULL;
|
||||
|
||||
// Not sure where the upper bound of 11 comes from, the underlying array has a size of 16
|
||||
// The first 12 elements are used for the car race, the other 4 for jetski
|
||||
// As it increments by 2, counting to 10 or 11 is the same.
|
||||
for (MxS32 i = 0; i < 11; i += 2) {
|
||||
if (LegoPathController::GetControlEdgeA(i + 1) == m_destEdge) {
|
||||
m_boundary = LegoPathController::GetControlBoundaryA(i + 1);
|
||||
@ -148,8 +149,8 @@ MxS32 LegoCarRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edg
|
||||
if (LegoPathController::GetControlEdgeA(i) == p_edge) {
|
||||
m_actorState = c_ready;
|
||||
|
||||
if (m_worldSpeed < g_unk0x100f7aec) {
|
||||
m_worldSpeed = g_unk0x100f7aec;
|
||||
if (m_worldSpeed < g_maxSpeed) {
|
||||
m_worldSpeed = g_maxSpeed;
|
||||
}
|
||||
|
||||
m_destEdge = LegoPathController::GetControlEdgeA(i + 1);
|
||||
@ -168,12 +169,12 @@ MxS32 LegoCarRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edg
|
||||
Vector3* v2 = m_destEdge->CWVertex(*m_boundary);
|
||||
assert(v1 && v2);
|
||||
|
||||
LERP3(pointUnknown, *v1, *v2, m_destScale);
|
||||
LERP3(targetPosition, *v1, *v2, m_destScale);
|
||||
|
||||
m_destEdge->GetFaceNormal(*m_boundary, destEdgeUnknownVector);
|
||||
|
||||
crossProduct.EqualsCross(*m_boundary->GetUp(), destEdgeUnknownVector);
|
||||
crossProduct.Unitize();
|
||||
targetDirection.EqualsCross(*m_boundary->GetUp(), destEdgeUnknownVector);
|
||||
targetDirection.Unitize();
|
||||
|
||||
Mx3DPointFloat worldDirection(Vector3(m_roi->GetWorldDirection()));
|
||||
|
||||
@ -182,10 +183,10 @@ MxS32 LegoCarRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edg
|
||||
}
|
||||
|
||||
worldDirection *= 5.0f;
|
||||
crossProduct *= 5.0f;
|
||||
targetDirection *= 5.0f;
|
||||
|
||||
MxResult callResult =
|
||||
SetSpline(Vector3(m_roi->GetWorldPosition()), worldDirection, pointUnknown, crossProduct);
|
||||
SetSpline(Vector3(m_roi->GetWorldPosition()), worldDirection, targetPosition, targetDirection);
|
||||
|
||||
if (callResult) {
|
||||
m_traveledDistance = 0;
|
||||
@ -231,7 +232,7 @@ void LegoCarRaceActor::Animate(float p_time)
|
||||
if (SDL_strcasecmp(value, g_racing) == 0) {
|
||||
m_animState = 1;
|
||||
m_transformTime = p_time - 1.0f;
|
||||
m_unk0x1c = p_time;
|
||||
m_lastAcceleration = p_time;
|
||||
}
|
||||
}
|
||||
|
||||
@ -246,7 +247,7 @@ MxResult LegoCarRaceActor::CalculateSpline()
|
||||
{
|
||||
LegoOrientedEdge* d = m_destEdge;
|
||||
|
||||
if (VTable0x1c(m_boundary, m_destEdge)) {
|
||||
if (HandleJump(m_boundary, m_destEdge)) {
|
||||
LegoPathBoundary* b = m_boundary;
|
||||
|
||||
SwitchBoundary(m_boundary, m_destEdge, m_destScale);
|
||||
@ -257,27 +258,27 @@ MxResult LegoCarRaceActor::CalculateSpline()
|
||||
Vector3* v2 = m_destEdge->CCWVertex(*m_boundary);
|
||||
assert(v1 && v2);
|
||||
|
||||
Mx3DPointFloat point1;
|
||||
LERP3(point1, *v1, *v2, m_destScale);
|
||||
Mx3DPointFloat end;
|
||||
LERP3(end, *v1, *v2, m_destScale);
|
||||
|
||||
Mx3DPointFloat point2;
|
||||
Mx3DPointFloat point3;
|
||||
Mx3DPointFloat point4;
|
||||
Mx3DPointFloat point5;
|
||||
Mx3DPointFloat startEdgeNormal;
|
||||
Mx3DPointFloat endEdgeNormal;
|
||||
Mx3DPointFloat startDirection;
|
||||
Mx3DPointFloat endDirection;
|
||||
|
||||
d->GetFaceNormal(*b, point2);
|
||||
m_destEdge->GetFaceNormal(*m_boundary, point3);
|
||||
d->GetFaceNormal(*b, startEdgeNormal);
|
||||
m_destEdge->GetFaceNormal(*m_boundary, endEdgeNormal);
|
||||
|
||||
point4.EqualsCross(point2, *m_boundary->GetUp());
|
||||
point5.EqualsCross(*m_boundary->GetUp(), point3);
|
||||
startDirection.EqualsCross(startEdgeNormal, *m_boundary->GetUp());
|
||||
endDirection.EqualsCross(*m_boundary->GetUp(), endEdgeNormal);
|
||||
|
||||
point4.Unitize();
|
||||
point5.Unitize();
|
||||
startDirection.Unitize();
|
||||
endDirection.Unitize();
|
||||
|
||||
point4 *= 5.0f;
|
||||
point5 *= 5.0f;
|
||||
startDirection *= 5.0f;
|
||||
endDirection *= 5.0f;
|
||||
|
||||
MxResult res = SetSpline(m_roi->GetWorldPosition(), point4, point1, point5);
|
||||
MxResult res = SetSpline(m_roi->GetWorldPosition(), startDirection, end, endDirection);
|
||||
|
||||
#ifdef BETA10
|
||||
if (res) {
|
||||
@ -296,15 +297,15 @@ MxResult LegoCarRaceActor::CalculateSpline()
|
||||
// FUNCTION: BETA10 0x100a8990
|
||||
LegoJetskiRaceActor::LegoJetskiRaceActor()
|
||||
{
|
||||
m_unk0x10 = 0.95f;
|
||||
m_unk0x14 = 0.04f;
|
||||
m_unk0x18 = 0.5f;
|
||||
m_curveSpeedFactor = 0.95f;
|
||||
m_acceleration = 0.04f;
|
||||
m_rubberBandFactor = 0.5f;
|
||||
m_linearRotationRatio = 1.5f;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10081120
|
||||
// FUNCTION: BETA10 0x100ce19f
|
||||
MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edge)
|
||||
MxS32 LegoJetskiRaceActor::HandleJump(LegoPathBoundary* p_boundary, LegoEdge* p_edge)
|
||||
{
|
||||
// These are almost certainly not the correct names, but they produce the correct BETA10 stack
|
||||
Mx3DPointFloat a;
|
||||
@ -338,8 +339,8 @@ MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_
|
||||
if (p_edge == LegoPathController::GetControlEdgeA(12)) {
|
||||
m_actorState = c_ready;
|
||||
|
||||
if (m_worldSpeed < g_unk0x100da044) {
|
||||
m_worldSpeed = g_unk0x100da044;
|
||||
if (m_worldSpeed < g_maxWorldSpeed) {
|
||||
m_worldSpeed = g_maxWorldSpeed;
|
||||
}
|
||||
|
||||
m_destEdge = LegoPathController::GetControlEdgeA(13);
|
||||
@ -348,8 +349,8 @@ MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_
|
||||
else if (p_edge == LegoPathController::GetControlEdgeA(14)) {
|
||||
m_actorState = c_ready;
|
||||
|
||||
if (m_worldSpeed < g_unk0x100da044) {
|
||||
m_worldSpeed = g_unk0x100da044;
|
||||
if (m_worldSpeed < g_maxWorldSpeed) {
|
||||
m_worldSpeed = g_maxWorldSpeed;
|
||||
}
|
||||
|
||||
m_destEdge = LegoPathController::GetControlEdgeA(15);
|
||||
@ -404,7 +405,7 @@ void LegoJetskiRaceActor::Animate(float p_time)
|
||||
if (!SDL_strcasecmp(raceState, g_racing)) {
|
||||
m_animState = 1;
|
||||
m_transformTime = p_time - 1.0f;
|
||||
m_unk0x1c = p_time;
|
||||
m_lastAcceleration = p_time;
|
||||
}
|
||||
else if (!m_userNavFlag) {
|
||||
LegoAnimActor::Animate(m_transformTime + 1.0f);
|
||||
|
||||
@ -103,10 +103,10 @@ Act3Script::Script g_bricksterDonutSounds[] = {
|
||||
};
|
||||
|
||||
// GLOBAL: LEGO1 0x100f7814
|
||||
MxU8 g_unk0x100f7814 = 0;
|
||||
MxU8 g_copSelector = 0;
|
||||
|
||||
// GLOBAL: LEGO1 0x100d95e8
|
||||
Act3Script::Script g_unk0x100d95e8[] =
|
||||
Act3Script::Script g_explanationAnimations[] =
|
||||
{Act3Script::c_tlp053in_RunAnim, Act3Script::c_tlp064la_RunAnim, Act3Script::c_tlp068in_RunAnim};
|
||||
|
||||
// FUNCTION: LEGO1 0x10071d40
|
||||
@ -247,7 +247,7 @@ Act3::Act3()
|
||||
m_copter = NULL;
|
||||
m_shark = NULL;
|
||||
m_time = -1;
|
||||
m_unk0x421e = 0;
|
||||
m_helicopterDotCount = 0;
|
||||
|
||||
memset(m_helicopterDots, 0, sizeof(m_helicopterDots));
|
||||
|
||||
@ -327,7 +327,7 @@ MxResult Act3::ShootPizza(LegoPathController* p_controller, Vector3& p_location,
|
||||
for (nextPizza = 0; nextPizza < (MxS32) sizeOfArray(m_pizzas); nextPizza++) {
|
||||
if (!m_pizzas[nextPizza].IsValid()) {
|
||||
LegoPathBoundary* boundary = NULL;
|
||||
MxU32 local18 = TRUE;
|
||||
MxU32 noBoundaryIntersected = TRUE;
|
||||
|
||||
m_pizzas[nextPizza].Create(this, TRUE, nextPizza);
|
||||
|
||||
@ -335,26 +335,26 @@ MxResult Act3::ShootPizza(LegoPathController* p_controller, Vector3& p_location,
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
MxFloat unk0x19c = *m_pizzas[nextPizza].GetApexParameter();
|
||||
MxFloat apexParameter = *m_pizzas[nextPizza].GetApexParameter();
|
||||
if (p_controller->FindIntersectionBoundary(
|
||||
p_location,
|
||||
p_direction,
|
||||
m_pizzas[nextPizza].GetCoefficients(),
|
||||
boundary,
|
||||
unk0x19c
|
||||
apexParameter
|
||||
) == SUCCESS) {
|
||||
Mx3DPointFloat direction;
|
||||
|
||||
direction = p_direction;
|
||||
direction *= unk0x19c;
|
||||
direction *= apexParameter;
|
||||
direction += p_location;
|
||||
|
||||
assert(m_brickster && m_brickster->GetROI());
|
||||
|
||||
direction -= m_brickster->GetROI()->GetLocal2World()[3];
|
||||
|
||||
local18 = FALSE;
|
||||
if (m_pizzas[nextPizza].Shoot(p_controller, boundary, unk0x19c) == SUCCESS) {
|
||||
noBoundaryIntersected = FALSE;
|
||||
if (m_pizzas[nextPizza].Shoot(p_controller, boundary, apexParameter) == SUCCESS) {
|
||||
p_controller->PlaceActor(&m_pizzas[nextPizza]);
|
||||
boundary->AddActor(&m_pizzas[nextPizza]);
|
||||
m_pizzas[nextPizza].SetWorldSpeed(10.0f);
|
||||
@ -362,7 +362,7 @@ MxResult Act3::ShootPizza(LegoPathController* p_controller, Vector3& p_location,
|
||||
}
|
||||
}
|
||||
|
||||
if (local18 && m_pizzas[nextPizza].Shoot(p_controller, unk0x19c) == SUCCESS) {
|
||||
if (noBoundaryIntersected && m_pizzas[nextPizza].Shoot(p_controller, apexParameter) == SUCCESS) {
|
||||
p_controller->PlaceActor(&m_pizzas[nextPizza]);
|
||||
m_pizzas[nextPizza].SetWorldSpeed(10.0f);
|
||||
return SUCCESS;
|
||||
@ -390,22 +390,22 @@ MxResult Act3::ShootDonut(LegoPathController* p_controller, Vector3& p_location,
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
MxFloat unk0x19c = *m_donuts[nextDonut].GetApexParameter();
|
||||
MxFloat apexParameter = *m_donuts[nextDonut].GetApexParameter();
|
||||
if (p_controller->FindIntersectionBoundary(
|
||||
p_location,
|
||||
p_direction,
|
||||
m_donuts[nextDonut].GetCoefficients(),
|
||||
boundary,
|
||||
unk0x19c
|
||||
apexParameter
|
||||
) == SUCCESS) {
|
||||
if (m_donuts[nextDonut].Shoot(p_controller, boundary, unk0x19c) == SUCCESS) {
|
||||
if (m_donuts[nextDonut].Shoot(p_controller, boundary, apexParameter) == SUCCESS) {
|
||||
p_controller->PlaceActor(&m_donuts[nextDonut]);
|
||||
boundary->AddActor(&m_donuts[nextDonut]);
|
||||
m_donuts[nextDonut].SetWorldSpeed(10.0f);
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
else if (m_donuts[nextDonut].Shoot(p_controller, unk0x19c) == SUCCESS) {
|
||||
else if (m_donuts[nextDonut].Shoot(p_controller, apexParameter) == SUCCESS) {
|
||||
p_controller->PlaceActor(&m_donuts[nextDonut]);
|
||||
m_donuts[nextDonut].SetWorldSpeed(10.0f);
|
||||
return SUCCESS;
|
||||
@ -469,14 +469,14 @@ void Act3::TriggerHitSound(undefined4 p_param1)
|
||||
m_bricksterDonutSound = 0;
|
||||
}
|
||||
|
||||
m_unk0x4220.Insert(g_bricksterDonutSounds[m_bricksterDonutSound++], Act3ListElement::e_replaceAction);
|
||||
m_soundList.Insert(g_bricksterDonutSounds[m_bricksterDonutSound++], Act3ListElement::e_replaceAction);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
m_unk0x4220.Insert(objectId, Act3ListElement::e_onlyIfEmpty);
|
||||
m_soundList.Insert(objectId, Act3ListElement::e_onlyIfEmpty);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10072c30
|
||||
@ -599,24 +599,24 @@ MxLong Act3::Notify(MxParam& p_param)
|
||||
|
||||
MxS32 length;
|
||||
LegoBuildingInfo* info = BuildingManager()->GetInfoArray(length);
|
||||
m_unk0x421e = 0;
|
||||
m_helicopterDotCount = 0;
|
||||
|
||||
while (--length >= 0) {
|
||||
if (info[length].m_counter < 0 && info[length].m_boundary != NULL &&
|
||||
info[length].m_entity != NULL) {
|
||||
m_unk0x421e++;
|
||||
m_helicopterDotCount++;
|
||||
}
|
||||
}
|
||||
|
||||
length = 0;
|
||||
m_unk0x421e--;
|
||||
m_helicopterDotCount--;
|
||||
char buf[80];
|
||||
|
||||
do {
|
||||
sprintf(buf, "HelicopterDotOn%d_Bitmap", length + 1);
|
||||
m_helicopterDots[length] = (MxPresenter*) Find("MxPresenter", buf);
|
||||
|
||||
if (m_unk0x421e > length) {
|
||||
if (m_helicopterDotCount > length) {
|
||||
m_helicopterDots[length]->Enable(TRUE);
|
||||
}
|
||||
else {
|
||||
@ -627,7 +627,7 @@ MxLong Act3::Notify(MxParam& p_param)
|
||||
} while (length < (MxS32) sizeOfArray(m_helicopterDots));
|
||||
}
|
||||
else {
|
||||
m_unk0x4220.RemoveByObjectIdOrFirst(param.GetAction()->GetObjectId());
|
||||
m_soundList.RemoveByObjectIdOrFirst(param.GetAction()->GetObjectId());
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -647,7 +647,7 @@ MxLong Act3::Notify(MxParam& p_param)
|
||||
case c_notificationEndAnim:
|
||||
if (m_state->m_state == Act3State::e_ready) {
|
||||
assert(m_copter && m_brickster && m_cop1 && m_cop2);
|
||||
m_unk0x4220.RemoveByObjectIdOrFirst(0);
|
||||
m_soundList.RemoveByObjectIdOrFirst(0);
|
||||
m_state->m_state = Act3State::e_initial;
|
||||
Disable(TRUE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen);
|
||||
m_copter->HandleClick();
|
||||
@ -683,9 +683,18 @@ void Act3::ReadyWorld()
|
||||
AnimationManager()->FUN_1005f6d0(FALSE);
|
||||
VideoManager()->Get3DManager()->SetFrustrum(90.0f, 0.1f, 125.0f);
|
||||
|
||||
m_unk0x426c = g_unk0x100d95e8[SDL_rand(3)];
|
||||
AnimationManager()
|
||||
->FUN_10060dc0(m_unk0x426c, NULL, TRUE, LegoAnimationManager::e_unk0, NULL, TRUE, FALSE, FALSE, FALSE);
|
||||
m_explanationAnimation = g_explanationAnimations[SDL_rand(3)];
|
||||
AnimationManager()->FUN_10060dc0(
|
||||
m_explanationAnimation,
|
||||
NULL,
|
||||
TRUE,
|
||||
LegoAnimationManager::e_unk0,
|
||||
NULL,
|
||||
TRUE,
|
||||
FALSE,
|
||||
FALSE,
|
||||
FALSE
|
||||
);
|
||||
|
||||
m_state->m_state = Act3State::e_ready;
|
||||
}
|
||||
@ -698,11 +707,11 @@ MxResult Act3::Tickle()
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
if (m_unk0x426c != (Act3Script::Script) 0) {
|
||||
if (AnimationManager()->FUN_10064ee0(m_unk0x426c)) {
|
||||
if (m_explanationAnimation != (Act3Script::Script) 0) {
|
||||
if (AnimationManager()->FUN_10064ee0(m_explanationAnimation)) {
|
||||
Disable(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen);
|
||||
TickleManager()->UnregisterClient(this);
|
||||
m_unk0x426c = (Act3Script::Script) 0;
|
||||
m_explanationAnimation = (Act3Script::Script) 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -711,7 +720,7 @@ MxResult Act3::Tickle()
|
||||
|
||||
// FUNCTION: LEGO1 0x10073360
|
||||
// FUNCTION: BETA10 0x100169d5
|
||||
MxResult Act3::FUN_10073360(Act3Ammo& p_ammo, const Vector3& p_param2)
|
||||
MxResult Act3::HitBrickster(Act3Ammo& p_ammo, const Vector3& p_param2)
|
||||
{
|
||||
assert(m_brickster);
|
||||
m_brickster->FUN_100417a0(p_ammo, p_param2);
|
||||
@ -721,11 +730,11 @@ MxResult Act3::FUN_10073360(Act3Ammo& p_ammo, const Vector3& p_param2)
|
||||
|
||||
// FUNCTION: LEGO1 0x10073390
|
||||
// FUNCTION: BETA10 0x10016a40
|
||||
MxResult Act3::FUN_10073390(Act3Ammo& p_ammo, const Vector3& p_param2)
|
||||
MxResult Act3::HitCop(Act3Ammo& p_ammo, const Vector3& p_param2)
|
||||
{
|
||||
assert(m_cop1 && m_cop2);
|
||||
|
||||
if (!(g_unk0x100f7814 & 1)) {
|
||||
if (!(g_copSelector & 1)) {
|
||||
m_cop1->FUN_10040350(p_ammo, p_param2);
|
||||
}
|
||||
else {
|
||||
@ -733,7 +742,7 @@ MxResult Act3::FUN_10073390(Act3Ammo& p_ammo, const Vector3& p_param2)
|
||||
}
|
||||
|
||||
TriggerHitSound(3);
|
||||
g_unk0x100f7814++;
|
||||
g_copSelector++;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@ -757,7 +766,7 @@ void Act3::SetBrickster(Act3Brickster* p_brickster)
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10073400
|
||||
void Act3::FUN_10073400()
|
||||
void Act3::TransitionToGoodEnding()
|
||||
{
|
||||
m_state->m_state = Act3State::e_goodEnding;
|
||||
m_destLocation = LegoGameState::e_infomain;
|
||||
@ -765,7 +774,7 @@ void Act3::FUN_10073400()
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10073430
|
||||
void Act3::FUN_10073430()
|
||||
void Act3::TransitionToBadEnding()
|
||||
{
|
||||
m_state->m_state = Act3State::e_badEnding;
|
||||
m_destLocation = LegoGameState::e_infomain;
|
||||
@ -783,7 +792,7 @@ void Act3::GoodEnding(const Matrix4& p_destination)
|
||||
m_brickster->SetActorState(LegoPathActor::c_disabled);
|
||||
|
||||
#ifndef BETA10
|
||||
m_unk0x4220.Clear();
|
||||
m_soundList.Clear();
|
||||
m_copter->FUN_10004640(p_destination);
|
||||
|
||||
DebugPrintf("In Good Ending...");
|
||||
@ -868,7 +877,7 @@ void Act3::BadEnding(const Matrix4& p_destination)
|
||||
m_cop2->SetActorState(LegoPathActor::c_disabled);
|
||||
m_brickster->SetActorState(LegoPathActor::c_disabled);
|
||||
|
||||
m_unk0x4220.Clear();
|
||||
m_soundList.Clear();
|
||||
m_copter->FUN_10004670(p_destination);
|
||||
|
||||
DebugPrintf("In Bad Ending...");
|
||||
@ -884,10 +893,10 @@ void Act3::BadEnding(const Matrix4& p_destination)
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10073a60
|
||||
void Act3::FUN_10073a60()
|
||||
void Act3::DisableHelicopterDot()
|
||||
{
|
||||
m_unk0x421e--;
|
||||
m_helicopterDots[m_unk0x421e]->Enable(FALSE);
|
||||
m_helicopterDotCount--;
|
||||
m_helicopterDots[m_helicopterDotCount]->Enable(FALSE);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10073a90
|
||||
|
||||
@ -52,7 +52,7 @@ MxS32 g_animationsBricksterIsLoose[] = {
|
||||
const LegoChar* g_charactersBricksterIsLoose[] = {"bd", "pg", "rd", "sy", "ro", "cl"};
|
||||
|
||||
// GLOBAL: LEGO1 0x100f4428
|
||||
MxS32 g_unk0x100f4428[] = {
|
||||
MxS32 g_animationsAfterChase[] = {
|
||||
Act2mainScript::c_snsx07pa_RunAnim,
|
||||
Act2mainScript::c_snsx12ni_RunAnim,
|
||||
Act2mainScript::c_snsx15la_RunAnim,
|
||||
@ -68,7 +68,7 @@ MxS32 g_unk0x100f4428[] = {
|
||||
};
|
||||
|
||||
// GLOBAL: LEGO1 0x100f4458
|
||||
const LegoChar* g_unk0x100f4458[] = {"papa", "nick", "laura", "cl", "pg", "rd", "sy"};
|
||||
const LegoChar* g_charactersAfterChase[] = {"papa", "nick", "laura", "cl", "pg", "rd", "sy"};
|
||||
|
||||
// FUNCTION: LEGO1 0x1004fce0
|
||||
// FUNCTION: BETA10 0x1003a5a0
|
||||
@ -82,7 +82,7 @@ LegoAct2::LegoAct2()
|
||||
m_unk0x1130 = 0;
|
||||
m_nextBrick = 0;
|
||||
m_removedBricks = 0;
|
||||
m_unk0x1138 = NULL;
|
||||
m_ambulanceActor = NULL;
|
||||
m_currentAction = (Act2mainScript::Script) 0;
|
||||
m_infomanDirecting = (Act2mainScript::Script) 0;
|
||||
m_destLocation = LegoGameState::e_undefined;
|
||||
@ -100,7 +100,7 @@ LegoAct2::~LegoAct2()
|
||||
TickleManager()->UnregisterClient(this);
|
||||
}
|
||||
|
||||
FUN_10051900();
|
||||
DisableAnimations();
|
||||
InputManager()->UnRegister(this);
|
||||
if (UserActor()) {
|
||||
Remove(UserActor());
|
||||
@ -246,7 +246,7 @@ MxResult LegoAct2::Tickle()
|
||||
else {
|
||||
m_state = LegoAct2::e_goingToHide;
|
||||
m_timeSinceLastStage = 0;
|
||||
m_unk0x1138->GoingToHide();
|
||||
m_ambulanceActor->GoingToHide();
|
||||
}
|
||||
}
|
||||
|
||||
@ -303,30 +303,30 @@ MxLong LegoAct2::Notify(MxParam& p_param)
|
||||
|
||||
LegoEntity* entity = (LegoEntity*) param.GetSender();
|
||||
|
||||
Mx3DPointFloat local20(entity->GetROI()->GetWorldPosition());
|
||||
Mx3DPointFloat locale8(m_pepper->GetWorldPosition());
|
||||
Mx3DPointFloat locala4(locale8);
|
||||
Mx3DPointFloat pepperToBrick(entity->GetROI()->GetWorldPosition());
|
||||
Mx3DPointFloat pepperPosition(m_pepper->GetWorldPosition());
|
||||
Mx3DPointFloat position(pepperPosition);
|
||||
|
||||
local20 -= locale8;
|
||||
pepperToBrick -= pepperPosition;
|
||||
|
||||
MxMatrix local2world(m_pepper->GetLocal2World());
|
||||
Vector3 local30(local2world[0]);
|
||||
Vector3 localac(local2world[1]);
|
||||
Vector3 local28(local2world[2]);
|
||||
Vector3 right(local2world[0]);
|
||||
Vector3 up(local2world[1]);
|
||||
Vector3 dir(local2world[2]);
|
||||
|
||||
local28 = local20;
|
||||
local28.Unitize();
|
||||
dir = pepperToBrick;
|
||||
dir.Unitize();
|
||||
|
||||
Mx3DPointFloat local90(local28);
|
||||
local90 *= 1.25f;
|
||||
locala4 += local90;
|
||||
locala4[1] += 0.25;
|
||||
local30.EqualsCross(localac, local28);
|
||||
local30.Unitize();
|
||||
Mx3DPointFloat positionOffset(dir);
|
||||
positionOffset *= 1.25f;
|
||||
position += positionOffset;
|
||||
position[1] += 0.25;
|
||||
right.EqualsCross(up, dir);
|
||||
right.Unitize();
|
||||
|
||||
Mx3DPointFloat locald4(local2world[2]);
|
||||
Mx3DPointFloat direction(local2world[2]);
|
||||
Mx3DPointFloat localc0(local2world[1]);
|
||||
StartAction(Act2mainScript::c_tns051in_RunAnim, TRUE, TRUE, &locala4, &locald4, NULL);
|
||||
StartAction(Act2mainScript::c_tns051in_RunAnim, TRUE, TRUE, &position, &direction, NULL);
|
||||
|
||||
m_state = LegoAct2::e_allPiecesCollected;
|
||||
m_timeSinceLastStage = 0;
|
||||
@ -414,8 +414,8 @@ MxLong LegoAct2::HandleEndAction(MxEndActionNotificationParam& p_param)
|
||||
((LegoPathActor*) m_pepper->GetEntity())->SetActorState(LegoPathActor::c_disabled);
|
||||
AnimationManager()->EnableCamAnims(TRUE);
|
||||
AnimationManager()->FUN_1005f6d0(TRUE);
|
||||
AnimationManager()->FUN_100604f0(g_unk0x100f4428, sizeOfArray(g_unk0x100f4428));
|
||||
AnimationManager()->FUN_10060480(g_unk0x100f4458, sizeOfArray(g_unk0x100f4458));
|
||||
AnimationManager()->FUN_100604f0(g_animationsAfterChase, sizeOfArray(g_animationsAfterChase));
|
||||
AnimationManager()->FUN_10060480(g_charactersAfterChase, sizeOfArray(g_charactersAfterChase));
|
||||
break;
|
||||
case LegoAct2::e_distributeRemainingBricks: {
|
||||
LegoROI* roi;
|
||||
@ -452,7 +452,7 @@ MxLong LegoAct2::HandleEndAction(MxEndActionNotificationParam& p_param)
|
||||
m_bricks[i].Remove();
|
||||
}
|
||||
|
||||
FUN_10051900();
|
||||
DisableAnimations();
|
||||
m_destLocation = LegoGameState::e_copterbuild;
|
||||
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
||||
break;
|
||||
@ -488,7 +488,7 @@ void LegoAct2::ReadyWorld()
|
||||
m_pepper = FindROI("pepper");
|
||||
IslePathActor* pepper = (IslePathActor*) m_pepper->GetEntity();
|
||||
pepper->SpawnPlayer(
|
||||
LegoGameState::e_unk50,
|
||||
LegoGameState::e_pepperSpawnAct2,
|
||||
TRUE,
|
||||
IslePathActor::c_spawnBit1 | IslePathActor::c_playMusic | IslePathActor::c_spawnBit3
|
||||
);
|
||||
@ -513,7 +513,7 @@ void LegoAct2::ReadyWorld()
|
||||
PlaceActor(actor, "EDG00_149", 0, 0.5f, 2, 0.5f);
|
||||
|
||||
PlayMusic(JukeboxScript::c_Jail_Music);
|
||||
FUN_10051900();
|
||||
DisableAnimations();
|
||||
VideoManager()->Get3DManager()->SetFrustrum(90.0f, 0.1f, 250.f);
|
||||
m_gameState->m_enabled = TRUE;
|
||||
}
|
||||
@ -573,7 +573,7 @@ void LegoAct2::Enable(MxBool p_enable)
|
||||
m_transformOnDisable = m_pepper->GetLocal2World();
|
||||
m_boundaryOnDisable = ((LegoPathActor*) m_pepper->GetEntity())->GetBoundary();
|
||||
|
||||
FUN_10051900();
|
||||
DisableAnimations();
|
||||
BackgroundAudioManager()->Stop();
|
||||
UninitBricks();
|
||||
DeleteObjects(&m_atomId, Act2mainScript::c_VOhead0_PlayWav, Act2mainScript::c_VOhide_PlayWav);
|
||||
@ -599,7 +599,7 @@ MxLong LegoAct2::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
||||
LegoPathActor* actor = (LegoPathActor*) m_pepper->GetEntity();
|
||||
actor->SetActorState(LegoPathActor::c_disabled);
|
||||
actor->SetWorldSpeed(0.0f);
|
||||
FUN_10051900();
|
||||
DisableAnimations();
|
||||
|
||||
if (m_timeSinceLastStage < 90000) {
|
||||
StartAction(Act2mainScript::c_tra031ni_RunAnim, TRUE, TRUE, NULL, NULL, NULL);
|
||||
@ -631,7 +631,7 @@ MxLong LegoAct2::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
||||
m_currentAction = Act2mainScript::c_VOhide_PlayWav;
|
||||
}
|
||||
|
||||
m_unk0x1138->Hide();
|
||||
m_ambulanceActor->Hide();
|
||||
|
||||
m_state = LegoAct2::e_hidden;
|
||||
m_timeSinceLastStage = 0;
|
||||
@ -644,7 +644,7 @@ MxLong LegoAct2::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
||||
MxMatrix local2world = m_ambulance->GetLocal2World();
|
||||
MxMatrix local2world2 = local2world;
|
||||
|
||||
LegoPathBoundary* boundary = m_unk0x1138->GetBoundary();
|
||||
LegoPathBoundary* boundary = m_ambulanceActor->GetBoundary();
|
||||
local2world[3][1] += 1.5;
|
||||
local2world2[3][1] -= 0.1;
|
||||
|
||||
@ -656,7 +656,7 @@ MxLong LegoAct2::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
||||
|
||||
// FUNCTION: LEGO1 0x100516b0
|
||||
// FUNCTION: BETA10 0x1003bcbc
|
||||
MxResult LegoAct2::CreateBrick()
|
||||
MxResult LegoAct2::CreateDroppingBrick()
|
||||
{
|
||||
if (m_nextBrick > 4) {
|
||||
return FAILURE;
|
||||
@ -668,7 +668,7 @@ MxResult LegoAct2::CreateBrick()
|
||||
MxMatrix local2world = m_ambulance->GetLocal2World();
|
||||
MxMatrix local2world2 = local2world;
|
||||
|
||||
LegoPathBoundary* boundary = m_unk0x1138->GetBoundary();
|
||||
LegoPathBoundary* boundary = m_ambulanceActor->GetBoundary();
|
||||
local2world[3][1] += 1.3;
|
||||
local2world2[3][1] -= 0.1;
|
||||
|
||||
@ -680,7 +680,7 @@ MxResult LegoAct2::CreateBrick()
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100517b0
|
||||
void LegoAct2::FUN_100517b0()
|
||||
void LegoAct2::CreateBrick()
|
||||
{
|
||||
Act2Brick& brick = m_bricks[m_nextBrick];
|
||||
brick.Create(m_nextBrick);
|
||||
@ -708,7 +708,7 @@ void LegoAct2::PlayMusic(JukeboxScript::Script p_objectId)
|
||||
|
||||
// FUNCTION: LEGO1 0x10051900
|
||||
// FUNCTION: BETA10 0x1003bed1
|
||||
void LegoAct2::FUN_10051900()
|
||||
void LegoAct2::DisableAnimations()
|
||||
{
|
||||
if (AnimationManager()) {
|
||||
AnimationManager()->Suspend();
|
||||
@ -931,7 +931,7 @@ MxResult LegoAct2::BadEnding()
|
||||
m_bricks[i].Remove();
|
||||
}
|
||||
|
||||
LegoPathActor* actor = m_unk0x1138;
|
||||
LegoPathActor* actor = m_ambulanceActor;
|
||||
actor->SetActorState(LegoPathActor::c_disabled);
|
||||
|
||||
m_gameState->SetState(LegoAct2State::c_badEnding);
|
||||
@ -1096,7 +1096,7 @@ MxResult LegoAct2::StartAction(
|
||||
MxBool p_ignoreCurrentAction,
|
||||
Mx3DPointFloat* p_location,
|
||||
Mx3DPointFloat* p_direction,
|
||||
Mx3DPointFloat* p_param6
|
||||
Mx3DPointFloat* p_up
|
||||
)
|
||||
{
|
||||
if (m_currentAction == (Act2mainScript::Script) 0 || p_ignoreCurrentAction) {
|
||||
@ -1140,19 +1140,19 @@ MxResult LegoAct2::StartAction(
|
||||
oneVectorNotNull = TRUE;
|
||||
}
|
||||
|
||||
if (p_param6) {
|
||||
matrix[1][0] = (*p_param6)[0];
|
||||
matrix[1][1] = (*p_param6)[1];
|
||||
matrix[1][2] = (*p_param6)[2];
|
||||
if (p_up) {
|
||||
matrix[1][0] = (*p_up)[0];
|
||||
matrix[1][1] = (*p_up)[1];
|
||||
matrix[1][2] = (*p_up)[2];
|
||||
oneVectorNotNull = TRUE;
|
||||
}
|
||||
|
||||
Vector3 firstColumn(matrix[0]);
|
||||
Vector3 secondColumn(matrix[1]);
|
||||
Vector3 thirdColumn(matrix[2]);
|
||||
Vector3 right(matrix[0]);
|
||||
Vector3 up(matrix[1]);
|
||||
Vector3 dir(matrix[2]);
|
||||
|
||||
firstColumn.EqualsCross(secondColumn, thirdColumn);
|
||||
firstColumn.Unitize();
|
||||
right.EqualsCross(up, dir);
|
||||
right.Unitize();
|
||||
|
||||
MxMatrix* pmatrix = NULL;
|
||||
|
||||
@ -1202,28 +1202,28 @@ MxResult LegoAct2::StartAction(
|
||||
// FUNCTION: BETA10 0x10014aa8
|
||||
MxResult LegoAct2::InitializeShooting()
|
||||
{
|
||||
LegoPathActor* actor = m_unk0x1138;
|
||||
LegoPathActor* actor = m_ambulanceActor;
|
||||
LegoLocomotionAnimPresenter* ap;
|
||||
|
||||
PlaceActor(actor, "EDG01_27", 2, 0.5f, 0, 0.5f);
|
||||
|
||||
ap = (LegoLocomotionAnimPresenter*) Find("LegoAnimPresenter", "Ambul_Anim0");
|
||||
assert(ap);
|
||||
ap->CreateROIAndBuildMap(m_unk0x1138, 0.0f);
|
||||
ap->CreateROIAndBuildMap(m_ambulanceActor, 0.0f);
|
||||
|
||||
ap = (LegoLocomotionAnimPresenter*) Find("LegoAnimPresenter", "Ambul_Anim2");
|
||||
assert(ap);
|
||||
ap->CreateROIAndBuildMap(m_unk0x1138, 6.0f);
|
||||
ap->CreateROIAndBuildMap(m_ambulanceActor, 6.0f);
|
||||
|
||||
ap = (LegoLocomotionAnimPresenter*) Find("LegoAnimPresenter", "Ambul_Anim3");
|
||||
assert(ap);
|
||||
ap->CreateROIAndBuildMap(m_unk0x1138, 3.0f);
|
||||
ap->CreateROIAndBuildMap(m_ambulanceActor, 3.0f);
|
||||
|
||||
ap = (LegoLocomotionAnimPresenter*) Find("LegoAnimPresenter", "BrShoot");
|
||||
assert(ap);
|
||||
ap->CreateROIAndBuildMap(m_unk0x1138, -1.0f);
|
||||
ap->CreateROIAndBuildMap(m_ambulanceActor, -1.0f);
|
||||
|
||||
actor->SetWorldSpeed(0.0f);
|
||||
m_unk0x1138->InitializeNextShot();
|
||||
m_ambulanceActor->InitializeNextShot();
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@ -52,6 +52,7 @@ inline ViewManager* Lego3DView::GetViewManager()
|
||||
return m_pViewManager;
|
||||
}
|
||||
|
||||
// FUNCTION: BETA10 0x1006aae0
|
||||
inline ViewROI* Lego3DView::GetPointOfView()
|
||||
{
|
||||
return m_pPointOfView;
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
DECOMP_SIZE_ASSERT(LegoEdge, 0x24)
|
||||
|
||||
// FUNCTION: LEGO1 0x1009a470
|
||||
// FUNCTION: BETA10 0x10182250
|
||||
LegoEdge::LegoEdge()
|
||||
{
|
||||
m_faceA = NULL;
|
||||
@ -19,36 +20,65 @@ LegoEdge::LegoEdge()
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1009a4c0
|
||||
// FUNCTION: BETA10 0x101822c2
|
||||
LegoEdge::~LegoEdge()
|
||||
{
|
||||
}
|
||||
|
||||
// FUNCTION: BETA10 0x101822e1
|
||||
LegoResult LegoEdge::SetCounterclockwiseEdge(LegoWEEdge& p_face, LegoEdge* p_edge)
|
||||
{
|
||||
// unreferenced in BETA10, not in LEGO1
|
||||
if (&p_face == m_faceA) {
|
||||
m_ccwA = p_edge;
|
||||
return SUCCESS;
|
||||
}
|
||||
if (&p_face == m_faceB) {
|
||||
m_ccwB = p_edge;
|
||||
return SUCCESS;
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// FUNCTION: BETA10 0x1018233c
|
||||
LegoResult LegoEdge::SetClockwiseEdge(LegoWEEdge& p_face, LegoEdge* p_edge)
|
||||
{
|
||||
// unreferenced in BETA10, not in LEGO1
|
||||
if (&p_face == m_faceA) {
|
||||
m_cwA = p_edge;
|
||||
return SUCCESS;
|
||||
}
|
||||
if (&p_face == m_faceB) {
|
||||
m_cwB = p_edge;
|
||||
return SUCCESS;
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1009a4d0
|
||||
// FUNCTION: BETA10 0x10182397
|
||||
LegoEdge* LegoEdge::GetClockwiseEdge(LegoWEEdge& p_face)
|
||||
{
|
||||
if (&p_face == m_faceA) {
|
||||
return m_cwA;
|
||||
}
|
||||
else if (&p_face == m_faceB) {
|
||||
if (&p_face == m_faceB) {
|
||||
return m_cwB;
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1009a4f0
|
||||
// FUNCTION: BETA10 0x101823e5
|
||||
LegoEdge* LegoEdge::GetCounterclockwiseEdge(LegoWEEdge& p_face)
|
||||
{
|
||||
if (&p_face == m_faceA) {
|
||||
return m_ccwA;
|
||||
}
|
||||
else if (&p_face == m_faceB) {
|
||||
if (&p_face == m_faceB) {
|
||||
return m_ccwB;
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1009a510
|
||||
@ -58,10 +88,8 @@ Vector3* LegoEdge::CWVertex(LegoWEEdge& p_face)
|
||||
if (m_faceA == &p_face) {
|
||||
return m_pointB;
|
||||
}
|
||||
else {
|
||||
assert(m_faceB == &p_face);
|
||||
return m_pointA;
|
||||
}
|
||||
assert(m_faceB == &p_face);
|
||||
return m_pointA;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1009a530
|
||||
@ -71,8 +99,6 @@ Vector3* LegoEdge::CCWVertex(LegoWEEdge& p_face)
|
||||
if (m_faceB == &p_face) {
|
||||
return m_pointB;
|
||||
}
|
||||
else {
|
||||
assert(m_faceA == &p_face);
|
||||
return m_pointA;
|
||||
}
|
||||
assert(m_faceA == &p_face);
|
||||
return m_pointA;
|
||||
}
|
||||
|
||||
@ -7,11 +7,14 @@ class LegoWEEdge;
|
||||
class Vector3;
|
||||
|
||||
// VTABLE: LEGO1 0x100db7b8
|
||||
// VTABLE: BETA10 0x101c3728
|
||||
// SIZE 0x24
|
||||
struct LegoEdge {
|
||||
LegoEdge();
|
||||
virtual ~LegoEdge(); // vtable+0x00
|
||||
|
||||
LegoResult SetCounterclockwiseEdge(LegoWEEdge& p_face, LegoEdge* p_edge);
|
||||
LegoResult SetClockwiseEdge(LegoWEEdge& p_face, LegoEdge* p_edge);
|
||||
LegoEdge* GetClockwiseEdge(LegoWEEdge& p_face);
|
||||
LegoEdge* GetCounterclockwiseEdge(LegoWEEdge& p_face);
|
||||
Vector3* CWVertex(LegoWEEdge& p_face);
|
||||
@ -32,6 +35,7 @@ struct LegoEdge {
|
||||
Vector3* GetPointB() { return m_pointB; }
|
||||
|
||||
// SYNTHETIC: LEGO1 0x1009a4a0
|
||||
// SYNTHETIC: BETA10 0x10182b30
|
||||
// LegoEdge::`scalar deleting destructor'
|
||||
|
||||
LegoWEEdge* m_faceA; // 0x04
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
#include <assert.h>
|
||||
|
||||
// VTABLE: LEGO1 0x100db7f4
|
||||
// VTABLE: BETA10 0x101c3794
|
||||
// SIZE 0x40
|
||||
struct LegoOrientedEdge : public LegoEdge {
|
||||
public:
|
||||
@ -99,8 +100,12 @@ struct LegoOrientedEdge : public LegoEdge {
|
||||
inline LegoU32 FUN_10048c40(const Vector3& p_position);
|
||||
|
||||
// SYNTHETIC: LEGO1 0x1009a6c0
|
||||
// SYNTHETIC: BETA10 0x101840f0
|
||||
// LegoOrientedEdge::`scalar deleting destructor'
|
||||
|
||||
// SYNTHETIC: BETA10 0x100bd390
|
||||
// LegoOrientedEdge::~LegoOrientedEdge
|
||||
|
||||
LegoU16 m_flags; // 0x24
|
||||
Mx3DPointFloat m_dir; // 0x28
|
||||
float m_length; // 0x3c
|
||||
|
||||
@ -873,6 +873,12 @@
|
||||
// LIBRARY: BETA10 0x100fa0e0
|
||||
// atof
|
||||
|
||||
// LIBRARY: BETA10 0x1005a500
|
||||
// sqrt
|
||||
|
||||
// LIBRARY: BETA10 0x1005a530
|
||||
// sqrtf
|
||||
|
||||
// LIBRARY: BETA10 0x1005a9c0
|
||||
// fabs
|
||||
|
||||
|
||||
@ -29,6 +29,7 @@ void OrientableROI::WrappedSetLocal2WorldWithWorldDataUpdate(const Matrix4& p_lo
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100a46b0
|
||||
// FUNCTION: BETA10 0x1016528f
|
||||
void OrientableROI::UpdateTransformationRelativeToParent(const Matrix4& p_transform)
|
||||
{
|
||||
MxMatrix mat;
|
||||
|
||||
@ -18,6 +18,10 @@ Kaitai Struct allows you to define binary formats in a YAML-based `.ksy` file, w
|
||||
| [`savegame.ksy`](/docs/savegame.ksy) | `.GS` | Main game save data (game state, progress, customizations) |
|
||||
| [`players.ksy`](/docs/players.ksy) | `.gsi` | Player profile save data (usernames) |
|
||||
| [`history.ksy`](/docs/history.ksy) | `.gsi` | Score history and high scores |
|
||||
| [`animation.ksy`](/docs/animation.ksy) | `.ani` | Animation data (keyframes, actor references, camera animation) |
|
||||
| [`wdb.ksy`](/docs/wdb.ksy) | `.wdb` | World database (textures, parts, models, ROI hierarchies, LODs) |
|
||||
| [`dta.ksy`](/docs/dta.ksy) | `.dta` | Animation data (world animation info, model placement) |
|
||||
| [`tex.ksy`](/docs/tex.ksy) | `.tex` | Texture data (named textures with palette and pixel data) |
|
||||
|
||||
## Using the Tools
|
||||
|
||||
@ -38,6 +42,18 @@ ksv samples/Players.gsi players.ksy
|
||||
|
||||
# View a History.gsi file
|
||||
ksv samples/History.gsi history.ksy
|
||||
|
||||
# View an animation file
|
||||
ksv samples/pns065rd.ani animation.ksy
|
||||
|
||||
# View the world database (from game installation)
|
||||
ksv /path/to/lego/data/world.wdb wdb.ksy
|
||||
|
||||
# View an animation data file
|
||||
ksv samples/BLDRINF.DTA dta.ksy
|
||||
|
||||
# View a texture data file
|
||||
ksv samples/Dbfrfn.tex tex.ksy
|
||||
```
|
||||
|
||||
### Kaitai Struct Dump (ksdump)
|
||||
@ -53,11 +69,28 @@ ksdump --format json samples/Players.gsi players.ksy
|
||||
|
||||
# Dump History.gsi to YAML
|
||||
ksdump --format yaml samples/History.gsi history.ksy
|
||||
|
||||
# Dump an animation file to JSON
|
||||
ksdump --format json samples/pns065rd.ani animation.ksy
|
||||
|
||||
# Dump world database to YAML (from game installation)
|
||||
ksdump --format yaml /path/to/lego/data/world.wdb wdb.ksy
|
||||
|
||||
# Dump an animation data file to JSON
|
||||
ksdump --format json samples/BLDRINF.DTA dta.ksy
|
||||
|
||||
# Dump a texture data file to JSON
|
||||
ksdump --format json samples/Dbfrfn.tex tex.ksy
|
||||
```
|
||||
|
||||
## Sample Files
|
||||
|
||||
The [`samples/`](/docs/samples/) directory contains example save files for testing:
|
||||
The [`samples/`](/docs/samples/) directory contains example files for testing:
|
||||
- `G0.GS`, `G1.GS`, `G2.GS` - Sample main game save files (slots 0, 1, 2)
|
||||
- `Players.gsi` - Sample player profile data
|
||||
- `History.gsi` - Sample score history data
|
||||
- `pns065rd.ani` - Sample animation file
|
||||
- `BLDRINF.DTA` - Sample animation data file
|
||||
- `Dbfrfn.tex` - Sample texture data file (dune buggy front fender)
|
||||
|
||||
Note: The world database (`world.wdb`) can be found in your LEGO Island installation at `lego/data/world.wdb`.
|
||||
|
||||
310
docs/animation.ksy
Normal file
310
docs/animation.ksy
Normal file
@ -0,0 +1,310 @@
|
||||
meta:
|
||||
id: animation
|
||||
title: Animation File
|
||||
application: LEGO Island
|
||||
file-extension: ani
|
||||
license: CC0-1.0
|
||||
endian: le
|
||||
doc: |
|
||||
Animation file format for LEGO Island (1997). Contains skeletal animation
|
||||
data including actor references, keyframes for translation/rotation/scale,
|
||||
morph visibility keys, and optional camera animation data.
|
||||
|
||||
Animation files are embedded within SI (Interleaf) files and
|
||||
parsed by LegoAnimPresenter. The format consists of a header with bounding
|
||||
information, an actor list, animation duration, optional camera animation,
|
||||
and a hierarchical tree of animation nodes.
|
||||
|
||||
seq:
|
||||
- id: magic
|
||||
type: s4
|
||||
doc: |
|
||||
Magic number identifying the file format. Must be 0x11 (17 decimal).
|
||||
- id: bounding_radius
|
||||
type: f4
|
||||
doc: |
|
||||
Radius of the bounding sphere encompassing the entire animation.
|
||||
Used for visibility culling and collision detection.
|
||||
- id: center_x
|
||||
type: f4
|
||||
doc: X coordinate of the bounding sphere center point.
|
||||
- id: center_y
|
||||
type: f4
|
||||
doc: Y coordinate of the bounding sphere center point.
|
||||
- id: center_z
|
||||
type: f4
|
||||
doc: Z coordinate of the bounding sphere center point.
|
||||
- id: has_camera_anim
|
||||
type: s4
|
||||
doc: |
|
||||
Flag indicating whether camera animation data follows the actor list.
|
||||
If non-zero, a camera_anim structure is present after the duration field.
|
||||
- id: unused
|
||||
type: s4
|
||||
doc: |
|
||||
Unused field. Read by the parser but not used for anything.
|
||||
- id: num_actors
|
||||
type: u4
|
||||
doc: Number of actor entries in the actor list.
|
||||
- id: actors
|
||||
type: actor_entry
|
||||
repeat: expr
|
||||
repeat-expr: num_actors
|
||||
doc: |
|
||||
List of actors referenced by this animation. Each entry contains
|
||||
the actor name and type, which determines how the actor ROI is
|
||||
managed during animation playback.
|
||||
- id: duration
|
||||
type: s4
|
||||
doc: Total duration of the animation in milliseconds.
|
||||
- id: camera_anim
|
||||
type: camera_anim
|
||||
if: has_camera_anim != 0
|
||||
doc: |
|
||||
Camera animation data including position, target, and rotation keys.
|
||||
Only present if has_camera_anim is non-zero.
|
||||
- id: root_node
|
||||
type: tree_node
|
||||
doc: |
|
||||
Root node of the animation tree. The tree structure mirrors the
|
||||
skeletal hierarchy of the animated model, with each node containing
|
||||
keyframe data for its corresponding bone/part.
|
||||
|
||||
types:
|
||||
actor_entry:
|
||||
doc: |
|
||||
An actor reference in the animation. The name identifies which ROI
|
||||
(Realtime Object Instance) to animate, and the type determines
|
||||
how the actor is managed by the character manager.
|
||||
seq:
|
||||
- id: name_length
|
||||
type: u4
|
||||
doc: Length of the actor name in bytes.
|
||||
- id: name
|
||||
type: str
|
||||
size: name_length
|
||||
encoding: ASCII
|
||||
if: name_length > 0
|
||||
doc: Actor name used to look up the ROI in the scene.
|
||||
- id: actor_type
|
||||
type: u4
|
||||
enum: actor_type
|
||||
if: name_length > 0
|
||||
doc: |
|
||||
Determines how the actor ROI is created and managed.
|
||||
See actor_type enum for possible values.
|
||||
|
||||
camera_anim:
|
||||
doc: |
|
||||
Camera animation data (LegoAnimScene). Contains keyframes for camera
|
||||
position, look-at target position, and roll rotation around the
|
||||
view axis.
|
||||
seq:
|
||||
- id: num_translation_keys
|
||||
type: u2
|
||||
doc: Number of camera position keyframes.
|
||||
- id: translation_keys
|
||||
type: translation_key
|
||||
repeat: expr
|
||||
repeat-expr: num_translation_keys
|
||||
doc: Camera position keyframes.
|
||||
- id: num_target_keys
|
||||
type: u2
|
||||
doc: Number of look-at target position keyframes.
|
||||
- id: target_keys
|
||||
type: translation_key
|
||||
repeat: expr
|
||||
repeat-expr: num_target_keys
|
||||
doc: Look-at target position keyframes.
|
||||
- id: num_rotation_keys
|
||||
type: u2
|
||||
doc: Number of camera roll rotation keyframes.
|
||||
- id: rotation_keys
|
||||
type: rotation_z_key
|
||||
repeat: expr
|
||||
repeat-expr: num_rotation_keys
|
||||
doc: Camera roll rotation keyframes (rotation around view axis).
|
||||
|
||||
tree_node:
|
||||
doc: |
|
||||
A node in the animation tree hierarchy. Each node contains animation
|
||||
data for one part of the model and references to child nodes.
|
||||
seq:
|
||||
- id: data
|
||||
type: node_data
|
||||
doc: Animation keyframe data for this node.
|
||||
- id: num_children
|
||||
type: u4
|
||||
doc: Number of child nodes.
|
||||
- id: children
|
||||
type: tree_node
|
||||
repeat: expr
|
||||
repeat-expr: num_children
|
||||
doc: Child nodes in the animation hierarchy.
|
||||
|
||||
node_data:
|
||||
doc: |
|
||||
Animation data for a single node (LegoAnimNodeData). Contains the
|
||||
node name and arrays of keyframes for translation, rotation, scale,
|
||||
and morph (visibility) animations.
|
||||
seq:
|
||||
- id: name_length
|
||||
type: u4
|
||||
doc: Length of the node name in bytes.
|
||||
- id: name
|
||||
type: str
|
||||
size: name_length
|
||||
encoding: ASCII
|
||||
if: name_length > 0
|
||||
doc: |
|
||||
Node name used to match this animation data to a ROI in the scene.
|
||||
Names starting with '*' indicate special handling (actor name
|
||||
substitution). Names starting with '-' are ignored.
|
||||
- id: num_translation_keys
|
||||
type: u2
|
||||
doc: Number of translation keyframes.
|
||||
- id: translation_keys
|
||||
type: translation_key
|
||||
repeat: expr
|
||||
repeat-expr: num_translation_keys
|
||||
doc: Translation (position) keyframes.
|
||||
- id: num_rotation_keys
|
||||
type: u2
|
||||
doc: Number of rotation keyframes.
|
||||
- id: rotation_keys
|
||||
type: rotation_key
|
||||
repeat: expr
|
||||
repeat-expr: num_rotation_keys
|
||||
doc: Rotation keyframes (quaternion format).
|
||||
- id: num_scale_keys
|
||||
type: u2
|
||||
doc: Number of scale keyframes.
|
||||
- id: scale_keys
|
||||
type: scale_key
|
||||
repeat: expr
|
||||
repeat-expr: num_scale_keys
|
||||
doc: Scale keyframes.
|
||||
- id: num_morph_keys
|
||||
type: u2
|
||||
doc: Number of morph (visibility) keyframes.
|
||||
- id: morph_keys
|
||||
type: morph_key
|
||||
repeat: expr
|
||||
repeat-expr: num_morph_keys
|
||||
doc: Morph keyframes controlling visibility.
|
||||
|
||||
anim_key:
|
||||
doc: |
|
||||
Base animation key containing time and flags. The time and flags
|
||||
are packed into a single 32-bit value: bits 0-23 contain the time
|
||||
in milliseconds, and bits 24-31 contain flags.
|
||||
seq:
|
||||
- id: time_and_flags
|
||||
type: s4
|
||||
doc: |
|
||||
Packed time and flags value.
|
||||
- Bits 0-23: Time in milliseconds (mask with 0xFFFFFF)
|
||||
- Bits 24-31: Flags (shift right by 24)
|
||||
instances:
|
||||
time:
|
||||
value: time_and_flags & 0xFFFFFF
|
||||
doc: Keyframe time in milliseconds.
|
||||
flags:
|
||||
value: (time_and_flags >> 24) & 0xFF
|
||||
doc: |
|
||||
Keyframe flags:
|
||||
- 0x01 (active): Key has meaningful data
|
||||
- 0x02 (negate_rotation): Negate quaternion for interpolation
|
||||
- 0x04 (skip_interpolation): Use this key's value without blending
|
||||
|
||||
translation_key:
|
||||
doc: |
|
||||
Translation keyframe containing position offset (LegoTranslationKey).
|
||||
The translation is applied relative to the parent node's transform.
|
||||
seq:
|
||||
- id: key
|
||||
type: anim_key
|
||||
doc: Base key with time and flags.
|
||||
- id: x
|
||||
type: f4
|
||||
doc: X component of translation.
|
||||
- id: y
|
||||
type: f4
|
||||
doc: Y component of translation.
|
||||
- id: z
|
||||
type: f4
|
||||
doc: Z component of translation.
|
||||
|
||||
rotation_key:
|
||||
doc: |
|
||||
Rotation keyframe containing a quaternion (LegoRotationKey).
|
||||
The quaternion is stored as (angle, x, y, z) where angle is the
|
||||
scalar/w component and (x, y, z) is the vector part.
|
||||
seq:
|
||||
- id: key
|
||||
type: anim_key
|
||||
doc: Base key with time and flags.
|
||||
- id: angle
|
||||
type: f4
|
||||
doc: |
|
||||
Quaternion scalar component (w). A value of 1.0 with x=y=z=0
|
||||
represents no rotation (identity quaternion).
|
||||
- id: x
|
||||
type: f4
|
||||
doc: Quaternion x component.
|
||||
- id: y
|
||||
type: f4
|
||||
doc: Quaternion y component.
|
||||
- id: z
|
||||
type: f4
|
||||
doc: Quaternion z component.
|
||||
|
||||
scale_key:
|
||||
doc: |
|
||||
Scale keyframe containing scale factors (LegoScaleKey).
|
||||
Scale is applied relative to the local origin of the node.
|
||||
seq:
|
||||
- id: key
|
||||
type: anim_key
|
||||
doc: Base key with time and flags.
|
||||
- id: x
|
||||
type: f4
|
||||
doc: X scale factor (1.0 = no scaling).
|
||||
- id: y
|
||||
type: f4
|
||||
doc: Y scale factor (1.0 = no scaling).
|
||||
- id: z
|
||||
type: f4
|
||||
doc: Z scale factor (1.0 = no scaling).
|
||||
|
||||
morph_key:
|
||||
doc: |
|
||||
Morph/visibility keyframe (LegoMorphKey). Controls whether the
|
||||
node's ROI is visible at a given time.
|
||||
seq:
|
||||
- id: key
|
||||
type: anim_key
|
||||
doc: Base key with time and flags.
|
||||
- id: visible
|
||||
type: u1
|
||||
doc: Visibility flag. Non-zero means visible.
|
||||
|
||||
rotation_z_key:
|
||||
doc: |
|
||||
Z-axis rotation keyframe (LegoRotationZKey). Used for camera roll
|
||||
animation where only rotation around the view axis is needed.
|
||||
seq:
|
||||
- id: key
|
||||
type: anim_key
|
||||
doc: Base key with time and flags.
|
||||
- id: z
|
||||
type: f4
|
||||
doc: Rotation angle around the Z axis in radians.
|
||||
|
||||
enums:
|
||||
actor_type:
|
||||
2: managed_lego_actor
|
||||
3: managed_invisible_roi_trimmed
|
||||
4: managed_invisible_roi
|
||||
5: scene_roi_1
|
||||
6: scene_roi_2
|
||||
135
docs/dta.ksy
Normal file
135
docs/dta.ksy
Normal file
@ -0,0 +1,135 @@
|
||||
meta:
|
||||
id: dta
|
||||
title: Animation Data File
|
||||
application: LEGO Island
|
||||
file-extension: dta
|
||||
license: CC0-1.0
|
||||
endian: le
|
||||
|
||||
doc: |
|
||||
Animation data file format for LEGO Island (1997). Contains animation
|
||||
information for world objects including their positions, orientations,
|
||||
and associated models.
|
||||
|
||||
DTA files are located at `<install_path>/lego/data/<world>inf.dta` where
|
||||
<world> is the world name (e.g., "isle", "act1", "act2m", etc.). They are
|
||||
loaded by LegoAnimationManager::LoadWorldInfo() to populate animation
|
||||
information for the current world.
|
||||
|
||||
File structure:
|
||||
1. Header - version (must be 3) and animation count
|
||||
2. AnimInfo entries - animation references with nested model placement data
|
||||
|
||||
seq:
|
||||
- id: version
|
||||
type: u4
|
||||
doc: |
|
||||
File format version. Must be 3 for valid files.
|
||||
The game rejects files with mismatched versions.
|
||||
- id: num_anims
|
||||
type: u2
|
||||
doc: Number of animation info entries in this file.
|
||||
- id: anims
|
||||
type: anim_info
|
||||
repeat: expr
|
||||
repeat-expr: num_anims
|
||||
doc: Animation information entries.
|
||||
|
||||
types:
|
||||
anim_info:
|
||||
doc: |
|
||||
Animation information for a single animation (AnimInfo struct).
|
||||
Contains metadata about the animation and a list of models involved.
|
||||
Parsed by LegoAnimationManager::ReadAnimInfo().
|
||||
seq:
|
||||
- id: name_length
|
||||
type: u1
|
||||
doc: Length of the animation name in bytes.
|
||||
- id: name
|
||||
type: str
|
||||
size: name_length
|
||||
encoding: ASCII
|
||||
doc: |
|
||||
Animation name identifier. The last two characters are used
|
||||
to look up a character index via GetCharacterIndex().
|
||||
- id: object_id
|
||||
type: u4
|
||||
doc: Object ID used to identify this animation in the game.
|
||||
- id: location
|
||||
type: s2
|
||||
doc: |
|
||||
Location index referencing a LegoLocation. A value of -1
|
||||
indicates no specific location is assigned.
|
||||
- id: unk_0x0a
|
||||
type: u1
|
||||
doc: Boolean flag (MxBool). Purpose unknown.
|
||||
- id: unk_0x0b
|
||||
type: u1
|
||||
doc: Unknown byte field.
|
||||
- id: unk_0x0c
|
||||
type: u1
|
||||
doc: Unknown byte field.
|
||||
- id: unk_0x0d
|
||||
type: u1
|
||||
doc: Unknown byte field.
|
||||
- id: unk_0x10
|
||||
type: f4
|
||||
repeat: expr
|
||||
repeat-expr: 4
|
||||
doc: Array of 4 unknown float values (16 bytes total).
|
||||
- id: model_count
|
||||
type: u1
|
||||
doc: Number of model entries that follow.
|
||||
- id: models
|
||||
type: model_info
|
||||
repeat: expr
|
||||
repeat-expr: model_count
|
||||
doc: Model information for each model in this animation.
|
||||
|
||||
model_info:
|
||||
doc: |
|
||||
Model information defining position and orientation for a single
|
||||
model within an animation (ModelInfo struct). Used to place characters
|
||||
and objects in the world during animation playback.
|
||||
Parsed by LegoAnimationManager::ReadModelInfo().
|
||||
seq:
|
||||
- id: name_length
|
||||
type: u1
|
||||
doc: Length of the model name in bytes.
|
||||
- id: name
|
||||
type: str
|
||||
size: name_length
|
||||
encoding: ASCII
|
||||
doc: |
|
||||
Model name used to look up the character or vehicle.
|
||||
Examples: "caprc01" (race car), "irt001d1" (character).
|
||||
- id: unk_0x04
|
||||
type: u1
|
||||
doc: Unknown byte field.
|
||||
- id: position
|
||||
type: vertex3
|
||||
doc: World position (X, Y, Z) of the model.
|
||||
- id: direction
|
||||
type: vertex3
|
||||
doc: Forward direction vector of the model.
|
||||
- id: up
|
||||
type: vertex3
|
||||
doc: Up direction vector of the model.
|
||||
- id: unk_0x2c
|
||||
type: u1
|
||||
doc: |
|
||||
Boolean flag. When non-zero, this model is considered a vehicle
|
||||
and tracked in the animation's vehicle list (m_unk0x2a).
|
||||
|
||||
vertex3:
|
||||
doc: A 3D point or vector with X, Y, Z components.
|
||||
seq:
|
||||
- id: x
|
||||
type: f4
|
||||
doc: X component.
|
||||
- id: y
|
||||
type: f4
|
||||
doc: Y component.
|
||||
- id: z
|
||||
type: f4
|
||||
doc: Z component.
|
||||
BIN
docs/samples/BLDRINF.DTA
Executable file
BIN
docs/samples/BLDRINF.DTA
Executable file
Binary file not shown.
BIN
docs/samples/Dbfrfn.tex
Executable file
BIN
docs/samples/Dbfrfn.tex
Executable file
Binary file not shown.
BIN
docs/samples/pns065rd.ani
Normal file
BIN
docs/samples/pns065rd.ani
Normal file
Binary file not shown.
@ -101,8 +101,10 @@ types:
|
||||
if: not is_end_marker
|
||||
doc: |
|
||||
Variable value. For colors this is a color name like "lego red".
|
||||
For backgroundcolor this is "set R G B".
|
||||
For lightposition this is a number "1" or "2".
|
||||
For backgroundcolor and tempBackgroundColor this is "set H S V" where
|
||||
H, S, V are HSV color values scaled 0-100 (not RGB). The game internally
|
||||
converts to RGB using ConvertHSVToRGB().
|
||||
For lightposition this is a number "0" through "5" (6 sun positions).
|
||||
instances:
|
||||
is_end_marker:
|
||||
value: name == "END_OF_VARIABLES"
|
||||
@ -153,88 +155,127 @@ types:
|
||||
doc: Margaret Patricia "Maggie" Post
|
||||
- id: bu
|
||||
type: standard_character_entry
|
||||
doc: Buck Pounds
|
||||
- id: ml
|
||||
type: standard_character_entry
|
||||
doc: Ed Mail
|
||||
- id: nu
|
||||
type: standard_character_entry
|
||||
doc: Nubby Stevens
|
||||
- id: na
|
||||
type: standard_character_entry
|
||||
doc: Nancy Nubbins
|
||||
- id: cl
|
||||
type: standard_character_entry
|
||||
doc: Dr. Clickitt
|
||||
- id: en
|
||||
type: standard_character_entry
|
||||
doc: Enter
|
||||
- id: re
|
||||
type: standard_character_entry
|
||||
doc: Return
|
||||
- id: ro
|
||||
type: standard_character_entry
|
||||
doc: Captain D. Rom
|
||||
- id: d1
|
||||
type: standard_character_entry
|
||||
doc: Bill Ding (Race Car)
|
||||
- id: d2
|
||||
type: standard_character_entry
|
||||
doc: Bill Ding (Helicopter)
|
||||
- id: d3
|
||||
type: standard_character_entry
|
||||
doc: Bill Ding (Dune Buggy)
|
||||
- id: d4
|
||||
type: standard_character_entry
|
||||
doc: Bill Ding (Jetski)
|
||||
- id: l1
|
||||
type: standard_character_entry
|
||||
doc: The Flying Legandos #1
|
||||
- id: l2
|
||||
type: standard_character_entry
|
||||
doc: The Flying Legandos #2
|
||||
- id: l3
|
||||
type: standard_character_entry
|
||||
doc: The Flying Legandos #3
|
||||
- id: l4
|
||||
type: standard_character_entry
|
||||
doc: The Flying Legandos #4
|
||||
- id: l5
|
||||
type: standard_character_entry
|
||||
doc: The Flying Legandos #5
|
||||
- id: l6
|
||||
type: standard_character_entry
|
||||
doc: The Flying Legandos #6
|
||||
- id: b1
|
||||
type: standard_character_entry
|
||||
doc: The Legobobs #1
|
||||
- id: b2
|
||||
type: standard_character_entry
|
||||
doc: The Legobobs #2
|
||||
- id: b3
|
||||
type: standard_character_entry
|
||||
doc: The Legobobs #3
|
||||
- id: b4
|
||||
type: standard_character_entry
|
||||
doc: The Legobobs #4
|
||||
- id: cm
|
||||
type: standard_character_entry
|
||||
doc: Brazilian Carmen
|
||||
- id: gd
|
||||
type: standard_character_entry
|
||||
doc: Gideon Worse
|
||||
- id: rd
|
||||
type: standard_character_entry
|
||||
doc: Red Greenbase
|
||||
- id: pg
|
||||
type: standard_character_entry
|
||||
doc: Polly Gone
|
||||
- id: bd
|
||||
type: standard_character_entry
|
||||
doc: Bradford Brickford
|
||||
- id: sy
|
||||
type: standard_character_entry
|
||||
doc: Shiney Doris
|
||||
- id: gn
|
||||
type: standard_character_entry
|
||||
doc: Glen Funberg
|
||||
- id: df
|
||||
type: standard_character_entry
|
||||
doc: Dorothy Funberg
|
||||
- id: bs
|
||||
type: standard_character_entry
|
||||
doc: Brian Shrimp
|
||||
- id: lt
|
||||
type: standard_character_entry
|
||||
doc: Luke Tepid
|
||||
- id: st
|
||||
type: standard_character_entry
|
||||
doc: Shorty Tails
|
||||
- id: bm
|
||||
type: standard_character_entry
|
||||
doc: Bumpy Kindergreen
|
||||
- id: jk
|
||||
type: standard_character_entry
|
||||
doc: Jack O'Trades
|
||||
- id: ghost
|
||||
type: ghost_character_entry
|
||||
doc: Ghost #1
|
||||
- id: ghost01
|
||||
type: ghost_character_entry
|
||||
doc: Ghost #2
|
||||
- id: ghost02
|
||||
type: ghost_character_entry
|
||||
doc: Ghost #3
|
||||
- id: ghost03
|
||||
type: ghost_character_entry
|
||||
doc: Ghost #4
|
||||
- id: ghost04
|
||||
type: ghost_character_entry
|
||||
doc: Ghost #5
|
||||
- id: ghost05
|
||||
type: ghost_character_entry
|
||||
doc: Ghost #6
|
||||
- id: hg
|
||||
type: standard_character_entry
|
||||
- id: pntgy
|
||||
|
||||
91
docs/tex.ksy
Normal file
91
docs/tex.ksy
Normal file
@ -0,0 +1,91 @@
|
||||
meta:
|
||||
id: tex
|
||||
title: Texture Data File
|
||||
application: LEGO Island
|
||||
file-extension: tex
|
||||
license: CC0-1.0
|
||||
endian: le
|
||||
|
||||
doc: |
|
||||
Texture data format for LEGO Island (1997). Contains one or more named
|
||||
textures with 8-bit indexed color image data.
|
||||
|
||||
Texture data is embedded in SI (Interleaf) container files and parsed by
|
||||
LegoTexturePresenter::Read(). Each texture consists of a length-prefixed
|
||||
name followed by image data with a color palette and pixel indices.
|
||||
|
||||
The image format is shared with the world database (world.wdb) texture
|
||||
data, using the same LegoImage and LegoPaletteEntry serialization.
|
||||
|
||||
File structure:
|
||||
1. Texture count
|
||||
2. Named texture entries - name + palette + pixel data
|
||||
|
||||
seq:
|
||||
- id: num_textures
|
||||
type: u4
|
||||
doc: Number of textures in this file.
|
||||
- id: textures
|
||||
type: named_texture
|
||||
repeat: expr
|
||||
repeat-expr: num_textures
|
||||
doc: Array of named textures.
|
||||
|
||||
types:
|
||||
named_texture:
|
||||
doc: |
|
||||
A named texture with 8-bit indexed color image data.
|
||||
seq:
|
||||
- id: name_length
|
||||
type: u4
|
||||
doc: Length of the texture name buffer in bytes.
|
||||
- id: name
|
||||
type: str
|
||||
size: name_length
|
||||
encoding: ASCII
|
||||
terminator: 0
|
||||
doc: |
|
||||
Texture name (e.g., "dbfrfn.gif"). The name is a null-terminated
|
||||
C string within the allocated buffer. Bytes after the null
|
||||
terminator are unused padding and consumed but not included
|
||||
in the string value.
|
||||
- id: image
|
||||
type: image
|
||||
doc: The texture image data.
|
||||
|
||||
image:
|
||||
doc: |
|
||||
An 8-bit indexed color image with palette. Parsed by LegoImage::Read().
|
||||
seq:
|
||||
- id: width
|
||||
type: u4
|
||||
doc: Image width in pixels.
|
||||
- id: height
|
||||
type: u4
|
||||
doc: Image height in pixels.
|
||||
- id: palette_size
|
||||
type: u4
|
||||
doc: Number of entries in the color palette (max 256).
|
||||
- id: palette
|
||||
type: palette_entry
|
||||
repeat: expr
|
||||
repeat-expr: palette_size
|
||||
doc: Color palette entries.
|
||||
- id: pixels
|
||||
size: width * height
|
||||
doc: |
|
||||
Pixel data as palette indices. Each byte is an index into
|
||||
the palette array.
|
||||
|
||||
palette_entry:
|
||||
doc: RGB color palette entry. Parsed by LegoPaletteEntry::Read().
|
||||
seq:
|
||||
- id: red
|
||||
type: u1
|
||||
doc: Red component (0-255).
|
||||
- id: green
|
||||
type: u1
|
||||
doc: Green component (0-255).
|
||||
- id: blue
|
||||
type: u1
|
||||
doc: Blue component (0-255).
|
||||
819
docs/wdb.ksy
Normal file
819
docs/wdb.ksy
Normal file
@ -0,0 +1,819 @@
|
||||
meta:
|
||||
id: wdb
|
||||
title: World Database File
|
||||
application: LEGO Island
|
||||
file-extension: wdb
|
||||
license: CC0-1.0
|
||||
endian: le
|
||||
|
||||
doc: |
|
||||
World Database file format for LEGO Island (1997). Contains world geometry
|
||||
data including textures, parts (ROI definitions), and models with their
|
||||
transforms and LOD (Level of Detail) information.
|
||||
|
||||
The file is located at `<install_path>/lego/data/world.wdb` on either
|
||||
the hard drive or CD-ROM.
|
||||
|
||||
File structure:
|
||||
1. World headers - list of worlds with part/model references
|
||||
2. Global textures - shared texture data (read once)
|
||||
3. Global parts - shared part definitions (read once)
|
||||
4. Part data blobs - at offsets specified in headers
|
||||
5. Model data blobs - at offsets specified in headers
|
||||
|
||||
seq:
|
||||
- id: num_worlds
|
||||
type: s4
|
||||
doc: Number of world entries in this file.
|
||||
- id: worlds
|
||||
type: world_entry
|
||||
repeat: expr
|
||||
repeat-expr: num_worlds
|
||||
doc: |
|
||||
World entries containing references to parts and models.
|
||||
Each world represents a distinct game area (e.g., "Act1", "Act2", "Act3").
|
||||
- id: global_textures_size
|
||||
type: u4
|
||||
doc: Size in bytes of the global textures block.
|
||||
- id: global_textures
|
||||
type: texture_list
|
||||
size: global_textures_size
|
||||
doc: |
|
||||
Global textures shared across all worlds. These are loaded once
|
||||
when the first world is loaded and cached for subsequent worlds.
|
||||
- id: global_parts_size
|
||||
type: u4
|
||||
doc: Size in bytes of the global parts block.
|
||||
- id: global_parts
|
||||
type: part_list
|
||||
size: global_parts_size
|
||||
doc: |
|
||||
Global parts (ROI definitions) shared across all worlds.
|
||||
Like textures, these are loaded once and cached.
|
||||
|
||||
types:
|
||||
world_entry:
|
||||
doc: |
|
||||
A world entry containing references to parts and models.
|
||||
Parts define reusable geometry, while models are placed instances
|
||||
with specific transforms.
|
||||
seq:
|
||||
- id: name_length
|
||||
type: s4
|
||||
doc: Length of the world name in bytes.
|
||||
- id: name
|
||||
type: str
|
||||
size: name_length
|
||||
encoding: ASCII
|
||||
doc: |
|
||||
World name used to identify this world (e.g., "Act1", "Act2", "Act3").
|
||||
- id: num_parts
|
||||
type: s4
|
||||
doc: Number of part references in this world.
|
||||
- id: parts
|
||||
type: part_reference
|
||||
repeat: expr
|
||||
repeat-expr: num_parts
|
||||
doc: References to part data stored elsewhere in the file.
|
||||
- id: num_models
|
||||
type: s4
|
||||
doc: Number of model entries in this world.
|
||||
- id: models
|
||||
type: model_entry
|
||||
repeat: expr
|
||||
repeat-expr: num_models
|
||||
doc: |
|
||||
Model entries with transform data. Each model references
|
||||
geometry and specifies its position, orientation, and visibility.
|
||||
|
||||
part_reference:
|
||||
doc: |
|
||||
Reference to part data stored at an offset in the file.
|
||||
The actual part data contains ROI definitions with textures and LODs.
|
||||
seq:
|
||||
- id: name_length
|
||||
type: u4
|
||||
doc: Length of the ROI name in bytes.
|
||||
- id: name
|
||||
type: str
|
||||
size: name_length
|
||||
encoding: ASCII
|
||||
doc: ROI (Realtime Object Instance) name identifying this part.
|
||||
- id: data_length
|
||||
type: u4
|
||||
doc: Length of the part data in bytes.
|
||||
- id: data_offset
|
||||
type: u4
|
||||
doc: Absolute file offset to the part data.
|
||||
instances:
|
||||
data:
|
||||
io: _root._io
|
||||
pos: data_offset
|
||||
size: data_length
|
||||
type: part_data
|
||||
doc: The actual part data at the specified offset.
|
||||
|
||||
model_entry:
|
||||
doc: |
|
||||
A model entry defining a placed instance in the world.
|
||||
Contains transform data (location, direction, up vector) and
|
||||
a reference to the model geometry.
|
||||
seq:
|
||||
- id: name_length
|
||||
type: u4
|
||||
doc: Length of the model name in bytes.
|
||||
- id: name
|
||||
type: str
|
||||
size: name_length
|
||||
encoding: ASCII
|
||||
doc: |
|
||||
Model name. Names starting with "isle" have quality variants
|
||||
(isle_lo, isle, isle_hi). Names starting with "haus" have
|
||||
special loading rules.
|
||||
- id: data_length
|
||||
type: u4
|
||||
doc: Length of the model data in bytes.
|
||||
- id: data_offset
|
||||
type: u4
|
||||
doc: Absolute file offset to the model data.
|
||||
- id: presenter_name_length
|
||||
type: u4
|
||||
doc: Length of the presenter class name in bytes.
|
||||
- id: presenter_name
|
||||
type: str
|
||||
size: presenter_name_length
|
||||
encoding: ASCII
|
||||
doc: |
|
||||
Presenter class name determining how the model is created.
|
||||
Common values: "LegoActorPresenter", "LegoEntityPresenter".
|
||||
- id: location
|
||||
type: vertex3
|
||||
doc: World position of the model (X, Y, Z).
|
||||
- id: direction
|
||||
type: vertex3
|
||||
doc: Forward direction vector of the model.
|
||||
- id: up
|
||||
type: vertex3
|
||||
doc: Up direction vector of the model.
|
||||
- id: visible
|
||||
type: u1
|
||||
doc: Visibility flag. Non-zero means the model is initially visible.
|
||||
instances:
|
||||
data:
|
||||
io: _root._io
|
||||
pos: data_offset
|
||||
size: data_length
|
||||
type: model_data
|
||||
doc: The model data (textures, animation, ROI) at the specified offset.
|
||||
|
||||
texture_list:
|
||||
doc: |
|
||||
A list of named textures. Each texture includes palette and pixel data.
|
||||
seq:
|
||||
- id: num_textures
|
||||
type: u4
|
||||
doc: Number of textures in this list.
|
||||
- id: textures
|
||||
type: named_texture
|
||||
repeat: expr
|
||||
repeat-expr: num_textures
|
||||
doc: Array of named textures.
|
||||
|
||||
named_texture:
|
||||
doc: |
|
||||
A named texture with 8-bit indexed color image data.
|
||||
seq:
|
||||
- id: name_length
|
||||
type: u4
|
||||
doc: Length of the texture name in bytes.
|
||||
- id: name
|
||||
type: str
|
||||
size: name_length
|
||||
encoding: ASCII
|
||||
doc: Texture name used for lookup.
|
||||
- id: image
|
||||
type: image
|
||||
doc: The texture image data.
|
||||
|
||||
image:
|
||||
doc: |
|
||||
An 8-bit indexed color image with palette.
|
||||
seq:
|
||||
- id: width
|
||||
type: u4
|
||||
doc: Image width in pixels.
|
||||
- id: height
|
||||
type: u4
|
||||
doc: Image height in pixels.
|
||||
- id: palette_size
|
||||
type: u4
|
||||
doc: Number of entries in the color palette (max 256).
|
||||
- id: palette
|
||||
type: palette_entry
|
||||
repeat: expr
|
||||
repeat-expr: palette_size
|
||||
doc: Color palette entries.
|
||||
- id: pixels
|
||||
size: width * height
|
||||
doc: |
|
||||
Pixel data as palette indices. Each byte is an index into
|
||||
the palette array.
|
||||
|
||||
palette_entry:
|
||||
doc: RGB color palette entry.
|
||||
seq:
|
||||
- id: red
|
||||
type: u1
|
||||
doc: Red component (0-255).
|
||||
- id: green
|
||||
type: u1
|
||||
doc: Green component (0-255).
|
||||
- id: blue
|
||||
type: u1
|
||||
doc: Blue component (0-255).
|
||||
|
||||
part_list:
|
||||
doc: |
|
||||
A list of named parts (ROI definitions). Parts can be shared
|
||||
across multiple models and worlds.
|
||||
seq:
|
||||
- id: texture_info_offset
|
||||
type: u4
|
||||
doc: Offset within this block to texture information.
|
||||
- id: num_rois
|
||||
type: u4
|
||||
doc: Number of ROI definitions.
|
||||
- id: rois
|
||||
type: named_part
|
||||
repeat: expr
|
||||
repeat-expr: num_rois
|
||||
doc: Array of named part definitions.
|
||||
|
||||
named_part:
|
||||
doc: |
|
||||
A named part containing LOD (Level of Detail) definitions.
|
||||
seq:
|
||||
- id: name_length
|
||||
type: u4
|
||||
doc: Length of the ROI name in bytes.
|
||||
- id: name
|
||||
type: str
|
||||
size: name_length
|
||||
encoding: ASCII
|
||||
doc: ROI name for lookup.
|
||||
- id: num_lods
|
||||
type: u4
|
||||
doc: Number of LOD levels for this part.
|
||||
- id: next_roi_offset
|
||||
type: u4
|
||||
doc: Offset to the next ROI definition (for skipping LOD data).
|
||||
- id: lods
|
||||
type: lod
|
||||
repeat: expr
|
||||
repeat-expr: num_lods
|
||||
doc: LOD definitions from highest to lowest detail.
|
||||
|
||||
part_data:
|
||||
doc: |
|
||||
Part data blob containing textures and ROI definitions.
|
||||
This is the format used for part data at offsets in the file.
|
||||
seq:
|
||||
- id: texture_info_offset
|
||||
type: u4
|
||||
doc: Offset within this block to texture information.
|
||||
- id: num_rois
|
||||
type: u4
|
||||
doc: Number of ROI definitions in this part.
|
||||
- id: rois
|
||||
type: named_part
|
||||
repeat: expr
|
||||
repeat-expr: num_rois
|
||||
doc: ROI definitions for this part.
|
||||
|
||||
model_data:
|
||||
doc: |
|
||||
Model data blob containing version info, textures, animation data,
|
||||
and ROI hierarchy. This is the format used for model data at offsets.
|
||||
Parsed by LegoModelPresenter::CreateROI.
|
||||
seq:
|
||||
- id: version
|
||||
type: u4
|
||||
doc: Format version. Must be 19 (MODEL_VERSION).
|
||||
- id: texture_info_offset
|
||||
type: u4
|
||||
doc: Offset within this blob to texture information.
|
||||
- id: num_rois
|
||||
type: u4
|
||||
doc: Number of ROIs (typically 1 for models).
|
||||
- id: anim
|
||||
type: model_anim
|
||||
doc: Animation data for this model.
|
||||
- id: roi
|
||||
type: roi
|
||||
doc: The root ROI containing the model geometry.
|
||||
|
||||
model_anim:
|
||||
doc: |
|
||||
Animation data embedded in model data. This is a simplified form
|
||||
of LegoAnim without camera/scene animation (p_parseScene=FALSE).
|
||||
seq:
|
||||
- id: num_actors
|
||||
type: u4
|
||||
doc: Number of actor entries.
|
||||
- id: actors
|
||||
type: anim_actor_entry
|
||||
repeat: expr
|
||||
repeat-expr: num_actors
|
||||
doc: Actor entries for this animation.
|
||||
- id: duration
|
||||
type: s4
|
||||
doc: Animation duration in milliseconds.
|
||||
- id: root_node
|
||||
type: anim_tree_node
|
||||
doc: Root node of the animation tree.
|
||||
|
||||
anim_actor_entry:
|
||||
doc: |
|
||||
An actor reference in the animation. The name identifies which ROI
|
||||
(Realtime Object Instance) to animate, and the type determines
|
||||
how the actor is managed by the character manager.
|
||||
seq:
|
||||
- id: name_length
|
||||
type: u4
|
||||
doc: Length of the actor name in bytes.
|
||||
- id: name
|
||||
type: str
|
||||
size: name_length
|
||||
encoding: ASCII
|
||||
if: name_length > 0
|
||||
doc: Actor name used to look up the ROI in the scene.
|
||||
- id: actor_type
|
||||
type: u4
|
||||
enum: actor_type
|
||||
if: name_length > 0
|
||||
doc: |
|
||||
Determines how the actor ROI is created and managed.
|
||||
See actor_type enum for possible values.
|
||||
|
||||
anim_tree_node:
|
||||
doc: Node in the animation tree hierarchy.
|
||||
seq:
|
||||
- id: data
|
||||
type: anim_node_data
|
||||
doc: Animation keyframe data for this node.
|
||||
- id: num_children
|
||||
type: u4
|
||||
doc: Number of child nodes.
|
||||
- id: children
|
||||
type: anim_tree_node
|
||||
repeat: expr
|
||||
repeat-expr: num_children
|
||||
doc: Child nodes.
|
||||
|
||||
anim_node_data:
|
||||
doc: Animation keyframe data for a single node.
|
||||
seq:
|
||||
- id: name_length
|
||||
type: u4
|
||||
doc: Length of node name.
|
||||
- id: name
|
||||
type: str
|
||||
size: name_length
|
||||
encoding: ASCII
|
||||
if: name_length > 0
|
||||
doc: Node name for matching to ROI.
|
||||
- id: num_translation_keys
|
||||
type: u2
|
||||
doc: Number of translation keyframes.
|
||||
- id: translation_keys
|
||||
type: translation_key
|
||||
repeat: expr
|
||||
repeat-expr: num_translation_keys
|
||||
doc: Translation keyframes.
|
||||
- id: num_rotation_keys
|
||||
type: u2
|
||||
doc: Number of rotation keyframes.
|
||||
- id: rotation_keys
|
||||
type: rotation_key
|
||||
repeat: expr
|
||||
repeat-expr: num_rotation_keys
|
||||
doc: Rotation keyframes (quaternion format).
|
||||
- id: num_scale_keys
|
||||
type: u2
|
||||
doc: Number of scale keyframes.
|
||||
- id: scale_keys
|
||||
type: scale_key
|
||||
repeat: expr
|
||||
repeat-expr: num_scale_keys
|
||||
doc: Scale keyframes.
|
||||
- id: num_morph_keys
|
||||
type: u2
|
||||
doc: Number of morph (visibility) keyframes.
|
||||
- id: morph_keys
|
||||
type: morph_key
|
||||
repeat: expr
|
||||
repeat-expr: num_morph_keys
|
||||
doc: Morph keyframes.
|
||||
|
||||
anim_key:
|
||||
doc: |
|
||||
Base animation key containing time and flags. The time and flags
|
||||
are packed into a single 32-bit value: bits 0-23 contain the time
|
||||
in milliseconds, and bits 24-31 contain flags.
|
||||
seq:
|
||||
- id: time_and_flags
|
||||
type: s4
|
||||
doc: |
|
||||
Packed time and flags value.
|
||||
- Bits 0-23: Time in milliseconds (mask with 0xFFFFFF)
|
||||
- Bits 24-31: Flags (shift right by 24)
|
||||
instances:
|
||||
time:
|
||||
value: time_and_flags & 0xFFFFFF
|
||||
doc: Keyframe time in milliseconds.
|
||||
flags:
|
||||
value: (time_and_flags >> 24) & 0xFF
|
||||
doc: |
|
||||
Keyframe flags:
|
||||
- 0x01 (active): Key has meaningful data
|
||||
- 0x02 (negate_rotation): Negate quaternion for interpolation
|
||||
- 0x04 (skip_interpolation): Use this key's value without blending
|
||||
|
||||
translation_key:
|
||||
doc: |
|
||||
Translation keyframe containing position offset (LegoTranslationKey).
|
||||
The translation is applied relative to the parent node's transform.
|
||||
seq:
|
||||
- id: key
|
||||
type: anim_key
|
||||
doc: Base key with time and flags.
|
||||
- id: x
|
||||
type: f4
|
||||
doc: X component of translation.
|
||||
- id: y
|
||||
type: f4
|
||||
doc: Y component of translation.
|
||||
- id: z
|
||||
type: f4
|
||||
doc: Z component of translation.
|
||||
|
||||
rotation_key:
|
||||
doc: |
|
||||
Rotation keyframe containing a quaternion (LegoRotationKey).
|
||||
The quaternion is stored as (angle, x, y, z) where angle is the
|
||||
scalar/w component and (x, y, z) is the vector part.
|
||||
seq:
|
||||
- id: key
|
||||
type: anim_key
|
||||
doc: Base key with time and flags.
|
||||
- id: angle
|
||||
type: f4
|
||||
doc: |
|
||||
Quaternion scalar component (w). A value of 1.0 with x=y=z=0
|
||||
represents no rotation (identity quaternion).
|
||||
- id: x
|
||||
type: f4
|
||||
doc: Quaternion x component.
|
||||
- id: y
|
||||
type: f4
|
||||
doc: Quaternion y component.
|
||||
- id: z
|
||||
type: f4
|
||||
doc: Quaternion z component.
|
||||
|
||||
scale_key:
|
||||
doc: |
|
||||
Scale keyframe containing scale factors (LegoScaleKey).
|
||||
Scale is applied relative to the local origin of the node.
|
||||
seq:
|
||||
- id: key
|
||||
type: anim_key
|
||||
doc: Base key with time and flags.
|
||||
- id: x
|
||||
type: f4
|
||||
doc: X scale factor (1.0 = no scaling).
|
||||
- id: y
|
||||
type: f4
|
||||
doc: Y scale factor (1.0 = no scaling).
|
||||
- id: z
|
||||
type: f4
|
||||
doc: Z scale factor (1.0 = no scaling).
|
||||
|
||||
morph_key:
|
||||
doc: |
|
||||
Morph/visibility keyframe (LegoMorphKey). Controls whether the
|
||||
node's ROI is visible at a given time.
|
||||
seq:
|
||||
- id: key
|
||||
type: anim_key
|
||||
doc: Base key with time and flags.
|
||||
- id: visible
|
||||
type: u1
|
||||
doc: Visibility flag. Non-zero means visible.
|
||||
|
||||
roi:
|
||||
doc: |
|
||||
ROI (Realtime Object Instance) defining a piece of geometry.
|
||||
ROIs form a hierarchy with parent-child relationships.
|
||||
seq:
|
||||
- id: name_length
|
||||
type: u4
|
||||
doc: Length of the ROI name in bytes.
|
||||
- id: name
|
||||
type: str
|
||||
size: name_length
|
||||
encoding: ASCII
|
||||
doc: ROI name used for lookup and animation binding.
|
||||
- id: bounding_sphere
|
||||
type: sphere
|
||||
doc: Bounding sphere for visibility culling.
|
||||
- id: bounding_box
|
||||
type: box
|
||||
doc: Axis-aligned bounding box.
|
||||
- id: texture_name_length
|
||||
type: u4
|
||||
doc: Length of texture/material name (0 if none).
|
||||
- id: texture_name
|
||||
type: str
|
||||
size: texture_name_length
|
||||
encoding: ASCII
|
||||
if: texture_name_length > 0
|
||||
doc: |
|
||||
Texture or material name. Names starting with "t_" reference
|
||||
textures; other names are color aliases (e.g., "lego red").
|
||||
- id: shared_lod_list
|
||||
type: u1
|
||||
doc: |
|
||||
If non-zero, LODs are shared with another ROI and not stored here.
|
||||
The ROI name (minus trailing digits) is used to look up shared LODs.
|
||||
- id: num_lods
|
||||
type: u4
|
||||
if: shared_lod_list == 0
|
||||
doc: Number of LOD levels (only if not using shared LODs).
|
||||
- id: next_roi_offset
|
||||
type: u4
|
||||
if: shared_lod_list == 0 and num_lods > 0
|
||||
doc: Offset to continue reading after LOD data.
|
||||
- id: lods
|
||||
type: lod
|
||||
repeat: expr
|
||||
repeat-expr: num_lods
|
||||
if: shared_lod_list == 0 and num_lods > 0
|
||||
doc: LOD definitions from highest to lowest detail.
|
||||
- id: num_children
|
||||
type: u4
|
||||
doc: Number of child ROIs in this hierarchy.
|
||||
- id: children
|
||||
type: roi
|
||||
repeat: expr
|
||||
repeat-expr: num_children
|
||||
doc: Child ROIs forming a hierarchy.
|
||||
|
||||
sphere:
|
||||
doc: Bounding sphere defined by center point and radius.
|
||||
seq:
|
||||
- id: center
|
||||
type: vertex3
|
||||
doc: Center point of the sphere.
|
||||
- id: radius
|
||||
type: f4
|
||||
doc: Radius of the sphere.
|
||||
|
||||
box:
|
||||
doc: Axis-aligned bounding box defined by min and max corners.
|
||||
seq:
|
||||
- id: min
|
||||
type: vertex3
|
||||
doc: Minimum corner (smallest X, Y, Z values).
|
||||
- id: max
|
||||
type: vertex3
|
||||
doc: Maximum corner (largest X, Y, Z values).
|
||||
|
||||
vertex3:
|
||||
doc: A 3D point or vector with X, Y, Z components.
|
||||
seq:
|
||||
- id: x
|
||||
type: f4
|
||||
doc: X component.
|
||||
- id: y
|
||||
type: f4
|
||||
doc: Y component.
|
||||
- id: z
|
||||
type: f4
|
||||
doc: Z component.
|
||||
|
||||
lod:
|
||||
doc: |
|
||||
Level of Detail definition containing mesh data.
|
||||
LODs are ordered from highest to lowest detail.
|
||||
seq:
|
||||
- id: flags
|
||||
type: u4
|
||||
doc: |
|
||||
LOD flags. Bit 0 (0x01) indicates this is an "extra" LOD.
|
||||
Other bits control visibility and rendering behavior.
|
||||
- id: num_meshes
|
||||
type: u4
|
||||
doc: Number of meshes in this LOD.
|
||||
- id: vertex_normal_counts
|
||||
type: u4
|
||||
if: num_meshes > 0
|
||||
doc: |
|
||||
Packed vertex and normal counts.
|
||||
Lower 16 bits: vertex count
|
||||
Upper 15 bits (shifted right by 1): normal count
|
||||
- id: num_texture_vertices
|
||||
type: s4
|
||||
if: num_meshes > 0
|
||||
doc: Number of texture coordinate pairs.
|
||||
- id: vertices
|
||||
type: vertex3
|
||||
repeat: expr
|
||||
repeat-expr: vertex_count
|
||||
if: num_meshes > 0 and vertex_count > 0
|
||||
doc: Vertex positions shared across meshes.
|
||||
- id: normals
|
||||
type: vertex3
|
||||
repeat: expr
|
||||
repeat-expr: normal_count
|
||||
if: num_meshes > 0 and normal_count > 0
|
||||
doc: Normal vectors shared across meshes.
|
||||
- id: texture_vertices
|
||||
type: texture_vertex
|
||||
repeat: expr
|
||||
repeat-expr: num_texture_vertices
|
||||
if: num_meshes > 0 and num_texture_vertices > 0
|
||||
doc: Texture coordinates (UV pairs).
|
||||
- id: meshes
|
||||
type: mesh
|
||||
repeat: expr
|
||||
repeat-expr: num_meshes
|
||||
if: num_meshes > 0
|
||||
doc: Mesh definitions using the shared vertex/normal/UV data.
|
||||
instances:
|
||||
vertex_count:
|
||||
value: '(num_meshes > 0) ? (vertex_normal_counts & 0xFFFF) : 0'
|
||||
doc: Number of vertices (lower 16 bits of packed value).
|
||||
normal_count:
|
||||
value: '(num_meshes > 0) ? ((vertex_normal_counts >> 17) & 0x7FFF) : 0'
|
||||
doc: Number of normals (upper 15 bits, shifted right by 1).
|
||||
|
||||
texture_vertex:
|
||||
doc: Texture coordinate pair (UV).
|
||||
seq:
|
||||
- id: u
|
||||
type: f4
|
||||
doc: U coordinate (horizontal, 0.0-1.0).
|
||||
- id: v
|
||||
type: f4
|
||||
doc: V coordinate (vertical, 0.0-1.0).
|
||||
|
||||
mesh:
|
||||
doc: |
|
||||
A mesh within an LOD, containing polygons and material properties.
|
||||
seq:
|
||||
- id: num_polygons
|
||||
type: u2
|
||||
doc: Number of triangular polygons.
|
||||
- id: num_vertices
|
||||
type: u2
|
||||
doc: Number of vertices used by this mesh.
|
||||
- id: polygon_indices
|
||||
type: polygon_indices
|
||||
repeat: expr
|
||||
repeat-expr: num_polygons
|
||||
doc: Vertex indices for each triangle.
|
||||
- id: num_texture_indices
|
||||
type: u4
|
||||
doc: |
|
||||
Total number of texture indices. Should equal num_polygons * 3
|
||||
if textured, or 0 if untextured.
|
||||
- id: texture_indices
|
||||
type: texture_indices
|
||||
repeat: expr
|
||||
repeat-expr: num_polygons
|
||||
if: num_texture_indices > 0
|
||||
doc: |
|
||||
Texture coordinate indices for each triangle. Unlike polygon_indices,
|
||||
these are simple U32 indices into the LOD's texture_vertices array,
|
||||
not packed values. Each index directly references a UV coordinate pair.
|
||||
- id: properties
|
||||
type: mesh_properties
|
||||
doc: Material and rendering properties.
|
||||
|
||||
polygon_indices:
|
||||
doc: |
|
||||
Three packed indices forming a triangle. Each 32-bit value contains
|
||||
vertex index, normal index, and a "create vertex" flag used by
|
||||
Direct3D Retained Mode mesh building.
|
||||
|
||||
Bit layout of each packed value:
|
||||
- Bits 0-15 (16 bits): When create flag is set, this is the index into
|
||||
the LOD's vertices array. When create flag is clear, this is the index
|
||||
into the mesh's built vertex buffer (referencing a previously created vertex).
|
||||
- Bits 16-30 (15 bits): Index into the LOD's normals array
|
||||
- Bit 31: Create vertex flag. When set (1), a new mesh vertex is created
|
||||
combining position, normal, and texture UV. When clear (0), the value
|
||||
in bits 0-15 references an existing mesh vertex by index.
|
||||
|
||||
The mesh builder creates a vertex buffer where each unique position+normal+UV
|
||||
combination gets an entry. Texture indices (in texture_indices) are only
|
||||
consumed when the create flag is set.
|
||||
seq:
|
||||
- id: a
|
||||
type: u4
|
||||
doc: First packed vertex/normal index with create flag.
|
||||
- id: b
|
||||
type: u4
|
||||
doc: Second packed vertex/normal index with create flag.
|
||||
- id: c
|
||||
type: u4
|
||||
doc: Third packed vertex/normal index with create flag.
|
||||
|
||||
texture_indices:
|
||||
doc: |
|
||||
Three texture coordinate indices forming a triangle. Unlike polygon_indices,
|
||||
these are simple U32 values that directly index into the LOD's texture_vertices
|
||||
array. Each value is only used when the corresponding polygon_indices entry
|
||||
has its create flag (bit 31) set.
|
||||
seq:
|
||||
- id: a
|
||||
type: u4
|
||||
doc: First texture vertex index.
|
||||
- id: b
|
||||
type: u4
|
||||
doc: Second texture vertex index.
|
||||
- id: c
|
||||
type: u4
|
||||
doc: Third texture vertex index.
|
||||
|
||||
mesh_properties:
|
||||
doc: |
|
||||
Material and rendering properties for a mesh.
|
||||
seq:
|
||||
- id: color
|
||||
type: color_rgb
|
||||
doc: Base color of the mesh.
|
||||
- id: alpha
|
||||
type: f4
|
||||
doc: Transparency (0.0 = fully transparent, 1.0 = opaque).
|
||||
- id: shading
|
||||
type: u1
|
||||
enum: shading_mode
|
||||
doc: Shading mode for rendering this mesh.
|
||||
- id: unknown_0x0d
|
||||
type: u1
|
||||
doc: Unknown flag. When > 0, special material is applied.
|
||||
- id: unknown_0x20
|
||||
type: u1
|
||||
doc: Unknown field.
|
||||
- id: use_alias
|
||||
type: u1
|
||||
doc: |
|
||||
If non-zero, texture_name and material_name are looked up
|
||||
as aliases rather than literal names.
|
||||
- id: texture_name_length
|
||||
type: u4
|
||||
doc: Length of texture name (0 if no texture).
|
||||
- id: texture_name
|
||||
type: str
|
||||
size: texture_name_length
|
||||
encoding: ASCII
|
||||
if: texture_name_length > 0
|
||||
doc: Texture name for this mesh.
|
||||
- id: material_name_length
|
||||
type: u4
|
||||
doc: Length of material/color name (0 if none).
|
||||
- id: material_name
|
||||
type: str
|
||||
size: material_name_length
|
||||
encoding: ASCII
|
||||
if: material_name_length > 0
|
||||
doc: |
|
||||
Material or color alias name (e.g., "lego red", "lego blue").
|
||||
|
||||
color_rgb:
|
||||
doc: RGB color with 8-bit components.
|
||||
seq:
|
||||
- id: red
|
||||
type: u1
|
||||
doc: Red component (0-255).
|
||||
- id: green
|
||||
type: u1
|
||||
doc: Green component (0-255).
|
||||
- id: blue
|
||||
type: u1
|
||||
doc: Blue component (0-255).
|
||||
|
||||
enums:
|
||||
shading_mode:
|
||||
0: flat
|
||||
1: gouraud
|
||||
2: wireframe
|
||||
|
||||
actor_type:
|
||||
2: managed_lego_actor
|
||||
3: managed_invisible_roi_trimmed
|
||||
4: managed_invisible_roi
|
||||
5: scene_roi_1
|
||||
6: scene_roi_2
|
||||
Loading…
Reference in New Issue
Block a user