Skip to content

Player: Implement PlayerStateJump - #1327

Open
c4nvm wants to merge 6 commits into
MonsterDruide1:masterfrom
c4nvm:master
Open

Player: Implement PlayerStateJump#1327
c4nvm wants to merge 6 commits into
MonsterDruide1:masterfrom
c4nvm:master

Conversation

@c4nvm

@c4nvm c4nvm commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

status: 43 / 43 functions matching (was 37 / 43)

this closes the remaining six:

  • appear — the jump-type dispatch (1104 insns),
    an outer switch over types 12–18 whose cases each setNerve and return (tail-merged into one call),
    then a shared gravity / isMove / velocity·gravity block,
    then an inner switch over types 1–17 whose default is the normal-jump and cap-catch path,
    calcJumpPowerBorderSpeed{Min,Max}, calcJumpPower{Min,Max} and calcJumpGravity all inline into it to feed PlayerActionFunction::calcJumpSpeed
  • the constructor, calcJumpPowerMax, calcJumpGravity and tryCountUpContinuousJump (previously Wip)
  • ~PlayerStateJump (D0) — it only became emittable once appear, the key function for this vtable, was defined

header changes

  • PlayerActionAirMoveControl: replaced set_42/44/48 with setMaxJumpSpeed(f32 minSpeed, f32 maxSpeed),
    the three field writes are a single inline,
    and corrected _44 from s32 to f32,
    appear's prologue stores it paired with _48 (stp s0, s8, [x8, #0x44]), receiving the force-run speed, or 0.0f when not force-running,
    also added set_33 (the "in 2D area" flag appear sets)
  • PlayerActionVelocityControl: getVelocityFront()
  • PlayerTrigger: EActionTrigger_val21, used by appear

notes for review

three constructs here exist for codegen reasons rather than clarity,
each is load-bearing so removing any one breaks the match,
but i'm happy to reshape them if there's a preferred house style:

  • the sead::Vector3f dir = jumpDir; / lastJumpDir copies before each dot product,
    without them the six component loads interleave with the multiplies,
    with them they group into ldp pairs as in the target,
    .dot() itself is fine — appear's other dot (al::getVelocity(actor).dot(gravity)) matches with the plain form
  • bool isInMessageJumpRange as its own statement,
    with the shift on the left of the && in the message-jump bitmask test,
    that ordering is what yields and + tbnz with cset ahead of lsr
  • calcVelocityFrontSpeed, a file-local helper (always inlined so it leaves no out-of-line symbol),
    used at the two sites whose result is consumed,
    alongside a plain PlayerActionVelocityControl local in the cap-catch branch,
    allocas from an inlined function are hoisted to the top of the caller's entry block,
    which is what places the merged velocity-control stack slot at sp+0x38 as in the target,
    using the helper in both branches of if (isCapCatchJump) instead lets SimplifyCFG hoist the constructor above the branch,
    the cap-catch object being constructed and never read is also what the target does

verification

  • all 43 functions in Player/PlayerStateJump.o report OK,
    and tools/check -p passes for the newly matched ones
  • the 175 already-matching functions across the 17 other translation units that include the touched headers were re-checked with no regressions
  • clang-format (18, as pinned by the lint workflow) and tools/check-format.py clean

This change is Reviewable


Report for 1.0 (0de3c75 - d099663)

📈 Matched code: 15.47% (+0.11%, +14228 bytes)

