Files
sm-vita/src/sm_91.c
Snesrev f591d89f84 Some tooling to extract assets
Run:
restool.py decode
to extract assets into assets/defs/*

Run:
restool.py compile
to compile the assets back into a rom
2023-04-17 20:29:29 +02:00

3981 lines
119 KiB
C

// Aran
#include "ida_types.h"
#include "variables.h"
#include "funcs.h"
#include "sm_rtl.h"
#define unk_91CAF2 (*(SpawnHdmaObject_Args*)RomFixedPtr(0x91caf2))
#define stru_91D2D6 ((XrayBlockData*)RomFixedPtr(0x91d2d6))
#define stru_91D2D6 ((XrayBlockData*)RomFixedPtr(0x91d2d6))
#define off_91D727 ((uint16*)RomFixedPtr(0x91d727))
#define kSamusPalette_HyperBeam ((uint16*)RomFixedPtr(0x91d829))
#define kSamusPalette_NonPseudoScrew ((uint16*)RomFixedPtr(0x91d7d5))
#define kSamusPalette_PseudoScrew ((uint16*)RomFixedPtr(0x91d7ff))
#define word_9BA3C0 ((uint16*)RomFixedPtr(0x9ba3c0))
#define kSamus_SpeedBoostingPalettes ((uint16*)RomFixedPtr(0x91d998))
#define kSamus_HyperBeamPalettes ((uint16*)RomFixedPtr(0x91d99e))
#define kSamusPal_ScrewAttack ((uint16*)RomFixedPtr(0x91da4a))
#define kSamusPal_SpeedBoost ((uint16*)RomFixedPtr(0x91daa9))
#define kSamusPal_SpeedBoostShine ((uint16*)RomFixedPtr(0x91db10))
#define kSamusPal_Shinespark ((uint16*)RomFixedPtr(0x91db75))
#define stru_91DC00 ((SamusCrystalFlashPalTable*)RomFixedPtr(0x91dc00))
#define off_91DC28 ((uint16*)RomFixedPtr(0x91dc28))
#define word_91E921 ((uint16*)RomFixedPtr(0x91e921))
#define word_91E9F3 ((uint16*)RomFixedPtr(0x91e9f3))
#define word_91EB74 ((uint16*)RomFixedPtr(0x91eb74))
#define kSamusTurnPose_Standing ((uint8*)RomFixedPtr(0x91f9c2))
#define kSamusTurnPose_Crouching ((uint8*)RomFixedPtr(0x91f9cc))
#define kSamusTurnPose_Jumping ((uint8*)RomFixedPtr(0x91f9d6))
#define kSamusTurnPose_Falling ((uint8*)RomFixedPtr(0x91f9e0))
#define kSamusTurnPose_Moonwalk ((uint8*)RomFixedPtr(0x91f9ea))
static void Xray_Func12(uint16 dst_r22, const uint8 *jp);
static void Xray_Func13(uint16 dst_r22, uint16 j);
static void Xray_Func14(uint16 dst_r22, const uint8 *jp);
static void Xray_Func15(uint16 dst_r22, const uint8 *jp);
static void Xray_Func16(uint16 dst_r22, uint16 j);
typedef struct Pair_R18_R20 {
uint16 r18, r20;
} Pair_R18_R20;
Pair_R18_R20 TranslateCustomControllerBindingsToDefault(void);
static Func_V *const kSamusInputHandlers[28] = {
Samus_Input_00_Standing,
Samus_Input_01_Running,
Samus_Input_02_NormalJumping,
Samus_Input_03_SpinJumping,
Samus_Input_04_MorphBallOnGround,
Samus_Input_05_Crouching,
Samus_Input_06_Falling,
Samus_Input_07_Unused,
Samus_Input_08_MorphBallFalling,
Samus_Input_09_Unused,
Samus_Input_0A_KnockbackOrCrystalFlashEnding,
Samus_Input_0B_Unused,
Samus_Input_0C_Unused,
Samus_Input_0D_Unused,
Samus_Input_0E_TurningAroundOnGround,
Samus_Input_0F_CrouchingEtcTransition,
Samus_Input_10_Moonwalking,
Samus_Input_11_SpringBallOnGround,
Samus_Input_12_SpringBallInAir,
Samus_Input_13_SpringBallFalling,
Samus_Input_14_WallJumping,
Samus_Input_15_RanIntoWall,
Samus_Input_16_Grappling,
Samus_Input_17_TurningAroundJumping,
Samus_Input_18_TurningAroundFalling,
Samus_Input_19_DamageBoost,
Samus_Input_1A_GrabbedByDraygon,
Samus_Input_1B_ShinesparkEtc,
};
void Samus_InputHandler(void) { // 0x918000
kSamusInputHandlers[samus_movement_type]();
}
void Samus_Input_00_Standing(void) { // 0x91804D
if (samus_pose && samus_pose != kPose_9B_FaceF_VariaGravitySuit || !elevator_status)
Samus_LookupTransitionTable();
}
void Samus_Input_01_Running(void) { // 0x918066
Samus_LookupTransitionTable();
}
void Samus_Input_02_NormalJumping(void) { // 0x91806E
Samus_LookupTransitionTable();
}
void Samus_Input_03_SpinJumping(void) { // 0x918076
Samus_LookupTransitionTable();
}
void Samus_Input_04_MorphBallOnGround(void) { // 0x91807E
Samus_LookupTransitionTable();
}
void Samus_Input_07_Unused(void) { // 0x918086
;
}
void Samus_Input_05_Crouching(void) { // 0x918087
if (time_is_frozen_flag) {
Samus_Func20();
} else {
Samus_LookupTransitionTable();
if (!samus_movement_type) {
samus_y_pos -= 5;
samus_prev_y_pos -= 5;
}
}
}
void Samus_Input_06_Falling(void) { // 0x9180B6
Samus_LookupTransitionTable();
}
void Samus_Input_08_MorphBallFalling(void) { // 0x91810A
Samus_LookupTransitionTable();
}
void Samus_Input_09_Unused(void) { // 0x918112
;
}
void Samus_Input_0A_KnockbackOrCrystalFlashEnding(void) { // 0x918113
Samus_LookupTransitionTable();
if (samus_movement_type != kMovementType_0A_KnockbackOrCrystalFlashEnding) {
Samus_InitJump();
samus_knockback_timer = 0;
}
}
void Samus_Input_0B_Unused(void) { // 0x91812D
;
}
void Samus_Input_0C_Unused(void) { // 0x918132
Samus_LookupTransitionTable();
}
void Samus_Input_0D_Unused(void) { // 0x91813A
Samus_LookupTransitionTable();
}
void Samus_Input_0E_TurningAroundOnGround(void) { // 0x918142
Samus_LookupTransitionTable();
}
void Samus_Input_0F_CrouchingEtcTransition(void) { // 0x918146
;
}
void Samus_Input_10_Moonwalking(void) { // 0x918147
Samus_LookupTransitionTable();
}
void Samus_Input_11_SpringBallOnGround(void) { // 0x91814F
Samus_LookupTransitionTable();
}
void Samus_Input_12_SpringBallInAir(void) { // 0x918157
Samus_LookupTransitionTable();
}
void Samus_Input_13_SpringBallFalling(void) { // 0x91815F
Samus_LookupTransitionTable();
}
void Samus_Input_14_WallJumping(void) { // 0x918167
Samus_LookupTransitionTable();
}
void Samus_Input_15_RanIntoWall(void) { // 0x91816F
if (time_is_frozen_flag)
Samus_Func20();
else
Samus_LookupTransitionTable();
}
void Samus_Input_16_Grappling(void) { // 0x918181
Samus_LookupTransitionTable();
}
void Samus_Input_17_TurningAroundJumping(void) { // 0x918189
Samus_LookupTransitionTable();
}
void Samus_Input_18_TurningAroundFalling(void) { // 0x91818D
Samus_LookupTransitionTable();
}
void Samus_Input_19_DamageBoost(void) { // 0x918191
Samus_LookupTransitionTable();
}
void Samus_Input_1A_GrabbedByDraygon(void) { // 0x918199
Samus_LookupTransitionTable();
}
void Samus_Input_1B_ShinesparkEtc(void) { // 0x9181A1
Samus_LookupTransitionTable();
}
void Samus_LookupTransitionTable(void) { // 0x9181A9
if (joypad1_lastkeys) {
Pair_R18_R20 pair = TranslateCustomControllerBindingsToDefault();
PoseEntry *pe = get_PoseEntry(kPoseTransitionTable[samus_pose]);
if (pe->new_input == 0xFFFF)
return;
do {
if ((pair.r18 & pe->new_input) == 0 && (pair.r20 & pe->cur_input) == 0) {
if (pe->new_pose != samus_pose) {
samus_new_pose = pe->new_pose;
bomb_jump_dir = 0;
}
return;
}
pe++;
} while (pe->new_input != 0xFFFF);
}
UNUSED_word_7E0A18 = 0;
Samus_Pose_CancelGrapple();
}
Pair_R18_R20 TranslateCustomControllerBindingsToDefault(void) { // 0x9181F4
uint16 r18 = joypad1_newkeys & (kButton_Up | kButton_Down | kButton_Left | kButton_Right);
uint16 r20 = joypad1_lastkeys & (kButton_Up | kButton_Down | kButton_Left | kButton_Right);
uint16 v0 = joypad1_newkeys;
if ((button_config_shoot_x & joypad1_newkeys) != 0)
r18 |= kButton_X;
if ((button_config_jump_a & v0) != 0)
r18 |= kButton_A;
if ((button_config_run_b & v0) != 0)
r18 |= kButton_B;
if ((button_config_itemcancel_y & v0) != 0)
r18 |= kButton_Y;
if ((button_config_aim_up_R & v0) != 0) {
if ((button_config_aim_up_R & (kButton_L | kButton_R)) != 0)
r18 |= kButton_R;
}
if ((button_config_aim_down_L & v0) != 0 && (button_config_aim_down_L & (kButton_L | kButton_R)) != 0)
r18 |= kButton_L;
uint16 v1 = joypad1_lastkeys;
if ((button_config_shoot_x & joypad1_lastkeys) != 0)
r20 |= kButton_X;
if ((button_config_jump_a & v1) != 0)
r20 |= kButton_A;
if ((button_config_run_b & v1) != 0)
r20 |= kButton_B;
if ((button_config_itemcancel_y & v1) != 0)
r20 |= kButton_Y;
if ((button_config_aim_up_R & v1) != 0) {
if ((button_config_aim_up_R & (kButton_L | kButton_R)) != 0)
r20 |= kButton_R;
}
if ((button_config_aim_down_L & v1) != 0 && (button_config_aim_down_L & (kButton_L | kButton_R)) != 0)
r20 |= kButton_L;
return (Pair_R18_R20) { ~r18, ~r20 };
}
void Samus_Pose_CancelGrapple(void) { // 0x9182D9
if (Samus_Pose_Func2() & 1 || kPoseParams[samus_pose].new_pose_unless_buttons == 255)
samus_new_pose = samus_pose;
else
samus_new_pose = kPoseParams[samus_pose].new_pose_unless_buttons;
}
static const uint8 kSamus_Pose_Func2_Tab[28] = { // 0x918304
2, 1, 1, 0, 6, 2, 8, 2, 1, 6, 2, 2, 2, 6, 2, 2,
2, 6, 6, 6, 6, 2, 6, 2, 2, 2, 2, 2,
};
uint8 Samus_Pose_Func2(void) {
uint16 v0 = kSamus_Pose_Func2_Tab[samus_movement_type];
if (v0 != 1)
goto LABEL_2;
if (!samus_x_base_speed && !samus_x_base_subspeed) {
v0 = 2;
LABEL_2:
samus_momentum_routine_index = v0;
return 0;
}
samus_momentum_routine_index = 1;
return 1;
}
void EnableDemoInput(void) { // 0x91834E
samus_input_handler = FUNC16(Samus_InputHandler_E91D);
demo_enable |= 0x8000;
}
void DisableDemoInput(void) { // 0x91835F
samus_input_handler = FUNC16(Samus_InputHandler_E913);
demo_enable &= ~0x8000;
}
void ResetDemoData(void) { // 0x918370
demo_input_pre_instr = 0;
demo_input_instr_timer = 0;
demo_input_instr_ptr = 0;
demo_timer_counter = 0;
xray_angle = 0;
demo_input = 0;
demo_input_new = 0;
demo_input_prev = 0;
demo_input_prev_new = 0;
demo_enable = 0;
}
void LoadDemoInputObject(uint16 a, uint16 j) { // 0x918395
DemoInputObject *dio;
xray_angle = a;
dio = get_DemoInputObject(j);
demo_input_pre_instr = dio->pre_instr;
demo_input_instr_ptr = dio->instr_ptr;
demo_input_instr_timer = 1;
demo_timer_counter = 0;
// Call(dio->ptr | 0x910000);
}
void DemoObjectInputHandler(void) { // 0x9183C0
if ((demo_enable & 0x8000) != 0) {
if (demo_input_instr_ptr) {
ProcessDemoInputObject();
joypad1_input_samusfilter = demo_input_prev;
joypad1_newinput_samusfilter = demo_input_prev_new;
joypad1_lastkeys = demo_input;
demo_input_prev = demo_input;
joypad1_newkeys = demo_input_new;
demo_input_prev_new = demo_input_new;
}
}
}
void CallDemoPreInstr(uint32 ea) {
switch (ea) {
case fnDemoPreInstr_nullsub_162: return;
case fnDemoPreInstr_864F: DemoPreInstr_864F(); return;
case fnDemoPreInstr_866A: DemoPreInstr_866A(); return;
case fnDemoPreInstr_CheckLeaveDemo: DemoPreInstr_CheckLeaveDemo(); return;
case fnDemoPreInstr_8AB0: DemoPreInstr_8AB0(); return;
default: Unreachable();
}
}
uint16 CallDemoInstr(uint32 ea, uint16 k, uint16 j) {
switch (ea) {
case fnDemoInstr_Finish: return DemoInstr_Finish(k, j);
case fnDemoInstr_SetPreInstr: return DemoInstr_SetPreInstr(k, j);
case fnDemoInstr_ClearPreInstr: return DemoInstr_ClearPreInstr(k, j);
case fnDemoInstr_Goto: return DemoInstr_Goto(k, j);
case fnDemoInstr_DecTimerAndGoto: return DemoInstr_DecTimerAndGoto(k, j);
case fnDemoInstr_SetTimer: return DemoInstr_SetTimer(k, j);
case fnDemoInstr_Func2: return DemoInstr_Func2(k, j);
case fnDemoInstr_Disable: return DemoInstr_Disable(k, j);
case fnDemoInstr_Func3: return DemoInstr_Func3(k, j);
default: return Unreachable();
}
}
void ProcessDemoInputObject(void) { // 0x9183F2
CallDemoPreInstr(demo_input_pre_instr | 0x910000);
if (!--demo_input_instr_timer) {
uint16 v0 = demo_input_instr_ptr;
uint16 *v1;
while (1) {
v1 = (uint16 *)RomPtr_91(v0);
uint16 v2 = *v1;
if ((*v1 & 0x8000) == 0)
break;
v0 = CallDemoInstr(v2 | 0x910000, 0, v0 + 2);
if (!v0)
return;
}
demo_input_instr_timer = *v1;
const uint8 *v3 = RomPtr_91(v0);
demo_input = GET_WORD(v3 + 2);
demo_input_new = GET_WORD(v3 + 4);
demo_input_instr_ptr = v0 + 6;
}
}
uint16 DemoInstr_Finish(uint16 k, uint16 j) { // 0x918427
demo_input_instr_ptr = 0;
demo_input = 0;
demo_input_new = 0;
return 0;
}
uint16 DemoInstr_SetPreInstr(uint16 k, uint16 j) { // 0x918434
demo_input_pre_instr = *(uint16 *)RomPtr_91(j);
return j + 2;
}
uint16 DemoInstr_ClearPreInstr(uint16 k, uint16 j) { // 0x91843F
demo_input_pre_instr = 0x8447;
return j;
}
uint16 DemoInstr_Goto(uint16 k, uint16 j) { // 0x918448
return *(uint16 *)RomPtr_91(j);
}
uint16 DemoInstr_DecTimerAndGoto(uint16 k, uint16 j) { // 0x91844F
if (--demo_timer_counter)
return DemoInstr_Goto(k, j);
else
return j + 2;
}
uint16 DemoInstr_SetTimer(uint16 k, uint16 j) { // 0x918459
demo_timer_counter = *(uint16 *)RomPtr_91(j);
return j + 2;
}
uint16 DemoInstr_Func2(uint16 k, uint16 j) { // 0x9185FC
frame_handler_alfa = FUNC16(Samus_FrameHandlerAlfa_Func11);
frame_handler_beta = FUNC16(Samus_FrameHandlerBeta_Func17);
DisableDemoInput();
return j;
}
void DemoPreInstr_864F(void) { // 0x91864F
if (sign16(samus_x_pos - 178)) {
demo_input_pre_instr = FUNC16(DemoPreInstr_866A);
demo_input_instr_ptr = 0x8623;
demo_input_instr_timer = 1;
}
}
void DemoPreInstr_866A(void) { // 0x91866A
if (!eproj_x_pos[0]) {
demo_input_pre_instr = FUNC16(DemoPreInstr_nullsub_162);
demo_input_instr_ptr = addr_off_91864B;
demo_input_instr_timer = 1;
}
}
uint16 DemoInstr_Disable(uint16 k, uint16 j) { // 0x918682
frame_handler_alfa = FUNC16(EmptyFunction);
frame_handler_beta = FUNC16(EmptyFunction);
DisableDemoInput();
return j;
}
void UNUSED_DemoInstr_Func4(void) { // 0x9186FE
frame_handler_alfa = FUNC16(Samus_FrameHandlerAlfa_Func13);
samus_pose = kPose_02_FaceL_Normal;
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;
DisableDemoInput();
samus_input_handler = FUNC16(nullsub_152);
}
uint16 DemoInstr_Func3(uint16 k, uint16 j) { // 0x918739
frame_handler_alfa = FUNC16(Samus_FrameHandlerAlfa_Func13);
samus_pose = kPose_02_FaceL_Normal;
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;
DisableDemoInput();
samus_input_handler = FUNC16(nullsub_152);
return j;
}
static Func_V *const kDemoSetFuncPtrs_0[6] = { // 0x918790
DemoSetFunc_0,
DemoSetFunc_1,
DemoSetFunc_1,
DemoSetFunc_2,
DemoSetFunc_1,
DemoSetFunc_3,
};
static Func_V *const kDemoSetFuncPtrs_1[6] = {
DemoSetFunc_2,
DemoSetFunc_2,
DemoSetFunc_1,
DemoSetFunc_2,
DemoSetFunc_1,
DemoSetFunc_4,
};
static Func_V *const kDemoSetFuncPtrs_2[6] = {
DemoSetFunc_2,
DemoSetFunc_5,
DemoSetFunc_1,
DemoSetFunc_1,
DemoSetFunc_1,
DemoSetFunc_1,
};
static Func_V *const kDemoSetFuncPtrs_3[5] = {
DemoSetFunc_6,
DemoSetFunc_2,
DemoSetFunc_2,
DemoSetFunc_1,
DemoSetFunc_7,
};
static Func_V *const *const kDemoSetFuncPtrs[4] = {
kDemoSetFuncPtrs_0,
kDemoSetFuncPtrs_1,
kDemoSetFuncPtrs_2,
kDemoSetFuncPtrs_3,
};
void LoadDemoData(void) {
DemoSetDef *DemoSetDef;
uint16 v0 = 16 * demo_scene + kDemoSetDefPtrs[demo_set];
DemoSetDef = get_DemoSetDef(v0);
collected_items = DemoSetDef->items;
equipped_items = collected_items;
samus_max_missiles = DemoSetDef->missiles;
samus_missiles = samus_max_missiles;
samus_max_super_missiles = DemoSetDef->super_missiles;
samus_super_missiles = samus_max_super_missiles;
samus_max_power_bombs = DemoSetDef->power_bombs;
samus_power_bombs = samus_max_power_bombs;
samus_max_health = DemoSetDef->health;
samus_health = samus_max_health;
collected_beams = DemoSetDef->beams;
equipped_beams = DemoSetDef->equipped_beams_;
samus_reserve_health = 0;
ResetDemoData();
EnableDemoInput();
uint16 demo_obj = get_DemoSetDef(v0)->demo_obj;
LoadDemoInputObject(demo_obj, demo_obj);
kDemoSetFuncPtrs[demo_set][demo_scene]();
frame_handler_alfa = FUNC16(Samus_FrameHandlerAlfa_Func12);
frame_handler_beta = FUNC16(Samus_FrameHandlerBeta_Func14);
samus_momentum_routine_index = 0;
samus_special_transgfx_index = 0;
samus_hurt_switch_index = 0;
Samus_LoadSuitPalette();
UpdateBeamTilesAndPalette();
button_config_up = kButton_Up;
button_config_down = kButton_Down;
button_config_left = kButton_Left;
button_config_right = kButton_Right;
button_config_shoot_x = kButton_X;
button_config_jump_a = kButton_A;
button_config_run_b = kButton_B;
button_config_itemcancel_y = kButton_Y;
button_config_itemswitch = kButton_Select;
button_config_aim_up_R = kButton_R;
button_config_aim_down_L = kButton_L;
UNUSED_word_7E09E8 = 1;
debug_flag = 1;
moonwalk_flag = 0;
UNUSED_word_7E0DF8 = 0;
UNUSED_word_7E0DFA = 0;
UNUSED_word_7E0DFC = 0;
}
void DemoSetFunc_0(void) { // 0x918A33
MakeSamusFaceForward();
samus_draw_handler = FUNC16(SamusDrawHandler_Default);
}
void DemoSetFunc_3(void) { // 0x918A3E
DemoSetFunc_Common(0x1F);
}
void DemoSetFunc_7(void) { // 0x918A43
samus_health = 20;
DemoSetFunc_2();
}
void DemoSetFunc_2(void) { // 0x918A49
DemoSetFunc_Common(2);
}
void DemoSetFunc_4(void) { // 0x918A4E
DemoSetFunc_Common(0x2A);
}
void DemoSetFunc_1(void) { // 0x918A53
DemoSetFunc_Common(1);
}
void DemoSetFunc_Common(uint16 a) { // 0x918A56
samus_pose = a;
SamusFunc_F433();
Samus_SetAnimationFrameIfPoseChanged();
samus_draw_handler = FUNC16(SamusDrawHandler_Default);
}
void DemoSetFunc_5(void) { // 0x918A68
samus_draw_handler = FUNC16(SamusDrawHandler_Default);
Projectile_Func7_Shinespark();
samus_pose = kPose_CD_FaceR_Shinespark_Diag;
SamusFunc_F433();
Samus_SetAnimationFrameIfPoseChanged();
}
void DemoSetFunc_6(void) { // 0x918A81
samus_draw_handler = FUNC16(SamusDrawHandler_Default);
Projectile_Func7_Shinespark();
samus_pose = kPose_CA_FaceL_Shinespark_Horiz;
SamusFunc_F433();
Samus_SetAnimationFrameIfPoseChanged();
}
void DemoPreInstr_CheckLeaveDemo(void) { // 0x918A9B
if (game_state == kGameState_44_TransitionFromDemo) {
demo_input_instr_ptr = addr_kDemoInstrs_LeaveDemo;
demo_input_instr_timer = 1;
}
}
void DemoPreInstr_8AB0(void) { // 0x918AB0
if (samus_movement_type != kMovementType_1A_GrabbedByDraygon) {
demo_input_pre_instr = FUNC16(DemoPreInstr_CheckLeaveDemo);
demo_input_instr_ptr = addr_stru_919346;
demo_input_instr_timer = 1;
}
}
typedef struct XrayHdmaCtx {
uint16 r22;
uint16 r24;
uint16 r26;
uint16 r28;
uint16 r30;
uint16 r32;
uint16 r18_avoid;
uint16 *dest;
} XrayHdmaCtx;
static void XrayFillUp(uint16 *dest, uint16 fill_with, uint16 v1) {
do {
dest[v1 >> 1] = fill_with;
} while (!sign16(v1 -= 2));
}
static void XrayFillDown(uint16 *dest, uint16 fill_with, uint16 v1) {
do {
dest[v1 >> 1] = fill_with;
} while ((v1 += 2) < 460);
}
static void XrayFillUpRamped(uint16 *dest, int pos, uint32 left, uint32 left_step, uint32 right, uint32 right_step, int adjust) {
do {
left += left_step;
right += right_step;
uint32 left_val = (left & ~0xffff) ? (((int32)left < 0) ? 0 : 0xffff) : left;
uint32 right_val = (right & ~0xffff) ? (((int32)right < 0) ? 0 : 0xffff) : right;
// If both left and right reached the end, fill the remainder with 0xff
bool finished = (left & ~0xffff) && (right & ~0xffff) && (((left_step ^ left) | (right_step ^ right)) >> 31) == 0;
dest[pos >> 1] = ((int32)right < 0 || (int32)left >= 0x10000) ? 0xff : (left_val >> 8 | right_val & ~0xff);
if (finished) {
pos += adjust;
while ((pos -= 2) >= 0)
dest[pos >> 1] = 0xff;
return;
}
} while ((pos -= 2) >= 0);
}
static void XrayFillDownRamped(uint16 *dest, int pos, uint32 left, uint32 left_step, uint32 right, uint32 right_step, int adjust) {
do {
left += left_step;
right += right_step;
uint32 left_val = (left & ~0xffff) ? (((int32)left < 0) ? 0 : 0xffff) : left;
uint32 right_val = (right & ~0xffff) ? (((int32)right < 0) ? 0 : 0xffff) : right;
bool finished = (left & ~0xffff) && (right & ~0xffff) && (((left_step ^ left) | (right_step ^ right)) >> 31) == 0;
// If both left and right got clamped, fill the remainder with 0xff
dest[pos >> 1] = ((int32)right < 0 || (int32)left >= 0x10000) ? 0xff : (left_val >> 8 | right_val & ~0xff);
if (finished) {
pos += adjust;
while ((pos += 2) < 460)
dest[pos >> 1] = 0xff;
return;
}
} while ((pos += 2) < 460);
}
typedef void XrayHdma0Func(XrayHdmaCtx *ctx);
static void XrayHdmaFunc_BeamAimedD(XrayHdmaCtx *ctx);
static void XrayHdmaFunc_BeamAimedL(XrayHdmaCtx *ctx);
static void XrayHdmaFunc_BeamAimedR(XrayHdmaCtx *ctx);
static void XrayHdmaFunc_BeamAimedU(XrayHdmaCtx *ctx);
static void XrayHdmaFunc_BeamHoriz(XrayHdmaCtx *ctx);
static void XrayHdmaOnScreen_BeamAimedD(XrayHdmaCtx *ctx);
static void XrayHdmaOnScreen_BeamAimedL(XrayHdmaCtx *ctx);
static void XrayHdmaOnScreen_BeamAimedR(XrayHdmaCtx *ctx);
static void XrayHdmaOnScreen_BeamAimedU(XrayHdmaCtx *ctx);
static void XrayHdmaOnScreen_BeamHoriz(XrayHdmaCtx *ctx);
static void XrayHdmaFunc_BeamAimedR(XrayHdmaCtx *ctx) { // 0x91BEC2
int p = 2 * ctx->r24;
XrayFillUpRamped(ctx->dest, p - 2, ctx->r22 - 0x10000, ctx->r30, 65535, 1, 2);
XrayFillDownRamped(ctx->dest, p, ctx->r22 - 0x10000, ctx->r32, 65535, 1, -2);
}
static void XrayHdmaFunc_BeamAimedL(XrayHdmaCtx *ctx) { // 0x91BF72
int t = 2 * ctx->r24;
XrayFillUpRamped(ctx->dest, t - 2, 0, -1, ctx->r22 + 0x10000, -ctx->r32, 2);
XrayFillDownRamped(ctx->dest, t, 0, -1, ctx->r22 + 0x10000, -ctx->r30, -2);
}
static void XrayHdmaFunc_BeamAimedU(XrayHdmaCtx *ctx) {
int p = 2 * ctx->r24;
if (sign16(ctx->r26 - 192)) {
XrayFillUpRamped(ctx->dest, p - 2, ctx->r22 - 0x10000, ctx->r30, ctx->r22 - 0x10000, ctx->r32, 0);
} else if (sign16(ctx->r28 - 192)) {
XrayFillUpRamped(ctx->dest, p - 2, ctx->r22 + 0x10000, -ctx->r30, ctx->r22 - 0x10000, ctx->r32, 0);
} else {
XrayFillUpRamped(ctx->dest, p - 2, ctx->r22 + 0x10000, -ctx->r30, ctx->r22 + 0x10000, -ctx->r32, 2);
}
XrayFillDown(ctx->dest, 0xff, p);
}
static void XrayHdmaFunc_BeamAimedD(XrayHdmaCtx *ctx) {
int p = 2 * ctx->r24;
if (sign16(ctx->r28 - 128)) {
XrayFillDownRamped(ctx->dest, p, ctx->r22 - 0x10000, ctx->r32, ctx->r22 - 0x10000, ctx->r30, 0);
} else if (sign16(ctx->r26 - 128)) {
XrayFillDownRamped(ctx->dest, p, ctx->r22 + 0x10000, -ctx->r32, ctx->r22 - 0x10000, ctx->r30, 0);
} else {
XrayFillDownRamped(ctx->dest, p, ctx->r22 + 0x10000, -ctx->r32, ctx->r22 + 0x10000, -ctx->r30, 0);
}
XrayFillUp(ctx->dest, 0xff, p - 2);
}
static void XrayHdmaFunc_BeamHoriz(XrayHdmaCtx *ctx) { // 0x91C505
uint16 v0 = 2 * (ctx->r24 - 1);
ctx->dest[v0 >> 1] = 0xff00;
XrayFillUp(ctx->dest, 0xff, v0 - 2);
XrayFillDown(ctx->dest, 0xff, v0 + 2);
}
static void XrayHdmaOnScreen_BeamAimedR(XrayHdmaCtx *ctx) { // 0x91C5FF
int p = 2 * ctx->r24;
ctx->dest[(p - 2) >> 1] = ctx->r22 >> 8 | 0xff00;
XrayFillUpRamped(ctx->dest, p - 4, ctx->r22, ctx->r30, 65535, 1, 2);
XrayFillDownRamped(ctx->dest, p, ctx->r22, ctx->r32, 65535, 1, -2);
}
static void XrayHdmaOnScreen_BeamAimedL(XrayHdmaCtx *ctx) { // 0x91C660
int v0 = 2 * ctx->r24;
ctx->dest[(v0 - 2) >> 1] = (ctx->r22 >> 8) << 8;
XrayFillUpRamped(ctx->dest, v0 - 4, 0, -1, ctx->r22, -ctx->r32, 2);
XrayFillDownRamped(ctx->dest, v0, 0, -1, ctx->r22, -ctx->r30, -2);
}
static void XrayHdmaOnScreen_BeamAimedU(XrayHdmaCtx *ctx) { // 0x91C6C1
int v0 = 2 * ctx->r24;
ctx->dest[(v0 - 2) >> 1] = (ctx->r22 >> 8) * 0x101;
if (sign16(ctx->r26 - 192)) {
XrayFillUpRamped(ctx->dest, v0 - 4, ctx->r22, ctx->r30, ctx->r22, ctx->r32, 0);
} else if (sign16(ctx->r28 - 192)) {
XrayFillUpRamped(ctx->dest, v0 - 4, ctx->r22, -ctx->r30, ctx->r22, ctx->r32, 0);
} else {
XrayFillUpRamped(ctx->dest, v0 - 4, ctx->r22, -ctx->r30, ctx->r22, -ctx->r32, 2);
}
XrayFillDown(ctx->dest, 0xff, v0);
}
static void XrayHdmaOnScreen_BeamAimedD(XrayHdmaCtx *ctx) { // 0x91C822
int v0 = 2 * ctx->r24;
ctx->dest[(v0 - 2) >> 1] = (ctx->r22 >> 8) * 0x101;
if (sign16(ctx->r28 - 128)) {
XrayFillDownRamped(ctx->dest, v0, ctx->r22, ctx->r32, ctx->r22, ctx->r30, 0);
} else if (sign16(ctx->r26 - 128)) {
XrayFillDownRamped(ctx->dest, v0, ctx->r22, -ctx->r32, ctx->r22, ctx->r30, 0);
} else {
XrayFillDownRamped(ctx->dest, v0, ctx->r22, -ctx->r32, ctx->r22, -ctx->r30, 0);
}
XrayFillUp(ctx->dest, 0xff, v0 - 4);
}
static void XrayHdmaOnScreen_BeamHoriz(XrayHdmaCtx *ctx) { // 0x91C998
uint16 v0 = 2 * (ctx->r24 - 1);
uint32 t = (ctx->r22 >> 8);
ctx->dest[v0 >> 1] = (ctx->r18_avoid == 64) ? t | 0xFF00 : t << 8;
XrayFillUp(ctx->dest, 0xff, v0 - 2);
XrayFillDown(ctx->dest, 0xff, v0 + 2);
}
void CalculateXrayHdmaTableInner(uint16 k, uint16 j, uint16 r18, uint16 r20, bool off_screen, uint16 *dest_addr) {
int v3;
XrayHdmaCtx ctx[1];
ctx->dest = (uint16*)dest_addr;
ctx->r18_avoid = r18;
ctx->r22 = k << 8;
ctx->r24 = j;
ctx->r26 = r18 - r20;
ctx->r26 += (ctx->r26 & 0x8000) != 0 ? 0x100 : 0;
ctx->r28 = r20 + r18;
if (!sign16(r20 + r18 - 257))
ctx->r28 = r20 + r18 - 256;
ctx->r30 = kTanTable[sign16(ctx->r26 - 128) ? ctx->r26 : ctx->r26 - 128];
ctx->r32 = kTanTable[sign16(ctx->r28 - 128) ? ctx->r28 : ctx->r28 - 128];
if (!r20 && (r18 == 64 || r18 == 192)) {
v3 = 8;
} else if (sign16(ctx->r26 - 128)) {
if (!sign16(ctx->r26 - 64)) {
v3 = 4;
} else if (!sign16(ctx->r28 - 64)) {
v3 = 0;
} else {
v3 = 2;
}
} else {
if (!sign16(ctx->r26 - 192)) {
v3 = 2;
} else if (!sign16(ctx->r28 - 192)) {
v3 = 6;
} else {
v3 = 4;
}
}
if (off_screen) {
static XrayHdma0Func *const kXrayHdmaFuncs[5] = { // 0x91BE11
XrayHdmaFunc_BeamAimedR,
XrayHdmaFunc_BeamAimedU,
XrayHdmaFunc_BeamAimedD,
XrayHdmaFunc_BeamAimedL,
XrayHdmaFunc_BeamHoriz,
};
kXrayHdmaFuncs[v3 >> 1](ctx);
} else {
static XrayHdma0Func *const kXrayHdmaOnScreen_Funcs[5] = {
XrayHdmaOnScreen_BeamAimedR,
XrayHdmaOnScreen_BeamAimedU,
XrayHdmaOnScreen_BeamAimedD,
XrayHdmaOnScreen_BeamAimedL,
XrayHdmaOnScreen_BeamHoriz,
};
kXrayHdmaOnScreen_Funcs[v3 >> 1](ctx);
}
}
void XrayRunHandler(void) { // 0x91CAD6
if (!time_is_frozen_flag && (button_config_run_b & joypad1_lastkeys) != 0) {
if (Xray_Initialize() & 1)
SpawnHdmaObject(0x91, &unk_91CAF2);
}
}
void Xray_SetupStage1_FreezeTimeBackup(uint16 k) { // 0x91CAF9
LOBYTE(time_is_frozen_flag) = 1;
*((uint8 *)hdma_object_A + (uint8)k) = reg_BG2HOFS;
*((uint8 *)hdma_object_A + (uint8)k + 1) = HIBYTE(reg_BG2HOFS);
*((uint8 *)hdma_object_B + (uint8)k) = reg_BG2VOFS;
*((uint8 *)hdma_object_B + (uint8)k + 1) = HIBYTE(reg_BG2VOFS);
*((uint8 *)hdma_object_C + (uint8)k) = reg_BG2SC;
}
void Xray_SetupStage2_ReadBg1_2ndScreen(void) { // 0x91CB1C
uint16 v0 = vram_read_queue_tail;
*(uint16 *)((uint8 *)&vram_read_queue[0].vram_target + v0) = ((reg_BG1SC & 0xFC) << 8) + 1024;
*(uint16 *)((uint8 *)&vram_read_queue[0].dma_parameters + v0) = 129;
*(uint16 *)((uint8 *)&vram_read_queue[0].dma_parameters + v0 + 1) = 57;
*(VoidP *)((uint8 *)&vram_read_queue[0].src.addr + v0) = ADDR16_OF_RAM(ram4000) + 0x2800;
*(uint16 *)(&vram_read_queue[0].src.bank + v0) = 126;
*(uint16 *)((uint8 *)&vram_read_queue[0].size + v0) = 2048;
vram_read_queue_tail = v0 + 9;
}
void Xray_SetupStage3_ReadBg1_1stScreen(void) { // 0x91CB57
uint16 v0 = vram_read_queue_tail;
*(uint16 *)((uint8 *)&vram_read_queue[0].vram_target + v0) = (reg_BG1SC & 0xFC) << 8;
*(uint16 *)((uint8 *)&vram_read_queue[0].dma_parameters + v0) = 129;
*(uint16 *)((uint8 *)&vram_read_queue[0].dma_parameters + v0 + 1) = 57;
*(VoidP *)((uint8 *)&vram_read_queue[0].src.addr + v0) = ADDR16_OF_RAM(ram4000) + 0x2000;
*(uint16 *)(&vram_read_queue[0].src.bank + v0) = 126;
*(uint16 *)((uint8 *)&vram_read_queue[0].size + v0) = 2048;
vram_read_queue_tail = v0 + 9;
}
void Xray_SetupStage4(void) { // 0x91CB8E
uint16 r24 = 4 * ((layer1_y_pos + bg1_y_offset) & 0xF0);
r24 += ((layer1_x_pos + bg1_x_offset) & 0xF0) >> 3;
r24 += 4 * ((layer1_x_pos + bg1_x_offset) & 0x100);
uint16 r22 = 0;
int m = 16;
do {
int n = 16;
uint16 r26 = r24 & 0x7E0;
uint16 r28 = r24 & 0x1F;
uint16 r30 = 0;
do {
if (!sign16(r30 + r28 - 32)) {
r26 = (r26 + 1024) & 0x7E0;
r28 = 0;
r30 = 0;
}
uint16 v0 = r30 + r28 + r26;
uint16 v11 = ram4000.xray_tilemaps[v0 + 4096];
uint16 v10 = ram4000.xray_tilemaps[v0 + 4097];
uint16 v9 = ram4000.xray_tilemaps[v0 + 4128];
uint16 v1 = ram4000.xray_tilemaps[v0 + 4129];
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[33] + r22) = v1;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[32] + r22) = v9;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[1] + r22) = v10;
*(uint16 *)((uint8 *)ram4000.xray_tilemaps + r22) = v11;
r22 += 4;
r30 += 2;
} while (--n);
Xray_SetupStage4_Func1(r22, r26, r28, r30);
r24 = (r24 & 0x400) + ((r24 + 64) & 0x3FF);
r22 += 64;
} while (--m);
assert((uint16)(layer1_y_pos >> 12) == 0);
uint16 r34 = Mult8x8(layer1_y_pos >> 4, room_width_in_blocks) + (layer1_x_pos >> 4);
r22 = 0;
m = 16;
do {
Xray_SetupStage4_Func2(r22, r34);
int n = 16;
uint16 r36 = r34;
do {
Xray_SetupStage4_Func3(n, r22, r36);
r22 += 4;
r36 += 1;
} while (--n);
uint16 v12 = r22;
r22 += 1984;
Xray_SetupStage4_Func3(0, r22, r36);
r22 = v12 + 64;
r34 += room_width_in_blocks;
} while (--m);
LoadXrayBlocks();
uint16 v7 = vram_read_queue_tail;
*(uint16 *)((uint8 *)&vram_read_queue[0].vram_target + v7) = (reg_BG2SC & 0xFC) << 8;
*(uint16 *)((uint8 *)&vram_read_queue[0].dma_parameters + v7) = 129;
*(uint16 *)((uint8 *)&vram_read_queue[0].dma_parameters + v7 + 1) = 57;
*(VoidP *)((uint8 *)&vram_read_queue[0].src.addr + v7) = 0x5000;
*(uint16 *)(&vram_read_queue[0].src.bank + v7) = 126;
*(uint16 *)((uint8 *)&vram_read_queue[0].size + v7) = 2048;
vram_read_queue_tail = v7 + 9;
}
void Xray_SetupStage4_Func1(uint16 dst_r22, uint16 r26, uint16 r28, uint16 r30) { // 0x91CCF1
int16 v0;
uint16 R32 = r26;
v0 = r30 + r28;
if (!sign16(r30 + r28 - 32)) {
R32 = (R32 + 1024) & 0x7E0;
v0 = 0;
}
uint16 v1 = R32 + v0;
uint16 v6 = ram4000.xray_tilemaps[v1 + 4096];
uint16 v5 = ram4000.xray_tilemaps[v1 + 4097];
uint16 v4 = ram4000.xray_tilemaps[v1 + 4128];
uint16 v3 = ram4000.xray_tilemaps[v1 + 4129];
uint16 v2 = dst_r22 + 1984;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[33] + v2) = v3;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[32] + v2) = v4;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[1] + v2) = v5;
*(uint16 *)((uint8 *)ram4000.xray_tilemaps + v2) = v6;
}
static const uint8 *Xray_GetXrayedBlock(uint16 k) { // 0x91CDD6
uint16 value;
uint16 bts = BTS[k];
uint16 r40 = level_data[k] & 0xF000;
for (int i = 0; ; ++i) {
value = stru_91D2D6[i].value;
if (value == 0xFFFF)
break;
if (value == r40) {
for (const uint8 *p = RomPtr_91(stru_91D2D6[i].addr); ; p += 4) {
value = GET_WORD(p);
if (value == 0xFFFF)
break;
if (value == 0xFF00 || value == bts)
return RomPtr_91(GET_WORD(p + 2));
}
return NULL;
}
}
return NULL;
}
void Xray_SetupStage4_Func2(uint16 dst_r22, uint16 r34) { // 0x91CD42
// bug: passing 0xffff to this function is invalid and will read invalid memory.
if (r34 == 0)
return;
const uint8 *jp = Xray_GetXrayedBlock(r34 - 1);
uint16 *dst = (uint16 *)((uint8 *)ram4000.xray_tilemaps + dst_r22);
if (jp == NULL)
return;
if (GET_WORD(jp) != FUNC16(Xray_Func9)) {
if (GET_WORD(jp) != FUNC16(Xray_Func11))
return;
TileTable *src = tile_table.tables + GET_WORD(jp + 8);
dst[64] = src->top_left;
dst[65] = src->top_right;
dst[96] = src->bottom_left;
dst[97] = src->bottom_right;
}
TileTable *src = tile_table.tables + GET_WORD(jp + 4);
dst[0] = src->top_left;
dst[1] = src->top_right;
dst[32] = src->bottom_left;
dst[33] = src->bottom_right;
}
static void Xray_CombinedMove(uint16 dst_r22, uint16 r36, bool which_dir) {
uint16 y = r36 / room_width_in_blocks;
uint16 x = r36 % room_width_in_blocks;
uint16 r48 = level_data[r36] & 0xF000;
int step = (int8)BTS[r36];
if (step) {
uint16 *variable = which_dir ? &y : &x;
for (;;) {
if ((int16)(*variable + step) < 0) {
Xray_Func13(dst_r22, 0xFF);
return;
}
*variable += step;
int pos = y * room_width_in_blocks + x;
step = (int8)BTS[pos];
r48 = level_data[pos] & 0xF000;
if (r48 == 0xd000) {
variable = &y;
continue;
}
if (r48 != 0x5000)
break;
if (step < 0)
variable = &x; // wtf?
}
}
if (stru_91D2D6[1].value == r48) {
uint16 *t = (uint16 *)RomPtr_91(stru_91D2D6[1].addr);
for (; t[0] != 0xffff; t += 2) {
if (t[0] == 0xff00 || t[0] == (step & 0xff)) {
Xray_Func12(dst_r22, RomPtr_91(t[1] + 2));
return;
}
}
}
}
static void Xray_Func7(uint16 dst_r22, const uint8 *jp) { // 0x91CF36
Xray_Func12(dst_r22, jp + 2);
}
static void Xray_Func8(uint16 dst_r22, const uint8 *jp) { // 0x91CF3E
if (area_index == 1)
Xray_Func12(dst_r22, jp + 2);
}
static void Xray_Func9(uint16 r18, uint16 dst_r22, const uint8 *jp) { // 0x91CF4E
Xray_Func12(dst_r22, jp + 2);
if (r18 != 1)
Xray_Func14(dst_r22, jp + 4);
}
static void Xray_Func10(uint16 dst_r22, const uint8 *jp) { // 0x91CF62
Xray_Func12(dst_r22, jp + 2);
Xray_Func15(dst_r22, jp + 2);
}
static void Xray_Func11(uint16 r18, uint16 dst_r22, const uint8 *jp) { // 0x91CF6F
Xray_Func12(dst_r22, jp + 2);
if (r18 != 1)
Xray_Func14(dst_r22, jp + 4);
Xray_Func15(dst_r22, jp + 6);
if (r18 != 1) {
uint16 v5 = GET_WORD(jp + 8);
uint16 top_left = tile_table.tables[v5].top_left;
uint16 top_right = tile_table.tables[v5].top_right;
uint16 bottom_left = tile_table.tables[v5].bottom_left;
uint16 bottom_right = tile_table.tables[v5].bottom_right;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[99] + dst_r22) = bottom_right;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[98] + dst_r22) = bottom_left;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[67] + dst_r22) = top_right;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[66] + dst_r22) = top_left;
}
}
static void CallXrayFunc(uint32 ea, const uint8 *jp, uint16 r18, uint16 r22, uint16 r36) {
switch (ea) {
case fnXray_Func6: Xray_CombinedMove(r22, r36, true); return;
case fnXray_Func6B: Xray_CombinedMove(r22, r36, false); return;
case fnXray_Func7: Xray_Func7(r22, jp); return;
case fnXray_Func8: Xray_Func8(r22, jp); return;
case fnXray_Func9: Xray_Func9(r18, r22, jp); return;
case fnXray_Func10: Xray_Func10(r22, jp); return;
case fnXray_Func11: Xray_Func11(r18, r22, jp); return;
default: Unreachable();
}
}
void Xray_SetupStage4_Func3(uint16 r18, uint16 r22, uint16 r36) { // 0x91CDBE
const uint8 *jp = Xray_GetXrayedBlock(r36);
if (jp != NULL) {
CallXrayFunc(GET_WORD(jp) | 0x910000, jp, r18, r22, r36);
}
}
static void Xray_Func12(uint16 dst_r22, const uint8 *jp) { // 0x91CFBF
Xray_Func13(dst_r22, GET_WORD(jp));
}
static void Xray_Func13(uint16 dst_r22, uint16 a) { // 0x91CFC1
uint16 top_left = tile_table.tables[a].top_left;
uint16 top_right = tile_table.tables[a].top_right;
uint16 bottom_left = tile_table.tables[a].bottom_left;
uint16 bottom_right = tile_table.tables[a].bottom_right;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[33] + dst_r22) = bottom_right;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[32] + dst_r22) = bottom_left;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[1] + dst_r22) = top_right;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[0] + dst_r22) = top_left;
}
static void Xray_Func14(uint16 dst_r22, const uint8 *jp) { // 0x91CFEE
uint16 a = GET_WORD(jp);
uint16 top_left = tile_table.tables[a].top_left;
uint16 top_right = tile_table.tables[a].top_right;
uint16 bottom_left = tile_table.tables[a].bottom_left;
uint16 bottom_right = tile_table.tables[a].bottom_right;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[35] + dst_r22) = bottom_right;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[34] + dst_r22) = bottom_left;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[3] + dst_r22) = top_right;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[2] + dst_r22) = top_left;
}
static void Xray_Func15(uint16 dst_r22, const uint8 *jp) { // 0x91D01D
uint16 a = GET_WORD(jp);
uint16 top_left = tile_table.tables[a].top_left;
uint16 top_right = tile_table.tables[a].top_right;
uint16 bottom_left = tile_table.tables[a].bottom_left;
uint16 bottom_right = tile_table.tables[a].bottom_right;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[97] + dst_r22) = bottom_right;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[96] + dst_r22) = bottom_left;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[65] + dst_r22) = top_right;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[64] + dst_r22) = top_left;
}
static void Xray_Func16(uint16 dst_r22, uint16 a) { // 0x91D0A6
uint16 top_left = tile_table.tables[a].top_left;
uint16 top_right = tile_table.tables[a].top_right;
uint16 bottom_left = tile_table.tables[a].bottom_left;
uint16 bottom_right = tile_table.tables[a].bottom_right;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[1] + dst_r22) = bottom_right;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[0] + dst_r22) = bottom_left;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[33] + dst_r22) = top_right;
*(uint16 *)((uint8 *)&ram4000.xray_tilemaps[32] + dst_r22) = top_left;
}
void LoadBlockToXrayTilemap(uint16 a, uint16 k, uint16 j) { // 0x91D04C
uint16 R24 = k - (layer1_x_pos >> 4);
uint16 R26 = j - (layer1_y_pos >> 4);
if (!sign16(R24) && sign16(R24 - 16) && !sign16(R26) && sign16(R26 - 16)) {
uint16 R22 = 4 * (R24 + 32 * R26);
if ((a & 0x800) != 0)
Xray_Func16(R22, a & 0x3FF);
else
Xray_Func13(R22, a & 0x3FF);
}
}
void Xray_SetupStage5(void) { // 0x91D0D3
unsigned int v1;
if (CanXrayShowBlocks()) {
if (earthquake_timer) {
reg_BG1HOFS = layer1_x_pos + bg1_x_offset;
reg_BG1VOFS = layer1_y_pos + bg1_y_offset;
}
reg_BG2HOFS = reg_BG1HOFS & 0xF;
reg_BG2VOFS = reg_BG1VOFS & 0xF;
reg_BG2SC = 73;
}
uint16 v0 = vram_read_queue_tail;
v1 = vram_read_queue_tail;
*(uint16 *)((uint8 *)&vram_read_queue[0].vram_target + vram_read_queue_tail) = ((reg_BG2SC & 0xFC) << 8) + 1024;
*(uint16 *)((uint8 *)&vram_read_queue[0].dma_parameters + v1 + 1) = 57;
*(VoidP *)((uint8 *)&vram_read_queue[0].src.addr + v0) = 0x5800;
*(uint16 *)(&vram_read_queue[0].src.bank + v0) = 126;
*(uint16 *)((uint8 *)&vram_read_queue[0].size + v0) = 2048;
vram_read_queue_tail = v0 + 9;
}
bool CanXrayShowBlocks(void) { // 0x91D143
if (room_ptr == addr_kRoom_a66a || room_ptr == addr_kRoom_cefb)
return false;
if (fx_type == 0x24)
return false;
if (boss_id == 3 || boss_id == 6 || boss_id == 7 || boss_id == 8 || boss_id == 10)
return false;
return true;
}
void Xray_SetupStage6(void) { // 0x91D173
VramWriteEntry *v1;
if (CanXrayShowBlocks()) {
uint16 v0 = vram_write_queue_tail;
v1 = gVramWriteEntry(vram_write_queue_tail);
v1->size = 2048;
v1->src.addr = ADDR16_OF_RAM(ram4000);
*(uint16 *)&v1->src.bank = 126;
v1->vram_dst = (reg_BG2SC & 0xFC) << 8;
vram_write_queue_tail = v0 + 7;
}
}
void Xray_SetupStage7(void) { // 0x91D1A0
VramWriteEntry *v1;
if (CanXrayShowBlocks()) {
uint16 v0 = vram_write_queue_tail;
v1 = gVramWriteEntry(vram_write_queue_tail);
v1->size = 2048;
v1->src.addr = 0x4800;
*(uint16 *)&v1->src.bank = 126;
v1->vram_dst = ((reg_BG2SC & 0xFC) << 8) + 1024;
vram_write_queue_tail = v0 + 7;
}
mov24(&hdma_ptr_1, 0x9800E4);
mov24(&hdma_ptr_2, 0x98C8E4);
mov24(&hdma_ptr_3, 0x999098);
hdma_var_1 = 0;
demo_input_pre_instr = 0;
demo_input_instr_timer = 0;
demo_input_instr_ptr = 0;
demo_input = 0;
demo_input_new = 0;
if (samus_pose_x_dir == 4)
xray_angle = 192;
else
xray_angle = 64;
}
void HdmaobjPreInstr_XraySetup(uint16 k) { // 0x91D27F
uint16 v1;
v1 = 4096;
if (fx_type == 36) {
if (!sign16((reg_COLDATA[0] & 0x1F) - 7))
goto LABEL_5;
goto LABEL_4;
}
v1 = 0x2000;
if (CanXrayShowBlocks()) {
v1 = 0x4000;
LABEL_4:
*(uint16 *)&reg_COLDATA[0] = 0x27;
*(uint16 *)&reg_COLDATA[1] = 0x47;
*(uint16 *)&reg_COLDATA[2] = 0x87;
}
LABEL_5:
fx_layer_blending_config_c |= v1;
}
void Xray_SetupStage8_SetBackdropColor(void) { // 0x91D2BC
palette_buffer[0] = 3171;
}
void GameState_28_Unused_(void) { // 0x91D4DA
Unreachable();
}
void VariaSuitPickup(void) { // 0x91D4E4
suit_pickup_color_math_R = 48;
suit_pickup_color_math_G = 80;
suit_pickup_color_math_B = 0x80;
suit_pickup_palette_transition_color = 0;
Samus_CancelSpeedBoost();
SetHiLo(&samus_x_extra_run_speed, &samus_x_extra_run_subspeed, 0);
samus_x_base_speed = 0;
samus_x_base_subspeed = 0;
samus_y_subspeed = 0;
samus_y_speed = 0;
samus_y_dir = 0;
used_for_ball_bounce_on_landing = 0;
samus_x_accel_mode = 0;
elevator_status = 0;
substate = 0;
suit_pickup_light_beam_pos = 0;
suit_pickup_light_beam_widening_speed = 256;
for (int i = 510; i >= 0; i -= 2)
hdma_table_1[i >> 1] = 255;
if (samus_movement_type == 3 || samus_movement_type == 20)
QueueSfx1_Max9(0x32);
if ((equipped_items & 0x20) != 0)
samus_pose = kPose_9B_FaceF_VariaGravitySuit;
else
samus_pose = kPose_00_FaceF_Powersuit;
SamusFunc_F433();
Samus_SetAnimationFrameIfPoseChanged();
CallSomeSamusCode(0x15);
samus_x_pos = layer1_x_pos + 120;
samus_prev_x_pos = layer1_x_pos + 120;
samus_y_pos = layer1_y_pos + 136;
samus_prev_y_pos = layer1_y_pos + 136;
QueueSfx2_Max6(0x56);
static const SpawnHdmaObject_Args unk_91D59B = { 0x41, 0x26, 0xd5a2 };
SpawnHdmaObject(0x91, &unk_91D59B);
}
void GravitySuitPickup(void) { // 0x91D5BA
suit_pickup_color_math_R = 48;
suit_pickup_color_math_G = 73;
suit_pickup_color_math_B = -112;
suit_pickup_palette_transition_color = 1;
Samus_CancelSpeedBoost();
SetHiLo(&samus_x_extra_run_speed, &samus_x_extra_run_subspeed, 0);
samus_x_base_speed = 0;
samus_x_base_subspeed = 0;
samus_y_subspeed = 0;
samus_y_speed = 0;
samus_y_dir = 0;
used_for_ball_bounce_on_landing = 0;
samus_x_accel_mode = 0;
elevator_status = 0;
substate = 0;
suit_pickup_light_beam_pos = 0;
suit_pickup_light_beam_widening_speed = 256;
for (int i = 510; i >= 0; i -= 2)
hdma_table_1[i >> 1] = 255;
if (samus_movement_type == kMovementType_03_SpinJumping || samus_movement_type == kMovementType_14_WallJumping)
QueueSfx1_Max9(0x32);
if ((equipped_items & 1) != 0)
samus_pose = kPose_9B_FaceF_VariaGravitySuit;
else
samus_pose = kPose_00_FaceF_Powersuit;
SamusFunc_F433();
Samus_SetAnimationFrameIfPoseChanged();
CallSomeSamusCode(0x15);
samus_x_pos = layer1_x_pos + 120;
samus_prev_x_pos = layer1_x_pos + 120;
samus_y_pos = layer1_y_pos + 136;
samus_prev_y_pos = layer1_y_pos + 136;
QueueSfx2_Max6(0x56);
static const SpawnHdmaObject_Args unk_91D673 = { 0x41, 0x26, 0xd67a };
SpawnHdmaObject(0x91, &unk_91D673);
}
void InitializeSuitPickupHdma(void) { // 0x91D692
reg_TM = 19;
reg_TMW = 19;
reg_TS = 4;
reg_TSW = 4;
next_gameplay_CGWSEL = 16;
reg_W12SEL = 0;
reg_W34SEL = 2;
reg_WOBJSEL = 32;
next_gameplay_CGADSUB = 51;
reg_COLDATA[0] = suit_pickup_color_math_R;
reg_COLDATA[1] = suit_pickup_color_math_G;
reg_COLDATA[2] = suit_pickup_color_math_B;
mov24(&hdma_ptr_1, 0x9800E4);
mov24(&hdma_ptr_2, 0x98C8E4);
mov24(&hdma_ptr_3, 0x999098);
hdma_var_1 = 0;
}
static Func_U8 *const off_91D72D[11] = { // 0x91D6F7
Samus_HandleScrewAttackSpeedBoostingPals,
Samus_SpeedBoosterShinePals,
(Func_U8 *)HandleMiscSamusPalette,
0,
0,
0,
Samus_HandleShinesparkingPals,
Samus_HandleCrystalFlashPals,
Samus_HandleXrayPals,
HandleVisorPalette,
nullsub_164,
};
void Samus_HandlePalette(void) {
if ((samus_special_super_palette_flags & 0x8000) == 0
&& (HandleBeamChargePalettes() & 1
|| !(off_91D72D[timer_for_shine_timer]() & 1))) {
CopyToSamusSuitPalette(off_91D727[samus_suit_palette_index >> 1]);
}
HandleMiscSamusPalette();
}
uint8 HandleBeamChargePalettes(void) { // 0x91D743
if (charged_shot_glow_timer) {
if (hyper_beam_flag) {
if ((charged_shot_glow_timer & 1) == 0) {
if ((charged_shot_glow_timer & 0x1E) == 0) {
charged_shot_glow_timer = 0;
return 1;
}
CopyToSamusSuitPalette(kSamusPalette_HyperBeam[(charged_shot_glow_timer & 0x1E) >> 1]);
}
--charged_shot_glow_timer;
return 0;
}
if (--charged_shot_glow_timer) {
for (int i = 28; i >= 0; i -= 2)
palette_buffer[(i >> 1) + 193] = 1023;
return 0;
} else {
return 1;
}
} else if (grapple_beam_function == FUNC16(GrappleBeamFunc_Inactive)
&& flare_counter
&& !sign16(flare_counter - 60)) {
uint16 R36;
if (samus_contact_damage_index == 4)
R36 = kSamusPalette_PseudoScrew[samus_suit_palette_index >> 1];
else
R36 = kSamusPalette_NonPseudoScrew[samus_suit_palette_index >> 1];
CopyToSamusSuitPalette(*(uint16 *)RomPtr_91(R36 + samus_charge_palette_index));
uint16 v1 = samus_charge_palette_index + 2;
if (!sign16(samus_charge_palette_index - 10))
v1 = 0;
samus_charge_palette_index = v1;
return 0;
} else {
samus_charge_palette_index = 0;
return HandleVisorPalette();
}
}
uint8 HandleVisorPalette(void) { // 0x91D83F
if (timer_for_shine_timer == 8)
return 0;
if (fx_layer_blending_config_a == 40 || fx_layer_blending_config_a == 42) {
uint16 v1 = samus_visor_palette_timer_index - 1;
samus_visor_palette_timer_index = v1;
if ((uint8)v1)
return 0;
samus_visor_palette_timer_index = v1 | 5;
palette_buffer[196] = word_9BA3C0[HIBYTE(v1) >> 1];
int v2 = HIBYTE(v1) + 2;
if (sign16(v2 - 12)) {
samus_visor_palette_timer_index = swap16(v2) | (uint8)samus_visor_palette_timer_index;
} else {
samus_visor_palette_timer_index = (uint8)samus_visor_palette_timer_index | 0x600;
}
return 0;
} else {
samus_visor_palette_timer_index = 1537;
return 0;
}
}
void HandleMiscSamusPalette(void) { // 0x91D8A5
if (!samus_special_super_palette_flags) {
uint16 v0 = samus_hurt_flash_counter;
if (!samus_hurt_flash_counter)
return;
if (samus_hurt_flash_counter == 2) {
if (!cinematic_function
&& (frame_handler_beta != FUNC16(j_HandleDemoRecorder_2_0)
|| samus_pose != kPose_54_FaceL_Knockback)) {
QueueSfx1_Max6(0x35);
goto LABEL_14;
}
v0 = samus_hurt_flash_counter;
}
if (!sign16(v0 - 7))
goto LABEL_17;
if ((v0 & 1) != 0) {
CopyToSamusSuitPalette(addr_word_9BA380);
goto LABEL_17;
}
LABEL_14:
if (cinematic_function)
CopyToSamusSuitPalette(addr_word_9BA3A0);
else
Samus_LoadSuitPalette();
LABEL_17:;
uint16 v1 = samus_hurt_flash_counter + 1;
samus_hurt_flash_counter = v1;
if (v1 == 40) {
if (grapple_beam_function == FUNC16(GrappleBeamFunc_Inactive)) {
if (samus_movement_type == kMovementType_03_SpinJumping || samus_movement_type == kMovementType_14_WallJumping) {
CallSomeSamusCode(0x1C);
} else if (!sign16(flare_counter - 16) && (button_config_shoot_x & joypad1_lastkeys) != 0) {
play_resume_charging_beam_sfx = 1;
}
} else if (sign16(grapple_beam_function + 0x37AA)) {
QueueSfx1_Max9(6);
}
} else if (!sign16(v1 - 60)) {
samus_hurt_flash_counter = 0;
}
return;
}
if ((samus_special_super_palette_flags & 0x8000) != 0) {
CopyToSamusSuitPalette(kSamus_HyperBeamPalettes[samus_charge_palette_index]);
bool v2 = (--special_samus_palette_timer & 0x8000) != 0;
if (!special_samus_palette_timer || v2) {
special_samus_palette_timer = special_samus_palette_frame;
if (!sign16(++samus_charge_palette_index - 10))
samus_charge_palette_index = 0;
}
} else {
if ((samus_special_super_palette_flags & 1) != 0)
CopyToSamusSuitPalette(kSamus_SpeedBoostingPalettes[samus_suit_palette_index >> 1]);
else
Samus_LoadSuitPalette();
++samus_special_super_palette_flags;
}
}
uint8 Samus_HandleScrewAttackSpeedBoostingPals(void) { // 0x91D9B2
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))
return 1;
} else if (sign16(fx_y_pos - r20) && (fx_liquid_options & 4) == 0) {
return 1;
}
}
if (samus_movement_type == kMovementType_03_SpinJumping) {
if ((equipped_items & 8) == 0)
goto LABEL_10;
if (samus_anim_frame) {
if (!sign16(samus_anim_frame - 27))
return 0;
goto LABEL_18;
}
goto LABEL_21;
}
if (samus_movement_type == kMovementType_14_WallJumping) {
if ((equipped_items & 8) == 0)
return 1;
if (!sign16(samus_anim_frame - 3)) {
LABEL_18:;
uint16 R36 = kSamusPal_ScrewAttack[samus_suit_palette_index >> 1];
uint16 v1 = *(uint16 *)RomPtr_91(R36 + special_samus_palette_frame);
CopyToSamusSuitPalette(v1);
uint16 v2 = special_samus_palette_frame + 2;
if (special_samus_palette_frame >= 10)
v2 = 0;
special_samus_palette_frame = v2;
return 1;
}
LABEL_21:
special_samus_palette_frame = 0;
return 1;
}
LABEL_10:
if ((speed_boost_counter & 0xFF00) != 1024)
return 1;
bool v3 = (--special_samus_palette_timer & 0x8000) != 0;
if (!special_samus_palette_timer || v3) {
special_samus_palette_timer = 4;
uint16 R36 = kSamusPal_SpeedBoost[samus_suit_palette_index >> 1];
// Bugfix: The original game can do an out of bounds read here.
if (special_samus_palette_frame > 6)
special_samus_palette_frame = 6;
uint16 v4 = *(uint16 *)RomPtr_91(R36 + special_samus_palette_frame);
CopyToSamusSuitPalette(v4);
uint16 v5 = special_samus_palette_frame + 2;
if (special_samus_palette_frame >= 6)
v5 = 6;
special_samus_palette_frame = v5;
}
return 1;
}
uint8 Samus_SpeedBoosterShinePals(void) { // 0x91DAC7
uint16 v0 = samus_shine_timer;
if (samus_shine_timer == 170) {
uint16 v4 = samus_shine_timer;
QueueSfx3_Max9(0xC);
v0 = v4;
}
samus_shine_timer = v0 - 1;
if ((int16)(v0 - 1) <= 0) {
special_samus_palette_frame = 0;
timer_for_shine_timer = 0;
return 0;
} else {
uint16 R36 = kSamusPal_SpeedBoostShine[samus_suit_palette_index >> 1];
uint16 v1 = *(uint16 *)RomPtr_91(R36 + special_samus_palette_frame);
CopyToSamusSuitPalette(v1);
uint16 v2 = special_samus_palette_frame + 2;
if (!sign16(special_samus_palette_frame - 10))
v2 = 0;
special_samus_palette_frame = v2;
return 1;
}
}
uint8 Samus_HandleShinesparkingPals(void) { // 0x91DB3A
bool v0 = (--samus_shine_timer & 0x8000) != 0;
if (!samus_shine_timer || v0) {
timer_for_shine_timer = 0;
special_samus_palette_frame = 0;
return 0;
} else {
uint16 R36 = kSamusPal_Shinespark[samus_suit_palette_index >> 1];
uint16 v1 = *(uint16 *)RomPtr_91(R36 + special_samus_palette_frame);
CopyToSamusSuitPalette(v1);
uint16 v2 = special_samus_palette_frame + 2;
if (!sign16(special_samus_palette_frame - 6))
v2 = 0;
special_samus_palette_frame = v2;
return 1;
}
}
uint8 Samus_HandleCrystalFlashPals(void) { // 0x91DB93
if ((samus_shine_timer & 0x8000) != 0) {
WriteBeamPalette_A(equipped_beams);
timer_for_shine_timer = 0;
special_samus_palette_frame = 0;
special_samus_palette_timer = 0;
samus_shine_timer = 0;
return 0;
} else {
if ((int16)--samus_shine_timer <= 0) {
samus_shine_timer = 5;
Samus_Copy6PalColors(off_91DC28[special_samus_palette_frame >> 1]);
uint16 v0 = special_samus_palette_frame + 2;
if (!sign16(special_samus_palette_frame - 10))
v0 = 0;
special_samus_palette_frame = v0;
}
bool v1 = (int16)-- * (uint16 *)&suit_pickup_color_math_B < 0;
if (!*(uint16 *)&suit_pickup_color_math_B || v1) {
*(uint16 *)&suit_pickup_color_math_B = *(uint16 *)((uint8 *)&stru_91DC00[0].timer + special_samus_palette_timer);
Samus_Copy10PalColors(*(VoidP *)((uint8 *)&stru_91DC00[0].ptr + special_samus_palette_timer));
uint16 v2 = special_samus_palette_timer + 4;
if (!sign16(special_samus_palette_timer - 36))
v2 = 0;
special_samus_palette_timer = v2;
}
return 1;
}
}
void Samus_Copy10PalColors(uint16 v0) { // 0x91DC34
memcpy(&palette_buffer[224], RomPtr_9B(v0), 20);
}
void Samus_Copy6PalColors(uint16 j) { // 0x91DC82
memcpy(&palette_buffer[234], RomPtr_9B(j), 12);
}
uint8 Samus_HandleXrayPals(void) { // 0x91DCB4
if ((demo_timer_counter & 0x8000) != 0) {
timer_for_shine_timer = 0;
special_samus_palette_frame = 0;
special_samus_palette_timer = 0;
demo_timer_counter = 0;
return 0;
} else {
if (!demo_timer_counter) {
if (sign16(demo_input_pre_instr - 2)) {
bool v0 = (--special_samus_palette_timer & 0x8000) != 0;
if (!special_samus_palette_timer || v0) {
special_samus_palette_timer = 5;
palette_buffer[196] = word_9BA3C0[special_samus_palette_frame >> 1];
if (sign16(special_samus_palette_frame - 4))
special_samus_palette_frame += 2;
}
return 1;
}
special_samus_palette_frame = 6;
special_samus_palette_timer = 1;
demo_timer_counter = 1;
}
bool v2 = (--special_samus_palette_timer & 0x8000) != 0;
if (special_samus_palette_timer && !v2)
return 1;
special_samus_palette_timer = 5;
palette_buffer[196] = word_9BA3C0[special_samus_palette_frame >> 1];
uint16 v3 = special_samus_palette_frame + 2;
if (!sign16(special_samus_palette_frame - 10))
v3 = 6;
special_samus_palette_frame = v3;
return 1;
}
}
uint8 nullsub_164(void) { // 0x91DD31
return 0;
}
void CopyToSamusSuitPalette(uint16 k) { // 0x91DD5B
memcpy(&palette_buffer[192], (uint16 *)RomPtr_9B(k), 32);
}
void CopyToSamusSuitTargetPalette(uint16 k) { // 0x91DDD7
memcpy(&target_palettes[192], (uint16 *)RomPtr_9B(k), 32);
}
void Samus_CancelSpeedBoost(void) { // 0x91DE53
if (samus_has_momentum_flag) {
samus_has_momentum_flag = 0;
speed_boost_counter = 0;
special_samus_palette_frame = 0;
special_samus_palette_timer = 0;
if ((equipped_items & 0x20) != 0) {
CopyToSamusSuitPalette(addr_kSamusPalette_GravitySuit);
} else if ((equipped_items & 1) != 0) {
CopyToSamusSuitPalette(addr_kSamusPalette_VariaSuit);
} else {
CopyToSamusSuitPalette(addr_kSamusPalette_PowerSuit);
}
}
if ((speed_echoes_index & 0x8000) == 0) {
speed_echoes_index = -1;
if (samus_pose_x_dir == 4) {
speed_echo_xspeed[0] = -8;
speed_echo_xspeed[1] = -8;
} else {
speed_echo_xspeed[0] = 8;
speed_echo_xspeed[1] = 8;
}
}
}
void Samus_LoadSuitPalette(void) { // 0x91DEBA
if ((equipped_items & 0x20) != 0) {
CopyToSamusSuitPalette(addr_kSamusPalette_GravitySuit);
} else if ((equipped_items & 1) != 0) {
CopyToSamusSuitPalette(addr_kSamusPalette_VariaSuit);
} else {
CopyToSamusSuitPalette(addr_kSamusPalette_PowerSuit);
}
}
void Samus_LoadSuitTargetPalette(void) { // 0x91DEE6
if ((equipped_items & 0x20) != 0) {
CopyToSamusSuitTargetPalette(addr_kSamusPalette_GravitySuit);
} else if ((equipped_items & 1) != 0) {
CopyToSamusSuitTargetPalette(addr_kSamusPalette_VariaSuit);
} else {
CopyToSamusSuitTargetPalette(addr_kSamusPalette_PowerSuit);
}
}
void Samus_RestoreHealth(uint16 a) { // 0x91DF12
uint16 v1 = a + samus_health;
samus_health = v1;
if ((int16)(v1 - samus_max_health) >= 0) {
uint16 v2 = samus_reserve_health + v1 - samus_max_health;
if ((int16)(v2 - samus_max_reserve_health) >= 0)
v2 = samus_max_reserve_health;
samus_reserve_health = v2;
if (v2) {
if (!reserve_health_mode)
reserve_health_mode = 1;
}
samus_health = samus_max_health;
}
}
void Samus_DealDamage(uint16 a) { // 0x91DF51
if ((a & 0x8000) == 0) {
if (a != 300 && !time_is_frozen_flag) {
samus_health -= a;
if ((samus_health & 0x8000) != 0)
samus_health = 0;
}
} else {
InvalidInterrupt_Crash();
}
}
void Samus_RestoreMissiles(uint16 a) { // 0x91DF80
uint16 v1 = samus_missiles + a;
samus_missiles = v1;
if ((int16)(v1 - samus_max_missiles) >= 0) {
if (sign16(samus_max_missiles - 99)) {
samus_reserve_missiles += v1 - samus_max_missiles;
if ((int16)(samus_reserve_missiles - samus_max_missiles) >= 0)
samus_reserve_missiles = samus_max_missiles;
} else {
samus_reserve_missiles += v1 - samus_max_missiles;
if (!sign16(samus_reserve_missiles - 99))
samus_reserve_missiles = 99;
}
samus_missiles = samus_max_missiles;
}
}
void Samus_RestoreSuperMissiles(uint16 a) { // 0x91DFD3
uint16 v1 = samus_super_missiles + a;
samus_super_missiles = v1;
if ((int16)(v1 - samus_max_super_missiles) >= 0 && v1 != samus_max_super_missiles)
samus_super_missiles = samus_max_super_missiles;
}
void Samus_RestorePowerBombs(uint16 a) { // 0x91DFF0
uint16 v1 = samus_power_bombs + a;
samus_power_bombs = v1;
if ((int16)(v1 - samus_max_power_bombs) >= 0 && v1 != samus_max_power_bombs)
samus_power_bombs = samus_max_power_bombs;
}
void Samus_Initialize(void) { // 0x91E00D
static const uint16 word_909EAF = 0;
static const uint16 word_909EAD = 1;
static const uint16 word_909EB3 = 0;
static const uint16 word_909EB1 = 1;
static const uint16 word_909EA1 = 0x1c00;
static const uint16 word_909EA7 = 0;
uint16 r18 = debug_invincibility;
uint16 v0 = 0xE0B;
do
*RomPtr_RAM(v0--) = 0;
while ((int16)(v0 - 0xA02) >= 0);
if (game_state != kGameState_40_TransitionToDemo) {
frame_handler_alfa = FUNC16(EmptyFunction);
if (loading_game_state == kGameState_34_CeresGoesBoom) {
frame_handler_beta = FUNC16(SetContactDamageIndexAndUpdateMinimap);
samus_draw_handler = FUNC16(SamusDrawHandler_Default);
samus_momentum_routine_index = -1;
samus_special_transgfx_index = 0;
samus_hurt_switch_index = 0;
Samus_LoadSuitPalette();
samus_input_handler = FUNC16(Samus_InputHandler_E913);
} else {
frame_handler_beta = FUNC16(Samus_Func16);
samus_draw_handler = FUNC16(SamusDrawHandler_Default);
samus_momentum_routine_index = 0;
samus_special_transgfx_index = 0;
samus_hurt_switch_index = 0;
samus_input_handler = FUNC16(Samus_InputHandler_E913);
debug_invincibility = r18;
}
}
samus_new_pose = -1;
samus_new_pose_interrupted = -1;
samus_new_pose_transitional = -1;
if (area_index == 6)
frame_handler_gamma = FUNC16(Samus_Func3);
else
frame_handler_gamma = FUNC16(nullsub_152);
samus_movement_handler = FUNC16(Samus_MovementHandler_Normal);
UNUSED_word_7E0A5E = -2764;
samus_prev_health_for_flash = 50;
samus_visor_palette_timer_index = 1537;
uint16 v1 = 0;
do {
projectile_bomb_pre_instructions[v1 >> 1] = FUNC16(ProjPreInstr_Empty);
v1 += 2;
} while ((int16)(v1 - 20) < 0);
grapple_beam_function = FUNC16(GrappleBeamFunc_Inactive);
enable_horiz_slope_coll = 3;
samus_hurt_flash_counter = 0;
samus_special_super_palette_flags = 0;
absolute_moved_last_frame_x_fract = word_909EAF;
absolute_moved_last_frame_x = word_909EAD;
absolute_moved_last_frame_y_fract = word_909EB3;
absolute_moved_last_frame_y = word_909EB1;
for (int i = 510; i >= 0; i -= 2)
hdma_table_1[i >> 1] = 255;
samus_y_subaccel = word_909EA1;
samus_y_accel = word_909EA7;
fx_y_pos = -1;
lava_acid_y_pos = -1;
UpdateBeamTilesAndPalette();
cinematic_function = 0;
samus_pose = kPose_00_FaceF_Powersuit;
*(uint16 *)&samus_pose_x_dir = 0;
samus_prev_pose = 0;
*(uint16 *)&samus_prev_pose_x_dir = 0;
samus_last_different_pose = 0;
*(uint16 *)&samus_last_different_pose_x_dir = 0;
enemy_index_to_shake = -1;
hud_item_index = 0;
samus_auto_cancel_hud_item_index = 0;
samus_invincibility_timer = 0;
samus_knockback_timer = 0;
samus_hurt_flash_counter = 0;
debug_invincibility = 0;
if (game_state == kGameState_40_TransitionToDemo)
LoadDemoData();
samus_prev_health_for_flash = samus_health;
}
uint8 Xray_Initialize(void) { // 0x91E16D
static const uint8 byte_91E291[28] = {
1, 1, 0, 0, 0, 2, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 0, 0,
0, 0, 0, 0,
};
if (cooldown_timer == 7 && bomb_counter == 5 && samus_x_speed_divisor == 2
|| !sign16(samus_pose - kPose_A4_FaceR_LandJump)
&& (sign16(samus_pose - kPose_A8_FaceR_Grappling)
|| !sign16(samus_pose - kPose_E0_FaceR_LandJump_AimU) && sign16(samus_pose - kPose_E8_FaceR_Drained_CrouchFalling))
|| game_state != 8
|| power_bomb_explosion_status
|| samus_y_speed
|| samus_y_subspeed
|| !byte_91E291[samus_prev_movement_type]) {
return 0;
}
if (byte_91E291[samus_movement_type] == 1) {
if (samus_pose_x_dir == 4)
samus_new_pose_interrupted = kPose_D6_FaceL_Xray_Stand;
else
samus_new_pose_interrupted = kPose_D5_FaceR_Xray_Stand;
} else {
if (byte_91E291[samus_movement_type] != 2)
return 0;
if (samus_pose_x_dir == 4)
samus_new_pose_interrupted = kPose_DA_FaceL_Xray_Crouch;
else
samus_new_pose_interrupted = kPose_D9_FaceR_Xray_Crouch;
}
time_is_frozen_flag = 1;
samus_special_transgfx_index = 5;
for (int i = 510; i >= 0; i -= 2)
hdma_table_1[i >> 1] = 255;
DisableEprojs();
DisablePLMs();
DisableAnimtiles();
DisablePaletteFx();
mov24(&hdma_ptr_1, 0x980001);
*(uint16 *)((uint8 *)&demo_num_input_frames + 1) = 0;
demo_input_prev = -26424;
mov24(&hdma_ptr_3, 0x999098);
hdma_var_1 = 0;
demo_input_pre_instr = 0;
demo_input_instr_timer = 0;
demo_input_instr_ptr = 0;
demo_input = 0;
demo_input_new = 0;
if (samus_pose_x_dir == 4)
xray_angle = 192;
else
xray_angle = 64;
return 1;
}
void ResponsibleForXrayStandupGlitch(void) { // 0x91E2AD
if (samus_movement_type == kMovementType_05_Crouching) {
if (samus_pose_x_dir == 4)
samus_pose = kPose_28_FaceL_Crouch;
else
samus_pose = kPose_27_FaceR_Crouch;
} else if (samus_pose_x_dir == kPose_04_FaceL_AimU) {
samus_pose = kPose_02_FaceL_Normal;
} else {
samus_pose = kPose_01_FaceR_Normal;
}
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_movement_handler = FUNC16(Samus_MovementHandler_Normal);
samus_input_handler = FUNC16(Samus_InputHandler_E913);
demo_timer_counter = -1;
uint16 r18 = kPoseParams[samus_pose].y_radius - samus_y_radius;
if ((r18 & 0x8000) == 0) {
samus_y_pos -= r18;
samus_prev_y_pos = samus_y_pos;
}
EnableEprojs();
EnablePLMs();
EnableAnimtiles();
EnablePaletteFx();
}
void MakeSamusFaceForward(void) { // 0x91E3F6
if ((equipped_items & 0x20) != 0 || (equipped_items & 1) != 0)
samus_pose = kPose_9B_FaceF_VariaGravitySuit;
else
samus_pose = kPose_00_FaceF_Powersuit;
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;
if (samus_y_radius != 24) {
samus_y_pos -= 3;
samus_prev_y_pos = samus_y_pos;
}
frame_handler_alfa = FUNC16(Samus_FrameHandlerAlfa_Func13);
frame_handler_beta = FUNC16(SetContactDamageIndexAndUpdateMinimap);
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;
CallSomeSamusCode(0x1F);
SetHiLo(&samus_x_extra_run_speed, &samus_x_extra_run_subspeed, 0);
samus_x_base_speed = 0;
samus_x_base_subspeed = 0;
samus_y_subspeed = 0;
samus_y_speed = 0;
samus_y_dir = 0;
used_for_ball_bounce_on_landing = 0;
samus_x_accel_mode = 0;
flare_counter = 0;
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;
Samus_LoadSuitPalette();
}
static Func_U8 *const kSomeMotherBrainScripts[5] = { // 0x91E4AD
SomeMotherBrainScripts_0,
SomeMotherBrainScripts_1,
SomeMotherBrainScripts_2,
SomeMotherBrainScripts_3_EnableHyperBeam,
SomeMotherBrainScripts_4,
};
void SomeMotherBrainScripts(uint16 a) {
if (kSomeMotherBrainScripts[a]() & 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_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;
}
}
uint8 SomeMotherBrainScripts_0(void) { // 0x91E4F8
samus_y_pos -= 21 - samus_y_radius;
samus_prev_y_pos = samus_y_pos;
if (samus_pose_x_dir == 4)
samus_pose = kPose_E9_FaceL_Drained_CrouchFalling;
else
samus_pose = kPose_E8_FaceR_Drained_CrouchFalling;
samus_anim_frame_skip = 2;
SamusFunc_F433();
Samus_SetAnimationFrameIfPoseChanged();
samus_y_radius = kPoseParams[samus_pose].y_radius;
samus_x_base_speed = 0;
samus_x_base_subspeed = 0;
samus_y_subspeed = 0;
samus_y_speed = 0;
samus_y_dir = 2;
flare_counter = 0;
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;
Samus_LoadSuitPalette();
return 1;
}
uint8 SomeMotherBrainScripts_1(void) { // 0x91E571
samus_anim_frame_timer = 16;
samus_anim_frame = 0;
if (samus_pose_x_dir == 4)
samus_pose = kPose_EB_FaceL_Drained_Stand;
else
samus_pose = kPose_EA_FaceR_Drained_Stand;
frame_handler_gamma = FUNC16(nullsub_152);
return 1;
}
uint8 SomeMotherBrainScripts_2(void) { // 0x91E59B
if (samus_pose == kPose_E8_FaceR_Drained_CrouchFalling || samus_pose == kPose_E9_FaceL_Drained_CrouchFalling) {
samus_anim_frame_timer = 1;
samus_anim_frame = 13;
} else if (samus_pose == kPose_EA_FaceR_Drained_Stand || samus_pose == kPose_EB_FaceL_Drained_Stand) {
samus_anim_frame_timer = 1;
samus_anim_frame = 4;
}
samus_y_radius = kPoseParams[samus_pose].y_radius;
samus_x_base_speed = 0;
samus_x_base_subspeed = 0;
samus_y_subspeed = 0;
samus_y_speed = 0;
samus_y_dir = 2;
return 1;
}
uint8 SomeMotherBrainScripts_3_EnableHyperBeam(void) { // 0x91E5F0
equipped_beams = 4105;
UpdateBeamTilesAndPalette();
SpawnPalfxObject(addr_stru_8DE1F0);
hyper_beam_flag = FUNC16(Samus_InputHandler);
play_resume_charging_beam_sfx = 0;
return 0;
}
uint8 SomeMotherBrainScripts_4(void) { // 0x91E60C
samus_anim_frame_timer = 16;
samus_anim_frame = 8;
if (samus_pose_x_dir == 4)
samus_pose = kPose_E9_FaceL_Drained_CrouchFalling;
else
samus_pose = kPose_E8_FaceR_Drained_CrouchFalling;
return 1;
}
void nullsub_17(void) {}
static Func_V *const off_91E6E1[28] = { // 0x91E633
SamusFunc_E633_0,
nullsub_17,
nullsub_17,
SamusFunc_E633_3,
SamusFunc_E633_4,
nullsub_17,
nullsub_17,
nullsub_17,
SamusFunc_E633_4,
nullsub_17,
nullsub_17,
nullsub_17,
nullsub_17,
nullsub_17,
nullsub_17,
nullsub_17,
nullsub_17,
SamusFunc_E633_17,
SamusFunc_E633_17,
SamusFunc_E633_17,
SamusFunc_E633_20,
nullsub_17,
nullsub_17,
nullsub_17,
nullsub_17,
nullsub_17,
nullsub_17,
nullsub_17,
};
void SamusFunc_E633(void) {
off_91E6E1[samus_movement_type]();
if ((equipped_items & 0x2000) != 0) {
if (samus_has_momentum_flag && !speed_boost_counter) {
special_samus_palette_timer = speed_boost_counter;
special_samus_palette_frame = 0;
speed_boost_counter = kSpeedBoostToCtr[0];
}
} else {
speed_echoes_index = 0;
speed_echo_xspeed[0] = 0;
speed_echo_xspeed[1] = 0;
samus_has_momentum_flag = 0;
speed_boost_counter = 0;
special_samus_palette_frame = 0;
special_samus_palette_timer = 0;
speed_echo_xpos[0] = 0;
speed_echo_xpos[1] = 0;
speed_echo_ypos[0] = 0;
speed_echo_ypos[1] = 0;
}
if (grapple_beam_function == FUNC16(GrappleBeamFunc_Inactive)) {
if ((equipped_beams & 0x1000) != 0) {
if (!sign16(flare_counter - 16))
QueueSfx1_Max6(0x41);
} else {
flare_counter = 0;
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;
}
} else {
LoadProjectilePalette(2);
QueueSfx1_Max6(6);
}
Samus_LoadSuitPalette();
if (sign16(samus_health - 31))
QueueSfx3_Max6(2);
}
void Samus_UpdatePreviousPose_0(void) { // 0x91E719
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;
}
void SamusFunc_E633_0(void) { // 0x91E733
if (samus_pose) {
if (samus_pose == kPose_9B_FaceF_VariaGravitySuit && (equipped_items & 1) == 0 && (equipped_items & 0x20) == 0) {
samus_pose = kPose_00_FaceF_Powersuit;
goto LABEL_10;
}
} else if ((equipped_items & 1) != 0 || (equipped_items & 0x20) != 0) {
samus_pose = kPose_9B_FaceF_VariaGravitySuit;
LABEL_10:
SamusFunc_F433();
Samus_SetAnimationFrameIfPoseChanged();
Samus_UpdatePreviousPose_0();
}
}
void SamusFunc_E633_3(void) { // 0x91E776
if (samus_pose_x_dir == 4)
*(uint16 *)&samus_prev_pose_x_dir = 260;
else
*(uint16 *)&samus_prev_pose_x_dir = 264;
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_18;
if ((equipped_items & 8) != 0) {
if (samus_pose_x_dir == 4)
samus_pose = kPose_82_FaceL_Screwattack;
else
samus_pose = kPose_81_FaceR_Screwattack;
goto LABEL_18;
}
goto LABEL_15;
}
if ((equipped_items & 8) == 0) {
LABEL_15:
if (samus_pose_x_dir == 4)
samus_pose = kPose_1A_FaceL_SpinJump;
else
samus_pose = kPose_19_FaceR_SpinJump;
}
LABEL_18:
SamusFunc_F433();
Samus_SetAnimationFrameIfPoseChanged();
if (samus_pose_x_dir == 4)
*(uint16 *)&samus_prev_pose_x_dir = 772;
else
*(uint16 *)&samus_prev_pose_x_dir = 776;
Samus_UpdatePreviousPose_0();
}
void SamusFunc_E633_4(void) { // 0x91E83A
if ((equipped_items & 2) != 0) {
if (samus_pose_x_dir == 4)
samus_pose = kPose_7A_FaceL_Springball_Ground;
else
samus_pose = kPose_79_FaceR_Springball_Ground;
SamusFunc_F433();
Samus_SetAnimationFrameIfPoseChanged();
Samus_UpdatePreviousPose_0();
}
}
void SamusFunc_E633_17(void) { // 0x91E867
if ((equipped_items & 2) == 0) {
if (samus_pose_x_dir == 4)
samus_pose = kPose_41_FaceL_Morphball_Ground;
else
samus_pose = kPose_1D_FaceR_Morphball_Ground;
SamusFunc_F433();
Samus_SetAnimationFrameIfPoseChanged();
Samus_UpdatePreviousPose_0();
}
}
void SamusFunc_E633_20(void) { // 0x91E894
if ((equipped_items & 8) != 0)
samus_anim_frame = 23;
else
samus_anim_frame = 3;
}
void nullsub_18(void) {
}
static Func_V *const kSamus_HandleTransFromBlockColl[6] = { // 0x91E8B6
nullsub_18,
Samus_HandleTransFromBlockColl_1,
Samus_HandleTransFromBlockColl_2,
Samus_HandleTransFromBlockColl_3,
Samus_HandleTransFromBlockColl_4,
Samus_HandleTransFromBlockColl_5,
};
void Samus_HandleTransFromBlockColl(void) {
if (input_to_pose_calc)
kSamus_HandleTransFromBlockColl[(uint8)input_to_pose_calc]();
}
void Samus_HandleTransFromBlockColl_3(void) { // 0x91E8D8
samus_new_pose = samus_pose;
samus_momentum_routine_index = 5;
}
void Samus_HandleTransFromBlockColl_4(void) { // 0x91E8E5
samus_new_pose = samus_pose;
samus_momentum_routine_index = 5;
}
uint8 nullsub_18_U8(void) {
return 0;
}
static Func_U8 *const off_91E951[6] = { // 0x91E8F2
Samus_HandleTransFromBlockColl_1_0,
Samus_HandleTransFromBlockColl_1_1,
Samus_HandleTransFromBlockColl_1_2,
Samus_HandleTransFromBlockColl_1_3,
nullsub_18_U8,
Samus_HandleTransFromBlockColl_1_5,
};
void Samus_HandleTransFromBlockColl_2(void) {
if (HIBYTE(input_to_pose_calc) != 4) {
uint16 v0 = 4 * HIBYTE(input_to_pose_calc);
if (samus_pose_x_dir == 4)
samus_new_pose = word_91E921[(v0 >> 1) + 1];
else
samus_new_pose = word_91E921[v0 >> 1];
samus_momentum_routine_index = 5;
}
}
void Samus_HandleTransFromBlockColl_1(void) { // 0x91E931
if (HIBYTE(input_to_pose_calc) != 4) {
if (off_91E951[HIBYTE(input_to_pose_calc)]() & 1)
samus_momentum_routine_index = 0;
else
samus_momentum_routine_index = 5;
}
}
uint8 Samus_HandleTransFromBlockColl_1_0(void) { // 0x91E95D
int16 v0;
if (samus_prev_movement_type2 == kMovementType_03_SpinJumping
|| samus_prev_movement_type2 == kMovementType_14_WallJumping) {
if (samus_pose_x_dir == 4)
samus_new_pose = kPose_A7_FaceL_LandSpinJump;
else
samus_new_pose = kPose_A6_FaceR_LandSpinJump;
return 0;
} else {
v0 = kPoseParams[samus_pose].direction_shots_fired;
if (v0 == 255) {
if (samus_pose_x_dir == 4)
samus_new_pose = kPose_A5_FaceL_LandJump;
else
samus_new_pose = kPose_A4_FaceR_LandJump;
return 0;
} else {
if (v0 != 2 && v0 != 7)
goto LABEL_6;
if ((button_config_shoot_x & joypad1_lastkeys) == 0) {
v0 = kPoseParams[samus_pose].direction_shots_fired;
LABEL_6:
samus_new_pose = word_91E9F3[v0];
return 0;
}
if (samus_pose_x_dir == 4)
samus_new_pose = kPose_E7_FaceL_LandJump_Fire;
else
samus_new_pose = kPose_E6_FaceR_LandJump_Fire;
return 0;
}
}
}
uint8 Samus_HandleTransFromBlockColl_1_1(void) { // 0x91EA07
int16 v0;
v0 = 2 * used_for_ball_bounce_on_landing;
if (2 * used_for_ball_bounce_on_landing) {
if (v0 == 2) {
samus_new_pose = samus_pose;
return 0;
}
if (v0 != 4)
Unreachable();
} else if (!sign16(samus_y_speed - 3)) {
samus_new_pose = samus_pose;
return 0;
}
if (samus_pose_x_dir == 4)
samus_new_pose = kPose_41_FaceL_Morphball_Ground;
else
samus_new_pose = kPose_1D_FaceR_Morphball_Ground;
return 0;
}
uint8 Samus_HandleTransFromBlockColl_1_2(void) { // 0x91EA48
if (samus_pose_x_dir == 4)
samus_new_pose = 66;
else
samus_new_pose = 32;
return 0;
}
uint8 Samus_HandleTransFromBlockColl_1_3(void) { // 0x91EA63
int16 v1;
if ((button_config_jump_a & joypad1_lastkeys) != 0) {
samus_new_pose = samus_pose;
return 0;
}
v1 = 2 * (uint8)used_for_ball_bounce_on_landing;
if (v1) {
if (v1 == 2) {
samus_new_pose = samus_pose;
return 0;
}
if (v1 != 4)
Unreachable();
} else if (!sign16(samus_y_speed - 3)) {
samus_new_pose = samus_pose;
return 0;
}
if (samus_pose_x_dir == 4)
samus_new_pose = kPose_7A_FaceL_Springball_Ground;
else
samus_new_pose = 121;
return 0;
}
uint8 Samus_HandleTransFromBlockColl_1_5(void) { // 0x91EAB6
samus_new_pose = samus_pose;
return 0;
}
void Samus_HandleTransFromBlockColl_5(void) { // 0x91EABE
if (samus_pose_x_dir == 4)
samus_new_pose = kPose_84_FaceL_Walljump;
else
samus_new_pose = kPose_83_FaceR_Walljump;
samus_momentum_routine_index = 5;
}
void Samus_CheckWalkedIntoSomething(void) { // 0x91EADE
int32 amt;
if (samus_collides_with_solid_enemy && samus_movement_type == 1) {
samus_new_pose = word_91EB74[*(&kPoseParams[0].direction_shots_fired + (8 * samus_pose))];
samus_collides_with_solid_enemy = 0;
return;
}
if (samus_new_pose == 0xFFFF || kPoseParams[samus_new_pose].movement_type != 1) {
samus_collides_with_solid_enemy = 0;
return;
}
if (samus_pose_x_dir != 4) {
samus_collision_direction = 1;
amt = INT16_SHL16(1);
CheckEnemyColl_Result cres = Samus_CheckSolidEnemyColl(amt);
if (!cres.collision) {
samus_collision_direction = 1;
amt = INT16_SHL16(1);
goto LABEL_10;
}
LABEL_11:
samus_new_pose = word_91EB74[*(&kPoseParams[0].direction_shots_fired + (8 * samus_new_pose))];
samus_collides_with_solid_enemy = 0;
return;
}
samus_collision_direction = 0;
amt = INT16_SHL16(1);
CheckEnemyColl_Result cres = Samus_CheckSolidEnemyColl(amt);
if (cres.collision)
goto LABEL_11;
amt = INT16_SHL16(-1);
samus_collision_direction = 0;
LABEL_10:
Samus_MoveRight_NoSolidColl(amt);
if (samus_collision_flag)
goto LABEL_11;
samus_collides_with_solid_enemy = 0;
}
void nullsub_19(void) {}
void nullsub_20(void) {}
void nullsub_21(void) {}
void nullsub_22(void) {}
static Func_V *const kSamus_HandleTransitionsA[9] = { // 0x91EB88
nullsub_18,
Samus_HandleTransitionsA_1,
Samus_HandleTransitionsA_2,
nullsub_21,
nullsub_22,
Samus_HandleTransitionsA_5,
Samus_HandleTransitionsA_6,
Samus_HandleTransitionsA_7,
Samus_HandleTransitionsA_8,
};
static Func_V *const kSamus_HandleTransitionsB[11] = {
nullsub_18,
Samus_HandleTransitionsB_1,
Samus_HandleTransitionsB_2,
Samus_HandleTransitionsB_3,
Samus_HandleTransitionsB_4,
Samus_HandleTransitionsB_5,
nullsub_19,
nullsub_20,
Samus_HandleTransitionsB_8,
Samus_HandleTransitionsB_9,
Samus_HandleTransitionsB_10,
};
static Func_V *const kSamus_HandleTransitionsC[9] = {
nullsub_18,
Samus_HandleTransitionsC_1,
Samus_HandleTransitionsC_2,
Samus_HandleTransitionsC_3,
Samus_HandleTransitionsC_4,
Samus_HandleTransitionsC_5,
Samus_HandleTransitionsC_6,
Samus_HandleTransitionsC_7,
Samus_HandleTransitionsC_8,
};
void Samus_HandleTransitions(void) {
if ((samus_new_pose_transitional & 0x8000) == 0) {
if (samus_hurt_switch_index != 3) {
if (samus_hurt_switch_index == 1)
goto LABEL_7;
goto LABEL_6;
}
if (samus_special_transgfx_index != 9) {
LABEL_6:
samus_pose = samus_new_pose_transitional;
SamusFunc_F433();
Samus_SetAnimationFrameIfPoseChanged();
LABEL_7:
kSamus_HandleTransitionsC[samus_hurt_switch_index]();
LABEL_15:
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;
goto LABEL_16;
}
}
if ((samus_new_pose_interrupted & 0x8000) == 0) {
samus_pose = samus_new_pose_interrupted;
if (!(SamusFunc_F404() & 1))
kSamus_HandleTransitionsB[samus_special_transgfx_index]();
goto LABEL_15;
}
Samus_CheckWalkedIntoSomething();
if ((samus_new_pose & 0x8000) == 0) {
samus_pose = samus_new_pose;
if (!(SamusFunc_F404() & 1))
kSamus_HandleTransitionsA[samus_momentum_routine_index]();
goto LABEL_15;
}
LABEL_16:
input_to_pose_calc = 0;
}
void Samus_HandleTransitionsA_1(void) { // 0x91EC50
if (samus_x_base_speed || samus_x_base_subspeed) {
AddToHiLo(&samus_x_base_speed, &samus_x_base_subspeed, __PAIR32__(samus_x_extra_run_speed, samus_x_extra_run_subspeed));
samus_x_accel_mode = 2;
Samus_CancelSpeedBoost();
SetHiLo(&samus_x_extra_run_speed, &samus_x_extra_run_subspeed, 0);
SamusFunc_EC80();
} else {
Samus_HandleTransitionsA_2();
}
}
void Samus_HandleTransitionsA_6(void) { // 0x91EC85
samus_x_accel_mode = 0;
samus_x_base_speed = 0;
samus_x_base_subspeed = 0;
Samus_HandleTransitionsA_8();
}
void Samus_HandleTransitionsA_8(void) { // 0x91EC8E
Samus_CancelSpeedBoost();
SetHiLo(&samus_x_extra_run_speed, &samus_x_extra_run_subspeed, 0);
SamusFunc_EC80();
}
void Samus_HandleTransitionsA_2(void) { // 0x91ECD0
samus_x_accel_mode = 0;
Samus_CancelSpeedBoost();
}
static const uint16 word_91ED36[12] = { // 0x91ECDA
5, 5, 9, 9, 0, 0, 0, 0,
0, 0, 0, 0,
};
void Samus_HandleTransitionsA_7(void) {
int32 amt;
if (sign16(samus_pose - kPose_DB)) {
amt = INT16_SHL16(word_91ED36[samus_pose - 53]);
if (amt) {
LABEL_4:
samus_y_radius = kPoseParams[samus_pose].y_radius;
amt = Samus_CollDetectChangedPose(amt);
}
samus_y_pos += amt >> 16;
samus_prev_y_pos = samus_y_pos;
if (used_for_ball_bounce_on_landing) {
used_for_ball_bounce_on_landing = 0;
samus_y_subspeed = 0;
samus_y_speed = 0;
samus_y_dir = 0;
}
} else if (!sign16(samus_pose - kPose_F1_FaceR_CrouchTrans_AimU) && sign16(samus_pose - kPose_F7_FaceR_StandTrans_AimU)) {
amt = INT16_SHL16(5);
goto LABEL_4;
}
}
static Func_U8 *const kSamus_HandleTransitionsB_1[28] = { // 0x91ED4E
Samus_HandleTransitionsB_1_0,
Samus_HandleTransitionsB_1_0,
Samus_HandleTransitionsB_1_0,
Samus_HandleTransitionsB_1_0,
Samus_HandleTransitionsB_1_4,
Samus_HandleTransitionsB_1_0,
Samus_HandleTransitionsB_1_6,
Samus_HandleTransitionsB_1_7,
Samus_HandleTransitionsB_1_4,
Samus_HandleTransitionsB_1_4,
Samus_HandleTransitionsB_1_10,
Samus_HandleTransitionsB_1_11,
Samus_HandleTransitionsB_1_11,
Samus_HandleTransitionsB_1_0,
Samus_HandleTransitionsB_1_11,
Samus_HandleTransitionsB_1_11,
Samus_HandleTransitionsB_1_0,
Samus_HandleTransitionsB_1_4,
Samus_HandleTransitionsB_1_4,
Samus_HandleTransitionsB_1_4,
Samus_HandleTransitionsB_1_0,
Samus_HandleTransitionsB_1_0,
Samus_HandleTransitionsB_1_10,
Samus_HandleTransitionsB_1_11,
Samus_HandleTransitionsB_1_11,
Samus_HandleTransitionsB_1_11,
Samus_HandleTransitionsB_1_11,
Samus_HandleTransitionsB_1_11,
};
void Samus_HandleTransitionsB_1(void) {
kSamus_HandleTransitionsB_1[samus_prev_movement_type2]();
Samus_SetSpeedForKnockback_Y();
bomb_jump_dir = 0;
samus_contact_damage_index = 0;
samus_hurt_flash_counter = 1;
}
uint8 Samus_HandleTransitionsB_1_10(void) { // 0x91EDA2
return 0;
}
uint8 Samus_HandleTransitionsB_1_11(void) { // 0x91EDA4
return 0;
}
uint8 Samus_HandleTransitionsB_1_6(void) { // 0x91EDA6
if (frame_handler_gamma == FUNC16(Samus_Func9))
return 0;
else
return Samus_HandleTransitionsB_1_0();
}
uint8 Samus_HandleTransitionsB_1_0(void) { // 0x91EDB0
if (samus_pose_x_dir == 4) {
if (knockback_x_dir) {
if ((joypad1_lastkeys & 0x200) != 0)
knockback_dir = 5;
else
knockback_dir = 2;
} else if ((joypad1_lastkeys & 0x200) != 0) {
knockback_dir = 4;
} else {
knockback_dir = 1;
}
} else if (knockback_x_dir) {
if ((joypad1_lastkeys & 0x100) != 0)
knockback_dir = 5;
else
knockback_dir = 2;
} else if ((joypad1_lastkeys & 0x100) != 0) {
knockback_dir = 4;
} else {
knockback_dir = 1;
}
samus_movement_handler = FUNC16(Samus_MoveHandler_Knockback);
return 1;
}
uint8 Samus_HandleTransitionsB_1_4(void) { // 0x91EE27
if (samus_pose_x_dir == 4)
knockback_dir = 1;
else
knockback_dir = 2;
samus_movement_handler = FUNC16(Samus_MoveHandler_Knockback);
return 0;
}
uint8 Samus_HandleTransitionsB_1_7(void) { // 0x91EE48
if (samus_pose_x_dir == 4)
knockback_dir = 1;
else
knockback_dir = 2;
samus_movement_handler = FUNC16(Samus_MoveHandler_Knockback);
return 1;
}
void Samus_HandleTransitionsB_2(void) { // 0x91EE69
knockback_dir = 0;
samus_movement_handler = FUNC16(Samus_MovementHandler_Normal);
samus_y_speed = 0;
samus_y_subspeed = 0;
samus_y_dir = 0;
Samus_AlignBottomWithPrevPose();
}
void Samus_HandleTransitionsB_3(void) { // 0x91EE80
bomb_jump_dir = (uint8)bomb_jump_dir | 0x800;
samus_movement_handler = FUNC16(Samus_MoveHandler_BombJumpStart);
if (samus_input_handler != FUNC16(Samus_InputHandler_E91D))
samus_input_handler = FUNC16(nullsub_152);
}
void Samus_HandleTransitionsB_4(void) { // 0x91EEA1
Samus_InitJump();
}
void Samus_HandleTransitionsB_5(void) { // 0x91EEA6
switch (samus_movement_type) {
case kMovementType_00_Standing:
goto LABEL_5;
case kMovementType_05_Crouching:
if (samus_pose_x_dir == 4)
xray_angle = 192;
else
xray_angle = 64;
goto LABEL_11;
case kMovementType_15_RanIntoWall:
case kMovementType_01_Running:
LABEL_5:
if (samus_pose_x_dir == 4)
xray_angle = 192;
else
xray_angle = 64;
LABEL_11:
samus_anim_frame = 2;
samus_anim_frame_timer = 63;
samus_movement_handler = FUNC16(SamusMovementType_Xray);
samus_input_handler = FUNC16(Samus_Func20_);
timer_for_shine_timer = 8;
special_samus_palette_timer = 1;
special_samus_palette_frame = 0;
samus_shine_timer = 0;
flare_counter = 0;
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;
QueueSfx1_Max6(9);
break;
}
}
void Samus_HandleTransitionsB_8(void) { // 0x91EF3B
samus_y_pos -= 5;
samus_prev_y_pos = samus_y_pos;
frame_handler_alfa = FUNC16(EmptyFunction);
}
void Samus_HandleTransitionsB_9(void) { // 0x91EF4F
int16 v0;
int16 v1;
GrappleBeamFunc_BD95();
v0 = samus_x_pos - samus_prev_x_pos;
if ((int16)(samus_x_pos - samus_prev_x_pos) < 0) {
if (sign16(v0 + 12))
samus_prev_x_pos = samus_x_pos + 12;
} else if (!sign16(v0 - 13)) {
samus_prev_x_pos = samus_x_pos - 12;
}
v1 = samus_y_pos - samus_prev_y_pos;
if ((int16)(samus_y_pos - samus_prev_y_pos) < 0) {
if (sign16(v1 + 12))
samus_prev_y_pos = samus_y_pos + 12;
} else if (!sign16(v1 - 13)) {
samus_prev_y_pos = samus_y_pos - 12;
}
Samus_CancelSpeedBoost();
samus_x_base_speed = 0;
samus_x_base_subspeed = 0;
samus_y_subspeed = 0;
samus_y_speed = 0;
SetHiLo(&samus_x_extra_run_speed, &samus_x_extra_run_subspeed, 0);
}
void Samus_HandleTransitionsB_10(void) { // 0x91EFBC
GrappleBeamFunc_BEEB();
Samus_HandleTransitionsB_9B();
}
void Samus_HandleTransitionsB_9B(void) { // 0x91EF53
int16 v0;
int16 v1;
v0 = samus_x_pos - samus_prev_x_pos;
if ((int16)(samus_x_pos - samus_prev_x_pos) < 0) {
if (sign16(v0 + 12))
samus_prev_x_pos = samus_x_pos + 12;
} else if (!sign16(v0 - 13)) {
samus_prev_x_pos = samus_x_pos - 12;
}
v1 = samus_y_pos - samus_prev_y_pos;
if ((int16)(samus_y_pos - samus_prev_y_pos) < 0) {
if (sign16(v1 + 12))
samus_prev_y_pos = samus_y_pos + 12;
} else if (!sign16(v1 - 13)) {
samus_prev_y_pos = samus_y_pos - 12;
}
Samus_CancelSpeedBoost();
samus_x_base_speed = 0;
samus_x_base_subspeed = 0;
samus_y_subspeed = 0;
samus_y_speed = 0;
SetHiLo(&samus_x_extra_run_speed, &samus_x_extra_run_subspeed, 0);
}
void nullsub_23(void) { // 0x91EFDE
}
static Func_V *const kSamus_HandleTransitionsA_5[7] = { // 0x91EFC4
sub_91EFC3,
Samus_HandleTransitionsA_5_1,
Samus_HandleTransitionsA_5_2,
nullsub_23,
Samus_HandleTransitionsA_5_4,
Samus_HandleTransitionsA_5_5,
Samus_HandleTransitionsA_5_6,
};
void Samus_HandleTransitionsA_5(void) {
kSamus_HandleTransitionsA_5[(uint8)input_to_pose_calc]();
}
void Samus_HandleTransitionsA_5_4(void) { // 0x91EFDF
samus_y_subspeed = 0;
samus_y_speed = 0;
UNUSED_word_7E0B1A = 0;
samus_y_dir = 2;
}
void Samus_HandleTransitionsA_5_2(void) { // 0x91EFEF
if (samus_y_dir != 1) {
used_for_ball_bounce_on_landing = 0;
samus_y_subspeed = 0;
samus_y_speed = 0;
samus_is_falling_flag = 1;
samus_y_dir = 2;
}
UNUSED_word_7E0A18 = 0;
}
void sub_91EFC3(void) {}
uint8 sub_91EFC3_rv(void) { return 0; }
static Func_U8 *const kSamus_HandleTransitionsA_5_1[6] = { // 0x91F010
Samus_HandleTransitionsA_5_1_0,
Samus_MorphBallBounceNoSpringballTrans,
Samus_HandleTransitionsA_5_1_2,
Samus_MorphBallBounceSpringballTrans,
sub_91EFC3_rv,
Samus_HandleTransitionsA_5_1_5,
};
void Samus_HandleTransitionsA_5_1(void) {
HandleLandingSoundEffectsAndGfx();
if (HIBYTE(input_to_pose_calc) == 4) {
SamusFunc_F1D3();
} else if (!(kSamus_HandleTransitionsA_5_1[HIBYTE(input_to_pose_calc)]() & 1)) {
UNUSED_word_7E0A18 = 0;
samus_x_accel_mode = 0;
samus_x_base_speed = 0;
samus_x_base_subspeed = 0;
SamusFunc_F1D3();
}
}
void HandleLandingSoundEffectsAndGfx(void) { // 0x91F046
if ((samus_prev_movement_type2 == kMovementType_03_SpinJumping
|| samus_prev_movement_type2 == kMovementType_14_WallJumping)
&& !cinematic_function) {
if (samus_prev_pose == kPose_81_FaceR_Screwattack || samus_prev_pose == kPose_82_FaceL_Screwattack)
QueueSfx1_Max6(0x34);
else
QueueSfx1_Max6(0x32);
}
if (samus_y_speed && !sign16(samus_y_speed - 5)) {
if (!cinematic_function)
QueueSfx3_Max6(4);
} else {
if (!samus_y_subspeed)
return;
if (!cinematic_function)
QueueSfx3_Max6(5);
}
HandleLandingGraphics();
}
static Func_V *const off_91F0AE[8] = { // 0x91F0A5
HandleLandingGraphics_Crateria,
HandleLandingGraphics_Brinstar,
HandleLandingGraphics_Norfair,
HandleLandingGraphics_Norfair,
HandleLandingGraphics_Maridia,
HandleLandingGraphics_Tourian,
HandleLandingGraphics_Ceres,
HandleLandingGraphics_Ceres,
};
void HandleLandingGraphics(void) {
off_91F0AE[(area_index)]();
}
void HandleLandingGraphics_Ceres(void) { // 0x91F0BE
atmospheric_gfx_frame_and_type[2] = 0;
atmospheric_gfx_frame_and_type[3] = 0;
}
static const uint8 g_byte_91F0F3[17] = { // 0x91F0C5
1, 0, 0, 0, 0, 2, 0, 4,
0, 4, 4, 4, 4, 0, 4, 0,
0,
};
void HandleLandingGraphics_Crateria(void) {
if (cinematic_function)
goto LABEL_13;
if (room_index == 28) {
HandleLandingGraphics_Norfair();
return;
}
if ((int16)(room_index - 16) >= 0)
goto LABEL_13;
if ((g_byte_91F0F3[room_index] & 1) == 0) {
if ((g_byte_91F0F3[room_index] & 2) != 0) {
if (!sign16(samus_y_pos - 944))
goto LABEL_14;
} else if ((g_byte_91F0F3[room_index] & 4) != 0) {
goto LABEL_14;
}
LABEL_13:
HandleLandingGraphics_Ceres();
return;
}
if (fx_type != 10)
goto LABEL_13;
LABEL_14:
HandleLandingGraphics_Maridia();
}
void HandleLandingGraphics_Maridia(void) { // 0x91F116
uint16 bottom = Samus_GetBottom_R18();
if ((fx_y_pos & 0x8000) == 0) {
if (sign16(fx_y_pos - bottom) && (fx_liquid_options & 4) == 0)
return;
LABEL_7:
atmospheric_gfx_frame_and_type[2] = 256;
atmospheric_gfx_frame_and_type[3] = 256;
atmospheric_gfx_anim_timer[2] = 3;
atmospheric_gfx_anim_timer[3] = 3;
atmospheric_gfx_x_pos[2] = samus_x_pos + 4;
atmospheric_gfx_x_pos[3] = samus_x_pos - 3;
atmospheric_gfx_y_pos[2] = bottom - 4;
atmospheric_gfx_y_pos[3] = bottom - 4;
return;
}
if ((lava_acid_y_pos & 0x8000) != 0 || !sign16(lava_acid_y_pos - bottom))
goto LABEL_7;
}
void HandleLandingGraphics_Norfair(void) { // 0x91F166
uint16 bottom = Samus_GetBottom_R18();
if ((fx_y_pos & 0x8000) == 0) {
if (sign16(fx_y_pos - bottom) && (fx_liquid_options & 4) == 0)
return;
LABEL_7:
atmospheric_gfx_frame_and_type[2] = 1536;
atmospheric_gfx_frame_and_type[3] = 1536;
atmospheric_gfx_anim_timer[2] = 3;
atmospheric_gfx_anim_timer[3] = 3;
atmospheric_gfx_x_pos[2] = samus_x_pos + 8;
atmospheric_gfx_x_pos[3] = samus_x_pos - 8;
atmospheric_gfx_y_pos[2] = bottom;
atmospheric_gfx_y_pos[3] = bottom;
return;
}
if ((lava_acid_y_pos & 0x8000) != 0 || !sign16(lava_acid_y_pos - bottom))
goto LABEL_7;
}
void HandleLandingGraphics_Brinstar(void) { // 0x91F1B2
if (room_index == 8)
HandleLandingGraphics_Norfair();
else
HandleLandingGraphics_Tourian();
}
void HandleLandingGraphics_Tourian(void) { // 0x91F1BA
if (!sign16(room_index - 5) && (sign16(room_index - 9) || room_index == 11)) {
HandleLandingGraphics_Norfair();
} else {
atmospheric_gfx_frame_and_type[2] = 0;
atmospheric_gfx_frame_and_type[3] = 0;
}
}
void SamusFunc_F1D3(void) { // 0x91F1D3
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;
used_for_ball_bounce_on_landing = 0;
}
uint8 Samus_HandleTransitionsA_5_1_0(void) { // 0x91F1EC
if (samus_input_handler != FUNC16(Samus_InputHandler_E91D))
samus_input_handler = FUNC16(HandleAutoJumpHack);
return 0;
}
static const uint16 g_word_909EB5 = 1;
static const uint16 g_word_909EB7 = 0;
uint8 Samus_MorphBallBounceNoSpringballTrans(void) { // 0x91F1FC
int16 v0;
v0 = 2 * used_for_ball_bounce_on_landing;
if (2 * used_for_ball_bounce_on_landing) {
if (v0 == 2) {
++used_for_ball_bounce_on_landing;
samus_y_dir = 1;
samus_y_subspeed = g_word_909EB7;
samus_y_speed = g_word_909EB5 - 1;
return 1;
}
if (v0 != 4)
Unreachable();
} else if (!sign16(samus_y_speed - 3)) {
++used_for_ball_bounce_on_landing;
samus_y_dir = 1;
samus_y_subspeed = g_word_909EB7;
samus_y_speed = g_word_909EB5;
return 1;
}
used_for_ball_bounce_on_landing = 0;
samus_y_dir = 0;
samus_y_subspeed = 0;
samus_y_speed = 0;
return 0;
}
uint8 Samus_HandleTransitionsA_5_1_2(void) { // 0x91F253
used_for_ball_bounce_on_landing = 0;
enable_horiz_slope_coll = 3;
return 0;
}
uint8 Samus_MorphBallBounceSpringballTrans(void) { // 0x91F25E
int16 v1;
if ((button_config_jump_a & joypad1_lastkeys) != 0) {
used_for_ball_bounce_on_landing = 0;
Samus_InitJump();
return 1;
}
v1 = 2 * (uint8)used_for_ball_bounce_on_landing;
if (v1) {
if (v1 == 2) {
used_for_ball_bounce_on_landing = 1538;
samus_y_dir = 1;
samus_y_subspeed = g_word_909EB7;
samus_y_speed = g_word_909EB5 - 1;
return 1;
}
if (v1 != 4)
Unreachable();
} else if (!sign16(samus_y_speed - 3)) {
used_for_ball_bounce_on_landing = 1537;
samus_y_dir = 1;
samus_y_subspeed = g_word_909EB7;
samus_y_speed = g_word_909EB5;
return 1;
}
used_for_ball_bounce_on_landing = 0;
samus_y_dir = 0;
samus_y_subspeed = 0;
samus_y_speed = 0;
return 0;
}
uint8 Samus_HandleTransitionsA_5_1_5(void) { // 0x91F2CE
used_for_ball_bounce_on_landing = 0;
return 0;
}
void Samus_HandleTransitionsA_5_5(void) { // 0x91F2D3
samus_x_accel_mode = 0;
samus_collides_with_solid_enemy = 0;
samus_is_falling_flag = 0;
UNUSED_word_7E0B1A = 0;
samus_x_base_speed = 0;
samus_x_base_subspeed = 0;
UNUSED_word_7E0A18 = 0;
QueueSfx3_Max6(5);
}
void Samus_HandleTransitionsA_5_6(void) { // 0x91F2F0
if (samus_collides_with_solid_enemy) {
if (samus_prev_movement_type2 == 9) {
enable_horiz_slope_coll = samus_pose_x_dir != 4;
UNUSED_word_7E0A18 = 0;
}
}
}
void Samus_HandleTransitionsC_1(void) { // 0x91F31D
knockback_dir = 0;
samus_movement_handler = FUNC16(Samus_MovementHandler_Normal);
used_for_ball_bounce_on_landing = 0;
samus_y_subspeed = 0;
samus_y_speed = 0;
samus_is_falling_flag = 1;
samus_y_dir = 2;
Samus_AlignBottomWithPrevPose();
if (samus_input_handler != FUNC16(Samus_InputHandler_E91D))
samus_input_handler = FUNC16(Samus_InputHandler_E913);
}
void Samus_HandleTransitionsC_2(void) { // 0x91F34E
Samus_AlignBottomWithPrevPose();
samus_movement_handler = FUNC16(Samus_MovementHandler_Normal);
if (game_state == kGameState_42_PlayingDemo)
samus_input_handler = FUNC16(Samus_InputHandler_E91D);
else
samus_input_handler = FUNC16(Samus_InputHandler_E913);
}
void Samus_HandleTransitionsC_3(void) { // 0x91F36E
used_for_ball_bounce_on_landing = 0;
samus_anim_frame_timer += samus_anim_frame_buffer;
}
void Samus_HandleTransitionsC_4(void) { // 0x91F37C
samus_x_pos = layer1_x_pos + 128;
samus_prev_x_pos = layer1_x_pos + 128;
samus_y_pos = layer1_y_pos + 128;
samus_prev_y_pos = layer1_y_pos + 128;
}
void Samus_HandleTransitionsC_5(void) { // 0x91F397
samus_y_pos += 5;
samus_prev_y_pos = samus_y_pos;
}
void Samus_HandleTransitionsC_6(void) { // 0x91F3A5
HandleJumpTransition();
}
void Samus_HandleTransitionsC_7(void) { // 0x91F3AA
int16 v0;
int16 v1;
v0 = samus_x_pos - samus_prev_x_pos;
if ((int16)(samus_x_pos - samus_prev_x_pos) < 0) {
if (sign16(v0 + 12))
samus_prev_x_pos = samus_x_pos + 12;
} else if (!sign16(v0 - 13)) {
samus_prev_x_pos = samus_x_pos - 12;
}
v1 = samus_y_pos - samus_prev_y_pos;
if ((int16)(samus_y_pos - samus_prev_y_pos) < 0) {
if (sign16(v1 + 12))
samus_prev_y_pos = samus_y_pos + 12;
} else if (!sign16(v1 - 13)) {
samus_prev_y_pos = samus_y_pos - 12;
}
}
void Samus_HandleTransitionsC_8(void) { // 0x91F3FD
Samus_HandleTransitionsC_1();
Samus_HandleTransitionsC_3();
}
uint8 SamusFunc_F404(void) { // 0x91F404
SamusPose v1;
v1 = samus_pose;
if (samus_pose != samus_prev_pose) {
HandleCollDueToChangedPose();
SamusFunc_F433();
HandleJumpTransition();
Samus_SetAnimationFrameIfPoseChanged();
samus_anim_frame_skip = 0;
}
return v1 != samus_pose;
}
void SamusFunc_F433(void) { // 0x91F433
*(uint16 *)&samus_pose_x_dir = *(uint16 *)(&kPoseParams[0].pose_x_dir + (8 * samus_pose));
SamusFunc_F468();
if ((samus_prev_movement_type2 == kMovementType_03_SpinJumping
|| samus_prev_movement_type2 == kMovementType_14_WallJumping)
&& (equipped_items & 8) != 0) {
Samus_LoadSuitPalette();
}
}
static Func_U8 *const off_91F4A2[28] = { // 0x91F468
SamusFunc_F468_Standing,
SamusFunc_F468_Running,
SamusFunc_F468_NormalJump,
SamusFunc_F468_SpinJump,
SamusFunc_F468_MorphBall,
SamusFunc_F468_Crouching,
SamusFunc_F468_Falling,
SamusFunc_F468_Unused,
SamusFunc_F468_MorphBall,
SamusFunc_F468_Unused,
SamusFunc_F468_Unused,
SamusFunc_F468_Unused,
SamusFunc_F468_Unused,
SamusFunc_F468_Unused,
SamusFunc_F468_TurningAroundOnGround,
SamusFunc_F468_CrouchTransEtc,
SamusFunc_F468_Moonwalking,
SamusFunc_F468_Springball,
SamusFunc_F468_Springball,
SamusFunc_F468_Springball,
SamusFunc_F468_WallJumping,
SamusFunc_F468_Unused,
SamusFunc_F468_Unused,
SamusFunc_F468_TurnAroundJumping,
SamusFunc_F468_TurnAroundFalling,
SamusFunc_F468_DamageBoost,
SamusFunc_F468_Unused,
SamusFunc_F468_Shinespark,
};
void SamusFunc_F468(void) {
if (off_91F4A2[samus_movement_type]() & 1) {
*(uint16 *)&samus_pose_x_dir = *(uint16 *)(&kPoseParams[0].pose_x_dir + (8 * samus_pose));
if ((*(uint16 *)&samus_pose_x_dir & 0xFF00) == 3584) {
off_91F4A2[14]();
*(uint16 *)&samus_pose_x_dir = *(uint16 *)(&kPoseParams[0].pose_x_dir + (8 * samus_pose));
}
}
}
uint8 SamusFunc_F468_Unused(void) { // 0x91F4DA
return 0;
}
uint8 SamusFunc_F468_Standing(void) { // 0x91F4DC
if ((!kPoseParams[samus_pose].direction_shots_fired
|| kPoseParams[samus_pose].direction_shots_fired == 9)
&& (!kPoseParams[samus_prev_pose].direction_shots_fired
|| kPoseParams[samus_prev_pose].direction_shots_fired == 9)) {
samus_anim_frame_skip = 1;
}
return 0;
}
uint8 SamusFunc_F468_Running(void) { // 0x91F50C
if (samus_prev_movement_type2 == 1)
samus_anim_frame_skip = FUNC16(Samus_InputHandler);
if (!UNUSED_word_7E0DF8)
return 0;
if (samus_pose == (kPose_44_FaceL_Turn_Crouch | kPose_01_FaceR_Normal)) {
samus_pose = kPose_25_FaceR_Turn_Stand;
return 1;
}
if (samus_pose == (kPose_44_FaceL_Turn_Crouch | kPose_02_FaceL_Normal)) {
samus_pose = kPose_26_FaceL_Turn_Stand;
return 1;
}
return 0;
}
uint8 SamusFunc_F468_NormalJump(void) { // 0x91F543
if (samus_pose != kPose_4E_FaceL_Jump_NoAim_NoMove_NoGun) {
if (samus_pose == kPose_4D_FaceR_Jump_NoAim_NoMove_NoGun || samus_pose == kPose_15_FaceR_Jump_AimU) {
LABEL_7:
if (samus_shine_timer) {
samus_pose = kPose_C7_FaceR_ShinesparkWindup_Vert;
LABEL_11:
Projectile_Func7_Shinespark();
if (samus_prev_movement_type2 == kMovementType_02_NormalJumping)
samus_prev_y_pos = --samus_y_pos;
return 1;
}
goto LABEL_14;
}
if (samus_pose != kPose_16_FaceL_Jump_AimU && samus_pose != kPose_6A_FaceL_Jump_AimUL) {
if (samus_pose != kPose_69_FaceR_Jump_AimUR)
goto LABEL_14;
goto LABEL_7;
}
}
if (samus_shine_timer) {
samus_pose = kPose_C8_FaceL_ShinesparkWindup_Vert;
goto LABEL_11;
}
LABEL_14:
if (samus_x_extra_run_speed || samus_x_extra_run_subspeed)
samus_x_accel_mode = 2;
else
samus_x_accel_mode = 0;
if ((samus_pose == kPose_15_FaceR_Jump_AimU || samus_pose == kPose_16_FaceL_Jump_AimU)
&& (samus_prev_pose == kPose_55_FaceR_Jumptrans_AimU || samus_prev_pose == kPose_56_FaceL_Jumptrans_AimU)) {
samus_anim_frame_skip = 1;
}
if ((button_config_shoot_x & joypad1_newkeys) != 0)
new_projectile_direction_changed_pose = kPoseParams[samus_pose].direction_shots_fired | 0x8000;
return 0;
}
uint8 SamusFunc_F468_Crouching(void) { // 0x91F5EB
if ((samus_pose == kPose_85_FaceR_Crouch_AimU || samus_pose == kPose_86_FaceL_Crouch_AimU)
&& (samus_prev_pose == kPose_F1_FaceR_CrouchTrans_AimU || samus_prev_pose == kPose_F2_FaceL_CrouchTrans_AimU)) {
samus_anim_frame_skip = 1;
}
return 0;
}
uint8 SamusFunc_F468_Falling(void) { // 0x91F60D
if (samus_x_extra_run_speed || samus_x_extra_run_subspeed)
samus_x_accel_mode = 2;
else
samus_x_accel_mode = 0;
return 0;
}
uint8 SamusFunc_F468_SpinJump(void) { // 0x91F624
if (samus_prev_movement_type2 == kMovementType_03_SpinJumping
|| samus_prev_movement_type2 == kMovementType_14_WallJumping) {
samus_anim_frame_skip = 1;
if ((samus_prev_pose_x_dir & 0xF) == 8) {
if (*(uint16 *)&samus_pose_x_dir != 772)
goto LABEL_9;
} else if ((samus_prev_pose_x_dir & 0xF) != 4 || *(uint16 *)&samus_pose_x_dir != 776) {
goto LABEL_9;
}
AddToHiLo(&samus_x_base_speed, &samus_x_base_subspeed, __PAIR32__(samus_x_extra_run_speed, samus_x_extra_run_subspeed));
Samus_CancelSpeedBoost();
SetHiLo(&samus_x_extra_run_speed, &samus_x_extra_run_subspeed, 0);
samus_x_accel_mode = 1;
}
LABEL_9:
if (samus_pose_x_dir == 4) {
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))
return 0;
} else if (sign16(fx_y_pos - r20) && (fx_liquid_options & 4) == 0) {
return 0;
}
}
if ((equipped_items & 8) != 0) {
samus_pose = kPose_82_FaceL_Screwattack;
goto LABEL_40;
}
if ((equipped_items & 0x200) != 0) {
QueueSfx1_Max6(0x3E);
samus_pose = kPose_1C_FaceL_SpaceJump;
return 0;
}
if (!samus_anim_frame_skip && !cinematic_function) {
LABEL_22:
QueueSfx1_Max6(0x31);
return 0;
}
return 0;
}
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))
return 0;
} else if (sign16(fx_y_pos - r20) && (fx_liquid_options & 4) == 0) {
return 0;
}
}
if ((equipped_items & 8) != 0) {
samus_pose = kPose_81_FaceR_Screwattack;
LABEL_40:
if (!samus_anim_frame_skip)
QueueSfx1_Max6(0x33);
return 0;
}
if ((equipped_items & 0x200) == 0) {
if (samus_anim_frame_skip || cinematic_function)
return 0;
goto LABEL_22;
}
QueueSfx1_Max6(0x3E);
samus_pose = kPose_1B_FaceR_SpaceJump;
return 0;
}
static Func_U8 *const off_91F790[12] = { // 0x91F758
Samus_CrouchTrans,
Samus_CrouchTrans,
Samus_MorphTrans,
Samus_MorphTrans,
MaybeUnused_sub_91F7F4,
MaybeUnused_sub_91F840,
Samus_StandOrUnmorphTrans,
Samus_StandOrUnmorphTrans,
Samus_StandOrUnmorphTrans,
Samus_StandOrUnmorphTrans,
Samus_StandOrUnmorphTrans,
Samus_StandOrUnmorphTrans,
};
static Func_U8 *const off_91F7A8[4] = {
Samus_MorphTrans,
Samus_MorphTrans,
Samus_StandOrUnmorphTrans,
Samus_StandOrUnmorphTrans,
};
uint8 SamusFunc_F468_CrouchTransEtc(void) {
uint16 v0;
if (sign16(samus_pose - kPose_F1_FaceR_CrouchTrans_AimU)) {
if (sign16(samus_pose - kPose_DB)) {
v0 = 2 * (samus_pose - 53);
LABEL_4:
samus_momentum_routine_index = 7;
return off_91F790[v0 >> 1]();
}
return off_91F7A8[samus_pose - 219]();
} else {
if (sign16(samus_pose - kPose_F7_FaceR_StandTrans_AimU)) {
v0 = 0;
goto LABEL_4;
}
samus_momentum_routine_index = 7;
}
return 0;
}
uint8 Samus_CrouchTrans(void) { // 0x91F7B0
if (!sign16((speed_boost_counter & 0xFF00) - 1024)) {
samus_shine_timer = 180;
timer_for_shine_timer = 1;
special_samus_palette_frame = 0;
}
return 0;
}
uint8 Samus_StandOrUnmorphTrans(void) { // 0x91F7CC
return 0;
}
uint8 Samus_MorphTrans(void) { // 0x91F7CE
if ((equipped_items & 4) != 0) {
if (samus_prev_movement_type2 == kMovementType_03_SpinJumping)
samus_x_accel_mode = 2;
bomb_spread_charge_timeout_counter = 0;
return 0;
} else {
samus_pose = samus_prev_pose;
return 1;
}
}
uint8 MaybeUnused_sub_91F7F4(void) { // 0x91F7F4
if (samus_prev_movement_type2 == kMovementType_08_MorphBallFalling
|| samus_prev_movement_type2 == kMovementType_13_SpringBallFalling) {
if ((equipped_items & 2) != 0)
samus_pose = kPose_7D_FaceR_Springball_Fall;
else
samus_pose = kPose_31_FaceR_Morphball_Air;
} else if ((equipped_items & 2) != 0) {
samus_pose = kPose_79_FaceR_Springball_Ground;
} else {
samus_pose = kPose_1D_FaceR_Morphball_Ground;
}
return 1;
}
uint8 MaybeUnused_sub_91F840(void) { // 0x91F840
if (samus_prev_movement_type2 == kMovementType_08_MorphBallFalling
|| samus_prev_movement_type2 == kMovementType_13_SpringBallFalling) {
if ((equipped_items & 2) != 0)
samus_pose = kPose_7E_FaceL_Springball_Fall;
else
samus_pose = kPose_32_FaceL_Morphball_Air;
} else if ((equipped_items & 2) != 0) {
samus_pose = kPose_7A_FaceL_Springball_Ground;
} else {
samus_pose = kPose_41_FaceL_Morphball_Ground;
}
return 1;
}
uint8 SamusFunc_F468_Moonwalking(void) { // 0x91F88C
if (moonwalk_flag)
return 0;
if (samus_pose_x_dir == 4)
samus_pose = kPose_25_FaceR_Turn_Stand;
else
samus_pose = kPose_26_FaceL_Turn_Stand;
return 1;
}
uint8 SamusFunc_F468_DamageBoost(void) { // 0x91F8AE
return SamusFunc_F468_DamageBoost_();
}
uint8 MaybeUnused_sub_91F8B0(void) { // 0x91F8B0
if (samus_pose_x_dir == 4)
samus_pose = kPose_54_FaceL_Knockback;
else
samus_pose = kPose_53_FaceR_Knockback;
return 1;
}
uint8 SamusFunc_F468_DamageBoost_(void) { // 0x91F8CB
samus_movement_handler = FUNC16(Samus_MovementHandler_Normal);
return 0;
}
uint8 SamusFunc_F468_TurningAroundOnGround(void) { // 0x91F8D3
if (samus_prev_pose && samus_prev_pose != kPose_9B_FaceF_VariaGravitySuit) {
uint16 v0 = kPoseParams[samus_prev_pose].direction_shots_fired;
if (samus_prev_movement_type2 == kMovementType_10_Moonwalking) {
new_projectile_direction_changed_pose = v0 | 0x100;
if ((button_config_jump_a & joypad1_lastkeys) != 0) {
samus_pose = kSamusTurnPose_Moonwalk[v0];
} else {
samus_pose = kSamusTurnPose_Standing[v0];
}
} else if (samus_prev_movement_type2 == 5) {
samus_pose = kSamusTurnPose_Crouching[v0];
} else {
samus_pose = kSamusTurnPose_Standing[v0];
}
}
AddToHiLo(&samus_x_base_speed, &samus_x_base_subspeed, __PAIR32__(samus_x_extra_run_speed, samus_x_extra_run_subspeed));
SetHiLo(&samus_x_extra_run_speed, &samus_x_extra_run_subspeed, 0);
samus_x_accel_mode = 1;
return 1;
}
uint8 SamusFunc_F468_TurnAroundJumping(void) { // 0x91F952
samus_pose = kSamusTurnPose_Jumping[kPoseParams[samus_prev_pose].direction_shots_fired];
AddToHiLo(&samus_x_base_speed, &samus_x_base_subspeed, __PAIR32__(samus_x_extra_run_speed, samus_x_extra_run_subspeed));
SetHiLo(&samus_x_extra_run_speed, &samus_x_extra_run_subspeed, 0);
samus_x_accel_mode = 1;
return 1;
}
uint8 SamusFunc_F468_TurnAroundFalling(void) { // 0x91F98A
samus_pose = kSamusTurnPose_Falling[kPoseParams[samus_prev_pose].direction_shots_fired];
AddToHiLo(&samus_x_base_speed, &samus_x_base_subspeed, __PAIR32__(samus_x_extra_run_speed, samus_x_extra_run_subspeed));
SetHiLo(&samus_x_extra_run_speed, &samus_x_extra_run_subspeed, 0);
samus_x_accel_mode = 1;
return 1;
}
uint8 SamusFunc_F468_MorphBall(void) { // 0x91F9F4
if (samus_prev_movement_type2 == kMovementType_04_MorphBallOnGround
|| samus_prev_movement_type2 == kMovementType_08_MorphBallFalling) {
samus_anim_frame_skip = FUNC16(Samus_InputHandler);
}
SamusFunc_FA0A();
return 0;
}
void SamusFunc_FA0A(void) { // 0x91FA0F
if (samus_prev_pose_x_dir == 8) {
if (samus_pose_x_dir != 4)
return;
goto LABEL_5;
}
if (samus_pose_x_dir == 8) {
LABEL_5:;
AddToHiLo(&samus_x_base_speed, &samus_x_base_subspeed, __PAIR32__(samus_x_extra_run_speed, samus_x_extra_run_subspeed));
Samus_CancelSpeedBoost();
SetHiLo(&samus_x_extra_run_speed, &samus_x_extra_run_subspeed, 0);
samus_x_accel_mode = 1;
}
}
uint8 SamusFunc_F468_Springball(void) { // 0x91FA56
if (samus_prev_movement_type2 == kMovementType_11_SpringBallOnGround
|| samus_prev_movement_type2 == kMovementType_12_SpringBallInAir
|| samus_prev_movement_type2 == kMovementType_13_SpringBallFalling) {
samus_anim_frame_skip = FUNC16(Samus_InputHandler);
}
SamusFunc_FA0A();
return 0;
}
uint8 SamusFunc_F468_WallJumping(void) { // 0x91FA76
uint16 bottom = Samus_GetBottom_R18();
if ((fx_y_pos & 0x8000) != 0) {
if ((lava_acid_y_pos & 0x8000) == 0 && sign16(lava_acid_y_pos - bottom))
return 0;
} else if (sign16(fx_y_pos - bottom) && (fx_liquid_options & 4) == 0) {
return 0;
}
atmospheric_gfx_frame_and_type[3] = 1536;
atmospheric_gfx_anim_timer[3] = 3;
atmospheric_gfx_y_pos[3] = bottom;
if (samus_pose_x_dir != 8) {
atmospheric_gfx_x_pos[3] = samus_x_pos + 6;
return 0;
}
atmospheric_gfx_x_pos[3] = samus_x_pos - 6;
return 0;
}
static uint16 kSamusFunc_F468_Shinespark[6] = { // 0x91FACA
(uint16)fnSamus_MoveHandler_Shinespark_Horiz,
(uint16)fnSamus_MoveHandler_Shinespark_Horiz,
(uint16)fnSamus_MoveHandlerVerticalShinespark,
(uint16)fnSamus_MoveHandlerVerticalShinespark,
(uint16)fnSamus_MoveHandler_Shinespark_Diag,
(uint16)fnSamus_MoveHandler_Shinespark_Diag,
};
uint8 SamusFunc_F468_Shinespark(void) {
if (sign16(samus_pose - kPose_CF_FaceR_Ranintowall_AimUR)) {
samus_movement_handler = kSamusFunc_F468_Shinespark[samus_pose - 201];
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);
}
return 0;
}
static const uint16 kSamusPhys_AnimDelayInWater = 3;
static const uint16 kSamusPhys_AnimDelayInAcid = 2;
void Samus_SetAnimationFrameIfPoseChanged(void) { // 0x91FB08
uint16 t;
if ((equipped_items & 0x20) != 0) {
t = samus_x_speed_divisor;
} else {
uint16 r = samus_y_pos + kPoseParams[samus_pose].y_radius - 1;
if ((fx_y_pos & 0x8000) == 0) {
t = (sign16(fx_y_pos - r) && (fx_liquid_options & 4) == 0) ? kSamusPhys_AnimDelayInWater : samus_x_speed_divisor;
} else if ((lava_acid_y_pos & 0x8000) != 0 || !sign16(lava_acid_y_pos - r)) {
t = samus_x_speed_divisor;
} else {
t = kSamusPhys_AnimDelayInAcid;
}
}
if ((samus_anim_frame_skip & 0x8000) == 0 && samus_pose != samus_prev_pose) {
samus_anim_frame = samus_anim_frame_skip;
samus_anim_frame_timer = t + *RomPtr_91(kSamusAnimationDelayData[samus_pose] + samus_anim_frame_skip);
}
}
void SamusFunc_EC80(void) { // 0x91FB8E
if (samus_prev_movement_type2 != kMovementType_06_Falling && samus_movement_type == kMovementType_06_Falling) {
samus_y_subspeed = 0;
samus_y_speed = 0;
samus_y_dir = 2;
}
}
void UNUSED_sub_91FC42(void);
void nullsub_24(void) {}
void nullsub_25(void) {}
static Func_V *const kHandleJumpTrans[28] = { // 0x91FBBB
nullsub_24,
nullsub_24,
HandleJumpTransition_NormalJump,
HandleJumpTransition_SpinJump,
nullsub_24,
nullsub_24,
nullsub_24,
nullsub_24,
nullsub_24,
nullsub_24,
nullsub_24,
nullsub_24,
nullsub_24,
UNUSED_sub_91FC42,
nullsub_24,
nullsub_24,
nullsub_24,
nullsub_24,
HandleJumpTransition_SpringBallInAir,
nullsub_24,
HandleJumpTransition_WallJump,
nullsub_24,
nullsub_24,
nullsub_24,
nullsub_24,
nullsub_25,
nullsub_24,
nullsub_24,
};
void HandleJumpTransition(void) {
kHandleJumpTrans[(samus_movement_type)]();
}
void HandleJumpTransition_WallJump(void) { // 0x91FC08
if (samus_prev_movement_type2 != kMovementType_14_WallJumping)
Samus_InitWallJump();
}
void HandleJumpTransition_SpringBallInAir(void) { // 0x91FC18
if (samus_pose == kPose_7F_FaceR_Springball_Air) {
if (samus_prev_movement_type2 != kMovementType_11_SpringBallOnGround)
return;
LABEL_6:
Samus_InitJump();
return;
}
if (samus_pose == kPose_80_FaceL_Springball_Air && samus_prev_movement_type2 == kMovementType_11_SpringBallOnGround)
goto LABEL_6;
}
void UNUSED_sub_91FC42(void) { // 0x91FC42
if (samus_pose == (kPose_44_FaceL_Turn_Crouch | kPose_01_FaceR_Normal | 0x20)) {
if (samus_prev_pose != 100)
return;
LABEL_6:
Samus_InitJump();
return;
}
if (samus_pose == (kPose_44_FaceL_Turn_Crouch | kPose_02_FaceL_Normal | 0x20) && samus_prev_pose == 99)
goto LABEL_6;
}
void HandleJumpTransition_NormalJump(void) { // 0x91FC66
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)) {
if (samus_prev_pose == kPose_27_FaceR_Crouch || samus_prev_pose == kPose_28_FaceL_Crouch)
samus_y_pos -= 10;
Samus_InitJump();
}
}
void HandleJumpTransition_SpinJump(void) { // 0x91FC99
if (samus_prev_movement_type2 != kMovementType_03_SpinJumping
&& samus_prev_movement_type2 != kMovementType_14_WallJumping) {
Samus_InitJump();
}
}
void Samus_Func20(void) { // 0x91FCAF
if (samus_movement_type == 14) {
if (samus_anim_frame == 2 && samus_anim_frame_timer == 1) {
if (samus_pose_x_dir == 4) {
if (samus_pose == kPose_25_FaceR_Turn_Stand)
samus_pose = kPose_D6_FaceL_Xray_Stand;
else
samus_pose = kPose_DA_FaceL_Xray_Crouch;
} else if (samus_pose == kPose_26_FaceL_Turn_Stand) {
samus_pose = kPose_D5_FaceR_Xray_Stand;
} else {
samus_pose = kPose_D9_FaceR_Xray_Crouch;
}
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;
}
} else {
if (samus_pose_x_dir == 4) {
if ((button_config_right & joypad1_lastkeys) == 0)
return;
xray_angle = 256 - xray_angle;
if (samus_movement_type == 5)
samus_pose = kPose_44_FaceL_Turn_Crouch;
else
samus_pose = kPose_26_FaceL_Turn_Stand;
} else {
if ((button_config_left & joypad1_lastkeys) == 0)
return;
xray_angle = 256 - xray_angle;
if (samus_movement_type == kMovementType_05_Crouching)
samus_pose = kPose_43_FaceR_Turn_Crouch;
else
samus_pose = kPose_25_FaceR_Turn_Stand;
}
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;
}
}
static Func_U8 *const off_91FE8A[4] = { // 0x91FDAE
HandleCollDueToChangedPose_Solid_NoColl,
HandleCollDueToChangedPose_Solid_CollAbove,
HandleCollDueToChangedPose_Solid_CollBelow,
HandleCollDueToChangedPose_Solid_CollBoth,
};
static Func_U8 *const off_91FE92[4] = {
HandleCollDueToChangedPose_Block_NoColl,
HandleCollDueToChangedPose_Block_CollAbove,
HandleCollDueToChangedPose_Block_CollBelow,
HandleCollDueToChangedPose_Block_CollBoth,
};
void HandleCollDueToChangedPose(void) {
CheckEnemyColl_Result cres;
int32 amt;
int16 v0;
if (!samus_pose || samus_pose == kPose_9B_FaceF_VariaGravitySuit)
return;
solid_enemy_collision_flags = 0;
block_collision_flags = 0;
v0 = kPoseParams[samus_prev_pose].y_radius;
if (!sign16(v0 - kPoseParams[samus_pose].y_radius))
return;
samus_y_radius = kPoseParams[samus_prev_pose].y_radius;
samus_y_radius_diff = kPoseParams[samus_pose].y_radius - v0;
samus_collision_direction = 2;
cres = Samus_CheckSolidEnemyColl(INT16_SHL16(samus_y_radius_diff));
samus_collision_flag = cres.collision, amt = cres.amt;
if (samus_collision_flag)
solid_enemy_collision_flags = 1;
samus_space_to_move_up_enemy = (amt >> 16);
samus_collision_direction = 3;
cres = Samus_CheckSolidEnemyColl(INT16_SHL16(samus_y_radius_diff));
samus_collision_flag = cres.collision, amt = cres.amt;
if (samus_collision_flag)
solid_enemy_collision_flags |= 2;
samus_space_to_move_down_enemy = (amt >> 16);
if (off_91FE8A[solid_enemy_collision_flags]()) {
samus_pose = samus_prev_pose;
return;
}
amt = Samus_CollDetectChangedPose(INT16_SHL16(-samus_y_radius_diff));
if (samus_collision_flag)
block_collision_flags = 1;
samus_space_to_move_up_blocks = (amt >> 16);
amt = Samus_CollDetectChangedPose(INT16_SHL16(samus_y_radius_diff));
if (samus_collision_flag)
block_collision_flags |= 2;
samus_space_to_move_down_blocks = (amt >> 16);
if (off_91FE92[block_collision_flags]()) {
samus_pose = samus_prev_pose;
}
}
uint8 HandleCollDueToChangedPose_Solid_NoColl(void) { // 0x91FE9A
return 0;
}
uint8 HandleCollDueToChangedPose_Solid_CollBoth(void) { // 0x91FE9C
return 0;
}
uint8 HandleCollDueToChangedPose_Solid_CollAbove(void) { // 0x91FE9E
uint16 v1 = samus_y_radius;
samus_y_radius = kPoseParams[samus_pose].y_radius;
samus_collision_direction = 3;
CheckEnemyColl_Result cres = Samus_CheckSolidEnemyColl(INT16_SHL16(samus_y_radius_diff - samus_space_to_move_up_enemy));
samus_y_radius = v1;
samus_collision_flag = cres.collision;
if (samus_collision_flag)
return 1;
samus_space_to_move_up_enemy = cres.amt >> 16;
return 0;
}
uint8 HandleCollDueToChangedPose_Solid_CollBelow(void) { // 0x91FEDF
uint16 v1 = samus_y_radius;
samus_y_radius = kPoseParams[samus_pose].y_radius;
samus_collision_direction = 2;
CheckEnemyColl_Result cres = Samus_CheckSolidEnemyColl(INT16_SHL16(samus_y_radius_diff - samus_space_to_move_down_enemy));
samus_y_radius = v1;
samus_collision_flag = cres.collision;
if (samus_collision_flag)
return 1;
samus_space_to_move_down_enemy = cres.amt >> 16;
return 0;
}
uint8 HandleCollDueToChangedPose_Block_CollAbove(void) { // 0x91FF20
int32 amt = Samus_CollDetectChangedPose(INT16_SHL16(samus_y_radius_diff - samus_space_to_move_up_blocks));
if (samus_collision_flag)
return 1;
if ((solid_enemy_collision_flags & 2) != 0)
return HandleCollDueToChangedPose_Block_CollBoth();
samus_y_pos += amt >> 16;
samus_prev_y_pos = samus_y_pos;
return 0;
}
uint8 HandleCollDueToChangedPose_Block_CollBelow(void) { // 0x91FF49
int32 amt = Samus_CollDetectChangedPose(INT16_SHL16(samus_space_to_move_down_blocks - samus_y_radius_diff));
if (samus_collision_flag)
return 1;
if ((solid_enemy_collision_flags & 1) != 0)
return HandleCollDueToChangedPose_Block_CollBoth();
samus_y_pos -= amt >> 16;
samus_prev_y_pos = samus_y_pos;
return 0;
}
uint8 HandleCollDueToChangedPose_Block_NoColl(void) { // 0x91FF76
switch (solid_enemy_collision_flags) {
case 0:
return 0;
case 1:
samus_y_pos += samus_space_to_move_up_enemy;
samus_prev_y_pos = samus_y_pos;
return 0;
case 2:
samus_y_pos -= samus_space_to_move_down_enemy;
samus_prev_y_pos = samus_y_pos;
return 0;
case 3:
return HandleCollDueToChangedPose_Block_CollBoth();
default:
Unreachable();
return 0;
}
}
uint8 HandleCollDueToChangedPose_Block_CollBoth(void) { // 0x91FFA7
if (sign16(samus_y_radius - 8))
return 1;
samus_pose = (samus_pose_x_dir == 4) ? kPose_28_FaceL_Crouch : kPose_27_FaceR_Crouch;
uint16 r18 = kPoseParams[samus_pose].y_radius;
if (sign16(samus_y_radius - r18)) {
samus_y_pos += samus_y_radius - r18;
samus_prev_y_pos = samus_y_pos;
}
return 0;
}