Merge remote-tracking branch 'isle/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

This commit is contained in:
Christian Semmler 2026-01-07 16:39:54 -07:00
commit d121ae1ecd
No known key found for this signature in database
GPG Key ID: 086DAA1360BEEE5C
38 changed files with 701 additions and 451 deletions

View File

@ -66,22 +66,22 @@ class CarRace : public LegoRace {
// FUNCTION: BETA10 0x100f16f0
void SetSkeleton(RaceSkel* p_skeleton) { m_skeleton = p_skeleton; }
void FUN_10017820(MxS32 p_param1, MxS16 p_param2);
void SetProgressPosition(MxS32 p_actorId, MxS16 p_progress);
// SYNTHETIC: LEGO1 0x10016c70
// CarRace::`scalar deleting destructor'
private:
static MxS32 g_unk0x100d5d10[];
static MxS32 g_unk0x100d5d30[];
static MxS32 g_unk0x100d5d40[];
static MxS32 g_unk0x100d5d50[];
static MxS32 g_unk0x100d5d60[];
static MxS32 g_introAnimations[];
static MxS32 g_studsWinsAnimations[];
static MxS32 g_studsLoosesAnimation[];
static MxS32 g_rhodaWinsAnimations[];
static MxS32 g_rhodaLoosesAnimation[];
MxS32 m_unk0x144; // 0x144
MxS32 m_unk0x148; // 0x148
MxS32 m_unk0x14c; // 0x14c
RaceSkel* m_skeleton; // 0x150
MxS32 m_introAnimation; // 0x144
MxS32 m_firstFinishAnimation; // 0x148
MxS32 m_secondFinishAnimation; // 0x14c
RaceSkel* m_skeleton; // 0x150
};
#endif // CARRACE_H

View File

@ -36,10 +36,10 @@ class JetskiRace : public LegoRace {
MxLong HandlePathStruct(LegoPathStructNotificationParam&) override; // vtable+0x70
MxLong HandleEndAction(MxEndActionNotificationParam&) override; // vtable+0x74
void FUN_10016930(MxS32 p_param1, MxS16 p_param2);
void SetProgressPosition(MxS32 p_actorId, MxS16 p_progress);
private:
static MxS32 g_unk0x100f0c78;
static MxS32 g_lapsCount;
};
// VTABLE: LEGO1 0x100d4fa8

View File