✅ 43 new matches
Unit Item Bytes Before After
Player/PlayerStateJump PlayerStateJump::appear() +4416 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::exeJump() +1472 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::exeJumpSpinFlower() +916 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::exeJumpTurn() +764 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::exeHoveringJump2D() +716 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::exeJumpSpinGround() +668 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::exeJumpBack() +668 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::updateNerveDownFall(char const*, float, float, float, al::Nerve const*) +600 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::exeHovering2D() +400 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::PlayerStateJump(al::LiveActor*, PlayerConst const*, IPlayerModelChanger const*, IUseDimension const*, PlayerInput const*, PlayerJumpMessageRequest const*, IJudge const*, PlayerCounterForceRun const*, PlayerJointControlKeeper const*, IUsePlayerCollision const*, PlayerTrigger*, PlayerContinuousJump*, PlayerAnimator*, PlayerActionDiveInWater*, HackCap*, IJudge*, bool) +396 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::tryCountUpContinuousJump(PlayerContinuousJump*) +320 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::calcJumpAnimName() const +204 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::isEndJumpDownFallLand() const +200 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::calcJumpPowerMin() const +176 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::calcJumpPowerMax() const +172 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::exeJumpSpinGroundDownFall() +164 0.00% 100.00%
Player/PlayerStateJump (anonymous namespace)::PlayerStateJumpNrvJumpSpinGroundDownFall::execute(al::NerveKeeper*) const +164 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::isFormSquat2D() const +156 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::isEnableHipDropStart() const +144 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::isEnableCancelCarryThrow() const +144 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::exeJumpSpinFlowerDownFall() +128 0.00% 100.00%
Player/PlayerStateJump (anonymous namespace)::PlayerStateJumpNrvJumpSpinFlowerDownFall::execute(al::NerveKeeper*) const +128 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::isJumpCapCatch() const +116 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::calcJumpGravity() const +100 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::isEnableTrampleByHipDropAttack() const +96 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::calcJumpPowerBorderSpeedMin() const +92 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::calcJumpPowerBorderSpeedMax() const +92 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::isJumpSpinFlower() const +92 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::isJumpSpinGround() const +92 0.00% 100.00%
Player/PlayerStateJump PlayerStateJump::isHovering() const +92 0.00% 100.00%

...and 13 more new matches

@github-actions github-actions Bot added the status:waiting for review This PR is ready to take the first or another look at it! label Jul 25, 2026

@MonsterDruide1 MonsterDruide1 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@MonsterDruide1 reviewed 5 files and all commit messages, and made 3 comments.
Reviewable status: 5 of 7 files reviewed, 3 unresolved discussions (waiting on c4nvm).


src/Player/PlayerStateJump.cpp line 106 at r1 (raw file):

    }

    if ((u32)mJumpMessageRequest->jumpType == 0xf && !mJumpMessageRequest->isEnableStandUp) {

create enum values for all possible jump types, potentially with placeholder names

Suggestion:

mJumpMessageRequest->jumpType == PlayerJumpType::val_0F

src/Player/PlayerStateJump.cpp line 121 at r1 (raw file):

    rs::scaleVelocityInertiaWallHit(actor, mCollider, 0.25f, 1.0f,
                                    getNormalMaxSpeed(mConst, mModelChanger));

TODO: continue below here


src/Player/PlayerStateJump.cpp line 124 at r1 (raw file):

    u32 messageJumpBit = (u32)mJumpMessageRequest->jumpType - 1;
    bool isInMessageJumpRange = messageJumpBit < 0x10;
    bool isMessageJump = ((0x9001u >> (u16)messageJumpBit) & 1) && isInMessageJumpRange;

try to never cast jumpType to the raw integer.
For checking JumpRange, create an enum entry JumpType::MAX that can be used instead of a magical number.

For the shift-and-AND-ing, this is a list of allowed values: 0, 12, 15 that you need to check against (t == 0 || t == 12 || t == 15, with enum entries for these constants).

Code quote:

    u32 messageJumpBit = (u32)mJumpMessageRequest->jumpType - 1;
    bool isInMessageJumpRange = messageJumpBit < 0x10;
    bool isMessageJump = ((0x9001u >> (u16)messageJumpBit) & 1) && isInMessageJumpRange;

@github-actions github-actions Bot removed the status:waiting for review This PR is ready to take the first or another look at it! label Aug 2, 2026
@MonsterDruide1 MonsterDruide1 changed the title finishes PlayerStateJump Player: Implement PlayerStateJump Aug 2, 2026
@github-actions github-actions Bot added the status:waiting for author Reviews have shown that the author of this PR needs to change some things. label Aug 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status:waiting for author Reviews have shown that the author of this PR needs to change some things.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants