Files
sm-vita/src/sm_82.c
2023-03-06 03:23:18 +01:00

5566 lines
163 KiB
C

// Top level main game routines
#include "sm_rtl.h"
#include "ida_types.h"
#include "variables.h"
#include "funcs.h"
#include "enemy_types.h"
#define kDemoRoomData ((uint16*)RomPtr(0x82876c))
void CallDemoRoomDataFunc(uint32 ea) {
switch (ea) {
case fnDemoRoom_ChargeBeamRoomScroll21: DemoRoom_ChargeBeamRoomScroll21(); return;
case fnnullsub_291: return;
case fnDemoRoom_SetBG2TilemapBase: DemoRoom_SetBG2TilemapBase(); return;
case fnDemoRoom_SetKraidFunctionTimer: DemoRoom_SetKraidFunctionTimer(); return;
case fnDemoRoom_SetBrinstarBossBits: DemoRoom_SetBrinstarBossBits(); return;
default: Unreachable();
}
}
CoroutineRet InitAndLoadGameData_Async(void) { // 0x828000
int16 v0;
int16 v2;
int16 v4;
int16 v7;
COROUTINE_BEGIN(coroutine_state_1, 0)
if (game_state == kGameState_40_TransitionToDemo) {
InitIoForGameplay();
LoadStdBG3andSpriteTilesClearTilemaps();
LoadInitialPalette();
Samus_Initialize();
LoadDemoRoomData();
} else {
if (loading_game_state != kLoadingGameState_5_Main) {
if (loading_game_state == kLoadingGameState_1F_StartingAtCeres) {
area_index = 6;
load_station_index = 0;
ClearTimerRam();
} else if (loading_game_state == kLoadingGameState_22_EscapingCeres) {
area_index = 0;
load_station_index = 18;
LoadMirrorOfExploredMapTiles();
}
}
InitIoForGameplay();
LoadStdBG3andSpriteTilesClearTilemaps();
LoadInitialPalette();
Samus_Initialize();
LoadFromLoadStation();
}
COROUTINE_AWAIT(1, StartGameplay_Async());
InitializeHud();
// nullsub_4();
{
v0 = 32;
uint16 v1 = 0;
do {
target_palettes[(v1 >> 1) + 192] = palette_buffer[(v1 >> 1) + 192];
v1 += 2;
v0 -= 2;
} while (v0);
}
screen_fade_delay = 1;
screen_fade_counter = 1;
EnableNMI();
EnableEnemyProjectiles();
EnablePLMs();
EnablePaletteFx();
EnableHdmaObjects();
EnableAnimtiles();
SetLiquidPhysicsType();
if (game_state == kGameState_40_TransitionToDemo) {
loop_counter_transfer_enemies_to_vram = 6;
do {
TransferEnemyTilesToVramAndInit();
COROUTINE_AWAIT(2, WaitForNMI_Async());
--loop_counter_transfer_enemies_to_vram;
} while ((loop_counter_transfer_enemies_to_vram & 0x8000u) == 0);
R18_ = 18 * (demo_scene - 1);
R18_ = get_DemoRoomData(R18_ + kDemoRoomData[demo_set])->demo_code_ptr;
CallDemoRoomDataFunc(R18_ | 0x820000);
++game_state;
v7 = 512;
uint16 v8 = 0;
do {
palette_buffer[v8 >> 1] = target_palettes[v8 >> 1];
v8 += 2;
v7 -= 2;
} while (v7);
} else if (loading_game_state == kLoadingGameState_22_EscapingCeres) {
QueueMusic_Delayed8(5u);
loop_counter_transfer_enemies_to_vram = 15;
do {
TransferEnemyTilesToVramAndInit();
COROUTINE_AWAIT(3, WaitForNMI_Async());
--loop_counter_transfer_enemies_to_vram;
} while ((loop_counter_transfer_enemies_to_vram & 0x8000u) == 0);
++game_state;
v2 = 512;
uint16 v3 = 0;
do {
palette_buffer[v3 >> 1] = target_palettes[v3 >> 1];
v3 += 2;
v2 -= 2;
} while (v2);
} else {
loop_counter_transfer_enemies_to_vram = 6;
do {
TransferEnemyTilesToVramAndInit();
COROUTINE_AWAIT(4, WaitForNMI_Async());
--loop_counter_transfer_enemies_to_vram;
} while ((loop_counter_transfer_enemies_to_vram & 0x8000u) == 0);
game_state = kGameState_7_MainGameplayFadeIn;
v4 = 512;
uint16 v5 = 0;
do {
palette_buffer[v5 >> 1] = target_palettes[v5 >> 1];
v5 += 2;
v4 -= 2;
} while (v4);
if (loading_game_state == kLoadingGameState_1F_StartingAtCeres) {
palette_buffer[223] = 0;
CallSomeSamusCode(8u);
} else {
CallSomeSamusCode(9u);
}
}
COROUTINE_END(0);
}
void InitIoForGameplay(void) { // 0x82819B
InitCpuForGameplay();
InitPpuForGameplay();
}
void InitCpuForGameplay(void) { // 0x8281A4
WriteReg(NMITIMEN, 1u);
reg_NMITIMEN = 1;
WriteReg(WRIO, 0);
WriteReg(WRMPYA, 0);
WriteReg(WRMPYB, 0);
WriteReg(WRDIVL, 0);
WriteReg(WRDIVH, 0);
WriteReg(WRDIVB, 0);
WriteReg(HTIMEL, 0);
WriteReg(HTIMEH, 0);
WriteReg(VTIMEL, 0);
WriteReg(VTIMEH, 0);
WriteReg(MDMAEN, 0);
WriteReg(HDMAEN, 0);
reg_HDMAEN = 0;
WriteReg(MEMSEL, 1u);
reg_MEMSEL = 1;
}
void InitPpuForGameplay(void) { // 0x8281DD
WriteReg(INIDISP, 0x80);
reg_INIDISP = 0x80;
WriteReg(OBSEL, 3u);
reg_OBSEL = 3;
WriteReg(OAMADDL, 0);
LOBYTE(reg_OAMaddr_UNUSED) = 0;
WriteReg(OAMADDH, 0x80);
HIBYTE(reg_OAMaddr_UNUSED) = 0x80;
WriteReg(OAMDATA, 0);
WriteReg(OAMDATA, 0);
WriteReg(BGMODE, 9u);
reg_BGMODE = 9;
WriteReg(MOSAIC, 0);
reg_MOSAIC = 0;
reg_BG12NBA = 0;
WriteReg(BG12NBA, 0);
reg_BG34NBA = 4;
WriteReg(BG34NBA, 4u);
reg_BG1SC = 81;
WriteReg(BG1SC, 0x51u);
reg_BG2SC = 73;
WriteReg(BG2SC, 0x49u);
reg_BG3SC = 90;
WriteReg(BG3SC, 0x5Au);
reg_BG4SC = 0;
WriteReg(BG4SC, 0);
WriteReg(VMAIN, 0);
WriteReg(W12SEL, 0);
reg_W12SEL = 0;
WriteReg(W12SEL, 0);
reg_W12SEL = 0;
WriteReg(W34SEL, 0);
reg_W34SEL = 0;
WriteReg(WOBJSEL, 0);
reg_WOBJSEL = 0;
WriteReg(WH0, 0);
reg_WH0 = 0;
WriteReg(WH1, 0);
reg_WH1 = 0;
WriteReg(WH2, 0);
reg_WH2 = 0;
WriteReg(WH3, 0);
reg_WH3 = 0;
WriteReg(WBGLOG, 0);
reg_WBGLOG = 0;
WriteReg(WOBJLOG, 0);
reg_WOBJLOG = 0;
WriteReg(TM, 0x17u);
reg_TM = 23;
WriteReg(TMW, 0);
reg_TMW = 0;
WriteReg(TS, 0);
reg_TS = 0;
WriteReg(TSW, 0);
reg_TSW = 0;
WriteReg(CGWSEL, 0);
next_gameplay_CGWSEL = 0;
WriteReg(CGADSUB, 0);
next_gameplay_CGADSUB = 0;
WriteReg(COLDATA, 0xE0u);
WriteReg(SETINI, 0);
reg_SETINI = 0;
oam_next_ptr = 0;
memset7E(ADDR16_OF_RAM(ram3000), 0, 0x7FEu);
memset7E(ADDR16_OF_RAM(ram4000), 0x6Fu, 0x7FEu);
memset7E(ADDR16_OF_RAM(ram4000.bg2_tilemap), 0x2C0Fu, 0xFEu);
}
#define kInitialPalette ((uint16*)RomPtr(0x9a8000))
void LoadInitialPalette(void) { // 0x8282C5
int16 v0;
v0 = 512;
uint16 v1 = 0;
do {
palette_buffer[v1 >> 1] = kInitialPalette[v1 >> 1];
v1 += 2;
v0 -= 2;
} while (v0);
}
void LoadStdBG3andSpriteTilesClearTilemaps(void) { // 0x8282E2
WriteReg(VMADDL, 0);
WriteReg(VMADDH, 0x40u);
WriteReg(VMAIN, 0x80);
static const StartDmaCopy unk_8282F8 = { 1, 1, 0x18, LONGPTR(0x9ab200), 0x2000 };
SetupDmaTransfer(&unk_8282F8);
WriteReg(MDMAEN, 2u);
WriteReg(VMADDL, 0);
WriteReg(VMADDH, 0x60u);
WriteReg(VMAIN, 0x80);
static const StartDmaCopy unk_828318 = { 1, 1, 0x18, LONGPTR(0x9ad200), 0x4000 };
SetupDmaTransfer(&unk_828318);
WriteReg(MDMAEN, 2u);
WriteReg(VMADDL, 0);
WriteReg(VMADDH, 0x50u);
WriteReg(VMAIN, 0x80);
static const StartDmaCopy unk_828338 = { 1, 1, 0x18, LONGPTR(0x7e4000), 0x1000 };
SetupDmaTransfer(&unk_828338);
WriteReg(MDMAEN, 2u);
WriteReg(VMADDL, 0);
WriteReg(VMADDH, 0x58u);
WriteReg(VMAIN, 0x80);
static const StartDmaCopy unk_828358 = { 1, 1, 0x18, LONGPTR(0x7e4000), 0x0800 };
SetupDmaTransfer(&unk_828358);
WriteReg(MDMAEN, 2u);
}
CoroutineRet GameState_32_MadeItToCeresElevator(void) { // 0x828367
if (timer_status)
DrawTimer();
GameState_8_MainGameplay();
bool v0 = (--reached_ceres_elevator_fade_timer & 0x8000u) != 0;
if (!reached_ceres_elevator_fade_timer || v0) {
++game_state;
screen_fade_delay = 0;
screen_fade_counter = 0;
}
return kCoroutineNone;
}
CoroutineRet GameState_33_BlackoutFromCeres(void) { // 0x828388
if (timer_status)
DrawTimer();
GameState_8_MainGameplay();
HandleFadeOut();
if (reg_INIDISP == 0x80) {
EnableNMI();
WaitUntilEndOfVblankAndClearHdma();
DisableIrqInterrupts();
fx_layer_blending_config_a = 0;
cur_irq_handler = 0;
next_gameplay_CGWSEL = 0;
next_gameplay_CGADSUB = 0;
reg_TM = 16;
reg_TS = 0;
reg_TMW = 0;
reg_TSW = 0;
reg_BGMODE = 9;
screen_fade_delay = 0;
screen_fade_counter = 0;
loading_game_state = kLoadingGameState_22_EscapingCeres;
game_state = 34;
SaveToSram(selected_save_slot);
cinematic_function = FUNC16(CinematicFunctionBlackoutFromCeres);
ceres_status = 0;
timer_status = 0;
QueueMusic_Delayed8(0);
QueueSfx1_Max15(2u);
QueueSfx2_Max15(0x71u);
QueueSfx3_Max15(1u);
}
return kCoroutineNone;
}
CoroutineRet GameState_35_TimeUp(void) { // 0x828411
GameState_8_MainGameplay();
palette_change_denom = 8;
if (AdvancePaletteFadeForAllPalettes()) {
game_state = kGameState_36_WhitingOutFromTimeUp;
screen_fade_delay = 0;
screen_fade_counter = 0;
}
return kCoroutineNone;
}
CoroutineRet GameState_36_WhitingOutFromTimeUp(void) { // 0x828431
HandleFadeOut();
if (reg_INIDISP == 0x80) {
EnableNMI();
WaitUntilEndOfVblankAndClearHdma();
DisableIrqInterrupts();
fx_layer_blending_config_a = 0;
cur_irq_handler = 0;
next_gameplay_CGWSEL = 0;
next_gameplay_CGADSUB = 0;
reg_TM = 16;
reg_TS = 0;
reg_TMW = 0;
reg_TSW = 0;
reg_BGMODE = 9;
screen_fade_delay = 0;
screen_fade_counter = 0;
ceres_status = 0;
timer_status = 0;
QueueSfx1_Max15(2u);
QueueSfx2_Max15(0x71u);
QueueSfx3_Max15(1u);
if (CheckEventHappened(0xEu)) {
game_options_screen_index = 0;
menu_index = 0;
for (int i = 254; i >= 0; i -= 2)
enemy_projectile_y_subpos[(i >> 1) + 15] = 0;
game_state = kGameState_25_SamusNoHealth;
} else {
game_state = kGameState_37_CeresGoesBoomWithSamus;
cinematic_function = FUNC16(CinematicFunctionBlackoutFromCeres);
}
}
return kCoroutineNone;
}
CoroutineRet GameState_38_SamusEscapesFromZebes(void) { // 0x8284BD
GameState_8_MainGameplay();
HandleFadeOut();
if (reg_INIDISP == 0x80) {
EnableNMI();
WaitUntilEndOfVblankAndClearHdma();
DisableIrqInterrupts();
fx_layer_blending_config_a = 0;
next_gameplay_CGWSEL = 0;
next_gameplay_CGADSUB = 0;
reg_TM = 16;
reg_TS = 0;
reg_TMW = 0;
reg_TSW = 0;
reg_BGMODE = 9;
screen_fade_delay = 0;
screen_fade_counter = 0;
game_state = kGameState_39_EndingAndCredits;
cinematic_function = FUNC16(CinematicFunctionEscapeFromCebes);
timer_status = 0;
QueueMusic_Delayed8(0);
QueueSfx1_Max15(2u);
QueueSfx2_Max15(0x71u);
QueueSfx3_Max15(1u);
}
return kCoroutineNone;
}
CoroutineRet GameState_41_TransitionToDemo(void) { // 0x82852D
GameState_8_MainGameplay();
HdmaObjectHandler();
++game_state;
reg_INIDISP = 15;
return kCoroutineNone;
}
CoroutineRet GameState_42_PlayingDemo_Async(void) { // 0x828548
COROUTINE_BEGIN(coroutine_state_3, 0)
// assert(0);
GameState_8_MainGameplay();
if (joypad1_newkeys) {
substate = 1;
goto LABEL_10;
}
demo_timer--;
if (!demo_timer || (demo_timer & 0x8000u) != 0) {
substate = 0;
my_counter = 90;
while (1) {
COROUTINE_AWAIT(1, WaitForNMI_Async());
if (joypad1_newkeys)
break;
if (!--my_counter)
goto LABEL_10;
}
substate = 1;
LABEL_10:
++game_state;
debug_disable_sounds = 0;
reg_INIDISP = 0x80;
screen_fade_delay = 1;
screen_fade_counter = 1;
}
COROUTINE_END(0);
}
CoroutineRet GameState_43_TransitionFromDemo(void) { // 0x828593
if (substate != 1)
CheckForNextDemo();
EnableNMI();
++game_state;
screen_fade_delay = 0;
screen_fade_counter = 0;
WaitUntilEndOfVblankAndClearHdma();
DisableIrqInterrupts();
fx_layer_blending_config_a = 0;
cur_irq_handler = 0;
irqhandler_next_handler = 0;
DisablePaletteFx();
ClearPaletteFXObjects();
for (int i = 656; i >= 0; i -= 2)
*(uint16 *)((char *)&enemy_projectile_enable_flag + i) = 0;
for (int j = 538; j >= 0; j -= 2)
*(uint16 *)((char *)&hud_item_tilemap_palette_bits + j) = 0;
next_gameplay_CGWSEL = 0;
next_gameplay_CGADSUB = 0;
reg_TM = 16;
reg_TS = 0;
reg_TMW = 0;
reg_TSW = 0;
return kCoroutineNone;
}
CoroutineRet GameState_44_TransitionFromDemo(void) { // 0x8285FB
game_state = kGameState_1_OpeningCinematic;
if ((substate & 0x8000u) != 0) {
game_state = kGameState_40_TransitionToDemo;
} else if (substate) {
LoadTitleSequenceGraphics();
enemy_projectile_x_pos[4] = 2;
cinematic_function = FUNC16(CinematicFunctionNone);
} else {
QueueMusic_Delayed8(0);
debug_disable_sounds = 0;
cinematic_function = FUNC16(CinematicFunctionOpening);
}
return kCoroutineNone;
}
#define kDemoRoomData ((uint16*)RomPtr(0x82876c))
void CheckForNextDemo(void) { // 0x828637
R18_ = 2 * (demo_scene + 8 * demo_scene);
if (*(uint16 *)RomPtr_82(R18_ + kDemoRoomData[demo_set]) == 0xFFFF) {
substate = 0;
uint16 v0 = demo_set + 1;
if ((uint16)(demo_set + 1) >= num_demo_sets)
v0 = 0;
demo_set = v0;
demo_scene = 0;
} else {
substate = 0x8000;
}
}
void LoadDemoRoomData(void) { // 0x828679
DemoRoomData *drd;
door_def_ptr = 0;
R18_ = 18 * demo_scene;
drd = get_DemoRoomData(18 * demo_scene + kDemoRoomData[demo_set]);
room_ptr = drd->room_ptr_;
door_def_ptr = drd->door_ptr;
door_bts = drd->door_slot;
layer1_x_pos = drd->screen_x_pos;
bg1_x_offset = layer1_x_pos;
layer1_y_pos = drd->screen_y_pos;
bg1_y_offset = layer1_y_pos;
samus_y_pos = layer1_y_pos + drd->samus_x_offs;
samus_prev_y_pos = samus_y_pos;
samus_x_pos = drd->samus_y_offs + layer1_x_pos + 128;
samus_prev_x_pos = samus_x_pos;
demo_timer = drd->demo_length;
LOBYTE(area_index) = get_RoomDefHeader(room_ptr)->area_index_;
reg_BG1HOFS = 0;
reg_BG1VOFS = 0;
++demo_scene;
uint16 v1 = 0;
do {
int v2 = v1 >> 1;
WORD(room_chozo_bits[v1]) = -1;
*(uint16 *)&item_bit_array[v1] = -1;
UNUSED_word_7ED8F0[v2] = -1;
*(uint16 *)&map_station_byte_array[v1] = -1;
*(uint16 *)&used_save_stations_and_elevators[v1] = -1;
*(uint16 *)&used_save_stations_and_elevators[v1 + 8] = -1;
WORD(opened_door_bit_array[v1]) = 0;
WORD(events_that_happened[v1]) = 0;
*(uint16 *)&boss_bits_for_area[v1] = 0;
v1 += 2;
} while ((int16)(v1 - 8) < 0);
do {
int v3 = v1 >> 1;
WORD(room_chozo_bits[v1]) = -1;
*(uint16 *)&item_bit_array[v1] = -1;
WORD(opened_door_bit_array[v1]) = 0;
v1 += 2;
} while ((int16)(v1 - 64) < 0);
uint16 v4 = 0;
do {
explored_map_tiles_saved[v4 >> 1] = 0;
v4 += 2;
} while ((int16)(v4 - 1536) < 0);
samus_max_reserve_health = 0;
samus_reserve_health = 0;
reserve_health_mode = 0;
loading_game_state = kLoadingGameState_0_Intro;
debug_disable_minimap = 0;
}
void DemoRoom_ChargeBeamRoomScroll21(void) { // 0x82891A
scrolls[33] = 0;
}
void DemoRoom_SetBG2TilemapBase(void) { // 0x828925
*(uint16 *)&reg_BG2SC = 74;
}
void DemoRoom_SetKraidFunctionTimer(void) { // 0x82892B
enemy_data[0].ai_preinstr = 60;
}
void DemoRoom_SetBrinstarBossBits(void) { // 0x828932
boss_bits_for_area[1] = 1;
}
static Func_V_Coroutine *const kGameStateFuncs[45] = {
GameState_0_Reset_Async,
GameState_1_OpeningCinematic,
GameState_2_GameOptionsMenu,
GameState_3_Null,
GameState_4_FileSelectMenus,
GameState_5_FileSelectMap,
InitAndLoadGameData_Async,
GameState_7_MainGameplayFadeIn,
GameState_8_MainGameplay,
GameState_9_HitDoorBlock,
GameState_10_LoadingNextRoom_Async,
GameState_11_LoadingNextRoom_Async,
GameState_12_Pausing_Darkening_Async,
GameState_13_Pausing_Async,
GameState_14_Paused_Async,
GameState_15_Paused_Async,
GameState_16_Unpausing_Async,
GameState_17_Unpausing_Async,
GameState_18_Unpausing,
GameState_19_SamusNoHealth,
GameState_20_SamusNoHealth_BlackOut,
GameState_21_SamusNoHealth,
GameState_22_SamusNoHealth_Dying,
GameState_23_SamusNoHealth_Flashing,
GameState_24_SamusNoHealth_Explosion,
GameState_25_SamusNoHealth_BlackOut,
GameState_26_GameOverMenu,
GameState_27_ReserveTanksAuto,
GameState_28_Unused,
GameState_29_DebugGameOverMenu,
GameState_37_CeresGoesBoomWithSamus,
InitAndLoadGameData_Async,
GameState_32_MadeItToCeresElevator,
GameState_33_BlackoutFromCeres,
GameState_37_CeresGoesBoomWithSamus,
GameState_35_TimeUp,
GameState_36_WhitingOutFromTimeUp,
GameState_37_CeresGoesBoomWithSamus,
GameState_38_SamusEscapesFromZebes,
GameState_39_EndingAndCredits,
InitAndLoadGameData_Async,
GameState_41_TransitionToDemo,
GameState_42_PlayingDemo_Async,
GameState_43_TransitionFromDemo,
GameState_44_TransitionFromDemo,
};
CoroutineRet RunGameStateTrampoline_Async(void) {
// printf("gamestate %d\n", game_state);
return kGameStateFuncs[(uint16)(2 * (uint8)game_state) >> 1]();
}
CoroutineRet RunOneFrameOfGameInner(void) {
COROUTINE_BEGIN(coroutine_state_0, 1: case 2: case 3);
COROUTINE_AWAIT_ONLY(Vector_RESET_Async())
COROUTINE_MANUAL_POS(0);
ReadJoypadInputs();
HdmaObjectHandler();
NextRandom();
ClearOamExt();
oam_next_ptr = 0;
nmi_copy_samus_halves = 0;
nmi_copy_samus_top_half_src = 0;
nmi_copy_samus_bottom_half_src = 0;
COROUTINE_AWAIT(4, RunGameStateTrampoline_Async());
HandleSoundEffects();
ClearUnusedOam();
ShowSpareCpu();
COROUTINE_END(0);
}
void RunOneFrameOfGame(void) { // 0x828948
CoroutineRet ret = RunOneFrameOfGameInner();
if (ret == 0)
waiting_for_nmi = 1;
Vector_NMI();
}
CoroutineRet GameState_29_DebugGameOverMenu(void) { // 0x8289DB
DebugGameOverMenu();
return kCoroutineNone;
}
CoroutineRet GameState_26_GameOverMenu(void) { // 0x8289E0
GameOverMenu();
return kCoroutineNone;
}
CoroutineRet GameState_4_FileSelectMenus(void) { // 0x8289E5
FileSelectMenu();
return kCoroutineNone;
}
CoroutineRet GameState_5_FileSelectMap(void) { // 0x8289EA
FileSelectMap();
return kCoroutineNone;
}
static Func_Y_V *const kSfxHandlers[5] = { // 0x8289EF
SfxHandlers_0_SendToApu,
SfxHandlers_1_WaitForAck,
SfxHandlers_2_ClearRequest,
SfxHandlers_3_WaitForAck,
SfxHandlers_4_Reset,
};
void HandleSoundEffects(void) {
if ((int8)(sound_handler_downtime - 1) >= 0) {
LOBYTE(sound_handler_downtime) = sound_handler_downtime - 1;
RtlApuWrite(APUI01, 0);
sfx_cur[0] = 0;
RtlApuWrite(APUI02, 0);
sfx_cur[1] = 0;
RtlApuWrite(APUI03, 0);
sfx_cur[2] = 0;
} else {
for (int i = 0; i < 3; ++i)
kSfxHandlers[sfx_state[i]](i);
}
}
void SfxHandlers_0_SendToApu(uint16 j) { // 0x828A2C
if (sfx_readpos[j] != sfx_writepos[j]) {
uint8 v2 = sfx_readpos[j] + j * 16;
uint8 v3 = sfx1_queue[v2];
RtlApuWrite((SnesRegs)(j + APUI01), v3);
sfx_cur[j] = v3;
sfx_readpos[j] = (v2 + 1) & 0xF;
++sfx_state[j];
}
}
void SfxHandlers_1_WaitForAck(uint16 j) { // 0x828A55
// Modified from original
uint8 v1 = sfx_cur[j];
++sfx_state[j];
sfx_clear_delay[j] = 6;
}
void SfxHandlers_2_ClearRequest(uint16 j) { // 0x828A6C
// Modified from original
if (sfx_clear_delay[j]-- == 1) {
sfx_cur[j] = 0;
++sfx_state[j];
}
}
void SfxHandlers_3_WaitForAck(uint16 j) { // 0x828A7C
// Modified from original
uint8 v1 = sfx_cur[j];
sfx_state[j] = 0;
SfxHandlers_0_SendToApu(j);
}
void SfxHandlers_4_Reset(uint16 j) { // 0x828A90
if (sfx_clear_delay[j]-- == 1)
sfx_state[j] = 0;
}
void ResetSoundQueues(void) { // 0x828A9A
*(uint16 *)sfx_readpos = 0;
*(uint16 *)&sfx_readpos[2] = 0;
*(uint16 *)&sfx_writepos[1] = 0;
*(uint16 *)sfx_state = 0;
sfx_state[2] = 0;
}
void ShowSpareCpu(void) { // 0x828AB0
if ((joypad_dbg_1 & 0x4000) != 0)
debug_spare_cpu_display_flag = debug_spare_cpu_display_flag == 0;
if (debug_spare_cpu_display_flag)
WriteReg(INIDISP, reg_INIDISP & 0xF0 | 5);
joypad1_input_samusfilter = joypad1_lastkeys;
}
CoroutineRet GameState_0_Reset_Async(void) { // 0x828AE4
UNUSED_word_7E0DF8 = 0;
UNUSED_word_7E0DFA = 0;
UNUSED_word_7E0DFC = 0;
cinematic_function = FUNC16(CinematicFunctionOpening);
demo_set = 0;
if (num_demo_sets == 4)
demo_set = 3;
++game_state;
return kCoroutineNone;
}
CoroutineRet GameState_1_OpeningCinematic(void) { // 0x828B08
return GameState_1_OpeningCinematic_();
}
CoroutineRet GameState_3_Null(void) {
return kCoroutineNone;
}
CoroutineRet GameState_37_CeresGoesBoomWithSamus(void) { // 0x828B0E
return GameState_37_CeresGoesBoomWithSamus_();
}
CoroutineRet GameState_39_EndingAndCredits(void) { // 0x828B13
return GameState_39_EndingAndCredits_();
}
CoroutineRet GameState_7_MainGameplayFadeIn(void) { // 0x828B20
GameState_8_MainGameplay();
HandleFadeIn();
if (reg_INIDISP == 15) {
screen_fade_delay = 0;
screen_fade_counter = 0;
++game_state;
}
return kCoroutineNone;
}
CoroutineRet GameState_28_Unused(void) { // 0x828B3F
GameState_28_Unused_();
return kCoroutineNone;
}
CoroutineRet GameState_8_MainGameplay(void) { // 0x828B44
COROUTINE_BEGIN(coroutine_state_1, 0);
DetermineWhichEnemiesToProcess();
if (1) { // !DebugHandler()) {
PaletteFxHandler();
HandleControllerInputForGamePhysics();
if (!debug_disable_sprite_interact)
SamusProjectileInteractionHandler();
EnemyMain();
if (queued_message_box_index) {
COROUTINE_AWAIT(1, DisplayMessageBox_Async(queued_message_box_index));
queued_message_box_index = 0;
}
HandleSamusMovementAndPause();
EprojRunAll();
COROUTINE_AWAIT(2, PlmHandler_Async());
AnimtilesHandler();
if (!debug_disable_sprite_interact) {
EprojSamusCollDetect();
EprojProjCollDet();
ProcessEnemyPowerBombInteraction();
}
MainScrollingRoutine();
int debug_scrolling_enabled = 0;
if (debug_scrolling_enabled)
DebugScrollPosSaveLoad();
DrawSamusEnemiesAndProjectiles();
QueueEnemyBG2TilemapTransfers();
}
HandleHudTilemap();
CalculateLayer2PosAndScrollsWhenScrolling();
RunRoomMainCode();
HandleSamusOutOfHealthAndGameTile();
HandleRoomShaking();
DecrementSamusTimers();
COROUTINE_END(0);
}
void DeleteAllOptionsMenuObjects_(void) {
for (int i = 14; i >= 0; i -= 2) {
int v1 = i >> 1;
enemy_projectile_y_pos[v1 + 5] = 0;
enemy_projectile_y_vel[v1 + 17] = 0;
}
}
void CallOptionsEntryFunc(uint32 ea, uint16 j) {
switch (ea) {
case fnsub_82F296: sub_82F296(j); return;
case fnsub_82F34B: sub_82F34B(j); return;
case fnsub_82F353: sub_82F353(j); return;
case fnsub_82F35B: sub_82F35B(j); return;
case fnsub_82F363: sub_82F363(j); return;
case fnsub_82F419: sub_82F419(j); return;
default: Unreachable();
}
}
uint8 CreateOptionsMenuObject_(uint16 a, uint16 j) {
options_menu_init_param = a;
uint16 v3 = 14;
while (optionsmenu_instr_ptr[v3 >> 1]) {
v3 -= 2;
if ((v3 & 0x8000u) != 0)
return 1;
}
uint8 *v5 = RomPtr_82(j);
int v6 = v3 >> 1;
optionsmenu_arr1[v6] = *((uint16 *)v5 + 1);
optionsmenu_instr_ptr[v6] = *((uint16 *)v5 + 2);
optionsmenu_instr_timer[v6] = 1;
optionsmenu_cur_data[v6] = 0;
optionsmenu_arr5[v6] = 0;
optionsmenu_arr6[v6] = 0;
optionsmenu_arr7[v6] = 0;
CallOptionsEntryFunc(*(uint16 *)v5 | 0x820000, v3);
return 0;
}
void OptionsPreInstr_nullsub_57(uint16 k) { // 0x828C10
;
}
void OptionsMenuFunc1(void) { // 0x828C11
for (int i = 14; i >= 0; i -= 2) {
optionsmenu_index = i;
if (optionsmenu_instr_ptr[i >> 1]) {
OptionsMenuFunc2(i);
i = optionsmenu_index;
}
}
}
void CallOptionsPreInstr(uint32 ea, uint16 k) {
switch (ea) {
case fnOptionsPreInstr_nullsub_57: OptionsPreInstr_nullsub_57(k); return;
case fnOptionsPreInstr_F2A9: OptionsPreInstr_F2A9(k); return;
case fnOptionsPreInstr_F376: OptionsPreInstr_F376(k); return;
case fnOptionsPreInstr_F3A0: OptionsPreInstr_F3A0(k); return;
case fnOptionsPreInstr_F3E2: OptionsPreInstr_F3E2(k); return;
case fnOptionsPreInstr_F42C: OptionsPreInstr_F42C(k); return;
default: Unreachable();
}
}
uint16 CallOptionsInstr(uint32 ea, uint16 k, uint16 j) {
switch (ea) {
case fnOptionsInstr_Destroy: return OptionsInstr_Destroy(k, j);
case fnOptionsInstr_8C64: return OptionsInstr_8C64(k, j);
case fnOptionsInstr_SetPreInstr: return OptionsInstr_SetPreInstr(k, j);
case fnOptionsInstr_8C79: return OptionsInstr_8C79(k, j);
case fnOptionsInstr_Goto: return OptionsInstr_Goto(k, j);
case fnOptionsInstr_8C89: return OptionsInstr_8C89(k, j);
case fnOptionsInstr_8C93: return OptionsInstr_8C93(k, j);
default: return Unreachable();
}
}
void OptionsMenuFunc2(uint16 k) { // 0x828C2B
CallOptionsPreInstr(optionsmenu_arr1[k >> 1] | 0x820000, k);
uint16 v1 = optionsmenu_index;
int v2 = optionsmenu_index >> 1;
if (optionsmenu_instr_timer[v2]-- == 1) {
uint16 v4 = optionsmenu_instr_ptr[v2], v6;
while (1) {
uint16 *v5 = (uint16 *)RomPtr_82(v4);
v6 = *v5;
if ((*v5 & 0x8000u) == 0)
break;
R18_ = *v5;
v4 = CallOptionsInstr(v6 | 0x820000, v1, v4 + 2);
if (!v4)
return;
}
int v7 = v1 >> 1;
optionsmenu_instr_timer[v7] = v6;
optionsmenu_cur_data[v7] = *((uint16 *)RomPtr_82(v4) + 1);
optionsmenu_instr_ptr[v7] = v4 + 4;
}
}
uint16 OptionsInstr_Destroy(uint16 k, uint16 j) { // 0x828C5A
int v2 = k >> 1;
optionsmenu_cur_data[v2] = 0;
optionsmenu_instr_ptr[v2] = 0;
return 0;
}
uint16 OptionsInstr_8C64(uint16 k, uint16 j) { // 0x828C64
optionsmenu_instr_ptr[k >> 1] = j - 2;
return 0;
}
uint16 OptionsInstr_SetPreInstr(uint16 k, uint16 j) { // 0x828C6E
optionsmenu_arr1[k >> 1] = *(uint16 *)RomPtr_82(j);
return j + 2;
}
uint16 OptionsInstr_8C79(uint16 k, uint16 j) { // 0x828C79
optionsmenu_arr1[k >> 1] = FUNC16(locret_828C81);
return j;
}
uint16 OptionsInstr_Goto(uint16 k, uint16 j) { // 0x828C82
return *(uint16 *)RomPtr_82(j);
}
uint16 OptionsInstr_8C89(uint16 k, uint16 j) { // 0x828C89
int v2 = k >> 1;
if (optionsmenu_arr5[v2]-- == 1)
return j + 2;
else
return OptionsInstr_Goto(k, j);
}
uint16 OptionsInstr_8C93(uint16 k, uint16 j) { // 0x828C93
optionsmenu_arr5[k >> 1] = *(uint16 *)RomPtr_82(j);
return j + 2;
}
void DrawOptionsMenuSpritemaps(void) { // 0x828CA1
for (int i = 14; i >= 0; i -= 2) {
int v1 = i >> 1;
if (optionsmenu_cur_data[v1]) {
uint16 v2 = optionsmenu_cur_data[v1];
R22_ = optionsmenu_arr10[v1];
R20_ = optionsmenu_arr8[v1];
R18_ = optionsmenu_arr9[v1];
DrawSpritemap(0x82u, v2);
}
}
}
CoroutineRet GameState_12_Pausing_Darkening_Async(void) { // 0x828CCF
GameState_8_MainGameplay();
HandleFadeOut();
if ((reg_INIDISP & 0xF) == 0) {
EnableNMI();
screen_fade_delay = 0;
screen_fade_counter = 0;
++game_state;
}
return kCoroutineNone;
}
void CallPauseHook(uint32 ea) {
switch (ea) {
case fnPauseHook_Empty: return;
case fnPauseHook_DraygonRoom: PauseHook_DraygonRoom(); return;
case fnUnpauseHook_DraygonRoom: UnpauseHook_DraygonRoom(); return;
case fnUnpauseHook_Kraid_IsDead: UnpauseHook_Kraid_IsDead(); return;
case fnUnpauseHook_Kraid_IsAlive: UnpauseHook_Kraid_IsAlive(); return;
case fnKraid_UnpauseHook_IsSinking: Kraid_UnpauseHook_IsSinking(); return;
case fnPauseHook_Kraid: PauseHook_Kraid(); return;
case fnMotherBrainsBody_UnpauseHook: MotherBrainsBody_UnpauseHook(); return;
default: Unreachable();
}
}
CoroutineRet GameState_13_Pausing_Async(void) { // 0x828CEF
DisableHdmaObjects();
reg_HDMAEN = 0;
WriteReg(HDMAEN, 0);
DisableAnimtiles();
BackupBG2TilemapForPauseMenu();
CallPauseHook(Load24(&pause_hook));
CancelSoundEffects();
BackupSomeGfxStateForPause();
LoadPauseMenuTilesAndClearBG2();
LoadPauseScreenBaseTilemaps();
LoadPauseMenuMapTilemapAndAreaLabel();
BackupGameplayPalettesAndLoadForPause();
ContinueInitPauseMenu();
screen_fade_delay = 1;
screen_fade_counter = 1;
pausemenu_leftarrow_animation_frame = 0;
pausemenu_palette_animation_timer = 1;
map_scrolling_direction = 0;
map_scrolling_speed_index = 0;
QueueClearingOfFxTilemap();
++game_state;
return kCoroutineNone;
}
void BackupBG2TilemapForPauseMenu(void) { // 0x828D51
WriteReg(VMADDL, 1u);
WriteReg(VMADDH, reg_BG2SC & 0xFC);
WriteReg(DMAP1, 0x81u);
WriteReg(BBAD1, 0x39u);
WriteReg(A1T1L, 0x5C);
WriteReg(A1T1H, 0xDFu);
WriteReg(A1B1, 0x7Eu);
WriteReg(DAS1L, 0);
WriteReg(DAS1H, 0x10u);
WriteReg(DAS10, 0);
WriteReg(A2A1L, 0);
WriteReg(A2A1H, 0);
WriteReg(NTRL1, 0);
WriteReg(MDMAEN, 2u);
}
void RestoreBG2TilemapFromPauseScreen(void) { // 0x828D96
WriteReg(VMADDL, 0);
WriteReg(VMADDH, reg_BG2SC & 0xFC);
WriteReg(VMAIN, 0x80);
static const StartDmaCopy unk_828DAE = { 1, 1, 0x18, LONGPTR(0x7edf5c), 0x1000 };
SetupDmaTransfer(&unk_828DAE);
WriteReg(MDMAEN, 2u);
}
void BackupSomeGfxStateForPause(void) { // 0x828DBD
pausemenu_bak_BG1SC = reg_BG1SC;
pausemenu_bak_BG2SC = reg_BG2SC;
pausemenu_bak_BG3SC = reg_BG3SC;
pausemenu_bak_BG12NBA = reg_BG12NBA;
pausemenu_bak_BG34NBA = reg_BG34NBA;
pausemenu_bak_OBSEL = reg_OBSEL;
pausemenu_bak_BG1HOFS = reg_BG1HOFS;
pausemenu_bak_BG2HOFS = reg_BG2HOFS;
pausemenu_bak_BG3HOFS = reg_BG3HOFS;
pausemenu_bak_BG1VOFS = reg_BG1VOFS;
pausemenu_bak_BG2VOFS = reg_BG2VOFS;
pausemenu_bak_BG3VOFS = reg_BG3VOFS;
pausemenu_bak_BGMODE = reg_BGMODE;
pausemenu_bak_layer2_scroll_x = layer2_scroll_x;
pausemenu_bak_layer2_scroll_y = layer2_scroll_y;
pausemenu_bak_MOSAIC = reg_MOSAIC;
pausemenu_bak_CGADSUB = next_gameplay_CGADSUB;
}
void RestoreSomeGfxStateForPause(void) { // 0x828E19
layer2_scroll_x = pausemenu_bak_layer2_scroll_x;
layer2_scroll_y = pausemenu_bak_layer2_scroll_y;
reg_BGMODE = pausemenu_bak_BGMODE;
LOBYTE(reg_BG3VOFS) = pausemenu_bak_BG3VOFS;
LOBYTE(reg_BG2VOFS) = pausemenu_bak_BG2VOFS;
LOBYTE(reg_BG1VOFS) = pausemenu_bak_BG1VOFS;
LOBYTE(reg_BG3HOFS) = pausemenu_bak_BG3HOFS;
LOBYTE(reg_BG2HOFS) = pausemenu_bak_BG2HOFS;
LOBYTE(reg_BG1HOFS) = pausemenu_bak_BG1HOFS;
reg_OBSEL = pausemenu_bak_OBSEL;
reg_BG34NBA = pausemenu_bak_BG34NBA;
reg_BG12NBA = pausemenu_bak_BG12NBA;
reg_BG3SC = pausemenu_bak_BG3SC;
reg_BG2SC = pausemenu_bak_BG2SC;
reg_BG1SC = pausemenu_bak_BG1SC;
reg_MOSAIC = pausemenu_bak_MOSAIC;
next_gameplay_CGADSUB = pausemenu_bak_CGADSUB;
}
void LoadPauseMenuTilesAndClearBG2(void) { // 0x828E75
WriteReg(VMADDL, 0);
WriteReg(VMADDH, 0);
WriteReg(VMAIN, 0x80);
static const StartDmaCopy unk_828E8B = { 1, 1, 0x18, LONGPTR(0xb68000), 0x4000 };
SetupDmaTransfer(&unk_828E8B);
WriteReg(MDMAEN, 2u);
WriteReg(VMADDL, 0);
WriteReg(VMADDH, 0x20u);
WriteReg(VMAIN, 0x80);
static const StartDmaCopy unk_828EAB = { 1, 1, 0x18, LONGPTR(0xb6c000), 0x2000 };
SetupDmaTransfer(&unk_828EAB);
WriteReg(MDMAEN, 2u);
WriteReg(VMADDL, 0);
WriteReg(VMADDH, 0x40u);
WriteReg(VMAIN, 0x80);
static const StartDmaCopy unk_828ECB = { 1, 1, 0x18, LONGPTR(0x9ab200), 0x2000 };
SetupDmaTransfer(&unk_828ECB);
WriteReg(MDMAEN, 2u);
}
void LoadPauseScreenBaseTilemaps(void) { // 0x828EDA
WriteReg(VMADDL, 0);
WriteReg(VMADDH, 0x38u);
WriteReg(VMAIN, 0x80);
static const StartDmaCopy unk_828EF0 = { 1, 1, 0x18, LONGPTR(0xb6e000), 0x0800 };
SetupDmaTransfer(&unk_828EF0);
WriteReg(MDMAEN, 2u);
WriteReg(WMADDL, 0);
WriteReg(WMADDM, 0x34u);
WriteReg(WMADDH, 0x7Eu);
static const StartDmaCopy unk_828F10 = { 1, 0, 0x80, LONGPTR(0xb6e400), 0x0400 };
SetupDmaTransfer(&unk_828F10);
WriteReg(MDMAEN, 2u);
WriteReg(WMADDL, 0);
WriteReg(WMADDM, 0x38u);
WriteReg(WMADDH, 0x7Eu);
static const StartDmaCopy unk_828F30 = { 1, 0, 0x80, LONGPTR(0xb6e800), 0x0800 };
SetupDmaTransfer(&unk_828F30);
WriteReg(MDMAEN, 2u);
uint16 v0 = addr_kDummySamusWireframeTilemap;
uint16 v1 = 236;
R20_ = 17;
do {
R18_ = 8;
do {
ram3000.pause_menu_map_tilemap[v1++] = *(uint16 *)RomPtr_82(v0);
v0 += 2;
--R18_;
} while (R18_);
v1 += 8;
--R20_;
} while (R20_);
WriteSamusWireframeTilemap();
LoadEqupmentScreenReserveHealthTilemap();
}
void LoadEqupmentScreenReserveHealthTilemap(void) { // 0x828F70
if (samus_max_reserve_health) {
R42 = samus_reserve_health / 100;
int rest = samus_reserve_health % 100;
int div10 = rest / 10;
int mod10 = rest % 10;
ram3800.cinematic_bg_tilemap[394] = mod10 + 2052;
ram3800.cinematic_bg_tilemap[393] = div10 + 2052;
ram3800.cinematic_bg_tilemap[392] = R42 + 2052;
}
}
#define kPauseScreenPalettes ((uint16*)RomPtr(0xb6f000))
void BackupGameplayPalettesAndLoadForPause(void) { // 0x828FD4
int16 v0;
int16 v2;
v0 = 512;
uint16 v1 = 0;
do {
ram3000.pause_menu_map_tilemap[v1 + 384] = palette_buffer[v1];
++v1;
v0 -= 2;
} while (v0);
v2 = 512;
uint16 v3 = 0;
do {
palette_buffer[v3 >> 1] = kPauseScreenPalettes[v3 >> 1];
v3 += 2;
v2 -= 2;
} while (v2);
}
void ContinueInitPauseMenu(void) { // 0x829009
SetupPpuForPauseMenu();
ResetPauseMenuAnimations();
LoadEquipmentScreenEquipmentTilemaps();
SetPauseScreenButtonLabelPalettes_0();
UpdatePauseMenuLRStartVramTilemap();
DetermineMapScrollLimits();
SetupMapScrollingForPauseMenu(0x80);
}
void SetupMapScrollingForFileSelectMap(void) { // 0x829028
int16 v0;
int16 v1;
ResetPauseMenuAnimations();
DetermineMapScrollLimits();
reg_BG1HOFS = map_min_x_scroll + ((uint16)(map_max_x_scroll - map_min_x_scroll) >> 1) - 128;
R18_ = 8 * (room_x_coordinate_on_map + (uint8)((uint16)(samus_x_pos & 0xFF00) >> 8)) - reg_BG1HOFS;
v0 = 224 - R18_;
if ((int16)(224 - R18_) >= 0) {
R18_ = 32 - R18_;
if ((R18_ & 0x8000u) == 0)
reg_BG1HOFS -= R18_;
} else {
R18_ = 224 - R18_;
reg_BG1HOFS -= v0;
}
R18_ = map_min_y_scroll + ((uint16)(map_max_y_scroll - map_min_y_scroll) >> 1) + 16;
reg_BG1VOFS = -((112 - R18_) & 0xFFF8);
R18_ = 8 * (room_y_coordinate_on_map + HIBYTE(samus_y_pos) + 1) + ((112 - R18_) & 0xFFF8);
v1 = 64 - R18_;
if ((int16)(64 - R18_) >= 0) {
R18_ = 64 - R18_;
reg_BG1VOFS -= v1;
if (sign16(reg_BG1VOFS + 40))
reg_BG1VOFS = -40;
}
}
CoroutineRet GameState_14_Paused_Async(void) { // 0x8290C8
DrawPauseMenuDuringFadeIn();
HandleFadeIn();
if (reg_INIDISP == 15) {
screen_fade_delay = 0;
screen_fade_counter = 0;
++game_state;
}
return kCoroutineNone;
}
CoroutineRet GameState_15_Paused_Async(void) { // 0x8290E8
ReleaseButtonsFilter(3);
MainPauseRoutine();
HandleHudTilemap();
HandlePauseScreenPaletteAnimation();
return kCoroutineNone;
}
static Func_V *const kPauseMenuFuncs[8] = { // 0x8290FF
PauseMenu_0_MapScreen,
PauseMenu_1_EquipmentScreen,
PauseMenu_2,
PauseMenu_3_MapToEquipment_Load,
PauseMenu_4_MapToEquipment_FadeIn,
PauseMenu_5,
PauseMenu_6_EquipmentToMap_Load,
PauseMenu_7_EquipmentToMap_FadeIn,
};
void MainPauseRoutine(void) {
kPauseMenuFuncs[menu_index]();
}
void PauseMenu_0_MapScreen(void) { // 0x829120
HandlePauseScreenLR();
HandlePauseScreenStart();
HandleMapScrollArrows();
MapScrolling();
MapScreenDrawSamusPositionIndicator();
DrawMapIcons();
DisplayMapElevatorDestinations();
pause_screen_mode = 0;
}
void PauseMenu_1_EquipmentScreen(void) { // 0x829142
reg_BG1HOFS = 0;
reg_BG1VOFS = 0;
EquipmentScreenMain();
HandlePauseScreenLR();
HandlePauseScreenStart();
pause_screen_mode = 1;
}
void PauseMenu_2(void) { // 0x829156
DisplayMapElevatorDestinations();
MapScreenDrawSamusPositionIndicator();
DrawMapIcons();
HandlePauseMenuLRPressHighlight();
pause_screen_mode = 0;
HandleFadeOut();
if (reg_INIDISP == 0x80) {
EnableNMI();
screen_fade_delay = 0;
screen_fade_counter = 0;
++menu_index;
}
}
void PauseMenu_5(void) { // 0x829186
EquipmentScreenDrawItemSelector();
EquipmentScreenDisplayReserveTankAmount();
HandlePauseMenuLRPressHighlight();
HandleFadeOut();
if (reg_INIDISP == 0x80) {
EnableNMI();
screen_fade_delay = 0;
screen_fade_counter = 0;
++menu_index;
}
}
#define kPauseLrHighlightAnimData ((uint8*)RomPtr(0x82c10c))
void PauseMenu_3_MapToEquipment_Load(void) { // 0x8291AB
DisplayMapElevatorDestinations();
EquipmentScreenSetupReserveMode();
EquipmentScreenTransferBG1Tilemap();
pause_screen_mode = 1;
SetPauseScreenButtonLabelPalettes();
pausemenu_lr_animation_frame = 0;
pausemenu_lr_animation_timer = *(uint16 *)kPauseLrHighlightAnimData;
screen_fade_delay = 1;
screen_fade_counter = 1;
++menu_index;
}
void PauseMenu_6_EquipmentToMap_Load(void) { // 0x8291D7
DisplayMapElevatorDestinations();
LoadPauseMenuMapTilemapAndAreaLabel();
SetPauseScreenButtonLabelPalettes();
pausemenu_lr_animation_frame = 0;
pausemenu_lr_animation_timer = *(uint16 *)kPauseLrHighlightAnimData;
screen_fade_delay = 1;
screen_fade_counter = 1;
pause_screen_mode = 0;
++menu_index;
}
void PauseMenu_7_EquipmentToMap_FadeIn(void) { // 0x829200
MapScreenDrawSamusPositionIndicator();
DrawMapIcons();
DisplayMapElevatorDestinations();
pause_screen_mode = 0;
HandleFadeIn();
if (reg_INIDISP == 15) {
screen_fade_delay = 0;
screen_fade_counter = 0;
uint16 v0 = pausemenu_button_label_mode;
if (pausemenu_button_label_mode)
v0 = 1;
menu_index = v0;
}
}
void PauseMenu_4_MapToEquipment_FadeIn(void) { // 0x829231
EquipmentScreenDrawItemSelector();
EquipmentScreenDisplayReserveTankAmount();
pause_screen_mode = 1;
HandleFadeIn();
if (reg_INIDISP == 15) {
screen_fade_delay = 0;
screen_fade_counter = 0;
uint16 v0 = pausemenu_button_label_mode;
if (pausemenu_button_label_mode)
v0 = 1;
menu_index = v0;
}
}
static Func_V *const kMapScrollingFuncs[5] = { // 0x82925D
MapScrolling_0_None,
MapScrolling_1_Left,
MapScrolling_2_Right,
MapScrolling_3_Up,
MapScrolling_4_Down,
};
void MapScrolling(void) {
kMapScrollingFuncs[map_scrolling_direction]();
}
void MapScrolling_0_None(void) { // 0x829278
map_scrolling_gear_switch_timer = 4;
}
uint16 MapScrolling_GetSpeedIndex(void) { // 0x82927F
uint16 result = map_scrolling_speed_index;
if (!map_scrolling_gear_switch_timer)
return map_scrolling_speed_index + 32;
return result;
}
static const uint16 kMapScrollingSpeedTable[32] = { // 0x82928E
0, 0, 0, 8,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 8,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
};
void MapScrolling_1_Left(void) {
reg_BG1HOFS -= kMapScrollingSpeedTable[MapScrolling_GetSpeedIndex() >> 1];
MapScrolling_Common();
}
void MapScrolling_Common(void) { // 0x829299
++map_scrolling_speed_index;
if ((++map_scrolling_speed_index & 0xF) == 0) {
QueueSfx1_Max6(0x36u);
map_scrolling_direction = 0;
map_scrolling_speed_index = 0;
if (map_scrolling_gear_switch_timer)
--map_scrolling_gear_switch_timer;
}
}
void MapScrolling_2_Right(void) { // 0x8292BD
reg_BG1HOFS += kMapScrollingSpeedTable[MapScrolling_GetSpeedIndex() >> 1];
MapScrolling_Common();
}
void MapScrolling_3_Up(void) { // 0x8292CA
reg_BG1VOFS -= kMapScrollingSpeedTable[MapScrolling_GetSpeedIndex() >> 1];
MapScrolling_Common();
}
void MapScrolling_4_Down(void) { // 0x8292D7
reg_BG1VOFS += kMapScrollingSpeedTable[MapScrolling_GetSpeedIndex() >> 1];
MapScrolling_Common();
}
CoroutineRet GameState_16_Unpausing_Async(void) { // 0x829324
HighlightPauseScreenButton();
DrawPauseMenuDuringFadeout();
HandleFadeOut();
if (reg_INIDISP == 0x80) {
EnableNMI();
screen_fade_delay = 0;
screen_fade_counter = 0;
++game_state;
}
return kCoroutineNone;
}
void DrawPauseMenuDuringFadeout(void) { // 0x82934B
if (pause_screen_mode == 1) {
EquipmentScreenDrawItemSelector();
EquipmentScreenDisplayReserveTankAmount();
HandlePauseMenuLRPressHighlight();
} else {
DisplayMapElevatorDestinations();
DrawMapIcons();
MapScreenDrawSamusPositionIndicator();
}
}
CoroutineRet GameState_17_Unpausing_Async(void) { // 0x829367
ClearSamusBeamTiles();
ContinueInitGameplayResume();
ResumeGameplay();
RestoreSomeGfxStateForPause();
RestoreBG2TilemapFromPauseScreen();
screen_fade_delay = 1;
screen_fade_counter = 1;
CallPauseHook(Load24(&unpause_hook));
EnableHdmaObjects();
EnableAnimtiles();
QueueSamusMovementSfx();
++game_state;
return kCoroutineNone;
}
CoroutineRet GameState_18_Unpausing(void) { // 0x8293A1
GameState_8_MainGameplay();
HandleFadeIn();
if (reg_INIDISP == 15) {
screen_fade_delay = 0;
screen_fade_counter = 0;
game_state = kGameState_8_MainGameplay;
}
return kCoroutineNone;
}
#define kPauseAreaLabelTilemap ((uint16*)RomPtr(0x82965f))
void LoadPauseMenuMapTilemapAndAreaLabel(void) { // 0x8293C3
reg_BG1HOFS = reg_BG4HOFS;
reg_BG1VOFS = reg_BG4VOFS;
WriteReg(VMADDL, 0);
WriteReg(VMADDH, 0x30u);
WriteReg(VMAIN, 0x80);
LoadPauseMenuMapTilemap();
static const StartDmaCopy unk_8293E9 = { 1, 1, 0x18, LONGPTR(0x7e4000), 0x1000 };
SetupDmaTransfer(&unk_8293E9);
WriteReg(MDMAEN, 2u);
WriteReg(VMADDL, 0xAAu);
WriteReg(VMADDH, 0x38u);
WriteReg(VMAIN, 0x80);
WriteReg(DMAP1, 1u);
WriteReg(BBAD1, 0x18u);
WriteReg(DAS1L, 0x18u);
WriteReg(DAS1H, 0);
uint16 v0 = area_index;
if (!sign16(area_index - 7))
v0 = 0;
WriteRegWord(A1T1L, kPauseAreaLabelTilemap[v0]);
WriteReg(A1B1, 0x82u);
WriteReg(MDMAEN, 2u);
}
#define kPauseMenuMapTilemaps ((LongPtr*)RomPtr(0x82964a))
#define kPauseMenuMapData ((uint16*)RomPtr(0x829717))
void LoadPauseMenuMapTilemap(void) { // 0x82943D
uint16 v5;
uint16 v6;
int16 v9;
uint16 v13;
uint16 v0 = area_index;
if (!sign16(area_index - 7))
v0 = 0;
R18_ = v0;
R0_.addr = *(VoidP *)((char *)&kPauseMenuMapTilemaps[0].addr + (uint16)(3 * v0));
*(uint16 *)&R0_.bank = *(uint16 *)(&kPauseMenuMapTilemaps[0].bank + (uint16)(3 * v0));
R3_.addr = ADDR16_OF_RAM(ram4000);
*(uint16 *)&R3_.bank = 126;
R8_ = 130;
R6_ = kPauseMenuMapData[v0];
if (map_station_byte_array[area_index]) {
uint8 *v4 = IndirPtr(&R6_, 0);
LOBYTE(v5) = HIBYTE(*(uint16 *)v4);
HIBYTE(v5) = *(uint16 *)v4;
R38 = v5;
++R6_;
++R6_;
v6 = ADDR16_OF_RAM(*map_tiles_explored);
*(uint16 *)((char *)&R10_ + 1) = 0;
*(uint16 *)((char *)&R8_ + 1) = v6;
uint8 *v7 = IndirPtr((char *)&R8_ + 1, 0);
LOBYTE(v5) = HIBYTE(*(uint16 *)v7);
HIBYTE(v5) = *(uint16 *)v7;
R40 = v5;
++ *(uint16 *)((char *)&R8_ + 1);
++ *(uint16 *)((char *)&R8_ + 1);
uint16 v8 = 0;
v9 = 16;
do {
uint16 v10 = *(uint16 *)IndirPtr(&R0_, v8);
bool v11 = R40 >> 15;
R40 *= 2;
if (v11) {
v10 &= ~0x400u;
R38 *= 2;
} else {
v11 = R38 >> 15;
R38 *= 2;
if (!v11)
v10 = 31;
}
IndirWriteWord(&R3_, v8, v10);
if (!--v9) {
v9 = 16;
uint8 *v12 = IndirPtr(&R6_, 0);
LOBYTE(v13) = HIBYTE(*(uint16 *)v12);
HIBYTE(v13) = *(uint16 *)v12;
R38 = v13;
++R6_;
++R6_;
uint8 *v14 = IndirPtr((char *)&R8_ + 1, 0);
LOBYTE(v13) = HIBYTE(*(uint16 *)v14);
HIBYTE(v13) = *(uint16 *)v14;
R40 = v13;
++ *(uint16 *)((char *)&R8_ + 1);
++ *(uint16 *)((char *)&R8_ + 1);
}
v8 += 2;
} while ((int16)(v8 - 4096) < 0);
} else {
uint16 v1 = 0;
uint16 v2 = 0;
LOBYTE(R18_) = 0;
while (1) {
uint8 t = map_tiles_explored[v2];
map_tiles_explored[v2] <<= 1;
if (!(t & 0x80)) {
IndirWriteWord(&R3_, v1, 0x1Fu);
} else {
++map_tiles_explored[v2];
uint8 *v3 = IndirPtr(&R0_, v1);
IndirWriteWord(&R3_, v1, *(uint16 *)v3 & 0xFBFF);
}
v1 += 2;
LOBYTE(R18_) = R18_ + 1;
if (!sign8(R18_ - 8)) {
LOBYTE(R18_) = 0;
if ((int16)(++v2 - 256) >= 0)
break;
}
}
}
}
void DrawRoomSelectMap(void) { // 0x829517
uint16 v3; // r8
uint16 v6;
unsigned int v7; // kr00_4
int16 v10;
uint16 v14;
VramWriteEntry *v17;
reg_BG12NBA = 51;
reg_TM = 19;
reg_BG1VOFS = -40;
uint16 v0 = area_index;
if (!sign16(area_index - 7))
v0 = 0;
R18_ = v0;
R0_.addr = *(VoidP *)((char *)&kPauseMenuMapTilemaps[0].addr + (uint16)(3 * v0));
*(uint16 *)&R0_.bank = *(uint16 *)(&kPauseMenuMapTilemaps[0].bank + (uint16)(3 * v0));
R3_.addr = ADDR16_OF_RAM(ram3000);
R3_.bank = 126;
R8_ = 130;
R6_ = kPauseMenuMapData[v0];
if (map_station_byte_array[area_index]) {
uint8 *v5 = IndirPtr(&R6_, 0);
LOBYTE(v6) = HIBYTE(*(uint16 *)v5);
HIBYTE(v6) = *(uint16 *)v5;
R38 = v6;
++R6_;
++R6_;
v7 = 2039;
*(uint16 *)((char *)&R10_ + 1) = HIWORD(v7);
*(uint16 *)((char *)&R8_ + 1) = v7;
uint8 *v8 = IndirPtr((char *)&R8_ + 1, 0);
LOBYTE(v6) = HIBYTE(*(uint16 *)v8);
HIBYTE(v6) = *(uint16 *)v8;
R40 = v6;
++ *(uint16 *)((char *)&R8_ + 1);
++ *(uint16 *)((char *)&R8_ + 1);
uint16 v9 = 0;
v10 = 16;
do {
uint16 v11 = *(uint16 *)IndirPtr(&R0_, v9);
bool v12 = R40 >> 15;
R40 *= 2;
if (v12) {
v11 &= ~0x400u;
R38 *= 2;
} else {
v12 = R38 >> 15;
R38 *= 2;
if (!v12)
v11 = 31;
}
IndirWriteWord(&R3_, v9, v11);
if (!--v10) {
v10 = 16;
uint8 *v13 = IndirPtr(&R6_, 0);
LOBYTE(v14) = HIBYTE(*(uint16 *)v13);
HIBYTE(v14) = *(uint16 *)v13;
R38 = v14;
++R6_;
++R6_;
uint8 *v15 = IndirPtr((char *)&R8_ + 1, 0);
LOBYTE(v14) = HIBYTE(*(uint16 *)v15);
HIBYTE(v14) = *(uint16 *)v15;
R40 = v14;
++ *(uint16 *)((char *)&R8_ + 1);
++ *(uint16 *)((char *)&R8_ + 1);
}
v9 += 2;
} while ((int16)(v9 - 4096) < 0);
} else {
uint16 v1 = 0;
uint16 v2 = 0;
LOBYTE(R18_) = 0;
while (1) {
uint8 what = map_tiles_explored[v2];
map_tiles_explored[v2] <<= 1;
if (!(what & 0x80)) {
IndirWriteWord(&R3_, v1, 0xFu);
} else {
++map_tiles_explored[v2];
IndirWriteWord(&R3_, v1, *(uint16 *)IndirPtr(&R0_, v1) & ~0x400);
}
v1 += 2;
LOBYTE(R18_) = R18_ + 1;
LOBYTE(v3) = R18_ - 8;
if (!(uint8)sign8(v3)) {
LOBYTE(R18_) = 0;
if ((__int16)(++v2 - 256) >= 0)
break;
}
}
}
uint16 v16 = vram_write_queue_tail;
v17 = gVramWriteEntry(vram_write_queue_tail);
v17->size = 4096;
v17->src.addr = ADDR16_OF_RAM(ram3000);
*(uint16 *)&v17->src.bank = 126;
v17->vram_dst = (reg_BG1SC & 0xFC) << 8;
vram_write_queue_tail = v16 + 7;
}
void DrawRoomSelectMapAreaLabel(void) { // 0x829628
uint16 v0 = kPauseAreaLabelTilemap[area_index];
uint16 v1 = 0;
do {
uint8 *v2 = RomPtr_82(v0);
IndirWriteWord(&R0_, v1, *(uint16 *)v2 & 0xEFFF);
v0 += 2;
v1 += 2;
} while ((int16)(v1 - 24) < 0);
}
void SetupMapScrollingForPauseMenu(uint16 a) { // 0x829E27
int16 v1;
int16 v2;
R20_ = a;
reg_BG1HOFS = map_min_x_scroll + ((uint16)(map_max_x_scroll - map_min_x_scroll) >> 1) - 128;
R18_ = 8 * (room_x_coordinate_on_map + (uint8)((uint16)(samus_x_pos & 0xFF00) >> 8)) - reg_BG1HOFS;
v1 = 224 - R18_;
if ((int16)(224 - R18_) >= 0) {
R18_ = 32 - R18_;
if ((R18_ & 0x8000u) == 0)
reg_BG1HOFS -= R18_;
} else {
R18_ = 224 - R18_;
reg_BG1HOFS -= v1;
}
R18_ = map_min_y_scroll + ((uint16)(map_max_y_scroll - map_min_y_scroll) >> 1) + 16;
reg_BG1VOFS = -((R20_ - R18_) & 0xFFF8);
R18_ = 8 * (room_y_coordinate_on_map + HIBYTE(samus_y_pos) + 1) + ((R20_ - R18_) & 0xFFF8);
v2 = 64 - R18_;
if ((int16)(64 - R18_) >= 0) {
R18_ = 64 - R18_;
reg_BG1VOFS -= v2;
if (sign16(reg_BG1VOFS + 40))
reg_BG1VOFS = -40;
}
}
void DetermineMapScrollLimits(void) { // 0x829EC4
if (has_area_map) {
R8_ = 130;
R6_ = addr_kPauseMenuMapData;
R6_ = *(uint16 *)IndirPtr(&R6_, 2 * area_index);
} else {
R8_ = 0;
R6_ = 2039;
}
R0_.bank = R8_;
R0_.addr = R6_;
uint16 v0 = DetermineLeftmostMapColumn();
map_min_x_scroll = MultiplyBy8(v0);
if (area_index == 4)
map_min_x_scroll -= 24;
R0_.addr = R6_ + 131;
uint16 v1 = DetermineRightmostMapColumn();
map_max_x_scroll = MultiplyBy8(v1);
R0_.addr = R6_;
uint16 v2 = DetermineTopmostMapColumn();
map_min_y_scroll = MultiplyBy8(v2);
R0_.addr = R6_ + 124;
uint16 v3 = DetermineBottommostMapColumn();
map_max_y_scroll = MultiplyBy8(v3);
}
uint16 MultiplyBy8(uint16 k) { // 0x829F45
return 8 * k;
}
static const uint8 k0x80Shr[8] = { // 0x829F4A
0x80, 0x40, 0x20, 0x10,
8, 4, 2, 1,
};
static const uint8 k0x80Shr_0[8] = { 0x80, 0x40, 0x20, 0x10, 8, 4, 2, 1 };
uint16 DetermineLeftmostMapColumn(void) {
uint16 v0;
HIBYTE(v0) = 0;
uint16 result = 0;
LABEL_2:
LOBYTE(v0) = result & 7;
LOBYTE(R18_) = k0x80Shr[v0];
uint16 v2 = 0;
while (((uint8)R18_ & *IndirPtr(&R0_, v2)) == 0) {
v2 += 4;
if ((int16)(v2 - 128) >= 0) {
if ((int16)(++result - 64) >= 0)
return 26;
if ((result & 7) == 0) {
R0_.addr += 1;
}
if (result == 32) {
R0_.addr += 123;
}
goto LABEL_2;
}
}
return result;
}
uint16 DetermineRightmostMapColumn(void) { // 0x829FA9
uint16 result = 63;
LABEL_2:
LOBYTE(R18_) = k0x80Shr_0[result & 7];
uint16 v1 = 0;
while (((uint8)R18_ & *IndirPtr(&R0_, v1)) == 0) {
v1 += 4;
if ((int16)(v1 - 128) >= 0) {
if ((--result & 0x8000u) != 0)
return 28;
if ((result & 7) == 7) {
bool v2 = LOBYTE(R0_.addr)-- != 0;
HIBYTE(R0_.addr) -= !v2;
}
if (result == 31)
R0_.addr -= 124;
goto LABEL_2;
}
}
return result;
}
uint16 DetermineTopmostMapColumn(void) { // 0x82A009
R3_.addr = R0_.addr + 128;
R3_.bank = R0_.bank;
uint16 result = 0;
uint16 v1 = 0;
while (!*IndirPtr(&R0_, v1) && !*IndirPtr(&R3_, v1)) {
if ((int16)(++v1 - 4) >= 0) {
v1 = 0;
R0_.addr += 4;
R3_.addr += 4;
if ((int16)(++result - 31) >= 0)
return 1;
}
}
return result;
}
uint16 DetermineBottommostMapColumn(void) { // 0x82A053
R3_.addr = R0_.addr + 128;
R3_.bank = R0_.bank;
uint16 result = 31;
uint16 v1 = 0;
while (!*IndirPtr(&R0_, v1) && !*IndirPtr(&R3_, v1)) {
if ((int16)(++v1 - 4) >= 0) {
v1 = 0;
R0_.addr -= 4;
R3_.addr -= 4;
if (!--result)
return 11;
}
}
return result;
}
void SetupPpuForPauseMenu(void) { // 0x82A09A
WriteReg(OBSEL, 1u);
reg_OBSEL = 1;
WriteReg(BGMODE, 9u);
reg_BGMODE = 9;
reg_BG12NBA = 0;
WriteReg(BG12NBA, 0);
reg_BG34NBA = 4;
WriteReg(BG34NBA, 4u);
reg_BG1SC = 49;
WriteReg(BG1SC, 0x31u);
reg_BG2SC = 56;
WriteReg(BG2SC, 0x38u);
reg_BG3SC = 88;
WriteReg(BG3SC, 0x58u);
reg_BG4SC = 0;
WriteReg(BG4SC, 0);
WriteReg(TM, 0x17u);
reg_TM = 23;
WriteReg(MOSAIC, 0);
reg_MOSAIC = 0;
reg_COLDATA[0] &= 0xE0u;
reg_COLDATA[1] &= 0xE0u;
reg_COLDATA[2] &= 0xE0u;
next_gameplay_CGADSUB = 0;
}
void ResetPauseMenuAnimations(void) { // 0x82A0F7
pausemenu_reserve_tank_delay_ctr = 0;
reg_BG1HOFS = 0;
reg_BG2HOFS = 0;
reg_BG3HOFS = 0;
reg_BG2VOFS = 0;
reg_BG3VOFS = 0;
pausemenu_button_label_mode = 0;
pausemenu_lr_animation_frame = 0;
UNUSED_word_7E0745 = 0;
samus_position_indicator_animation_frame = 0;
samus_position_indicator_animation_timer = 0;
samus_position_indicator_animation_loop_counter = 0;
pausemenu_lr_animation_timer = *(uint16 *)kPauseLrHighlightAnimData;
pausemenu_palette_animation_timer = 1;
pausemenu_palette_animation_frame = 0;
}
#define kEquipmentTilemaps_Tanks ((uint16*)RomPtr(0x82c088))
#define kEquipmentTilemaps_Weapons ((uint16*)RomPtr(0x82c08c))
#define kEquipmentTilemaps_Suits ((uint16*)RomPtr(0x82c096))
#define kEquipmentTilemaps_Boots ((uint16*)RomPtr(0x82c0a2))
#define kHyperBeamWeaponsTilemaps ((uint16*)RomPtr(0x82c0a8))
#define kEquipmentBitmasks_Weapons ((uint16*)RomPtr(0x82c04c))
#define kEquipmentBitmasks_Suits ((uint16*)RomPtr(0x82c056))
#define kEquipmentBitmasks_Boots ((uint16*)RomPtr(0x82c062))
void LoadEquipmentScreenEquipmentTilemaps(void) { // 0x82A12B
if (samus_max_reserve_health) {
R3_.addr = addr_kEquipmentTilemapOffs_Tanks;
*(uint16 *)&R3_.bank = 130;
R0_.addr = *(uint16 *)IndirPtr(&R3_, 0);
R22_ = 14;
Copy_R22_Bytes(kEquipmentTilemaps_Tanks[0]);
R3_.addr = addr_kEquipmentTilemapOffs_Tanks;
*(uint16 *)&R3_.bank = 130;
R0_.addr = *(uint16 *)IndirPtr(&R3_, 2u);
R22_ = 14;
Copy_R22_Bytes(kEquipmentTilemaps_Tanks[1]);
}
uint16 v0 = 0;
R3_.addr = addr_kEquipmentTilemapOffs_Weapons;
*(uint16 *)&R3_.bank = 130;
R0_.addr = *(uint16 *)IndirPtr(&R3_, 0);
if (hyper_beam_flag) {
uint16 v3 = 0;
do {
uint16 v4 = kHyperBeamWeaponsTilemaps[v3 >> 1];
R22_ = 10;
Copy_R22_Bytes(v4);
v3 += 2;
R0_.addr = *(uint16 *)IndirPtr(&R3_, v3);
} while ((int16)(v3 - 10) < 0);
} else {
do {
int v1 = v0 >> 1;
if ((collected_beams & kEquipmentBitmasks_Weapons[v1]) != 0) {
uint16 v2 = kEquipmentTilemaps_Weapons[v1];
R22_ = 10;
Copy_R22_Bytes(v2);
if ((equipped_beams & kEquipmentBitmasks_Weapons[v1]) == 0) {
R18_ = 3072;
R22_ = 10;
SetPaletteOfR22TilemapBytesToR18();
}
} else {
R22_ = 10;
Copy_R22_Bytes(addr_kEquipmentScreenTilemap_Blank);
}
v0 += 2;
R0_.addr = *(uint16 *)IndirPtr(&R3_, v0);
} while ((int16)(v0 - 12) < 0);
}
uint16 v5 = 0;
R3_.addr = addr_kEquipmentTilemapOffs_Suits;
*(uint16 *)&R3_.bank = 130;
R0_.addr = *(uint16 *)IndirPtr(&R3_, 0);
do {
int v6 = v5 >> 1;
if ((collected_items & kEquipmentBitmasks_Suits[v6]) != 0) {
uint16 v7 = kEquipmentTilemaps_Suits[v6];
R22_ = 18;
Copy_R22_Bytes(v7);
if ((equipped_items & kEquipmentBitmasks_Suits[v6]) == 0) {
R18_ = 3072;
R22_ = 18;
SetPaletteOfR22TilemapBytesToR18();
}
} else {
R22_ = 18;
Copy_R22_Bytes(addr_kEquipmentScreenTilemap_Blank);
}
v5 += 2;
R0_.addr = *(uint16 *)IndirPtr(&R3_, v5);
} while ((int16)(v5 - 12) < 0);
uint16 v8 = 0;
R3_.addr = addr_kEquipmentTilemapOffs_Boots;
*(uint16 *)&R3_.bank = 130;
R0_.addr = *(uint16 *)IndirPtr(&R3_, 0);
do {
int v9 = v8 >> 1;
if ((collected_items & kEquipmentBitmasks_Boots[v9]) != 0) {
R22_ = 18;
Copy_R22_Bytes(kEquipmentTilemaps_Boots[v9]);
if ((equipped_items & kEquipmentBitmasks_Boots[v9]) == 0) {
R18_ = 3072;
R22_ = 18;
SetPaletteOfR22TilemapBytesToR18();
}
} else {
R22_ = 18;
Copy_R22_Bytes(addr_kEquipmentScreenTilemap_Blank);
}
v8 += 2;
R0_.addr = *(uint16 *)IndirPtr(&R3_, v8);
} while ((int16)(v8 - 6) < 0);
}
void Copy_R22_Bytes(uint16 k) { // 0x82A27E
R0_.bank = 126;
uint16 v1 = 0;
do {
uint16 *v2 = (uint16 *)RomPtr_82(k);
IndirWriteWord(&R0_, v1, *v2);
k += 2;
v1 += 2;
--R22_;
--R22_;
} while (R22_);
}
void SetPaletteOfR22TilemapBytesToR18(void) { // 0x82A29D
R0_.bank = 126;
uint16 v0 = 0;
do {
uint8 *v1 = IndirPtr(&R0_, v0);
IndirWriteWord(&R0_, v0, R18_ | *(uint16 *)v1 & 0xE3FF);
v0 += 2;
--R22_;
--R22_;
} while (R22_);
}
void ClearSamusBeamTiles(void) { // 0x82A2BE
WriteReg(VMADDL, 0);
WriteReg(VMADDH, 0x60u);
WriteReg(VMAIN, 0x80);
static const StartDmaCopy unk_82A2D4 = { 1, 1, 0x18, LONGPTR(0x9ad200), 0x1000 };
SetupDmaTransfer(&unk_82A2D4);
WriteReg(MDMAEN, 2u);
}
void ContinueInitGameplayResume(void) { // 0x82A2E3
int16 v0;
v0 = 512;
uint16 v1 = 0;
do {
palette_buffer[v1] = ram3000.pause_menu_map_tilemap[v1 + 384];
++v1;
v0 -= 2;
} while (v0);
SetupPpuForGameplayResume();
CalculateBgScrolls_Unpause();
UpdateBeamTilesAndPalette_Unpause();
ClearPauseMenuData();
CallSomeSamusCode(0xCu);
}
void SetupPpuForGameplayResume(void) { // 0x82A313
WriteReg(OBSEL, 3u);
reg_OBSEL = 3;
WriteReg(BGMODE, 9u);
reg_BGMODE = 9;
reg_BG12NBA = 0;
WriteReg(BG12NBA, 0);
reg_BG34NBA = 4;
WriteReg(BG34NBA, 4u);
reg_BG1SC = 81;
WriteReg(BG1SC, 0x51u);
reg_BG2SC = 73;
WriteReg(BG2SC, 0x49u);
reg_BG3SC = 90;
WriteReg(BG3SC, 0x5Au);
reg_BG4SC = 0;
WriteReg(BG4SC, 0);
}
void CalculateBgScrolls_Unpause(void) { // 0x82A34E
reg_BG1HOFS = bg1_x_offset + layer1_x_pos;
reg_BG1VOFS = bg1_y_offset + layer1_y_pos;
reg_BG2HOFS = bg2_x_scroll + layer2_x_pos;
reg_BG2VOFS = bg2_y_scroll + layer2_y_pos;
}
void UpdateBeamTilesAndPalette_Unpause(void) { // 0x82A377
UpdateBeamTilesAndPalette();
}
void ClearPauseMenuData(void) { // 0x82A380
menu_index = 0;
pausemenu_start_lr_pressed_highlight_timer = 0;
pausemenu_lr_animation_timer = 0;
pausemenu_item_selector_animation_timer = 0;
pausemenu_reserve_tank_animation_timer = 0;
UNUSED_word_7E0731 = 0;
pausemenu_uparrow_animation_timer = 0;
pausemenu_downarrow_animation_timer = 0;
pausemenu_rightarrow_animation_timer = 0;
pausemenu_leftarrow_animation_timer = 0;
UNUSED_word_7E073D = 0;
pausemenu_lr_animation_frame = 0;
pausemenu_item_selector_animation_frame = 0;
pausemenu_reserve_tank_animation_frame = 0;
UNUSED_word_7E0745 = 0;
pausemenu_uparrow_animation_frame = 0;
pausemenu_downarrow_animation_frame = 0;
pausemenu_rightarrow_animation_frame = 0;
pausemenu_leftarrow_animation_frame = 0;
pausemenu_shoulder_button_highlight = 0;
pausemenu_button_label_mode = 0;
pausemenu_equipment_category_item = 0;
pausemenu_reserve_tank_delay_ctr = 0;
UNUSED_word_7E0759 = 0;
UNUSED_word_7E075B = 0;
UNUSED_word_7E075D = 0;
UNUSED_word_7E075F = 0;
UNUSED_word_7E0761 = 0;
}
void sub_82A425(void) { // 0x82A425
;
}
void sub_82A42A(void) { // 0x82A42A
if (samus_pose == kPose_81_FaceR_Screwattack || samus_pose == kPose_82_FaceL_Screwattack) {
if ((equipped_items & 8) != 0)
return;
goto LABEL_8;
}
if ((samus_pose == kPose_1B_FaceR_SpaceJump || samus_pose == kPose_1C_FaceL_SpaceJump)
&& (equipped_items & 0x20) == 0) {
LABEL_8:
if (samus_pose_x_dir == 4)
samus_pose = kPose_1A_FaceL_SpinJump;
else
samus_pose = kPose_19_FaceR_SpinJump;
SamusFunc_F433();
Samus_SetAnimationFrameIfPoseChanged();
}
}
void sub_82A47B(void) { // 0x82A47B
if ((equipped_items & 4) == 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();
}
}
void sub_82A4A9(void) { // 0x82A4A9
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();
}
}
void HandlePauseScreenLR(void) { // 0x82A505
HandlePauseScreenLrInput();
DrawLrHighlight();
}
void HandlePauseScreenLrInput(void) { // 0x82A50C
if ((newly_held_down_timed_held_input & kButton_L) != 0) {
if (!pausemenu_button_label_mode)
return;
pausemenu_start_lr_pressed_highlight_timer = 5;
menu_index = 5;
pausemenu_shoulder_button_highlight = 1;
pausemenu_button_label_mode = 0;
SetPauseScreenButtonLabelPalettes();
goto LABEL_7;
}
if ((newly_held_down_timed_held_input & kButton_R) != 0 && pausemenu_button_label_mode != 2) {
pausemenu_start_lr_pressed_highlight_timer = 5;
menu_index = 2;
pausemenu_shoulder_button_highlight = 2;
pausemenu_button_label_mode = 2;
SetPauseScreenButtonLabelPalettes();
LABEL_7:
QueueSfx1_Max6(0x38u);
}
}
static const uint16 kPauseLrButtonPressedHighlight_Spritemap[2] = { 0x28, 0x29 };
static const uint16 kPauseLrButtonPressedHighlight_Y[2] = { 0x18, 0xe8 };
static const uint16 kPauseLrButtonPressedHighlight_X[2] = { 0xd0, 0xd0 };
void HandlePauseMenuLRPressHighlight(void) { // 0x82A56D
if (pausemenu_start_lr_pressed_highlight_timer) {
--pausemenu_start_lr_pressed_highlight_timer;
if (pausemenu_shoulder_button_highlight) {
R3_.addr = 0;
int v0 = pausemenu_shoulder_button_highlight - 1;
DrawMenuSpritemap(
kPauseLrButtonPressedHighlight_Spritemap[v0],
kPauseLrButtonPressedHighlight_Y[v0],
kPauseLrButtonPressedHighlight_X[v0] - 1);
}
}
}
void DrawLrHighlight(void) { // 0x82A59A
DrawPauseScreenSpriteAnim(2u, 0x18u, 0xD0u);
DrawPauseScreenSpriteAnim(2u, 0xE8u, 0xD0u);
}
void HandlePauseScreenStart(void) { // 0x82A5B7
if ((newly_held_down_timed_held_input & kButton_Start) != 0) {
QueueSfx1_Max6(0x38u);
screen_fade_delay = 1;
screen_fade_counter = 1;
uint16 v0 = pausemenu_button_label_mode;
pausemenu_button_label_mode = 1;
SetPauseScreenButtonLabelPalettes();
pausemenu_button_label_mode = v0;
pausemenu_start_lr_pressed_highlight_timer = 11;
++game_state;
}
UpdatePauseMenuLRStartVramTilemap();
}
void HighlightPauseScreenButton(void) { // 0x82A5F1
if (pausemenu_start_lr_pressed_highlight_timer) {
--pausemenu_start_lr_pressed_highlight_timer;
R3_.addr = 0;
DrawMenuSpritemap(0x2Bu, 0x90u, 0xD0u);
}
}
static Func_V *const kSetPauseScreenButtonLabelPalettes_Funcs[3] = { // 0x82A615
SetPauseScreenButtonLabelPalettes_0,
SetPauseScreenButtonLabelPalettes_1,
SetPauseScreenButtonLabelPalettes_2,
};
void SetPauseScreenButtonLabelPalettes(void) {
kSetPauseScreenButtonLabelPalettes_Funcs[pausemenu_button_label_mode]();
}
void SetPauseScreenButtonLabelPalettes_2(void) { // 0x82A628
int16 v0;
int16 v2;
int16 v4;
int16 v6;
int16 v8;
int16 v10;
v0 = 10;
uint16 v1 = 0;
do {
ram3000.pause_menu_map_tilemap[v1 + 805] = ram3000.pause_menu_map_tilemap[v1 + 805] & 0xE3FF | 0x800;
++v1;
v0 -= 2;
} while (v0);
v2 = 10;
uint16 v3 = 0;
do {
ram3000.pause_menu_map_tilemap[v3 + 837] = ram3000.pause_menu_map_tilemap[v3 + 837] & 0xE3FF | 0x800;
++v3;
v2 -= 2;
} while (v2);
v4 = 8;
uint16 v5 = 0;
do {
ram3000.pause_menu_map_tilemap[v5 + 812] = ram3000.pause_menu_map_tilemap[v5 + 812] & 0xE3FF | 0x800;
++v5;
v4 -= 2;
} while (v4);
v6 = 8;
uint16 v7 = 0;
do {
ram3000.pause_menu_map_tilemap[v7 + 844] = ram3000.pause_menu_map_tilemap[v7 + 844] & 0xE3FF | 0x800;
++v7;
v6 -= 2;
} while (v6);
v8 = 10;
uint16 v9 = 0;
do {
ram3000.pause_menu_map_tilemap[v9 + 822] = ram3000.pause_menu_map_tilemap[v9 + 822] & 0xE3FF | 0x1400;
++v9;
v8 -= 2;
} while (v8);
v10 = 10;
uint16 v11 = 0;
do {
ram3000.pause_menu_map_tilemap[v11 + 854] = ram3000.pause_menu_map_tilemap[v11 + 854] & 0xE3FF | 0x1400;
++v11;
v10 -= 2;
} while (v10);
}
void SetPauseScreenButtonLabelPalettes_1(void) { // 0x82A6DF
int16 v0;
int16 v2;
int16 v4;
int16 v6;
int16 v8;
int16 v10;
v0 = 8;
uint16 v1 = 0;
do {
ram3000.pause_menu_map_tilemap[v1 + 812] = ram3000.pause_menu_map_tilemap[v1 + 812] & 0xE3FF | 0x800;
++v1;
v0 -= 2;
} while (v0);
v2 = 8;
uint16 v3 = 0;
do {
ram3000.pause_menu_map_tilemap[v3 + 844] = ram3000.pause_menu_map_tilemap[v3 + 844] & 0xE3FF | 0x800;
++v3;
v2 -= 2;
} while (v2);
v4 = 10;
uint16 v5 = 0;
do {
ram3000.pause_menu_map_tilemap[v5 + 805] = ram3000.pause_menu_map_tilemap[v5 + 805] & 0xE3FF | 0x1400;
++v5;
v4 -= 2;
} while (v4);
v6 = 10;
uint16 v7 = 0;
do {
ram3000.pause_menu_map_tilemap[v7 + 837] = ram3000.pause_menu_map_tilemap[v7 + 837] & 0xE3FF | 0x1400;
++v7;
v6 -= 2;
} while (v6);
v8 = 10;
uint16 v9 = 0;
do {
ram3000.pause_menu_map_tilemap[v9 + 822] = ram3000.pause_menu_map_tilemap[v9 + 822] & 0xE3FF | 0x1400;
++v9;
v8 -= 2;
} while (v8);
v10 = 10;
uint16 v11 = 0;
do {
ram3000.pause_menu_map_tilemap[v11 + 854] = ram3000.pause_menu_map_tilemap[v11 + 854] & 0xE3FF | 0x1400;
++v11;
v10 -= 2;
} while (v10);
}
void SetPauseScreenButtonLabelPalettes_0(void) { // 0x82A796
int16 v0;
int16 v2;
int16 v4;
int16 v6;
int16 v8;
int16 v10;
v0 = 10;
uint16 v1 = 0;
do {
ram3000.pause_menu_map_tilemap[v1 + 822] = ram3000.pause_menu_map_tilemap[v1 + 822] & 0xE3FF | 0x800;
++v1;
v0 -= 2;
} while (v0);
v2 = 10;
uint16 v3 = 0;
do {
ram3000.pause_menu_map_tilemap[v3 + 854] = ram3000.pause_menu_map_tilemap[v3 + 854] & 0xE3FF | 0x800;
++v3;
v2 -= 2;
} while (v2);
v4 = 8;
uint16 v5 = 0;
do {
ram3000.pause_menu_map_tilemap[v5 + 812] = ram3000.pause_menu_map_tilemap[v5 + 812] & 0xE3FF | 0x800;
++v5;
v4 -= 2;
} while (v4);
v6 = 8;
uint16 v7 = 0;
do {
ram3000.pause_menu_map_tilemap[v7 + 844] = ram3000.pause_menu_map_tilemap[v7 + 844] & 0xE3FF | 0x800;
++v7;
v6 -= 2;
} while (v6);
v8 = 10;
uint16 v9 = 0;
do {
ram3000.pause_menu_map_tilemap[v9 + 805] = ram3000.pause_menu_map_tilemap[v9 + 805] & 0xE3FF | 0x1400;
++v9;
v8 -= 2;
} while (v8);
v10 = 10;
uint16 v11 = 0;
do {
ram3000.pause_menu_map_tilemap[v11 + 837] = ram3000.pause_menu_map_tilemap[v11 + 837] & 0xE3FF | 0x1400;
++v11;
v10 -= 2;
} while (v10);
}
void UpdatePauseMenuLRStartVramTilemap(void) { // 0x82A84D
uint16 v0 = vram_write_queue_tail;
gVramWriteEntry(vram_write_queue_tail)->size = 128;
v0 += 2;
gVramWriteEntry(v0)->size = 0x3640;
v0 += 2;
LOBYTE(gVramWriteEntry(v0++)->size) = 126;
gVramWriteEntry(v0)->size = ((reg_BG2SC & 0xFC) << 8) + 800;
vram_write_queue_tail = v0 + 2;
}
#define kPauseScreenSpriteAnimationData_0 (*(PauseScreenSpriteAnimationData*)RomPtr(0x82c0b2))
#define kPauseScreenSpriteAnimationData_1 (*(PauseScreenSpriteAnimationData*)RomPtr(0x82c0c4))
#define kPauseScreenSpriteAnimationData_2 (*(PauseScreenSpriteAnimationData*)RomPtr(0x82c0d6))
#define kPauseScreenSpriteAnimationData_3 (*(PauseScreenSpriteAnimationData*)RomPtr(0x82c0e8))
#define kPAuseSpritePaletteIndexValues ((uint16*)RomPtr(0x82c0fa))
#define kPausePtsToAnimationSpritemapBaseIds ((uint16*)RomPtr(0x82c1e4))
void DrawPauseScreenSpriteAnim(uint16 a, uint16 k, uint16 j) { // 0x82A881
int16 v9;
int16 v10;
int16 v12;
R18_ = k;
R20_ = j;
uint16 v3 = 2 * (a - 1);
uint16 v4 = *(VoidP *)((char *)&kPauseScreenSpriteAnimationData_0.unused + v3);
uint8 *v5 = RomPtr_RAM(v4);
bool v6 = *(uint16 *)v5 == 1;
bool v7 = (int16)-- * (uint16 *)v5 < 0;
if (v6 || v7) {
R24_ = v4;
uint8 *v8 = RomPtr_RAM(*(VoidP *)((char *)&kPauseScreenSpriteAnimationData_1.unused + v3));
v9 = *(uint16 *)v8 + 1;
*(uint16 *)v8 = v9;
R22_ = *(uint16 *)v8 + 2 * v9;
v10 = *RomPtr_82(R22_ + *(VoidP *)((char *)&kPauseScreenSpriteAnimationData_3.unused + v3));
if (v10 == 255) {
*(uint16 *)RomPtr_RAM(*(VoidP *)((char *)&kPauseScreenSpriteAnimationData_1.unused + v3)) = 0;
v10 = *RomPtr_82(*(VoidP *)((char *)&kPauseScreenSpriteAnimationData_3.unused + v3));
}
*(uint16 *)RomPtr_RAM(R24_) = v10;
}
R24_ = 3 * *(uint16 *)RomPtr_RAM(*(VoidP *)((char *)&kPauseScreenSpriteAnimationData_1.unused + v3));
v12 = R24_ + *(VoidP *)((char *)&kPauseScreenSpriteAnimationData_3.unused + v3) + 1;
R3_.addr = kPAuseSpritePaletteIndexValues[3];
R24_ = *RomPtr_82(v12 + 1);
R26_ = 2 * *RomPtr_RAM(*(VoidP *)((char *)&kPauseScreenSpriteAnimationData_2.unused + v3));
uint8 *v11 = RomPtr_82(R26_ + kPausePtsToAnimationSpritemapBaseIds[v3 >> 1]);
DrawMenuSpritemap(R24_ + *(uint16 *)v11, R18_, R20_ - 1);
}
#define kPauseAnimatedPalette ((uint16*)RomPtr(0x82a987))
void HandlePauseScreenPaletteAnimation(void) { // 0x82A92B
uint16 v2;
uint16 j;
uint8 v1;
if ((uint8)pausemenu_palette_animation_timer) {
LOBYTE(pausemenu_palette_animation_timer) = pausemenu_palette_animation_timer - 1;
if (!(uint8)pausemenu_palette_animation_timer) {
for (int i = pausemenu_palette_animation_frame + 1; ; i = 0) {
LOBYTE(pausemenu_palette_animation_frame) = i;
v1 = kPauseLrHighlightAnimData[(uint8)(3 * i)];
if (v1 != 0xFF)
break;
QueueSfx3_Max6(0x2Au);
}
LOBYTE(pausemenu_palette_animation_timer) = v1;
LOBYTE(v2) = 0;
HIBYTE(v2) = pausemenu_palette_animation_frame;
uint16 v3 = (v2 >> 3) + 30;
for (j = 30; (j & 0x8000u) == 0; j -= 2) {
palette_buffer[(j >> 1) + 176] = kPauseAnimatedPalette[v3 >> 1];
v3 -= 2;
}
}
}
}
#define kPauseReserveTankAnimationData ((uint8*)RomPtr(0x82c165))
void EquipmentScreenSetupReserveMode(void) { // 0x82AB47
VoidP v0;
int16 v3;
int16 v5;
int16 v7;
int16 v8;
reg_BG4HOFS = reg_BG1HOFS;
reg_BG4VOFS = reg_BG1VOFS;
reg_BG1HOFS = 0;
reg_BG1VOFS = 0;
if (samus_max_reserve_health && reserve_health_mode) {
v0 = addr_kEquipmentScreenTilemap_AUTO;
if (reserve_health_mode != 1)
v0 = addr_kEquipmentScreenTilemap_MANUAL;
*(uint16 *)&R0_.bank = 130;
R0_.addr = v0;
R18_ = 4;
uint16 v1 = 0;
uint16 v2 = 0;
do {
v3 = ram3800.cinematic_bg_tilemap[v1 + 327] & 0xFC00;
ram3800.cinematic_bg_tilemap[v1 + 327] = *(uint16 *)IndirPtr(&R0_, v2) | v3;
v2 += 2;
++v1;
--R18_;
} while (R18_);
}
pausemenu_item_selector_animation_frame = 0;
pausemenu_item_selector_animation_timer = kPauseLrHighlightAnimData[0];
pausemenu_reserve_tank_animation_frame = 0;
pausemenu_reserve_tank_animation_timer = kPauseReserveTankAnimationData[0];
if (samus_max_reserve_health) {
pausemenu_equipment_category_item = 0;
} else if (hyper_beam_flag) {
LABEL_15:;
uint16 v6 = 0;
do {
if ((kEquipmentBitmasks_Suits[v6 >> 1] & collected_items) != 0) {
LOBYTE(v7) = (uint16)(v6 >> 1) >> 8;
HIBYTE(v7) = v6 >> 1;
pausemenu_equipment_category_item = v7 | 2;
goto LABEL_21;
}
v6 += 2;
} while ((int16)(v6 - 12) < 0);
v8 = 0;
do
v8 += 2;
while ((int16)(v8 - 6) < 0);
} else {
uint16 v4 = 0;
while ((kEquipmentBitmasks_Weapons[v4 >> 1] & collected_beams) == 0) {
v4 += 2;
if ((int16)(v4 - 10) >= 0)
goto LABEL_15;
}
LOBYTE(v5) = (uint16)(v4 >> 1) >> 8;
HIBYTE(v5) = v4 >> 1;
pausemenu_equipment_category_item = v5 | 1;
}
LABEL_21:
if (samus_reserve_health) {
EquipmentScreenGlowingArrowSolidOn();
WriteSamusWireframeTilemapAndQueue();
}
}
void EquipmentScreenTransferBG1Tilemap(void) { // 0x82AC22
WriteReg(VMADDL, 0);
WriteReg(VMADDH, 0x30u);
WriteReg(VMAIN, 0x80);
static const StartDmaCopy unk_82AC3B = { 1, 1, 0x18, LONGPTR(0x7e3800), 0x0800 };
SetupDmaTransfer(&unk_82AC3B);
WriteReg(MDMAEN, 2u);
reg_BG1VOFS = 0;
}
static Func_V *const kEquipmentScreenCategories[4] = { // 0x82AC4F
EquipmentScreenCategory_Tanks,
EquipmentScreenCategory_Weapons,
EquipmentScreenCategory_Suit,
EquipmentScreenCategory_Boots,
};
void EquipmentScreenMain(void) {
kEquipmentScreenCategories[(uint16)(2 * (uint8)pausemenu_equipment_category_item) >> 1]();
EquipmentScreenDrawItemSelector();
EquipmentScreenDisplayReserveTankAmount();
WriteSamusWireframeTilemapAndQueue();
}
static Func_V *const kEquipmentScreenCategory_TanksFuncs[2] = { // 0x82AC70
EquipmentScreenCategory_Tanks_0,
EquipmentScreenCategory_Tanks_1,
};
void EquipmentScreenCategory_Tanks(void) {
kEquipmentScreenCategory_TanksFuncs[(uint16)(2 * HIBYTE(pausemenu_equipment_category_item)) >> 1]();
EquipmentScreenHandleDpad();
EquipmentScreenGlowingArrow();
}
void EquipmentScreenHandleDpad(void) { // 0x82AC8B
R18_ = pausemenu_equipment_category_item;
if ((joypad1_newkeys & kButton_Right) != 0) {
if ((joypad1_newkeys & kButton_Down) != 0 || EquipmentScreenMoveLowerOnSuitsMisc(0) == 0xFFFF)
EquipmentScreenMoveToHighJumpOrLowerInBoots(0);
} else if ((joypad1_newkeys & kButton_Up) != 0) {
if ((pausemenu_equipment_category_item & 0xFF00) != 0) {
QueueSfx1_Max6(0x37u);
pausemenu_equipment_category_item -= 256;
}
} else if ((joypad1_newkeys & kButton_Down) != 0) {
if ((pausemenu_equipment_category_item & 0xFF00) == 256
|| reserve_health_mode == 1
|| (pausemenu_equipment_category_item += 256, !samus_reserve_health)) {
EquipmentScreenMoveToBeams(0);
} else {
QueueSfx1_Max6(0x37u);
}
}
}
static Func_V *const kEquipmentScreenGlowingArrowFuncs[2] = { // 0x82AD0A
EquipmentScreenGlowingArrowAnimated,
EquipmentScreenGlowingArrowSolidOn,
};
void EquipmentScreenGlowingArrow(void) {
if ((uint8)pausemenu_equipment_category_item)
EquipmentScreenGlowingArrowSolidOff();
else
kEquipmentScreenGlowingArrowFuncs[0]();
}
static const uint16 kEquipmentScreenGlowingArrowPalettes0[32] = { 0x39e, 0x77d, 0xb5c, 0xf5b, 0x133a, 0x171a, 0x1f19, 0x22f8, 0x26d7, 0x2ad6, 0x2eb6, 0x3695, 0x3a94, 0x3e73, 0x4253, 0x4a52, 0x4a52, 0x4253, 0x3e73, 0x3a94, 0x3695, 0x2eb6, 0x2ad6, 0x26d7, 0x22f8, 0x1f19, 0x171a, 0x133a, 0xf5b, 0xb5c, 0x77d, 0x39e };
static const uint16 kEquipmentScreenGlowingArrowPalettes1[32] = { 0x156, 0x155, 0x554, 0x954, 0xd53, 0xd52, 0x1152, 0x1551, 0x1970, 0x1d70, 0x1d6f, 0x216e, 0x256e, 0x296d, 0x296c, 0x318c, 0x318c, 0x296c, 0x296d, 0x256e, 0x216e, 0x1d6f, 0x1d70, 0x1970, 0x1551, 0x1152, 0xd52, 0xd53, 0x954, 0x554, 0x155, 0x156 };
void EquipmentScreenGlowingArrowAnimated(void) { // 0x82AD29
if (reserve_health_mode == 1) {
int v0 = nmi_frame_counter_byte & 0x1F;
palette_buffer[102] = kEquipmentScreenGlowingArrowPalettes0[v0];
palette_buffer[107] = kEquipmentScreenGlowingArrowPalettes1[v0];
EquipmentScreenEnergyArrowGlow_On();
} else {
palette_buffer[107] = 926;
palette_buffer[102] = 342;
EquipmentScreenEnergyArrowGlow_Off();
}
}
void EquipmentScreenGlowingArrowSolidOn(void) { // 0x82ADDD
palette_buffer[107] = 926;
palette_buffer[102] = 342;
EquipmentScreenEnergyArrowGlow_On();
}
void EquipmentScreenGlowingArrowSolidOff(void) { // 0x82ADEF
palette_buffer[107] = 926;
palette_buffer[102] = 342;
EquipmentScreenEnergyArrowGlow_Off();
}
void EquipmentScreenEnergyArrowGlow_On(void) { // 0x82AE01
int16 v0;
int16 v2;
v0 = 16;
uint16 v1 = 0;
do {
ram3800.cinematic_bg_tilemap[v1 + 129] = ram3800.cinematic_bg_tilemap[v1 + 129] & 0xE3FF | 0x1800;
v1 += 32;
v0 -= 2;
} while (v0);
v2 = 4;
uint16 v3 = 0;
do {
ram3800.cinematic_bg_tilemap[v3 + 385] = ram3800.cinematic_bg_tilemap[v3 + 385] & 0xE3FF | 0x1800;
++v3;
v2 -= 2;
} while (v2);
}
void EquipmentScreenEnergyArrowGlow_Off(void) { // 0x82AE46
int16 v0;
int16 v2;
v0 = 16;
uint16 v1 = 0;
do {
ram3800.cinematic_bg_tilemap[v1 + 129] = ram3800.cinematic_bg_tilemap[v1 + 129] & 0xE3FF | 0x1C00;
v1 += 32;
v0 -= 2;
} while (v0);
v2 = 4;
uint16 v3 = 0;
do {
ram3800.cinematic_bg_tilemap[v3 + 385] = ram3800.cinematic_bg_tilemap[v3 + 385] & 0xE3FF | 0x1C00;
++v3;
v2 -= 2;
} while (v2);
}
static const uint16 kEquipmentScreenTilemap_MODE_MANUAL[7] = { 0x2519, 0x251a, 0x251b, 0x3d46, 0x3d47, 0x3d48, 0x3d49 };
static const uint16 kEquipmentScreenTilemap_RESERVE_TANK[7] = { 0x3c80, 0x3c81, 0x3c82, 0x3c83, 0x3c84, 0x3c85, 0x3c86 };
static const uint16 kEquipmentScreenTilemap_MANUAL[4] = { 0x3d46, 0x3d47, 0x3d48, 0x3d49 };
static const uint16 kEquipmentScreenTilemap_AUTO[4] = { 0x3d56, 0x3d57, 0x3d58, 0x3d59 };
static const uint16 kEquipmentScreenTilemap_CHARGE[5] = { 0x8ff, 0x8d8, 0x8d9, 0x8da, 0x8e7 };
static const uint16 kEquipmentScreenTilemap_ICE[5] = { 0x8ff, 0x8db, 0x8dc, 0x8d4, 0x8d4 };
static const uint16 kEquipmentScreenTilemap_WAVE[5] = { 0x8ff, 0x8dd, 0x8de, 0x8df, 0x8d4 };
static const uint16 kEquipmentScreenTilemap_SPAZER[5] = { 0x8ff, 0x8e8, 0x8e9, 0x8ea, 0x8eb };
static const uint16 kEquipmentScreenTilemap_PLASMA[5] = { 0x8ff, 0x8ec, 0x8ed, 0x8ee, 0x8ef };
static const uint16 kEquipmentScreenTilemap_VARIASUIT[9] = { // 0x82AE8B
0x8ff, 0x900, 0x901, 0x902, 0x903, 0x904, 0x905, 0x8d4,
0x8d4,
};
static const uint16 kEquipmentScreenTilemap_GRAVITYSUIT[9] = {
0x8ff, 0x8d0, 0x8d1, 0x8d2, 0x8d3, 0x903, 0x904, 0x905,
0x8d4,
};
static const uint16 kEquipmentScreenTilemap_MORPHINGBALL[9] = {
0x8ff, 0x920, 0x921, 0x922, 0x923, 0x917, 0x918, 0x90f,
0x91f,
};
static const uint16 kEquipmentScreenTilemap_BOMBS[9] = {
0x8ff, 0x8d5, 0x8d6, 0x8d7, 0x8d4, 0x8d4, 0x8d4, 0x8d4,
0x8d4,
};
static const uint16 kEquipmentScreenTilemap_SPRING_BALL[9] = {
0x8ff, 0x910, 0x911, 0x912, 0x913, 0x914, 0x915, 0x916,
0x8d4,
};
static const uint16 kEquipmentScreenTilemap_SCREW_ATTACK[9] = {
0x8ff, 0x8e0, 0x8e1, 0x8e2, 0x8e3, 0x8e4, 0x8e5, 0x8e6,
0x8d4,
};
static const uint16 kEquipmentScreenTilemap_HIJUMP_BOOTS[9] = {
0x8ff, 0x930, 0x931, 0x932, 0x933, 0x934, 0x935, 0x936,
0x8d4,
};
static const uint16 kEquipmentScreenTilemap_SPACE_JUMP[9] = {
0x8ff, 0x8f0, 0x8f1, 0x8f2, 0x8f3, 0x8f4, 0x8f5, 0x8d4,
0x8d4,
};
static const uint16 kEquipmentScreenTilemap_SPEED_BOOSTER[9] = {
0x8ff, 0x924, 0x925, 0x926, 0x927, 0x928, 0x929, 0x92a,
0x92b,
};
static const uint16 kEquipmentScreenTilemap_HYPER[9] = {
0x8ff, 0x937, 0x938, 0x939, 0x92f, 0x8d4, 0x8d4, 0x8d4,
0x8d4,
};
static const uint16 kEquipmentScreenTilemap_Blank[9] = {
0, 0, 0, 0, 0, 0, 0, 0,
0,
};
void EquipmentScreenCategory_Tanks_0(void) {
int16 v0;
int16 v2;
if ((joypad1_newkeys & kButton_A) != 0 && samus_max_reserve_health) {
QueueSfx1_Max6(0x37u);
if (reserve_health_mode == 1) {
reserve_health_mode = 2;
EquipmentScreenHudReserveAutoTilemap_Off();
v0 = 8;
uint16 v1 = 0;
do {
ram3800.cinematic_bg_tilemap[v1 + 327] = kEquipmentScreenTilemap_MANUAL[v1] | ram3800.cinematic_bg_tilemap[v1 + 327] & 0xFC00;
++v1;
v0 -= 2;
} while (v0);
} else {
reserve_health_mode = 1;
EquipmentScreenHudReserveAutoTilemap_On_BUGGY();
v2 = 8;
uint16 v3 = 0;
do {
ram3800.cinematic_bg_tilemap[v3 + 327] = kEquipmentScreenTilemap_AUTO[v3] | ram3800.cinematic_bg_tilemap[v3 + 327] & 0xFC00;
++v3;
v2 -= 2;
} while (v2);
}
}
}
void EquipmentScreenHudReserveAutoTilemap_On_BUGGY(void) { // 0x82AEFD
uint16 v0 = -26229;
if (!samus_reserve_health)
v0 = -26217;
uint16 *v1 = (uint16 *)RomPtr_82(v0);
hud_tilemap[8] = *v1;
hud_tilemap[9] = v1[1];
hud_tilemap[40] = v1[2];
hud_tilemap[41] = v1[3];
hud_tilemap[72] = v1[4];
hud_tilemap[73] = v1[5];
}
void EquipmentScreenHudReserveAutoTilemap_Off(void) { // 0x82AF33
hud_tilemap[8] = 11279;
hud_tilemap[9] = 11279;
hud_tilemap[40] = 11279;
hud_tilemap[41] = 11279;
hud_tilemap[72] = 11279;
hud_tilemap[73] = 11279;
}
static const uint16 kReserveTankEnergyTransferPerFrame = 1;
void EquipmentScreenCategory_Tanks_1(void) { // 0x82AF4F
if (!pausemenu_reserve_tank_delay_ctr) {
if ((joypad1_newkeys & kButton_A) == 0)
return;
pausemenu_reserve_tank_delay_ctr = (samus_reserve_health + 7) & 0xFFF8;
}
if ((--pausemenu_reserve_tank_delay_ctr & 7) == 7)
QueueSfx3_Max6(0x2Du);
samus_health += kReserveTankEnergyTransferPerFrame;
if ((int16)(samus_health - samus_max_health) < 0) {
bool v0 = (int16)(samus_reserve_health - kReserveTankEnergyTransferPerFrame) < 0;
samus_reserve_health -= kReserveTankEnergyTransferPerFrame;
if (samus_reserve_health) {
if (!v0)
return;
samus_health += samus_reserve_health;
}
} else {
samus_health = samus_max_health;
}
samus_reserve_health = 0;
pausemenu_reserve_tank_delay_ctr = 0;
EquipmentScreenEnergyArrowGlow_Off();
pausemenu_equipment_category_item = 0;
}
void EquipmentScreenCategory_Weapons(void) { // 0x82AFBE
EquipmentScreenCategory_Weapons_MoveButtons();
R36 = equipped_beams;
if (collected_beams) {
R24_ = 10;
EquipmentScreenCategory_ButtonResponse();
EquipmentScreenCategory_Weapons_PlazmaSpazerCheck();
}
}
void EquipmentScreenCategory_Weapons_MoveButtons(void) { // 0x82AFDB
R18_ = pausemenu_equipment_category_item;
if ((joypad1_newkeys & 0x100) != 0) {
if ((joypad1_newkeys & 0x800) != 0) {
EquipmentScreenMoveLowerOnSuitsMisc(0);
} else if (EquipmentScreenMoveLowerOnSuitsMisc(4u)) {
EquipmentScreenMoveToHighJumpOrLowerInBoots(0);
}
} else if ((joypad1_newkeys & 0x400) != 0) {
if (!hyper_beam_flag && pausemenu_equipment_category_item != 1025) {
pausemenu_equipment_category_item += 256;
EquipmentScreenMoveToBeams(2 * HIBYTE(pausemenu_equipment_category_item));
}
} else if ((joypad1_newkeys & 0x800) != 0) {
if ((pausemenu_equipment_category_item & 0xFF00) == 0
|| (pausemenu_equipment_category_item -= 256,
EquipmentScreenMoveToBottomOfBeams(2 * HIBYTE(pausemenu_equipment_category_item)) == 0xFFFF)) {
if (!EquipmentScreenMoveToReserveTanks())
pausemenu_equipment_category_item = R18_;
}
}
}
#define kEquipmentTilemapOffs_Tanks ((uint16*)RomPtr(0x82c068))
#define kEquipmentTilemapOffs_Weapons ((uint16*)RomPtr(0x82c06c))
#define kEquipmentTilemapOffs_Suits ((uint16*)RomPtr(0x82c076))
#define kEquipmentTilemapOffs_Boots ((uint16*)RomPtr(0x82c082))
#define kEquipmentTilemaps_Tanks ((uint16*)RomPtr(0x82c088))
#define kEquipmentTilemaps_Weapons ((uint16*)RomPtr(0x82c08c))
#define kEquipmentTilemaps_Suits ((uint16*)RomPtr(0x82c096))
#define kEquipmentTilemaps_Boots ((uint16*)RomPtr(0x82c0a2))
void EquipmentScreenCategory_Weapons_PlazmaSpazerCheck(void) { // 0x82B068
if (((uint8)equipped_beams & (uint8)~(uint8)R36 & 4) != 0) {
if ((R36 & 4) == 0 && (equipped_beams & 8) != 0) {
equipped_beams &= ~8;
R0_.addr = kEquipmentTilemapOffs_Weapons[4];
goto LABEL_9;
}
} else if (((uint8)equipped_beams & (uint8)~(uint8)R36 & 8) != 0
&& (R36 & 8) == 0
&& (equipped_beams & 4) != 0) {
equipped_beams &= ~4;
R0_.addr = kEquipmentTilemapOffs_Weapons[3];
LABEL_9:
R18_ = 3072;
R22_ = 10;
SetPaletteOfR22TilemapBytesToR18();
}
}
void EquipmentScreenCategory_Suit(void) { // 0x82B0C2
EquipmentScreenCategory_Suit_MoveResponse();
R24_ = 18;
EquipmentScreenCategory_ButtonResponse();
}
void EquipmentScreenCategory_Suit_MoveResponse(void) { // 0x82B0D2
R18_ = pausemenu_equipment_category_item;
if ((joypad1_newkeys & kButton_Left) != 0) {
if ((joypad1_newkeys & kButton_Down) == 0) {
if (EquipmentScreenMoveToReserveTanks())
return;
pausemenu_equipment_category_item = R18_;
}
EquipmentScreenMoveToBeams(0);
} else if ((joypad1_newkeys & kButton_Up) != 0) {
if ((pausemenu_equipment_category_item & 0xFF00) != 0) {
pausemenu_equipment_category_item -= 256;
EquipmentScreenMoveToScrewOrHigherOnSuits(2 * HIBYTE(pausemenu_equipment_category_item));
}
} else if ((joypad1_newkeys & kButton_Down) != 0) {
if ((pausemenu_equipment_category_item & 0xFF00) == 1280
|| (pausemenu_equipment_category_item += 256,
EquipmentScreenMoveLowerOnSuitsMisc(2 * HIBYTE(pausemenu_equipment_category_item)) == 0xFFFF)) {
EquipmentScreenMoveToHighJumpOrLowerInBoots(0);
}
}
}
void EquipmentScreenCategory_Boots(void) { // 0x82B150
EquipmentScreenCategory_Boots_MoveResponse();
R24_ = 18;
EquipmentScreenCategory_ButtonResponse();
}
void EquipmentScreenCategory_Boots_MoveResponse(void) { // 0x82B160
R18_ = pausemenu_equipment_category_item;
if ((joypad1_newkeys & kButton_Left) != 0) {
if (((joypad1_newkeys & kButton_Up) != 0 || EquipmentScreenMoveToBottomOfBeams(8u) == 0xFFFF)
&& !EquipmentScreenMoveToReserveTanks()) {
pausemenu_equipment_category_item = R18_;
}
} else if ((joypad1_newkeys & kButton_Down) != 0) {
if (pausemenu_equipment_category_item != 515) {
pausemenu_equipment_category_item += 256;
EquipmentScreenMoveToHighJumpOrLowerInBoots(2 * HIBYTE(pausemenu_equipment_category_item));
}
} else if ((joypad1_newkeys & kButton_Up) != 0) {
if ((pausemenu_equipment_category_item & 0xFF00) == 0
|| (pausemenu_equipment_category_item -= 256,
EquipmentScreenCategory_Boots_MoveUpInBoots(2 * HIBYTE(pausemenu_equipment_category_item)) == 0xFFFF)) {
EquipmentScreenMoveToScrewOrHigherOnSuits(0xAu);
}
}
}
void WriteSamusWireframeTilemapAndQueue(void) { // 0x82B1E0
WriteSamusWireframeTilemap();
uint16 v0 = vram_write_queue_tail;
gVramWriteEntry(vram_write_queue_tail)->size = 1280;
v0 += 2;
gVramWriteEntry(v0)->size = ADDR16_OF_RAM(ram3800) + 256;
v0 += 2;
LOBYTE(gVramWriteEntry(v0++)->size) = 126;
gVramWriteEntry(v0)->size = 0x3080;
vram_write_queue_tail = v0 + 2;
}
#define kEquipmentScreenWireframeCmp ((uint16*)RomPtr(0x82b257))
#define kEquipmentScreenWireframePtrs ((uint16*)RomPtr(0x82b25f))
void WriteSamusWireframeTilemap(void) { // 0x82B20C
uint16 i;
for (i = 0; (equipped_items & 0x101) != kEquipmentScreenWireframeCmp[i >> 1]; i += 2)
;
R0_.addr = kEquipmentScreenWireframePtrs[i >> 1];
*(uint16 *)&R0_.bank = 130;
R20_ = 17;
uint16 v1 = 0;
uint16 v2 = 472;
do {
uint16 v3 = v2;
R18_ = 8;
do {
*(uint16 *)((char *)ram3800.cinematic_bg_tilemap + v2) = *(uint16 *)IndirPtr(&R0_, v1);
v2 += 2;
v1 += 2;
--R18_;
} while (R18_);
v2 = v3 + 64;
--R20_;
} while (R20_);
}
#define kEquipmentScreenPtrsToItemXYpos ((uint16*)RomPtr(0x82c18e))
void EquipmentScreenDrawItemSelector(void) { // 0x82B267
if (samus_max_reserve_health | (uint16)(collected_items | collected_beams)) {
R18_ = kEquipmentScreenPtrsToItemXYpos[(uint16)(2 * (uint8)pausemenu_equipment_category_item) >> 1];
uint16 v0 = *(uint16 *)RomPtr_82(R18_ + 4 * HIBYTE(pausemenu_equipment_category_item)) - 1;
uint16 v1 = *(uint16 *)RomPtr_82(R18_ + 4 * HIBYTE(pausemenu_equipment_category_item) + 2);
DrawPauseScreenSpriteAnim(3u, v0, v1);
}
}
void EquipmentScreenDisplayReserveTankAmount(void) { // 0x82B2A2
EquipmentScreenDisplayReserveTankAmount_();
}
static const uint16 kEquipmentScreenReserveTank_X[6] = { // 0x82B2AA
0x18, 0x20,
0x28, 0x30,
0x38, 0x40,
};
static const uint16 kEquipmentScreenReserveTank_Y = 0x60;
static const uint16 kPartialReserveTankSpritemapIds[16] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27 };
void EquipmentScreenDisplayReserveTankAmount_(void) {
uint16 a;
R3_.addr = 0;
EquipmentScreenDisplayReserves_PaletteSetup();
bg3_tilemap_offset = 0;
if (samus_max_reserve_health) {
R44 = samus_max_reserve_health / 100;
int mod_value = samus_reserve_health % 100;
R50 = mod_value;
R42 = samus_reserve_health / 100;
R48 = R42;
R46 = R42;
if (R42) {
uint16 v0 = 0;
do {
a = v0;
DrawMenuSpritemap(0x1Bu, kEquipmentScreenReserveTank_X[v0 >> 1], kEquipmentScreenReserveTank_Y - 1);
v0 += 2;
--R46;
} while (R46);
bg3_tilemap_offset = a + 2;
}
uint16 RegWord = mod_value;
if (RegWord) {
uint16 v2 = 2 * (RegWord / 14);
if (sign16(v2 - 7) && RegWord % 14 && (nmi_frame_counter_byte & 4) == 0)
v2 += 2;
if (!sign16(samus_reserve_health - 100))
v2 += 16;
DrawMenuSpritemap(
kPartialReserveTankSpritemapIds[v2 >> 1],
kEquipmentScreenReserveTank_X[bg3_tilemap_offset >> 1],
kEquipmentScreenReserveTank_Y - 1);
++R48;
++bg3_tilemap_offset;
++bg3_tilemap_offset;
}
while (sign16(R48 - R44)) {
DrawMenuSpritemap(
0x20u,
kEquipmentScreenReserveTank_X[bg3_tilemap_offset >> 1],
kEquipmentScreenReserveTank_Y - 1);
++bg3_tilemap_offset;
++bg3_tilemap_offset;
++R48;
}
DrawMenuSpritemap(
0x1Fu,
kEquipmentScreenReserveTank_X[bg3_tilemap_offset >> 1],
kEquipmentScreenReserveTank_Y - 1);
int div_val = R50 / 10;
int mod_val = R50 % 10;
ram3800.cinematic_bg_tilemap[394] = mod_val + 2052;
ram3800.cinematic_bg_tilemap[393] = div_val + 2052;
ram3800.cinematic_bg_tilemap[392] = R42 + 2052;
}
}
void EquipmentScreenDisplayReserves_PaletteSetup(void) { // 0x82B3F9
R3_.addr = 1536;
if (samus_reserve_health) {
bool v0 = (--pausemenu_reserve_tank_animation_timer & 0x8000u) != 0;
if (!pausemenu_reserve_tank_animation_timer || v0) {
++pausemenu_reserve_tank_animation_frame;
uint16 v1 = kPauseReserveTankAnimationData[(uint16)(2 * pausemenu_reserve_tank_animation_frame)];
if (v1 == 255) {
pausemenu_reserve_tank_animation_frame = 0;
v1 = kPauseReserveTankAnimationData[0];
}
pausemenu_reserve_tank_animation_timer = v1;
}
R3_.addr = kPAuseSpritePaletteIndexValues[3];
}
}
uint16 EquipmentScreenMoveToReserveTanks(void) { // 0x82B43F
uint16 result = samus_max_reserve_health;
if (samus_max_reserve_health) {
pausemenu_equipment_category_item = 0;
QueueSfx1_Max6(0x37u);
return 1;
}
return result;
}
void EquipmentScreenMoveToBeams(uint16 v0) { // 0x82B456
int16 v1;
if (hyper_beam_flag) {
LABEL_4:
pausemenu_equipment_category_item = R18_;
} else {
while ((kEquipmentBitmasks_Weapons[v0 >> 1] & collected_beams) == 0) {
v0 += 2;
if ((int16)(v0 - 10) >= 0)
goto LABEL_4;
}
LOBYTE(v1) = (uint16)(v0 >> 1) >> 8;
HIBYTE(v1) = v0 >> 1;
pausemenu_equipment_category_item = v1 & 0xFF00 | 1;
QueueSfx1_Max6(0x37u);
}
}
uint16 EquipmentScreenMoveToBottomOfBeams(uint16 k) { // 0x82B489
int16 v2;
if (hyper_beam_flag)
return -1;
while ((kEquipmentBitmasks_Weapons[k >> 1] & collected_beams) == 0) {
k -= 2;
if ((k & 0x8000u) != 0)
return -1;
}
QueueSfx1_Max6(0x37u);
LOBYTE(v2) = (uint16)(k >> 1) >> 8;
HIBYTE(v2) = k >> 1;
uint16 result = v2 & 0xFF00 | 1;
pausemenu_equipment_category_item = result;
return result;
}
uint16 EquipmentScreenMoveLowerOnSuitsMisc(uint16 v0) { // 0x82B4B7
int16 v1;
while ((kEquipmentBitmasks_Suits[v0 >> 1] & collected_items) == 0) {
v0 += 2;
if ((int16)(v0 - 10) >= 0)
return -1;
}
QueueSfx1_Max6(0x37u);
LOBYTE(v1) = (uint16)(v0 >> 1) >> 8;
HIBYTE(v1) = v0 >> 1;
pausemenu_equipment_category_item = v1 & 0xFF00 | 2;
return 0;
}
void EquipmentScreenMoveToScrewOrHigherOnSuits(uint16 v0) { // 0x82B4E6
int16 v1;
while ((kEquipmentBitmasks_Suits[v0 >> 1] & collected_items) == 0) {
v0 -= 2;
if ((v0 & 0x8000u) != 0) {
pausemenu_equipment_category_item = R18_;
return;
}
}
QueueSfx1_Max6(0x37u);
LOBYTE(v1) = (uint16)(v0 >> 1) >> 8;
HIBYTE(v1) = v0 >> 1;
pausemenu_equipment_category_item = v1 & 0xFF00 | 2;
}
void EquipmentScreenMoveToHighJumpOrLowerInBoots(uint16 v0) { // 0x82B511
int16 v1;
while ((kEquipmentBitmasks_Boots[v0 >> 1] & collected_items) == 0) {
v0 += 2;
if ((int16)(v0 - 6) >= 0) {
pausemenu_equipment_category_item = R18_;
return;
}
}
QueueSfx1_Max6(0x37u);
LOBYTE(v1) = (uint16)(v0 >> 1) >> 8;
HIBYTE(v1) = v0 >> 1;
pausemenu_equipment_category_item = v1 & 0xFF00 | 3;
}
uint16 EquipmentScreenCategory_Boots_MoveUpInBoots(uint16 k) { // 0x82B53F
int16 v2;
while ((kEquipmentBitmasks_Boots[k >> 1] & collected_items) == 0) {
k -= 2;
if ((k & 0x8000u) != 0)
return -1;
}
QueueSfx1_Max6(0x37u);
LOBYTE(v2) = (uint16)(k >> 1) >> 8;
HIBYTE(v2) = k >> 1;
uint16 result = v2 & 0xFF00 | 3;
pausemenu_equipment_category_item = result;
return result;
}
#define kEquipmentPtrsToRamTilemapOffsets ((uint16*)RomPtr(0x82c02c))
#define kEquipmentPtrsToBitmasks ((uint16*)RomPtr(0x82c034))
#define kEquipmentPtrsToBitsets ((uint16*)RomPtr(0x82c03c))
#define kEquipmentPtrsToEquipmentTilemaps ((uint16*)RomPtr(0x82c044))
void EquipmentScreenCategory_ButtonResponse(void) { // 0x82B568
if ((joypad1_newkeys & kButton_A) != 0) {
QueueSfx1_Max6(0x38u);
R26_ = 2 * (uint8)pausemenu_equipment_category_item;
R18_ = 2 * HIBYTE(pausemenu_equipment_category_item);
int v0 = R26_ >> 1;
R0_.addr = *(uint16 *)RomPtr_82(R18_ + kEquipmentPtrsToRamTilemapOffsets[v0]);
uint16 v1 = kEquipmentPtrsToBitsets[v0];
uint16 v2 = R18_ + kEquipmentPtrsToBitmasks[v0];
uint8 *v3 = RomPtr_RAM(v1);
uint8 *v4 = RomPtr_82(v2);
if ((*(uint16 *)v4 & *(uint16 *)v3) != 0) {
R18_ = ~*(uint16 *)RomPtr_82(v2);
uint8 *v6 = RomPtr_RAM(v1);
*(uint16 *)v6 &= R18_;
R18_ = 3072;
R22_ = R24_;
SetPaletteOfR22TilemapBytesToR18();
} else {
*(uint16 *)v3 |= *(uint16 *)v4;
R22_ = R24_;
uint16 v5 = *(uint16 *)RomPtr_82(R18_ + kEquipmentPtrsToEquipmentTilemaps[R26_ >> 1]);
Copy_R22_Bytes(v5);
}
}
}
void DrawPauseMenuDuringFadeIn(void) { // 0x82B62B
if (menu_index) {
EquipmentScreenDrawItemSelector();
EquipmentScreenDisplayReserveTankAmount();
} else {
MapScreenDrawSamusPositionIndicator();
DrawMapIcons();
DisplayMapElevatorDestinations();
}
}
void UNKNOWN_sub_82B650(void) { // 0x82B650
if (pausemenu_button_label_mode) {
DisplayMapElevatorDestinations();
MapScreenDrawSamusPositionIndicator();
DrawMapIcons();
} else {
EquipmentScreenDrawItemSelector();
EquipmentScreenDisplayReserveTankAmount();
}
}
static const uint16 kMap_Criteria_SavePoints[16] = { 0xd8, 0x28, 0x90, 0x38, 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xfffe, 0xfffe };
void DrawMapIcons(void) { // 0x82B672
DrawBossMapIcons(9u, addr_kMapIconDataPointers);
R3_.addr = 3584;
DrawSimpleMapIcons(0xBu, addr_kMapIconDataPointers + 0x10);
DrawSimpleMapIcons(0xAu, addr_kMapIconDataPointers + 0x20);
DrawSimpleMapIcons(0x4Eu, addr_kMapIconDataPointers + 0x30);
R3_.addr = 1024;
DrawSaveStationMapIcon(8u, 0xC80B);
if (enable_debug)
DrawSimpleMapIcons(8u, 0xC82B);
if (!area_index) {
R3_.addr = 3584;
DrawMenuSpritemap(
0x63u,
kMap_Criteria_SavePoints[0] - reg_BG1HOFS,
kMap_Criteria_SavePoints[1] - reg_BG1VOFS);
}
}
#define kMapIconDataPointers ((MapIconDataPointers*)RomPtr(0x82c7cb))
void DrawFileSelectMapIcons(void) { // 0x82B6DD
int16 v0;
HandlePauseScreenPaletteAnimation();
DrawBossMapIcons(9u, 0xC7CBu);
R3_.addr = 3584;
DrawSimpleMapIcons(0xBu, 0xC7DBu);
DrawSimpleMapIcons(0xAu, 0xC7EBu);
DrawSimpleMapIcons(0x4Eu, 0xC7FBu);
R3_.addr = 3584;
uint16 a = UpdateSamusPositionIndicatorAnimation();
*(uint16 *)&R0_.bank = 130;
R0_.addr = *(VoidP *)((char *)&kMapIconDataPointers[4].crateria + (uint16)(2 * area_index));
v0 = 4 * load_station_index;
uint16 v1 = *(uint16 *)IndirPtr(&R0_, 4 * load_station_index) - reg_BG1HOFS;
uint16 v2 = *(uint16 *)IndirPtr(&R0_, v0 + 2) - reg_BG1VOFS;
if ((samus_position_indicator_animation_loop_counter & 1) == 0)
DrawMenuSpritemap(0x12u, v1, v2);
DrawMenuSpritemap(a, v1, v2);
if (enable_debug) {
R3_.addr = 1536;
DrawDebugSaveMapIcons(0xCu, 0xC80B);
DrawDebugElevatorMapIcons(0x17u, 0xC81B);
DrawSimpleMapIcons(0xCu, 0xC82B);
}
if (!area_index) {
R3_.addr = 3584;
DrawMenuSpritemap(
0x63u,
kMap_Criteria_SavePoints[0] - reg_BG1HOFS,
kMap_Criteria_SavePoints[1] - reg_BG1VOFS);
}
}
void DrawSaveStationMapIcon(uint16 a, uint16 k) { // 0x82B798
static const uint8 kShlBit[8] = { 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80 };
R32 = k;
R34 = a;
if (area_index == sram_area_index) {
R36 = *(uint16 *)&used_save_stations_and_elevators[(uint16)(2 * area_index)];
LOBYTE(R36) = R36 & kShlBit[load_station_index];
uint16 v2 = *(uint16 *)RomPtr_82(R32 + 2 * area_index);
if (v2)
DrawMapIconsOfType(v2);
}
}
void DrawDebugSaveMapIcons(uint16 a, uint16 k) { // 0x82B7D1
R32 = k;
R34 = a;
R36 = *(uint16 *)&used_save_stations_and_elevators[(uint16)(2 * area_index)];
uint16 v2 = *(uint16 *)RomPtr_82(k + 2 * area_index);
if (v2)
DrawMapIconsOfType(v2);
}
void DrawDebugElevatorMapIcons(uint16 a, uint16 k) { // 0x82B7EB
R32 = k;
R34 = a;
R36 = *(uint16 *)&used_save_stations_and_elevators[(uint16)(2 * area_index) + 1];
uint16 v2 = *(uint16 *)RomPtr_82(k + 2 * area_index);
if (v2)
DrawMapIconsOfType(v2);
}
void DrawSimpleMapIcons(uint16 a, uint16 k) { // 0x82B805
R32 = k;
R34 = a;
R36 = -1;
uint16 v2 = *(uint16 *)RomPtr_82(k + 2 * area_index);
if (v2)
DrawMapIconsOfType(v2);
}
void DrawMapIconsOfType(uint16 a) { // 0x82B81C
char v3; // cf
int16 v4;
while (1) {
uint16 *v2 = (uint16 *)RomPtr_82(a);
if ((*v2 & 0x8000u) != 0)
break;
v3 = R36 & 1;
R36 >>= 1;
if (v3) {
v4 = CheckIfMapPositionIsExplored(*v2, v2[1]);
if (v4) {
uint8 *v5 = RomPtr_82(a);
DrawMenuSpritemap(R34, *(uint16 *)v5 - reg_BG1HOFS, *((uint16 *)v5 + 1) - reg_BG1VOFS);
}
}
a += 4;
}
}
uint16 CheckIfMapPositionIsExplored(uint16 k, uint16 j) { // 0x82B855
static const uint8 kBits0x80Shr[8] = { 0x80, 0x40, 0x20, 0x10, 8, 4, 2, 1 };
uint16 v2;
uint16 v4; // dx
R18_ = (uint16)(k & 0xFF00) >> 1;
R18_ += (uint8)k >> 6;
R18_ += (uint16)(j & 0xFFF8) >> 1;
uint16 v3 = (k >> 3) & 7;
HIBYTE(v2) = HIBYTE(v3);
LOBYTE(v2) = map_tiles_explored[R18_];
HIBYTE(v4) = HIBYTE(v3);
LOBYTE(v4) = kBits0x80Shr[v3];
return (v4 & v2) != 0;
}
void DrawBossMapIcons(uint16 a, uint16 k) { // 0x82B892
int16 v4;
char v5; // cf
R32 = k;
R34 = a;
R36 = boss_bits_for_area[area_index];
uint8 *v2 = RomPtr_82(k + 2 * area_index);
if (*(uint16 *)v2) {
for (int i = *(uint16 *)v2; ; i += 4) {
v4 = *(uint16 *)RomPtr_82(i);
if (v4 == -1)
return;
if (v4 != -2) {
R3_.addr = 3584;
v5 = R36 & 1;
R36 >>= 1;
if (v5) {
{
uint8 *v7 = RomPtr_82(i);
DrawMenuSpritemap(0x62u, *(uint16 *)v7 - reg_BG1HOFS, *((uint16 *)v7 + 1) - reg_BG1VOFS);
R3_.addr = 3072;
}
LABEL_7:;
uint8 *v6 = RomPtr_82(i);
DrawMenuSpritemap(R34, *(uint16 *)v6 - reg_BG1HOFS, *((uint16 *)v6 + 1) - reg_BG1VOFS);
continue;
}
if (has_area_map)
goto LABEL_7;
}
R36 >>= 1;
}
}
}
void DrawMapScrollArrowAndCheckToScroll(uint8 db, uint16 k) { // 0x82B90A
uint16 *v1 = (uint16 *)RomPtrWithBank(db, k);
DrawPauseScreenSpriteAnim(v1[2], *v1, v1[1]);
uint8 *v2 = RomPtrWithBank(db, k);
if ((joypad1_lastkeys & *((uint16 *)v2 + 3)) != 0 && !map_scrolling_direction)
map_scrolling_direction = *((uint16 *)v2 + 4);
}
void sub_82B932(void) { // 0x82B932
HandleMapScrollArrows();
}
#define g_stru_82B9A0 ((MapScrollArrowData*)RomPtr(0x82b9a0))
#define g_stru_82B9AA ((MapScrollArrowData*)RomPtr(0x82b9aa))
#define g_stru_82B9B4 ((MapScrollArrowData*)RomPtr(0x82b9b4))
#define g_stru_82B9BE (*(MapScrollArrowData*)RomPtr(0x82b9be))
void HandleMapScrollArrows(void) { // 0x82B934
if (sign16(map_min_x_scroll - 24 - reg_BG1HOFS))
DrawMapScrollArrowAndCheckToScroll(0x82, addr_stru_82B9A0);
if (!sign16(map_max_x_scroll - 232 - reg_BG1HOFS))
DrawMapScrollArrowAndCheckToScroll(0x82, addr_stru_82B9AA);
if (sign16(map_min_y_scroll - 56 - reg_BG1VOFS))
DrawMapScrollArrowAndCheckToScroll(0x82, addr_stru_82B9B4);
if (sign16(map_max_y_scroll - 177 - reg_BG1VOFS)) {
if (map_scrolling_direction == g_stru_82B9BE.map_scroll_dir) {
map_scrolling_gear_switch_timer = 0;
map_scrolling_direction = 0;
map_scrolling_speed_index = 0;
}
} else {
DrawMapScrollArrowAndCheckToScroll(0x82, addr_stru_82B9BE);
}
}
void MapScreenDrawSamusPositionIndicator(void) { // 0x82B9C8
R3_.addr = 3584;
uint16 a = UpdateSamusPositionIndicatorAnimation();
DrawMenuSpritemap(
a,
8 * (room_x_coordinate_on_map + HIBYTE(samus_x_pos)) - reg_BG1HOFS,
8 * (room_y_coordinate_on_map + HIBYTE(samus_y_pos) + 1) - reg_BG1VOFS);
}
static const uint16 kMap_SamusPositionIndicator_Delays[4] = { 8, 4, 8, 4 };
static const uint16 kMap_SamusPositionIndicator_SpritemapIds[4] = { 0x5f, 0x60, 0x61, 0x60 };
uint16 UpdateSamusPositionIndicatorAnimation(void) { // 0x82B9FC
uint16 v0 = samus_position_indicator_animation_timer;
if (!v0) {
uint16 v1 = samus_position_indicator_animation_frame + 2;
if ((int16)(v1 - 8) >= 0) {
++samus_position_indicator_animation_loop_counter;
v1 = 0;
}
samus_position_indicator_animation_frame = v1;
v0 = kMap_SamusPositionIndicator_Delays[v1 >> 1];
samus_position_indicator_animation_timer = v0;
}
samus_position_indicator_animation_timer = v0 - 1;
return kMap_SamusPositionIndicator_SpritemapIds[samus_position_indicator_animation_frame >> 1];
}
void DrawBorderAroundSamusData(void) { // 0x82BA35
R3_.addr = 3584;
DrawMenuSpritemap(0x48u, 0x80, 0x10u);
}
void DrawBorderAroundDataCopyMode(void) { // 0x82BA48
R3_.addr = 3584;
DrawMenuSpritemap(0x49u, 0x80, 0x10u);
}
void DrawBorderAroundDataClearMode(void) { // 0x82BA5B
R3_.addr = 3584;
DrawMenuSpritemap(0x4Au, 0x7Cu, 0x10u);
}
static const uint16 kDrawMenuSelectionMissile_Enable[4] = { 8, 8, 8, 8 };
static const uint16 kDrawMenuSelectionMissile_SpriteMap[4] = { 0x37, 0x36, 0x35, 0x34 };
void DrawMenuSelectionMissile(void) { // 0x82BA6E
if (enemy_projectile_enable_flag) {
if (!--enemy_projectile_enable_flag) {
enemy_projectile_id[0] = (LOBYTE(enemy_projectile_id[0]) + 1) & 3;
enemy_projectile_enable_flag = kDrawMenuSelectionMissile_Enable[enemy_projectile_id[0]];
}
}
R3_.addr = 3584;
DrawMenuSpritemap(
kDrawMenuSelectionMissile_SpriteMap[enemy_projectile_id[0]],
enemy_projectile_id[5],
enemy_projectile_id[10]);
}
#define file_copy_arrow_stuff ((FileCopyArrowStuff*)RomPtr(0x82bb0c))
void DrawFileCopyArrow(void) { // 0x82BABA
uint16 v0;
if ((int16)(enemy_projectile_id[16] - enemy_projectile_id[17]) >= 0) {
v0 = 3;
if (sign16(enemy_projectile_id[16] - enemy_projectile_id[17] - 2)) {
v0 = 4;
if (enemy_projectile_id[16] != 1)
v0 = 5;
}
} else {
v0 = 0;
if (sign16(enemy_projectile_id[17] - enemy_projectile_id[16] - 2)) {
v0 = 1;
if (enemy_projectile_id[16])
v0 = 2;
}
}
R3_.addr = 512;
DrawMenuSpritemap(
file_copy_arrow_stuff[v0].spritemap,
file_copy_arrow_stuff[v0].xpos,
file_copy_arrow_stuff[v0].ypos);
}
#define kMapElevatorDests ((uint16*)RomPtr(0x82c74d))
void DisplayMapElevatorDestinations(void) { // 0x82BB30
R3_.addr = 0;
if (map_station_byte_array[area_index]) {
for (int i = kMapElevatorDests[area_index]; ; i += 6) {
uint8 *v1 = RomPtr_82(i);
if (*(uint16 *)v1 == 0xFFFF)
break;
DrawMenuSpritemap(*((uint16 *)v1 + 2), *(uint16 *)v1 - reg_BG1HOFS, *((uint16 *)v1 + 1) - reg_BG1VOFS);
}
}
}
void HandleGameOverBabyMetroid(void) { // 0x82BB75
if (enemy_data[0].instruction_timer)
sub_82BB7F(enemy_data[0].instruction_timer);
else
sub_82BBDD();
}
void CallBabyMetroidPlaySfx(uint32 ea) {
switch (ea) {
case fnBabyMetroidPlaySfx0x23: BabyMetroidPlaySfx0x23(); return;
case fnBabyMetroidPlaySfx0x26: BabyMetroidPlaySfx0x26(); return;
case fnBabyMetroidPlaySfx0x27: BabyMetroidPlaySfx0x27(); return;
default: Unreachable();
}
}
void sub_82BB7F(uint16 a) { // 0x82BB7F
uint16 current_instruction = enemy_data[0].current_instruction;
enemy_data[0].instruction_timer = a - 1;
if (a == 1) {
uint8 *v2 = RomPtr_82(enemy_data[0].current_instruction);
if (*((uint16 *)v2 + 3) == 0xFFFF) {
sub_82BBDD();
} else if ((int16)(*((uint16 *)v2 + 3) + 1) >= 0) {
enemy_data[0].instruction_timer = *((uint16 *)v2 + 3);
enemy_data[0].current_instruction += 6;
DrawBabyMetroid(current_instruction + 6);
} else {
R18_ = *((uint16 *)v2 + 3);
CallBabyMetroidPlaySfx(R18_ | 0x820000);
}
} else {
DrawBabyMetroid(enemy_data[0].current_instruction);
}
}
void sub_82BBDD(void) { // 0x82BBDD
enemy_data[0].current_instruction = addr_kgameOverBabyMetridInstructionList;
enemy_data[0].instruction_timer = 10;
sub_82BB7F(0xAu);
}
void DrawBabyMetroid(uint16 k) { // 0x82BB9E
uint16 v1 = *((uint16 *)RomPtr_82(k) + 2);
uint16 v2 = 0;
do {
palette_buffer[(v2 >> 1) + 192] = *(uint16 *)RomPtr_82(v1);
v1 += 2;
v2 += 2;
} while ((int16)(v2 - 32) < 0);
R3_.addr = 2048;
uint8 *v3 = RomPtr_82(k);
DrawMenuSpritemap(*((uint16 *)v3 + 1), 0x7Cu, 0x50u);
R3_.addr = 2560;
DrawMenuSpritemap(0x64u, 0x7Cu, 0x50u);
}
void FinishProcessingGameOverBabyMetroidAsm(void) { // 0x82BBF0
uint16 current_instruction = enemy_data[0].current_instruction;
enemy_data[0].instruction_timer = *((uint16 *)RomPtr_82(enemy_data[0].current_instruction) + 4);
enemy_data[0].current_instruction += 8;
if (*(uint16 *)RomPtr_82(current_instruction + 8) == 0xFFFF)
sub_82BBDD();
else
DrawBabyMetroid(enemy_data[0].current_instruction);
}
void BabyMetroidPlaySfx0x23(void) { // 0x82BC0C
QueueSfx3_Max6(0x23u);
FinishProcessingGameOverBabyMetroidAsm();
}
void BabyMetroidPlaySfx0x26(void) { // 0x82BC15
QueueSfx3_Max6(0x26u);
FinishProcessingGameOverBabyMetroidAsm();
}
void BabyMetroidPlaySfx0x27(void) { // 0x82BC1E
QueueSfx3_Max6(0x27u);
FinishProcessingGameOverBabyMetroidAsm();
}
void CancelSoundEffects(void) { // 0x82BE17
QueueSfx1_Max6(2u);
QueueSfx2_Max6(0x71u);
QueueSfx3_Max6(1u);
}
void QueueSamusMovementSfx(void) { // 0x82BE2F
if ((speed_boost_counter & 0xFF00) == 1024)
QueueSfx3_Max6(0x2Bu);
if (!sign16(flare_counter - 16))
QueueSfx1_Max6(0x41u);
CallSomeSamusCode(0x14u);
}
uint8 AdvancePaletteFadeForAllPalettes_0xc(void) { // 0x82D961
palette_change_denom = 12;
return AdvancePaletteFadeForAllPalettes();
}
uint8 AdvancePaletteFade_BgPalette6(void) { // 0x82D96C
palette_change_denom = 12;
if (palette_change_num <= 0xDu) {
for (int i = 192; i < 0xE0u; i += 2)
palette_buffer[i >> 1] = CalculateNthTransitionColorFromXtoY(
palette_change_num,
palette_buffer[i >> 1],
target_palettes[i >> 1]);
++palette_change_num;
return 0;
} else {
palette_change_num = 0;
return 1;
}
}
uint8 AdvanceGradualColorChangeOfPalette(uint16 k, uint16 j) { // 0x82D9B8
palette_change_denom = 15;
if ((int16)(15 - palette_change_num) >= 0) {
R34 = j;
do {
palette_buffer[k >> 1] = CalculateNthTransitionColorFromXtoY(
palette_change_num + 1,
palette_buffer[k >> 1],
target_palettes[k >> 1]);
k += 2;
} while (k < R34);
++palette_change_num;
return 0;
} else {
palette_change_num = 0;
return 1;
}
}
uint8 AdvancePaletteFadeForAllPalettes(void) { // 0x82DA02
if ((uint16)(palette_change_denom + 1) >= palette_change_num) {
for (int i = 0; i < 0x200u; i += 2) {
g_word_7EC404 = i;
int v2 = i >> 1;
if (target_palettes[v2] != palette_buffer[v2]) {
uint16 v3 = CalculateNthTransitionColorFromXtoY(palette_change_num, palette_buffer[v2], target_palettes[v2]);
i = g_word_7EC404;
palette_buffer[g_word_7EC404 >> 1] = v3;
}
}
++palette_change_num;
return 0;
} else {
palette_change_num = 0;
return 1;
}
}
uint16 CalculateNthTransitionColorFromXtoY(uint16 a, uint16 k, uint16 j) { // 0x82DA4A
int16 v3;
char v4; // t0
int16 v8;
uint16 v7 = CalculateNthTransitionColorComponentFromXtoY(a, k & 0x1F, j & 0x1F);
v8 = v7 | (32 * CalculateNthTransitionColorComponentFromXtoY(a, (k >> 5) & 0x1F, (j >> 5) & 0x1F));
v3 = 4
* CalculateNthTransitionColorComponentFromXtoY(
a,
((uint16)(k >> 2) >> 8) & 0x1F,
((uint16)(j >> 2) >> 8) & 0x1F);
v4 = v3;
LOBYTE(v3) = HIBYTE(v3);
HIBYTE(v3) = v4;
return v8 | v3;
}
uint16 CalculateNthTransitionColorComponentFromXtoY(uint16 a, uint16 k, uint16 j) { // 0x82DAA6
int16 v4;
char v6; // t0
int16 v8;
if (!a)
return k;
v4 = a - 1;
if (v4 == palette_change_denom)
return j;
R20_ = v4 + 1;
R18_ = j - k;
uint16 v5 = abs16(j - k);
v6 = v5;
LOBYTE(v5) = HIBYTE(v5);
HIBYTE(v5) = v6;
uint16 RegWord = SnesDivide(v5 & 0xFF00, palette_change_denom - R20_ + 1);
R18_ = sign16(R18_) ? -RegWord : RegWord;
LOBYTE(v8) = HIBYTE(k);
HIBYTE(v8) = k;
return (uint16)(R18_ + v8) >> 8;
}
uint8 sub_82DAF7(uint16 a) { // 0x82DAF7
palette_change_denom = 12;
return sub_82DB0C(a);
}
uint8 sub_82DB0C(uint16 a) { // 0x82DB0C
if ((uint16)(palette_change_denom + 1) >= palette_change_num) {
g_word_7EC404 = 0;
while (a) {
if (!(a & 1))
g_word_7EC404 += 32;
else
sub_82DB41();
a >>= 1;
}
++palette_change_num;
return 0;
} else {
palette_change_num = 0;
return 1;
}
}
void sub_82DB41(void) { // 0x82DB41
uint16 v0 = g_word_7EC404;
do {
int v1 = v0 >> 1;
if (target_palettes[v1] != palette_buffer[v1]) {
uint16 v2 = CalculateNthTransitionColorFromXtoY(palette_change_num, palette_buffer[v1], target_palettes[v1]);
v0 = g_word_7EC404;
palette_buffer[g_word_7EC404 >> 1] = v2;
}
v0 += 2;
g_word_7EC404 = v0;
} while ((v0 & 0x1F) != 0);
}
void HandleSamusOutOfHealthAndGameTile(void) { // 0x82DB69
if ((int16)samus_health <= 0) {
if ((reserve_health_mode & 1) != 0 && samus_reserve_health) {
time_is_frozen_flag = 0x8000;
game_state = kGameState_27_ReserveTanksAuto;
CallSomeSamusCode(0x1Bu);
} else {
if (game_state != kGameState_8_MainGameplay)
return;
time_is_frozen_flag = 0x8000;
CallSomeSamusCode(0x11u);
game_state = kGameState_19_SamusNoHealth;
}
}
if (!sign16(++game_time_frames - 60)) {
game_time_frames = 0;
if (!sign16(++game_time_seconds - 60)) {
game_time_seconds = 0;
if (!sign16(++game_time_minutes - 60)) {
game_time_minutes = 0;
++game_time_hours;
}
}
}
if (!sign16(game_time_hours - 100)) {
game_time_frames = 59;
game_time_seconds = 59;
game_time_minutes = 59;
game_time_hours = 99;
}
}
CoroutineRet GameState_27_ReserveTanksAuto(void) { // 0x82DC10
if (RefillHealthFromReserveTanks()) {
time_is_frozen_flag = 0;
game_state = kGameState_8_MainGameplay;
CallSomeSamusCode(0x10u);
}
GameState_8_MainGameplay();
Samus_LowHealthCheck_0();
return kCoroutineNone;
}
uint8 RefillHealthFromReserveTanks(void) { // 0x82DC31
if (samus_reserve_health) {
if ((nmi_frame_counter_word & 7) == 0)
QueueSfx3_Max3(0x2Du);
if ((int16)(++samus_health - samus_max_health) >= 0) {
samus_health = samus_max_health;
LABEL_9:
samus_reserve_health = 0;
return samus_reserve_health == 0;
}
bool v0 = (--samus_reserve_health & 0x8000u) != 0;
if (!samus_reserve_health)
goto LABEL_9;
if (v0) {
samus_health += samus_reserve_health;
goto LABEL_9;
}
}
return samus_reserve_health == 0;
}
CoroutineRet GameState_19_SamusNoHealth(void) { // 0x82DC80
uint16 j;
uint16 k;
uint16 m;
GameState_8_MainGameplay();
for (int i = 255; i >= 0; --i)
ram3000.pause_menu_map_tilemap[i + 384] = palette_buffer[i];
for (j = 382; (j & 0x8000u) == 0; j -= 2)
target_palettes[j >> 1] = 0;
for (k = 94; (k & 0x8000u) == 0; k -= 2)
target_palettes[(k >> 1) + 208] = 0;
for (m = 30; (m & 0x8000u) == 0; m -= 2)
target_palettes[(m >> 1) + 192] = palette_buffer[(m >> 1) + 192];
game_options_screen_index = 3;
g_word_7E0DE4 = 0;
g_word_7E0DE6 = 0;
g_word_7E0DE8 = 0;
hud_item_index = 0;
samus_auto_cancel_hud_item_index = 0;
samus_invincibility_timer = 0;
samus_knockback_timer = 0;
++game_state;
return kCoroutineNone;
}
CoroutineRet GameState_20_SamusNoHealth_BlackOut(void) { // 0x82DCE0
GameState_8_MainGameplay();
palette_change_denom = 6;
if (AdvancePaletteFadeForAllPalettes()) {
WaitUntilEndOfVblankAndClearHdma();
DisableIrqInterrupts();
fx_layer_blending_config_a = 0;
cur_irq_handler = 0;
next_gameplay_CGWSEL = 0;
next_gameplay_CGADSUB = 0;
reg_TM = 16;
reg_TS = 0;
reg_TMW = 0;
reg_TSW = 0;
reg_BGMODE = 9;
game_options_screen_index = 0;
screen_fade_delay = 0;
screen_fade_counter = 0;
for (int i = 254; i >= 0; i -= 2)
enemy_projectile_y_subpos[(i >> 1) + 15] = 0;
g_word_7E0DE8 = 16;
game_options_screen_index = 3;
g_word_7E0DE4 = 0;
g_word_7E0DE6 = 0;
++game_state;
power_bomb_explosion_status = 0;
QueueSfx1_Max15(2u);
QueueSfx2_Max15(0x71u);
QueueSfx3_Max15(1u);
QueueMusic_Delayed8(0);
QueueMusic_Delayed8(0xFF39u);
QueueMusic_DelayedY(5u, 0xEu);
}
return kCoroutineNone;
}
CoroutineRet GameState_21_SamusNoHealth(void) { // 0x82DD71
Samus_DrawWhenNotAnimatingOrDying();
if (!HasQueuedMusic()) {
StartSamusDeathAnimation();
++game_state;
}
return kCoroutineNone;
}
CoroutineRet GameState_22_SamusNoHealth_Dying(void) { // 0x82DD87
DrawSamusStartingDeathAnim_();
bool v0 = (--g_word_7E0DE8 & 0x8000u) != 0;
if (!g_word_7E0DE8 || v0)
++game_state;
return kCoroutineNone;
}
CoroutineRet GameState_23_SamusNoHealth_Flashing(void) { // 0x82DD9A
if (HandleSamusDeathSequence())
++game_state;
else
Samus_DrawDuringDeathAnim();
return kCoroutineNone;
}
CoroutineRet GameState_24_SamusNoHealth_Explosion(void) { // 0x82DDAF
if (GameState_24_SamusNoHealth_Explosion_Helper()) {
screen_fade_delay = 1;
screen_fade_counter = 1;
++game_state;
}
return kCoroutineNone;
}
CoroutineRet GameState_25_SamusNoHealth_BlackOut(void) { // 0x82DDC7
HandleFadeOut();
if (reg_INIDISP == 0x80) {
EnableNMI();
screen_fade_delay = 0;
screen_fade_counter = 0;
++game_state;
menu_index = 0;
debug_disable_sounds = 0;
}
return kCoroutineNone;
}
void LoaadDesinationRoomCreBitset(void) { // 0x82DDF1
uint16 room_definition_ptr = get_DoorDef(door_def_ptr)->room_definition_ptr;
previous_cre_bitset = cre_bitset;
cre_bitset = get_RoomDefHeader(room_definition_ptr)->cre_bitset_;
}
void LoadDoorHeader(void) { // 0x82DE12
DoorDef *DoorDef;
int16 samus_distance_from_door;
DoorDef = get_DoorDef(door_def_ptr);
room_ptr = DoorDef->room_definition_ptr;
elevator_door_properties_orientation = *(uint16 *)&DoorDef->door_bitflags;
elevator_flags = elevator_door_properties_orientation & 0x80;
door_direction = DoorDef->door_orientation;
door_destination_x_pos = DoorDef->x_pos_in_room << 8;
door_destination_y_pos = DoorDef->y_pos_in_room << 8;
R18_ = 0;
R20_ = 0;
samus_distance_from_door = DoorDef->samus_distance_from_door;
if (samus_distance_from_door < 0) {
if ((door_direction & 2) != 0)
samus_distance_from_door = 384;
else
samus_distance_from_door = 200;
}
*(uint16 *)((char *)&R18_ + 1) = samus_distance_from_door;
samus_door_transition_subspeed = R18_;
samus_door_transition_speed = R20_;
}
void LoadRoomHeader(void) { // 0x82DE6F
RoomDefHeader *RoomDefHeader;
RoomDefHeader = get_RoomDefHeader(room_ptr);
room_index = RoomDefHeader->semiunique_room_number;
area_index = RoomDefHeader->area_index_;
room_x_coordinate_on_map = RoomDefHeader->x_coordinate_on_map;
room_y_coordinate_on_map = RoomDefHeader->y_coordinate_on_map;
room_width_in_scrolls = RoomDefHeader->width;
room_width_in_blocks = 16 * room_width_in_scrolls;
room_height_in_scrolls = RoomDefHeader->height;
room_height_in_blocks = 16 * room_height_in_scrolls;
up_scroller = RoomDefHeader->up_scroller_;
down_scroller = RoomDefHeader->down_scroller_;
door_list_pointer = RoomDefHeader->ptr_to_doorout;
HandleRoomDefStateSelect(room_ptr);
uint16 prod = Mult8x8(room_width_in_blocks, room_height_in_blocks);
room_size_in_blocks = 2 * prod;
}
#define kStateHeaderGraphicsSets ((uint16*)RomPtr(0x8fe7a7))
void LoadStateHeader(void) { // 0x82DEF2
StateHeaderTiles *StateHeaderTiles; // r10
RoomDefRoomstate *RoomDefRoomstate; // r11
int v0 = (uint16)(2 * get_RoomDefRoomstate(roomdefroomstate_ptr)->graphics_set) >> 1;
StateHeaderTiles = get_StateHeaderTiles(kStateHeaderGraphicsSets[v0]);
copy24(&tileset_tile_table_pointer, &StateHeaderTiles->tile_table_ptr);
copy24(&tileset_tiles_pointer, &StateHeaderTiles->tiles_ptr);
copy24(&tileset_compr_palette_ptr, &StateHeaderTiles->palette_ptr);
RoomDefRoomstate = get_RoomDefRoomstate(roomdefroomstate_ptr);
copy24(&room_compr_level_data_ptr, &RoomDefRoomstate->compressed_room_map_ptr);
room_music_data_index = RoomDefRoomstate->music_track;
room_music_track_index = RoomDefRoomstate->music_control;
room_layer3_asm_ptr = RoomDefRoomstate->room_layer3_fx_ptr;
room_enemy_population_ptr = RoomDefRoomstate->enemy_population_ptr_;
room_enemy_tilesets_ptr = RoomDefRoomstate->enemy_tilesets_ptr;
*(uint16 *)&layer2_scroll_x = RoomDefRoomstate->vertical_screen_nudge_limit;
room_main_code_ptr = RoomDefRoomstate->main_code_ptr;
}
void WaitUntilEndOfVblankAndEnableIrq(void) { // 0x82DF69
if ((reg_NMITIMEN & 0x30) != 0x30)
EnableIrqInterruptsNow();
}
void PointlessFunctionStupidToo(void) { // 0x82DF80
}
void SaveMapExploredifElevator(void) { // 0x82DF99
if ((elevator_door_properties_orientation & 0xF) != 0)
SetElevatorsAsUsed();
if ((get_DoorDef(door_def_ptr)->door_bitflags & 0x40) != 0)
SaveExploredMapTilesToSaved();
}
void LoadMapExploredIfElevator(void) { // 0x82DFB6
if ((get_DoorDef(door_def_ptr)->door_bitflags & 0x40) != 0)
LoadMirrorOfExploredMapTiles();
}
void EnsureSamusDrawnEachFrame(void) { // 0x82DFC7
if (!elevator_flags)
Samus_DrawWhenNotAnimatingOrDying();
}
void LoadEnemyGfxToVram(void) { // 0x82DFD1
EnemyDef_A2 *EnemyDef_A2;
R18_ = 28672;
uint16 v0 = room_enemy_tilesets_ptr;
if (room_enemy_tilesets_ptr) {
for (int i = room_enemy_tilesets_ptr; ; v0 = i) {
uint16 enemy_def = get_EnemyTileset(v0)->enemy_def;
if (enemy_def == 0xFFFF)
break;
EnemyDef_A2 = get_EnemyDef_A2(enemy_def);
copy24(&door_transition_vram_update_src, &EnemyDef_A2->tile_data);
if ((EnemyDef_A2->tile_data_size & 0x8000u) != 0) {
door_transition_vram_update_size = EnemyDef_A2->tile_data_size & 0x7FFF;
door_transition_vram_update_dst = ((uint16)(get_EnemyTileset(i)->vram_dst & 0xF000) >> 4) | 0x6000;
} else {
door_transition_vram_update_size = EnemyDef_A2->tile_data_size;
door_transition_vram_update_dst = R18_;
R18_ += EnemyDef_A2->tile_data_size >> 1;
}
WaitForIrqDoorTransitionVramUpdate();
i += 4;
}
}
}
void CopyToVramAtNextInterrupt(const void *p) { // 0x82E039
const CopyToVramAtNextInterruptArgs *pp = (const CopyToVramAtNextInterruptArgs *)p;
door_transition_vram_update_src = pp->source;
door_transition_vram_update_dst = pp->dest;
door_transition_vram_update_size = pp->size;
WaitForIrqDoorTransitionVramUpdate();
}
void LoadRoomMusic(void) { // 0x82E071
if (game_state < kGameState_40_TransitionToDemo && room_music_data_index && room_music_data_index != music_data_index) {
QueueMusic_Delayed8(0);
QueueMusic_Delayed8((uint8)room_music_data_index | 0xFF00);
}
}
void UpdateMusicTrackIndex(void) { // 0x82E09B
if (game_state < kGameState_40_TransitionToDemo && room_music_track_index) {
R18_ = (uint8)room_music_data_index << 8;
R18_ |= room_music_track_index;
R20_ = (uint8)music_data_index << 8;
R20_ |= music_track_index;
if (R18_ != R20_)
music_track_index = room_music_track_index;
}
}
void LoadNewMusicTrackIfChanged(void) { // 0x82E0D5
if (game_state < 0x28u && room_music_track_index) {
R18_ = (uint8)room_music_data_index << 8;
R18_ |= room_music_track_index;
R20_ = (uint8)music_data_index << 8;
R20_ |= music_track_index;
if (R18_ != R20_)
QueueMusic_DelayedY(room_music_track_index, 6u);
}
}
void NullFunc(void) { // 0x82E113
;
}
void PlayRoomMusicTrackAfterAFrames(uint16 a) { // 0x82E118
if (game_state < kGameState_40_TransitionToDemo) {
QueueMusic_DelayedY(0, a);
QueueMusic_Delayed8(music_track_index);
}
}
#define kCommonSpritesPalette1 ((uint16*)RomPtr(0x9afc00))
void LoadColorsForSpritesBeamsAndEnemies(void) { // 0x82E139
uint16 j;
uint16 k;
for (int i = 30; i >= 0; i -= 2)
target_palettes[(i >> 1) + 208] = kInitialPalette[(i >> 1) + 208];
for (j = 30; (j & 0x8000u) == 0; j -= 2)
target_palettes[(j >> 1) + 224] = palette_buffer[(j >> 1) + 224];
for (k = 30; (k & 0x8000u) == 0; k -= 2)
target_palettes[(k >> 1) + 128] = kCommonSpritesPalette1[k >> 1];
}
CoroutineRet CallDoorTransitionFunction_Async(uint32 ea) {
switch (ea) {
case fnDoorTransitionFunction_HandleElevator: return DoorTransitionFunction_HandleElevator();
case fnDoorTransitionFunction_Wait48frames: return DoorTransitionFunction_Wait48frames();
case fnDoorTransitionFunction_WaitForSoundsToFinish: return DoorTransitionFunction_WaitForSoundsToFinish();
case fnDoorTransitionFunction_FadeOutScreen: return DoorTransitionFunction_FadeOutScreen();
case fnDoorTransitionFunction_LoadDoorHeaderEtc: return DoorTransitionFunction_LoadDoorHeaderEtc();
case fnDoorTransitionFunction_ScrollScreenToAlignment: return DoorTransitionFunction_ScrollScreenToAlignment();
case fnDoorTransitionFunction_FixDoorsMovingUp: return DoorTransitionFunction_FixDoorsMovingUp();
case fnDoorTransitionFunction_SetupNewRoom: return DoorTransitionFunction_SetupNewRoom();
case fnDoorTransitionFunction_SetupScrolling: return DoorTransitionFunction_SetupScrolling();
case fnDoorTransitionFunction_PlaceSamusLoadTiles: return DoorTransitionFunction_PlaceSamusLoadTiles();
case fnDoorTransitionFunction_LoadMoreThings_Async: return DoorTransitionFunction_LoadMoreThings_Async();
case fnDoorTransition_C_HandleAnimTiles: return DoorTransition_C_HandleAnimTiles();
case fnDoorTransition_WaitForMusicToClear: return DoorTransition_WaitForMusicToClear();
case fnDoorTransition_HandleTransition: return DoorTransition_HandleTransition();
case fnDoorTransition_FadeInScreenAndFinish: return DoorTransition_FadeInScreenAndFinish();
default: return Unreachable();
}
}
CoroutineRet GameState_9_HitDoorBlock(void) { // 0x82E169
return CallDoorTransitionFunction_Async(door_transition_function | 0x820000);
}
CoroutineRet DoorTransitionFunction_HandleElevator(void) { // 0x82E17D
if (!elevator_flags) {
++game_state;
return GameState_10_LoadingNextRoom_Async();
}
CallSomeSamusCode(0);
if ((elevator_direction & 0x8000u) != 0) {
++game_state;
return GameState_10_LoadingNextRoom_Async();
}
downwards_elevator_delay_timer = 48;
door_transition_function = FUNC16(DoorTransitionFunction_Wait48frames);
return DoorTransitionFunction_Wait48frames();
}
CoroutineRet DoorTransitionFunction_Wait48frames(void) { // 0x82E19F
if ((--downwards_elevator_delay_timer & 0x8000u) != 0) {
++game_state;
return GameState_10_LoadingNextRoom_Async();
} else {
DetermineWhichEnemiesToProcess();
EnemyMain();
DrawSamusEnemiesAndProjectiles();
EnsureSamusDrawnEachFrame();
}
return kCoroutineNone;
}
CoroutineRet GameState_10_LoadingNextRoom_Async(void) { // 0x82E1B7
door_transition_flag_enemies = 1;
door_transition_flag_elevator_zebetites = 1;
debug_disable_minimap = 0;
save_station_lockout_flag = 0;
DetermineWhichEnemiesToProcess();
EnemyMain();
DrawSamusEnemiesAndProjectiles();
EnsureSamusDrawnEachFrame();
LoaadDesinationRoomCreBitset();
for (int i = 254; i >= 0; i -= 2) {
int v1 = i >> 1;
target_palettes[v1] = 0;
target_palettes[v1 + 128] = 0;
}
target_palettes[9] = palette_buffer[9];
target_palettes[10] = palette_buffer[10];
target_palettes[13] = palette_buffer[13];
target_palettes[14] = palette_buffer[14];
target_palettes[17] = palette_buffer[17];
target_palettes[18] = palette_buffer[18];
target_palettes[19] = palette_buffer[19];
target_palettes[29] = palette_buffer[29];
if (((previous_cre_bitset | cre_bitset) & 1) == 0) {
target_palettes[20] = palette_buffer[20];
target_palettes[21] = palette_buffer[21];
target_palettes[22] = palette_buffer[22];
target_palettes[23] = palette_buffer[23];
target_palettes[28] = palette_buffer[28];
if (timer_status) {
target_palettes[209] = palette_buffer[209];
target_palettes[210] = palette_buffer[210];
target_palettes[212] = palette_buffer[212];
target_palettes[221] = palette_buffer[221];
DrawTimer();
}
}
ClearSoundsWhenGoingThroughDoor();
QueueSfx2_Max15(0x71u);
debug_disable_sounds = -1;
door_transition_function = FUNC16(DoorTransitionFunction_WaitForSoundsToFinish);
++game_state;
return kCoroutineNone;
}
CoroutineRet GameState_11_LoadingNextRoom_Async(void) { // 0x82E288
COROUTINE_AWAIT_ONLY(CallDoorTransitionFunction_Async(door_transition_function | 0x820000));
if (timer_status)
DrawTimer();
return kCoroutineNone;
}
CoroutineRet DoorTransitionFunction_WaitForSoundsToFinish(void) { // 0x82E29E
DetermineWhichEnemiesToProcess();
EnemyMain();
DrawSamusEnemiesAndProjectiles();
EnsureSamusDrawnEachFrame();
if (((sfx_writepos[0] - sfx_readpos[0]) & 0xF) == 0
&& ((sfx_writepos[1] - sfx_readpos[1]) & 0xF) == 0
&& ((sfx_writepos[2] - sfx_readpos[2]) & 0xF) == 0) {
door_transition_function = FUNC16(DoorTransitionFunction_FadeOutScreen);
}
return kCoroutineNone;
}
CoroutineRet DoorTransitionFunction_FadeOutScreen(void) { // 0x82E2DB
if (AdvancePaletteFadeForAllPalettes_0xc()) {
door_transition_function = FUNC16(DoorTransitionFunction_LoadDoorHeaderEtc);
} else {
DetermineWhichEnemiesToProcess();
EnemyMain();
DrawSamusEnemiesAndProjectiles();
EnsureSamusDrawnEachFrame();
}
return kCoroutineNone;
}
CoroutineRet DoorTransitionFunction_LoadDoorHeaderEtc(void) { // 0x82E2F7
LoadDoorHeader();
sub_8882AC();
hdma_objects_enable_flag &= ~0x8000u;
irqhandler_next_handler = 8;
door_transition_function = FUNC16(DoorTransitionFunction_ScrollScreenToAlignment);
return kCoroutineNone;
}
CoroutineRet DoorTransitionFunction_ScrollScreenToAlignment(void) { // 0x82E310
if ((door_direction & 2) != 0) {
if ((uint8)layer1_x_pos) {
if ((layer1_x_pos & 0x80) != 0)
++layer1_x_pos;
else
--layer1_x_pos;
goto LABEL_10;
}
} else if ((uint8)layer1_y_pos) {
if ((layer1_y_pos & 0x80) != 0)
++layer1_y_pos;
else
--layer1_y_pos;
LABEL_10:
CalculateLayer2PosAndScrollsWhenScrolling();
return kCoroutineNone;
}
CalculateLayer2PosAndScrollsWhenScrolling();
door_transition_function = FUNC16(DoorTransitionFunction_FixDoorsMovingUp);
return kCoroutineNone;
}
CoroutineRet DoorTransitionFunction_FixDoorsMovingUp(void) { // 0x82E353
if ((door_direction & 3) == 3)
FixDoorsMovingUp();
door_transition_function = FUNC16(DoorTransitionFunction_SetupNewRoom);
return kCoroutineNone;
}
CoroutineRet DoorTransitionFunction_SetupNewRoom(void) { // 0x82E36E
SaveMapExploredifElevator();
LoadRoomHeader();
LoadStateHeader();
LoadMapExploredIfElevator();
InitializeSpecialEffectsForNewRoom();
LoadLevelScrollAndCre();
door_transition_function = FUNC16(DoorTransitionFunction_SetupScrolling);
return kCoroutineNone;
}
CoroutineRet DoorTransitionFunction_SetupScrolling(void) { // 0x82E38E
reg_BG2HOFS = 0;
reg_BG2VOFS = 0;
scrolling_finished_hook = 0;
if ((door_direction & 3) == 2)
++reg_BG1VOFS;
if ((door_direction & 3) != 3)
door_transition_frame_counter = 0;
DoorTransitionScrollingSetup();
door_transition_function = FUNC16(DoorTransitionFunction_PlaceSamusLoadTiles);
return kCoroutineNone;
}
CoroutineRet DoorTransitionFunction_PlaceSamusLoadTiles(void) { // 0x82E3C0
static const LongPtr unk_82E421 = LONGPTR(0x7e7000);
static const LongPtr unk_82E432 = LONGPTR(0x7e2000);
static const LongPtr unk_82E443 = LONGPTR(0x7ec200);
static const CopyToVramAtNextInterruptArgs unk_82E449 = { LONGPTR(0x7e2000), 0x0000, 0x2000 };
static const CopyToVramAtNextInterruptArgs unk_82E453 = { LONGPTR(0x7e4000), 0x1000, 0x2000 };
static const CopyToVramAtNextInterruptArgs unk_82E45D = { LONGPTR(0x7e6000), 0x2000, 0x1000 };
static const CopyToVramAtNextInterruptArgs unk_82E477 = { LONGPTR(0x7e7000), 0x2800, 0x1000 };
static const CopyToVramAtNextInterruptArgs unk_82E481 = { LONGPTR(0x7e8000), 0x3000, 0x2000 };
static const CopyToVramAtNextInterruptArgs unk_82E48B = { LONGPTR(0x9ab200), 0x4000, 0x1000 };
uint16 v0;
samus_x_pos = layer1_x_pos + (uint8)samus_x_pos;
samus_prev_x_pos = samus_x_pos;
samus_y_pos = layer1_y_pos + (uint8)samus_y_pos;
samus_prev_y_pos = samus_y_pos;
door_transition_flag = 0;
door_transition_vram_update_enabled = 0;
if ((door_direction & 3) == 2)
v0 = 16;
else
v0 = 22;
irqhandler_next_handler = v0;
WaitUntilEndOfVblankAndEnableIrq();
if ((cre_bitset & 2) != 0 && door_def_ptr != (uint16)addr_kDoorDef_947a) {
mov24(&decompress_src, 0xb98000);
DecompressToMem_IpArg(&unk_82E421);
}
copy24(&decompress_src, &tileset_tiles_pointer);
DecompressToMem_IpArg(&unk_82E432);
copy24(&decompress_src, &tileset_compr_palette_ptr);
DecompressToMem_IpArg(&unk_82E443);
CopyToVramAtNextInterrupt(&unk_82E449);
CopyToVramAtNextInterrupt(&unk_82E453);
CopyToVramAtNextInterrupt(&unk_82E45D);
if ((cre_bitset & 6) != 0 && door_def_ptr != (uint16)addr_kDoorDef_947a) {
CopyToVramAtNextInterrupt(&unk_82E477);
CopyToVramAtNextInterrupt(&unk_82E481);
CopyToVramAtNextInterrupt(&unk_82E48B);
}
if ((door_direction & 3) == 3)
irqhandler_next_handler = 16;
door_transition_function = FUNC16(DoorTransitionFunction_LoadMoreThings_Async);
return kCoroutineNone;
}
static Func_Y_Y *const kUpdateBackgroundCommands[8] = {
UpdateBackgroundCommand_0_Finish,
UpdateBackgroundCommand_2_TransferToVram,
UpdateBackgroundCommand_4_Decompression,
UpdateBackgroundCommand_6_ClearFxTilemap,
UpdateBackgroundCommand_8_TransferToVramAndSetBg3,
UpdateBackgroundCommand_A_ClearBg2Tilemap,
UpdateBackgroundCommand_C_ClearKraidBg2Tilemap,
UpdateBackgroundCommand_E_DoorDependentTransferToVRAM,
};
CoroutineRet DoorTransitionFunction_LoadMoreThings_Async(void) {
int16 bg_data_ptr;
COROUTINE_BEGIN(coroutine_state_1, 0);
LoadEnemyGfxToVram();
LoadRoomMusic();
ClearEnemyProjectiles();
ClearAnimtiles();
ClearPaletteFXObjects();
ClearPLMs();
CreatePlmsExecuteDoorAsmRoomSetup();
LoadFXHeader();
SpawnDoorClosingPLM();
UpdateBeamTilesAndPalette();
LoadColorsForSpritesBeamsAndEnemies();
LoadEnemies();
InitializeEnemies();
ResetProjectileData();
Samus_LoadSuitTargetPalette();
ClearFxTilemap();
*(VoidP *)((char *)&door_transition_vram_update_src.addr + 1) = -30208;
if (fx_tilemap_ptr) {
door_transition_vram_update_src.addr = fx_tilemap_ptr;
door_transition_vram_update_dst = addr_unk_605BE0;
door_transition_vram_update_size = 2112;
WaitForIrqDoorTransitionVramUpdate();
}
bg_data_ptr = get_RoomDefRoomstate(roomdefroomstate_ptr)->bg_data_ptr;
if (bg_data_ptr < 0) {
do {
int v1 = *(uint16 *)RomPtr_8F(bg_data_ptr) >> 1;
bg_data_ptr = kUpdateBackgroundCommands[v1](bg_data_ptr + 2);
} while (bg_data_ptr);
}
// Wait until the screen has finished scrolling as a result of the door opening
while ((door_transition_flag & 0x8000u) == 0) {
COROUTINE_AWAIT(1, WaitForNMI_Async());
}
palette_buffer[196] = 15328;
SpawnBG3ScrollHdmaObject();
hdma_objects_enable_flag |= 0x8000;
COROUTINE_AWAIT(2, PlmHandler_Async());
if ((door_direction & 2) == 0) {
if ((door_direction & 3) != 0)
samus_x_pos &= 0xFFF8u;
else
samus_x_pos |= 7u;
}
door_transition_function = FUNC16(DoorTransition_C_HandleAnimTiles);
COROUTINE_END(0);
}
static const CopyToVramAtNextInterruptArgs unk_82E5B5 = { LONGPTR(0x7e4000), 0x4000, 0x1000 };
static const CopyToVramAtNextInterruptArgs unk_82E5BF = { LONGPTR(0x7e4000), 0x4800, 0x1000 };
static const CopyToVramAtNextInterruptArgs unk_82E57B = { LONGPTR(0x7e4000), 0x5880, 0x0f00 };
static const CopyToVramAtNextInterruptArgs unk_82E598 = { LONGPTR(0x7e4000), 0x4800, 0x1000 };
void ClearFxTilemap(void) { // 0x82E566
for (int i = 959; i >= 0; --i) {
ram4000.xray_tilemaps[i] = 6222;
ram4000.xray_tilemaps[i + 960] = 6222;
}
CopyToVramAtNextInterrupt(&unk_82E57B);
}
void ClearBg2Tilemap(void) { // 0x82E583
for (int i = 1023; i >= 0; --i) {
ram4000.xray_tilemaps[i] = 824;
ram4000.xray_tilemaps[i + 1024] = 824;
}
CopyToVramAtNextInterrupt(&unk_82E598);
}
void ClearKraidBg2Tilemap(void) { // 0x82E5A0
for (int i = 1023; i >= 0; --i) {
ram4000.xray_tilemaps[i] = 824;
ram4000.xray_tilemaps[i + 1024] = 824;
}
CopyToVramAtNextInterrupt(&unk_82E5B5);
CopyToVramAtNextInterrupt(&unk_82E5BF);
}
uint16 UpdateBackgroundCommand_0_Finish(uint16 y) { // 0x82E5D7
return 0;
}
uint16 UpdateBackgroundCommand_E_DoorDependentTransferToVRAM(uint16 j) { // 0x82E5D9
if (door_def_ptr == *(uint16 *)RomPtr_8F(j))
return UpdateBackgroundCommand_2_TransferToVram(j + 2);
else
return j + 9;
}
uint16 UpdateBackgroundCommand_2_TransferToVram(uint16 j) { // 0x82E5EB
uint8 *v1 = RomPtr_8F(j);
door_transition_vram_update_dst = *(uint16 *)(v1 + 3);
copy24(&door_transition_vram_update_src, (LongPtr *)v1);
door_transition_vram_update_size = *(uint16 *)(v1 + 5);
WaitForIrqDoorTransitionVramUpdate();
return j + 7;
}
uint16 UpdateBackgroundCommand_4_Decompression(uint16 j) { // 0x82E616
LongPtr *v1;
v1 = (LongPtr *)RomPtr_8F(j);
copy24(&decompress_src, v1);
*(VoidP *)((char *)&decompress_dst.addr + 1) = 32256;
decompress_dst.addr = v1[1].addr;
DecompressToMem();
return j + 5;
}
uint16 UpdateBackgroundCommand_6_ClearFxTilemap(uint16 j) { // 0x82E637
ClearFxTilemap();
return j;
}
uint16 UpdateBackgroundCommand_8_TransferToVramAndSetBg3(uint16 j) { // 0x82E63E
j = UpdateBackgroundCommand_2_TransferToVram(j);
reg_BG34NBA = 2;
return j;
}
uint16 UpdateBackgroundCommand_A_ClearBg2Tilemap(uint16 j) { // 0x82E64B
ClearBg2Tilemap();
return j;
}
uint16 UpdateBackgroundCommand_C_ClearKraidBg2Tilemap(uint16 j) { // 0x82E652
ClearKraidBg2Tilemap();
return j;
}
CoroutineRet DoorTransition_C_HandleAnimTiles(void) { // 0x82E659
AnimtilesHandler();
door_transition_function = FUNC16(DoorTransition_WaitForMusicToClear);
return kCoroutineNone;
}
CoroutineRet DoorTransition_WaitForMusicToClear(void) { // 0x82E664
if (!HasQueuedMusic()) {
door_transition_function = FUNC16(DoorTransition_HandleTransition);
LoadNewMusicTrackIfChanged();
}
return kCoroutineNone;
}
CoroutineRet DoorTransition_HandleTransition(void) { // 0x82E6A2
if ((samus_x_pos & 0xF0) == 16) {
samus_x_pos = (samus_x_pos | 0xF) + 8;
} else if ((samus_x_pos & 0xF0) == 224) {
samus_x_pos = (samus_x_pos & 0xFFF0) - 8;
}
if ((samus_y_pos & 0xF0) == 16)
samus_y_pos = (samus_y_pos | 0xF) + 8;
for (int i = 510; i >= 0; i -= 2) {
*(uint16 *)&mother_brain_indirect_hdma[i] = 0;
*(uint16 *)(&hdma_window_1_left_pos[0].field_0 + i) = 0;
}
uint16 v1 = room_loading_irq_handler;
if (!room_loading_irq_handler)
v1 = 4;
irqhandler_next_handler = v1;
PointlessFunctionStupidToo();
if (elevator_flags) {
if ((elevator_direction & 0x8000u) == 0)
CallSomeSamusCode(7u);
else
CallSomeSamusCode(0);
}
SetLiquidPhysicsType();
door_transition_function = FUNC16(DoorTransition_FadeInScreenAndFinish);
*(uint16 *)&reg_INIDISP |= 0x1Fu;
return kCoroutineNone;
}
CoroutineRet DoorTransition_FadeInScreenAndFinish(void) { // 0x82E737
AnimtilesHandler();
DetermineWhichEnemiesToProcess();
EnemyMain();
EprojRunAll();
DrawSamusEnemiesAndProjectiles();
EnsureSamusDrawnEachFrame();
QueueEnemyBG2TilemapTransfers();
if (AdvancePaletteFadeForAllPalettes_0xc()) {
debug_disable_sounds = 0;
PlaySpinJumpSoundIfSpinJumping();
door_transition_flag_elevator_zebetites = 0;
door_transition_flag_enemies = 0;
game_state = kGameState_8_MainGameplay;
}
return kCoroutineNone;
}
void LoadDestinationRoomThings(void) { // 0x82E76B
LoaadDesinationRoomCreBitset();
LoadDoorHeader();
LoadRoomHeader();
LoadStateHeader();
LoadCRETilesTilesetTilesAndPalette();
}
void LoadCRETilesTilesetTilesAndPalette(void) { // 0x82E783
elevator_flags = 0;
WriteRegWord(VMAIN, 0x80);
mov24(&decompress_src, 0xb98000);
decompress_dst.addr = addr_unk_605000;
WriteRegWord(VMADDL, 0x2800u);
DecompressToVRAM();
copy24(&decompress_src, &tileset_tiles_pointer);
WriteRegWord(VMADDL, 0);
decompress_dst.addr = 0;
DecompressToVRAM();
*(VoidP *)((char *)&decompress_src.addr + 1) = *(VoidP *)((char *)&tileset_compr_palette_ptr.addr + 1);
decompress_src.addr = tileset_compr_palette_ptr.addr;
static const LongPtr unk_82E7CD = LONGPTR(0x7ec200);
DecompressToMem_IpArg(&unk_82E7CD);
}
void LoadLevelDataAndOtherThings(void) { // 0x82E7D3
uint16 j;
int16 v3;
uint16 k;
RoomDefRoomstate *v12;
RoomDefRoomstate *RoomDefRoomstate;
int16 rdf_scroll_ptr;
uint16 m;
char v10;
char v11;
uint16 n;
char v14;
static const LongPtr unk_82E849 = LONGPTR(0x7ea000);
static const LongPtr unk_82E85A = LONGPTR(0x7ea800);
static const LongPtr unk_82E86D = LONGPTR(0x7ea000);
for (int i = 25598; i >= 0; i -= 2)
level_data[i >> 1] = 0x8000;
copy24(&decompress_src, &room_compr_level_data_ptr);
static const DecompressToParams unk_82E7F8 = { LONGPTR(0x7f0000) };
DecompressToMem_IpArg(&unk_82E7F8);
uint16 v1 = ram7F_start;
for (j = ram7F_start + ram7F_start + (ram7F_start >> 1); ; custom_background[v1 >> 1] = level_data[j >> 1]) {
j -= 2;
v1 -= 2;
if ((v1 & 0x8000u) != 0)
break;
}
v3 = ram7F_start >> 1;
for (k = ram7F_start + (ram7F_start >> 1); ; *(uint16 *)&BTS[(uint16)v3] = level_data[k >> 1]) {
k -= 2;
v3 -= 2;
if (v3 < 0)
break;
}
if (area_index == 6) {
copy24(&decompress_src, &tileset_tile_table_pointer);
DecompressToMem_IpArg(&unk_82E86D);
} else {
mov24(&decompress_src, 0xb9a09d);
DecompressToMem_IpArg(&unk_82E849);
copy24(&decompress_src, &tileset_tile_table_pointer);
DecompressToMem_IpArg(&unk_82E85A);
}
RoomDefRoomstate = get_RoomDefRoomstate(roomdefroomstate_ptr);
rdf_scroll_ptr = RoomDefRoomstate->rdf_scroll_ptr;
if (rdf_scroll_ptr >= 0) {
R18_ = RoomDefRoomstate->rdf_scroll_ptr;
LOBYTE(R20_) = room_height_in_scrolls - 1;
uint8 v8 = 2;
uint8 v9 = 0;
v10 = 0;
do {
if (v10 == (uint8)R20_)
v8 = R18_ + 1;
v14 = v10;
v11 = 0;
do {
scrolls[v9++] = v8;
++v11;
} while (v11 != (uint8)room_width_in_scrolls);
v10 = v14 + 1;
} while (v14 + 1 != (uint8)room_height_in_scrolls);
} else {
for (m = 0; m != 50; m += 2) {
*(uint16 *)&scrolls[m] = *(uint16 *)RomPtr_8F(rdf_scroll_ptr);
rdf_scroll_ptr += 2;
}
}
v12 = get_RoomDefRoomstate(roomdefroomstate_ptr);
if (v12->room_plm_header_ptr) {
for (n = v12->room_plm_header_ptr; get_RoomPlmEntry(n)->plm_header_ptr_; n += 6)
SpawnRoomPLM(n);
}
RunDoorSetupCode();
RunRoomSetupCode();
if (elevator_flags)
elevator_status = 2;
}
void SpawnDoorClosingPLM(void) { // 0x82E8EB
if (!CheckIfColoredDoorCapSpawned()) {
uint16 *v0 = (uint16 *)RomPtr_8F(2 * door_direction - 6518);
if (*v0) {
R18_ = *v0;
R20_ = *(uint16 *)&get_DoorDef(door_def_ptr)->x_pos_plm;
//SpawnRoomPLM(0x12u); // WTF?
}
}
}
uint8 CheckIfColoredDoorCapSpawned(void) { // 0x82E91C
DoorDef *DoorDef;
int16 x_pos_plm;
int16 v2;
int16 v6;
DoorDef = get_DoorDef(door_def_ptr);
uint16 prod = Mult8x8(DoorDef->y_pos_plm, room_width_in_blocks);
x_pos_plm = DoorDef->x_pos_plm;
v2 = 2 * (prod + x_pos_plm);
uint16 v3 = 78;
while (v2 != plm_block_indices[v3 >> 1]) {
v3 -= 2;
if ((v3 & 0x8000u) != 0)
return 0;
}
int v5 = v3 >> 1;
if (!plm_header_ptr[v5])
return 0;
v6 = plm_room_arguments[v5];
if (v6 >= 0) {
int idx = PrepareBitAccess(v6);
if ((bitmask & opened_door_bit_array[idx]) != 0)
return 0;
}
int v7 = v3 >> 1;
plm_instruction_timer[v7] = 1;
uint16 v8 = plm_header_ptr[v7];
if (!v8)
return 0;
plm_instr_list_ptrs[v3 >> 1] = get_PlmHeader_Size4(v8)[1].func_ptr;
return 1;
}
static Func_Y_Y *const kLoadLibraryBackgroundFuncs[8] = { // 0x82E97C
LoadLibraryBackgroundFunc_0_DONE,
LoadLibraryBackgroundFunc_2_TransferToVram,
LoadLibraryBackgroundFunc_4_Decompress,
LoadLibraryBackgroundFunc_6_ClearFxTilemap,
LoadLibraryBackgroundFunc_8_TransferToVramAndSetBg3,
LoadLibraryBackgroundFunc_A_ClearBG2Tilemap,
LoadLibraryBackgroundFunc_C_ClearKraidLayer2,
LoadLibraryBackgroundFunc_E_DoorDependentTransferToVram,
};
void LoadLibraryBackground(void) {
int16 bg_data_ptr;
ClearFXTilemap();
if (fx_tilemap_ptr) {
WriteRegWord(A1T1L, fx_tilemap_ptr);
WriteRegWord(VMADDL, addr_unk_605BE0);
WriteRegWord(DMAP1, 0x1801u);
WriteRegWord(A1B1, 0x8Au);
WriteRegWord(DAS1L, 0x840u);
WriteReg(VMAIN, 0x80);
WriteReg(MDMAEN, 2u);
}
bg_data_ptr = get_RoomDefRoomstate(roomdefroomstate_ptr)->bg_data_ptr;
if (bg_data_ptr < 0) {
do {
uint16 v1 = *(uint16 *)RomPtr_8F(bg_data_ptr);
bg_data_ptr += 2;
bg_data_ptr = kLoadLibraryBackgroundFuncs[v1 >> 1](bg_data_ptr);
} while (bg_data_ptr);
}
}
uint16 LoadLibraryBackgroundFunc_0_DONE(uint16 j) { // 0x82E9E5
return 0;
}
uint16 LoadLibraryBackgroundFunc_E_DoorDependentTransferToVram(uint16 j) { // 0x82E9E7
if (door_def_ptr == get_LoadBg_E(j)->field_0)
return LoadLibraryBackgroundFunc_2_TransferToVram(j + 2);
else
return j + 9;
}
uint16 LoadLibraryBackgroundFunc_2_TransferToVram(uint16 j) { // 0x82E9F9
uint16 *LoadBg_28 = (uint16 *)get_LoadBg_28(j);
WriteRegWord(VMADDL, *(uint16 *)((char *)LoadBg_28 + 3));
WriteRegWord(DMAP1, 0x1801u);
WriteRegWord(A1T1L, *LoadBg_28);
WriteRegWord(A1B1, LoadBg_28[1]);
WriteRegWord(DAS1L, *(uint16 *)((char *)LoadBg_28 + 5));
WriteReg(VMAIN, 0x80);
WriteReg(MDMAEN, 2u);
return j + 7;
}
uint16 LoadLibraryBackgroundFunc_4_Decompress(uint16 j) { // 0x82EA2D
LongPtr *LoadBg_28;
LoadBg_28 = (LongPtr *)get_LoadBg_28(j);
copy24(&decompress_src, LoadBg_28);
*(VoidP *)((char *)&decompress_dst.addr + 1) = 32256;
decompress_dst.addr = LoadBg_28[1].addr;
DecompressToMem();
return j + 5;
}
uint16 LoadLibraryBackgroundFunc_6_ClearFxTilemap(uint16 j) { // 0x82EA4E
ClearFXTilemap();
return j;
}
uint16 LoadLibraryBackgroundFunc_A_ClearBG2Tilemap(uint16 j) { // 0x82EA56
ClearBG2Tilemap();
return j;
}
uint16 LoadLibraryBackgroundFunc_C_ClearKraidLayer2(uint16 j) { // 0x82EA5E
ClearBG2Tilemap();
return j;
}
uint16 LoadLibraryBackgroundFunc_8_TransferToVramAndSetBg3(uint16 j) { // 0x82EA66
j = LoadLibraryBackgroundFunc_2_TransferToVram(j);
reg_BG34NBA = 2;
return j;
}
void LoadLevelScrollAndCre(void) { // 0x82EA73
uint16 j;
int16 v3;
uint16 k;
RoomDefRoomstate *RoomDefRoomstate;
int16 rdf_scroll_ptr;
uint16 m;
char v10;
char v11;
char v12;
static const LongPtr unk_82EAA0 = LONGPTR(0x7f0000);
static const LongPtr unk_82EAF9 = LONGPTR(0x7ea000);
static const LongPtr unk_82EB0A = LONGPTR(0x7ea800);
static const LongPtr unk_82EB1D = LONGPTR(0x7ea000);
for (int i = 6398; i >= 0; i -= 2) {
level_data[i >> 1] = 0x8000;
level_data[(i >> 1) + 3200 * 1] = 0x8000;
level_data[(i >> 1) + 3200 * 2] = 0x8000;
level_data[(i >> 1) + 3200 * 3] = 0x8000;
}
copy24(&decompress_src, &room_compr_level_data_ptr);
DecompressToMem_IpArg(&unk_82EAA0);
uint16 v1 = ram7F_start;
for (j = ram7F_start + ram7F_start + (ram7F_start >> 1); ; custom_background[v1 >> 1] = level_data[j >> 1]) {
j -= 2;
v1 -= 2;
if ((v1 & 0x8000u) != 0)
break;
}
v3 = ram7F_start >> 1;
for (k = ram7F_start + (ram7F_start & 1) + (ram7F_start >> 1);
;
*(uint16 *)&BTS[(uint16)v3] = level_data[k >> 1]) {
k -= 2;
v3 -= 2;
if (v3 < 0)
break;
}
if (area_index == 6) {
copy24(&decompress_src, &tileset_tile_table_pointer);
DecompressToMem_IpArg(&unk_82EB1D);
} else {
if ((cre_bitset & 2) != 0) {
mov24(&decompress_src, 0xb9a09d);
DecompressToMem_IpArg(&unk_82EAF9);
}
copy24(&decompress_src, &tileset_tile_table_pointer);
DecompressToMem_IpArg(&unk_82EB0A);
}
RoomDefRoomstate = get_RoomDefRoomstate(roomdefroomstate_ptr);
rdf_scroll_ptr = RoomDefRoomstate->rdf_scroll_ptr;
if (rdf_scroll_ptr >= 0) {
R18_ = RoomDefRoomstate->rdf_scroll_ptr;
LOBYTE(R20_) = room_height_in_scrolls - 1;
uint8 v8 = 2;
uint8 v9 = 0;
v10 = 0;
do {
if (v10 == (uint8)R20_)
v8 = R18_ + 1;
v12 = v10;
v11 = 0;
do {
scrolls[v9++] = v8;
++v11;
} while (v11 != (uint8)room_width_in_scrolls);
v10 = v12 + 1;
} while (v12 + 1 != (uint8)room_height_in_scrolls);
} else {
for (m = 0; m != 50; m += 2) {
*(uint16 *)&scrolls[m] = *(uint16 *)RomPtr_8F(rdf_scroll_ptr);
rdf_scroll_ptr += 2;
}
}
}
void CreatePlmsExecuteDoorAsmRoomSetup(void) { // 0x82EB6C
RoomDefRoomstate *RoomDefRoomstate;
RoomDefRoomstate = get_RoomDefRoomstate(roomdefroomstate_ptr);
if (RoomDefRoomstate->room_plm_header_ptr) {
for (int i = RoomDefRoomstate->room_plm_header_ptr; get_PlmHeader_Size6(i)->func_ptr; i += 6)
SpawnRoomPLM(i);
}
RunDoorSetupCode();
RunRoomSetupCode();
if (elevator_flags)
elevator_status = 2;
}
static Func_V *const kGameOptionsMenuFuncs[13] = { // 0x82EB9F
GameOptionsMenuFunc_0,
GameOptionsMenu_1_LoadingOptionsScreen,
GameOptionsMenu_2_FadeInOptionsScreen,
GameOptionsMenu_3_OptionsScreen,
GameOptionsMenu_4_StartGame,
GameOptionsMenu_5_DissolveOutScreen,
GameOptionsMenu_6_DissolveInScreen,
GameOptionsMenu_7_ControllerSettings,
GameOptionsMenu_8_SpecialSettings,
GameOptionsMenu_9_ScrollControllerSettingsDown,
GameOptionsMenu_A_ScrollControllerSettingsUp,
GameOptionsMenu_B_TransitionBackToFileSelect,
GameOptionsMenu_C_FadeOutOptionsScreenToStart,
};
CoroutineRet GameState_2_GameOptionsMenu(void) {
kGameOptionsMenuFuncs[game_options_screen_index]();
OptionsMenuFunc1();
DrawOptionsMenuSpritemaps();
if (!sign16(game_options_screen_index - 2))
OptionsMenu_AddToVramQueue();
return kCoroutineNone;
}
void GameOptionsMenuFunc_0(void) { // 0x82EBDB
HandleFadeOut();
if (reg_INIDISP == 0x80) {
EnableNMI();
screen_fade_delay = 0;
screen_fade_counter = 0;
++game_options_screen_index;
} else if (reg_INIDISP == 14) {
uint16 v0 = reg_TS;
if ((reg_TS & 4) == 0)
CreateOptionsMenuObject_(v0, addr_stru_82F4D6);
}
}
#define kMenuPalettes ((uint16*)RomPtr(0x8ee400))
void GameOptionsMenu_1_LoadingOptionsScreen(void) { // 0x82EC11
uint16 j;
static const DecompressToParams unk_82EC74 = { LONGPTR(0x7fc000) };
static const DecompressToParams unk_82EC85 = { LONGPTR(0x7fc800) };
static const DecompressToParams unk_82EC96 = { LONGPTR(0x7fd000) };
static const DecompressToParams unk_82ECA7 = { LONGPTR(0x7fd800) };
static const DecompressToParams unk_82ECB8 = { LONGPTR(0x7fe000) };
reg_BG12NBA = 0;
reg_TM = 19;
reg_TS = 0;
reg_TMW = 0;
reg_TSW = 0;
next_gameplay_CGWSEL = 0;
next_gameplay_CGADSUB = 0;
reg_CGWSEL = 0;
reg_CGADSUB = 0;
WriteReg(VMADDL, 0);
WriteReg(VMADDH, 0x58u);
WriteReg(VMAIN, 0x80);
static const StartDmaCopy unk_82EC3D = { 1, 1, 0x18, LONGPTR(0x8edc00), 0x0800 };
SetupDmaTransfer(&unk_82EC3D);
WriteReg(MDMAEN, 2u);
reg_BG1HOFS = 0;
reg_BG1VOFS = 0;
reg_BG2HOFS = 0;
reg_BG2VOFS = 0;
debug_invincibility = 0;
for (int i = 510; i >= 0; i -= 2)
palette_buffer[i >> 1] = kMenuPalettes[i >> 1];
mov24(&decompress_src, 0x978DF4u);
DecompressToMem_IpArg(&unk_82EC74);
mov24(&decompress_src, 0x978FCDu);
DecompressToMem_IpArg(&unk_82EC85);
mov24(&decompress_src, 0x9791C4u);
DecompressToMem_IpArg(&unk_82EC96);
mov24(&decompress_src, 0x97938Du);
DecompressToMem_IpArg(&unk_82ECA7);
mov24(&decompress_src, 0x97953Au);
DecompressToMem_IpArg(&unk_82ECB8);
for (j = 1023; (j & 0x8000u) == 0; --j)
ram3000.pause_menu_map_tilemap[j] = custom_background[j + 5375];
menu_option_index = 0;
DeleteAllOptionsMenuObjects_();
CreateOptionsMenuObject_(0, addr_stru_82F4B8);
CreateOptionsMenuObject_(0, addr_stru_82F4C4);
++game_options_screen_index;
OptionsMenuFunc4();
}
void GameOptionsMenu_2_FadeInOptionsScreen(void) { // 0x82ECE4
HandleFadeIn();
if (reg_INIDISP == 15) {
screen_fade_delay = 0;
screen_fade_counter = 0;
++game_options_screen_index;
}
}
void OptionsMenu_AddToVramQueue(void) { // 0x82ECFF
uint16 v0 = vram_write_queue_tail;
gVramWriteEntry(vram_write_queue_tail)->size = 2048;
v0 += 2;
gVramWriteEntry(v0)->size = 12288;
v0 += 2;
LOBYTE(gVramWriteEntry(v0++)->size) = 126;
gVramWriteEntry(v0)->size = 20480;
vram_write_queue_tail = v0 + 2;
}
void OptionsMenuFunc5(uint16 a, uint16 k, uint16 j) { // 0x82ED28
R18_ = a;
do {
*(uint16 *)((char *)ram3000.pause_menu_map_tilemap + k) = R18_ | *(uint16 *)((uint8 *)ram3000.pause_menu_map_tilemap
+ k) & 0xE3FF;
k += 2;
j -= 2;
} while (j);
}
static Func_V *const kGameOptionsMenuItemFuncs[5] = { // 0x82ED42
GameOptionsMenuItemFunc_0,
GameOptionsMenuItemFunc_2_ToggleJapanese,
GameOptionsMenuItemFunc_2_ToggleJapanese,
GameOptionsMenuItemFunc_4,
GameOptionsMenuItemFunc_4,
};
void GameOptionsMenu_3_OptionsScreen(void) {
if ((joypad1_newkeys & kButton_Up) != 0) {
QueueSfx1_Max6(0x37u);
if ((--menu_option_index & 0x8000u) != 0)
menu_option_index = 4;
} else if ((joypad1_newkeys & kButton_Down) != 0) {
QueueSfx1_Max6(0x37u);
if (++menu_option_index == 5)
menu_option_index = 0;
}
if ((joypad1_newkeys & 0x8000u) != 0) {
game_options_screen_index = 11;
} else if ((joypad1_newkeys & kButton_A) != 0 || (joypad1_newkeys & kButton_Start) != 0) {
QueueSfx1_Max6(0x38u);
kGameOptionsMenuItemFuncs[menu_option_index]();
}
}
void GameOptionsMenuItemFunc_0(void) { // 0x82EDB1
if (enable_debug && (joypad1_lastkeys & kButton_L) == 0 || loading_game_state == kGameState_5_FileSelectMap) {
game_options_screen_index = 4;
} else {
screen_fade_delay = 0;
screen_fade_counter = 0;
game_options_screen_index = 12;
}
}
void GameOptionsMenuItemFunc_2_ToggleJapanese(void) { // 0x82EDDA
menu_option_index = 0;
japanese_text_flag = japanese_text_flag == 0;
OptionsMenuFunc4();
}
void OptionsMenuFunc4(void) { // 0x82EDED
if (japanese_text_flag) {
OptionsMenuFunc5(0x400u, 0x288u, 0x18u);
OptionsMenuFunc5(0x400u, 0x2C8u, 0x18u);
OptionsMenuFunc5(0, 0x348u, 0x32u);
OptionsMenuFunc5(0, 0x388u, 0x32u);
} else {
OptionsMenuFunc5(0, 0x288u, 0x18u);
OptionsMenuFunc5(0, 0x2C8u, 0x18u);
OptionsMenuFunc5(0x400u, 0x348u, 0x32u);
OptionsMenuFunc5(0x400u, 0x388u, 0x32u);
}
}
void GameOptionsMenuItemFunc_4(void) { // 0x82EE55
reg_MOSAIC = 3;
screen_fade_delay = 0;
screen_fade_counter = 0;
game_options_screen_index = 5;
}
void GameOptionsMenu_B_TransitionBackToFileSelect(void) { // 0x82EE6A
HandleFadeOut();
if (reg_INIDISP == 0x80) {
EnableNMI();
screen_fade_delay = 0;
screen_fade_counter = 0;
game_state = kGameState_4_FileSelectMenus;
menu_index = 0;
game_options_screen_index = 0;
}
}
void GameOptionsMenu_C_FadeOutOptionsScreenToStart(void) { // 0x82EE92
HandleFadeOut();
if (reg_INIDISP == 0x80) {
EnableNMI();
screen_fade_delay = 0;
screen_fade_counter = 0;
game_options_screen_index = 4;
}
}
void GameOptionsMenu_4_StartGame(void) { // 0x82EEB4
game_options_screen_index = 0;
if (enable_debug && (joypad1_lastkeys & 0x20) == 0) {
game_state = kGameState_5_FileSelectMap;
if (loading_game_state != kLoadingGameState_5_Main) {
loading_game_state = kGameState_5_FileSelectMap;
SaveToSram(selected_save_slot);
}
} else if (loading_game_state) {
game_state = loading_game_state;
if (loading_game_state == kGameState_34_CeresGoesBoom)
cinematic_function = FUNC16(CinematicFunctionBlackoutFromCeres);
menu_option_index = 0;
game_options_screen_index = 0;
} else {
game_state = kGameState_30_IntroCinematic;
cinematic_function = FUNC16(CinematicFunction_Intro_Initial);
menu_option_index = 0;
screen_fade_delay = 0;
screen_fade_counter = 0;
}
}
void GameOptionsMenu_5_DissolveOutScreen(void) { // 0x82EF18
uint16 m;
uint16 k;
uint16 j;
uint16 n;
uint16 v1;
HandleFadeOut();
if (reg_MOSAIC != 0xF3)
reg_MOSAIC += 16;
if (reg_INIDISP == 0x80) {
EnableNMI();
screen_fade_delay = 0;
screen_fade_counter = 0;
reg_BG1VOFS = 0;
++game_options_screen_index;
if (menu_option_index) {
if ((menu_option_index & 4) != 0) {
if (japanese_text_flag) {
for (int i = 1023; i >= 0; --i)
ram3000.pause_menu_map_tilemap[i] = custom_background[i + 9471];
} else {
for (j = 1023; (j & 0x8000u) == 0; --j)
ram3000.pause_menu_map_tilemap[j] = custom_background[j + 8447];
}
menu_option_index = 0;
OptionsMenuFunc7();
menu_option_index = 1;
OptionsMenuFunc7();
menu_option_index = 4;
CreateOptionsMenuObject_(4u, addr_stru_82F4D0);
} else {
if (japanese_text_flag) {
for (k = 1023; (k & 0x8000u) == 0; --k) {
v1 = custom_background[k + 7423];
ram3000.pause_menu_map_tilemap[k] = v1;
}
} else {
for (m = 1023; (m & 0x8000u) == 0; --m) {
v1 = custom_background[m + 6399];
ram3000.pause_menu_map_tilemap[m] = v1;
}
}
CreateOptionsMenuObject_(v1, addr_stru_82F4CA);
LoadControllerOptionsFromControllerBindings();
OptionsMenuFunc6();
}
} else {
for (n = 1023; (n & 0x8000u) == 0; --n)
ram3000.pause_menu_map_tilemap[n] = custom_background[n + 5375];
OptionsMenuFunc4();
uint16 v6 = 0; // bug
CreateOptionsMenuObject_(v6, addr_stru_82F4C4);
}
}
}
void GameOptionsMenu_6_DissolveInScreen(void) { // 0x82EFDB
HandleFadeIn();
if (reg_MOSAIC != 3)
reg_MOSAIC -= 16;
if (reg_INIDISP == 15) {
reg_MOSAIC = 0;
screen_fade_delay = 0;
screen_fade_counter = 0;
if (menu_option_index) {
if ((menu_option_index & 4) != 0)
game_options_screen_index = 8;
else
game_options_screen_index = 7;
menu_option_index = 0;
} else {
game_options_screen_index = 3;
}
}
}
static Func_V *const kGameOptionsMenuSpecialSettings[3] = { // 0x82F024
GameOptionsMenuSpecialSettings_0,
GameOptionsMenuSpecialSettings_0,
GameOptionsMenuSpecialSettings_2,
};
void GameOptionsMenu_8_SpecialSettings(void) {
if ((joypad1_newkeys & kButton_Up) != 0) {
QueueSfx1_Max6(0x37u);
if ((--menu_option_index & 0x8000u) != 0)
menu_option_index = 2;
} else if ((joypad1_newkeys & kButton_Down) != 0) {
QueueSfx1_Max6(0x37u);
if (++menu_option_index == 3)
menu_option_index = 0;
}
if ((joypad1_newkeys & 0x8000u) == 0) {
if ((joypad1_newkeys & (kButton_Start | kButton_Left | kButton_Right | kButton_A)) != 0) {
QueueSfx1_Max6(0x38u);
kGameOptionsMenuSpecialSettings[menu_option_index]();
}
} else {
QueueSfx1_Max6(0x38u);
menu_option_index = 0;
GameOptionsMenuItemFunc_4();
}
}
#define kOptionsMenuSpecialPtrs ((uint16*)RomPtr(0x82f0ae))
void GameOptionsMenuSpecialSettings_0(void) { // 0x82F08E
uint8 *v0 = RomPtr_RAM(kOptionsMenuSpecialPtrs[menu_option_index]);
if (*(uint16 *)v0)
*(uint16 *)v0 = 0;
else
*(uint16 *)v0 = 1;
OptionsMenuFunc7();
}
void GameOptionsMenuSpecialSettings_2(void) { // 0x82F0B2
menu_option_index = 0;
GameOptionsMenuItemFunc_4();
}
static const uint16 g_word_82F149[4] = { // 0x82F0B9
0x1e0, 0x220,
0x360, 0x3a0,
};
static const uint16 g_word_82F151[4] = {
0x1ee, 0x22e,
0x36e, 0x3ae,
};
void OptionsMenuFunc7(void) {
uint16 v0 = 4 * menu_option_index;
if (*(uint16 *)RomPtr_RAM(kOptionsMenuSpecialPtrs[menu_option_index])) {
OptionsMenuFunc5(0, g_word_82F149[(uint16)(4 * menu_option_index) >> 1], 0xCu);
OptionsMenuFunc5(0, g_word_82F149[(v0 >> 1) + 1], 0xCu);
OptionsMenuFunc5(0x400u, g_word_82F151[v0 >> 1], 0xCu);
OptionsMenuFunc5(0x400u, g_word_82F151[(v0 >> 1) + 1], 0xCu);
} else {
OptionsMenuFunc5(0x400u, g_word_82F149[(uint16)(4 * menu_option_index) >> 1], 0xCu);
OptionsMenuFunc5(0x400u, g_word_82F149[(v0 >> 1) + 1], 0xCu);
OptionsMenuFunc5(0, g_word_82F151[v0 >> 1], 0xCu);
OptionsMenuFunc5(0, g_word_82F151[(v0 >> 1) + 1], 0xCu);
}
}
static const uint16 word_82F204[16] = { // 0x82F159
0x20, 0x20, 0x20, 0x20,
0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x4000, 0x40,
0x40, 0x80, 0x80, 0x80,
};
void GameOptionsMenu_7_ControllerSettings(void) {
if ((joypad1_newkeys & kButton_Up) != 0) {
QueueSfx1_Max6(0x37u);
uint16 v0 = --menu_option_index;
if ((menu_option_index & 0x8000u) == 0) {
if (v0 != 6)
return;
game_options_screen_index = 10;
return;
}
menu_option_index = 8;
game_options_screen_index = 9;
return;
}
if ((joypad1_newkeys & kButton_Down) != 0) {
QueueSfx1_Max6(0x37u);
uint16 v1 = menu_option_index + 1;
menu_option_index = v1;
if (v1 == 7) {
game_options_screen_index = 9;
return;
}
if (v1 == 9) {
menu_option_index = 0;
game_options_screen_index = 10;
return;
}
} else if (joypad1_newkeys) {
QueueSfx1_Max6(0x38u);
static Func_V *const kOptionsMenuControllerFuncs[9] = {
OptionsMenuControllerFunc_0,
OptionsMenuControllerFunc_0,
OptionsMenuControllerFunc_0,
OptionsMenuControllerFunc_0,
OptionsMenuControllerFunc_0,
OptionsMenuControllerFunc_0,
OptionsMenuControllerFunc_0,
OptionsMenuControllerFunc_7,
OptionsMenuControllerFunc_8,
};
kOptionsMenuControllerFuncs[menu_option_index]();
} else if (joypad2_new_keys && menu_option_index == 8 && sign16(debug_invincibility - 16)) {
if ((word_82F204[debug_invincibility] & joypad2_new_keys) == word_82F204[debug_invincibility])
++debug_invincibility;
else
debug_invincibility = 0;
}
}
void OptionsMenuControllerFunc_8(void) { // 0x82F224
if ((joypad1_newkeys & (kButton_Start | kButton_A)) != 0) {
button_config_shoot_x = 64;
button_config_jump_a = 128;
button_config_run_b = 0x8000;
button_config_itemcancel_y = 0x4000;
button_config_itemswitch = 0x2000;
button_config_aim_up_R = 16;
button_config_aim_down_L = 32;
LoadControllerOptionsFromControllerBindings();
OptionsMenuFunc6();
}
}
void OptionsMenuControllerFunc_7(void) { // 0x82F25D
if ((joypad1_newkeys & (kButton_Start | kButton_A)) != 0 && !OptionsMenuFunc8()) {
menu_option_index = 0;
GameOptionsMenuItemFunc_4();
}
}
void GameOptionsMenu_9_ScrollControllerSettingsDown(void) { // 0x82F271
reg_BG1VOFS += 2;
if (reg_BG1VOFS == 32)
game_options_screen_index = 7;
}
void GameOptionsMenu_A_ScrollControllerSettingsUp(void) { // 0x82F285
reg_BG1VOFS -= 2;
if (!reg_BG1VOFS)
game_options_screen_index = 7;
}
void sub_82F296(uint16 j) { // 0x82F296
int v1 = j >> 1;
enemy_projectile_y_pos[v1 + 13] = 24;
enemy_projectile_x_vel[v1 + 3] = 56;
enemy_projectile_x_vel[v1 + 11] = 3584;
}
#define off_82F2ED ((uint16*)RomPtr(0x82f2ed))
void OptionsPreInstr_F2A9(uint16 v0) { // 0x82F2A9
if (game_state == kGameState_2_GameOptionsMenu) {
int v2 = game_options_screen_index;
uint16 v3 = off_82F2ED[v2];
if (v3) {
R18_ = off_82F2ED[v2];
uint16 *v4 = (uint16 *)RomPtr_82(v3 + 4 * menu_option_index);
int v5 = v0 >> 1;
enemy_projectile_y_pos[v5 + 13] = *v4;
enemy_projectile_x_vel[v5 + 3] = v4[1];
} else {
int v6 = v0 >> 1;
enemy_projectile_y_pos[v6 + 13] = 384;
enemy_projectile_x_vel[v6 + 3] = 16;
}
} else {
int v1 = v0 >> 1;
enemy_projectile_E[v1 + 15] = 1;
enemy_projectile_y_vel[v1 + 17] = addr_off_82F4B6;
}
}
void sub_82F34B(uint16 j) { // 0x82F34B
enemy_projectile_y_pos[(j >> 1) + 13] = 124;
sub_82F369(j);
}
void sub_82F353(uint16 j) { // 0x82F353
enemy_projectile_y_pos[(j >> 1) + 13] = 132;
sub_82F369(j);
}
void sub_82F35B(uint16 j) { // 0x82F35B
enemy_projectile_y_pos[(j >> 1) + 13] = 128;
sub_82F369(j);
}
void sub_82F363(uint16 j) { // 0x82F363
enemy_projectile_y_pos[(j >> 1) + 13] = 128;
sub_82F369(j);
}
void sub_82F369(uint16 j) { // 0x82F369
int v1 = j >> 1;
enemy_projectile_x_vel[v1 + 3] = 16;
enemy_projectile_x_vel[v1 + 11] = 3584;
}
void OptionsPreInstr_F376(uint16 k) { // 0x82F376
if (game_state != kGameState_2_GameOptionsMenu || game_options_screen_index == 6 && reg_INIDISP == 0x80) {
int v1 = k >> 1;
enemy_projectile_E[v1 + 15] = 1;
enemy_projectile_y_vel[v1 + 17] = addr_off_82F4B6;
}
}
void OptionsPreInstr_F3A0(uint16 k) { // 0x82F3A0
switch (game_options_screen_index) {
case 6u:
if (reg_INIDISP == 0x80) {
int v1 = k >> 1;
enemy_projectile_E[v1 + 15] = 1;
enemy_projectile_y_vel[v1 + 17] = -2890;
}
break;
case 9u:
enemy_projectile_x_vel[(k >> 1) + 3] -= 2;
break;
case 0xAu:
enemy_projectile_x_vel[(k >> 1) + 3] += 2;
break;
}
}
void OptionsPreInstr_F3E2(uint16 k) { // 0x82F3E2
if (game_options_screen_index == 6 && reg_INIDISP == 0x80) {
int v1 = k >> 1;
enemy_projectile_E[v1 + 15] = 1;
enemy_projectile_y_vel[v1 + 17] = -2890;
}
}
void sub_82F404(uint16 k) { // 0x82F404
if (game_options_screen_index == 1) {
int v1 = k >> 1;
enemy_projectile_E[v1 + 15] = 1;
enemy_projectile_y_vel[v1 + 17] = -2890;
}
}
void sub_82F419(uint16 j) { // 0x82F419
int v1 = j >> 1;
enemy_projectile_y_pos[v1 + 13] = 216;
enemy_projectile_x_vel[v1 + 3] = 16;
enemy_projectile_x_vel[v1 + 11] = 3584;
}
void OptionsPreInstr_F42C(uint16 k) { // 0x82F42C
if (game_state != 2) {
int v1 = k >> 1;
enemy_projectile_E[v1 + 15] = 1;
enemy_projectile_y_vel[v1 + 17] = addr_off_82F4B6;
}
}
#define off_82F54A ((uint16*)RomPtr(0x82f54a))
void LoadControllerOptionsFromControllerBindings(void) { // 0x82F4DC
int16 v2;
uint16 v0 = 0;
do {
int v1 = v0 >> 1;
v2 = *(uint16 *)RomPtr_7E(off_82F54A[v1]);
if ((v2 & kButton_X) != 0) {
LABEL_9:
enemy_projectile_F[v1 + 13] = 0;
goto LABEL_16;
}
if ((v2 & kButton_A) != 0) {
enemy_projectile_F[v1 + 13] = 1;
} else if (v2 < 0) {
enemy_projectile_F[v1 + 13] = 2;
} else if ((v2 & kButton_Select) != 0) {
enemy_projectile_F[v1 + 13] = 3;
} else if ((v2 & kButton_Y) != 0) {
enemy_projectile_F[v1 + 13] = 4;
} else if ((v2 & kButton_L) != 0) {
enemy_projectile_F[v1 + 13] = 5;
} else {
if ((v2 & kButton_R) == 0)
goto LABEL_9;
enemy_projectile_F[v1 + 13] = 6;
}
LABEL_16:
v0 += 2;
} while ((int16)(v0 - 14) < 0);
}
static const Buttons word_82F575[9] = { // 0x82F558
kButton_X,
kButton_A,
kButton_B,
kButton_Select,
kButton_Y,
kButton_L,
kButton_R,
kButton_Left,
kButton_Right,
};
uint8 OptionsMenuFunc8(void) {
uint16 v0 = 0, v2;
do {
v2 = v0;
*(uint16 *)RomPtr_7E(off_82F54A[v0 >> 1]) = word_82F575[(uint16)(2 * enemy_projectile_F[(v0 >> 1) + 13]) >> 1];
v0 += 2;
} while ((int16)(v2 - 12) < 0);
return 0;
}
#define g_word_82F639 ((uint16*)RomPtr(0x82f639))
#define g_off_82F647 ((uint16*)RomPtr(0x82f647))
static const uint16 g_word_82F6AD[6] = { // 0x82F587
0,
0xe,
0xe,
0x10,
0x1f,
0x1f,
};
void OptionsMenuFunc6(void) {
uint16 v0 = 0, v4;
do {
v4 = v0;
int v1 = v0 >> 1;
uint16 v2 = g_word_82F639[v1];
uint16 *v3 = (uint16 *)RomPtr_82(g_off_82F647[(uint16)(2 * enemy_projectile_F[v1 + 13]) >> 1]);
*(uint16 *)((char *)ram3000.pause_menu_map_tilemap + v2) = *v3;
*(uint16 *)((char *)&ram3000.pause_menu_map_tilemap[1] + v2) = v3[1];
*(uint16 *)((char *)&ram3000.pause_menu_map_tilemap[2] + v2) = v3[2];
*(uint16 *)((char *)&ram3000.pause_menu_map_tilemap[32] + v2) = v3[3];
*(uint16 *)((char *)&ram3000.pause_menu_map_tilemap[33] + v2) = v3[4];
*(uint16 *)((char *)&ram3000.pause_menu_map_tilemap[34] + v2) = v3[5];
v0 = v4 + 2;
} while ((int16)(v4 - 12) < 0);
if (enemy_projectile_instr_list_ptr[0] != 5 && enemy_projectile_instr_list_ptr[0] != 6) {
*(uint32 *)&ram3000.menu.backup_of_io_registers_in_gameover[46] = *(uint32 *)g_word_82F6AD;
ram3000.pause_menu_map_tilemap[665] = g_word_82F6AD[2];
*(uint32 *)&ram3000.menu.field_536[56] = *(uint32 *)&g_word_82F6AD[3];
ram3000.pause_menu_map_tilemap[697] = g_word_82F6AD[5];
}
if (enemy_projectile_instr_list_ptr[1] != 5 && enemy_projectile_instr_list_ptr[1] != 6) {
*(uint32 *)&ram3000.menu.field_536[184] = *(uint32 *)g_word_82F6AD;
ram3000.pause_menu_map_tilemap[761] = g_word_82F6AD[2];
*(uint32 *)&ram3000.menu.menu_tilemap[46] = *(uint32 *)&g_word_82F6AD[3];
ram3000.pause_menu_map_tilemap[793] = g_word_82F6AD[5];
}
}
void OptionsMenuControllerFunc_0(void) { // 0x82F6B9
uint16 v0 = 12;
while ((word_82F575[v0 >> 1] & joypad1_newkeys) == 0) {
v0 -= 2;
if ((v0 & 0x8000u) != 0)
return;
}
R18_ = v0 >> 1;
uint16 v1 = 2 * menu_option_index + 2;
if (!sign16(2 * menu_option_index - 12))
v1 = 0;
uint16 v2 = v1;
for (int i = 5; i >= 0; --i) {
if (enemy_projectile_F[(v2 >> 1) + 13] == R18_)
break;
v2 += 2;
if ((int16)(v2 - 14) >= 0)
v2 = 0;
}
int v4 = menu_option_index;
R20_ = enemy_projectile_F[v4 + 13];
enemy_projectile_F[v4 + 13] = R18_;
enemy_projectile_F[(v2 >> 1) + 13] = R20_;
OptionsMenuFunc6();
}