From 454b7b86afe761108565c145b71c18c24881e569 Mon Sep 17 00:00:00 2001 From: boebie <329328699+boebie-dev@users.noreply.github.com> Date: Thu, 8 Oct 2026 22:03:32 -0400 Subject: [PATCH 1/7] Link MobilePlatform.cpp --- configure.py | 2 +- include/common/MKSceneManager.h | 1 + include/ty/props/MobilePlatform.h | 64 +++++++ src/ty/source/props/MobilePlatform.cpp | 230 +++++++++++++++++++++++++ 4 files changed, 296 insertions(+), 1 deletion(-) create mode 100644 include/ty/props/MobilePlatform.h create mode 100644 src/ty/source/props/MobilePlatform.cpp diff --git a/configure.py b/configure.py index 9509ae3..2587e98 100644 --- a/configure.py +++ b/configure.py @@ -462,7 +462,7 @@ def MatchingFor(*versions): Object(NonMatching, "ty/source/props/LavaBurner.cpp"), Object(NonMatching, "ty/source/props/LilyPad.cpp"), Object(NonMatching, "ty/source/props/Log.cpp"), - Object(NonMatching, "ty/source/props/MobilePlatform.cpp"), + Object(Matching, "ty/source/props/MobilePlatform.cpp"), Object(NonMatching, "ty/source/props/MorayEel.cpp"), Object(NonMatching, "ty/source/props/MusicalIcicle.cpp"), Object(NonMatching, "ty/source/props/OpalCollector.cpp"), diff --git a/include/common/MKSceneManager.h b/include/common/MKSceneManager.h index 0f2cd0d..24a84cd 100644 --- a/include/common/MKSceneManager.h +++ b/include/common/MKSceneManager.h @@ -19,6 +19,7 @@ // these are the values used in GameObject::Message #define MKMSG_Reset -1 #define MKMSG_Deinit -2 +#define MKMSG_UNK_3 -3 struct MKMessage { int unk0; }; diff --git a/include/ty/props/MobilePlatform.h b/include/ty/props/MobilePlatform.h new file mode 100644 index 0000000..41dd335 --- /dev/null +++ b/include/ty/props/MobilePlatform.h @@ -0,0 +1,64 @@ +#ifndef MOBILEPLATFORM_H +#define MOBILEPLATFORM_H + +#include "ty/props/Platform.h" +#include "ty/CommonGameObjectFlags.h" +#include "ty/Spline.h" +#include "ty/tools.h" + +void MobilePlatform_LoadResources(KromeIni* pIni); + +struct MobilePlatformDesc : PlatformDesc { + float bobSpeed; // Number of bobs per second + float bobHeight; + + virtual void Init(ModuleInfoBase* pMod, char* pMdlName, char* pDescrName, int _searchMask, int _flags); +}; + +// Temporary info used while loading a MobilePlatform +struct MobilePlatformLoadInfo { + Tools_WayPoints wayPoints; + float speed; + float startTime; // Normalised starting position on the path [0, 1] + bool bNonCircular; +}; + +struct MobilePlatform : Platform { + float turnSpeed; + int bReverse; // Set when moving backwards along a non-circular path + int pathFrames; // Number of frames to travel the path once + int startFrame; + int defaultStartFrame; + int frameOffset; + int bobFrameOffset; + UniformSpline spline; + bool bCircular; + bool bMoveOne; // Deactivates once the end of the path is reached + CommonGameObjFlagsComponent gameObjFlags; + + static MobilePlatformLoadInfo mpfLoadInfo; + + virtual bool LoadLine(KromeIniLine* pLine); + virtual void LoadDone(void); + virtual void Reset(void); + virtual void Update(void); + virtual void Message(MKMessage* pMsg); + virtual void Init(GameObjDesc* pDesc); + virtual void Deinit(void); + void UpdateMove(void); + void UpdateBob(void); + float GetTime(void); + void SetYaw(float time, float maxTurn); + + MobilePlatformDesc* GetDesc(void) { + return descr_cast(pDescriptor); + } + + // Returns the number of frames of a full cycle + // Non-circular paths travel forwards then backwards + uint GetCycleFrames(void) { + return pathFrames * (!bCircular + 1); + } +}; + +#endif // MOBILEPLATFORM_H diff --git a/src/ty/source/props/MobilePlatform.cpp b/src/ty/source/props/MobilePlatform.cpp new file mode 100644 index 0000000..24e2b1b --- /dev/null +++ b/src/ty/source/props/MobilePlatform.cpp @@ -0,0 +1,230 @@ +#include "ty/props/MobilePlatform.h" +#include "ty/GameObjectManager.h" +#include "ty/global.h" +#include "common/StdMath.h" +#include "common/System_GC.h" + +extern "C" double atan2(double, double); +void GameCamera_AddDynamicCollisionItem(Model* pModel, int subObjectIndex); + +static ModuleInfo mobilePlatformModuleInfo; +MobilePlatformLoadInfo MobilePlatform::mpfLoadInfo; + +void MobilePlatformDesc::Init(ModuleInfoBase* pMod, char* pMdlName, char* pDescrName, int _searchMask, int _flags) { + PlatformDesc::Init(pMod, pMdlName, pDescrName, _searchMask, _flags | 0x80); + bobSpeed = 0.0f; + bobHeight = 0.0f; +} + +void MobilePlatform_LoadResources(KromeIni* pIni) { + MobilePlatformDesc defaultMobilePlatformDesc; + defaultMobilePlatformDesc.Init(&mobilePlatformModuleInfo, "", "", GOID_Platform, 1); + LoadDescriptors(pIni, "MobilePlatforms", &defaultMobilePlatformDesc); +} + +void MobilePlatform::Init(GameObjDesc* pDesc) { + Platform::Init(pDesc); + mpfLoadInfo.wayPoints.Init(); + mpfLoadInfo.bNonCircular = false; + mpfLoadInfo.speed = 7.0f; + mpfLoadInfo.startTime = 0.0f; + bReverse = 0; + bCircular = false; + bMoveOne = false; + pathFrames = 0; + turnSpeed = 0.0f; + startFrame = 0; + bobFrameOffset = 0; + gameObjFlags.Init(GameObjFlags_All); +} + +void MobilePlatform::Deinit(void) { + spline.Deinit(); + Platform::Deinit(); +} + +void MobilePlatform::Reset(void) { + Platform::Reset(); + gameObjFlags.Reset(); + startFrame = defaultStartFrame; + UpdateMove(); +} + +bool MobilePlatform::LoadLine(KromeIniLine* pLine) { + return gameObjFlags.LoadLine(pLine) || + LoadLevel_LoadBool(pLine, "bCircular", &bCircular) || + LoadLevel_LoadFloat(pLine, "turnSpeed", &turnSpeed) || + LoadLevel_LoadFloat(pLine, "speed", &mpfLoadInfo.speed) || + LoadLevel_LoadFloat(pLine, "startTime", &mpfLoadInfo.startTime) || + LoadLevel_LoadBool(pLine, "bMoveOne", &bMoveOne) || + LoadLevel_LoadBool(pLine, "bNonCircular", &mpfLoadInfo.bNonCircular) || + mpfLoadInfo.wayPoints.LoadLine(pLine, Tools_WayPoints::LOAD_MODE_1) || + Platform::LoadLine(pLine); +} + +void MobilePlatform::LoadDone(void) { + Tools_WayPoints* pWayPoints = &mpfLoadInfo.wayPoints; + + gameObjFlags.SetDefaultFlags(); + + Vector* pPos = GetPos(); + pPos->x = pWayPoints->vecs[0].x; + pPos->y = pWayPoints->vecs[0].y; + pPos->z = pWayPoints->vecs[0].z; + + if (pWayPoints->unk104 > 1) { + if (pWayPoints->unk104 > 2 && !mpfLoadInfo.bNonCircular) { + bCircular = true; + } + + // Face the platform towards the second waypoint + // mixing pWayPoints and mpfLoadInfo is needed to match + float dx = mpfLoadInfo.wayPoints.vecs[1].x - mpfLoadInfo.wayPoints.vecs[0].x; + float dz = mpfLoadInfo.wayPoints.vecs[1].z - pWayPoints->vecs[0].z; + if (dx * dx + dz * dz > 0.0001f && turnSpeed > 0.0f) { + StaticProp::loadInfo.defaultRot.y = PI2 + (float)atan2(dz, dx); + } + + spline.Init(pWayPoints->unk104 + bCircular, true); + + for (int i = 0; i < pWayPoints->unk104; i++) { + spline.AddNode(&mpfLoadInfo.wayPoints.vecs[i]); + } + + if (bCircular) { + spline.AddNode(&mpfLoadInfo.wayPoints.vecs[0]); + spline.MergeEnds(); + } else { + spline.mpPoints[0].unk10.SetZero(); + spline.mpPoints[spline.mNumPoints - 1].unk10.SetZero(); + } + + spline.RegulateSpeed(); + + pathFrames = gDisplay.fps * (spline.unk8 / mpfLoadInfo.speed); + } else { + spline.Init(pWayPoints->unk104, false); + spline.AddNode(&mpfLoadInfo.wayPoints.vecs[0]); + } + + startFrame = pathFrames * Clamp(0.0f, mpfLoadInfo.startTime, 1.0f); + defaultStartFrame = startFrame; + frameOffset = startFrame - gb.logicGameCount; + + if (GetDesc()->bobSpeed) { + MobilePlatformDesc* pDesc = GetDesc(); + bobFrameOffset = (gDisplay.fps * RandomFR(&gb.mRandSeed, 0.0f, 1.0f)) / pDesc->bobSpeed; + } + + GameCamera_AddDynamicCollisionItem(pModel, -1); + Platform::LoadDone(); +} + +void MobilePlatform::Update(void) { + BeginUpdate(); + UpdateTilt(); + UpdateMove(); + UpdateBob(); + EndUpdate(); +} + +void MobilePlatform::Message(MKMessage* pMsg) { + switch (pMsg->unk0) { + case MSG_Activate: + if (!gameObjFlags.CheckFlags(GameObjFlags_Active)) { + frameOffset = startFrame - gb.logicGameCount; + } + break; + case MSG_Deactivate: + if (gameObjFlags.CheckFlags(GameObjFlags_Active)) { + startFrame = (frameOffset + gb.logicGameCount) % GetCycleFrames(); + } + break; + case MSG_Resolve: + rider.Resolve(); + rider.Attach(this); + for (int i = 0; i < spline.mNumPoints; i++) { + rider.ToLocal(&spline.mpPoints[i].mPos); + rider.ToLocalDir(&spline.mpPoints[i].unk10); + } + break; + case MKMSG_UNK_3: + if (turnSpeed > 0.0f && spline.mNumPoints > 1) { + BeginUpdate(); + SetYaw(GetTime(), 2.0f * PI); + EndUpdate(); + } + break; + } + + gameObjFlags.Message(pMsg); + Platform::Message(pMsg); +} + +void MobilePlatform::UpdateMove(void) { + if (spline.mNumPoints > 1) { + float time = GetTime(); + *GetPos() = spline.GetPosition(time); + GetPos()->w = 1.0f; + rider.ToWorld(GetPos()); + + if (turnSpeed > 0.0f) { + SetYaw(time, turnSpeed); + } + + if (bMoveOne && gameObjFlags.CheckFlags(GameObjFlags_Active) && time > 0.99f && bReverse == 0) { + MKMessage msg = {MSG_Deactivate}; + Message(&msg); + } + } else { + *GetPos() = spline.mpPoints[0].mPos; + GetPos()->w = 1.0f; + rider.ToWorld(GetPos()); + } +} + +void MobilePlatform::UpdateBob(void) { + if (GetDesc()->bobHeight > 0.0f && GetDesc()->bobSpeed > 0.0f) { + int bobFrames = gDisplay.fps / GetDesc()->bobSpeed; + float t = (float)((gb.logicGameCount + bobFrameOffset) % bobFrames) / (float)bobFrames; + GetPos()->y += _table_sinf((2.0f * PI) * t) * GetDesc()->bobHeight; + } +} + +float MobilePlatform::GetTime(void) { + if (!gameObjFlags.CheckFlags(GameObjFlags_Active)) { + frameOffset = startFrame - gb.logicGameCount; + } + + float time = (float)((gb.logicGameCount + frameOffset) % GetCycleFrames()) / (float)pathFrames; + + if (time > 1.0f) { + bReverse = 1; + time = 2.0f - time; + } else { + bReverse = 0; + } + + return time; +} + +void MobilePlatform::SetYaw(float time, float maxTurn) { + if (spline.mNumPoints > 0) { + Vector dir = spline.GetVelocity(time); + rider.ToWorldDir(&dir); + dir.y = 0.0f; + + if (dir.MagSquared() > 0.0001f) { + float yaw = atan2(dir.z, dir.x); + float direction; + if (bReverse == 0) { + direction = 1.0f; + } else { + direction = -1.0f; + } + + float angle = GetSmallestAngle(mCurrRot.y, (2.0f * PI) * direction + (PI2 + yaw)); + mCurrRot.y += Clamp(-Abs(maxTurn), angle, Abs(maxTurn)); + } + } +} From 1e1f4cd821e841417d28a5cadcf0dc4c3ff3a4ad Mon Sep 17 00:00:00 2001 From: boebie <329328699+boebie-dev@users.noreply.github.com> Date: Thu, 8 Oct 2026 23:28:51 -0400 Subject: [PATCH 2/7] MobilePlatform: remove unneeded pWayPoints variable in LoadDone --- src/ty/source/props/MobilePlatform.cpp | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/ty/source/props/MobilePlatform.cpp b/src/ty/source/props/MobilePlatform.cpp index 24e2b1b..1452e33 100644 --- a/src/ty/source/props/MobilePlatform.cpp +++ b/src/ty/source/props/MobilePlatform.cpp @@ -63,31 +63,28 @@ bool MobilePlatform::LoadLine(KromeIniLine* pLine) { } void MobilePlatform::LoadDone(void) { - Tools_WayPoints* pWayPoints = &mpfLoadInfo.wayPoints; - gameObjFlags.SetDefaultFlags(); Vector* pPos = GetPos(); - pPos->x = pWayPoints->vecs[0].x; - pPos->y = pWayPoints->vecs[0].y; - pPos->z = pWayPoints->vecs[0].z; + pPos->x = mpfLoadInfo.wayPoints.vecs[0].x; + pPos->y = mpfLoadInfo.wayPoints.vecs[0].y; + pPos->z = mpfLoadInfo.wayPoints.vecs[0].z; - if (pWayPoints->unk104 > 1) { - if (pWayPoints->unk104 > 2 && !mpfLoadInfo.bNonCircular) { + if (mpfLoadInfo.wayPoints.unk104 > 1) { + if (mpfLoadInfo.wayPoints.unk104 > 2 && !mpfLoadInfo.bNonCircular) { bCircular = true; } // Face the platform towards the second waypoint - // mixing pWayPoints and mpfLoadInfo is needed to match float dx = mpfLoadInfo.wayPoints.vecs[1].x - mpfLoadInfo.wayPoints.vecs[0].x; - float dz = mpfLoadInfo.wayPoints.vecs[1].z - pWayPoints->vecs[0].z; + float dz = mpfLoadInfo.wayPoints.vecs[1].z - mpfLoadInfo.wayPoints.vecs[0].z; if (dx * dx + dz * dz > 0.0001f && turnSpeed > 0.0f) { StaticProp::loadInfo.defaultRot.y = PI2 + (float)atan2(dz, dx); } - spline.Init(pWayPoints->unk104 + bCircular, true); + spline.Init(mpfLoadInfo.wayPoints.unk104 + bCircular, true); - for (int i = 0; i < pWayPoints->unk104; i++) { + for (int i = 0; i < mpfLoadInfo.wayPoints.unk104; i++) { spline.AddNode(&mpfLoadInfo.wayPoints.vecs[i]); } @@ -103,7 +100,7 @@ void MobilePlatform::LoadDone(void) { pathFrames = gDisplay.fps * (spline.unk8 / mpfLoadInfo.speed); } else { - spline.Init(pWayPoints->unk104, false); + spline.Init(mpfLoadInfo.wayPoints.unk104, false); spline.AddNode(&mpfLoadInfo.wayPoints.vecs[0]); } From 4c90f6582afa560cf4abf1575002e6d75b90a060 Mon Sep 17 00:00:00 2001 From: boebie <329328699+boebie-dev@users.noreply.github.com> Date: Thu, 8 Oct 2026 23:29:00 -0400 Subject: [PATCH 3/7] MobilePlatform: remove unneeded pDesc variable in LoadDone --- src/ty/source/props/MobilePlatform.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ty/source/props/MobilePlatform.cpp b/src/ty/source/props/MobilePlatform.cpp index 1452e33..2dde10a 100644 --- a/src/ty/source/props/MobilePlatform.cpp +++ b/src/ty/source/props/MobilePlatform.cpp @@ -109,8 +109,7 @@ void MobilePlatform::LoadDone(void) { frameOffset = startFrame - gb.logicGameCount; if (GetDesc()->bobSpeed) { - MobilePlatformDesc* pDesc = GetDesc(); - bobFrameOffset = (gDisplay.fps * RandomFR(&gb.mRandSeed, 0.0f, 1.0f)) / pDesc->bobSpeed; + bobFrameOffset = (gDisplay.fps * RandomFR(&gb.mRandSeed, 0.0f, 1.0f)) / GetDesc()->bobSpeed; } GameCamera_AddDynamicCollisionItem(pModel, -1); From 846d7bf51146def487291279ae75d336e6a0c646 Mon Sep 17 00:00:00 2001 From: boebie <329328699+boebie-dev@users.noreply.github.com> Date: Thu, 8 Oct 2026 23:30:05 -0400 Subject: [PATCH 4/7] MobilePlatform: use Vector::Copy for start position in LoadDone --- src/ty/source/props/MobilePlatform.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/ty/source/props/MobilePlatform.cpp b/src/ty/source/props/MobilePlatform.cpp index 2dde10a..b8085ab 100644 --- a/src/ty/source/props/MobilePlatform.cpp +++ b/src/ty/source/props/MobilePlatform.cpp @@ -65,10 +65,7 @@ bool MobilePlatform::LoadLine(KromeIniLine* pLine) { void MobilePlatform::LoadDone(void) { gameObjFlags.SetDefaultFlags(); - Vector* pPos = GetPos(); - pPos->x = mpfLoadInfo.wayPoints.vecs[0].x; - pPos->y = mpfLoadInfo.wayPoints.vecs[0].y; - pPos->z = mpfLoadInfo.wayPoints.vecs[0].z; + GetPos()->Copy(&mpfLoadInfo.wayPoints.vecs[0]); if (mpfLoadInfo.wayPoints.unk104 > 1) { if (mpfLoadInfo.wayPoints.unk104 > 2 && !mpfLoadInfo.bNonCircular) { From 65515c1c6457c7b8775dd261947bba25b48e6e12 Mon Sep 17 00:00:00 2001 From: boebie <329328699+boebie-dev@users.noreply.github.com> Date: Thu, 8 Oct 2026 23:30:11 -0400 Subject: [PATCH 5/7] MobilePlatform: use Sqr for distance thresholds in LoadDone and SetYaw --- src/ty/source/props/MobilePlatform.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ty/source/props/MobilePlatform.cpp b/src/ty/source/props/MobilePlatform.cpp index b8085ab..ffc3a1c 100644 --- a/src/ty/source/props/MobilePlatform.cpp +++ b/src/ty/source/props/MobilePlatform.cpp @@ -75,7 +75,7 @@ void MobilePlatform::LoadDone(void) { // Face the platform towards the second waypoint float dx = mpfLoadInfo.wayPoints.vecs[1].x - mpfLoadInfo.wayPoints.vecs[0].x; float dz = mpfLoadInfo.wayPoints.vecs[1].z - mpfLoadInfo.wayPoints.vecs[0].z; - if (dx * dx + dz * dz > 0.0001f && turnSpeed > 0.0f) { + if (Sqr(dx) + Sqr(dz) > Sqr(0.01f) && turnSpeed > 0.0f) { StaticProp::loadInfo.defaultRot.y = PI2 + (float)atan2(dz, dx); } @@ -207,7 +207,7 @@ void MobilePlatform::SetYaw(float time, float maxTurn) { rider.ToWorldDir(&dir); dir.y = 0.0f; - if (dir.MagSquared() > 0.0001f) { + if (dir.MagSquared() > Sqr(0.01f)) { float yaw = atan2(dir.z, dir.x); float direction; if (bReverse == 0) { From 9e937d0308839eec403cd3ef5c5e77828ab916c6 Mon Sep 17 00:00:00 2001 From: boebie <329328699+boebie-dev@users.noreply.github.com> Date: Sat, 10 Oct 2026 20:52:21 -0400 Subject: [PATCH 6/7] Mark unofficial names Names not taken from debug symbols or a .ini key are marked with "Unofficial" --- include/ty/props/MobilePlatform.h | 26 ++++++++++---------- src/ty/source/props/MobilePlatform.cpp | 34 +++++++++++++------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/include/ty/props/MobilePlatform.h b/include/ty/props/MobilePlatform.h index 41dd335..1045ebb 100644 --- a/include/ty/props/MobilePlatform.h +++ b/include/ty/props/MobilePlatform.h @@ -9,15 +9,15 @@ void MobilePlatform_LoadResources(KromeIni* pIni); struct MobilePlatformDesc : PlatformDesc { - float bobSpeed; // Number of bobs per second - float bobHeight; + float bobSpeed; // Unofficial: unkF0. Number of bobs per second + float bobHeight; // Unofficial: unkF4 virtual void Init(ModuleInfoBase* pMod, char* pMdlName, char* pDescrName, int _searchMask, int _flags); }; // Temporary info used while loading a MobilePlatform struct MobilePlatformLoadInfo { - Tools_WayPoints wayPoints; + Tools_WayPoints wayPoints; // Unofficial: unk0 float speed; float startTime; // Normalised starting position on the path [0, 1] bool bNonCircular; @@ -25,18 +25,18 @@ struct MobilePlatformLoadInfo { struct MobilePlatform : Platform { float turnSpeed; - int bReverse; // Set when moving backwards along a non-circular path - int pathFrames; // Number of frames to travel the path once - int startFrame; - int defaultStartFrame; - int frameOffset; - int bobFrameOffset; - UniformSpline spline; + int bReverse; // Unofficial: unkD8. Set when moving backwards along a non-circular path + int pathFrames; // Unofficial: unkDC. Number of frames to travel the path once + int startFrame; // Unofficial: unkE0 + int defaultStartFrame; // Unofficial: unkE4 + int frameOffset; // Unofficial: unkE8 + int bobFrameOffset; // Unofficial: unkEC + UniformSpline spline; // Unofficial: unkF0 bool bCircular; bool bMoveOne; // Deactivates once the end of the path is reached - CommonGameObjFlagsComponent gameObjFlags; + CommonGameObjFlagsComponent gameObjFlags; // Unofficial: unk106 - static MobilePlatformLoadInfo mpfLoadInfo; + static MobilePlatformLoadInfo mpfLoadInfo; // Unofficial virtual bool LoadLine(KromeIniLine* pLine); virtual void LoadDone(void); @@ -48,7 +48,7 @@ struct MobilePlatform : Platform { void UpdateMove(void); void UpdateBob(void); float GetTime(void); - void SetYaw(float time, float maxTurn); + void SetYaw(float time, float maxTurn); // Unofficial: time, maxTurn MobilePlatformDesc* GetDesc(void) { return descr_cast(pDescriptor); diff --git a/src/ty/source/props/MobilePlatform.cpp b/src/ty/source/props/MobilePlatform.cpp index ffc3a1c..98cdeca 100644 --- a/src/ty/source/props/MobilePlatform.cpp +++ b/src/ty/source/props/MobilePlatform.cpp @@ -7,7 +7,7 @@ extern "C" double atan2(double, double); void GameCamera_AddDynamicCollisionItem(Model* pModel, int subObjectIndex); -static ModuleInfo mobilePlatformModuleInfo; +static ModuleInfo mobilePlatformModuleInfo; // Unofficial MobilePlatformLoadInfo MobilePlatform::mpfLoadInfo; void MobilePlatformDesc::Init(ModuleInfoBase* pMod, char* pMdlName, char* pDescrName, int _searchMask, int _flags) { @@ -16,8 +16,8 @@ void MobilePlatformDesc::Init(ModuleInfoBase* pMod, char* pMdlName, char* pDescr bobHeight = 0.0f; } -void MobilePlatform_LoadResources(KromeIni* pIni) { - MobilePlatformDesc defaultMobilePlatformDesc; +void MobilePlatform_LoadResources(KromeIni* pIni) { // Unofficial: pIni + MobilePlatformDesc defaultMobilePlatformDesc; // Unofficial defaultMobilePlatformDesc.Init(&mobilePlatformModuleInfo, "", "", GOID_Platform, 1); LoadDescriptors(pIni, "MobilePlatforms", &defaultMobilePlatformDesc); } @@ -73,15 +73,15 @@ void MobilePlatform::LoadDone(void) { } // Face the platform towards the second waypoint - float dx = mpfLoadInfo.wayPoints.vecs[1].x - mpfLoadInfo.wayPoints.vecs[0].x; - float dz = mpfLoadInfo.wayPoints.vecs[1].z - mpfLoadInfo.wayPoints.vecs[0].z; + float dx = mpfLoadInfo.wayPoints.vecs[1].x - mpfLoadInfo.wayPoints.vecs[0].x; // Unofficial + float dz = mpfLoadInfo.wayPoints.vecs[1].z - mpfLoadInfo.wayPoints.vecs[0].z; // Unofficial if (Sqr(dx) + Sqr(dz) > Sqr(0.01f) && turnSpeed > 0.0f) { StaticProp::loadInfo.defaultRot.y = PI2 + (float)atan2(dz, dx); } spline.Init(mpfLoadInfo.wayPoints.unk104 + bCircular, true); - for (int i = 0; i < mpfLoadInfo.wayPoints.unk104; i++) { + for (int i = 0; i < mpfLoadInfo.wayPoints.unk104; i++) { // Unofficial: i spline.AddNode(&mpfLoadInfo.wayPoints.vecs[i]); } @@ -136,7 +136,7 @@ void MobilePlatform::Message(MKMessage* pMsg) { case MSG_Resolve: rider.Resolve(); rider.Attach(this); - for (int i = 0; i < spline.mNumPoints; i++) { + for (int i = 0; i < spline.mNumPoints; i++) { // Unofficial: i rider.ToLocal(&spline.mpPoints[i].mPos); rider.ToLocalDir(&spline.mpPoints[i].unk10); } @@ -156,7 +156,7 @@ void MobilePlatform::Message(MKMessage* pMsg) { void MobilePlatform::UpdateMove(void) { if (spline.mNumPoints > 1) { - float time = GetTime(); + float time = GetTime(); // Unofficial *GetPos() = spline.GetPosition(time); GetPos()->w = 1.0f; rider.ToWorld(GetPos()); @@ -166,7 +166,7 @@ void MobilePlatform::UpdateMove(void) { } if (bMoveOne && gameObjFlags.CheckFlags(GameObjFlags_Active) && time > 0.99f && bReverse == 0) { - MKMessage msg = {MSG_Deactivate}; + MKMessage msg = {MSG_Deactivate}; // Unofficial Message(&msg); } } else { @@ -178,8 +178,8 @@ void MobilePlatform::UpdateMove(void) { void MobilePlatform::UpdateBob(void) { if (GetDesc()->bobHeight > 0.0f && GetDesc()->bobSpeed > 0.0f) { - int bobFrames = gDisplay.fps / GetDesc()->bobSpeed; - float t = (float)((gb.logicGameCount + bobFrameOffset) % bobFrames) / (float)bobFrames; + int bobFrames = gDisplay.fps / GetDesc()->bobSpeed; // Unofficial + float t = (float)((gb.logicGameCount + bobFrameOffset) % bobFrames) / (float)bobFrames; // Unofficial: t GetPos()->y += _table_sinf((2.0f * PI) * t) * GetDesc()->bobHeight; } } @@ -189,7 +189,7 @@ float MobilePlatform::GetTime(void) { frameOffset = startFrame - gb.logicGameCount; } - float time = (float)((gb.logicGameCount + frameOffset) % GetCycleFrames()) / (float)pathFrames; + float time = (float)((gb.logicGameCount + frameOffset) % GetCycleFrames()) / (float)pathFrames; // Unofficial: time if (time > 1.0f) { bReverse = 1; @@ -201,22 +201,22 @@ float MobilePlatform::GetTime(void) { return time; } -void MobilePlatform::SetYaw(float time, float maxTurn) { +void MobilePlatform::SetYaw(float time, float maxTurn) { // Unofficial: time, maxTurn if (spline.mNumPoints > 0) { - Vector dir = spline.GetVelocity(time); + Vector dir = spline.GetVelocity(time); // Unofficial rider.ToWorldDir(&dir); dir.y = 0.0f; if (dir.MagSquared() > Sqr(0.01f)) { - float yaw = atan2(dir.z, dir.x); - float direction; + float yaw = atan2(dir.z, dir.x); // Unofficial + float direction; // Unofficial if (bReverse == 0) { direction = 1.0f; } else { direction = -1.0f; } - float angle = GetSmallestAngle(mCurrRot.y, (2.0f * PI) * direction + (PI2 + yaw)); + float angle = GetSmallestAngle(mCurrRot.y, (2.0f * PI) * direction + (PI2 + yaw)); // Unofficial: angle mCurrRot.y += Clamp(-Abs(maxTurn), angle, Abs(maxTurn)); } } From 5e00dd7604b9203c241217e0c266819e469b5263 Mon Sep 17 00:00:00 2001 From: boebie <329328699+boebie-dev@users.noreply.github.com> Date: Sun, 11 Oct 2026 09:22:59 -0400 Subject: [PATCH 7/7] main: call MobilePlatform_LoadResources after Platform_LoadResources --- src/ty/source/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ty/source/main.cpp b/src/ty/source/main.cpp index c739a98..fa28da9 100644 --- a/src/ty/source/main.cpp +++ b/src/ty/source/main.cpp @@ -12,6 +12,7 @@ #include "ty/Mist.h" #include "ty/props/AnimatingProp.h" +#include "ty/props/MobilePlatform.h" #include "ty/props/Shatterable.h" #include "ty/props/WeatherProp.h" @@ -118,6 +119,7 @@ void Main_LoadStaticResources(void) { Shatterable_LoadResources(&ini); Platform_LoadResources(&ini); + MobilePlatform_LoadResources(&ini); AnimatingProp_LoadResources(&ini); TyAttributes_LoadResources(&ini);