summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhuderlem <huderlem@gmail.com>2019-03-17 17:32:42 -0500
committerGitHub <noreply@github.com>2019-03-17 17:32:42 -0500
commit7154d2614d21c5a5931fc944e247059d49cda782 (patch)
tree414ed687f836521c1a966531e87122951c070083 /src
parent4ae8a52473a0e4842cf140bf0c59f0276125a896 (diff)
parente9a3cc6d51ce3818eed11de585f5084342450093 (diff)
Merge pull request #595 from Phlosioneer/move-tutor
Move tutor
Diffstat (limited to 'src')
-rw-r--r--src/battle_pyramid_bag.c12
-rw-r--r--src/battle_script_commands.c12
-rw-r--r--src/decoration.c2
-rw-r--r--src/egg_hatch.c2
-rw-r--r--src/field_screen_effect.c26
-rw-r--r--src/field_specials.c6
-rwxr-xr-xsrc/item_menu.c4
-rw-r--r--src/learn_move.c833
-rw-r--r--src/list_menu.c4
-rw-r--r--src/menu_specialized.c2094
-rw-r--r--src/move_relearner.c976
-rw-r--r--src/overworld.c2
-rwxr-xr-xsrc/party_menu.c9
-rw-r--r--src/player_pc.c8
-rw-r--r--src/pokeblock.c10
-rw-r--r--src/roulette.c2
-rw-r--r--src/secret_base.c4
-rwxr-xr-xsrc/shop.c2
-rw-r--r--src/strings.c30
-rw-r--r--src/trade.c2
-rw-r--r--src/use_pokeblock.c17
-rw-r--r--src/walda_phrase.c2
22 files changed, 3148 insertions, 911 deletions
diff --git a/src/battle_pyramid_bag.c b/src/battle_pyramid_bag.c
index 3b8cac14f..ee35ed45b 100644
--- a/src/battle_pyramid_bag.c
+++ b/src/battle_pyramid_bag.c
@@ -576,7 +576,7 @@ static void SetBagItemsListTemplate(void)
}
StringCopy(gPyramidBagResources->itemStrings[i], gText_CloseBag);
gPyramidBagResources->bagListItems[i].name = gPyramidBagResources->itemStrings[i];
- gPyramidBagResources->bagListItems[i].id = LIST_B_PRESSED;
+ gPyramidBagResources->bagListItems[i].id = LIST_CANCEL;
gMultiuseListMenuTemplate = gUnknown_0861F2C0;
gMultiuseListMenuTemplate.totalItems = gPyramidBagResources->listMenuCount;
gMultiuseListMenuTemplate.items = gPyramidBagResources->bagListItems;
@@ -607,7 +607,7 @@ static void PyramidBagMoveCursorFunc(s32 itemIndex, bool8 onInit, struct ListMen
if (gPyramidBagResources->unk814 == 0xFF)
{
sub_81C6FF8(gPyramidBagResources->unk815 ^ 1);
- if (itemIndex != LIST_B_PRESSED)
+ if (itemIndex != LIST_CANCEL)
ShowItemImage(gSaveBlock2Ptr->frontier.pyramidBag.itemId[gSaveBlock2Ptr->frontier.lvlMode][itemIndex], gPyramidBagResources->unk815);
else
ShowItemImage(0xFFFF, gPyramidBagResources->unk815);
@@ -619,7 +619,7 @@ static void PyramidBagMoveCursorFunc(s32 itemIndex, bool8 onInit, struct ListMen
static void PrintItemQuantity(u8 windowId, s32 itemIndex, u8 y)
{
s32 xAlign;
- if (itemIndex == LIST_B_PRESSED)
+ if (itemIndex == LIST_CANCEL)
return;
if (gPyramidBagResources->unk814 != 0xFF)
@@ -641,7 +641,7 @@ static void PrintItemQuantity(u8 windowId, s32 itemIndex, u8 y)
static void PrintItemDescription(s32 listMenuId)
{
const u8 *desc;
- if (listMenuId != LIST_B_PRESSED)
+ if (listMenuId != LIST_CANCEL)
{
desc = ItemId_GetDescription(gSaveBlock2Ptr->frontier.pyramidBag.itemId[gSaveBlock2Ptr->frontier.lvlMode][listMenuId]);
}
@@ -859,7 +859,7 @@ static void Task_HandlePyramidBagInput(u8 taskId)
{
case LIST_NOTHING_CHOSEN:
break;
- case LIST_B_PRESSED:
+ case LIST_CANCEL:
PlaySE(SE_SELECT);
gSpecialVar_ItemId = 0;
sub_81C5B14(taskId);
@@ -1293,7 +1293,7 @@ static void Task_ItemSwapHandleInput(u8 taskId)
{
case LIST_NOTHING_CHOSEN:
break;
- case LIST_B_PRESSED:
+ case LIST_CANCEL:
PlaySE(SE_SELECT);
if (gMain.newKeys & A_BUTTON)
PerformItemSwap(taskId);
diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c
index 025d694e4..0eb6dfec0 100644
--- a/src/battle_script_commands.c
+++ b/src/battle_script_commands.c
@@ -49,14 +49,12 @@
#include "field_specials.h"
#include "pokemon_summary_screen.h"
#include "pokenav.h"
+#include "menu_specialized.h"
extern struct MusicPlayerInfo gMPlayInfo_BGM;
extern const u8* const gBattleScriptsForMoveEffects[];
-// functions
-extern void sub_81D388C(struct Pokemon* mon, void* statStoreLocation); // pokenav.s
-
#define DEFENDER_IS_PROTECTED ((gProtectStructs[gBattlerTarget].protected) && (gBattleMoves[gCurrentMove].flags & FLAG_PROTECT_AFFECTED))
// this file's functions
@@ -6319,16 +6317,16 @@ static void sub_804F100(void)
{
struct StatsArray currentStats;
- sub_81D388C(&gPlayerParty[gBattleStruct->expGetterMonId], &currentStats);
- sub_81D3640(0xD, gBattleResources->statsBeforeLvlUp, &currentStats, 0xE, 0xD, 0xF);
+ GetMonLevelUpWindowStats(&gPlayerParty[gBattleStruct->expGetterMonId], &currentStats);
+ DrawLevelUpWindowPg1(0xD, gBattleResources->statsBeforeLvlUp, &currentStats, 0xE, 0xD, 0xF);
}
static void sub_804F144(void)
{
struct StatsArray currentStats;
- sub_81D388C(&gPlayerParty[gBattleStruct->expGetterMonId], &currentStats);
- sub_81D3784(0xD, &currentStats, 0xE, 0xD, 0xF);
+ GetMonLevelUpWindowStats(&gPlayerParty[gBattleStruct->expGetterMonId], &currentStats);
+ DrawLevelUpWindowPg2(0xD, &currentStats, 0xE, 0xD, 0xF);
}
static void sub_804F17C(void)
diff --git a/src/decoration.c b/src/decoration.c
index 47e3ae18c..3c8809c6a 100644
--- a/src/decoration.c
+++ b/src/decoration.c
@@ -941,7 +941,7 @@ void sub_812764C(u8 taskId)
{
case LIST_NOTHING_CHOSEN:
break;
- case LIST_B_PRESSED:
+ case LIST_CANCEL:
PlaySE(SE_SELECT);
SecretBasePC_SelectedDecorActions[data[11]][1](taskId);
break;
diff --git a/src/egg_hatch.c b/src/egg_hatch.c
index 00b67a5d9..fc559e001 100644
--- a/src/egg_hatch.c
+++ b/src/egg_hatch.c
@@ -469,7 +469,7 @@ static void Task_EggHatch(u8 taskID)
{
CleanupOverworldWindowsAndTilemaps();
SetMainCallback2(CB2_EggHatch_0);
- gFieldCallback = sub_80AF168;
+ gFieldCallback = FieldCallback_ReturnToEventScript2;
DestroyTask(taskID);
}
}
diff --git a/src/field_screen_effect.c b/src/field_screen_effect.c
index b6dcf212c..5769f44af 100644
--- a/src/field_screen_effect.c
+++ b/src/field_screen_effect.c
@@ -44,7 +44,7 @@ static void task0A_fade_n_map_maybe(u8);
static void sub_808115C(u8);
static void palette_bg_faded_fill_white(void);
static void sub_80AF438(u8);
-static bool32 sub_80AF71C(void);
+static bool32 WaitForWeatherFadeIn(void);
static void task0A_mpl_807E31C(u8 taskId);
static void sub_80AFA0C(u8 taskId);
static void sub_80AFA88(u8 taskId);
@@ -119,7 +119,7 @@ static void sub_80AF0F4(u8 arg)
static void task0A_nop_for_a_while(u8 taskId)
{
- if (sub_80AF71C() == TRUE)
+ if (WaitForWeatherFadeIn() == TRUE)
DestroyTask(taskId);
}
@@ -133,14 +133,14 @@ void sub_80AF128(void)
static void task0A_asap_script_env_2_enable_and_set_ctx_running(u8 taskID)
{
- if (sub_80AF71C() == TRUE)
+ if (WaitForWeatherFadeIn() == TRUE)
{
DestroyTask(taskID);
EnableBothScriptContexts();
}
}
-void sub_80AF168(void)
+void FieldCallback_ReturnToEventScript2(void)
{
ScriptContext2_Enable();
Overworld_PlaySpecialMapMusic();
@@ -173,7 +173,7 @@ static void task_mpl_807DD60(u8 taskId)
}
break;
case 2:
- if (sub_80AF71C() == TRUE)
+ if (WaitForWeatherFadeIn() == TRUE)
{
ScriptContext2_Disable();
DestroyTask(taskId);
@@ -213,7 +213,7 @@ static void sub_80AF234(u8 taskId)
}
break;
case 2:
- if (sub_80AF71C() == TRUE)
+ if (WaitForWeatherFadeIn() == TRUE)
{
sub_8009F18();
ScriptContext2_Disable();
@@ -333,7 +333,7 @@ static void sub_80AF438(u8 taskId)
task->data[0] = 1;
break;
case 1:
- if (sub_80AF71C())
+ if (WaitForWeatherFadeIn())
{
u8 eventObjId;
sub_80AF0F4(1);
@@ -381,7 +381,7 @@ static void task_map_chg_seq_0807E20C(u8 taskId)
task->data[0] = 1;
break;
case 1:
- if (sub_80AF71C())
+ if (WaitForWeatherFadeIn())
{
u8 eventObjId;
sub_80AF0F4(1);
@@ -414,7 +414,7 @@ static void task_map_chg_seq_0807E2CC(u8 taskId)
gTasks[taskId].data[0]++;
break;
case 1:
- if (sub_80AF71C())
+ if (WaitForWeatherFadeIn())
{
UnfreezeEventObjects();
ScriptContext2_Disable();
@@ -426,7 +426,7 @@ static void task_map_chg_seq_0807E2CC(u8 taskId)
static void sub_80AF660(u8 taskId)
{
- if (sub_80AF71C() == TRUE)
+ if (WaitForWeatherFadeIn() == TRUE)
{
DestroyTask(taskId);
CreateTask(sub_809FA34, 80);
@@ -448,7 +448,7 @@ bool8 sub_80AF6A4(void)
static void task_mpl_807E3C8(u8 taskId)
{
- if (sub_80AF71C() == 1)
+ if (WaitForWeatherFadeIn() == 1)
{
ScriptContext2_Disable();
DestroyTask(taskId);
@@ -476,7 +476,7 @@ static bool32 PaletteFadeActive(void)
return gPaletteFade.active;
}
-static bool32 sub_80AF71C(void)
+static bool32 WaitForWeatherFadeIn(void)
{
if (IsWeatherNotFadingIn() == TRUE)
return TRUE;
@@ -1007,7 +1007,7 @@ static void task0A_mpl_807E31C(u8 taskId)
gTasks[taskId].data[0]++;
break;
case 1:
- if (sub_80AF71C() && sub_808D1B4() != TRUE)
+ if (WaitForWeatherFadeIn() && sub_808D1B4() != TRUE)
{
UnfreezeEventObjects();
ScriptContext2_Disable();
diff --git a/src/field_specials.c b/src/field_specials.c
index 436b06f53..2ae494dad 100644
--- a/src/field_specials.c
+++ b/src/field_specials.c
@@ -2610,7 +2610,7 @@ static void sub_813A4EC(u8 taskId)
{
case LIST_NOTHING_CHOSEN:
break;
- case LIST_B_PRESSED:
+ case LIST_CANCEL:
gSpecialVar_Result = 0x7F;
PlaySE(SE_SELECT);
sub_813A570(taskId);
@@ -2690,10 +2690,10 @@ static void sub_813A664(u8 taskId)
static void sub_813A694(u8 taskId)
{
static const struct ScrollArrowsTemplate gUnknown_085B3030 = {
- .firstArrowType = 2,
+ .firstArrowType = SCROLL_ARROW_UP,
.firstX = 0,
.firstY = 0,
- .secondArrowType = 3,
+ .secondArrowType = SCROLL_ARROW_DOWN,
.secondX = 0,
.secondY = 0,
.fullyUpThreshold = 0,
diff --git a/src/item_menu.c b/src/item_menu.c
index 5738757bd..81bc120a8 100755
--- a/src/item_menu.c
+++ b/src/item_menu.c
@@ -1107,7 +1107,7 @@ void Task_BagMenu(u8 taskId)
{
case LIST_NOTHING_CHOSEN:
break;
- case LIST_B_PRESSED:
+ case LIST_CANCEL:
if (gUnknown_0203CE58.location == 5)
{
PlaySE(SE_HAZURE);
@@ -1323,7 +1323,7 @@ void sub_81AC3C0(u8 taskId)
{
case LIST_NOTHING_CHOSEN:
break;
- case LIST_B_PRESSED:
+ case LIST_CANCEL:
PlaySE(SE_SELECT);
if (gMain.newKeys & A_BUTTON)
sub_81AC498(taskId);
diff --git a/src/learn_move.c b/src/learn_move.c
deleted file mode 100644
index 879acff6d..000000000
--- a/src/learn_move.c
+++ /dev/null
@@ -1,833 +0,0 @@
-#include "global.h"
-#include "main.h"
-#include "battle.h"
-#include "bg.h"
-#include "contest_effect.h"
-#include "data2.h"
-#include "event_data.h"
-#include "field_screen_effect.h"
-#include "gpu_regs.h"
-#include "learn_move.h"
-#include "list_menu.h"
-#include "alloc.h"
-#include "menu.h"
-#include "menu_helpers.h"
-#include "overworld.h"
-#include "palette.h"
-#include "pokemon_summary_screen.h"
-#include "pokenav.h"
-#include "script.h"
-#include "sound.h"
-#include "sprite.h"
-#include "string_util.h"
-#include "strings.h"
-#include "task.h"
-#include "constants/rgb.h"
-#include "constants/songs.h"
-
-static EWRAM_DATA struct
-{
- u8 state;
- u8 spriteIds[16]; /*0x001*/
- u16 movesToLearn[4]; /*0x012*/
- u8 filler1A[0x44 - 0x1A]; /*0x01A*/
- u8 partyMon; /*0x044*/
- u8 moveSlot; /*0x045*/
- struct ListMenuItem menuItems[20]; /*0x048*/
- u8 fillerE8[0x110 - 0xE8]; /*0x0E8*/
- u8 numMenuChoices; /*0x110*/
- u8 numToShowAtOnce; /*0x111*/
- u8 listMenuTask; /*0x112*/
- u8 scrollArrowTaskId1; /*0x113*/
- u8 scrollArrowTaskId2; /*0x114*/
- u16 scrollOffset; /*0x116*/
-} *sLearnMoveStruct = {0};
-
-static EWRAM_DATA struct {
- u16 listOffset;
- u16 listRow;
- u8 showContestInfo;
-} sLearnMoveStruct2 = {0};
-
-const u16 gUnknown_085CE9F8[] = INCBIN_U16("graphics/interface/ui_learn_move.gbapal");
-const u8 gUnknown_085CEA18[] = INCBIN_U8("graphics/interface/ui_learn_move.4bpp");
-
-const struct OamData gUnknown_085CEB98 =
-{
- .y = 0,
- .affineMode = 0,
- .objMode = ST_OAM_OBJ_NORMAL,
- .mosaic = 0,
- .bpp = ST_OAM_4BPP,
- .shape = ST_OAM_SQUARE,
- .x = 0,
- .matrixNum = 0,
- .size = 0,
- .tileNum = 0,
- .priority = 0,
- .paletteNum = 0,
- .affineParam = 0,
-};
-
-const struct OamData gUnknown_085CEBA0 =
-{
- .y = 0,
- .affineMode = 0,
- .objMode = ST_OAM_OBJ_NORMAL,
- .mosaic = 0,
- .bpp = ST_OAM_4BPP,
- .shape = ST_OAM_V_RECTANGLE,
- .x = 0,
- .matrixNum = 0,
- .size = 0,
- .tileNum = 0,
- .priority = 0,
- .paletteNum = 0,
- .affineParam = 0,
-};
-
-const struct OamData gUnknown_085CEBA8 =
-{
- .y = 0,
- .affineMode = 0,
- .objMode = ST_OAM_OBJ_NORMAL,
- .mosaic = 0,
- .bpp = ST_OAM_4BPP,
- .shape = ST_OAM_H_RECTANGLE,
- .x = 0,
- .matrixNum = 0,
- .size = 0,
- .tileNum = 0,
- .priority = 0,
- .paletteNum = 0,
- .affineParam = 0,
-};
-
-const struct SpriteSheet gUnknown_085CEBB0 =
-{
- .data = gUnknown_085CEA18,
- .size = 0x180,
- .tag = 5525
-};
-
-const struct SpritePalette gUnknown_085CEBB8 =
-{
- .data = gUnknown_085CE9F8,
- .tag = 5526
-};
-
-const struct ScrollArrowsTemplate gUnknown_085CEBC0 =
-{
- .firstArrowType = 0,
- .firstX = 27,
- .firstY = 16,
- .secondArrowType = 1,
- .secondX = 117,
- .secondY = 16,
- .fullyUpThreshold = -1,
- .fullyDownThreshold = -1,
- .tileTag = 5325,
- .palTag = 5325,
- .palNum = 0,
-};
-
-const struct ScrollArrowsTemplate gUnknown_085CEBD0 =
-{
- .firstArrowType = 2,
- .firstX = 192,
- .firstY = 8,
- .secondArrowType = 3,
- .secondX = 192,
- .secondY = 104,
- .fullyUpThreshold = 0,
- .fullyDownThreshold = 0,
- .tileTag = 5425,
- .palTag = 5425,
- .palNum = 0,
-};
-
-const union AnimCmd gUnknown_085CEBE0[] =
-{
- ANIMCMD_FRAME(8, 5, FALSE, FALSE),
- ANIMCMD_END
-};
-
-const union AnimCmd gUnknown_085CEBE8[] =
-{
- ANIMCMD_FRAME(9, 5, FALSE, FALSE),
- ANIMCMD_END
-};
-
-const union AnimCmd gUnknown_085CEBF0[] =
-{
- ANIMCMD_FRAME(10, 5, FALSE, FALSE),
- ANIMCMD_END
-};
-
-const union AnimCmd gUnknown_085CEBF8[] =
-{
- ANIMCMD_FRAME(11, 5, FALSE, FALSE),
- ANIMCMD_END
-};
-
-const union AnimCmd *const gUnknown_085CEC00[] =
-{
- gUnknown_085CEBE0,
- gUnknown_085CEBE8,
- gUnknown_085CEBF0,
- gUnknown_085CEBF8,
-};
-
-const struct SpriteTemplate gUnknown_085CEC10 =
-{
- .tileTag = 5525,
- .paletteTag = 5526,
- .oam = &gUnknown_085CEB98,
- .anims = gUnknown_085CEC00,
- .images = NULL,
- .affineAnims = gDummySpriteAffineAnimTable,
- .callback = SpriteCallbackDummy
-};
-
-const struct BgTemplate gUnknown_085CEC28[] =
-{
- {
- .bg = 0,
- .charBaseIndex = 0,
- .mapBaseIndex = 31,
- .screenSize = 0,
- .paletteMode = 0,
- .priority = 0,
- .baseTile = 0,
- },
- {
- .bg = 1,
- .charBaseIndex = 0,
- .mapBaseIndex = 30,
- .screenSize = 0,
- .paletteMode = 0,
- .priority = 1,
- .baseTile = 0,
- },
-};
-
-static void LearnMoveMain(void);
-static void CreateMenuItemsList(void);
-static void CreateHearts(void);
-static void CB2_Main(void);
-static void Task_WaitForFadeOut(u8 taskId);
-static void CB2_InitLearnMove(void);
-static void CB2_InitLearnMoveReturnFromSelectMove(void);
-static void InitBGs(void);
-static void AddScrollArrows(void);
-static void HandleInput(u8);
-static void ShowTeachMoveText(u8);
-static s32 GetCurrentItemId(void);
-static void FreeListMenuResources(void);
-static void RemoveScrollArrows(void);
-static void HideSpritesAndPrintTeachText(bool8);
-
-static void VBlankCB_LearnMove(void)
-{
- LoadOam();
- ProcessSpriteCopyRequests();
- TransferPlttBuffer();
-}
-
-void TeachMoveTutorMove(void)
-{
- ScriptContext2_Enable();
- CreateTask(Task_WaitForFadeOut, 0xA);
- BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, 0);
-}
-
-static void Task_WaitForFadeOut(u8 taskId)
-{
- if (!gPaletteFade.active)
- {
- SetMainCallback2(CB2_InitLearnMove);
- gFieldCallback = sub_80AF168;
- DestroyTask(taskId);
- }
-}
-
-static void CB2_InitLearnMove(void)
-{
- ResetSpriteData();
- FreeAllSpritePalettes();
- ResetTasks();
- clear_scheduled_bg_copies_to_vram();
- sLearnMoveStruct = AllocZeroed(sizeof(*sLearnMoveStruct));
- sLearnMoveStruct->partyMon = gSpecialVar_0x8004;
- SetVBlankCallback(VBlankCB_LearnMove);
-
- InitBGs();
- sub_81D2824(0);
-
- sLearnMoveStruct2.listOffset = 0;
- sLearnMoveStruct2.listRow = 0;
- sLearnMoveStruct2.showContestInfo = FALSE;
-
- CreateMenuItemsList();
-
- LoadSpriteSheet(&gUnknown_085CEBB0);
- LoadSpritePalette(&gUnknown_085CEBB8);
- CreateHearts();
-
- sLearnMoveStruct->listMenuTask = ListMenuInit(&gMultiuseListMenuTemplate, sLearnMoveStruct2.listOffset, sLearnMoveStruct2.listRow);
- FillPalette(RGB_BLACK, 0, 2);
- SetMainCallback2(CB2_Main);
-}
-
-static void CB2_InitLearnMoveReturnFromSelectMove(void)
-{
- ResetSpriteData();
- FreeAllSpritePalettes();
- ResetTasks();
- clear_scheduled_bg_copies_to_vram();
- sLearnMoveStruct = AllocZeroed(sizeof(*sLearnMoveStruct));
- sLearnMoveStruct->state = 28;
- sLearnMoveStruct->partyMon = gSpecialVar_0x8004;
- sLearnMoveStruct->moveSlot = gSpecialVar_0x8005;
- SetVBlankCallback(VBlankCB_LearnMove);
-
- InitBGs();
- sub_81D2824(sLearnMoveStruct2.showContestInfo);
- CreateMenuItemsList();
-
- LoadSpriteSheet(&gUnknown_085CEBB0);
- LoadSpritePalette(&gUnknown_085CEBB8);
- CreateHearts();
-
- sLearnMoveStruct->listMenuTask = ListMenuInit(&gMultiuseListMenuTemplate, sLearnMoveStruct2.listOffset, sLearnMoveStruct2.listRow);
- FillPalette(RGB_BLACK, 0, 2);
- SetMainCallback2(CB2_Main);
-}
-
-static void InitBGs(void)
-{
- ResetVramOamAndBgCntRegs();
- ResetBgsAndClearDma3BusyFlags(0);
- InitBgsFromTemplates(0, gUnknown_085CEC28, 2);
- ResetAllBgsCoordinates();
- SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 |
- DISPCNT_OBJ_1D_MAP |
- DISPCNT_OBJ_ON);
- ShowBg(0);
- ShowBg(1);
- SetGpuReg(REG_OFFSET_BLDCNT, 0);
-}
-
-static void CB2_Main(void)
-{
- LearnMoveMain();
- RunTasks();
- AnimateSprites();
- BuildOamBuffer();
- do_scheduled_bg_tilemap_copies_to_vram();
- UpdatePaletteFade();
-}
-
-static void sub_816084C(const u8 *src)
-{
- StringExpandPlaceholders(gStringVar4, src);
- sub_81D2BF4(gStringVar4);
-}
-
-static void LearnMoveMain(void)
-{
- switch (sLearnMoveStruct->state)
- {
- case 0:
- sLearnMoveStruct->state++;
- HideSpritesAndPrintTeachText(FALSE);
- BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK);
- break;
- case 1:
- if (!gPaletteFade.active)
- {
- sLearnMoveStruct->state = 4;
- }
- break;
- case 2:
- sLearnMoveStruct->state++;
- break;
- case 3:
- HideSpritesAndPrintTeachText(FALSE);
- sLearnMoveStruct->state++;
- AddScrollArrows();
- break;
- case 4:
- HandleInput(FALSE);
- return;
- case 5:
- ShowTeachMoveText(FALSE);
- sLearnMoveStruct->state++;
- AddScrollArrows();
- break;
- case 6:
- HandleInput(TRUE);
- break;
- case 8:
- if (!sub_81D2C3C())
- {
- sub_81D2C50();
- sLearnMoveStruct->state++;
- }
- break;
- case 9:
- {
- s8 selection = Menu_ProcessInputNoWrapClearOnChoose();
-
- if (selection == 0)
- {
- if (GiveMoveToMon(&gPlayerParty[sLearnMoveStruct->partyMon], GetCurrentItemId()) != 0xFFFF)
- {
- sub_816084C(gText_PkmnLearnedMove4);
- gSpecialVar_0x8004 = 1;
- sLearnMoveStruct->state = 31;
- }
- else
- {
- sLearnMoveStruct->state = 16;
- }
- }
- else if (selection == -1 || selection == 1)
- {
- if (sLearnMoveStruct2.showContestInfo == FALSE)
- {
- sLearnMoveStruct->state = 3;
- }
- else if (sLearnMoveStruct2.showContestInfo == TRUE)
- {
- sLearnMoveStruct->state = 5;
- }
- }
- }
- break;
- case 12:
- if (!sub_81D2C3C())
- {
- sub_81D2C50();
- sLearnMoveStruct->state++;
- }
- break;
- case 13:
- {
- s8 selection = Menu_ProcessInputNoWrapClearOnChoose();
-
- if (selection == 0)
- {
- gSpecialVar_0x8004 = selection;
- sLearnMoveStruct->state = 14;
- }
- else if (selection == -1 || selection == 1)
- {
- if (sLearnMoveStruct2.showContestInfo == FALSE)
- {
- sLearnMoveStruct->state = 3;
- }
- else if (sLearnMoveStruct2.showContestInfo == TRUE)
- {
- sLearnMoveStruct->state = 5;
- }
- }
- }
- break;
- case 16:
- sub_816084C(gText_PkmnTryingToLearnMove);
- sLearnMoveStruct->state++;
- break;
- case 17:
- if (!sub_81D2C3C())
- {
- sub_81D2C50();
- sLearnMoveStruct->state = 18;
- }
- break;
- case 18:
- {
- s8 var = Menu_ProcessInputNoWrapClearOnChoose();
-
- if (var == 0)
- {
- sub_816084C(gText_WhichMoveToForget2);
- sLearnMoveStruct->state = 19;
- }
- else if (var == -1 || var == 1)
- {
- sLearnMoveStruct->state = 24;
- }
- }
- break;
- case 24:
- StringCopy(gStringVar2, gMoveNames[GetCurrentItemId()]);
- sub_816084C(gText_StopTryingToTeachMove);
- sLearnMoveStruct->state++;
- break;
- case 25:
- if (!sub_81D2C3C())
- {
- sub_81D2C50();
- sLearnMoveStruct->state++;
- }
- break;
- case 26:
- {
- s8 var = Menu_ProcessInputNoWrapClearOnChoose();
-
- if (var == 0)
- {
- sLearnMoveStruct->state = 27;
- }
- else if (var == -1 || var == 1)
- {
- // What's the point? It gets set to 16, anyway.
- if (sLearnMoveStruct2.showContestInfo == FALSE)
- {
- sLearnMoveStruct->state = 3;
- }
- else if (sLearnMoveStruct2.showContestInfo == TRUE)
- {
- sLearnMoveStruct->state = 5;
- }
- sLearnMoveStruct->state = 16;
- }
- }
- break;
- case 27:
- if (!sub_81D2C3C())
- {
- FillWindowPixelBuffer(3, PIXEL_FILL(1));
- if (sLearnMoveStruct2.showContestInfo == FALSE)
- {
- sLearnMoveStruct->state = 3;
- }
- else if (sLearnMoveStruct2.showContestInfo == TRUE)
- {
- sLearnMoveStruct->state = 5;
- }
- }
- break;
- case 19:
- if (!sub_81D2C3C())
- {
- sLearnMoveStruct->state = 20;
- BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK);
- }
- break;
- case 20:
- if (!gPaletteFade.active)
- {
- ShowSelectMovePokemonSummaryScreen(gPlayerParty, sLearnMoveStruct->partyMon, gPlayerPartyCount - 1, CB2_InitLearnMoveReturnFromSelectMove, GetCurrentItemId());
- FreeListMenuResources();
- }
- break;
- case 21:
- if (!sub_81D2C3C())
- {
- sLearnMoveStruct->state = 14;
- }
- break;
- case 22:
- BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK);
- break;
- case 14:
- BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK);
- sLearnMoveStruct->state++;
- break;
- case 15:
- if (!gPaletteFade.active)
- {
- FreeListMenuResources();
- SetMainCallback2(CB2_ReturnToField);
- }
- break;
- case 28:
- BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK);
- sLearnMoveStruct->state++;
- if (sLearnMoveStruct2.showContestInfo == FALSE)
- {
- HideSpritesAndPrintTeachText(TRUE);
- }
- else if (sLearnMoveStruct2.showContestInfo == TRUE)
- {
- ShowTeachMoveText(TRUE);
- }
- RemoveScrollArrows();
- CopyWindowToVram(3, 2);
- break;
- case 29:
- if (!gPaletteFade.active)
- {
- if (sLearnMoveStruct->moveSlot == MAX_MON_MOVES)
- {
- sLearnMoveStruct->state = 24;
- }
- else
- {
- u16 moveId = GetMonData(&gPlayerParty[sLearnMoveStruct->partyMon], MON_DATA_MOVE1 + sLearnMoveStruct->moveSlot);
-
- StringCopy(gStringVar3, gMoveNames[moveId]);
- RemoveMonPPBonus(&gPlayerParty[sLearnMoveStruct->partyMon], sLearnMoveStruct->moveSlot);
- SetMonMoveSlot(&gPlayerParty[sLearnMoveStruct->partyMon], GetCurrentItemId(), sLearnMoveStruct->moveSlot);
- StringCopy(gStringVar2, gMoveNames[GetCurrentItemId()]);
- sub_816084C(gText_12AndPoof);
- sLearnMoveStruct->state = 30;
- gSpecialVar_0x8004 = 1;
- }
- }
- break;
- case 30:
- if (!sub_81D2C3C())
- {
- sub_816084C(gText_PkmnForgotMoveAndLearnedNew);
- sLearnMoveStruct->state = 31;
- PlayFanfare(MUS_FANFA1);
- }
- break;
- case 31:
- if (!sub_81D2C3C())
- {
- PlayFanfare(MUS_FANFA1);
- sLearnMoveStruct->state = 32;
- }
- break;
- case 32:
- if (IsFanfareTaskInactive())
- {
- sLearnMoveStruct->state = 33;
- }
- break;
- case 33:
- if (gMain.newKeys & A_BUTTON)
- {
- PlaySE(SE_SELECT);
- sLearnMoveStruct->state = 14;
- }
- break;
- }
-}
-
-static void FreeListMenuResources(void)
-{
- RemoveScrollArrows();
- DestroyListMenuTask(sLearnMoveStruct->listMenuTask, &sLearnMoveStruct2.listOffset, &sLearnMoveStruct2.listRow);
- FreeAllWindowBuffers();
- FREE_AND_SET_NULL(sLearnMoveStruct);
- ResetSpriteData();
- FreeAllSpritePalettes();
-}
-
-static void HideSpritesAndPrintTeachText(bool8 a)
-{
- s32 i;
-
- for (i = 0; i < 16; i++)
- {
- gSprites[sLearnMoveStruct->spriteIds[i]].invisible = TRUE;
- }
-
- if (!a)
- {
- StringExpandPlaceholders(gStringVar4, gText_TeachWhichMoveToPkmn);
- FillWindowPixelBuffer(3, PIXEL_FILL(1));
- AddTextPrinterParameterized(3, 1, gStringVar4, 0, 1, 0, NULL);
- }
-}
-
-static void HandleInput(bool8 showContest)
-{
- s32 itemId = ListMenu_ProcessInput(sLearnMoveStruct->listMenuTask);
- ListMenuGetScrollAndRow(sLearnMoveStruct->listMenuTask, &sLearnMoveStruct2.listOffset, &sLearnMoveStruct2.listRow);
-
- switch (itemId)
- {
- case LIST_NOTHING_CHOSEN:
- if (!(gMain.newKeys & (DPAD_LEFT | DPAD_RIGHT)) && !GetLRKeysState())
- {
- break;
- }
-
- PlaySE(SE_SELECT);
-
- if (showContest == FALSE)
- {
- PutWindowTilemap(1);
- sLearnMoveStruct->state = 5;
- sLearnMoveStruct2.showContestInfo = TRUE;
- }
- else
- {
- PutWindowTilemap(0);
- sLearnMoveStruct->state = 3;
- sLearnMoveStruct2.showContestInfo = FALSE;
- }
-
- schedule_bg_copy_tilemap_to_vram(1);
- ShowHideHearts(GetCurrentItemId());
- break;
- case LIST_B_PRESSED:
- PlaySE(SE_SELECT);
- RemoveScrollArrows();
- sLearnMoveStruct->state = 12;
- StringExpandPlaceholders(gStringVar4, gText_GiveUpTeachingNewMove);
- sub_81D2BF4(gStringVar4);
- break;
- default:
- PlaySE(SE_SELECT);
- RemoveScrollArrows();
- sLearnMoveStruct->state = 8;
- StringCopy(gStringVar2, gMoveNames[itemId]);
- StringExpandPlaceholders(gStringVar4, gText_TeachX);
- sub_81D2BF4(gStringVar4);
- break;
- }
-}
-
-static s32 GetCurrentItemId(void)
-{
- return sLearnMoveStruct->menuItems[sLearnMoveStruct2.listRow + sLearnMoveStruct2.listOffset].id;
-}
-
-static void ShowTeachMoveText(bool8 showContest)
-{
- if (showContest == FALSE)
- {
- StringExpandPlaceholders(gStringVar4, gText_TeachWhichMoveToPkmn);
- FillWindowPixelBuffer(3, PIXEL_FILL(1));
- AddTextPrinterParameterized(3, 1, gStringVar4, 0, 1, 0, NULL);
- }
-}
-
-static void CreateHearts(void)
-{
- int i;
-
- sLearnMoveStruct->scrollArrowTaskId2 = -1;
- sLearnMoveStruct->scrollArrowTaskId1 = -1;
- AddScrollArrows();
-
- for (i = 0; i < 8; i++)
- {
- sLearnMoveStruct->spriteIds[i] = CreateSprite(&gUnknown_085CEC10, (i - (i / 4) * 4) * 8 + 104, (i / 4) * 8 + 36, 0);
- }
-
- for (i = 0; i < 8; i++)
- {
- sLearnMoveStruct->spriteIds[i + 8] = CreateSprite(&gUnknown_085CEC10, (i - (i / 4) * 4) * 8 + 104, (i / 4) * 8 + 52, 0);
- StartSpriteAnim(&gSprites[sLearnMoveStruct->spriteIds[i + 8]], 2);
- }
-
- for (i = 0; i < 16; i++)
- {
- gSprites[sLearnMoveStruct->spriteIds[i]].invisible = TRUE;
- }
-}
-
-static void AddScrollArrows(void)
-{
- if (sLearnMoveStruct->scrollArrowTaskId2 == 0xFF)
- {
- sLearnMoveStruct->scrollArrowTaskId2 = AddScrollIndicatorArrowPair(&gUnknown_085CEBC0, &sLearnMoveStruct->scrollOffset);
- }
-
- if (sLearnMoveStruct->scrollArrowTaskId1 == 0xFF)
- {
- gTempScrollArrowTemplate = gUnknown_085CEBD0;
- gTempScrollArrowTemplate.fullyDownThreshold = sLearnMoveStruct->numMenuChoices - sLearnMoveStruct->numToShowAtOnce;
- sLearnMoveStruct->scrollArrowTaskId1 = AddScrollIndicatorArrowPair(&gTempScrollArrowTemplate, &sLearnMoveStruct2.listOffset);
- }
-}
-
-static void RemoveScrollArrows(void)
-{
- if (sLearnMoveStruct->scrollArrowTaskId2 != 0xFF)
- {
- RemoveScrollIndicatorArrowPair(sLearnMoveStruct->scrollArrowTaskId2);
- sLearnMoveStruct->scrollArrowTaskId2 = 0xFF;
- }
-
- if (sLearnMoveStruct->scrollArrowTaskId1 != 0xFF)
- {
- RemoveScrollIndicatorArrowPair(sLearnMoveStruct->scrollArrowTaskId1);
- sLearnMoveStruct->scrollArrowTaskId1 = 0xFF;
- }
-}
-
-static void CreateMenuItemsList(void)
-{
- s32 i;
- u8 nickname[POKEMON_NAME_LENGTH + 1];
-
- sLearnMoveStruct->numMenuChoices = GetMoveRelearnerMoves(&gPlayerParty[sLearnMoveStruct->partyMon], sLearnMoveStruct->movesToLearn);
-
- for (i = 0; i < sLearnMoveStruct->numMenuChoices; i++)
- {
- sLearnMoveStruct->menuItems[i].name = gMoveNames[sLearnMoveStruct->movesToLearn[i]];
- sLearnMoveStruct->menuItems[i].id = sLearnMoveStruct->movesToLearn[i];
- }
-
- GetMonData(&gPlayerParty[sLearnMoveStruct->partyMon], MON_DATA_NICKNAME, nickname);
- StringCopy10(gStringVar1, nickname);
- sLearnMoveStruct->menuItems[sLearnMoveStruct->numMenuChoices].name = gText_Cancel;
- sLearnMoveStruct->menuItems[sLearnMoveStruct->numMenuChoices].id = LIST_B_PRESSED;
- sLearnMoveStruct->numMenuChoices++;
- sLearnMoveStruct->numToShowAtOnce = sub_81D28C8(sLearnMoveStruct->menuItems, sLearnMoveStruct->numMenuChoices);
-}
-
-void ShowHideHearts(s32 item)
-{
- u16 numHearts;
- u16 i;
-
- if (!sLearnMoveStruct2.showContestInfo || item == LIST_B_PRESSED)
- {
- for (i = 0; i < 16; i++)
- {
- gSprites[sLearnMoveStruct->spriteIds[i]].invisible = TRUE;
- }
- }
- else
- {
- numHearts = (u8)(gContestEffects[gContestMoves[item].effect].appeal / 10);
-
- if (numHearts == 0xFF)
- {
- numHearts = 0;
- }
-
- for (i = 0; i < 8; i++)
- {
- if (i < numHearts)
- {
- StartSpriteAnim(&gSprites[sLearnMoveStruct->spriteIds[i]], 1);
- }
- else
- {
- StartSpriteAnim(&gSprites[sLearnMoveStruct->spriteIds[i]], 0);
- }
- gSprites[sLearnMoveStruct->spriteIds[i]].invisible = FALSE;
- }
-
- numHearts = (u8)(gContestEffects[gContestMoves[item].effect].jam / 10);
-
- if (numHearts == 0xFF)
- {
- numHearts = 0;
- }
-
- for (i = 0; i < 8; i++)
- {
- if (i < numHearts)
- {
- StartSpriteAnim(&gSprites[sLearnMoveStruct->spriteIds[i + 8]], 3);
- }
- else
- {
- StartSpriteAnim(&gSprites[sLearnMoveStruct->spriteIds[i + 8]], 2);
- }
- gSprites[sLearnMoveStruct->spriteIds[i + 8]].invisible = FALSE;
- }
- }
-}
diff --git a/src/list_menu.c b/src/list_menu.c
index a5786754c..57bcc5c4f 100644
--- a/src/list_menu.c
+++ b/src/list_menu.c
@@ -341,7 +341,7 @@ s32 DoMysteryGiftListMenu(struct WindowTemplate *windowTemplate, struct ListMenu
}
if (gMain.newKeys & B_BUTTON)
{
- sMysteryGiftLinkMenu.currItemId = LIST_B_PRESSED;
+ sMysteryGiftLinkMenu.currItemId = LIST_CANCEL;
sMysteryGiftLinkMenu.state = 2;
}
if (sMysteryGiftLinkMenu.state == 2)
@@ -416,7 +416,7 @@ s32 ListMenu_ProcessInput(u8 listTaskId)
}
else if (gMain.newKeys & B_BUTTON)
{
- return LIST_B_PRESSED;
+ return LIST_CANCEL;
}
else if (gMain.newAndRepeatedKeys & DPAD_UP)
{
diff --git a/src/menu_specialized.c b/src/menu_specialized.c
new file mode 100644
index 000000000..8371c7a70
--- /dev/null
+++ b/src/menu_specialized.c
@@ -0,0 +1,2094 @@
+#include "global.h"
+#include "alloc.h"
+#include "battle_main.h"
+#include "contest_effect.h"
+#include "gpu_regs.h"
+#include "menu.h"
+#include "international_string_util.h"
+#include "menu.h"
+#include "menu_specialized.h"
+#include "move_relearner.h"
+#include "palette.h"
+#include "player_pc.h"
+#include "pokemon_summary_screen.h"
+#include "scanline_effect.h"
+#include "sound.h"
+#include "strings.h"
+#include "string_util.h"
+#include "text_window.h"
+#include "trig.h"
+#include "window.h"
+#include "constants/songs.h"
+#include "gba/io_reg.h"
+
+EWRAM_DATA static u8 sUnknown_0203CF48[3] = {0};
+EWRAM_DATA static struct ListMenuItem *sUnknown_0203CF4C = NULL;
+
+static void sub_81D1E7C(s32 itemIndex, bool8 onInit, struct ListMenu *list);
+static void sub_81D24A4(struct UnknownStruct_81D1ED4 *a0);
+static void sub_81D2634(struct UnknownStruct_81D1ED4 *a0);
+static void MoveRelearnerCursorCallback(s32 itemIndex, bool8 onInit, struct ListMenu *list);
+static void nullsub_79(void);
+
+static const struct WindowTemplate sUnknown_086253E8[] =
+{
+ {
+ .bg = 0,
+ .tilemapLeft = 1,
+ .tilemapTop = 1,
+ .width = 8,
+ .height = 2,
+ .paletteNum = 0xF,
+ .baseBlock = 0x8
+ },
+ {
+ .bg = 0,
+ .tilemapLeft = 21,
+ .tilemapTop = 1,
+ .width = 8,
+ .height = 18,
+ .paletteNum = 0xF,
+ .baseBlock = 0x18
+ },
+ {
+ .bg = 0,
+ .tilemapLeft = 1,
+ .tilemapTop = 1,
+ .width = 11,
+ .height = 8,
+ .paletteNum = 0xF,
+ .baseBlock = 0x18
+ }
+};
+
+static const u8 sUnknown_08625400[] =
+{
+ 1, 2, 3
+};
+
+static const u8 sEmptyItemName[] = _("");
+
+static const struct ScanlineEffectParams sUnknown_08625404 =
+{
+ .dmaDest = (void*)REG_ADDR_WIN0H,
+ .dmaControl = SCANLINE_EFFECT_DMACNT_32BIT,
+ .initState = 1,
+ .unused9 = 0
+};
+
+
+static const u8 sUnknown_08625410[] =
+{
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9, 9,
+ 10, 10,
+ 0xB, 0xB,
+ 0xC, 0xC,
+ 0xD, 0xD,
+ 0xD, 0xD,
+ 0xE, 0xE, 0xE, 0xE,
+ 0xF, 0xF, 0xF, 0xF,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
+ 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
+ 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
+ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
+ 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
+ 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
+ 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
+ 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
+ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B,
+ 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
+ 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D, 0x1D,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
+ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
+ 0x23
+};
+
+
+static const struct WindowTemplate sMoveRelearnerWindowTemplates[] =
+{
+ {
+ .bg = 1,
+ .tilemapLeft = 1,
+ .tilemapTop = 1,
+ .width = 16,
+ .height = 12,
+ .paletteNum = 0xF,
+ .baseBlock = 0xA
+ },
+ {
+ .bg = 1,
+ .tilemapLeft = 1,
+ .tilemapTop = 1,
+ .width = 16,
+ .height = 12,
+ .paletteNum = 0xF,
+ .baseBlock = 0xCA
+ },
+ {
+ .bg = 1,
+ .tilemapLeft = 19,
+ .tilemapTop = 1,
+ .width = 10,
+ .height = 12,
+ .paletteNum = 0xF,
+ .baseBlock = 0x18A
+ },
+ {
+ .bg = 1,
+ .tilemapLeft = 4,
+ .tilemapTop = 15,
+ .width = 22,
+ .height = 4,
+ .paletteNum = 0xF,
+ .baseBlock = 0x202
+ },
+ {
+ .bg = 0,
+ .tilemapLeft = 22,
+ .tilemapTop = 8,
+ .width = 5,
+ .height = 4,
+ .paletteNum = 0xF,
+ .baseBlock = 0x25A
+ },
+ DUMMY_WIN_TEMPLATE
+};
+
+static const struct WindowTemplate sMoveRelearnerYesNoMenuTemplate =
+{
+ .bg = 0,
+ .tilemapLeft = 22,
+ .tilemapTop = 8,
+ .width = 5,
+ .height = 4,
+ .paletteNum = 0xF,
+ .baseBlock = 0x25A
+};
+
+
+static const struct ListMenuTemplate sMoveRelearnerMovesListTemplate =
+{
+ .items = NULL,
+ .moveCursorFunc = MoveRelearnerCursorCallback,
+ .itemPrintFunc = NULL,
+ .totalItems = 0,
+ .maxShowed = 0,
+ .windowId = 2,
+ .header_X = 0,
+ .item_X = 8,
+ .cursor_X = 0,
+ .upText_Y = 1,
+ .cursorPal = 2,
+ .fillValue = 1,
+ .cursorShadowPal = 3,
+ .lettersSpacing = 0,
+ .itemVerticalPadding = 0,
+ .scrollMultiple = LIST_NO_MULTIPLE_SCROLL,
+ .fontId = 1,
+ .cursorKind = 0
+};
+
+bool8 sub_81D1C44(u8 count)
+{
+ u32 i;
+ struct ListMenuItem **v1;
+ v1 = &sUnknown_0203CF4C;
+ *v1 = Alloc(count * sizeof(struct ListMenuItem) + sizeof(struct ListMenuItem));
+
+ if (sUnknown_0203CF4C == NULL)
+ return FALSE;
+
+ for (i = 0; i < ARRAY_COUNT(sUnknown_0203CF48); i = (u8)(i + 1))
+ {
+ sUnknown_0203CF48[i] |= 0xFF;
+ }
+
+ return TRUE;
+}
+
+u8 sub_81D1C84(u8 a0)
+{
+ struct WindowTemplate template;
+
+ u8 windowId = sUnknown_0203CF48[a0];
+ if (windowId == 0xFF)
+ {
+ if (a0 == 2)
+ {
+ u32 v1;
+ u32 v2;
+ s32 v3;
+
+ template = sUnknown_086253E8[2];
+ v3 = GetMaxWidthInMenuTable(&gMailboxMailOptions[0], 4);
+ template.width = v3;
+ sUnknown_0203CF48[2] = AddWindow(&template);
+ }
+ else
+ {
+ sUnknown_0203CF48[a0] = AddWindow(&sUnknown_086253E8[a0]);
+ }
+ SetStandardWindowBorderStyle(sUnknown_0203CF48[a0], 0);
+ }
+ return sUnknown_0203CF48[a0];
+}
+
+void sub_81D1D04(u8 a0)
+{
+ ClearStdWindowAndFrameToTransparent(sUnknown_0203CF48[a0], 0);
+ ClearWindowTilemap(sUnknown_0203CF48[a0]);
+ RemoveWindow(sUnknown_0203CF48[a0]);
+ sUnknown_0203CF48[a0] = 0xFF;
+}
+
+static u8 sub_81D1D34(u8 a0)
+{
+ return sUnknown_0203CF48[a0];
+}
+
+static void sub_81D1D44(u8 windowId, s32 itemId, u8 y)
+{
+ u8 buffer[30];
+ u16 length;
+
+ if (itemId == LIST_CANCEL)
+ return;
+
+ StringCopy(buffer, gSaveBlock1Ptr->mail[6 + itemId].playerName);
+ sub_81DB52C(buffer);
+ length = StringLength(buffer);
+ if (length <= 5)
+ ConvertInternationalString(buffer, LANGUAGE_JAPANESE);
+ AddTextPrinterParameterized4(windowId, 1, 8, y, 0, 0, sUnknown_08625400, -1, buffer);
+}
+
+u8 sub_81D1DC0(struct PlayerPCItemPageStruct *page)
+{
+ u16 i;
+ for (i = 0; i < page->count; i++)
+ {
+ sUnknown_0203CF4C[i].name = sEmptyItemName;
+ sUnknown_0203CF4C[i].id = i;
+ }
+
+ sUnknown_0203CF4C[i].name = gText_Cancel2;
+ sUnknown_0203CF4C[i].id = LIST_CANCEL;
+
+ gMultiuseListMenuTemplate.items = sUnknown_0203CF4C;
+ gMultiuseListMenuTemplate.totalItems = page->count + 1;
+ gMultiuseListMenuTemplate.windowId = sUnknown_0203CF48[1];
+ gMultiuseListMenuTemplate.header_X = 0;
+ gMultiuseListMenuTemplate.item_X = 8;
+ gMultiuseListMenuTemplate.cursor_X = 0;
+ gMultiuseListMenuTemplate.maxShowed = 8;
+ gMultiuseListMenuTemplate.upText_Y = 9;
+ gMultiuseListMenuTemplate.cursorPal = 2;
+ gMultiuseListMenuTemplate.fillValue = 1;
+ gMultiuseListMenuTemplate.cursorShadowPal = 3;
+ gMultiuseListMenuTemplate.moveCursorFunc = sub_81D1E7C;
+ gMultiuseListMenuTemplate.itemPrintFunc = sub_81D1D44;
+ gMultiuseListMenuTemplate.fontId = 1;
+ gMultiuseListMenuTemplate.cursorKind = 0;
+ gMultiuseListMenuTemplate.lettersSpacing = 0;
+ gMultiuseListMenuTemplate.itemVerticalPadding = 0;
+ gMultiuseListMenuTemplate.scrollMultiple = LIST_NO_MULTIPLE_SCROLL;
+ return ListMenuInit(&gMultiuseListMenuTemplate, page->itemsAbove, page->cursorPos);
+}
+
+static void sub_81D1E7C(s32 itemIndex, bool8 onInit, struct ListMenu *list)
+{
+ if (onInit != TRUE)
+ PlaySE(SE_SELECT);
+}
+
+void sub_81D1E90(struct PlayerPCItemPageStruct *page)
+{
+ page->scrollIndicatorId = AddScrollIndicatorArrowPairParameterized(2, 0xC8, 12, 0x94, page->count - page->pageItems + 1, 0x6E, 0x6E, &page->itemsAbove);
+}
+
+void sub_81D1EC0(void)
+{
+ Free(sUnknown_0203CF4C);
+}
+
+void sub_81D1ED4(struct UnknownStruct_81D1ED4 *a0)
+{
+ u8 j;
+ u8 i;
+ for (j = 0; j < 5; j++)
+ {
+ for (i = 0; i < 10; i++)
+ {
+ a0->unk64[i][j].unk0 = 0;
+ a0->unk64[i][j].unk2 = 0;
+ }
+ for (i = 0; i < 4; i++)
+ {
+ a0->unk0[i][j] = 0;
+ a0->unk14[i][j].unk0 = 0x9B;
+ a0->unk14[i][j].unk2 = 0x5B;
+ }
+
+ a0->unk12C[j].unk0 = 0;
+ a0->unk12C[j].unk2 = 0;
+ }
+
+ a0->unk354 = 0;
+ a0->unk352 = 0;
+}
+
+NAKED
+void sub_81D1F84(struct UnknownStruct_81D1ED4 *arg0, struct UnknownSubStruct_81D1ED4 arg1[4][5], struct UnknownSubStruct_81D1ED4 arg2[4][5])
+{
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ mov r7, r10\n\
+ mov r6, r9\n\
+ mov r5, r8\n\
+ push {r5-r7}\n\
+ sub sp, 0x8\n\
+ mov r8, r0\n\
+ str r1, [sp]\n\
+ mov r9, r2\n\
+ movs r7, 0\n\
+_081D1F98:\n\
+ lsls r4, r7, 2\n\
+ ldr r1, [sp]\n\
+ adds r0, r4, r1\n\
+ ldrh r1, [r0]\n\
+ lsls r5, r1, 8\n\
+ mov r2, r9\n\
+ adds r0, r4, r2\n\
+ ldrh r0, [r0]\n\
+ subs r0, r1\n\
+ lsls r0, 8\n\
+ movs r1, 0xA\n\
+ bl __divsi3\n\
+ adds r6, r0, 0\n\
+ movs r3, 0\n\
+ adds r7, 0x1\n\
+ mov r10, r7\n\
+ mov r12, r4\n\
+_081D1FBC:\n\
+ lsls r0, r3, 2\n\
+ adds r0, r3\n\
+ lsls r0, 2\n\
+ add r0, r12\n\
+ add r0, r8\n\
+ asrs r2, r5, 8\n\
+ asrs r1, r5, 7\n\
+ movs r7, 0x1\n\
+ ands r1, r7\n\
+ adds r2, r1\n\
+ adds r0, 0x64\n\
+ strh r2, [r0]\n\
+ adds r5, r6\n\
+ adds r0, r3, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r3, r0, 16\n\
+ cmp r3, 0x8\n\
+ bls _081D1FBC\n\
+ lsls r0, r3, 2\n\
+ adds r0, r3\n\
+ lsls r0, 2\n\
+ adds r0, r4, r0\n\
+ add r0, r8\n\
+ mov r1, r9\n\
+ adds r2, r4, r1\n\
+ ldrh r1, [r2]\n\
+ adds r0, 0x64\n\
+ strh r1, [r0]\n\
+ ldr r7, [sp]\n\
+ adds r0, r4, r7\n\
+ ldrh r1, [r0, 0x2]\n\
+ lsls r5, r1, 8\n\
+ ldrh r0, [r2, 0x2]\n\
+ subs r0, r1\n\
+ lsls r0, 8\n\
+ movs r1, 0xA\n\
+ bl __divsi3\n\
+ adds r6, r0, 0\n\
+ movs r3, 0\n\
+ str r4, [sp, 0x4]\n\
+ movs r0, 0x1\n\
+ mov r12, r0\n\
+_081D2012:\n\
+ lsls r0, r3, 2\n\
+ adds r0, r3\n\
+ lsls r0, 2\n\
+ ldr r1, [sp, 0x4]\n\
+ adds r0, r1, r0\n\
+ add r0, r8\n\
+ asrs r2, r5, 8\n\
+ asrs r1, r5, 7\n\
+ mov r7, r12\n\
+ ands r1, r7\n\
+ adds r2, r1\n\
+ adds r0, 0x66\n\
+ strh r2, [r0]\n\
+ adds r5, r6\n\
+ adds r0, r3, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r3, r0, 16\n\
+ cmp r3, 0x8\n\
+ bls _081D2012\n\
+ lsls r0, r3, 2\n\
+ adds r0, r3\n\
+ lsls r0, 2\n\
+ adds r0, r4, r0\n\
+ add r0, r8\n\
+ mov r2, r9\n\
+ adds r1, r4, r2\n\
+ ldrh r1, [r1, 0x2]\n\
+ adds r0, 0x66\n\
+ strh r1, [r0]\n\
+ mov r7, r10\n\
+ lsls r0, r7, 16\n\
+ lsrs r7, r0, 16\n\
+ cmp r7, 0x4\n\
+ bls _081D1F98\n\
+ ldr r1, =0x00000352\n\
+ add r1, r8\n\
+ movs r0, 0\n\
+ strh r0, [r1]\n\
+ add sp, 0x8\n\
+ pop {r3-r5}\n\
+ mov r8, r3\n\
+ mov r9, r4\n\
+ mov r10, r5\n\
+ pop {r4-r7}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .pool\n\
+ .syntax divided");
+}
+
+bool32 sub_81D2074(struct UnknownStruct_81D1ED4 *a0)
+{
+ if (a0->unk352 < 10)
+ {
+ sub_81D2230(a0);
+ return ++a0->unk352 != 10;
+ }
+ else
+ {
+ return FALSE;
+ }
+
+}
+
+void sub_81D20AC(struct UnknownStruct_81D1ED4 *a0)
+{
+ a0->unk355 = 0;
+}
+
+bool8 sub_81D20BC(struct UnknownStruct_81D1ED4 *arg0)
+{
+ struct ScanlineEffectParams params;
+ switch (arg0->unk355)
+ {
+ case 0:
+ ScanlineEffect_Clear();
+ arg0->unk355++;
+ return TRUE;
+ case 1:
+ params = sUnknown_08625404;
+ ScanlineEffect_SetParams(params);
+ arg0->unk355++;
+ return FALSE;
+ default:
+ return FALSE;
+ }
+}
+
+NAKED
+void sub_81D2108(struct UnknownStruct_81D1ED4 *arg0)
+{
+ // Three of the additions are in the wrong order.
+#ifdef NONMATCHING
+ u16 i;
+ u32 v3;
+ u32 v4;
+ u16 *scanBuffer1;
+ u16 *scanBuffer2;
+ u32 scanBufferWidth;
+ u32 mask;
+ u16 *unkBuff1;
+ u16 *unkBuff2;
+ u16 *unkBuff3;
+ u16 *unkBuff4;
+
+ if (arg0->unk354 == 0)
+ return;
+
+ sub_81D24A4(arg0);
+ sub_81D2634(arg0);
+
+ i = 0;
+ scanBuffer1 = gScanlineEffectRegBuffers[0];
+ scanBufferWidth = ARRAY_COUNT(gScanlineEffectRegBuffers[0]);
+ scanBuffer2 = scanBuffer1 + scanBufferWidth;
+
+ // This function accesses the arrays "manually", where every other entry
+ // is just handled differently, rather than a pairwise struct.
+ unkBuff1 = (u16*)&arg0->unk13C[0].unk0;
+ mask = 0xFFFF;
+ unkBuff2 = (u16*)&arg0->unk13C[0].unk2;
+ unkBuff3 = (u16*)&arg0->unk248[0].unk0;
+ unkBuff4 = (u16*)&arg0->unk248[0].unk2;
+
+ for (; i < 0x42; i++)
+ {
+ u32 offset1;
+ register u32 offset2 asm("r2");
+ u32 offset3;
+
+ offset1 = (i + 0x37) * 2;
+ offset2 = i + 0x37;
+ scanBuffer2[offset1] = (scanBuffer1[offset1] = (unkBuff1[i * 2] << 8) | unkBuff2[i * 2]) & mask;
+
+ offset3 = offset2 * 2 + 1;
+ scanBuffer2[offset3] = (scanBuffer1[offset3] = (unkBuff3[i * 2] << 8) | unkBuff4[i * 2]) & mask;
+ }
+
+ arg0->unk354 = 0;
+#else
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ mov r7, r10\n\
+ mov r6, r9\n\
+ mov r5, r8\n\
+ push {r5-r7}\n\
+ sub sp, 0x10\n\
+ adds r6, r0, 0\n\
+ movs r1, 0xD5\n\
+ lsls r1, 2\n\
+ adds r0, r6, r1\n\
+ ldrb r0, [r0]\n\
+ cmp r0, 0\n\
+ beq _081D21BE\n\
+ adds r0, r6, 0\n\
+ bl sub_81D24A4\n\
+ adds r0, r6, 0\n\
+ bl sub_81D2634\n\
+ movs r7, 0\n\
+ ldr r5, =gScanlineEffectRegBuffers\n\
+ mov r12, r5\n\
+ movs r0, 0xF0\n\
+ lsls r0, 3\n\
+ add r0, r12\n\
+ mov r9, r0\n\
+ movs r1, 0xA0\n\
+ lsls r1, 1\n\
+ adds r1, r6, r1\n\
+ str r1, [sp]\n\
+ ldr r5, =0x0000ffff\n\
+ mov r8, r5\n\
+ movs r0, 0xA1\n\
+ lsls r0, 1\n\
+ adds r0, r6, r0\n\
+ str r0, [sp, 0x4]\n\
+ movs r1, 0x92\n\
+ lsls r1, 2\n\
+ adds r1, r6, r1\n\
+ str r1, [sp, 0x8]\n\
+ ldr r5, =0x0000024a\n\
+ adds r5, r6\n\
+ mov r10, r5\n\
+_081D215E:\n\
+ adds r2, r7, 0\n\
+ adds r2, 0x37\n\
+ lsls r3, r2, 2\n\
+ mov r0, r9\n\
+ adds r0, r3, r0\n\
+ str r0, [sp, 0xC]\n\
+ add r3, r12\n\
+ lsls r4, r7, 2\n\
+ ldr r1, [sp]\n\
+ adds r0, r1, r4\n\
+ ldrh r0, [r0]\n\
+ lsls r0, 8\n\
+ ldr r5, [sp, 0x4]\n\
+ adds r1, r5, r4\n\
+ ldrh r1, [r1]\n\
+ orrs r0, r1\n\
+ strh r0, [r3]\n\
+ mov r1, r8\n\
+ ands r0, r1\n\
+ ldr r5, [sp, 0xC]\n\
+ strh r0, [r5]\n\
+ lsls r2, 1\n\
+ adds r2, 0x1\n\
+ lsls r2, 1\n\
+ mov r0, r9\n\
+ adds r3, r2, r0\n\
+ add r2, r12\n\
+ ldr r1, [sp, 0x8]\n\
+ adds r0, r1, r4\n\
+ ldrh r0, [r0]\n\
+ lsls r0, 8\n\
+ add r4, r10\n\
+ ldrh r1, [r4]\n\
+ orrs r0, r1\n\
+ strh r0, [r2]\n\
+ mov r5, r8\n\
+ ands r0, r5\n\
+ strh r0, [r3]\n\
+ adds r0, r7, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r7, r0, 16\n\
+ cmp r7, 0x41\n\
+ bls _081D215E\n\
+ movs r0, 0xD5\n\
+ lsls r0, 2\n\
+ adds r1, r6, r0\n\
+ movs r0, 0\n\
+ strb r0, [r1]\n\
+_081D21BE:\n\
+ add sp, 0x10\n\
+ pop {r3-r5}\n\
+ mov r8, r3\n\
+ mov r9, r4\n\
+ mov r10, r5\n\
+ pop {r4-r7}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .pool\n\
+ .syntax divided");
+#endif
+}
+
+void sub_81D21DC(u8 bg)
+{
+ u8 flags;
+
+ if (bg > 3)
+ bg = 0;
+
+ // Unset the WINOUT flag for the bg.
+ flags = (WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ) & ~(1 << bg);
+
+ SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(0, 0xF0));
+ SetGpuReg(REG_OFFSET_WIN1H, WIN_RANGE(0, 0x9B));
+ SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(0x38, 0x79));
+ SetGpuReg(REG_OFFSET_WIN1V, WIN_RANGE(0x38, 0x79));
+ SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
+ SetGpuReg(REG_OFFSET_WINOUT, flags);
+}
+
+void sub_81D2230(struct UnknownStruct_81D1ED4 *arg0)
+{
+ u16 i;
+ for (i = 0; i < 5; i++)
+ {
+ arg0->unk12C[i] = arg0->unk64[arg0->unk352][i];
+ }
+ arg0->unk354 = 1;
+}
+
+NAKED
+static void sub_81D2278(void *a0, void *a1, u16 *a2, u16 *a3, u8 a38, u32 a3C)
+{
+#ifdef NONMATCHING
+ // a0 => sp0
+ // a1 => r6
+ // a2 => r5
+ // a3 => sp4
+ // a38 => r9
+ // a3C => r7
+ u32 v1; // r10
+ u32 v2; // sp8
+ u32 v3; // spC
+ u32 v4;
+ u32 v5;
+ u16 v6; // r8
+ u32 v7;
+ u32 v8; // sp10
+
+ v3 = 0;
+
+ // v4 => r4
+ // v5 => r0
+ // v7 => r1
+ if (a2[1] < a3[1])
+ {
+ v1 = a2[1];
+ v5 = a3[1];
+ v7 = a2[0];
+ v4 = v7 << 10;
+ v2 = a3[0];
+ }
+ else
+ {
+ v5 = a2[1];
+ v1 = a3[1];
+ v7 = a3[0];
+ v4 = v7 << 10;
+ v2 = a2[0];
+ }
+
+ v6 = v5 - v1;
+ if (v6 != 0)
+ {
+ v3 = (v2 - v7) / v6;
+ }
+ v6++;
+
+ if (a3C == 0)
+ {
+ v8 =
+ }
+#else
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ mov r7, r10\n\
+ mov r6, r9\n\
+ mov r5, r8\n\
+ push {r5-r7}\n\
+ sub sp, 0x18\n\
+ str r0, [sp]\n\
+ adds r6, r1, 0\n\
+ adds r5, r2, 0\n\
+ str r3, [sp, 0x4]\n\
+ ldr r0, [sp, 0x38]\n\
+ ldr r7, [sp, 0x3C]\n\
+ lsls r0, 24\n\
+ lsrs r0, 24\n\
+ mov r9, r0\n\
+ movs r0, 0\n\
+ str r0, [sp, 0xC]\n\
+ ldrh r0, [r5, 0x2]\n\
+ ldrh r1, [r3, 0x2]\n\
+ cmp r0, r1\n\
+ bcs _081D22B2\n\
+ adds r2, r0, 0\n\
+ mov r10, r2\n\
+ ldrh r0, [r3, 0x2]\n\
+ ldrh r1, [r5]\n\
+ lsls r4, r1, 10\n\
+ ldrh r3, [r3]\n\
+ str r3, [sp, 0x8]\n\
+ b _081D22C6\n\
+_081D22B2:\n\
+ ldrh r0, [r5, 0x2]\n\
+ ldr r1, [sp, 0x4]\n\
+ ldrh r1, [r1, 0x2]\n\
+ mov r10, r1\n\
+ ldr r2, [sp, 0x4]\n\
+ ldrh r1, [r2]\n\
+ lsls r4, r1, 10\n\
+ ldrh r3, [r5]\n\
+ str r3, [sp, 0x8]\n\
+ mov r2, r10\n\
+_081D22C6:\n\
+ subs r0, r2\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ mov r8, r0\n\
+ cmp r0, 0\n\
+ beq _081D22DE\n\
+ subs r0, r3, r1\n\
+ lsls r0, 10\n\
+ mov r1, r8\n\
+ bl __divsi3\n\
+ str r0, [sp, 0xC]\n\
+_081D22DE:\n\
+ mov r0, r8\n\
+ adds r0, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ mov r8, r0\n\
+ cmp r7, 0\n\
+ bne _081D2328\n\
+ mov r0, r10\n\
+ subs r0, 0x38\n\
+ lsls r0, 2\n\
+ adds r6, r0\n\
+ movs r5, 0\n\
+ mov r3, r9\n\
+ lsls r3, 1\n\
+ mov r12, r3\n\
+ ldr r0, [sp, 0x8]\n\
+ add r0, r9\n\
+ str r0, [sp, 0x10]\n\
+ cmp r7, r8\n\
+ bcs _081D23B6\n\
+ movs r7, 0x1\n\
+_081D2308:\n\
+ adds r2, r3, r6\n\
+ asrs r1, r4, 10\n\
+ asrs r0, r4, 9\n\
+ ands r0, r7\n\
+ adds r1, r0\n\
+ add r1, r9\n\
+ strh r1, [r2]\n\
+ ldr r1, [sp, 0xC]\n\
+ adds r4, r1\n\
+ adds r6, 0x4\n\
+ adds r0, r5, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r5, r0, 16\n\
+ cmp r5, r8\n\
+ bcc _081D2308\n\
+ b _081D23B6\n\
+_081D2328:\n\
+ ldr r2, [sp, 0xC]\n\
+ cmp r2, 0\n\
+ ble _081D23C0\n\
+ mov r0, r10\n\
+ subs r0, 0x38\n\
+ lsls r0, 2\n\
+ adds r7, r0\n\
+ movs r5, 0\n\
+ mov r3, r9\n\
+ lsls r3, 1\n\
+ mov r12, r3\n\
+ ldr r0, [sp, 0x8]\n\
+ add r0, r9\n\
+ str r0, [sp, 0x10]\n\
+ cmp r5, r8\n\
+ bcs _081D237A\n\
+ ldr r0, =0x00026bff\n\
+ cmp r4, r0\n\
+ bgt _081D237A\n\
+ mov r1, r12\n\
+ str r1, [sp, 0x14]\n\
+_081D2352:\n\
+ ldr r3, [sp, 0x14]\n\
+ adds r2, r3, r7\n\
+ asrs r1, r4, 10\n\
+ asrs r0, r4, 9\n\
+ movs r3, 0x1\n\
+ ands r0, r3\n\
+ adds r1, r0\n\
+ add r1, r9\n\
+ strh r1, [r2]\n\
+ ldr r0, [sp, 0xC]\n\
+ adds r4, r0\n\
+ adds r7, 0x4\n\
+ adds r0, r5, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r5, r0, 16\n\
+ cmp r5, r8\n\
+ bcs _081D237A\n\
+ ldr r1, =0x00026bff\n\
+ cmp r4, r1\n\
+ ble _081D2352\n\
+_081D237A:\n\
+ mov r2, r10\n\
+ adds r1, r2, r5\n\
+ ldr r3, [sp]\n\
+ movs r2, 0xD4\n\
+ lsls r2, 2\n\
+ adds r0, r3, r2\n\
+ strh r1, [r0]\n\
+ ldrh r0, [r0]\n\
+ subs r0, 0x38\n\
+ lsls r0, 2\n\
+ adds r6, r0\n\
+ cmp r5, r8\n\
+ bcs _081D23B6\n\
+ mov r3, r12\n\
+ movs r7, 0x1\n\
+_081D2398:\n\
+ adds r2, r3, r6\n\
+ asrs r1, r4, 10\n\
+ asrs r0, r4, 9\n\
+ ands r0, r7\n\
+ adds r1, r0\n\
+ add r1, r9\n\
+ strh r1, [r2]\n\
+ ldr r0, [sp, 0xC]\n\
+ adds r4, r0\n\
+ adds r6, 0x4\n\
+ adds r0, r5, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r5, r0, 16\n\
+ cmp r5, r8\n\
+ bcc _081D2398\n\
+_081D23B6:\n\
+ subs r0, r6, 0x4\n\
+ b _081D248C\n\
+ .pool\n\
+_081D23C0:\n\
+ ldr r1, [sp, 0xC]\n\
+ cmp r1, 0\n\
+ bge _081D2464\n\
+ mov r0, r10\n\
+ subs r0, 0x38\n\
+ lsls r0, 2\n\
+ adds r6, r0\n\
+ movs r5, 0\n\
+ mov r2, r9\n\
+ lsls r2, 1\n\
+ mov r12, r2\n\
+ ldr r3, [sp, 0x8]\n\
+ add r3, r9\n\
+ str r3, [sp, 0x10]\n\
+ cmp r5, r8\n\
+ bcs _081D241E\n\
+ adds r3, r2, r6\n\
+ asrs r1, r4, 10\n\
+ asrs r0, r4, 9\n\
+ movs r2, 0x1\n\
+ ands r0, r2\n\
+ adds r1, r0\n\
+ add r1, r9\n\
+ strh r1, [r3]\n\
+ b _081D2414\n\
+_081D23F2:\n\
+ ldr r0, [sp, 0xC]\n\
+ adds r4, r0\n\
+ adds r6, 0x4\n\
+ adds r0, r5, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r5, r0, 16\n\
+ cmp r5, r8\n\
+ bcs _081D241E\n\
+ mov r1, r12\n\
+ adds r3, r1, r6\n\
+ asrs r2, r4, 10\n\
+ asrs r0, r4, 9\n\
+ movs r1, 0x1\n\
+ ands r0, r1\n\
+ adds r2, r0\n\
+ add r2, r9\n\
+ strh r2, [r3]\n\
+_081D2414:\n\
+ ldr r0, =0x00026bff\n\
+ cmp r4, r0\n\
+ bgt _081D23F2\n\
+ movs r0, 0x9B\n\
+ strh r0, [r3]\n\
+_081D241E:\n\
+ mov r2, r10\n\
+ adds r1, r2, r5\n\
+ ldr r3, [sp]\n\
+ movs r2, 0xD4\n\
+ lsls r2, 2\n\
+ adds r0, r3, r2\n\
+ strh r1, [r0]\n\
+ ldrh r0, [r0]\n\
+ subs r0, 0x38\n\
+ lsls r0, 2\n\
+ adds r7, r0\n\
+ cmp r5, r8\n\
+ bcs _081D245A\n\
+ mov r3, r12\n\
+ movs r6, 0x1\n\
+_081D243C:\n\
+ adds r2, r3, r7\n\
+ asrs r1, r4, 10\n\
+ asrs r0, r4, 9\n\
+ ands r0, r6\n\
+ adds r1, r0\n\
+ add r1, r9\n\
+ strh r1, [r2]\n\
+ ldr r0, [sp, 0xC]\n\
+ adds r4, r0\n\
+ adds r7, 0x4\n\
+ adds r0, r5, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r5, r0, 16\n\
+ cmp r5, r8\n\
+ bcc _081D243C\n\
+_081D245A:\n\
+ subs r0, r7, 0x4\n\
+ b _081D248C\n\
+ .pool\n\
+_081D2464:\n\
+ ldr r1, [sp]\n\
+ movs r2, 0xD4\n\
+ lsls r2, 2\n\
+ adds r0, r1, r2\n\
+ mov r3, r10\n\
+ strh r3, [r0]\n\
+ mov r0, r10\n\
+ subs r0, 0x38\n\
+ lsls r0, 2\n\
+ adds r6, r0\n\
+ adds r7, r0\n\
+ ldrh r0, [r5]\n\
+ adds r0, 0x1\n\
+ strh r0, [r6, 0x2]\n\
+ ldr r1, [sp, 0x4]\n\
+ ldrh r0, [r1]\n\
+ strh r0, [r7]\n\
+ movs r0, 0x9B\n\
+ strh r0, [r7, 0x2]\n\
+ b _081D2494\n\
+_081D248C:\n\
+ add r0, r12\n\
+ mov r2, sp\n\
+ ldrh r2, [r2, 0x10]\n\
+ strh r2, [r0]\n\
+_081D2494:\n\
+ add sp, 0x18\n\
+ pop {r3-r5}\n\
+ mov r8, r3\n\
+ mov r9, r4\n\
+ mov r10, r5\n\
+ pop {r4-r7}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .syntax divided");
+#endif
+}
+
+NAKED
+static void sub_81D24A4(struct UnknownStruct_81D1ED4 *a0)
+{
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ sub sp, 0x8\n\
+ adds r4, r0, 0\n\
+ movs r0, 0x97\n\
+ lsls r0, 1\n\
+ adds r2, r4, r0\n\
+ movs r3, 0x99\n\
+ lsls r3, 1\n\
+ adds r1, r4, r3\n\
+ ldrh r0, [r2]\n\
+ ldrh r3, [r1]\n\
+ cmp r0, r3\n\
+ bcs _081D24E0\n\
+ adds r7, r0, 0\n\
+ movs r0, 0xA0\n\
+ lsls r0, 1\n\
+ adds r1, r4, r0\n\
+ movs r3, 0x96\n\
+ lsls r3, 1\n\
+ adds r2, r4, r3\n\
+ subs r0, 0x10\n\
+ adds r3, r4, r0\n\
+ movs r0, 0x1\n\
+ str r0, [sp]\n\
+ movs r0, 0\n\
+ str r0, [sp, 0x4]\n\
+ adds r0, r4, 0\n\
+ bl sub_81D2278\n\
+ b _081D2500\n\
+_081D24E0:\n\
+ ldrh r7, [r1]\n\
+ movs r2, 0xA0\n\
+ lsls r2, 1\n\
+ adds r1, r4, r2\n\
+ movs r3, 0x98\n\
+ lsls r3, 1\n\
+ adds r2, r4, r3\n\
+ movs r0, 0x96\n\
+ lsls r0, 1\n\
+ adds r3, r4, r0\n\
+ movs r0, 0\n\
+ str r0, [sp]\n\
+ str r0, [sp, 0x4]\n\
+ adds r0, r4, 0\n\
+ bl sub_81D2278\n\
+_081D2500:\n\
+ movs r1, 0xA0\n\
+ lsls r1, 1\n\
+ adds r5, r4, r1\n\
+ movs r3, 0x98\n\
+ lsls r3, 1\n\
+ adds r2, r4, r3\n\
+ movs r0, 0x9A\n\
+ lsls r0, 1\n\
+ adds r6, r4, r0\n\
+ movs r0, 0x1\n\
+ str r0, [sp]\n\
+ movs r0, 0\n\
+ str r0, [sp, 0x4]\n\
+ adds r0, r4, 0\n\
+ adds r1, r5, 0\n\
+ adds r3, r6, 0\n\
+ bl sub_81D2278\n\
+ movs r2, 0\n\
+ movs r1, 0x9B\n\
+ lsls r1, 1\n\
+ adds r0, r4, r1\n\
+ movs r3, 0x9D\n\
+ lsls r3, 1\n\
+ adds r1, r4, r3\n\
+ ldrh r0, [r0]\n\
+ ldrh r1, [r1]\n\
+ cmp r0, r1\n\
+ bhi _081D253C\n\
+ movs r2, 0x1\n\
+_081D253C:\n\
+ movs r0, 0x9C\n\
+ lsls r0, 1\n\
+ adds r3, r4, r0\n\
+ str r2, [sp]\n\
+ movs r1, 0x92\n\
+ lsls r1, 2\n\
+ adds r0, r4, r1\n\
+ str r0, [sp, 0x4]\n\
+ adds r0, r4, 0\n\
+ adds r1, r5, 0\n\
+ adds r2, r6, 0\n\
+ bl sub_81D2278\n\
+ movs r2, 0x38\n\
+ cmp r2, r7\n\
+ bcs _081D257E\n\
+ adds r6, r5, 0\n\
+ movs r3, 0\n\
+ movs r0, 0xA1\n\
+ lsls r0, 1\n\
+ adds r5, r4, r0\n\
+_081D2566:\n\
+ adds r0, r2, 0\n\
+ subs r0, 0x38\n\
+ lsls r0, 2\n\
+ adds r1, r6, r0\n\
+ strh r3, [r1]\n\
+ adds r0, r5, r0\n\
+ strh r3, [r0]\n\
+ adds r0, r2, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r2, r0, 16\n\
+ cmp r2, r7\n\
+ bcc _081D2566\n\
+_081D257E:\n\
+ movs r1, 0x97\n\
+ lsls r1, 1\n\
+ adds r0, r4, r1\n\
+ ldrh r2, [r0]\n\
+ movs r3, 0xD4\n\
+ lsls r3, 2\n\
+ adds r0, r4, r3\n\
+ ldrh r1, [r0]\n\
+ cmp r2, r1\n\
+ bhi _081D25B2\n\
+ movs r1, 0xA0\n\
+ lsls r1, 1\n\
+ adds r3, r4, r1\n\
+ movs r5, 0x9B\n\
+ adds r1, r0, 0\n\
+_081D259C:\n\
+ adds r0, r2, 0\n\
+ subs r0, 0x38\n\
+ lsls r0, 2\n\
+ adds r0, r3, r0\n\
+ strh r5, [r0]\n\
+ adds r0, r2, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r2, r0, 16\n\
+ ldrh r0, [r1]\n\
+ cmp r2, r0\n\
+ bls _081D259C\n\
+_081D25B2:\n\
+ movs r2, 0x9B\n\
+ lsls r2, 1\n\
+ adds r1, r4, r2\n\
+ movs r3, 0xD4\n\
+ lsls r3, 2\n\
+ adds r0, r4, r3\n\
+ ldrh r0, [r0]\n\
+ ldrh r1, [r1]\n\
+ cmp r0, r1\n\
+ bcs _081D25C8\n\
+ adds r0, r1, 0\n\
+_081D25C8:\n\
+ adds r0, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r2, r0, 16\n\
+ cmp r2, 0x79\n\
+ bhi _081D25F8\n\
+ movs r0, 0xA0\n\
+ lsls r0, 1\n\
+ adds r6, r4, r0\n\
+ movs r3, 0\n\
+ movs r1, 0xA1\n\
+ lsls r1, 1\n\
+ adds r5, r4, r1\n\
+_081D25E0:\n\
+ adds r0, r2, 0\n\
+ subs r0, 0x38\n\
+ lsls r0, 2\n\
+ adds r1, r6, r0\n\
+ strh r3, [r1]\n\
+ adds r0, r5, r0\n\
+ strh r3, [r0]\n\
+ adds r0, r2, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r2, r0, 16\n\
+ cmp r2, 0x79\n\
+ bls _081D25E0\n\
+_081D25F8:\n\
+ movs r2, 0x38\n\
+ movs r3, 0xA0\n\
+ lsls r3, 1\n\
+ adds r5, r4, r3\n\
+ movs r0, 0xA1\n\
+ lsls r0, 1\n\
+ adds r4, r0\n\
+ movs r6, 0x9B\n\
+_081D2608:\n\
+ adds r0, r2, 0\n\
+ subs r0, 0x38\n\
+ lsls r1, r0, 2\n\
+ adds r3, r5, r1\n\
+ ldrh r0, [r3]\n\
+ cmp r0, 0\n\
+ bne _081D2620\n\
+ adds r0, r4, r1\n\
+ ldrh r0, [r0]\n\
+ cmp r0, 0\n\
+ beq _081D2620\n\
+ strh r6, [r3]\n\
+_081D2620:\n\
+ adds r0, r2, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r2, r0, 16\n\
+ cmp r2, 0x79\n\
+ bls _081D2608\n\
+ add sp, 0x8\n\
+ pop {r4-r7}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .syntax divided");
+}
+
+NAKED
+static void sub_81D2634(struct UnknownStruct_81D1ED4 *a0)
+{
+ asm(".syntax unified\n\
+ push {r4-r6,lr}\n\
+ sub sp, 0x8\n\
+ adds r4, r0, 0\n\
+ movs r0, 0x97\n\
+ lsls r0, 1\n\
+ adds r2, r4, r0\n\
+ movs r3, 0x9F\n\
+ lsls r3, 1\n\
+ adds r1, r4, r3\n\
+ ldrh r0, [r2]\n\
+ ldrh r5, [r1]\n\
+ cmp r0, r5\n\
+ bcs _081D266E\n\
+ adds r6, r0, 0\n\
+ movs r0, 0x92\n\
+ lsls r0, 2\n\
+ adds r1, r4, r0\n\
+ subs r3, 0x12\n\
+ adds r2, r4, r3\n\
+ movs r5, 0x9E\n\
+ lsls r5, 1\n\
+ adds r3, r4, r5\n\
+ movs r0, 0\n\
+ str r0, [sp]\n\
+ str r0, [sp, 0x4]\n\
+ adds r0, r4, 0\n\
+ bl sub_81D2278\n\
+ b _081D2690\n\
+_081D266E:\n\
+ ldrh r6, [r1]\n\
+ movs r0, 0x92\n\
+ lsls r0, 2\n\
+ adds r1, r4, r0\n\
+ movs r3, 0x9E\n\
+ lsls r3, 1\n\
+ adds r2, r4, r3\n\
+ movs r5, 0x96\n\
+ lsls r5, 1\n\
+ adds r3, r4, r5\n\
+ movs r0, 0x1\n\
+ str r0, [sp]\n\
+ movs r0, 0\n\
+ str r0, [sp, 0x4]\n\
+ adds r0, r4, 0\n\
+ bl sub_81D2278\n\
+_081D2690:\n\
+ movs r0, 0x92\n\
+ lsls r0, 2\n\
+ adds r5, r4, r0\n\
+ movs r1, 0x9E\n\
+ lsls r1, 1\n\
+ adds r2, r4, r1\n\
+ movs r0, 0x9C\n\
+ lsls r0, 1\n\
+ adds r3, r4, r0\n\
+ movs r0, 0\n\
+ str r0, [sp]\n\
+ str r0, [sp, 0x4]\n\
+ adds r0, r4, 0\n\
+ adds r1, r5, 0\n\
+ bl sub_81D2278\n\
+ cmp r6, 0x38\n\
+ ble _081D26C8\n\
+ movs r0, 0\n\
+ adds r1, r5, 0\n\
+ adds r2, r6, 0\n\
+ subs r2, 0x38\n\
+_081D26BC:\n\
+ strh r0, [r1]\n\
+ strh r0, [r1, 0x2]\n\
+ adds r1, 0x4\n\
+ subs r2, 0x1\n\
+ cmp r2, 0\n\
+ bne _081D26BC\n\
+_081D26C8:\n\
+ movs r1, 0x97\n\
+ lsls r1, 1\n\
+ adds r0, r4, r1\n\
+ ldrh r2, [r0]\n\
+ movs r3, 0xD4\n\
+ lsls r3, 2\n\
+ adds r0, r4, r3\n\
+ ldrh r5, [r0]\n\
+ cmp r2, r5\n\
+ bgt _081D26F6\n\
+ movs r3, 0x9B\n\
+ adds r1, r0, 0\n\
+ lsls r0, r2, 2\n\
+ movs r5, 0xB5\n\
+ lsls r5, 1\n\
+ adds r0, r5\n\
+ adds r0, r4\n\
+_081D26EA:\n\
+ strh r3, [r0]\n\
+ adds r0, 0x4\n\
+ adds r2, 0x1\n\
+ ldrh r5, [r1]\n\
+ cmp r2, r5\n\
+ ble _081D26EA\n\
+_081D26F6:\n\
+ movs r1, 0x9D\n\
+ lsls r1, 1\n\
+ adds r0, r4, r1\n\
+ ldrh r0, [r0]\n\
+ adds r1, r0, 0x1\n\
+ movs r2, 0xD4\n\
+ lsls r2, 2\n\
+ adds r0, r4, r2\n\
+ ldrh r0, [r0]\n\
+ cmp r0, r1\n\
+ bge _081D270E\n\
+ adds r0, r1, 0\n\
+_081D270E:\n\
+ adds r2, r0, 0\n\
+ cmp r2, 0x79\n\
+ bgt _081D272C\n\
+ movs r1, 0\n\
+ lsls r0, r2, 2\n\
+ movs r3, 0xB4\n\
+ lsls r3, 1\n\
+ adds r0, r3\n\
+ adds r0, r4\n\
+_081D2720:\n\
+ strh r1, [r0]\n\
+ strh r1, [r0, 0x2]\n\
+ adds r0, 0x4\n\
+ adds r2, 0x1\n\
+ cmp r2, 0x79\n\
+ ble _081D2720\n\
+_081D272C:\n\
+ movs r3, 0\n\
+ movs r5, 0x92\n\
+ lsls r5, 2\n\
+ adds r1, r4, r5\n\
+ movs r2, 0x41\n\
+_081D2736:\n\
+ ldrh r0, [r1]\n\
+ ldrh r4, [r1, 0x2]\n\
+ cmp r0, r4\n\
+ bcc _081D2742\n\
+ strh r3, [r1, 0x2]\n\
+ strh r3, [r1]\n\
+_081D2742:\n\
+ adds r1, 0x4\n\
+ subs r2, 0x1\n\
+ cmp r2, 0\n\
+ bge _081D2736\n\
+ add sp, 0x8\n\
+ pop {r4-r6}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .syntax divided");
+}
+
+NAKED
+void sub_81D2754(struct UnknownStruct_81D1ED4 *arg0, struct UnknownSubStruct_81D1ED4 *arg1)
+{
+ // There are some register-renaming issues here. The cause of the problem seems to be that
+ // GCC tries to save sUnknown_08625410 in a register, instead of loading the constant repeatedly.
+ // But this is one too many things to keep track of, so GCC is forced to use the stack.
+#ifdef NONMATCHING
+ u8* v1;
+ u8 v2;
+ u8 v3;
+ s8 v4;
+ u16 v5;
+
+ v1 = arg0->unk0[0];
+ v2 = sUnknown_08625410[*v1];
+ v1++;
+ arg1[0].unk0 = 0x9B;
+ arg1[0].unk2 = 0x5B - v2;
+ for (v3 = 0x40, v4 = 0, v5 = 1; v5 < 5; v5++)
+ {
+ v3 += 0x33;
+ v4--;
+ if (v4 < 0)
+ {
+ v4 = 4;
+ }
+ if (v4 == 2)
+ {
+ v3++;
+ }
+
+ v2 = sUnknown_08625410[*v1];
+ v1++;
+ arg1[v4].unk0 = ((gSineTable[v3 + 0x40] * v2) >> 8) + 0x9B;
+ arg1[v4].unk2 = ((gSineTable[v3] * v2) >> 8) - 0x5B;
+ if (v4 <= 2 && (v2 != 0x20 || v4 != 2))
+ {
+ arg1[v4].unk0 = arg1[v4].unk0 + 1;
+ }
+ }
+#else
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ mov r7, r10\n\
+ mov r6, r9\n\
+ mov r5, r8\n\
+ push {r5-r7}\n\
+ adds r6, r0, 0\n\
+ mov r8, r1\n\
+ ldr r1, =sUnknown_08625410\n\
+ ldrb r0, [r6]\n\
+ adds r0, r1\n\
+ ldrb r2, [r0]\n\
+ adds r6, 0x1\n\
+ movs r0, 0x9B\n\
+ mov r3, r8\n\
+ strh r0, [r3]\n\
+ movs r0, 0x5B\n\
+ subs r0, r2\n\
+ strh r0, [r3, 0x2]\n\
+ movs r7, 0x40\n\
+ movs r0, 0\n\
+ mov r12, r0\n\
+ movs r2, 0x1\n\
+ mov r9, r2\n\
+ ldr r3, =gSineTable\n\
+ mov r10, r3\n\
+_081D2786:\n\
+ adds r0, r7, 0\n\
+ adds r0, 0x33\n\
+ lsls r0, 24\n\
+ lsrs r7, r0, 24\n\
+ mov r1, r12\n\
+ lsls r0, r1, 24\n\
+ movs r2, 0xFF\n\
+ lsls r2, 24\n\
+ adds r0, r2\n\
+ lsrs r3, r0, 24\n\
+ mov r12, r3\n\
+ cmp r0, 0\n\
+ bge _081D27A4\n\
+ movs r0, 0x4\n\
+ mov r12, r0\n\
+_081D27A4:\n\
+ mov r1, r12\n\
+ lsls r0, r1, 24\n\
+ asrs r4, r0, 24\n\
+ cmp r4, 0x2\n\
+ bne _081D27B4\n\
+ adds r0, r7, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r7, r0, 24\n\
+_081D27B4:\n\
+ ldrb r0, [r6]\n\
+ ldr r2, =sUnknown_08625410\n\
+ adds r0, r2\n\
+ ldrb r2, [r0]\n\
+ adds r6, 0x1\n\
+ lsls r0, r4, 2\n\
+ mov r1, r8\n\
+ adds r3, r0, r1\n\
+ adds r0, r7, 0\n\
+ adds r0, 0x40\n\
+ lsls r0, 1\n\
+ add r0, r10\n\
+ movs r1, 0\n\
+ ldrsh r0, [r0, r1]\n\
+ muls r0, r2\n\
+ asrs r5, r0, 8\n\
+ adds r0, r5, 0\n\
+ adds r0, 0x9B\n\
+ strh r0, [r3]\n\
+ lsls r0, r7, 1\n\
+ add r0, r10\n\
+ movs r1, 0\n\
+ ldrsh r0, [r0, r1]\n\
+ adds r1, r2, 0\n\
+ muls r1, r0\n\
+ asrs r1, 8\n\
+ movs r0, 0x5B\n\
+ subs r0, r1\n\
+ strh r0, [r3, 0x2]\n\
+ cmp r4, 0x2\n\
+ bgt _081D2800\n\
+ cmp r2, 0x20\n\
+ bne _081D27FA\n\
+ cmp r4, 0x2\n\
+ beq _081D2800\n\
+_081D27FA:\n\
+ adds r0, r5, 0\n\
+ adds r0, 0x9C\n\
+ strh r0, [r3]\n\
+_081D2800:\n\
+ mov r0, r9\n\
+ adds r0, 0x1\n\
+ lsls r0, 16\n\
+ lsrs r0, 16\n\
+ mov r9, r0\n\
+ cmp r0, 0x4\n\
+ bls _081D2786\n\
+ pop {r3-r5}\n\
+ mov r8, r3\n\
+ mov r9, r4\n\
+ mov r10, r5\n\
+ pop {r4-r7}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .pool\n\
+ .syntax divided");
+#endif
+}
+
+void InitMoveRelearnerWindows(bool8 useContextWindow)
+{
+ u8 i;
+
+ InitWindows(sMoveRelearnerWindowTemplates);
+ DeactivateAllTextPrinters();
+ LoadUserWindowBorderGfx(0, 1, 0xE0);
+ LoadPalette(gUnknown_0860F074, 0xF0, 0x20);
+
+ for (i = 0; i < 5; i++)
+ {
+ FillWindowPixelBuffer(i, PIXEL_FILL(1));
+ }
+
+ if (!useContextWindow)
+ {
+ PutWindowTilemap(0);
+ DrawStdFrameWithCustomTileAndPalette(0, 0, 0x1, 0xE);
+ }
+ else
+ {
+ PutWindowTilemap(1);
+ DrawStdFrameWithCustomTileAndPalette(1, 0, 1, 0xE);
+ }
+ PutWindowTilemap(2);
+ PutWindowTilemap(3);
+ DrawStdFrameWithCustomTileAndPalette(2, 0, 1, 0xE);
+ DrawStdFrameWithCustomTileAndPalette(3, 0, 1, 0xE);
+ nullsub_79();
+ schedule_bg_copy_tilemap_to_vram(1);
+}
+
+static void nullsub_79(void)
+{
+
+}
+
+u8 LoadMoveRelearnerMovesList(const struct ListMenuItem *items, u16 numChoices)
+{
+ gMultiuseListMenuTemplate = sMoveRelearnerMovesListTemplate;
+ gMultiuseListMenuTemplate.totalItems = numChoices;
+ gMultiuseListMenuTemplate.items = items;
+
+ if (numChoices < 6)
+ {
+ gMultiuseListMenuTemplate.maxShowed = numChoices;
+ }
+ else
+ {
+ gMultiuseListMenuTemplate.maxShowed = 6;
+ }
+ return gMultiuseListMenuTemplate.maxShowed;
+}
+
+NAKED
+static void MoveRelearnerLoadBattleMoveDescription(u32 chosenMove)
+{
+ // Two small issues, and a few renamed registers.
+#ifdef NONMATCHING
+ u8 offset;
+ s32 width;
+ const struct BattleMove *move;
+ u8 buffer[0x20];
+ const u8 *labelStr;
+
+ FillWindowPixelBuffer(0, PIXEL_FILL(1));
+ labelStr = gText_MoveRelearnerBattleMoves;
+ offset = GetStringCenterAlignXOffset(1, labelStr, 0x80);
+ AddTextPrinterParameterized(0, 1, labelStr, offset, 1, TEXT_SPEED_FF, NULL);
+
+ labelStr = gText_MoveRelearnerPP;
+ AddTextPrinterParameterized(0, 1, labelStr, 4, 0x29, TEXT_SPEED_FF, NULL);
+
+ labelStr = gText_MoveRelearnerPower;
+ offset = GetStringRightAlignXOffset(1, labelStr, 0x6A);
+ AddTextPrinterParameterized(0, 1, labelStr, offset, 0x19, TEXT_SPEED_FF, NULL);
+
+ labelStr = gText_MoveRelearnerAccuracy;
+ offset = GetStringRightAlignXOffset(1, labelStr, 0x6A);
+ AddTextPrinterParameterized(0, 1, labelStr, offset, 0x29, TEXT_SPEED_FF, NULL);
+ if (chosenMove == LIST_CANCEL)
+ {
+ CopyWindowToVram(0, 2);
+ return;
+ }
+ move = &gBattleMoves[chosenMove];
+ labelStr = gTypeNames[move->type];
+ // GCC tries to be smart, and preserves the same 0x19 from above for this.
+ // The original asm just loads the constant 0x19 twice.
+ AddTextPrinterParameterized(0, 1, labelStr, 4, 0x19, TEXT_SPEED_FF, NULL);
+
+ // GCC tries to generate this as:
+ // add r4, r0, 0
+ // add r4, r4, 4
+ // But the original asm is:
+ // add r4, r0, 4
+ width = 4 + GetStringWidth(1, gText_MoveRelearnerPP, 0);
+
+ ConvertIntToDecimalStringN(buffer, move->pp, 0, 2);
+ AddTextPrinterParameterized(0, 1, buffer, width, 0x29, TEXT_SPEED_FF, NULL);
+
+
+ if (move->power < 2)
+ {
+ labelStr = gText_ThreeDashes;
+ }
+ else
+ {
+ ConvertIntToDecimalStringN(buffer, move->power, 0, 3);
+ labelStr = buffer;
+ }
+ AddTextPrinterParameterized(0, 1, labelStr, 0x6A, 0x19, TEXT_SPEED_FF, NULL);
+
+ if (move->accuracy == 0)
+ {
+ labelStr = gText_ThreeDashes;
+ }
+ else
+ {
+ ConvertIntToDecimalStringN(buffer, move->accuracy, 0, 3);
+ labelStr = buffer;
+ }
+ AddTextPrinterParameterized(0, 1, labelStr, 0x6A, 0x29, TEXT_SPEED_FF, NULL);
+ labelStr = gMoveDescriptionPointers[chosenMove - 1];
+ AddTextPrinterParameterized(0, 7, labelStr, 0, 0x41, 0, NULL);
+#else
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ mov r7, r10\n\
+ mov r6, r9\n\
+ mov r5, r8\n\
+ push {r5-r7}\n\
+ sub sp, 0x2C\n\
+ mov r9, r0\n\
+ movs r0, 0\n\
+ movs r1, 0x11\n\
+ bl FillWindowPixelBuffer\n\
+ ldr r5, =gText_MoveRelearnerBattleMoves\n\
+ movs r0, 0x1\n\
+ adds r1, r5, 0\n\
+ movs r2, 0x80\n\
+ bl GetStringCenterAlignXOffset\n\
+ adds r4, r0, 0\n\
+ lsls r3, r4, 24\n\
+ lsrs r3, 24\n\
+ movs r0, 0x1\n\
+ str r0, [sp]\n\
+ movs r0, 0xFF\n\
+ mov r8, r0\n\
+ str r0, [sp, 0x4]\n\
+ movs r7, 0\n\
+ str r7, [sp, 0x8]\n\
+ movs r0, 0\n\
+ movs r1, 0x1\n\
+ adds r2, r5, 0\n\
+ bl AddTextPrinterParameterized\n\
+ ldr r5, =gText_MoveRelearnerPP\n\
+ movs r1, 0x29\n\
+ mov r10, r1\n\
+ str r1, [sp]\n\
+ mov r0, r8\n\
+ str r0, [sp, 0x4]\n\
+ str r7, [sp, 0x8]\n\
+ movs r0, 0\n\
+ movs r1, 0x1\n\
+ adds r2, r5, 0\n\
+ movs r3, 0x4\n\
+ bl AddTextPrinterParameterized\n\
+ ldr r5, =gText_MoveRelearnerPower\n\
+ movs r0, 0x1\n\
+ adds r1, r5, 0\n\
+ movs r2, 0x6A\n\
+ bl GetStringRightAlignXOffset\n\
+ adds r4, r0, 0\n\
+ lsls r3, r4, 24\n\
+ lsrs r3, 24\n\
+ movs r1, 0x19\n\
+ str r1, [sp]\n\
+ mov r0, r8\n\
+ str r0, [sp, 0x4]\n\
+ str r7, [sp, 0x8]\n\
+ movs r0, 0\n\
+ movs r1, 0x1\n\
+ adds r2, r5, 0\n\
+ bl AddTextPrinterParameterized\n\
+ ldr r5, =gText_MoveRelearnerAccuracy\n\
+ movs r0, 0x1\n\
+ adds r1, r5, 0\n\
+ movs r2, 0x6A\n\
+ bl GetStringRightAlignXOffset\n\
+ adds r4, r0, 0\n\
+ lsls r3, r4, 24\n\
+ lsrs r3, 24\n\
+ mov r1, r10\n\
+ str r1, [sp]\n\
+ mov r0, r8\n\
+ str r0, [sp, 0x4]\n\
+ str r7, [sp, 0x8]\n\
+ movs r0, 0\n\
+ movs r1, 0x1\n\
+ adds r2, r5, 0\n\
+ bl AddTextPrinterParameterized\n\
+ movs r0, 0x2\n\
+ negs r0, r0\n\
+ cmp r9, r0\n\
+ bne _081D29C4\n\
+ movs r0, 0\n\
+ movs r1, 0x2\n\
+ bl CopyWindowToVram\n\
+ b _081D2AB6\n\
+ .pool\n\
+_081D29C4:\n\
+ mov r1, r9\n\
+ lsls r0, r1, 1\n\
+ add r0, r9\n\
+ lsls r0, 2\n\
+ ldr r1, =gBattleMoves\n\
+ adds r6, r0, r1\n\
+ ldrb r1, [r6, 0x2]\n\
+ lsls r0, r1, 3\n\
+ subs r0, r1\n\
+ ldr r1, =gTypeNames\n\
+ adds r5, r0, r1\n\
+ movs r0, 0x19\n\
+ str r0, [sp]\n\
+ mov r1, r8\n\
+ str r1, [sp, 0x4]\n\
+ str r7, [sp, 0x8]\n\
+ movs r0, 0\n\
+ movs r1, 0x1\n\
+ adds r2, r5, 0\n\
+ movs r3, 0x4\n\
+ bl AddTextPrinterParameterized\n\
+ ldr r1, =gText_MoveRelearnerPP\n\
+ movs r0, 0x1\n\
+ movs r2, 0\n\
+ bl GetStringWidth\n\
+ adds r4, r0, 0x4\n\
+ ldrb r1, [r6, 0x4]\n\
+ add r0, sp, 0xC\n\
+ movs r2, 0\n\
+ movs r3, 0x2\n\
+ bl ConvertIntToDecimalStringN\n\
+ lsls r3, r4, 24\n\
+ lsrs r3, 24\n\
+ mov r0, r10\n\
+ str r0, [sp]\n\
+ mov r1, r8\n\
+ str r1, [sp, 0x4]\n\
+ str r7, [sp, 0x8]\n\
+ movs r0, 0\n\
+ movs r1, 0x1\n\
+ add r2, sp, 0xC\n\
+ bl AddTextPrinterParameterized\n\
+ ldrb r0, [r6, 0x1]\n\
+ cmp r0, 0x1\n\
+ bhi _081D2A3C\n\
+ ldr r5, =gText_ThreeDashes\n\
+ b _081D2A4A\n\
+ .pool\n\
+_081D2A3C:\n\
+ ldrb r1, [r6, 0x1]\n\
+ add r0, sp, 0xC\n\
+ movs r2, 0\n\
+ movs r3, 0x3\n\
+ bl ConvertIntToDecimalStringN\n\
+ add r5, sp, 0xC\n\
+_081D2A4A:\n\
+ movs r0, 0x19\n\
+ str r0, [sp]\n\
+ movs r0, 0xFF\n\
+ str r0, [sp, 0x4]\n\
+ movs r0, 0\n\
+ str r0, [sp, 0x8]\n\
+ movs r1, 0x1\n\
+ adds r2, r5, 0\n\
+ movs r3, 0x6A\n\
+ bl AddTextPrinterParameterized\n\
+ ldrb r0, [r6, 0x3]\n\
+ cmp r0, 0\n\
+ bne _081D2A70\n\
+ ldr r5, =gText_ThreeDashes\n\
+ b _081D2A7E\n\
+ .pool\n\
+_081D2A70:\n\
+ ldrb r1, [r6, 0x3]\n\
+ add r0, sp, 0xC\n\
+ movs r2, 0\n\
+ movs r3, 0x3\n\
+ bl ConvertIntToDecimalStringN\n\
+ add r5, sp, 0xC\n\
+_081D2A7E:\n\
+ movs r0, 0x29\n\
+ str r0, [sp]\n\
+ movs r0, 0xFF\n\
+ str r0, [sp, 0x4]\n\
+ movs r4, 0\n\
+ str r4, [sp, 0x8]\n\
+ movs r0, 0\n\
+ movs r1, 0x1\n\
+ adds r2, r5, 0\n\
+ movs r3, 0x6A\n\
+ bl AddTextPrinterParameterized\n\
+ ldr r1, =gMoveDescriptionPointers\n\
+ mov r0, r9\n\
+ subs r0, 0x1\n\
+ lsls r0, 2\n\
+ adds r0, r1\n\
+ ldr r5, [r0]\n\
+ movs r0, 0x41\n\
+ str r0, [sp]\n\
+ str r4, [sp, 0x4]\n\
+ str r4, [sp, 0x8]\n\
+ movs r0, 0\n\
+ movs r1, 0x7\n\
+ adds r2, r5, 0\n\
+ movs r3, 0\n\
+ bl AddTextPrinterParameterized\n\
+_081D2AB6:\n\
+ add sp, 0x2C\n\
+ pop {r3-r5}\n\
+ mov r8, r3\n\
+ mov r9, r4\n\
+ mov r10, r5\n\
+ pop {r4-r7}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .pool\n\
+ .syntax divided");
+#endif
+}
+
+NAKED
+static void MoveRelearnerMenuLoadContestMoveDescription(u32 chosenMove)
+{
+#ifdef NONMATCHING
+ //u8 offset;
+ const u8 *labelStr;
+ const struct ContestMove *move;
+ u8 category;
+ const u8 **temp;
+
+ MoveRelearnerShowHideHearts(chosenMove);
+ FillWindowPixelBuffer(1, PIXEL_FILL(1));
+ labelStr = gText_MoveRelearnerContestMovesTitle;
+ // GCC compiles these as:
+ // add r3, r0, 0
+ // lsls r3, r3, 24
+ // lsrs r3, r3, 24
+ // But in the original asm:
+ // lsls r3, r0, 24
+ // lsrs r3, r3, 24
+ //offset = GetStringCenterAlignXOffset(1, labelStr, 0x80);
+ AddTextPrinterParameterized(1, 1, labelStr, GetStringCenterAlignXOffset(1, labelStr, 0x80), 1, TEXT_SPEED_FF, NULL);
+
+ labelStr = gText_MoveRelearnerAppeal;
+ //offset = GetStringRightAlignXOffset(1, labelStr, 0x5C);
+ AddTextPrinterParameterized(1, 1, labelStr, GetStringCenterAlignXOffset(1, labelStr, 0x5C), 0x19, TEXT_SPEED_FF, NULL);
+
+ labelStr = gText_MoveRelearnerJam;
+ //offset = GetStringRightAlignXOffset(1, labelStr, 0x5C);
+ AddTextPrinterParameterized(1, 1, labelStr, GetStringCenterAlignXOffset(1, labelStr, 0x5C), 0x29, TEXT_SPEED_FF, NULL);
+
+ if (chosenMove == MENU_NOTHING_CHOSEN)
+ {
+ CopyWindowToVram(1, 2);
+ return;
+ }
+
+ move = &gContestMoves[chosenMove];
+ temp = (const u8**)gContestMoveTypeTextPointers;
+ category = move->contestCategory;
+ labelStr = temp[category];
+ AddTextPrinterParameterized(1, 1, labelStr, 4, 0x19, TEXT_SPEED_FF, NULL);
+
+ labelStr = gContestEffectDescriptionPointers[move->effect];
+ AddTextPrinterParameterized(1, 1, labelStr, 0, 0x41, TEXT_SPEED_FF, NULL);
+
+ CopyWindowToVram(1, 2);
+#else
+ asm(".syntax unified\n\
+ push {r4-r7,lr}\n\
+ mov r7, r8\n\
+ push {r7}\n\
+ sub sp, 0xC\n\
+ adds r4, r0, 0\n\
+ bl MoveRelearnerShowHideHearts\n\
+ movs r0, 0x1\n\
+ movs r1, 0x11\n\
+ bl FillWindowPixelBuffer\n\
+ ldr r5, =gText_MoveRelearnerContestMovesTitle\n\
+ movs r0, 0x1\n\
+ adds r1, r5, 0\n\
+ movs r2, 0x80\n\
+ bl GetStringCenterAlignXOffset\n\
+ lsls r3, r0, 24\n\
+ lsrs r3, 24\n\
+ movs r0, 0x1\n\
+ str r0, [sp]\n\
+ movs r7, 0xFF\n\
+ str r7, [sp, 0x4]\n\
+ movs r6, 0\n\
+ str r6, [sp, 0x8]\n\
+ movs r1, 0x1\n\
+ adds r2, r5, 0\n\
+ bl AddTextPrinterParameterized\n\
+ ldr r5, =gText_MoveRelearnerAppeal\n\
+ movs r0, 0x1\n\
+ adds r1, r5, 0\n\
+ movs r2, 0x5C\n\
+ bl GetStringRightAlignXOffset\n\
+ lsls r3, r0, 24\n\
+ lsrs r3, 24\n\
+ movs r0, 0x19\n\
+ mov r8, r0\n\
+ str r0, [sp]\n\
+ str r7, [sp, 0x4]\n\
+ str r6, [sp, 0x8]\n\
+ movs r0, 0x1\n\
+ movs r1, 0x1\n\
+ adds r2, r5, 0\n\
+ bl AddTextPrinterParameterized\n\
+ ldr r5, =gText_MoveRelearnerJam\n\
+ movs r0, 0x1\n\
+ adds r1, r5, 0\n\
+ movs r2, 0x5C\n\
+ bl GetStringRightAlignXOffset\n\
+ lsls r3, r0, 24\n\
+ lsrs r3, 24\n\
+ movs r0, 0x29\n\
+ str r0, [sp]\n\
+ str r7, [sp, 0x4]\n\
+ str r6, [sp, 0x8]\n\
+ movs r0, 0x1\n\
+ movs r1, 0x1\n\
+ adds r2, r5, 0\n\
+ bl AddTextPrinterParameterized\n\
+ movs r0, 0x2\n\
+ negs r0, r0\n\
+ cmp r4, r0\n\
+ bne _081D2B6C\n\
+ movs r0, 0x1\n\
+ movs r1, 0x2\n\
+ bl CopyWindowToVram\n\
+ b _081D2BB8\n\
+ .pool\n\
+_081D2B6C:\n\
+ lsls r4, 3\n\
+ ldr r0, =gContestMoves\n\
+ adds r4, r0\n\
+ ldr r1, =gContestMoveTypeTextPointers\n\
+ ldrb r0, [r4, 0x1]\n\
+ lsls r0, 29\n\
+ lsrs r0, 27\n\
+ adds r0, r1\n\
+ ldr r5, [r0]\n\
+ mov r0, r8\n\
+ str r0, [sp]\n\
+ str r7, [sp, 0x4]\n\
+ str r6, [sp, 0x8]\n\
+ movs r0, 0x1\n\
+ movs r1, 0x1\n\
+ adds r2, r5, 0\n\
+ movs r3, 0x4\n\
+ bl AddTextPrinterParameterized\n\
+ ldr r1, =gContestEffectDescriptionPointers\n\
+ ldrb r0, [r4]\n\
+ lsls r0, 2\n\
+ adds r0, r1\n\
+ ldr r5, [r0]\n\
+ movs r0, 0x41\n\
+ str r0, [sp]\n\
+ str r7, [sp, 0x4]\n\
+ str r6, [sp, 0x8]\n\
+ movs r0, 0x1\n\
+ movs r1, 0x7\n\
+ adds r2, r5, 0\n\
+ movs r3, 0\n\
+ bl AddTextPrinterParameterized\n\
+ movs r0, 0x1\n\
+ movs r1, 0x2\n\
+ bl CopyWindowToVram\n\
+_081D2BB8:\n\
+ add sp, 0xC\n\
+ pop {r3}\n\
+ mov r8, r3\n\
+ pop {r4-r7}\n\
+ pop {r0}\n\
+ bx r0\n\
+ .pool\n\
+ .syntax divided");
+#endif
+}
+
+static void MoveRelearnerCursorCallback(s32 itemIndex, bool8 onInit, struct ListMenu *list)
+{
+ if (onInit != TRUE)
+ PlaySE(SE_SELECT);
+ MoveRelearnerLoadBattleMoveDescription(itemIndex);
+ MoveRelearnerMenuLoadContestMoveDescription(itemIndex);
+}
+
+void MoveRelearnerPrintText(u8 *str)
+{
+ u8 speed;
+
+ FillWindowPixelBuffer(3, PIXEL_FILL(1));
+ gTextFlags.canABSpeedUpPrint = TRUE;
+ speed = GetPlayerTextSpeedDelay();
+ AddTextPrinterParameterized2(3, 1, str, speed, NULL, TEXT_COLOR_DARK_GREY, TEXT_COLOR_WHITE, 3);
+}
+
+bool16 MoveRelearnerRunTextPrinters(void)
+{
+ RunTextPrinters();
+ return IsTextPrinterActive(3);
+}
+
+void MoveRelearnerCreateYesNoMenu(void)
+{
+ CreateYesNoMenu(&sMoveRelearnerYesNoMenuTemplate, 1, 0xE, 0);
+} \ No newline at end of file
diff --git a/src/move_relearner.c b/src/move_relearner.c
new file mode 100644
index 000000000..e148b9ace
--- /dev/null
+++ b/src/move_relearner.c
@@ -0,0 +1,976 @@
+#include "global.h"
+#include "main.h"
+#include "battle.h"
+#include "bg.h"
+#include "contest_effect.h"
+#include "data2.h"
+#include "event_data.h"
+#include "field_screen_effect.h"
+#include "gpu_regs.h"
+#include "move_relearner.h"
+#include "list_menu.h"
+#include "alloc.h"
+#include "menu.h"
+#include "menu_helpers.h"
+#include "menu_specialized.h"
+#include "overworld.h"
+#include "palette.h"
+#include "pokemon_summary_screen.h"
+#include "script.h"
+#include "sound.h"
+#include "sprite.h"
+#include "string_util.h"
+#include "strings.h"
+#include "task.h"
+#include "constants/rgb.h"
+#include "constants/songs.h"
+
+/*
+ * Move relearner state machine
+ * ------------------------
+ *
+ * Entry point: TeachMoveRelearnerMove
+ *
+ * TeachMoveRelearnerMove
+ * Task_WaitForFadeOut
+ * CB2_InitLearnMove
+ * - Creates moveDisplayArrowTask to listen to right/left buttons.
+ * - Creates moveListScrollArrowTask to listen to up/down buttons.
+ * - Whenever the selected move changes (and once on init), the MoveRelearnerCursorCallback
+ * is called (see sMoveRelearnerMovesListTemplate). That callback will reload the contest
+ * display and battle display windows for the new move. Both are always loaded in
+ * memory, but only the currently active one is copied to VRAM. The exception to this
+ * is the appeal and jam hearts, which are sprites. MoveRelearnerShowHideHearts is called
+ * while reloading the contest display to control them.
+ * DoMoveRelearnerMain: MENU_STATE_FADE_TO_BLACK
+ * DoMoveRelearnerMain: MENU_STATE_WAIT_FOR_FADE
+ * - Go to MENU_STATE_IDLE_BATTLE_MODE
+ *
+ * DoMoveRelearnerMain: MENU_STATE_SETUP_BATTLE_MODE
+ * DoMoveRelearnerMain: MENU_STATE_IDLE_BATTLE_MODE
+ * - If the player selected a move (pressed A), go to MENU_STATE_PRINT_TEACH_MOVE_PROMPT.
+ * - If the player cancelled (pressed B), go to MENU_STATE_PRINT_GIVE_UP_PROMPT.
+ * - If the player pressed left or right, swap the move display window to contest mode,
+ * and go to MENU_STATE_SETUP_CONTEST_MODE.
+ *
+ * DoMoveRelearnerMain: MENU_STATE_SETUP_CONTEST_MODE
+ * DoMoveRelearnerMain: MENU_STATE_IDLE_CONTEST_MODE
+ * - If the player selected a move, go to MENU_STATE_PRINT_TEACH_MOVE_PROMPT.
+ * - If the player cancelled, go to MENU_STATE_PRINT_GIVE_UP_PROMPT
+ * - If the player pressed left or right, swap the move display window to battle mode,
+ * and go to MENU_STATE_SETUP_BATTLE_MODE.
+ *
+ * DoMoveRelearnerMain: MENU_STATE_PRINT_TEACH_MOVE_PROMPT
+ * DoMoveRelearnerMain: MENU_STATE_TEACH_MOVE_CONFIRM
+ * - Wait for the player to confirm.
+ * - If cancelled, go to either MENU_STATE_SETUP_BATTLE_MODE or MENU_STATE_SETUP_CONTEST_MODE.
+ * - If confirmed and the pokemon had an empty move slot, set VAR_0x8004 to TRUE and go to
+ * MENU_STATE_PRINT_TEXT_THEN_FANFARE.
+ * - If confirmed and the pokemon doesn't have an empty move slot, go to
+ * MENU_STATE_PRINT_TRYING_TO_LEARN_PROMPT.
+ *
+ * DoMoveRelearnerMain: MENU_STATE_PRINT_TRYING_TO_LEARN_PROMPT
+ * DoMoveRelearnerMain: MENU_STATE_WAIT_FOR_TRYING_TO_LEARN
+ * DoMoveRelearnerMain: MENU_STATE_CONFIRM_DELETE_OLD_MOVE
+ * - If the player confirms, go to MENU_STATE_PRINT_WHICH_MOVE_PROMPT.
+ * - If the player cancels, go to MENU_STATE_PRINT_STOP_TEACHING
+ *
+ * DoMoveRelearnerMain: MENU_STATE_PRINT_STOP_TEACHING
+ * DoMoveRelearnerMain: MENU_STATE_WAIT_FOR_STOP_TEACHING
+ * DoMoveRelearnerMain: MENU_STATE_CONFIRM_STOP_TEACHING
+ * - If the player confirms, go to MENU_STATE_CHOOSE_SETUP_STATE.
+ * - If the player cancels, go back to MENU_STATE_PRINT_TRYING_TO_LEARN_PROMPT.
+ *
+ * DoMoveRelearnerMain: MENU_STATE_PRINT_WHICH_MOVE_PROMPT
+ * DoMoveRelearnerMain: MENU_STATE_SHOW_MOVE_SUMMARY_SCREEN
+ * - Go to ShowSelectMovePokemonSummaryScreen. When done, control returns to
+ * CB2_InitLearnMoveReturnFromSelectMove.
+ *
+ * DoMoveRelearnerMain: MENU_STATE_DOUBLE_FANFARE_FORGOT_MOVE
+ * DoMoveRelearnerMain: MENU_STATE_PRINT_TEXT_THEN_FANFARE
+ * DoMoveRelearnerMain: MENU_STATE_WAIT_FOR_FANFARE
+ * DoMoveRelearnerMain: MENU_STATE_WAIT_FOR_A_BUTTON
+ * DoMoveRelearnerMain: MENU_STATE_FADE_AND_RETURN
+ * DoMoveRelearnerMain: MENU_STATE_RETURN_TO_FIELD
+ * - Clean up and go to CB2_ReturnToField.
+ *
+ * DoMoveRelearnerMain: MENU_STATE_PRINT_GIVE_UP_PROMPT
+ * DoMoveRelearnerMain: MENU_STATE_GIVE_UP_CONFIRM
+ * - If the player confirms, go to MENU_STATE_FADE_AND_RETURN, and set VAR_0x8004 to FALSE.
+ * - If the player cancels, go to either MENU_STATE_SETUP_BATTLE_MODE or
+ * MENU_STATE_SETUP_CONTEST_MODE.
+ *
+ * CB2_InitLearnMoveReturnFromSelectMove:
+ * - Do most of the same stuff as CB2_InitLearnMove.
+ * DoMoveRelearnerMain: MENU_STATE_FADE_FROM_SUMMARY_SCREEN
+ * DoMoveRelearnerMain: MENU_STATE_TRY_OVERWRITE_MOVE
+ * - If any of the pokemon's existing moves were chosen, overwrite the move and
+ * go to MENU_STATE_DOUBLE_FANFARE_FORGOT_MOVE and set VAR_0x8004 to TRUE.
+ * - If the chosen move is the one the player selected before the summary screen,
+ * go to MENU_STATE_PRINT_STOP_TEACHING.
+ *
+ */
+
+#define MENU_STATE_FADE_TO_BLACK 0
+#define MENU_STATE_WAIT_FOR_FADE 1
+#define MENU_STATE_UNREACHABLE 2
+#define MENU_STATE_SETUP_BATTLE_MODE 3
+#define MENU_STATE_IDLE_BATTLE_MODE 4
+#define MENU_STATE_SETUP_CONTEST_MODE 5
+#define MENU_STATE_IDLE_CONTEST_MODE 6
+// State 7 is skipped.
+#define MENU_STATE_PRINT_TEACH_MOVE_PROMPT 8
+#define MENU_STATE_TEACH_MOVE_CONFIRM 9
+// States 10 and 11 are skipped.
+#define MENU_STATE_PRINT_GIVE_UP_PROMPT 12
+#define MENU_STATE_GIVE_UP_CONFIRM 13
+#define MENU_STATE_FADE_AND_RETURN 14
+#define MENU_STATE_RETURN_TO_FIELD 15
+#define MENU_STATE_PRINT_TRYING_TO_LEARN_PROMPT 16
+#define MENU_STATE_WAIT_FOR_TRYING_TO_LEARN 17
+#define MENU_STATE_CONFIRM_DELETE_OLD_MOVE 18
+#define MENU_STATE_PRINT_WHICH_MOVE_PROMPT 19
+#define MENU_STATE_SHOW_MOVE_SUMMARY_SCREEN 20
+// States 21, 22, and 23 are skipped.
+#define MENU_STATE_PRINT_STOP_TEACHING 24
+#define MENU_STATE_WAIT_FOR_STOP_TEACHING 25
+#define MENU_STATE_CONFIRM_STOP_TEACHING 26
+#define MENU_STATE_CHOOSE_SETUP_STATE 27
+#define MENU_STATE_FADE_FROM_SUMMARY_SCREEN 28
+#define MENU_STATE_TRY_OVERWRITE_MOVE 29
+#define MENU_STATE_DOUBLE_FANFARE_FORGOT_MOVE 30
+#define MENU_STATE_PRINT_TEXT_THEN_FANFARE 31
+#define MENU_STATE_WAIT_FOR_FANFARE 32
+#define MENU_STATE_WAIT_FOR_A_BUTTON 33
+
+// The different versions of hearts are selected using animation
+// commands.
+#define APPEAL_HEART_EMPTY 0
+#define APPEAL_HEART_FULL 1
+#define JAM_HEART_EMPTY 2
+#define JAM_HEART_FULL 3
+
+static EWRAM_DATA struct
+{
+ u8 state;
+ u8 heartSpriteIds[16]; /*0x001*/
+ u16 movesToLearn[4]; /*0x012*/
+ u8 filler1A[0x44 - 0x1A]; /*0x01A*/
+ u8 partyMon; /*0x044*/
+ u8 moveSlot; /*0x045*/
+ struct ListMenuItem menuItems[20]; /*0x048*/
+ u8 fillerE8[0x110 - 0xE8]; /*0x0E8*/
+ u8 numMenuChoices; /*0x110*/
+ u8 numToShowAtOnce; /*0x111*/
+ u8 moveListMenuTask; /*0x112*/
+ u8 moveListScrollArrowTask; /*0x113*/
+ u8 moveDisplayArrowTask; /*0x114*/
+ u16 scrollOffset; /*0x116*/
+} *sMoveRelearnerStruct = {0};
+
+static EWRAM_DATA struct {
+ u16 listOffset;
+ u16 listRow;
+ bool8 showContestInfo;
+} sMoveRelearnerMenuSate = {0};
+
+static const u16 sMoveRelearnerPaletteData[] = INCBIN_U16("graphics/interface/ui_learn_move.gbapal");
+
+// The arrow sprites in this spritesheet aren't used. The scroll-arrow system provides its own
+// arrow sprites.
+static const u8 sMoveRelearnerSpriteSheetData[] = INCBIN_U8("graphics/interface/ui_learn_move.4bpp");
+
+static const struct OamData sHeartSpriteOamData =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = ST_OAM_OBJ_NORMAL,
+ .mosaic = 0,
+ .bpp = ST_OAM_4BPP,
+ .shape = ST_OAM_SQUARE,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 0,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const struct OamData sUnusedOam1 =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = ST_OAM_OBJ_NORMAL,
+ .mosaic = 0,
+ .bpp = ST_OAM_4BPP,
+ .shape = ST_OAM_V_RECTANGLE,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 0,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const struct OamData sUnusedOam2 =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = ST_OAM_OBJ_NORMAL,
+ .mosaic = 0,
+ .bpp = ST_OAM_4BPP,
+ .shape = ST_OAM_H_RECTANGLE,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 0,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const struct SpriteSheet sMoveRelearnerSpriteSheet =
+{
+ .data = sMoveRelearnerSpriteSheetData,
+ .size = 0x180,
+ .tag = 5525
+};
+
+static const struct SpritePalette sMoveRelearnerPalette =
+{
+ .data = sMoveRelearnerPaletteData,
+ .tag = 5526
+};
+
+static const struct ScrollArrowsTemplate sDisplayModeArrowsTemplate =
+{
+ .firstArrowType = SCROLL_ARROW_LEFT,
+ .firstX = 27,
+ .firstY = 16,
+ .secondArrowType = SCROLL_ARROW_RIGHT,
+ .secondX = 117,
+ .secondY = 16,
+ .fullyUpThreshold = -1,
+ .fullyDownThreshold = -1,
+ .tileTag = 5325,
+ .palTag = 5325,
+ .palNum = 0,
+};
+
+static const struct ScrollArrowsTemplate sMoveListScrollArrowsTemplate =
+{
+ .firstArrowType = SCROLL_ARROW_UP,
+ .firstX = 192,
+ .firstY = 8,
+ .secondArrowType = SCROLL_ARROW_DOWN,
+ .secondX = 192,
+ .secondY = 104,
+ .fullyUpThreshold = 0,
+ .fullyDownThreshold = 0,
+ .tileTag = 5425,
+ .palTag = 5425,
+ .palNum = 0,
+};
+
+static const union AnimCmd sHeartSprite_AppealEmptyFrame[] =
+{
+ ANIMCMD_FRAME(8, 5, FALSE, FALSE),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sHeartSprite_AppealFullFrame[] =
+{
+ ANIMCMD_FRAME(9, 5, FALSE, FALSE),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sHeartSprite_JamEmptyFrame[] =
+{
+ ANIMCMD_FRAME(10, 5, FALSE, FALSE),
+ ANIMCMD_END
+};
+
+static const union AnimCmd sHeartSprite_JamFullFrame[] =
+{
+ ANIMCMD_FRAME(11, 5, FALSE, FALSE),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sHeartSpriteAnimationCommands[] =
+{
+ [APPEAL_HEART_EMPTY] = sHeartSprite_AppealEmptyFrame,
+ [APPEAL_HEART_FULL] = sHeartSprite_AppealFullFrame,
+ [JAM_HEART_EMPTY] = sHeartSprite_JamEmptyFrame,
+ [JAM_HEART_FULL] = sHeartSprite_JamFullFrame,
+};
+
+static const struct SpriteTemplate sConstestMoveHeartSprite =
+{
+ .tileTag = 5525,
+ .paletteTag = 5526,
+ .oam = &sHeartSpriteOamData,
+ .anims = sHeartSpriteAnimationCommands,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy
+};
+
+static const struct BgTemplate sMoveRelearnerMenuBackgroundTemplates[] =
+{
+ {
+ .bg = 0,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 31,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 0,
+ .baseTile = 0,
+ },
+ {
+ .bg = 1,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 30,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 1,
+ .baseTile = 0,
+ },
+};
+
+static void DoMoveRelearnerMain(void);
+static void CreateLearnableMovesList(void);
+static void CreateUISprites(void);
+static void CB2_MoveRelearnerMain(void);
+static void Task_WaitForFadeOut(u8 taskId);
+static void CB2_InitLearnMove(void);
+static void CB2_InitLearnMoveReturnFromSelectMove(void);
+static void InitMoveRelearnerBackgroundLayers(void);
+static void AddScrollArrows(void);
+static void HandleInput(u8);
+static void ShowTeachMoveText(u8);
+static s32 GetCurrentSelectedMove(void);
+static void FreeMoveRelearnerResources(void);
+static void RemoveScrollArrows(void);
+static void HideHeartSpritesAndShowTeachMoveText(bool8);
+
+static void VBlankCB_MoveRelearner(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+// Script arguments: The pokemon to teach is in VAR_0x8004
+void TeachMoveRelearnerMove(void)
+{
+ ScriptContext2_Enable();
+ CreateTask(Task_WaitForFadeOut, 10);
+ // Fade to black
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK);
+}
+
+static void Task_WaitForFadeOut(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ SetMainCallback2(CB2_InitLearnMove);
+ gFieldCallback = FieldCallback_ReturnToEventScript2;
+ DestroyTask(taskId);
+ }
+}
+
+static void CB2_InitLearnMove(void)
+{
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ ResetTasks();
+ clear_scheduled_bg_copies_to_vram();
+ sMoveRelearnerStruct = AllocZeroed(sizeof(*sMoveRelearnerStruct));
+ sMoveRelearnerStruct->partyMon = gSpecialVar_0x8004;
+ SetVBlankCallback(VBlankCB_MoveRelearner);
+
+ InitMoveRelearnerBackgroundLayers();
+ InitMoveRelearnerWindows(FALSE);
+
+ sMoveRelearnerMenuSate.listOffset = 0;
+ sMoveRelearnerMenuSate.listRow = 0;
+ sMoveRelearnerMenuSate.showContestInfo = FALSE;
+
+ CreateLearnableMovesList();
+
+ LoadSpriteSheet(&sMoveRelearnerSpriteSheet);
+ LoadSpritePalette(&sMoveRelearnerPalette);
+ CreateUISprites();
+
+ sMoveRelearnerStruct->moveListMenuTask = ListMenuInit(&gMultiuseListMenuTemplate, sMoveRelearnerMenuSate.listOffset, sMoveRelearnerMenuSate.listRow);
+ FillPalette(RGB_BLACK, 0, 2);
+ SetMainCallback2(CB2_MoveRelearnerMain);
+}
+
+static void CB2_InitLearnMoveReturnFromSelectMove(void)
+{
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ ResetTasks();
+ clear_scheduled_bg_copies_to_vram();
+ sMoveRelearnerStruct = AllocZeroed(sizeof(*sMoveRelearnerStruct));
+ sMoveRelearnerStruct->state = MENU_STATE_FADE_FROM_SUMMARY_SCREEN;
+ sMoveRelearnerStruct->partyMon = gSpecialVar_0x8004;
+ sMoveRelearnerStruct->moveSlot = gSpecialVar_0x8005;
+ SetVBlankCallback(VBlankCB_MoveRelearner);
+
+ InitMoveRelearnerBackgroundLayers();
+ InitMoveRelearnerWindows(sMoveRelearnerMenuSate.showContestInfo);
+ CreateLearnableMovesList();
+
+ LoadSpriteSheet(&sMoveRelearnerSpriteSheet);
+ LoadSpritePalette(&sMoveRelearnerPalette);
+ CreateUISprites();
+
+ sMoveRelearnerStruct->moveListMenuTask = ListMenuInit(&gMultiuseListMenuTemplate, sMoveRelearnerMenuSate.listOffset, sMoveRelearnerMenuSate.listRow);
+ FillPalette(RGB_BLACK, 0, 2);
+ SetMainCallback2(CB2_MoveRelearnerMain);
+}
+
+static void InitMoveRelearnerBackgroundLayers(void)
+{
+ ResetVramOamAndBgCntRegs();
+ ResetBgsAndClearDma3BusyFlags(0);
+ InitBgsFromTemplates(0, sMoveRelearnerMenuBackgroundTemplates, ARRAY_COUNT(sMoveRelearnerMenuBackgroundTemplates));
+ ResetAllBgsCoordinates();
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 |
+ DISPCNT_OBJ_1D_MAP |
+ DISPCNT_OBJ_ON);
+ ShowBg(0);
+ ShowBg(1);
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+}
+
+static void CB2_MoveRelearnerMain(void)
+{
+ DoMoveRelearnerMain();
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ do_scheduled_bg_tilemap_copies_to_vram();
+ UpdatePaletteFade();
+}
+
+static void FormatAndPrintText(const u8 *src)
+{
+ StringExpandPlaceholders(gStringVar4, src);
+ MoveRelearnerPrintText(gStringVar4);
+}
+
+// See the state machine doc at the top of the file.
+static void DoMoveRelearnerMain(void)
+{
+ switch (sMoveRelearnerStruct->state)
+ {
+ case MENU_STATE_FADE_TO_BLACK:
+ sMoveRelearnerStruct->state++;
+ HideHeartSpritesAndShowTeachMoveText(FALSE);
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK);
+ break;
+ case MENU_STATE_WAIT_FOR_FADE:
+ if (!gPaletteFade.active)
+ {
+ sMoveRelearnerStruct->state = MENU_STATE_IDLE_BATTLE_MODE;
+ }
+ break;
+ case MENU_STATE_UNREACHABLE:
+ sMoveRelearnerStruct->state++;
+ break;
+ case MENU_STATE_SETUP_BATTLE_MODE:
+
+ HideHeartSpritesAndShowTeachMoveText(FALSE);
+ sMoveRelearnerStruct->state++;
+ AddScrollArrows();
+ break;
+ case MENU_STATE_IDLE_BATTLE_MODE:
+ HandleInput(FALSE);
+ break;
+ case MENU_STATE_SETUP_CONTEST_MODE:
+ ShowTeachMoveText(FALSE);
+ sMoveRelearnerStruct->state++;
+ AddScrollArrows();
+ break;
+ case MENU_STATE_IDLE_CONTEST_MODE:
+ HandleInput(TRUE);
+ break;
+ case MENU_STATE_PRINT_TEACH_MOVE_PROMPT:
+ if (!MoveRelearnerRunTextPrinters())
+ {
+ MoveRelearnerCreateYesNoMenu();
+ sMoveRelearnerStruct->state++;
+ }
+ break;
+ case MENU_STATE_TEACH_MOVE_CONFIRM:
+ {
+ s8 selection = Menu_ProcessInputNoWrapClearOnChoose();
+
+ if (selection == 0)
+ {
+ if (GiveMoveToMon(&gPlayerParty[sMoveRelearnerStruct->partyMon], GetCurrentSelectedMove()) != 0xFFFF)
+ {
+ FormatAndPrintText(gText_MoveRelearnerPkmnLearnedMove);
+ gSpecialVar_0x8004 = TRUE;
+ sMoveRelearnerStruct->state = MENU_STATE_PRINT_TEXT_THEN_FANFARE;
+ }
+ else
+ {
+ sMoveRelearnerStruct->state = MENU_STATE_PRINT_TRYING_TO_LEARN_PROMPT;
+ }
+ }
+ else if (selection == MENU_B_PRESSED || selection == 1)
+ {
+ if (sMoveRelearnerMenuSate.showContestInfo == FALSE)
+ {
+ sMoveRelearnerStruct->state = MENU_STATE_SETUP_BATTLE_MODE;
+ }
+ else if (sMoveRelearnerMenuSate.showContestInfo == TRUE)
+ {
+ sMoveRelearnerStruct->state = MENU_STATE_SETUP_CONTEST_MODE;
+ }
+ }
+ }
+ break;
+ case MENU_STATE_PRINT_GIVE_UP_PROMPT:
+ if (!MoveRelearnerRunTextPrinters())
+ {
+ MoveRelearnerCreateYesNoMenu();
+ sMoveRelearnerStruct->state++;
+ }
+ break;
+ case MENU_STATE_GIVE_UP_CONFIRM:
+ {
+ s8 selection = Menu_ProcessInputNoWrapClearOnChoose();
+
+ if (selection == 0)
+ {
+ gSpecialVar_0x8004 = FALSE;
+ sMoveRelearnerStruct->state = MENU_STATE_FADE_AND_RETURN;
+ }
+ else if (selection == -1 || selection == 1)
+ {
+ if (sMoveRelearnerMenuSate.showContestInfo == FALSE)
+ {
+ sMoveRelearnerStruct->state = MENU_STATE_SETUP_BATTLE_MODE;
+ }
+ else if (sMoveRelearnerMenuSate.showContestInfo == TRUE)
+ {
+ sMoveRelearnerStruct->state = MENU_STATE_SETUP_CONTEST_MODE;
+ }
+ }
+ }
+ break;
+ case MENU_STATE_PRINT_TRYING_TO_LEARN_PROMPT:
+ FormatAndPrintText(gText_MoveRelearnerPkmnTryingToLearnMove);
+ sMoveRelearnerStruct->state++;
+ break;
+ case MENU_STATE_WAIT_FOR_TRYING_TO_LEARN:
+ if (!MoveRelearnerRunTextPrinters())
+ {
+ MoveRelearnerCreateYesNoMenu();
+ sMoveRelearnerStruct->state = MENU_STATE_CONFIRM_DELETE_OLD_MOVE;
+ }
+ break;
+ case MENU_STATE_CONFIRM_DELETE_OLD_MOVE:
+ {
+ s8 var = Menu_ProcessInputNoWrapClearOnChoose();
+
+ if (var == 0)
+ {
+ FormatAndPrintText(gText_MoveRelearnerWhichMoveToForget);
+ sMoveRelearnerStruct->state = MENU_STATE_PRINT_WHICH_MOVE_PROMPT;
+ }
+ else if (var == -1 || var == 1)
+ {
+ sMoveRelearnerStruct->state = MENU_STATE_PRINT_STOP_TEACHING;
+ }
+ }
+ break;
+ case MENU_STATE_PRINT_STOP_TEACHING:
+ StringCopy(gStringVar2, gMoveNames[GetCurrentSelectedMove()]);
+ FormatAndPrintText(gText_MoveRelearnerStopTryingToTeachMove);
+ sMoveRelearnerStruct->state++;
+ break;
+ case MENU_STATE_WAIT_FOR_STOP_TEACHING:
+ if (!MoveRelearnerRunTextPrinters())
+ {
+ MoveRelearnerCreateYesNoMenu();
+ sMoveRelearnerStruct->state++;
+ }
+ break;
+ case MENU_STATE_CONFIRM_STOP_TEACHING:
+ {
+ s8 var = Menu_ProcessInputNoWrapClearOnChoose();
+
+ if (var == 0)
+ {
+ sMoveRelearnerStruct->state = MENU_STATE_CHOOSE_SETUP_STATE;
+ }
+ else if (var == MENU_B_PRESSED || var == 1)
+ {
+ // What's the point? It gets set to MENU_STATE_PRINT_TRYING_TO_LEARN_PROMPT, anyway.
+ if (sMoveRelearnerMenuSate.showContestInfo == FALSE)
+ {
+ sMoveRelearnerStruct->state = MENU_STATE_SETUP_BATTLE_MODE;
+ }
+ else if (sMoveRelearnerMenuSate.showContestInfo == TRUE)
+ {
+ sMoveRelearnerStruct->state = MENU_STATE_SETUP_CONTEST_MODE;
+ }
+ sMoveRelearnerStruct->state = MENU_STATE_PRINT_TRYING_TO_LEARN_PROMPT;
+ }
+ }
+ break;
+ case MENU_STATE_CHOOSE_SETUP_STATE:
+ if (!MoveRelearnerRunTextPrinters())
+ {
+ FillWindowPixelBuffer(3, 0x11);
+ if (sMoveRelearnerMenuSate.showContestInfo == FALSE)
+ {
+ sMoveRelearnerStruct->state = MENU_STATE_SETUP_BATTLE_MODE;
+ }
+ else if (sMoveRelearnerMenuSate.showContestInfo == TRUE)
+ {
+ sMoveRelearnerStruct->state = MENU_STATE_SETUP_CONTEST_MODE;
+ }
+ }
+ break;
+ case MENU_STATE_PRINT_WHICH_MOVE_PROMPT:
+ if (!MoveRelearnerRunTextPrinters())
+ {
+ sMoveRelearnerStruct->state = MENU_STATE_SHOW_MOVE_SUMMARY_SCREEN;
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK);
+ }
+ break;
+ case MENU_STATE_SHOW_MOVE_SUMMARY_SCREEN:
+ if (!gPaletteFade.active)
+ {
+ ShowSelectMovePokemonSummaryScreen(gPlayerParty, sMoveRelearnerStruct->partyMon, gPlayerPartyCount - 1, CB2_InitLearnMoveReturnFromSelectMove, GetCurrentSelectedMove());
+ FreeMoveRelearnerResources();
+ }
+ break;
+ case 21:
+ if (!MoveRelearnerRunTextPrinters())
+ {
+ sMoveRelearnerStruct->state = MENU_STATE_FADE_AND_RETURN;
+ }
+ break;
+ case 22:
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK);
+ break;
+ case MENU_STATE_FADE_AND_RETURN:
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK);
+ sMoveRelearnerStruct->state++;
+ break;
+ case MENU_STATE_RETURN_TO_FIELD:
+ if (!gPaletteFade.active)
+ {
+ FreeMoveRelearnerResources();
+ SetMainCallback2(CB2_ReturnToField);
+ }
+ break;
+ case MENU_STATE_FADE_FROM_SUMMARY_SCREEN:
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK);
+ sMoveRelearnerStruct->state++;
+ if (sMoveRelearnerMenuSate.showContestInfo == FALSE)
+ {
+ HideHeartSpritesAndShowTeachMoveText(TRUE);
+ }
+ else if (sMoveRelearnerMenuSate.showContestInfo == TRUE)
+ {
+ ShowTeachMoveText(TRUE);
+ }
+ RemoveScrollArrows();
+ CopyWindowToVram(3, 2);
+ break;
+ case MENU_STATE_TRY_OVERWRITE_MOVE:
+ if (!gPaletteFade.active)
+ {
+ if (sMoveRelearnerStruct->moveSlot == MAX_MON_MOVES)
+ {
+ sMoveRelearnerStruct->state = MENU_STATE_PRINT_STOP_TEACHING;
+ }
+ else
+ {
+ u16 moveId = GetMonData(&gPlayerParty[sMoveRelearnerStruct->partyMon], MON_DATA_MOVE1 + sMoveRelearnerStruct->moveSlot);
+
+ StringCopy(gStringVar3, gMoveNames[moveId]);
+ RemoveMonPPBonus(&gPlayerParty[sMoveRelearnerStruct->partyMon], sMoveRelearnerStruct->moveSlot);
+ SetMonMoveSlot(&gPlayerParty[sMoveRelearnerStruct->partyMon], GetCurrentSelectedMove(), sMoveRelearnerStruct->moveSlot);
+ StringCopy(gStringVar2, gMoveNames[GetCurrentSelectedMove()]);
+ FormatAndPrintText(gText_MoveRelearnerAndPoof);
+ sMoveRelearnerStruct->state = MENU_STATE_DOUBLE_FANFARE_FORGOT_MOVE;
+ gSpecialVar_0x8004 = TRUE;
+ }
+ }
+ break;
+ case MENU_STATE_DOUBLE_FANFARE_FORGOT_MOVE:
+ if (!MoveRelearnerRunTextPrinters())
+ {
+ FormatAndPrintText(gText_MoveRelearnerPkmnForgotMoveAndLearnedNew);
+ sMoveRelearnerStruct->state = MENU_STATE_PRINT_TEXT_THEN_FANFARE;
+ PlayFanfare(MUS_FANFA1);
+ }
+ break;
+ case MENU_STATE_PRINT_TEXT_THEN_FANFARE:
+ if (!MoveRelearnerRunTextPrinters())
+ {
+ PlayFanfare(MUS_FANFA1);
+ sMoveRelearnerStruct->state = MENU_STATE_WAIT_FOR_FANFARE;
+ }
+ break;
+ case MENU_STATE_WAIT_FOR_FANFARE:
+ if (IsFanfareTaskInactive())
+ {
+ sMoveRelearnerStruct->state = MENU_STATE_WAIT_FOR_A_BUTTON;
+ }
+ break;
+ case MENU_STATE_WAIT_FOR_A_BUTTON:
+ if (gMain.newKeys & A_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ sMoveRelearnerStruct->state = MENU_STATE_FADE_AND_RETURN;
+ }
+ break;
+ }
+}
+
+static void FreeMoveRelearnerResources(void)
+{
+ RemoveScrollArrows();
+ DestroyListMenuTask(sMoveRelearnerStruct->moveListMenuTask, &sMoveRelearnerMenuSate.listOffset, &sMoveRelearnerMenuSate.listRow);
+ FreeAllWindowBuffers();
+ FREE_AND_SET_NULL(sMoveRelearnerStruct);
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+}
+
+// Note: The hearts are already made invisible by MoveRelearnerShowHideHearts,
+// which is called whenever the cursor in either list changes.
+static void HideHeartSpritesAndShowTeachMoveText(bool8 onlyHideSprites)
+{
+ s32 i;
+
+ for (i = 0; i < 16; i++)
+ {
+ gSprites[sMoveRelearnerStruct->heartSpriteIds[i]].invisible = TRUE;
+ }
+
+ if (!onlyHideSprites)
+ {
+ StringExpandPlaceholders(gStringVar4, gText_TeachWhichMoveToPkmn);
+ FillWindowPixelBuffer(3, 0x11);
+ AddTextPrinterParameterized(3, 1, gStringVar4, 0, 1, 0, NULL);
+ }
+}
+
+static void HandleInput(bool8 showContest)
+{
+ s32 itemId = ListMenu_ProcessInput(sMoveRelearnerStruct->moveListMenuTask);
+ ListMenuGetScrollAndRow(sMoveRelearnerStruct->moveListMenuTask, &sMoveRelearnerMenuSate.listOffset, &sMoveRelearnerMenuSate.listRow);
+
+ switch (itemId)
+ {
+ case LIST_NOTHING_CHOSEN:
+ if (!(gMain.newKeys & (DPAD_LEFT | DPAD_RIGHT)) && !GetLRKeysState())
+ {
+ break;
+ }
+
+ PlaySE(SE_SELECT);
+
+ if (showContest == FALSE)
+ {
+ PutWindowTilemap(1);
+ sMoveRelearnerStruct->state = MENU_STATE_SETUP_CONTEST_MODE;
+ sMoveRelearnerMenuSate.showContestInfo = TRUE;
+ }
+ else
+ {
+ PutWindowTilemap(0);
+ sMoveRelearnerStruct->state = MENU_STATE_SETUP_BATTLE_MODE;
+ sMoveRelearnerMenuSate.showContestInfo = FALSE;
+ }
+
+ schedule_bg_copy_tilemap_to_vram(1);
+ MoveRelearnerShowHideHearts(GetCurrentSelectedMove());
+ break;
+ case LIST_CANCEL:
+ PlaySE(SE_SELECT);
+ RemoveScrollArrows();
+ sMoveRelearnerStruct->state = MENU_STATE_PRINT_GIVE_UP_PROMPT;
+ StringExpandPlaceholders(gStringVar4, gText_MoveRelearnerGiveUp);
+ MoveRelearnerPrintText(gStringVar4);
+ break;
+ default:
+ PlaySE(SE_SELECT);
+ RemoveScrollArrows();
+ sMoveRelearnerStruct->state = MENU_STATE_PRINT_TEACH_MOVE_PROMPT;
+ StringCopy(gStringVar2, gMoveNames[itemId]);
+ StringExpandPlaceholders(gStringVar4, gText_MoveRelearnerTeachMoveConfirm);
+ MoveRelearnerPrintText(gStringVar4);
+ break;
+ }
+}
+
+static s32 GetCurrentSelectedMove(void)
+{
+ return sMoveRelearnerStruct->menuItems[sMoveRelearnerMenuSate.listRow + sMoveRelearnerMenuSate.listOffset].id;
+}
+
+// Theory: This used to make the heart sprites visible again (i.e.
+// this was the inverse of HideHeartsAndShowTeachMoveText), but the
+// code was commented out. The bool argument would have been named
+// "justShowHearts." The code for showing/hiding the heards was moved
+// to MoveRelearnerShowHideHearts, which is called whenever a new move is
+// selected and whenever the display mode changes.
+static void ShowTeachMoveText(bool8 shouldDoNothingInstead)
+{
+ if (shouldDoNothingInstead == FALSE)
+ {
+ StringExpandPlaceholders(gStringVar4, gText_TeachWhichMoveToPkmn);
+ FillWindowPixelBuffer(3, 0x11);
+ AddTextPrinterParameterized(3, 1, gStringVar4, 0, 1, 0, NULL);
+ }
+}
+
+static void CreateUISprites(void)
+{
+ int i;
+
+ sMoveRelearnerStruct->moveDisplayArrowTask = 0xFF;
+ sMoveRelearnerStruct->moveListScrollArrowTask = 0xFF;
+ AddScrollArrows();
+
+ // These are the appeal hearts.
+ for (i = 0; i < 8; i++)
+ {
+ sMoveRelearnerStruct->heartSpriteIds[i] = CreateSprite(&sConstestMoveHeartSprite, (i - (i / 4) * 4) * 8 + 104, (i / 4) * 8 + 36, 0);
+ }
+
+ // These are the jam harts.
+ // The animation is used to toggle between full/empty heart sprites.
+ for (i = 0; i < 8; i++)
+ {
+ sMoveRelearnerStruct->heartSpriteIds[i + 8] = CreateSprite(&sConstestMoveHeartSprite, (i - (i / 4) * 4) * 8 + 104, (i / 4) * 8 + 52, 0);
+ StartSpriteAnim(&gSprites[sMoveRelearnerStruct->heartSpriteIds[i + 8]], 2);
+ }
+
+ for (i = 0; i < 16; i++)
+ {
+ gSprites[sMoveRelearnerStruct->heartSpriteIds[i]].invisible = TRUE;
+ }
+}
+
+static void AddScrollArrows(void)
+{
+ if (sMoveRelearnerStruct->moveDisplayArrowTask == 0xFF)
+ {
+ sMoveRelearnerStruct->moveDisplayArrowTask = AddScrollIndicatorArrowPair(&sDisplayModeArrowsTemplate, &sMoveRelearnerStruct->scrollOffset);
+ }
+
+ if (sMoveRelearnerStruct->moveListScrollArrowTask == 0xFF)
+ {
+ gTempScrollArrowTemplate = sMoveListScrollArrowsTemplate;
+ gTempScrollArrowTemplate.fullyDownThreshold = sMoveRelearnerStruct->numMenuChoices - sMoveRelearnerStruct->numToShowAtOnce;
+ sMoveRelearnerStruct->moveListScrollArrowTask = AddScrollIndicatorArrowPair(&gTempScrollArrowTemplate, &sMoveRelearnerMenuSate.listOffset);
+ }
+}
+
+static void RemoveScrollArrows(void)
+{
+ if (sMoveRelearnerStruct->moveDisplayArrowTask != 0xFF)
+ {
+ RemoveScrollIndicatorArrowPair(sMoveRelearnerStruct->moveDisplayArrowTask);
+ sMoveRelearnerStruct->moveDisplayArrowTask = 0xFF;
+ }
+
+ if (sMoveRelearnerStruct->moveListScrollArrowTask != 0xFF)
+ {
+ RemoveScrollIndicatorArrowPair(sMoveRelearnerStruct->moveListScrollArrowTask);
+ sMoveRelearnerStruct->moveListScrollArrowTask = 0xFF;
+ }
+}
+
+static void CreateLearnableMovesList(void)
+{
+ s32 i;
+ u8 nickname[POKEMON_NAME_LENGTH + 1];
+
+ sMoveRelearnerStruct->numMenuChoices = GetMoveRelearnerMoves(&gPlayerParty[sMoveRelearnerStruct->partyMon], sMoveRelearnerStruct->movesToLearn);
+
+ for (i = 0; i < sMoveRelearnerStruct->numMenuChoices; i++)
+ {
+ sMoveRelearnerStruct->menuItems[i].name = gMoveNames[sMoveRelearnerStruct->movesToLearn[i]];
+ sMoveRelearnerStruct->menuItems[i].id = sMoveRelearnerStruct->movesToLearn[i];
+ }
+
+ GetMonData(&gPlayerParty[sMoveRelearnerStruct->partyMon], MON_DATA_NICKNAME, nickname);
+ StringCopy10(gStringVar1, nickname);
+ sMoveRelearnerStruct->menuItems[sMoveRelearnerStruct->numMenuChoices].name = gText_Cancel;
+ sMoveRelearnerStruct->menuItems[sMoveRelearnerStruct->numMenuChoices].id = LIST_CANCEL;
+ sMoveRelearnerStruct->numMenuChoices++;
+ sMoveRelearnerStruct->numToShowAtOnce = LoadMoveRelearnerMovesList(sMoveRelearnerStruct->menuItems, sMoveRelearnerStruct->numMenuChoices);
+}
+
+void MoveRelearnerShowHideHearts(s32 moveId)
+{
+ u16 numHearts;
+ u16 i;
+
+ if (!sMoveRelearnerMenuSate.showContestInfo || moveId == LIST_CANCEL)
+ {
+ for (i = 0; i < 16; i++)
+ {
+ gSprites[sMoveRelearnerStruct->heartSpriteIds[i]].invisible = TRUE;
+ }
+ }
+ else
+ {
+ numHearts = (u8)(gContestEffects[gContestMoves[moveId].effect].appeal / 10);
+
+ if (numHearts == 0xFF)
+ {
+ numHearts = 0;
+ }
+
+ for (i = 0; i < 8; i++)
+ {
+ if (i < numHearts)
+ {
+ StartSpriteAnim(&gSprites[sMoveRelearnerStruct->heartSpriteIds[i]], 1);
+ }
+ else
+ {
+ StartSpriteAnim(&gSprites[sMoveRelearnerStruct->heartSpriteIds[i]], 0);
+ }
+ gSprites[sMoveRelearnerStruct->heartSpriteIds[i]].invisible = FALSE;
+ }
+
+ numHearts = (u8)(gContestEffects[gContestMoves[moveId].effect].jam / 10);
+
+ if (numHearts == 0xFF)
+ {
+ numHearts = 0;
+ }
+
+ for (i = 0; i < 8; i++)
+ {
+ if (i < numHearts)
+ {
+ StartSpriteAnim(&gSprites[sMoveRelearnerStruct->heartSpriteIds[i + 8]], 3);
+ }
+ else
+ {
+ StartSpriteAnim(&gSprites[sMoveRelearnerStruct->heartSpriteIds[i + 8]], 2);
+ }
+ gSprites[sMoveRelearnerStruct->heartSpriteIds[i + 8]].invisible = FALSE;
+ }
+ }
+}
diff --git a/src/overworld.c b/src/overworld.c
index 0ff8d5b7f..ce1e21ab1 100644
--- a/src/overworld.c
+++ b/src/overworld.c
@@ -1688,7 +1688,7 @@ void CB2_ReturnToFieldContinueScript(void)
void CB2_ReturnToFieldContinueScriptPlayMapMusic(void)
{
FieldClearVBlankHBlankCallbacks();
- gFieldCallback = sub_80AF168;
+ gFieldCallback = FieldCallback_ReturnToEventScript2;
CB2_ReturnToField();
}
diff --git a/src/party_menu.c b/src/party_menu.c
index bedd0ce57..7db24b6ca 100755
--- a/src/party_menu.c
+++ b/src/party_menu.c
@@ -37,15 +37,16 @@
#include "main.h"
#include "menu.h"
#include "menu_helpers.h"
+#include "menu_specialized.h"
#include "metatile_behavior.h"
#include "overworld.h"
#include "palette.h"
#include "party_menu.h"
+#include "player_pc.h"
#include "pokemon.h"
#include "pokemon_icon.h"
#include "pokemon_storage_system.h"
#include "pokemon_summary_screen.h"
-#include "pokenav.h"
#include "region_map.h"
#include "reshow_battle_screen.h"
#include "rom_8011DC0.h"
@@ -6006,7 +6007,7 @@ static void sub_81B767C(u8 taskId)
s16 *arrayPtr = gUnknown_0203CEC4->data;
arrayPtr[12] = sub_81B3364();
- sub_81D3640(arrayPtr[12], arrayPtr, &arrayPtr[6], 1, 2, 3);
+ DrawLevelUpWindowPg1(arrayPtr[12], arrayPtr, &arrayPtr[6], 1, 2, 3);
CopyWindowToVram(arrayPtr[12], 2);
schedule_bg_copy_tilemap_to_vram(2);
}
@@ -6015,7 +6016,7 @@ static void sub_81B76C8(u8 taskId)
{
s16 *arrayPtr = gUnknown_0203CEC4->data;
- sub_81D3784(arrayPtr[12], &arrayPtr[6], 1, 2, 3);
+ DrawLevelUpWindowPg2(arrayPtr[12], &arrayPtr[6], 1, 2, 3);
CopyWindowToVram(arrayPtr[12], 2);
schedule_bg_copy_tilemap_to_vram(2);
}
@@ -7288,7 +7289,7 @@ static void sub_81B9640(u8 taskId)
void sub_81B968C(void)
{
ShowPokemonSummaryScreen(PSS_MODE_SELECT_MOVE, gPlayerParty, gSpecialVar_0x8004, gPlayerPartyCount - 1, CB2_ReturnToField);
- gFieldCallback = sub_80AF168;
+ gFieldCallback = FieldCallback_ReturnToEventScript2;
}
void sub_81B96D0(void)
diff --git a/src/player_pc.c b/src/player_pc.c
index 6e78533e7..49b9cc5f5 100644
--- a/src/player_pc.c
+++ b/src/player_pc.c
@@ -20,7 +20,6 @@
#include "overworld.h"
#include "palette.h"
#include "party_menu.h"
-#include "pokenav.h"
#include "player_pc.h"
#include "script.h"
#include "sound.h"
@@ -29,6 +28,7 @@
#include "strings.h"
#include "task.h"
#include "window.h"
+#include "menu_specialized.h"
// structures
struct Struct203BCC4
@@ -645,7 +645,7 @@ static void Mailbox_ProcessInput(u8 taskId)
{
case LIST_NOTHING_CHOSEN:
break;
- case LIST_B_PRESSED:
+ case LIST_CANCEL:
PlaySE(SE_SELECT);
RemoveScrollIndicatorArrowPair(playerPCItemPageInfo.scrollIndicatorId);
Mailbox_ReturnToPlayerPC(taskId);
@@ -1151,7 +1151,7 @@ static void ItemStorage_ProcessInput(u8 taskId)
{
case LIST_NOTHING_CHOSEN:
break;
- case LIST_B_PRESSED:
+ case LIST_CANCEL:
PlaySE(SE_SELECT);
ItemStorage_GoBackToPlayerPCMenu(taskId);
break;
@@ -1226,7 +1226,7 @@ static void sub_816C4FC(u8 taskId)
{
case LIST_NOTHING_CHOSEN:
break;
- case LIST_B_PRESSED:
+ case LIST_CANCEL:
if (gMain.newKeys & A_BUTTON)
{
ItemStorage_DoItemSwap(taskId, FALSE);
diff --git a/src/pokeblock.c b/src/pokeblock.c
index ee18d0251..325c2d5d0 100644
--- a/src/pokeblock.c
+++ b/src/pokeblock.c
@@ -709,7 +709,7 @@ static void HandlePokeblockListMenuItems(void)
StringCopy(sPokeblockMenu->menuItemsStrings[i], gText_StowCase);
sPokeblockMenu->items[i].name = sPokeblockMenu->menuItemsStrings[i];
- sPokeblockMenu->items[i].id = LIST_B_PRESSED;
+ sPokeblockMenu->items[i].id = LIST_CANCEL;
gMultiuseListMenuTemplate = sPokeblockListMenuTemplate;
gMultiuseListMenuTemplate.fontId = 7;
@@ -751,7 +751,7 @@ static void sub_8135FCC(s32 pkblId)
FillWindowPixelBuffer(7, PIXEL_FILL(0));
- if (pkblId != LIST_B_PRESSED)
+ if (pkblId != LIST_CANCEL)
{
pokeblock = &gSaveBlock1Ptr->pokeblocks[pkblId];
rectTilemapSrc[0] = 0x17;
@@ -959,7 +959,7 @@ static void Task_FreeDataAndExitPokeblockCase(u8 taskId)
if (!gPaletteFade.active)
{
if (sPokeblockMenu->caseId == PBLOCK_CASE_FEEDER || sPokeblockMenu->caseId == PBLOCK_CASE_GIVE)
- gFieldCallback = sub_80AF168;
+ gFieldCallback = FieldCallback_ReturnToEventScript2;
DestroyListMenuTask(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
sub_8136418();
@@ -1011,7 +1011,7 @@ static void Task_HandlePokeblockMenuInput(u8 taskId)
{
case LIST_NOTHING_CHOSEN:
break;
- case LIST_B_PRESSED:
+ case LIST_CANCEL:
PlaySE(SE_SELECT);
gSpecialVar_Result = 0xFFFF;
gSpecialVar_ItemId = 0;
@@ -1066,7 +1066,7 @@ static void Task_HandlePokeblocksSwapInput(u8 taskId)
{
case LIST_NOTHING_CHOSEN:
break;
- case LIST_B_PRESSED: // same id as STOW CASE field
+ case LIST_CANCEL: // same id as STOW CASE field
PlaySE(SE_SELECT);
if (gMain.newKeys & A_BUTTON)
HandlePokeblocksSwap(taskId, FALSE);
diff --git a/src/roulette.c b/src/roulette.c
index 5c08c99a0..39db5630b 100644
--- a/src/roulette.c
+++ b/src/roulette.c
@@ -1984,7 +1984,7 @@ static void sub_8141E7C(u8 taskId) // end roulette ?
ResetPaletteFade();
ResetSpriteData();
sub_8140418();
- gFieldCallback = sub_80AF168;
+ gFieldCallback = FieldCallback_ReturnToEventScript2;
SetMainCallback2(CB2_ReturnToField);
DestroyTask(taskId);
}
diff --git a/src/secret_base.c b/src/secret_base.c
index 4b270e424..e19aecba3 100644
--- a/src/secret_base.c
+++ b/src/secret_base.c
@@ -389,7 +389,7 @@ void sub_80E8FD0(u8 taskId)
}
sub_80E8F9C();
WarpIntoMap();
- gFieldCallback = sub_80AF168;
+ gFieldCallback = FieldCallback_ReturnToEventScript2;
SetMainCallback2(CB2_LoadMap);
DestroyTask(taskId);
break;
@@ -957,7 +957,7 @@ void sub_80E9E90(u8 taskId)
{
case LIST_NOTHING_CHOSEN:
break;
- case LIST_B_PRESSED:
+ case LIST_CANCEL:
PlaySE(SE_SELECT);
DestroyListMenuTask(data[5], NULL, NULL);
RemoveScrollIndicatorArrowPair(data[8]);
diff --git a/src/shop.c b/src/shop.c
index e03e2ab0c..32caafb64 100755
--- a/src/shop.c
+++ b/src/shop.c
@@ -918,7 +918,7 @@ static void Task_BuyMenu(u8 taskId)
{
case LIST_NOTHING_CHOSEN:
break;
- case LIST_B_PRESSED:
+ case LIST_CANCEL:
PlaySE(SE_SELECT);
ExitBuyMenu(taskId);
break;
diff --git a/src/strings.c b/src/strings.c
index f81a19083..577d26f5c 100644
--- a/src/strings.c
+++ b/src/strings.c
@@ -1742,23 +1742,23 @@ const u8 gText_TrainerHill2F[] = _("2F");
const u8 gText_TrainerHill3F[] = _("3F");
const u8 gText_TrainerHill4F[] = _("4F");
const u8 gText_TeachWhichMoveToPkmn[] = _("Teach which move to {STR_VAR_1}?");
-const u8 gText_TeachX[] = _("Teach {STR_VAR_2}?");
-const u8 gText_PkmnLearnedMove4[] = _("{STR_VAR_1} learned\n{STR_VAR_2}!");
-const u8 gText_PkmnTryingToLearnMove[] = _("{STR_VAR_1} is trying to learn\n{STR_VAR_2}.\pBut {STR_VAR_1} can't learn more\nthan four moves.\pDelete an older move to make\nroom for {STR_VAR_2}?");
-const u8 gText_StopTryingToTeachMove[] = _("Stop trying to teach\n{STR_VAR_2}?");
-const u8 gText_12AndPoof[] = _("{PAUSE 32}1, {PAUSE 15}2, and {PAUSE 15}… {PAUSE 15}… {PAUSE 15}… {PAUSE 15}{PLAY_SE 0x0038}Poof!\p");
-const u8 gText_PkmnForgotMoveAndLearnedNew[] = _("{STR_VAR_1} forgot {STR_VAR_3}.\pAnd…\p{STR_VAR_1} learned {STR_VAR_2}.");
+const u8 gText_MoveRelearnerTeachMoveConfirm[] = _("Teach {STR_VAR_2}?");
+const u8 gText_MoveRelearnerPkmnLearnedMove[] = _("{STR_VAR_1} learned\n{STR_VAR_2}!");
+const u8 gText_MoveRelearnerPkmnTryingToLearnMove[] = _("{STR_VAR_1} is trying to learn\n{STR_VAR_2}.\pBut {STR_VAR_1} can't learn more\nthan four moves.\pDelete an older move to make\nroom for {STR_VAR_2}?");
+const u8 gText_MoveRelearnerStopTryingToTeachMove[] = _("Stop trying to teach\n{STR_VAR_2}?");
+const u8 gText_MoveRelearnerAndPoof[] = _("{PAUSE 32}1, {PAUSE 15}2, and {PAUSE 15}… {PAUSE 15}… {PAUSE 15}… {PAUSE 15}{PLAY_SE 0x0038}Poof!\p");
+const u8 gText_MoveRelearnerPkmnForgotMoveAndLearnedNew[] = _("{STR_VAR_1} forgot {STR_VAR_3}.\pAnd…\p{STR_VAR_1} learned {STR_VAR_2}.");
const u8 gUnknown_085EF9C8[] = _("{STR_VAR_1} did not learn the\nmove {STR_VAR_2}.");
-const u8 gText_GiveUpTeachingNewMove[] = _("Give up trying to teach a new\nmove to {STR_VAR_1}?");
-const u8 gText_WhichMoveToForget2[] = _("Which move should be\nforgotten?\p");
-const u8 gText_BattleMoves2[] = _("BATTLE MOVES");
-const u8 gText_ContestMoves2[] = _("CONTEST MOVES");
+const u8 gText_MoveRelearnerGiveUp[] = _("Give up trying to teach a new\nmove to {STR_VAR_1}?");
+const u8 gText_MoveRelearnerWhichMoveToForget[] = _("Which move should be\nforgotten?\p");
+const u8 gText_MoveRelearnerBattleMoves[] = _("BATTLE MOVES");
+const u8 gText_MoveRelearnerContestMovesTitle[] = _("CONTEST MOVES");
const u8 gUnknown_085EFA4C[] = _("TYPE/");
-const u8 gText_PPSlash[] = _("PP/");
-const u8 gText_PowerSlash[] = _("POWER/");
-const u8 gText_AccuracySlash[] = _("ACCURACY/");
-const u8 gText_Appeal2[] = _("APPEAL");
-const u8 gText_Jam2[] = _("JAM");
+const u8 gText_MoveRelearnerPP[] = _("PP/");
+const u8 gText_MoveRelearnerPower[] = _("POWER/");
+const u8 gText_MoveRelearnerAccuracy[] = _("ACCURACY/");
+const u8 gText_MoveRelearnerAppeal[] = _("APPEAL");
+const u8 gText_MoveRelearnerJam[] = _("JAM");
const u8 gText_Kira[] = _("KIRA");
const u8 gText_Amy[] = _("AMY");
const u8 gText_John[] = _("JOHN");
diff --git a/src/trade.c b/src/trade.c
index be6768fe3..df8f493f1 100644
--- a/src/trade.c
+++ b/src/trade.c
@@ -6141,7 +6141,7 @@ static void sub_807F110(u8 taskId)
if (!gPaletteFade.active)
{
SetMainCallback2(sub_807B270);
- gFieldCallback = sub_80AF168;
+ gFieldCallback = FieldCallback_ReturnToEventScript2;
DestroyTask(taskId);
}
}
diff --git a/src/use_pokeblock.c b/src/use_pokeblock.c
index 762019ecd..b06d0cba9 100644
--- a/src/use_pokeblock.c
+++ b/src/use_pokeblock.c
@@ -4,6 +4,7 @@
#include "alloc.h"
#include "palette.h"
#include "pokenav.h"
+#include "menu_specialized.h"
#include "scanline_effect.h"
#include "text.h"
#include "bg.h"
@@ -33,7 +34,7 @@ struct UsePokeblockSubStruct
struct UsePokeblockStruct
{
u8 field_0[0x7C58];
- u8 field_7C58[0x378];
+ struct UnknownStruct_81D1ED4 field_7C58;
struct UsePokeblockSubStruct info;
};
@@ -130,7 +131,7 @@ void sub_8166340(void)
LoadOam();
ProcessSpriteCopyRequests();
TransferPlttBuffer();
- sub_81D2108(gUnknown_0203BCAC->field_7C58);
+ sub_81D2108(&gUnknown_0203BCAC->field_7C58);
ScanlineEffect_InitHBlankDmaTransfer();
}
@@ -146,7 +147,7 @@ void sub_8166380(void)
{
case 0:
gUnknown_0203BCAC->field_0[0x7B10] = 0xFF;
- sub_81D1ED4(gUnknown_0203BCAC->field_7C58);
+ sub_81D1ED4(&gUnknown_0203BCAC->field_7C58);
gUnknown_0203BC90->field_50++;
break;
case 1:
@@ -202,19 +203,19 @@ void sub_8166380(void)
gUnknown_0203BC90->field_50++;
break;
case 11:
- sub_81D2754(gUnknown_0203BCAC->field_7C58, &gUnknown_0203BCAC->field_0[0x7C6C]);
- sub_81D20AC(gUnknown_0203BCAC->field_7C58);
+ sub_81D2754(&gUnknown_0203BCAC->field_7C58, gUnknown_0203BCAC->field_7C58.unk14[0]);
+ sub_81D20AC(&gUnknown_0203BCAC->field_7C58);
gUnknown_0203BC90->field_50++;
break;
case 12:
- if (!sub_81D20BC(gUnknown_0203BCAC->field_7C58))
+ if (!sub_81D20BC(&gUnknown_0203BCAC->field_7C58))
{
- sub_81D1F84(gUnknown_0203BCAC->field_7C58, &gUnknown_0203BCAC->field_7C58[0x14], &gUnknown_0203BCAC->field_7C58[0x14]);
+ sub_81D1F84(&gUnknown_0203BCAC->field_7C58, gUnknown_0203BCAC->field_7C58.unk14, gUnknown_0203BCAC->field_7C58.unk14);
gUnknown_0203BC90->field_50++;
}
break;
case 13:
- sub_81D2230(gUnknown_0203BCAC->field_7C58);
+ sub_81D2230(&gUnknown_0203BCAC->field_7C58);
gUnknown_0203BC90->field_50++;
break;
case 14:
diff --git a/src/walda_phrase.c b/src/walda_phrase.c
index 83004777f..e8c1e4aed 100644
--- a/src/walda_phrase.c
+++ b/src/walda_phrase.c
@@ -70,7 +70,7 @@ static void CB2_HandleGivenWaldaPhrase(void)
}
StringCopy(gStringVar1, GetWaldaPhrasePtr());
- gFieldCallback = sub_80AF168;
+ gFieldCallback = FieldCallback_ReturnToEventScript2;
SetMainCallback2(CB2_ReturnToField);
}