Merge from isle/master

This commit is contained in:
Christian Semmler 2024-11-24 08:00:33 -07:00
commit 5f0575124f
No known key found for this signature in database
GPG key ID: 086DAA1360BEEE5C
56 changed files with 1406 additions and 255 deletions

View file

@ -1,13 +1,16 @@
root = true
[*.{py,txt,editorconfig}]
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true
[*.{cpp,h}]
indent_style = tab
tab_width = 4
insert_final_newline = true
trim_trailing_whitespace = true
root = true
[*.{py,txt,editorconfig}]
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true
[*.{cpp,h}]
indent_style = tab
tab_width = 4
insert_final_newline = true
trim_trailing_whitespace = true
[{CMakeLists.txt,*.cmake}]
indent_size = 2

View file

@ -66,12 +66,22 @@ public:
// FUNCTION: BETA10 0x100f16f0
void SetSkeleton(RaceSkel* p_skeleton) { m_skeleton = p_skeleton; }
void FUN_10017820(MxS32 p_param1, MxS16 p_param2);
// SYNTHETIC: LEGO1 0x10016c70
// CarRace::`scalar deleting destructor'
private:
undefined m_unk0x144[12]; // 0x144
RaceSkel* m_skeleton; // 0x150
static MxS32 g_unk0x100d5d10[];
static MxS32 g_unk0x100d5d30[];
static MxS32 g_unk0x100d5d40[];
static MxS32 g_unk0x100d5d50[];
static MxS32 g_unk0x100d5d60[];
MxS32 m_unk0x144; // 0x144
MxS32 m_unk0x148; // 0x148
MxS32 m_unk0x14c; // 0x14c
RaceSkel* m_skeleton; // 0x150
};
#endif // CARRACE_H

View file

@ -27,7 +27,7 @@ public:
void ParseAction(char* p_extra) override; // vtable+0x20
void VTable0x70(float p_float) override; // vtable+0x70
MxResult VTable0x94(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94
virtual double VTable0xcc(float p_float); // vtable+0xcc
virtual MxFloat VTable0xcc(float p_float); // vtable+0xcc
// SYNTHETIC: LEGO1 0x1000e580
// Doors::`scalar deleting destructor'

View file

@ -102,6 +102,7 @@ public:
};
// VTABLE: LEGO1 0x100d6fb8
// VTABLE: BETA10 0x101b9cc8
// SIZE 0x140
class Isle : public LegoWorld {
public:
@ -116,6 +117,7 @@ public:
MxLong Notify(MxParam& p_param) override; // vtable+0x04
// FUNCTION: LEGO1 0x10030910
// FUNCTION: BETA10 0x10035d70
const char* ClassName() const override // vtable+0x0c
{
// STRING: LEGO1 0x100f0458

View file

@ -61,9 +61,18 @@ public:
MxLong HandleClick(LegoEventNotificationParam&) override; // vtable+0x6c
MxLong HandlePathStruct(LegoPathStructNotificationParam&) override; // vtable+0x70
MxLong HandleEndAction(MxEndActionNotificationParam&) override; // vtable+0x74
void FUN_10016930(MxS32 p_param1, MxS16 p_param2);
private:
static MxS32 g_unk0x100f0c78;
};
// SYNTHETIC: LEGO1 0x1000f530
// SYNTHETIC: BETA10 0x100a9b70
// JetskiRace::`scalar deleting destructor'
// SYNTHETIC: BETA10 0x100aa150
// JetskiRace::~JetskiRace
#endif // JETSKIRACE_H

View file

@ -29,8 +29,8 @@ struct LegoBuildingInfo {
MxS8 m_unk0x11; // 0x11
MxS8 m_initialUnk0x11; // 0x12 - initial value loaded to m_unk0x11
MxU8 m_flags; // 0x13
float m_unk0x014; // 0x14
const char* m_unk0x18; // 0x18
float m_unk0x14; // 0x14
const char* m_boundaryName; // 0x18
float m_x; // 0x1c
float m_y; // 0x20
float m_z; // 0x24
@ -100,7 +100,7 @@ private:
static MxU32 g_maxSound;
MxU8 m_nextVariant; // 0x08
MxU8 m_unk0x09; // 0x09
MxBool m_unk0x09; // 0x09
AnimEntry* m_entries[5]; // 0x0c
MxS8 m_numEntries; // 0x20
LegoCacheSound* m_sound; // 0x24

View file

@ -57,11 +57,10 @@ public:
LegoCacheSound* FindSoundByKey(const char* p_key);
LegoCacheSound* ManageSoundEntry(LegoCacheSound* p_sound);
LegoCacheSound* Play(const char* p_key, const char* p_name, MxBool p_looping);
LegoCacheSound* Play(LegoCacheSound* p_sound, const char* p_name, MxBool p_looping);
void Destroy(LegoCacheSound*& p_sound);
private:
LegoCacheSound* Play(LegoCacheSound* p_sound, const char* p_name, MxBool p_looping);
Set100d6b4c m_set; // 0x04
List100d6b4c m_list; // 0x14
};

View file

@ -10,6 +10,7 @@ class MxDSAction;
class Vector3;
// VTABLE: LEGO1 0x100d4858
// VTABLE: BETA10 0x101b9388
// SIZE 0x68
class LegoEntity : public MxEntity {
public:
@ -38,6 +39,7 @@ public:
MxLong Notify(MxParam& p_param) override; // vtable+0x04
// FUNCTION: LEGO1 0x1000c2f0
// FUNCTION: BETA10 0x10012730
const char* ClassName() const override // vtable+0x0c
{
// STRING: LEGO1 0x100f0064
@ -90,6 +92,8 @@ public:
LegoROI* GetROI() { return m_roi; }
MxU8 GetType() { return m_type; }
// FUNCTION: BETA10 0x1007ff00
MxBool GetCameraFlag() { return m_cameraFlag; }
void SetFlags(MxU8 p_flags) { m_flags = p_flags; }
@ -114,8 +118,11 @@ protected:
// For tokens from the extra string that look like this:
// "Action:openram;\lego\scripts\Race\CarRaceR;0"
Extra::ActionType m_actionType; // 0x5c
char* m_filename; // 0x60
MxS32 m_targetEntityId; // 0x64
// variable name verified by BETA10 0x1007eddf
char* m_siFile; // 0x60
MxS32 m_targetEntityId; // 0x64
};
// SYNTHETIC: LEGO1 0x1000c3b0

View file

@ -7,12 +7,17 @@
// VTABLE: LEGO1 0x100da228 LegoRaceActor
// VTABLE: LEGO1 0x100da230 LegoAnimActor
// VTABLE: LEGO1 0x100da240 LegoPathActor
// VTABLE: BETA10 0x101bd348 LegoCarRaceActor
// VTABLE: BETA10 0x101bd370 LegoRaceActor
// VTABLE: BETA10 0x101bd378 LegoAnimActor
// VTABLE: BETA10 0x101bd390 LegoPathActor
// SIZE 0x1a8
class LegoJetskiRaceActor : public virtual LegoCarRaceActor {
public:
LegoJetskiRaceActor();
// FUNCTION: LEGO1 0x10081d90
// FUNCTION: BETA10 0x100aa920
const char* ClassName() const override // vtable+0x0c
{
// STRING: LEGO1 0x100f0554
@ -20,6 +25,7 @@ public:
}
// FUNCTION: LEGO1 0x10081db0
// FUNCTION: BETA10 0x100aa960
MxBool IsA(const char* p_name) const override // vtable+0x10
{
return !strcmp(p_name, LegoJetskiRaceActor::ClassName()) || LegoCarRaceActor::IsA(p_name);
@ -46,4 +52,16 @@ public:
// LegoJetskiRaceActor::~LegoJetskiRaceActor
};
// GLOBAL: LEGO1 0x100da1f0
// LegoJetskiRaceActor::`vbtable'{for `LegoJetskiRaceActor'}
// GLOBAL: LEGO1 0x100da1e8
// LegoJetskiRaceActor::`vbtable'{for `LegoAnimActor'}
// GLOBAL: LEGO1 0x100da1d8
// LegoJetskiRaceActor::`vbtable'{for `LegoRaceActor'}
// GLOBAL: LEGO1 0x100da1c8
// LegoJetskiRaceActor::`vbtable'{for `LegoCarRaceActor'}
#endif // LEGOJETSKIRACEACTOR_H

View file

@ -82,6 +82,12 @@ public:
// FUNCTION: BETA10 0x100b0f40
void SetLinearVel(MxFloat p_linearVel) { m_linearVel = p_linearVel; }
// FUNCTION: BETA10 0x100c99e0
void SetDeadZone(MxS32 p_deadZone) { m_deadZone = p_deadZone; }
// FUNCTION: BETA10 0x100c7880
void SetTrackDefault(MxS32 p_trackDefault) { m_trackDefault = p_trackDefault; }
MxFloat GetLinearVel() { return m_linearVel; }
MxFloat GetRotationalVel() { return m_rotationalVel; }
MxFloat GetMaxLinearVel() { return m_maxLinearVel; }
@ -91,6 +97,9 @@ public:
m_trackDefault = 0;
}
// FUNCTION: BETA10 0x100c9a10
int GetDefaultDeadZone() { return g_defdeadZone; }
// SYNTHETIC: LEGO1 0x10054c10
// LegoNavController::`scalar deleting destructor'

View file

@ -15,6 +15,7 @@ struct LegoUnknown100db7f4;
class LegoWEEdge;
extern MxLong g_unk0x100f3308;
extern const char* g_strHIT_WALL_SOUND;
// VTABLE: LEGO1 0x100d6e28
// SIZE 0x154

View file

@ -81,6 +81,7 @@ private:
// _Tree<LegoPathActor *,LegoPathActor *,set<LegoPathActor *,LegoPathActorSetCompare,allocator<LegoPathActor *> >::_Kfn,LegoPathActorSetCompare,allocator<LegoPathActor *> >::erase
// TEMPLATE: LEGO1 0x1002c440
// TEMPLATE: BETA10 0x100b6480
// _Tree<LegoPathActor *,LegoPathActor *,set<LegoPathActor *,LegoPathActorSetCompare,allocator<LegoPathActor *> >::_Kfn,LegoPathActorSetCompare,allocator<LegoPathActor *> >::find
// TEMPLATE: LEGO1 0x1002c4c0
@ -93,6 +94,7 @@ private:
// set<LegoPathActor *,LegoPathActorSetCompare,allocator<LegoPathActor *> >::~set<LegoPathActor *,LegoPathActorSetCompare,allocator<LegoPathActor *> >
// TEMPLATE: LEGO1 0x1002c6c0
// TEMPLATE: BETA10 0x10020760
// Set<LegoPathActor *,LegoPathActorSetCompare>::~Set<LegoPathActor *,LegoPathActorSetCompare>
// TEMPLATE: LEGO1 0x1002eb10
@ -101,6 +103,9 @@ private:
// TEMPLATE: LEGO1 0x1002ebc0
// _Tree<LegoAnimPresenter *,LegoAnimPresenter *,set<LegoAnimPresenter *,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::_Kfn,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::_Min
// TEMPLATE: LEGO1 0x100822a0
// _Tree<LegoPathActor *,LegoPathActor *,set<LegoPathActor *,LegoPathActorSetCompare,allocator<LegoPathActor *> >::_Kfn,LegoPathActorSetCompare,allocator<LegoPathActor *> >::_Min
// TEMPLATE: LEGO1 0x10045d80
// _Tree<LegoPathActor *,LegoPathActor *,set<LegoPathActor *,LegoPathActorSetCompare,allocator<LegoPathActor *> >::_Kfn,LegoPathActorSetCompare,allocator<LegoPathActor *> >::iterator::_Dec
@ -137,6 +142,9 @@ private:
// TEMPLATE: LEGO1 0x10057210
// Set<LegoAnimPresenter *,LegoAnimPresenterSetCompare>::~Set<LegoAnimPresenter *,LegoAnimPresenterSetCompare>
// TEMPLATE: BETA10 0x10082de0
// set<LegoAnimPresenter *,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::begin
// TEMPLATE: LEGO1 0x100573e0
// _Tree<LegoPathActor *,LegoPathActor *,set<LegoPathActor *,LegoPathActorSetCompare,allocator<LegoPathActor *> >::_Kfn,LegoPathActorSetCompare,allocator<LegoPathActor *> >::begin
@ -176,6 +184,27 @@ private:
// TEMPLATE: LEGO1 0x10081cd0
// _Tree<LegoPathActor *,LegoPathActor *,set<LegoPathActor *,LegoPathActorSetCompare,allocator<LegoPathActor *> >::_Kfn,LegoPathActorSetCompare,allocator<LegoPathActor *> >::lower_bound
// TEMPLATE: BETA10 0x10082b90
// _Tree<LegoAnimPresenter *,LegoAnimPresenter *,set<LegoAnimPresenter *,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::_Kfn,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::const_iterator::operator++
// TEMPLATE: BETA10 0x10082ee0
// set<LegoAnimPresenter *,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::end
// TEMPLATE: BETA10 0x10082b40
// _Tree<LegoAnimPresenter *,LegoAnimPresenter *,set<LegoAnimPresenter *,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::_Kfn,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::const_iterator::operator*
// TEMPLATE: BETA10 0x10021dc0
// Set<LegoPathActor *,LegoPathActorSetCompare>::Set<LegoPathActor *,LegoPathActorSetCompare>
// TEMPLATE: BETA10 0x100202d0
// set<LegoPathActor *,LegoPathActorSetCompare,allocator<LegoPathActor *> >::begin
// TEMPLATE: BETA10 0x10020030
// _Tree<LegoPathActor *,LegoPathActor *,set<LegoPathActor *,LegoPathActorSetCompare,allocator<LegoPathActor *> >::_Kfn,LegoPathActorSetCompare,allocator<LegoPathActor *> >::const_iterator::operator++
// TEMPLATE: BETA10 0x100203d0
// set<LegoPathActor *,LegoPathActorSetCompare,allocator<LegoPathActor *> >::end
// GLOBAL: LEGO1 0x100f11a4
// _Tree<LegoPathActor *,LegoPathActor *,set<LegoPathActor *,LegoPathActorSetCompare,allocator<LegoPathActor *> >::_Kfn,LegoPathActorSetCompare,allocator<LegoPathActor *> >::_Nil

View file

@ -28,7 +28,10 @@ public:
return new LegoPathStructNotificationParam(m_type, m_sender, m_trigger, m_data);
} // vtable+0x04
// FUNCTION: BETA10 0x10024270
MxU8 GetTrigger() { return m_trigger; }
// FUNCTION: BETA10 0x100242a0
MxS16 GetData() { return m_data; }
protected:

View file

@ -81,8 +81,6 @@ public:
Entry* GetState(MxU8 p_id);
undefined4 GetUnknown0x28() { return m_unk0x28; }
// SYNTHETIC: LEGO1 0x1000f6f0
// RaceState::~RaceState
@ -151,12 +149,12 @@ public:
// LegoRace::`scalar deleting destructor'
protected:
undefined4 m_unk0xf8; // 0xf8
undefined4 m_unk0xfc; // 0xfc
undefined4 m_unk0x100; // 0x100
undefined4 m_unk0x104; // 0x104
undefined4 m_unk0x108; // 0x108
undefined4 m_unk0x10c; // 0x10c
MxS32 m_unk0xf8; // 0xf8
MxS32 m_unk0xfc; // 0xfc
MxS32 m_unk0x100; // 0x100
MxS32 m_unk0x104; // 0x104
MxS32 m_unk0x108; // 0x108
MxS32 m_unk0x10c; // 0x10c
LegoRaceActor* m_unk0x110[3]; // 0x110
LegoGameState::Area m_destLocation; // 0x11c
LegoPathActor* m_pathActor; // 0x120

View file

@ -43,6 +43,7 @@ public:
MxLong Notify(MxParam& p_param) override; // vtable+0x04
// FUNCTION: LEGO1 0x100142a0
// FUNCTION: BETA10 0x100cd500
const char* ClassName() const override // vtable+0x0c
{
// STRING: LEGO1 0x100f0548
@ -76,6 +77,7 @@ public:
virtual MxU32 HandleSkeletonKicks(float p_param1);
static void FUN_10012de0();
static void FUN_10012e00();
static void FUN_10013670();
// SYNTHETIC: LEGO1 0x10014240
@ -115,6 +117,8 @@ private:
static MxLong g_timeLastSoundPlayed;
static MxS32 g_unk0x100f0b88;
static MxBool g_unk0x100f0b8c;
static undefined4 g_unk0x100f0bac;
static undefined4 g_unk0x100f0bb0;
};
#endif // LEGORACERS_H

View file

@ -3,6 +3,10 @@
#include "legoraceactor.h"
extern const char* g_raceState;
extern const char* g_fuel;
extern const char* g_racing;
// VTABLE: LEGO1 0x100da0c0 LegoRaceActor
// VTABLE: LEGO1 0x100da0c8 LegoAnimActor
// VTABLE: LEGO1 0x100da0d8 LegoPathActor

View file

@ -40,10 +40,10 @@ class LegoTreeNode;
extern MxAtomId* g_isleScript;
LegoEntity* PickEntity(MxLong, MxLong);
LegoROI* PickROI(MxLong, MxLong);
LegoROI* PickParentROI(MxLong p_a, MxLong p_b);
void FUN_1003dde0(LegoROI* p_param1, MxFloat p_param2);
LegoEntity* PickEntity(MxLong p_x, MxLong p_y);
LegoROI* PickROI(MxLong p_x, MxLong p_y);
LegoROI* PickRootROI(MxLong p_x, MxLong p_y);
void RotateY(LegoROI* p_roi, MxFloat p_angle);
MxBool SpheresIntersect(const BoundingSphere& p_sphere1, const BoundingSphere& p_sphere2);
MxBool FUN_1003ded0(MxFloat p_param1[2], MxFloat p_param2[3], MxFloat p_param3[3]);
MxBool TransformWorldToScreen(const MxFloat p_world[3], MxFloat p_screen[4]);

View file

@ -253,7 +253,7 @@ MxLong Ambulance::HandleButtonDown(LegoControlManagerNotificationParam& p_param)
return 1;
}
roi = PickParentROI(p_param.GetX(), p_param.GetY());
roi = PickRootROI(p_param.GetX(), p_param.GetY());
if (roi != NULL && !strcmpi(roi->GetName(), "gd")) {
m_unk0x170 = 3;

View file

@ -4,11 +4,24 @@
#include "mxmisc.h"
#include "mxtimer.h"
#include "roi/legoroi.h"
#include "tgl/tglvector.h"
#include <assert.h>
DECOMP_SIZE_ASSERT(Doors, 0x1f8)
// GLOBAL: LEGO1 0x100d8e7c
// GLOBAL: BETA10 0x101b954c
MxFloat g_unk0x100d8e7c = 1000.0f;
// GLOBAL: LEGO1 0x100d8e80
// GLOBAL: BETA10 0x101b9550
MxFloat g_unk0x100d8e80 = 4000.0f;
// GLOBAL: LEGO1 0x100d8e84
// GLOBAL: BETA10 0x101b9554
MxFloat g_unk0x100d8e84 = 6000.0f;
// FUNCTION: LEGO1 0x10066100
// FUNCTION: BETA10 0x10026850
MxResult Doors::VTable0x94(LegoPathActor* p_actor, MxBool p_bool)
@ -25,11 +38,29 @@ MxResult Doors::VTable0x94(LegoPathActor* p_actor, MxBool p_bool)
return m_unk0x1f4 < 0.001 ? SUCCESS : FAILURE;
}
// STUB: LEGO1 0x10066190
// FUNCTION: LEGO1 0x10066190
// FUNCTION: BETA10 0x1002696b
double Doors::VTable0xcc(float p_float)
MxFloat Doors::VTable0xcc(float p_float)
{
return 0.0;
MxFloat fVar1;
fVar1 = p_float - m_unk0x158;
if (fVar1 <= 0.0f) {
return 0.0f;
}
if (fVar1 <= g_unk0x100d8e7c) {
return fVar1 * 1.570796 / g_unk0x100d8e7c;
}
else if (fVar1 <= g_unk0x100d8e7c + g_unk0x100d8e80) {
return 1.570796012878418; // Pi / 2
}
else if (fVar1 <= g_unk0x100d8e84) {
return (1.0 - ((fVar1 - g_unk0x100d8e80) - g_unk0x100d8e7c) / g_unk0x100d8e7c) * 1.570796;
}
return 0.0f;
}
// FUNCTION: LEGO1 0x10066250
@ -71,7 +102,7 @@ void Doors::VTable0x70(float p_float)
m_unk0x1f4 = local8;
}
if (m_unk0x158 + 6000.0f < p_float) {
if (m_unk0x158 + g_unk0x100d8e84 < p_float) {
m_ltDoor->FUN_100a58f0(m_ltDoorLocal);
m_rtDoor->FUN_100a58f0(m_rtDoorLocal);
m_ltDoor->VTable0x14();

View file

@ -1,7 +1,12 @@
#include "racecar.h"
#include "isle.h"
#include "isle_actions.h"
#include "legocontrolmanager.h"
#include "legoutils.h"
#include "legoworld.h"
#include "misc.h"
#include "mxtransitionmanager.h"
DECOMP_SIZE_ASSERT(RaceCar, 0x164)
@ -18,16 +23,29 @@ RaceCar::~RaceCar()
Exit();
}
// STUB: LEGO1 0x10028490
// FUNCTION: LEGO1 0x10028490
MxResult RaceCar::Create(MxDSAction& p_dsAction)
{
// TODO
return SUCCESS;
MxResult result = IslePathActor::Create(p_dsAction);
m_world = CurrentWorld();
if (m_world) {
m_world->Add(this);
}
ControlManager()->Register(this);
return result;
}
// STUB: LEGO1 0x100284d0
// FUNCTION: LEGO1 0x100284d0
MxLong RaceCar::HandleClick()
{
// TODO
return 0;
if (!FUN_1003ef60()) {
return 1;
}
Isle* isle = (Isle*) FindWorld(*g_isleScript, IsleScript::c__Isle);
isle->SetDestLocation(LegoGameState::Area::e_carrace);
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
return 1;
}

View file

@ -12,6 +12,7 @@
#include "legocontrolmanager.h"
#include "legogamestate.h"
#include "legoinputmanager.h"
#include "legomain.h"
#include "legosoundmanager.h"
#include "legoutils.h"
#include "misc.h"
@ -553,7 +554,7 @@ MxResult LegoCarBuild::Tickle()
}
if (m_unk0x100 == 5 && m_unk0x110) {
FUN_1003dde0(m_unk0x110, g_unk0x100d65a4);
RotateY(m_unk0x110, g_unk0x100d65a4);
}
if (m_unk0x10a) {
@ -1254,7 +1255,7 @@ void LegoCarBuild::FUN_10024ef0()
m_buildState->m_animationState = LegoVehicleBuildState::e_cutscene;
FUN_10025720(FUN_10025d70());
m_buildState->m_unk0x4c += 1;
FUN_10015820(FALSE, 7);
FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen);
}
// FUNCTION: LEGO1 0x10024f30

