### Description <!-- What is the purpose of this PR and what it adds? --> ### Will this Pull Request break anything? <!-- Will it break the compiling? --> ### Suggested Testing Steps <!-- See if the compiling fails/break anything in the game. -->
7264 lines
222 KiB
C
7264 lines
222 KiB
C
// Samus
|
|
|
|
#include "ida_types.h"
|
|
#include "variables.h"
|
|
#include "sm_rtl.h"
|
|
#include "funcs.h"
|
|
|
|
#define kSamusFramesForUnderwaterSfx ((uint8*)RomFixedPtr(0x90a514))
|
|
#define kPauseMenuMapData ((uint16*)RomFixedPtr(0x829717))
|
|
#define kPauseMenuMapTilemaps ((LongPtr*)RomFixedPtr(0x82964a))
|
|
#define kBeamTilePtrs ((uint16*)RomFixedPtr(0x90c3b1))
|
|
#define kBeamPalettePtrs ((uint16*)RomFixedPtr(0x90c3c9))
|
|
#define off_90B5BB ((uint16*)RomFixedPtr(0x90b5bb))
|
|
#define off_90B609 ((uint16*)RomFixedPtr(0x90b609))
|
|
#define kFlareAnimDelays ((uint16*)RomFixedPtr(0x90c481))
|
|
|
|
static Pair_Bool_Amt Samus_CalcBaseSpeed_NoDecel_X(uint16 k);
|
|
|
|
static const uint16 kUnchargedProjectile_Sfx[12] = { 0xb, 0xd, 0xc, 0xe, 0xf, 0x12, 0x10, 0x11, 0x13, 0x16, 0x14, 0x15 };
|
|
static const uint16 kChargedProjectile_Sfx[12] = { 0x17, 0x19, 0x18, 0x1a, 0x1b, 0x1e, 0x1c, 0x1d, 0x1f, 0x22, 0x20, 0x21 };
|
|
static const uint16 kNonBeamProjectile_Sfx[9] = { 0, 3, 4, 0, 0, 0, 0, 0, 0 };
|
|
static const uint8 kProjectileCooldown_Uncharged[38] = {
|
|
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 12, 15, 0, 0, 0, 0,
|
|
30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0,
|
|
};
|
|
static const uint8 kNonBeamProjectileCooldowns[9] = { 0, 0xa, 0x14, 0x28, 0, 0x10, 0, 0, 0 };
|
|
static const uint8 kBeamAutoFireCooldowns[12] = { 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19 };
|
|
|
|
static void Samus_HandleAnimDelay(void);
|
|
|
|
void nullsub_12(void) {}
|
|
|
|
static Func_V *const kSamusFxHandlers[8] = {
|
|
Samus_Animate_NoFx,
|
|
Samus_Animate_LavaFx,
|
|
Samus_Animate_AcidFx,
|
|
Samus_Animate_WaterFx,
|
|
nullsub_12,
|
|
nullsub_12,
|
|
nullsub_12,
|
|
nullsub_12,
|
|
};
|
|
|
|
void Samus_Animate(void) { // 0x908000
|
|
kSamusFxHandlers[(fx_type & 0xF) >> 1]();
|
|
if (samus_pose == kPose_4D_FaceR_Jump_NoAim_NoMove_NoGun || samus_pose == kPose_4E_FaceL_Jump_NoAim_NoMove_NoGun) {
|
|
if (samus_y_dir != 2 && samus_anim_frame == 1 && samus_anim_frame_timer == 1)
|
|
samus_anim_frame_timer = 4;
|
|
bool v1 = (--samus_anim_frame_timer & 0x8000) != 0;
|
|
if (!samus_anim_frame_timer || v1) {
|
|
++samus_anim_frame;
|
|
Samus_HandleAnimDelay();
|
|
}
|
|
} else {
|
|
bool v0 = (--samus_anim_frame_timer & 0x8000) != 0;
|
|
if (!samus_anim_frame_timer || v0) {
|
|
++samus_anim_frame;
|
|
Samus_HandleAnimDelay();
|
|
}
|
|
}
|
|
}
|
|
|
|
void Samus_Animate_NoFx(void) { // 0x908078
|
|
uint16 r18 = Samus_GetBottom_R18();
|
|
samus_anim_frame_buffer = samus_x_speed_divisor;
|
|
if (liquid_physics_type) {
|
|
if ((liquid_physics_type & 1) != 0) {
|
|
liquid_physics_type = 0;
|
|
QueueSfx2_Max6(0xE);
|
|
if ((samus_suit_palette_index & 4) == 0 && (samus_movement_type == 3 || samus_movement_type == 20))
|
|
QueueSfx1_Max6(0x30);
|
|
Samus_SpawnWaterSplash(r18);
|
|
} else {
|
|
liquid_physics_type = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Samus_Animate_WaterFx(void) { // 0x9080B8
|
|
static const uint16 kSamusPhys_AnimDelayInWater = 3;
|
|
uint16 r18 = Samus_GetBottom_R18();
|
|
if ((fx_y_pos & 0x8000) == 0 && sign16(fx_y_pos - r18) && (fx_liquid_options & 4) == 0) {
|
|
samus_anim_frame_buffer = kSamusPhys_AnimDelayInWater;
|
|
if (liquid_physics_type == kLiquidPhysicsType_Water) {
|
|
Samus_SpawnAirBubbles();
|
|
} else {
|
|
liquid_physics_type = kLiquidPhysicsType_Water;
|
|
QueueSfx2_Max6(0xD);
|
|
Samus_SpawnWaterSplash(r18);
|
|
}
|
|
} else {
|
|
Samus_Animate_NoFx();
|
|
}
|
|
}
|
|
|
|
void Samus_SpawnWaterSplash(uint16 r18) { // 0x9080E6
|
|
static const uint8 kWaterSplashTypeTable[28] = {
|
|
1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
|
|
};
|
|
if (kWaterSplashTypeTable[samus_movement_type]) {
|
|
atmospheric_gfx_frame_and_type[0] = 256;
|
|
atmospheric_gfx_frame_and_type[1] = 256;
|
|
atmospheric_gfx_anim_timer[0] = 3;
|
|
atmospheric_gfx_anim_timer[1] = 3;
|
|
atmospheric_gfx_x_pos[0] = samus_x_pos + 4;
|
|
atmospheric_gfx_x_pos[1] = samus_x_pos - 3;
|
|
atmospheric_gfx_y_pos[0] = r18 - 4;
|
|
atmospheric_gfx_y_pos[1] = r18 - 4;
|
|
} else {
|
|
atmospheric_gfx_frame_and_type[0] = 768;
|
|
atmospheric_gfx_anim_timer[0] = 2;
|
|
atmospheric_gfx_x_pos[0] = samus_x_pos;
|
|
atmospheric_gfx_y_pos[0] = fx_y_pos;
|
|
}
|
|
Samus_SpawnAirBubbles();
|
|
}
|
|
|
|
void Samus_SpawnAirBubbles() { // 0x90813E
|
|
uint16 r20 = Samus_GetTop_R20();
|
|
if ((int16)(r20 - 24 - fx_y_pos) >= 0 && (nmi_frame_counter_word & 0x7F) == 0
|
|
&& !atmospheric_gfx_frame_and_type[2]) {
|
|
atmospheric_gfx_frame_and_type[2] = 1280;
|
|
atmospheric_gfx_anim_timer[2] = 3;
|
|
atmospheric_gfx_x_pos[2] = samus_x_pos;
|
|
atmospheric_gfx_y_pos[2] = samus_y_pos - samus_y_radius + 6;
|
|
QueueSfx2_Max6((NextRandom() & 1) ? 15 : 17);
|
|
}
|
|
if (samus_pose == kPose_00_FaceF_Powersuit || samus_pose == kPose_9B_FaceF_VariaGravitySuit
|
|
|| (equipped_items & 0x20) != 0) {
|
|
samus_anim_frame_buffer = 0;
|
|
}
|
|
}
|
|
|
|
void Samus_Animate_LavaFx(void) { // 0x9081C0
|
|
static const uint16 kSamusPhys_LavaDamagePerFrame = 0;
|
|
static const uint16 kSamusPhys_LavaSubdamagePerFrame = 0x8000;
|
|
|
|
uint16 r18 = Samus_GetBottom_R18();
|
|
if ((lava_acid_y_pos & 0x8000) == 0 && sign16(lava_acid_y_pos - r18)) {
|
|
if (speed_boost_counter) {
|
|
Samus_CancelSpeedBoost();
|
|
samus_x_extra_run_speed = 0;
|
|
samus_x_extra_run_subspeed = 0;
|
|
}
|
|
if ((equipped_items & 0x20) != 0) {
|
|
samus_anim_frame_buffer = 0;
|
|
liquid_physics_type = 2;
|
|
} else {
|
|
if ((game_time_frames & 7) == 0 && !sign16(samus_health - 71))
|
|
QueueSfx3_Max3(0x2D);
|
|
uint16 v0 = (__PAIR32__(kSamusPhys_LavaDamagePerFrame, kSamusPhys_LavaSubdamagePerFrame)
|
|
+ __PAIR32__(samus_periodic_damage, samus_periodic_subdamage)) >> 16;
|
|
samus_periodic_subdamage += kSamusPhys_LavaSubdamagePerFrame;
|
|
samus_periodic_damage = v0;
|
|
Samus_Animate_SubmergedLavaAcid();
|
|
}
|
|
} else {
|
|
Samus_Animate_NoFx();
|
|
}
|
|
}
|
|
|
|
void Samus_Animate_AcidFx(void) { // 0x908219
|
|
static const uint16 kSamusPhys_AcidSubdamagePerFrame = 0x8000;
|
|
static const uint16 kSamusPhys_AcidDamagePerFrame = 1;
|
|
uint16 r18 = Samus_GetBottom_R18();
|
|
|
|
if ((lava_acid_y_pos & 0x8000) == 0 && sign16(lava_acid_y_pos - r18)) {
|
|
if ((game_time_frames & 7) == 0 && !sign16(samus_health - 71))
|
|
QueueSfx3_Max3(0x2D);
|
|
uint16 v0 = (__PAIR32__(kSamusPhys_AcidDamagePerFrame, kSamusPhys_AcidSubdamagePerFrame)
|
|
+ __PAIR32__(samus_periodic_damage, samus_periodic_subdamage)) >> 16;
|
|
samus_periodic_subdamage += kSamusPhys_AcidSubdamagePerFrame;
|
|
samus_periodic_damage = v0;
|
|
Samus_Animate_SubmergedLavaAcid();
|
|
} else {
|
|
Samus_Animate_NoFx();
|
|
}
|
|
}
|
|
|
|
void Samus_Animate_SubmergedLavaAcid(void) { // 0x90824C
|
|
static const uint16 kSamusPhys_AnimDelayInAcid = 2;
|
|
uint16 r20 = Samus_GetTop_R20();
|
|
samus_anim_frame_buffer = kSamusPhys_AnimDelayInAcid;
|
|
liquid_physics_type = 2;
|
|
if ((int16)(r20 - lava_acid_y_pos) < 0 && (atmospheric_gfx_frame_and_type[0] & 0x400) == 0) {
|
|
atmospheric_gfx_frame_and_type[0] = 1024;
|
|
atmospheric_gfx_frame_and_type[1] = 1024;
|
|
atmospheric_gfx_frame_and_type[2] = 1024;
|
|
atmospheric_gfx_frame_and_type[3] = 1024;
|
|
atmospheric_gfx_anim_timer[0] = 3;
|
|
atmospheric_gfx_anim_timer[3] = 3;
|
|
atmospheric_gfx_anim_timer[1] = -32766;
|
|
atmospheric_gfx_anim_timer[2] = -32766;
|
|
atmospheric_gfx_y_pos[0] = lava_acid_y_pos;
|
|
atmospheric_gfx_y_pos[1] = lava_acid_y_pos;
|
|
atmospheric_gfx_y_pos[2] = lava_acid_y_pos;
|
|
atmospheric_gfx_y_pos[3] = lava_acid_y_pos;
|
|
atmospheric_gfx_x_pos[0] = samus_x_pos + 6;
|
|
atmospheric_gfx_x_pos[1] = samus_x_pos;
|
|
*(uint32 *)&atmospheric_gfx_x_pos[2] = __PAIR32__(samus_x_pos - (samus_x_pos >= 0xFFFA), samus_x_pos)
|
|
- ((int)(samus_x_pos >= 0xFFFA) | 0x60000);
|
|
if ((game_time_frames & 1) == 0)
|
|
QueueSfx2_Max6(0x10);
|
|
}
|
|
if (samus_pose == kPose_00_FaceF_Powersuit
|
|
|| samus_pose == kPose_9B_FaceF_VariaGravitySuit
|
|
|| (equipped_items & 0x20) != 0) {
|
|
samus_anim_frame_buffer = 0;
|
|
}
|
|
}
|
|
|
|
static uint8 Samus_HandleSpeedBoosterAnimDelay(const uint8 *jp);
|
|
|
|
|
|
typedef bool Func_AnimDelay(const uint8 *jp);
|
|
|
|
static bool Samus_AnimDelayFunc_0to5(const uint8 *jp) { // 0x908344
|
|
return false;
|
|
}
|
|
|
|
static bool Samus_AnimDelayFunc_6_GotoStartIfLittleHealth(const uint8 *jp) { // 0x908346
|
|
samus_anim_frame = sign16(samus_health - 30) ? samus_anim_frame + 1 : 0;
|
|
return true;
|
|
}
|
|
|
|
static bool Samus_AnimDelayFunc_7(const uint8 *jp) { // 0x908360
|
|
samus_movement_handler = FUNC16(Samus_HandleMovement_DrainedCrouching);
|
|
samus_anim_frame++;
|
|
return true;
|
|
}
|
|
|
|
static bool Samus_AnimDelayFunc_13_TransToPose(const uint8 *jp) { // 0x9084B6
|
|
samus_new_pose_transitional = jp[1];
|
|
samus_hurt_switch_index = 3;
|
|
return false;
|
|
}
|
|
|
|
static bool Samus_AnimDelayFunc_8_AutoJumpHack(const uint8 *jp) { // 0x908370
|
|
if (samus_input_handler == FUNC16(Samus_InputHandler_E91D))
|
|
return Samus_AnimDelayFunc_13_TransToPose(jp);
|
|
if (samus_new_pose != kPose_4B_FaceR_Jumptrans
|
|
&& samus_new_pose != kPose_4C_FaceL_Jumptrans
|
|
&& samus_new_pose != kPose_19_FaceR_SpinJump
|
|
&& samus_new_pose != kPose_1A_FaceL_SpinJump) {
|
|
samus_input_handler = FUNC16(HandleAutoJumpHack);
|
|
return Samus_AnimDelayFunc_13_TransToPose(jp);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static bool Samus_AnimDelayFunc_9_TransToPose(const uint8 *jp) { // 0x90839A
|
|
if ((GET_WORD(jp + 1) & equipped_items) != 0) {
|
|
if (samus_y_speed || samus_y_subspeed)
|
|
samus_new_pose_transitional = jp[6];
|
|
else
|
|
samus_new_pose_transitional = jp[5];
|
|
} else if (samus_y_speed || samus_y_subspeed) {
|
|
samus_new_pose_transitional = jp[4];
|
|
} else {
|
|
samus_new_pose_transitional = jp[3];
|
|
}
|
|
samus_hurt_switch_index = 3;
|
|
return false;
|
|
}
|
|
|
|
static bool UNUSED_Samus_AnimDelayFunc_10(const uint8 *jp) { // 0x9083F6
|
|
if (samus_y_speed || samus_y_subspeed)
|
|
samus_new_pose_transitional = jp[2];
|
|
else
|
|
samus_new_pose_transitional = jp[1];
|
|
samus_hurt_switch_index = 3;
|
|
return false;
|
|
}
|
|
|
|
static bool Samus_AnimDelayFunc_11_SelectDelaySequenceWalljump(const uint8 *jp) { // 0x90841D
|
|
if ((equipped_items & 0x20) == 0) {
|
|
uint16 r20 = Samus_GetTop_R20();
|
|
if ((fx_y_pos & 0x8000) != 0) {
|
|
if ((lava_acid_y_pos & 0x8000) == 0 && sign16(lava_acid_y_pos - r20))
|
|
goto LABEL_10;
|
|
} else if (sign16(fx_y_pos - r20) && (fx_liquid_options & 4) == 0) {
|
|
goto LABEL_10;
|
|
}
|
|
}
|
|
if ((equipped_items & 8) != 0) {
|
|
QueueSfx1_Max6(0x33);
|
|
samus_anim_frame += 21;
|
|
} else {
|
|
if ((equipped_items & 0x200) == 0) {
|
|
LABEL_10:
|
|
QueueSfx1_Max6(0x31);
|
|
samus_anim_frame += 1;
|
|
} else {
|
|
QueueSfx1_Max6(0x3E);
|
|
samus_anim_frame += 11;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static bool Samus_AnimDelayFunc_12_TransToPose(const uint8 *jp) { // 0x90848B
|
|
if ((GET_WORD(jp + 1) & equipped_items) != 0)
|
|
samus_new_pose_transitional = jp[4];
|
|
else
|
|
samus_new_pose_transitional = jp[3];
|
|
samus_hurt_switch_index = 3;
|
|
return false;
|
|
}
|
|
|
|
static bool Samus_AnimDelayFunc_14_Goto(const uint8 *jp) { // 0x9084C7
|
|
samus_anim_frame -= jp[1];
|
|
return true;
|
|
}
|
|
|
|
static bool Samus_AnimDelayFunc_15_GotoStart(const uint8 *jp) { // 0x9084DB
|
|
samus_anim_frame = 0;
|
|
return true;
|
|
}
|
|
|
|
static Func_AnimDelay *const kAnimDelayFuncs[16] = { // 0x9082DC
|
|
Samus_AnimDelayFunc_0to5,
|
|
Samus_AnimDelayFunc_0to5,
|
|
Samus_AnimDelayFunc_0to5,
|
|
Samus_AnimDelayFunc_0to5,
|
|
Samus_AnimDelayFunc_0to5,
|
|
Samus_AnimDelayFunc_0to5,
|
|
Samus_AnimDelayFunc_6_GotoStartIfLittleHealth,
|
|
Samus_AnimDelayFunc_7,
|
|
Samus_AnimDelayFunc_8_AutoJumpHack,
|
|
Samus_AnimDelayFunc_9_TransToPose,
|
|
UNUSED_Samus_AnimDelayFunc_10,
|
|
Samus_AnimDelayFunc_11_SelectDelaySequenceWalljump,
|
|
Samus_AnimDelayFunc_12_TransToPose,
|
|
Samus_AnimDelayFunc_13_TransToPose,
|
|
Samus_AnimDelayFunc_14_Goto,
|
|
Samus_AnimDelayFunc_15_GotoStart,
|
|
};
|
|
|
|
|
|
#define kDefaultAnimFramePtr ((uint16 *)RomFixedPtr(0x91B5D1))
|
|
|
|
static uint8 Samus_HandleSpeedBoosterAnimDelay(const uint8 *jp) { // 0x90852C
|
|
if (!samus_has_momentum_flag || (button_config_run_b & joypad1_lastkeys) == 0 || samus_movement_type != 1)
|
|
return jp[0];
|
|
if ((equipped_items & 0x2000) == 0) {
|
|
samus_anim_frame = 0;
|
|
samus_anim_frame_timer = samus_anim_frame_buffer + RomPtr_91(*kDefaultAnimFramePtr)[0];
|
|
return 0;
|
|
}
|
|
if ((uint8)--speed_boost_counter)
|
|
return jp[0];
|
|
uint16 v2 = speed_boost_counter;
|
|
if ((speed_boost_counter & 0x400) == 0) {
|
|
v2 = speed_boost_counter + 256;
|
|
speed_boost_counter = v2;
|
|
if ((v2 & 0x400) != 0) {
|
|
// The original code forgets to preserve A here.
|
|
samus_echoes_sound_flag = 1;
|
|
QueueSfx3_Max6(3);
|
|
//v2 = 0x103; // bug!
|
|
}
|
|
}
|
|
int v3 = HIBYTE(v2);
|
|
speed_boost_counter = kSpeedBoostToCtr[v3] | speed_boost_counter & 0xFF00;
|
|
samus_anim_frame = 0;
|
|
samus_anim_frame_timer = samus_anim_frame_buffer + RomPtr_91(kSpeedBoostToAnimFramePtr[v3])[0];
|
|
return 0;
|
|
}
|
|
|
|
static void Samus_HandleAnimDelay(void) {
|
|
const uint8 *p = RomPtr_91(kSamusAnimationDelayData[samus_pose]);
|
|
if ((p[samus_anim_frame] & 0x80) != 0) {
|
|
uint8 v1 = Samus_HandleSpeedBoosterAnimDelay(p + samus_anim_frame);
|
|
if (kAnimDelayFuncs[v1 & 0xF](p + samus_anim_frame))
|
|
samus_anim_frame_timer = samus_anim_frame_buffer + p[samus_anim_frame];
|
|
} else {
|
|
if (samus_has_momentum_flag && samus_movement_type == 1) {
|
|
uint16 addr = ((equipped_items & 0x2000) != 0) ? kSpeedBoostToAnimFramePtr[HIBYTE(speed_boost_counter)] : *kDefaultAnimFramePtr;
|
|
p = RomPtr_91(addr);
|
|
}
|
|
samus_anim_frame_timer = samus_anim_frame_buffer + p[samus_anim_frame];
|
|
}
|
|
}
|
|
|
|
static Func_U8 *const kSamusIsBottomDrawnFuncs[28] = { // 0x9085E2
|
|
SamusBottomDrawn_0_Standing,
|
|
SamusBottomDrawn_1,
|
|
SamusBottomDrawn_1,
|
|
SamusBottomDrawn_3_SpinJump,
|
|
SamusBottomDrawn_4,
|
|
SamusBottomDrawn_1,
|
|
SamusBottomDrawn_1,
|
|
SamusBottomDrawn_4,
|
|
SamusBottomDrawn_4,
|
|
SamusBottomDrawn_4,
|
|
SamusBottomDrawn_A_Knockback,
|
|
SamusBottomDrawn_1,
|
|
SamusBottomDrawn_1,
|
|
UNUSED_SamusBottomDrawn_D,
|
|
SamusBottomDrawn_1,
|
|
SamusBottomDrawn_F_Transitions,
|
|
SamusBottomDrawn_1,
|
|
SamusBottomDrawn_4,
|
|
SamusBottomDrawn_4,
|
|
SamusBottomDrawn_4,
|
|
SamusBottomDrawn_14_WallJump,
|
|
SamusBottomDrawn_1,
|
|
SamusBottomDrawn_1,
|
|
SamusBottomDrawn_1,
|
|
SamusBottomDrawn_1,
|
|
SamusBottomDrawn_19_DamageBoost,
|
|
SamusBottomDrawn_1,
|
|
SamusBottomDrawn_1B,
|
|
};
|
|
|
|
void Samus_Draw(void) {
|
|
PairU16 v0;
|
|
|
|
if (samus_knockback_timer || !samus_invincibility_timer || samus_shine_timer || (nmi_frame_counter_word & 1) == 0) {
|
|
uint16 v2 = 2 * samus_pose;
|
|
samus_top_half_spritemap_index = samus_anim_frame
|
|
+ kSamusPoseToBaseSpritemapIndexTop[samus_pose];
|
|
uint16 a = samus_top_half_spritemap_index;
|
|
v0 = Samus_CalcSpritemapPos(2 * samus_pose);
|
|
DrawSamusSpritemap(a, v0.k, v0.j);
|
|
uint16 R36 = v2;
|
|
if (kSamusIsBottomDrawnFuncs[samus_movement_type]() & 1) {
|
|
samus_bottom_half_spritemap_index = samus_anim_frame + kSamusPoseToBaseSpritemapIndexBottom[R36 >> 1];
|
|
DrawSamusSpritemap(samus_bottom_half_spritemap_index, samus_spritemap_x_pos, samus_spritemap_y_pos);
|
|
}
|
|
}
|
|
SetSamusTilesDefsForCurAnim();
|
|
}
|
|
|
|
uint8 SamusBottomDrawn_1(void) { // 0x908686
|
|
return 1;
|
|
}
|
|
|
|
uint8 SamusBottomDrawn_4(void) { // 0x908688
|
|
samus_bottom_half_spritemap_index = 0;
|
|
return 0;
|
|
}
|
|
|
|
uint8 SamusBottomDrawn_0_Standing(void) { // 0x90868D
|
|
OamEnt *v1;
|
|
|
|
if (samus_pose == kPose_00_FaceF_Powersuit) {
|
|
uint16 v0 = oam_next_ptr;
|
|
v1 = gOamEnt(oam_next_ptr);
|
|
*(uint16 *)&v1->xcoord = samus_x_pos - 7 - layer1_x_pos;
|
|
*(uint16 *)&v1->ycoord = samus_y_pos - 17 - layer1_y_pos;
|
|
*(uint16 *)&v1->charnum = 14369;
|
|
oam_next_ptr = v0 + 4;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
uint8 SamusBottomDrawn_3_SpinJump(void) { // 0x9086C6
|
|
if (samus_pose == kPose_81_FaceR_Screwattack
|
|
|| samus_pose == kPose_82_FaceL_Screwattack
|
|
|| samus_pose == kPose_1B_FaceR_SpaceJump
|
|
|| samus_pose == kPose_1C_FaceL_SpaceJump
|
|
|| !samus_anim_frame
|
|
|| !sign16(samus_anim_frame - kPose_0B_MoveR_Gun)) {
|
|
return 1;
|
|
}
|
|
samus_bottom_half_spritemap_index = 0;
|
|
return 0;
|
|
}
|
|
|
|
uint8 SamusBottomDrawn_A_Knockback(void) { // 0x9086EE
|
|
if (samus_pose != kPose_D7_FaceR_CrystalFlashEnd && samus_pose != kPose_D8_FaceL_CrystalFlashEnd
|
|
|| !sign16(samus_anim_frame - 3)) {
|
|
return 1;
|
|
}
|
|
samus_bottom_half_spritemap_index = 0;
|
|
return 0;
|
|
}
|
|
|
|
uint8 SamusBottomDrawn_F_Transitions(void) { // 0x90870C
|
|
if (!sign16(samus_pose - kPose_F1_FaceR_CrouchTrans_AimU))
|
|
return 1;
|
|
if (!sign16(samus_pose - 219)) {
|
|
if (sign16(samus_pose - 221)) {
|
|
if (samus_anim_frame)
|
|
goto LABEL_8;
|
|
} else if (samus_anim_frame != 2) {
|
|
goto LABEL_8;
|
|
}
|
|
return 1;
|
|
}
|
|
if (samus_pose == kPose_35_FaceR_CrouchTrans
|
|
|| samus_pose == kPose_36_FaceL_CrouchTrans
|
|
|| samus_pose == kPose_3B_FaceR_StandTrans
|
|
|| samus_pose == kPose_3C_FaceL_StandTrans) {
|
|
return 1;
|
|
}
|
|
LABEL_8:
|
|
samus_bottom_half_spritemap_index = 0;
|
|
return 0;
|
|
}
|
|
|
|
uint8 UNUSED_SamusBottomDrawn_D(void) { // 0x90874C
|
|
if (samus_pose != (kPose_44_FaceL_Turn_Crouch | kPose_01_FaceR_Normal | 0x20)
|
|
&& samus_pose != (kPose_44_FaceL_Turn_Crouch | kPose_02_FaceL_Normal | 0x20)
|
|
|| sign16(samus_anim_frame - 1)) {
|
|
return 1;
|
|
}
|
|
samus_bottom_half_spritemap_index = 0;
|
|
return 0;
|
|
}
|
|
|
|
uint8 SamusBottomDrawn_14_WallJump(void) { // 0x908768
|
|
if (sign16(samus_anim_frame - 3) || !sign16(samus_anim_frame - 13))
|
|
return 1;
|
|
samus_bottom_half_spritemap_index = 0;
|
|
return 0;
|
|
}
|
|
|
|
uint8 SamusBottomDrawn_19_DamageBoost(void) { // 0x90877C
|
|
if (sign16(samus_anim_frame - 2) || !sign16(samus_anim_frame - 9))
|
|
return 1;
|
|
samus_bottom_half_spritemap_index = 0;
|
|
return 0;
|
|
}
|
|
|
|
uint8 SamusBottomDrawn_1B(void) { // 0x908790
|
|
if (sign16(samus_pose - kPose_CF_FaceR_Ranintowall_AimUR)) {
|
|
if (samus_pose != kPose_CB_FaceR_Shinespark_Vert && samus_pose != kPose_CC_FaceL_Shinespark_Vert)
|
|
return 1;
|
|
} else if (samus_pose != kPose_E8_FaceR_Drained_CrouchFalling && samus_pose != kPose_E9_FaceL_Drained_CrouchFalling
|
|
|| !sign16(samus_anim_frame - 2)) {
|
|
return 1;
|
|
}
|
|
samus_bottom_half_spritemap_index = 0;
|
|
return 0;
|
|
}
|
|
|
|
void Samus_DrawEchoes(void) { // 0x9087BD
|
|
if ((speed_echoes_index & 0x8000) == 0) {
|
|
if ((speed_boost_counter & 0xFF00) == 1024) {
|
|
if (speed_echo_xpos[1])
|
|
Samus_DrawEcho(2);
|
|
if (speed_echo_xpos[0])
|
|
Samus_DrawEcho(0);
|
|
}
|
|
return;
|
|
}
|
|
for (int i = 2; i >= 0; i -= 2) {
|
|
int v1 = i >> 1;
|
|
if (!speed_echo_xpos[v1])
|
|
continue;
|
|
uint16 v2 = speed_echo_ypos[v1], v3;
|
|
if (v2 != samus_y_pos) {
|
|
if ((int16)(v2 - samus_y_pos) < 0)
|
|
v3 = v2 + 2;
|
|
else
|
|
v3 = v2 - 2;
|
|
speed_echo_ypos[v1] = v3;
|
|
}
|
|
if ((speed_echo_xspeed[v1] & 0x8000) != 0) {
|
|
uint16 v5 = speed_echo_xspeed[v1] + speed_echo_xpos[v1];
|
|
speed_echo_xpos[v1] = v5;
|
|
if ((int16)(v5 - samus_x_pos) < 0) {
|
|
speed_echo_xpos[v1] = 0;
|
|
continue;
|
|
}
|
|
} else {
|
|
uint16 v4 = speed_echo_xspeed[v1] + speed_echo_xpos[v1];
|
|
speed_echo_xpos[v1] = v4;
|
|
if ((int16)(v4 - samus_x_pos) >= 0) {
|
|
speed_echo_xpos[v1] = 0;
|
|
continue;
|
|
}
|
|
}
|
|
Samus_DrawEcho(i);
|
|
}
|
|
if (!speed_echo_xpos[1] && !speed_echo_xpos[0])
|
|
speed_echoes_index = 0;
|
|
}
|
|
|
|
void Samus_DrawEcho(uint16 j) { // 0x908855
|
|
int v1 = j >> 1;
|
|
int16 v2 = speed_echo_ypos[v1] - kPoseParams[samus_pose].y_offset_to_gfx - layer1_y_pos;
|
|
if (v2 >= 0 && sign16(v2 - 248)) {
|
|
DrawSamusSpritemap(samus_top_half_spritemap_index, speed_echo_xpos[v1] - layer1_x_pos, v2);
|
|
if (samus_bottom_half_spritemap_index)
|
|
DrawSamusSpritemap(samus_bottom_half_spritemap_index, speed_echo_xpos[v1] - layer1_x_pos, v2);
|
|
}
|
|
}
|
|
|
|
void Samus_DrawShinesparkCrashEchoes(uint16 k) { // 0x9088BA
|
|
if ((nmi_frame_counter_word & 1) != 0) {
|
|
uint16 a = samus_anim_frame + kSamusPoseToBaseSpritemapIndexTop[samus_pose];
|
|
int16 v2 = speed_echo_ypos[k >> 1] - kPoseParams[samus_pose].y_offset_to_gfx - layer1_y_pos;
|
|
if (v2 >= 0 && sign16(v2 - 248)) {
|
|
DrawSamusSpritemap(a, speed_echo_xpos[k >> 1] - layer1_x_pos, v2);
|
|
if (kSamusIsBottomDrawnFuncs[samus_movement_type]() & 1) {
|
|
uint16 v5 = samus_anim_frame + kSamusPoseToBaseSpritemapIndexBottom[samus_pose];
|
|
DrawSamusSpritemap(v5, speed_echo_xpos[k >> 1] - layer1_x_pos, v2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Samus_DrawShinesparkCrashEchoProjectiles(void) { // 0x908953
|
|
if ((nmi_frame_counter_word & 1) != 0) {
|
|
if (speed_echo_xspeed[3])
|
|
Samus_DrawEcho(6);
|
|
if (speed_echo_xspeed[2])
|
|
Samus_DrawEcho(4);
|
|
}
|
|
}
|
|
|
|
void Samus_DrawStartingDeathAnim(void) { // 0x908976
|
|
bool v0 = (--samus_anim_frame_timer & 0x8000) != 0;
|
|
if (!samus_anim_frame_timer || v0) {
|
|
++samus_anim_frame;
|
|
Samus_HandleAnimDelay();
|
|
}
|
|
Samus_DrawDuringDeathAnim();
|
|
}
|
|
|
|
void Samus_DrawDuringDeathAnim(void) { // 0x908998
|
|
uint16 v1 = 2 * samus_pose;
|
|
uint16 a = samus_anim_frame + kSamusPoseToBaseSpritemapIndexTop[samus_pose];
|
|
Samus_CalcSpritemapPos(2 * samus_pose);
|
|
DrawSamusSpritemap(a, layer1_x_pos + samus_spritemap_x_pos, layer1_y_pos + samus_spritemap_y_pos);
|
|
uint16 R36 = v1;
|
|
if (kSamusIsBottomDrawnFuncs[samus_movement_type]() & 1)
|
|
DrawSamusSpritemap(
|
|
samus_anim_frame + kSamusPoseToBaseSpritemapIndexBottom[R36 >> 1],
|
|
layer1_x_pos + samus_spritemap_x_pos,
|
|
layer1_y_pos + samus_spritemap_y_pos);
|
|
SetSamusTilesDefsForCurAnim();
|
|
}
|
|
|
|
void Samus_DrawWhenNotAnimatingOrDying(void) { // 0x908A00
|
|
PairU16 v0;
|
|
|
|
uint16 v2 = 2 * samus_pose;
|
|
uint16 a = samus_anim_frame + kSamusPoseToBaseSpritemapIndexTop[samus_pose];
|
|
v0 = Samus_CalcSpritemapPos(2 * samus_pose);
|
|
DrawSamusSpritemap(a, v0.k, v0.j);
|
|
uint16 R36 = v2;
|
|
if (kSamusIsBottomDrawnFuncs[samus_movement_type]() & 1)
|
|
DrawSamusSpritemap(
|
|
samus_anim_frame + kSamusPoseToBaseSpritemapIndexBottom[R36 >> 1],
|
|
samus_spritemap_x_pos,
|
|
samus_spritemap_y_pos);
|
|
SetSamusTilesDefsForCurAnim();
|
|
}
|
|
|
|
static FuncXY_V *const kAtmosphericTypeFuncs[8] = { // 0x908A4C
|
|
0,
|
|
AtmosphericTypeFunc_1_FootstepSplash,
|
|
AtmosphericTypeFunc_1_FootstepSplash,
|
|
AtmosphericTypeFunc_3_DivingSplash,
|
|
AtmosphericTypeFunc_4_LavaSurfaceDmg,
|
|
AtmosphericTypeFunc_5_Bubbles,
|
|
AtmosphericTypeFunc_67_Dust,
|
|
AtmosphericTypeFunc_67_Dust,
|
|
};
|
|
|
|
void HandleAtmosphericEffects(void) {
|
|
int16 v4;
|
|
|
|
for (int i = 6; i >= 0; i -= 2) {
|
|
int v1 = i >> 1;
|
|
uint16 v2 = atmospheric_gfx_frame_and_type[v1];
|
|
if (!v2)
|
|
continue;
|
|
uint16 r18 = 2 * (uint8)v2;
|
|
uint16 v3 = 2 * HIBYTE(v2);
|
|
v4 = atmospheric_gfx_anim_timer[v1] - 1;
|
|
atmospheric_gfx_anim_timer[v1] = v4;
|
|
if (v4) {
|
|
if (v4 < 0) {
|
|
if (v4 != (int16)0x8000)
|
|
continue;
|
|
atmospheric_gfx_anim_timer[v1] = *(uint16 *)RomPtr_90(r18 + kAtmosphericGraphicAnimationTimers[v3 >> 1]);
|
|
}
|
|
} else {
|
|
atmospheric_gfx_anim_timer[v1] = *(uint16 *)RomPtr_90(r18 + kAtmosphericGraphicAnimationTimers[v3 >> 1]);
|
|
uint16 v5 = atmospheric_gfx_frame_and_type[v1] + 1;
|
|
atmospheric_gfx_frame_and_type[v1] = v5;
|
|
if ((int16)((uint8)v5 - kAtmosphericTypeNumFrames[v3 >> 1]) >= 0) {
|
|
atmospheric_gfx_frame_and_type[v1] = 0;
|
|
continue;
|
|
}
|
|
}
|
|
kAtmosphericTypeFuncs[v3 >> 1](v3, i);
|
|
}
|
|
}
|
|
|
|
void AtmosphericTypeFunc_1_FootstepSplash(uint16 k, uint16 j) { // 0x908AC5
|
|
int16 v4;
|
|
OamEnt *v5;
|
|
int16 v6;
|
|
|
|
int v2 = j >> 1;
|
|
uint16 r18 = 2 * LOBYTE(atmospheric_gfx_frame_and_type[v2]);
|
|
uint16 v3 = oam_next_ptr;
|
|
v4 = atmospheric_gfx_x_pos[v2] - layer1_x_pos - 4;
|
|
if (v4 >= 0) {
|
|
if (sign16(atmospheric_gfx_x_pos[v2] - layer1_x_pos - 260)) {
|
|
v5 = gOamEnt(oam_next_ptr);
|
|
v5->xcoord = v4;
|
|
v6 = atmospheric_gfx_y_pos[v2] - layer1_y_pos - 4;
|
|
if (v6 >= 0) {
|
|
if (sign16(atmospheric_gfx_y_pos[v2] - layer1_y_pos - 260)) {
|
|
v5->ycoord = v6;
|
|
*(uint16 *)&v5->charnum = *(uint16 *)RomPtr_90(r18 + g_off_908BFF[k >> 1]);
|
|
oam_next_ptr = v3 + 4;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void AtmosphericTypeFunc_Common(uint16 j, uint16 a) { // 0x908B74
|
|
int v1 = j >> 1;
|
|
if (((atmospheric_gfx_y_pos[v1] - layer1_y_pos) & 0xFF00) == 0)
|
|
DrawSamusSpritemap(a, atmospheric_gfx_x_pos[v1] - layer1_x_pos, atmospheric_gfx_y_pos[v1] - layer1_y_pos);
|
|
}
|
|
|
|
void AtmosphericTypeFunc_3_DivingSplash(uint16 k, uint16 j) { // 0x908B16
|
|
int v2 = j >> 1;
|
|
uint16 r18 = LOBYTE(atmospheric_gfx_frame_and_type[v2]);
|
|
atmospheric_gfx_y_pos[v2] = fx_y_pos;
|
|
AtmosphericTypeFunc_Common(j, r18 + 399);
|
|
}
|
|
|
|
void AtmosphericTypeFunc_4_LavaSurfaceDmg(uint16 k, uint16 j) { // 0x908B2E
|
|
int v2 = j >> 1;
|
|
uint16 v3;
|
|
if ((j & 4) != 0)
|
|
v3 = atmospheric_gfx_x_pos[v2] - 1;
|
|
else
|
|
v3 = atmospheric_gfx_x_pos[v2] + 1;
|
|
atmospheric_gfx_x_pos[v2] = v3;
|
|
--atmospheric_gfx_y_pos[j >> 1];
|
|
AtmosphericTypeFunc_1_FootstepSplash(k, j);
|
|
}
|
|
|
|
void AtmosphericTypeFunc_67_Dust(uint16 k, uint16 j) { // 0x908B57
|
|
--atmospheric_gfx_y_pos[j >> 1];
|
|
AtmosphericTypeFunc_1_FootstepSplash(k, j);
|
|
}
|
|
|
|
void AtmosphericTypeFunc_5_Bubbles(uint16 k, uint16 j) { // 0x908B64
|
|
uint16 r18 = LOBYTE(atmospheric_gfx_frame_and_type[j >> 1]);
|
|
AtmosphericTypeFunc_Common(j, r18 + 390);
|
|
}
|
|
|
|
static Func_Y_To_PairU16 *const kSamus_CalcSpritemapPos[28] = { // 0x908C1F
|
|
&Samus_CalcSpritemapPos_Standing,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Crouch,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Default,
|
|
&Samus_CalcSpritemapPos_Special,
|
|
};
|
|
|
|
PairU16 Samus_CalcSpritemapPos(uint16 k) {
|
|
PairU16 v1;
|
|
|
|
if ((ceres_status & 0x8000) == 0) {
|
|
v1 = kSamus_CalcSpritemapPos[samus_movement_type](k);
|
|
} else {
|
|
uint16 old_x = samus_x_pos, old_y = samus_y_pos;
|
|
Samus_CalcPos_Mode7();
|
|
v1 = kSamus_CalcSpritemapPos[samus_movement_type](k);
|
|
samus_y_pos = old_y;
|
|
samus_x_pos = old_x;
|
|
}
|
|
return MakePairU16(v1.k, v1.j);
|
|
}
|
|
|
|
PairU16 Samus_CalcSpritemapPos_Default(uint16 j) { // 0x908C94
|
|
int v1 = (int8)*(&kPoseParams[0].y_offset_to_gfx + 4 * j);
|
|
samus_spritemap_y_pos = samus_y_pos - v1 - layer1_y_pos;
|
|
samus_spritemap_x_pos = samus_x_pos - layer1_x_pos;
|
|
return MakePairU16(samus_spritemap_x_pos, samus_spritemap_y_pos);
|
|
}
|
|
|
|
PairU16 Samus_CalcSpritemapPos_Standing(uint16 j) { // 0x908CC3
|
|
static const uint8 g_byte_908D28[16] = {
|
|
3, 6, 0, 0,
|
|
3, 6, 0, 0,
|
|
3, 3, 6, 0,
|
|
3, 3, 6, 0,
|
|
};
|
|
|
|
int16 v1;
|
|
PairU16 v3;
|
|
|
|
v1 = j >> 1;
|
|
if (!(j >> 1) || v1 == kPose_9B_FaceF_VariaGravitySuit) {
|
|
if (!sign16(samus_anim_frame - 2)) {
|
|
samus_spritemap_y_pos = samus_y_pos - 1 - layer1_y_pos;
|
|
samus_spritemap_x_pos = samus_x_pos - layer1_x_pos;
|
|
return MakePairU16(samus_x_pos - layer1_x_pos, samus_y_pos - 1 - layer1_y_pos);
|
|
}
|
|
} else if (!sign16(v1 - kPose_A4_FaceR_LandJump) && sign16(v1 - kPose_A8_FaceR_Grappling)) {
|
|
uint16 r18 = *(uint16 *)&g_byte_908D28[(uint16)(samus_anim_frame + 4 * (v1 - 164))];
|
|
samus_spritemap_y_pos = samus_y_pos - r18 - layer1_y_pos;
|
|
samus_spritemap_x_pos = samus_x_pos - layer1_x_pos;
|
|
return MakePairU16(samus_x_pos - layer1_x_pos, samus_y_pos - r18 - layer1_y_pos);
|
|
}
|
|
v3 = Samus_CalcSpritemapPos_Default(j);
|
|
return MakePairU16(v3.k, v3.j);
|
|
}
|
|
|
|
PairU16 Samus_CalcSpritemapPos_Crouch(uint16 j) { // 0x908D3C
|
|
static const int8 byte_908D80[24] = {
|
|
-8, 0, -8, 0,
|
|
-4, -2, -4, -2,
|
|
0, 0, 0, 0,
|
|
-4, 0, -4, 0,
|
|
5, 4, 5, 4,
|
|
0, 0, 0, 0,
|
|
};
|
|
|
|
int16 v1;
|
|
|
|
v1 = j >> 1;
|
|
if (sign16((j >> 1) - kPose_35_FaceR_CrouchTrans) || !sign16(v1 - kPose_41_FaceL_Morphball_Ground)) {
|
|
return Samus_CalcSpritemapPos_Default(j);
|
|
} else {
|
|
int v4 = byte_908D80[(uint16)(samus_anim_frame + 2 * (v1 - 53))];
|
|
samus_spritemap_y_pos = v4 + samus_y_pos - layer1_y_pos;
|
|
samus_spritemap_x_pos = samus_x_pos - layer1_x_pos;
|
|
return MakePairU16(samus_x_pos - layer1_x_pos, samus_spritemap_y_pos);
|
|
}
|
|
}
|
|
|
|
PairU16 Samus_CalcSpritemapPos_Special(uint16 j) { // 0x908D98
|
|
static const int8 byte_908DEF[32] = {
|
|
7, 5, -8, -8, -8, -8, -8, -5,
|
|
4, 4, 4, 4, 0, 0, 4, -3,
|
|
-5, 0, 0, 4, -3, -5, -3, 4,
|
|
0, 0, 4, 0, 0, 4, 0, 0,
|
|
};
|
|
int v1, v2;
|
|
|
|
v1 = j >> 1;
|
|
if (v1 == kPose_E8_FaceR_Drained_CrouchFalling || v1 == kPose_E9_FaceL_Drained_CrouchFalling) {
|
|
v2 = byte_908DEF[samus_anim_frame];
|
|
} else {
|
|
if (v1 != kPose_EA_FaceR_Drained_Stand && v1 != kPose_EB_FaceL_Drained_Stand || (int16)(samus_anim_frame - 5) < 0) {
|
|
return Samus_CalcSpritemapPos_Default(j);
|
|
}
|
|
v2 = -3;
|
|
}
|
|
samus_spritemap_y_pos = v2 + samus_y_pos - layer1_y_pos;
|
|
samus_spritemap_x_pos = samus_x_pos - layer1_x_pos;
|
|
return MakePairU16(samus_x_pos - layer1_x_pos, v2 + samus_y_pos - layer1_y_pos);
|
|
}
|
|
|
|
void SetLiquidPhysicsType(void) {
|
|
uint16 r18 = Samus_GetBottom_R18();
|
|
switch ((fx_type & 0xF) >> 1) {
|
|
case 1:
|
|
case 2:
|
|
if ((lava_acid_y_pos & 0x8000) == 0 && sign16(lava_acid_y_pos - r18))
|
|
liquid_physics_type = kLiquidPhysicsType_LavaAcid;
|
|
else
|
|
liquid_physics_type = 0;
|
|
break;
|
|
case 3:
|
|
if ((fx_y_pos & 0x8000) == 0 && sign16(fx_y_pos - r18) && (fx_liquid_options & 4) == 0)
|
|
liquid_physics_type = kLiquidPhysicsType_Water;
|
|
else
|
|
liquid_physics_type = 0;
|
|
break;
|
|
default:
|
|
liquid_physics_type = 0;
|
|
}
|
|
}
|
|
|
|
void Samus_HandleMovement_X(void) { // 0x908E64
|
|
Samus_HandleExtraRunspeedX();
|
|
Samus_MoveX(Samus_CalcBaseSpeed_X(Samus_DetermineSpeedTableEntryPtr_X()));
|
|
}
|
|
|
|
void Samus_MoveX(int32 amt) { // 0x908EA9
|
|
if (!samus_x_accel_mode || samus_x_accel_mode == 2) {
|
|
if (samus_pose_x_dir != 4) {
|
|
LABEL_6:
|
|
amt = Samus_CalcDisplacementMoveRight(amt);
|
|
goto LABEL_8;
|
|
}
|
|
} else if (samus_pose_x_dir != 8) {
|
|
goto LABEL_6;
|
|
}
|
|
amt = Samus_CalcDisplacementMoveLeft(amt);
|
|
LABEL_8:
|
|
if (amt < 0)
|
|
Samus_MoveLeft(amt);
|
|
else
|
|
Samus_MoveRight(amt);
|
|
}
|
|
|
|
void Samus_BombJumpRisingXMovement_(void) {
|
|
int32 amt;
|
|
if (knockback_dir) {
|
|
amt = Samus_CalcBaseSpeed_X(Samus_DetermineSpeedTableEntryPtr_X());
|
|
if (!knockback_x_dir)
|
|
goto LABEL_6;
|
|
LABEL_5:
|
|
amt = Samus_CalcDisplacementMoveRight(amt);
|
|
goto LABEL_7;
|
|
}
|
|
amt = Samus_CalcBaseSpeed_X(addr_stru_909F25);
|
|
if ((uint8)bomb_jump_dir != 1)
|
|
goto LABEL_5;
|
|
LABEL_6:
|
|
amt = Samus_CalcDisplacementMoveLeft(amt);
|
|
LABEL_7:
|
|
if (amt < 0)
|
|
Samus_MoveLeft(amt);
|
|
else
|
|
Samus_MoveRight(amt);
|
|
}
|
|
|
|
void Samus_BombJumpRisingYMovement_(void) {
|
|
if (samus_y_dir == 1) {
|
|
if ((samus_y_speed & 0x8000) != 0) {
|
|
samus_y_subspeed = 0;
|
|
samus_y_speed = 0;
|
|
samus_y_dir = 2;
|
|
if ((uint8)bomb_jump_dir != 2)
|
|
samus_x_accel_mode = 2;
|
|
} else if (sign16(samus_y_speed - 1)) {
|
|
if (samus_input_handler != FUNC16(Samus_InputHandler_E91D))
|
|
samus_input_handler = FUNC16(Samus_InputHandler_E913);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Samus_BombJumpFallingXMovement_(void) {
|
|
int32 amt = Samus_CalcBaseSpeed_X(Samus_DetermineSpeedTableEntryPtr_X());
|
|
if (samus_var62 == 1)
|
|
amt = Samus_CalcDisplacementMoveLeft(amt);
|
|
else
|
|
amt = Samus_CalcDisplacementMoveRight(amt);
|
|
if (amt < 0)
|
|
Samus_MoveLeft(amt);
|
|
else
|
|
Samus_MoveRight(amt);
|
|
}
|
|
|
|
void Samus_BombJumpFallingYMovement_(void) {
|
|
if (sign16(samus_y_speed - 5))
|
|
AddToHiLo(&samus_y_speed, &samus_y_subspeed, __PAIR32__(samus_y_accel, samus_y_subaccel));
|
|
Samus_MoveDown(__PAIR32__(samus_y_speed, samus_y_subspeed));
|
|
}
|
|
|
|
void Samus_JumpingMovement(void) { // 0x908FB3
|
|
Samus_HandleExtraRunspeedX();
|
|
if (samus_pose == kPose_4B_FaceR_Jumptrans
|
|
|| samus_pose == kPose_4C_FaceL_Jumptrans
|
|
|| !sign16(samus_pose - kPose_55_FaceR_Jumptrans_AimU) && sign16(samus_pose - kPose_5B)) {
|
|
samus_x_accel_mode = 0;
|
|
Samus_Move_NoBaseSpeed_X();
|
|
Samus_MoveExtraY();
|
|
return;
|
|
}
|
|
if (samus_y_dir == 1 && ((button_config_jump_a & joypad1_lastkeys) == 0 || (samus_y_speed & 0x8000) != 0)) {
|
|
samus_y_subspeed = 0;
|
|
samus_y_speed = 0;
|
|
samus_y_dir = 2;
|
|
}
|
|
Pair_Bool_Amt pair = Samus_CalcBaseSpeed_NoDecel_X(Samus_DetermineSpeedTableEntryPtr_X());
|
|
if (samus_movement_type == 20) {
|
|
if (!samus_x_accel_mode)
|
|
samus_x_accel_mode = 2;
|
|
goto LABEL_17;
|
|
}
|
|
if (samus_x_accel_mode || (joypad1_lastkeys & 0x100) != 0 || (joypad1_lastkeys & 0x200) != 0) {
|
|
LABEL_17:
|
|
Samus_MoveX(pair.amt);
|
|
goto LABEL_18;
|
|
}
|
|
samus_x_base_speed = 0;
|
|
samus_x_base_subspeed = 0;
|
|
samus_collision_flag = 0;
|
|
LABEL_18:
|
|
Samus_MoveY_WithSpeedCalc();
|
|
}
|
|
|
|
void Samus_SpinJumpMovement(void) { // 0x909040
|
|
static const uint16 g_word_909E9F = 8;
|
|
|
|
Samus_HandleExtraRunspeedX();
|
|
if (samus_y_dir == 1 && ((button_config_jump_a & joypad1_lastkeys) == 0 || (samus_y_speed & 0x8000) != 0)) {
|
|
samus_y_subspeed = 0;
|
|
samus_y_speed = 0;
|
|
samus_y_dir = 2;
|
|
}
|
|
Pair_Bool_Amt pair = Samus_CalcBaseSpeed_NoDecel_X(Samus_DetermineSpeedTableEntryPtr_X());
|
|
if (pair.flag || samus_x_accel_mode == 1)
|
|
goto LABEL_12;
|
|
if (samus_pose_x_dir == 4) {
|
|
if ((joypad1_lastkeys & kButton_Left) != 0)
|
|
goto LABEL_12;
|
|
LABEL_11:
|
|
pair.amt = 0;
|
|
samus_x_base_speed = 0;
|
|
samus_x_base_subspeed = 0;
|
|
samus_collision_flag = 0;
|
|
samus_x_accel_mode = 0;
|
|
goto LABEL_14;
|
|
}
|
|
if ((joypad1_lastkeys & kButton_Right) == 0)
|
|
goto LABEL_11;
|
|
LABEL_12:
|
|
if (!samus_x_accel_mode)
|
|
samus_x_accel_mode = 2;
|
|
LABEL_14:
|
|
Samus_MoveX(pair.amt);
|
|
if (!Samus_WallJumpCheck(INT16_SHL16(g_word_909E9F)))
|
|
Samus_MoveY_WithSpeedCalc();
|
|
}
|
|
|
|
void Samus_CheckStartFalling(void) { // 0x9090C4
|
|
if (samus_y_dir == 1 && (samus_y_speed & 0x8000) != 0) {
|
|
samus_y_subspeed = 0;
|
|
samus_y_speed = 0;
|
|
samus_y_dir = 2;
|
|
}
|
|
}
|
|
|
|
void Samus_MoveY_WithSpeedCalc(void) { // 0x9090E2
|
|
int32 amt = __PAIR32__(samus_y_speed, samus_y_subspeed);
|
|
if (samus_y_dir == 2) {
|
|
if (samus_y_speed != 5)
|
|
AddToHiLo(&samus_y_speed, &samus_y_subspeed, __PAIR32__(samus_y_accel, samus_y_subaccel));
|
|
} else {
|
|
AddToHiLo(&samus_y_speed, &samus_y_subspeed, -(int32)__PAIR32__(samus_y_accel, samus_y_subaccel));
|
|
}
|
|
if (samus_y_dir != 2)
|
|
amt = -amt;
|
|
amt += __PAIR32__(extra_samus_y_displacement, extra_samus_y_subdisplacement);
|
|
if (amt < 0)
|
|
Samus_MoveUp(amt);
|
|
else
|
|
Samus_MoveDown(amt);
|
|
}
|
|
|
|
void Samus_FallingMovement(void) { // 0x909168
|
|
Samus_HandleExtraRunspeedX();
|
|
Pair_Bool_Amt pair = Samus_CalcBaseSpeed_NoDecel_X(Samus_DetermineSpeedTableEntryPtr_X());
|
|
if (samus_x_accel_mode || (joypad1_lastkeys & kButton_Right) != 0 || (joypad1_lastkeys & kButton_Left) != 0) {
|
|
Samus_MoveX(pair.amt);
|
|
} else {
|
|
samus_x_base_speed = 0;
|
|
samus_x_base_subspeed = 0;
|
|
samus_collision_flag = 0;
|
|
}
|
|
Samus_CheckStartFalling();
|
|
Samus_MoveY_WithSpeedCalc();
|
|
}
|
|
|
|
void Samus_MorphedFallingMovement(void) { // 0x90919F
|
|
Pair_Bool_Amt pair = Samus_CalcBaseSpeed_NoDecel_X(Samus_DetermineSpeedTableEntryPtr_X());
|
|
if (!samus_x_accel_mode && (joypad1_lastkeys & kButton_Right) == 0 && (joypad1_lastkeys & kButton_Left) == 0) {
|
|
pair.amt = 0;
|
|
samus_x_base_speed = 0;
|
|
samus_x_base_subspeed = 0;
|
|
samus_collision_flag = 0;
|
|
}
|
|
Samus_MoveX(pair.amt);
|
|
Samus_CheckStartFalling();
|
|
Samus_MoveY_WithSpeedCalc();
|
|
}
|
|
|
|
void Samus_MorphedBouncingMovement(void) { // 0x9091D1
|
|
Pair_Bool_Amt pair = Samus_CalcBaseSpeed_NoDecel_X(Samus_DetermineSpeedTableEntryPtr_X());
|
|
if (!samus_x_accel_mode && (joypad1_lastkeys & kButton_Right) == 0 && (joypad1_lastkeys & kButton_Left) == 0) {
|
|
pair.amt = 0;
|
|
samus_x_base_speed = 0;
|
|
samus_x_base_subspeed = 0;
|
|
samus_collision_flag = 0;
|
|
}
|
|
Samus_MoveX(pair.amt);
|
|
if (!knockback_dir) {
|
|
if (extra_samus_y_displacement || extra_samus_y_subdisplacement) {
|
|
samus_y_dir = 2;
|
|
samus_y_subspeed = 0;
|
|
samus_y_speed = 0;
|
|
int32 amt = __PAIR32__(extra_samus_y_displacement, extra_samus_y_subdisplacement);
|
|
if (amt < 0) {
|
|
Samus_MoveUp(amt);
|
|
} else {
|
|
Samus_MoveDown(amt + INT16_SHL16(1));
|
|
}
|
|
} else {
|
|
Samus_CheckStartFalling();
|
|
Samus_MoveY_WithSpeedCalc();
|
|
}
|
|
}
|
|
}
|
|
|
|
void Samus_Move_NoSpeedCalc_Y(void) { // 0x90923F
|
|
int32 amt = __PAIR32__(extra_samus_y_displacement, extra_samus_y_subdisplacement);
|
|
if (amt == 0) {
|
|
if (!samus_pos_adjusted_by_slope_flag)
|
|
amt = __PAIR32__(samus_total_x_speed, samus_total_x_subspeed);
|
|
Samus_MoveDown(amt + INT16_SHL16(1));
|
|
} else {
|
|
if (amt < 0)
|
|
Samus_MoveUp(amt);
|
|
else
|
|
Samus_MoveDown(amt + INT16_SHL16(1));
|
|
}
|
|
}
|
|
|
|
void Samus_MoveExtraY(void) { // 0x909288
|
|
int32 amt = __PAIR32__(extra_samus_y_displacement, extra_samus_y_subdisplacement);
|
|
if (amt != 0) {
|
|
if (amt < 0)
|
|
Samus_MoveUp(amt);
|
|
else
|
|
Samus_MoveDown(amt + INT16_SHL16(1));
|
|
}
|
|
}
|
|
|
|
uint8 Samus_CheckAndMoveY(void) { // 0x9092B8
|
|
if (!samus_y_dir)
|
|
return 0;
|
|
Samus_CheckStartFalling();
|
|
Samus_MoveY_WithSpeedCalc();
|
|
return 1;
|
|
}
|
|
|
|
uint8 Samus_MoveY_Simple_(void) { // 0x9092C7
|
|
if (!samus_y_dir)
|
|
return 0;
|
|
Samus_CheckStartFalling();
|
|
Samus_MoveY_WithSpeedCalc();
|
|
return 1;
|
|
}
|
|
|
|
void Samus_Move_NoBaseSpeed_X(void) { // 0x909348
|
|
Samus_MoveX(0);
|
|
}
|
|
|
|
void Samus_MoveLeft(int32 amt) { // 0x909350
|
|
amt = -amt;
|
|
CheckEnemyColl_Result cres = Samus_CheckSolidEnemyColl(amt);
|
|
samus_collision_flag = cres.collision, amt = cres.amt;
|
|
if (samus_collision_flag) {
|
|
Samus_ClearXSpeedIfColl();
|
|
Samus_MoveLeft_NoColl(amt);
|
|
Samus_AlignYPosSlope();
|
|
} else {
|
|
amt = Samus_MoveRight_NoSolidColl(-amt);
|
|
SetHiLo(&projectile_init_speed_samus_moved_left, &projectile_init_speed_samus_moved_left_fract, amt);
|
|
if ((samus_collision_direction & 1) != 0)
|
|
samus_collision_flag = 0;
|
|
Samus_ClearXSpeedIfColl();
|
|
Samus_AlignYPosSlope();
|
|
}
|
|
}
|
|
|
|
void Samus_MoveRight(int32 amt) { // 0x9093B1
|
|
CheckEnemyColl_Result cres = Samus_CheckSolidEnemyColl(amt);
|
|
samus_collision_flag = cres.collision, amt = cres.amt;
|
|
if (samus_collision_flag) {
|
|
Samus_ClearXSpeedIfColl();
|
|
Samus_MoveRight_NoColl(amt);
|
|
Samus_AlignYPosSlope();
|
|
} else {
|
|
amt = Samus_MoveRight_NoSolidColl(amt);
|
|
SetHiLo(&projectile_init_speed_samus_moved_right, &projectile_init_speed_samus_moved_right_fract, amt);
|
|
if ((samus_collision_direction & 1) == 0)
|
|
samus_collision_flag = 0;
|
|
Samus_ClearXSpeedIfColl();
|
|
Samus_AlignYPosSlope();
|
|
}
|
|
}
|
|
|
|
void Samus_MoveUp(int32 amt) { // 0x9093EC
|
|
samus_collision_direction = 2;
|
|
CheckEnemyColl_Result cres = Samus_CheckSolidEnemyColl(-amt);
|
|
samus_collision_flag = cres.collision, amt = cres.amt;
|
|
if (samus_collision_flag) {
|
|
Samus_MoveUp_SetPoseCalcInput();
|
|
Samus_MoveUp_NoColl(amt);
|
|
} else {
|
|
amt = Samus_MoveDown_NoSolidColl(-amt);
|
|
SetHiLo(&projectile_init_speed_samus_moved_up, &projectile_init_speed_samus_moved_up_fract, amt);
|
|
Samus_MoveUp_SetPoseCalcInput();
|
|
}
|
|
}
|
|
|
|
void Samus_MoveDown(int32 amt) { // 0x909440
|
|
samus_collision_direction = 3;
|
|
CheckEnemyColl_Result cres = Samus_CheckSolidEnemyColl(amt);
|
|
samus_collision_flag = cres.collision, amt = cres.amt;
|
|
if (samus_collision_flag) {
|
|
Samus_MoveDown_SetPoseCalcInput();
|
|
Samus_MoveDown_NoColl(amt);
|
|
} else {
|
|
amt = Samus_MoveDown_NoSolidColl(amt);
|
|
projectile_init_speed_samus_moved_down_fract = amt;
|
|
projectile_init_speed_samus_moved_down = amt >> 16;
|
|
Samus_MoveDown_SetPoseCalcInput();
|
|
}
|
|
}
|
|
|
|
void Samus_MoveHandler_ReleaseFromGrapple(void) { // 0x90946E
|
|
if (samus_y_dir == 1 && (samus_y_speed & 0x8000) != 0) {
|
|
samus_y_subspeed = 0;
|
|
samus_y_speed = 0;
|
|
samus_y_dir = 2;
|
|
samus_movement_handler = FUNC16(Samus_MovementHandler_Normal);
|
|
}
|
|
samus_x_accel_mode = 2;
|
|
int32 amt = Samus_CalcBaseSpeed_X(Samus_DetermineGrappleSwingSpeed_X());
|
|
if (samus_x_accel_mode || (joypad1_lastkeys & kButton_Right) != 0 || (joypad1_lastkeys & kButton_Left) != 0) {
|
|
Samus_MoveX(amt);
|
|
} else {
|
|
samus_x_base_speed = 0;
|
|
samus_x_base_subspeed = 0;
|
|
samus_collision_flag = 0;
|
|
}
|
|
Samus_MoveY_WithSpeedCalc();
|
|
if (input_to_pose_calc)
|
|
samus_movement_handler = FUNC16(Samus_MovementHandler_Normal);
|
|
}
|
|
|
|
void Samus_HandleMovement_DrainedCrouching(void) { // 0x9094CB
|
|
Samus_MoveY_WithSpeedCalc();
|
|
if (samus_collision_flag) {
|
|
samus_movement_handler = FUNC16(Samus_MovementHandler_Normal);
|
|
samus_anim_frame_timer = 8;
|
|
samus_anim_frame = 7;
|
|
samus_y_subspeed = 0;
|
|
samus_y_speed = 0;
|
|
}
|
|
}
|
|
|
|
void CallScrollingFinishedHook(uint32 ea) {
|
|
switch (ea) {
|
|
case fnSamus_ScrollFinishedHook_SporeSpawnFight: Samus_ScrollFinishedHook_SporeSpawnFight(); return;
|
|
default: Unreachable();
|
|
}
|
|
}
|
|
|
|
void MainScrollingRoutine(void) { // 0x9094EC
|
|
if (slow_grabble_scrolling_flag) {
|
|
if ((samus_x_pos & 0x8000) != 0)
|
|
goto LABEL_14;
|
|
uint16 v0;
|
|
v0 = samus_x_pos - layer1_x_pos;
|
|
if (samus_x_pos < layer1_x_pos)
|
|
goto LABEL_7;
|
|
if (v0 >= 0xA0) {
|
|
layer1_x_pos += 3;
|
|
goto LABEL_8;
|
|
}
|
|
if (v0 < 0x60)
|
|
LABEL_7:
|
|
layer1_x_pos -= 3;
|
|
LABEL_8:
|
|
if ((samus_y_pos & 0x8000) == 0) {
|
|
uint16 v1 = samus_y_pos - layer1_y_pos;
|
|
if (samus_y_pos >= layer1_y_pos) {
|
|
if (v1 >= 0x90) {
|
|
layer1_y_pos += 3;
|
|
goto LABEL_14;
|
|
}
|
|
if (v1 >= 0x70)
|
|
goto LABEL_14;
|
|
}
|
|
layer1_y_pos -= 3;
|
|
}
|
|
LABEL_14:
|
|
HandleAutoscrolling_X();
|
|
HandleAutoscrolling_Y();
|
|
goto LABEL_16;
|
|
}
|
|
Samus_CalcDistanceMoved_X();
|
|
Samus_HandleScroll_X();
|
|
Samus_CalcDistanceMoved_Y();
|
|
Samus_HandleScroll_Y();
|
|
LABEL_16:
|
|
if (scrolling_finished_hook)
|
|
CallScrollingFinishedHook(scrolling_finished_hook | 0x900000);
|
|
samus_prev_x_pos = samus_x_pos;
|
|
samus_prev_x_subpos = samus_x_subpos;
|
|
samus_prev_y_pos = samus_y_pos;
|
|
samus_prev_y_subpos = samus_y_subpos;
|
|
}
|
|
|
|
void Samus_ScrollFinishedHook_SporeSpawnFight(void) { // 0x909589
|
|
if (layer1_y_pos <= 0x1D0)
|
|
layer1_y_pos = 464;
|
|
}
|
|
|
|
void Samus_HandleScroll_X(void) { // 0x9095A0
|
|
static const uint16 kSamus_HandleScroll_X_FaceLeft[4] = { 0xa0, 0x50, 0x20, 0xe0 };
|
|
static const uint16 kSamus_HandleScroll_X_FaceRight[4] = { 0x60, 0x40, 0x20, 0xe0 };
|
|
|
|
|
|
if (samus_prev_x_pos == samus_x_pos) {
|
|
HandleAutoscrolling_X();
|
|
return;
|
|
}
|
|
// r18 = layer1_x_pos;
|
|
if (knockback_dir || samus_movement_type == 16 || samus_x_accel_mode == 1) {
|
|
if (samus_pose_x_dir == 4) {
|
|
LABEL_9:
|
|
ideal_layer1_xpos = samus_x_pos - kSamus_HandleScroll_X_FaceRight[camera_distance_index >> 1];
|
|
goto LABEL_11;
|
|
}
|
|
} else if (samus_pose_x_dir != 4) {
|
|
goto LABEL_9;
|
|
}
|
|
ideal_layer1_xpos = samus_x_pos - kSamus_HandleScroll_X_FaceLeft[camera_distance_index >> 1];
|
|
LABEL_11:
|
|
if (ideal_layer1_xpos != layer1_x_pos) {
|
|
if ((int16)(ideal_layer1_xpos - layer1_x_pos) < 0) {
|
|
uint16 v1 = (__PAIR32__(layer1_x_pos, layer1_x_subpos) - __PAIR32__(absolute_moved_last_frame_x, absolute_moved_last_frame_x_fract)) >> 16;
|
|
layer1_x_subpos -= absolute_moved_last_frame_x_fract;
|
|
layer1_x_pos = v1;
|
|
HandleScrollingWhenTriggeringScrollLeft();
|
|
} else {
|
|
uint16 v0 = (__PAIR32__(absolute_moved_last_frame_x, absolute_moved_last_frame_x_fract) + __PAIR32__(layer1_x_pos, layer1_x_subpos)) >> 16;
|
|
layer1_x_subpos += absolute_moved_last_frame_x_fract;
|
|
layer1_x_pos = v0;
|
|
HandleScrollingWhenTriggeringScrollRight();
|
|
}
|
|
}
|
|
}
|
|
|
|
void Samus_HandleScroll_Y(void) { // 0x90964F
|
|
if (samus_prev_y_pos == samus_y_pos) {
|
|
HandleAutoscrolling_Y();
|
|
} else {
|
|
//r18 = layer1_y_pos;
|
|
if (samus_y_dir == 1)
|
|
ideal_layer1_ypos = samus_y_pos - down_scroller;
|
|
else
|
|
ideal_layer1_ypos = samus_y_pos - up_scroller;
|
|
if (ideal_layer1_ypos != layer1_y_pos) {
|
|
if ((int16)(ideal_layer1_ypos - layer1_y_pos) < 0) {
|
|
uint16 v1 = (__PAIR32__(layer1_y_pos, layer1_y_subpos)
|
|
- __PAIR32__(absolute_moved_last_frame_y, absolute_moved_last_frame_y_fract)) >> 16;
|
|
layer1_y_subpos -= absolute_moved_last_frame_y_fract;
|
|
layer1_y_pos = v1;
|
|
HandleScrollingWhenTriggeringScrollUp();
|
|
} else {
|
|
uint16 v0 = (__PAIR32__(absolute_moved_last_frame_y, absolute_moved_last_frame_y_fract)
|
|
+ __PAIR32__(layer1_y_pos, layer1_y_subpos)) >> 16;
|
|
layer1_y_subpos += absolute_moved_last_frame_y_fract;
|
|
layer1_y_pos = v0;
|
|
HandleScrollingWhenTriggeringScrollDown();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static const uint16 g_word_909EAD = 1;
|
|
|
|
void Samus_CalcDistanceMoved_X(void) { // 0x9096C0
|
|
if ((int16)(samus_x_pos - samus_prev_x_pos) >= 0) {
|
|
absolute_moved_last_frame_x_fract = samus_x_subpos - samus_prev_x_subpos;
|
|
absolute_moved_last_frame_x = g_word_909EAD + ((__PAIR32__(samus_x_pos, samus_x_subpos) - __PAIR32__(samus_prev_x_pos, samus_prev_x_subpos)) >> 16);
|
|
} else {
|
|
absolute_moved_last_frame_x_fract = samus_prev_x_subpos - samus_x_subpos;
|
|
absolute_moved_last_frame_x = g_word_909EAD + ((__PAIR32__(samus_prev_x_pos, samus_prev_x_subpos) - __PAIR32__(samus_x_pos, samus_x_subpos)) >> 16);
|
|
}
|
|
}
|
|
|
|
void Samus_CalcDistanceMoved_Y(void) { // 0x9096FF
|
|
if ((int16)(samus_y_pos - samus_prev_y_pos) >= 0) {
|
|
absolute_moved_last_frame_y_fract = samus_y_subpos - samus_prev_y_subpos;
|
|
absolute_moved_last_frame_y = g_word_909EAD + ((__PAIR32__(samus_y_pos, samus_y_subpos) - __PAIR32__(samus_prev_y_pos, samus_prev_y_subpos)) >> 16);
|
|
} else {
|
|
absolute_moved_last_frame_y_fract = samus_prev_y_subpos - samus_y_subpos;
|
|
absolute_moved_last_frame_y = g_word_909EAD + ((__PAIR32__(samus_prev_y_pos, samus_prev_y_subpos) - __PAIR32__(samus_y_pos, samus_y_subpos)) >> 16);
|
|
}
|
|
}
|
|
|
|
static const uint16 kSamus_HandleExtraRunspeedX_Tab0[3] = { 0, 0, 0 };
|
|
static const uint16 kSamus_HandleExtraRunspeedX_Tab1[3] = { 0x1000, 0x400, 0x400 };
|
|
static const uint16 kSamus_HandleExtraRunspeedX_Tab2[3] = { 7, 4, 4 };
|
|
static const uint16 kSamus_HandleExtraRunspeedX_Tab3[3] = { 0, 0, 0 };
|
|
static const uint16 kSamus_HandleExtraRunspeedX_Tab4[3] = { 2, 1, 0 };
|
|
static const uint16 kSamus_HandleExtraRunspeedX_Tab5[3] = { 0, 0, 0 };
|
|
|
|
void Samus_HandleExtraRunspeedX(void) { // 0x90973E
|
|
if ((equipped_items & 0x20) == 0) {
|
|
uint16 r18 = Samus_GetBottom_R18();
|
|
if ((fx_y_pos & 0x8000) != 0) {
|
|
if ((lava_acid_y_pos & 0x8000) == 0 && sign16(lava_acid_y_pos - r18)) {
|
|
LABEL_24:
|
|
if (!samus_has_momentum_flag) {
|
|
samus_x_extra_run_speed = 0;
|
|
samus_x_extra_run_subspeed = 0;
|
|
}
|
|
goto LABEL_26;
|
|
}
|
|
} else if (sign16(fx_y_pos - r18) && (fx_liquid_options & 4) == 0) {
|
|
goto LABEL_24;
|
|
}
|
|
}
|
|
if (samus_movement_type != 1 || (button_config_run_b & joypad1_lastkeys) == 0)
|
|
goto LABEL_24;
|
|
if ((equipped_items & 0x2000) != 0) {
|
|
if (!samus_has_momentum_flag) {
|
|
samus_has_momentum_flag = 1;
|
|
special_samus_palette_timer = 1;
|
|
special_samus_palette_frame = 0;
|
|
speed_boost_counter = kSpeedBoostToCtr[0];
|
|
}
|
|
if ((int16)(samus_x_extra_run_speed - kSamus_HandleExtraRunspeedX_Tab2[0]) >= 0
|
|
&& (int16)(samus_x_extra_run_subspeed - kSamus_HandleExtraRunspeedX_Tab3[0]) >= 0) {
|
|
samus_x_extra_run_speed = kSamus_HandleExtraRunspeedX_Tab2[0];
|
|
samus_x_extra_run_subspeed = kSamus_HandleExtraRunspeedX_Tab3[0];
|
|
goto LABEL_26;
|
|
}
|
|
} else {
|
|
if (!samus_has_momentum_flag) {
|
|
samus_has_momentum_flag = 1;
|
|
speed_boost_counter = 0;
|
|
}
|
|
if ((int16)(samus_x_extra_run_speed - kSamus_HandleExtraRunspeedX_Tab4[0]) >= 0
|
|
&& (int16)(samus_x_extra_run_subspeed - kSamus_HandleExtraRunspeedX_Tab5[0]) >= 0) {
|
|
samus_x_extra_run_speed = kSamus_HandleExtraRunspeedX_Tab4[0];
|
|
samus_x_extra_run_subspeed = kSamus_HandleExtraRunspeedX_Tab5[0];
|
|
goto LABEL_26;
|
|
}
|
|
}
|
|
bool v0;
|
|
v0 = __CFADD__uint16(kSamus_HandleExtraRunspeedX_Tab1[0], samus_x_extra_run_subspeed);
|
|
samus_x_extra_run_subspeed += kSamus_HandleExtraRunspeedX_Tab1[0];
|
|
samus_x_extra_run_speed += kSamus_HandleExtraRunspeedX_Tab0[0] + v0;
|
|
LABEL_26:
|
|
if ((speed_boost_counter & 0xFF00) == 1024)
|
|
samus_contact_damage_index = 1;
|
|
}
|
|
|
|
void Samus_MoveRight_NoColl(int32 amt) { // 0x909826
|
|
AddToHiLo(&samus_x_pos, &samus_x_subpos, amt);
|
|
SetHiLo(&projectile_init_speed_samus_moved_right, &projectile_init_speed_samus_moved_right_fract, amt);
|
|
}
|
|
|
|
void Samus_MoveLeft_NoColl(int32 amt) { // 0x909842
|
|
AddToHiLo(&samus_x_pos, &samus_x_subpos, -amt);
|
|
SetHiLo(&projectile_init_speed_samus_moved_left, &projectile_init_speed_samus_moved_left_fract, -amt);
|
|
}
|
|
|
|
void Samus_MoveDown_NoColl(int32 amt) { // 0x909871
|
|
AddToHiLo(&samus_y_pos, &samus_y_subpos, amt);
|
|
SetHiLo(&projectile_init_speed_samus_moved_down, &projectile_init_speed_samus_moved_down_fract, amt);
|
|
}
|
|
|
|
void Samus_MoveUp_NoColl(int32 amt) { // 0x90988D
|
|
AddToHiLo(&samus_y_pos, &samus_y_subpos, -amt);
|
|
SetHiLo(&projectile_init_speed_samus_moved_up, &projectile_init_speed_samus_moved_up_fract, -amt);
|
|
}
|
|
|
|
void Samus_InitJump(void) { // 0x9098BC
|
|
static const uint16 kSamus_InitJump_Speed_Y[3] = { 4, 1, 2 };
|
|
static const uint16 kSamus_InitJump_Subspeed_Y[3] = { 0xe000, 0xc000, 0xc000 };
|
|
static const uint16 kSamus_InitJump_Tab2[3] = { 6, 2, 3 };
|
|
static const uint16 kSamus_InitJump_Tab3[3] = { 0, 0x8000, 0x8000 };
|
|
uint16 v0;
|
|
|
|
if ((equipped_items & 0x20) != 0)
|
|
goto LABEL_7;
|
|
uint16 r18 = Samus_GetBottom_R18();
|
|
if ((fx_y_pos & 0x8000) == 0) {
|
|
if (sign16(fx_y_pos - r18) && (fx_liquid_options & 4) == 0) {
|
|
v0 = 2;
|
|
goto LABEL_11;
|
|
}
|
|
LABEL_7:
|
|
v0 = 0;
|
|
goto LABEL_11;
|
|
}
|
|
if ((lava_acid_y_pos & 0x8000) != 0 || !sign16(lava_acid_y_pos - r18))
|
|
goto LABEL_7;
|
|
v0 = 4;
|
|
LABEL_11:;
|
|
int v1 = v0 >> 1;
|
|
if ((equipped_items & 0x100) != 0) {
|
|
samus_y_subspeed = kSamus_InitJump_Tab3[v1];
|
|
samus_y_speed = kSamus_InitJump_Tab2[v1];
|
|
} else {
|
|
samus_y_subspeed = kSamus_InitJump_Subspeed_Y[v1];
|
|
samus_y_speed = kSamus_InitJump_Speed_Y[v1];
|
|
}
|
|
if ((equipped_items & 0x2000) != 0) {
|
|
samus_y_subspeed += samus_x_extra_run_subspeed;
|
|
samus_y_speed += samus_x_extra_run_speed >> 1;
|
|
}
|
|
grapple_walljump_timer = 0;
|
|
reached_ceres_elevator_fade_timer = 0;
|
|
samus_y_dir = 1;
|
|
}
|
|
|
|
void Samus_InitWallJump(void) { // 0x909949
|
|
static const uint16 kSamus_InitWallJump_0[3] = { 4, 0, 2 };
|
|
static const uint16 kSamus_InitWallJump_1[3] = { 0xa000, 0x4000, 0xa000 };
|
|
static const uint16 kSamus_InitWallJump_2[3] = { 5, 0, 3 };
|
|
static const uint16 kSamus_InitWallJump_3[3] = { 0x8000, 0x8000, 0x8000 };
|
|
uint16 v0;
|
|
|
|
if ((equipped_items & 0x20) != 0)
|
|
goto LABEL_7;
|
|
uint16 r18 = Samus_GetBottom_R18();
|
|
if ((fx_y_pos & 0x8000) == 0) {
|
|
if (sign16(fx_y_pos - r18) && (fx_liquid_options & 4) == 0) {
|
|
v0 = 2;
|
|
goto LABEL_11;
|
|
}
|
|
LABEL_7:
|
|
v0 = 0;
|
|
goto LABEL_11;
|
|
}
|
|
if ((lava_acid_y_pos & 0x8000) != 0 || !sign16(lava_acid_y_pos - r18))
|
|
goto LABEL_7;
|
|
v0 = 4;
|
|
LABEL_11:;
|
|
int v1 = v0 >> 1;
|
|
if ((equipped_items & 0x100) != 0) {
|
|
samus_y_subspeed = kSamus_InitWallJump_3[v1];
|
|
samus_y_speed = kSamus_InitWallJump_2[v1];
|
|
} else {
|
|
samus_y_subspeed = kSamus_InitWallJump_1[v1];
|
|
samus_y_speed = kSamus_InitWallJump_0[v1];
|
|
}
|
|
if ((equipped_items & 0x2000) != 0) {
|
|
r18 = samus_x_extra_run_speed >> 1;
|
|
samus_y_subspeed += samus_x_extra_run_subspeed;
|
|
samus_y_speed += samus_x_extra_run_speed >> 1;
|
|
}
|
|
grapple_walljump_timer = 0;
|
|
reached_ceres_elevator_fade_timer = 0;
|
|
samus_y_dir = 1;
|
|
}
|
|
|
|
static const uint16 kSamus_SetSpeedForKnockback_Y_Speed[3] = { 5, 2, 2 };
|
|
static const uint16 kSamus_SetSpeedForKnockback_Y_Subspeed[3] = { 0, 0, 0 };
|
|
|
|
void Samus_SetSpeedForKnockback_Y(void) { // 0x9099D6
|
|
uint16 v0;
|
|
|
|
if ((equipped_items & 0x20) == 0) {
|
|
uint16 r18 = Samus_GetBottom_R18();
|
|
if ((fx_y_pos & 0x8000) != 0) {
|
|
if ((lava_acid_y_pos & 0x8000) == 0 && sign16(lava_acid_y_pos - r18)) {
|
|
v0 = 4;
|
|
goto LABEL_11;
|
|
}
|
|
} else if (sign16(fx_y_pos - r18) && (fx_liquid_options & 4) == 0) {
|
|
v0 = 2;
|
|
goto LABEL_11;
|
|
}
|
|
}
|
|
v0 = 0;
|
|
LABEL_11:;
|
|
int v1 = v0 >> 1;
|
|
samus_y_subspeed = kSamus_SetSpeedForKnockback_Y_Subspeed[v1];
|
|
samus_y_speed = kSamus_SetSpeedForKnockback_Y_Speed[v1];
|
|
grapple_walljump_timer = 0;
|
|
reached_ceres_elevator_fade_timer = 0;
|
|
samus_y_dir = 1;
|
|
}
|
|
|
|
void Samus_InitBombJump(void) { // 0x909A2C
|
|
static const uint16 kSamus_InitBombJump_Speed[3] = { 2, 0, 0 };
|
|
static const uint16 kSamus_InitBombJump_Subspeed[3] = { 0xc000, 0x1000, 0x1000 };
|
|
uint16 v0;
|
|
|
|
if ((equipped_items & 0x20) == 0) {
|
|
uint16 r18 = Samus_GetBottom_R18();
|
|
if ((fx_y_pos & 0x8000) != 0) {
|
|
if ((lava_acid_y_pos & 0x8000) == 0 && sign16(lava_acid_y_pos - r18)) {
|
|
v0 = 4;
|
|
goto LABEL_11;
|
|
}
|
|
} else if (sign16(fx_y_pos - r18) && (fx_liquid_options & 4) == 0) {
|
|
v0 = 2;
|
|
goto LABEL_11;
|
|
}
|
|
}
|
|
v0 = 0;
|
|
LABEL_11:;
|
|
int v1 = v0 >> 1;
|
|
samus_y_subspeed = kSamus_InitBombJump_Subspeed[v1];
|
|
samus_y_speed = kSamus_InitBombJump_Speed[v1];
|
|
grapple_walljump_timer = 0;
|
|
reached_ceres_elevator_fade_timer = 0;
|
|
samus_y_dir = 1;
|
|
}
|
|
|
|
int32 Samus_CalcBaseSpeed_X(uint16 k) { // 0x909A7E
|
|
SamusSpeedTableEntry *sste = get_SamusSpeedTableEntry(k);
|
|
uint16 r18, r20;
|
|
|
|
if (samus_x_accel_mode) {
|
|
if (samus_x_decel_mult) {
|
|
r20 = Mult8x8(samus_x_decel_mult, HIBYTE(sste->decel_sub));
|
|
r18 = Mult8x8(samus_x_decel_mult, sste->decel) >> 8;
|
|
} else {
|
|
r20 = sste->decel_sub;
|
|
r18 = sste->decel;
|
|
}
|
|
int16 v8 = (__PAIR32__(samus_x_base_speed, samus_x_base_subspeed) - __PAIR32__(r18, r20)) >> 16;
|
|
samus_x_base_subspeed -= r20;
|
|
samus_x_base_speed = v8;
|
|
if (v8 < 0) {
|
|
samus_x_base_speed = 0;
|
|
samus_x_base_subspeed = 0;
|
|
samus_x_accel_mode = 0;
|
|
}
|
|
} else {
|
|
bool v2 = __CFADD__uint16(sste->accel_sub, samus_x_base_subspeed);
|
|
samus_x_base_subspeed += sste->accel_sub;
|
|
uint16 v3 = sste->accel + v2 + samus_x_base_speed;
|
|
samus_x_base_speed = v3;
|
|
if ((int16)(v3 - sste->max_speed) >= 0) {
|
|
if (v3 != sste->max_speed
|
|
|| ((int16)(samus_x_base_subspeed - sste->max_speed_sub) >= 0)
|
|
&& samus_x_base_subspeed != sste->max_speed_sub) {
|
|
samus_x_base_speed = sste->max_speed;
|
|
samus_x_base_subspeed = sste->max_speed_sub;
|
|
}
|
|
}
|
|
}
|
|
return __PAIR32__(samus_x_base_speed, samus_x_base_subspeed);
|
|
}
|
|
|
|
static Pair_Bool_Amt Samus_CalcBaseSpeed_NoDecel_X(uint16 k) { // 0x909B1F
|
|
uint16 r18, r20;
|
|
SamusSpeedTableEntry *sste = get_SamusSpeedTableEntry(k);
|
|
|
|
if ((samus_x_accel_mode & 1) != 0) {
|
|
if (samus_x_decel_mult) {
|
|
r20 = Mult8x8(samus_x_decel_mult, HIBYTE(sste->decel_sub));
|
|
r18 = Mult8x8(samus_x_decel_mult, sste->decel) >> 8;
|
|
} else {
|
|
r20 = sste->decel_sub;
|
|
r18 = sste->decel;
|
|
}
|
|
int16 v8 = (__PAIR32__(samus_x_base_speed, samus_x_base_subspeed) - __PAIR32__(r18, r20)) >> 16;
|
|
samus_x_base_subspeed -= r20;
|
|
samus_x_base_speed = v8;
|
|
if (v8 < 0) {
|
|
samus_x_base_speed = 0;
|
|
samus_x_base_subspeed = 0;
|
|
samus_x_accel_mode = 0;
|
|
}
|
|
} else {
|
|
bool v2 = __CFADD__uint16(sste->accel_sub, samus_x_base_subspeed);
|
|
samus_x_base_subspeed += sste->accel_sub;
|
|
uint16 v3 = sste->accel + v2 + samus_x_base_speed;
|
|
samus_x_base_speed = v3;
|
|
if ((int16)(v3 - sste->max_speed) >= 0) {
|
|
if (v3 != sste->max_speed
|
|
|| ((int16)(samus_x_base_subspeed - sste->max_speed_sub) >= 0)
|
|
&& samus_x_base_subspeed != sste->max_speed_sub) {
|
|
samus_x_base_speed = sste->max_speed;
|
|
samus_x_base_subspeed = sste->max_speed_sub;
|
|
return (Pair_Bool_Amt) { true, __PAIR32__(samus_x_base_speed, samus_x_base_subspeed) };
|
|
}
|
|
}
|
|
}
|
|
return (Pair_Bool_Amt) { false, __PAIR32__(samus_x_base_speed, samus_x_base_subspeed) };
|
|
}
|
|
|
|
uint16 Samus_DetermineSpeedTableEntryPtr_X(void) { // 0x909BD1
|
|
if ((equipped_items & 0x20) == 0) {
|
|
uint16 r18 = Samus_GetBottom_R18();
|
|
if ((fx_y_pos & 0x8000) != 0) {
|
|
if ((lava_acid_y_pos & 0x8000) == 0 && sign16(lava_acid_y_pos - r18))
|
|
samus_x_speed_table_pointer = addr_kSamusSpeedTable_LavaAcid_X;
|
|
} else if (sign16(fx_y_pos - r18) && (fx_liquid_options & 4) == 0) {
|
|
samus_x_speed_table_pointer = addr_kSamusSpeedTable_Water_X;
|
|
}
|
|
}
|
|
return samus_x_speed_table_pointer + 12 * samus_movement_type;
|
|
}
|
|
|
|
uint16 Samus_DetermineGrappleSwingSpeed_X(void) { // 0x909C21
|
|
if ((equipped_items & 0x20) != 0)
|
|
return addr_stru_909F31;
|
|
uint16 r18 = Samus_GetBottom_R18();
|
|
if ((fx_y_pos & 0x8000) == 0) {
|
|
if (sign16(fx_y_pos - r18) && (fx_liquid_options & 4) == 0)
|
|
return addr_stru_909F3D;
|
|
return addr_stru_909F31;
|
|
}
|
|
if ((lava_acid_y_pos & 0x8000) != 0 || !sign16(lava_acid_y_pos - r18))
|
|
return addr_stru_909F31;
|
|
return addr_kSamusSpeedTable_Normal_X;
|
|
}
|
|
|
|
void Samus_DetermineAccel_Y(void) { // 0x909C5B
|
|
static const uint16 g_word_909EA1 = 0x1c00;
|
|
static const uint16 g_word_909EA3 = 0x800;
|
|
static const uint16 g_word_909EA5 = 0x900;
|
|
static const uint16 g_word_909EA7 = 0;
|
|
static const uint16 g_word_909EA9 = 0;
|
|
static const uint16 g_word_909EAB = 0;
|
|
static const uint16 g_word_909EAD = 1;
|
|
|
|
if ((equipped_items & 0x20) != 0)
|
|
goto LABEL_7;
|
|
uint16 r18 = Samus_GetBottom_R18();
|
|
if ((fx_y_pos & 0x8000) == 0) {
|
|
if (sign16(fx_y_pos - r18) && (fx_liquid_options & 4) == 0) {
|
|
samus_y_subaccel = g_word_909EA3;
|
|
samus_y_accel = g_word_909EA9;
|
|
return;
|
|
}
|
|
LABEL_7:
|
|
samus_y_subaccel = g_word_909EA1;
|
|
samus_y_accel = g_word_909EA7;
|
|
return;
|
|
}
|
|
if ((lava_acid_y_pos & 0x8000) != 0 || !sign16(lava_acid_y_pos - r18))
|
|
goto LABEL_7;
|
|
samus_y_subaccel = g_word_909EA5;
|
|
samus_y_accel = g_word_909EAB;
|
|
}
|
|
|
|
uint8 Samus_GrappleWallJumpCheck(int32 amt) { // 0x909CAC
|
|
enemy_index_to_shake = -1;
|
|
if (samus_pose_x_dir != 4) {
|
|
if (samus_pose_x_dir != 8)
|
|
return 0;
|
|
samus_collision_direction = 1;
|
|
} else {
|
|
samus_collision_direction = 0;
|
|
}
|
|
CheckEnemyColl_Result cres = Samus_CheckSolidEnemyColl(amt);
|
|
if (!cres.collision) {
|
|
amt = WallJumpBlockCollDetect(cres.amt);
|
|
return samus_collision_flag && (button_config_jump_a & joypad1_newkeys) != 0;
|
|
}
|
|
if ((button_config_jump_a & joypad1_newkeys) == 0)
|
|
return 0;
|
|
enemy_index_to_shake = collision_detection_index;
|
|
return 1;
|
|
}
|
|
|
|
uint8 Samus_WallJumpCheck(int32 amt) { // 0x909D35
|
|
CheckEnemyColl_Result cres;
|
|
|
|
if (samus_last_different_pose_movement_type != 3 && samus_last_different_pose_movement_type != 20)
|
|
return 0;
|
|
if (samus_pose == kPose_81_FaceR_Screwattack || samus_pose == kPose_82_FaceL_Screwattack) {
|
|
if (!sign16(samus_anim_frame - 27))
|
|
goto LABEL_22;
|
|
goto LABEL_8;
|
|
}
|
|
if (sign16(samus_anim_frame - 11)) {
|
|
LABEL_8:
|
|
if ((joypad1_lastkeys & kButton_Left) == 0) {
|
|
if ((joypad1_lastkeys & kButton_Right) == 0)
|
|
return 0;
|
|
samus_collision_direction = 0;
|
|
cres = Samus_CheckSolidEnemyColl(amt);
|
|
amt = cres.amt;
|
|
if (!cres.collision) {
|
|
amt = WallJumpBlockCollDetect(-amt);
|
|
if (!samus_collision_flag)
|
|
return 0;
|
|
}
|
|
} else {
|
|
samus_collision_direction = 1;
|
|
cres = Samus_CheckSolidEnemyColl(amt);
|
|
amt = cres.amt;
|
|
if (!cres.collision) {
|
|
amt = WallJumpBlockCollDetect(amt);
|
|
if (!samus_collision_flag)
|
|
return 0;
|
|
}
|
|
}
|
|
if (samus_pose == kPose_81_FaceR_Screwattack || samus_pose == kPose_82_FaceL_Screwattack) {
|
|
samus_anim_frame_timer = 1;
|
|
samus_anim_frame = 26;
|
|
} else {
|
|
samus_anim_frame_timer = 1;
|
|
samus_anim_frame = 10;
|
|
}
|
|
return 0;
|
|
}
|
|
LABEL_22:
|
|
enemy_index_to_shake = -1;
|
|
if ((joypad1_lastkeys & kButton_Left) != 0) {
|
|
samus_collision_direction = 1;
|
|
cres = Samus_CheckSolidEnemyColl(amt), amt = cres.amt;
|
|
if (!cres.collision) {
|
|
amt = WallJumpBlockCollDetect(amt);
|
|
if (samus_collision_flag && (button_config_jump_a & joypad1_newkeys) != 0)
|
|
goto LABEL_40;
|
|
return 0;
|
|
}
|
|
if ((button_config_jump_a & joypad1_newkeys) == 0)
|
|
return 0;
|
|
goto LABEL_38;
|
|
} else {
|
|
if ((joypad1_lastkeys & kButton_Right) == 0)
|
|
return 0;
|
|
samus_collision_direction = 0;
|
|
cres = Samus_CheckSolidEnemyColl(amt), amt = cres.amt;
|
|
if (!cres.collision) {
|
|
amt = -amt;
|
|
WallJumpBlockCollDetect(amt);
|
|
if (samus_collision_flag && (button_config_jump_a & joypad1_newkeys) != 0)
|
|
goto LABEL_40;
|
|
return 0;
|
|
}
|
|
if ((button_config_jump_a & joypad1_newkeys) == 0)
|
|
return 0;
|
|
goto LABEL_38;
|
|
|
|
LABEL_40:
|
|
if (sign16((amt >> 16) - 8)) {
|
|
input_to_pose_calc = 5;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
LABEL_38:
|
|
if (sign16((amt >> 16) - 8)) {
|
|
input_to_pose_calc = 5;
|
|
enemy_index_to_shake = collision_detection_index;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void Samus_Movement_07_Unused(void) { // 0x90A32D
|
|
input_to_pose_calc = 0;
|
|
}
|
|
|
|
static HandlerFunc *const kSamusMovementHandlers[28] = { // 0x90A337
|
|
&Samus_Movement_00_Standing,
|
|
&Samus_Movement_01_Running,
|
|
&Samus_Movement_02_NormalJumping,
|
|
&Samus_Movement_03_SpinJumping,
|
|
&Samus_Movement_04_MorphBallOnGround,
|
|
&Samus_Movement_05_Crouching,
|
|
&Samus_Movement_06_Falling,
|
|
&Samus_Movement_07_Unused,
|
|
&Samus_Movement_08_MorphBallFalling,
|
|
&Samus_Movement_09_Unused,
|
|
&Samus_Movement_0A_KnockbackOrCrystalFlashEnding,
|
|
&Samus_Movement_0B_Unused,
|
|
&Samus_Movement_0C_Unused,
|
|
&Samus_Movement_0D_Unused,
|
|
&Samus_Movement_0E_TurningAroundOnGround,
|
|
&Samus_Movement_0F_CrouchingEtcTransition,
|
|
&Samus_Movement_10_Moonwalking,
|
|
&Samus_Movement_11_SpringBallOnGround,
|
|
&Samus_Movement_12_SpringBallInAir,
|
|
&Samus_Movement_13_SpringBallFalling,
|
|
&Samus_Movement_14_WallJumping,
|
|
&Samus_Movement_15_RanIntoWall,
|
|
&Samus_Movement_16_Grappling,
|
|
&Samus_Movement_17_TurningAroundJumping,
|
|
&Samus_Movement_18_TurningAroundFalling,
|
|
&Samus_Movement_19_DamageBoost,
|
|
&Samus_Movement_1A_GrabbedByDraygon,
|
|
&Samus_Movement_1B_ShinesparkEtc,
|
|
};
|
|
|
|
void Samus_MovementHandler_Normal(void) {
|
|
if (!time_is_frozen_flag) {
|
|
kSamusMovementHandlers[samus_movement_type]();
|
|
Samus_UpdateSpeedEchoPos();
|
|
}
|
|
}
|
|
|
|
void Samus_Movement_00_Standing(void) { // 0x90A383
|
|
if (samus_pose && samus_pose != kPose_9B_FaceF_VariaGravitySuit) {
|
|
if ((samus_pose == kPose_01_FaceR_Normal || samus_pose == kPose_02_FaceL_Normal)
|
|
&& (button_config_shoot_x & joypad1_lastkeys) != 0) {
|
|
samus_anim_frame_timer = 16;
|
|
samus_anim_frame = 0;
|
|
}
|
|
Samus_Move_NoBaseSpeed_X();
|
|
Samus_Move_NoSpeedCalc_Y();
|
|
Samus_CancelSpeedBoost();
|
|
samus_x_extra_run_speed = 0;
|
|
samus_x_extra_run_subspeed = 0;
|
|
samus_x_base_speed = 0;
|
|
samus_x_base_subspeed = 0;
|
|
samus_x_accel_mode = 0;
|
|
} else {
|
|
if (elevator_status) {
|
|
samus_collision_direction = 2;
|
|
Samus_MoveDown_NoSolidColl(INT16_SHL16(1));
|
|
}
|
|
input_to_pose_calc = 0;
|
|
}
|
|
}
|
|
|
|
void Samus_Movement_01_Running(void) { // 0x90A3E5
|
|
static const uint8 kSamusFootstepFrame[10] = { 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 };
|
|
Samus_HandleMovement_X();
|
|
Samus_Move_NoSpeedCalc_Y();
|
|
if (samus_anim_frame_timer == 1) {
|
|
if (kSamusFootstepFrame[samus_anim_frame]) {
|
|
Samus_FootstepGraphics();
|
|
if (!cinematic_function && !boss_id && !samus_shine_timer && (speed_boost_counter & 0x400) == 0)
|
|
QueueSfx3_Max6(6);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Samus_Movement_02_NormalJumping(void) { // 0x90A42E
|
|
Samus_JumpingMovement();
|
|
}
|
|
|
|
// Warning: OOB
|
|
|
|
void Samus_Movement_03_SpinJumping(void) { // 0x90A436
|
|
static const uint16 kSamusPhys_JumpMinYVelAir = 0x280;
|
|
static const uint16 kSamusPhys_JumpMaxYVelAir = 0x500;
|
|
static const uint16 kSamusPhys_JumpMinYVelWater = 0x80;
|
|
static const uint16 kSamusPhys_JumpMaxYVelWater = 0x500;
|
|
uint16 r18 = 0;
|
|
if ((samus_suit_palette_index & 4) == 0) {
|
|
uint16 r20 = Samus_GetTop_R20();
|
|
if ((fx_y_pos & 0x8000) != 0) {
|
|
if ((lava_acid_y_pos & 0x8000) == 0 && sign16(lava_acid_y_pos - r20))
|
|
r18 = 1;
|
|
} else if (sign16(fx_y_pos - r20) && (fx_liquid_options & 4) == 0) {
|
|
r18 = 1;
|
|
}
|
|
}
|
|
if (!r18) {
|
|
if ((equipped_items & 0x200) != 0) {
|
|
if (samus_y_dir != 2)
|
|
goto LABEL_24;
|
|
if (liquid_physics_type) {
|
|
if ((int16)(*(uint16 *)((uint8 *)&samus_y_subspeed + 1) - kSamusPhys_JumpMinYVelWater) < 0
|
|
|| (int16)(*(uint16 *)((uint8 *)&samus_y_subspeed + 1) - kSamusPhys_JumpMaxYVelWater) >= 0) {
|
|
goto LABEL_24;
|
|
}
|
|
} else if ((int16)(*(uint16 *)((uint8 *)&samus_y_subspeed + 1) - kSamusPhys_JumpMinYVelAir) < 0
|
|
|| (int16)(*(uint16 *)((uint8 *)&samus_y_subspeed + 1) - kSamusPhys_JumpMaxYVelAir) >= 0) {
|
|
goto LABEL_24;
|
|
}
|
|
UNUSED_word_7E0DFA = UNUSED_word_7E0DFA & 0xFF00 | 1;
|
|
if ((button_config_jump_a & joypad1_newkeys) != 0)
|
|
Samus_InitJump(); // bug: this overwrites r18
|
|
}
|
|
LABEL_24:;
|
|
if (samus_pose == kPose_81_FaceR_Screwattack || samus_pose == kPose_82_FaceL_Screwattack) {
|
|
samus_contact_damage_index = 3;
|
|
} else if (!sign16(flare_counter - 60)) {
|
|
samus_contact_damage_index = 4;
|
|
}
|
|
} else {
|
|
if (samus_anim_frame_timer == 1 && kSamusFramesForUnderwaterSfx[samus_anim_frame])
|
|
QueueSfx1_Max6(0x2F);
|
|
}
|
|
Samus_SpinJumpMovement();
|
|
}
|
|
|
|
void Samus_Movement_04_MorphBallOnGround(void) { // 0x90A521
|
|
if (!samus_x_accel_mode) {
|
|
if (samus_pose_x_dir == 4) {
|
|
if (samus_pose == kPose_41_FaceL_Morphball_Ground)
|
|
goto LABEL_6;
|
|
} else if (samus_pose == kPose_1D_FaceR_Morphball_Ground) {
|
|
LABEL_6:
|
|
Samus_Move_NoBaseSpeed_X();
|
|
if (!(Samus_CheckAndMoveY() & 1)) {
|
|
Samus_Move_NoSpeedCalc_Y();
|
|
Samus_CancelSpeedBoost();
|
|
samus_x_extra_run_speed = 0;
|
|
samus_x_extra_run_subspeed = 0;
|
|
samus_x_base_speed = 0;
|
|
samus_x_base_subspeed = 0;
|
|
samus_x_accel_mode = 0;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
Samus_HandleMovement_X();
|
|
if (!(Samus_CheckAndMoveY() & 1))
|
|
Samus_Move_NoSpeedCalc_Y();
|
|
}
|
|
|
|
void Samus_Movement_05_Crouching(void) { // 0x90A573
|
|
Samus_Move_NoBaseSpeed_X();
|
|
Samus_Move_NoSpeedCalc_Y();
|
|
samus_x_extra_run_speed = 0;
|
|
samus_x_extra_run_subspeed = 0;
|
|
samus_x_base_speed = 0;
|
|
samus_x_base_subspeed = 0;
|
|
samus_x_accel_mode = 0;
|
|
}
|
|
|
|
void Samus_Movement_06_Falling(void) { // 0x90A58D
|
|
Samus_FallingMovement();
|
|
if ((samus_pose == kPose_29_FaceR_Fall
|
|
|| samus_pose == kPose_2A_FaceL_Fall
|
|
|| samus_pose == kPose_67_FaceR_Fall_Gun
|
|
|| samus_pose == kPose_68_FaceL_Fall_Gun)
|
|
&& !sign16(samus_y_speed - 5)) {
|
|
if (sign16(samus_anim_frame - 5)) {
|
|
samus_anim_frame_timer = 8;
|
|
samus_anim_frame = 5;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Samus_Movement_08_MorphBallFalling(void) { // 0x90A5CA
|
|
if ((joypad1_lastkeys & (kButton_Left | kButton_Right)) == 0 && !samus_x_accel_mode) {
|
|
Samus_CancelSpeedBoost();
|
|
samus_x_extra_run_speed = 0;
|
|
samus_x_extra_run_subspeed = 0;
|
|
samus_x_base_speed = 0;
|
|
samus_x_base_subspeed = 0;
|
|
samus_x_accel_mode = 0;
|
|
}
|
|
if (used_for_ball_bounce_on_landing)
|
|
Samus_MorphedBouncingMovement();
|
|
else
|
|
Samus_MorphedFallingMovement();
|
|
}
|
|
|
|
void Samus_Movement_09_Unused(void) { // 0x90A5FB
|
|
;
|
|
}
|
|
|
|
void Samus_Movement_0A_KnockbackOrCrystalFlashEnding(void) { // 0x90A5FC
|
|
input_to_pose_calc = 0;
|
|
Samus_Move_NoSpeedCalc_Y();
|
|
}
|
|
|
|
void Samus_Movement_0B_Unused(void) { // 0x90A607
|
|
input_to_pose_calc = 0;
|
|
}
|
|
|
|
void Samus_Movement_0C_Unused(void) { // 0x90A60F
|
|
input_to_pose_calc = 0;
|
|
}
|
|
|
|
void Samus_Movement_0D_Unused(void) { // 0x90A617
|
|
;
|
|
}
|
|
|
|
void nullsub_13(void) {}
|
|
|
|
static HandlerFunc *const kSamusCrouchingEtcFuncs[12] = { // 0x90A61C
|
|
nullsub_13,
|
|
nullsub_13,
|
|
nullsub_13,
|
|
nullsub_13,
|
|
SamusCrouchingEtcFunc,
|
|
SamusCrouchingEtcFunc,
|
|
nullsub_13,
|
|
nullsub_13,
|
|
nullsub_13,
|
|
nullsub_13,
|
|
SamusCrouchingEtcFunc,
|
|
SamusCrouchingEtcFunc,
|
|
};
|
|
|
|
void Samus_Movement_0F_CrouchingEtcTransition(void) {
|
|
if (sign16(samus_pose - kPose_F1_FaceR_CrouchTrans_AimU)) {
|
|
if (!sign16(samus_pose - kPose_DB))
|
|
goto LABEL_6;
|
|
kSamusCrouchingEtcFuncs[samus_pose - 53]();
|
|
}
|
|
Samus_Move_NoBaseSpeed_X();
|
|
if (!(Samus_MoveY_Simple_() & 1))
|
|
Samus_Move_NoSpeedCalc_Y();
|
|
LABEL_6:
|
|
if (input_to_pose_calc == 1025) {
|
|
samus_y_subspeed = 0;
|
|
samus_y_speed = 0;
|
|
samus_y_dir = 0;
|
|
used_for_ball_bounce_on_landing = 0;
|
|
}
|
|
input_to_pose_calc = 0;
|
|
}
|
|
|
|
void SamusCrouchingEtcFunc(void) { // 0x90A672
|
|
enable_horiz_slope_coll = 3;
|
|
UNUSEDword_7E0AA4 = 0;
|
|
}
|
|
|
|
void Samus_Movement_0E_TurningAroundOnGround(void) { // 0x90A67C
|
|
Samus_HandleMovement_X();
|
|
Samus_Move_NoSpeedCalc_Y();
|
|
Samus_CancelSpeedBoost();
|
|
samus_x_extra_run_speed = 0;
|
|
samus_x_extra_run_subspeed = 0;
|
|
input_to_pose_calc = 0;
|
|
}
|
|
|
|
void Samus_Movement_10_Moonwalking(void) { // 0x90A694
|
|
Samus_HandleMovement_X();
|
|
Samus_Move_NoSpeedCalc_Y();
|
|
}
|
|
|
|
void Samus_Movement_11_SpringBallOnGround(void) { // 0x90A69F
|
|
if (!samus_x_accel_mode) {
|
|
if (samus_pose_x_dir == 4) {
|
|
if (samus_pose == kPose_7A_FaceL_Springball_Ground)
|
|
goto LABEL_6;
|
|
} else if (samus_pose == kPose_79_FaceR_Springball_Ground) {
|
|
LABEL_6:
|
|
Samus_Move_NoBaseSpeed_X();
|
|
if (!(Samus_CheckAndMoveY() & 1)) {
|
|
Samus_Move_NoSpeedCalc_Y();
|
|
Samus_CancelSpeedBoost();
|
|
samus_x_extra_run_speed = 0;
|
|
samus_x_extra_run_subspeed = 0;
|
|
samus_x_base_speed = 0;
|
|
samus_x_base_subspeed = 0;
|
|
samus_x_accel_mode = 0;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
Samus_HandleMovement_X();
|
|
if (!(Samus_CheckAndMoveY() & 1))
|
|
Samus_Move_NoSpeedCalc_Y();
|
|
}
|
|
|
|
void Samus_Movement_12_SpringBallInAir(void) { // 0x90A6F1
|
|
if (used_for_ball_bounce_on_landing)
|
|
Samus_MorphedBouncingMovement();
|
|
else
|
|
Samus_JumpingMovement();
|
|
}
|
|
|
|
void Samus_Movement_13_SpringBallFalling(void) { // 0x90A703
|
|
if ((joypad1_lastkeys & (kButton_Left | kButton_Right)) == 0 && !samus_x_accel_mode) {
|
|
Samus_CancelSpeedBoost();
|
|
samus_x_extra_run_speed = 0;
|
|
samus_x_extra_run_subspeed = 0;
|
|
samus_x_base_speed = 0;
|
|
samus_x_base_subspeed = 0;
|
|
samus_x_accel_mode = 0;
|
|
}
|
|
if (used_for_ball_bounce_on_landing)
|
|
Samus_MorphedBouncingMovement();
|
|
else
|
|
Samus_MorphedFallingMovement();
|
|
}
|
|
|
|
void Samus_Movement_14_WallJumping(void) { // 0x90A734
|
|
if (sign16(samus_anim_frame - 23)) {
|
|
if (!sign16(samus_anim_frame - 3) && !sign16(flare_counter - 60))
|
|
samus_contact_damage_index = 4;
|
|
} else {
|
|
samus_contact_damage_index = 3;
|
|
}
|
|
Samus_JumpingMovement();
|
|
}
|
|
|
|
void Samus_Movement_15_RanIntoWall(void) { // 0x90A75F
|
|
Samus_Move_NoBaseSpeed_X();
|
|
Samus_Move_NoSpeedCalc_Y();
|
|
Samus_CancelSpeedBoost();
|
|
samus_x_extra_run_speed = 0;
|
|
samus_x_extra_run_subspeed = 0;
|
|
samus_x_base_speed = 0;
|
|
samus_x_base_subspeed = 0;
|
|
samus_x_accel_mode = 0;
|
|
}
|
|
|
|
void Samus_Movement_16_Grappling(void) { // 0x90A780
|
|
if (input_to_pose_calc != 5)
|
|
input_to_pose_calc = 0;
|
|
}
|
|
|
|
void Samus_Movement_17_TurningAroundJumping(void) { // 0x90A790
|
|
Samus_HandleMovement_X();
|
|
if (!(Samus_CheckAndMoveY() & 1))
|
|
Samus_Move_NoSpeedCalc_Y();
|
|
Samus_CancelSpeedBoost();
|
|
samus_x_extra_run_speed = 0;
|
|
samus_x_extra_run_subspeed = 0;
|
|
input_to_pose_calc = 0;
|
|
}
|
|
|
|
void Samus_Movement_18_TurningAroundFalling(void) { // 0x90A7AD
|
|
Samus_HandleMovement_X();
|
|
if (!(Samus_CheckAndMoveY() & 1))
|
|
Samus_Move_NoSpeedCalc_Y();
|
|
Samus_CancelSpeedBoost();
|
|
samus_x_extra_run_speed = 0;
|
|
samus_x_extra_run_subspeed = 0;
|
|
input_to_pose_calc = 0;
|
|
}
|
|
|
|
void Samus_Movement_19_DamageBoost(void) { // 0x90A7CA
|
|
Samus_JumpingMovement();
|
|
}
|
|
|
|
void Samus_Movement_1A_GrabbedByDraygon(void) { // 0x90A7D2
|
|
input_to_pose_calc = 0;
|
|
}
|
|
|
|
void Samus_Movement_1B_ShinesparkEtc(void) { // 0x90A7DA
|
|
input_to_pose_calc = 0;
|
|
}
|
|
|
|
static const uint8 kShr0x80[8] = { 0x80, 0x40, 0x20, 0x10, 8, 4, 2, 1 };
|
|
static const uint16 kShr0xFc00[8] = { 0xfc00, 0x7e00, 0x3f00, 0x1f80, 0xfc0, 0x7e0, 0x3f0, 0x1f8 };
|
|
|
|
static void MarkMapTileAsExplored(uint16 r18, uint16 r24) { // 0x90A8A6
|
|
uint8 v0 = (uint16)(r18 & 0xFF00) >> 8;
|
|
uint16 R34 = (room_x_coordinate_on_map + v0) & 0x20;
|
|
uint16 r20 = ((room_x_coordinate_on_map + v0) & 0x1F) >> 3;
|
|
uint16 R22 = room_y_coordinate_on_map + ((r24 & 0xFF00) >> 8) + 1;
|
|
map_tiles_explored[(uint16)(r20 + 4 * (R34 + R22))] |= kShr0x80[(room_x_coordinate_on_map + v0) & 7];
|
|
}
|
|
|
|
void DisableMinimapAndMarkBossRoomAsExplored(void) { // 0x90A7E2
|
|
debug_disable_minimap = 1;
|
|
uint16 v0 = 0;
|
|
do {
|
|
int v1 = v0 >> 1;
|
|
hud_tilemap[v1 + 26] = 11295;
|
|
hud_tilemap[v1 + 58] = 11295;
|
|
hud_tilemap[v1 + 90] = 11295;
|
|
v0 += 2;
|
|
} while ((int16)(v0 - 10) < 0);
|
|
uint16 v2 = 5;
|
|
while (boss_id != g_stru_90A83A[v2].boss_id_) {
|
|
if ((--v2 & 0x8000) != 0)
|
|
return;
|
|
}
|
|
for (int i = g_stru_90A83A[v2].ptrs; ; i += 4) {
|
|
const uint16 *v4 = (const uint16 *)RomPtr_90(i);
|
|
if ((*v4 & 0x8000) != 0)
|
|
break;
|
|
MarkMapTileAsExplored(v4[0], v4[1]);
|
|
}
|
|
}
|
|
|
|
void InitializeMiniMapBroken(void) { // 0x90A8EF
|
|
//SetR18_R20(room_x_coordinate_on_map + ((samus_x_pos & 0xFF00) >> 8), r18 >> 3);
|
|
//R22_ = room_y_coordinate_on_map + ((samus_y_pos & 0xFF00) >> 8) + 1;
|
|
//UpdateMinimapInside();
|
|
}
|
|
|
|
|
|
void UpdateMinimap(void) { // 0x90A91B
|
|
int16 v4;
|
|
int16 v10;
|
|
LongPtr r9;
|
|
|
|
if (debug_disable_minimap || (samus_x_pos >> 4) >= room_width_in_blocks ||
|
|
(samus_y_pos >> 4) >= room_height_in_blocks)
|
|
return;
|
|
uint16 r46 = 0;
|
|
uint8 v0 = (uint16)(samus_x_pos & 0xFF00) >> 8;
|
|
uint16 r34 = (room_x_coordinate_on_map + v0) & 0x20;
|
|
uint16 r18 = (room_x_coordinate_on_map + v0) & 0x1F;
|
|
uint16 v1 = (room_x_coordinate_on_map + v0) & 7;
|
|
uint16 r20 = ((room_x_coordinate_on_map + v0) & 0x1F) >> 3;
|
|
uint16 r22 = room_y_coordinate_on_map + ((samus_y_pos & 0xFF00) >> 8) + 1;
|
|
uint16 v2 = r20 + 4 * (r34 + r22);
|
|
map_tiles_explored[v2] |= kShr0x80[(room_x_coordinate_on_map + v0) & 7];
|
|
uint16 r32 = v1;
|
|
uint16 r30 = v2;
|
|
uint16 v3 = v2 - 4;
|
|
v4 = v1 - 2;
|
|
if ((int16)(v1 - 2) < 0) {
|
|
v4 &= 7;
|
|
--v3;
|
|
++r46;
|
|
}
|
|
uint16 R50 = v3;
|
|
bg3_tilemap_offset = 2 * v4;
|
|
int v6 = bg3_tilemap_offset >> 1;
|
|
uint16 r24 = kShr0xFc00[v6] & swap16(*(uint16 *)&map_tiles_explored[v3]);
|
|
uint16 r26 = kShr0xFc00[v6] & swap16(*(uint16 *)&map_tiles_explored[v3 + 4]);
|
|
uint16 r28 = kShr0xFc00[v6] & swap16(*(uint16 *)&map_tiles_explored[v3 + 8]);
|
|
r9.bank = 130;
|
|
r9.addr = kPauseMenuMapData[area_index];
|
|
uint16 r15 = r9.addr;
|
|
r9.addr += v3;
|
|
uint16 r38 = swap16(IndirReadWord(r9, 0));
|
|
r9.addr += 4;
|
|
uint16 r40 = swap16(IndirReadWord(r9, 0));
|
|
r9.addr += 4;
|
|
uint16 r42 = swap16(IndirReadWord(r9, 0));
|
|
if ((R50 & 3) == 3) {
|
|
v10 = r46 ? bg3_tilemap_offset >> 1 : r32;
|
|
if (!sign16(v10 - 6)) {
|
|
uint8 R48 = r34 ? (R50 - 124) : (R50 + 125);
|
|
|
|
uint16 v0 = (uint8)R48;
|
|
uint16 r44 = 0;
|
|
r9.addr = r15 + (uint8)R48;
|
|
LOBYTE(r44) = map_tiles_explored[(uint8)R48];
|
|
HIBYTE(r44) = IndirReadByte(r9, 0);
|
|
if ((uint8)r34 == 32) {
|
|
HIBYTE(r38) = HIBYTE(r44);
|
|
HIBYTE(r24) = r44;
|
|
} else {
|
|
LOBYTE(r38) = HIBYTE(r44);
|
|
LOBYTE(r24) = r44;
|
|
}
|
|
LOBYTE(r44) = map_tiles_explored[v0 + 4];
|
|
r9.addr += 4;
|
|
HIBYTE(r44) = IndirReadByte(r9, 0);
|
|
if ((uint8)r34 == 32) {
|
|
HIBYTE(r40) = HIBYTE(r44);
|
|
HIBYTE(r26) = r44;
|
|
} else {
|
|
LOBYTE(r40) = HIBYTE(r44);
|
|
LOBYTE(r26) = r44;
|
|
}
|
|
LOBYTE(r44) = map_tiles_explored[v0 + 8];
|
|
r9.addr += 4;
|
|
HIBYTE(r44) = IndirReadByte(r9, 0);
|
|
if ((uint8)r34 == 32) {
|
|
HIBYTE(r42) = HIBYTE(r44);
|
|
HIBYTE(r28) = r44;
|
|
} else {
|
|
LOBYTE(r42) = HIBYTE(r44);
|
|
LOBYTE(r28) = r44;
|
|
}
|
|
}
|
|
}
|
|
for (int n = bg3_tilemap_offset >> 1; n; n--) {
|
|
r24 *= 2;
|
|
r38 *= 2;
|
|
r26 *= 2;
|
|
r40 *= 2;
|
|
r28 *= 2;
|
|
r42 *= 2;
|
|
}
|
|
UpdateMinimapInside(r18, r22, r34, r30, r32, r38, r24, r40, r26, r42, r28);
|
|
}
|
|
|
|
void UpdateMinimapInside(uint16 r18, uint16 r22, uint16 r34, uint16 r30, uint16 r32,
|
|
uint16 r38, uint16 r24, uint16 r40,
|
|
uint16 r26, uint16 r42, uint16 r28) { // 0x90AA43
|
|
uint16 v0;
|
|
int16 v1;
|
|
int16 v5;
|
|
int16 v7;
|
|
int16 v8;
|
|
LongPtr r0, r3, r6;
|
|
|
|
LOBYTE(v0) = (uint16)(r34 + r22) >> 8;
|
|
HIBYTE(v0) = r34 + r22;
|
|
uint16 t = r18 + (v0 >> 3);
|
|
if (r34 && sign16((t & 0x1F) - 2))
|
|
v1 = t - 1026;
|
|
else
|
|
v1 = t - 34;
|
|
uint16 v2 = 2 * v1;
|
|
r0 = kPauseMenuMapTilemaps[area_index];
|
|
r3.bank = r0.bank;
|
|
r6.bank = r0.bank;
|
|
r3.addr = r0.addr + 64;
|
|
r6.addr = r0.addr + 128;
|
|
int n = 5;
|
|
uint16 v3 = 0;
|
|
do {
|
|
bool v4 = r38 >> 15;
|
|
r38 *= 2;
|
|
if (!v4 || (v5 = IndirReadWord(r0, v2), !has_area_map))
|
|
v5 = 31;
|
|
int v6 = v3 >> 1;
|
|
hud_tilemap[v6 + 26] = v5 & 0xC3FF | 0x2C00;
|
|
|
|
v4 = r24 >> 15;
|
|
r24 *= 2;
|
|
if (v4)
|
|
hud_tilemap[v6 + 26] = IndirReadWord(r0, v2) & 0xC3FF | 0x2800;
|
|
|
|
v4 = r40 >> 15;
|
|
r40 *= 2;
|
|
if (!v4 || (v7 = IndirReadWord(r3, v2), !has_area_map))
|
|
v7 = 31;
|
|
hud_tilemap[v6 + 58] = v7 & 0xC3FF | 0x2C00;
|
|
|
|
v4 = r26 >> 15;
|
|
r26 *= 2;
|
|
if (v4) {
|
|
hud_tilemap[v6 + 58] = IndirReadWord(r3, v2) & 0xC3FF | 0x2800;
|
|
if (n == 3 && (hud_tilemap[v6 + 58] & 0x1FF) == 40) {
|
|
// MarkMapTileAboveSamusAsExplored
|
|
*((uint8 *)&music_data_index + r30) |= kShr0x80[r32];
|
|
}
|
|
}
|
|
|
|
v4 = r42 >> 15;
|
|
r42 *= 2;
|
|
if (!v4 || (v8 = IndirReadWord(r6, v2), !has_area_map))
|
|
v8 = 31;
|
|
hud_tilemap[v6 + 90] = v8 & 0xC3FF | 0x2C00;
|
|
|
|
v4 = r28 >> 15;
|
|
r28 *= 2;
|
|
if (v4)
|
|
hud_tilemap[v6 + 90] = IndirReadWord(r6, v2) & 0xC3FF | 0x2800;
|
|
|
|
v3 += 2;
|
|
v2 += 2;
|
|
if ((v2 & 0x3F) == 0)
|
|
v2 += 1984;
|
|
} while (--n);
|
|
if ((nmi_frame_counter_byte & 8) == 0)
|
|
hud_tilemap[60] |= 0x1C00;
|
|
}
|
|
|
|
void Samus_HandleCooldown(void) { // 0x90AC1C
|
|
if (time_is_frozen_flag) {
|
|
cooldown_timer = 32;
|
|
} else if (cooldown_timer) {
|
|
if ((cooldown_timer & 0x8000) != 0 || (--cooldown_timer, (cooldown_timer & 0x8000) != 0))
|
|
cooldown_timer = 0;
|
|
}
|
|
}
|
|
|
|
uint8 Samus_CanFireBeam(void) { // 0x90AC39
|
|
if (!sign16(projectile_counter - 5) || (uint8)cooldown_timer)
|
|
return 0;
|
|
cooldown_timer = 1;
|
|
++projectile_counter;
|
|
return 1;
|
|
}
|
|
|
|
uint8 Samus_CanFireSuperMissile(void) { // 0x90AC5A
|
|
if (hud_item_index != 2) {
|
|
if (!sign16(projectile_counter - 5))
|
|
return 0;
|
|
LABEL_3:
|
|
if (!(uint8)cooldown_timer) {
|
|
cooldown_timer = 1;
|
|
++projectile_counter;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
if (sign16(projectile_counter - 4))
|
|
goto LABEL_3;
|
|
return 0;
|
|
}
|
|
|
|
|
|
void UpdateBeamTilesAndPalette(void) { // 0x90AC8D
|
|
uint16 v0 = 2 * (equipped_beams & 0xFFF);
|
|
uint16 v1 = vram_write_queue_tail;
|
|
gVramWriteEntry(vram_write_queue_tail)->size = 256;
|
|
v1 += 2;
|
|
gVramWriteEntry(v1)->size = kBeamTilePtrs[v0 >> 1];
|
|
v1 += 2;
|
|
LOBYTE(gVramWriteEntry(v1++)->size) = -102;
|
|
gVramWriteEntry(v1)->size = addr_unk_606300;
|
|
vram_write_queue_tail = v1 + 2;
|
|
WriteBeamPalette_Y(v0);
|
|
}
|
|
|
|
void WriteBeamPalette_A(uint16 a) { // 0x90ACC2
|
|
WriteBeamPalette_Y(2 * (a & 0xFFF));
|
|
}
|
|
|
|
void WriteBeamPalette_Y(uint16 j) { // 0x90ACCD
|
|
uint16 r0 = kBeamPalettePtrs[j >> 1];
|
|
uint16 v1 = 0;
|
|
uint16 v2 = 0;
|
|
do {
|
|
palette_buffer[(v2 >> 1) + 224] = GET_WORD(RomPtr_90(r0 + v1));
|
|
v2 += 2;
|
|
v1 += 2;
|
|
} while ((int16)(v1 - 32) < 0);
|
|
}
|
|
|
|
void LoadProjectilePalette(uint16 a) { // 0x90ACFC
|
|
uint16 r0 = kBeamPalettePtrs[a & 0xFFF];
|
|
uint16 v1 = 0;
|
|
uint16 v2 = 0;
|
|
do {
|
|
palette_buffer[(v2 >> 1) + 224] = GET_WORD(RomPtr_90(r0 + v1));
|
|
v2 += 2;
|
|
v1 += 2;
|
|
} while ((int16)(v1 - 32) < 0);
|
|
}
|
|
|
|
void ResetProjectileData(void) { // 0x90AD22
|
|
uint16 v0 = 0;
|
|
do {
|
|
int v1 = v0 >> 1;
|
|
projectile_timers[v1] = 0;
|
|
projectile_x_pos[v1] = 0;
|
|
projectile_y_pos[v1] = 0;
|
|
projectile_dir[v1] = 0;
|
|
projectile_bomb_x_speed[v1] = 0;
|
|
projectile_bomb_y_speed[v1] = 0;
|
|
projectile_x_radius[v1] = 0;
|
|
projectile_y_radius[v1] = 0;
|
|
projectile_type[v1] = 0;
|
|
projectile_damage[v1] = 0;
|
|
projectile_bomb_instruction_ptr[v1] = 0;
|
|
projectile_bomb_instruction_timers[v1] = 0;
|
|
projectile_variables[v1] = 0;
|
|
projectile_spritemap_pointers[v1] = 0;
|
|
projectile_bomb_pre_instructions[v1] = FUNC16(ProjPreInstr_Empty);
|
|
v0 += 2;
|
|
} while ((int16)(v0 - 20) < 0);
|
|
bomb_counter = 0;
|
|
cooldown_timer = 0;
|
|
projectile_counter = 0;
|
|
power_bomb_flag = 0;
|
|
if (hud_auto_cancel_flag) {
|
|
hud_item_index = 0;
|
|
samus_auto_cancel_hud_item_index = 0;
|
|
}
|
|
speed_echo_xpos[0] = 0;
|
|
speed_echo_xpos[1] = 0;
|
|
speed_echo_xpos[2] = 0;
|
|
speed_echo_xpos[3] = 0;
|
|
speed_echo_ypos[0] = 0;
|
|
speed_echo_ypos[1] = 0;
|
|
speed_echo_ypos[2] = 0;
|
|
speed_echo_ypos[3] = 0;
|
|
speed_echo_xspeed[0] = 0;
|
|
speed_echo_xspeed[1] = 0;
|
|
speed_echo_xspeed[2] = 0;
|
|
speed_echo_xspeed[3] = 0;
|
|
speed_echoes_index = 0;
|
|
if (samus_special_super_palette_flags) {
|
|
samus_special_super_palette_flags = 0;
|
|
Samus_LoadSuitTargetPalette();
|
|
}
|
|
if (hyper_beam_flag)
|
|
SpawnPalfxObject(addr_stru_8DE1F0);
|
|
}
|
|
|
|
void ClearProjectile(uint16 k) { // 0x90ADB7
|
|
int v1 = k >> 1;
|
|
projectile_x_pos[v1] = 0;
|
|
projectile_y_pos[v1] = 0;
|
|
projectile_bomb_x_subpos[v1] = 0;
|
|
projectile_bomb_y_subpos[v1] = 0;
|
|
projectile_dir[v1] = 0;
|
|
projectile_bomb_x_speed[v1] = 0;
|
|
projectile_bomb_y_speed[v1] = 0;
|
|
projectile_x_radius[v1] = 0;
|
|
projectile_y_radius[v1] = 0;
|
|
projectile_type[v1] = 0;
|
|
projectile_damage[v1] = 0;
|
|
projectile_bomb_instruction_ptr[v1] = 0;
|
|
projectile_bomb_instruction_timers[v1] = 0;
|
|
projectile_variables[v1] = 0;
|
|
projectile_spritemap_pointers[v1] = 0;
|
|
projectile_bomb_pre_instructions[v1] = FUNC16(ProjPreInstr_Empty);
|
|
if ((int16)(k - 10) >= 0) {
|
|
if ((--bomb_counter & 0x8000) != 0)
|
|
bomb_counter = 0;
|
|
} else if ((--projectile_counter & 0x8000) != 0) {
|
|
projectile_counter = 0;
|
|
}
|
|
}
|
|
|
|
static Func_Y_V *const kKillProjectileFuncs[10] = { // 0x90AE06
|
|
KillProjectileFunc_0,
|
|
KillProjectileFunc_1,
|
|
KillProjectileFunc_2,
|
|
KillProjectileFunc_3,
|
|
KillProjectileFunc_4,
|
|
KillProjectileFunc_4,
|
|
KillProjectileFunc_6,
|
|
KillProjectileFunc_7,
|
|
KillProjectileFunc_8,
|
|
KillProjectileFunc_0,
|
|
};
|
|
|
|
void KillProjectile(uint16 k) {
|
|
|
|
int v1 = k >> 1;
|
|
if ((projectile_type[v1] & 0xF00) != 0) {
|
|
if (!sign16((HIBYTE(projectile_type[v1]) & 0xF) - 3)) {
|
|
ClearProjectile(k);
|
|
return;
|
|
}
|
|
} else {
|
|
kKillProjectileFuncs[projectile_dir[v1] & 0xF](k);
|
|
}
|
|
KillProjectileInner(k);
|
|
projectile_bomb_pre_instructions[k >> 1] = FUNC16(ProjPreInstr_Empty);
|
|
}
|
|
|
|
void KillProjectileFunc_0(uint16 j) { // 0x90AE4E
|
|
projectile_y_pos[j >> 1] -= projectile_y_radius[j >> 1];
|
|
}
|
|
|
|
void KillProjectileFunc_1(uint16 j) { // 0x90AE59
|
|
int v1 = j >> 1;
|
|
projectile_x_pos[v1] += projectile_x_radius[v1];
|
|
projectile_y_pos[v1] -= projectile_y_radius[v1];
|
|
}
|
|
|
|
void KillProjectileFunc_2(uint16 j) { // 0x90AE6E
|
|
projectile_x_pos[j >> 1] += projectile_x_radius[j >> 1];
|
|
}
|
|
|
|
void KillProjectileFunc_3(uint16 j) { // 0x90AE79
|
|
int v1 = j >> 1;
|
|
projectile_x_pos[v1] += projectile_x_radius[v1];
|
|
projectile_y_pos[v1] += projectile_y_radius[v1];
|
|
}
|
|
|
|
void KillProjectileFunc_4(uint16 j) { // 0x90AE8E
|
|
projectile_y_pos[j >> 1] += projectile_y_radius[j >> 1];
|
|
}
|
|
|
|
void KillProjectileFunc_6(uint16 j) { // 0x90AE99
|
|
int v1 = j >> 1;
|
|
projectile_x_pos[v1] -= projectile_x_radius[v1];
|
|
projectile_y_pos[v1] += projectile_y_radius[v1];
|
|
}
|
|
|
|
void KillProjectileFunc_7(uint16 j) { // 0x90AEAE
|
|
projectile_x_pos[j >> 1] -= projectile_x_radius[j >> 1];
|
|
}
|
|
|
|
void KillProjectileFunc_8(uint16 j) { // 0x90AEB9
|
|
int v1 = j >> 1;
|
|
projectile_x_pos[v1] -= projectile_x_radius[v1];
|
|
projectile_y_pos[v1] -= projectile_y_radius[v1];
|
|
}
|
|
|
|
void CallProjPreInstr(uint32 ea, uint16 k) {
|
|
switch (ea) {
|
|
case fnProjPreInstr_Empty: return;
|
|
case fnProjPreInstr_Beam_NoWaveBeam: ProjPreInstr_Beam_NoWaveBeam(k); return;
|
|
case fnProjPreInstr_Dir0459: ProjPreInstr_Dir0459(k); return;
|
|
case fnProjPreInstr_Dir1368: ProjPreInstr_Dir1368(k); return;
|
|
case fnProjPreInstr_Dir27: ProjPreInstr_Dir27(k); return;
|
|
case fnProjPreInstr_Missile: ProjPreInstr_Missile(k); return;
|
|
case fnProjPreInstr_Missile_Func0459: ProjPreInstr_Missile_Func0459(k); return;
|
|
case fnProjPreInstr_Missile_Func1368: ProjPreInstr_Missile_Func1368(k); return;
|
|
case fnProjPreInstr_Missile_Func27: ProjPreInstr_Missile_Func27(k); return;
|
|
case fnProjPreInstr_SuperMissile: ProjPreInstr_SuperMissile(k); return;
|
|
case fnProjPreInstr_SuperMissile_Func0459: ProjPreInstr_SuperMissile_Func0459(k); return;
|
|
case fnProjPreInstr_SuperMissile_Func1368: ProjPreInstr_SuperMissile_Func1368(k); return;
|
|
case fnProjPreInstr_SuperMissile_Func27: ProjPreInstr_SuperMissile_Func27(k); return;
|
|
case fnProjPreInstr_Func1: ProjPreInstr_Func1(k); return;
|
|
case fnProjPreInstr_Bomb: ProjPreInstr_Bomb(k); return;
|
|
case fnProjPreInstr_PowerBomb: ProjPreInstr_PowerBomb(k); return;
|
|
case fnProjPreInstr_WavePlasmaEtc: ProjPreInstr_WavePlasmaEtc(k); return;
|
|
case fnProjPreInstr_BeamOrIceWave: ProjPreInstr_BeamOrIceWave(k); return;
|
|
case fnProjPreInstr_Wave_Shared: ProjPreInstr_Wave_Shared(k); return;
|
|
case fnProjPreInstr_WavePlasmaEtc_0459: ProjPreInstr_WavePlasmaEtc_0459(k); return;
|
|
case fnProjPreInstr_WavePlasmaEtc_1368: ProjPreInstr_WavePlasmaEtc_1368(k); return;
|
|
case fnProjPreInstr_WavePlasmaEtc_27: ProjPreInstr_WavePlasmaEtc_27(k); return;
|
|
case fnProjPreInstr_HyperBeam: ProjPreInstr_HyperBeam(k); return;
|
|
case fnProjPreInstr_IceSba: ProjPreInstr_IceSba(k); return;
|
|
case fnProjPreInstr_IceSba2: ProjPreInstr_IceSba2(k); return;
|
|
case fnProjPreInstr_SpeedEcho: ProjPreInstr_SpeedEcho(k); return;
|
|
case fnProjPreInstr_PlasmaSba: ProjPreInstr_PlasmaSba(k); return;
|
|
case fnProjPreInstr_PlasmaSbaFunc_0: ProjPreInstr_PlasmaSbaFunc_0(k); return;
|
|
case fnProjPreInstr_PlasmaSbaFunc_1: ProjPreInstr_PlasmaSbaFunc_1(k); return;
|
|
case fnProjPreInstr_PlasmaSbaFunc_2: ProjPreInstr_PlasmaSbaFunc_2(k); return;
|
|
case fnProjPreInstr_SpreadBomb: ProjPreInstr_SpreadBomb(k); return;
|
|
case fnProjPreInstr_WaveSba: ProjPreInstr_WaveSba(k); return;
|
|
case fnProjPreInstr_SpazerSba: ProjPreInstr_SpazerSba(k); return;
|
|
case fnProjPreInstr_EndOfSpazerSba: ProjPreInstr_EndOfSpazerSba(k); return;
|
|
case fnProjPreInstr_UnknownProj8027: ProjPreInstr_UnknownProj8027(k); return;
|
|
default: Unreachable();
|
|
}
|
|
}
|
|
|
|
void HandleProjectile(void) { // 0x90AECE
|
|
projectile_index = 18;
|
|
for (int i = 18; i >= 0; projectile_index = i) {
|
|
int v1 = i >> 1;
|
|
if (projectile_bomb_instruction_ptr[v1]) {
|
|
CallProjPreInstr(projectile_bomb_pre_instructions[v1] | 0x900000, i);
|
|
RunProjectileInstructions();
|
|
i = projectile_index;
|
|
}
|
|
i -= 2;
|
|
}
|
|
}
|
|
|
|
static const int16 kDirToVelMult16_X[10] = { 0, 16, 16, 16, 0, 0, -16, -16, -16, 0 };
|
|
static const int16 kDirToVelMult16_Y[10] = { -16, -16, 0, 16, 16, 16, 16, 0, -16, -16 };
|
|
|
|
static Func_Y_V *const kProjPreInstr_Beam_Funcs[10] = { // 0x90AEF3
|
|
ProjPreInstr_Dir0459,
|
|
ProjPreInstr_Dir1368,
|
|
ProjPreInstr_Dir27,
|
|
ProjPreInstr_Dir1368,
|
|
ProjPreInstr_Dir0459,
|
|
ProjPreInstr_Dir0459,
|
|
ProjPreInstr_Dir1368,
|
|
ProjPreInstr_Dir27,
|
|
ProjPreInstr_Dir1368,
|
|
ProjPreInstr_Dir0459,
|
|
};
|
|
|
|
void ProjPreInstr_Beam_NoWaveBeam(uint16 k) {
|
|
|
|
int v1 = k >> 1;
|
|
if ((projectile_dir[v1] & 0xF0) != 0) {
|
|
ClearProjectile(k);
|
|
} else {
|
|
if (projectile_timers[v1]-- == 1) {
|
|
projectile_timers[v1] = 4;
|
|
SpawnProjectileTrail(k);
|
|
k = projectile_index;
|
|
}
|
|
int v3 = k >> 1;
|
|
uint16 v4 = 2 * (projectile_dir[v3] & 0xF);
|
|
int v5 = v4 >> 1;
|
|
projectile_bomb_x_speed[v3] += kDirToVelMult16_X[v5];
|
|
projectile_bomb_y_speed[v3] += kDirToVelMult16_Y[v5];
|
|
kProjPreInstr_Beam_Funcs[v5](v4);
|
|
DeleteProjectileIfFarOffScreen();
|
|
}
|
|
}
|
|
|
|
void ProjPreInstr_Dir0459(uint16 k) { // 0x90AF4A
|
|
BlockCollNoWaveBeamVert(projectile_index);
|
|
}
|
|
|
|
void ProjPreInstr_Dir1368(uint16 k) { // 0x90AF52
|
|
uint16 v1 = projectile_index;
|
|
if (!(BlockCollNoWaveBeamHoriz(projectile_index) & 1))
|
|
BlockCollNoWaveBeamVert(v1);
|
|
}
|
|
|
|
void ProjPreInstr_Dir27(uint16 k) { // 0x90AF60
|
|
BlockCollNoWaveBeamHoriz(projectile_index);
|
|
}
|
|
|
|
static Func_Y_V *const kProjPreInstr_Missile_Funcs[10] = { // 0x90AF68
|
|
ProjPreInstr_Missile_Func0459,
|
|
ProjPreInstr_Missile_Func1368,
|
|
ProjPreInstr_Missile_Func27,
|
|
ProjPreInstr_Missile_Func1368,
|
|
ProjPreInstr_Missile_Func0459,
|
|
ProjPreInstr_Missile_Func0459,
|
|
ProjPreInstr_Missile_Func1368,
|
|
ProjPreInstr_Missile_Func27,
|
|
ProjPreInstr_Missile_Func1368,
|
|
ProjPreInstr_Missile_Func0459,
|
|
};
|
|
|
|
void ProjPreInstr_Missile(uint16 k) {
|
|
|
|
int v1 = k >> 1;
|
|
if ((projectile_dir[v1] & 0xF0) != 0) {
|
|
ClearProjectile(k);
|
|
} else {
|
|
if (projectile_timers[v1]-- == 1) {
|
|
projectile_timers[v1] = 4;
|
|
SpawnProjectileTrail(k);
|
|
k = projectile_index;
|
|
}
|
|
int v3 = k >> 1;
|
|
uint16 v4 = 2 * (projectile_dir[v3] & 0xF);
|
|
int v5 = v4 >> 1;
|
|
projectile_bomb_x_speed[v3] += kDirToVelMult16_X[v5];
|
|
projectile_bomb_y_speed[v3] += kDirToVelMult16_Y[v5];
|
|
Missile_Func1(k);
|
|
kProjPreInstr_Missile_Funcs[v4 >> 1](v4);
|
|
DeleteProjectileIfFarOffScreen();
|
|
}
|
|
}
|
|
|
|
void ProjPreInstr_Missile_Func0459(uint16 k) { // 0x90AFC7
|
|
BlockCollMissileVert(projectile_index);
|
|
}
|
|
|
|
void ProjPreInstr_Missile_Func1368(uint16 k) { // 0x90AFCF
|
|
uint16 v1 = projectile_index;
|
|
if (!BlockCollMissileHoriz(projectile_index))
|
|
BlockCollMissileVert(v1);
|
|
}
|
|
|
|
void ProjPreInstr_Missile_Func27(uint16 k) { // 0x90AFDD
|
|
BlockCollMissileHoriz(projectile_index);
|
|
}
|
|
|
|
static Func_Y_V *const kProjPreInstr_SuperMissile_Funcs[10] = { // 0x90AFE5
|
|
ProjPreInstr_SuperMissile_Func0459,
|
|
ProjPreInstr_SuperMissile_Func1368,
|
|
ProjPreInstr_SuperMissile_Func27,
|
|
ProjPreInstr_SuperMissile_Func1368,
|
|
ProjPreInstr_SuperMissile_Func0459,
|
|
ProjPreInstr_SuperMissile_Func0459,
|
|
ProjPreInstr_SuperMissile_Func1368,
|
|
ProjPreInstr_SuperMissile_Func27,
|
|
ProjPreInstr_SuperMissile_Func1368,
|
|
ProjPreInstr_SuperMissile_Func0459,
|
|
};
|
|
|
|
void ProjPreInstr_SuperMissile(uint16 k) {
|
|
int16 v3;
|
|
|
|
int v1 = k >> 1;
|
|
if ((projectile_dir[v1] & 0xF0) != 0) {
|
|
ClearProjectile(k);
|
|
LABEL_7:
|
|
for (int i = 8; i >= 0; i -= 2) {
|
|
if ((projectile_type[i >> 1] & 0xFFF) == 512)
|
|
ClearProjectile(i);
|
|
}
|
|
return;
|
|
}
|
|
if (projectile_timers[v1]-- == 1) {
|
|
projectile_timers[v1] = 2;
|
|
SpawnProjectileTrail(k);
|
|
k = projectile_index;
|
|
}
|
|
v3 = projectile_dir[k >> 1] & 0xF;
|
|
Missile_Func1(k);
|
|
kProjPreInstr_SuperMissile_Funcs[v3](v3);
|
|
if (DeleteProjectileIfFarOffScreen() & 1)
|
|
goto LABEL_7;
|
|
}
|
|
|
|
void ProjPreInstr_SuperMissile_Func0459(uint16 k) { // 0x90B047
|
|
BlockCollMissileVert(projectile_index);
|
|
SuperMissileBlockCollDetect_Y();
|
|
}
|
|
|
|
void ProjPreInstr_SuperMissile_Func1368(uint16 k) { // 0x90B052
|
|
uint16 v1 = projectile_index;
|
|
if (BlockCollMissileHoriz(projectile_index)) {
|
|
SuperMissileBlockCollDetect_X();
|
|
} else {
|
|
SuperMissileBlockCollDetect_X();
|
|
BlockCollMissileVert(v1);
|
|
SuperMissileBlockCollDetect_Y();
|
|
}
|
|
}
|
|
|
|
void ProjPreInstr_SuperMissile_Func27(uint16 k) { // 0x90B06A
|
|
BlockCollMissileHoriz(projectile_index);
|
|
SuperMissileBlockCollDetect_X();
|
|
}
|
|
|
|
void ProjPreInstr_Func1(uint16 k) { // 0x90B075
|
|
if ((projectile_dir[k >> 1] & 0xF0) != 0) {
|
|
ClearProjectile(k);
|
|
for (int i = 8; i >= 0; i -= 2) {
|
|
if ((projectile_type[i >> 1] & 0xFFF) == 512)
|
|
ClearProjectile(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ProjPreInstr_Bomb(uint16 k) { // 0x90B099
|
|
if ((projectile_dir[k >> 1] & 0xF0) != 0) {
|
|
ClearProjectile(k);
|
|
} else {
|
|
Bomb_Func2();
|
|
BombOrPowerBomb_Func1(k);
|
|
}
|
|
}
|
|
|
|
void ProjPreInstr_PowerBomb(uint16 k) { // 0x90B0AE
|
|
if ((projectile_dir[k >> 1] & 0xF0) != 0) {
|
|
ClearProjectile(k);
|
|
} else {
|
|
PowerBomb_Func3();
|
|
BombOrPowerBomb_Func1(k);
|
|
}
|
|
}
|
|
|
|
void ProjPreInstr_WavePlasmaEtc(uint16 k) { // 0x90B0C3
|
|
int v1 = k >> 1;
|
|
if ((projectile_dir[v1] & 0xF0) != 0) {
|
|
ClearProjectile(k);
|
|
} else if (projectile_timers[v1]-- == 1) {
|
|
projectile_timers[v1] = 4;
|
|
SpawnProjectileTrail(k);
|
|
ProjPreInstr_Wave_Shared(projectile_index);
|
|
} else {
|
|
ProjPreInstr_Wave_Shared(k);
|
|
}
|
|
}
|
|
|
|
void ProjPreInstr_BeamOrIceWave(uint16 k) { // 0x90B0E4
|
|
int v1 = k >> 1;
|
|
if ((projectile_dir[v1] & 0xF0) != 0) {
|
|
ClearProjectile(k);
|
|
} else if (projectile_timers[v1]-- == 1) {
|
|
projectile_timers[v1] = 3;
|
|
SpawnProjectileTrail(k);
|
|
ProjPreInstr_Wave_Shared(projectile_index);
|
|
} else {
|
|
ProjPreInstr_Wave_Shared(k);
|
|
}
|
|
}
|
|
|
|
static Func_Y_V *const kProjPreInstr_WavePlasmaEtcFuncs[10] = { // 0x90B103
|
|
ProjPreInstr_WavePlasmaEtc_0459,
|
|
ProjPreInstr_WavePlasmaEtc_1368,
|
|
ProjPreInstr_WavePlasmaEtc_27,
|
|
ProjPreInstr_WavePlasmaEtc_1368,
|
|
ProjPreInstr_WavePlasmaEtc_0459,
|
|
ProjPreInstr_WavePlasmaEtc_0459,
|
|
ProjPreInstr_WavePlasmaEtc_1368,
|
|
ProjPreInstr_WavePlasmaEtc_27,
|
|
ProjPreInstr_WavePlasmaEtc_1368,
|
|
ProjPreInstr_WavePlasmaEtc_0459,
|
|
};
|
|
|
|
void ProjPreInstr_Wave_Shared(uint16 k) {
|
|
|
|
int v1 = k >> 1;
|
|
uint16 v2 = 2 * (projectile_dir[v1] & 0xF);
|
|
int v3 = v2 >> 1;
|
|
projectile_bomb_x_speed[v1] += kDirToVelMult16_X[v3];
|
|
projectile_bomb_y_speed[v1] += kDirToVelMult16_Y[v3];
|
|
kProjPreInstr_WavePlasmaEtcFuncs[v3](v2);
|
|
DeleteProjectileIfFarOffScreen();
|
|
}
|
|
|
|
void ProjPreInstr_WavePlasmaEtc_0459(uint16 k) { // 0x90B13B
|
|
BlockCollWaveBeamVert(projectile_index);
|
|
}
|
|
|
|
void ProjPreInstr_WavePlasmaEtc_1368(uint16 k) { // 0x90B143
|
|
uint16 v1 = projectile_index;
|
|
if (!(BlockCollWaveBeamHoriz(projectile_index) & 1))
|
|
BlockCollWaveBeamVert(v1);
|
|
}
|
|
|
|
void ProjPreInstr_WavePlasmaEtc_27(uint16 k) { // 0x90B151
|
|
BlockCollWaveBeamHoriz(projectile_index);
|
|
}
|
|
|
|
void ProjPreInstr_HyperBeam(uint16 k) { // 0x90B159
|
|
if ((projectile_dir[k >> 1] & 0xF0) != 0)
|
|
ClearProjectile(k);
|
|
else
|
|
ProjPreInstr_Wave_Shared(k);
|
|
}
|
|
|
|
uint8 DeleteProjectileIfFarOffScreen(void) { // 0x90B16A
|
|
int16 v0;
|
|
int16 v2;
|
|
|
|
v0 = projectile_x_pos[projectile_index >> 1] - layer1_x_pos;
|
|
if (!sign16(v0 + 64)) {
|
|
if (sign16(v0 - 320)) {
|
|
v2 = projectile_y_pos[projectile_index >> 1] - layer1_y_pos;
|
|
if (!sign16(v2 + 64)) {
|
|
if (sign16(v2 - 320))
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
ClearProjectile(projectile_index);
|
|
return 1;
|
|
}
|
|
|
|
static const uint16 kInitializeProjectileSpeed_XY_Diag[24] = { // 0x90B197
|
|
0x400, 0x2ab,
|
|
0x400, 0x2ab,
|
|
0x400, 0x2ab,
|
|
0x400, 0x2ab,
|
|
0x400, 0x2ab,
|
|
0x400, 0x2ab,
|
|
0x400, 0x2ab,
|
|
0x400, 0x2ab,
|
|
0x400, 0x2ab,
|
|
0x400, 0x2ab,
|
|
0x400, 0x2ab,
|
|
0x400, 0x2ab,
|
|
};
|
|
|
|
void SetInitialProjectileSpeed(uint16 r20) {
|
|
int v0 = r20 >> 1;
|
|
uint16 v1 = 4 * (projectile_type[v0] & 0xF);
|
|
uint16 v2 = 2 * (projectile_dir[v0] & 0xF);
|
|
uint16 r22;
|
|
if (!v2 || v2 == 4 || v2 == 8 || v2 == 10 || v2 == 14 || v2 == 18) {
|
|
r22 = kInitializeProjectileSpeed_XY_Diag[v1 >> 1];
|
|
} else {
|
|
if (v2 != 2 && v2 != 6 && v2 != 12 && v2 != 16)
|
|
Unreachable();
|
|
r22 = kInitializeProjectileSpeed_XY_Diag[(v1 >> 1) + 1];
|
|
}
|
|
InitializeProjectileSpeed(r20, r22);
|
|
}
|
|
|
|
void InitializeProjectileSpeedOfType(uint16 r20) { // 0x90B1DD
|
|
InitializeProjectileSpeed(r20, 0);
|
|
}
|
|
|
|
void InitializeProjectileSpeed(uint16 k, uint16 r22) { // 0x90B1F3
|
|
uint16 r18;
|
|
|
|
int kh = k >> 1;
|
|
projectile_bomb_x_subpos[kh] = 0;
|
|
projectile_bomb_y_subpos[kh] = 0;
|
|
switch (2 * (projectile_dir[kh] & 0xF)) {
|
|
case 0:
|
|
case 18: {
|
|
if ((uint8)projectile_init_speed_samus_moved_up)
|
|
r18 = (*(uint16 *)((uint8 *)&projectile_init_speed_samus_moved_right_fract + 1) >> 2) | 0xC000;
|
|
else
|
|
r18 = 0;
|
|
projectile_bomb_y_speed[kh] = r18 - r22;
|
|
projectile_bomb_x_speed[kh] = 0;
|
|
break;
|
|
}
|
|
case 2: {
|
|
if ((uint8)projectile_init_speed_samus_moved_up)
|
|
r18 = (*(uint16 *)((uint8 *)&projectile_init_speed_samus_moved_right_fract + 1) >> 2) | 0xC000;
|
|
else
|
|
r18 = 0;
|
|
projectile_bomb_y_speed[kh] = r18 - r22;
|
|
projectile_bomb_x_speed[kh] = *(uint16 *)((uint8 *)&projectile_init_speed_samus_moved_left_fract + 1) + r22;
|
|
break;
|
|
}
|
|
case 4: {
|
|
projectile_bomb_y_speed[kh] = 0;
|
|
projectile_bomb_x_speed[kh] = *(uint16 *)((uint8 *)&projectile_init_speed_samus_moved_left_fract + 1) + r22;
|
|
break;
|
|
}
|
|
case 6: {
|
|
projectile_bomb_y_speed[kh] = *(uint16 *)((uint8 *)&projectile_init_speed_samus_moved_up_fract + 1) + r22;
|
|
projectile_bomb_x_speed[kh] = *(uint16 *)((uint8 *)&projectile_init_speed_samus_moved_left_fract + 1) + r22;
|
|
break;
|
|
}
|
|
case 8:
|
|
case 10: {
|
|
projectile_bomb_y_speed[kh] = *(uint16 *)((uint8 *)&projectile_init_speed_samus_moved_up_fract + 1) + r22;
|
|
projectile_bomb_x_speed[kh] = 0;
|
|
break;
|
|
}
|
|
case 12: {
|
|
projectile_bomb_y_speed[kh] = *(uint16 *)((uint8 *)&projectile_init_speed_samus_moved_up_fract + 1) + r22;
|
|
projectile_bomb_x_speed[kh] = *(uint16 *)((uint8 *)&absolute_moved_last_frame_y_fract + 1) - r22;
|
|
break;
|
|
}
|
|
case 14: {
|
|
projectile_bomb_y_speed[kh] = 0;
|
|
projectile_bomb_x_speed[kh] = *(uint16 *)((uint8 *)&absolute_moved_last_frame_y_fract + 1) - r22;
|
|
break;
|
|
}
|
|
case 16: {
|
|
if ((uint8)projectile_init_speed_samus_moved_up)
|
|
r18 = (*(uint16 *)((uint8 *)&projectile_init_speed_samus_moved_right_fract + 1) >> 2) | 0xC000;
|
|
else
|
|
r18 = 0;
|
|
projectile_bomb_y_speed[kh] = r18 - r22;
|
|
projectile_bomb_x_speed[kh] = *(uint16 *)((uint8 *)&absolute_moved_last_frame_y_fract + 1) - r22;
|
|
break;
|
|
}
|
|
default:
|
|
Unreachable();
|
|
}
|
|
}
|
|
|
|
void Missile_Func1(uint16 k) { // 0x90B2F6
|
|
static const uint16 word_90C301 = 0x100;
|
|
uint16 v3;
|
|
|
|
int v1 = k >> 1;
|
|
if ((projectile_variables[v1] & 0xFF00) != 0) {
|
|
if ((projectile_type[v1] & 0x200) != 0)
|
|
v3 = addr_kSuperMissileAccelerations2;
|
|
else
|
|
v3 = addr_kSuperMissileAccelerations;
|
|
const uint8 *v4 = RomPtr_90(v3 + 4 * (projectile_dir[v1] & 0xF));
|
|
projectile_bomb_x_speed[v1] += GET_WORD(v4);
|
|
projectile_bomb_y_speed[v1] += GET_WORD(v4 + 2);
|
|
} else {
|
|
uint16 v2 = word_90C301 + projectile_variables[v1];
|
|
projectile_variables[v1] = v2;
|
|
if ((v2 & 0xFF00) != 0) {
|
|
InitializeProjectileSpeed(k, projectile_variables[v1]);
|
|
if ((projectile_type[v1] & 0x200) != 0)
|
|
Missile_Func2();
|
|
}
|
|
}
|
|
}
|
|
|
|
void SuperMissileBlockCollDetect_Y(void) { // 0x90B366
|
|
int v0 = projectile_index >> 1;
|
|
if ((projectile_type[v0] & 0xF00) == 512 || (projectile_type[v0] & 0xF00) == 2048) {
|
|
uint8 v5 = projectile_variables[v0];
|
|
if (*((uint8 *)projectile_variables + projectile_index + 1)) {
|
|
uint16 v1 = abs16(projectile_bomb_y_speed[v0]) & 0xFF00;
|
|
if (sign16(v1 - 2816)) {
|
|
int v4 = projectile_index >> 1;
|
|
if ((projectile_type[v4] & 0xF00) != 2048) {
|
|
projectile_y_pos[v5 >> 1] = projectile_y_pos[v4];
|
|
return;
|
|
}
|
|
} else {
|
|
uint16 r18 = (v1 >> 8) - 10;
|
|
if ((projectile_bomb_y_speed[v0] & 0x8000) == 0) {
|
|
uint16 v6 = projectile_index;
|
|
projectile_y_pos[v5 >> 1] = projectile_y_pos[v0] - r18;
|
|
projectile_index = v5;
|
|
BlockCollMissileVert(v5);
|
|
projectile_index = v6;
|
|
if ((projectile_type[v6 >> 1] & 0xF00) == 2048)
|
|
ClearProjectile(v5);
|
|
return;
|
|
}
|
|
uint16 v7 = projectile_index;
|
|
projectile_y_pos[v5 >> 1] = r18 + projectile_y_pos[projectile_index >> 1];
|
|
projectile_index = v5;
|
|
BlockCollMissileVert(v5);
|
|
projectile_index = v7;
|
|
if ((projectile_type[v7 >> 1] & 0xF00) != 2048)
|
|
return;
|
|
}
|
|
ClearProjectile(v5);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Projectile_Func4(uint16 k) { // 0x90B4A6
|
|
int v1 = k >> 1;
|
|
if (*((uint8 *)projectile_variables + k + 1)) {
|
|
if ((projectile_type[v1] & 0xF00) == 2048)
|
|
ClearProjectile((uint8)projectile_variables[v1]);
|
|
}
|
|
}
|
|
|
|
void SuperMissileBlockCollDetect_X(void) { // 0x90B406
|
|
int v0 = projectile_index >> 1;
|
|
if ((projectile_type[v0] & 0xF00) == 512 || (projectile_type[v0] & 0xF00) == 2048) {
|
|
uint8 v5 = projectile_variables[v0];
|
|
if (*((uint8 *)projectile_variables + projectile_index + 1)) {
|
|
uint16 v1 = abs16(projectile_bomb_x_speed[v0]) & 0xFF00;
|
|
if (sign16(v1 - 2816)) {
|
|
int v4 = projectile_index >> 1;
|
|
if ((projectile_type[v4] & 0xF00) != 2048) {
|
|
projectile_x_pos[v5 >> 1] = projectile_x_pos[v4];
|
|
return;
|
|
}
|
|
} else {
|
|
uint16 r18 = (v1 >> 8) - 10;
|
|
if ((projectile_bomb_x_speed[v0] & 0x8000) == 0) {
|
|
uint16 v6 = projectile_index;
|
|
projectile_x_pos[v5 >> 1] = projectile_x_pos[v0] - r18;
|
|
projectile_index = v5;
|
|
BlockCollMissileHoriz(v5);
|
|
projectile_index = v6;
|
|
if ((projectile_type[v6 >> 1] & 0xF00) == 2048)
|
|
ClearProjectile(v5);
|
|
return;
|
|
}
|
|
uint16 v7 = projectile_index;
|
|
projectile_x_pos[v5 >> 1] = r18 + projectile_x_pos[projectile_index >> 1];
|
|
projectile_index = v5;
|
|
BlockCollMissileHoriz(v5);
|
|
projectile_index = v7;
|
|
if ((projectile_type[v7 >> 1] & 0xF00) != 2048)
|
|
return;
|
|
}
|
|
ClearProjectile(v5);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ProjInstr_MoveLeftProjectileTrailDown(uint16 j) { // 0x90B525
|
|
++projectiletrail_left_y_pos[j >> 1];
|
|
}
|
|
|
|
void ProjInstr_MoveRightProjectileTrailDown(uint16 j) { // 0x90B587
|
|
++projectiletrail_right_y_pos[j >> 1];
|
|
}
|
|
|
|
void ProjInstr_MoveLeftProjectileTrailUp(uint16 j) { // 0x90B5B3
|
|
--projectiletrail_left_y_pos[j >> 1];
|
|
}
|
|
|
|
void SpawnProjectileTrail(uint16 k) { // 0x90B657
|
|
int16 v2;
|
|
|
|
uint16 v1 = projectile_type[k >> 1];
|
|
if ((v1 & 0xF00) != 0) {
|
|
uint16 v3 = HIBYTE(v1) & 0xF;
|
|
if (v3 >= 3)
|
|
return;
|
|
v2 = v3 + 31;
|
|
} else {
|
|
v2 = projectile_type[k >> 1] & 0x3F;
|
|
}
|
|
uint16 v4 = 34;
|
|
while (projectiletrail_left_instr_timer[v4 >> 1]) {
|
|
v4 -= 2;
|
|
if ((v4 & 0x8000) != 0)
|
|
return;
|
|
}
|
|
int v5 = v4 >> 1;
|
|
projectiletrail_left_instr_timer[v5] = 1;
|
|
projectiletrail_right_instr_timer[v5] = 1;
|
|
int v6 = v2;
|
|
projectiletrail_left_instr_list_ptr[v5] = off_90B5BB[v6];
|
|
projectiletrail_right_instr_list_ptr[v5] = off_90B609[v6];
|
|
ProjectileTrail_Func5(projectile_index, v4);
|
|
}
|
|
|
|
void CallProjInstr(uint32 ea, uint16 j) {
|
|
switch (ea) {
|
|
case fnProjInstr_MoveLeftProjectileTrailDown: ProjInstr_MoveLeftProjectileTrailDown(j); return; // 0x90b525
|
|
case fnProjInstr_MoveRightProjectileTrailDown: ProjInstr_MoveRightProjectileTrailDown(j); return; // 0x90b587
|
|
case fnProjInstr_MoveLeftProjectileTrailUp: ProjInstr_MoveLeftProjectileTrailUp(j); return; // 0x90b5b3
|
|
default: Unreachable();
|
|
}
|
|
}
|
|
|
|
void HandleProjectileTrails(void) { // 0x90B6A9
|
|
int i;
|
|
int16 v10;
|
|
OamEnt *v11;
|
|
int16 v12;
|
|
uint16 j;
|
|
int16 v22;
|
|
OamEnt *v23;
|
|
int16 v24;
|
|
uint16 k;
|
|
int16 v28;
|
|
OamEnt *v29;
|
|
int16 v30;
|
|
int16 v33;
|
|
OamEnt *v34;
|
|
int16 v35;
|
|
uint16 v6, v18;
|
|
int v7;
|
|
|
|
if (!time_is_frozen_flag) {
|
|
uint16 v0 = 34;
|
|
while (1) {
|
|
uint16 v2;
|
|
int v1;
|
|
v1 = v0 >> 1;
|
|
v2 = projectiletrail_left_instr_timer[v1];
|
|
if (v2) {
|
|
uint16 v3 = v2 - 1;
|
|
projectiletrail_left_instr_timer[v1] = v3;
|
|
if (v3)
|
|
goto LABEL_10;
|
|
for (i = projectiletrail_left_instr_list_ptr[v1]; ; i += 2) {
|
|
const uint16 *v5 = (const uint16 *)RomPtr_90(i);
|
|
v6 = *v5;
|
|
if ((*v5 & 0x8000) == 0)
|
|
break;
|
|
CallProjInstr(v6 | 0x900000, v0);
|
|
}
|
|
v7 = v0 >> 1;
|
|
projectiletrail_left_instr_timer[v7] = v6;
|
|
if (v6)
|
|
break;
|
|
}
|
|
LABEL_14:;
|
|
int v13 = v0 >> 1;
|
|
uint16 v14 = projectiletrail_right_instr_timer[v13];
|
|
if (v14) {
|
|
uint16 v15 = v14 - 1;
|
|
projectiletrail_right_instr_timer[v13] = v15;
|
|
if (v15)
|
|
goto LABEL_21;
|
|
for (j = projectiletrail_right_instr_list_ptr[v13]; ; j += 2) {
|
|
const uint16 *v17 = (const uint16 *)RomPtr_90(j);
|
|
v18 = *v17;
|
|
if ((*v17 & 0x8000) == 0)
|
|
break;
|
|
CallProjInstr(v18 | 0x900000, v0);
|
|
}
|
|
int v19;
|
|
v19 = v0 >> 1;
|
|
projectiletrail_right_instr_timer[v19] = v18;
|
|
if (v18) {
|
|
projectiletrail_right_tile_and_attribs[v19] = *((uint16 *)RomPtr_90(j) + 1);
|
|
projectiletrail_right_instr_list_ptr[v19] = j + 4;
|
|
LABEL_21:;
|
|
uint16 v20 = oam_next_ptr;
|
|
if ((int16)(oam_next_ptr - 512) < 0) {
|
|
int v21 = v0 >> 1;
|
|
v22 = projectiletrail_right_x_pos[v21] - layer1_x_pos;
|
|
if ((v22 & 0xFF00) == 0) {
|
|
v23 = gOamEnt(oam_next_ptr);
|
|
*(uint16 *)&v23->xcoord = v22;
|
|
v24 = projectiletrail_right_y_pos[v21] - layer1_y_pos;
|
|
if ((v24 & 0xFF00) == 0) {
|
|
*(uint16 *)&v23->ycoord = v24;
|
|
*(uint16 *)&v23->charnum = projectiletrail_right_tile_and_attribs[v21];
|
|
oam_next_ptr = v20 + 4;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
v0 -= 2;
|
|
if ((v0 & 0x8000) != 0)
|
|
return;
|
|
}
|
|
projectiletrail_left_tile_and_attribs[v7] = *((uint16 *)RomPtr_90(i) + 1);
|
|
projectiletrail_left_instr_list_ptr[v7] = i + 4;
|
|
LABEL_10:;
|
|
uint16 v8 = oam_next_ptr;
|
|
if ((int16)(oam_next_ptr - 512) < 0) {
|
|
int v9 = v0 >> 1;
|
|
v10 = projectiletrail_left_x_pos[v9] - layer1_x_pos;
|
|
if ((v10 & 0xFF00) == 0) {
|
|
v11 = gOamEnt(oam_next_ptr);
|
|
*(uint16 *)&v11->xcoord = v10;
|
|
v12 = projectiletrail_left_y_pos[v9] - layer1_y_pos;
|
|
if ((v12 & 0xFF00) == 0) {
|
|
*(uint16 *)&v11->ycoord = v12;
|
|
*(uint16 *)&v11->charnum = projectiletrail_left_tile_and_attribs[v9];
|
|
oam_next_ptr = v8 + 4;
|
|
}
|
|
}
|
|
}
|
|
goto LABEL_14;
|
|
}
|
|
for (k = 34; (k & 0x8000) == 0; k -= 2) {
|
|
uint16 v26 = oam_next_ptr;
|
|
if ((int16)(oam_next_ptr - 512) < 0) {
|
|
int v27 = k >> 1;
|
|
if (projectiletrail_left_instr_timer[v27]) {
|
|
v28 = projectiletrail_left_x_pos[v27] - layer1_x_pos;
|
|
if ((v28 & 0xFF00) == 0) {
|
|
v29 = gOamEnt(oam_next_ptr);
|
|
*(uint16 *)&v29->xcoord = v28;
|
|
v30 = projectiletrail_left_y_pos[v27] - layer1_y_pos;
|
|
if ((v30 & 0xFF00) == 0) {
|
|
*(uint16 *)&v29->ycoord = v30;
|
|
*(uint16 *)&v29->charnum = projectiletrail_left_tile_and_attribs[v27];
|
|
oam_next_ptr = v26 + 4;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
uint16 v31 = oam_next_ptr;
|
|
if ((int16)(oam_next_ptr - 512) < 0) {
|
|
int v32 = k >> 1;
|
|
if (projectiletrail_right_instr_timer[v32]) {
|
|
v33 = projectiletrail_right_x_pos[v32] - layer1_x_pos;
|
|
if ((v33 & 0xFF00) == 0) {
|
|
v34 = gOamEnt(oam_next_ptr);
|
|
*(uint16 *)&v34->xcoord = v33;
|
|
v35 = projectiletrail_right_y_pos[v32] - layer1_y_pos;
|
|
if ((v35 & 0xFF00) == 0) {
|
|
*(uint16 *)&v34->ycoord = v35;
|
|
*(uint16 *)&v34->charnum = projectiletrail_right_tile_and_attribs[v32];
|
|
oam_next_ptr = v31 + 4;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void HudSelectionHandler_NothingOrPowerBombs(void) { // 0x90B80D
|
|
prev_beam_charge_counter = flare_counter;
|
|
if (hyper_beam_flag || (equipped_beams & 0x1000) == 0) {
|
|
if ((button_config_shoot_x & joypad1_lastkeys) != 0)
|
|
FireUnchargedBeam();
|
|
return;
|
|
}
|
|
if (new_projectile_direction_changed_pose) {
|
|
if (sign16(flare_counter - 60)) {
|
|
LABEL_14:
|
|
flare_counter = 0;
|
|
ClearFlareAnimationState();
|
|
FireUnchargedBeam();
|
|
return;
|
|
}
|
|
LABEL_15:
|
|
flare_counter = 0;
|
|
ClearFlareAnimationState();
|
|
FireChargedBeam();
|
|
return;
|
|
}
|
|
if ((button_config_shoot_x & joypad1_lastkeys) == 0) {
|
|
if (!flare_counter)
|
|
return;
|
|
if (sign16(flare_counter - 60))
|
|
goto LABEL_14;
|
|
goto LABEL_15;
|
|
}
|
|
if (sign16(flare_counter - 120)) {
|
|
if (++flare_counter == 1) {
|
|
ClearFlareAnimationState();
|
|
FireUnchargedBeam();
|
|
}
|
|
} else if (FireSba() & 1) {
|
|
flare_counter = 0;
|
|
ClearFlareAnimationState();
|
|
Samus_LoadSuitPalette();
|
|
}
|
|
}
|
|
|
|
static const uint16 kProjectileBombPreInstr[12] = { // 0x90B887
|
|
(uint16)fnProjPreInstr_Beam_NoWaveBeam,
|
|
(uint16)fnProjPreInstr_BeamOrIceWave,
|
|
(uint16)fnProjPreInstr_Beam_NoWaveBeam,
|
|
(uint16)fnProjPreInstr_BeamOrIceWave,
|
|
(uint16)fnProjPreInstr_Beam_NoWaveBeam,
|
|
(uint16)fnProjPreInstr_WavePlasmaEtc,
|
|
(uint16)fnProjPreInstr_Beam_NoWaveBeam,
|
|
(uint16)fnProjPreInstr_WavePlasmaEtc,
|
|
(uint16)fnProjPreInstr_Beam_NoWaveBeam,
|
|
(uint16)fnProjPreInstr_WavePlasmaEtc,
|
|
(uint16)fnProjPreInstr_Beam_NoWaveBeam,
|
|
(uint16)fnProjPreInstr_WavePlasmaEtc,
|
|
};
|
|
|
|
void FireUnchargedBeam(void) {
|
|
int8 v3;
|
|
|
|
if (hyper_beam_flag) {
|
|
FireHyperBeam();
|
|
return;
|
|
}
|
|
if (Samus_CanFireBeam() & 1) {
|
|
uint16 v0 = 0;
|
|
while (projectile_damage[v0 >> 1]) {
|
|
v0 += 2;
|
|
if ((int16)(v0 - 10) >= 0) {
|
|
v0 -= 2;
|
|
break;
|
|
}
|
|
}
|
|
if (!(InitProjectilePositionDirection(v0) & 1)) {
|
|
projectile_invincibility_timer = 10;
|
|
uint16 v1 = v0;
|
|
int v2 = v0 >> 1;
|
|
projectile_timers[v2] = 4;
|
|
v3 = equipped_beams;
|
|
projectile_type[v2] = equipped_beams | 0x8000;
|
|
QueueSfx1_Max15(kUnchargedProjectile_Sfx[v3 & 0xF]);
|
|
play_resume_charging_beam_sfx = 0;
|
|
InitializeProjectile(v1);
|
|
if ((equipped_beams & 0x1000) != 0
|
|
|| (button_config_shoot_x & joypad1_newkeys) != 0
|
|
|| (button_config_shoot_x & joypad1_newinput_samusfilter) != 0) {
|
|
uint16 v6;
|
|
v6 = projectile_type[v2];
|
|
cooldown_timer = kProjectileCooldown_Uncharged[v6 & 0x3F];
|
|
if ((v6 & 1) == 0)
|
|
goto LABEL_17;
|
|
} else {
|
|
uint16 v5;
|
|
v5 = projectile_type[v2];
|
|
cooldown_timer = kBeamAutoFireCooldowns[v5 & 0x3F];
|
|
if ((v5 & 1) == 0) {
|
|
LABEL_17:
|
|
projectile_bomb_x_speed[v2] = 0;
|
|
projectile_bomb_y_speed[v2] = 0;
|
|
projectile_index = v1;
|
|
CheckBeamCollByDir(v1);
|
|
v1 = projectile_index;
|
|
if ((projectile_type[projectile_index >> 1] & 0xF00) != 0)
|
|
return;
|
|
goto LABEL_20;
|
|
}
|
|
}
|
|
int v4;
|
|
v4 = v1 >> 1;
|
|
projectile_bomb_x_speed[v4] = 0;
|
|
projectile_bomb_y_speed[v4] = 0;
|
|
projectile_index = v1;
|
|
WaveBeam_CheckColl(v1);
|
|
LABEL_20:
|
|
projectile_bomb_pre_instructions[v1 >> 1] = kProjectileBombPreInstr[projectile_type[v1 >> 1] & 0xF];
|
|
SetInitialProjectileSpeed(v1);
|
|
return;
|
|
}
|
|
}
|
|
if (!sign16(prev_beam_charge_counter - 16)) {
|
|
play_resume_charging_beam_sfx = 0;
|
|
QueueSfx1_Max15(2);
|
|
}
|
|
}
|
|
|
|
static const uint16 kFireChargedBeam_Funcs[12] = { // 0x90B986
|
|
(uint16)fnProjPreInstr_Beam_NoWaveBeam,
|
|
(uint16)fnProjPreInstr_WavePlasmaEtc,
|
|
(uint16)fnProjPreInstr_Beam_NoWaveBeam,
|
|
(uint16)fnProjPreInstr_WavePlasmaEtc,
|
|
(uint16)fnProjPreInstr_Beam_NoWaveBeam,
|
|
(uint16)fnProjPreInstr_WavePlasmaEtc,
|
|
(uint16)fnProjPreInstr_Beam_NoWaveBeam,
|
|
(uint16)fnProjPreInstr_WavePlasmaEtc,
|
|
(uint16)fnProjPreInstr_Beam_NoWaveBeam,
|
|
(uint16)fnProjPreInstr_WavePlasmaEtc,
|
|
(uint16)fnProjPreInstr_Beam_NoWaveBeam,
|
|
(uint16)fnProjPreInstr_WavePlasmaEtc,
|
|
};
|
|
|
|
void FireChargedBeam(void) {
|
|
if (Samus_CanFireBeam() & 1) {
|
|
uint16 v0 = 0;
|
|
while (projectile_damage[v0 >> 1]) {
|
|
v0 += 2;
|
|
if ((int16)(v0 - 10) >= 0) {
|
|
v0 -= 2;
|
|
break;
|
|
}
|
|
}
|
|
uint16 r20 = v0;
|
|
if (!(InitProjectilePositionDirection(r20) & 1)) {
|
|
projectile_invincibility_timer = 10;
|
|
uint16 v1 = r20;
|
|
int v2 = r20 >> 1;
|
|
projectile_timers[v2] = 4;
|
|
uint16 v3 = equipped_beams & 0x100F | 0x8010;
|
|
projectile_type[v2] = v3;
|
|
QueueSfx1_Max15(kChargedProjectile_Sfx[v3 & 0xF]);
|
|
play_resume_charging_beam_sfx = 0;
|
|
InitializeProjectile(v1);
|
|
uint16 v5 = projectile_type[v2];
|
|
cooldown_timer = kProjectileCooldown_Uncharged[v5 & 0x3F];
|
|
if ((v5 & 1) != 0) {
|
|
int v4 = v1 >> 1;
|
|
projectile_bomb_x_speed[v4] = 0;
|
|
projectile_bomb_y_speed[v4] = 0;
|
|
projectile_index = v1;
|
|
WaveBeam_CheckColl(v1);
|
|
} else {
|
|
projectile_bomb_x_speed[v2] = 0;
|
|
projectile_bomb_y_speed[v2] = 0;
|
|
projectile_index = v1;
|
|
CheckBeamCollByDir(v1);
|
|
v1 = projectile_index;
|
|
if ((projectile_type[projectile_index >> 1] & 0xF00) != 0) {
|
|
LABEL_14:
|
|
charged_shot_glow_timer = 4;
|
|
return;
|
|
}
|
|
}
|
|
r20 = v1;
|
|
projectile_bomb_pre_instructions[v1 >> 1] = kFireChargedBeam_Funcs[projectile_type[v1 >> 1] & 0xF];
|
|
SetInitialProjectileSpeed(r20);
|
|
goto LABEL_14;
|
|
}
|
|
}
|
|
if (!sign16(prev_beam_charge_counter - 16)) {
|
|
play_resume_charging_beam_sfx = 0;
|
|
QueueSfx1_Max15(2);
|
|
}
|
|
}
|
|
|
|
static const int16 kProjectileOriginOffsets3_X[10] = { 2, 13, 11, 13, 2, -5, -14, -11, -19, -2 };
|
|
static const int16 kProjectileOriginOffsets3_Y[10] = { -8, -13, 1, 4, 13, 13, 4, 1, -19, -8 };
|
|
static const int16 kProjectileOriginOffsets4_X[10] = { 2, 15, 15, 13, 2, -5, -13, -13, -15, -2 };
|
|
static const int16 kProjectileOriginOffsets4_Y[10] = { -8, -16, -2, 1, 13, 13, 1, -2, -16, -8 };
|
|
|
|
uint8 InitProjectilePositionDirection(uint16 r20) { // 0x90BA56
|
|
uint16 v0 = samus_pose;
|
|
uint16 direction_shots_fired;
|
|
|
|
if (new_projectile_direction_changed_pose) {
|
|
direction_shots_fired = (uint8)new_projectile_direction_changed_pose;
|
|
new_projectile_direction_changed_pose = 0;
|
|
} else {
|
|
direction_shots_fired = kPoseParams[v0].direction_shots_fired;
|
|
if ((direction_shots_fired & 0xF0) != 0) {
|
|
if (direction_shots_fired != 16
|
|
|| (LOBYTE(direction_shots_fired) = kPoseParams[samus_last_different_pose].direction_shots_fired,
|
|
(direction_shots_fired & 0xF0) != 0)) {
|
|
--projectile_counter;
|
|
return 1;
|
|
}
|
|
direction_shots_fired = (uint8)direction_shots_fired;
|
|
v0 = samus_pose;
|
|
}
|
|
}
|
|
int v2 = r20 >> 1;
|
|
projectile_dir[v2] = direction_shots_fired;
|
|
uint16 r22 = kPoseParams[v0].y_offset_to_gfx;
|
|
uint16 v3 = 2 * (projectile_dir[v2] & 0xF);
|
|
if (samus_pose == kPose_75_FaceL_Moonwalk_AimUL
|
|
|| samus_pose == kPose_76_FaceR_Moonwalk_AimUR
|
|
|| samus_movement_type == 1) {
|
|
int v6 = v3 >> 1;
|
|
projectile_x_pos[v2] = samus_x_pos + kProjectileOriginOffsets4_X[v6];
|
|
projectile_y_pos[v2] = samus_y_pos + kProjectileOriginOffsets4_Y[v6] - r22;
|
|
return 0;
|
|
} else {
|
|
int v4 = v3 >> 1;
|
|
projectile_x_pos[v2] = samus_x_pos + kProjectileOriginOffsets3_X[v4];
|
|
projectile_y_pos[v2] = samus_y_pos + kProjectileOriginOffsets3_Y[v4] - r22;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void HandleChargingBeamGfxAudio(void) { // 0x90BAFC
|
|
int16 v1;
|
|
int16 v4;
|
|
uint16 v9;
|
|
|
|
if (hyper_beam_flag) {
|
|
if (flare_counter) {
|
|
for (int i = 4; i >= 0; i -= 2) {
|
|
bool v7 = *(uint16 *)((uint8 *)&flare_animation_timer + i) == 1;
|
|
bool v8 = (-- * (uint16 *)((uint8 *)&flare_animation_timer + i) & 0x8000) != 0;
|
|
if (v7 || v8) {
|
|
v7 = (*(uint16 *)((uint8 *)&flare_animation_frame + i))-- == 1;
|
|
if (v7) {
|
|
if (i == 4)
|
|
flare_counter = 0;
|
|
} else {
|
|
*(uint16 *)((uint8 *)&flare_animation_timer + i) = 3;
|
|
}
|
|
}
|
|
DrawFlareAnimationComponent(i);
|
|
}
|
|
}
|
|
} else if ((int16)flare_counter > 0) {
|
|
if (flare_counter == 1) {
|
|
flare_animation_frame = 0;
|
|
flare_slow_sparks_anim_frame = 0;
|
|
flare_fast_sparks_anim_frame = 0;
|
|
flare_animation_timer = 3;
|
|
flare_slow_sparks_anim_timer = 5;
|
|
flare_fast_sparks_anim_timer = 4;
|
|
}
|
|
if (!sign16(flare_counter - 15)) {
|
|
if (flare_counter == 16)
|
|
QueueSfx1_Max9(8);
|
|
uint16 v0 = 0;
|
|
do {
|
|
v1 = *(uint16 *)((uint8 *)&flare_animation_timer + v0) - 1;
|
|
*(uint16 *)((uint8 *)&flare_animation_timer + v0) = v1;
|
|
if (v1 < 0) {
|
|
uint16 v2 = *(uint16 *)((uint8 *)&flare_animation_frame + v0) + 1;
|
|
*(uint16 *)((uint8 *)&flare_animation_frame + v0) = v2;
|
|
uint16 v3 = v2;
|
|
const uint8 *r0 = RomPtr_90(kFlareAnimDelays[v0 >> 1]);
|
|
v4 = r0[v2];
|
|
if (v4 == 255) {
|
|
*(uint16 *)((uint8 *)&flare_animation_frame + v0) = 0;
|
|
v3 = 0;
|
|
} else if (v4 == 254) {
|
|
uint16 v5 = *(uint16 *)((uint8 *)&flare_animation_frame + v0) - r0[v3 + 1];
|
|
*(uint16 *)((uint8 *)&flare_animation_frame + v0) = v5;
|
|
v3 = v5;
|
|
}
|
|
*(uint16 *)((uint8 *)&flare_animation_timer + v0) = r0[v3];
|
|
}
|
|
v9 = v0;
|
|
DrawFlareAnimationComponent(v0);
|
|
if (sign16(flare_counter - 30))
|
|
break;
|
|
v0 += 2;
|
|
} while ((int16)(v9 - 4) < 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
static const int16 kProjectileOriginOffsets_X[13] = { 2, 18, 15, 17, 3, -4, -17, -15, -18, -2, -4, -4, -4 };
|
|
static const int16 kProjectileOriginOffsets_Y[13] = { -28, -19, 1, 6, 17, 17, 6, 1, -20, -28, -20, -2, 8 };
|
|
static const int16 kProjectileOriginOffsets2_X[10] = { 2, 19, 20, 18, 3, -4, -18, -20, -19, -2 };
|
|
static const int16 kProjectileOriginOffsets2_Y[10] = { -32, -22, -3, 6, 25, 25, 6, -3, -20, -32 };
|
|
|
|
void DrawFlareAnimationComponent(uint16 k) { // 0x90BBE1
|
|
static const uint16 word_93A225[3] = { 0, 0x1e, 0x24 };
|
|
static const uint16 word_93A22B[3] = { 0, 0x2a, 0x30 };
|
|
int16 v2;
|
|
uint16 v1;
|
|
uint16 r20;
|
|
uint16 r18 = *((uint8 *)&flare_animation_frame + k);
|
|
if (samus_pose_x_dir == 4)
|
|
v1 = word_93A22B[k >> 1];
|
|
else
|
|
v1 = word_93A225[k >> 1];
|
|
uint16 r22 = r18 + v1;
|
|
uint16 r24 = kPoseParams[samus_pose].y_offset_to_gfx;
|
|
v2 = kPoseParams[samus_pose].direction_shots_fired;
|
|
if (v2 != 255 && v2 != 16) {
|
|
uint16 v3 = 2 * (v2 & 0xF);
|
|
uint16 old_x = samus_x_pos, old_y = samus_y_pos;
|
|
if ((ceres_status & 0x8000) != 0)
|
|
Samus_CalcPos_Mode7();
|
|
int v4 = v3 >> 1;
|
|
uint16 v5;
|
|
if (samus_movement_type == 1) {
|
|
r20 = samus_x_pos + kProjectileOriginOffsets2_X[v4] - layer1_x_pos;
|
|
v5 = samus_y_pos + kProjectileOriginOffsets2_Y[v4] - r24 - layer1_y_pos;
|
|
} else {
|
|
r20 = samus_x_pos + kProjectileOriginOffsets_X[v4] - layer1_x_pos;
|
|
v5 = samus_y_pos + kProjectileOriginOffsets_Y[v4] - r24 - layer1_y_pos;
|
|
}
|
|
r18 = v5;
|
|
if ((v5 & 0xFF00) == 0)
|
|
DrawBeamGrappleSpritemap(r22, r20, r18);
|
|
if ((ceres_status & 0x8000) != 0)
|
|
samus_y_pos = old_y, samus_x_pos = old_x;
|
|
}
|
|
}
|
|
|
|
void ClearFlareAnimationState(void) { // 0x90BCBE
|
|
flare_animation_frame = 0;
|
|
flare_slow_sparks_anim_frame = 0;
|
|
flare_fast_sparks_anim_frame = 0;
|
|
flare_animation_timer = 0;
|
|
flare_slow_sparks_anim_timer = 0;
|
|
flare_fast_sparks_anim_timer = 0;
|
|
}
|
|
|
|
void FireHyperBeam(void) { // 0x90BCD1
|
|
if (Samus_CanFireBeam() & 1) {
|
|
uint16 v0 = 0;
|
|
while (projectile_damage[v0 >> 1]) {
|
|
v0 += 2;
|
|
if ((int16)(v0 - 10) >= 0) {
|
|
v0 -= 2;
|
|
break;
|
|
}
|
|
}
|
|
uint16 r20 = v0;
|
|
if (!(InitProjectilePositionDirection(r20) & 1)) {
|
|
projectile_invincibility_timer = 10;
|
|
uint16 k = r20;
|
|
projectile_type[r20 >> 1] = -28648;
|
|
QueueSfx1_Max15(kChargedProjectile_Sfx[8]);
|
|
play_resume_charging_beam_sfx = 0;
|
|
InitializeProjectile(k);
|
|
int v1 = k >> 1;
|
|
projectile_bomb_x_speed[v1] = 0;
|
|
projectile_bomb_y_speed[v1] = 0;
|
|
projectile_index = k;
|
|
WaveBeam_CheckColl(k);
|
|
uint16 v2 = projectile_index;
|
|
int v3 = projectile_index >> 1;
|
|
projectile_damage[v3] = 1000;
|
|
projectile_bomb_pre_instructions[v3] = FUNC16(ProjPreInstr_HyperBeam);
|
|
r20 = v2;
|
|
SetInitialProjectileSpeed(r20);
|
|
cooldown_timer = 21;
|
|
charged_shot_glow_timer = -32748;
|
|
flare_animation_frame = 29;
|
|
flare_slow_sparks_anim_frame = 5;
|
|
flare_fast_sparks_anim_frame = 5;
|
|
flare_animation_timer = 3;
|
|
flare_slow_sparks_anim_timer = 3;
|
|
flare_fast_sparks_anim_timer = 3;
|
|
flare_counter = 0x8000;
|
|
}
|
|
}
|
|
}
|
|
|
|
static Func_V *const kCheckBeamCollByDir[10] = { // 0x90BD64
|
|
CheckBeamCollByDir_0459,
|
|
CheckBeamCollByDir_1368,
|
|
CheckBeamCollByDir_2,
|
|
CheckBeamCollByDir_1368,
|
|
CheckBeamCollByDir_0459,
|
|
CheckBeamCollByDir_0459,
|
|
CheckBeamCollByDir_1368,
|
|
CheckBeamCollByDir_7,
|
|
CheckBeamCollByDir_1368,
|
|
CheckBeamCollByDir_0459,
|
|
};
|
|
|
|
void CheckBeamCollByDir(uint16 k) {
|
|
kCheckBeamCollByDir[projectile_dir[k >> 1] & 0xF]();
|
|
}
|
|
|
|
void CheckBeamCollByDir_0459(void) { // 0x90BD86
|
|
BlockCollNoWaveBeamVert(projectile_index);
|
|
}
|
|
|
|
void CheckBeamCollByDir_1368(void) { // 0x90BD8E
|
|
uint16 v0 = projectile_index;
|
|
if (!(BlockCollNoWaveBeamHoriz(projectile_index) & 1))
|
|
BlockCollNoWaveBeamVert(v0);
|
|
}
|
|
|
|
void CheckBeamCollByDir_2(void) { // 0x90BD9C
|
|
BlockCollNoWaveBeamHoriz(projectile_index);
|
|
}
|
|
|
|
void CheckBeamCollByDir_7(void) { // 0x90BDA4
|
|
uint16 v0 = projectile_index;
|
|
projectile_bomb_x_speed[projectile_index >> 1] = -1;
|
|
BlockCollNoWaveBeamHoriz(v0);
|
|
}
|
|
|
|
static Func_V *const kWaveBeam_CheckColl_Funcs[10] = { // 0x90BDB2
|
|
WaveBeam_CheckColl_0459,
|
|
WaveBeam_CheckColl_1368,
|
|
WaveBeam_CheckColl_2,
|
|
WaveBeam_CheckColl_1368,
|
|
WaveBeam_CheckColl_0459,
|
|
WaveBeam_CheckColl_0459,
|
|
WaveBeam_CheckColl_1368,
|
|
WaveBeam_CheckColl_7,
|
|
WaveBeam_CheckColl_1368,
|
|
WaveBeam_CheckColl_0459,
|
|
};
|
|
void WaveBeam_CheckColl(uint16 k) {
|
|
kWaveBeam_CheckColl_Funcs[projectile_dir[k >> 1] & 0xF]();
|
|
}
|
|
|
|
void WaveBeam_CheckColl_0459(void) { // 0x90BDD4
|
|
BlockCollWaveBeamVert(projectile_index);
|
|
}
|
|
|
|
void WaveBeam_CheckColl_1368(void) { // 0x90BDDC
|
|
uint16 v0 = projectile_index;
|
|
if (!(BlockCollWaveBeamHoriz(projectile_index) & 1))
|
|
BlockCollWaveBeamVert(v0);
|
|
}
|
|
|
|
void WaveBeam_CheckColl_2(void) { // 0x90BDEA
|
|
BlockCollWaveBeamHoriz(projectile_index);
|
|
}
|
|
|
|
void WaveBeam_CheckColl_7(void) { // 0x90BDF2
|
|
uint16 v0 = projectile_index;
|
|
projectile_bomb_x_speed[projectile_index >> 1] = -1;
|
|
BlockCollWaveBeamHoriz(v0);
|
|
}
|
|
|
|
void ProjectileReflection(uint16 r20) { // 0x90BE00
|
|
uint16 v0 = r20;
|
|
int v1 = r20 >> 1;
|
|
uint16 v2 = projectile_type[v1];
|
|
if ((v2 & 0x100) != 0) {
|
|
InitializeProjectile(r20);
|
|
projectile_bomb_pre_instructions[v1] = FUNC16(ProjPreInstr_Missile);
|
|
projectile_variables[v1] = 240;
|
|
} else if ((v2 & 0x200) != 0) {
|
|
uint16 k = r20;
|
|
ClearProjectile(LOBYTE(projectile_variables[v1]));
|
|
InitializeProjectile(k);
|
|
int v3 = k >> 1;
|
|
projectile_bomb_pre_instructions[v3] = FUNC16(ProjPreInstr_SuperMissile);
|
|
projectile_variables[v3] = 240;
|
|
} else {
|
|
SetInitialProjectileSpeed(r20);
|
|
InitializeProjectile(v0);
|
|
projectile_bomb_pre_instructions[v1] = kFireChargedBeam_Funcs[projectile_type[v1] & 0xF];
|
|
}
|
|
}
|
|
|
|
void HudSelectionHandler_MissilesOrSuperMissiles(void) { // 0x90BE62
|
|
if ((button_config_shoot_x & joypad1_newkeys) == 0 && (button_config_shoot_x & joypad1_newinput_samusfilter) == 0
|
|
|| !(Samus_CanFireSuperMissile() & 1)) {
|
|
return;
|
|
}
|
|
if (hud_item_index != 2) {
|
|
if (samus_missiles)
|
|
goto LABEL_10;
|
|
LABEL_5:
|
|
--projectile_counter;
|
|
return;
|
|
}
|
|
if (!samus_super_missiles)
|
|
goto LABEL_5;
|
|
LABEL_10:;
|
|
uint16 v0 = 0;
|
|
while (projectile_damage[v0 >> 1]) {
|
|
v0 += 2;
|
|
if ((int16)(v0 - 10) >= 0)
|
|
goto LABEL_5;
|
|
}
|
|
uint16 r20 = v0;
|
|
if (!(InitProjectilePositionDirection(r20) & 1)) {
|
|
projectile_invincibility_timer = 20;
|
|
if (hud_item_index == 2)
|
|
--samus_super_missiles;
|
|
else
|
|
--samus_missiles;
|
|
int v1 = r20 >> 1;
|
|
projectile_timers[v1] = 4;
|
|
uint16 v3 = hud_item_index;
|
|
uint16 r18 = swap16(hud_item_index);
|
|
projectile_type[v1] |= r18 | 0x8000;
|
|
uint16 v4 = 2 * (v3 & 0xF);
|
|
if (!cinematic_function)
|
|
QueueSfx1_Max6(kNonBeamProjectile_Sfx[v4 >> 1]);
|
|
InitializeProjectileSpeedOfType(r20);
|
|
InitializeProjectile(r20);
|
|
uint16 v7 = projectile_type[v1];
|
|
if ((v7 & 0x200) != 0)
|
|
projectile_bomb_pre_instructions[v1] = FUNC16(ProjPreInstr_SuperMissile);
|
|
else
|
|
projectile_bomb_pre_instructions[v1] = FUNC16(ProjPreInstr_Missile);
|
|
cooldown_timer = kNonBeamProjectileCooldowns[HIBYTE(v7) & 0xF];
|
|
if (samus_auto_cancel_hud_item_index) {
|
|
hud_item_index = 0;
|
|
samus_auto_cancel_hud_item_index = 0;
|
|
return;
|
|
}
|
|
if (hud_item_index == 2) {
|
|
if (samus_super_missiles)
|
|
return;
|
|
} else if (samus_missiles) {
|
|
return;
|
|
}
|
|
hud_item_index = 0;
|
|
}
|
|
}
|
|
|
|
void Missile_Func2(void) { // 0x90BF46
|
|
uint16 v0 = 0;
|
|
while (projectile_damage[v0 >> 1]) {
|
|
v0 += 2;
|
|
if ((int16)(v0 - 10) >= 0)
|
|
return;
|
|
}
|
|
uint16 r20 = v0;
|
|
int v1 = v0 >> 1;
|
|
projectile_type[v1] |= 0x8200;
|
|
int v2 = projectile_index >> 1;
|
|
projectile_x_pos[v1] = projectile_x_pos[v2];
|
|
projectile_y_pos[v1] = projectile_y_pos[v2];
|
|
projectile_dir[v1] = projectile_dir[v2];
|
|
InitProjectilePositionDirection(r20);
|
|
InitializeInstrForSuperMissile(v0);
|
|
projectile_bomb_pre_instructions[v1] = FUNC16(ProjPreInstr_Func1);
|
|
projectile_variables[projectile_index >> 1] = v0 + (projectile_variables[projectile_index >> 1] & 0xFF00);
|
|
++projectile_counter;
|
|
}
|
|
|
|
void HudSelectionHandler_MorphBall(void) { // 0x90BF9D
|
|
if ((button_config_shoot_x & joypad1_lastkeys) != 0) {
|
|
if (hud_item_index == 3) {
|
|
if ((power_bomb_flag & 0x8000) == 0) {
|
|
if (HudSelectionHandler_MorphBall_Helper2() & 1) {
|
|
if (samus_power_bombs) {
|
|
if ((--samus_power_bombs & 0x8000) == 0) {
|
|
power_bomb_flag = -1;
|
|
uint16 v2 = 10;
|
|
while (projectile_type[v2 >> 1]) {
|
|
v2 += 2;
|
|
if ((int16)(v2 - 20) >= 0) {
|
|
v2 -= 2;
|
|
break;
|
|
}
|
|
}
|
|
// r20 = v2;
|
|
uint16 r18 = swap16(hud_item_index);
|
|
int v4 = v2 >> 1;
|
|
uint16 v5 = r18 | projectile_type[v4];
|
|
projectile_type[v4] = v5;
|
|
uint8 v6 = HIBYTE(v5);
|
|
projectile_dir[v4] = 0;
|
|
projectile_x_pos[v4] = samus_x_pos;
|
|
projectile_y_pos[v4] = samus_y_pos;
|
|
projectile_variables[v4] = 60;
|
|
InitializeInstrForMissile(v2);
|
|
projectile_bomb_pre_instructions[v4] = FUNC16(ProjPreInstr_PowerBomb);
|
|
cooldown_timer = kNonBeamProjectileCooldowns[v6 & 0xF];
|
|
if (samus_auto_cancel_hud_item_index) {
|
|
hud_item_index = 0;
|
|
samus_auto_cancel_hud_item_index = 0;
|
|
} else if (hud_item_index == 3 && !samus_power_bombs) {
|
|
hud_item_index = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else if (HudSelectionHandler_MorphBall_Helper() & 1) {
|
|
uint16 v0 = 10;
|
|
while (projectile_type[v0 >> 1]) {
|
|
v0 += 2;
|
|
if ((int16)(v0 - 20) >= 0) {
|
|
v0 -= 2;
|
|
break;
|
|
}
|
|
}
|
|
// r20 = v0;
|
|
int v1 = v0 >> 1;
|
|
projectile_type[v1] = 1280;
|
|
projectile_dir[v1] = 0;
|
|
projectile_x_pos[v1] = samus_x_pos;
|
|
projectile_y_pos[v1] = samus_y_pos;
|
|
projectile_variables[v1] = 60;
|
|
InitializeInstrForMissile(v0);
|
|
projectile_bomb_pre_instructions[v1] = FUNC16(ProjPreInstr_Bomb);
|
|
cooldown_timer = kNonBeamProjectileCooldowns[5];
|
|
}
|
|
} else if (flare_counter) {
|
|
QueueSfx1_Max9(2);
|
|
flare_counter = 0;
|
|
ClearFlareAnimationState();
|
|
Samus_LoadSuitPalette();
|
|
}
|
|
}
|
|
|
|
uint8 HudSelectionHandler_MorphBall_Helper(void) { // 0x90C0AB
|
|
if ((equipped_items & 0x1000) != 0) {
|
|
if (sign16(flare_counter - 60) || bomb_counter)
|
|
return HudSelectionHandler_MorphBall_Helper2();
|
|
if ((joypad1_lastkeys & kButton_Down) != 0 && sign16((bomb_spread_charge_timeout_counter & 0xC0) - 192)) {
|
|
++bomb_spread_charge_timeout_counter;
|
|
} else {
|
|
BombSpread();
|
|
Samus_LoadSuitPalette();
|
|
QueueSfx1_Max9(2);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
uint8 HudSelectionHandler_MorphBall_Helper2(void) { // 0x90C0E7
|
|
if ((button_config_shoot_x & joypad1_newkeys) == 0
|
|
|| bomb_counter && (!sign16(bomb_counter - 5) || (uint8)cooldown_timer)) {
|
|
if (flare_counter) {
|
|
QueueSfx1_Max9(2);
|
|
flare_counter = 0;
|
|
ClearFlareAnimationState();
|
|
Samus_LoadSuitPalette();
|
|
}
|
|
return 0;
|
|
} else {
|
|
++cooldown_timer;
|
|
++bomb_counter;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
void Bomb_Func2(void) { // 0x90C128
|
|
uint16 v0 = projectile_index;
|
|
int v1 = projectile_index >> 1;
|
|
uint16 v2 = projectile_variables[v1];
|
|
if (v2) {
|
|
uint16 v3 = v2 - 1;
|
|
projectile_variables[v1] = v3;
|
|
if (v3) {
|
|
if (v3 == 15)
|
|
projectile_bomb_instruction_ptr[v1] += 28;
|
|
} else {
|
|
QueueSfx2_Max6(8);
|
|
InitializeBombExplosion(v0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void PowerBomb_Func3(void) { // 0x90C157
|
|
uint16 v0 = projectile_index;
|
|
int v1 = projectile_index >> 1;
|
|
uint16 v2 = projectile_variables[v1];
|
|
if (v2) {
|
|
uint16 v3 = v2 - 1;
|
|
projectile_variables[v1] = v3;
|
|
if (v3) {
|
|
if (v3 == 15)
|
|
projectile_bomb_instruction_ptr[v1] += 28;
|
|
} else {
|
|
power_bomb_explosion_x_pos = projectile_x_pos[v1];
|
|
power_bomb_explosion_y_pos = projectile_y_pos[v1];
|
|
EnableHdmaObjects();
|
|
SpawnPowerBombExplosion();
|
|
projectile_variables[v0 >> 1] = -1;
|
|
}
|
|
} else if (!power_bomb_flag) {
|
|
ClearProjectile(projectile_index);
|
|
}
|
|
}
|
|
|
|
static Func_U8 *const kRunSwitchedToHudHandler[6] = { // 0x90C4B5
|
|
SwitchToHudHandler_Nothing,
|
|
SwitchToHudHandler_Missiles,
|
|
SwitchToHudHandler_SuperMissiles,
|
|
SwitchToHudHandler_PowerBombs,
|
|
SwitchToHudHandler_Grapple,
|
|
SwitchToHudHandler_Xray,
|
|
};
|
|
void HandleSwitchingHudSelection(void) {
|
|
uint16 v0;
|
|
uint16 r22 = 0;
|
|
uint16 r18 = hud_item_index;
|
|
if ((button_config_itemcancel_y & joypad1_newkeys) != 0) {
|
|
samus_auto_cancel_hud_item_index = 0;
|
|
LABEL_5:
|
|
v0 = 0;
|
|
goto LABEL_6;
|
|
}
|
|
r22 = (button_config_itemcancel_y & joypad1_lastkeys) != 0;
|
|
if ((button_config_itemswitch & joypad1_newkeys) == 0)
|
|
goto LABEL_13;
|
|
v0 = hud_item_index + 1;
|
|
if (!sign16(hud_item_index - 5))
|
|
goto LABEL_5;
|
|
LABEL_6:
|
|
hud_item_index = v0;
|
|
while (kRunSwitchedToHudHandler[v0]() & 1) {
|
|
v0 = hud_item_index + 1;
|
|
hud_item_index = v0;
|
|
if (!sign16(v0 - 6)) {
|
|
v0 = 0;
|
|
hud_item_index = 0;
|
|
}
|
|
}
|
|
if (r22)
|
|
samus_auto_cancel_hud_item_index = hud_item_index;
|
|
else
|
|
samus_auto_cancel_hud_item_index = 0;
|
|
LABEL_13:
|
|
if (hud_item_index == r18) {
|
|
uint16 v1 = hud_item_changed_this_frame + 1;
|
|
if (!sign16(hud_item_changed_this_frame - 2))
|
|
v1 = 2;
|
|
hud_item_changed_this_frame = v1;
|
|
} else {
|
|
hud_item_changed_this_frame = 1;
|
|
}
|
|
}
|
|
|
|
uint8 SwitchToHudHandler_Nothing(void) { // 0x90C545
|
|
flare_counter = 0;
|
|
ClearFlareAnimationState();
|
|
Samus_LoadSuitPalette();
|
|
return 0;
|
|
}
|
|
|
|
uint8 SwitchToHudHandler_Missiles(void) { // 0x90C551
|
|
if (!samus_missiles)
|
|
return 1;
|
|
flare_counter = 0;
|
|
ClearFlareAnimationState();
|
|
Samus_LoadSuitPalette();
|
|
return 0;
|
|
}
|
|
|
|
uint8 SwitchToHudHandler_SuperMissiles(void) { // 0x90C564
|
|
if (!samus_super_missiles)
|
|
return 1;
|
|
flare_counter = 0;
|
|
ClearFlareAnimationState();
|
|
Samus_LoadSuitPalette();
|
|
return 0;
|
|
}
|
|
|
|
uint8 SwitchToHudHandler_PowerBombs(void) { // 0x90C577
|
|
if (!samus_power_bombs)
|
|
return 1;
|
|
flare_counter = 0;
|
|
ClearFlareAnimationState();
|
|
Samus_LoadSuitPalette();
|
|
return 0;
|
|
}
|
|
|
|
uint8 SwitchToHudHandler_Grapple(void) { // 0x90C58A
|
|
if ((equipped_items & 0x4000) == 0)
|
|
return 1;
|
|
if (grapple_beam_function == FUNC16(GrappleBeamFunc_Inactive)) {
|
|
Samus_LoadSuitPalette();
|
|
flare_counter = 0;
|
|
ClearFlareAnimationState();
|
|
grapple_beam_function = FUNC16(GrappleBeamFunc_Inactive);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
uint8 SwitchToHudHandler_Xray(void) { // 0x90C5AE
|
|
if ((equipped_items & 0x8000) == 0)
|
|
return 1;
|
|
flare_counter = 0;
|
|
ClearFlareAnimationState();
|
|
Samus_LoadSuitPalette();
|
|
return 0;
|
|
}
|
|
|
|
void HandleArmCannonOpenState(void) { // 0x90C5C4
|
|
if (flag_arm_cannon_opening_or_closing || UpdateArmCannonIsOpenFlag() & 1)
|
|
AdvanceArmCannonFrame();
|
|
arm_cannon_drawing_mode = RomPtr_90(kPlayerPoseToPtr[samus_pose])[1];
|
|
}
|
|
|
|
uint8 UpdateArmCannonIsOpenFlag(void) { // 0x90C5EB
|
|
static const int8 kFlagShouldArmCannonBeOpen[6] = { 0, 1, 1, 0, 1, 0 };
|
|
if (sign16(hud_item_changed_this_frame - 2))
|
|
return 0;
|
|
uint16 r18 = kFlagShouldArmCannonBeOpen[hud_item_index];
|
|
if (flag_arm_cannon_open_or_opening == r18)
|
|
return 0;
|
|
if (r18)
|
|
arm_cannon_frame = 0;
|
|
else
|
|
arm_cannon_frame = 4;
|
|
*(uint16 *)&flag_arm_cannon_open_or_opening = r18 | 0x100;
|
|
return 1;
|
|
}
|
|
|
|
void AdvanceArmCannonFrame(void) { // 0x90C627
|
|
if (flag_arm_cannon_open_or_opening) {
|
|
if (sign16(arm_cannon_frame - 2)) {
|
|
++arm_cannon_frame;
|
|
return;
|
|
}
|
|
arm_cannon_frame = 3;
|
|
} else {
|
|
if (arm_cannon_frame != 1 && (int16)(arm_cannon_frame - 1) >= 0) {
|
|
--arm_cannon_frame;
|
|
return;
|
|
}
|
|
arm_cannon_frame = 0;
|
|
}
|
|
*(uint16 *)&flag_arm_cannon_open_or_opening = flag_arm_cannon_open_or_opening;
|
|
}
|
|
|
|
void Samus_ArmCannon_Draw(void) { // 0x90C663
|
|
static const uint16 kDrawArmCannon_Char[10] = { 0x281f, 0x281f, 0x281f, 0x681f, 0xa81f, 0xe81f, 0x281f, 0x681f, 0x681f, 0x681f };
|
|
uint16 v3;
|
|
uint16 r22;
|
|
|
|
if (arm_cannon_frame && (!samus_invincibility_timer || (nmi_frame_counter_word & 1) == 0)) {
|
|
uint16 v0 = kPlayerPoseToPtr[samus_pose];
|
|
const uint8 *v1 = RomPtr_90(v0);
|
|
int16 v2 = *v1;
|
|
if ((v2 & 0x80) != 0) {
|
|
if (samus_anim_frame)
|
|
v3 = 2 * (v1[2] & 0x7F);
|
|
else
|
|
v3 = 2 * (*v1 & 0x7F);
|
|
r22 = v0 + 4;
|
|
} else {
|
|
v3 = 2 * v2;
|
|
r22 = v0 + 2;
|
|
}
|
|
uint16 r24 = kDrawArmCannon_Char[v3 >> 1];
|
|
const uint8 *v4 = RomPtr_90(r22 + 2 * samus_anim_frame);
|
|
uint16 r18 = (int8)v4[0], r20 = (int8)v4[1];
|
|
r22 = kPoseParams[samus_pose].y_offset_to_gfx;
|
|
uint16 v7 = oam_next_ptr;
|
|
int16 v8 = r18 + samus_x_pos - layer1_x_pos;
|
|
if (v8 >= 0) {
|
|
if (sign16(v8 - 256)) {
|
|
OamEnt *v9 = gOamEnt(oam_next_ptr);
|
|
v9->xcoord = v8;
|
|
int16 v10 = r20 + samus_y_pos - r22 - layer1_y_pos;
|
|
if (v10 >= 0) {
|
|
if (sign16(v10 - 256)) {
|
|
v9->ycoord = v10;
|
|
*(uint16 *)&v9->charnum = r24;
|
|
oam_next_ptr = v7 + 4;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
const uint8 *v11 = RomPtr_90(kPlayerPoseToPtr[samus_pose]);
|
|
int16 v12 = *v11;
|
|
if ((v12 & 0x80) != 0) {
|
|
if (samus_anim_frame)
|
|
v12 = *RomPtr_90(kPlayerPoseToPtr[samus_pose] + 2) & 0x7F;
|
|
else
|
|
v12 = *v11 & 0x7F;
|
|
}
|
|
uint16 v13 = kDrawArmCannon_Tab2[v12] + 2 * arm_cannon_frame;
|
|
uint16 v14 = vram_write_queue_tail;
|
|
gVramWriteEntry(vram_write_queue_tail)->size = 32;
|
|
v14 += 2;
|
|
uint16 v15 = *(uint16 *)RomPtr_90(v13);
|
|
gVramWriteEntry(v14)->size = v15;
|
|
v14 += 2;
|
|
LOBYTE(gVramWriteEntry(v14++)->size) = -102;
|
|
gVramWriteEntry(v14)->size = addr_unk_6061F0;
|
|
vram_write_queue_tail = v14 + 2;
|
|
}
|
|
}
|
|
|
|
static uint16 Projectile_SinLookup_Inner(uint16 k, uint16 r24) { // 0x90CC8A
|
|
uint16 prod = Mult8x8(*((uint8 *)&kSinCosTable8bit_Sext[64] + k), r24);
|
|
uint16 r18 = prod >> 8;
|
|
prod = Mult8x8(*((uint8 *)&kSinCosTable8bit_Sext[64] + k + 1), r24);
|
|
return r18 + prod;
|
|
}
|
|
|
|
Point16U Projectile_SinLookup(uint16 j, uint16 a) { // 0x90CC39
|
|
uint16 v2, v4;
|
|
uint16 r24 = a;
|
|
uint16 r26 = j;
|
|
if (sign16(j - 128))
|
|
v2 = Projectile_SinLookup_Inner(2 * j, r24);
|
|
else
|
|
v2 = -Projectile_SinLookup_Inner(2 * (uint8)(j + 0x80), r24);
|
|
int16 v3 = (uint8)(r26 - 64);
|
|
if (sign16(v3 - 128))
|
|
v4 = Projectile_SinLookup_Inner(2 * v3, r24);
|
|
else
|
|
v4 = -Projectile_SinLookup_Inner(2 * (uint8)(v3 + 0x80), r24);
|
|
return (Point16U) { v2, v4 };
|
|
}
|
|
|
|
|
|
static const uint16 kCostOfSbaInPowerBombs[12] = { // 0x90CCC0
|
|
0, 1, 1, 0, 1, 0, 0, 0,
|
|
1, 0, 0, 0,
|
|
};
|
|
|
|
static Func_V_A *const kFireSbaFuncs[12] = {
|
|
FireSba_ClearCarry,
|
|
FireSba_FireWave,
|
|
FireSba_FireIce,
|
|
FireSba_ClearCarry,
|
|
FireSba_FireSpazer,
|
|
FireSba_ClearCarry,
|
|
FireSba_ClearCarry,
|
|
FireSba_ClearCarry,
|
|
FireSba_FirePlasma,
|
|
FireSba_ClearCarry,
|
|
FireSba_ClearCarry,
|
|
FireSba_ClearCarry,
|
|
};
|
|
|
|
uint8 FireSba(void) {
|
|
int16 v2;
|
|
|
|
if (hud_item_index != 3)
|
|
return 0;
|
|
uint16 v1 = 2 * (equipped_beams & 0xF);
|
|
v2 = samus_power_bombs - kCostOfSbaInPowerBombs[v1 >> 1];
|
|
if (v2 < 0)
|
|
v2 = 0;
|
|
samus_power_bombs = v2;
|
|
uint8 rv = kFireSbaFuncs[v1 >> 1]();
|
|
if (!samus_power_bombs) {
|
|
hud_item_index = 0;
|
|
samus_auto_cancel_hud_item_index = 0;
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
uint8 FireSba_ClearCarry(void) { // 0x90CD18
|
|
return 0;
|
|
}
|
|
|
|
uint8 FireSba_FireWave(void) { // 0x90CD1A
|
|
static const int16 kFireSba_FireWave_X[4] = { 128, 128, -128, -128 };
|
|
static const int16 kFireSba_FireWave_Y[4] = { 128, -128, -128, 128 };
|
|
|
|
for (int i = 6; i >= 0; i -= 2) {
|
|
int v1 = i >> 1;
|
|
projectile_timers[v1] = 4;
|
|
projectile_type[v1] = equipped_beams & 0x100F | 0x8010;
|
|
projectile_dir[v1] = 0;
|
|
projectile_bomb_pre_instructions[v1] = FUNC16(ProjPreInstr_WaveSba);
|
|
projectile_bomb_y_speed[v1] = 600;
|
|
projectile_bomb_x_speed[v1] = 0;
|
|
projectile_variables[v1] = 0;
|
|
projectile_bomb_x_subpos[v1] = 0;
|
|
projectile_bomb_y_subpos[v1] = 0;
|
|
projectile_x_pos[v1] = kFireSba_FireWave_X[v1] + samus_x_pos;
|
|
projectile_y_pos[v1] = kFireSba_FireWave_Y[v1] + samus_y_pos;
|
|
InitializeSbaProjectile(i);
|
|
}
|
|
projectile_counter = 4;
|
|
cooldown_timer = kProjectileCooldown_Uncharged[projectile_type[0] & 0x3F];
|
|
used_for_sba_attacksB60 = 4;
|
|
QueueSfx1_Max6(0x28);
|
|
return 1;
|
|
}
|
|
|
|
uint8 FireSba_FireIce(void) { // 0x90CD9B
|
|
static const uint16 kIcePlasmaSbaProjectileOriginAngles[8] = { 0, 0x40, 0x80, 0xc0, 0x20, 0x60, 0xa0, 0xe0 };
|
|
|
|
if (projectile_bomb_pre_instructions[0] == FUNC16(ProjPreInstr_IceSba2)
|
|
|| projectile_bomb_pre_instructions[0] == FUNC16(ProjPreInstr_IceSba)) {
|
|
return 0;
|
|
}
|
|
for (int i = 6; i >= 0; i -= 2) {
|
|
int v2 = i >> 1;
|
|
projectile_timers[v2] = 4;
|
|
projectile_type[v2] = equipped_beams & 0x100F | 0x8010;
|
|
projectile_dir[v2] = 0;
|
|
projectile_bomb_pre_instructions[v2] = FUNC16(ProjPreInstr_IceSba);
|
|
projectile_variables[v2] = kIcePlasmaSbaProjectileOriginAngles[v2];
|
|
projectile_bomb_y_speed[v2] = 600;
|
|
InitializeProjectile(i);
|
|
}
|
|
projectile_counter = 4;
|
|
cooldown_timer = kProjectileCooldown_Uncharged[projectile_type[0] & 0x3F];
|
|
if (samus_pose_x_dir == 4)
|
|
used_for_sba_attacksB60 = -4;
|
|
else
|
|
used_for_sba_attacksB60 = 4;
|
|
QueueSfx1_Max6(0x23);
|
|
return 1;
|
|
}
|
|
|
|
uint8 FireSba_FireSpazer(void) { // 0x90CE14
|
|
static const int16 kFireSpazer_Timer[4] = { 0, 0, 4, 4 };
|
|
static const int16 kFireSpazer_Yspeed[4] = { 4, -4, 4, -4 };
|
|
|
|
for (int i = 6; i >= 0; i -= 2) {
|
|
int v1 = i >> 1;
|
|
projectile_timers[v1] = kFireSpazer_Timer[v1];
|
|
projectile_dir[v1] = 5;
|
|
projectile_bomb_pre_instructions[v1] = FUNC16(ProjPreInstr_SpazerSba);
|
|
projectile_bomb_x_speed[v1] = 40;
|
|
projectile_bomb_y_speed[v1] = kFireSpazer_Yspeed[v1];
|
|
projectile_variables[v1] = 0;
|
|
projectile_unk_A[v1] = 0;
|
|
projectile_bomb_x_subpos[v1] = 0;
|
|
projectile_bomb_y_subpos[v1] = 0;
|
|
if ((int16)(i - 4) >= 0) {
|
|
projectile_type[i >> 1] = -32732;
|
|
InitializeShinesparkEchoOrSpazerSba(i);
|
|
} else {
|
|
projectile_type[i >> 1] = equipped_beams & 0x100F | 0x8010;
|
|
InitializeSbaProjectile(i);
|
|
}
|
|
}
|
|
projectile_counter = 4;
|
|
cooldown_timer = kProjectileCooldown_Uncharged[projectile_type[0] & 0x3F];
|
|
used_for_sba_attacksB60 = 0;
|
|
QueueSfx1_Max6(0x25);
|
|
return 1;
|
|
}
|
|
|
|
uint8 FireSba_FirePlasma(void) { // 0x90CE98
|
|
static const uint16 kIcePlasmaSbaProjectileOriginAngles[8] = { 0, 0x40, 0x80, 0xc0, 0x20, 0x60, 0xa0, 0xe0 };
|
|
|
|
|
|
if (projectile_bomb_pre_instructions[0] == FUNC16(ProjPreInstr_PlasmaSba))
|
|
return 0;
|
|
for (int i = 6; i >= 0; i -= 2) {
|
|
int v2 = i >> 1;
|
|
projectile_type[v2] = equipped_beams & 0x100F | 0x8010;
|
|
projectile_dir[v2] = 0;
|
|
projectile_bomb_pre_instructions[v2] = FUNC16(ProjPreInstr_PlasmaSba);
|
|
projectile_variables[v2] = kIcePlasmaSbaProjectileOriginAngles[v2];
|
|
projectile_bomb_x_speed[v2] = 40;
|
|
projectile_bomb_y_speed[v2] = 0;
|
|
InitializeSbaProjectile(i);
|
|
}
|
|
projectile_counter = 4;
|
|
cooldown_timer = kProjectileCooldown_Uncharged[projectile_type[0] & 0x3F];
|
|
if (samus_pose_x_dir == 4)
|
|
used_for_sba_attacksB60 = -4;
|
|
else
|
|
used_for_sba_attacksB60 = 4;
|
|
QueueSfx1_Max6(0x27);
|
|
return 1;
|
|
}
|
|
|
|
void ProjPreInstr_IceSba(uint16 k) { // 0x90CF09
|
|
int v1 = k >> 1;
|
|
if ((projectile_dir[v1] & 0xF0) != 0) {
|
|
QueueSfx1_Max6(0x24);
|
|
ClearProjectile(k);
|
|
} else {
|
|
bool v2 = projectile_timers[v1]-- == 1;
|
|
if (v2) {
|
|
projectile_timers[v1] = 4;
|
|
SpawnProjectileTrail(k);
|
|
k = projectile_index;
|
|
}
|
|
int v3 = k >> 1;
|
|
Point16U pt = Projectile_SinLookup(projectile_variables[v3], 0x20);
|
|
projectile_x_pos[v3] = pt.x + samus_x_pos;
|
|
projectile_y_pos[v3] = pt.y + samus_y_pos;
|
|
projectile_variables[v3] = (uint8)(used_for_sba_attacksB60 + projectile_variables[v3]);
|
|
v2 = projectile_bomb_y_speed[v3]-- == 1;
|
|
if (v2) {
|
|
projectile_bomb_pre_instructions[v3] = FUNC16(ProjPreInstr_IceSba2);
|
|
projectile_bomb_x_speed[v3] = 40;
|
|
QueueSfx1_Max6(0x24);
|
|
}
|
|
cooldown_timer = 2;
|
|
flare_counter = 0;
|
|
}
|
|
}
|
|
|
|
void ProjPreInstr_IceSba2(uint16 k) { // 0x90CF7A
|
|
int16 v5;
|
|
int16 v6;
|
|
int16 v7;
|
|
|
|
int v1 = k >> 1;
|
|
if ((projectile_dir[v1] & 0xF0) != 0)
|
|
goto LABEL_9;
|
|
if (projectile_timers[v1]-- == 1) {
|
|
projectile_timers[v1] = 4;
|
|
SpawnProjectileTrail(k);
|
|
k = projectile_index;
|
|
}
|
|
int v3;
|
|
v3 = k >> 1;
|
|
Point16U pt = Projectile_SinLookup(projectile_variables[v3], projectile_bomb_x_speed[v3]);
|
|
pt.x += samus_x_pos;
|
|
projectile_x_pos[v3] = pt.x;
|
|
v5 = pt.x - layer1_x_pos;
|
|
if (sign16(v5 + 32)
|
|
|| !sign16(v5 - 288)
|
|
|| (v6 = pt.y + samus_y_pos, projectile_y_pos[v3] = pt.y + samus_y_pos, v7 = v6 - layer1_y_pos, sign16(v7 - 16))
|
|
|| !sign16(v7 - 256)) {
|
|
LABEL_9:
|
|
ClearProjectile(k);
|
|
} else {
|
|
projectile_variables[v3] = (uint8)(used_for_sba_attacksB60 + projectile_variables[v3]);
|
|
projectile_bomb_x_speed[v3] = (uint8)(projectile_bomb_x_speed[v3] + 8);
|
|
cooldown_timer = 2;
|
|
flare_counter = 0;
|
|
}
|
|
}
|
|
|
|
void Projectile_Func7_Shinespark(void) { // 0x90CFFA
|
|
samus_movement_handler = FUNC16(Samus_MoveHandlerShinesparkWindup);
|
|
samus_y_dir = 1;
|
|
speed_boost_counter = 1024;
|
|
samus_y_subspeed = 0;
|
|
samus_y_speed = 0;
|
|
knockback_dir = 0;
|
|
samus_x_extra_run_speed = 8;
|
|
samus_x_extra_run_subspeed = 0;
|
|
samus_x_base_speed = 0;
|
|
samus_x_base_subspeed = 0;
|
|
substate = 7;
|
|
suit_pickup_light_beam_pos = 0;
|
|
cooldown_timer = 0;
|
|
timer_for_shinesparks_startstop = 30;
|
|
samus_shine_timer = 60;
|
|
timer_for_shine_timer = 6;
|
|
special_samus_palette_frame = 0;
|
|
bomb_jump_dir = 0;
|
|
if (flare_counter) {
|
|
if (!sign16(flare_counter - 16))
|
|
QueueSfx1_Max9(2);
|
|
flare_counter = 0;
|
|
ClearFlareAnimationState();
|
|
}
|
|
}
|
|
|
|
void Samus_MoveHandlerShinesparkWindup(void) { // 0x90D068
|
|
bool v0 = (--timer_for_shinesparks_startstop & 0x8000) != 0;
|
|
if (!timer_for_shinesparks_startstop || v0) {
|
|
if (samus_pose_x_dir == 4)
|
|
samus_new_pose_interrupted = 204;
|
|
else
|
|
samus_new_pose_interrupted = 203;
|
|
samus_movement_handler = FUNC16(Samus_MoveHandlerVerticalShinespark);
|
|
samus_input_handler = FUNC16(nullsub_152);
|
|
speed_echoes_index = 0;
|
|
speed_echo_xspeed[0] = 0;
|
|
speed_echo_xspeed[1] = 0;
|
|
speed_echo_xpos[0] = 0;
|
|
speed_echo_xpos[1] = 0;
|
|
QueueSfx3_Max9(0xF);
|
|
}
|
|
}
|
|
|
|
void Samus_MoveHandlerVerticalShinespark(void) { // 0x90D0AB
|
|
samus_contact_damage_index = 2;
|
|
samus_hurt_flash_counter = 8;
|
|
Samus_UpdateSpeedEchoPos();
|
|
Samus_ShinesparkMove_Y();
|
|
Samus_EndSuperJump();
|
|
if (!sign16(samus_health - 30) && (--samus_health & 0x8000) != 0)
|
|
samus_health = 0;
|
|
}
|
|
|
|
void Samus_MoveHandler_Shinespark_Diag(void) { // 0x90D0D7
|
|
samus_contact_damage_index = 2;
|
|
samus_hurt_flash_counter = 8;
|
|
Samus_UpdateSpeedEchoPos();
|
|
Samus_ShinesparkMove_X();
|
|
Samus_ShinesparkMove_Y();
|
|
Samus_EndSuperJump();
|
|
if (!sign16(samus_health - 30) && (--samus_health & 0x8000) != 0)
|
|
samus_health = 0;
|
|
}
|
|
|
|
void Samus_MoveHandler_Shinespark_Horiz(void) { // 0x90D106
|
|
samus_contact_damage_index = 2;
|
|
samus_hurt_flash_counter = 8;
|
|
Samus_UpdateSpeedEchoPos();
|
|
Samus_ShinesparkMove_X();
|
|
Samus_EndSuperJump();
|
|
if (!sign16(samus_health - 30) && (--samus_health & 0x8000) != 0)
|
|
samus_health = 0;
|
|
}
|
|
|
|
static uint32 Samus_ClampSpeedHi(int32 amt, int val) {
|
|
if (!sign16((amt >> 16) - val))
|
|
amt = val << 16 | (amt & 0xffff);
|
|
return amt;
|
|
}
|
|
|
|
void Samus_ShinesparkMove_X(void) { // 0x90D132
|
|
int16 v4;
|
|
|
|
samus_shine_timer = 15;
|
|
uint16 v0 = (__PAIR32__(samus_y_accel, samus_y_subaccel) + __PAIR32__(samus_x_extra_run_speed, samus_x_extra_run_subspeed)) >> 16;
|
|
samus_x_extra_run_subspeed += samus_y_subaccel;
|
|
samus_x_extra_run_speed = v0;
|
|
if (!sign16(v0 - 15)) {
|
|
samus_x_extra_run_speed = 15;
|
|
samus_x_extra_run_subspeed = 0;
|
|
}
|
|
int32 amt = 0;
|
|
if (samus_pose_x_dir == 4) {
|
|
amt = Samus_ClampSpeedHi(-(int32)Samus_CalcDisplacementMoveLeft(amt), 15);
|
|
CheckEnemyColl_Result cres = Samus_CheckSolidEnemyColl(amt);
|
|
amt = cres.amt;
|
|
if (cres.collision) {
|
|
samus_collision_flag = cres.collision;
|
|
goto LABEL_18;
|
|
}
|
|
amt = -(int32)amt;
|
|
} else {
|
|
amt = Samus_ClampSpeedHi(Samus_CalcDisplacementMoveRight(amt), 25);
|
|
CheckEnemyColl_Result cres = Samus_CheckSolidEnemyColl(amt);
|
|
amt = cres.amt;
|
|
if (cres.collision) {
|
|
samus_collision_flag = cres.collision;
|
|
goto LABEL_18;
|
|
}
|
|
}
|
|
Samus_MoveRight_NoSolidColl(amt);
|
|
Samus_AlignYPosSlope();
|
|
LABEL_18:
|
|
v4 = samus_x_pos - samus_prev_x_pos;
|
|
if ((int16)(samus_x_pos - samus_prev_x_pos) < 0) {
|
|
if (sign16(v4 + 15))
|
|
samus_prev_x_pos = samus_x_pos + 15;
|
|
} else if (!sign16(v4 - 16)) {
|
|
samus_prev_x_pos = samus_x_pos - 15;
|
|
}
|
|
}
|
|
|
|
void Samus_ShinesparkMove_Y(void) { // 0x90D1FF
|
|
samus_shine_timer = 15;
|
|
|
|
AddToHiLo(&substate, &suit_pickup_light_beam_pos, __PAIR32__(samus_y_accel, samus_y_subaccel));
|
|
|
|
AddToHiLo(&samus_y_speed, &samus_y_subspeed, __PAIR32__(substate, suit_pickup_light_beam_pos));
|
|
int32 amt = Samus_ClampSpeedHi(__PAIR32__(samus_y_speed, samus_y_subspeed), 14);
|
|
amt -= __PAIR32__(extra_samus_y_displacement, extra_samus_y_subdisplacement);
|
|
samus_collision_direction = 2;
|
|
CheckEnemyColl_Result cres = Samus_CheckSolidEnemyColl(Samus_ClampSpeedHi(amt, 15));
|
|
amt = cres.amt;
|
|
if (cres.collision) {
|
|
samus_collision_flag = cres.collision;
|
|
} else {
|
|
Samus_MoveDown_NoSolidColl(-(int32)amt);
|
|
}
|
|
if (sign16(samus_y_pos - samus_prev_y_pos + 14))
|
|
samus_prev_y_pos = samus_y_pos + 14;
|
|
}
|
|
|
|
uint8 Samus_EndSuperJump(void) { // 0x90D2BA
|
|
if (!sign16(samus_health - 30) && !samus_collision_flag)
|
|
return 0;
|
|
if (samus_pose_x_dir == 4) {
|
|
speed_echo_xspeed[0] = 32;
|
|
speed_echo_xspeed[1] = 160;
|
|
speed_echo_xpos[2] = 4;
|
|
} else {
|
|
speed_echo_xspeed[0] = 224;
|
|
speed_echo_xspeed[1] = 96;
|
|
speed_echo_xpos[2] = -4;
|
|
}
|
|
samus_y_subspeed = 0;
|
|
samus_y_speed = 0;
|
|
samus_x_extra_run_speed = 0;
|
|
samus_x_extra_run_subspeed = 0;
|
|
speed_boost_counter = 0;
|
|
UNUSED_word_7E0B1A = 0;
|
|
samus_y_dir = 0;
|
|
samus_movement_handler = FUNC16(Samus_MoveHandler_ShinesparkCrash);
|
|
samus_draw_handler = FUNC16(Samus_DrawHandler_EndOfShinespark);
|
|
speed_echoes_index = 0;
|
|
speed_echo_xpos[0] = samus_x_pos;
|
|
speed_echo_xpos[1] = samus_x_pos;
|
|
speed_echo_ypos[0] = samus_y_pos;
|
|
speed_echo_ypos[1] = samus_y_pos;
|
|
speed_echo_xspeed[2] = 0;
|
|
samus_hurt_flash_counter = 0;
|
|
QueueSfx1_Max6(0x35);
|
|
QueueSfx3_Max6(0x10);
|
|
return 1;
|
|
}
|
|
|
|
static Func_V *const kSamus_MoveHandler_ShinesparkCrash[3] = { // 0x90D346
|
|
Samus_MoveHandler_ShinesparkCrash_0,
|
|
Samus_MoveHandler_ShinesparkCrash_1,
|
|
Samus_MoveHandler_ShinesparkCrash_2,
|
|
};
|
|
|
|
void Samus_MoveHandler_ShinesparkCrash(void) {
|
|
|
|
samus_shine_timer = 15;
|
|
kSamus_MoveHandler_ShinesparkCrash[HIBYTE(speed_echoes_index)]();
|
|
for (int i = 2; i >= 0; i -= 2) {
|
|
int v1 = i >> 1;
|
|
Point16U pt = Projectile_SinLookup(speed_echo_xspeed[v1], (uint8)speed_echoes_index);
|
|
speed_echo_xpos[v1] = pt.x + samus_x_pos;
|
|
speed_echo_ypos[v1] = pt.y + samus_y_pos;
|
|
}
|
|
}
|
|
|
|
void Samus_MoveHandler_ShinesparkCrash_0(void) { // 0x90D383
|
|
uint16 v0 = speed_echoes_index + 4;
|
|
if (!sign16(speed_echoes_index - 12))
|
|
v0 |= 0x100;
|
|
speed_echoes_index = v0;
|
|
}
|
|
|
|
void Samus_MoveHandler_ShinesparkCrash_1(void) { // 0x90D396
|
|
speed_echo_xspeed[0] = (uint8)(LOBYTE(speed_echo_xpos[2]) + LOBYTE(speed_echo_xspeed[0]));
|
|
speed_echo_xspeed[1] = (uint8)(LOBYTE(speed_echo_xpos[2]) + LOBYTE(speed_echo_xspeed[1]));
|
|
speed_echo_ypos[2] += 4;
|
|
if (!sign16(speed_echo_ypos[2] - 128))
|
|
speed_echoes_index = (uint8)speed_echoes_index | 0x200;
|
|
}
|
|
|
|
void Samus_MoveHandler_ShinesparkCrash_2(void) { // 0x90D3CC
|
|
speed_echoes_index -= 4;
|
|
if (!(uint8)speed_echoes_index) {
|
|
samus_movement_handler = FUNC16(Samus_MoveHandler_ShinesparkCrashEchoCircle);
|
|
timer_for_shinesparks_startstop = 30;
|
|
speed_echoes_index = 0;
|
|
speed_echo_xspeed[0] = 0;
|
|
speed_echo_xspeed[1] = 0;
|
|
}
|
|
}
|
|
|
|
void Samus_MoveHandler_ShinesparkCrashEchoCircle(void) { // 0x90D3F3
|
|
samus_shine_timer = 15;
|
|
bool v0 = (--timer_for_shinesparks_startstop & 0x8000) != 0;
|
|
if (!timer_for_shinesparks_startstop || v0) {
|
|
samus_movement_handler = FUNC16(Samus_MoveHandler_ShinesparkCrashFinish);
|
|
samus_draw_handler = FUNC16(SamusDrawHandler_Default);
|
|
}
|
|
}
|
|
|
|
void Samus_MoveHandler_ShinesparkCrashFinish(void) { // 0x90D40D
|
|
static const uint8 kShinesparkCrashFinish_Tab0[12] = { 0, 0x80, 0, 0x80, 0x40, 0xc0, 0x40, 0xc0, 0xe0, 0x60, 0x20, 0xa0 };
|
|
speed_echoes_index = 0;
|
|
if (sign16(projectile_counter - 5)) {
|
|
if (sign16(projectile_counter - 4)) {
|
|
++projectile_counter;
|
|
speed_echo_xspeed[2] = 64;
|
|
speed_echo_xpos[2] = samus_x_pos;
|
|
speed_echo_ypos[2] = samus_y_pos;
|
|
projectile_type[3] = addr_loc_908029;
|
|
InitializeShinesparkEchoOrSpazerSba(6);
|
|
projectile_bomb_pre_instructions[3] = FUNC16(ProjPreInstr_SpeedEcho);
|
|
projectile_variables[3] = kShinesparkCrashFinish_Tab0[(uint16)(2 * (samus_pose - 201))];
|
|
projectile_bomb_x_speed[3] = 0;
|
|
}
|
|
++projectile_counter;
|
|
speed_echo_xspeed[3] = 64;
|
|
speed_echo_xpos[3] = samus_x_pos;
|
|
speed_echo_ypos[3] = samus_y_pos;
|
|
projectile_type[4] = addr_loc_908029;
|
|
InitializeShinesparkEchoOrSpazerSba(8);
|
|
projectile_bomb_pre_instructions[4] = FUNC16(ProjPreInstr_SpeedEcho);
|
|
projectile_variables[4] = kShinesparkCrashFinish_Tab0[(uint16)(2 * (samus_pose - 201)) + 1];
|
|
projectile_bomb_x_speed[4] = 0;
|
|
}
|
|
cooldown_timer = 0;
|
|
samus_shine_timer = 1;
|
|
if (samus_pose_x_dir == 4)
|
|
samus_new_pose_transitional = 2;
|
|
else
|
|
samus_new_pose_transitional = 1;
|
|
samus_hurt_switch_index = 2;
|
|
substate = 0;
|
|
suit_pickup_light_beam_pos = 0;
|
|
}
|
|
|
|
void ProjPreInstr_SpeedEcho(uint16 k) { // 0x90D4D2
|
|
int16 v3;
|
|
uint16 v4;
|
|
int16 v5;
|
|
|
|
int v1 = k >> 1;
|
|
projectile_bomb_x_speed[v1] += 8;
|
|
Point16U pt = Projectile_SinLookup(projectile_variables[v1], LOBYTE(projectile_bomb_x_speed[v1]));
|
|
uint16 v2 = pt.x + samus_x_pos;
|
|
*(uint16 *)((uint8 *)&speed_echoes_index + k) = pt.x + samus_x_pos;
|
|
projectile_x_pos[v1] = v2;
|
|
v3 = v2 - layer1_x_pos;
|
|
if (v3 < 0
|
|
|| !sign16(v3 - 256)
|
|
|| (v4 = pt.y + samus_y_pos,
|
|
speed_echo_xpos[v1 + 3] = pt.y + samus_y_pos,
|
|
projectile_y_pos[v1] = v4,
|
|
v5 = v4 - layer1_y_pos,
|
|
v5 < 0)
|
|
|| !sign16(v5 - 256)) {
|
|
speed_echo_ypos[v1 + 3] = 0;
|
|
*(uint16 *)((uint8 *)&speed_echoes_index + k) = 0;
|
|
speed_echo_xpos[v1 + 3] = 0;
|
|
ClearProjectile(k);
|
|
}
|
|
}
|
|
|
|
void Grapple_Func1(void) { // 0x90D525
|
|
bool v0; // sf
|
|
|
|
if ((button_config_shoot_x & joypad1_lastkeys) != 0
|
|
&& (v0 = (int16)(grapple_walljump_timer - 1) < 0, --grapple_walljump_timer, grapple_walljump_timer)
|
|
&& !v0) {
|
|
if ((grapple_beam_length_delta & 0x8000) == 0) {
|
|
grapple_beam_length += grapple_beam_length_delta;
|
|
if (!sign16(grapple_beam_length - 96))
|
|
grapple_beam_length_delta = -16;
|
|
}
|
|
Point16U pt = Projectile_SinLookup(HIBYTE(grapple_beam_end_angle16), grapple_beam_length);
|
|
grapple_beam_end_x_pos = pt.x + x_pos_of_start_of_grapple_beam;
|
|
grapple_beam_end_y_pos = pt.y + y_pos_of_start_of_grapple_beam;
|
|
grapple_beam_end_angle16 += 2048;
|
|
GrappleBeamFunc_BF1B();
|
|
} else {
|
|
grapple_beam_function = FUNC16(GrappleBeamFunc_Cancel);
|
|
}
|
|
}
|
|
|
|
uint8 Hdmaobj_CrystalFlash(void) { // 0x90D5A2
|
|
SamusPose v1;
|
|
|
|
if (sign16(game_state - 40)) {
|
|
if (joypad1_lastkeys != (button_config_shoot_x | 0x430))
|
|
return 1;
|
|
}
|
|
if (samus_y_speed
|
|
|| samus_y_subspeed
|
|
|| !sign16(samus_health - 51)
|
|
|| samus_reserve_health
|
|
|| sign16(samus_missiles - 10)
|
|
|| sign16(samus_super_missiles - 10)
|
|
|| sign16(samus_power_bombs - 10)) {
|
|
return 1;
|
|
}
|
|
v1 = samus_pose_x_dir == 4 ? kPose_D4_FaceL_CrystalFlash : kPose_D3_FaceR_CrystalFlash;
|
|
samus_pose = v1;
|
|
SamusFunc_F433();
|
|
Samus_SetAnimationFrameIfPoseChanged();
|
|
if (samus_movement_type != 27)
|
|
return 1;
|
|
samus_last_different_pose = samus_prev_pose;
|
|
*(uint16 *)&samus_last_different_pose_x_dir = *(uint16 *)&samus_prev_pose_x_dir;
|
|
samus_prev_pose = samus_pose;
|
|
*(uint16 *)&samus_prev_pose_x_dir = *(uint16 *)&samus_pose_x_dir;
|
|
samus_movement_handler = FUNC16(SamusMoveHandler_CrystalFlashStart);
|
|
if (samus_input_handler != FUNC16(Samus_InputHandler_E91D))
|
|
samus_input_handler = FUNC16(nullsub_152);
|
|
timer_for_shinesparks_startstop = 9;
|
|
which_item_to_pickup = 0;
|
|
substate = 10;
|
|
suit_pickup_light_beam_pos = 0;
|
|
*(uint16 *)&suit_pickup_color_math_R = 0;
|
|
timer_for_shine_timer = 7;
|
|
special_samus_palette_frame = 0;
|
|
samus_shine_timer = 1;
|
|
*(uint16 *)&suit_pickup_color_math_B = 1;
|
|
samus_invincibility_timer = 0;
|
|
samus_knockback_timer = 0;
|
|
knockback_dir = 0;
|
|
return 0;
|
|
}
|
|
|
|
void SamusMoveHandler_CrystalFlashStart(void) { // 0x90D678
|
|
samus_y_pos -= 2;
|
|
if ((--timer_for_shinesparks_startstop & 0x8000) != 0) {
|
|
samus_anim_frame_timer = 3;
|
|
samus_anim_frame = 6;
|
|
*(uint16 *)&suit_pickup_color_math_R = samus_y_pos;
|
|
samus_movement_handler = FUNC16(SamusMoveHandler_CrystalFlashMain);
|
|
samus_invincibility_timer = 0;
|
|
samus_knockback_timer = 0;
|
|
QueueSfx3_Max15(1);
|
|
power_bomb_flag = 0;
|
|
power_bomb_explosion_x_pos = samus_x_pos;
|
|
power_bomb_explosion_y_pos = samus_y_pos;
|
|
EnableHdmaObjects();
|
|
SpawnCrystalFlashHdmaObjs();
|
|
}
|
|
}
|
|
|
|
static Func_V *const kSamusMoveHandler_CrystalFlashMainFuncs[3] = { // 0x90D6CE
|
|
SamusMoveHandler_CrystalFlashMain_0,
|
|
SamusMoveHandler_CrystalFlashMain_1,
|
|
SamusMoveHandler_CrystalFlashMain_2,
|
|
};
|
|
|
|
void SamusMoveHandler_CrystalFlashMain(void) {
|
|
kSamusMoveHandler_CrystalFlashMainFuncs[which_item_to_pickup]();
|
|
samus_invincibility_timer = 0;
|
|
samus_knockback_timer = 0;
|
|
}
|
|
|
|
void SamusMoveHandler_CrystalFlashMain_0(void) { // 0x90D6E3
|
|
if ((nmi_frame_counter_word & 7) == 0) {
|
|
--samus_missiles;
|
|
Samus_RestoreHealth(0x32);
|
|
bool v0 = (int16)(substate - 1) < 0;
|
|
if (!--substate || v0) {
|
|
substate = 10;
|
|
++which_item_to_pickup;
|
|
}
|
|
}
|
|
}
|
|
|
|
void SamusMoveHandler_CrystalFlashMain_1(void) { // 0x90D706
|
|
if ((nmi_frame_counter_word & 7) == 0) {
|
|
--samus_super_missiles;
|
|
Samus_RestoreHealth(0x32);
|
|
bool v0 = (int16)(substate - 1) < 0;
|
|
if (!--substate || v0) {
|
|
substate = 10;
|
|
++which_item_to_pickup;
|
|
}
|
|
}
|
|
}
|
|
|
|
void SamusMoveHandler_CrystalFlashMain_2(void) { // 0x90D729
|
|
if ((nmi_frame_counter_word & 7) == 0) {
|
|
--samus_power_bombs;
|
|
Samus_RestoreHealth(0x32);
|
|
bool v0 = (int16)(substate - 1) < 0;
|
|
if (!--substate || v0) {
|
|
samus_movement_handler = FUNC16(kSamusMoveHandler_CrystalFlashFinish);
|
|
samus_draw_handler = FUNC16(SamusDrawHandler_Default);
|
|
samus_anim_frame_timer = 3;
|
|
samus_anim_frame = 12;
|
|
}
|
|
}
|
|
}
|
|
|
|
void kSamusMoveHandler_CrystalFlashFinish(void) { // 0x90D75B
|
|
if (samus_y_pos != *(uint16 *)&suit_pickup_color_math_R)
|
|
++samus_y_pos;
|
|
if (!samus_movement_type) {
|
|
power_bomb_flag = 0;
|
|
samus_shine_timer = -1;
|
|
samus_movement_handler = FUNC16(Samus_MovementHandler_Normal);
|
|
if (samus_input_handler != FUNC16(Samus_InputHandler_E91D)) {
|
|
samus_input_handler = FUNC16(Samus_InputHandler_E913);
|
|
samus_invincibility_timer = 0;
|
|
samus_knockback_timer = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void ProjPreInstr_PlasmaSba(uint16 k) { // 0x90D793
|
|
int16 v3;
|
|
|
|
int v1 = k >> 1;
|
|
if ((projectile_dir[v1] & 0xF0) != 0) {
|
|
ClearProjectile(k);
|
|
} else {
|
|
cooldown_timer = 2;
|
|
flare_counter = 0;
|
|
Point16U pt = Projectile_SinLookup(projectile_variables[v1], projectile_bomb_x_speed[v1]);
|
|
projectile_x_pos[v1] = pt.x + samus_x_pos;
|
|
projectile_y_pos[v1] = pt.y + samus_y_pos;
|
|
projectile_variables[v1] = (uint8)(used_for_sba_attacksB60 + projectile_variables[v1]);
|
|
v3 = 2 * projectile_bomb_y_speed[v1];
|
|
if (v3) {
|
|
if (v3 == 2) {
|
|
ProjPreInstr_PlasmaSbaFunc_1(k);
|
|
} else {
|
|
if (v3 != 4) {
|
|
Unreachable();
|
|
while (1)
|
|
;
|
|
}
|
|
ProjPreInstr_PlasmaSbaFunc_2(k);
|
|
}
|
|
} else {
|
|
ProjPreInstr_PlasmaSbaFunc_0(k);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ProjPreInstr_PlasmaSbaFunc_0(uint16 j) { // 0x90D7E1
|
|
int v1 = j >> 1;
|
|
uint16 v2 = (uint8)(projectile_bomb_x_speed[v1] + 4);
|
|
projectile_bomb_x_speed[v1] = v2;
|
|
if (!sign16(v2 - 192))
|
|
projectile_bomb_y_speed[v1] = 1;
|
|
}
|
|
|
|
void ProjPreInstr_PlasmaSbaFunc_1(uint16 j) { // 0x90D7FA
|
|
int v1 = j >> 1;
|
|
uint16 v2 = (uint8)(projectile_bomb_x_speed[v1] - 4);
|
|
projectile_bomb_x_speed[v1] = v2;
|
|
if (sign16(v2 - 45))
|
|
projectile_bomb_y_speed[v1] = 2;
|
|
}
|
|
|
|
void ProjPreInstr_PlasmaSbaFunc_2(uint16 j) { // 0x90D813
|
|
int v1 = j >> 1;
|
|
if (sign16(projectile_x_pos[v1] - layer1_x_pos + 32)
|
|
|| !sign16(projectile_x_pos[v1] - layer1_x_pos - 288)
|
|
|| sign16(projectile_y_pos[v1] - layer1_y_pos - 16)
|
|
|| !sign16(projectile_y_pos[v1] - layer1_y_pos - 256)) {
|
|
ClearProjectile(j);
|
|
} else {
|
|
projectile_bomb_x_speed[v1] = (uint8)(projectile_bomb_x_speed[v1] + 4);
|
|
}
|
|
}
|
|
|
|
static const uint16 kBombSpread_Tab0[5] = { 0x78, 0x6e, 0x64, 0x6e, 0x78 };
|
|
static const uint16 kBombSpread_Tab1[5] = { 0x8100, 0x8080, 0, 0x80, 0x100 };
|
|
static const uint16 kBombSpread_Tab2[5] = { 0, 1, 2, 1, 0 };
|
|
static const uint16 kBombSpread_Tab3[5] = { 0, 0, 0x8000, 0, 0 };
|
|
|
|
void ProjPreInstr_SpreadBomb(uint16 k) { // 0x90D8F7
|
|
int v1 = k >> 1;
|
|
if ((projectile_dir[v1] & 0xF0) != 0) {
|
|
ClearProjectile(k);
|
|
return;
|
|
}
|
|
Bomb_Func2();
|
|
if (projectile_variables[v1]) {
|
|
uint16 v2 = projectile_timers[v1];
|
|
bool v3 = __CFADD__uint16(samus_y_subaccel, v2);
|
|
projectile_timers[v1] = samus_y_subaccel + v2;
|
|
projectile_bomb_y_speed[v1] += samus_y_accel + v3;
|
|
uint16 v4 = projectile_bomb_y_subpos[v1];
|
|
v3 = __CFADD__uint16(projectile_timers[v1], v4);
|
|
projectile_bomb_y_subpos[v1] = projectile_timers[v1] + v4;
|
|
projectile_y_pos[v1] += projectile_bomb_y_speed[v1] + v3;
|
|
if (BlockCollSpreadBomb(k) & 1) {
|
|
uint16 v5 = projectile_index - 10;
|
|
int v6 = projectile_index >> 1;
|
|
uint16 v7 = projectile_bomb_y_subpos[v6];
|
|
v3 = v7 < projectile_timers[v6];
|
|
projectile_bomb_y_subpos[v6] = v7 - projectile_timers[v6];
|
|
projectile_y_pos[v6] -= v3 + projectile_bomb_y_speed[v6];
|
|
if ((projectile_bomb_y_speed[v6] & 0x8000) != 0) {
|
|
projectile_bomb_y_speed[v6] = 0;
|
|
projectile_y_radius[v6] = 0;
|
|
} else {
|
|
projectile_timers[v6] = kBombSpread_Tab3[v5 >> 1];
|
|
projectile_bomb_y_speed[v6] = projectile_unk_A[v6];
|
|
}
|
|
return;
|
|
}
|
|
k = projectile_index;
|
|
int v8 = projectile_index >> 1;
|
|
uint16 t = projectile_bomb_x_speed[v8];
|
|
uint16 r20 = t << 8;
|
|
uint16 r18 = t >> 8;
|
|
if (t & 0x8000) {
|
|
r18 = r18 & 0x7F;
|
|
uint16 v11 = projectile_bomb_x_subpos[v8];
|
|
v3 = v11 < r20;
|
|
projectile_bomb_x_subpos[v8] = v11 - r20;
|
|
projectile_x_pos[v8] -= v3 + r18;
|
|
} else {
|
|
uint16 v10 = projectile_bomb_x_subpos[v8];
|
|
v3 = __CFADD__uint16(r20, v10);
|
|
projectile_bomb_x_subpos[v8] = r20 + v10;
|
|
projectile_x_pos[v8] += r18 + v3;
|
|
}
|
|
}
|
|
if (BlockCollSpreadBomb(k) & 1) {
|
|
int v12 = projectile_index >> 1;
|
|
uint16 t = projectile_bomb_x_speed[v12];
|
|
uint16 r20 = t << 8;
|
|
uint16 r18 = (t >> 8) & 0x7F;
|
|
if (t & 0x8000) {
|
|
projectile_bomb_x_speed[v12] = t | 0x8000;
|
|
uint16 v16 = projectile_bomb_x_subpos[v12];
|
|
bool v3 = v16 < r20;
|
|
projectile_bomb_x_subpos[v12] = v16 - r20;
|
|
projectile_x_pos[v12] -= v3 + r18;
|
|
} else {
|
|
projectile_bomb_x_speed[v12] = t & 0x7FFF;
|
|
uint16 v14 = projectile_bomb_x_subpos[v12];
|
|
bool v3 = __CFADD__uint16(r20, v14);
|
|
projectile_bomb_x_subpos[v12] = r20 + v14;
|
|
projectile_x_pos[v12] += r18 + v3;
|
|
}
|
|
}
|
|
}
|
|
|
|
void ProjPreInstr_WaveSba(uint16 k) { // 0x90DA08
|
|
int v1 = k >> 1;
|
|
bool v2, v3;
|
|
if ((projectile_dir[v1] & 0xF0) != 0
|
|
|| (v2 = projectile_bomb_y_speed[v1] == 1,
|
|
v3 = (int16)(projectile_bomb_y_speed[v1] - 1) < 0,
|
|
--projectile_bomb_y_speed[v1],
|
|
v2)
|
|
|| v3) {
|
|
QueueSfx1_Max6(0x29);
|
|
ClearProjectile(k);
|
|
return;
|
|
}
|
|
uint16 R34 = projectile_bomb_x_speed[v1];
|
|
//R36 = projectile_variables[v1];
|
|
v2 = projectile_timers[v1]-- == 1;
|
|
if (v2) {
|
|
projectile_timers[v1] = 4;
|
|
SpawnProjectileTrail(k);
|
|
k = projectile_index;
|
|
}
|
|
int v4 = k >> 1;
|
|
if ((int16)(samus_x_pos - projectile_x_pos[v4]) < 0) {
|
|
if (!sign16(projectile_bomb_x_speed[v4] + 2047))
|
|
projectile_bomb_x_speed[v4] -= 64;
|
|
} else if (sign16(projectile_bomb_x_speed[v4] - 2048)) {
|
|
projectile_bomb_x_speed[v4] += 64;
|
|
}
|
|
uint16 v5 = swap16(projectile_bomb_x_speed[v4]);
|
|
uint16 r20 = v5 & 0xFF00;
|
|
uint16 r18 = (int8)v5;
|
|
uint16 v6 = projectile_bomb_x_subpos[v4];
|
|
bool v7 = __CFADD__uint16(r20, v6);
|
|
projectile_bomb_x_subpos[v4] = r20 + v6;
|
|
projectile_x_pos[v4] += r18 + v7;
|
|
if ((int16)(samus_y_pos - projectile_y_pos[v4]) < 0) {
|
|
if (!sign16(projectile_variables[v4] + 2047))
|
|
projectile_variables[v4] -= 64;
|
|
} else if (sign16(projectile_variables[v4] - 2048)) {
|
|
projectile_variables[v4] += 64;
|
|
}
|
|
uint16 v8 = swap16(projectile_variables[v4]);
|
|
r20 = v8 & 0xFF00;
|
|
r18 = (int8)v8;
|
|
uint16 v9 = projectile_bomb_y_subpos[v4];
|
|
v7 = __CFADD__uint16(r20, v9);
|
|
projectile_bomb_y_subpos[v4] = r20 + v9;
|
|
projectile_y_pos[v4] += r18 + v7;
|
|
if (k == 6) {
|
|
if ((projectile_bomb_x_speed[3] & 0x8000) != 0) {
|
|
if ((R34 & 0x8000) == 0)
|
|
LABEL_26:
|
|
QueueSfx1_Max6(0x28);
|
|
} else if ((R34 & 0x8000) != 0) {
|
|
goto LABEL_26;
|
|
}
|
|
}
|
|
cooldown_timer = 2;
|
|
flare_counter = 0;
|
|
}
|
|
|
|
void BombSpread(void) { // 0x90D849
|
|
if (bomb_functions[0] != FUNC16(ProjPreInstr_SpreadBomb)) {
|
|
uint16 v0 = 10;
|
|
do {
|
|
int v1 = v0 >> 1;
|
|
projectile_type[v1] = -31488;
|
|
projectile_dir[v1] = 0;
|
|
projectile_bomb_pre_instructions[v1] = FUNC16(ProjPreInstr_SpreadBomb);
|
|
InitializeInstrForMissile(v0);
|
|
projectile_x_pos[v1] = samus_x_pos;
|
|
projectile_bomb_x_subpos[v1] = 0;
|
|
projectile_y_pos[v1] = samus_y_pos;
|
|
projectile_bomb_y_subpos[v1] = 0;
|
|
int v2 = (uint16)(v0 - 10) >> 1;
|
|
projectile_bomb_x_speed[v1] = kBombSpread_Tab1[v2];
|
|
projectile_timers[v1] = kBombSpread_Tab3[v2];
|
|
uint16 v3 = -(int16)(kBombSpread_Tab2[v2] + ((bomb_spread_charge_timeout_counter >> 6) & 3));
|
|
projectile_bomb_y_speed[v1] = v3;
|
|
projectile_unk_A[v1] = v3;
|
|
projectile_variables[v1] = kBombSpread_Tab0[v2];
|
|
v0 += 2;
|
|
} while ((int16)(v0 - 20) < 0);
|
|
bomb_counter = 5;
|
|
cooldown_timer = kNonBeamProjectileCooldowns[HIBYTE(projectile_type[5]) & 0xF];
|
|
bomb_spread_charge_timeout_counter = 0;
|
|
flare_counter = 0;
|
|
}
|
|
}
|
|
|
|
typedef void Func_SpazerSba_V(uint16 j, uint16 r22);
|
|
|
|
static Func_SpazerSba_V *const kProjPreInstr_SpazerSba_FuncsB[3] = { // 0x90DB06
|
|
ProjPreInstr_SpazerSba_FuncB_0,
|
|
ProjPreInstr_SpazerSba_FuncB_1,
|
|
ProjPreInstr_SpazerSba_FuncB_2,
|
|
};
|
|
|
|
static Func_Y_V *const kProjPreInstr_SpazerSba_FuncsA[4] = {
|
|
ProjPreInstr_SpazerSba_FuncA_0,
|
|
ProjPreInstr_SpazerSba_FuncA_1,
|
|
ProjPreInstr_SpazerSba_FuncA_2,
|
|
ProjPreInstr_SpazerSba_FuncA_3,
|
|
};
|
|
|
|
void ProjPreInstr_SpazerSba(uint16 k) {
|
|
int v1 = k >> 1;
|
|
if ((projectile_dir[v1] & 0xF0) != 0) {
|
|
kProjPreInstr_SpazerSba_FuncsA[v1](k);
|
|
} else {
|
|
int v2 = k >> 1;
|
|
if (projectile_timers[v2]-- == 1) {
|
|
projectile_timers[v2] = 4;
|
|
SpawnProjectileTrail(k);
|
|
k = projectile_index;
|
|
}
|
|
int v4 = k >> 1;
|
|
Point16U pt = Projectile_SinLookup(projectile_variables[v4], projectile_bomb_x_speed[v4]);
|
|
projectile_x_pos[v4] = pt.x + samus_x_pos;
|
|
kProjPreInstr_SpazerSba_FuncsB[projectile_unk_A[v4] >> 1](k, pt.y);
|
|
cooldown_timer = 2;
|
|
flare_counter = 0;
|
|
}
|
|
}
|
|
|
|
void ProjPreInstr_SpazerSba_FuncA_0(uint16 k) { // 0x90DB57
|
|
ClearProjectile(k);
|
|
ClearProjectile(4);
|
|
}
|
|
|
|
void ProjPreInstr_SpazerSba_FuncA_1(uint16 k) { // 0x90DB66
|
|
ClearProjectile(k);
|
|
ClearProjectile(6);
|
|
}
|
|
|
|
void ProjPreInstr_SpazerSba_FuncA_2(uint16 k) { // 0x90DB75
|
|
ClearProjectile(k);
|
|
ClearProjectile(0);
|
|
}
|
|
|
|
void ProjPreInstr_SpazerSba_FuncA_3(uint16 k) { // 0x90DB84
|
|
ClearProjectile(k);
|
|
ClearProjectile(2);
|
|
}
|
|
|
|
void ProjPreInstr_SpazerSba_FuncB_0(uint16 j, uint16 r22) { // 0x90DB93
|
|
static const int16 kProjPreInstr_SpazerSba_Yspeed[4] = { 2, -2, 2, -2 };
|
|
|
|
int v1 = j >> 1;
|
|
projectile_y_pos[v1] = r22 + samus_y_pos;
|
|
uint16 v2 = (uint8)(LOBYTE(projectile_bomb_y_speed[v1]) + LOBYTE(projectile_variables[v1]));
|
|
projectile_variables[v1] = v2;
|
|
if (v2 == 128) {
|
|
projectile_bomb_x_speed[v1] = 160;
|
|
projectile_bomb_y_speed[v1] = kProjPreInstr_SpazerSba_Yspeed[v1];
|
|
projectile_dir[v1] = 0;
|
|
projectile_unk_A[v1] = 2;
|
|
}
|
|
}
|
|
|
|
void ProjPreInstr_SpazerSba_FuncB_1(uint16 j, uint16 r22) { // 0x90DBCF
|
|
static const int16 kSpazerProjectileYSpeed[4] = { -2, 2, -2, 2 };
|
|
|
|
uint16 v1 = r22 + samus_y_pos - 114;
|
|
int v2 = j >> 1;
|
|
projectile_y_pos[v2] = v1;
|
|
if (sign16(v1 - layer1_y_pos - 16)) {
|
|
FireEndOfSpazerSba(j);
|
|
} else {
|
|
projectile_variables[v2] = (uint8)(LOBYTE(projectile_bomb_y_speed[v2]) + LOBYTE(projectile_variables[v2]));
|
|
uint16 v3 = projectile_bomb_x_speed[v2] - 5;
|
|
projectile_bomb_x_speed[v2] = v3;
|
|
if (!v3) {
|
|
projectile_bomb_y_speed[v2] = kSpazerProjectileYSpeed[v2];
|
|
projectile_variables[v2] = (uint8)(projectile_variables[v2] + 0x80);
|
|
projectile_unk_A[v2] = 4;
|
|
if (!j)
|
|
QueueSfx1_Max6(0x26);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ProjPreInstr_SpazerSba_FuncB_2(uint16 j, uint16 r22) { // 0x90DC30
|
|
int v2;
|
|
uint16 v3;
|
|
|
|
uint16 v1 = r22 + samus_y_pos - 114;
|
|
projectile_y_pos[j >> 1] = v1;
|
|
if (sign16(v1 - layer1_y_pos - 16)
|
|
|| (v2 = j >> 1,
|
|
projectile_variables[v2] = (uint8)(LOBYTE(projectile_bomb_y_speed[v2])
|
|
+ LOBYTE(projectile_variables[v2])),
|
|
v3 = projectile_bomb_x_speed[v2] + 5,
|
|
projectile_bomb_x_speed[v2] = v3,
|
|
!sign16(v3 - 96))) {
|
|
FireEndOfSpazerSba(j);
|
|
}
|
|
}
|
|
|
|
void FireEndOfSpazerSba(uint16 j) { // 0x90DC67
|
|
static const int16 kFireEndOfSpazerSba[4] = { 16, 16, -16, -16 };
|
|
|
|
int v1 = j >> 1;
|
|
projectile_x_pos[v1] += kFireEndOfSpazerSba[v1];
|
|
projectile_dir[v1] = 5;
|
|
projectile_timers[v1] = 4;
|
|
projectile_bomb_pre_instructions[v1] = FUNC16(ProjPreInstr_EndOfSpazerSba);
|
|
if ((int16)(j - 4) < 0) {
|
|
projectile_type[j >> 1] = -32732;
|
|
InitializeShinesparkEchoOrSpazerSba(j);
|
|
}
|
|
}
|
|
|
|
void ProjPreInstr_EndOfSpazerSba(uint16 k) { // 0x90DC9C
|
|
int v1 = k >> 1;
|
|
if ((projectile_dir[v1] & 0xF0) != 0)
|
|
goto LABEL_2;
|
|
if (projectile_timers[v1]-- == 1) {
|
|
projectile_timers[v1] = 4;
|
|
SpawnProjectileTrail(k);
|
|
k = projectile_index;
|
|
}
|
|
int v3;
|
|
v3 = k >> 1;
|
|
uint16 v4;
|
|
v4 = projectile_y_pos[v3] + 8;
|
|
projectile_y_pos[v3] = v4;
|
|
if (!sign16(v4 - layer1_y_pos - 248)) {
|
|
LABEL_2:
|
|
ClearProjectile(k);
|
|
} else {
|
|
cooldown_timer = 2;
|
|
flare_counter = 0;
|
|
}
|
|
}
|
|
|
|
static Func_V *kHandleHudSpecificBehaviorAndProjs[28] = { // 0x90DCDD
|
|
HudSelectionHandler_Normal,
|
|
HudSelectionHandler_Normal,
|
|
HudSelectionHandler_Normal,
|
|
HudSelectionHandler_JumpEtc,
|
|
HudSelectionHandler_MorphBall,
|
|
HudSelectionHandler_Normal,
|
|
HudSelectionHandler_Normal,
|
|
HudSelectionHandler_MorphBall,
|
|
HudSelectionHandler_MorphBall,
|
|
HudSelectionHandler_MorphBall,
|
|
HudSelectionHandler_JumpEtc,
|
|
HudSelectionHandler_Grappling,
|
|
HudSelectionHandler_Grappling,
|
|
HudSelectionHandler_JumpEtc,
|
|
HudSelectionHandler_TurningAround,
|
|
HudSelectionHandler_CrouchEtcTrans,
|
|
HudSelectionHandler_Normal,
|
|
HudSelectionHandler_MorphBall,
|
|
HudSelectionHandler_MorphBall,
|
|
HudSelectionHandler_MorphBall,
|
|
HudSelectionHandler_JumpEtc,
|
|
HudSelectionHandler_Normal,
|
|
HudSelectionHandler_Grappling,
|
|
HudSelectionHandler_TurningAround,
|
|
HudSelectionHandler_TurningAround,
|
|
HudSelectionHandler_JumpEtc,
|
|
HudSelectionHandler_GrabbedByDraygon,
|
|
HudSelectionHandler_JumpEtc,
|
|
};
|
|
|
|
void Samus_HandleHudSpecificBehaviorAndProjs(void) {
|
|
if (samus_pose == kPose_00_FaceF_Powersuit
|
|
|| samus_pose == kPose_9B_FaceF_VariaGravitySuit
|
|
|| (Samus_HandleCooldown(),
|
|
HandleSwitchingHudSelection(),
|
|
kHandleHudSpecificBehaviorAndProjs[samus_movement_type](),
|
|
!time_is_frozen_flag)) {
|
|
HandleProjectile();
|
|
}
|
|
}
|
|
|
|
void HudSelectionHandler_Normal(void) { // 0x90DD3D
|
|
static Func_V *const kHudSelectionHandler_Normal[7] = {
|
|
HudSelectionHandler_NothingOrPowerBombs,
|
|
HudSelectionHandler_MissilesOrSuperMissiles,
|
|
HudSelectionHandler_MissilesOrSuperMissiles,
|
|
HudSelectionHandler_NothingOrPowerBombs,
|
|
HudSelectionHandler_Grappling,
|
|
HudSelectionHandler_Xray,
|
|
HudSelectionHandler_TurningAround,
|
|
};
|
|
uint16 v0;
|
|
if (grapple_beam_function == FUNC16(GrappleBeamFunc_Inactive)) {
|
|
if (time_is_frozen_flag)
|
|
v0 = 10;
|
|
else
|
|
v0 = 2 * hud_item_index;
|
|
} else {
|
|
v0 = 8;
|
|
}
|
|
kHudSelectionHandler_Normal[v0 >> 1]();
|
|
}
|
|
|
|
void HudSelectionHandler_Grappling(void) { // 0x90DD6F
|
|
GrappleBeamHandler();
|
|
}
|
|
|
|
void HudSelectionHandler_TurningAround(void) { // 0x90DD74
|
|
if (new_projectile_direction_changed_pose) {
|
|
HudSelectionHandler_Normal();
|
|
} else if (grapple_beam_function != FUNC16(GrappleBeamFunc_Inactive)) {
|
|
grapple_beam_function = FUNC16(GrappleBeamFunc_Cancel);
|
|
}
|
|
}
|
|
|
|
void HudSelectionHandler_CrouchEtcTrans(void) { // 0x90DD8C
|
|
static const uint8 byte_90DDAA[12] = { 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1 };
|
|
if (!sign16(samus_pose - kPose_F1_FaceR_CrouchTrans_AimU))
|
|
goto LABEL_4;
|
|
if (!sign16(samus_pose - kPose_DB))
|
|
return;
|
|
if (byte_90DDAA[(uint16)(samus_pose - 53)]) {
|
|
if (grapple_beam_function != FUNC16(GrappleBeamFunc_Inactive)) {
|
|
grapple_beam_function = FUNC16(GrappleBeamFunc_Cancel);
|
|
HudSelectionHandler_Normal();
|
|
}
|
|
} else {
|
|
LABEL_4:
|
|
HudSelectionHandler_Normal();
|
|
}
|
|
}
|
|
|
|
void HudSelectionHandler_JumpEtc(void) { // 0x90DDB6
|
|
if (grapple_beam_function != FUNC16(GrappleBeamFunc_Inactive)) {
|
|
grapple_beam_function = FUNC16(GrappleBeamFunc_Cancel);
|
|
HudSelectionHandler_Normal();
|
|
}
|
|
}
|
|
|
|
void HudSelectionHandler_Xray(void) { // 0x90DDC8
|
|
if ((button_config_run_b & joypad1_lastkeys) != 0)
|
|
XrayRunHandler();
|
|
else
|
|
HudSelectionHandler_NothingOrPowerBombs();
|
|
}
|
|
|
|
void HudSelectionHandler_GrabbedByDraygon(void) { // 0x90DDD8
|
|
if (samus_pose == (kPose_DB | kPose_04_FaceL_AimU))
|
|
HudSelectionHandler_MorphBall();
|
|
else
|
|
HudSelectionHandler_Normal();
|
|
}
|
|
|
|
static Func_U8 *const kSamusHitInterrupts[28] = { // 0x90DDE9
|
|
Samus_HitInterrupt_Stand,
|
|
Samus_HitInterrupt_Stand,
|
|
Samus_HitInterrupt_Stand,
|
|
Samus_HitInterrupt_Stand,
|
|
Samus_HitInterrupt_Ball,
|
|
Samus_HitInterrupt_Stand,
|
|
Samus_HitInterrupt_Falling,
|
|
Samus_HitInterrupt_Unused,
|
|
Samus_HitInterrupt_Ball,
|
|
Samus_HitInterrupt_Ball,
|
|
Samus_HitInterrupt_KnockbackGrapple,
|
|
Samus_HitInterrupt_Turning,
|
|
Samus_HitInterrupt_Turning,
|
|
Samus_HitInterrupt_Stand,
|
|
Samus_HitInterrupt_Turning,
|
|
Samus_HitInterrupt_Turning,
|
|
Samus_HitInterrupt_Stand,
|
|
Samus_HitInterrupt_Ball,
|
|
Samus_HitInterrupt_Ball,
|
|
Samus_HitInterrupt_Ball,
|
|
Samus_HitInterrupt_Stand,
|
|
Samus_HitInterrupt_Stand,
|
|
Samus_HitInterrupt_KnockbackGrapple,
|
|
Samus_HitInterrupt_Turning,
|
|
Samus_HitInterrupt_Turning,
|
|
Samus_HitInterrupt_Turning,
|
|
Samus_HitInterrupt_Turning,
|
|
Samus_HitInterrupt_Shinespark,
|
|
};
|
|
|
|
void Samus_HitInterruption(void) {
|
|
if (samus_knockback_timer) {
|
|
if (sign16(debug_invincibility - 7)) {
|
|
if (!time_is_frozen_flag && !knockback_dir) {
|
|
if (kSamusHitInterrupts[samus_movement_type]() & 1)
|
|
samus_special_transgfx_index = 1;
|
|
}
|
|
} else {
|
|
samus_invincibility_timer = 0;
|
|
samus_knockback_timer = 0;
|
|
}
|
|
} else if (knockback_dir) {
|
|
if (samus_movement_type == kPose_0A_MoveL_NoAim) {
|
|
if (!sign16(flare_counter - 16))
|
|
QueueSfx1_Max6(0x41);
|
|
if (samus_pose_x_dir == 4)
|
|
samus_new_pose_transitional = kPose_2A_FaceL_Fall;
|
|
else
|
|
samus_new_pose_transitional = kPose_29_FaceR_Fall;
|
|
} else {
|
|
if (samus_hurt_switch_index == 3) {
|
|
samus_hurt_switch_index = 8;
|
|
return;
|
|
}
|
|
samus_new_pose_transitional = samus_pose;
|
|
}
|
|
samus_hurt_switch_index = 1;
|
|
} else if (bomb_jump_dir) {
|
|
SetupBombJump();
|
|
}
|
|
}
|
|
|
|
uint8 Samus_HitInterrupt_Shinespark(void) { // 0x90DEBA
|
|
if (samus_pose == kPose_E8_FaceR_Drained_CrouchFalling || samus_pose == kPose_E9_FaceL_Drained_CrouchFalling) {
|
|
samus_anim_frame_timer = 17;
|
|
samus_anim_frame = 26;
|
|
}
|
|
samus_special_transgfx_index = 0;
|
|
knockback_dir = 0;
|
|
return 0;
|
|
}
|
|
|
|
uint8 Samus_HitInterrupt_KnockbackGrapple(void) { // 0x90DEDD
|
|
samus_special_transgfx_index = 0;
|
|
return 0;
|
|
}
|
|
|
|
uint8 Samus_HitInterrupt_Turning(void) { // 0x90DEE2
|
|
samus_special_transgfx_index = 0;
|
|
knockback_dir = 0;
|
|
return 0;
|
|
}
|
|
|
|
uint8 Samus_HitInterrupt_Falling(void) { // 0x90DEEA
|
|
if (frame_handler_gamma != FUNC16(Samus_Func9))
|
|
return Samus_HitInterrupt_Stand();
|
|
samus_special_transgfx_index = 0;
|
|
knockback_dir = 0;
|
|
return 0;
|
|
}
|
|
|
|
uint8 Samus_HitInterrupt_Stand(void) { // 0x90DEFA
|
|
if (samus_pose_x_dir == 4)
|
|
samus_new_pose_interrupted = 84;
|
|
else
|
|
samus_new_pose_interrupted = 83;
|
|
return 1;
|
|
}
|
|
|
|
uint8 Samus_HitInterrupt_Ball(void) { // 0x90DF15
|
|
samus_new_pose_interrupted = samus_pose;
|
|
return 1;
|
|
}
|
|
|
|
uint8 Samus_HitInterrupt_Unused(void) { // 0x90DF1D
|
|
if (samus_pose_x_dir == 4)
|
|
samus_new_pose_interrupted = 52;
|
|
else
|
|
samus_new_pose_interrupted = 51;
|
|
return 1;
|
|
}
|
|
|
|
static Func_V *const kSamus_MoveHandler_Knockback[6] = { // 0x90DF38
|
|
Samus_MoveHandler_Knockback_0,
|
|
Samus_MoveHandler_Knockback_Up,
|
|
Samus_MoveHandler_Knockback_Up,
|
|
Samus_MoveHandler_Knockback_3,
|
|
Samus_MoveHandler_Knockback_Down,
|
|
Samus_MoveHandler_Knockback_Down,
|
|
};
|
|
|
|
void Samus_MoveHandler_Knockback(void) {
|
|
kSamus_MoveHandler_Knockback[knockback_dir]();
|
|
input_to_pose_calc = 0;
|
|
}
|
|
|
|
void Samus_MoveHandler_Knockback_0(void) { // 0x90DF50
|
|
InvalidInterrupt_Crash();
|
|
}
|
|
|
|
void Samus_MoveHandler_Knockback_Up(void) { // 0x90DF53
|
|
Samus_BombJumpRisingXMovement_();
|
|
Samus_MoveY_WithSpeedCalc();
|
|
Samus_ClearMoveVars();
|
|
}
|
|
|
|
void Samus_MoveHandler_Knockback_3(void) { // 0x90DF5D
|
|
Samus_MoveY_WithSpeedCalc();
|
|
Samus_ClearMoveVars();
|
|
}
|
|
|
|
void Samus_MoveHandler_Knockback_Down(void) { // 0x90DF64
|
|
Samus_BombJumpRisingXMovement_();
|
|
Samus_Move_NoSpeedCalc_Y();
|
|
Samus_ClearMoveVars();
|
|
}
|
|
|
|
void Samus_ClearMoveVars(void) { // 0x90DF6E
|
|
if (samus_collision_flag) {
|
|
samus_x_accel_mode = 0;
|
|
samus_collides_with_solid_enemy = 0;
|
|
samus_is_falling_flag = 0;
|
|
UNUSED_word_7E0B1A = 0;
|
|
UNUSED_word_7E0B2A = 0;
|
|
samus_y_subspeed = 0;
|
|
samus_y_speed = 0;
|
|
samus_y_dir = 0;
|
|
UNUSED_word_7E0B38 = 0;
|
|
samus_x_base_speed = 0;
|
|
samus_x_base_subspeed = 0;
|
|
Samus_AlignBottomWithPrevPose();
|
|
}
|
|
}
|
|
|
|
static Func_U8 *const kSetupBombJump[28] = { // 0x90DF99
|
|
SetupBombJump_StandCrouch,
|
|
SetupBombJump_1,
|
|
SetupBombJump_2,
|
|
SetupBombJump_2,
|
|
SetupBombJump_4,
|
|
SetupBombJump_StandCrouch,
|
|
SetupBombJump_1,
|
|
SetupBombJump_4,
|
|
SetupBombJump_4,
|
|
SetupBombJump_4,
|
|
SetupBombJump_4,
|
|
SetupBombJump_1,
|
|
SetupBombJump_1,
|
|
SetupBombJump_1,
|
|
SetupBombJump_2,
|
|
SetupBombJump_2,
|
|
SetupBombJump_1,
|
|
SetupBombJump_4,
|
|
SetupBombJump_4,
|
|
SetupBombJump_4,
|
|
SetupBombJump_1,
|
|
SetupBombJump_1,
|
|
SetupBombJump_1,
|
|
SetupBombJump_2,
|
|
SetupBombJump_2,
|
|
SetupBombJump_2,
|
|
SetupBombJump_1A,
|
|
SetupBombJump_1A,
|
|
};
|
|
void SetupBombJump(void) {
|
|
if (!HIBYTE(bomb_jump_dir)) {
|
|
if (kSetupBombJump[samus_movement_type]() & 1)
|
|
samus_special_transgfx_index = 3;
|
|
}
|
|
}
|
|
|
|
uint8 SetupBombJump_StandCrouch(void) { // 0x90DFED
|
|
if (!time_is_frozen_flag)
|
|
return SetupBombJump_1();
|
|
bomb_jump_dir = 0;
|
|
return 0;
|
|
}
|
|
|
|
uint8 SetupBombJump_1(void) { // 0x90DFF7
|
|
if (samus_pose_x_dir == 4)
|
|
samus_new_pose_interrupted = kPose_52_FaceL_Jump_NoAim_MoveF;
|
|
else
|
|
samus_new_pose_interrupted = kPose_51_FaceR_Jump_NoAim_MoveF;
|
|
return 1;
|
|
}
|
|
|
|
uint8 SetupBombJump_4(void) { // 0x90E012
|
|
samus_new_pose_interrupted = samus_pose;
|
|
return 1;
|
|
}
|
|
|
|
uint8 SetupBombJump_2(void) { // 0x90E01A
|
|
samus_input_handler = FUNC16(Samus_InputHandler_E913);
|
|
return SetupBombJump_1A();
|
|
}
|
|
|
|
uint8 SetupBombJump_1A(void) { // 0x90E020
|
|
bomb_jump_dir = 0;
|
|
return 0;
|
|
}
|
|
|
|
void Samus_MoveHandler_BombJumpStart(void) { // 0x90E025
|
|
Samus_InitBombJump();
|
|
samus_movement_handler = FUNC16(Samus_MoveHandler_BombJumpMain);
|
|
input_to_pose_calc = 0;
|
|
}
|
|
|
|
static Func_V *const kSamus_MoveHandler_BombJumpMain[4] = { // 0x90E032
|
|
Samus_MoveHandler_Knockback_0,
|
|
Samus_HorizontalBombJump,
|
|
Samus_VerticalBombJump,
|
|
Samus_HorizontalBombJump,
|
|
};
|
|
|
|
void Samus_MoveHandler_BombJumpMain(void) {
|
|
if (bomb_jump_dir)
|
|
kSamus_MoveHandler_BombJumpMain[(uint8)bomb_jump_dir]();
|
|
else
|
|
Samus_MoveHandler_BombJumpFunc1();
|
|
}
|
|
|
|
void Samus_HorizontalBombJump(void) { // 0x90E04C
|
|
Samus_BombJumpRisingXMovement_();
|
|
Samus_BombJumpRisingYMovement_();
|
|
if (samus_y_dir == 2 || (Samus_MoveY_WithSpeedCalc(), samus_collision_flag))
|
|
Samus_MoveHandler_BombJumpFunc1();
|
|
}
|
|
|
|
void Samus_VerticalBombJump(void) { // 0x90E066
|
|
Samus_BombJumpRisingYMovement_();
|
|
if (samus_y_dir == 2 || (Samus_MoveY_WithSpeedCalc(), samus_collision_flag))
|
|
Samus_MoveHandler_BombJumpFunc1();
|
|
}
|
|
|
|
void Samus_MoveHandler_BombJumpFunc1(void) { // 0x90E07D
|
|
samus_movement_handler = FUNC16(Samus_MovementHandler_Normal);
|
|
if (samus_input_handler != FUNC16(Samus_InputHandler_E91D))
|
|
samus_input_handler = FUNC16(Samus_InputHandler_E913);
|
|
bomb_jump_dir = 0;
|
|
}
|
|
|
|
void CallFrameHandlerGamma(uint32 ea) {
|
|
switch (ea) {
|
|
case fnSamus_Func1: Samus_Func1(); return;
|
|
case fnSamus_Func2: Samus_Func2(); return;
|
|
case fnSamus_Func3: Samus_Func3(); return;
|
|
case fnDrawTimer_: DrawTimer_(); return;
|
|
case fnSamus_PushOutOfRidleysWay: Samus_PushOutOfRidleysWay(); return;
|
|
case fnSamus_Func4: Samus_Func4(); return;
|
|
case fnSamus_GrabbedByDraygonFrameHandler: Samus_GrabbedByDraygonFrameHandler(); return;
|
|
case fnnullsub_151: return;
|
|
case fnSamus_Func7: Samus_Func7(); return;
|
|
case fnSamus_Func9: Samus_Func9(); return;
|
|
case fnnullsub_152: return;
|
|
default: Unreachable();
|
|
}
|
|
}
|
|
void RunFrameHandlerGamma(void) { // 0x90E097
|
|
CallFrameHandlerGamma(frame_handler_gamma | 0x900000);
|
|
}
|
|
|
|
void Samus_Func1(void) { // 0x90E09B
|
|
if (samus_pose == kPose_E9_FaceL_Drained_CrouchFalling
|
|
&& !sign16(samus_anim_frame - 8)
|
|
&& (joypad1_newkeys & kButton_Up) != 0) {
|
|
samus_anim_frame_timer = 1;
|
|
samus_anim_frame = 13;
|
|
frame_handler_gamma = FUNC16(nullsub_152);
|
|
}
|
|
}
|
|
|
|
void Samus_Func2(void) { // 0x90E0C5
|
|
if (!sign16(samus_anim_frame - 8) && sign16(samus_anim_frame - 12) && (joypad1_newkeys & kButton_Up) != 0) {
|
|
samus_anim_frame_timer = 1;
|
|
samus_anim_frame = 18;
|
|
}
|
|
}
|
|
|
|
void Samus_Func3(void) { // 0x90E0E6
|
|
if (ProcessTimer() & 1) {
|
|
game_state = kGameState_35_TimeUp;
|
|
for (int i = 510; i >= 0; i -= 2)
|
|
target_palettes[i >> 1] = 0x7FFF;
|
|
frame_handler_gamma = FUNC16(DrawTimer_);
|
|
DisablePaletteFx();
|
|
}
|
|
if (timer_status)
|
|
DrawTimer();
|
|
}
|
|
|
|
void DrawTimer_(void) { // 0x90E114
|
|
DrawTimer();
|
|
}
|
|
|
|
void Samus_SetPushedOutOfCeresRidley(void) { // 0x90E119
|
|
samus_movement_handler = FUNC16(nullsub_152);
|
|
frame_handler_gamma = FUNC16(Samus_PushOutOfRidleysWay);
|
|
}
|
|
|
|
void Samus_PushOutOfRidleysWay(void) { // 0x90E12E
|
|
if (samus_pose_x_dir == 4)
|
|
samus_pose = kPose_54_FaceL_Knockback;
|
|
else
|
|
samus_pose = kPose_53_FaceR_Knockback;
|
|
SamusFunc_F433();
|
|
Samus_SetAnimationFrameIfPoseChanged();
|
|
samus_last_different_pose = samus_prev_pose;
|
|
*(uint16 *)&samus_last_different_pose_x_dir = *(uint16 *)&samus_prev_pose_x_dir;
|
|
samus_prev_pose = samus_pose;
|
|
*(uint16 *)&samus_prev_pose_x_dir = *(uint16 *)&samus_pose_x_dir;
|
|
samus_y_pos -= 21 - samus_y_radius;
|
|
if (sign16(samus_x_pos - layer1_x_pos - 128))
|
|
samus_var62 = 1;
|
|
else
|
|
samus_var62 = 2;
|
|
samus_y_speed = 5;
|
|
samus_y_subspeed = 0;
|
|
bomb_jump_dir = 0;
|
|
frame_handler_gamma = FUNC16(Samus_Func4);
|
|
samus_new_pose = -1;
|
|
samus_new_pose_interrupted = -1;
|
|
samus_new_pose_transitional = -1;
|
|
samus_momentum_routine_index = 0;
|
|
samus_special_transgfx_index = 0;
|
|
samus_hurt_switch_index = 0;
|
|
ProcessTimer();
|
|
if (timer_status)
|
|
DrawTimer();
|
|
}
|
|
|
|
void Samus_Func4(void) { // 0x90E1C8
|
|
static Func_V *const off_90E1F7[3] = {
|
|
0,
|
|
Samus_Func5,
|
|
Samus_Func6,
|
|
};
|
|
|
|
if (samus_new_pose == kPose_4F_FaceL_Dmgboost || samus_new_pose == kPose_50_FaceR_Dmgboost) {
|
|
samus_new_pose = -1;
|
|
samus_momentum_routine_index = 0;
|
|
}
|
|
off_90E1F7[samus_var62]();
|
|
input_to_pose_calc = 0;
|
|
ProcessTimer();
|
|
if (timer_status)
|
|
DrawTimer();
|
|
}
|
|
|
|
void Samus_Func5(void) { // 0x90E1FD
|
|
Samus_BombJumpFallingXMovement_();
|
|
if (samus_collision_flag) {
|
|
samus_movement_handler = FUNC16(Samus_MovementHandler_Normal);
|
|
frame_handler_gamma = FUNC16(Samus_Func3);
|
|
samus_var62 = 0;
|
|
Samus_ClearMoveVars();
|
|
} else {
|
|
Samus_BombJumpFallingYMovement_();
|
|
}
|
|
}
|
|
void Samus_Func6(void) { // 0x90E21C
|
|
Samus_BombJumpFallingXMovement_();
|
|
if (samus_collision_flag) {
|
|
samus_movement_handler = FUNC16(Samus_MovementHandler_Normal);
|
|
frame_handler_gamma = FUNC16(Samus_Func3);
|
|
samus_var62 = 0;
|
|
Samus_ClearMoveVars();
|
|
} else {
|
|
Samus_BombJumpFallingYMovement_();
|
|
}
|
|
}
|
|
void Samus_GrabbedByDraygonFrameHandler(void) { // 0x90E2A1
|
|
if (grapple_beam_function == FUNC16(GrappleBeamFunc_ConnectedLockedInPlace)) {
|
|
samus_new_pose = -1;
|
|
samus_momentum_routine_index = 0;
|
|
}
|
|
if ((joypad1_newkeys & (kButton_Up | kButton_Down | kButton_Left | kButton_Right)) != 0
|
|
&& (joypad1_newkeys & (kButton_Up | kButton_Down | kButton_Left | kButton_Right)) != suit_pickup_light_beam_pos) {
|
|
suit_pickup_light_beam_pos = joypad1_newkeys & (kButton_Up | kButton_Down | kButton_Left | kButton_Right);
|
|
if ((int16)(++substate - 60) >= 0)
|
|
Samus_ReleaseFromDraygon();
|
|
}
|
|
}
|
|
|
|
void Samus_SetGrabbedByDraygonPose(uint16 a) { // 0x90E23B
|
|
if ((a & 1) != 0)
|
|
samus_pose = kPose_EC_FaceR_Draygon_NoMove_NoAim;
|
|
else
|
|
samus_pose = kPose_BA_FaceL_Draygon_NoMove_NoAim;
|
|
SamusFunc_F433();
|
|
Samus_SetAnimationFrameIfPoseChanged();
|
|
frame_handler_gamma = FUNC16(Samus_GrabbedByDraygonFrameHandler);
|
|
samus_movement_handler = FUNC16(nullsub_152);
|
|
substate = 0;
|
|
suit_pickup_light_beam_pos = 0;
|
|
*(uint16 *)&suit_pickup_color_math_R = 0;
|
|
samus_last_different_pose = samus_prev_pose;
|
|
*(uint16 *)&samus_last_different_pose_x_dir = *(uint16 *)&samus_prev_pose_x_dir;
|
|
samus_prev_pose = samus_pose;
|
|
*(uint16 *)&samus_prev_pose_x_dir = *(uint16 *)&samus_pose_x_dir;
|
|
samus_new_pose = -1;
|
|
samus_new_pose_interrupted = -1;
|
|
samus_new_pose_transitional = -1;
|
|
samus_momentum_routine_index = 0;
|
|
samus_special_transgfx_index = 0;
|
|
samus_hurt_switch_index = 0;
|
|
}
|
|
|
|
void Samus_ReleaseFromDraygon_(void) { // 0x90E2D4
|
|
Samus_ReleaseFromDraygon();
|
|
}
|
|
|
|
void Samus_ReleaseFromDraygon(void) { // 0x90E2DE
|
|
if (samus_pose_x_dir == 4)
|
|
samus_pose = kPose_02_FaceL_Normal;
|
|
else
|
|
samus_pose = kPose_01_FaceR_Normal;
|
|
SamusFunc_F433();
|
|
Samus_SetAnimationFrameIfPoseChanged();
|
|
samus_movement_handler = FUNC16(Samus_MovementHandler_Normal);
|
|
frame_handler_gamma = FUNC16(nullsub_152);
|
|
samus_last_different_pose = samus_prev_pose;
|
|
*(uint16 *)&samus_last_different_pose_x_dir = *(uint16 *)&samus_prev_pose_x_dir;
|
|
samus_prev_pose = samus_pose;
|
|
*(uint16 *)&samus_prev_pose_x_dir = *(uint16 *)&samus_pose_x_dir;
|
|
samus_x_base_speed = 0;
|
|
samus_x_base_subspeed = 0;
|
|
samus_new_pose = -1;
|
|
samus_new_pose_interrupted = -1;
|
|
samus_new_pose_transitional = -1;
|
|
samus_momentum_routine_index = 0;
|
|
samus_special_transgfx_index = 0;
|
|
samus_hurt_switch_index = 0;
|
|
samus_y_speed = 0;
|
|
samus_y_subspeed = 0;
|
|
samus_y_dir = 0;
|
|
used_for_ball_bounce_on_landing = 0;
|
|
samus_x_accel_mode = 0;
|
|
samus_grapple_flags = samus_grapple_flags & 0xFFFD | 2;
|
|
}
|
|
|
|
void Samus_Func7(void) { // 0x90E3A3
|
|
Samus_BombJumpFallingXMovement_();
|
|
if (samus_collision_flag || (Samus_BombJumpFallingYMovement_(), samus_collision_flag)) {
|
|
samus_movement_handler = FUNC16(Samus_MovementHandler_Normal);
|
|
frame_handler_gamma = FUNC16(nullsub_152);
|
|
samus_var62 = 0;
|
|
Samus_ClearMoveVars();
|
|
samus_new_pose_interrupted = 65;
|
|
samus_special_transgfx_index = 0;
|
|
}
|
|
}
|
|
|
|
void Samus_Func8(void) { // 0x90E400
|
|
samus_y_subspeed = 0;
|
|
samus_y_speed = 0;
|
|
samus_movement_handler = FUNC16(Samus_MovementHandler_Normal);
|
|
frame_handler_gamma = FUNC16(nullsub_152);
|
|
}
|
|
|
|
void Samus_Func9(void) { // 0x90E41B
|
|
if (sign16(samus_y_speed - 5)) {
|
|
uint32 v0 = __PAIR32__(samus_y_accel, samus_y_subaccel) + __PAIR32__(samus_y_speed, samus_y_subspeed);
|
|
samus_y_speed = HIWORD(v0);
|
|
samus_y_subspeed = v0;
|
|
}
|
|
if ((samus_pose == kPose_29_FaceR_Fall || samus_pose == kPose_2A_FaceL_Fall
|
|
|| samus_pose == kPose_67_FaceR_Fall_Gun || samus_pose == kPose_68_FaceL_Fall_Gun)
|
|
&& !sign16(samus_y_speed - 5)) {
|
|
samus_anim_frame_timer = 16;
|
|
samus_anim_frame = 4;
|
|
}
|
|
}
|
|
|
|
static int32 Samus_ClampSpeed(int32 amt) {
|
|
uint16 r18 = amt >> 16, r20 = amt;
|
|
int16 v0 = r18;
|
|
if (v0 < 0) {
|
|
if (sign16(v0 + 15))
|
|
r18 = -15;
|
|
} else if (!sign16(v0 - 16)) {
|
|
r18 = 15;
|
|
}
|
|
return r18 << 16 | r20;
|
|
}
|
|
|
|
int32 Samus_CalcDisplacementMoveLeft(int32 amt) { // 0x90E464
|
|
amt = Samus_CalcSpeed_X(amt);
|
|
samus_collision_direction = 0;
|
|
amt = __PAIR32__(extra_samus_x_displacement, extra_samus_x_subdisplacement) - amt;
|
|
return Samus_ClampSpeed(amt);
|
|
}
|
|
|
|
int32 Samus_CalcDisplacementMoveRight(int32 amt) { // 0x90E4AD
|
|
amt = Samus_CalcSpeed_X(amt);
|
|
samus_collision_direction = 1;
|
|
amt += __PAIR32__(extra_samus_x_displacement, extra_samus_x_subdisplacement);
|
|
return Samus_ClampSpeed(amt);
|
|
}
|
|
|
|
int32 Samus_CalcSpeed_X(int32 amt) { // 0x90E4E6
|
|
uint16 r18 = amt >> 16, r20 = amt;
|
|
uint16 v0 = samus_x_speed_divisor;
|
|
if (!sign16(samus_x_speed_divisor - 5))
|
|
v0 = 4;
|
|
switch (v0) {
|
|
case 0: {
|
|
bool v2 = __CFADD__uint16(samus_x_extra_run_subspeed, r20);
|
|
r20 += samus_x_extra_run_subspeed;
|
|
samus_total_x_subspeed = r20;
|
|
r18 += samus_x_extra_run_speed + v2;
|
|
samus_total_x_speed = r18;
|
|
break;
|
|
}
|
|
case 1: {
|
|
bool v2 = __CFADD__uint16(samus_x_extra_run_subspeed, r20);
|
|
r20 += samus_x_extra_run_subspeed;
|
|
uint16 t = samus_x_extra_run_speed + v2 + r18;
|
|
uint16 v3 = swap16(swap16(t) >> 1);
|
|
r18 = (uint8)v3;
|
|
samus_total_x_speed = (uint8)v3;
|
|
r20 = (v3 & 0xFF00) + (r20 >> 1);
|
|
samus_total_x_subspeed = r20;
|
|
break;
|
|
}
|
|
case 2: {
|
|
bool v2 = __CFADD__uint16(samus_x_extra_run_subspeed, r20);
|
|
r20 += samus_x_extra_run_subspeed;
|
|
uint16 t = samus_x_extra_run_speed + v2 + r18;
|
|
uint16 v5 = swap16(swap16(t) >> 2);
|
|
r18 = (uint8)v5;
|
|
samus_total_x_speed = (uint8)v5;
|
|
r20 = (v5 & 0xFF00) + (r20 >> 2);
|
|
samus_total_x_subspeed = r20;
|
|
break;
|
|
}
|
|
case 3: {
|
|
bool v2 = __CFADD__uint16(samus_x_extra_run_subspeed, r20);
|
|
r20 += samus_x_extra_run_subspeed;
|
|
uint16 t = samus_x_extra_run_speed + v2 + r18;
|
|
uint16 v7 = swap16(swap16(t) >> 3);
|
|
r18 = (uint8)v7;
|
|
samus_total_x_speed = (uint8)v7;
|
|
r20 = (v7 & 0xFF00) + (r20 >> 3);
|
|
samus_total_x_subspeed = r20;
|
|
break;
|
|
}
|
|
case 4: {
|
|
bool v2 = __CFADD__uint16(samus_x_extra_run_subspeed, r20);
|
|
r20 += samus_x_extra_run_subspeed;
|
|
uint16 t = samus_x_extra_run_speed + v2 + r18;
|
|
uint16 v9 = swap16(swap16(t) >> 4);
|
|
r18 = (uint8)v9;
|
|
samus_total_x_speed = (uint8)v9;
|
|
r20 = (v9 & 0xFF00) + (r20 >> 4);
|
|
samus_total_x_subspeed = r20;
|
|
break;
|
|
}
|
|
default:
|
|
Unreachable();
|
|
}
|
|
return r18 << 16 | r20;
|
|
}
|
|
|
|
void Samus_ClearXSpeedIfColl(void) { // 0x90E5CE
|
|
if (samus_collision_flag) {
|
|
if (samus_collision_direction)
|
|
samus_collides_with_solid_enemy = 8;
|
|
else
|
|
samus_collides_with_solid_enemy = 4;
|
|
Samus_CancelSpeedBoost();
|
|
samus_x_extra_run_speed = 0;
|
|
samus_x_extra_run_subspeed = 0;
|
|
samus_x_base_speed = 0;
|
|
samus_x_base_subspeed = 0;
|
|
samus_x_accel_mode = 0;
|
|
} else {
|
|
input_to_pose_calc = 0;
|
|
samus_collides_with_solid_enemy = 0;
|
|
}
|
|
}
|
|
|
|
void Samus_MoveUp_SetPoseCalcInput(void) { // 0x90E606
|
|
if (samus_collision_flag)
|
|
input_to_pose_calc = 4;
|
|
else
|
|
input_to_pose_calc = 0;
|
|
}
|
|
|
|
static const uint8 kSamus_MoveDown_SetPoseCalcInput_Tab0[28] = { // 0x90E61B
|
|
0, 0, 4, 4, 1, 0, 4, 2,
|
|
4, 4, 0, 0, 0, 0, 4, 4,
|
|
0, 3, 4, 4, 4, 0, 4, 4,
|
|
4, 4, 4, 4,
|
|
};
|
|
static const uint8 kSamus_MoveDown_SetPoseCalcInput_Tab1[28] = {
|
|
4, 4, 0, 0, 4, 4, 0, 4,
|
|
1, 2, 0, 4, 4, 0, 4, 4,
|
|
4, 4, 3, 3, 0, 4, 4, 4,
|
|
4, 0, 4, 4,
|
|
};
|
|
void Samus_MoveDown_SetPoseCalcInput(void) {
|
|
if (samus_collision_flag) {
|
|
input_to_pose_calc = 1;
|
|
HIBYTE(input_to_pose_calc) = kSamus_MoveDown_SetPoseCalcInput_Tab1[samus_movement_type];
|
|
} else if ((uint8)input_to_pose_calc != 5) {
|
|
input_to_pose_calc = 2;
|
|
HIBYTE(input_to_pose_calc) = kSamus_MoveDown_SetPoseCalcInput_Tab0[samus_movement_type];
|
|
}
|
|
}
|
|
|
|
void CallFrameHandlerAlfa(uint32 ea) {
|
|
switch (ea) {
|
|
case fnSamus_FrameHandlerAlfa_Func11: Samus_FrameHandlerAlfa_Func11(); return;
|
|
case fnSamus_FrameHandlerAlfa_Func12: Samus_FrameHandlerAlfa_Func12(); return;
|
|
case fnSamus_FrameHandlerAlfa_Func13: Samus_FrameHandlerAlfa_Func13(); return;
|
|
case fnEmptyFunction: return;
|
|
default: Unreachable();
|
|
}
|
|
}
|
|
void HandleControllerInputForGamePhysics(void) { // 0x90E692
|
|
CallFrameHandlerAlfa(frame_handler_alfa | 0x900000);
|
|
}
|
|
|
|
void Samus_FrameHandlerAlfa_Func11(void) { // 0x90E695
|
|
samus_new_pose = -1;
|
|
samus_new_pose_interrupted = -1;
|
|
samus_new_pose_transitional = -1;
|
|
samus_momentum_routine_index = 0;
|
|
samus_special_transgfx_index = 0;
|
|
samus_hurt_switch_index = 0;
|
|
Samus_SetRadius();
|
|
Samus_CallInputHandler();
|
|
Samus_UpdateSuitPaletteIndex();
|
|
Samus_DetermineAccel_Y();
|
|
BlockInsideDetection();
|
|
Samus_HandleHudSpecificBehaviorAndProjs();
|
|
Samus_Func10();
|
|
}
|
|
|
|
void Samus_FrameHandlerAlfa_Func12(void) { // 0x90E6C9
|
|
samus_new_pose = -1;
|
|
samus_new_pose_interrupted = -1;
|
|
samus_new_pose_transitional = -1;
|
|
samus_momentum_routine_index = 0;
|
|
samus_special_transgfx_index = 0;
|
|
samus_hurt_switch_index = 0;
|
|
controller1_input_for_demo = joypad1_lastkeys;
|
|
controller1_new_input_for_demo = joypad1_newkeys;
|
|
demo_backup_prev_controller_input = joypad1_input_samusfilter;
|
|
demo_backup_prev_controller_input_new = joypad1_newinput_samusfilter;
|
|
Samus_SetRadius();
|
|
Samus_UpdateSuitPaletteIndex();
|
|
Samus_CallInputHandler();
|
|
Samus_DetermineAccel_Y();
|
|
BlockInsideDetection();
|
|
Samus_HandleHudSpecificBehaviorAndProjs();
|
|
Samus_Func10();
|
|
}
|
|
|
|
void Samus_FrameHandlerAlfa_Func13(void) { // 0x90E713
|
|
HandleProjectile();
|
|
Samus_Func10();
|
|
}
|
|
|
|
void CallFrameHandlerBeta(uint32 ea) {
|
|
switch (ea) {
|
|
case fnSamus_FrameHandlerBeta_Func17: Samus_FrameHandlerBeta_Func17(); return;
|
|
case fnHandleDemoRecorder_3: HandleDemoRecorder_3(); return;
|
|
case fnSamus_FrameHandlerBeta_Func14: Samus_FrameHandlerBeta_Func14(); return;
|
|
case fnSamus_Func15: Samus_Func15(); return;
|
|
case fnSamus_Func16: Samus_Func16(); return;
|
|
case fnSamus_Func18: Samus_Func18(); return;
|
|
case fnEmptyFunction: return;
|
|
case fnj_HandleDemoRecorder_2: return;
|
|
case fnj_HandleDemoRecorder_2_0: return;
|
|
case fnSetContactDamageIndexAndUpdateMinimap: SetContactDamageIndexAndUpdateMinimap(); return;
|
|
case fnSamus_Func19: Samus_Func19(); return;
|
|
case fnSamus_LowHealthCheck: Samus_LowHealthCheck(); return;
|
|
default: Unreachable();
|
|
}
|
|
}
|
|
|
|
void HandleSamusMovementAndPause(void) { // 0x90E722
|
|
CallFrameHandlerBeta(frame_handler_beta | 0x900000);
|
|
}
|
|
|
|
void Samus_FrameHandlerBeta_Func17(void) { // 0x90E725
|
|
samus_contact_damage_index = 0;
|
|
RunSamusMovementHandler();
|
|
UpdateMinimap();
|
|
RunFrameHandlerGamma();
|
|
Samus_Animate();
|
|
Samus_HitInterruption();
|
|
Samus_HandleTransFromBlockColl();
|
|
Samus_HandleTransitions();
|
|
Samus_HandlePalette();
|
|
Samus_HandlePeriodicDamage();
|
|
Samus_PauseCheck();
|
|
Samus_LowHealthCheck_();
|
|
}
|
|
|
|
void HandleDemoRecorder_1(void) { // 0x90E786
|
|
if ((joypad2_new_keys & 0x8000) == 0) {
|
|
if (!debug_flag && (joypad2_new_keys & 0x80) != 0) {
|
|
DisableEnemyProjectiles();
|
|
time_is_frozen_flag = 1;
|
|
frame_handler_alfa = FUNC16(EmptyFunction);
|
|
frame_handler_beta = FUNC16(HandleDemoRecorder_3);
|
|
}
|
|
} else if (debug_flag) {
|
|
samus_draw_handler = FUNC16(nullsub_152);
|
|
debug_flag = 0;
|
|
} else {
|
|
debug_flag = 1;
|
|
samus_draw_handler = FUNC16(SamusDrawHandler_Default);
|
|
}
|
|
}
|
|
|
|
void HandleDemoRecorder_3(void) { // 0x90E7D2
|
|
if ((joypad2_new_keys & 0x80) != 0) {
|
|
frame_handler_alfa = FUNC16(Samus_FrameHandlerAlfa_Func11);
|
|
frame_handler_beta = FUNC16(Samus_FrameHandlerBeta_Func17);
|
|
EnableEnemyProjectiles();
|
|
time_is_frozen_flag = 0;
|
|
}
|
|
}
|
|
|
|
void Samus_FrameHandlerBeta_Func14(void) { // 0x90E7F5
|
|
samus_contact_damage_index = 0;
|
|
RunSamusMovementHandler();
|
|
UpdateMinimap();
|
|
Samus_Animate();
|
|
Samus_HitInterruption();
|
|
Samus_HandleTransFromBlockColl();
|
|
Samus_HandleTransitions();
|
|
Samus_HandlePalette();
|
|
joypad1_lastkeys = controller1_input_for_demo;
|
|
joypad1_newkeys = controller1_new_input_for_demo;
|
|
joypad1_input_samusfilter = demo_backup_prev_controller_input;
|
|
joypad1_newinput_samusfilter = demo_backup_prev_controller_input_new;
|
|
}
|
|
|
|
void Samus_Func15(void) { // 0x90E833
|
|
samus_contact_damage_index = 0;
|
|
RunSamusMovementHandler();
|
|
Samus_Animate();
|
|
Samus_HitInterruption();
|
|
Samus_HandleTransFromBlockColl();
|
|
Samus_HandleTransitions();
|
|
Samus_HandlePalette();
|
|
joypad1_lastkeys = controller1_input_for_demo;
|
|
joypad1_newkeys = controller1_new_input_for_demo;
|
|
joypad1_input_samusfilter = demo_backup_prev_controller_input;
|
|
joypad1_newinput_samusfilter = demo_backup_prev_controller_input_new;
|
|
}
|
|
|
|
void Samus_Func16(void) { // 0x90E86A
|
|
Samus_SetRadius();
|
|
UpdateMinimap();
|
|
Samus_Animate();
|
|
elevator_status = 0;
|
|
samus_prev_y_pos = samus_y_pos;
|
|
if (PlaySamusFanfare() & 1) {
|
|
if (sign16(debug_invincibility - 7) || (joypad2_last & 0x8000) == 0)
|
|
debug_invincibility = 0;
|
|
frame_handler_alfa = FUNC16(Samus_FrameHandlerAlfa_Func11);
|
|
frame_handler_beta = FUNC16(Samus_FrameHandlerBeta_Func17);
|
|
}
|
|
}
|
|
|
|
void Samus_Func18(void) { // 0x90E8AA
|
|
Samus_FrameHandlerBeta_Func17();
|
|
if (frame_handler_gamma == FUNC16(DrawTimer_) && game_state != kGameState_35_TimeUp)
|
|
game_state = kGameState_35_TimeUp;
|
|
}
|
|
|
|
void SetContactDamageIndexAndUpdateMinimap(void) { // 0x90E8DC
|
|
samus_contact_damage_index = 0;
|
|
UpdateMinimap();
|
|
}
|
|
|
|
void Samus_Func19(void) { // 0x90E8EC
|
|
samus_contact_damage_index = 0;
|
|
RunSamusMovementHandler();
|
|
UpdateMinimap();
|
|
Samus_Animate();
|
|
}
|
|
|
|
void Samus_LowHealthCheck(void) { // 0x90E902
|
|
Samus_LowHealthCheck_();
|
|
}
|
|
|
|
void CallSamusInputHandler(uint32 ea) {
|
|
switch (ea) {
|
|
case fnnullsub_152: return;
|
|
case fnSamus_InputHandler_E913: Samus_InputHandler_E913(); return;
|
|
case fnSamus_Func20_: Samus_Func20_(); return;
|
|
case fnSamus_InputHandler_E91D: Samus_InputHandler_E91D(); return;
|
|
case fnHandleAutoJumpHack: HandleAutoJumpHack(); return;
|
|
default: Unreachable();
|
|
}
|
|
}
|
|
|
|
void Samus_CallInputHandler(void) { // 0x90E90F
|
|
CallSamusInputHandler(samus_input_handler | 0x900000);
|
|
}
|
|
|
|
void Samus_InputHandler_E913(void) { // 0x90E913
|
|
Samus_InputHandler();
|
|
}
|
|
|
|
void Samus_Func20_(void) { // 0x90E918
|
|
Samus_Func20();
|
|
}
|
|
|
|
void Samus_InputHandler_E91D(void) { // 0x90E91D
|
|
DemoObjectInputHandler();
|
|
Samus_InputHandler();
|
|
}
|
|
|
|
void HandleAutoJumpHack(void) { // 0x90E926
|
|
uint16 v0 = joypad1_newkeys;
|
|
if (autojump_timer && sign16(autojump_timer - 9)) {
|
|
joypad1_newkeys |= button_config_jump_a;
|
|
autojump_timer = 0;
|
|
}
|
|
Samus_InputHandler();
|
|
joypad1_newkeys = v0;
|
|
samus_input_handler = FUNC16(Samus_InputHandler_E913);
|
|
}
|
|
|
|
void CallSamusMovementHandler(uint32 ea) {
|
|
switch (ea) {
|
|
case fnSamus_MoveHandler_ReleaseFromGrapple: Samus_MoveHandler_ReleaseFromGrapple(); return;
|
|
case fnSamus_HandleMovement_DrainedCrouching: Samus_HandleMovement_DrainedCrouching(); return;
|
|
case fnSamus_MovementHandler_Normal: Samus_MovementHandler_Normal(); return;
|
|
case fnSamus_MoveHandlerShinesparkWindup: Samus_MoveHandlerShinesparkWindup(); return;
|
|
case fnSamus_MoveHandlerVerticalShinespark: Samus_MoveHandlerVerticalShinespark(); return;
|
|
case fnSamus_MoveHandler_Shinespark_Diag: Samus_MoveHandler_Shinespark_Diag(); return;
|
|
case fnSamus_MoveHandler_Shinespark_Horiz: Samus_MoveHandler_Shinespark_Horiz(); return;
|
|
case fnSamus_MoveHandler_ShinesparkCrash: Samus_MoveHandler_ShinesparkCrash(); return;
|
|
case fnSamus_MoveHandler_ShinesparkCrash_0: Samus_MoveHandler_ShinesparkCrash_0(); return;
|
|
case fnSamus_MoveHandler_ShinesparkCrash_1: Samus_MoveHandler_ShinesparkCrash_1(); return;
|
|
case fnSamus_MoveHandler_ShinesparkCrash_2: Samus_MoveHandler_ShinesparkCrash_2(); return;
|
|
case fnSamus_MoveHandler_ShinesparkCrashEchoCircle: Samus_MoveHandler_ShinesparkCrashEchoCircle(); return;
|
|
case fnSamus_MoveHandler_ShinesparkCrashFinish: Samus_MoveHandler_ShinesparkCrashFinish(); return;
|
|
case fnSamusMoveHandler_CrystalFlashStart: SamusMoveHandler_CrystalFlashStart(); return;
|
|
case fnSamusMoveHandler_CrystalFlashMain: SamusMoveHandler_CrystalFlashMain(); return;
|
|
case fnkSamusMoveHandler_CrystalFlashFinish: kSamusMoveHandler_CrystalFlashFinish(); return;
|
|
case fnSamus_MoveHandler_Knockback: Samus_MoveHandler_Knockback(); return;
|
|
case fnSamus_MoveHandler_Knockback_0: Samus_MoveHandler_Knockback_0(); return;
|
|
case fnSamus_MoveHandler_Knockback_Up: Samus_MoveHandler_Knockback_Up(); return;
|
|
case fnSamus_MoveHandler_Knockback_3: Samus_MoveHandler_Knockback_3(); return;
|
|
case fnSamus_MoveHandler_Knockback_Down: Samus_MoveHandler_Knockback_Down(); return;
|
|
case fnSamus_MoveHandler_BombJumpStart: Samus_MoveHandler_BombJumpStart(); return;
|
|
case fnSamus_MoveHandler_BombJumpMain: Samus_MoveHandler_BombJumpMain(); return;
|
|
case fnSamus_MoveHandler_BombJumpFunc1: Samus_MoveHandler_BombJumpFunc1(); return;
|
|
case fnnullsub_152: return;
|
|
case fnSamusMovementType_Xray: SamusMovementType_Xray(); return;
|
|
case fnSamus_Func25_ShineSpark: Samus_Func25_ShineSpark(); return;
|
|
case fnSamus_MoveHandler_F072: Samus_MoveHandler_F072(); return;
|
|
default: Unreachable();
|
|
}
|
|
}
|
|
|
|
void RunSamusMovementHandler(void) { // 0x90E94B
|
|
CallSamusMovementHandler(samus_movement_handler | 0x900000);
|
|
}
|
|
|
|
void SamusMovementType_Xray(void) { // 0x90E94F
|
|
uint16 v0;
|
|
if (samus_movement_type != kMovementType_0E_TurningAroundOnGround) {
|
|
samus_anim_frame_timer = 15;
|
|
if (samus_pose_x_dir == 4) {
|
|
if (sign16(xray_angle - 153)) {
|
|
v0 = 4;
|
|
} else if (sign16(xray_angle - 178)) {
|
|
v0 = 3;
|
|
} else if (sign16(xray_angle - 203)) {
|
|
v0 = 2;
|
|
} else {
|
|
v0 = sign16(xray_angle - 228) != 0;
|
|
}
|
|
} else if (sign16(xray_angle - 25)) {
|
|
v0 = 0;
|
|
} else if (sign16(xray_angle - 50)) {
|
|
v0 = 1;
|
|
} else if (sign16(xray_angle - 75)) {
|
|
v0 = 2;
|
|
} else if (sign16(xray_angle - 100)) {
|
|
v0 = 3;
|
|
} else {
|
|
v0 = 4;
|
|
}
|
|
samus_anim_frame = v0;
|
|
}
|
|
}
|
|
|
|
void Samus_HandlePeriodicDamage(void) { // 0x90E9CE
|
|
int16 v0;
|
|
int16 v1;
|
|
int16 v2;
|
|
|
|
if (time_is_frozen_flag)
|
|
goto LABEL_10;
|
|
if ((equipped_items & 0x20) != 0) {
|
|
uint16 v4 = *(uint16 *)((uint8 *)&samus_periodic_subdamage + 1) >> 2;
|
|
LOBYTE(v1) = (uint16)(*(uint16 *)((uint8 *)&samus_periodic_subdamage + 1) >> 2) >> 8;
|
|
HIBYTE(v1) = *(uint16 *)((uint8 *)&samus_periodic_subdamage + 1) >> 2;
|
|
samus_periodic_subdamage = v1 & 0xFF00;
|
|
samus_periodic_damage = HIBYTE(v4);
|
|
} else if ((equipped_items & 1) != 0) {
|
|
uint16 v3 = *(uint16 *)((uint8 *)&samus_periodic_subdamage + 1) >> 1;
|
|
LOBYTE(v0) = (uint16)(*(uint16 *)((uint8 *)&samus_periodic_subdamage + 1) >> 1) >> 8;
|
|
HIBYTE(v0) = *(uint16 *)((uint8 *)&samus_periodic_subdamage + 1) >> 1;
|
|
samus_periodic_subdamage = v0 & 0xFF00;
|
|
samus_periodic_damage = HIBYTE(v3);
|
|
}
|
|
if ((samus_periodic_damage & 0x8000) != 0) {
|
|
InvalidInterrupt_Crash();
|
|
return;
|
|
}
|
|
v2 = (__PAIR32__(samus_health, samus_subunit_health) - __PAIR32__(samus_periodic_damage, samus_periodic_subdamage)) >> 16;
|
|
samus_subunit_health -= samus_periodic_subdamage;
|
|
samus_health = v2;
|
|
if (v2 >= 0) {
|
|
LABEL_10:
|
|
samus_periodic_subdamage = 0;
|
|
samus_periodic_damage = 0;
|
|
} else {
|
|
samus_subunit_health = 0;
|
|
samus_health = 0;
|
|
samus_periodic_subdamage = 0;
|
|
samus_periodic_damage = 0;
|
|
}
|
|
}
|
|
|
|
void Samus_PauseCheck(void) { // 0x90EA45
|
|
if (!power_bomb_flag
|
|
&& !time_is_frozen_flag
|
|
&& !door_transition_flag_enemies
|
|
&& area_index != 6
|
|
&& game_state == kGameState_8_MainGameplay
|
|
&& (joypad1_newkeys & kButton_Start) != 0) {
|
|
screen_fade_delay = 1;
|
|
screen_fade_counter = 1;
|
|
game_state = kGameState_12_Pausing;
|
|
}
|
|
}
|
|
|
|
void Samus_LowHealthCheck_(void) { // 0x90EA7F
|
|
if (sign16(samus_health - 31)) {
|
|
if (!samus_health_warning) {
|
|
QueueSfx3_Max6(2);
|
|
samus_health_warning = 1;
|
|
}
|
|
} else if (samus_health_warning) {
|
|
samus_health_warning = 0;
|
|
QueueSfx3_Max6(1);
|
|
}
|
|
}
|
|
|
|
void Samus_LowHealthCheck_0(void) { // 0x90EAAB
|
|
Samus_LowHealthCheck_();
|
|
}
|
|
|
|
void Samus_JumpCheck(void) { // 0x90EAB3
|
|
if ((button_config_jump_a & joypad1_lastkeys) != 0 && (button_config_jump_a & joypad1_input_samusfilter) != 0)
|
|
++autojump_timer;
|
|
else
|
|
autojump_timer = 0;
|
|
joypad1_input_samusfilter = joypad1_lastkeys;
|
|
joypad1_newinput_samusfilter = joypad1_newkeys;
|
|
if ((int16)(samus_health - samus_prev_health_for_flash) >= 0)
|
|
goto LABEL_10;
|
|
if (!samus_hurt_flash_counter)
|
|
samus_hurt_flash_counter = 1;
|
|
if (sign16(debug_invincibility - 7))
|
|
LABEL_10:
|
|
samus_prev_health_for_flash = samus_health;
|
|
else
|
|
samus_health = samus_prev_health_for_flash;
|
|
}
|
|
|
|
void Samus_Func10(void) { // 0x90EB02
|
|
projectile_init_speed_samus_moved_left = 0;
|
|
projectile_init_speed_samus_moved_left_fract = 0;
|
|
projectile_init_speed_samus_moved_right = 0;
|
|
projectile_init_speed_samus_moved_right_fract = 0;
|
|
projectile_init_speed_samus_moved_up = 0;
|
|
projectile_init_speed_samus_moved_up_fract = 0;
|
|
projectile_init_speed_samus_moved_down = 0;
|
|
projectile_init_speed_samus_moved_down_fract = 0;
|
|
samus_anim_frame_skip = 0;
|
|
new_projectile_direction_changed_pose = 0;
|
|
UNUSED_word_7E0DFA <<= 8;
|
|
WORD(g_ram[0xa10]) = *(uint16 *)&samus_pose_x_dir;
|
|
}
|
|
|
|
void DrawSamusAndProjectiles(void) { // 0x90EB35
|
|
SamusDrawSprites();
|
|
DrawPlayerExplosions2();
|
|
Samus_JumpCheck();
|
|
Samus_ShootCheck();
|
|
}
|
|
|
|
void CallSamusDrawHandler(uint32 ea) {
|
|
switch (ea) {
|
|
case fnSamusDrawHandler_Default: SamusDrawHandler_Default(); return;
|
|
case fnsub_90EB86: sub_90EB86(); return;
|
|
case fnnullsub_152:
|
|
case fnnullsub_156: return;
|
|
case fnSamus_DrawHandler_EndOfShinespark: Samus_DrawHandler_EndOfShinespark(); return;
|
|
case fnSamusDisplayHandler_UsingElevator: SamusDisplayHandler_UsingElevator(); return;
|
|
case fnSamusDisplayHandler_SamusReceivedFatal: SamusDisplayHandler_SamusReceivedFatal(); return;
|
|
default: Unreachable();
|
|
}
|
|
}
|
|
|
|
void SamusDrawSprites(void) { // 0x90EB4B
|
|
HandleArmCannonOpenState();
|
|
CallSamusDrawHandler(samus_draw_handler | 0x900000);
|
|
}
|
|
|
|
void SamusDrawHandler_Default(void) { // 0x90EB52
|
|
HandleChargingBeamGfxAudio();
|
|
sub_90EB55();
|
|
}
|
|
|
|
void sub_90EB55(void) { // 0x90EB55
|
|
if ((arm_cannon_drawing_mode & 0xF) != 0) {
|
|
if ((arm_cannon_drawing_mode & 0xF) == 2) {
|
|
HandleAtmosphericEffects();
|
|
Samus_Draw();
|
|
Samus_ArmCannon_Draw();
|
|
} else {
|
|
HandleAtmosphericEffects();
|
|
Samus_ArmCannon_Draw();
|
|
Samus_Draw();
|
|
}
|
|
Samus_DrawEchoes();
|
|
} else {
|
|
HandleAtmosphericEffects();
|
|
Samus_Draw();
|
|
Samus_DrawEchoes();
|
|
}
|
|
}
|
|
|
|
void sub_90EB86(void) { // 0x90EB86
|
|
if (!sign16(grapple_beam_function + 0x37AA)) {
|
|
sub_90EB55();
|
|
return;
|
|
}
|
|
if (grapple_beam_function == FUNC16(GrappleBeamFunc_Firing)
|
|
|| grapple_beam_function == FUNC16(UNUSED_sub_9BC759)) {
|
|
GrappleBeamFunc_BF1B();
|
|
}
|
|
HandleGrappleBeamFlare();
|
|
if ((arm_cannon_drawing_mode & 0xF) != 0) {
|
|
if ((arm_cannon_drawing_mode & 0xF) == 2) {
|
|
HandleAtmosphericEffects();
|
|
Samus_Draw();
|
|
Samus_ArmCannon_Draw();
|
|
UpdateGrappleBeamTilesAndIncrFlameCtr();
|
|
if (!grapple_beam_length)
|
|
return;
|
|
} else {
|
|
HandleAtmosphericEffects();
|
|
Samus_ArmCannon_Draw();
|
|
Samus_Draw();
|
|
UpdateGrappleBeamTilesAndIncrFlameCtr();
|
|
if (!grapple_beam_length)
|
|
return;
|
|
}
|
|
} else {
|
|
HandleAtmosphericEffects();
|
|
Samus_Draw();
|
|
UpdateGrappleBeamTilesAndIncrFlameCtr();
|
|
if (!grapple_beam_length)
|
|
return;
|
|
}
|
|
HandleGrappleBeamGfx();
|
|
}
|
|
|
|
void Samus_DrawHandler_EndOfShinespark(void) { // 0x90EBF3
|
|
Samus_Draw();
|
|
for (int i = 2; i >= 0; i -= 2)
|
|
Samus_DrawShinesparkCrashEchoes(i);
|
|
}
|
|
|
|
void Samus_DrawManyEchoes(void) { // 0x90EC03
|
|
SamusDrawHandler_Default();
|
|
for (int i = 2; i >= 0; i -= 2)
|
|
Samus_DrawEchoes();
|
|
}
|
|
|
|
void SamusDisplayHandler_UsingElevator(void) { // 0x90EC14
|
|
if ((nmi_frame_counter_word & 1) == 0)
|
|
SamusDisplayHandler_SamusReceivedFatal();
|
|
}
|
|
|
|
void SamusDisplayHandler_SamusReceivedFatal(void) { // 0x90EC1D
|
|
Samus_DrawWhenNotAnimatingOrDying();
|
|
}
|
|
|
|
void Samus_SetRadius(void) { // 0x90EC22
|
|
samus_y_radius = kPoseParams[samus_pose].y_radius;
|
|
samus_x_radius = 5;
|
|
}
|
|
|
|
uint16 Samus_GetBottom_R18(void) {
|
|
return samus_y_pos + kPoseParams[samus_pose].y_radius - 1;
|
|
}
|
|
|
|
uint16 Samus_GetTop_R20(void) {
|
|
return samus_y_pos - kPoseParams[samus_pose].y_radius;
|
|
}
|
|
|
|
void Samus_AlignBottomWithPrevPose(void) { // 0x90EC7E
|
|
uint16 r18 = kPoseParams[samus_pose].y_radius;
|
|
r18 = kPoseParams[samus_prev_pose].y_radius - r18;
|
|
samus_y_pos += r18;
|
|
samus_prev_y_pos += r18;
|
|
}
|
|
|
|
void Samus_UpdateSuitPaletteIndex(void) { // 0x90ECB6
|
|
if ((equipped_items & 0x20) != 0) {
|
|
samus_suit_palette_index = 4;
|
|
} else if ((equipped_items & 1) != 0) {
|
|
samus_suit_palette_index = 2;
|
|
} else {
|
|
samus_suit_palette_index = 0;
|
|
}
|
|
}
|
|
|
|
void MoveSamusWithControlPad(void) { // 0x90ECD5
|
|
if ((joypad1_lastkeys & 0x800) != 0)
|
|
Samus_MoveUp(INT16_SHL16(-4));
|
|
if ((joypad1_lastkeys & 0x400) != 0)
|
|
Samus_MoveDown(INT16_SHL16(4));
|
|
if ((joypad1_lastkeys & 0x200) != 0)
|
|
Samus_MoveLeft(INT16_SHL16(-4));
|
|
if ((joypad1_lastkeys & 0x100) != 0)
|
|
Samus_MoveRight(INT16_SHL16(4));
|
|
}
|
|
|
|
static const uint8 byte_90ED50[28] = { // 0x90ED26
|
|
0, 0, 0, 0, 1, 0, 0, 1,
|
|
1, 1, 0, 0, 0, 0, 0, 0,
|
|
0, 1, 1, 1, 0, 0, 0, 0,
|
|
0, 0, 0, 0,
|
|
};
|
|
|
|
void SwappedAmmoRoutine(void) {
|
|
if (byte_90ED50[samus_movement_type]) {
|
|
samus_missiles = samus_x_pos >> 4;
|
|
samus_max_missiles = samus_x_pos >> 4;
|
|
samus_super_missiles = samus_y_pos >> 4;
|
|
samus_max_super_missiles = samus_y_pos >> 4;
|
|
}
|
|
}
|
|
|
|
void UNUSEDsub_90ED6C(void) { // 0x90ED6C
|
|
samus_missiles = game_time_hours;
|
|
samus_max_missiles = game_time_hours;
|
|
samus_super_missiles = game_time_minutes;
|
|
samus_max_super_missiles = game_time_minutes;
|
|
samus_power_bombs = game_time_seconds;
|
|
samus_max_power_bombs = game_time_seconds;
|
|
}
|
|
|
|
static Func_V *const kSamus_FootstepGraphics[8] = { // 0x90ED88
|
|
Samus_FootstepGraphics_Crateria,
|
|
Samus_FootstepGraphics_1,
|
|
Samus_FootstepGraphics_1,
|
|
Samus_FootstepGraphics_1,
|
|
Samus_FootstepGraphics_Maridia,
|
|
Samus_FootstepGraphics_1,
|
|
Samus_FootstepGraphics_1,
|
|
Samus_FootstepGraphics_1,
|
|
};
|
|
void Samus_FootstepGraphics(void) {
|
|
kSamus_FootstepGraphics[area_index]();
|
|
}
|
|
|
|
static const uint8 byte_90EDC9[16] = { // 0x90EDA1
|
|
1, 0, 0, 0, 0, 2, 0, 4,
|
|
0, 4, 4, 4, 4, 0, 4, 0,
|
|
};
|
|
void Samus_FootstepGraphics_Crateria(void) {
|
|
if (cinematic_function || (int16)(room_index - 16) >= 0)
|
|
goto LABEL_11;
|
|
if ((byte_90EDC9[room_index] & 1) == 0) {
|
|
if ((byte_90EDC9[room_index] & 2) != 0) {
|
|
if (!sign16(samus_y_pos - 944))
|
|
goto LABEL_12;
|
|
} else if ((byte_90EDC9[room_index] & 4) != 0) {
|
|
goto LABEL_12;
|
|
}
|
|
LABEL_11:
|
|
Samus_FootstepGraphics_1();
|
|
return;
|
|
}
|
|
if (fx_type != 10)
|
|
goto LABEL_11;
|
|
LABEL_12:
|
|
Samus_FootstepGraphics_Maridia();
|
|
}
|
|
|
|
void Samus_FootstepGraphics_Maridia(void) { // 0x90EDEC
|
|
uint16 r18 = Samus_GetBottom_R18();
|
|
if ((fx_y_pos & 0x8000) != 0) {
|
|
if ((lava_acid_y_pos & 0x8000) == 0 && sign16(lava_acid_y_pos - r18))
|
|
return;
|
|
} else if (sign16(fx_y_pos - r18) && (fx_liquid_options & 4) == 0) {
|
|
return;
|
|
}
|
|
if (samus_pose_x_dir == 4) {
|
|
atmospheric_gfx_x_pos[0] = samus_x_pos - 12;
|
|
atmospheric_gfx_x_pos[1] = samus_x_pos + 8;
|
|
} else {
|
|
atmospheric_gfx_x_pos[0] = samus_x_pos + 12;
|
|
atmospheric_gfx_x_pos[1] = samus_x_pos - 8;
|
|
}
|
|
atmospheric_gfx_y_pos[0] = samus_y_pos + 16;
|
|
atmospheric_gfx_y_pos[1] = samus_y_pos + 16;
|
|
atmospheric_gfx_frame_and_type[0] = 256;
|
|
atmospheric_gfx_frame_and_type[1] = 256;
|
|
atmospheric_gfx_anim_timer[0] = -32766;
|
|
atmospheric_gfx_anim_timer[1] = 3;
|
|
}
|
|
|
|
void Samus_FootstepGraphics_1(void) { // 0x90EE64
|
|
if ((speed_boost_counter & 0xFF00) == 1024) {
|
|
uint16 r18 = Samus_GetBottom_R18();
|
|
if ((fx_y_pos & 0x8000) != 0) {
|
|
if ((lava_acid_y_pos & 0x8000) == 0 && sign16(lava_acid_y_pos - r18))
|
|
return;
|
|
} else if (sign16(fx_y_pos - r18) && (fx_liquid_options & 4) == 0) {
|
|
return;
|
|
}
|
|
if (samus_pose_x_dir == 4) {
|
|
atmospheric_gfx_x_pos[0] = samus_x_pos - 12;
|
|
atmospheric_gfx_x_pos[1] = samus_x_pos + 8;
|
|
} else {
|
|
atmospheric_gfx_x_pos[0] = samus_x_pos + 12;
|
|
atmospheric_gfx_x_pos[1] = samus_x_pos - 8;
|
|
}
|
|
atmospheric_gfx_y_pos[0] = samus_y_pos + 16;
|
|
atmospheric_gfx_y_pos[1] = samus_y_pos + 16;
|
|
atmospheric_gfx_frame_and_type[0] = 1792;
|
|
atmospheric_gfx_frame_and_type[1] = 1792;
|
|
atmospheric_gfx_anim_timer[0] = -32766;
|
|
atmospheric_gfx_anim_timer[1] = 3;
|
|
}
|
|
}
|
|
|
|
void Samus_UpdateSpeedEchoPos(void) { // 0x90EEE7
|
|
if ((speed_boost_counter & 0xFF00) == 1024 && (speed_echoes_index & 0x8000) == 0 && (game_time_frames & 3) == 0) {
|
|
uint16 v0 = speed_echoes_index;
|
|
int v1 = speed_echoes_index >> 1;
|
|
speed_echo_xpos[v1] = samus_x_pos;
|
|
speed_echo_ypos[v1] = samus_y_pos;
|
|
uint16 v2 = v0 + 2;
|
|
if ((int16)(v2 - 4) >= 0)
|
|
v2 = 0;
|
|
speed_echoes_index = v2;
|
|
}
|
|
}
|
|
|
|
void Samus_PostGrappleCollisionDetect(void) { // 0x90EF22
|
|
PostGrappleCollisionDetect_X();
|
|
PostGrappleCollisionDetect_Y();
|
|
if (!distance_to_eject_samus_down || !distance_to_eject_samus_up) {
|
|
if (distance_to_eject_samus_up) {
|
|
samus_y_pos -= distance_to_eject_samus_up;
|
|
if (!sign16(samus_y_radius - 16)) {
|
|
PostGrappleCollisionDetect_Y();
|
|
samus_y_pos -= distance_to_eject_samus_up;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void ProjPreInstr_UnknownProj8027(uint16 k) { // 0x90EFD3
|
|
static const int16 kProjPreInstr_UnknownProj8027_X[4] = { -4, -4, 4, 4 };
|
|
static const int16 kProjPreInstr_UnknownProj8027_Y[4] = { 4, -4, -4, 4 };
|
|
static const int16 kProjPreInstr_UnknownProj8027_X2[4] = { 0x80, 0x80, -0x80, -0x80 };
|
|
static const int16 kProjPreInstr_UnknownProj8027_Y2[4] = { -0x80, 0x80, 0x80, -0x80 };
|
|
|
|
int v1 = k >> 1;
|
|
projectile_x_pos[v1] += kProjPreInstr_UnknownProj8027_X[v1];
|
|
uint16 v2 = kProjPreInstr_UnknownProj8027_Y[v1] + projectile_y_pos[v1];
|
|
projectile_y_pos[v1] = v2;
|
|
if (v2 == samus_y_pos) {
|
|
if (projectile_variables[v1] == 1) {
|
|
if (k == 6)
|
|
samus_movement_handler = FUNC16(Samus_Func25_ShineSpark);
|
|
ClearProjectile(k);
|
|
} else {
|
|
int v3 = k >> 1;
|
|
++projectile_variables[v3];
|
|
samus_shine_timer = 180;
|
|
timer_for_shine_timer = 1;
|
|
special_samus_palette_frame = 0;
|
|
projectile_x_pos[v3] = kProjPreInstr_UnknownProj8027_X2[v3] + samus_x_pos;
|
|
projectile_y_pos[v3] = kProjPreInstr_UnknownProj8027_Y2[v3] + samus_y_pos;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Samus_Func25_ShineSpark(void) { // 0x90F04B
|
|
if (!samus_shine_timer) {
|
|
special_samus_palette_frame = 6;
|
|
special_samus_palette_timer = 1;
|
|
demo_timer_counter = 1;
|
|
timer_for_shine_timer = 10;
|
|
samus_shine_timer = 120;
|
|
samus_movement_handler = FUNC16(Samus_MoveHandler_F072);
|
|
}
|
|
}
|
|
|
|
void Samus_MoveHandler_F072(void) { // 0x90F072
|
|
if (!samus_shine_timer) {
|
|
frame_handler_alfa = FUNC16(Samus_FrameHandlerAlfa_Func11);
|
|
samus_movement_handler = FUNC16(Samus_MovementHandler_Normal);
|
|
}
|
|
}
|
|
|
|
static Func_U8 *const kSamusCodeHandlers[32] = { // 0x90F084
|
|
SamusCode_00_LockSamus,
|
|
SamusCode_01_UnlockSamus,
|
|
SamusCode_02_ReachCeresElevator,
|
|
SamusCode_03,
|
|
SamusCode_04,
|
|
SamusCode_05_SetupDrained,
|
|
SamusCode_06_LockToStation,
|
|
SamusCode_07_SetupForElevator,
|
|
SamusCode_08_SetupForCeresStart,
|
|
SamusCode_08_SetupForZebesStart,
|
|
SamusCode_0A_ClearDrawHandler,
|
|
SamusCode_0B_DrawHandlerDefault,
|
|
SamusCode_0C_UnlockFromMapStation,
|
|
SamusCode_0D_IsGrappleActive,
|
|
SamusCode_0E,
|
|
SamusCode_0F_EnableTimerHandling,
|
|
SamusCode_10,
|
|
SamusCode_11_SetupForDeath,
|
|
SamusCode_12_SetSuperPaletteFlag1,
|
|
SamusCode_12_SetSuperPaletteFlag0,
|
|
SamusCode_14,
|
|
SamusCode_15_CalledBySuitAcquision,
|
|
SamusCode_16,
|
|
SamusCode_17_DisableRainbowSamusAndStandUp,
|
|
SamusCode_18,
|
|
SamusCode_17_FreezeDrainedSamus,
|
|
SamusCode_1A,
|
|
SamusCode_1B_CheckedLockSamus,
|
|
SamusCode_1C,
|
|
SamusCode_1D_ClearSoundInDoor,
|
|
SamusCode_1E,
|
|
SamusCode_1F,
|
|
};
|
|
|
|
uint16 CallSomeSamusCode(uint16 a) {
|
|
uint16 code = kSamusCodeHandlers[a & 0x1F]();
|
|
if (!(code & 1))
|
|
return code >> 1;
|
|
samus_new_pose = -1;
|
|
samus_new_pose_interrupted = -1;
|
|
samus_new_pose_transitional = -1;
|
|
samus_momentum_routine_index = 0;
|
|
samus_special_transgfx_index = 0;
|
|
samus_hurt_switch_index = 0;
|
|
return -1;
|
|
}
|
|
|
|
void Samus_UpdatePreviousPose(void) { // 0x90F0EE
|
|
samus_last_different_pose = samus_prev_pose;
|
|
*(uint16 *)&samus_last_different_pose_x_dir = *(uint16 *)&samus_prev_pose_x_dir;
|
|
samus_prev_pose = samus_pose;
|
|
*(uint16 *)&samus_prev_pose_x_dir = *(uint16 *)&samus_pose_x_dir;
|
|
}
|
|
|
|
uint8 ClearCarry(void) { // 0x90F107
|
|
return 0;
|
|
}
|
|
|
|
uint8 SamusCode_00_LockSamus(void) { // 0x90F109
|
|
frame_handler_alfa = FUNC16(Samus_FrameHandlerAlfa_Func13);
|
|
frame_handler_beta = FUNC16(SetContactDamageIndexAndUpdateMinimap);
|
|
return 1;
|
|
}
|
|
|
|
uint8 SamusCode_01_UnlockSamus(void) { // 0x90F117
|
|
frame_handler_alfa = FUNC16(Samus_FrameHandlerAlfa_Func11);
|
|
frame_handler_beta = FUNC16(Samus_FrameHandlerBeta_Func17);
|
|
return 1;
|
|
}
|
|
|
|
uint8 SamusCode_02_ReachCeresElevator(void) { // 0x90F125
|
|
if (samus_pose_x_dir == 4)
|
|
samus_pose = kPose_02_FaceL_Normal;
|
|
else
|
|
samus_pose = kPose_01_FaceR_Normal;
|
|
samus_anim_frame_skip = 0;
|
|
SamusFunc_F433();
|
|
Samus_SetAnimationFrameIfPoseChanged();
|
|
reached_ceres_elevator_fade_timer = 60;
|
|
return SamusCode_00_LockSamus();
|
|
}
|
|
|
|
uint8 SamusCode_03(void) { // 0x90F152
|
|
if (grapple_beam_function != FUNC16(GrappleBeamFunc_Inactive)) {
|
|
grapple_beam_function = FUNC16(GrappleBeam_Func2);
|
|
return 0;
|
|
}
|
|
if (samus_movement_type != kMovementType_03_SpinJumping && samus_movement_type != kMovementType_14_WallJumping)
|
|
return 0;
|
|
if (samus_pose_x_dir == kMovementType_04_MorphBallOnGround)
|
|
samus_pose = kPose_02_FaceL_Normal;
|
|
else
|
|
samus_pose = kPose_01_FaceR_Normal;
|
|
samus_anim_frame_skip = 0;
|
|
SamusFunc_F433();
|
|
Samus_SetAnimationFrameIfPoseChanged();
|
|
Samus_UpdatePreviousPose();
|
|
return 1;
|
|
}
|
|
|
|
uint8 SamusCode_04_06_Common(void) { // 0x90F19E
|
|
flare_counter = 0;
|
|
ClearFlareAnimationState();
|
|
Samus_LoadSuitPalette();
|
|
return 0;
|
|
}
|
|
|
|
uint8 SamusCode_04(void) { // 0x90F19B
|
|
samus_charge_palette_index = 0;
|
|
return SamusCode_04_06_Common();
|
|
}
|
|
|
|
uint8 SamusCode_06_LockToStation(void) { // 0x90F1AA
|
|
frame_handler_alfa = FUNC16(Samus_FrameHandlerAlfa_Func13);
|
|
frame_handler_beta = FUNC16(j_HandleDemoRecorder_2);
|
|
if (!sign16(flare_counter - 15))
|
|
QueueSfx1_Max15(2);
|
|
return SamusCode_04_06_Common();
|
|
}
|
|
|
|
uint8 SamusCode_07_SetupForElevator(void) { // 0x90F1C8
|
|
MakeSamusFaceForward();
|
|
frame_handler_beta = FUNC16(Samus_Func19);
|
|
samus_movement_handler = FUNC16(Samus_MovementHandler_Normal);
|
|
samus_draw_handler = FUNC16(SamusDisplayHandler_UsingElevator);
|
|
samus_input_handler = FUNC16(Samus_InputHandler_E913);
|
|
bomb_jump_dir = 0;
|
|
return 1;
|
|
}
|
|
|
|
uint8 SamusCode_08_SetupForCeresStart(void) { // 0x90F1E9
|
|
frame_handler_alfa = FUNC16(EmptyFunction);
|
|
frame_handler_beta = FUNC16(SetContactDamageIndexAndUpdateMinimap);
|
|
samus_pose = kPose_00_FaceF_Powersuit;
|
|
samus_anim_frame_skip = 0;
|
|
SamusFunc_F433();
|
|
Samus_SetAnimationFrameIfPoseChanged();
|
|
Samus_LoadSuitPalette();
|
|
samus_draw_handler = FUNC16(SamusDrawHandler_Default);
|
|
samus_prev_pose = samus_pose;
|
|
samus_last_different_pose = samus_pose;
|
|
*(uint16 *)&samus_prev_pose_x_dir = *(uint16 *)&samus_pose_x_dir;
|
|
*(uint16 *)&samus_last_different_pose_x_dir = *(uint16 *)&samus_pose_x_dir;
|
|
samus_y_pos = 0;
|
|
SpawnEnemyProjectileWithGfx(0, 0, addr_kEproj_CeresElevatorPad);
|
|
SpawnEnemyProjectileWithGfx(0, 0, addr_kEproj_CeresElevatorPlatform);
|
|
debug_disable_minimap = 0;
|
|
PlayRoomMusicTrackAfterAFrames(0x20);
|
|
return 1;
|
|
}
|
|
|
|
uint8 SamusCode_08_SetupForZebesStart(void) { // 0x90F23C
|
|
if ((equipped_items & 0x20) != 0) {
|
|
SpawnPalfxObject(addr_stru_8DE1FC);
|
|
samus_pose = kPose_9B_FaceF_VariaGravitySuit;
|
|
} else if ((equipped_items & 1) != 0) {
|
|
SpawnPalfxObject(addr_stru_8DE1F8);
|
|
samus_pose = kPose_9B_FaceF_VariaGravitySuit;
|
|
} else {
|
|
SpawnPalfxObject(addr_stru_8DE1F4);
|
|
samus_pose = kPose_00_FaceF_Powersuit;
|
|
}
|
|
Samus_LoadSuitPalette();
|
|
SamusFunc_F433();
|
|
samus_anim_frame_timer = 3;
|
|
samus_anim_frame = 2;
|
|
substate = 0;
|
|
return 1;
|
|
}
|
|
|
|
uint8 SamusCode_0A_ClearDrawHandler(void) { // 0x90F28D
|
|
samus_draw_handler = FUNC16(nullsub_152);
|
|
return 0;
|
|
}
|
|
|
|
uint8 SamusCode_0B_DrawHandlerDefault(void) { // 0x90F295
|
|
samus_draw_handler = FUNC16(SamusDrawHandler_Default);
|
|
return SamusCode_01_UnlockSamus();
|
|
}
|
|
|
|
uint8 SamusCode_0C_UnlockFromMapStation(void) { // 0x90F29E
|
|
SamusFunc_E633();
|
|
if (frame_handler_beta == FUNC16(j_HandleDemoRecorder_2)) {
|
|
frame_handler_alfa = FUNC16(Samus_FrameHandlerAlfa_Func11);
|
|
frame_handler_beta = FUNC16(Samus_FrameHandlerBeta_Func17);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
uint8 SamusCode_0D_IsGrappleActive(void) { // 0x90F2B8
|
|
return (grapple_beam_function != FUNC16(GrappleBeamFunc_Inactive)) ? 2 : 0;
|
|
}
|
|
|
|
uint8 SamusCode_0D_IsGrappleActive_A(void) {
|
|
return grapple_beam_function != FUNC16(GrappleBeamFunc_Inactive);
|
|
}
|
|
|
|
uint8 SamusCode_0E(void) { // 0x90F2CA
|
|
frame_handler_alfa = FUNC16(Samus_FrameHandlerAlfa_Func11);
|
|
frame_handler_beta = FUNC16(Samus_Func18);
|
|
return 1;
|
|
}
|
|
|
|
uint8 SamusCode_0F_EnableTimerHandling(void) { // 0x90F2D8
|
|
frame_handler_gamma = FUNC16(Samus_Func3);
|
|
return 0;
|
|
}
|
|
|
|
uint8 SamusCode_10(void) { // 0x90F2E0
|
|
if (frame_handler_beta != FUNC16(j_HandleDemoRecorder_2_0)) {
|
|
frame_handler_alfa = FUNC16(Samus_FrameHandlerAlfa_Func11);
|
|
frame_handler_beta = FUNC16(Samus_FrameHandlerBeta_Func17);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
uint8 SamusCode_11_15_Common(void) { // 0x90F2FC
|
|
frame_handler_alfa = FUNC16(Samus_FrameHandlerAlfa_Func13);
|
|
frame_handler_beta = FUNC16(EmptyFunction);
|
|
samus_draw_handler = FUNC16(SamusDisplayHandler_SamusReceivedFatal);
|
|
return 1;
|
|
}
|
|
|
|
uint8 SamusCode_11_SetupForDeath(void) { // 0x90F2F8
|
|
DisablePaletteFx();
|
|
return SamusCode_11_15_Common();
|
|
}
|
|
|
|
uint8 SamusCode_15_CalledBySuitAcquision(void) { // 0x90F310
|
|
Samus_UpdatePreviousPose();
|
|
flare_counter = 0;
|
|
ClearFlareAnimationState();
|
|
Samus_LoadSuitPalette();
|
|
return SamusCode_11_15_Common();
|
|
}
|
|
|
|
uint8 SamusCode_12_SetSuperPaletteFlag1(void) { // 0x90F320
|
|
samus_special_super_palette_flags = 1;
|
|
return 0;
|
|
}
|
|
|
|
uint8 SamusCode_12_SetSuperPaletteFlag0(void) { // 0x90F328
|
|
samus_special_super_palette_flags = 0;
|
|
Samus_LoadSuitPalette();
|
|
return 0;
|
|
}
|
|
|
|
uint8 SamusCode_14(void) { // 0x90F331
|
|
if (sign16(samus_health - 31))
|
|
QueueSfx3_Max6(2);
|
|
if (!SamusCode_0D_IsGrappleActive_A()) {
|
|
if (samus_pose_x_dir == 3) {
|
|
if (samus_pose == kPose_81_FaceR_Screwattack || samus_pose == kPose_82_FaceL_Screwattack) {
|
|
QueueSfx1_Max6(0x33);
|
|
} else if (samus_pose == kPose_1B_FaceR_SpaceJump || samus_pose == kPose_1C_FaceL_SpaceJump) {
|
|
QueueSfx1_Max6(0x3E);
|
|
} else {
|
|
QueueSfx1_Max6(0x31);
|
|
}
|
|
}
|
|
} else {
|
|
QueueSfx1_Max6(6);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
uint8 SamusCode_05_SetupDrained(void) { // 0x90F38E
|
|
frame_handler_gamma = FUNC16(Samus_Func1);
|
|
return Samus_SetupForBeingDrained();
|
|
}
|
|
|
|
uint8 Samus_SetupForBeingDrained(void) { // 0x90F394
|
|
samus_pose = kPose_54_FaceL_Knockback;
|
|
samus_anim_frame_skip = 0;
|
|
SamusFunc_F433();
|
|
Samus_SetAnimationFrameIfPoseChanged();
|
|
Samus_UpdatePreviousPose();
|
|
flare_counter = 0;
|
|
ClearFlareAnimationState();
|
|
Samus_LoadSuitPalette();
|
|
frame_handler_alfa = FUNC16(Samus_FrameHandlerAlfa_Func13);
|
|
frame_handler_beta = FUNC16(j_HandleDemoRecorder_2_0);
|
|
return 1;
|
|
}
|
|
|
|
uint8 SamusCode_18(void) { // 0x90F3C0
|
|
frame_handler_gamma = FUNC16(Samus_Func2);
|
|
return Samus_SetupForBeingDrained();
|
|
}
|
|
|
|
uint8 SamusCode_16(void) { // 0x90F3C9
|
|
samus_special_super_palette_flags = 0x8000;
|
|
special_samus_palette_frame = 1;
|
|
special_samus_palette_timer = 1;
|
|
samus_charge_palette_index = 0;
|
|
return 0;
|
|
}
|
|
|
|
uint8 SamusCode_17_DisableRainbowSamusAndStandUp(void) { // 0x90F3DD
|
|
samus_special_super_palette_flags = 0;
|
|
special_samus_palette_frame = 0;
|
|
special_samus_palette_timer = 0;
|
|
samus_charge_palette_index = 0;
|
|
Samus_LoadSuitPalette();
|
|
samus_anim_frame_timer = 1;
|
|
samus_anim_frame = 13;
|
|
return 0;
|
|
}
|
|
|
|
uint8 SamusCode_17_FreezeDrainedSamus(void) { // 0x90F3FB
|
|
samus_anim_frame_timer = 1;
|
|
samus_anim_frame = 28;
|
|
return 1;
|
|
}
|
|
|
|
uint8 SamusCode_1A(void) { // 0x90F409
|
|
frame_handler_beta = FUNC16(Samus_LowHealthCheck);
|
|
return 0;
|
|
}
|
|
|
|
uint8 SamusCode_1B_CheckedLockSamus(void) { // 0x90F411
|
|
if (frame_handler_beta == FUNC16(j_HandleDemoRecorder_2_0))
|
|
return 1;
|
|
else
|
|
return SamusCode_00_LockSamus();
|
|
}
|
|
|
|
uint8 SamusCode_1C(void) { // 0x90F41E
|
|
if (samus_movement_type == kMovementType_14_WallJumping) {
|
|
if (sign16(samus_anim_frame - 23)) {
|
|
if (sign16(samus_anim_frame - 13)) {
|
|
LABEL_11:
|
|
QueueSfx1_Max9(0x31);
|
|
return 0;
|
|
}
|
|
goto LABEL_12;
|
|
}
|
|
} else {
|
|
if (samus_movement_type != kMovementType_03_SpinJumping)
|
|
return 0;
|
|
if (samus_pose != kPose_81_FaceR_Screwattack && samus_pose != kPose_82_FaceL_Screwattack) {
|
|
if (samus_pose != kPose_1B_FaceR_SpaceJump && samus_pose != kPose_1C_FaceL_SpaceJump)
|
|
goto LABEL_11;
|
|
LABEL_12:
|
|
QueueSfx1_Max9(0x3E);
|
|
return 0;
|
|
}
|
|
}
|
|
QueueSfx1_Max9(0x33);
|
|
return 0;
|
|
}
|
|
|
|
uint8 SamusCode_1D_ClearSoundInDoor(void) { // 0x90F471
|
|
if (samus_movement_type == 3 || samus_movement_type == 20) {
|
|
QueueSfx1_Max15(0x32);
|
|
return 0;
|
|
} else {
|
|
if ((button_config_shoot_x & joypad1_lastkeys) == 0) {
|
|
if (sign16(flare_counter - 16))
|
|
QueueSfx1_Max15(2);
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
uint8 SamusCode_1E(void) { // 0x90F4A2
|
|
if (game_state == 8) {
|
|
if (samus_movement_type == 3 || samus_movement_type == 20) {
|
|
SamusCode_1C();
|
|
return 0;
|
|
}
|
|
if (!sign16(flare_counter - 16))
|
|
QueueSfx1_Max9(0x41);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
uint8 SamusCode_1F(void) { // 0x90F4D0
|
|
if (grapple_beam_function != (uint16)addr_loc_90C4F0) {
|
|
grapple_beam_unkD1E = 0;
|
|
grapple_beam_unkD20 = 0;
|
|
grapple_beam_direction = 0;
|
|
grapple_beam_unkD36 = 0;
|
|
grapple_walljump_timer = 0;
|
|
slow_grabble_scrolling_flag = 0;
|
|
grapple_varCF6 = 0;
|
|
grapple_beam_flags = 0;
|
|
LoadProjectilePalette(equipped_beams);
|
|
grapple_beam_function = -15120;
|
|
samus_draw_handler = FUNC16(SamusDrawHandler_Default);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
uint8 Samus_Func26(void) { // 0x90F507
|
|
if (samus_movement_type != kMovementType_03_SpinJumping
|
|
&& samus_movement_type != kMovementType_14_WallJumping
|
|
&& (button_config_shoot_x & joypad1_lastkeys) != 0
|
|
&& !sign16(flare_counter - 16)) {
|
|
QueueSfx1_Max9(0x41);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void Samus_ShootCheck(void) { // 0x90F576
|
|
if ((play_resume_charging_beam_sfx & 0x8000) != 0)
|
|
goto LABEL_15;
|
|
if (play_resume_charging_beam_sfx) {
|
|
if ((button_config_shoot_x & joypad1_lastkeys) != 0)
|
|
QueueSfx1_Max9(0x41);
|
|
play_resume_charging_beam_sfx = 0;
|
|
}
|
|
if (samus_echoes_sound_flag && (speed_boost_counter & 0x400) == 0) {
|
|
samus_echoes_sound_flag = 0;
|
|
QueueSfx3_Max15(0x25);
|
|
}
|
|
if ((samus_prev_movement_type == 3 || samus_prev_movement_type == 20)
|
|
&& samus_movement_type != kMovementType_03_SpinJumping
|
|
&& samus_movement_type != kMovementType_14_WallJumping) {
|
|
QueueSfx1_Max15(0x32);
|
|
if (!sign16(flare_counter - 16) && (button_config_shoot_x & joypad1_lastkeys) != 0)
|
|
LABEL_15:
|
|
play_resume_charging_beam_sfx = 1;
|
|
}
|
|
if (enable_debug) {
|
|
if (samus_pose == kPose_00_FaceF_Powersuit || samus_pose == kPose_9B_FaceF_VariaGravitySuit) {
|
|
if ((joypad2_last & 0x30) == 48 && (joypad2_new_keys & 0x80) != 0)
|
|
debug_invincibility = 7;
|
|
} else {
|
|
if (!sign16(debug_invincibility - 7))
|
|
return;
|
|
debug_invincibility = 0;
|
|
}
|
|
}
|
|
if (CheckEventHappened(0xE) & 1
|
|
&& frame_handler_gamma == FUNC16(DrawTimer_)
|
|
&& game_state != kGameState_35_TimeUp) {
|
|
game_state = kGameState_35_TimeUp;
|
|
}
|
|
}
|