@ -56,11 +56,11 @@ class LegoActor : public LegoEntity {
// FUNCTION: LEGO1 0x10002ce0
// FUNCTION: BETA10 0x1000f440
virtual void VTable0x58(MxFloat p_unk0x70) { m_unk0x70 = p_unk0x70; } // vtable+0x58
virtual void SetLastPathStruct(MxFloat p_lastPathStruct) { m_lastPathStruct = p_lastPathStruct; } // vtable+0x58
// FUNCTION: LEGO1 0x10002cf0
// FUNCTION: BETA10 0x1000f470
virtual MxFloat VTable0x5c() { return m_unk0x70; } // vtable+0x5c
virtual MxFloat GetLastPathStruct() { return m_lastPathStruct; } // vtable+0x5c
// FUNCTION: LEGO1 0x10002d00
// FUNCTION: BETA10 0x1000f4a0
@ -77,7 +77,7 @@ class LegoActor : public LegoEntity {
protected:
MxFloat m_frequencyFactor; // 0x68
LegoCacheSound* m_sound; // 0x6c
MxFloat m_unk0x70; // 0x70
MxFloat m_lastPathStruct; // 0x70
MxU8 m_actorId; // 0x74
};

View File

@ -88,13 +88,13 @@ class LegoGameState {
e_regbook,
e_infoscor,
e_jetrace,
e_jetrace2,
e_jetraceFinished,
e_jetraceExterior,
e_jetskibuildExited,
e_carrace,
e_carraceExterior,
e_racecarbuildExited,
e_unk21,
e_carraceFinished,
e_pizzeriaExterior,
e_unk23,
e_unk24,

View File

@ -29,11 +29,11 @@ class RaceState : public LegoState {
Entry()
{
m_id = 0;
m_unk0x02 = 0;
m_lastScore = 0;
m_score = 0;
}
MxS16 GetUnknown0x02() { return m_unk0x02; }
MxS16 GetLastScore() { return m_lastScore; }
// FUNCTION: BETA10 0x10088970
MxS16 GetHighScore() { return m_score; }
@ -43,12 +43,12 @@ class RaceState : public LegoState {
{
if (p_storage->IsReadMode()) {
p_storage->ReadU8(m_id);
p_storage->ReadS16(m_unk0x02);
p_storage->ReadS16(m_lastScore);
p_storage->ReadS16(m_score);
}
else if (p_storage->IsWriteMode()) {
p_storage->WriteU8(m_id);
p_storage->WriteS16(m_unk0x02);
p_storage->WriteS16(m_lastScore);
p_storage->WriteS16(m_score);
}
else {
@ -59,9 +59,15 @@ class RaceState : public LegoState {
}
// TODO: Possibly private
MxU8 m_id; // 0x00
MxS16 m_unk0x02; // 0x02
MxS16 m_score; // 0x04
MxU8 m_id; // 0x00
MxS16 m_lastScore; // 0x02
MxS16 m_score; // 0x04
};
enum {
e_carrace = 0,
e_jetrace = 1,
e_finished = 2,
};
RaceState();
@ -94,8 +100,8 @@ class RaceState : public LegoState {
// TODO: Most likely getters/setters are not used according to BETA.
Entry m_state[5]; // 0x08
undefined4 m_unk0x28; // 0x28
Entry m_entries[5]; // 0x08
MxU32 m_state; // 0x28
};
// VTABLE: LEGO1 0x100d5db0
@ -147,9 +153,9 @@ class LegoRace : public LegoWorld {
// FUNCTION: LEGO1 0x1000dac0
// FUNCTION: BETA10 0x100a87d0
virtual void VTable0x7c(LegoRaceMap* p_map, MxU32 p_index) // vtable+0x7c
virtual void SetMapLocator(LegoRaceMap* p_map, MxU32 p_index) // vtable+0x7c
{
m_maps[p_index] = p_map;
m_mapsLocators[p_index] = p_map;
}
// FUNCTION: LEGO1 0x1000dae0
@ -161,20 +167,20 @@ class LegoRace : public LegoWorld {
// LegoRace::`scalar deleting destructor'
protected:
MxS32 m_unk0xf8; // 0xf8
MxS32 m_unk0xfc; // 0xfc
MxS32 m_unk0x100; // 0x100
MxS32 m_unk0x104; // 0x104
MxS32 m_unk0x108; // 0x108
MxS32 m_unk0x10c; // 0x10c
LegoRaceMap* m_maps[3]; // 0x110
LegoGameState::Area m_destLocation; // 0x11c
LegoPathActor* m_pathActor; // 0x120
Act1State* m_act1State; // 0x124
MxStillPresenter* m_unk0x128; // 0x128
MxStillPresenter* m_unk0x12c; // 0x12c
MxRect32 m_unk0x130; // 0x130
RaceState* m_raceState; // 0x140
MxS32 m_playerLaps; // 0xf8
MxS32 m_opponent1Laps; // 0xfc
MxS32 m_opponent2Laps; // 0x100
MxS32 m_playerLastPathStruct; // 0x104
MxS32 m_opponent1LastPathStruct; // 0x108
MxS32 m_opponent2LastPathStruct; // 0x10c
LegoRaceMap* m_mapsLocators[3]; // 0x110
LegoGameState::Area m_destLocation; // 0x11c
LegoPathActor* m_pathActor; // 0x120
Act1State* m_act1State; // 0x124
MxStillPresenter* m_opponent1Locator; // 0x128
MxStillPresenter* m_opponent2Locator; // 0x12c
MxRect32 m_progressBarRect; // 0x130
RaceState* m_raceState; // 0x140
};
#endif // LEGORACE_H

View File

@ -85,8 +85,8 @@ class Score : public LegoWorld {
void Enable(MxBool p_enable) override; // vtable+0x68
void Paint();
MxLong FUN_10001510(MxEndActionNotificationParam& p_param);
MxLong FUN_100016d0(LegoControlManagerNotificationParam& p_param);
MxLong HandleEndAction(MxEndActionNotificationParam& p_param);
MxLong HandleControl(LegoControlManagerNotificationParam& p_param);
void FillArea(MxS32 i_activity, MxS32 i_actor, MxS16 score);
protected:

View File

@ -192,12 +192,12 @@ class TowTrack : public IslePathActor {
private:
void Leave();
void PlayFinalAnimation(IsleScript::Script p_objectId);
void FUN_1004dcb0(IsleScript::Script p_objectId);
void PlayActorAnimation(IsleScript::Script p_objectId);
void PlayAction(IsleScript::Script p_objectId);
undefined4 m_unk0x160; // 0x160
undefined4 m_unused0x160; // 0x160
TowTrackMissionState* m_state; // 0x164
MxS16 m_unk0x168; // 0x168
MxS16 m_unused0x168; // 0x168
MxS16 m_actorId; // 0x16a
MxS16 m_treeBlockageTriggered; // 0x16c
MxS16 m_speedComplaintTriggered; // 0x16e

View File

@ -235,7 +235,7 @@ void IslePathActor::RegisterSpawnLocations()
JukeboxScript::c_Beach_Music
);
g_spawnLocations[6] = SpawnLocation(
LegoGameState::e_jetrace2,
LegoGameState::e_jetraceFinished,
g_isleScript,
0,
"EDG10_63",
@ -271,7 +271,7 @@ void IslePathActor::RegisterSpawnLocations()
JukeboxScript::c_CentralNorthRoad_Music
);
g_spawnLocations[9] = SpawnLocation(
LegoGameState::e_unk21,
LegoGameState::e_carraceFinished,
g_isleScript,
0,
"INT62",

View File

@ -31,7 +31,7 @@ extern MxU32 g_isleFlags;
// FUNCTION: LEGO1 0x1004c720
TowTrack::TowTrack()
{
m_unk0x168 = 0;
m_unused0x168 = 0;
m_actorId = -1;
m_state = NULL;
m_treeBlockageTriggered = 0;
@ -202,19 +202,19 @@ MxLong TowTrack::HandleEndAction(MxEndActionNotificationParam& p_param)
switch (m_actorId) {
case c_pepper:
FUN_1004dcb0(IsleScript::c_wgs085nu_RunAnim);
PlayActorAnimation(IsleScript::c_wgs085nu_RunAnim);
break;
case c_mama:
FUN_1004dcb0(IsleScript::c_wgs086nu_RunAnim);
PlayActorAnimation(IsleScript::c_wgs086nu_RunAnim);
break;
case c_papa:
FUN_1004dcb0(IsleScript::c_wgs088nu_RunAnim);
PlayActorAnimation(IsleScript::c_wgs088nu_RunAnim);
break;
case c_nick:
FUN_1004dcb0(IsleScript::c_wgs087nu_RunAnim);
PlayActorAnimation(IsleScript::c_wgs087nu_RunAnim);
break;
case c_laura:
FUN_1004dcb0(IsleScript::c_wgs089nu_RunAnim);
PlayActorAnimation(IsleScript::c_wgs089nu_RunAnim);
break;
}
@ -231,19 +231,19 @@ MxLong TowTrack::HandleEndAction(MxEndActionNotificationParam& p_param)
switch (m_actorId) {
case c_pepper:
FUN_1004dcb0(IsleScript::c_wgs091nu_RunAnim);
PlayActorAnimation(IsleScript::c_wgs091nu_RunAnim);
break;
case c_mama:
FUN_1004dcb0(IsleScript::c_wgs092nu_RunAnim);
PlayActorAnimation(IsleScript::c_wgs092nu_RunAnim);
break;
case c_papa:
FUN_1004dcb0(IsleScript::c_wgs094nu_RunAnim);
PlayActorAnimation(IsleScript::c_wgs094nu_RunAnim);
break;
case c_nick:
FUN_1004dcb0(IsleScript::c_wgs093nu_RunAnim);
PlayActorAnimation(IsleScript::c_wgs093nu_RunAnim);
break;
case c_laura:
FUN_1004dcb0(IsleScript::c_wgs095nu_RunAnim);
PlayActorAnimation(IsleScript::c_wgs095nu_RunAnim);
break;
}
@ -256,19 +256,19 @@ MxLong TowTrack::HandleEndAction(MxEndActionNotificationParam& p_param)
switch (m_actorId) {
case c_pepper:
FUN_1004dcb0(IsleScript::c_wgs098nu_RunAnim);
PlayActorAnimation(IsleScript::c_wgs098nu_RunAnim);
break;
case c_mama:
FUN_1004dcb0(IsleScript::c_wgs099nu_RunAnim);
PlayActorAnimation(IsleScript::c_wgs099nu_RunAnim);
break;
case c_papa:
FUN_1004dcb0(IsleScript::c_wgs101nu_RunAnim);
PlayActorAnimation(IsleScript::c_wgs101nu_RunAnim);
break;
case c_nick:
FUN_1004dcb0(IsleScript::c_wgs100nu_RunAnim);
PlayActorAnimation(IsleScript::c_wgs100nu_RunAnim);
break;
case c_laura:
FUN_1004dcb0(IsleScript::c_wgs102nu_RunAnim);
PlayActorAnimation(IsleScript::c_wgs102nu_RunAnim);
break;
}
@ -574,7 +574,7 @@ void TowTrack::PlayFinalAnimation(IsleScript::Script p_objectId)
}
// FUNCTION: LEGO1 0x1004dcb0
void TowTrack::FUN_1004dcb0(IsleScript::Script p_objectId)
void TowTrack::PlayActorAnimation(IsleScript::Script p_objectId)
{
AnimationManager()->FUN_1005f6d0(TRUE);
AnimationManager()

View File

@ -1391,7 +1391,7 @@ void LegoCarBuild::SetPartColor(MxS32 p_objectId)
m_Paint_Sound->Enable(FALSE);
m_Paint_Sound->Enable(TRUE);
m_selectedPart->FUN_100a93b0(color);
m_selectedPart->SetColorByName(color);
sprintf(buffer, "c_%s", m_selectedPart->GetName());
VariableTable()->SetVariable(buffer, color);
}

View File

@ -886,12 +886,12 @@ void LegoGameState::SwitchArea(Area p_area)
InvokeAction(Extra::ActionType::e_opendisk, *g_infodoorScript, InfodoorScript::c__StartUp, NULL);
break;
case e_infocenterExited:
case e_jetrace2:
case e_jetraceFinished:
case e_jetraceExterior:
case e_jetskibuildExited:
case e_carraceExterior:
case e_racecarbuildExited:
case e_unk21:
case e_carraceFinished:
case e_pizzeriaExterior:
case e_garageExterior:
case e_hospitalExterior:
@ -937,7 +937,7 @@ void LegoGameState::SwitchArea(Area p_area)
break;
case e_jetrace:
if (m_previousArea == e_infomain) {
m_currentArea = e_jetrace2;
m_currentArea = e_jetraceFinished;
LoadIsle();
}
else {

View File

@ -19,7 +19,7 @@ LegoActor::LegoActor()
{
m_frequencyFactor = 0.0f;
m_sound = NULL;
m_unk0x70 = 0.0f;
m_lastPathStruct = 0.0f;
m_interaction = 0;
m_actorId = 0;
}

View File

@ -30,7 +30,7 @@ Mx3DPointFloat g_unk0x10104c18 = Mx3DPointFloat(0.0f, 2.5f, 0.0f);
// FUNCTION: BETA10 0x10080908
LegoExtraActor::LegoExtraActor()
{
m_unk0x70 = 0.0f;
m_lastPathStruct = 0.0f;
m_scheduledTime = 0;
m_unk0x0c = 0;
m_unk0x0e = 0;
@ -508,7 +508,7 @@ inline MxU32 LegoExtraActor::VTable0x6c(
}
}
else {
if (roi->FUN_100a9410(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) {
if (roi->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) {
if (HitActor(actor, TRUE) < 0) {
return 0;
}

View File

@ -488,7 +488,7 @@ MxU32 LegoPathActor::VTable0x6c(
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->m_collideBox)) {
if (roi->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->m_collideBox)) {
HitActor(actor, TRUE);
actor->HitActor(this, FALSE);
return 2;

View File

@ -49,7 +49,7 @@ MxBool LegoPathStruct::HandleTrigger(LegoPathActor* p_actor, MxBool p_direction,
}
break;
case c_d: {
p_actor->VTable0x58(p_data);
p_actor->SetLastPathStruct(p_data);
LegoPathStructNotificationParam param(c_notificationPathStruct, p_actor, m_name[2], p_data);
p_actor->Notify(param);

View File

@ -27,7 +27,7 @@
DECOMP_SIZE_ASSERT(CarRace, 0x154)
// GLOBAL: LEGO1 0x100d5d10
MxS32 CarRace::g_unk0x100d5d10[] = {
MxS32 CarRace::g_introAnimations[] = {
CarraceScript::c_srt001sl_RunAnim,
CarraceScript::c_srt002sl_RunAnim,
CarraceScript::c_srt003sl_RunAnim,
@ -39,7 +39,7 @@ MxS32 CarRace::g_unk0x100d5d10[] = {
};
// GLOBAL: LEGO1 0x100d5d30
MxS32 CarRace::g_unk0x100d5d30[] = {
MxS32 CarRace::g_studsWinsAnimations[] = {
CarraceScript::c_srt011sl_RunAnim,
CarraceScript::c_srt012sl_RunAnim,
CarraceScript::c_srt013sl_RunAnim,
@ -47,15 +47,15 @@ MxS32 CarRace::g_unk0x100d5d30[] = {
};
// GLOBAL: LEGO1 0x100d5d40
MxS32 CarRace::g_unk0x100d5d40[] =
MxS32 CarRace::g_studsLoosesAnimation[] =
{CarraceScript::c_srt015sl_RunAnim, CarraceScript::c_srt016sl_RunAnim, CarraceScript::c_srt017sl_RunAnim};
// GLOBAL: LEGO1 0x100d5d50
MxS32 CarRace::g_unk0x100d5d50[] =
MxS32 CarRace::g_rhodaWinsAnimations[] =
{CarraceScript::c_srt007rh_RunAnim, CarraceScript::c_srt008rh_RunAnim, CarraceScript::c_srt009rh_RunAnim};
// GLOBAL: LEGO1 0x100d5d60
MxS32 CarRace::g_unk0x100d5d60[] =
MxS32 CarRace::g_rhodaLoosesAnimation[] =
{CarraceScript::c_srt010rh_RunAnim, CarraceScript::c_srt011rh_RunAnim, CarraceScript::c_srt012rh_RunAnim};
// GLOBAL: LEGO1 0x100f0c70
@ -67,14 +67,14 @@ const LegoChar* g_strCRCFRNTY6 = "C_RCFRNTY6";
const LegoChar* g_strCRCEDGEY0 = "C_RCEDGEY0";
// GLOBAL: LEGO1 0x100f0c7c
MxS32 g_unk0x100f0c7c = 2;
MxS32 g_lapsCount = 2;
// FUNCTION: LEGO1 0x10016a90
// FUNCTION: BETA10 0x100c82e8
CarRace::CarRace()
{
m_skeleton = NULL;
m_unk0x130 = MxRect32(0x16c, 0x154, 0x1ec, 0x15e);
m_progressBarRect = MxRect32(0x16c, 0x154, 0x1ec, 0x15e);
}
// FUNCTION: LEGO1 0x10016ce0
@ -99,15 +99,15 @@ MxResult CarRace::Create(MxDSAction& p_dsAction)
m_raceState = raceState;
m_act1State->m_state = Act1State::e_transitionToRacecar;
m_unk0x144 = -1;
m_unk0x148 = -1;
m_unk0x14c = -1;
m_introAnimation = -1;
m_firstFinishAnimation = -1;
m_secondFinishAnimation = -1;
LegoRaceCar::InitSoundIndices();
MxS32 streamId =
MxS32 raceCarDashboardStreamId =
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, raceCarDashboardStreamId, NULL);
InvokeAction(Extra::e_start, m_atomId, CarraceScript::c_RaceCarDashboard, NULL);
return result;
@ -129,16 +129,16 @@ void CarRace::ReadyWorld()
AnimationManager()->Resume();
Disable(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen);
m_unk0x144 = g_unk0x100d5d10[SDL_rand(8)];
m_introAnimation = g_introAnimations[SDL_rand(8)];
AnimationManager()
->FUN_10060dc0(m_unk0x144, NULL, TRUE, LegoAnimationManager::e_unk0, NULL, FALSE, TRUE, FALSE, TRUE);
->FUN_10060dc0(m_introAnimation, NULL, TRUE, LegoAnimationManager::e_unk0, NULL, FALSE, TRUE, FALSE, TRUE);
m_unk0x128 = (MxStillPresenter*) Find("MxPresenter", "CarLocator2");
m_unk0x128->SetPosition(m_unk0x130.GetLeft(), m_unk0x130.GetTop());
m_opponent1Locator = (MxStillPresenter*) Find("MxPresenter", "CarLocator2");
m_opponent1Locator->SetPosition(m_progressBarRect.GetLeft(), m_progressBarRect.GetTop());
m_unk0x12c = (MxStillPresenter*) Find("MxPresenter", "CarLocator3");
m_unk0x12c->SetPosition(m_unk0x130.GetLeft(), m_unk0x130.GetTop());
m_opponent2Locator = (MxStillPresenter*) Find("MxPresenter", "CarLocator3");
m_opponent2Locator->SetPosition(m_progressBarRect.GetLeft(), m_progressBarRect.GetTop());
VariableTable()->SetVariable("DISTANCE", "0.036");
}
@ -152,23 +152,32 @@ MxLong CarRace::HandleEndAction(MxEndActionNotificationParam& p_param)
MxDSAction* action = p_param.GetAction();
MxU32 objectId = action->GetObjectId();
if (m_unk0x144 == objectId) {
if (m_introAnimation == 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_maps[0]->Mute(FALSE);
m_maps[1]->Mute(FALSE);
m_maps[2]->Mute(FALSE);
m_mapsLocators[0]->Mute(FALSE);
m_mapsLocators[1]->Mute(FALSE);
m_mapsLocators[2]->Mute(FALSE);
VariableTable()->SetVariable(g_raceState, g_racing);
result = 1;
}
else if (m_unk0x148 == objectId) {
AnimationManager()
->FUN_10060dc0(m_unk0x14c, NULL, TRUE, LegoAnimationManager::e_unk0, NULL, FALSE, TRUE, FALSE, TRUE);
else if (m_firstFinishAnimation == objectId) {
AnimationManager()->FUN_10060dc0(
m_secondFinishAnimation,
NULL,
TRUE,
LegoAnimationManager::e_unk0,
NULL,
FALSE,
TRUE,
FALSE,
TRUE
);
}
else if (m_unk0x14c == objectId) {
else if (m_secondFinishAnimation == objectId) {
NotificationManager()->Send(this, MxNotificationParam());
}
}
@ -187,59 +196,63 @@ MxLong CarRace::HandlePathStruct(LegoPathStructNotificationParam& p_param)
MxS32 paramData = p_param.GetData();
switch (sender->GetEntityId()) {
case 10:
if (paramData <= m_unk0x104 || paramData >= m_unk0x104 + 5) {
case CarraceScript::c_UserCar_Actor:
if (paramData <= m_playerLastPathStruct || paramData >= m_playerLastPathStruct + 5) {
break;
}
m_unk0x104 = paramData;
m_playerLastPathStruct = paramData;
LegoChar buffer[20];
sprintf(buffer, "%g", 0.036 + 0.928 * (m_unk0xf8 * 20.0 + m_unk0x104) / (g_unk0x100f0c7c * 20.0));
sprintf(
buffer,
"%g",
0.036 + 0.928 * (m_playerLaps * 20.0 + m_playerLastPathStruct) / (g_lapsCount * 20.0)
);
VariableTable()->SetVariable("DISTANCE", buffer);
if (m_unk0x104 == 0x14) {
m_unk0x104 = 0;
m_unk0xf8++;
if (m_playerLastPathStruct == 0x14) {
m_playerLastPathStruct = 0;
m_playerLaps++;
if (g_unk0x100f0c7c == m_unk0xf8) {
if (g_lapsCount == m_playerLaps) {
VariableTable()->SetVariable(g_raceState, "");
m_maps[0]->Mute(TRUE);
m_maps[1]->Mute(TRUE);
m_maps[2]->Mute(TRUE);
m_mapsLocators[0]->Mute(TRUE);
m_mapsLocators[1]->Mute(TRUE);
m_mapsLocators[2]->Mute(TRUE);
m_maps[0]->SetMaxLinearVel(-1.0);
m_maps[1]->SetMaxLinearVel(-1.0);
m_maps[2]->SetMaxLinearVel(-1.0);
m_mapsLocators[0]->SetMaxLinearVel(-1.0);
m_mapsLocators[1]->SetMaxLinearVel(-1.0);
m_mapsLocators[2]->SetMaxLinearVel(-1.0);
RemoveActor(m_maps[1]);
m_maps[1]->ClearMaps();
RemoveActor(m_mapsLocators[1]);
m_mapsLocators[1]->ClearMaps();
RemoveActor(m_maps[2]);
m_maps[2]->ClearMaps();
RemoveActor(m_mapsLocators[2]);
m_mapsLocators[2]->ClearMaps();
MxS32 position;
MxS32 score;
if (m_unk0xfc < m_unk0xf8 && m_unk0x100 < m_unk0xf8) {
position = 3;
m_unk0x148 = g_unk0x100d5d40[SDL_rand(3)];
m_unk0x14c = g_unk0x100d5d60[SDL_rand(3)];
if (m_opponent1Laps < m_playerLaps && m_opponent2Laps < m_playerLaps) {
score = 3;
m_firstFinishAnimation = g_studsLoosesAnimation[SDL_rand(3)];
m_secondFinishAnimation = g_rhodaLoosesAnimation[SDL_rand(3)];
}
else if (m_unk0xfc < m_unk0xf8 || m_unk0x100 < m_unk0xf8) {
position = 2;
if (m_unk0xfc == g_unk0x100f0c7c) {
m_unk0x148 = g_unk0x100d5d30[SDL_rand(4)];
m_unk0x14c = g_unk0x100d5d60[SDL_rand(3)];
else if (m_opponent1Laps < m_playerLaps || m_opponent2Laps < m_playerLaps) {
score = 2;
if (m_opponent1Laps == g_lapsCount) {
m_firstFinishAnimation = g_studsWinsAnimations[SDL_rand(4)];
m_secondFinishAnimation = g_rhodaLoosesAnimation[SDL_rand(3)];
}
else {
m_unk0x148 = g_unk0x100d5d50[SDL_rand(3)];
m_unk0x14c = g_unk0x100d5d40[SDL_rand(3)];
m_firstFinishAnimation = g_rhodaWinsAnimations[SDL_rand(3)];
m_secondFinishAnimation = g_studsLoosesAnimation[SDL_rand(3)];
}
}
else {
position = 1;
m_unk0x148 = g_unk0x100d5d30[SDL_rand(4)];
m_unk0x14c = g_unk0x100d5d50[SDL_rand(3)];
score = 1;
m_firstFinishAnimation = g_studsWinsAnimations[SDL_rand(4)];
m_secondFinishAnimation = g_rhodaWinsAnimations[SDL_rand(3)];
}
InputManager()->DisableInputProcessing();
@ -248,17 +261,17 @@ MxLong CarRace::HandlePathStruct(LegoPathStructNotificationParam& p_param)
NavController()->SetDeadZone(NavController()->GetDefaultDeadZone());
NavController()->SetTrackDefault(1);
LegoRaceCar::InitYouCantStopSound();
m_raceState->m_unk0x28 = 2;
m_raceState->m_state = RaceState::e_finished;
RaceState::Entry* raceState = m_raceState->GetState(GameState()->GetActorId());
raceState->m_unk0x02 = position;
raceState->m_lastScore = score;
if (raceState->m_score < (MxS16) position) {
raceState->m_score = position;
if (raceState->m_score < (MxS16) score) {
raceState->m_score = score;
}
AnimationManager()->FUN_10060dc0(
m_unk0x148,
m_firstFinishAnimation,
NULL,
TRUE,
LegoAnimationManager::e_unk0,
@ -276,23 +289,23 @@ MxLong CarRace::HandlePathStruct(LegoPathStructNotificationParam& p_param)
}
break;
case 11:
if (paramData <= m_unk0x108 || paramData >= m_unk0x108 + 5) {
case CarraceScript::c_Studs_Actor:
if (paramData <= m_opponent1LastPathStruct || paramData >= m_opponent1LastPathStruct + 5) {
break;
}
FUN_10017820(11, paramData);
m_unk0x108 = paramData;
SetProgressPosition(CarraceScript::c_Studs_Actor, paramData);
m_opponent1LastPathStruct = paramData;
if (m_unk0x108 == 0x14) {
m_unk0x108 = 0;
m_unk0xfc++;
if (m_opponent1LastPathStruct == 0x14) {
m_opponent1LastPathStruct = 0;
m_opponent1Laps++;
if (g_unk0x100f0c7c == m_unk0xfc) {
m_maps[1]->SetMaxLinearVel(-1.0);
RemoveActor(m_maps[1]);
m_maps[1]->ClearMaps();
m_maps[1]->GetROI()->SetVisibility(FALSE);
if (g_lapsCount == m_opponent1Laps) {
m_mapsLocators[1]->SetMaxLinearVel(-1.0);
RemoveActor(m_mapsLocators[1]);
m_mapsLocators[1]->ClearMaps();
m_mapsLocators[1]->GetROI()->SetVisibility(FALSE);
LegoROI* roi = FindROI("rcblack");
@ -303,24 +316,23 @@ MxLong CarRace::HandlePathStruct(LegoPathStructNotificationParam& p_param)
}
break;
case 12:
if (paramData <= m_unk0x10c || paramData >= m_unk0x10c + 5) {
case CarraceScript::c_Rhoda_Actor:
if (paramData <= m_opponent2LastPathStruct || paramData >= m_opponent2LastPathStruct + 5) {
break;
}
FUN_10017820(12, paramData);
SetProgressPosition(CarraceScript::c_Rhoda_Actor, paramData);
m_opponent2LastPathStruct = paramData;
m_unk0x10c = paramData;
if (m_opponent2LastPathStruct == 0x14) {
m_opponent2LastPathStruct = 0;
m_opponent2Laps++;
if (m_unk0x10c == 0x14) {
m_unk0x10c = 0;
m_unk0x100++;
if (g_unk0x100f0c7c == m_unk0x100) {
m_maps[2]->SetMaxLinearVel(-1.0);
RemoveActor(m_maps[2]);
m_maps[2]->ClearMaps();
m_maps[2]->GetROI()->SetVisibility(FALSE);
if (g_lapsCount == m_opponent2Laps) {
m_mapsLocators[2]->SetMaxLinearVel(-1.0);
RemoveActor(m_mapsLocators[2]);
m_mapsLocators[2]->ClearMaps();
m_mapsLocators[2]->GetROI()->SetVisibility(FALSE);
LegoROI* roi = FindROI("rcgreen");
@ -377,8 +389,8 @@ MxLong CarRace::HandleControl(LegoControlManagerNotificationParam& p_param)
// FUNCTION: BETA10 0x100c8f59
MxLong CarRace::HandleType0Notification(MxNotificationParam&)
{
if (m_raceState->m_unk0x28 == 2) {
m_destLocation = LegoGameState::e_unk21;
if (m_raceState->m_state == RaceState::e_finished) {
m_destLocation = LegoGameState::e_carraceFinished;
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
}
@ -386,26 +398,28 @@ MxLong CarRace::HandleType0Notification(MxNotificationParam&)
}
// FUNCTION: LEGO1 0x10017820
void CarRace::FUN_10017820(MxS32 p_param1, MxS16 p_param2)
void CarRace::SetProgressPosition(MxS32 p_actorId, MxS16 p_progress)
{
MxS32 local4;
MxS32 laps;
MxStillPresenter* presenter = NULL;
MxS32 x, y;
if (p_param1 == 11) {
presenter = m_unk0x128;
local4 = m_unk0xfc;
if (p_actorId == CarraceScript::c_Studs_Actor) {
presenter = m_opponent1Locator;
laps = m_opponent1Laps;
}
else if (p_param1 == 12) {
presenter = m_unk0x12c;
local4 = m_unk0x100;
else if (p_actorId == CarraceScript::c_Rhoda_Actor) {
presenter = m_opponent2Locator;
laps = m_opponent2Laps;
}
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);
x = m_progressBarRect.GetLeft() + 0.5 +
(m_progressBarRect.GetRight() - m_progressBarRect.GetLeft() + 1) * (laps * 20.0 + p_progress) /
(g_lapsCount * 20.0);
y = m_progressBarRect.GetTop() + 0.5 +
(m_progressBarRect.GetBottom() - m_progressBarRect.GetTop() + 1) * (laps * 20.0 + p_progress) /
(g_lapsCount * 20.0);
presenter->SetPosition(x, y);
}

View File

@ -37,7 +37,7 @@ extern const char* g_strHIT_WALL_SOUND;
DECOMP_SIZE_ASSERT(JetskiRace, 0x144)
// GLOBAL: LEGO1 0x100f0c78
MxS32 JetskiRace::g_unk0x100f0c78 = 2;
MxS32 JetskiRace::g_lapsCount = 2;
// FUNCTION: LEGO1 0x100162c0
// FUNCTION: BETA10 0x100c7e6f
@ -60,16 +60,16 @@ MxResult JetskiRace::Create(MxDSAction& p_dsAction)
return FAILURE;
}
m_raceState->m_unk0x28 = 1;
m_unk0x130.SetLeft(397);
m_unk0x130.SetTop(317);
m_unk0x130.SetRight(543);
m_unk0x130.SetBottom(333);
m_raceState->m_state = RaceState::e_jetrace;
m_progressBarRect.SetLeft(397);
m_progressBarRect.SetTop(317);
m_progressBarRect.SetRight(543);
m_progressBarRect.SetBottom(333);
LegoJetski::InitSoundIndices();
MxS32 streamId =
MxS32 raceCarDashboardStreamId =
DuneBuggy::GetColorOffset(g_varJSFRNTY5) + (DuneBuggy::GetColorOffset(g_varJSWNSHY5) * 5 + 0xf) * 2;
InvokeAction(Extra::e_start, m_atomId, streamId, NULL);
InvokeAction(Extra::e_start, m_atomId, raceCarDashboardStreamId, NULL);
InvokeAction(Extra::e_start, m_atomId, JetraceScript::c_JetskiDashboard, NULL);
g_unk0x100f119c = TRUE;
@ -92,10 +92,10 @@ void JetskiRace::ReadyWorld()
AnimationManager()->Resume();
m_unk0x128 = (MxStillPresenter*) Find("MxPresenter", "JetskiLocator2");
m_unk0x128->SetPosition(m_unk0x130.GetLeft(), m_unk0x130.GetTop());
m_unk0x12c = (MxStillPresenter*) Find("MxPresenter", "JetskiLocator3");
m_unk0x12c->SetPosition(m_unk0x130.GetLeft(), m_unk0x130.GetTop());
m_opponent1Locator = (MxStillPresenter*) Find("MxPresenter", "JetskiLocator2");
m_opponent1Locator->SetPosition(m_progressBarRect.GetLeft(), m_progressBarRect.GetTop());
m_opponent2Locator = (MxStillPresenter*) Find("MxPresenter", "JetskiLocator3");
m_opponent2Locator->SetPosition(m_progressBarRect.GetLeft(), m_progressBarRect.GetTop());
Disable(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen);
@ -110,9 +110,9 @@ MxLong JetskiRace::HandleEndAction(MxEndActionNotificationParam& p_param)
MxLong result = 0;
if ((p_param.GetAction()) && (p_param.GetAction()->GetObjectId() == JetraceScript::c_AirHorn_PlayWav)) {
m_maps[0]->Mute(FALSE);
m_maps[1]->Mute(FALSE);
m_maps[2]->Mute(FALSE);
m_mapsLocators[0]->Mute(FALSE);
m_mapsLocators[1]->Mute(FALSE);
m_mapsLocators[2]->Mute(FALSE);
VariableTable()->SetVariable(g_raceState, g_racing);
result = 1;
@ -164,46 +164,50 @@ MxLong JetskiRace::HandlePathStruct(LegoPathStructNotificationParam& p_param)
MxS32 paramData = p_param.GetData();
switch (sender->GetEntityId()) {
case 10:
if (paramData <= m_unk0x104 || paramData >= m_unk0x104 + 5) {
case JetraceScript::c_UserJetski_Actor:
if (paramData <= m_playerLastPathStruct || paramData >= m_playerLastPathStruct + 5) {
break;
}
m_unk0x104 = paramData;
m_playerLastPathStruct = paramData;
LegoChar buffer[20];
sprintf(buffer, "%g", 0.032 + 0.936 * (m_unk0xf8 * 20.0 + m_unk0x104) / (g_unk0x100f0c78 * 20.0));
sprintf(
buffer,
"%g",
0.032 + 0.936 * (m_playerLaps * 20.0 + m_playerLastPathStruct) / (g_lapsCount * 20.0)
);
VariableTable()->SetVariable("DISTANCE", buffer);
if (m_unk0x104 == 0x14) {
m_unk0x104 = 0;
m_unk0xf8++;
if (m_playerLastPathStruct == 0x14) {
m_playerLastPathStruct = 0;
m_playerLaps++;
if (g_unk0x100f0c78 == m_unk0xf8) {
MxS32 position;
if (g_lapsCount == m_playerLaps) {
MxS32 score;
if (m_unk0xfc < m_unk0xf8 && m_unk0x100 < m_unk0xf8) {
position = 3;
if (m_opponent1Laps < m_playerLaps && m_opponent2Laps < m_playerLaps) {
score = 3;
}
else if (m_unk0xfc < m_unk0xf8 || m_unk0x100 < m_unk0xf8) {
position = 2;
else if (m_opponent1Laps < m_playerLaps || m_opponent2Laps < m_playerLaps) {
score = 2;
}
else {
position = 1;
score = 1;
}
VariableTable()->SetVariable(g_raceState, "");
VariableTable()->SetVariable(g_strHIT_WALL_SOUND, "");
LegoRaceCar::InitYouCantStopSound();
m_raceState->m_unk0x28 = 2;
m_raceState->m_state = RaceState::e_finished;
RaceState::Entry* raceStateEntry = m_raceState->GetState(GameState()->GetActorId());
raceStateEntry->m_unk0x02 = position;
raceStateEntry->m_lastScore = score;
if (raceStateEntry->m_score < (MxS16) position) {
raceStateEntry->m_score = position;
if (raceStateEntry->m_score < (MxS16) score) {
raceStateEntry->m_score = score;
}
m_destLocation = LegoGameState::e_jetrace2;
m_destLocation = LegoGameState::e_jetraceFinished;
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
EmitGameEvent(e_raceFinished);
@ -211,44 +215,44 @@ MxLong JetskiRace::HandlePathStruct(LegoPathStructNotificationParam& p_param)
result = 1;
}
else if (m_unk0x104 == 0xf) {
m_hideAnim->FUN_1006db40(m_unk0xf8 * 200 + 100);
else if (m_playerLastPathStruct == 0xf) {
m_hideAnim->FUN_1006db40(m_playerLaps * 200 + 100);
result = 1;
}
break;
case 11:
if (paramData <= m_unk0x108 || paramData >= m_unk0x108 + 5) {
case JetraceScript::c_Snap_Actor:
if (paramData <= m_opponent1LastPathStruct || paramData >= m_opponent1LastPathStruct + 5) {
break;
}
FUN_10016930(11, paramData);
m_unk0x108 = paramData;
SetProgressPosition(JetraceScript::c_Snap_Actor, paramData);
m_opponent1LastPathStruct = paramData;
if (m_unk0x108 == 0x14) {
m_unk0x108 = 0;
m_unk0xfc++;
if (m_opponent1LastPathStruct == 0x14) {
m_opponent1LastPathStruct = 0;
m_opponent1Laps++;
if (g_unk0x100f0c78 == m_unk0xfc) {
if (g_lapsCount == m_opponent1Laps) {
((LegoPathActor*) p_param.GetSender())->SetMaxLinearVel(0.1);
}
}
break;
case 12:
if (paramData <= m_unk0x10c || paramData >= m_unk0x10c + 5) {
case JetraceScript::c_Valerie_Actor:
if (paramData <= m_opponent2LastPathStruct || paramData >= m_opponent2LastPathStruct + 5) {
break;
}
FUN_10016930(12, paramData);
SetProgressPosition(JetraceScript::c_Valerie_Actor, paramData);
m_unk0x10c = paramData;
m_opponent2LastPathStruct = paramData;
if (m_unk0x10c == 0x14) {
m_unk0x10c = 0;
m_unk0x100++;
if (m_opponent2LastPathStruct == 0x14) {
m_opponent2LastPathStruct = 0;
m_opponent2Laps++;
if (g_unk0x100f0c78 == m_unk0x100) {
if (g_lapsCount == m_opponent2Laps) {
((LegoPathActor*) p_param.GetSender())->SetMaxLinearVel(0.1);
}
}
@ -261,26 +265,28 @@ MxLong JetskiRace::HandlePathStruct(LegoPathStructNotificationParam& p_param)
}
// FUNCTION: LEGO1 0x10016930
void JetskiRace::FUN_10016930(MxS32 p_param1, MxS16 p_param2)
void JetskiRace::SetProgressPosition(MxS32 p_actorId, MxS16 p_progress)
{
MxS32 local4;
MxS32 laps;
MxStillPresenter* presenter = NULL;
MxS32 x, y;
if (p_param1 == 11) {
presenter = m_unk0x128;
local4 = m_unk0xfc;
if (p_actorId == JetraceScript::c_Snap_Actor) {
presenter = m_opponent1Locator;
laps = m_opponent1Laps;
}
else if (p_param1 == 12) {
presenter = m_unk0x12c;
local4 = m_unk0x100;
else if (p_actorId == JetraceScript::c_Valerie_Actor) {
presenter = m_opponent2Locator;
laps = m_opponent2Laps;
}
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);
x = m_progressBarRect.GetLeft() + 0.5 +
(m_progressBarRect.GetRight() - m_progressBarRect.GetLeft() + 1) * (laps * 20.0 + p_progress) /
(g_lapsCount * 20.0);
y = m_progressBarRect.GetTop() + 0.5 +
(m_progressBarRect.GetBottom() - m_progressBarRect.GetTop() + 1) * (laps * 20.0 + p_progress) /
(g_lapsCount * 20.0);
presenter->SetPosition(x, y);
}

View File

@ -17,18 +17,18 @@ extern MxBool g_unk0x100f119c;
// FUNCTION: LEGO1 0x10015aa0
LegoRace::LegoRace()
{
m_unk0xf8 = 0;
m_unk0xfc = 0;
m_unk0x100 = 0;
m_unk0x104 = 0;
m_unk0x108 = 0;
m_unk0x10c = 0;
m_playerLaps = 0;
m_opponent1Laps = 0;
m_opponent2Laps = 0;
m_playerLastPathStruct = 0;
m_opponent1LastPathStruct = 0;
m_opponent2LastPathStruct = 0;
m_raceState = NULL;
m_maps[0] = NULL;
m_maps[1] = NULL;
m_maps[2] = NULL;
m_unk0x128 = 0;
m_unk0x12c = 0;
m_mapsLocators[0] = NULL;
m_mapsLocators[1] = NULL;
m_mapsLocators[2] = NULL;
m_opponent1Locator = 0;
m_opponent2Locator = 0;
m_pathActor = 0;
m_act1State = NULL;
m_destLocation = LegoGameState::e_undefined;
@ -116,22 +116,22 @@ void LegoRace::Enable(MxBool p_enable)
// FUNCTION: LEGO1 0x10015f30
RaceState::RaceState()
{
m_state[0].m_id = 1;
m_state[0].m_unk0x02 = 0;
m_state[0].m_score = 0;
m_state[1].m_id = 2;
m_state[1].m_unk0x02 = 0;
m_state[1].m_score = 0;
m_state[2].m_id = 3;
m_state[2].m_unk0x02 = 0;
m_state[2].m_score = 0;
m_state[3].m_id = 4;
m_state[3].m_unk0x02 = 0;
m_state[3].m_score = 0;
m_state[4].m_id = 5;
m_state[4].m_unk0x02 = 0;
m_state[4].m_score = 0;
m_unk0x28 = 0;
m_entries[0].m_id = 1;
m_entries[0].m_lastScore = 0;
m_entries[0].m_score = 0;
m_entries[1].m_id = 2;
m_entries[1].m_lastScore = 0;
m_entries[1].m_score = 0;
m_entries[2].m_id = 3;
m_entries[2].m_lastScore = 0;
m_entries[2].m_score = 0;
m_entries[3].m_id = 4;
m_entries[3].m_lastScore = 0;
m_entries[3].m_score = 0;
m_entries[4].m_id = 5;
m_entries[4].m_lastScore = 0;
m_entries[4].m_score = 0;
m_state = RaceState::e_carrace;
}
// FUNCTION: LEGO1 0x10016140
@ -141,7 +141,7 @@ MxResult RaceState::Serialize(LegoStorage* p_storage)
LegoState::Serialize(p_storage);
for (MxS16 i = 0; i < 5; i++) {
m_state[i].Serialize(p_storage);
m_entries[i].Serialize(p_storage);
}
return SUCCESS;
@ -156,8 +156,8 @@ RaceState::Entry* RaceState::GetState(MxU8 p_id)
return NULL;
}
if (m_state[i].m_id == p_id) {
return m_state + i;
if (m_entries[i].m_id == p_id) {
return m_entries + i;
}
}
}

View File

@ -19,7 +19,7 @@ Mx3DPointFloat LegoRaceActor::g_unk0x10102b08 = Mx3DPointFloat(0.0, 2.0, 0.0);
// FUNCTION: LEGO1 0x100145d0
LegoRaceActor::LegoRaceActor()
{
m_unk0x70 = 0;
m_lastPathStruct = 0;
m_unk0x08 = 0;
}

View File

@ -264,7 +264,7 @@ void LegoRaceCar::ParseAction(char* p_extra)
LegoRace* currentWorld = (LegoRace*) CurrentWorld();
if (KeyValueStringParse(buffer, g_strCOMP, p_extra) && currentWorld) {
currentWorld->VTable0x7c(this, atoi(buffer));
currentWorld->SetMapLocator(this, atoi(buffer));
}
if (m_userNavFlag) {
@ -663,7 +663,7 @@ void LegoJetski::ParseAction(char* p_extra)
JetskiRace* currentWorld = (JetskiRace*) CurrentWorld();
if (KeyValueStringParse(buffer, g_strCOMP, p_extra) && currentWorld) {
currentWorld->VTable0x7c(this, atoi(buffer));
currentWorld->SetMapLocator(this, atoi(buffer));
}
}

View File

@ -44,7 +44,7 @@ MxFloat g_unk0x100da044 = 8.0f;
LegoCarRaceActor::LegoCarRaceActor()
{
m_unk0x08 = 1.0f;
m_unk0x70 = 0.0f;
m_lastPathStruct = 0.0f;
m_animState = 0;
m_maxLinearVel = 0.0f;
m_frequencyFactor = 1.0f;
@ -76,8 +76,8 @@ void LegoCarRaceActor::FUN_10080590(float p_time)
LegoPathActor* userActor = UserActor();
if (userActor) {
// All known implementations of LegoPathActor->VTable0x5c() return LegoPathActor::m_unk0x70
deltaUnk0x70 = m_unk0x70 - userActor->VTable0x5c();
// All known implementations of LegoPathActor->GetLastPathStruct() return LegoPathActor::m_lastPathStruct
deltaUnk0x70 = m_lastPathStruct - userActor->GetLastPathStruct();
}
else {
deltaUnk0x70 = 0;
@ -457,14 +457,8 @@ MxU32 LegoCarRaceActor::VTable0x6c(
LegoROI* firstROI = (LegoROI*) co->front();
if (firstROI->FUN_100a9410(
p_v1,
p_v2,
p_f1,
p_f2,
p_v3,
m_collideBox && actor->GetCollideBox()
)) {
if (firstROI
->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) {
HitActor(actor, TRUE);
if (actor->HitActor(this, FALSE) < 0) {
@ -477,14 +471,8 @@ MxU32 LegoCarRaceActor::VTable0x6c(
LegoROI* lastROI = (LegoROI*) co->back();
if (lastROI->FUN_100a9410(
p_v1,
p_v2,
p_f1,
p_f2,
p_v3,
m_collideBox && actor->GetCollideBox()
)) {
if (lastROI
->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) {
HitActor(actor, TRUE);
if (actor->HitActor(this, FALSE) < 0) {
@ -497,7 +485,7 @@ MxU32 LegoCarRaceActor::VTable0x6c(
}
}
else {
if (roi->FUN_100a9410(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) {
if (roi->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) {
HitActor(actor, TRUE);
if (actor->HitActor(this, FALSE) < 0) {
@ -545,7 +533,7 @@ MxU32 LegoJetskiRaceActor::VTable0x6c(
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())) {
if (roi->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) {
HitActor(actor, TRUE);
if (actor->HitActor(this, FALSE) < 0) {

View File

@ -1201,7 +1201,7 @@ MxU32 LegoAnimPresenter::VTable0x94(Vector3& p_v1, Vector3& p_v2, float p_f1, fl
len = sqrt(len);
if (len <= m_unk0xa4 + p_f2 && m_roiMapSize != 0 && m_roiMap != NULL) {
for (MxU32 i = 1; i <= m_roiMapSize; i++) {
if (m_roiMap[i]->GetLODCount() != 0 && m_roiMap[i]->FUN_100a9410(p_v1, p_v2, p_f1, p_f2, p_v3, FALSE)) {
if (m_roiMap[i]->GetLODCount() != 0 && m_roiMap[i]->Intersect(p_v1, p_v2, p_f1, p_f2, p_v3, FALSE)) {
return TRUE;
}
}

View File

@ -604,8 +604,8 @@ void Isle::Enable(MxBool p_enable)
NotificationManager()->Send(this, MxNotificationParam(c_notificationTransitioned, NULL));
SetIsWorldActive(FALSE);
break;
case LegoGameState::e_jetrace2:
if (((JetskiRaceState*) GameState()->GetState("JetskiRaceState"))->m_unk0x28 == 2) {
case LegoGameState::e_jetraceFinished:
if (((JetskiRaceState*) GameState()->GetState("JetskiRaceState"))->m_state == RaceState::e_finished) {
m_act1state->m_state = Act1State::e_transitionToJetski;
}
@ -742,16 +742,16 @@ void Isle::Enable(MxBool p_enable)
case Act1State::e_transitionToJetski: {
((IslePathActor*) UserActor())
->SpawnPlayer(
LegoGameState::e_jetrace2,
LegoGameState::e_jetraceFinished,
FALSE,
IslePathActor::c_spawnBit1 | IslePathActor::c_playMusic | IslePathActor::c_spawnBit3
);
JetskiRaceState* raceState = (JetskiRaceState*) GameState()->GetState("JetskiRaceState");
if (raceState->m_unk0x28 == 2) {
if (raceState->m_state == RaceState::e_finished) {
IsleScript::Script script = IsleScript::c_noneIsle;
switch (raceState->GetState(GameState()->GetActorId())->GetUnknown0x02()) {
switch (raceState->GetState(GameState()->GetActorId())->GetLastScore()) {
case 1:
script = IsleScript::c_sjs014in_RunAnim;
break;
@ -776,16 +776,16 @@ void Isle::Enable(MxBool p_enable)
GameState()->m_currentArea = LegoGameState::e_carraceExterior;
((IslePathActor*) UserActor())
->SpawnPlayer(
LegoGameState::e_unk21,
LegoGameState::e_carraceFinished,
FALSE,
IslePathActor::c_spawnBit1 | IslePathActor::c_playMusic | IslePathActor::c_spawnBit3
);
CarRaceState* raceState = (CarRaceState*) GameState()->GetState("CarRaceState");
if (raceState->m_unk0x28 == 2) {
if (raceState->m_state == RaceState::e_finished) {
IsleScript::Script script = IsleScript::c_noneIsle;
switch (raceState->GetState(GameState()->GetActorId())->GetUnknown0x02()) {
switch (raceState->GetState(GameState()->GetActorId())->GetLastScore()) {
case 1:
script = IsleScript::c_srt003in_RunAnim;
break;
@ -849,7 +849,8 @@ void Isle::Enable(MxBool p_enable)
(m_act1state->m_state != Act1State::e_none || GameState()->m_currentArea != LegoGameState::e_copter) &&
(m_act1state->m_state != Act1State::e_none || GameState()->m_currentArea != LegoGameState::e_jetski) &&
(m_act1state->m_state != Act1State::e_none || GameState()->m_currentArea != LegoGameState::e_skateboard) &&
(m_act1state->m_state != Act1State::e_none || GameState()->m_currentArea != LegoGameState::e_jetrace2)) {
(m_act1state->m_state != Act1State::e_none || GameState()->m_currentArea != LegoGameState::e_jetraceFinished
)) {
Disable(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen);
}

View File

@ -93,7 +93,7 @@ MxLong Score::Notify(MxParam& p_param)
ret = 1;
break;
case c_notificationEndAction:
ret = FUN_10001510((MxEndActionNotificationParam&) p_param);
ret = HandleEndAction((MxEndActionNotificationParam&) p_param);
break;
case c_notificationKeyPress:
if (((LegoEventNotificationParam&) p_param).GetKey() == SDLK_SPACE) {
@ -102,7 +102,7 @@ MxLong Score::Notify(MxParam& p_param)
ret = 1;
break;
case c_notificationControl:
ret = FUN_100016d0((LegoControlManagerNotificationParam&) p_param);
ret = HandleControl((LegoControlManagerNotificationParam&) p_param);
break;
case c_notificationTransitioned:
DeleteObjects(g_infoscorScript, InfoscorScript::c_LegoBox1_Flc, InfoscorScript::c_LegoBox3_Flc);
@ -118,7 +118,7 @@ MxLong Score::Notify(MxParam& p_param)
}
// FUNCTION: LEGO1 0x10001510
MxLong Score::FUN_10001510(MxEndActionNotificationParam& p_param)
MxLong Score::HandleEndAction(MxEndActionNotificationParam& p_param)
{
MxDSAction* action = p_param.GetAction();
@ -163,11 +163,11 @@ void Score::ReadyWorld()
}
// FUNCTION: LEGO1 0x100016d0
MxLong Score::FUN_100016d0(LegoControlManagerNotificationParam& p_param)
MxLong Score::HandleControl(LegoControlManagerNotificationParam& p_param)
{
MxS16 unk0x28 = p_param.m_enabledChild;
MxS16 enabledChild = p_param.m_enabledChild;
if (unk0x28 == 1 || p_param.m_clickedObjectId == InfoscorScript::c_LegoBox_Ctl) {
if (enabledChild == 1 || p_param.m_clickedObjectId == InfoscorScript::c_LegoBox_Ctl) {
switch (p_param.m_clickedObjectId) {
case InfoscorScript::c_LeftArrow_Ctl:
m_destLocation = LegoGameState::e_infomain;
@ -190,7 +190,7 @@ MxLong Score::FUN_100016d0(LegoControlManagerNotificationParam& p_param)
break;
}
case InfoscorScript::c_LegoBox_Ctl: {
switch (unk0x28) {
switch (enabledChild) {
case 1: {
MxDSAction action;
action.SetObjectId(InfoscorScript::c_LegoBox1_Flc);
@ -293,21 +293,21 @@ void Score::Paint()
// FUNCTION: BETA10 0x100f4a52
void Score::FillArea(MxS32 i_activity, MxS32 i_actor, MxS16 score)
{
MxS32 local3c[] = {0x2b00, 0x5700, 0x8000, 0xab00, 0xd600};
MxS32 local14[] = {0x2a, 0x27, 0x29, 0x29, 0x2a};
MxS32 local50[] = {0x2f, 0x56, 0x81, 0xaa, 0xd4};
MxS32 local28[] = {0x25, 0x29, 0x27, 0x28, 0x28};
MxS32 areaYOffsets[] = {0x2b00, 0x5700, 0x8000, 0xab00, 0xd600};
MxS32 areaHeights[] = {0x2a, 0x27, 0x29, 0x29, 0x2a};
MxS32 areaXOffsets[] = {0x2f, 0x56, 0x81, 0xaa, 0xd4};
MxS32 areaWidths[] = {0x25, 0x29, 0x27, 0x28, 0x28};
MxS32 colors[] = {0x11, 0x0f, 0x08, 0x05};
assert(i_activity >= 0 && i_activity < 5);
assert(i_actor >= 0 && i_actor < 5);
assert(score >= 0 && score < 4);
MxU8* ptr = m_surface + local3c[i_actor] + local50[i_activity];
MxU8* ptr = m_surface + areaYOffsets[i_actor] + areaXOffsets[i_activity];
MxS32 color = colors[score];
MxS32 size = local28[i_activity];
MxS32 size = areaWidths[i_activity];
for (MxS32 i = 0; i < local14[i_actor]; i++) {
for (MxS32 i = 0; i < areaHeights[i_actor]; i++) {
memset(ptr, color, size);
ptr += 0x100;
}

View File

@ -15,19 +15,35 @@ DECOMP_SIZE_ASSERT(LegoLOD, 0x20)
DECOMP_SIZE_ASSERT(LegoLOD::Mesh, 0x08)
// GLOBAL: LEGO1 0x101013d4
LPDIRECT3DRMMATERIAL g_unk0x101013d4 = NULL;
// GLOBAL: BETA10 0x10207230
LPDIRECT3DRMMATERIAL g_lodMaterial = NULL;
// GLOBAL: LEGO1 0x101013dc
// GLOBAL: BETA10 0x10207238
const char* g_InhPrefix = "inh";
inline IDirect3DRM2* GetD3DRM(Tgl::Renderer* pRenderer);
inline BOOL GetMeshData(IDirect3DRMMesh*& mesh, D3DRMGROUPINDEX& index, Tgl::Mesh* pMesh);
#ifdef BETA10
inline BOOL GetD3DRM_legolod(IDirect3DRM2*& d3drm, Tgl::Renderer* pRenderer);
#else
inline IDirect3DRM2* GetD3DRM_legolod(Tgl::Renderer* pRenderer);
#endif
inline BOOL GetMeshData(IDirect3DRMMesh** mesh, D3DRMGROUPINDEX* index, Tgl::Mesh* pMesh);
// FUNCTION: LEGO1 0x100aa380
// FUNCTION: BETA10 0x1018ce90
LegoLOD::LegoLOD(Tgl::Renderer* p_renderer) : ViewLOD(p_renderer)
{
if (g_unk0x101013d4 == NULL) {
GetD3DRM(p_renderer)->CreateMaterial(10.0, &g_unk0x101013d4);
if (g_lodMaterial == NULL) {
#ifdef BETA10
IDirect3DRM2* d3drm = NULL;
assert((p_renderer != NULL));
GetD3DRM_legolod(d3drm, p_renderer);
if (d3drm->CreateMaterial(10.0, &g_lodMaterial)) {
assert(0);
}
#else
GetD3DRM_legolod(p_renderer)->CreateMaterial(10.0, &g_lodMaterial);
#endif
}
m_melems = NULL;
@ -38,6 +54,7 @@ LegoLOD::LegoLOD(Tgl::Renderer* p_renderer) : ViewLOD(p_renderer)
}
// FUNCTION: LEGO1 0x100aa450
// FUNCTION: BETA10 0x1018d017
LegoLOD::~LegoLOD()
{
if (m_numMeshes && m_melems != NULL) {
@ -54,21 +71,59 @@ LegoLOD::~LegoLOD()
}
}
#ifdef BETA10
/// This class does not exist in LEGO1.
class UnknownBeta0x1018e7e0 {
public:
// FUNCTION: BETA10 0x1018e7e0
UnknownBeta0x1018e7e0()
{
m_unk0x00 = 0;
m_unk0x04 = 0;
m_unk0x08 = 0;
m_unk0x0c = 0;
m_unk0x10 = 0;
m_unk0x14 = 0;
m_unk0x18 = 0;
}
// STUB: BETA10 0x1018e840
undefined4 BETA10_1018e840(LegoStorage* p_storage) { return 0; }
undefined4 m_unk0x00;
undefined4 m_unk0x04;
undefined4 m_unk0x08;
undefined4 m_unk0x0c;
undefined4 m_unk0x10;
undefined4 m_unk0x14;
undefined4 m_unk0x18;
undefined4 m_unk0x1c;
};
#endif
// FUNCTION: LEGO1 0x100aa510
// FUNCTION: BETA10 0x1018d15d
LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_textureContainer, LegoStorage* p_storage)
{
using Tgl::Succeeded;
float(*normals)[3] = NULL;
float(*vertices)[3] = NULL;
float(*textureVertices)[2] = NULL;
LegoS32 numVerts = 0;
LegoS32 numNormals = 0;
LegoS32 numTextureVertices = 0;
LegoMesh* mesh = NULL;
LegoMesh* legoMesh = NULL;
LegoU32(*polyIndices)[3] = NULL;
LegoU32(*textureIndices)[3] = NULL;
LegoTextureInfo* textureInfo = NULL;
LegoU8 local4c = 0; // BETA10 only, only written, never read
LegoU32 numPolys, numVertices, numTextureIndices, meshIndex;
LegoU32 i, indexBackwards, indexForwards, tempNumVertsAndNormals;
LegoFloat red, green, blue, alpha;
IDirect3DRMMesh* d3dmesh;
D3DRMGROUPINDEX index;
unsigned char paletteEntries[256];
if (p_storage->Read(&m_flags, sizeof(LegoU32)) != SUCCESS) {
@ -76,6 +131,14 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text
}
if (SkipReadingData()) {
#ifdef BETA10
// There was an additional field of the correct type here in BETA10
m_flags = (unsigned int) new UnknownBeta0x1018e7e0();
if (((UnknownBeta0x1018e7e0*) m_flags)->BETA10_1018e840(p_storage)) {
assert(0);
return FAILURE;
}
#endif
return SUCCESS;
}
@ -86,11 +149,15 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text
}
if (m_numMeshes == 0) {
#ifndef BETA10
ClearFlag(c_hasMesh);
#endif
return SUCCESS;
}
#ifndef BETA10
SetFlag(c_hasMesh);
#endif
m_melems = new Mesh[m_numMeshes];
memset(m_melems, 0, sizeof(*m_melems) * m_numMeshes);
@ -99,19 +166,24 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text
indexForwards = 0;
if (p_storage->Read(&tempNumVertsAndNormals, sizeof(LegoU32)) != SUCCESS) {
assertIfBeta10(0);
goto done;
}
// TODO: Can't get this one right
numVerts = *((LegoU16*) &tempNumVertsAndNormals) & MAXSHORT;
numNormals = (*((LegoU16*) &tempNumVertsAndNormals + 1) >> 1) & MAXSHORT;
if (p_storage->Read(&numTextureVertices, sizeof(LegoS32)) != SUCCESS) {
assertIfBeta10(0);
goto done;
}
if (numVerts > 0) {
vertices = new float[numVerts][sizeOfArray(*vertices)];
if (p_storage->Read(vertices, numVerts * 3 * sizeof(float)) != SUCCESS) {
// LINE: BETA10 0x1018d443
assertIfBeta10(0);
goto done;
}
}
@ -119,6 +191,7 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text
if (numNormals > 0) {
normals = new float[numNormals][sizeOfArray(*normals)];
if (p_storage->Read(normals, numNormals * 3 * sizeof(float)) != SUCCESS) {
assertIfBeta10(0);
goto done;
}
}
@ -126,37 +199,44 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text
if (numTextureVertices > 0) {
textureVertices = new float[numTextureVertices][sizeOfArray(*textureVertices)];
if (p_storage->Read(textureVertices, numTextureVertices * 2 * sizeof(float)) != SUCCESS) {
// LINE: BETA10 0x1018d513
assertIfBeta10(0);
goto done;
}
}
for (i = 0; i < m_numMeshes; i++) {
LegoU32 numPolys, numVertices, numTextureIndices, meshIndex;
local4c = 0;
const LegoChar *textureName, *materialName;
Tgl::ShadingModel shadingModel;
if (p_storage->Read(&numPolys, 2) != SUCCESS) {
assertIfBeta10(0);
goto done;
}
m_numPolys += numPolys & USHRT_MAX;
if (p_storage->Read(&numVertices, 2) != SUCCESS) {
assertIfBeta10(0);
goto done;
}
polyIndices = new LegoU32[numPolys & USHRT_MAX][sizeOfArray(*polyIndices)];
if (p_storage->Read(polyIndices, (numPolys & USHRT_MAX) * 3 * sizeof(LegoU32)) != SUCCESS) {
assertIfBeta10(0);
goto done;
}
if (p_storage->Read(&numTextureIndices, sizeof(numTextureIndices)) != SUCCESS) {
assertIfBeta10(0);
goto done;
}
if (numTextureIndices > 0) {
textureIndices = new LegoU32[numPolys & USHRT_MAX][sizeOfArray(*textureIndices)];
if (p_storage->Read(textureIndices, (numPolys & USHRT_MAX) * 3 * sizeof(LegoU32)) != SUCCESS) {
assertIfBeta10(0);
goto done;
}
}
@ -164,13 +244,14 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text
textureIndices = NULL;
}
mesh = new LegoMesh();
legoMesh = new LegoMesh();
if (mesh->Read(p_storage) != SUCCESS) {
if (legoMesh->Read(p_storage) != SUCCESS) {
assertIfBeta10(0);
goto done;
}
switch (mesh->GetShading()) {
switch (legoMesh->GetShading()) {
case LegoMesh::e_flat:
shadingModel = Tgl::Flat;
break;
@ -183,19 +264,23 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text
m_numVertices += numVertices & USHRT_MAX;
textureName = mesh->GetTextureName();
materialName = mesh->GetMaterialName();
textureName = legoMesh->GetTextureName();
materialName = legoMesh->GetMaterialName();
if (HasInhPrefix(textureName) || HasInhPrefix(materialName)) {
meshIndex = indexBackwards;
indexBackwards--;
}
else {
local4c = 1;
meshIndex = indexForwards;
indexForwards++;
}
m_melems[meshIndex].m_tglMesh = m_meshBuilder->CreateMesh(
Tgl::MeshBuilder* locMesh = m_meshBuilder;
assert(locMesh);
m_melems[meshIndex].m_tglMesh = locMesh->CreateMesh(
numPolys & USHRT_MAX,
numVertices & USHRT_MAX,
vertices,
@ -204,58 +289,84 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text
polyIndices,
textureIndices,
shadingModel
// LINE: LEGO1 0x100aa885
);
if (m_melems[meshIndex].m_tglMesh == NULL) {
assertIfBeta10(0);
goto done;
}
m_melems[meshIndex].m_tglMesh->SetShadingModel(shadingModel);
Tgl::Result tglResult = m_melems[meshIndex].m_tglMesh->SetShadingModel(shadingModel);
// clang-format off
assert(Succeeded( tglResult ));
// clang-format on
if (textureName != NULL) {
if (mesh->GetUseAlias()) {
LegoROI::GetPaletteEntries(textureName, paletteEntries, sizeOfArray(paletteEntries));
if (legoMesh->GetUseAlias() &&
LegoROI::GetPaletteEntries(textureName, paletteEntries, sizeOfArray(paletteEntries))) {
#ifdef BETA10
textureName = (const LegoChar*) paletteEntries;
#endif
}
textureInfo = p_textureContainer->Get(mesh->GetTextureName());
textureInfo = p_textureContainer->Get(legoMesh->GetTextureName());
if (textureInfo == NULL) {
assertIfBeta10(0);
goto done;
}
m_melems[meshIndex].m_tglMesh->SetColor(1.0F, 1.0F, 1.0F, 0.0F);
tglResult = m_melems[meshIndex].m_tglMesh->SetColor(1.0F, 1.0F, 1.0F, 0.0F);
// clang-format off
assert(Succeeded( tglResult ));
// clang-format on
#ifdef BETA10
// This typecast is invalid, `textureInfo` had a different type in BETA10
tglResult = m_melems[meshIndex].m_tglMesh->SetTexture((TglImpl::TextureImpl*) textureInfo);
// clang-format off
assert(Succeeded( tglResult ));
// clang-format on
#else
LegoTextureInfo::SetGroupTexture(m_melems[meshIndex].m_tglMesh, textureInfo);
#endif
m_melems[meshIndex].m_textured = TRUE;
}
else {
LegoFloat red = 1.0F;
LegoFloat green = 0.0F;
LegoFloat blue = 1.0F;
LegoFloat alpha = 0.0F;
red = 1.0F;
// LINE: BETA10 0x1018db2d
green = 0.0F;
blue = 1.0F;
alpha = 0.0F;
if (mesh->GetUseAlias()) {
if (legoMesh->GetUseAlias()) {
LegoROI::GetRGBAColor(materialName, red, green, blue, alpha);
}
else {
red = mesh->GetColor().GetRed() / 255.0;
green = mesh->GetColor().GetGreen() / 255.0;
blue = mesh->GetColor().GetBlue() / 255.0;
alpha = mesh->GetAlpha();
red = legoMesh->GetColor().GetRed() / 255.0;
green = legoMesh->GetColor().GetGreen() / 255.0;
blue = legoMesh->GetColor().GetBlue() / 255.0;
alpha = legoMesh->GetAlpha();
}
m_melems[meshIndex].m_tglMesh->SetColor(red, green, blue, alpha);
tglResult = m_melems[meshIndex].m_tglMesh->SetColor(red, green, blue, alpha);
// clang-format off
// LINE: BETA10 0x1018dc72
assert(Succeeded( tglResult ));
// clang-format on
}
if (mesh->GetUnknown0x0d() > 0) {
IDirect3DRMMesh* mesh;
D3DRMGROUPINDEX index;
GetMeshData(mesh, index, m_melems[meshIndex].m_tglMesh);
mesh->SetGroupMaterial(index, g_unk0x101013d4);
if (legoMesh->GetUnknown0x0d() > 0) {
GetMeshData(&d3dmesh, &index, m_melems[meshIndex].m_tglMesh);
d3dmesh->SetGroupMaterial(index, g_lodMaterial);
}
if (mesh != NULL) {
delete mesh;
mesh = NULL;
if (legoMesh != NULL) {
delete legoMesh;
legoMesh = NULL;
}
if (polyIndices != NULL) {
delete[] polyIndices;
@ -267,6 +378,7 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text
}
}
// LINE: LEGO1 0x100aab45
m_meshOffset = indexForwards;
if (textureVertices != NULL) {
@ -291,8 +403,8 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text
if (textureVertices != NULL) {
delete[] textureVertices;
}
if (mesh != NULL) {
delete mesh;
if (legoMesh != NULL) {
delete legoMesh;
}
if (polyIndices != NULL) {
delete[] polyIndices;
@ -305,6 +417,7 @@ LegoResult LegoLOD::Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_text
}
// FUNCTION: LEGO1 0x100aabb0
// FUNCTION: BETA10 0x1018e02a
LegoLOD* LegoLOD::Clone(Tgl::Renderer* p_renderer)
{
LegoLOD* dupLod = new LegoLOD(p_renderer);
@ -312,6 +425,8 @@ LegoLOD* LegoLOD::Clone(Tgl::Renderer* p_renderer)
dupLod->m_meshBuilder = m_meshBuilder->Clone();
dupLod->m_melems = new Mesh[m_numMeshes];
assert(dupLod->m_melems);
for (LegoU32 i = 0; i < m_numMeshes; i++) {
dupLod->m_melems[i].m_tglMesh = m_melems[i].m_tglMesh->ShallowClone(dupLod->m_meshBuilder);
dupLod->m_melems[i].m_textured = m_melems[i].m_textured;
@ -339,11 +454,22 @@ LegoResult LegoLOD::SetColor(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blu
}
// FUNCTION: LEGO1 0x100aad00
// FUNCTION: BETA10 0x1018e241
LegoResult LegoLOD::SetTextureInfo(LegoTextureInfo* p_textureInfo)
{
using Tgl::Succeeded;
for (LegoU32 i = m_meshOffset; i < m_numMeshes; i++) {
if (m_melems[i].m_textured) {
#ifdef BETA10
// This function likely had a different signature in BETA10
Tgl::Result tglResult = m_melems[i].m_tglMesh->SetTexture((const Tgl::Texture*) p_textureInfo);
// clang-format off
assert(Succeeded( tglResult ));
// clang-format on
#else
LegoTextureInfo::SetGroupTexture(m_melems[i].m_tglMesh, p_textureInfo);
#endif
m_melems[i].m_tglMesh->SetColor(1.0F, 1.0F, 1.0F, 0.0F);
m_melems[i].m_textured = TRUE;
}
@ -353,11 +479,22 @@ LegoResult LegoLOD::SetTextureInfo(LegoTextureInfo* p_textureInfo)
}
// FUNCTION: LEGO1 0x100aad70
// FUNCTION: BETA10 0x1018e32c
LegoResult LegoLOD::UpdateTextureInfo(LegoTextureInfo* p_textureInfo)
{
using Tgl::Succeeded;
for (LegoU32 i = m_meshOffset; i < m_numMeshes; i++) {
if (m_melems[i].m_textured) {
#ifdef BETA10
// This function likely had a different signature in BETA10
Tgl::Result tglResult = m_melems[i].m_tglMesh->SetTexture((const Tgl::Texture*) p_textureInfo);
// clang-format off
assert(Succeeded( tglResult ));
// clang-format on
#else
LegoTextureInfo::SetGroupTexture(m_melems[i].m_tglMesh, p_textureInfo);
#endif
}
}
@ -379,15 +516,15 @@ LegoResult LegoLOD::GetTextureInfo(LegoTextureInfo*& p_textureInfo)
}
// FUNCTION: LEGO1 0x100aae20
// FUNCTION: BETA10 0x1018e46d
LegoBool LegoLOD::HasInhPrefix(const LegoChar* p_name)
{
if (p_name != NULL) {
if (!SDL_strncasecmp(p_name, g_InhPrefix, strlen(g_InhPrefix))) {
return TRUE;
}
if (p_name != NULL && !SDL_strncasecmp(p_name, g_InhPrefix, strlen(g_InhPrefix))) {
return TRUE;
}
else {
return FALSE;
}
return FALSE;
}
// FUNCTION: LEGO1 0x100aae60
@ -397,14 +534,31 @@ void LegoLOD::ClearMeshOffset()
m_meshOffset = 0;
}
inline BOOL GetMeshData(IDirect3DRMMesh*& mesh, D3DRMGROUPINDEX& index, Tgl::Mesh* pMesh)
// FUNCTION: BETA10 0x1018dfc4
inline BOOL GetMeshData(IDirect3DRMMesh** mesh, D3DRMGROUPINDEX* index, Tgl::Mesh* p_tglElem)
{
mesh = ((TglImpl::MeshImpl*) pMesh)->ImplementationData()->groupMesh;
index = ((TglImpl::MeshImpl*) pMesh)->ImplementationData()->groupIndex;
assert(p_tglElem);
TglImpl::MeshImpl* meshImpl = (TglImpl::MeshImpl*) p_tglElem;
// Note: Diff in BETA10 (thunked in recompile but not in orig)
*mesh = meshImpl->ImplementationData()->groupMesh;
*index = meshImpl->ImplementationData()->groupIndex;
return FALSE;
}
inline IDirect3DRM2* GetD3DRM(Tgl::Renderer* pRenderer)
#ifdef BETA10
// FUNCTION: BETA10 0x1018cfc5
inline BOOL GetD3DRM_legolod(IDirect3DRM2*& d3drm, Tgl::Renderer* p_tglRenderer)
{
// Note: Code duplication with viewmanager.cpp:GetD3DRM()
assert(p_tglRenderer);
TglImpl::RendererImpl* renderer = (TglImpl::RendererImpl*) p_tglRenderer;
// Note: Diff in BETA10 (thunked in recompile but not in orig)
d3drm = renderer->ImplementationData();
return 0;
}
#else
inline IDirect3DRM2* GetD3DRM_legolod(Tgl::Renderer* pRenderer)
{
return ((TglImpl::RendererImpl*) pRenderer)->ImplementationData();
}
#endif

View File

@ -9,6 +9,7 @@ class LegoTextureInfo;
class LegoStorage;
// VTABLE: LEGO1 0x100dbf10
// VTABLE: BETA10 0x101c3978
// SIZE 0x20
class LegoLOD : public ViewLOD {
public:
@ -22,9 +23,11 @@ class LegoLOD : public ViewLOD {
~LegoLOD() override;
// FUNCTION: LEGO1 0x100aae70
// FUNCTION: BETA10 0x1018e650
int NumPolys() const override { return m_numPolys; } // vtable+0x0c
// FUNCTION: LEGO1 0x100aae80
// FUNCTION: BETA10 0x1018e670
float VTable0x10() override { return 0.0; } // vtable+0x10
LegoResult Read(Tgl::Renderer* p_renderer, LegoTextureContainer* p_textureContainer, LegoStorage* p_storage);
@ -38,6 +41,7 @@ class LegoLOD : public ViewLOD {
static LegoBool HasInhPrefix(const LegoChar* p_name);
// SYNTHETIC: LEGO1 0x100aa430
// SYNTHETIC: BETA10 0x1018e530
// LegoLOD::`scalar deleting destructor'
protected:

View File

@ -56,12 +56,13 @@ const char* g_alwaysLoadNames[] = {"rcuser", "jsuser", "dunebugy", "chtrblad", "
ColorOverride g_colorOverride = NULL;
// GLOBAL: LEGO1 0x101013b0
// GLOBAL: BETA10 0x10206f24
TextureHandler g_textureHandler = NULL;
// FUNCTION: LEGO1 0x100a81b0
// FUNCTION: BETA10 0x101898c0
// FUNCTION: ALPHA 0x100bb1c0
void LegoROI::FUN_100a81b0(const LegoChar* p_error, ...)
void LegoROI::ReportError(const LegoChar* p_error, ...)
{
// Probably a printf-like debug function that was removed early.
// No known implementation in any of the binaries.
@ -418,7 +419,7 @@ LegoResult LegoROI::ApplyChildAnimationTransformation(
}
}
else {
FUN_100a81b0("%s ROI Not found\n", name);
ReportError("%s ROI Not found\n", name);
#ifdef BETA10
_RPT1(_CRT_ASSERT, "%s ROI Not Found", name);
// Note that the macro inserts an INT3, which breaks the assumption that INT3
@ -582,7 +583,7 @@ LegoResult LegoROI::GetTextureInfo(LegoTextureInfo*& p_textureInfo)
// FUNCTION: LEGO1 0x100a9330
// FUNCTION: BETA10 0x1018b22c
LegoResult LegoROI::FUN_100a9330(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha)
LegoResult LegoROI::SetColor(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha)
{
return SetLodColor(p_red, p_green, p_blue, p_alpha);
}
@ -601,11 +602,11 @@ LegoResult LegoROI::SetLodColor(const LegoChar* p_name)
// FUNCTION: LEGO1 0x100a93b0
// FUNCTION: BETA10 0x1018b2c0
LegoResult LegoROI::FUN_100a93b0(const LegoChar* p_name)
LegoResult LegoROI::SetColorByName(const LegoChar* p_name)
{
MxFloat red, green, blue, alpha;
if (ColorAliasLookup(p_name, red, green, blue, alpha)) {
return FUN_100a9330(red, green, blue, alpha);
return SetColor(red, green, blue, alpha);
}
return 0;
@ -613,83 +614,85 @@ LegoResult LegoROI::FUN_100a93b0(const LegoChar* p_name)
// FUNCTION: LEGO1 0x100a9410
// FUNCTION: BETA10 0x1018b324
LegoU32 LegoROI::FUN_100a9410(
Vector3& p_v1,
Vector3& p_v2,
float p_f1,
float p_f2,
Vector3& p_v3,
LegoU32 LegoROI::Intersect(
Vector3& p_rayOrigin,
Vector3& p_rayDirection,
float p_rayLength,
float p_unused,
Vector3& p_intersectionPoint,
LegoBool p_collideBox
)
{
if (p_collideBox) {
Mx3DPointFloat v2(p_v2);
v2 *= p_f1;
v2 += p_v1;
Mx3DPointFloat v2(p_rayDirection);
v2 *= p_rayLength;
v2 += p_rayOrigin;
Mx4DPointFloat localc0;
Mx4DPointFloat local9c;
Mx4DPointFloat local168;
Mx4DPointFloat local70;
Mx4DPointFloat local150[6];
Mx4DPointFloat minPoint;
Mx4DPointFloat maxPoint;
Mx4DPointFloat centerPoint;
Mx4DPointFloat untransformedPoint;
Mx4DPointFloat boxFacePlanes[6];
Vector3 local58(&localc0[0]);
Vector3 locala8(&local9c[0]);
Vector3 local38(&local168[0]);
Vector3 boundingBoxMin(&minPoint[0]);
Vector3 boundingBoxMax(&maxPoint[0]);
Vector3 boundingBoxCenter(&centerPoint[0]);
Mx3DPointFloat local4c(p_v1);
Mx3DPointFloat rayOrigin(p_rayOrigin);
local58 = m_bounding_box.Min();
locala8 = m_bounding_box.Max();
boundingBoxMin = m_bounding_box.Min();
boundingBoxMax = m_bounding_box.Max();
localc0[3] = local9c[3] = local168[3] = 1.0f;
minPoint[3] = maxPoint[3] = centerPoint[3] = 1.0f;
local38 = local58;
local38 += locala8;
local38 *= 0.5f;
boundingBoxCenter = boundingBoxMin;
boundingBoxCenter += boundingBoxMax;
boundingBoxCenter *= 0.5f;
local70 = localc0;
localc0.SetMatrixProduct(local70, (float*) m_local2world.GetData());
untransformedPoint = minPoint;
minPoint.SetMatrixProduct(untransformedPoint, (float*) m_local2world.GetData());
local70 = local9c;
local9c.SetMatrixProduct(local70, (float*) m_local2world.GetData());
untransformedPoint = maxPoint;
maxPoint.SetMatrixProduct(untransformedPoint, (float*) m_local2world.GetData());
local70 = local168;
local168.SetMatrixProduct(local70, (float*) m_local2world.GetData());
untransformedPoint = centerPoint;
centerPoint.SetMatrixProduct(untransformedPoint, (float*) m_local2world.GetData());
p_v3 = m_local2world[3];
p_intersectionPoint = m_local2world[3];
LegoS32 i;
for (i = 0; i < 6; i++) {
local150[i] = m_local2world[i % 3];
boxFacePlanes[i] = m_local2world[i % 3];
if (i > 2) {
local150[i][3] = -local58.Dot(local58, local150[i]);
boxFacePlanes[i][3] = -boundingBoxMin.Dot(boundingBoxMin, boxFacePlanes[i]);
}
else {
local150[i][3] = -locala8.Dot(locala8, local150[i]);
boxFacePlanes[i][3] = -boundingBoxMax.Dot(boundingBoxMax, boxFacePlanes[i]);
}
if (local150[i][3] + local38.Dot(local38, local150[i]) < 0.0f) {
local150[i] *= -1.0f;
if (boxFacePlanes[i][3] + boundingBoxCenter.Dot(boundingBoxCenter, boxFacePlanes[i]) < 0.0f) {
boxFacePlanes[i] *= -1.0f;
}
}
for (i = 0; i < 6; i++) {
float local50 = p_v2.Dot(p_v2, local150[i]);
float intersectionDistance = p_rayDirection.Dot(p_rayDirection, boxFacePlanes[i]);
if (local50 >= 0.01 || local50 < -0.01) {
local50 = -((local150[i][3] + local4c.Dot(local4c, local150[i])) / local50);
if (intersectionDistance >= 0.01 || intersectionDistance < -0.01) {
intersectionDistance =
-((boxFacePlanes[i][3] + rayOrigin.Dot(rayOrigin, boxFacePlanes[i])) / intersectionDistance);
if (local50 >= 0.0f && local50 <= p_f1) {
Mx3DPointFloat local17c(p_v2);
local17c *= local50;
local17c += local4c;
if (intersectionDistance >= 0.0f && intersectionDistance <= p_rayLength) {
Mx3DPointFloat intersectionPoint(p_rayDirection);
intersectionPoint *= intersectionDistance;
intersectionPoint += rayOrigin;
LegoS32 j;
for (j = 0; j < 6; j++) {
if (i != j && i - j != 3 && j - i != 3) {
if (local150[j][3] + local17c.Dot(local17c, local150[j]) < 0.0f) {
if (boxFacePlanes[j][3] + intersectionPoint.Dot(intersectionPoint, boxFacePlanes[j]) <
0.0f) {
break;
}
}
@ -703,45 +706,46 @@ LegoU32 LegoROI::FUN_100a9410(
}
}
else {
Mx3DPointFloat v1(p_v1);
Mx3DPointFloat v1(p_rayOrigin);
v1 -= GetWorldBoundingSphere().Center();
float local10 = GetWorldBoundingSphere().Radius();
float local8 = p_v2.Dot(p_v2, p_v2);
float localc = p_v2.Dot(p_v2, v1) * 2.0f;
float local14 = v1.Dot(v1, v1) - (local10 * local10);
float radius = GetWorldBoundingSphere().Radius();
// Quadratic equation to solve for ray-sphere intersection: at^2 + bt + c = 0
float a = p_rayDirection.Dot(p_rayDirection, p_rayDirection);
float b = p_rayDirection.Dot(p_rayDirection, v1) * 2.0f;
float c = v1.Dot(v1, v1) - (radius * radius);
if (local8 >= 0.001 || local8 <= -0.001) {
float local1c = -1.0f;
float local18 = (localc * localc) - (local14 * local8 * 4.0f);
if (a >= 0.001 || a <= -0.001) {
float distance = -1.0f;
float discriminant = (b * b) - (c * a * 4.0f);
if (local18 >= -0.001) {
local8 *= 2.0f;
localc = -localc;
if (discriminant >= -0.001) {
a *= 2.0f;
b = -b;
if (local18 > 0.0f) {
local18 = sqrt(local18);
float local184 = (localc + local18) / local8;
float local188 = (localc - local18) / local8;
if (discriminant > 0.0f) {
discriminant = sqrt(discriminant);
float root1 = (b + discriminant) / a;
float root2 = (b - discriminant) / a;
if (local184 > 0.0f && local188 > local184) {
local1c = local184;
if (root1 > 0.0f && root2 > root1) {
distance = root1;
}
else if (local188 > 0.0f) {
local1c = local188;
else if (root2 > 0.0f) {
distance = root2;
}
else {
return 0;
}
}
else {
local1c = localc / local8;
distance = b / a;
}
if (local1c >= 0.0f && p_f1 >= local1c) {
p_v3 = p_v2;
p_v3 *= local1c;
p_v3 += p_v1;
if (distance >= 0.0f && p_rayLength >= distance) {
p_intersectionPoint = p_rayDirection;
p_intersectionPoint *= distance;
p_intersectionPoint += p_rayOrigin;
return 1;
}
}
@ -813,6 +817,7 @@ LegoBool LegoROI::ColorAliasLookup(const LegoChar* p_param, float& p_red, float&
}
// FUNCTION: LEGO1 0x100a9cf0
// FUNCTION: BETA10 0x1018bead
LegoBool LegoROI::GetPaletteEntries(const LegoChar* p_name, unsigned char* paletteEntries, LegoU32 p_numEntries)
{
if (p_name == NULL) {
@ -823,8 +828,10 @@ LegoBool LegoROI::GetPaletteEntries(const LegoChar* p_name, unsigned char* palet
if (g_textureHandler != NULL) {
return g_textureHandler(p_name, paletteEntries, p_numEntries);
}
else {
paletteEntries[0] = '\0';
}
paletteEntries[0] = '\0';
return FALSE;
}

View File

@ -51,10 +51,17 @@ class LegoROI : public ViewROI {
LegoResult SetLodColor(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha);
LegoResult SetTextureInfo(LegoTextureInfo* p_textureInfo);
LegoResult GetTextureInfo(LegoTextureInfo*& p_textureInfo);
LegoResult FUN_100a9330(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha);
LegoResult SetColor(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha);
LegoResult SetLodColor(const LegoChar* p_name);
LegoResult FUN_100a93b0(const LegoChar* p_name);
LegoU32 FUN_100a9410(Vector3& p_v1, Vector3& p_v2, float p_f1, float p_f2, Vector3& p_v3, LegoBool p_collideBox);
LegoResult SetColorByName(const LegoChar* p_name);
LegoU32 Intersect(
Vector3& p_rayOrigin,
Vector3& p_rayDirection,
float p_rayLength,
float p_unused,
Vector3& p_intersectionPoint,
LegoBool p_collideBox
);
void SetName(const LegoChar* p_name);
float IntrinsicImportance() const override; // vtable+0x04
@ -64,7 +71,7 @@ class LegoROI : public ViewROI {
void SetDisplayBB(int p_displayBB);
static LegoResult CreateLocalTransform(LegoAnimNodeData* p_data, LegoTime p_time, Matrix4& p_matrix);
static void FUN_100a81b0(const LegoChar* p_error, ...);
static void ReportError(const LegoChar* p_error, ...);
LEGO1_EXPORT static void configureLegoROI(int p_roi);
static void SetColorOverride(ColorOverride p_colorOverride);
static LegoBool GetRGBAColor(const LegoChar* p_name, float& p_red, float& p_green, float& p_blue, float& p_alpha);

View File

@ -6,6 +6,7 @@
DECOMP_SIZE_ASSERT(LegoColor, 0x03)
// FUNCTION: LEGO1 0x100d3a20
// FUNCTION: BETA10 0x10190730
LegoResult LegoColor::Read(LegoStorage* p_storage)
{
LegoResult result;

View File

@ -9,12 +9,22 @@ class LegoStorage;
class LegoColor {
public:
LegoColor() { m_red = m_green = m_blue = 0; }
// FUNCTION: BETA10 0x1018e690
LegoU8 GetRed() { return m_red; }
void SetRed(LegoU8 p_red) { m_red = p_red; }
// FUNCTION: BETA10 0x1018e6b0
LegoU8 GetGreen() { return m_green; }
void SetGreen(LegoU8 p_green) { m_green = p_green; }
// FUNCTION: BETA10 0x1018e6d0
LegoU8 GetBlue() { return m_blue; }
void SetBlue(LegoU8 p_blue) { m_blue = p_blue; }
LegoResult Read(LegoStorage* p_storage);
protected:

View File

@ -8,6 +8,7 @@ DECOMP_SIZE_ASSERT(LegoMeshUnkComponent, 0x1c)
DECOMP_SIZE_ASSERT(LegoMesh, 0x24)
// FUNCTION: LEGO1 0x100d3810
// FUNCTION: BETA10 0x1018fd60
LegoMesh::LegoMesh()
{
m_alpha = 0.0F;
@ -22,6 +23,7 @@ LegoMesh::LegoMesh()
}
// FUNCTION: LEGO1 0x100d3860
// FUNCTION: BETA10 0x1018fddb
LegoMesh::~LegoMesh()
{
if (m_textureName != NULL) {
@ -38,6 +40,7 @@ LegoMesh::~LegoMesh()
}
// FUNCTION: LEGO1 0x100d38f0
// FUNCTION: BETA10 0x1018ff5d
LegoResult LegoMesh::Read(LegoStorage* p_storage)
{
LegoResult result;

View File

@ -9,6 +9,7 @@ class LegoStorage;
// SIZE 0x1c
struct LegoMeshUnkComponent {
// FUNCTION: BETA10 0x101905b0
~LegoMeshUnkComponent()
{
if (m_unk0x08) {
@ -36,7 +37,11 @@ struct LegoMeshUnkComponent {
undefined* m_unk0x18; // 0x18
};
// SYNTHETIC: BETA10 0x10190530
// LegoMeshUnkComponent::`scalar deleting destructor'
// VTABLE: LEGO1 0x100dd228
// VTABLE: BETA10 0x101c39c4
// SIZE 0x24
class LegoMesh {
public:
@ -48,18 +53,36 @@ class LegoMesh {
LegoMesh();
virtual ~LegoMesh();
// FUNCTION: BETA10 0x1018e6f0
LegoColor GetColor() { return m_color; }
void SetColor(LegoColor p_color) { m_color = p_color; }
// FUNCTION: BETA10 0x1018e720
LegoFloat GetAlpha() { return m_alpha; }
// FUNCTION: BETA10 0x1018e740
LegoU8 GetShading() { return m_shading; }
void SetShading(LegoU8 p_shading) { m_shading = p_shading; }
// FUNCTION: BETA10 0x1018e760
LegoU8 GetUnknown0x0d() { return m_unk0x0d; }
// FUNCTION: BETA10 0x1018e780
const LegoChar* GetTextureName() { return m_textureName; }
// FUNCTION: BETA10 0x1018e7a0
const LegoChar* GetMaterialName() { return m_materialName; }
// FUNCTION: BETA10 0x1018e7c0
LegoBool GetUseAlias() { return m_useAlias; }
LegoResult Read(LegoStorage* p_storage);
// SYNTHETIC: LEGO1 0x100d3840
// SYNTHETIC: BETA10 0x101904f0
// LegoMesh::`scalar deleting destructor'
protected:

View File

@ -137,6 +137,7 @@
// ?__ArrayUnwind@@YGXPAXIHP6EX0@Z@Z
// LIBRARY: LEGO1 0x1008c410
// LIBRARY: BETA10 0x100fa340
// _strlwr
// LIBRARY: LEGO1 0x1008c570

View File

@ -70,12 +70,14 @@ class BoundingSphere {
* a geometric object.
*/
// VTABLE: LEGO1 0x100dbd90
// VTABLE: BETA10 0x101c34c0
// SIZE 0x04
class LODObject {
public:
// LODObject();
// FUNCTION: LEGO1 0x100a6f00
// FUNCTION: BETA10 0x10174c70
virtual ~LODObject() {}
virtual double AveragePolyArea() const = 0; // vtable+0x04
@ -84,9 +86,13 @@ class LODObject {
virtual float VTable0x10() = 0; // vtable+0x10
// SYNTHETIC: LEGO1 0x100a6f10
// SYNTHETIC: BETA10 0x10174c90
// LODObject::`scalar deleting destructor'
};
// SYNTHETIC: BETA10 0x1018e620
// LODObject::LODObject
/*
* A CompoundObject is simply a set of ROI objects which
* all together represent a single object with sub-parts.

View File

@ -1,7 +1,11 @@
#include "viewlod.h"
// FUNCTION: LEGO1 0x100a5e40
// FUNCTION: BETA10 0x10171bdf
ViewLOD::~ViewLOD()
{
delete m_meshBuilder;
if (m_meshBuilder) {
delete m_meshBuilder;
}
// something else happens on BETA10 here
}

View File

@ -10,6 +10,7 @@
//
// VTABLE: LEGO1 0x100dbd70
// VTABLE: BETA10 0x101c34a8
// SIZE 0x0c
class ViewLOD : public LODObject {
public:
@ -17,25 +18,33 @@ class ViewLOD : public LODObject {
c_hasMesh = 0x10
};
// FUNCTION: BETA10 0x1018e570
ViewLOD(Tgl::Renderer* pRenderer) : m_meshBuilder(NULL), m_flags(3) {}
~ViewLOD() override;
// FUNCTION: LEGO1 0x100a6f30
// FUNCTION: BETA10 0x10174db0
double AveragePolyArea() const override { return 2 * 3.14159 * 10.0 / NumPolys(); } // vtable+0x04
// FUNCTION: LEGO1 0x100a6f50
// FUNCTION: BETA10 0x10174de0
int NVerts() const override { return NumPolys() * 2; } // vtable+0x08
Tgl::MeshBuilder* GetMeshBuilder() { return m_meshBuilder; }
const Tgl::MeshBuilder* GetMeshBuilder() const { return m_meshBuilder; }
unsigned int GetFlags() { return m_flags; }
// FUNCTION: BETA10 0x1018e600
unsigned char SkipReadingData() { return m_flags & 0xffffff04; }
unsigned char IsExtraLOD() { return m_flags & 0xffffff08; }
void SetFlag(unsigned char p_flag) { m_flags |= p_flag; }
void ClearFlag(unsigned char p_flag) { m_flags &= ~p_flag; }
// SYNTHETIC: LEGO1 0x100a6f60
// SYNTHETIC: BETA10 0x10174f10
// ViewLOD::`scalar deleting destructor'
protected:

View File

@ -35,7 +35,7 @@ float g_viewDistance = 0.000125F;
float g_elapsedSeconds = 0;
inline void SetAppData(ViewROI* p_roi, LPD3DRM_APPDATA data);
inline undefined4 GetD3DRM(IDirect3DRM2*& d3drm, Tgl::Renderer* pRenderer);
inline undefined4 GetD3DRM_viewmanager(IDirect3DRM2*& d3drm, Tgl::Renderer* pRenderer);
inline undefined4 GetFrame(IDirect3DRMFrame2** frame, Tgl::Group* scene);
// FUNCTION: LEGO1 0x100a5eb0
@ -45,7 +45,7 @@ ViewManager::ViewManager(Tgl::Renderer* pRenderer, Tgl::Group* scene, const Orie
{
SetPOVSource(point_of_view);
prev_render_time = 0.09;
GetD3DRM(d3drm, pRenderer);
GetD3DRM_viewmanager(d3drm, pRenderer);
GetFrame(&frame, scene);
width = 0.0;
@ -568,7 +568,7 @@ inline void SetAppData(ViewROI* p_roi, LPD3DRM_APPDATA data)
}
// FUNCTION: BETA10 0x10171f30
inline undefined4 GetD3DRM(IDirect3DRM2*& d3drm, Tgl::Renderer* p_tglRenderer)
inline undefined4 GetD3DRM_viewmanager(IDirect3DRM2*& d3drm, Tgl::Renderer* p_tglRenderer)
{
assert(p_tglRenderer);
TglImpl::RendererImpl* renderer = (TglImpl::RendererImpl*) p_tglRenderer;

View File

@ -23,6 +23,12 @@
#define sizeOfArray(arr) (sizeof(arr) / sizeof(arr[0]))
#endif
#ifdef BETA10
#define assertIfBeta10(A) assert(A)
#else
#define assertIfBeta10(A)
#endif
typedef unsigned char undefined;
typedef unsigned short undefined2;
typedef unsigned int undefined4;