data/claims/sms.yamlSuper Mario Sunshine (the doldecomp decompilation, doldecomp/sms)
Game: Super Mario Sunshine.
In the doldecomp decompilation of Super Mario Sunshine, most of Mario's movement constants are named parameters (TParamRT), each built with a default in the code, in sets that each name a file, such as /Mario/Jump.prm. TParams::load, in a file configure.py marks as matching the game's code, reads the set's file from the scene's /map/params folder if it is there and from the params archive if not, and a record whose key and name match a parameter replaces that parameter's default; the rest keep theirs. The values the game plays with are data on the disc, which the atlas hasn't read, so the numbers in these claims are the code's defaults. The jump set's gravity, mGravity, defaults to 0.8. In the jumping states, jumpProcess in the decompilers' Player code, which doesn't yet match, moves Mario by a quarter of his velocity in one step per update. Then fallProcess subtracts mGravity from his vertical speed, except in a dive (the dive set's own gravity, with a cap of its own), in a spin jump's descent (mSpinJumpGravity, default 0.6), and when a release cuts the rise (sms/jump); in every case it then caps the fall at −75. Super Mario 64 also moves Mario a quarter of his velocity at a time, but in four steps a frame (sm64/units). sms/params
About: Super Mario Sunshine Gravity
Value: 0.8 units/update²
Code notesnon-matching codesms: a decompilation of Super Mario Sunshine (doldecomp/sms) ·configure.py#L314-L315Matching = True # Object matches and should be linked
NonMatching = False # Object does not match and should not be linkedsms: a decompilation of Super Mario Sunshine (doldecomp/sms) · configure.py#L879Object(Matching, "System/Params.cpp"),sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · configure.py#L950Object(NonMatching, "Player/MarioPhysics.cpp"),sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · configure.py#L964PCHObject(NonMatching, "Player/MarioInit.cpp"),sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · include/System/ParamInst.hpp#L8-L9#define PARAM_INIT(member, defaultValue) \
member(this, defaultValue, JDrama::TNameRef::calcKeyCode(#member), #member)sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/System/Params.cpp#L12-L29if (mHead != nullptr) {
s32 length = stream.readS32();
for (int i = 0; i < length; i++) {
u16 keyCode = stream.read16b();
…
if (keyCode == param->keyCode && !strcmp(buffer, param->name)) {
param->load(stream);
break;
…
if (param == nullptr) {
s32 end = stream.read32b();
stream.skip(end);sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/System/Params.cpp#L54-L66if (mSceneArc != nullptr && mSceneArc->becomeCurrent(SceneParamsDir)) {
resource = mSceneArc->getResource(filename);
…
if (mArc != nullptr) {
mArc->becomeCurrent("/");
void* resource2 = mArc->getResource(filename);sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/System/Params.cpp#L5static const char SceneParamsDir[] = "/map/params";sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioInit.cpp#L544-L547TMario::TJumpParams::TJumpParams()
: TParams("/Mario/Jump.prm")
, PARAM_INIT(mGravity, 0.8f)
, PARAM_INIT(mSpinJumpGravity, 0.6f)sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioPhysics.cpp#L498-L509Vec next;
next.x = mPosition.x + 0.25f * mVel.x;
next.y = mPosition.y + 0.25f * mVel.y;
next.z = mPosition.z + 0.25f * mVel.z;
int ret = checkGroundAtJumping(next, param_1);
…
fallProcess();sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioPhysics.cpp#L464-L485void TMario::fallProcess()
{
if (mStatus == MARIO_STATUS_DIVE) {
mVel.y -= mDivingParams.mGravity.get();
…
if (isFallCancel()) {
mVel.y *= 0.75f;
} else if ((mStatus == MARIO_STATUS_LEFT_ROTATE_JUMP
|| mStatus == MARIO_STATUS_RIGHT_ROTATE_JUMP)
&& mVel.y < 0.0f) {
mVel.y -= mJumpParams.mSpinJumpGravity.get();
} else {
…sm64: a decompilation of Super Mario 64 (n64decomp/sm64) · src/game/mario_step.c#L618-L621for (i = 0; i < 4; i++) {
intendedPos[0] = m->pos[0] + m->vel[0] / 4.0f;
intendedPos[1] = m->pos[1] + m->vel[1] / 4.0f;
intendedPos[2] = m->pos[2] + m->vel[2] / 4.0f;Checked by claude, 2026-10-22 — read Params.cpp whole, the PARAM_INIT macro, the TJumpParams constructor, jumpProcess and fallProcess whole, and the configure.py lines; how often the game calls Mario's update each frame isn't read, so the claims count updates, not framesjumpProcess makes one collision step of a quarter of the velocity, where Super Mario 64's perform_air_step makes four, so the same speed number moves Sunshine's Mario a quarter as far per update. Without the frame rate or the disc's values, no jump height or duration is computed here.
Cited by: Gravity, Super Mario Sunshine
In Super Mario Sunshine, by the decompilers' Player code, which doesn't yet match, a press that starts a jump through changePlayerJumping first goes to a miss jump if isJumpMiss is true, then to a spin jump if considerRotateJumpStart reads the stick's recent turning as a spin, and otherwise to the status it asks for. For the single jump, MARIO_STATUS_JUMP, setStatusToJumping sets Mario's vertical speed to 42 plus a quarter of his forward speed and multiplies the forward speed by 0.8, constants in the code rather than parameters, and the same take-off as Super Mario 64's single jump (sm64/jump-speed). On two kinds of floor, which the code tells apart only as isThing2 and isThing3, the speed is replaced or added to and the jump becomes MARIO_STATUS_FORCE_JUMP; on Yoshi it is multiplied by the parameter mJumpYoshiMult, and while isSinking() is true both speeds are scaled by a factor from the mGraffitoParams set. When the new jumping status carries the bit the code calls MARIO_STATUS_FLAG_UNK2000000 (0x2000000), as the single jump, the double jump, and the wall kick do, setStatusToJumping sets bit 0x100 of unk78, and it clears that bit for any other jumping status (other code clears it too). While that bit is set, the status has neither bit 0x1000 nor 0x20000, A isn't held, and Mario rises faster than 20, fallProcess multiplies his vertical speed by 0.75 on each update in place of the gravity. Super Mario 64 divides it by 4 on each frame when A isn't held and Mario rises faster than 20, if its MARIO_UNKNOWN_08 flag is set, the action is neither intangible nor invulnerable, and the action has ACT_FLAG_CONTROL_JUMP_HEIGHT, the same bit, 0x02000000 (sm64/jump-release). The status numbers line up too: Sunshine's single jump is 0x2000000 | 0x800 | 0x080 (computed 0x2000880), and Super Mario 64's ACT_JUMP is 0x03000880. sms/jump
About: Super Mario Sunshine Jump
Value: 42 velocity units
Code notesnon-matching codesms: a decompilation of Super Mario Sunshine (doldecomp/sms) ·configure.py#L949-L950PCHObject(NonMatching, "Player/MarioMove.cpp"),
Object(NonMatching, "Player/MarioPhysics.cpp"),sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioMove.cpp#L764-L772int TMario::changePlayerJumping(u32 param_1, u32 param_2)
{
if (isJumpMiss()) {
setMissJumping();
} else {
if (considerRotateJumpStart())
return 1;
…
changePlayerStatus(param_1, param_2, false);sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioMove.cpp#L420-L423void TMario::setPlayerJumpSpeed(f32 speed_mult, f32 force)
{
mVel.y = (mForwardVel * speed_mult) + force;
}sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioMove.cpp#L434-L456switch (status) {
case MARIO_STATUS_JUMP:
case 0x89C:
setPlayerJumpSpeed(0.25f, 42.0f);
mForwardVel *= 0.8f;
…
if (mGroundPlane->isThing2()) {
mVel.y = 0.01f * mGroundPlane->getActiveJumpPower();
nextStatus = MARIO_STATUS_FORCE_JUMP;
…
} else if (mGroundPlane->isThing3()) {
mVel.y += -unkBC + getGroundJumpPower();
…sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioMove.cpp#L647-L654if (isSinking()) {
f32 scale = ((mGraffitoParams.mSinkJumpRateMax.get()
…
mVel.y *= scale;
mForwardVel *= scale;sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioMove.cpp#L663-L673if (onYoshi()) {
mVel.y *= mYoshiParams.mJumpYoshiMult.get();
…
if (nextStatus & MARIO_STATUS_FLAG_UNK2000000)
unk78 |= 0x100;
else
unk78 &= ~0x100;sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioMove.cpp#L1482-L1483if (mGamePad->checkMeaning(TMarioGamePad::MEANING_A))
mInput |= 0x80;sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioPhysics.cpp#L450-L459BOOL TMario::isFallCancel()
{
if (!(unk78 & 0x100 ? true : false))
return false;
…
if (mStatus & 0x21000)
return false;
…
if (!(mInput & 0x80) && mVel.y > 20.0f)
return true;sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioPhysics.cpp#L471-L472if (isFallCancel()) {
mVel.y *= 0.75f;sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · include/Player/MarioStatus.hpp#L7MARIO_STATUS_FLAG_JUMPING = 0x800,sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · include/Player/MarioStatus.hpp#L17MARIO_STATUS_FLAG_UNK2000000 = 0x2000000,sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · include/Player/MarioStatus.hpp#L26MARIO_STATUS_TYPE_JUMPING = 0x080,sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · include/Player/MarioStatus.hpp#L119-L133MARIO_STATUS_JUMP = MARIO_STATUS_FLAG_UNK2000000 | MARIO_STATUS_FLAG_JUMPING
| MARIO_STATUS_TYPE_JUMPING | 0x0, // 0x2000880
MARIO_STATUS_SECOND_JUMP = MARIO_STATUS_FLAG_UNK2000000
…
MARIO_STATUS_WALL_JUMP = MARIO_STATUS_FLAG_UNK2000000sm64: a decompilation of Super Mario 64 (n64decomp/sm64) · src/game/mario.c#L821-L825case ACT_JUMP:
case ACT_HOLD_JUMP:
…
set_mario_y_vel_based_on_fspeed(m, 42.0f, 0.25f);
m->forwardVel *= 0.8f;sm64: a decompilation of Super Mario 64 (n64decomp/sm64) · src/game/mario.c#L763-L766static void set_mario_y_vel_based_on_fspeed(struct MarioState *m, f32 initialVelY, f32 multiplier) {
…
m->vel[1] = initialVelY + get_additive_y_vel_for_jumps() + m->forwardVel * multiplier;sm64: a decompilation of Super Mario 64 (n64decomp/sm64) · src/game/mario_step.c#L519-L529u32 should_strengthen_gravity_for_jump_ascent(struct MarioState *m) {
if (!(m->flags & MARIO_UNKNOWN_08)) {
return FALSE;
…
if (m->action & (ACT_FLAG_INTANGIBLE | ACT_FLAG_INVULNERABLE)) {
return FALSE;
…
if (!(m->input & INPUT_A_DOWN) && m->vel[1] > 20.0f) {
return (m->action & ACT_FLAG_CONTROL_JUMP_HEIGHT) != 0;sm64: a decompilation of Super Mario 64 (n64decomp/sm64) · src/game/mario_step.c#L559-L560} else if (should_strengthen_gravity_for_jump_ascent(m)) {
m->vel[1] /= 4.0f;sm64: a decompilation of Super Mario 64 (n64decomp/sm64) · include/sm64.h#L165#define ACT_FLAG_CONTROL_JUMP_HEIGHT /* 0x02000000 */ (1 << 25)sm64: a decompilation of Super Mario 64 (n64decomp/sm64) · include/sm64.h#L256#define ACT_JUMP 0x03000880 // (0x080 | ACT_FLAG_AIR | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION | ACT_FLAG_CONTROL_JUMP_HEIGHT)Checked by claude, 2026-10-22 — read setStatusToJumping whole (L425-L676), changePlayerJumping, setPlayerJumpSpeed, the input synthesis, isFallCancel and fallProcess, and the status enum; SM64's take-off and should_strengthen_gravity_for_jump_ascent read at the cited lines; isJumpMiss, isThing2/isThing3, and the sinking factor's parameters are not tracedThe 0x2000880 beside MARIO_STATUS_JUMP is the decompilers' comment; the statement computes it from the three flags. Super Mario 64's should_strengthen_gravity_for_jump_ascent also needs the MARIO_UNKNOWN_08 flag and rules out intangible and invulnerable actions, the counterpart of Sunshine's unk78 bit and its 0x21000 test. Sunshine's speeds move a quarter as far per update as Super Mario 64's per frame (sms/params), so the shared 42 is a number in each game's own units.
Cited by: Jump, Super Mario Sunshine, Variable jump height
In Super Mario Sunshine, by the decompilers' Player code, which doesn't yet match, the double jump, the backflip (MARIO_STATUS_BACK_JUMP), the spin jump, and the jumps the code calls trample and wireJumping all land in MARIO_STATUS_SEC_JUMP_SLIP. Its jumpSlipEvents counts updates and ends the landing on the 16th, before reading A, so a press on one of the first 15 (computed) goes to changePlayerJumping, which can still turn it into a miss or spin jump (sms/jump): the triple jump, MARIO_STATUS_ULTRA_JUMP, if the forward speed is at least the parameter mTriJumpEnableSp (default 20), and a single jump if not. The single jump and the wall kick land in MARIO_STATUS_JUMP_SLIP instead, where a press makes a double jump only at a forward speed of at least mSecJumpEnableSp (default 20). The triple jump takes off at mUltraJumpForce plus mUltraJumpSpeedMult times the forward speed (defaults 70 and 0.25) and multiplies the forward speed by mUltraJumpXZMult (default 0.8); its status lacks the bit that lets a release cut the rise. Super Mario 64's triple jump starts from the double jump's 4-frame landing at a forward speed above 20, takes off at 69 whatever the speed, and can't be cut either (sm64/triple-jump, sm64/jump-release). sms/triple-jump
About: Super Mario Sunshine Triple jump
Value: 70 velocity units
Code notesnon-matching codesms: a decompilation of Super Mario Sunshine (doldecomp/sms) ·configure.py#L947-L964Object(NonMatching, "Player/MarioJump.cpp"),
…
PCHObject(NonMatching, "Player/MarioMove.cpp"),
…
PCHObject(NonMatching, "Player/MarioRun.cpp"),
…
PCHObject(NonMatching, "Player/MarioInit.cpp"),sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioJump.cpp#L341-L357BOOL TMario::secJumping()
…
jumpingBasic(MARIO_STATUS_SEC_JUMP_SLIP, anim, 3);sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioJump.cpp#L378-L392BOOL TMario::backJumping()
…
jumpingBasic(MARIO_STATUS_SEC_JUMP_SLIP, 0xF7, 0);
else
jumpingBasic(MARIO_STATUS_SEC_JUMP_SLIP, ANIM_LAND, 0);sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioJump.cpp#L773-L778BOOL TMario::trample()
…
jumpingBasic(MARIO_STATUS_SEC_JUMP_SLIP, mAnimationId, 3);sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioJump.cpp#L997-L1007BOOL TMario::rotateJumping()
…
jumpingBasic(MARIO_STATUS_SEC_JUMP_SLIP, mAnimationId, 0);sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioJump.cpp#L1021-L1035BOOL TMario::wireJumping()
…
jumpingBasic(MARIO_STATUS_SEC_JUMP_SLIP, mAnimationId, 3);sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioJump.cpp#L335jumpingBasic(MARIO_STATUS_JUMP_SLIP, ANIM_JUMP, 3);sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioJump.cpp#L454jumpingBasic(MARIO_STATUS_JUMP_SLIP, ANIM_WJMP, 3);sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioRun.cpp#L1538-L1557BOOL TMario::jumpSlipEvents(JumpSlipRecord* rec)
…
mStatusTimer++;
…
if (mStatusTimer >= rec->mMaxTimer)
return changePlayerStatus(rec->mEndStatus, 0, false);
…
if (mInput & 0x2) {
if (rec->mJumpStatus == MARIO_STATUS_SECOND_JUMP)
if (mForwardVel >= mJumpParams.mSecJumpEnableSp.get())
return changePlayerJumping(MARIO_STATUS_SECOND_JUMP, 0);
…
…sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioRun.cpp#L1599-L1602BOOL TMario::secJumpSlip()
{
static TMario::JumpSlipRecord param
= { 0x10, MARIO_STATUS_SEC_JUMP_END, MARIO_STATUS_ULTRA_JUMP,sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioMove.cpp#L471-L474case MARIO_STATUS_ULTRA_JUMP:
setPlayerJumpSpeed(mJumpParams.mUltraJumpSpeedMult.get(),
mJumpParams.mUltraJumpForce.get());
mForwardVel *= mJumpParams.mUltraJumpXZMult.get();sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioInit.cpp#L572-L579, PARAM_INIT(mSecJumpEnableSp, 20.0f)
…
, PARAM_INIT(mTriJumpEnableSp, 20.0f)
, PARAM_INIT(mUltraJumpForce, 70.0f)
, PARAM_INIT(mUltraJumpSpeedMult, 0.25f)
, PARAM_INIT(mUltraJumpXZMult, 0.8f)sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · include/Player/MarioStatus.hpp#L124-L125MARIO_STATUS_ULTRA_JUMP
= MARIO_STATUS_FLAG_JUMPING | MARIO_STATUS_TYPE_JUMPING | 0x2, // 0x882sm64: a decompilation of Super Mario 64 (n64decomp/sm64) · src/game/mario_actions_moving.c#L1874-L1875s32 act_double_jump_land(struct MarioState *m) {
if (common_landing_cancels(m, &sDoubleJumpLandAction, set_triple_jump_action)) {sm64: a decompilation of Super Mario 64 (n64decomp/sm64) · src/game/mario_actions_moving.c#L50-L51struct LandingAction sDoubleJumpLandAction = {
4, 5, ACT_FREEFALL, ACT_DOUBLE_JUMP_LAND_STOP, ACT_JUMP, ACT_FREEFALL, ACT_BEGIN_SLIDING,sm64: a decompilation of Super Mario 64 (n64decomp/sm64) · src/game/mario_actions_moving.c#L150-L151} else if (m->forwardVel > 20.0f) {
return set_mario_action(m, ACT_TRIPLE_JUMP, 0);sm64: a decompilation of Super Mario 64 (n64decomp/sm64) · src/game/mario.c#L796-L798case ACT_TRIPLE_JUMP:
set_mario_y_vel_based_on_fspeed(m, 69.0f, 0.0f);
m->forwardVel *= 0.8f;sm64: a decompilation of Super Mario 64 (n64decomp/sm64) · include/sm64.h#L258#define ACT_TRIPLE_JUMP 0x01000882 // (0x082 | ACT_FLAG_AIR | ACT_FLAG_ALLOW_VERTICAL_WIND_ACTION)Checked by claude, 2026-10-22 — read jumpSlipEvents, the slip records for the jump, double-jump, and triple-jump landings, every jumpingBasic call that names SEC_JUMP_SLIP or JUMP_SLIP in MarioJump.cpp, the ULTRA_JUMP take-off, and the TJumpParams defaults; SM64's lines read at the cited rangesSunshine's landing counts updates and Super Mario 64's counts frames, so the 16 and the 4 don't compare until the update rate is known. jumpSlipEvents also ends a landing at once on bit 0x10 of mInput, which the input synthesis read here doesn't set. With the wing cap, Super Mario 64's press starts the flying triple jump instead.
Cited by: Super Mario Sunshine, Triple jump
In Super Mario Sunshine, by the decompilers' Player code, which doesn't yet match, when jumpProcess reports a wall to jumpingBasic during a jump, Mario is knocked back if his forward speed is above the parameter mClashSpeed (default 50) outside the wire roll jump, stops on Yoshi, stops on a wall marked isNoWallJump, and catches a fence (isFence). Otherwise, at a forward speed above 16, he turns about (after playerRefrection) and, against a wall, holds on in MARIO_STATUS_WALL_SLIDE. There stayWall adds 1 to the status timer each update, capped at 60, and 1 more while it is below 20, so he hangs still for 10 updates and then slides down at half the timer: −10.5 on the 11th update, then 0.5 faster each update to −30 (computed). An A press on any update on the wall kicks: startJumpWall turns him about and enters MARIO_STATUS_WALL_JUMP, whose take-off in setStatusToJumping is 62 up and 24 forward, constants in the code; the 52 that startJumpWall writes first is overwritten. Landing or losing the wall ends the hold. Super Mario 64 kicks at the same 62 up and at least 24 forward, and its act_air_hit_wall also writes a 52 that the kick's take-off overwrites, but it holds Mario only 2 frames and then bonks him away, with A still working for 5 more: 7 frames in all (sm64/wall-kick). With no wall to hold, Sunshine bonks him the way Super Mario 64 does: back down at 38 or faster, and at −8 if faster than 8. sms/wall-kick
About: Super Mario Sunshine Wall jump
Value: 62 velocity units
Code notesnon-matching codesms: a decompilation of Super Mario Sunshine (doldecomp/sms) ·configure.py#L947-L964Object(NonMatching, "Player/MarioJump.cpp"),
…
PCHObject(NonMatching, "Player/MarioMove.cpp"),
Object(NonMatching, "Player/MarioPhysics.cpp"),
…
PCHObject(NonMatching, "Player/MarioInit.cpp"),sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioJump.cpp#L201-L250case 2:
if (mStatus != MARIO_STATUS_WIRE_ROLL_JUMP
&& mForwardVel > mDeParams.mClashSpeed.get()) {
…
changePlayerDropping(MARIO_STATUS_JUMP_SHORT_BACK_DOWN, 0U);
…
if (onYoshi()) {
setPlayerVelocity(0.0f);
…
if (mWallPlane->isNoWallJump()) {
…
if (mWallPlane->isFence()) {
…sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioJump.cpp#L252-L254if (mForwardVel > 8.0f)
setPlayerVelocity(-8.0f);
return changePlayerStatus(MARIO_STATUS_LAND_SAFE_DOWN, 0, 0);sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioInit.cpp#L510, PARAM_INIT(mClashSpeed, 50.0f)sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioJump.cpp#L586-L620BOOL TMario::stayWall()
{
mStatusTimer += 1;
if (mStatusTimer > 60)
mStatusTimer = 60;
…
if (mInput & 2)
return startJumpWall();
…
if (mStatusTimer < 20) {
mStatusTimer += 1;
mVel.set(0.0f, 0.0f, 0.0f);
…sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioJump.cpp#L16-L30BOOL TMario::startJumpWall()
…
mVel.y = 52.0f;
mFaceAngle.y += 0x8000;
if (mVel.y + (160.0f + mPosition.y) >= mFloorPosition.x)
mVel.y = 1.0f;
…
return changePlayerStatus(MARIO_STATUS_WALL_JUMP, 0, 0);sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioMove.cpp#L517-L519case MARIO_STATUS_WALL_JUMP:
setPlayerJumpSpeed(0.0f, 62.0f);
mForwardVel = 24.0f;sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioMove.cpp#L733-L738switch (status & MARIO_STATUS_TYPE_MASK) {
…
case MARIO_STATUS_TYPE_JUMPING:
status = setStatusToJumping(status, arg);sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioMove.cpp#L1479-L1480if (mGamePad->checkFrameMeaning(TMarioGamePad::MEANING_A))
mInput |= 0x2;sm64: a decompilation of Super Mario 64 (n64decomp/sm64) · src/game/mario_actions_airborne.c#L1314-L1337if (++(m->actionTimer) <= 2) {
if (m->input & INPUT_A_PRESSED) {
m->vel[1] = 52.0f;
m->faceAngle[1] += 0x8000;
return set_mario_action(m, ACT_WALL_KICK_AIR, 0);
}
} else if (m->forwardVel >= 38.0f) {
m->wallKickTimer = 5;
…
return set_mario_action(m, ACT_BACKWARD_AIR_KB, 0);
…
if (m->forwardVel > 8.0f) {
…sm64: a decompilation of Super Mario 64 (n64decomp/sm64) · src/game/mario_actions_airborne.c#L1147-L1151s32 check_wall_kick(struct MarioState *m) {
if ((m->input & INPUT_A_PRESSED) && m->wallKickTimer != 0 && m->prevAction == ACT_AIR_HIT_WALL) {
m->faceAngle[1] += 0x8000;
return set_mario_action(m, ACT_WALL_KICK_AIR, 0);sm64: a decompilation of Super Mario 64 (n64decomp/sm64) · src/game/mario.c#L1407-L1409if (m->wallKickTimer > 0) {
m->wallKickTimer--;sm64: a decompilation of Super Mario 64 (n64decomp/sm64) · src/game/mario.c#L828-L833case ACT_WALL_KICK_AIR:
case ACT_TOP_OF_POLE_JUMP:
set_mario_y_vel_based_on_fspeed(m, 62.0f, 0.0f);
if (m->forwardVel < 24.0f) {
m->forwardVel = 24.0f;Checked by claude, 2026-10-22 — read jumpingBasic's wall case, stayWall whole, startJumpWall, the WALL_JUMP take-off, changePlayerStatus, and the TDeParams default; worked the timer through by hand; SM64's act_air_hit_wall and the kick take-off read at the cited lines; playerRefrection and what the wall flags mark aren't tracedjumpProcess moves a quarter of the slide speed each update, so the slide covers a quarter of the numbers given (sms/params). Super Mario 64 sets the kick's forward speed to at least 24; Sunshine sets it to 24 whatever it was. stayWall also nudges Mario into the wall by its normal each update, and checks checkBackTrig, which can start MARIO_STATUS_HIP_DROP or MARIO_STATUS_JUMP_CATCH, before the slide.
Cited by: Super Mario Sunshine, Wall jump
In Super Mario Sunshine, by the decompilers' Player code, which doesn't yet match, FLUDD's hover nozzle holds Mario up through the status the code calls MARIO_STATUS_ROCKET. rocketCheck, which the jumps, the wall kick, standing, and running call, enters it, unless Mario is already in it or in MARIO_STATUS_ROCKET_LANDING, when he has FLUDD, the current nozzle's mRocketType parameter is 1, his upper body is in UPPER_STATE_PUMPING, and the nozzle is spraying (canSpray, a name a decompilers' comment calls fabricated), and sets a target height mHoverHeight (default 160) above him; standing or running, the callers set it above the floor instead. The status's entry code has a voice for the hover, rocket, and turbo nozzles, and the height-holding code in rocketing runs only for the hover. Each update rocketing sets his vertical speed to the gap to the target times the parameter mAccelRate (default 0.03) and multiplies his forward speed by mBrake (default 0.95), the stick adding forward speed or turning him, and then jumpProcess moves him a quarter of his velocity: with the defaults he closes 0.75% of the gap each update (computed), and any rise or fall he carried in is dropped at once. The hover is a trigger nozzle (TNozzleTrigger). While Mario pumps, and in water only with a full tank, each update adds 150 times R's analog reading to mInsidePressure, and every update takes away mInsidePressureDec (default 100); when the pressure passes mInsidePressureMax (default 4500) while the spray is idle and the nozzle's mRumbleOnCharge is false, the spray starts with a timer of mTriggerTime updates (with mRumbleOnCharge true, an A press with R held starts it instead). An empty tank sets the spray back to idle; the timer running out or the pumping stopping sets it to the state the code calls SPRAY_STATE_DEAD, which returns to idle only once R reads 0. Without a spray, rocketing ends in MARIO_STATUS_ROCKET_LANDING. On each update it sprays, each of the nozzle's emitters asks the water manager for drops, between mNumMin and mNum by the pressure, and the tank, which holds mAmountMax (default 2100), loses mDecRate for each drop accepted. Which nozzles have mRocketType 1, the timer, and the tank are data in each nozzle's file, NozzleTrgHover.prm for the hover. Banjo-Kazooie's Feathery Flap, a lift of 280 units/s and a fall capped at −399.9 units/s for up to 2.5 s, slows a fall where the hover holds a height (banjo-kazooie/feathery-flap). sms/hover
About: Super Mario Sunshine Flight
Value: 160 units above the start
Code notesnon-matching codesms: a decompilation of Super Mario Sunshine (doldecomp/sms) ·configure.py#L947-L964Object(NonMatching, "Player/MarioJump.cpp"),
…
PCHObject(NonMatching, "Player/MarioMove.cpp"),
Object(NonMatching, "Player/MarioPhysics.cpp"),
…
PCHObject(NonMatching, "Player/MarioRun.cpp"),
…
Object(NonMatching, "Player/MarioWait.cpp"),
…
PCHObject(NonMatching, "Player/WaterGun.cpp"),
…
PCHObject(NonMatching, "Player/MarioInit.cpp"),sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioJump.cpp#L880-L904BOOL TMario::rocketCheck()
…
if (mStatus == MARIO_STATUS_ROCKET)
bVar2 = false;
if (mStatus == MARIO_STATUS_ROCKET_LANDING)
bVar2 = false;
…
if (checkFlag(MARIO_FLAG_HAS_FLUDD)) {
if (mWaterGun->getCurrentNozzle()->mRocketType.get() != 1)
bVar2 = false;
…
if (!isUpperState(UPPER_STATE_PUMPING))
…sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioWait.cpp#L118-L121if (rocketCheck()) {
unk314
= mFloorPosition.y + mWaterGun->mWatergunParams.mHoverHeight.get();
return changePlayerStatus(MARIO_STATUS_ROCKET, 0, false);sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioRun.cpp#L697-L700if (rocketCheck()) {
unk314
= mFloorPosition.y + mWaterGun->mWatergunParams.mHoverHeight.get();
return changePlayerStatus(MARIO_STATUS_ROCKET, 0, false);sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioJump.cpp#L451if (rocketCheck())sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · include/Player/WaterGun.hpp#L19, PARAM_INIT(mHoverHeight, 160.0f)sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · include/Player/WaterGun.hpp#L238-L250// TODO: get rid of this -- it's real name is isEmitting() and it
// wasn't stripped in MarioRun.cpp
// //Fabricated
bool canSpray() const
{
if (mCurrentWater == 0)
return false;
…
if (triggerNozzle->getSprayState()
== TNozzleTrigger::SPRAY_STATE_ACTIVE)
return true;sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioMove.cpp#L573-L583case MARIO_STATUS_ROCKET: {
…
if ((int)mWaterGun->mCurrentNozzle == TWaterGun::Rocket) {
…
if ((int)mWaterGun->mCurrentNozzle == TWaterGun::Turbo)
…
if ((int)mWaterGun->mCurrentNozzle == TWaterGun::Hover)
startVoice(MSD_SE_MV21_JUMP_SMALL_01);
setPlayerJumpSpeed(0.0f, 10.0f);sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioJump.cpp#L909-L918BOOL TMario::rocketing()
{
if (!checkFlag(MARIO_FLAG_HAS_FLUDD))
return changePlayerStatus(MARIO_STATUS_ROCKET_LANDING, 0, 0);
…
if (mWaterGun->getCurrentNozzle()->mRocketType.get() != 1)
return changePlayerStatus(MARIO_STATUS_ROCKET_LANDING, 0, 0);
…
if (!isUpperState(UPPER_STATE_PUMPING) || !mWaterGun->canSpray())
return changePlayerStatus(MARIO_STATUS_ROCKET_LANDING, 0, 0);sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioJump.cpp#L920-L959if (mInput & 1) {
switch (mWaterGun->mCurrentNozzle) {
case TWaterGun::Hover:
…
mForwardVel += mag * JMASCos(angleDiff)
* mDivingParams.mAccelControl.get();
…
s16 rotSp = mHoverParams.mRotSp.get();
mFaceAngle.y
= mIntendedYaw
- IConverge((s16)(mIntendedYaw - mFaceAngle.y), 0,
rotSp, rotSp);sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioJump.cpp#L971-L978switch (mWaterGun->getCurrentNozzleType()) {
case TWaterGun::Hover:
mVel.y = (unk314 - mPosition.y) * mHoverParams.mAccelRate.get();
mForwardVel *= mHoverParams.mBrake.get();
break;
}
…
switch (jumpProcess(2)) {sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioPhysics.cpp#L500next.y = mPosition.y + 0.25f * mVel.y;sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioInit.cpp#L45, mHoverParams("/Mario/HHover.prm")sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioInit.cpp#L916-L922TMario::THHoverParams::THHoverParams(const char* prm)
: TParams(prm)
, PARAM_INIT(mRotSp, 0x80)
, PARAM_INIT(mAccelRate, 0.029999999f)
, PARAM_INIT(mBrake, 0.94999999f)
{
TParams::load(mPrmPath);sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioMove.cpp#L2375-L2387stateMachine();
…
gunExec();sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioMove.cpp#L2300mWaterGun->triggerPressureMovement(*unk108);sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/MarioMove.cpp#L2316-L2317} else if (mUpperState == UPPER_STATE_PUMPING) {
mWaterGun->emit();sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/WaterGun.cpp#L1148, mNozzleHover("hover_wg", "/Mario/WaterGun/NozzleTrgHover.prm", this)sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/WaterGun.cpp#L1163mNozzleList[Hover] = &mNozzleHover;sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/WaterGun.cpp#L197, PARAM_INIT(mAmountMax, 0x834)sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/WaterGun.cpp#L222-L224, PARAM_INIT(mInsidePressureDec, 100.0f)
, PARAM_INIT(mInsidePressureMax, 4500.0f)
, PARAM_INIT(mTriggerTime, 1)sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/WaterGun.cpp#L508-L527void TNozzleTrigger::movement(const TMarioControllerWork& controllerWork)
{
if (mFludd->getCurrentWater() <= 0) {
mSprayState = TNozzleTrigger::SPRAY_STATE_INACTIVE;
…
if (mSprayState == TNozzleTrigger::SPRAY_STATE_ACTIVE) {
mSprayTimer -= 1;
…
if (!isPumping || mSprayTimer <= 0) {
mSprayState = TNozzleTrigger::SPRAY_STATE_DEAD;sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/WaterGun.cpp#L529-L540if ((mRumbleOnCharge == true
&& (controllerWork.mFrameInput & TMarioControllerWork::A) != 0
&& (controllerWork.mInput & TMarioControllerWork::R) != 0)
&& mSprayState == TNozzleTrigger::SPRAY_STATE_INACTIVE) {
mSprayState = TNozzleTrigger::SPRAY_STATE_ACTIVE;
…
mSprayTimer = mTriggerTime.get();sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/WaterGun.cpp#L545-L553if (!mFludd->getMario()->isUpperState(TMario::UPPER_STATE_PUMPING))
canSpray = false;
…
if (mFludd->getMario()->checkFlag(MARIO_FLAG_IN_ANY_WATER) == true
&& mFludd->getCurrentWater() < mAmountMax.get())
canSpray = false;
…
if (canSpray == true) {
mInsidePressure += 150.0f * controllerWork.mAnalogR;sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/WaterGun.cpp#L570-L580mInsidePressure -= mInsidePressureDec.get();
…
if (mInsidePressure > mInsidePressureMax.get()) {
mInsidePressure = mInsidePressureMax.get();
if (!mRumbleOnCharge
&& mSprayState == TNozzleTrigger::SPRAY_STATE_INACTIVE) {
mSprayState = TNozzleTrigger::SPRAY_STATE_ACTIVE;
mSprayTimer = mTriggerTime.get();sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/WaterGun.cpp#L595-L598if (mSprayState == TNozzleTrigger::SPRAY_STATE_DEAD) {
mInsidePressure = 0.0f;
if (controllerWork.mAnalogR == 0.0f) {
mSprayState = TNozzleTrigger::SPRAY_STATE_INACTIVE;sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/WaterGun.cpp#L605-L650void TNozzleTrigger::emit(int param_1)
{
if (mFludd->mCurrentWater > 0
&& (u8)mSprayState == TNozzleTrigger::SPRAY_STATE_ACTIVE) {
…
f32 pressure = triggerFill / insidePressureMax;
…
mEmitNum += pressure * (emitNum - emitNumMin) + emitNumMin;
…
u8 emittedWater = gpModelWaterManager->emitRequest(*emitInfo);
…
if (emittedWater != 0) {
…sms: a decompilation of Super Mario Sunshine (doldecomp/sms) · src/Player/WaterGun.cpp#L1779-L1780for (int i = 0; i < nozzleBmdData.getEmitterCount(currentNozzleType); ++i)
currentNozzle->emit(i);banjo-kazooie: a decompilation of Banjo-Kazooie (banjo.decomp/banjo-kazooie) · src/core2/bs/bFlap.c#L13-L15const f32 D_80364A10 = 280.0f;
const f32 D_80364A14 = -1100.0f;
const f32 D_80364A18 = -399.9f;banjo-kazooie: a decompilation of Banjo-Kazooie (banjo.decomp/banjo-kazooie) · src/core2/bs/bFlap.c#L126-L128baphysics_set_vertical_velocity(D_80364A10);
baphysics_set_gravity(D_80364A14);
baphysics_set_terminal_velocity(D_80364A18);banjo-kazooie: a decompilation of Banjo-Kazooie (banjo.decomp/banjo-kazooie) · src/core2/bs/bFlap.c#L180-L181batimer_decrement(0);
if(batimer_isZero(0))banjo-kazooie: a decompilation of Banjo-Kazooie (banjo.decomp/banjo-kazooie) · src/core2/bs/bFlap.c#L33-L37baphysics_set_vertical_velocity(0.0f);
baphysics_set_gravity(D_80364A14);
modelAppendages_setKazooiesUpperHalfVisibility(TRUE);
baflag_set(BA_FLAG_12_HAS_FLAPPED);
batimer_set(0, 2.5f);Checked by claude, 2026-10-22 — read rocketCheck and rocketing whole, the ROCKET entry in setStatusToJumping, the ground callers in MarioWait.cpp and MarioRun.cpp, TNozzleTrigger::movement and emit whole, TWaterGun::emit's emitter loop, canSpray, gunExec's order in playerControl, and the parameter defaults; Banjo's bFlap.c read at the cited lines; the upper-body state machine (what makes UPPER_STATE_PUMPING) and the water manager's emitRequest aren't tracedrocketing writes the vertical speed just before jumpProcess, so the gravity fallProcess subtracts afterward and any water reaction gunExec adds later in the update are overwritten on the next update; for the hover only the height gap moves Mario. The status's 10 units of take-off speed from setStatusToJumping are overwritten the same way. The rocket and turbo nozzles reach the same status when their files set mRocketType to 1, but rocketing sets no vertical speed for them. mRumbleOnCharge, which lets an A press start a trigger spray, is set only for the Yoshi nozzle's bomb.
Cited by: Flight, Super Mario Sunshine