Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
build
build.ninja
compile_commands.json

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you clarify where these files are coming from? I'm not sure if these need to be added to the .gitignore. Even if they should be added, I think this doesn't pertain to the scope of this PR

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Zed forces clangd down your throat and this is the only way to prevent it :P if .vscode is gitignored then so should these really.

.cache/**
__pycache__
out
.vs
.vscode
.zed
*.szs
statusTestCases.json
.env
26 changes: 23 additions & 3 deletions source/game/system/GhostFile.cc
Original file line number Diff line number Diff line change
Expand Up @@ -141,20 +141,36 @@ bool RawGhostFile::decompress(const u8 *rkg) {
}

/// @addr{0x8051C120}
/// @todo Check for valid controller type?
/// @todo Check lap times sum to race time?
bool RawGhostFile::isValid(const u8 *rkg) const {
if (strncmp(reinterpret_cast<const char *>(rkg), "RKGD", 4) != 0) {
PANIC("RKG header malformed");
return false;
}

u8 laps = *(rkg+0x10);

if (laps > 5) {
return false;
}

Timer finalTime = Timer(parse<u32>(*reinterpret_cast<const u32*>(rkg+0x4)));
Timer lapSum = Timer();
for (u8 i = 0; i < laps; i++) {
Timer lapTime = Timer(parse<u32>(*reinterpret_cast<const u32*>(rkg + 0x11 + (i*3))));
lapSum += lapTime;
}

if (finalTime != lapSum) {
return false;
}

u32 ids = parse<u32>(*reinterpret_cast<const u32 *>(rkg + 0x8));
Vehicle vehicle = static_cast<Vehicle>(ids >> 0x1a);
Character character = static_cast<Character>((ids >> 0x14) & 0x3f);
u8 year = (ids >> 0xd) & 0x7f;
u8 day = (ids >> 0x4) & 0x1f;
u8 month = (ids >> 0x9) & 0xf;
u8 day = (ids >> 0x4) & 0x1f;
u8 controllerType = ids & 0xf;

if (vehicle >= Vehicle::Max || character >= Character::Max) {
return false;
Expand All @@ -163,6 +179,10 @@ bool RawGhostFile::isValid(const u8 *rkg) const {
if (year >= 100 || day >= 32 || month > 12) {
return false;
}

if (controllerType > 3) {
return false;
}

// Validate weight class match
WeightClass charWeight = CharacterToWeight(character);
Expand Down
32 changes: 31 additions & 1 deletion source/game/system/TimerManager.hh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace System {

/// @brief A simple struct to represent a lap or race finish time.
struct Timer {
Timer(); ///< @unused Creates a zero'd timer.
Timer(); /// Creates a zero'd timer.
Timer(u16 min_, u8 sec_, u16 mil_);
Timer(u32 data);
~Timer();
Expand Down Expand Up @@ -82,7 +82,37 @@ struct Timer {

return Timer(newMin, newSec, newMs);
}

Timer operator+(const Timer &rhs) const {
s16 addMin = 0;
s16 addSec = 0;

s16 newMs = rhs.mil + mil;
if (newMs > 999) {
addSec = 1;
newMs -= 1000;
}

s16 newSec = rhs.sec + sec + addSec;
if (newSec > 59) {
addMin = 1;
newSec -= 60;
}

s16 newMin = rhs.min + min + addMin;
if (newMin > 999) {
newMin = 999;
newSec = 59;
newMs = 999;
}

return Timer(newMin, newSec, newMs);
}

Timer &operator+=(const Timer &rhs) {
return *this = *this + rhs;
}

u16 min;
u8 sec;
u16 mil; ///< @todo We will likely want to expand this to a float for more precise finish times.
Expand Down