From ab7ef87126c742e055836d45800f296ef4b6b256 Mon Sep 17 00:00:00 2001 From: em-eight Date: Sat, 24 Feb 2024 20:03:03 +0200 Subject: [PATCH] Rudimentary RaceManager and ElineController definitions --- source/game/system/ElineControlManager.hpp | 15 ++ source/game/system/ElineController.hpp | 15 ++ source/game/system/GhostFile.hpp | 6 + source/game/system/RaceManager.cpp | 4 - source/game/system/RaceManager.hpp | 189 +++++++++++++++++++++ 5 files changed, 225 insertions(+), 4 deletions(-) create mode 100644 source/game/system/ElineControlManager.hpp create mode 100644 source/game/system/ElineController.hpp diff --git a/source/game/system/ElineControlManager.hpp b/source/game/system/ElineControlManager.hpp new file mode 100644 index 000000000..31c51b142 --- /dev/null +++ b/source/game/system/ElineControlManager.hpp @@ -0,0 +1,15 @@ + +#pragma once + +#include "ElineController.hpp" + +namespace System { +// TODO: TU 0x8052d46c-0x8052d96c +class ElineControlManager { +public: + ElineControlManager(); + + ElineController** controllers; + u16 controllerCount; +}; +} diff --git a/source/game/system/ElineController.hpp b/source/game/system/ElineController.hpp new file mode 100644 index 000000000..4f12994a9 --- /dev/null +++ b/source/game/system/ElineController.hpp @@ -0,0 +1,15 @@ + +#pragma once + +#include "CourseMap.hpp" + +namespace System { +// TODO: TU 0x8052d270-0x8052d46c +class ElineController { + ElineController* next; + s16 controllerFrameCounter; + s16 pathIdx; + s16 controllerDurationFrames; + bool isFinalNode; +}; +} diff --git a/source/game/system/GhostFile.hpp b/source/game/system/GhostFile.hpp index 5fa696667..fc64f6faf 100644 --- a/source/game/system/GhostFile.hpp +++ b/source/game/system/GhostFile.hpp @@ -48,6 +48,12 @@ class Time { mSeconds = seconds; mMilliseconds = milliseconds; } + void set2(u16 minutes, u8 seconds, u16 milliseconds, bool isValid) { + mMinutes = minutes; + mSeconds = seconds; + mMilliseconds = milliseconds; + mIsValid = isValid; + } private: u16 mMinutes; diff --git a/source/game/system/RaceManager.cpp b/source/game/system/RaceManager.cpp index a99c30e5d..784f3bcf2 100644 --- a/source/game/system/RaceManager.cpp +++ b/source/game/system/RaceManager.cpp @@ -43,14 +43,10 @@ extern UNKNOWN_FUNCTION(__cvt_ull_flt); extern UNKNOWN_FUNCTION(__cvt_dbl_ull); // PAL: 0x800850b0 extern UNKNOWN_FUNCTION(unk_800850b0); -// PAL: 0x801aad74 -extern UNKNOWN_FUNCTION(OSGetTick); // PAL: 0x80229dcc extern UNKNOWN_FUNCTION(__nw__FUl); // PAL: 0x80229df0 extern UNKNOWN_FUNCTION(__nwa__FUl); -// PAL: 0x80229e14 -// extern UNKNOWN_FUNCTION(__dl__FPv); // PAL: 0x80229ee0 extern UNKNOWN_FUNCTION(__dla__FPv); // PAL: 0x8022f80c diff --git a/source/game/system/RaceManager.hpp b/source/game/system/RaceManager.hpp index d0865f6c2..c02e8d985 100644 --- a/source/game/system/RaceManager.hpp +++ b/source/game/system/RaceManager.hpp @@ -232,3 +232,192 @@ UNKNOWN_FUNCTION(unk_80538344); #ifdef __cplusplus } #endif + +#include "KPadDirector.hpp" +#include "GhostFile.hpp" +#include "CourseMap.hpp" +#include "RaceConfig.hpp" +#include "ElineControlManager.hpp" +#include "game/util/Random.hpp" +#include "ResourceManager.hpp" + +namespace System { +enum RaceStage { + INTRO_CAMERA=0 /* Course preview */, + COUNTDOWN=1 /* Includes starting pan */, + RACE=2, + FINISHED_RACE=3 +}; + +// TODO: Maybe defines/bitfield and not enum? +enum RaceManagerPlayerFlags { + IN_RACE=1, + FINISHED=2, + DRIVING_WRONG_WAY=4, + DISCONNECTED=16, + COMING_LAST_ANIMATION=64 +}; + +struct KmgFileRaw { + char magic[4]; /* RKMG in ASCII */ + u32 fileSize; /* in bytes */ + s32 field2_0x8; + void* coinRunnersOff; /* relative to 0x10 */ + s16 balloonBattleTimeLimits[10][11]; + u16 field5_0xec[10][11]; + s16 enemyHitScore; + s16 enemyDefeatScore; + s16 allBalloonLossScore; + s16 hitByEnemyScore; + s16 teammateHitScore; + s16 hitByTeammateScore; + s16 field12_0x1d4; + s16 field13_0x1d6; + s16 field14_0x1d8; + s16 field15_0x1da; + s16 coinRunnersTimeLimits[10][11]; + u16 field17_0x2b8[10][11]; + u16 startCoinCounts[10][11]; + u16 maxCoinCounts[10][11]; + u16 field20_0x54c[10][11]; + u16 field21_0x628[10][11]; + unk8 unk[0x712-0x704]; + s16 fallOffCoinLoss; + s16 hitCoinLoss; + s16 coinLossPercent; /* ?? Copied from wiki */ +}; +static_assert(sizeof(KmgFileRaw) == 0x718); + +class KmgFile { +public: + KmgFile(void* file) { fromRaw(file); } + void fromRaw(void* file); + virtual ~KmgFile(); + s16 getBattleCourseId(CourseId courseId); + + KmgFileRaw* data; +}; +static_assert(sizeof(KmgFile) == 0x8); + +// Maybe its own header file +class TimerManagerBase { +public: + TimerManagerBase() { reset(); } + virtual ~TimerManagerBase(); + virtual void reset(); + virtual void update(); + +protected: + Time timer1; + Time timer2; + Time timer3; + Util::Random random; + s8 field26_0x40; + bool raceHasStarted; + bool timerIsReversed; + u32 raceDurationMillis; + unk8 unk48[0x50-0x48]; +}; + +class TimerManager : public TimerManagerBase { +public: + TimerManager() : TimerManagerBase() {} + virtual ~TimerManager() override; + virtual void reset() override; + virtual void update() override; + inline void setLimit(u16 minutes, u8 seconds) { + this->timer3.set2(minutes, seconds, 0, true); + this->timerIsReversed = true; + this->timer2.set2(minutes, seconds, 0, true); + this->raceDurationMillis = (seconds+60*minutes)*1000; + } +}; +static_assert(sizeof(TimerManager) == 0x50); + +/** + * currentBit is a 1 that rotates arounds the region defined by mask every frame. Could be slipstream related? + * Overall a weird timer which rotates a single bit around a u32 + * */ +class MovingMask { +public: + MovingMask(u32); + int mask; + int currentBit; +}; + +class RaceManagerPlayer { +public: + RaceManagerPlayer(u8 idx, u8 lapCount); + virtual ~RaceManagerPlayer(); + + unk32 field_0x4; + s8 idx; + u16 checkpointId; + float raceCompletion; + float raceCompletionMax; + float checkpointFactor; + float checkpointStartLapCompletion; + float lapCompletion; + s8 position; + s8 respawn; + u16 battleScore; + s16 currentLap; + s8 maxLap; + s8 currentKcp; + s8 maxKcp; + u32 frameCounter; + u32 framesInFirstPlace; + s32 field25_0x34; + RaceManagerPlayerFlags flags; + Time* lapFinishTimes; + Time* raceFinishTime; + u32 somethingRaceEndMessageOnline; + KPadPlayer* kpadPlayer; + unk8 unk_4c_50[0x50-0x4c]; + u16 playersAheadFlags; + s8 field36_0x52; + s8 finishingPosition; +}; +static_assert(sizeof(RaceManagerPlayer) == 0x54); + +class RaceMode; // todo in another file +class RaceManager { +public: + virtual ~RaceManager(); + RaceManager(); + + static RaceManager* createInstance(); + static void destroyInstance(); + static RaceManager* spInstance; + static u8 getLapCount(); + + RaceMode* initGamemode(RaceConfig::Settings::GameMode mode); + RaceMode* createCompetitionMode(); + u16 getBattleTimeLimit(); + + Util::Random* random1; + Util::Random* random2; + RaceManagerPlayer** players; + RaceMode* raceMode; + TimerManager* timerManager; + s8* player_id_in_each_position; + s8 finished_player_count; + s8 disconnectedPlayerCount; + s16 introTimer; + u32 timer; /* Begins counting when race countdown starts */ + s8 battleKtptStart; + s8 field12_0x25; + RaceStage stage; + bool introWasSkipped; + bool spectatorMode; + bool canCountdownStart; + bool cutSceneMode; + bool lapCountingIsEnabled; + MovingMask movingMask; + KmgFile* kmgFile; + ElineControlManager* eline_control_manager; + float dpWaterHeightCheck; + bool dpDisableLowerRespawns; +}; +static_assert(sizeof(RaceManager) == 0x4c); +}