Skip to content

mkw: Match KartState::init, improve KartCollide::checkNeighborhood, decompile RaceinfoPlayer_getLapSplit - #12

Open
ManuDigitalSun wants to merge 3 commits into
doldecomp:mainfrom
ManuDigitalSun:raceinfo-lapsplit
Open

ManuDigitalSun wants to merge 3 commits into
doldecomp:mainfrom
ManuDigitalSun:raceinfo-lapsplit

Conversation

@ManuDigitalSun

Copy link
Copy Markdown

Summary

  • Match KartState::init (56 bytes @ 0x8059455C) — 100.0% Objdiff match.
  • Improve KartCollide::checkNeighborhood — enables and refines the existing partial implementation by em-eight (7974069), 77.65% → 99.60% (0x224 / 548 bytes, matches target size). Known remaining mismatch: equivalent float constants use a different read-only-data layout (target uses @5034 / lbl_1_rodata_2020; current build uses anonymous local literals at different offsets).
  • Decompile RaceinfoPlayer_getLapSplit — 98.910255% (312/312 bytes).

Verification

Verified with Objdiff and a full local build:

AI assistance disclosure

AI-assisted: OpenAI Codex was used for target-assembly analysis, source-shape experiments, build-environment troubleshooting, and Ninja/Objdiff build iteration. All changes were reviewed and the matches independently verified by me.

Match the 56-byte function at 0x8059455C.

Verified with Objdiff at 100.0% and:
ninja all_source progress build/RMCP01/report.json

AI assistance: Used an AI coding assistant for build-environment troubleshooting, report/candidate analysis, target-assembly interpretation, and drafting the implementation. I reviewed the change and independently verified the final match and full local build.
Enable and refine the existing partial implementation.

Objdiff: 77.65% -> 99.60%
Function size: 0x224 / 548 bytes (matches target).

Original partial implementation by em-eight (7974069).

Known remaining mismatch: equivalent float constants use a different
read-only-data layout. The target uses @5034 and lbl_1_rodata_2020;
the current build uses anonymous local literals at different offsets.

AI-assisted: OpenAI Codex was used for assembly analysis, source-shape
experiments, and Ninja/Objdiff build iteration.
Objdiff: 98.910255% (312/312 bytes).

AI-assisted: OpenAI Codex was used for target-assembly analysis, source-shape experiments, and Ninja/Objdiff build iteration.
@decomp-dev

decomp-dev Bot commented Oct 5, 2026

Copy link
Copy Markdown

Report for RMCP01 (fa12730 - bf6a07a)

📉 Matched code: 5.77% (-0.00%, -132 bytes)

✅ 1 new match
Unit Item Bytes Before After
StaticR/kart/KartState Kart::KartState::init() +56 0.00% 100.00%
🥀 1 broken match
Unit Item Bytes Before After
main/gamespy/qr2/qr2 qr2_check_queries -1 100.00% 99.68%
📈 3 improvements in unmatched items
Unit Item Bytes Before After
StaticR/kart/KartCollide Kart::KartCollide::checkNeighborhood(Kart::KartCollisionInfo&, const Kart::Hitbox&, const Field::ColInfo&) +546 0.00% 99.67%
StaticR/system/RaceManager RaceinfoPlayer_getLapSplit +308 0.00% 98.91%
StaticR/kart/KartCollide .rodata +12 17.14% 26.32%

}
}

extern "C" void RaceinfoPlayer_getLapSplit(RaceManagerPlayer* player, u32 lap, Time* split) {

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.

Why is extern C used here? Why not the C++ name? Maybe the LLM used does not understand code warrior mangling?

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.

Maybe, it's a good question to understand how the LLM thinks about these problems. I asked the model about it:

Prompt: In the RaceManagercpp RaceInfoPlayer_getlapsplit, why did you use extern C instead of the c++ name? Do you not understand code warrior mangling?

Answer:

I understand CodeWarrior mangling. extern "C" was a linkage workaround, not proof that the original function was written as C.

The target symbol is literally:

RaceinfoPlayer_getLapSplit

without CodeWarrior mangling. A normal C++ definition such as:

void RaceManagerPlayer::getLapSplit(u32 lap, Time* split)

would emit a mangled symbol resembling:

getLapSplit__Q26System17RaceManagerPlayerFUiPQ26System4Time

and would not replace the plain target symbol by itself.

However, the ABI strongly suggests it behaves like a member method:

r3 = RaceManagerPlayer* this
r4 = lap
r5 = Time* split

So the honest answer is: I used extern "C" to make the source emit the target label while we had not recovered the proper C++ declaration/name mapping. It is technically valid for matching the ABI and label, but it is not ideal recovered source.

A cleaner reconstruction would be to add:

void getLapSplit(u32 lap, Time* split);

to RaceManagerPlayer, then determine how this project expects the member’s CodeWarrior-mangled output to be mapped/aliased to the existing target label. We should not blindly change it now, because the emitted mangled symbol would stop covering RaceinfoPlayer_getLapSplit unless we also resolve that symbol-mapping issue

Comment thread src/kart/KartCollide.cpp
if ((kartColInfo.flags & (COL_FLAG_WALL_AT_LEFT_CLOSER | COL_FLAG_WALL_AT_RIGHT_CLOSER)) == 0) {
if (fabsf(hitbox.bsp->pos.x) > 10.0f) {
if (hitbox.bsp->pos.x > 0.0f) {
((vu32&)kartColInfo.flags) |= COL_FLAG_WALL_AT_RIGHT_CLOSER;

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.

Since this is not 100% matched anyways I would not include the vu32 casts in the commit

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.

Fine, thx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants