1263 lines
43 KiB
C
1263 lines
43 KiB
C
#include "sm_cpu_infra.h"
|
|
#include "ida_types.h"
|
|
#include "variables.h"
|
|
#include "funcs.h"
|
|
|
|
#define g_off_9BA4B3 ((uint16*)RomPtr(0x9ba4b3))
|
|
#define g_off_9BA4CB ((uint16*)RomPtr(0x9ba4cb))
|
|
#define g_off_9BA4E3 ((uint16*)RomPtr(0x9ba4e3))
|
|
static const uint8 kDeathAnimationFrames[28] = {
|
|
5, 5, 5, 5, 1, 5, 5, 0, 1,
|
|
0, 5, 5, 5, 5, 5, 5, 5, 1,
|
|
1, 1, 5, 5, 5, 5, 5, 5, 5,
|
|
5,
|
|
};
|
|
#define g_off_9BB5C8 ((uint16*)RomPtr(0x9bb5c8))
|
|
#define g_byte_9BB823 ((uint8*)RomPtr(0x9bb823))
|
|
#define g_off_9BB6D2 ((uint16*)RomPtr(0x9bb6d2))
|
|
|
|
#define kDeathSequencePals_PowerSuit ((uint16*)RomPtr(0x9bb7d3))
|
|
#define kDeathSequencePals_VariaSuit ((uint16*)RomPtr(0x9bb7e7))
|
|
#define kDeathSequencePals_GravitySuit ((uint16*)RomPtr(0x9bb7fb))
|
|
#define kDeathSequencePals_Suitless ((uint16*)RomPtr(0x9bb80f))
|
|
#define g_off_9BC3C6 ((uint16*)RomPtr(0x9bc3c6))
|
|
#define g_off_9BC3EE ((uint16*)RomPtr(0x9bc3ee))
|
|
#define g_off_9BC416 ((uint16*)RomPtr(0x9bc416))
|
|
#define grapple_beam_special_angles ((GrappleBeamSpecialAngles*)RomPtr(0x9bc43e))
|
|
static const uint16 g_word_9BC118 = 24;
|
|
static const uint16 g_word_9BC11A = 0xc;
|
|
static const uint16 g_word_9BC11C = 5;
|
|
static const uint16 g_word_9BC11E = 0x480;
|
|
static const uint16 g_word_9BC120 = 0x300;
|
|
|
|
static const uint16 g_word_9BB7BF[5] = { 0x8400, 0x8800, 0x8c00, 0x9000, 0x8000 };
|
|
static const uint16 g_word_9BB7C9[5] = { 0x6200, 0x6400, 0x6600, 0x6800, 0x6000 };
|
|
static const uint16 kShadesOfWhite[22] = {
|
|
0x421, 0xc63, 0x14a5, 0x1ce7, 0x2529, 0x2d6b, 0x35ad, 0x4210,
|
|
0x4a52, 0x4e73, 0x5294, 0x56b5, 0x5ad6, 0x5ef7, 0x6318, 0x6739,
|
|
0x6b5a, 0x6f7b, 0x739c, 0x77bd, 0x7bde, 0x7fff,
|
|
};
|
|
static const uint8 kIsGrappleBannedForMovementType[28] = {
|
|
0, 0, 0, 1, 1, 0, 0, 1, 1, 1,
|
|
1, 0, 0, 1, 1, 1, 0, 1, 1, 1,
|
|
1, 0, 0, 1, 1, 1, 0, 1,
|
|
};
|
|
#define kGrappleBeam_SwingingData ((uint8*)RomPtr(0x9bc1c2))
|
|
#define kGrappleBeam_SwingingData2 ((uint8*)RomPtr(0x9bc2c2))
|
|
#define kGrappleBeam_SwingingData3 ((uint8*)RomPtr(0x9bc302))
|
|
#define kGrappleBeam_OriginX_NoRun ((uint16*)RomPtr(0x9bc122))
|
|
#define kGrappleBeam_OriginY_NoRun ((uint16*)RomPtr(0x9bc136))
|
|
#define kGrappleBeam_0x0d1a_offs_NoRun ((uint16*)RomPtr(0x9bc14a))
|
|
#define kGrappleBeam_0x0d1c_offs_NoRun ((uint16*)RomPtr(0x9bc15e))
|
|
#define kGrappleBeam_OriginX_Run ((uint16*)RomPtr(0x9bc172))
|
|
#define kGrappleBeam_OriginY_Run ((uint16*)RomPtr(0x9bc186))
|
|
#define kGrappleBeam_0x0d1a_offs_Run ((uint16*)RomPtr(0x9bc19a))
|
|
#define kGrappleBeam_0x0d1c_offs_Run ((uint16*)RomPtr(0x9bc1ae))
|
|
#define g_off_9BC344 (*(uint16*)RomPtr(0x9bc344))
|
|
#define g_off_9BC342 (*(uint16*)RomPtr(0x9bc342))
|
|
#define g_off_9BC346 ((uint16*)RomPtr(0x9bc346))
|
|
#define kFlareAnimDelays ((uint16*)RomPtr(0x90c481))
|
|
#define kFlareAnimDelays_Main ((uint8*)RomPtr(0x90c487))
|
|
#define kFlareAnimDelays_SlowSparks ((uint8*)RomPtr(0x90c4a7))
|
|
#define kFlareAnimDelays_FastSparks ((uint8*)RomPtr(0x90c4ae))
|
|
#define g_word_93A22B ((uint16*)RomPtr(0x93a22b))
|
|
#define g_word_93A225 ((uint16*)RomPtr(0x93a225))
|
|
#define g_byte_9BC9BA ((uint8*)RomPtr(0x9bc9ba))
|
|
#define g_byte_9BC9C4 ((uint8*)RomPtr(0x9bc9c4))
|
|
#define kGrappleBeam_Ext_Xvel ((uint16*)RomPtr(0x9bc0db))
|
|
#define kGrappleBeam_Ext_Yvel ((uint16*)RomPtr(0x9bc0ef))
|
|
#define kGrappleBeam_Init_EndAngle ((uint16*)RomPtr(0x9bc104))
|
|
|
|
void ProjectileTrail_Func5(uint16 k, uint16 j) { // 0x9BA3CC
|
|
ProjectileInsts_GetValue(k);
|
|
if ((ceres_status & 0x8000u) == 0) {
|
|
int v2 = k >> 1;
|
|
R18_ = projectile_x_pos[v2];
|
|
R20_ = projectile_y_pos[v2];
|
|
} else {
|
|
CalcExplosion_Mode7(k);
|
|
uint16 v10 = R18_;
|
|
R18_ = layer1_x_pos + R20_;
|
|
R20_ = layer1_y_pos + v10;
|
|
}
|
|
int v3 = k >> 1;
|
|
uint16 v4 = projectile_type[v3], v5;
|
|
if ((v4 & 0x20) != 0) {
|
|
v5 = g_off_9BA4E3[projectile_type[v3] & 0xF] + 2 * (projectile_dir[v3] & 0xF);
|
|
} else if ((v4 & 0x10) != 0) {
|
|
v5 = g_off_9BA4CB[projectile_type[v3] & 0xF] + 2 * (projectile_dir[v3] & 0xF);
|
|
} else {
|
|
v5 = g_off_9BA4B3[projectile_type[v3] & 0xF] + 2 * (projectile_dir[v3] & 0xF);
|
|
}
|
|
uint16 v6 = *(uint16 *)RomPtr_9B(v5) + 4 * R22_;
|
|
uint8 *p = RomPtr_9B(v6);
|
|
int v7 = j >> 1;
|
|
projectiletrail_left_y_pos[v7] = R20_ + (int8)p[1] - 4;
|
|
projectiletrail_left_x_pos[v7] = R18_ + (int8)p[0] - 4;
|
|
projectiletrail_right_y_pos[v7] = R20_ + (int8)p[3] - 4;
|
|
projectiletrail_right_x_pos[v7] = R18_ + (int8)p[2] - 4;
|
|
}
|
|
|
|
void StartSamusDeathAnimation(void) { // 0x9BB3A7
|
|
uint16 v0 = samus_movement_type;
|
|
if (samus_movement_type == 3)
|
|
QueueSfx1_Max6(0x32u);
|
|
uint16 v1 = kDeathAnimationFrames[v0];
|
|
if (samus_pose_x_dir == 4)
|
|
samus_pose = kPose_D8_FaceL_CrystalFlashEnd;
|
|
else
|
|
samus_pose = kPose_D7_FaceR_CrystalFlashEnd;
|
|
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_anim_frame_skip = 0;
|
|
samus_anim_frame = v1;
|
|
samus_x_pos -= layer1_x_pos;
|
|
samus_y_pos -= layer1_y_pos;
|
|
}
|
|
|
|
void DrawSamusStartingDeathAnim_(void) { // 0x9BB43C
|
|
Samus_DrawStartingDeathAnim();
|
|
}
|
|
|
|
uint16 HandleSamusDeathSequence(void) { // 0x9BB441
|
|
if (sign16(g_word_7E0DE6 - 4))
|
|
QueueTransferOfSamusDeathSequence(2 * g_word_7E0DE6);
|
|
if (sign16(++g_word_7E0DE6 - 60)) {
|
|
bool v0 = (--game_options_screen_index & 0x8000u) != 0;
|
|
if (!game_options_screen_index || v0) {
|
|
if (g_word_7E0DE4) {
|
|
g_word_7E0DE4 = 0;
|
|
game_options_screen_index = 3;
|
|
} else {
|
|
g_word_7E0DE4 = 1;
|
|
game_options_screen_index = 1;
|
|
}
|
|
CopyPalettesForSamusDeath(g_word_7E0DE4 * 2);
|
|
}
|
|
return 0;
|
|
} else {
|
|
HandleSamusDeathSequence_Helper2();
|
|
substate = (joypad2_last & 0xB0) == (kButton_A | kButton_L | kButton_R);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
void HandleSamusDeathSequence_Helper2(void) { // 0x9BB4B6
|
|
uint16 *v0 = (uint16 *)RomPtr_9B(g_off_9BB5C8[samus_suit_palette_index >> 1]);
|
|
uint16 *v1 = (uint16 *)RomPtr_9B(*v0);
|
|
palette_buffer[192] = *v1;
|
|
palette_buffer[193] = v1[1];
|
|
palette_buffer[194] = v1[2];
|
|
palette_buffer[195] = v1[3];
|
|
palette_buffer[196] = v1[4];
|
|
palette_buffer[197] = v1[5];
|
|
palette_buffer[198] = v1[6];
|
|
palette_buffer[199] = v1[7];
|
|
palette_buffer[200] = v1[8];
|
|
palette_buffer[201] = v1[9];
|
|
palette_buffer[202] = v1[10];
|
|
palette_buffer[203] = v1[11];
|
|
palette_buffer[204] = v1[12];
|
|
palette_buffer[205] = v1[13];
|
|
palette_buffer[206] = v1[14];
|
|
palette_buffer[207] = v1[15];
|
|
uint16 *v2 = (uint16 *)RomPtr_9B(0xA120);
|
|
palette_buffer[240] = *v2;
|
|
palette_buffer[241] = v2[1];
|
|
palette_buffer[242] = v2[2];
|
|
palette_buffer[243] = v2[3];
|
|
palette_buffer[244] = v2[4];
|
|
palette_buffer[245] = v2[5];
|
|
palette_buffer[246] = v2[6];
|
|
palette_buffer[247] = v2[7];
|
|
palette_buffer[248] = v2[8];
|
|
palette_buffer[249] = v2[9];
|
|
palette_buffer[250] = v2[10];
|
|
palette_buffer[251] = v2[11];
|
|
palette_buffer[252] = v2[12];
|
|
palette_buffer[253] = v2[13];
|
|
palette_buffer[254] = v2[14];
|
|
palette_buffer[255] = v2[15];
|
|
QueueTransferOfSamusDeathSequence(8);
|
|
game_options_screen_index = g_byte_9BB823[0];
|
|
g_word_7E0DE4 = 0;
|
|
g_word_7E0DE6 = 0;
|
|
GameState_24_SamusNoHealth_Explosion_2();
|
|
}
|
|
|
|
void CopyPalettesForSamusDeath(uint16 v0) { // 0x9BB5CE
|
|
R20_ = g_off_9BB6D2[samus_suit_palette_index >> 1];
|
|
R18_ = kDeathSequencePals_Suitless[v0 >> 1];
|
|
uint16 *v1 = (uint16 *)RomPtr_9B(R20_ + v0);
|
|
uint16 *v2 = (uint16 *)RomPtr_9B(*v1);
|
|
palette_buffer[192] = *v2;
|
|
palette_buffer[193] = v2[1];
|
|
palette_buffer[194] = v2[2];
|
|
palette_buffer[195] = v2[3];
|
|
palette_buffer[196] = v2[4];
|
|
palette_buffer[197] = v2[5];
|
|
palette_buffer[198] = v2[6];
|
|
palette_buffer[199] = v2[7];
|
|
palette_buffer[200] = v2[8];
|
|
palette_buffer[201] = v2[9];
|
|
palette_buffer[202] = v2[10];
|
|
palette_buffer[203] = v2[11];
|
|
palette_buffer[204] = v2[12];
|
|
palette_buffer[205] = v2[13];
|
|
palette_buffer[206] = v2[14];
|
|
palette_buffer[207] = v2[15];
|
|
uint16 *v3 = (uint16 *)RomPtr_9B(R18_);
|
|
palette_buffer[240] = *v3;
|
|
palette_buffer[241] = v3[1];
|
|
palette_buffer[242] = v3[2];
|
|
palette_buffer[243] = v3[3];
|
|
palette_buffer[244] = v3[4];
|
|
palette_buffer[245] = v3[5];
|
|
palette_buffer[246] = v3[6];
|
|
palette_buffer[247] = v3[7];
|
|
palette_buffer[248] = v3[8];
|
|
palette_buffer[249] = v3[9];
|
|
palette_buffer[250] = v3[10];
|
|
palette_buffer[251] = v3[11];
|
|
palette_buffer[252] = v3[12];
|
|
palette_buffer[253] = v3[13];
|
|
palette_buffer[254] = v3[14];
|
|
palette_buffer[255] = v3[15];
|
|
}
|
|
|
|
void QueueTransferOfSamusDeathSequence(uint16 v0) { // 0x9BB6D8
|
|
uint16 v1 = vram_write_queue_tail;
|
|
gVramWriteEntry(vram_write_queue_tail)->size = 1024;
|
|
v1 += 2;
|
|
int v2 = v0 >> 1;
|
|
gVramWriteEntry(v1)->size = g_word_9BB7BF[v2];
|
|
v1 += 2;
|
|
LOBYTE(gVramWriteEntry(v1++)->size) = -101;
|
|
gVramWriteEntry(v1)->size = g_word_9BB7C9[v2];
|
|
vram_write_queue_tail = v1 + 2;
|
|
}
|
|
|
|
uint16 GameState_24_SamusNoHealth_Explosion_Helper(void) { // 0x9BB701
|
|
GameState_24_SamusNoHealth_Explosion_1();
|
|
return GameState_24_SamusNoHealth_Explosion_2();
|
|
}
|
|
|
|
void GameState_24_SamusNoHealth_Explosion_1(void) { // 0x9BB710
|
|
*(VoidP *)((char *)&R0_.addr + 1) = 32256;
|
|
if (!substate && g_word_7E0DE4) {
|
|
uint16 v0 = 2 * g_word_7E0DE6;
|
|
R0_.addr = -16384;
|
|
uint16 v1 = 0;
|
|
do {
|
|
IndirWriteWord(&R0_, v1, kShadesOfWhite[v0 >> 1]);
|
|
v1 += 2;
|
|
} while ((int16)(v1 - 384) < 0);
|
|
uint16 v2 = 416;
|
|
do {
|
|
IndirWriteWord(&R0_, v2, kShadesOfWhite[v0 >> 1]);
|
|
v2 += 2;
|
|
} while ((int16)(v2 - 480) < 0);
|
|
if (sign16(g_word_7E0DE6 - 20))
|
|
++g_word_7E0DE6;
|
|
}
|
|
}
|
|
|
|
uint16 GameState_24_SamusNoHealth_Explosion_2(void) { // 0x9BB758
|
|
bool v0 = (--game_options_screen_index & 0x8000u) != 0;
|
|
if (!game_options_screen_index || v0) {
|
|
if (!sign16(++g_word_7E0DE4 - 9)) {
|
|
g_word_7E0DE6 = 21;
|
|
GameState_24_SamusNoHealth_Explosion_1();
|
|
substate = 0;
|
|
return 1;
|
|
}
|
|
if (!substate || sign16(g_word_7E0DE4 - 2)) {
|
|
game_options_screen_index = g_byte_9BB823[(uint16)(2 * g_word_7E0DE4)];
|
|
CopyPalettesForSamusDeath(2 * g_byte_9BB823[(uint16)(2 * g_word_7E0DE4) + 1]);
|
|
} else {
|
|
game_options_screen_index = g_byte_9BB823[(uint16)(2 * g_word_7E0DE4)];
|
|
}
|
|
}
|
|
DrawSamusSuitExploding();
|
|
return 0;
|
|
}
|
|
|
|
void CancelGrappleBeamIfIncompatiblePose(void) { // 0x9BB861
|
|
int16 v0;
|
|
|
|
if (kIsGrappleBannedForMovementType[samus_movement_type]) {
|
|
LABEL_2:
|
|
if (grapple_beam_function != (uint16)FUNC16(GrappleBeamFunc_Inactive))
|
|
grapple_beam_function = FUNC16(GrappleBeamFunc_Cancel);
|
|
return;
|
|
}
|
|
if (grapple_beam_function != (uint16)FUNC16(GrappleBeamFunc_Inactive)
|
|
&& sign16(grapple_beam_function + 0x3882)) {
|
|
v0 = *(&kPoseParams[0].direction_shots_fired + (uint16)(8 * samus_pose));
|
|
if ((v0 & 0xF0) == 0) {
|
|
if (v0 == grapple_beam_direction)
|
|
return;
|
|
if (grapple_varCF6) {
|
|
QueueSfx1_Max6(7u);
|
|
grapple_beam_function = FUNC16(GrappleBeamFunc_FireGoToCancel);
|
|
return;
|
|
}
|
|
}
|
|
goto LABEL_2;
|
|
}
|
|
}
|
|
|
|
void UNUSED_sub_9BB8D5(void) { // 0x9BB8D5
|
|
int16 v0;
|
|
|
|
v0 = *(&kPoseParams[0].direction_shots_fired + (uint16)(8 * samus_pose));
|
|
if ((v0 & 0xF0) == 0 && v0 != grapple_beam_direction)
|
|
grapple_beam_direction = *(&kPoseParams[0].direction_shots_fired + (uint16)(8 * samus_pose));
|
|
}
|
|
|
|
uint8 CheckIfGrappleIsConnectedToBlock(void) { // 0x9BB8F1
|
|
grapple_beam_extension_x_velocity = 0;
|
|
grapple_beam_extension_y_velocity = 0;
|
|
if ((BlockReactGrapple() & 1) == 0)
|
|
return 0;
|
|
samus_grapple_flags = 1;
|
|
return 1;
|
|
}
|
|
|
|
int ProcessEnemyGrappleBeamColl(uint16 a) { // 0x9BB907
|
|
int16 v1;
|
|
uint16 v3;
|
|
|
|
v1 = 2 * a;
|
|
switch (v1) {
|
|
case 0:
|
|
case 4:
|
|
return -1; // clc
|
|
case 6:
|
|
return 1;
|
|
case 2:
|
|
case 8:
|
|
case 10:
|
|
return 0;
|
|
}
|
|
if (v1 != 12) {
|
|
Unreachable();
|
|
while (1);
|
|
}
|
|
R18_ = *((uint16 *)RomPtr_A0(R18_) + 3);
|
|
if ((equipped_items & 0x20) != 0) {
|
|
R18_ >>= 1;
|
|
R18_ >>= 1;
|
|
v3 = R18_;
|
|
} else {
|
|
if (equipped_items & 1)
|
|
R18_ >>= 1;
|
|
v3 = R18_;
|
|
}
|
|
Samus_DealDamage(v3);
|
|
samus_invincibility_timer = 96;
|
|
samus_knockback_timer = 5;
|
|
knockback_x_dir = samus_pose_x_dir == 4;
|
|
return 1;
|
|
}
|
|
|
|
void CallGrappleNextFunc(uint32 ea) {
|
|
switch (ea) {
|
|
case fnGrappleNext_SwingClockwise: GrappleNext_SwingClockwise(); return;
|
|
case fnGrappleNext_SwingAntiClockwise: GrappleNext_SwingAntiClockwise(); return;
|
|
case fnGrappleNext_StandAimRight: GrappleNext_StandAimRight(); return;
|
|
case fnGrappleNext_StandAimDownRight: GrappleNext_StandAimDownRight(); return;
|
|
case fnGrappleNext_StandAimDownLeft: GrappleNext_StandAimDownLeft(); return;
|
|
case fnGrappleNext_StandAimLeft: GrappleNext_StandAimLeft(); return;
|
|
case fnGrappleNext_CrouchAimRight: GrappleNext_CrouchAimRight(); return;
|
|
case fnGrappleNext_CrouchAimDownRight: GrappleNext_CrouchAimDownRight(); return;
|
|
case fnGrappleNext_CrouchAimDownLeft: GrappleNext_CrouchAimDownLeft(); return;
|
|
case fnGrappleNext_CrouchAimLeft: GrappleNext_CrouchAimLeft(); return;
|
|
default: Unreachable();
|
|
}
|
|
}
|
|
|
|
void HandleConnectingGrapple(void) { // 0x9BB97C
|
|
if (samus_movement_type == kMovementType_1A_GrabbedByDraygon) {
|
|
grapple_beam_function = FUNC16(GrappleBeamFunc_ConnectedLockedInPlace);
|
|
grapple_beam_length_delta = 0;
|
|
} else {
|
|
uint16 v0 = 4 * grapple_beam_direction;
|
|
if (samus_y_speed || samus_y_subspeed) {
|
|
int v2 = v0 >> 1;
|
|
grapple_beam_function = g_off_9BC3EE[v2];
|
|
grapple_beam_tmpD82 = g_off_9BC3EE[v2 + 1];
|
|
CallGrappleNextFunc(grapple_beam_tmpD82 | 0x9B0000);
|
|
} else {
|
|
int v1 = v0 >> 1;
|
|
if (samus_movement_type == 5) {
|
|
grapple_beam_function = g_off_9BC416[v1];
|
|
grapple_beam_tmpD82 = g_off_9BC416[v1 + 1];
|
|
} else {
|
|
grapple_beam_function = g_off_9BC3C6[v1];
|
|
grapple_beam_tmpD82 = g_off_9BC3C6[v1 + 1];
|
|
}
|
|
CallGrappleNextFunc(grapple_beam_tmpD82 | 0x9B0000);
|
|
}
|
|
}
|
|
}
|
|
|
|
void GrappleNext_SwingClockwise(void) { // 0x9BB9D9
|
|
samus_new_pose_interrupted = kPose_B2_FaceR_Grapple_Air;
|
|
HandleConnectingGrapple_Swinging();
|
|
}
|
|
|
|
void GrappleNext_SwingAntiClockwise(void) { // 0x9BB9E2
|
|
samus_new_pose_interrupted = kPose_B3_FaceL_Grapple_Air;
|
|
HandleConnectingGrapple_Swinging();
|
|
}
|
|
|
|
void GrappleNext_StandAimRight(void) { // 0x9BB9EA
|
|
samus_new_pose_interrupted = kPose_A8_FaceR_Grappling;
|
|
HandleConnectingGrapple_StuckInPlace();
|
|
}
|
|
|
|
void GrappleNext_StandAimDownRight(void) { // 0x9BB9F3
|
|
samus_new_pose_interrupted = kPose_AA_FaceR_Grappling_AimDR;
|
|
HandleConnectingGrapple_StuckInPlace();
|
|
}
|
|
|
|
void GrappleNext_StandAimDownLeft(void) { // 0x9BB9FC
|
|
samus_new_pose_interrupted = kPose_AB_FaceL_Grappling_AimDL;
|
|
HandleConnectingGrapple_StuckInPlace();
|
|
}
|
|
|
|
void GrappleNext_StandAimLeft(void) { // 0x9BBA05
|
|
samus_new_pose_interrupted = kPose_A9_FaceL_Grappling;
|
|
HandleConnectingGrapple_StuckInPlace();
|
|
}
|
|
|
|
void GrappleNext_CrouchAimRight(void) { // 0x9BBA0E
|
|
samus_new_pose_interrupted = kPose_B4_FaceR_Grappling_Crouch;
|
|
HandleConnectingGrapple_StuckInPlace();
|
|
}
|
|
|
|
void GrappleNext_CrouchAimDownRight(void) { // 0x9BBA17
|
|
samus_new_pose_interrupted = kPose_B6_FaceR_Grappling_Crouch_AimDR;
|
|
HandleConnectingGrapple_StuckInPlace();
|
|
}
|
|
|
|
void GrappleNext_CrouchAimDownLeft(void) { // 0x9BBA20
|
|
samus_new_pose_interrupted = kPose_B7_FaceL_Grappling_Crouch_AimDL;
|
|
HandleConnectingGrapple_StuckInPlace();
|
|
}
|
|
|
|
void GrappleNext_CrouchAimLeft(void) { // 0x9BBA29
|
|
samus_new_pose_interrupted = kPose_B5_FaceL_Grappling_Crouch;
|
|
HandleConnectingGrapple_StuckInPlace();
|
|
}
|
|
|
|
void UNUSED_sub_9BBA31(void) { // 0x9BBA31
|
|
samus_new_pose_interrupted = 172;
|
|
HandleConnectingGrapple_StuckInPlace();
|
|
}
|
|
|
|
void HandleConnectingGrapple_Swinging(void) { // 0x9BBA61
|
|
char v1; // t0
|
|
|
|
samus_special_transgfx_index = 9;
|
|
R18_ = samus_x_pos - grapple_beam_end_x_pos;
|
|
R20_ = samus_y_pos - grapple_beam_end_y_pos;
|
|
uint16 v0 = CalculateAngleFromXY();
|
|
v1 = v0;
|
|
LOBYTE(v0) = HIBYTE(v0);
|
|
HIBYTE(v0) = v1;
|
|
*(uint16 *)&grapple_beam_end_subangle = v0;
|
|
grapple_beam_end_angles_mirror = v0;
|
|
grapple_beam_length_delta = 0;
|
|
if (!sign16(grapple_beam_length - 64))
|
|
grapple_beam_length -= 24;
|
|
BlockFunc_AC11();
|
|
}
|
|
|
|
void HandleConnectingGrapple_StuckInPlace(void) { // 0x9BBA9B
|
|
char v1; // t0
|
|
|
|
samus_special_transgfx_index = 10;
|
|
R18_ = samus_x_pos - grapple_beam_end_x_pos;
|
|
R20_ = samus_y_pos - grapple_beam_end_y_pos;
|
|
uint16 v0 = CalculateAngleFromXY();
|
|
v1 = v0;
|
|
LOBYTE(v0) = HIBYTE(v0);
|
|
HIBYTE(v0) = v1;
|
|
*(uint16 *)&grapple_beam_end_subangle = v0;
|
|
grapple_beam_end_angles_mirror = v0;
|
|
grapple_beam_length_delta = 0;
|
|
if (!sign16(grapple_beam_length - 64))
|
|
grapple_beam_length -= 24;
|
|
BlockFunc_AC11();
|
|
}
|
|
|
|
uint8 HandleSpecialGrappleBeamAngles(void) { // 0x9BBAD5
|
|
int16 v2;
|
|
int16 v3;
|
|
|
|
uint16 v0 = 7;
|
|
while (*(uint16 *)&grapple_beam_end_subangle != grapple_beam_special_angles[v0].field_0) {
|
|
if ((--v0 & 0x8000u) != 0)
|
|
return 0;
|
|
}
|
|
samus_new_pose_interrupted = grapple_beam_special_angles[v0].field_2;
|
|
samus_x_pos = grapple_beam_end_x_pos + grapple_beam_special_angles[v0].field_4;
|
|
samus_y_pos = grapple_beam_end_y_pos + grapple_beam_special_angles[v0].field_6;
|
|
grapple_beam_function = grapple_beam_special_angles[v0].field_8;
|
|
samus_special_transgfx_index = 0;
|
|
slow_grabble_scrolling_flag = 0;
|
|
v2 = samus_x_pos - samus_prev_x_pos;
|
|
if ((int16)(samus_x_pos - samus_prev_x_pos) < 0) {
|
|
if (sign16(v2 + 12))
|
|
samus_prev_x_pos = samus_x_pos + 12;
|
|
} else if (!sign16(v2 - 13)) {
|
|
samus_prev_x_pos = samus_x_pos - 12;
|
|
}
|
|
v3 = samus_y_pos - samus_prev_y_pos;
|
|
if ((int16)(samus_y_pos - samus_prev_y_pos) < 0) {
|
|
if (sign16(v3 + 12))
|
|
samus_prev_y_pos = samus_y_pos + 12;
|
|
} else if (!sign16(v3 - 13)) {
|
|
samus_prev_y_pos = samus_y_pos - 12;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
void GrappleBeamFunc_BB64(void) { // 0x9BBB64
|
|
if ((joypad1_newkeys & kButton_Up) != 0) {
|
|
if (grapple_beam_length)
|
|
grapple_beam_length_delta = -2;
|
|
} else if ((joypad1_newkeys & kButton_Down) != 0) {
|
|
if (sign16(grapple_beam_length - 64))
|
|
grapple_beam_length_delta = 2;
|
|
else
|
|
grapple_beam_length = 64;
|
|
}
|
|
if (sign16((grapple_beam_end_angle << 8) - 0x4000) || !sign16((grapple_beam_end_angle << 8) + 0x4000))
|
|
goto LABEL_13;
|
|
if ((joypad1_lastkeys & 0x200) != 0) {
|
|
if (grapple_beam_end_angle << 8 == 0x8000 && !grapple_beam_unkD26)
|
|
grapple_beam_unkD26 = 256;
|
|
if (grapple_beam_flags && (grapple_beam_flags & 1) != 0)
|
|
grapple_beam_unkD2A = g_word_9BC11A >> 1;
|
|
else
|
|
grapple_beam_unkD2A = g_word_9BC11A;
|
|
} else {
|
|
if ((joypad1_lastkeys & 0x100) == 0) {
|
|
LABEL_13:
|
|
grapple_beam_unkD2A = 0;
|
|
return;
|
|
}
|
|
if (grapple_beam_end_angle << 8 == 0x8000 && !grapple_beam_unkD26)
|
|
grapple_beam_unkD26 = -256;
|
|
if (grapple_beam_flags && (grapple_beam_flags & 1) != 0)
|
|
grapple_beam_unkD2A = -(g_word_9BC11A >> 1);
|
|
else
|
|
grapple_beam_unkD2A = -g_word_9BC11A;
|
|
}
|
|
}
|
|
|
|
void GrappleBeamFunc_BC1F(void) { // 0x9BBC1F
|
|
if ((*(uint16 *)&grapple_beam_end_subangle & 0xC000) == 0xC000) {
|
|
grapple_beam_unkD2C = -(g_word_9BC11C >> 2);
|
|
if (grapple_beam_flags && (grapple_beam_flags & 1) != 0)
|
|
grapple_beam_unkD28 = -(g_word_9BC118 >> 3);
|
|
else
|
|
grapple_beam_unkD28 = -(g_word_9BC118 >> 2);
|
|
} else if (*(int16 *)&grapple_beam_end_subangle < 0) {
|
|
if (grapple_beam_end_angle << 8 == 0x8000) {
|
|
grapple_beam_unkD28 = 0;
|
|
grapple_beam_unkD2C = 0;
|
|
uint16 v0 = grapple_beam_unkD26;
|
|
if ((grapple_beam_unkD26 & 0x8000u) != 0)
|
|
v0 = ~(grapple_beam_unkD26 - 1);
|
|
if (sign16(HIBYTE(v0) - 1))
|
|
grapple_beam_unkD26 = 0;
|
|
} else {
|
|
grapple_beam_unkD2C = -g_word_9BC11C;
|
|
if (grapple_beam_flags && (grapple_beam_flags & 1) != 0)
|
|
grapple_beam_unkD28 = -(g_word_9BC118 >> 1);
|
|
else
|
|
grapple_beam_unkD28 = -g_word_9BC118;
|
|
}
|
|
} else if ((*(uint16 *)&grapple_beam_end_subangle & 0x4000) != 0) {
|
|
grapple_beam_unkD2C = g_word_9BC11C;
|
|
if (grapple_beam_flags && (grapple_beam_flags & 1) != 0)
|
|
grapple_beam_unkD28 = g_word_9BC118 >> 1;
|
|
else
|
|
grapple_beam_unkD28 = g_word_9BC118;
|
|
} else {
|
|
grapple_beam_unkD2C = g_word_9BC11C >> 2;
|
|
if (grapple_beam_flags && (grapple_beam_flags & 1) != 0)
|
|
grapple_beam_unkD28 = g_word_9BC118 >> 3;
|
|
else
|
|
grapple_beam_unkD28 = g_word_9BC118 >> 2;
|
|
}
|
|
}
|
|
|
|
void GrappleBeamFunc_BCFF(void) { // 0x9BBCFF
|
|
grapple_beam_unkD26 += grapple_beam_unkD2A + grapple_beam_unkD28;
|
|
if (((grapple_beam_unkD26 ^ *(uint16 *)&grapple_beam_end_subangle) & 0x8000u) != 0)
|
|
grapple_beam_unkD26 += grapple_beam_unkD2C;
|
|
if ((grapple_beam_unkD26 & 0x8000u) == 0) {
|
|
if (grapple_beam_unkD26 >= g_word_9BC11E)
|
|
grapple_beam_unkD26 = g_word_9BC11E;
|
|
} else if ((uint16)-grapple_beam_unkD26 >= g_word_9BC11E) {
|
|
grapple_beam_unkD26 = -g_word_9BC11E;
|
|
}
|
|
}
|
|
|
|
void GrappleBeamFunc_BD44(void) { // 0x9BBD44
|
|
if (grapple_beam_unkD30 && (button_config_jump_a & joypad1_newkeys) != 0) {
|
|
if (grapple_beam_unkD26) {
|
|
if ((grapple_beam_unkD26 & 0x8000u) != 0) {
|
|
if (grapple_beam_flags && (grapple_beam_flags & 1) != 0)
|
|
grapple_beam_unkD2E = -(g_word_9BC120 >> 1);
|
|
else
|
|
grapple_beam_unkD2E = -g_word_9BC120;
|
|
} else if (grapple_beam_flags && (grapple_beam_flags & 1) != 0) {
|
|
grapple_beam_unkD2E = g_word_9BC120 >> 1;
|
|
} else {
|
|
grapple_beam_unkD2E = g_word_9BC120;
|
|
}
|
|
} else {
|
|
grapple_beam_unkD2E = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void GrappleBeamFunc_BD95(void) { // 0x9BBD95
|
|
uint16 v0 = abs16(grapple_beam_unkD26);
|
|
uint16 v1;
|
|
|
|
if (!sign16(v0 - 64)) {
|
|
slow_grabble_scrolling_flag = 1;
|
|
LABEL_7:
|
|
samus_anim_frame_timer = 15;
|
|
v1 = kGrappleBeam_SwingingData[HIBYTE(grapple_beam_end_angles_mirror)];
|
|
samus_anim_frame = v1;
|
|
goto LABEL_8;
|
|
}
|
|
slow_grabble_scrolling_flag = 0;
|
|
if (grapple_beam_end_angle << 8 != 0x8000)
|
|
goto LABEL_7;
|
|
if (sign16(samus_anim_frame - 64)) {
|
|
samus_anim_frame_timer = 8;
|
|
samus_anim_frame = 64;
|
|
}
|
|
v1 = kGrappleBeam_SwingingData[HIBYTE(grapple_beam_end_angles_mirror)];
|
|
LABEL_8:;
|
|
uint16 v2 = 2 * v1;
|
|
if ((abs16(grapple_beam_unkD2E) & 0xFF00) == 256) {
|
|
uint16 v3 = samus_anim_frame;
|
|
if (!sign16(samus_anim_frame - 64))
|
|
v3 = 16;
|
|
samus_anim_frame = v3 + 32;
|
|
}
|
|
if (samus_pose_x_dir == 4) {
|
|
samus_x_pos = x_pos_of_start_of_grapple_beam + (int8)kGrappleBeam_SwingingData2[v2];
|
|
samus_y_pos = y_pos_of_start_of_grapple_beam + (int8)kGrappleBeam_SwingingData2[v2 + 1];
|
|
} else {
|
|
samus_x_pos = x_pos_of_start_of_grapple_beam + (int8)kGrappleBeam_SwingingData3[v2];
|
|
samus_y_pos = y_pos_of_start_of_grapple_beam + (int8)kGrappleBeam_SwingingData3[v2 + 1];
|
|
}
|
|
x_pos_of_start_of_grapple_beam_prevframe = x_pos_of_start_of_grapple_beam;
|
|
y_pos_of_start_of_grapple_beam_prevframe = y_pos_of_start_of_grapple_beam;
|
|
GrappleBeamFunc_BE98();
|
|
}
|
|
|
|
void GrappleBeamFunc_BE98(void) { // 0x9BBE98
|
|
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 GrappleBeamFunc_BEEB(void) { // 0x9BBEEB
|
|
int v0 = grapple_beam_direction;
|
|
samus_x_pos = x_pos_of_start_of_grapple_beam - kGrappleBeam_OriginX_NoRun[v0];
|
|
x_pos_of_start_of_grapple_beam_prevframe = kGrappleBeam_0x0d1a_offs_NoRun[v0] + samus_x_pos;
|
|
samus_y_pos = y_pos_of_start_of_grapple_beam - kGrappleBeam_OriginY_NoRun[v0];
|
|
y_pos_of_start_of_grapple_beam_prevframe = kGrappleBeam_0x0d1c_offs_NoRun[v0] + samus_y_pos;
|
|
}
|
|
|
|
void GrappleBeamFunc_BF1B(void) { // 0x9BBF1B
|
|
R22_ = *(&kPoseParams[0].y_offset_to_gfx + (uint16)(8 * samus_pose));
|
|
uint16 v0 = 2 * grapple_beam_direction;
|
|
if (samus_pose == kPose_49_FaceL_Moonwalk || samus_pose == kPose_4A_FaceR_Moonwalk || samus_movement_type != 1) {
|
|
int v1 = v0 >> 1;
|
|
x_pos_of_start_of_grapple_beam = kGrappleBeam_OriginX_NoRun[v1] + samus_x_pos;
|
|
x_pos_of_start_of_grapple_beam_prevframe = kGrappleBeam_0x0d1a_offs_NoRun[v1] + samus_x_pos;
|
|
y_pos_of_start_of_grapple_beam = kGrappleBeam_OriginY_NoRun[v1] + samus_y_pos - R22_;
|
|
y_pos_of_start_of_grapple_beam_prevframe = kGrappleBeam_0x0d1c_offs_NoRun[v1] + samus_y_pos - R22_;
|
|
} else {
|
|
int v2 = v0 >> 1;
|
|
x_pos_of_start_of_grapple_beam = kGrappleBeam_OriginX_Run[v2] + samus_x_pos;
|
|
x_pos_of_start_of_grapple_beam_prevframe = kGrappleBeam_0x0d1a_offs_Run[v2] + samus_x_pos;
|
|
y_pos_of_start_of_grapple_beam = kGrappleBeam_OriginY_Run[v2] + samus_y_pos - R22_;
|
|
y_pos_of_start_of_grapple_beam_prevframe = kGrappleBeam_0x0d1c_offs_Run[v2] + samus_y_pos - R22_;
|
|
}
|
|
}
|
|
|
|
void UpdateGrappleBeamTilesAndIncrFlameCtr(void) { // 0x9BBFA5
|
|
UpdateGrappleBeamTiles();
|
|
if (sign16(flare_counter - 120))
|
|
++flare_counter;
|
|
}
|
|
|
|
void UpdateGrappleBeamTiles(void) { // 0x9BBFBD
|
|
if ((--grapple_point_anim_timer & 0x8000u) != 0) {
|
|
grapple_point_anim_timer = 5;
|
|
grapple_point_anim_ptr += 512;
|
|
if ((int16)(grapple_point_anim_ptr - g_off_9BC344) >= 0)
|
|
grapple_point_anim_ptr = g_off_9BC342;
|
|
}
|
|
uint16 v0 = vram_write_queue_tail;
|
|
gVramWriteEntry(vram_write_queue_tail)->size = 32;
|
|
v0 += 2;
|
|
gVramWriteEntry(v0)->size = grapple_point_anim_ptr;
|
|
v0 += 2;
|
|
LOBYTE(gVramWriteEntry(v0++)->size) = -102;
|
|
gVramWriteEntry(v0)->size = 25088;
|
|
vram_write_queue_tail = v0 + 2;
|
|
uint16 v1 = (grapple_beam_end_angle >> 1) & 0xFE;
|
|
v0 += 2;
|
|
gVramWriteEntry(v0)->size = 128;
|
|
v0 += 2;
|
|
gVramWriteEntry(v0)->size = g_off_9BC346[v1 >> 1];
|
|
v0 += 2;
|
|
LOBYTE(gVramWriteEntry(v0++)->size) = -102;
|
|
gVramWriteEntry(v0)->size = 25104;
|
|
vram_write_queue_tail = v0 + 2;
|
|
}
|
|
|
|
void HandleGrappleBeamFlare(void) { // 0x9BC036
|
|
if (flare_counter) {
|
|
if (flare_counter == 1) {
|
|
flare_animation_frame = 16;
|
|
flare_animation_timer = 3;
|
|
}
|
|
if ((--flare_animation_timer & 0x8000u) != 0) {
|
|
uint16 v0 = ++flare_animation_frame;
|
|
if (kFlareAnimDelays_Main[flare_animation_frame] == 254) {
|
|
R18_ = kFlareAnimDelays_Main[(uint16)(flare_animation_frame + 1)];
|
|
flare_animation_frame -= R18_;
|
|
v0 = flare_animation_frame;
|
|
}
|
|
flare_animation_timer = kFlareAnimDelays_Main[v0];
|
|
}
|
|
if (samus_pose_x_dir == 4)
|
|
R22_ = flare_animation_frame + g_word_93A22B[0];
|
|
else
|
|
R22_ = flare_animation_frame + g_word_93A225[0];
|
|
R20_ = x_pos_of_start_of_grapple_beam_prevframe - layer1_x_pos;
|
|
R18_ = y_pos_of_start_of_grapple_beam_prevframe - layer1_y_pos;
|
|
if (((y_pos_of_start_of_grapple_beam_prevframe - layer1_y_pos) & 0xFF00) != 0)
|
|
;
|
|
else
|
|
DrawBeamGrappleSpritemap(R22_);
|
|
}
|
|
}
|
|
|
|
void CallGrappleBeamFunc(uint32 ea) {
|
|
switch (ea) {
|
|
case fnGrappleBeamFunc_BB64: GrappleBeamFunc_BB64(); return;
|
|
case fnGrappleBeamFunc_BC1F: GrappleBeamFunc_BC1F(); return;
|
|
case fnGrappleBeamFunc_BCFF: GrappleBeamFunc_BCFF(); return;
|
|
case fnGrappleBeamFunc_BD44: GrappleBeamFunc_BD44(); return;
|
|
case fnGrappleBeamFunc_BD95: GrappleBeamFunc_BD95(); return;
|
|
case fnGrappleBeamFunc_BE98: GrappleBeamFunc_BE98(); return;
|
|
case fnGrappleBeamFunc_BEEB: GrappleBeamFunc_BEEB(); return;
|
|
case fnGrappleBeamFunc_BF1B: GrappleBeamFunc_BF1B(); return;
|
|
case fnGrappleBeamFunc_Inactive: GrappleBeamFunc_Inactive(); return;
|
|
case fnGrappleBeamFunc_FireGoToCancel: GrappleBeamFunc_FireGoToCancel(); return;
|
|
case fnGrappleBeamFunc_Firing: GrappleBeamFunc_Firing(); return;
|
|
case fnGrappleBeamFunc_ConnectedLockedInPlace: GrappleBeamFunc_ConnectedLockedInPlace(); return;
|
|
case fnGrappleBeamFunc_Connected_Swinging: GrappleBeamFunc_Connected_Swinging(); return;
|
|
case fnGrappleBeamFunc_Wallgrab: GrappleBeamFunc_Wallgrab(); return;
|
|
case fnGrappleBeamFunc_C832: GrappleBeamFunc_C832(); return;
|
|
case fnGrappleBeamFunc_Cancel: GrappleBeamFunc_Cancel(); return;
|
|
case fnGrappleBeamFunc_C9CE: GrappleBeamFunc_C9CE(); return;
|
|
case fnGrappleBeamFunc_ReleaseFromSwing: GrappleBeamFunc_ReleaseFromSwing(); return;
|
|
case fnGrappleBeam_Func2: GrappleBeam_Func2(); return;
|
|
default: Unreachable();
|
|
}
|
|
}
|
|
|
|
void GrappleBeamHandler(void) { // 0x9BC490
|
|
if (grapple_varCF6)
|
|
--grapple_varCF6;
|
|
samus_grapple_flags &= ~1u;
|
|
CancelGrappleBeamIfIncompatiblePose();
|
|
CallGrappleBeamFunc(grapple_beam_function | 0x9B0000);
|
|
if (grapple_beam_function != (uint16)FUNC16(GrappleBeamFunc_Inactive)
|
|
&& sign16(grapple_beam_function + 0x37AA)
|
|
&& (samus_suit_palette_index & 4) == 0
|
|
&& fx_type
|
|
&& (Samus_GetTopBottomBoundary(), (fx_y_pos & 0x8000u) == 0)
|
|
&& sign16(fx_y_pos - R18_)) {
|
|
grapple_beam_flags |= 1u;
|
|
} else {
|
|
grapple_beam_flags &= ~1u;
|
|
}
|
|
}
|
|
|
|
void GrappleBeamFunc_Inactive(void) { // 0x9BC4F0
|
|
if ((button_config_shoot_x & joypad1_newkeys) != 0 || (button_config_shoot_x & joypad1_newinput_samusfilter) != 0) {
|
|
GrappleBeamFunc_FireGoToCancel();
|
|
} else if (flare_counter) {
|
|
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();
|
|
}
|
|
}
|
|
|
|
void GrappleBeamFunc_FireGoToCancel(void) { // 0x9BC51E
|
|
int v0;
|
|
if (samus_pose == kPose_F0_FaceR_Draygon_Move || samus_pose == kPose_BE_FaceL_Draygon_Move) {
|
|
v0 = CheckBannedDraygonGrappleDirs(samus_pose);
|
|
if (!(v0 & 0x80000000))
|
|
goto LABEL_4;
|
|
} else {
|
|
R22_ = *(&kPoseParams[0].y_offset_to_gfx + (uint16)(8 * samus_pose));
|
|
v0 = *(&kPoseParams[0].direction_shots_fired + (uint16)(8 * samus_pose));
|
|
if ((v0 & 0xF0) != 0) {
|
|
LABEL_4:
|
|
grapple_beam_function = FUNC16(GrappleBeamFunc_Cancel);
|
|
return;
|
|
}
|
|
}
|
|
grapple_beam_direction = v0;
|
|
int v1 = v0;
|
|
grapple_beam_extension_x_velocity = kGrappleBeam_Ext_Xvel[v1];
|
|
grapple_beam_extension_y_velocity = kGrappleBeam_Ext_Yvel[v1];
|
|
*(uint16 *)&grapple_beam_end_subangle = kGrappleBeam_Init_EndAngle[v1];
|
|
grapple_beam_end_angles_mirror = *(uint16 *)&grapple_beam_end_subangle;
|
|
grapple_varCF6 = 10;
|
|
if (samus_pose == kPose_49_FaceL_Moonwalk || samus_pose == kPose_4A_FaceR_Moonwalk || samus_movement_type != 1) {
|
|
grapple_beam_origin_x_offset = kGrappleBeam_OriginX_NoRun[v1];
|
|
grapple_beam_origin_y_offset = kGrappleBeam_OriginY_NoRun[v1] - R22_;
|
|
grapple_beam_end_x_pos = kGrappleBeam_OriginX_NoRun[v1] + samus_x_pos;
|
|
x_pos_of_start_of_grapple_beam = grapple_beam_end_x_pos;
|
|
x_pos_of_start_of_grapple_beam_prevframe = kGrappleBeam_0x0d1a_offs_NoRun[v1] + samus_x_pos;
|
|
grapple_beam_end_y_pos = kGrappleBeam_OriginY_NoRun[v1] + samus_y_pos - R22_;
|
|
y_pos_of_start_of_grapple_beam = grapple_beam_end_y_pos;
|
|
y_pos_of_start_of_grapple_beam_prevframe = kGrappleBeam_0x0d1c_offs_NoRun[v1] + samus_y_pos - R22_;
|
|
} else {
|
|
grapple_beam_origin_x_offset = kGrappleBeam_OriginX_Run[v1];
|
|
grapple_beam_origin_y_offset = kGrappleBeam_OriginY_Run[v1] - R22_;
|
|
grapple_beam_end_x_pos = kGrappleBeam_OriginX_Run[v1] + samus_x_pos;
|
|
x_pos_of_start_of_grapple_beam = grapple_beam_end_x_pos;
|
|
x_pos_of_start_of_grapple_beam_prevframe = kGrappleBeam_0x0d1a_offs_Run[v1] + samus_x_pos;
|
|
grapple_beam_end_y_pos = kGrappleBeam_OriginY_Run[v1] + samus_y_pos - R22_;
|
|
y_pos_of_start_of_grapple_beam = grapple_beam_end_y_pos;
|
|
y_pos_of_start_of_grapple_beam_prevframe = kGrappleBeam_0x0d1c_offs_Run[v1] + samus_y_pos - R22_;
|
|
}
|
|
grapple_beam_end_x_subpos = 0;
|
|
grapple_beam_end_y_subpos = 0;
|
|
grapple_beam_end_x_suboffset = 0;
|
|
grapple_beam_end_x_offset = 0;
|
|
grapple_beam_end_y_suboffset = 0;
|
|
grapple_beam_end_y_offset = 0;
|
|
grapple_beam_flags = 0;
|
|
grapple_beam_length_delta = 12;
|
|
grapple_beam_length = 0;
|
|
grapple_beam_unkD26 = 0;
|
|
grapple_beam_unkD28 = 0;
|
|
grapple_beam_unkD2A = 0;
|
|
grapple_beam_unkD2C = 0;
|
|
grapple_beam_unkD2E = 0;
|
|
grapple_beam_unkD30 = 0;
|
|
grapple_beam_unkD1E = 0;
|
|
grapple_beam_unkD20 = 0;
|
|
grapple_beam_unkD3A = 2;
|
|
grapple_beam_unkD3C = 0;
|
|
grapple_point_anim_timer = 5;
|
|
grapple_point_anim_ptr = g_off_9BC342;
|
|
grapple_beam_tmpD82 = 0;
|
|
grapple_beam_tmpD84 = 0;
|
|
grapple_beam_y_quarter_subvel = 0;
|
|
grapple_beam_y_quarter_vel = 0;
|
|
grapple_beam_tmpD8A = 0;
|
|
grapple_beam_varD8C = 0;
|
|
grapple_beam_varD8E = 0;
|
|
grapple_beam_grapple_start_x = 0;
|
|
grapple_beam_unkD38 = 0;
|
|
grapple_beam_unkD36 = 0;
|
|
slow_grabble_scrolling_flag = 0;
|
|
GrappleFunc_AF87();
|
|
samus_draw_handler = FUNC16(sub_90EB86);
|
|
grapple_walljump_timer = 0;
|
|
LoadProjectilePalette(2u);
|
|
palette_buffer[223] = 32657;
|
|
grapple_beam_function = FUNC16(GrappleBeamFunc_Firing);
|
|
QueueSfx1_Max1(5u);
|
|
flare_counter = 1;
|
|
play_resume_charging_beam_sfx = 0;
|
|
if (samus_movement_handler == FUNC16(Samus_MoveHandler_ReleaseFromGrapple))
|
|
samus_movement_handler = FUNC16(Samus_MovementHandler_Normal);
|
|
}
|
|
|
|
int CheckBannedDraygonGrappleDirs(uint16 a) { // 0x9BC6B2
|
|
if (a == kPose_BE_FaceL_Draygon_Move) {
|
|
R22_ = 6;
|
|
if ((joypad1_lastkeys & kButton_Left) != 0) {
|
|
if ((joypad1_lastkeys & kButton_Down) != 0)
|
|
return -2147483642;
|
|
if ((joypad1_lastkeys & kButton_Up) != 0)
|
|
return -2147483640;
|
|
}
|
|
return -2147483641;
|
|
}
|
|
R22_ = 6;
|
|
if ((joypad1_lastkeys & kButton_Right) == 0)
|
|
return -2147483646;
|
|
if ((joypad1_lastkeys & kButton_Down) != 0)
|
|
return -2147483645;
|
|
if ((joypad1_lastkeys & kButton_Up) == 0)
|
|
return -2147483646;
|
|
return -2147483647;
|
|
}
|
|
|
|
uint8 ClearCarry_12(void) { // 0x9BC701
|
|
return 0;
|
|
}
|
|
|
|
void GrappleBeamFunc_Firing(void) { // 0x9BC703
|
|
if ((button_config_shoot_x & joypad1_lastkeys) == 0) {
|
|
grapple_beam_function = FUNC16(GrappleBeamFunc_Cancel);
|
|
return;
|
|
}
|
|
grapple_beam_length += grapple_beam_length_delta;
|
|
if (!sign16(grapple_beam_length - 128)) {
|
|
grapple_beam_function = FUNC16(GrappleBeamFunc_Cancel);
|
|
return;
|
|
}
|
|
int v1 = ProcessEnemyGrappleBeamColl(GrappleBeam_CollDetect_Enemy());
|
|
if (v1 >= 0) {
|
|
if (v1) {
|
|
grapple_beam_function = FUNC16(GrappleBeamFunc_Cancel);
|
|
return;
|
|
}
|
|
} else {
|
|
uint8 v2 = BlockCollGrappleBeam();
|
|
if ((v2 & 1) == 0)
|
|
return;
|
|
if ((v2 & 0x40) == 0) {
|
|
grapple_beam_function = FUNC16(GrappleBeamFunc_Cancel);
|
|
return;
|
|
}
|
|
}
|
|
QueueSfx1_Max6(6u);
|
|
HandleConnectingGrapple();
|
|
grapple_beam_length_delta = -8;
|
|
samus_grapple_flags |= 1u;
|
|
}
|
|
|
|
void UNUSED_sub_9BC759(void) { // 0x9BC759
|
|
if ((button_config_shoot_x & joypad1_lastkeys) == 0
|
|
|| (grapple_beam_length -= grapple_beam_length_delta, sign16(grapple_beam_length - 13))) {
|
|
grapple_beam_function = FUNC16(GrappleBeamFunc_Cancel);
|
|
} else {
|
|
BlockCollGrappleBeam();
|
|
}
|
|
}
|
|
|
|
void GrappleBeamFunc_ConnectedLockedInPlace(void) { // 0x9BC77E
|
|
if ((button_config_shoot_x & joypad1_lastkeys) != 0
|
|
&& (GrappleBeam_CollDetect_Enemy() || CheckIfGrappleIsConnectedToBlock() & 1)) {
|
|
ClearCarry_11();
|
|
} else {
|
|
grapple_beam_function = FUNC16(GrappleBeamFunc_Cancel);
|
|
}
|
|
}
|
|
|
|
void GrappleBeamFunc_Connected_Swinging(void) { // 0x9BC79D
|
|
if ((button_config_shoot_x & joypad1_lastkeys) != 0) {
|
|
GrappleBeamFunc_BB64();
|
|
if (grapple_beam_length_delta)
|
|
BlockFunc_AC31();
|
|
GrappleBeamFunc_BC1F();
|
|
GrappleBeamFunc_BCFF();
|
|
GrappleBeamFunc_BD44();
|
|
HandleMovementAndCollForSamusGrapple();
|
|
if ((grapple_beam_unkD36 & 0x8000u) != 0 && HandleSpecialGrappleBeamAngles() & 1) {
|
|
ClearCarry_11();
|
|
return;
|
|
}
|
|
if (GrappleBeam_CollDetect_Enemy()) {
|
|
grapple_beam_flags |= 0x8000u;
|
|
} else if (!(CheckIfGrappleIsConnectedToBlock() & 1)) {
|
|
goto LABEL_2;
|
|
}
|
|
BlockFunc_AC11();
|
|
ClearCarry_11();
|
|
GrappleBeamFunc_BD95();
|
|
return;
|
|
}
|
|
LABEL_2:
|
|
if (grapple_beam_unkD26 || *(uint16 *)&grapple_beam_end_subangle != 0x8000) {
|
|
PropelSamusFromGrappleSwing();
|
|
grapple_beam_function = FUNC16(GrappleBeamFunc_ReleaseFromSwing);
|
|
samus_movement_handler = FUNC16(Samus_MoveHandler_ReleaseFromGrapple);
|
|
} else {
|
|
grapple_beam_function = FUNC16(GrappleBeam_Func2);
|
|
}
|
|
}
|
|
|
|
void GrappleBeamFunc_Wallgrab(void) { // 0x9BC814
|
|
if ((button_config_shoot_x & joypad1_lastkeys) != 0 && CheckIfGrappleIsConnectedToBlock() & 1) {
|
|
ClearCarry_11();
|
|
} else {
|
|
grapple_walljump_timer = 30;
|
|
grapple_beam_function = FUNC16(GrappleBeamFunc_C832);
|
|
}
|
|
}
|
|
|
|
void GrappleBeamFunc_C832(void) { // 0x9BC832
|
|
if ((--grapple_walljump_timer & 0x8000u) == 0) {
|
|
R18_ = 16;
|
|
R20_ = 0;
|
|
if (Samus_GrappleWallJumpCheck() & 1)
|
|
grapple_beam_function = FUNC16(GrappleBeamFunc_C9CE);
|
|
} else {
|
|
grapple_beam_function = FUNC16(GrappleBeam_Func2);
|
|
}
|
|
}
|
|
|
|
void GrappleBeamFunc_Cancel(void) { // 0x9BC856
|
|
QueueSfx1_Max15(7u);
|
|
if (samus_movement_type == kMovementType_16_Grappling)
|
|
Samus_Pose_CancelGrapple();
|
|
else
|
|
CallSomeSamusCode(0x1Cu);
|
|
grapple_beam_unkD1E = 0;
|
|
grapple_beam_unkD20 = 0;
|
|
grapple_beam_direction = 0;
|
|
grapple_beam_unkD36 = 0;
|
|
grapple_walljump_timer = 0;
|
|
slow_grabble_scrolling_flag = 0;
|
|
grapple_varCF6 = 0;
|
|
grapple_beam_flags = 0;
|
|
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;
|
|
LoadProjectilePalette(equipped_beams);
|
|
grapple_beam_function = FUNC16(GrappleBeamFunc_Inactive);
|
|
samus_draw_handler = FUNC16(SamusDrawHandler_Default);
|
|
Samus_PostGrappleCollisionDetect();
|
|
if (samus_auto_cancel_hud_item_index) {
|
|
hud_item_index = 0;
|
|
samus_auto_cancel_hud_item_index = 0;
|
|
}
|
|
}
|
|
|
|
void GrappleBeam_Func2(void) { // 0x9BC8C5
|
|
QueueSfx1_Max15(7u);
|
|
if (samus_pose == kPose_B2_FaceR_Grapple_Air)
|
|
goto LABEL_5;
|
|
if (samus_pose == kPose_B3_FaceL_Grapple_Air) {
|
|
LABEL_6:
|
|
samus_new_pose_transitional = kPose_02_FaceL_Normal;
|
|
goto LABEL_15;
|
|
}
|
|
if (sign16(samus_y_radius - 17)) {
|
|
if ((*(&kPoseParams[0].direction_shots_fired + (uint16)(8 * samus_pose)) & 0xF0) != 0) {
|
|
if (samus_pose_x_dir == 4)
|
|
samus_new_pose_transitional = kPose_28_FaceL_Crouch;
|
|
else
|
|
samus_new_pose_transitional = kPose_27_FaceR_Crouch;
|
|
} else {
|
|
samus_new_pose_transitional = g_byte_9BC9C4[*(&kPoseParams[0].direction_shots_fired
|
|
+ (uint16)(8 * samus_pose))];
|
|
}
|
|
goto LABEL_15;
|
|
}
|
|
if ((*(&kPoseParams[0].direction_shots_fired + (uint16)(8 * samus_pose)) & 0xF0) != 0) {
|
|
if (samus_pose_x_dir != 4) {
|
|
LABEL_5:
|
|
samus_new_pose_transitional = kPose_01_FaceR_Normal;
|
|
goto LABEL_15;
|
|
}
|
|
goto LABEL_6;
|
|
}
|
|
samus_new_pose_transitional = g_byte_9BC9BA[*(&kPoseParams[0].direction_shots_fired
|
|
+ (uint16)(8 * samus_pose))];
|
|
LABEL_15:
|
|
samus_hurt_switch_index = 0;
|
|
input_to_pose_calc = 1;
|
|
samus_x_base_speed = 0;
|
|
samus_x_base_subspeed = 0;
|
|
samus_y_subspeed = 0;
|
|
samus_y_speed = 0;
|
|
grapple_beam_unkD1E = 0;
|
|
grapple_beam_unkD20 = 0;
|
|
grapple_beam_direction = 0;
|
|
grapple_beam_unkD36 = 0;
|
|
grapple_walljump_timer = 0;
|
|
slow_grabble_scrolling_flag = 0;
|
|
grapple_varCF6 = 0;
|
|
grapple_beam_flags = 0;
|
|
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;
|
|
LoadProjectilePalette(equipped_beams);
|
|
grapple_beam_function = FUNC16(GrappleBeamFunc_Inactive);
|
|
samus_draw_handler = FUNC16(SamusDrawHandler_Default);
|
|
Samus_PostGrappleCollisionDetect();
|
|
if (samus_auto_cancel_hud_item_index) {
|
|
hud_item_index = 0;
|
|
samus_auto_cancel_hud_item_index = 0;
|
|
}
|
|
}
|
|
|
|
void GrappleBeamFunc_C9CE(void) { // 0x9BC9CE
|
|
QueueSfx1_Max15(7u);
|
|
if (samus_pose_x_dir == 8)
|
|
samus_new_pose_transitional = kPose_84_FaceL_Walljump;
|
|
else
|
|
samus_new_pose_transitional = kPose_83_FaceR_Walljump;
|
|
samus_hurt_switch_index = 6;
|
|
samus_x_accel_mode = 0;
|
|
samus_collides_with_solid_enemy = 0;
|
|
samus_is_falling_flag = 0;
|
|
UNUSED_word_7E0B1A = 0;
|
|
UNUSED_word_7E0B2A = 0;
|
|
samus_y_subspeed = 0;
|
|
samus_y_speed = 0;
|
|
samus_y_dir = 0;
|
|
UNUSED_word_7E0B38 = 0;
|
|
samus_x_base_speed = 0;
|
|
samus_x_base_subspeed = 0;
|
|
grapple_beam_unkD1E = 0;
|
|
grapple_beam_unkD20 = 0;
|
|
grapple_beam_direction = 0;
|
|
grapple_beam_unkD36 = 0;
|
|
grapple_walljump_timer = 0;
|
|
slow_grabble_scrolling_flag = 0;
|
|
grapple_varCF6 = 0;
|
|
grapple_beam_flags = 0;
|
|
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;
|
|
LoadProjectilePalette(equipped_beams);
|
|
grapple_beam_function = FUNC16(GrappleBeamFunc_Inactive);
|
|
samus_draw_handler = FUNC16(SamusDrawHandler_Default);
|
|
Samus_PostGrappleCollisionDetect();
|
|
if (samus_auto_cancel_hud_item_index) {
|
|
hud_item_index = 0;
|
|
samus_auto_cancel_hud_item_index = 0;
|
|
}
|
|
}
|
|
|
|
void PropelSamusFromGrappleSwing(void) { // 0x9BCA65
|
|
int16 v1;
|
|
int16 v2;
|
|
uint16 v0;
|
|
|
|
if ((grapple_beam_unkD26 & 0x8000u) == 0) {
|
|
v0 = 2 * grapple_beam_unkD26;
|
|
v2 = kSinCosTable8bit_Sext[((uint16)(2 * HIBYTE(*(uint16 *)&grapple_beam_end_subangle)) >> 1) + 64];
|
|
if (v2 >= 0) {
|
|
Multiply16x16(v2, v0);
|
|
samus_y_subspeed = mult_product_lo;
|
|
samus_y_speed = mult_product_hi;
|
|
samus_y_dir = 2;
|
|
} else {
|
|
Multiply16x16(-v2, v0);
|
|
samus_y_subspeed = mult_product_lo;
|
|
samus_y_speed = mult_product_hi;
|
|
samus_y_dir = 1;
|
|
}
|
|
} else {
|
|
v0 = -2 * grapple_beam_unkD26;
|
|
v1 = kSinCosTable8bit_Sext[((uint16)(2 * HIBYTE(*(uint16 *)&grapple_beam_end_subangle)) >> 1) + 64];
|
|
if (v1 < 0) {
|
|
Multiply16x16(-v1, v0);
|
|
samus_y_subspeed = mult_product_lo;
|
|
samus_y_speed = mult_product_hi;
|
|
samus_y_dir = 2;
|
|
} else {
|
|
Multiply16x16(v1, v0);
|
|
samus_y_subspeed = mult_product_lo;
|
|
samus_y_speed = mult_product_hi;
|
|
samus_y_dir = 1;
|
|
}
|
|
}
|
|
samus_x_accel_mode = 2;
|
|
R18_ = 3 * (v0 >> 9);
|
|
R18_ = 64 - R18_;
|
|
uint16 v3 = abs16(kSinCosTable8bit_Sext[((uint16)(2 * (uint8)(grapple_beam_end_angle - R18_)) >> 1) + 64]);
|
|
Multiply16x16(v3, v0);
|
|
samus_x_base_subspeed = mult_product_lo;
|
|
samus_x_base_speed = mult_product_hi;
|
|
}
|
|
|
|
void GrappleBeamFunc_ReleaseFromSwing(void) { // 0x9BCB8B
|
|
QueueSfx1_Max15(7u);
|
|
if ((grapple_beam_unkD26 & 0x8000u) == 0)
|
|
samus_new_pose_transitional = kPose_52_FaceL_Jump_NoAim_MoveF;
|
|
else
|
|
samus_new_pose_transitional = kPose_51_FaceR_Jump_NoAim_MoveF;
|
|
samus_hurt_switch_index = 7;
|
|
grapple_beam_unkD1E = 0;
|
|
grapple_beam_unkD20 = 0;
|
|
grapple_beam_direction = 0;
|
|
grapple_beam_unkD36 = 0;
|
|
grapple_walljump_timer = 0;
|
|
slow_grabble_scrolling_flag = 0;
|
|
grapple_varCF6 = 0;
|
|
grapple_beam_flags = 0;
|
|
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;
|
|
LoadProjectilePalette(equipped_beams);
|
|
grapple_beam_function = FUNC16(GrappleBeamFunc_Inactive);
|
|
samus_draw_handler = FUNC16(SamusDrawHandler_Default);
|
|
Samus_PostGrappleCollisionDetect();
|
|
if (samus_auto_cancel_hud_item_index) {
|
|
hud_item_index = 0;
|
|
samus_auto_cancel_hud_item_index = 0;
|
|
}
|
|
}
|