Skip to content

Conversation

@malvarezcastillo
Copy link
Contributor

@malvarezcastillo malvarezcastillo commented Jan 29, 2026

Had claude work on the largest portion of unmatched code to see how it'd do. Here's the result. Did it do an acceptable job? It couldn't push it over 71% without doing fake black magic code patterns, this is the best "honest" attempt.

Claude:

Assessment of function "realness" at 70.17%:

Fakey pattern found:

  • Lines 346-348: Using digit_jobj->u.dobj->mobj->tobj instead of the just-assigned tobj variable. Removing it drops to 69%. This is a register allocation workaround.

Legitimate patterns:

  • PAD_STACK(96) - standard technique for stack alignment
  • HudIndex* hud and anim_base caching - proper variable patterns
  • (void) 0 after label - required C syntax
  • The mat_anim ->child->next->next chains - actual data structure traversal

Verdict: The function is "real enough" - the logic, structs, and data flow are correctly decompiled. The only questionable thing is that one tobj workaround (~1% impact). Everything else reflects what the code actually
does. Whether to keep that workaround is a style/philosophy question for the project maintainers.

Implements ~35% of the 3180-byte function. This is the largest
stubbed function in the codebase.

Implemented:
- Player state lookup via bdnz loop
- Death animation early return
- Animation status flag handling
- Digit visibility based on damage value (hide tens/hundreds)
- JObj position calculations for digit "1" spacing
- Shake animation trigger
- Final scale adjustment

Still missing (~65%):
- TObj texture animation setup (HSD_TObjAddAnimAll chains)
- Color interpolation based on damage percentage
- Detailed JObj/TObj pointer chain traversals
Implement ~66% of the 3180-byte function (largest in codebase).

Implemented:
- Player state lookup loop (bdnz pattern attempt)
- Death animation check and early return
- Animation status flags and setup
- TObj texture animations for all digits
- Digit visibility logic (hide tens/hundreds when < 10/100)
- Color interpolation based on damage percentage
  - Stamina mode: 0-100% range with inverted lerp
  - Normal mode: 0-300% range with direct lerp
- JObj position tracking during animations
- Digit "1" spacing adjustments (0.5069F offset)
- Shake timer and final scale

Still needs work:
- Loop counter structure (not generating bdnz)
- Register allocation differences (r24+ vs r23+)
- Some TObj animation chain navigation details
Partial decompilation of the largest stubbed function in ifstatus.c
(3180 bytes). Changes include:
- Proper stack frame with PAD_STACK(96)
- HudIndex* hud variable for register allocation
- HSD_MatAnimJoint** anim_base caching
- Player search loop with goto pattern
- Mat_anim chain access via ->child->next->next
- Digit TObj animation setup
- Color interpolation for damage display
- JObj position updates with jobj_flagCheckSetMtxDirtySub

Remaining issues:
- Loop generates addic./bne instead of mtctr/bdnz
- Code 416 bytes shorter than target
- Register allocation differences
@malvarezcastillo malvarezcastillo marked this pull request as ready for review January 29, 2026 10:34
@encounter
Copy link
Contributor

encounter commented Jan 29, 2026

Report for GALE01 (4781872 - 76284cd)

📈 2 improvements in unmatched functions
Unit Item Bytes Before After
main/melee/if/ifstatus ifStatus_802F4EDC +2281 0.18% 71.92%
main/melee/if/ifstatus .sdata2 +7 52.78% 59.57%

ribbanya
ribbanya previously approved these changes Jan 29, 2026
Copy link
Collaborator

@ribbanya ribbanya left a comment

Choose a reason for hiding this comment

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

Seems quite acceptable as a first pass. Function needs to be broken up into inline calls, like the found_player control flow. There's probably a missing struct on the stack that's causing the insane padding value. jobj.h asserts are inlines which can easily be found by line number in jobj.h.

@malvarezcastillo
Copy link
Contributor Author

Let me have a go at that, one sec.

@malvarezcastillo malvarezcastillo marked this pull request as draft January 29, 2026 14:41
@malvarezcastillo
Copy link
Contributor Author

Seems quite acceptable as a first pass. Function needs to be broken up into inline calls, like the found_player control flow. There's probably a missing struct on the stack that's causing the insane padding value. jobj.h asserts are inlines which can easily be found by line number in jobj.h.

Nevermind:

I've been working extensively on this function. Here's the current status:

Current match: 71.92% (improved from initial 71.52%)

Successful improvements committed:

  1. Used function-level i for player-finding loop index
  2. Reordered variable declarations for better register allocation

Key blockers to reaching 90%:

  1. bdnz loop pattern not generating: Target uses mtctr + bdnz (CTR-based loop), but mwcc generates addic. + bne regardless of the C loop structure. This is a fundamental codegen difference.
  2. Register allocation: Target saves r23-r31, generated saves r22-r31 (one extra register being used).
  3. Inline expansion differences: Target has ~49 function calls, generated has ~100 - suggesting different inline behavior.

I've tried many approaches including different loop structures, inline functions, variable declaration orders, and pragma settings, but haven't been able to break past ~72%.

The reviewer's suggestions (bdnz loop, missing struct on stack, jobj.h inlines) are accurate but the specific code patterns to trigger them are proving difficult to find. This function may need consultation with other
decompilers who have experience with this specific pattern, or acceptance of the current ~72% match as a first pass.

Shall I continue experimenting, or would you like me to document the current state and move on?

@malvarezcastillo malvarezcastillo marked this pull request as ready for review January 29, 2026 17:15
- Fix translation_x vs translation_y bug in position calculations
- Convert reading loop to use pointer increments (matches target pattern)
- Remove tex_anim caching in first animation block (reduces register pressure)
Improves match from 71.52% to 71.83%
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.

3 participants