### Description <!-- What is the purpose of this PR and what it adds? --> ### Will this Pull Request break anything? <!-- Will it break the compiling? --> ### Suggested Testing Steps <!-- See if the compiling fails/break anything in the game. -->
435 lines
14 KiB
C
435 lines
14 KiB
C
// Message boxes
|
|
#include "ida_types.h"
|
|
#include "variables.h"
|
|
#include "funcs.h"
|
|
|
|
uint16 message_box_das0l_value;
|
|
|
|
|
|
#define kMessageBoxDefs ((MsgBoxConfig*)RomFixedPtr(0x85869b))
|
|
static const uint16 kMsgBoxSpecialButtonTilemapOffs[27] = { // 0x8583D1
|
|
0, 0x12a, 0x12a, 0x12c, 0x12c, 0x12c, 0, 0, 0, 0, 0, 0, 0x120, 0, 0, 0,
|
|
0, 0, 0x12a, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
};
|
|
static const uint16 kTileNumbersForButtonLetters[8] = { 0x28e0, 0x3ce1, 0x2cf7, 0x38f8, 0x38d0, 0x38eb, 0x38f1, 0x284e };
|
|
|
|
static void InitializePpuForMessageBoxes(void) { // 0x858143
|
|
save_confirmation_selection = 0;
|
|
WriteReg(HDMAEN, 0);
|
|
WriteReg(CGADD, 0x19);
|
|
WriteReg(CGDATA, 0xB1);
|
|
WriteReg(CGDATA, 0xB);
|
|
WriteReg(CGDATA, 0x1F);
|
|
WriteReg(CGDATA, 0);
|
|
ram3000.msgbox.backup_of_enabled_hdma_channels = reg_HDMAEN;
|
|
ram3000.misc.field_3E8[3] = gameplay_BG3SC;
|
|
gameplay_BG3SC = 88;
|
|
gameplay_TM = 23;
|
|
gameplay_CGWSEL = 0;
|
|
gameplay_CGADSUB = 0;
|
|
WriteReg(COLDATA, 0x20);
|
|
WriteReg(COLDATA, 0x40);
|
|
WriteReg(COLDATA, 0x80);
|
|
ReadReg(BG3HOFS);
|
|
WriteReg(BG3HOFS, 0);
|
|
WriteReg(BG3HOFS, 0);
|
|
ReadReg(BG3VOFS);
|
|
WriteReg(BG3VOFS, 0);
|
|
WriteReg(BG3VOFS, 0);
|
|
for (int i = 128; i >= 0; i -= 2)
|
|
*(uint16 *)((uint8 *)ram3000.pause_menu_map_tilemap + (uint16)i) = 0;
|
|
WriteRegWord(VMADDL, addr_unk_605880);
|
|
ReadRegWord(RDVRAML);
|
|
WriteRegWord(DMAP1, 0x3981);
|
|
WriteRegWord(A1T1L, ADDR16_OF_RAM(ram4000) + 256);
|
|
WriteRegWord(A1B1, 0x7E);
|
|
WriteRegWord(DAS1L, 0x700);
|
|
WriteRegWord(DAS10, 0);
|
|
WriteRegWord(A2A1H, 0);
|
|
WriteReg(VMAIN, 0x80);
|
|
WriteReg(MDMAEN, 2);
|
|
}
|
|
|
|
static void ClearMessageBoxBg3Tilemap(void) { // 0x8581F3
|
|
int16 v0;
|
|
v0 = 1790;
|
|
do {
|
|
*(uint16 *)((uint8 *)ram3800.cinematic_bg_tilemap + (uint16)v0) = 0xe;
|
|
v0 -= 2;
|
|
} while (v0 >= 0);
|
|
WriteRegWord(VMADDL, addr_unk_605880);
|
|
WriteRegWord(DMAP1, 0x1801);
|
|
WriteRegWord(A1T1L, ADDR16_OF_RAM(ram3800));
|
|
WriteRegWord(A1B1, 0x7E);
|
|
WriteRegWord(DAS1L, 0x700);
|
|
WriteRegWord(DAS10, 0);
|
|
WriteRegWord(A2A1H, 0);
|
|
WriteReg(VMAIN, 0x80);
|
|
WriteReg(MDMAEN, 2);
|
|
}
|
|
|
|
static const uint16 kLargeMsgBoxTopBottomBorderTilemap[32] = { // 0x85825A
|
|
0xe, 0xe, 0xe, 0x284e, 0x284e, 0x284e, 0x284e, 0x284e, 0x284e, 0x280f, 0x280f, 0x280f, 0x280f, 0x280f, 0x280f, 0x280f,
|
|
0x280f, 0x280f, 0x280f, 0x280f, 0x280f, 0x280f, 0x280f, 0x280f, 0x280f, 0x280f, 0x280f, 0x284e, 0x284e, 0xe, 0xe, 0xe,
|
|
};
|
|
static const uint16 kSmallMsgBoxTopBottomBorderTilemap[32] = {
|
|
0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0x284e, 0x284e, 0x284e, 0x284e, 0x284e, 0x284e, 0x284e, 0x284e, 0x284e, 0x284e,
|
|
0x284e, 0x284e, 0x284e, 0x284e, 0x284e, 0x284e, 0x284e, 0x284e, 0x284e, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe,
|
|
};
|
|
|
|
static uint16 WriteMessageTilemap(void) { // 0x8582B8
|
|
message_box_animation_y1 = 112;
|
|
message_box_animation_y0 = 124;
|
|
message_box_animation_y_radius = 0;
|
|
for (int i = 0; i != 112; ++i)
|
|
ram3000.pause_menu_map_tilemap[i] = 0;
|
|
bg3_tilemap_offset = 2 * (message_box_index - 1);
|
|
uint16 r0 = *(VoidP *)((uint8 *)&kMessageBoxDefs[0].message_tilemap + (6 * (message_box_index - 1)));
|
|
uint16 r9 = *(VoidP *)((uint8 *)&kMessageBoxDefs[1].message_tilemap + (6 * (message_box_index - 1))) - r0;
|
|
int n = r9 >> 1;
|
|
r9 += 128;
|
|
message_box_das0l_value = r9;
|
|
uint16 v1 = 32;
|
|
uint16 v2 = 0;
|
|
do {
|
|
ram3000.pause_menu_map_tilemap[v1 + 256] = *(uint16 *)&RomPtr_85(r0)[v2];
|
|
++v1;
|
|
v2 += 2;
|
|
} while (--n);
|
|
return v1;
|
|
}
|
|
|
|
static void WriteLargeMessageBoxTilemap(void) {
|
|
for (int i = 0; i != 32; ++i)
|
|
ram3000.pause_menu_map_tilemap[i + 256] = kLargeMsgBoxTopBottomBorderTilemap[i];
|
|
uint16 i = WriteMessageTilemap();
|
|
int n = 32;
|
|
uint16 v1 = 0;
|
|
do {
|
|
ram3000.pause_menu_map_tilemap[i + 256] = kLargeMsgBoxTopBottomBorderTilemap[v1 >> 1];
|
|
v1 += 2;
|
|
++i;
|
|
} while (--n);
|
|
}
|
|
|
|
static void WriteSmallMessageBoxTilemap(void) { // 0x858289
|
|
for (int i = 0; i != 32; ++i)
|
|
ram3000.pause_menu_map_tilemap[i + 256] = kSmallMsgBoxTopBottomBorderTilemap[i];
|
|
uint16 i = WriteMessageTilemap();
|
|
int n = 32;
|
|
uint16 v1 = 0;
|
|
do {
|
|
ram3000.pause_menu_map_tilemap[i + 256] = kSmallMsgBoxTopBottomBorderTilemap[v1 >> 1];
|
|
v1 += 2;
|
|
++i;
|
|
} while (--n);
|
|
}
|
|
|
|
static void CallMsgBoxDraw(uint32 ea) {
|
|
switch (ea) {
|
|
case fnWriteLargeMessageBoxTilemap: WriteLargeMessageBoxTilemap(); return;
|
|
case fnWriteSmallMessageBoxTilemap: WriteSmallMessageBoxTilemap(); return;
|
|
default: Unreachable();
|
|
}
|
|
}
|
|
|
|
static void MsgBoxMakeHdmaTable(void) {
|
|
message_box_animation_y2 = (uint16)(31488 - message_box_animation_y_radius) >> 8;
|
|
message_box_animation_y3 = 99;
|
|
message_box_animation_y0 = (uint16)(message_box_animation_y_radius + 31744) >> 8;
|
|
message_box_animation_y1 = 148;
|
|
uint16 v0 = 123;
|
|
uint16 v1 = 124;
|
|
uint16 r20 = 30;
|
|
do {
|
|
ram3000.pause_menu_map_tilemap[v0] = message_box_animation_y3 - message_box_animation_y2;
|
|
--message_box_animation_y3;
|
|
--message_box_animation_y2;
|
|
ram3000.pause_menu_map_tilemap[v1] = message_box_animation_y1 - message_box_animation_y0;
|
|
--v0;
|
|
++message_box_animation_y1;
|
|
++message_box_animation_y0;
|
|
++v1;
|
|
} while (--r20);
|
|
uint16 v2 = v1 * 2;
|
|
do {
|
|
*(uint16 *)((uint8 *)ram3000.pause_menu_map_tilemap + v2) = 0;
|
|
v2 += 2;
|
|
} while ((int16)(v2 - 480) < 0);
|
|
}
|
|
|
|
static void SetupMessageBoxBg3YscrollHdma(void) { // 0x858363
|
|
*(uint32 *)&ram3000.menu.palette_backup_in_menu[64] = -516947713;
|
|
ram3000.pause_menu_map_tilemap[450] = 12542;
|
|
ram3000.msgbox.indirect_hdma[6] = 0;
|
|
WriteReg(DMAP6, 0x42);
|
|
WriteReg(BBAD6, 0x12);
|
|
WriteReg(A1T6L, 0x80);
|
|
WriteReg(DAS6L, 0x80);
|
|
WriteReg(A1T6H, 0x33);
|
|
WriteReg(DAS6H, 0x33);
|
|
WriteReg(A1B6, 0x7E);
|
|
WriteReg(DAS60, 0x7E);
|
|
WriteReg(A2A6L, 0);
|
|
WriteReg(A2A6H, 0);
|
|
WriteReg(NTRL6, 0);
|
|
MsgBoxMakeHdmaTable();
|
|
WriteReg(HDMAEN, 0x40);
|
|
}
|
|
|
|
static void SetupPpuForActiveMessageBox(void) { // 0x85831E
|
|
SetupMessageBoxBg3YscrollHdma();
|
|
bg3_tilemap_offset += 22528;
|
|
WriteRegWord(VMADDL, bg3_tilemap_offset);
|
|
WriteRegWord(DMAP1, 0x1801);
|
|
WriteRegWord(A1T1L, ADDR16_OF_RAM(ram3000) + 512);
|
|
WriteRegWord(A1B1, 0x7E);
|
|
WriteRegWord(DAS1L, message_box_das0l_value);
|
|
WriteRegWord(DAS10, 0);
|
|
WriteRegWord(A2A1H, 0);
|
|
WriteReg(VMAIN, 0x80);
|
|
WriteReg(MDMAEN, 2);
|
|
}
|
|
|
|
static void DrawSpecialButtonAndSetupPpuForLargeMessageBox(uint16 a) {
|
|
uint16 v1 = 0;
|
|
if ((a & kButton_A) == 0) {
|
|
v1 = 2;
|
|
if ((a & 0x8000) == 0) {
|
|
v1 = 4;
|
|
if ((a & kButton_X) == 0) {
|
|
v1 = 6;
|
|
if ((a & kButton_Y) == 0) {
|
|
v1 = 8;
|
|
if ((a & kButton_Select) == 0) {
|
|
v1 = 10;
|
|
if ((a & kButton_L) == 0) {
|
|
v1 = 12;
|
|
if ((a & kButton_R) == 0)
|
|
v1 = 14;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*(uint16 *)((uint8 *)&ram3000.pause_menu_map_tilemap[256] + kMsgBoxSpecialButtonTilemapOffs[message_box_index - 1]) = kTileNumbersForButtonLetters[v1 >> 1];
|
|
bg3_tilemap_offset = 416;
|
|
SetupPpuForActiveMessageBox();
|
|
}
|
|
|
|
static void DrawShootButtonAndSetupPpuForLargeMessageBox(void) { // 0x8583C5
|
|
DrawSpecialButtonAndSetupPpuForLargeMessageBox(button_config_shoot_x);
|
|
}
|
|
|
|
static void DrawRunButtonAndSetupPpuForLargeMessageBox(void) { // 0x8583CC
|
|
DrawSpecialButtonAndSetupPpuForLargeMessageBox(button_config_run_b);
|
|
}
|
|
|
|
static void SetupPpuForSmallMessageBox(void) { // 0x858436
|
|
bg3_tilemap_offset = 448;
|
|
SetupPpuForActiveMessageBox();
|
|
}
|
|
|
|
static void SetupPpuForLargeMessageBox(void) { // 0x858441
|
|
bg3_tilemap_offset = 416;
|
|
SetupPpuForActiveMessageBox();
|
|
}
|
|
|
|
static void CallMsgBoxModify(uint32 ea) {
|
|
switch (ea) {
|
|
case fnDrawShootButtonAndSetupPpuForLargeMessageBox: DrawShootButtonAndSetupPpuForLargeMessageBox(); return;
|
|
case fnDrawRunButtonAndSetupPpuForLargeMessageBox: DrawRunButtonAndSetupPpuForLargeMessageBox(); return;
|
|
case fnSetupPpuForSmallMessageBox: SetupPpuForSmallMessageBox(); return;
|
|
case fnSetupPpuForLargeMessageBox: SetupPpuForLargeMessageBox(); return;
|
|
default: Unreachable();
|
|
}
|
|
}
|
|
|
|
static void InitializeMessageBox(void) { // 0x858241
|
|
bg3_tilemap_offset = 2 * (message_box_index - 1);
|
|
uint16 v0 = message_box_index - 1;
|
|
CallMsgBoxDraw(kMessageBoxDefs[v0].draw_initial_tilemap | 0x850000);
|
|
CallMsgBoxModify(kMessageBoxDefs[v0].modify_box_func | 0x850000);
|
|
}
|
|
|
|
|
|
static const uint16 kSaveConfirmationSelectionTilemap[96] = { // 0x858507
|
|
0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0x3c4e, 0x3c4e, 0x38cc, 0x38cd, 0x3cf8, 0x3ce4, 0x3cf2, 0x3c4e, 0x3c4e, 0x3c4e,
|
|
0x3c4e, 0x3c4e, 0x3c4e, 0x2ced, 0x2cee, 0x3c4e, 0x3c4e, 0x3c4e, 0x3c4e, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe,
|
|
0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0x3c4e, 0x3c4e, 0x38cc, 0x38cd, 0x3cf8, 0x3ce4, 0x3cf2, 0x3c4e, 0x3c4e, 0x3c4e,
|
|
0x3c4e, 0x3c4e, 0x3c4e, 0x2ced, 0x2cee, 0x3c4e, 0x3c4e, 0x3c4e, 0x3c4e, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe,
|
|
0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0x3c4e, 0x3c4e, 0x3c4e, 0x3c4e, 0x2cf8, 0x2ce4, 0x2cf2, 0x3c4e, 0x3c4e, 0x3c4e,
|
|
0x3c4e, 0x38cc, 0x38cd, 0x3ced, 0x3cee, 0x3c4e, 0x3c4e, 0x3c4e, 0x3c4e, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe,
|
|
};
|
|
|
|
static void ToggleSaveConfirmationSelection(void) {
|
|
save_confirmation_selection ^= 2;
|
|
uint16 v0 = 64;
|
|
if (save_confirmation_selection == 2)
|
|
v0 = 128;
|
|
uint16 v1 = 128;
|
|
bg3_tilemap_offset = 32;
|
|
do {
|
|
ram3000.pause_menu_map_tilemap[v1 + 256] = kSaveConfirmationSelectionTilemap[v0 >> 1];
|
|
++v1;
|
|
v0 += 2;
|
|
--bg3_tilemap_offset;
|
|
} while (bg3_tilemap_offset);
|
|
bg3_tilemap_offset = addr_unk_6059A0;
|
|
WriteRegWord(VMADDL, addr_unk_6059A0);
|
|
WriteRegWord(DMAP1, 0x1801);
|
|
WriteRegWord(A1T1L, ADDR16_OF_RAM(ram3000) + 512);
|
|
WriteRegWord(A1B1, 0x7E);
|
|
WriteRegWord(DAS1L, 0x180);
|
|
WriteRegWord(DAS10, 0);
|
|
WriteRegWord(A2A1H, 0);
|
|
WriteReg(VMAIN, 0x80);
|
|
WriteReg(MDMAEN, 2);
|
|
}
|
|
|
|
static void RestorePpuForMessageBox(void) { // 0x85861A
|
|
WriteRegWord(VMADDL, addr_unk_605880);
|
|
WriteRegWord(DMAP1, 0x1801);
|
|
WriteRegWord(A1T1L, ADDR16_OF_RAM(ram4000) + 256);
|
|
WriteRegWord(A1B1, 0x7E);
|
|
WriteRegWord(DAS1L, 0x700);
|
|
WriteRegWord(DAS10, 0);
|
|
WriteRegWord(A2A1H, 0);
|
|
WriteReg(VMAIN, 0x80);
|
|
WriteReg(MDMAEN, 2);
|
|
reg_HDMAEN = ram3000.msgbox.backup_of_enabled_hdma_channels;
|
|
WriteReg(HDMAEN, ram3000.msgbox.backup_of_enabled_hdma_channels);
|
|
gameplay_BG3SC = ram3000.misc.field_3E8[3];
|
|
gameplay_TM = reg_TM;
|
|
gameplay_CGWSEL = next_gameplay_CGWSEL;
|
|
gameplay_CGADSUB = next_gameplay_CGADSUB;
|
|
WriteReg(CGADD, 0x19);
|
|
WriteReg(CGDATA, palette_buffer[25]);
|
|
WriteReg(CGDATA, HIBYTE(palette_buffer[25]));
|
|
WriteReg(CGDATA, palette_buffer[26]);
|
|
WriteReg(CGDATA, HIBYTE(palette_buffer[26]));
|
|
}
|
|
|
|
static CoroutineRet OpenMessageBox_Async(void) { // 0x85844C
|
|
COROUTINE_BEGIN(coroutine_state_4, 0);
|
|
for (message_box_animation_y_radius = 0;; message_box_animation_y_radius += 512) {
|
|
COROUTINE_AWAIT(1, WaitForNMI_NoUpdate_Async());
|
|
HandleMusicQueue();
|
|
HandleSoundEffects();
|
|
MsgBoxMakeHdmaTable();
|
|
if (message_box_animation_y_radius == 0x1800)
|
|
break;
|
|
}
|
|
COROUTINE_END(0);
|
|
}
|
|
|
|
static CoroutineRet HandleMessageBoxInteraction_Async(void) { // 0x85846D
|
|
COROUTINE_BEGIN(coroutine_state_4, 0);
|
|
|
|
if (message_box_index == 23 || message_box_index == 28) {
|
|
save_confirmation_selection = 0;
|
|
while (1) {
|
|
do {
|
|
COROUTINE_AWAIT(1, WaitForNMI_NoUpdate_Async());
|
|
HandleMusicQueue();
|
|
HandleSoundEffects();
|
|
ReadJoypadInputs();
|
|
} while (!joypad1_newkeys);
|
|
if ((joypad1_newkeys & kButton_A) != 0)
|
|
break;
|
|
if ((joypad1_newkeys & kButton_B) != 0) {
|
|
save_confirmation_selection = 2;
|
|
goto GETOUT;
|
|
}
|
|
if ((joypad1_newkeys & (kButton_Select | kButton_Left | kButton_Right)) != 0) {
|
|
ToggleSaveConfirmationSelection();
|
|
QueueSfx1_Max6(0x37);
|
|
}
|
|
}
|
|
} else {
|
|
my_counter = 10;
|
|
if (message_box_index != 20 && message_box_index != 21 && message_box_index != 22 && message_box_index != 24)
|
|
my_counter = 360;
|
|
do {
|
|
COROUTINE_AWAIT(2, WaitForNMI_NoUpdate_Async());
|
|
HandleMusicQueue();
|
|
HandleSoundEffects();
|
|
} while (--my_counter);
|
|
do {
|
|
COROUTINE_AWAIT(3, WaitForNMI_NoUpdate_Async());
|
|
ReadJoypadInputs();
|
|
} while ((bug_fix_counter < 1 ? joypad1_newkeys : joypad1_lastkeys) == 0);
|
|
}
|
|
GETOUT:;
|
|
COROUTINE_END(0);
|
|
}
|
|
|
|
static CoroutineRet CloseMessageBox_Async(void) { // 0x858589
|
|
COROUTINE_BEGIN(coroutine_state_4, 0);
|
|
do {
|
|
COROUTINE_AWAIT(1, WaitForNMI_NoUpdate_Async());
|
|
HandleMusicQueue();
|
|
HandleSoundEffects();
|
|
MsgBoxMakeHdmaTable();
|
|
message_box_animation_y_radius -= 512;
|
|
} while ((message_box_animation_y_radius & 0x8000) == 0);
|
|
COROUTINE_END(0);
|
|
}
|
|
|
|
CoroutineRet DisplayMessageBox_Async(uint16 a) { // 0x858080
|
|
COROUTINE_BEGIN(coroutine_state_3, 0)
|
|
message_box_index = a;
|
|
CancelSoundEffects();
|
|
InitializePpuForMessageBoxes();
|
|
ClearMessageBoxBg3Tilemap();
|
|
InitializeMessageBox();
|
|
COROUTINE_AWAIT(2, OpenMessageBox_Async());
|
|
COROUTINE_AWAIT(3, HandleMessageBoxInteraction_Async());
|
|
COROUTINE_AWAIT(4, CloseMessageBox_Async());
|
|
|
|
if (message_box_index == 28 && save_confirmation_selection != 2) {
|
|
message_box_index = 24;
|
|
ClearMessageBoxBg3Tilemap();
|
|
QueueSfx1_Max6(0x2E);
|
|
|
|
my_counter = 160;
|
|
do {
|
|
HandleMusicQueue();
|
|
HandleSoundEffects();
|
|
COROUTINE_AWAIT(8, WaitForNMI_NoUpdate_Async());
|
|
} while (--my_counter);
|
|
|
|
InitializeMessageBox();
|
|
COROUTINE_AWAIT(5, OpenMessageBox_Async());
|
|
COROUTINE_AWAIT(6, HandleMessageBoxInteraction_Async());
|
|
COROUTINE_AWAIT(7, CloseMessageBox_Async());
|
|
message_box_index = 28;
|
|
}
|
|
ClearMessageBoxBg3Tilemap();
|
|
RestorePpuForMessageBox();
|
|
QueueSamusMovementSfx();
|
|
|
|
if (message_box_index == 20) {
|
|
game_state = kGameState_12_Pausing;
|
|
}
|
|
COROUTINE_END(0);
|
|
// else if (message_box_index == 28 || message_box_index == 23) {
|
|
// return save_confirmation_selection;
|
|
// }
|
|
// return 0;
|
|
}
|
|
|
|
int DisplayMessageBox_Poll(uint16 a) {
|
|
if (a == message_box_index) {
|
|
message_box_index = 0;
|
|
return save_confirmation_selection;
|
|
}
|
|
queued_message_box_index = a;
|
|
return -1;
|
|
}
|
|
|
|
void DisplayMessageBox(uint16 a) { // 0x858080
|
|
queued_message_box_index = a;
|
|
}
|