View file

@ -408,7 +408,7 @@ void LegoCarBuildAnimPresenter::FUN_10079160()
root = m_anim->GetRoot();
data2 = (LegoAnimNodeData*) root->GetData();
destData->FUN_100a0360(data2->GetName());
destData->SetName(data2->GetName());
destNode->SetNumChildren(1);
children = new LegoTreeNode*;

View file

@ -9,10 +9,13 @@
#include "legoworld.h"
#include "misc.h"
#include "misc/legostorage.h"
#include "mxdebug.h"
#include "mxmisc.h"
#include "mxticklemanager.h"
#include "mxtimer.h"
#include <vec.h>
DECOMP_SIZE_ASSERT(LegoBuildingManager, 0x30)
DECOMP_SIZE_ASSERT(LegoBuildingInfo, 0x2c)
DECOMP_SIZE_ASSERT(LegoBuildingManager::AnimEntry, 0x14)
@ -249,7 +252,7 @@ void LegoBuildingManager::Init()
}
m_nextVariant = 0;
m_unk0x09 = 0;
m_unk0x09 = FALSE;
m_numEntries = 0;
m_sound = NULL;
m_unk0x28 = FALSE;
@ -270,7 +273,7 @@ void LegoBuildingManager::LoadWorldInfo()
LegoEntity* entity = (LegoEntity*) world->Find("MxEntity", g_buildingInfoVariants[0]);
if (entity) {
entity->GetROI()->SetVisibility(TRUE);
m_unk0x09 = 0;
m_unk0x09 = FALSE;
}
}
else {
@ -282,7 +285,7 @@ void LegoBuildingManager::LoadWorldInfo()
}
}
m_unk0x09 = 0;
m_unk0x09 = FALSE;
}
// FUNCTION: LEGO1 0x1002fa90
@ -297,7 +300,7 @@ void LegoBuildingManager::CreateBuilding(MxS32 p_index, LegoWorld* p_world)
LegoROI* roi = entity->GetROI();
AdjustHeight(p_index);
MxMatrix mat = roi->GetLocal2World();
mat[3][1] = g_buildingInfo[p_index].m_unk0x014;
mat[3][1] = g_buildingInfo[p_index].m_unk0x14;
roi->UpdateTransformationRelativeToParent(mat);
VideoManager()->Get3DManager()->Moved(*roi);
}
@ -312,7 +315,7 @@ void LegoBuildingManager::Reset()
g_buildingInfo[i].m_entity = NULL;
}
m_unk0x09 = 0;
m_unk0x09 = FALSE;
for (i = 0; i < m_numEntries; i++) {
delete m_entries[i];
@ -400,13 +403,13 @@ void LegoBuildingManager::AdjustHeight(MxS32 p_index)
{
if (g_buildingInfo[p_index].m_unk0x11 > 0) {
float value = g_buildingInfoDownshift[p_index] - g_buildingInfo[p_index].m_unk0x11;
g_buildingInfo[p_index].m_unk0x014 =
g_buildingInfoInit[p_index].m_unk0x014 - value * g_buildingInfoDownshiftScale[p_index];
g_buildingInfo[p_index].m_unk0x14 =
g_buildingInfoInit[p_index].m_unk0x14 - value * g_buildingInfoDownshiftScale[p_index];
}
else if (g_buildingInfo[p_index].m_unk0x11 == 0) {
float value = g_buildingInfoDownshift[p_index] - g_buildingInfo[p_index].m_unk0x11;
g_buildingInfo[p_index].m_unk0x014 =
g_buildingInfoInit[p_index].m_unk0x014 - value * g_buildingInfoDownshiftScale[p_index];
g_buildingInfo[p_index].m_unk0x14 =
g_buildingInfoInit[p_index].m_unk0x14 - value * g_buildingInfoDownshiftScale[p_index];
if (g_buildingInfo[p_index].m_entity != NULL) {
LegoROI* roi = g_buildingInfo[p_index].m_entity->GetROI();
@ -416,7 +419,7 @@ void LegoBuildingManager::AdjustHeight(MxS32 p_index)
}
}
else {
g_buildingInfo[p_index].m_unk0x014 = g_buildingInfoInit[p_index].m_unk0x014;
g_buildingInfo[p_index].m_unk0x14 = g_buildingInfoInit[p_index].m_unk0x14;
}
}
@ -594,10 +597,54 @@ MxBool LegoBuildingManager::FUN_10030000(LegoEntity* p_entity)
return FUN_10030030(info - g_buildingInfo);
}
// STUB: LEGO1 0x10030030
inline LegoBuildingInfo* GetBuildingInfo(MxS32 p_index)
{
if (p_index >= sizeOfArray(g_buildingInfo)) {
return NULL;
}
return &g_buildingInfo[p_index];
}
// FUNCTION: LEGO1 0x10030030
MxBool LegoBuildingManager::FUN_10030030(MxS32 p_index)
{
return TRUE;
if (p_index >= sizeOfArray(g_buildingInfo)) {
return FALSE;
}
LegoBuildingInfo* info = GetBuildingInfo(p_index);
if (!info) {
return FALSE;
}
MxBool result = TRUE;
if (info->m_unk0x11 < 0) {
info->m_unk0x11 = g_buildingInfoDownshift[p_index];
}
if (info->m_unk0x11 <= 0) {
result = FALSE;
}
else {
LegoROI* roi = info->m_entity->GetROI();
info->m_unk0x11 -= 2;
if (info->m_unk0x11 == 1) {
info->m_unk0x11 = 0;
roi->SetVisibility(FALSE);
}
else {
AdjustHeight(p_index);
MxMatrix mat = roi->GetLocal2World();
mat[3][1] = g_buildingInfo[p_index].m_unk0x14;
roi->UpdateTransformationRelativeToParent(mat);
VideoManager()->Get3DManager()->Moved(*roi);
}
}
return result;
}
// FUNCTION: LEGO1 0x10030110
@ -638,18 +685,77 @@ void LegoBuildingManager::ScheduleAnimation(LegoEntity* p_entity, MxLong p_lengt
FUN_100307b0(p_entity, -2);
}
// STUB: LEGO1 0x10030220
// FUNCTION: LEGO1 0x10030220
MxResult LegoBuildingManager::Tickle()
{
// WIP, included some of this to understand the AnimEntry array.
LegoTime time = Timer()->GetTime();
MxLong time = Timer()->GetTime();
if (m_numEntries != 0) {
if (m_numEntries > 0) {
for (MxS32 i = 0; i < m_numEntries; i++) {
AnimEntry* entry = m_entries[i];
if (entry->m_time <= time) {
// Code to animate and play sounds
for (MxS32 i = 0; i < m_numEntries; i++) {
AnimEntry** ppEntry = &m_entries[i];
AnimEntry* entry = *ppEntry;
if (m_world != CurrentWorld() || !entry->m_entity) {
delete entry;
m_numEntries--;
if (m_numEntries != i) {
m_entries[i] = m_entries[m_numEntries];
m_entries[m_numEntries] = NULL;
}
break;
}
if (entry->m_time - time > 1000) {
break;
}
if (!entry->m_muted) {
entry->m_muted = TRUE;
SoundManager()->GetCacheSoundManager()->Play(m_sound, entry->m_roi->GetName(), FALSE);
}
MxMatrix local48;
MxMatrix locald8;
MxMatrix local120(entry->m_roi->GetLocal2World());
Mx3DPointFloat local134(local120[3]);
ZEROVEC3(local120[3]);
locald8.SetIdentity();
local48 = local120;
local134[1] = sin(((entry->m_time - time) * 10) * 0.0062831999f) * 0.4 + (entry->m_unk0x0c -= 0.05);
SET3(local120[3], local134);
entry->m_roi->UpdateTransformationRelativeToParent(local120);
VideoManager()->Get3DManager()->Moved(*entry->m_roi);
if (entry->m_time < time) {
LegoBuildingInfo* info = GetInfo(entry->m_entity);
if (info->m_unk0x11 && !m_unk0x28) {
MxS32 index = info - g_buildingInfo;
AdjustHeight(index);
MxMatrix mat = entry->m_roi->GetLocal2World();
mat[3][1] = g_buildingInfo[index].m_unk0x14;
entry->m_roi->UpdateTransformationRelativeToParent(mat);
VideoManager()->Get3DManager()->Moved(*entry->m_roi);
}
else {
info->m_unk0x11 = 0;
entry->m_roi->SetVisibility(FALSE);
}
delete entry;
m_numEntries--;
if (m_numEntries != i) {
i--;
*ppEntry = m_entries[m_numEntries];
m_entries[m_numEntries] = NULL;
}
}
}
@ -673,23 +779,87 @@ void LegoBuildingManager::FUN_10030590()
if (g_buildingInfo[i].m_entity != NULL) {
LegoROI* roi = g_buildingInfo[i].m_entity->GetROI();
MxMatrix mat = roi->GetLocal2World();
mat[3][1] = g_buildingInfo[i].m_unk0x014;
mat[3][1] = g_buildingInfo[i].m_unk0x14;
roi->UpdateTransformationRelativeToParent(mat);
VideoManager()->Get3DManager()->Moved(*roi);
}
}
}
// STUB: LEGO1 0x10030630
// FUNCTION: LEGO1 0x10030630
// FUNCTION: BETA10 0x100648ab
MxResult LegoBuildingManager::FUN_10030630()
{
LegoWorld* world = CurrentWorld();
if (world == NULL) {
return FAILURE;
}
for (MxS32 i = 0; i < sizeOfArray(g_buildingInfo); i++) {
if (g_buildingInfo[i].m_entity != NULL && g_buildingInfo[i].m_boundaryName != NULL) {
g_buildingInfo[i].m_boundary = world->FindPathBoundary(g_buildingInfo[i].m_boundaryName);
if (g_buildingInfo[i].m_boundary != NULL) {
Mx3DPointFloat position(g_buildingInfo[i].m_x, g_buildingInfo[i].m_y, g_buildingInfo[i].m_z);
LegoPathBoundary* boundary = g_buildingInfo[i].m_boundary;
for (MxS32 j = 0; j < boundary->GetNumEdges(); j++) {
Mx4DPointFloat* normal = boundary->GetEdgeNormal(j);
if (position.Dot(normal, &position) + (*normal)[3] < -0.001) {
MxTrace(
"Building %d shot location (%g, %g, %g) is not in boundary %s.\n",
i,
position[0],
position[1],
position[2],
boundary->GetName()
);
g_buildingInfo[i].m_boundary = NULL;
break;
}
}
if (g_buildingInfo[i].m_boundary != NULL) {
Mx4DPointFloat& unk0x14 = *g_buildingInfo[i].m_boundary->GetUnknown0x14();
if (position.Dot(&position, &unk0x14) + unk0x14[3] <= 0.001 &&
position.Dot(&position, &unk0x14) + unk0x14[3] >= -0.001) {
continue;
}
g_buildingInfo[i].m_y =
-((unk0x14[3] + unk0x14[0] * position[0] + unk0x14[2] * position[2]) / unk0x14[1]);
MxTrace(
"Building %d shot location (%g, %g, %g) is not on plane of boundary %s...adjusting to (%g, %g, "
"%g)\n",
i,
position[0],
position[1],
position[2],
g_buildingInfo[i].m_boundary->GetName(),
position[0],
g_buildingInfo[i].m_y,
position[2]
);
}
}
else {
MxTrace("Building %d is in boundary %s that does not exist.\n", i, g_buildingInfo[i].m_boundaryName);
}
}
}
m_unk0x09 = TRUE;
return SUCCESS;
}
// FUNCTION: LEGO1 0x10030790
LegoBuildingInfo* LegoBuildingManager::GetInfoArray(MxS32& p_length)
{
if (m_unk0x09 == 0) {
if (!m_unk0x09) {
FUN_10030630();
}

View file

@ -222,6 +222,7 @@ done:
}
// FUNCTION: LEGO1 0x10083500
// FUNCTION: BETA10 0x10074345
LegoROI* LegoCharacterManager::GetActorROI(const char* p_name, MxBool p_createEntity)
{
LegoCharacter* character = NULL;
@ -428,6 +429,7 @@ void LegoCharacterManager::ReleaseAutoROI(LegoROI* p_roi)
}
// FUNCTION: LEGO1 0x10084010
// FUNCTION: BETA10 0x10074e20
void LegoCharacterManager::RemoveROI(LegoROI* p_roi)
{
VideoManager()->Get3DManager()->Remove(*p_roi);
@ -944,6 +946,7 @@ void LegoCharacterManager::SetCustomizeAnimFile(const char* p_value)
}
// FUNCTION: LEGO1 0x10085210
// FUNCTION: BETA10 0x10076995
LegoROI* LegoCharacterManager::CreateAutoROI(const char* p_name, const char* p_lodName, MxBool p_createEntity)
{
LegoROI* roi = NULL;

View file

@ -206,6 +206,7 @@ void LegoGameState::RemoveActor()
}
// FUNCTION: LEGO1 0x10039940
// FUNCTION: BETA10 0x10084069
void LegoGameState::ResetROI()
{
if (m_actorId) {
@ -215,8 +216,8 @@ void LegoGameState::ResetROI()
LegoROI* roi = actor->GetROI();
if (roi) {
VideoManager()->Get3DManager()->GetLego3DView()->Remove(*roi);
VideoManager()->Get3DManager()->GetLego3DView()->Add(*roi);
VideoManager()->Get3DManager()->Remove(*roi);
VideoManager()->Get3DManager()->Add(*roi);
}
}
}

View file

@ -16,6 +16,7 @@
#include "viewmanager/viewmanager.h"
#include <stdio.h>
#include <vec.h>
DECOMP_SIZE_ASSERT(LegoPlantManager, 0x2c)
DECOMP_SIZE_ASSERT(LegoPlantManager::AnimEntry, 0x0c)
@ -521,9 +522,75 @@ void LegoPlantManager::ScheduleAnimation(LegoEntity* p_entity, MxLong p_length)
FUN_100271b0(p_entity, -1);
}
// STUB: LEGO1 0x10026e00
// FUNCTION: LEGO1 0x10026e00
MxResult LegoPlantManager::Tickle()
{
MxLong time = Timer()->GetTime();
if (m_numEntries != 0) {
for (MxS32 i = 0; i < m_numEntries; i++) {
AnimEntry** ppEntry = &m_entries[i];
AnimEntry* entry = *ppEntry;
if (m_world != CurrentWorld() || !entry->m_entity) {
delete entry;
m_numEntries--;
if (m_numEntries != i) {
m_entries[i] = m_entries[m_numEntries];
m_entries[m_numEntries] = NULL;
}
break;
}
if (entry->m_time - time > 1000) {
break;
}
MxMatrix local90;
MxMatrix local48;
MxMatrix locald8(entry->m_roi->GetLocal2World());
Mx3DPointFloat localec(locald8[3]);
ZEROVEC3(locald8[3]);
locald8[1][0] = sin(((entry->m_time - time) * 2) * 0.0062832f) * 0.2;
locald8[1][2] = sin(((entry->m_time - time) * 4) * 0.0062832f) * 0.2;
locald8.Scale(1.03f, 0.95f, 1.03f);
SET3(locald8[3], localec);
entry->m_roi->FUN_100a58f0(locald8);
entry->m_roi->VTable0x14();
if (entry->m_time < time) {
LegoPlantInfo* info = GetInfo(entry->m_entity);
if (info->m_unk0x16 == 0) {
entry->m_roi->SetVisibility(FALSE);
}
else {
FUN_10026860(info - g_plantInfo);
info->m_entity->SetLocation(info->m_position, info->m_direction, info->m_up, FALSE);
}
delete entry;
m_numEntries--;
if (m_numEntries != i) {
i--;
*ppEntry = m_entries[m_numEntries];
m_entries[m_numEntries] = NULL;
}
}
}
}
else {
TickleManager()->UnregisterClient(this);
}
return SUCCESS;
}

View file

@ -37,20 +37,20 @@
// FUNCTION: LEGO1 0x1003dd70
// FUNCTION: BETA10 0x100d3410
LegoROI* PickROI(MxLong p_a, MxLong p_b)
LegoROI* PickROI(MxLong p_x, MxLong p_y)
{
LegoVideoManager* videoManager = VideoManager();
Lego3DView* view = videoManager->Get3DManager()->GetLego3DView();
return (LegoROI*) view->Pick(p_a, p_b);
return (LegoROI*) view->Pick(p_x, p_y);
}
// FUNCTION: LEGO1 0x1003dd90
// FUNCTION: BETA10 0x100d3449
LegoROI* PickParentROI(MxLong p_a, MxLong p_b)
LegoROI* PickRootROI(MxLong p_x, MxLong p_y)
{
LegoVideoManager* videoManager = VideoManager();
Lego3DView* view = videoManager->Get3DManager()->GetLego3DView();
LegoROI* roi = (LegoROI*) view->Pick(p_a, p_b);
LegoROI* roi = (LegoROI*) view->Pick(p_x, p_y);
while (roi != NULL && roi->GetParentROI() != NULL) {
roi = (LegoROI*) roi->GetParentROI();
@ -59,18 +59,35 @@ LegoROI* PickParentROI(MxLong p_a, MxLong p_b)
return roi;
}
// STUB: LEGO1 0x1003ddc0
LegoEntity* PickEntity(MxLong, MxLong)
// FUNCTION: LEGO1 0x1003ddc0
LegoEntity* PickEntity(MxLong p_x, MxLong p_y)
{
// TODO
return NULL;
LegoROI* roi = PickRootROI(p_x, p_y);
if (roi == NULL) {
return NULL;
}
return roi->GetEntity();
}
// STUB: LEGO1 0x1003dde0
// STUB: BETA10 0x100d358e
void FUN_1003dde0(LegoROI* p_param1, MxFloat p_param2)
// FUNCTION: LEGO1 0x1003dde0
// FUNCTION: BETA10 0x100d358e
void RotateY(LegoROI* p_roi, MxFloat p_angle)
{
// TODO
MxMatrix mat;
const Matrix4& local2world = p_roi->GetLocal2World();
mat = local2world;
float fsin = sin(p_angle);
float fcos = cos(p_angle);
for (MxS32 i = 0; i < 3; i++) {
mat[i][0] = (local2world[i][0] * fcos) + (local2world[i][2] * fsin);
mat[i][2] = (local2world[i][2] * fcos) - (local2world[i][0] * fsin);
}
p_roi->WrappedSetLocalTransform(mat);
}
// FUNCTION: LEGO1 0x1003de80
@ -156,6 +173,7 @@ LegoTreeNode* GetTreeNode(LegoTreeNode* p_node, MxU32 p_index)
}
// FUNCTION: LEGO1 0x1003e050
// FUNCTION: BETA10 0x100d3abc
void FUN_1003e050(LegoAnimPresenter* p_presenter)
{
MxMatrix viewMatrix;

View file

@ -41,8 +41,10 @@ MxBackgroundAudioManager* BackgroundAudioManager()
}
// FUNCTION: LEGO1 0x10015740
// FUNCTION: BETA10 0x100e4895
LegoInputManager* InputManager()
{
assert(LegoOmni::GetInstance());
return LegoOmni::GetInstance()->GetInputManager();
}
@ -95,8 +97,10 @@ LegoWorld* CurrentWorld()
}
// FUNCTION: LEGO1 0x100157b0
// FUNCTION: BETA10 0x100e4a8d
LegoCharacterManager* CharacterManager()
{
assert(LegoOmni::GetInstance());
return LegoOmni::GetInstance()->GetCharacterManager();
}
@ -131,8 +135,10 @@ ViewLODListManager* GetViewLODListManager()
}
// FUNCTION: LEGO1 0x10015820
// FUNCTION: BETA10 0x100e4c92
void FUN_10015820(MxBool p_disable, MxU16 p_flags)
{
assert(LegoOmni::GetInstance());
LegoOmni::GetInstance()->FUN_1005b4f0(p_disable, p_flags);
}

View file

@ -140,6 +140,7 @@ void LegoActor::SetROI(LegoROI* p_roi, MxBool p_bool1, MxBool p_bool2)
}
// FUNCTION: LEGO1 0x1002d6e0
// FUNCTION: BETA10 0x1003d6f2
void LegoActor::Mute(MxBool p_muted)
{
if (m_sound != NULL) {

View file

@ -28,7 +28,7 @@ void LegoEntity::Init()
m_worldSpeed = 0;
m_roi = NULL;
m_cameraFlag = FALSE;
m_filename = NULL;
m_siFile = NULL;
m_unk0x10 = 0;
m_flags = 0;
m_actionType = Extra::ActionType::e_unknown;
@ -37,6 +37,7 @@ void LegoEntity::Init()
}
// FUNCTION: LEGO1 0x10010650
// FUNCTION: BETA10 0x1007e39a
void LegoEntity::ResetWorldTransform(MxBool p_cameraFlag)
{
LegoWorld* world = CurrentWorld();
@ -66,6 +67,7 @@ void LegoEntity::ResetWorldTransform(MxBool p_cameraFlag)
}
// FUNCTION: LEGO1 0x10010790
// FUNCTION: BETA10 0x1007e4f6
void LegoEntity::SetWorldTransform(const Vector3& p_location, const Vector3& p_direction, const Vector3& p_up)
{
LegoWorld* world = CurrentWorld();
@ -78,6 +80,7 @@ void LegoEntity::SetWorldTransform(const Vector3& p_location, const Vector3& p_d
}
// FUNCTION: LEGO1 0x100107e0
// FUNCTION: BETA10 0x1007e572
MxResult LegoEntity::Create(MxDSAction& p_dsAction)
{
m_entityId = p_dsAction.GetObjectId();
@ -87,6 +90,7 @@ MxResult LegoEntity::Create(MxDSAction& p_dsAction)
}
// FUNCTION: LEGO1 0x10010810
// FUNCTION: BETA10 0x1007e5b9
void LegoEntity::Destroy(MxBool p_fromDestructor)
{
if (m_roi) {
@ -98,16 +102,17 @@ void LegoEntity::Destroy(MxBool p_fromDestructor)
CharacterManager()->ReleaseActor(m_roi);
}
else {
VideoManager()->Get3DManager()->GetLego3DView()->Remove(*m_roi);
VideoManager()->Get3DManager()->Remove(*m_roi);
delete m_roi;
}
}
delete[] m_filename;
delete[] m_siFile;
Init();
}
// FUNCTION: LEGO1 0x10010880
// FUNCTION: BETA10 0x1007e6e1
void LegoEntity::SetWorld()
{
LegoWorld* world = CurrentWorld();
@ -118,6 +123,7 @@ void LegoEntity::SetWorld()
}
// FUNCTION: LEGO1 0x100108a0
// FUNCTION: BETA10 0x1007e724
void LegoEntity::SetROI(LegoROI* p_roi, MxBool p_bool1, MxBool p_bool2)
{
m_roi = p_roi;
@ -136,7 +142,7 @@ void LegoEntity::SetROI(LegoROI* p_roi, MxBool p_bool1, MxBool p_bool2)
}
m_roi->SetEntity(this);
VideoManager()->Get3DManager()->GetLego3DView()->Moved(*m_roi);
VideoManager()->Get3DManager()->Moved(*m_roi);
if (p_bool1) {
ClearFlag(c_bit1);
@ -148,6 +154,7 @@ void LegoEntity::SetROI(LegoROI* p_roi, MxBool p_bool1, MxBool p_bool2)
}
// FUNCTION: LEGO1 0x100109b0
// FUNCTION: BETA10 0x1007e8b8
void LegoEntity::SetLocation(const Vector3& p_location, const Vector3& p_direction, const Vector3& p_up, MxBool p_und)
{
Mx3DPointFloat direction;
@ -173,7 +180,7 @@ void LegoEntity::SetLocation(const Vector3& p_location, const Vector3& p_directi
);
m_roi->UpdateTransformationRelativeToParent(mat);
VideoManager()->Get3DManager()->GetLego3DView()->Moved(*m_roi);
VideoManager()->Get3DManager()->Moved(*m_roi);
if (p_und) {
FUN_10010c30();
@ -225,6 +232,7 @@ Mx3DPointFloat LegoEntity::GetWorldPosition()
}
// FUNCTION: LEGO1 0x10010e10
// FUNCTION: BETA10 0x1007ec97
void LegoEntity::ParseAction(char* p_extra)
{
char copy[1024];
@ -232,16 +240,22 @@ void LegoEntity::ParseAction(char* p_extra)
strcpy(copy, p_extra);
if (KeyValueStringParse(actionValue, g_strACTION, copy)) {
m_actionType = MatchActionString(strtok(actionValue, g_parseExtraTokens));
char* token = strtok(actionValue, g_parseExtraTokens);
assert(token);
m_actionType = MatchActionString(token);
if (m_actionType != Extra::ActionType::e_exit) {
char* token = strtok(NULL, g_parseExtraTokens);
token = strtok(NULL, g_parseExtraTokens);
assert(token);
m_filename = new char[strlen(token) + 1];
strcpy(m_filename, token);
m_siFile = new char[strlen(token) + 1];
assert(m_siFile);
strcpy(m_siFile, token);
if (m_actionType != Extra::ActionType::e_run) {
m_targetEntityId = atoi(strtok(NULL, g_parseExtraTokens));
token = strtok(NULL, g_parseExtraTokens);
assert(token);
m_targetEntityId = atoi(token);
}
}
}
@ -458,7 +472,7 @@ MxLong LegoEntity::Notify(MxParam& p_param)
}
if (m_actionType != Extra::e_unknown) {
InvokeAction(m_actionType, MxAtomId(m_filename, e_lowerCase2), m_targetEntityId, this);
InvokeAction(m_actionType, MxAtomId(m_siFile, e_lowerCase2), m_targetEntityId, this);
}
else {
switch (GameState()->GetActorId()) {

View file

@ -1,8 +1,21 @@
#include "legojetskiraceactor.h"
#include "legonavcontroller.h"
#include "legopathcontroller.h"
#include "misc.h"
#include "mxmisc.h"
#include "mxvariabletable.h"
#include <vec.h>
DECOMP_SIZE_ASSERT(LegoJetskiRaceActor, 0x1a8)
// GLOBAL: LEGO1 0x100da044
// GLOBAL: BETA10 0x101be9fc
const MxFloat g_eight = 8.0f;
// FUNCTION: LEGO1 0x10080ef0
// FUNCTION: BETA10 0x100a8990
LegoJetskiRaceActor::LegoJetskiRaceActor()
{
m_unk0x10 = 0.95f;
@ -11,20 +24,121 @@ LegoJetskiRaceActor::LegoJetskiRaceActor()
m_unk0x150 = 1.5f;
}
// STUB: LEGO1 0x10081120
// FUNCTION: LEGO1 0x10081120
// FUNCTION: BETA10 0x100ce19f
MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_edge)
{
// TODO
return 0;
// These are almost certainly not the correct names, but they produce the correct BETA10 stack
Mx3DPointFloat a;
Mx3DPointFloat bbb;
Mx3DPointFloat c;
// These names are verified by an assertion below
Vector3* v1 = NULL;
Vector3* v2 = NULL;
if (m_state == 1) {
if (m_destEdge == LegoPathController::GetControlEdgeA(13)) {
m_boundary = (LegoPathBoundary*) m_destEdge->OtherFace(LegoPathController::GetControlBoundaryA(13));
}
else if (m_destEdge == LegoPathController::GetControlEdgeA(15)) {
m_boundary = (LegoPathBoundary*) m_destEdge->OtherFace(LegoPathController::GetControlBoundaryA(15));
}
m_state = 0;
m_unk0x7c = 0;
if (m_userNavFlag) {
NavController()->SetLinearVel(m_worldSpeed);
return 0;
}
else {
return 1;
}
}
else {
if (p_edge == LegoPathController::GetControlEdgeA(12)) {
m_state = 1;
if (m_worldSpeed < g_eight) {
m_worldSpeed = g_eight;
}
m_destEdge = LegoPathController::GetControlEdgeA(13);
m_boundary = LegoPathController::GetControlBoundaryA(13);
}
else if (p_edge == LegoPathController::GetControlEdgeA(14)) {
m_state = 1;
if (m_worldSpeed < g_eight) {
m_worldSpeed = g_eight;
}
m_destEdge = LegoPathController::GetControlEdgeA(15);
m_boundary = LegoPathController::GetControlBoundaryA(15);
}
if (m_state == 1) {
if (m_userNavFlag) {
m_unk0xe4 = 0.5f;
}
v1 = m_destEdge->CCWVertex(*m_boundary);
v2 = m_destEdge->CWVertex(*m_boundary);
assert(v1 && v2);
LERP3(a, *v1, *v2, m_unk0xe4);
m_destEdge->FUN_1002ddc0(*m_boundary, bbb);
c.EqualsCross(&bbb, m_boundary->GetUnknown0x14());
c.Unitize();
Mx3DPointFloat worldDirection(m_roi->GetWorldDirection());
if (!m_userNavFlag) {
((Vector2*) &worldDirection)->Mul(-1.0f);
}
if (VTable0x80(m_roi->GetWorldPosition(), worldDirection, a, c)) {
#ifdef NDEBUG
m_unk0x7c = 0;
return 0;
#else
assert(0);
return -1;
#endif
}
m_unk0x7c = 0;
return 0;
}
else {
return 1;
}
}
}
// STUB: LEGO1 0x10081550
// FUNCTION: LEGO1 0x10081550
void LegoJetskiRaceActor::VTable0x70(float p_float)
{
// TODO
if (m_unk0x0c == 0) {
const LegoChar* raceState = VariableTable()->GetVariable(g_raceState);
if (!stricmp(raceState, g_racing)) {
m_unk0x0c = 1;
m_lastTime = p_float - 1.0f;
m_unk0x1c = p_float;
}
else if (!m_userNavFlag) {
LegoAnimActor::VTable0x70(m_lastTime + 1.0f);
}
}
if (m_unk0x0c == 1) {
LegoAnimActor::VTable0x70(p_float);
}
}
// STUB: LEGO1 0x10081fd0
// FUNCTION: LEGO1 0x10081fd0
MxU32 LegoJetskiRaceActor::VTable0x6c(
LegoPathBoundary* p_boundary,
Vector3& p_v1,
@ -34,6 +148,39 @@ MxU32 LegoJetskiRaceActor::VTable0x6c(
Vector3& p_v3
)
{
// TODO
LegoAnimPresenterSet& presenters = p_boundary->GetPresenters();
for (LegoAnimPresenterSet::iterator itap = presenters.begin(); itap != presenters.end(); itap++) {
if ((*itap)->VTable0x94(p_v1, p_v2, p_f1, p_f2, p_v3)) {
return 1;
}
}
LegoPathActorSet& plpas = p_boundary->GetActors();
LegoPathActorSet lpas(plpas);
for (LegoPathActorSet::iterator itpa = lpas.begin(); itpa != lpas.end(); itpa++) {
if (plpas.find(*itpa) != plpas.end()) {
LegoPathActor* actor = *itpa;
if (this != actor) {
LegoROI* roi = actor->GetROI();
if (roi != NULL && (roi->GetVisibility() || actor->GetCameraFlag())) {
if (roi->FUN_100a9410(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) {
VTable0x94(actor, TRUE);
if (actor->VTable0x94(this, FALSE) < 0) {
return 0;
}
else {
return 2;
}
}
}
}
}
}
return 0;
}

View file

@ -403,6 +403,7 @@ MxBool LegoNavController::CalculateNewPosDir(
}
// FUNCTION: LEGO1 0x10055500
// FUNCTION: BETA10 0x1009bff8
MxResult LegoNavController::UpdateLocation(const char* p_location)
{
MxResult result = FAILURE;
@ -436,6 +437,7 @@ MxResult LegoNavController::UpdateLocation(const char* p_location)
}
// FUNCTION: LEGO1 0x10055620
// FUNCTION: BETA10 0x1009c145
MxResult LegoNavController::UpdateLocation(MxU32 p_location)
{
MxResult result = FAILURE;

View file

@ -138,6 +138,7 @@ void LegoPointOfViewController::AffectPointOfView()
}
// FUNCTION: LEGO1 0x10065930
// FUNCTION: BETA10 0x100c724d
MxResult LegoPointOfViewController::Tickle()
{
ViewROI* pov = m_lego3DView->GetPointOfView();

View file

@ -15,6 +15,7 @@ MxAtomId* g_jetskiScript = NULL;
MxAtomId* g_racecarScript = NULL;
// GLOBAL: LEGO1 0x100f452c
// GLOBAL: BETA10 0x10211514
MxAtomId* g_carraceScript = NULL;
// GLOBAL: LEGO1 0x100f4530

View file

@ -1,9 +1,73 @@
#include "carrace.h"
#include "actions/carrace_actions.h"
#include "actions/jukebox_actions.h"
#include "dunebuggy.h"
#include "isle.h"
#include "legoanimationmanager.h"
#include "legobackgroundcolor.h"
#include "legocontrolmanager.h"
#include "legohideanimpresenter.h"
#include "legomain.h"
#include "legonavcontroller.h"
#include "legopathstruct.h"
#include "legoracers.h"
#include "legoutils.h"
#include "misc.h"
#include "mxactionnotificationparam.h"
#include "mxbackgroundaudiomanager.h"
#include "mxmisc.h"
#include "mxnotificationmanager.h"
#include "mxstillpresenter.h"
#include "mxtransitionmanager.h"
#include "mxvariabletable.h"
#include "scripts.h"
DECOMP_SIZE_ASSERT(CarRace, 0x154)
// GLOBAL: LEGO1 0x100d5d10
MxS32 CarRace::g_unk0x100d5d10[] = {
CarraceScript::c_srt001sl_RunAnim,
CarraceScript::c_srt002sl_RunAnim,
CarraceScript::c_srt003sl_RunAnim,
CarraceScript::c_srt004sl_RunAnim,
CarraceScript::c_srt005sl_RunAnim,
CarraceScript::c_srt001rh_RunAnim,
CarraceScript::c_srt002rh_RunAnim,
CarraceScript::c_srt003rh_RunAnim
};
// GLOBAL: LEGO1 0x100d5d30
MxS32 CarRace::g_unk0x100d5d30[] = {
CarraceScript::c_srt011sl_RunAnim,
CarraceScript::c_srt012sl_RunAnim,
CarraceScript::c_srt013sl_RunAnim,
CarraceScript::c_srt014sl_RunAnim
};
// GLOBAL: LEGO1 0x100d5d40
MxS32 CarRace::g_unk0x100d5d40[] =
{CarraceScript::c_srt015sl_RunAnim, CarraceScript::c_srt016sl_RunAnim, CarraceScript::c_srt017sl_RunAnim};
// GLOBAL: LEGO1 0x100d5d50
MxS32 CarRace::g_unk0x100d5d50[] =
{CarraceScript::c_srt007rh_RunAnim, CarraceScript::c_srt008rh_RunAnim, CarraceScript::c_srt009rh_RunAnim};
// GLOBAL: LEGO1 0x100d5d60
MxS32 CarRace::g_unk0x100d5d60[] =
{CarraceScript::c_srt010rh_RunAnim, CarraceScript::c_srt011rh_RunAnim, CarraceScript::c_srt012rh_RunAnim};
// GLOBAL: LEGO1 0x100f0c70
// STRING: LEGO1 0x100f0c48
LegoChar* g_strCRCFRNTY6 = "C_RCFRNTY6";
// GLOBAL: LEGO1 0x100f0c74
// STRING: LEGO1 0x100f0c3c
LegoChar* g_strCRCEDGEY0 = "C_RCEDGEY0";
// GLOBAL: LEGO1 0x100f0c7c
static MxS32 g_unk0x100f0c7c = 2;
// FUNCTION: LEGO1 0x10016a90
CarRace::CarRace()
{
@ -11,50 +75,345 @@ CarRace::CarRace()
this->m_unk0x130 = MxRect32(0x16c, 0x154, 0x1ec, 0x15e);
}
// STUB: LEGO1 0x10016ce0
// FUNCTION: LEGO1 0x10016ce0
// FUNCTION: BETA10 0x100c8364
MxResult CarRace::Create(MxDSAction& p_dsAction)
{
// TODO
return SUCCESS;
MxResult result = LegoRace::Create(p_dsAction);
NavController()->SetDeadZone(1);
NavController()->SetTrackDefault(0);
GameState()->m_currentArea = LegoGameState::e_carrace;
GameState()->StopArea(LegoGameState::e_undefined);
LegoGameState* state = GameState();
RaceState* raceState = (RaceState*) state->GetState("CarRaceState");
if (!raceState) {
raceState = (RaceState*) state->CreateState("CarRaceState");
}
m_raceState = raceState;
m_act1State->m_unk0x018 = 6;
m_unk0x144 = -1;
m_unk0x148 = -1;
m_unk0x14c = -1;
LegoRaceCar::FUN_10012e00();
MxS32 streamId =
DuneBuggy::GetColorOffset(g_strCRCEDGEY0) + (DuneBuggy::GetColorOffset(g_strCRCFRNTY6) * 5 + 15) * 2;
InvokeAction(Extra::e_start, m_atomId, streamId, NULL);
InvokeAction(Extra::e_start, m_atomId, CarraceScript::c_RaceCarDashboard, NULL);
return result;
}
// STUB: LEGO1 0x10016dd0
// FUNCTION: LEGO1 0x10016dd0
// FUNCTION: BETA10 0x100c8490
void CarRace::ReadyWorld()
{
// TODO
assert(m_hideAnim);
LegoWorld::ReadyWorld();
m_hideAnim->FUN_1006db40(0);
MxDSAction action;
action.SetAtomId(*g_jukeboxScript);
action.SetObjectId(JukeboxScript::c_RaceTrackRoad_Music);
BackgroundAudioManager()->PlayMusic(action, 5, MxPresenter::e_repeating);
AnimationManager()->Resume();
FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen);
m_unk0x144 = g_unk0x100d5d10[rand() & 7];
AnimationManager()->FUN_10060dc0(m_unk0x144, NULL, TRUE, FALSE, NULL, FALSE, TRUE, FALSE, TRUE);
m_unk0x128 = (MxStillPresenter*) Find("MxPresenter", "CarLocator2");
m_unk0x128->SetPosition(m_unk0x130.GetLeft(), m_unk0x130.GetTop());
m_unk0x12c = (MxStillPresenter*) Find("MxPresenter", "CarLocator3");
m_unk0x12c->SetPosition(m_unk0x130.GetLeft(), m_unk0x130.GetTop());
VariableTable()->SetVariable("DISTANCE", "0.036");
}
// STUB: LEGO1 0x10016f60
MxLong CarRace::HandleEndAction(MxEndActionNotificationParam&)
// FUNCTION: LEGO1 0x10016f60
// FUNCTION: BETA10 0x100c85eb
MxLong CarRace::HandleEndAction(MxEndActionNotificationParam& p_param)
{
// TODO
return 0;
MxLong result = 0;
if (p_param.GetAction()) {
MxDSAction* action = p_param.GetAction();
MxU32 objectId = action->GetObjectId();
if (m_unk0x144 == objectId) {
InvokeAction(Extra::e_start, *g_carraceScript, CarraceScript::c_irtx08ra_PlayWav, NULL);
result = 1;
}
else if (objectId == CarraceScript::c_irtx08ra_PlayWav && m_destLocation == LegoGameState::e_undefined) {
m_unk0x110[0]->Mute(FALSE);
m_unk0x110[1]->Mute(FALSE);
m_unk0x110[2]->Mute(FALSE);
VariableTable()->SetVariable(g_raceState, g_racing);
result = 1;
}
else if (m_unk0x148 == objectId) {
AnimationManager()->FUN_10060dc0(m_unk0x14c, NULL, TRUE, FALSE, NULL, FALSE, TRUE, FALSE, TRUE);
}
else if (m_unk0x14c == objectId) {
NotificationManager()->Send(this, MxNotificationParam());
}
}
return result;
}
// STUB: LEGO1 0x100170e0
MxLong CarRace::HandlePathStruct(LegoPathStructNotificationParam&)
// FUNCTION: LEGO1 0x100170e0
// FUNCTION: BETA10 0x100c87ac
MxLong CarRace::HandlePathStruct(LegoPathStructNotificationParam& p_param)
{
// TODO
return 0;
MxLong result = 0;
if (p_param.GetTrigger() == 68) {
MxEntity* sender = (MxEntity*) p_param.GetSender();
MxS32 paramData = p_param.GetData();
switch (sender->GetEntityId()) {
case 10:
if (paramData <= m_unk0x104 || paramData >= m_unk0x104 + 5) {
break;
}
m_unk0x104 = paramData;
LegoChar buffer[20];
sprintf(buffer, "%g", 0.036 + 0.928 * (m_unk0xf8 * 20.0 + m_unk0x104) / (g_unk0x100f0c7c * 20.0));
VariableTable()->SetVariable("DISTANCE", buffer);
if (m_unk0x104 == 0x14) {
m_unk0x104 = 0;
m_unk0xf8++;
if (g_unk0x100f0c7c == m_unk0xf8) {
VariableTable()->SetVariable(g_raceState, "");
m_unk0x110[0]->Mute(TRUE);
m_unk0x110[1]->Mute(TRUE);
m_unk0x110[2]->Mute(TRUE);
m_unk0x110[0]->SetMaxLinearVel(-1.0);
m_unk0x110[1]->SetMaxLinearVel(-1.0);
m_unk0x110[2]->SetMaxLinearVel(-1.0);
RemoveActor(m_unk0x110[1]);
m_unk0x110[1]->ClearMaps();
RemoveActor(m_unk0x110[2]);
m_unk0x110[2]->ClearMaps();
MxS32 position;
if (m_unk0xfc < m_unk0xf8 && m_unk0x100 < m_unk0xf8) {
position = 3;
m_unk0x148 = g_unk0x100d5d40[rand() % 3];
m_unk0x14c = g_unk0x100d5d60[rand() % 3];
}
else if (m_unk0xfc < m_unk0xf8 || m_unk0x100 < m_unk0xf8) {
position = 2;
if (m_unk0xfc == g_unk0x100f0c7c) {
m_unk0x148 = g_unk0x100d5d30[rand() % 4];
m_unk0x14c = g_unk0x100d5d60[rand() % 3];
}
else {
m_unk0x148 = g_unk0x100d5d50[rand() % 3];
m_unk0x14c = g_unk0x100d5d40[rand() % 3];
}
}
else {
position = 1;
m_unk0x148 = g_unk0x100d5d30[rand() % 4];
m_unk0x14c = g_unk0x100d5d50[rand() % 3];
}
InputManager()->DisableInputProcessing();
InputManager()->SetUnknown336(TRUE);
VariableTable()->SetVariable(g_strHIT_WALL_SOUND, "");
NavController()->SetDeadZone(NavController()->GetDefaultDeadZone());
NavController()->SetTrackDefault(1);
LegoRaceCar::FUN_10012de0();
m_raceState->m_unk0x28 = 2;
RaceState::Entry* raceState = m_raceState->GetState(GameState()->GetActorId());
raceState->m_unk0x02 = position;
if (raceState->m_score < (MxS16) position) {
raceState->m_score = position;
}
AnimationManager()->FUN_10060dc0(m_unk0x148, NULL, TRUE, FALSE, NULL, FALSE, TRUE, FALSE, TRUE);
}
result = 1;
}
break;
case 11:
if (paramData <= m_unk0x108 || paramData >= m_unk0x108 + 5) {
break;
}
FUN_10017820(11, paramData);
m_unk0x108 = paramData;
if (m_unk0x108 == 0x14) {
m_unk0x108 = 0;
m_unk0xfc++;
if (g_unk0x100f0c7c == m_unk0xfc) {
m_unk0x110[1]->SetMaxLinearVel(-1.0);
RemoveActor(m_unk0x110[1]);
m_unk0x110[1]->ClearMaps();
m_unk0x110[1]->GetROI()->SetVisibility(FALSE);
LegoROI* roi = FindROI("rcblack");
if (roi) {
roi->SetVisibility(FALSE);
}
}
}
break;
case 12:
if (paramData <= m_unk0x10c || paramData >= m_unk0x10c + 5) {
break;
}
FUN_10017820(12, paramData);
m_unk0x10c = paramData;
if (m_unk0x10c == 0x14) {
m_unk0x10c = 0;
m_unk0x100++;
if (g_unk0x100f0c7c == m_unk0x100) {
m_unk0x110[2]->SetMaxLinearVel(-1.0);
RemoveActor(m_unk0x110[2]);
m_unk0x110[2]->ClearMaps();
m_unk0x110[2]->GetROI()->SetVisibility(FALSE);
LegoROI* roi = FindROI("rcgreen");
if (roi) {
roi->SetVisibility(FALSE);
}
}
}
break;
}
}
return result;
}
// STUB: LEGO1 0x10017650
MxLong CarRace::HandleClick(LegoEventNotificationParam&)
// FUNCTION: LEGO1 0x10017650
MxLong CarRace::HandleClick(LegoEventNotificationParam& p_param)
{
// TODO
return 0;
LegoControlManagerNotificationParam* param = (LegoControlManagerNotificationParam*) &p_param;
if (param->m_unk0x28 == 1) {
switch (param->m_clickedObjectId) {
case 3:
InvokeAction(Extra::e_stop, *g_carraceScript, CarraceScript::c_irtx08ra_PlayWav, NULL);
m_act1State->m_unk0x018 = 0;
VariableTable()->SetVariable(g_raceState, "");
VariableTable()->SetVariable(g_strHIT_WALL_SOUND, "");
NavController()->SetDeadZone(NavController()->GetDefaultDeadZone());
NavController()->SetTrackDefault(1);
LegoRaceCar::FUN_10012de0();
m_destLocation = LegoGameState::e_infomain;
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
GameState()->GetBackgroundColor()->SetValue("reset");
break;
case 98:
InvokeAction(Extra::e_stop, *g_carraceScript, CarraceScript::c_irtx08ra_PlayWav, NULL);
m_act1State->m_unk0x018 = 0;
VariableTable()->SetVariable(g_raceState, "");
VariableTable()->SetVariable(g_strHIT_WALL_SOUND, "");
NavController()->SetDeadZone(NavController()->GetDefaultDeadZone());
NavController()->SetTrackDefault(1);
LegoRaceCar::FUN_10012de0();
m_destLocation = LegoGameState::e_carraceExterior;
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
GameState()->GetBackgroundColor()->SetValue("reset");
break;
default:
break;
}
}
return 1;
}
// STUB: LEGO1 0x100177e0
// FUNCTION: LEGO1 0x100177e0
// FUNCTION: BETA10 0x100c8f59
MxLong CarRace::HandleType0Notification(MxNotificationParam&)
{
// TODO
return 0;
if (m_raceState->m_unk0x28 == 2) {
m_destLocation = LegoGameState::e_unk21;
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
}
return 1;
}
// STUB: LEGO1 0x10017900
// FUNCTION: LEGO1 0x10017820
void CarRace::FUN_10017820(MxS32 p_param1, MxS16 p_param2)
{
MxS32 local4;
MxStillPresenter* presenter;
MxS32 x, y;
if (p_param1 == 11) {
presenter = m_unk0x128;
local4 = m_unk0xfc;
}
else if (p_param1 == 12) {
presenter = m_unk0x12c;
local4 = m_unk0x100;
}
if (presenter) {
x = m_unk0x130.GetLeft() + 0.5 +
(m_unk0x130.GetRight() - m_unk0x130.GetLeft() + 1) * (local4 * 20.0 + p_param2) / (g_unk0x100f0c7c * 20.0);
y = m_unk0x130.GetTop() + 0.5 +
(m_unk0x130.GetBottom() - m_unk0x130.GetTop() + 1) * (local4 * 20.0 + p_param2) / (g_unk0x100f0c7c * 20.0);
presenter->SetPosition(x, y);
}
}
// FUNCTION: LEGO1 0x10017900
MxBool CarRace::Escape()
{
// TODO
return FALSE;
InvokeAction(Extra::e_stop, *g_carraceScript, CarraceScript::c_irtx08ra_PlayWav, NULL);
AnimationManager()->FUN_10061010(FALSE);
DeleteObjects(&m_atomId, 500, 999);
m_act1State->m_unk0x018 = 0;
VariableTable()->SetVariable(g_strHIT_WALL_SOUND, "");
VariableTable()->SetVariable(g_raceState, "");
NavController()->SetDeadZone(NavController()->GetDefaultDeadZone());
NavController()->SetTrackDefault(1);
LegoRaceCar::FUN_10012de0();
GameState()->GetBackgroundColor()->SetValue("reset");
m_destLocation = LegoGameState::e_infomain;
return TRUE;
}

View file

@ -29,15 +29,14 @@ extern MxBool g_unk0x100f119c;
extern const char* g_varJSFRNTY5;
extern const char* g_varJSWNSHY5;
// Defined in legoracespecial.cpp
extern const char* g_raceState;
extern const char* g_racing;
// Defined in legopathactor.cpp
extern const char* g_strHIT_WALL_SOUND;
DECOMP_SIZE_ASSERT(JetskiRace, 0x144)
// GLOBAL: LEGO1 0x100f0c78
MxS32 JetskiRace::g_unk0x100f0c78 = 2;
// FUNCTION: LEGO1 0x100162c0
// FUNCTION: BETA10 0x100c7e6f
MxResult JetskiRace::Create(MxDSAction& p_dsAction)
@ -125,6 +124,7 @@ MxLong JetskiRace::HandleEndAction(MxEndActionNotificationParam& p_param)
MxLong JetskiRace::HandleClick(LegoEventNotificationParam& p_param)
{
MxLong result = 0;
if (((LegoControlManagerNotificationParam*) &p_param)->m_unk0x28 == 1) {
switch (((LegoControlManagerNotificationParam*) &p_param)->m_clickedObjectId) {
case JetraceScript::c_JetskiArms_Ctl:
@ -148,13 +148,140 @@ MxLong JetskiRace::HandleClick(LegoEventNotificationParam& p_param)
break;
}
}
return result;
}
// STUB: LEGO1 0x100166a0
MxLong JetskiRace::HandlePathStruct(LegoPathStructNotificationParam&)
// FUNCTION: LEGO1 0x100166a0
// FUNCTION: BETA10 0x100c8085
MxLong JetskiRace::HandlePathStruct(LegoPathStructNotificationParam& p_param)
{
return 0;
MxLong result = 0;
MxEntity* sender = (MxEntity*) p_param.GetSender();
if (p_param.GetTrigger() == 68) {
MxS32 paramData = p_param.GetData();
switch (sender->GetEntityId()) {
case 10:
if (paramData <= m_unk0x104 || paramData >= m_unk0x104 + 5) {
break;
}
m_unk0x104 = paramData;
LegoChar buffer[20];
sprintf(buffer, "%g", 0.032 + 0.936 * (m_unk0xf8 * 20.0 + m_unk0x104) / (g_unk0x100f0c78 * 20.0));
VariableTable()->SetVariable("DISTANCE", buffer);
if (m_unk0x104 == 0x14) {
m_unk0x104 = 0;
m_unk0xf8++;
if (g_unk0x100f0c78 == m_unk0xf8) {
MxS32 position;
if (m_unk0xfc < m_unk0xf8 && m_unk0x100 < m_unk0xf8) {
position = 3;
}
else if (m_unk0xfc < m_unk0xf8 || m_unk0x100 < m_unk0xf8) {
position = 2;
}
else {
position = 1;
}
VariableTable()->SetVariable(g_raceState, "");
VariableTable()->SetVariable(g_strHIT_WALL_SOUND, "");
LegoRaceCar::FUN_10012de0();
m_raceState->m_unk0x28 = 2;
RaceState::Entry* raceStateEntry = m_raceState->GetState(GameState()->GetActorId());
raceStateEntry->m_unk0x02 = position;
if (raceStateEntry->m_score < (MxS16) position) {
raceStateEntry->m_score = position;
}
m_destLocation = LegoGameState::e_jetrace2;
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
}
result = 1;
}
else if (m_unk0x104 == 0xf) {
m_hideAnim->FUN_1006db40(m_unk0xf8 * 200 + 100);
result = 1;
}
break;
case 11:
if (paramData <= m_unk0x108 || paramData >= m_unk0x108 + 5) {
break;
}
FUN_10016930(11, paramData);
m_unk0x108 = paramData;
if (m_unk0x108 == 0x14) {
m_unk0x108 = 0;
m_unk0xfc++;
if (g_unk0x100f0c78 == m_unk0xfc) {
((LegoPathActor*) p_param.GetSender())->SetMaxLinearVel(0.1);
}
}
break;
case 12:
if (paramData <= m_unk0x10c || paramData >= m_unk0x10c + 5) {
break;
}
FUN_10016930(12, paramData);
m_unk0x10c = paramData;
if (m_unk0x10c == 0x14) {
m_unk0x10c = 0;
m_unk0x100++;
if (g_unk0x100f0c78 == m_unk0x100) {
((LegoPathActor*) p_param.GetSender())->SetMaxLinearVel(0.1);
}
}
break;
}
}
return result;
}
// FUNCTION: LEGO1 0x10016930
void JetskiRace::FUN_10016930(MxS32 p_param1, MxS16 p_param2)
{
MxS32 local4;
MxStillPresenter* presenter;
MxS32 x, y;
if (p_param1 == 11) {
presenter = m_unk0x128;
local4 = m_unk0xfc;
}
else if (p_param1 == 12) {
presenter = m_unk0x12c;
local4 = m_unk0x100;
}
if (presenter) {
x = m_unk0x130.GetLeft() + 0.5 +
(m_unk0x130.GetRight() - m_unk0x130.GetLeft() + 1) * (local4 * 20.0 + p_param2) / (g_unk0x100f0c78 * 20.0);
y = m_unk0x130.GetTop() + 0.5 +
(m_unk0x130.GetBottom() - m_unk0x130.GetTop() + 1) * (local4 * 20.0 + p_param2) / (g_unk0x100f0c78 * 20.0);
presenter->SetPosition(x, y);
}
}
// FUNCTION: LEGO1 0x10016a10

View file

@ -21,12 +21,6 @@ DECOMP_SIZE_ASSERT(EdgeReference, 0x08)
DECOMP_SIZE_ASSERT(SkeletonKickPhase, 0x10)
DECOMP_SIZE_ASSERT(LegoRaceCar, 0x200)
// GLOBAL: LEGO1 0x100f0bac
static undefined4 g_unk0x100f0bac = 0;
// GLOBAL: LEGO1 0x100f0bb0
static undefined4 g_unk0x100f0bb0 = 0;
// GLOBAL: LEGO1 0x100f0a20
// GLOBAL: BETA10 0x101f5e34
EdgeReference LegoRaceCar::g_skBMap[] = {
@ -142,6 +136,12 @@ MxS32 LegoRaceCar::g_unk0x100f0b88 = 0;
// GLOBAL: BETA10 0x101f5f98
MxBool LegoRaceCar::g_unk0x100f0b8c = TRUE;
// GLOBAL: LEGO1 0x100f0bac
undefined4 LegoRaceCar::g_unk0x100f0bac = 0;
// GLOBAL: LEGO1 0x100f0bb0
undefined4 LegoRaceCar::g_unk0x100f0bb0 = 0;
// Initialized at LEGO1 0x10012db0
// GLOBAL: LEGO1 0x10102af0
// GLOBAL: BETA10 0x102114c0
@ -180,6 +180,18 @@ void LegoRaceCar::FUN_10012de0()
g_unk0x100f0b88 = 0;
}
// FUNCTION: LEGO1 0x10012e00
// FUNCTION: BETA10 0x100cb129
void LegoRaceCar::FUN_10012e00()
{
// Note the (likely unintentional) order of operations: `%` is executed before `/`,
// so the division is performed at runtime.
g_srtsl18to29Index = rand() % sizeof(g_srtsl18to29) / sizeof(g_srtsl18to29[0]);
g_srtsl6to10Index = rand() % sizeof(g_srtsl6to10) / sizeof(g_srtsl6to10[0]);
g_emptySoundKeyListIndex = rand() % sizeof(g_emptySoundKeyList) / sizeof(g_emptySoundKeyList[0]);
g_srtrhIndex = rand() % sizeof(g_srtrh) / sizeof(g_srtrh[0]);
}
// FUNCTION: LEGO1 0x10012e60
// FUNCTION: BETA10 0x100cb191
void LegoRaceCar::SetWorldSpeed(MxFloat p_worldSpeed)

View file

@ -16,6 +16,8 @@ DECOMP_SIZE_ASSERT(LegoCarRaceActor, 0x1a0)
// GLOBAL: LEGO1 0x100f0c68
// STRING: LEGO1 0x100f0c5c
// GLOBAL: BETA10 0x101f5b04
// STRING: BETA10 0x101f5b14
const char* g_raceState = "RACE_STATE";
// GLOBAL: LEGO1 0x100f7af0
@ -24,6 +26,8 @@ const char* g_fuel = "FUEL";
// GLOBAL: LEGO1 0x100f0c6c
// STRING: LEGO1 0x100f0c54
// GLOBAL: BETA10 0x101f5b08
// STRING: BETA10 0x101f5b20
const char* g_racing = "RACING";
// GLOBAL: LEGO1 0x100f7aec

View file

@ -199,6 +199,7 @@ done:
}
// FUNCTION: LEGO1 0x1007ff70
// FUNCTION: BETA10 0x10099061
MxResult LegoModelPresenter::FUN_1007ff70(
MxDSChunk& p_chunk,
LegoEntity* p_entity,
@ -211,8 +212,8 @@ MxResult LegoModelPresenter::FUN_1007ff70(
ParseExtra();
if (m_roi == NULL && (result = CreateROI(&p_chunk)) == SUCCESS && p_entity != NULL) {
VideoManager()->Get3DManager()->GetLego3DView()->Add(*m_roi);
VideoManager()->Get3DManager()->GetLego3DView()->Moved(*m_roi);
VideoManager()->Get3DManager()->Add(*m_roi);
VideoManager()->Get3DManager()->Moved(*m_roi);
}
if (m_roi != NULL) {
@ -266,8 +267,8 @@ void LegoModelPresenter::ReadyTickle()
m_subscriber->FreeDataChunk(chunk);
if (result == SUCCESS) {
VideoManager()->Get3DManager()->GetLego3DView()->Add(*m_roi);
VideoManager()->Get3DManager()->GetLego3DView()->Moved(*m_roi);
VideoManager()->Get3DManager()->Add(*m_roi);
VideoManager()->Get3DManager()->Moved(*m_roi);
if (m_compositePresenter != NULL && m_compositePresenter->IsA("LegoEntityPresenter")) {
((LegoEntityPresenter*) m_compositePresenter)->GetInternalEntity()->SetROI(m_roi, TRUE, TRUE);
@ -289,6 +290,7 @@ void LegoModelPresenter::ReadyTickle()
}
// FUNCTION: LEGO1 0x100801b0
// FUNCTION: BETA10 0x10099443
void LegoModelPresenter::ParseExtra()
{
MxU16 extraLength;
@ -319,8 +321,8 @@ void LegoModelPresenter::ParseExtra()
roiList.erase(it);
m_addedToView = TRUE;
VideoManager()->Get3DManager()->GetLego3DView()->Add(*m_roi);
VideoManager()->Get3DManager()->GetLego3DView()->Moved(*m_roi);
VideoManager()->Get3DManager()->Add(*m_roi);
VideoManager()->Get3DManager()->Moved(*m_roi);
break;
}
}

View file

@ -69,6 +69,7 @@ MxResult LegoVideoManager::CreateDirect3D()
}
// FUNCTION: LEGO1 0x1007ac40
// FUNCTION: BETA10 0x100d5cf4
MxResult LegoVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyMS, MxBool p_createThread)
{
MxResult result = FAILURE;
@ -219,6 +220,7 @@ done:
}
// FUNCTION: LEGO1 0x1007b5e0
// FUNCTION: BETA10 0x100d6816
void LegoVideoManager::Destroy()
{
if (m_cursorSurface != NULL) {

View file

@ -529,6 +529,7 @@ MxLong Isle::HandlePathStruct(LegoPathStructNotificationParam& p_param)
}
// FUNCTION: LEGO1 0x10031820
// FUNCTION: BETA10 0x10034158
void Isle::Enable(MxBool p_enable)
{
if (m_set0xd0.empty() == p_enable) {
@ -595,7 +596,7 @@ void Isle::Enable(MxBool p_enable)
SetIsWorldActive(FALSE);
break;
case LegoGameState::e_jetrace2:
if (((JetskiRaceState*) GameState()->GetState("JetskiRaceState"))->GetUnknown0x28() == 2) {
if (((JetskiRaceState*) GameState()->GetState("JetskiRaceState"))->m_unk0x28 == 2) {
m_act1state->m_unk0x018 = 5;
}
@ -738,7 +739,7 @@ void Isle::Enable(MxBool p_enable)
);
JetskiRaceState* raceState = (JetskiRaceState*) GameState()->GetState("JetskiRaceState");
if (raceState->GetUnknown0x28() == 2) {
if (raceState->m_unk0x28 == 2) {
IsleScript::Script script = IsleScript::c_noneIsle;
switch (raceState->GetState(GameState()->GetActorId())->GetUnknown0x02()) {
@ -771,7 +772,7 @@ void Isle::Enable(MxBool p_enable)
);
CarRaceState* raceState = (CarRaceState*) GameState()->GetState("CarRaceState");
if (raceState->GetUnknown0x28() == 2) {
if (raceState->m_unk0x28 == 2) {
IsleScript::Script script = IsleScript::c_noneIsle;
switch (raceState->GetState(GameState()->GetActorId())->GetUnknown0x02()) {

View file

@ -73,6 +73,7 @@ private:
//
// Lego3DManager implementaion
// FUNCTION: BETA10 0x10079bd0
inline BOOL Lego3DManager::Add(ViewROI& rROI)
{
assert(m_pLego3DView);
@ -80,6 +81,7 @@ inline BOOL Lego3DManager::Add(ViewROI& rROI)
return m_pLego3DView->Add(rROI);
}
// FUNCTION: BETA10 0x10037430
inline BOOL Lego3DManager::Remove(ViewROI& rROI)
{
assert(m_pLego3DView);
@ -87,6 +89,7 @@ inline BOOL Lego3DManager::Remove(ViewROI& rROI)
return m_pLego3DView->Remove(rROI);
}
// FUNCTION: BETA10 0x100d8990
inline BOOL Lego3DManager::SetPointOfView(ViewROI& rROI)
{
assert(m_pLego3DView);
@ -94,6 +97,7 @@ inline BOOL Lego3DManager::SetPointOfView(ViewROI& rROI)
return m_pLego3DView->SetPointOfView(rROI);
}
// FUNCTION: BETA10 0x1004af70
inline BOOL Lego3DManager::Moved(ViewROI& rROI)
{
assert(m_pLego3DView);

View file

@ -74,6 +74,7 @@ void Lego3DView::Destroy()
}
// FUNCTION: LEGO1 0x100ab100
// FUNCTION: BETA10 0x1017d038
BOOL Lego3DView::Add(ViewROI& rROI)
{
assert(m_pViewManager);
@ -84,6 +85,7 @@ BOOL Lego3DView::Add(ViewROI& rROI)
}
// FUNCTION: LEGO1 0x100ab170
// FUNCTION: BETA10 0x1017d096
BOOL Lego3DView::Remove(ViewROI& rROI)
{
assert(m_pViewManager);
@ -99,6 +101,7 @@ BOOL Lego3DView::Remove(ViewROI& rROI)
}
// FUNCTION: LEGO1 0x100ab1b0
// FUNCTION: BETA10 0x1017d123
BOOL Lego3DView::SetPointOfView(ViewROI& rROI)
{
Tgl::FloatMatrix4 transformation;

View file

@ -46,6 +46,7 @@ private:
//
// Lego3DView implementation
// FUNCTION: BETA10 0x100576b0
inline ViewManager* Lego3DView::GetViewManager()
{
return m_pViewManager;

View file

@ -497,11 +497,16 @@ LegoResult LegoAnimNodeData::Write(LegoStorage* p_storage)
return SUCCESS;
}
// STUB: LEGO1 0x100a0360
// STUB: BETA10 0x1017f1e5
void LegoAnimNodeData::FUN_100a0360(LegoChar* p_param)
// FUNCTION: LEGO1 0x100a0360
// FUNCTION: BETA10 0x1017f1e5
void LegoAnimNodeData::SetName(LegoChar* p_name)
{
// TODO
if (m_name != NULL) {
delete[] m_name;
}
m_name = new LegoChar[strlen(p_name) + 1];
strcpy(m_name, p_name);
}
// FUNCTION: LEGO1 0x100a03c0

View file

@ -152,7 +152,7 @@ public:
LegoResult Read(LegoStorage* p_storage) override; // vtable+0x04
LegoResult Write(LegoStorage* p_storage) override; // vtable+0x08
void FUN_100a0360(LegoChar* p_param);
void SetName(LegoChar* p_name);
LegoResult CreateLocalTransform(LegoFloat p_time, Matrix4& p_matrix);
LegoBool FUN_100a0990(LegoFloat p_time);

View file

@ -16,6 +16,7 @@ public:
virtual LegoResult VTable0x04(); // vtable+0x04
// FUNCTION: BETA10 0x1001c980
LegoU8 GetNumEdges() { return m_numEdges; }
// FUNCTION: BETA10 0x1001cc30

View file

@ -46,6 +46,7 @@ public:
// FUNCTION: BETA10 0x1001ff80
Mx4DPointFloat* GetUnknown0x14() { return &m_unk0x14; }
// FUNCTION: BETA10 0x1001ca10
Mx4DPointFloat* GetEdgeNormal(int index) { return &m_edgeNormals[index]; }
// FUNCTION: BETA10 0x1001c9b0

View file

@ -744,4 +744,7 @@
// LIBRARY: BETA10 0x100f8ad0
// strcmp
// LIBRARY: BETA10 0x100f9610
// rand
#endif

View file

@ -47,6 +47,7 @@ public:
return new MxActionNotificationParam(m_type, m_sender, m_action, m_realloc);
} // vtable+0x04
// FUNCTION: BETA10 0x10017970
MxDSAction* GetAction() { return m_action; }
protected:

View file

@ -8,6 +8,7 @@
#include "mxtypes.h"
// VTABLE: LEGO1 0x100d5390
// VTABLE: BETA10 0x101b93e8
// SIZE 0x10
class MxEntity : public MxCore {
public:
@ -33,6 +34,7 @@ public:
}
// FUNCTION: LEGO1 0x10001070
// FUNCTION: BETA10 0x1000f3a0
virtual MxResult Create(MxS32 p_entityId, const MxAtomId& p_atomId)
{
m_entityId = p_entityId;
@ -47,7 +49,9 @@ public:
return SUCCESS;
}
// FUNCTION: BETA10 0x10031c60
MxS32 GetEntityId() { return m_entityId; }
MxAtomId& GetAtomId() { return m_atomId; }
void SetEntityId(MxS32 p_entityId) { m_entityId = p_entityId; }

View file

@ -7,6 +7,7 @@
#include <flic.h>
// VTABLE: LEGO1 0x100dc2c0
// VTABLE: BETA10 0x101c1eb0
// SIZE 0x68
class MxFlcPresenter : public MxVideoPresenter {
public:

View file

@ -40,7 +40,7 @@ short DecodeChunks(
);
void DecodeColors256(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_data);
void DecodeColorPackets(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_data);
void DecodeColorPacket(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_data, short p_index, WORD p_count);
void DecodeColorPacket(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_data, short p_index, short p_count);
void DecodeColors64(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_data);
void DecodeBrun(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData, BYTE* p_data, FLIC_HEADER* p_flcHeader);
void DecodeLC(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData, BYTE* p_data, FLIC_HEADER* p_flcHeader);
@ -49,14 +49,18 @@ void DecodeBlack(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData, BYTE* p_d
void DecodeCopy(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData, BYTE* p_data, FLIC_HEADER* p_flcHeader);
// FUNCTION: LEGO1 0x100bd530
// FUNCTION: BETA10 0x1013dd80
void WritePixel(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData, short p_column, short p_row, byte p_pixel)
{
if (p_column >= 0 && p_row >= 0 && p_column < p_bitmapHeader->biWidth && p_row < p_bitmapHeader->biHeight) {
*(((p_bitmapHeader->biWidth + 3) & -4) * p_row + p_column + p_pixelData) = p_pixel;
if (p_column < 0 || p_row < 0 || p_column >= p_bitmapHeader->biWidth || p_row >= p_bitmapHeader->biHeight) {
return;
}
*(((p_bitmapHeader->biWidth + 3) & -4) * p_row + p_column + p_pixelData) = p_pixel;
}
// FUNCTION: LEGO1 0x100bd580
// FUNCTION: BETA10 0x1013ddef
void WritePixels(
LPBITMAPINFOHEADER p_bitmapHeader,
BYTE* p_pixelData,
@ -66,51 +70,55 @@ void WritePixels(
short p_count
)
{
short col = p_column;
// ClampLine could modify p_column. Save the original value.
short zcol = p_column;
if (ClampLine(p_bitmapHeader, p_column, p_row, p_count)) {
short offset = p_column - col;
BYTE* pixels = offset ? p_data + offset : p_data;
memcpy(((p_bitmapHeader->biWidth + 3) & -4) * p_row + p_column + p_pixelData, pixels, p_count);
if (!ClampLine(p_bitmapHeader, p_column, p_row, p_count)) {
return;
}
short offset = p_column - zcol;
if (offset) {
p_data += offset;
}
BYTE* dest = ((p_bitmapHeader->biWidth + 3) & -4) * p_row + p_column + p_pixelData;
memcpy(dest, p_data, p_count);
}
// FUNCTION: LEGO1 0x100bd600
// FUNCTION: BETA10 0x1013de84
int ClampLine(LPBITMAPINFOHEADER p_bitmapHeader, short& p_column, short& p_row, short& p_count)
{
short column = p_column;
short row = p_row;
short count = p_count;
short end = column + count;
int result;
short a_row = p_row;
short f_count = p_count;
short end = column + f_count;
if (row < 0 || p_bitmapHeader->biHeight <= row || end < 0 || p_bitmapHeader->biWidth <= column) {
result = 0;
}
else {
if (column < 0) {
count += column;
p_count = end;
p_column = 0;
}
if (p_bitmapHeader->biWidth < end) {
count -= end - p_bitmapHeader->biWidth;
p_count = count;
}
if (count < 0) {
result = 0;
}
else {
result = 1;
}
if (a_row < 0 || p_bitmapHeader->biHeight <= a_row || end < 0 || p_bitmapHeader->biWidth <= column) {
return 0;
}
return result;
if (column < 0) {
f_count += column;
p_count = f_count;
p_column = 0;
}
if (p_bitmapHeader->biWidth < end) {
f_count -= end - (short) p_bitmapHeader->biWidth;
p_count = f_count;
}
if (f_count < 0) {
return 0;
}
return 1;
}
// FUNCTION: LEGO1 0x100bd680
// FUNCTION: BETA10 0x1013df77
void WritePixelRun(
LPBITMAPINFOHEADER p_bitmapHeader,
BYTE* p_pixelData,
@ -120,18 +128,19 @@ void WritePixelRun(
short p_count
)
{
short col = p_column;
if (!ClampLine(p_bitmapHeader, p_column, p_row, p_count)) {
return;
}
if (ClampLine(p_bitmapHeader, p_column, p_row, p_count)) {
BYTE* dst = ((p_bitmapHeader->biWidth + 3) & -4) * p_row + p_column + p_pixelData;
BYTE* dst = ((p_bitmapHeader->biWidth + 3) & -4) * p_row + p_column + p_pixelData;
while (--p_count >= 0) {
*dst++ = p_pixel;
}
while (--p_count >= 0) {
*dst++ = p_pixel;
}
}
// FUNCTION: LEGO1 0x100bd6e0
// FUNCTION: BETA10 0x1013dfee
void WritePixelPairs(
LPBITMAPINFOHEADER p_bitmapHeader,
BYTE* p_pixelData,
@ -143,22 +152,26 @@ void WritePixelPairs(
{
p_count <<= 1;
if (ClampLine(p_bitmapHeader, p_column, p_row, p_count)) {
short odd = p_count & 1;
p_count >>= 1;
if (!ClampLine(p_bitmapHeader, p_column, p_row, p_count)) {
return;
}
WORD* dst = (WORD*) (((p_bitmapHeader->biWidth + 3) & -4) * p_row + p_column + p_pixelData);
while (--p_count >= 0) {
*dst++ = p_pixel;
}
short is_odd = p_count & 1;
p_count >>= 1;
if (odd) {
*(BYTE*) dst = p_pixel;
}
WORD* dst = (WORD*) (((p_bitmapHeader->biWidth + 3) & -4) * p_row + p_column + p_pixelData);
while (--p_count >= 0) {
*dst++ = p_pixel;
}
if (is_odd) {
BYTE* dst_byte = (BYTE*) dst;
*dst_byte = p_pixel;
}
}
// FUNCTION: LEGO1 0x100bd760
// FUNCTION: BETA10 0x1013e097
short DecodeChunks(
LPBITMAPINFOHEADER p_bitmapHeader,
BYTE* p_pixelData,
@ -198,6 +211,8 @@ short DecodeChunks(
case FLI_CHUNK_COPY:
DecodeCopy(p_bitmapHeader, p_pixelData, (BYTE*) (chunk + 1), p_flcHeader);
break;
default:
break;
}
}
@ -205,71 +220,81 @@ short DecodeChunks(
}
// FUNCTION: LEGO1 0x100bd880
// FUNCTION: BETA10 0x1013e22c
void DecodeColors256(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_data)
{
DecodeColorPackets(p_bitmapHeader, p_data);
}
// FUNCTION: LEGO1 0x100bd8a0
// FUNCTION: BETA10 0x1013e24c
void DecodeColorPackets(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_data)
{
WORD colorIndex = 0;
BYTE* colors = p_data + 2;
short colorIndex = 0;
BYTE* colors = p_data;
short* pPackets = (short*) colors;
short packets = *pPackets;
colors += 2;
for (short packet = *((short*) p_data) - 1; packet >= 0; packet--) {
colorIndex += colors[0];
short colorCount = colors[1];
while (--packets >= 0) {
colorIndex += *colors++;
short colorCount = *colors++;
colors++;
colors++;
if (!colorCount) {
if (colorCount == 0) {
colorCount = 256;
}
DecodeColorPacket(p_bitmapHeader, colors, colorIndex, colorCount);
colorIndex += colorCount;
colors += colorCount * 3;
colorIndex += colorCount;
}
}
// FUNCTION: LEGO1 0x100bd8f0
void DecodeColorPacket(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_data, short index, WORD p_count)
// FUNCTION: BETA10 0x1013e2f8
void DecodeColorPacket(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_data, short index, short p_count)
{
BYTE* palette = (BYTE*) p_bitmapHeader + p_bitmapHeader->biSize + index * 4;
RGBQUAD* palette = (RGBQUAD*) ((BYTE*) p_bitmapHeader + p_bitmapHeader->biSize) + index;
while (p_count-- > 0) {
palette[2] = p_data[0];
palette[1] = p_data[1];
palette[0] = p_data[2];
while (p_count--) {
palette->rgbRed = p_data[0];
palette->rgbGreen = p_data[1];
palette->rgbBlue = p_data[2];
palette += 4;
palette++;
p_data += 3;
}
}
// FUNCTION: LEGO1 0x100bd940
// FUNCTION: BETA10 0x1013e364
void DecodeColors64(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_data)
{
DecodeColorPackets(p_bitmapHeader, p_data);
}
// FUNCTION: LEGO1 0x100bd960
// FUNCTION: BETA10 0x1013e384
void DecodeBrun(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData, BYTE* p_data, FLIC_HEADER* p_flcHeader)
{
BYTE* data = p_data;
short width = p_flcHeader->width;
short height = p_flcHeader->height;
BYTE* data = p_data;
BYTE* offset = ((p_bitmapHeader->biWidth + 3) & -4) * (height - 1) + p_pixelData;
for (short line = height - 1; line >= 0; line--) {
short line = height;
short width2 = width;
while (--line >= 0) {
short column = 0;
data++;
char count = 0;
while ((column += count) < width2) {
count = *data++;
for (short pixel = 0; pixel < width;) {
char count = *data++;
short i;
if (count >= 0) {
for (short i = 0; i < count; i++) {
for (i = 0; i < count; i++) {
*offset++ = *data;
}
@ -277,12 +302,10 @@ void DecodeBrun(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData, BYTE* p_da
}
else {
count = -count;
for (short i = 0; i < count; i++) {
for (i = 0; i < count; i++) {
*offset++ = *data++;
}
}
pixel += count;
}
offset -= (((p_bitmapHeader->biWidth + 3) & -4) + width);
@ -290,28 +313,37 @@ void DecodeBrun(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData, BYTE* p_da
}
// FUNCTION: LEGO1 0x100bda10
// FUNCTION: BETA10 0x1013e4ca
void DecodeLC(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData, BYTE* p_data, FLIC_HEADER* p_flcHeader)
{
short row = (short) p_flcHeader->height - *((short*) p_data) - 1;
BYTE* data = p_data + 4;
short xofs = 0;
short yofs = 0;
short* word_data = (short*) p_data;
BYTE* data = (BYTE*) word_data + 4;
short row = p_flcHeader->height - (*word_data + yofs) - 1;
for (short lines = *((short*) (p_data + 2)) - 1; lines >= 0; lines--) {
WORD column = 0;
word_data++;
short lines = *word_data;
while (--lines >= 0) {
short column = xofs;
BYTE packets = *data++;
for (BYTE i = 0; i < packets; i++) {
column += *data++;
while (packets > 0) {
column += *data++; // skip byte
char type = *((char*) data++);
if (type < 0) {
type = -type;
WritePixelRun(p_bitmapHeader, p_pixelData, column, row, *data++, type);
column += type;
packets = packets - 1;
}
else {
WritePixels(p_bitmapHeader, p_pixelData, column, row, data, type);
data += type;
column += type;
packets = packets - 1;
}
}
@ -320,6 +352,7 @@ void DecodeLC(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData, BYTE* p_data
}
// FUNCTION: LEGO1 0x100bdac0
// FUNCTION: BETA10 0x1013e61d
void DecodeSS2(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData, BYTE* p_data, FLIC_HEADER* p_flcHeader)
{
short width = (short) p_flcHeader->width - 1;
@ -384,40 +417,43 @@ void DecodeSS2(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData, BYTE* p_dat
}
// FUNCTION: LEGO1 0x100bdc00
// FUNCTION: BETA10 0x1013e85a
void DecodeBlack(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData, BYTE* p_data, FLIC_HEADER* p_flcHeader)
{
short line = p_flcHeader->height;
short height = p_flcHeader->height;
short width = p_flcHeader->width;
short t_col = 0;
short t_row = 0;
BYTE pixel[2];
pixel[1] = 0;
pixel[0] = 0;
pixel[0] = pixel[1] = 0;
while (--line >= 0) {
short count = width / 2;
short odd = width & 1;
for (short i = height - 1; i >= 0; i--) {
WritePixelPairs(p_bitmapHeader, p_pixelData, t_col, t_row + i, *(WORD*) pixel, width / 2);
WritePixelPairs(p_bitmapHeader, p_pixelData, 0, line, *((WORD*) pixel), count);
if (odd) {
WritePixel(p_bitmapHeader, p_pixelData, width - 1, line, 0);
if (width & 1) {
WritePixel(p_bitmapHeader, p_pixelData, t_col + width - 1, t_row + i, 0);
}
}
}
// FUNCTION: LEGO1 0x100bdc90
// FUNCTION: BETA10 0x1013e91f
void DecodeCopy(LPBITMAPINFOHEADER p_bitmapHeader, BYTE* p_pixelData, BYTE* p_data, FLIC_HEADER* p_flcHeader)
{
short line = p_flcHeader->height;
short height = p_flcHeader->height;
short width = p_flcHeader->width;
short t_col = 0;
short t_row = 0;
while (--line >= 0) {
WritePixels(p_bitmapHeader, p_pixelData, 0, line, p_data, width);
for (short i = height - 1; i >= 0; i--) {
WritePixels(p_bitmapHeader, p_pixelData, t_col, t_row + i, p_data, width);
p_data += width;
}
}
// FUNCTION: LEGO1 0x100bdce0
// FUNCTION: BETA10 0x1013e9a5
void DecodeFLCFrame(
LPBITMAPINFOHEADER p_bitmapHeader,
BYTE* p_pixelData,
@ -426,7 +462,12 @@ void DecodeFLCFrame(
BYTE* p_decodedColorMap
)
{
if (p_flcFrame->type == FLI_CHUNK_FRAME) {
DecodeChunks(p_bitmapHeader, p_pixelData, p_flcHeader, p_flcFrame, (BYTE*) (p_flcFrame + 1), p_decodedColorMap);
FLIC_FRAME* frame = p_flcFrame;
if (frame->type != FLI_CHUNK_FRAME) {
return;
}
if (DecodeChunks(p_bitmapHeader, p_pixelData, p_flcHeader, frame, (BYTE*) (p_flcFrame + 1), p_decodedColorMap)) {
return;
}
}

View file

@ -44,6 +44,7 @@ void MxFlcPresenter::CreateBitmap()
}
// FUNCTION: LEGO1 0x100b3570
// FUNCTION: BETA10 0x1013a10f
void MxFlcPresenter::LoadFrame(MxStreamChunk* p_chunk)
{
MxU8* data = p_chunk->GetData();

View file

@ -117,6 +117,7 @@ public:
// FUNCTION: BETA10 0x10027110
const CompoundObject* GetComp() const { return comp; }
// FUNCTION: BETA10 0x10049e10
unsigned char GetVisibility() { return m_visible; }
// FUNCTION: BETA10 0x10011720

View file

@ -46,12 +46,12 @@ Device* RendererImpl::CreateDevice(const DeviceDirect3DCreateData& data)
return device;
}
// GLOBAL: LEGO1 0x10101040
static int g_SetBufferCount = 1;
// FUNCTION: LEGO1 0x100a1900
Device* RendererImpl::CreateDevice(const DeviceDirectDrawCreateData& data)
{
// GLOBAL: LEGO1 0x10101040
static int g_SetBufferCount = 1;
DeviceImpl* device = new DeviceImpl();
HRESULT result = m_data->CreateDeviceFromSurface(
const_cast<LPGUID>(data.m_driverGUID),