mirror of
https://github.com/isledecomp/isle.git
synced 2024-11-27 10:05:52 -05:00
Implement CarRace
(#1165)
* Implement `CarRace` * Improve `CarRace::Create` * Fix arrays * Clean up array * Fix CI errors * Implement `LegoRaceCar::FUN_10012e00()` * Implement `Doors::VTable0xcc` * Address review comments, part 1 * Address review comments, part 2 --------- Co-authored-by: jonschz <jonschz@users.noreply.github.com>
This commit is contained in:
parent
e56ac9ab55
commit
0aa5e010ae
21 changed files with 533 additions and 61 deletions
|
@ -66,12 +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);
|
||||
|
||||
// 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
|
||||
|
|
|
@ -27,7 +27,7 @@ class Doors : public LegoPathActor {
|
|||
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'
|
||||
|
|
|
@ -65,8 +65,6 @@ class JetskiRace : public LegoRace {
|
|||
void FUN_10016930(MxS32 p_param1, MxS16 p_param2);
|
||||
|
||||
private:
|
||||
inline MxS32 PossiblyGetPlaceOfPlayer();
|
||||
|
||||
static MxS32 g_unk0x100f0c78;
|
||||
};
|
||||
|
||||
|
|
|
@ -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 @@ class LegoEntity : public MxEntity {
|
|||
MxLong Notify(MxParam& p_param) override; // vtable+0x04
|
||||
|
||||
// FUNCTION: LEGO1 0x1000c2f0
|
||||
// FUNCTION: BETA10 0x10012730
|
||||
const char* ClassName() const override // vtable+0x0c
|
||||
{
|
||||
// STRING: LEGO1 0x100f0064
|
||||
|
@ -116,8 +118,11 @@ class LegoEntity : public MxEntity {
|
|||
// 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
|
||||
|
|
|
@ -82,6 +82,12 @@ class LegoNavController : public MxCore {
|
|||
// 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 @@ class LegoNavController : public MxCore {
|
|||
m_trackDefault = 0;
|
||||
}
|
||||
|
||||
// FUNCTION: BETA10 0x100c9a10
|
||||
int GetDefaultDeadZone() { return g_defdeadZone; }
|
||||
|
||||
// SYNTHETIC: LEGO1 0x10054c10
|
||||
// LegoNavController::`scalar deleting destructor'
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ struct LegoUnknown100db7f4;
|
|||
class LegoWEEdge;
|
||||
|
||||
extern MxLong g_unk0x100f3308;
|
||||
extern const char* g_strHIT_WALL_SOUND;
|
||||
|
||||
// VTABLE: LEGO1 0x100d6e28
|
||||
// SIZE 0x154
|
||||
|
|
|
@ -77,6 +77,7 @@ class LegoRaceCar : public LegoCarRaceActor, public LegoRaceMap {
|
|||
virtual MxU32 HandleSkeletonKicks(float p_param1);
|
||||
|
||||
static void FUN_10012de0();
|
||||
static void FUN_10012e00();
|
||||
static void FUN_10013670();
|
||||
|
||||
// SYNTHETIC: LEGO1 0x10014240
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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"
|
||||
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
@ -103,11 +107,12 @@ void LegoEntity::Destroy(MxBool p_fromDestructor)
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -225,6 +231,7 @@ Mx3DPointFloat LegoEntity::GetWorldPosition()
|
|||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10010e10
|
||||
// FUNCTION: BETA10 0x1007ec97
|
||||
void LegoEntity::ParseAction(char* p_extra)
|
||||
{
|
||||
char copy[1024];
|
||||
|
@ -232,16 +239,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 +471,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()) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -152,18 +152,6 @@ MxLong JetskiRace::HandleClick(LegoEventNotificationParam& p_param)
|
|||
return result;
|
||||
}
|
||||
|
||||
inline MxS32 JetskiRace::PossiblyGetPlaceOfPlayer()
|
||||
{
|
||||
if (m_unk0xfc < m_unk0xf8 && m_unk0x100 < m_unk0xf8) {
|
||||
return 3;
|
||||
}
|
||||
else if (m_unk0xfc < m_unk0xf8 || m_unk0x100 < m_unk0xf8) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100166a0
|
||||
// FUNCTION: BETA10 0x100c8085
|
||||
MxLong JetskiRace::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
||||
|
@ -190,7 +178,17 @@ MxLong JetskiRace::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
|||
m_unk0xf8++;
|
||||
|
||||
if (g_unk0x100f0c78 == m_unk0xf8) {
|
||||
MxS16 sVar6 = PossiblyGetPlaceOfPlayer();
|
||||
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, "");
|
||||
|
@ -198,10 +196,10 @@ MxLong JetskiRace::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
|||
m_raceState->m_unk0x28 = 2;
|
||||
|
||||
RaceState::Entry* raceStateEntry = m_raceState->GetState(GameState()->GetActorId());
|
||||
raceStateEntry->m_unk0x02 = sVar6;
|
||||
raceStateEntry->m_unk0x02 = position;
|
||||
|
||||
if (raceStateEntry->m_score < sVar6) {
|
||||
raceStateEntry->m_score = sVar6;
|
||||
if (raceStateEntry->m_score < (MxS16) position) {
|
||||
raceStateEntry->m_score = position;
|
||||
}
|
||||
|
||||
m_destLocation = LegoGameState::e_jetrace2;
|
||||
|
@ -215,13 +213,14 @@ MxLong JetskiRace::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
|||
m_hideAnim->FUN_1006db40(m_unk0xf8 * 200 + 100);
|
||||
result = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
case 11:
|
||||
if (paramData <= m_unk0x108 || paramData >= m_unk0x108 + 5) {
|
||||
break;
|
||||
}
|
||||
|
||||
FUN_10016930(0xb, paramData);
|
||||
FUN_10016930(11, paramData);
|
||||
m_unk0x108 = paramData;
|
||||
|
||||
if (m_unk0x108 == 0x14) {
|
||||
|
@ -232,13 +231,14 @@ MxLong JetskiRace::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
|||
((LegoPathActor*) p_param.GetSender())->SetMaxLinearVel(0.1);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 12:
|
||||
if (paramData <= m_unk0x10c || paramData >= m_unk0x10c + 5) {
|
||||
break;
|
||||
}
|
||||
|
||||
FUN_10016930(0xc, paramData);
|
||||
FUN_10016930(12, paramData);
|
||||
|
||||
m_unk0x10c = paramData;
|
||||
|
||||
|
@ -250,6 +250,7 @@ MxLong JetskiRace::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
|||
((LegoPathActor*) p_param.GetSender())->SetMaxLinearVel(0.1);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -744,4 +744,7 @@
|
|||
// LIBRARY: BETA10 0x100f8ad0
|
||||
// strcmp
|
||||
|
||||
// LIBRARY: BETA10 0x100f9610
|
||||
// rand
|
||||
|
||||
#endif
|
||||
|
|
|
@ -47,6 +47,7 @@ class MxActionNotificationParam : public MxNotificationParam {
|
|||
return new MxActionNotificationParam(m_type, m_sender, m_action, m_realloc);
|
||||
} // vtable+0x04
|
||||
|
||||
// FUNCTION: BETA10 0x10017970
|
||||
MxDSAction* GetAction() { return m_action; }
|
||||
|
||||
protected:
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "mxtypes.h"
|
||||
|
||||
// VTABLE: LEGO1 0x100d5390
|
||||
// VTABLE: BETA10 0x101b93e8
|
||||
// SIZE 0x10
|
||||
class MxEntity : public MxCore {
|
||||
public:
|
||||
|
@ -33,6 +34,7 @@ class MxEntity : public MxCore {
|
|||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10001070
|
||||
// FUNCTION: BETA10 0x1000f3a0
|
||||
virtual MxResult Create(MxS32 p_entityId, const MxAtomId& p_atomId)
|
||||
{
|
||||
m_entityId = p_entityId;
|
||||
|
@ -47,7 +49,9 @@ class MxEntity : public MxCore {
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
// FUNCTION: BETA10 0x10031c60
|
||||
MxS32 GetEntityId() { return m_entityId; }
|
||||
|
||||
MxAtomId& GetAtomId() { return m_atomId; }
|
||||
|
||||
void SetEntityId(MxS32 p_entityId) { m_entityId = p_entityId; }
|
||||
|
|
|
@ -19,3 +19,14 @@ targets:
|
|||
source-root: LEGO1
|
||||
hash:
|
||||
sha256: d91435a40fa31f405fba33b03bd3bd40dcd4ca36ccf8ef6162c6c5ca0d7190e7
|
||||
ghidra:
|
||||
ignore-types:
|
||||
# these classes have been changed by hand to account for changes between LEGO1 and BETA10
|
||||
- LegoCarBuild
|
||||
- LegoCarBuildAnimPresenter
|
||||
- LegoRace
|
||||
- LegoWorld
|
||||
ignore-functions:
|
||||
# strcpy, strlen, ... (arguments are imported incorrectly)
|
||||
- 0x100fa200
|
||||
- 0x100f9780
|
||||
|
|
Loading…
Reference in a new issue