summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/battle_controller_safari.c7
-rw-r--r--src/berry_blender.c2
-rw-r--r--src/daycare.c9
-rw-r--r--src/decoration.c24
-rw-r--r--src/lilycove_lady.c2
-rw-r--r--src/new_game.c3
-rw-r--r--src/pokeblock.c1017
-rw-r--r--src/pokeblock_feed.c1108
-rw-r--r--src/pokemon_3.c12
-rwxr-xr-xsrc/pokemon_summary_screen.c8
-rw-r--r--src/safari_zone.c2
-rw-r--r--src/secret_base.c24
-rw-r--r--src/use_pokeblock.c230
13 files changed, 2401 insertions, 47 deletions
diff --git a/src/battle_controller_safari.c b/src/battle_controller_safari.c
index db4670523..64e6a0bc3 100644
--- a/src/battle_controller_safari.c
+++ b/src/battle_controller_safari.c
@@ -19,6 +19,7 @@
#include "reshow_battle_screen.h"
#include "pokeball.h"
#include "data2.h"
+#include "pokeblock.h"
extern u32 gBattleExecBuffer;
extern u8 gActiveBank;
@@ -291,13 +292,13 @@ static void CompleteOnSpecialAnimDone(void)
SafariBufferExecCompleted();
}
-static void OpenPokeblockCase(void)
+static void SafariOpenPokeblockCase(void)
{
if (!gPaletteFade.active)
{
gBattleBankFunc[gActiveBank] = CompleteWhenChosePokeblock;
FreeAllWindowBuffers();
- sub_81358F4();
+ OpenPokeblockCaseInBattle();
}
}
@@ -497,7 +498,7 @@ static void SafariHandleChooseItem(void)
s32 i;
BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
- gBattleBankFunc[gActiveBank] = OpenPokeblockCase;
+ gBattleBankFunc[gActiveBank] = SafariOpenPokeblockCase;
gBankInMenu = gActiveBank;
}
diff --git a/src/berry_blender.c b/src/berry_blender.c
index b1d36e2d9..fe646954d 100644
--- a/src/berry_blender.c
+++ b/src/berry_blender.c
@@ -134,8 +134,6 @@ extern u8 gInGameOpponentsNo;
extern u8 gUnknown_020322D5;
extern u8 gResultsWindowId;
-extern const u8 * const gPokeblockNames[];
-
// graphics
extern const u8 gBerryBlenderArrowTiles[];
extern const u8 gBerryBlenderStartTiles[];
diff --git a/src/daycare.c b/src/daycare.c
index ce9952531..59ee562bd 100644
--- a/src/daycare.c
+++ b/src/daycare.c
@@ -40,7 +40,7 @@ extern const u8 gDaycareText_PlayOther[];
extern u8 GetCursorSelectionMonId(void);
extern u16 ItemIdToBattleMoveId(u16);
-extern s32 ListMenuHandleInput(u8);
+extern s32 ListMenuHandleInputGetItemId(u8);
extern void sub_81AE6C8(u8, u16*, u16*);
extern void sub_819746C(u8, bool8);
extern void sub_81973FC(u8, bool8);
@@ -75,7 +75,7 @@ static const struct ListMenuItem sLevelMenuItems[] =
static const struct ListMenuTemplate sDaycareListMenuLevelTemplate =
{
.items = sLevelMenuItems,
- .unk_04 = sub_81AF078,
+ .moveCursorFunc = sub_81AF078,
.unk_08 = DaycarePrintMonInfo,
.totalItems = 3,
.maxShowed = 3,
@@ -90,7 +90,8 @@ static const struct ListMenuTemplate sDaycareListMenuLevelTemplate =
.unk_16_0 = TRUE,
.spaceBetweenItems = 0,
.unk_16_7 = FALSE,
- .unk_17_0 = 1
+ .unk_17_0 = 1,
+ .cursorKind = 0
};
static const u8 *const sCompatibilityMessages[] =
@@ -1256,7 +1257,7 @@ static void DaycarePrintMonInfo(u8 windowId, s32 daycareSlotId, u8 y)
static void Task_HandleDaycareLevelMenuInput(u8 taskId)
{
- u32 var = ListMenuHandleInput(gTasks[taskId].tMenuListTaskId);
+ u32 var = ListMenuHandleInputGetItemId(gTasks[taskId].tMenuListTaskId);
if (gMain.newKeys & A_BUTTON)
{
diff --git a/src/decoration.c b/src/decoration.c
index 987e628c5..faef779b7 100644
--- a/src/decoration.c
+++ b/src/decoration.c
@@ -792,17 +792,17 @@ void sub_8127330(u8 taskId)
for (i = 0; i < sDecorPCBuffer->unk_520 - 1; i ++)
{
sub_8127454(sDecorPCBuffer->names[i], gCurDecorInventoryItems[i]);
- sDecorPCBuffer->items[i].unk_00 = sDecorPCBuffer->names[i];
- sDecorPCBuffer->items[i].unk_04 = i;
+ sDecorPCBuffer->items[i].name = sDecorPCBuffer->names[i];
+ sDecorPCBuffer->items[i].id = i;
}
StringCopy(sDecorPCBuffer->names[i], gText_Cancel);
- sDecorPCBuffer->items[i].unk_00 = sDecorPCBuffer->names[i];
- sDecorPCBuffer->items[i].unk_04 = -2;
- gUnknown_03006310 = gUnknown_085A6BD0;
- gUnknown_03006310.unk_10 = sDecorMenuWindowIndices[1];
- gUnknown_03006310.totalItems = sDecorPCBuffer->unk_520;
- gUnknown_03006310.items = sDecorPCBuffer->items;
- gUnknown_03006310.maxShowed = sDecorPCBuffer->unk_521;
+ sDecorPCBuffer->items[i].name = sDecorPCBuffer->names[i];
+ sDecorPCBuffer->items[i].id = -2;
+ gMultiuseListMenuTemplate = gUnknown_085A6BD0;
+ gMultiuseListMenuTemplate.unk_10 = sDecorMenuWindowIndices[1];
+ gMultiuseListMenuTemplate.totalItems = sDecorPCBuffer->unk_520;
+ gMultiuseListMenuTemplate.items = sDecorPCBuffer->items;
+ gMultiuseListMenuTemplate.maxShowed = sDecorPCBuffer->unk_521;
}
void sub_8127454(u8 *dest, u16 decorId)
@@ -871,7 +871,7 @@ void sub_812759C(u8 taskId)
sub_81272C8();
sub_81272F8();
sub_8127330(taskId);
- data[13] = ListMenuInit(&gUnknown_03006310, sSecretBasePCSelectDecorPageNo, sSecretBasePCSelectDecorLineNo);
+ data[13] = ListMenuInit(&gMultiuseListMenuTemplate, sSecretBasePCSelectDecorPageNo, sSecretBasePCSelectDecorLineNo);
sub_8127500();
}
@@ -889,8 +889,8 @@ void sub_812764C(u8 taskId)
data = gTasks[taskId].data;
if (!gPaletteFade.active)
{
- input = ListMenuHandleInput(data[13]);
- get_coro_args_x18_x1A(data[13], &sSecretBasePCSelectDecorPageNo, &sSecretBasePCSelectDecorLineNo);
+ input = ListMenuHandleInputGetItemId(data[13]);
+ sub_81AE860(data[13], &sSecretBasePCSelectDecorPageNo, &sSecretBasePCSelectDecorLineNo);
switch (input)
{
case -1:
diff --git a/src/lilycove_lady.c b/src/lilycove_lady.c
index 95270974a..dab2b7768 100644
--- a/src/lilycove_lady.c
+++ b/src/lilycove_lady.c
@@ -1079,7 +1079,7 @@ void sub_818E914(void)
void sub_818E92C(void)
{
- sub_81357FC(3, c2_exit_to_overworld_2_switch);
+ OpenPokeblockCase(3, c2_exit_to_overworld_2_switch);
}
void sub_818E940(void)
diff --git a/src/new_game.c b/src/new_game.c
index 12873fec9..89771e92b 100644
--- a/src/new_game.c
+++ b/src/new_game.c
@@ -33,7 +33,6 @@ extern void Overworld_SetWarpDestination(s8 mapBank, s8 mapNo, s8 warpNo, s8 xPo
extern void warp_in(void);
extern void sub_80BB358(void);
extern void ResetBagScrollPositions(void);
-extern void sub_813624C(void); // clears something pokeblock related
extern void ResetPokedex(void);
extern void sub_8084400(void);
extern void ClearMailData(void);
@@ -148,7 +147,7 @@ void sub_808447C(void)
ZeroPlayerPartyMons();
ZeroEnemyPartyMons();
ResetBagScrollPositions();
- sub_813624C();
+ ResetPokeblockScrollPositions();
}
void NewGameInitData(void)
diff --git a/src/pokeblock.c b/src/pokeblock.c
new file mode 100644
index 000000000..6ea487bb2
--- /dev/null
+++ b/src/pokeblock.c
@@ -0,0 +1,1017 @@
+#include "global.h"
+#include "pokeblock.h"
+#include "bg.h"
+#include "strings.h"
+#include "text.h"
+#include "menu.h"
+#include "task.h"
+#include "menu_helpers.h"
+#include "pokemon.h"
+#include "graphics.h"
+#include "malloc.h"
+#include "main.h"
+#include "battle.h"
+#include "battle_controllers.h"
+#include "palette.h"
+#include "unknown_task.h"
+#include "list_menu.h"
+#include "gpu_regs.h"
+#include "decompress.h"
+#include "international_string_util.h"
+#include "item.h"
+#include "items.h"
+#include "string_util.h"
+#include "songs.h"
+#include "sound.h"
+#include "berry.h"
+#include "menu_indicators.h"
+#include "event_data.h"
+
+#define FIELD_E75_COUNT 7
+
+struct PokeblockMenuStruct
+{
+ u8 tilemap[0x800];
+ void (*debugCallback)(void);
+ const u8 *pokeblockOptions;
+ u8 optionsNo;
+ u8 caseId;
+ u8 itemsNo;
+ u8 maxShowed;
+ struct ListMenuItem items[POKEBLOCKS_COUNT + 1];
+ u8 menuItemsStrings[POKEBLOCKS_COUNT + 1][0x20]; // + 1 because of STOW CASE item
+ u8 pokeblockCaseSpriteId;
+ u8 field_E75[FIELD_E75_COUNT];
+ u8 unkTaskId;
+ bool8 isSwapping;
+ s16 gfxState;
+ u8 field_E80;
+ u8 field_E81;
+ u8 field_E82;
+ u8 field_E83;
+ u8 field_E84;
+ u8 field_E85;
+ u8 field_E86;
+ u8 field_E87;
+};
+
+struct PokeblockSavedData
+{
+ void (*callback)(void);
+ u16 lastItemPos;
+ u16 lastItemPage;
+};
+
+enum
+{
+ PKBL_USE_ON_FIELD,
+ PKBL_TOSS,
+ PKBL_CANCEL,
+ PKBL_USE_IN_BATTLE,
+ PKBL_USE_ON_FEEDER,
+ PKBL_GIVE_TO_LADY
+};
+
+extern u16 gSpecialVar_ItemId;
+extern void (*gFieldCallback)(void);
+
+extern const u16 gUnknown_0860F074[];
+
+extern void c2_exit_to_overworld_2_switch(void);
+extern bool8 sub_81221EC(void);
+extern void sub_809882C(u8, u16, u8);
+extern void copy_textbox_border_tile_patterns_to_vram(u8, u16, u8);
+extern void sub_80AF168(void);
+
+// this file's functions
+void CB2_InitPokeblockMenu(void);
+bool8 InitPokeblockMenu(void);
+static bool8 LoadPokeblockMenuGfx(void);
+static void HandleInitBackgrounds(void);
+static void HandleInitWindows(void);
+void SetMenuItemsCountAndMaxShowed(void);
+void sub_81362E0(void);
+void sub_8136344(void);
+void HandlePokeblockListMenuItems(void);
+void sub_81363BC(void);
+static void MovePokeblockMenuCursor(u32 pkblId, bool8 arg1, struct ListMenu *arg2);
+static void PutPokeblockInfoText(void);
+void HandlePokeblockMenuCursor(u16 cursorPos, u16 arg1);
+static void PutPokeblockListMenuString(u8 *dst, u16 pkblId);
+void Task_HandlePokeblockMenuInput(u8 taskId);
+void PokeblockAction_UseOnField(u8 taskId);
+void PokeblockAction_Toss(u8 taskId);
+void PokeblockAction_Cancel(u8 taskId);
+void PokeblockAction_UseInBattle(u8 taskId);
+void PokeblockAction_UseOnPokeblockFeeder(u8 taskId);
+void PokeblockAction_GiveToContestLady(u8 taskId);
+void TossPokeblockChoice_Yes(u8 taskId);
+void TossPokeblockChoice_No(u8 taskId);
+void Task_FreeDataAndExitPokeblockCase(u8 taskId);
+void PutPokeblockOptionsWindow(u8 taskId);
+static void Task_HandlePokeblocksSwapInput(u8 taskId);
+static void sub_8136470(struct Sprite *sprite);
+static void sub_8135FCC(s32 pkblId);
+void HandlePokeblocksSwap(u8 taskId, bool8 noSwap);
+
+// ram variables
+EWRAM_DATA struct PokeblockSavedData sSavedPokeblockData = {0};
+EWRAM_DATA struct PokeblockMenuStruct *sPokeblockMenu = NULL;
+
+// const rom data
+const s8 gPokeblockFlavorCompatibilityTable[] =
+{
+ // Cool, Beauty, Cute, Smart, Tough
+ 0, 0, 0, 0, 0, // Hardy
+ 1, 0, 0, 0, -1, // Lonely
+ 1, 0, -1, 0, 0, // Brave
+ 1, -1, 0, 0, 0, // Adamant
+ 1, 0, 0, -1, 0, // Naughty
+ -1, 0, 0, 0, 1, // Bold
+ 0, 0, 0, 0, 0, // Docile
+ 0, 0, -1, 0, 1, // Relaxed
+ 0, -1, 0, 0, 1, // Impish
+ 0, 0, 0, -1, 1, // Lax
+ -1, 0, 1, 0, 0, // Timid
+ 0, 0, 1, 0, -1, // Hasty
+ 0, 0, 0, 0, 0, // Serious
+ 0, -1, 1, 0, 0, // Jolly
+ 0, 0, 1, -1, 0, // Naive
+ -1, 1, 0, 0, 0, // Modest
+ 0, 1, 0, 0, -1, // Mild
+ 0, 1, -1, 0, 0, // Quiet
+ 0, 0, 0, 0, 0, // Bashful
+ 0, 1, 0, -1, 0, // Rash
+ -1, 0, 0, 1, 0, // Calm
+ 0, 0, 0, 1, -1, // Gentle
+ 0, 0, -1, 1, 0, // Sassy
+ 0, -1, 0, 1, 0, // Careful
+ 0, 0, 0, 0, 0 // Quirky
+};
+
+static const struct BgTemplate sBgTemplatesForPokeblockMenu[] =
+{
+ {
+ .bg = 0,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 31,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 1,
+ .baseTile = 0
+ },
+ {
+ .bg = 1,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 30,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 0,
+ .baseTile = 0
+ },
+ {
+ .bg = 2,
+ .charBaseIndex = 3,
+ .mapBaseIndex = 29,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 2,
+ .baseTile = 0
+ }
+};
+
+const u8 *const gPokeblockNames[] =
+{
+ NULL,
+ gText_RedPokeblock,
+ gText_BluePokeblock,
+ gText_PinkPokeblock,
+ gText_GreenPokeblock,
+ gText_YellowPokeblock,
+ gText_PurplePokeblock,
+ gText_IndigoPokeblock,
+ gText_BrownPokeblock,
+ gText_LiteBluePokeblock,
+ gText_OlivePokeblock,
+ gText_GrayPokeblock,
+ gText_BlackPokeblock,
+ gText_WhitePokeblock,
+ gText_GoldPokeblock
+};
+
+const struct MenuAction sPokeblockMenuActions[] =
+{
+ {gMenuText_Use, PokeblockAction_UseOnField},
+ {gMenuText_Toss, PokeblockAction_Toss},
+ {gText_Cancel2, PokeblockAction_Cancel},
+ {gMenuText_Use, PokeblockAction_UseInBattle},
+ {gMenuText_Use, PokeblockAction_UseOnPokeblockFeeder},
+ {gMenuText_Give2, PokeblockAction_GiveToContestLady},
+};
+
+const u8 sActionsOnField[] = {PKBL_USE_ON_FIELD, PKBL_TOSS, PKBL_CANCEL};
+const u8 sActionsInBattle[] = {PKBL_USE_IN_BATTLE, PKBL_CANCEL};
+const u8 sActionsOnPokeblockFeeder[] = {PKBL_USE_ON_FEEDER, PKBL_CANCEL};
+const u8 sActionsWhenGivingToLady[] = {PKBL_GIVE_TO_LADY, PKBL_CANCEL};
+
+const struct YesNoFuncTable sTossYesNoFuncTable = {TossPokeblockChoice_Yes, TossPokeblockChoice_No};
+
+static const u8 sContestStatsMonData[] = {MON_DATA_COOL, MON_DATA_BEAUTY, MON_DATA_CUTE, MON_DATA_SMART, MON_DATA_TOUGH};
+
+static const struct OamData sOamData_PokeblockCase =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 3,
+ .tileNum = 0,
+ .priority = 2,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const union AnimCmd sSpriteAnim_PokeblockCase[] =
+{
+ ANIMCMD_FRAME(0, 0),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sSpriteAnimTable_PokeblockCase[] =
+{
+ sSpriteAnim_PokeblockCase
+};
+
+static const union AffineAnimCmd gSpriteAffineAnim_85B26C8[] =
+{
+ AFFINEANIMCMD_FRAME(0, 0, -2, 2),
+ AFFINEANIMCMD_FRAME(0, 0, 2, 4),
+ AFFINEANIMCMD_FRAME(0, 0, -2, 4),
+ AFFINEANIMCMD_FRAME(0, 0, 2, 2),
+ AFFINEANIMCMD_END
+};
+
+const union AffineAnimCmd *const sSpriteAffineAnimTable_85B26F0[] =
+{
+ gSpriteAffineAnim_85B26C8
+};
+
+const struct CompressedSpriteSheet gPokeblockCase_SpriteSheet =
+{
+ gMenuPokeblockDevice_Gfx, 0x800, GFX_TAG_POKEBLOCK_CASE
+};
+
+const struct CompressedSpritePalette gPokeblockCase_SpritePal =
+{
+ gMenuPokeblockDevice_Pal, GFX_TAG_POKEBLOCK_CASE
+};
+
+static const struct SpriteTemplate sSpriteTemplate_PokeblockCase =
+{
+ GFX_TAG_POKEBLOCK_CASE,
+ GFX_TAG_POKEBLOCK_CASE,
+ &sOamData_PokeblockCase,
+ sSpriteAnimTable_PokeblockCase,
+ NULL,
+ gDummySpriteAffineAnimTable,
+ SpriteCallbackDummy
+};
+
+const struct TextColor sTextColorInPokeblockMenu = {0, 2, 3};
+
+const struct Pokeblock sFavoritePokeblocksTable[] =
+{
+ { PBLOCK_CLR_RED, 20, 0, 0, 0, 0, 20},
+ { PBLOCK_CLR_BLUE, 0, 20, 0, 0, 0, 20},
+ { PBLOCK_CLR_PINK, 0, 0, 20, 0, 0, 20},
+ { PBLOCK_CLR_GREEN, 0, 0, 0, 20, 0, 20},
+ { PBLOCK_CLR_YELLOW, 0, 0, 0, 0, 20, 20}
+};
+
+static const struct WindowTemplate sWindowTemplatesForPokeblockMenu[] =
+{
+ {0, 2, 1, 9, 2, 0xF, 0x1E},
+ {0, 0xF, 1, 0xE, 0x12, 0xF, 0x30},
+ {0, 2, 0xD, 5, 2, 0xF, 0x12C},
+ {0, 2, 0xF, 5, 2, 0xF, 0x136},
+ {0, 2, 0x11, 5, 2, 0xF, 0x140},
+ {0, 8, 0xD, 5, 2, 0xF, 0x14A},
+ {0, 8, 0xF, 5, 2, 0xF, 0x154},
+ {0, 0xB, 0x11, 2, 2, 0xF, 0x15E},
+ {1, 7, 5, 6, 6, 0xF, 0x162},
+ {1, 7, 7, 6, 4, 0xF, 0x186},
+ {1, 2, 0xF, 0x1B, 4, 0xF, 0x19E},
+ DUMMY_WIN_TEMPLATE
+};
+
+const struct WindowTemplate gUnknown_085B27A8[] = {1, 0x15, 9, 5, 4, 0xF, 0x20A};
+
+static const struct ListMenuTemplate sPokeblockListMenuTemplate =
+{
+ .items = NULL,
+ .moveCursorFunc = MovePokeblockMenuCursor,
+ .unk_08 = NULL,
+ .totalItems = 0,
+ .maxShowed = 0,
+ .unk_10 = 1,
+ .unk_11 = 0,
+ .unk_12 = 1,
+ .cursor_Y = 0,
+ .upText_Y = 1,
+ .cursorColor = 2,
+ .fillColor = 0,
+ .cursorShadowColor = 3,
+ .unk_16_0 = FALSE,
+ .spaceBetweenItems = 32,
+ .unk_16_7 = FALSE,
+ .unk_17_0 = 1,
+ .cursorKind = 1
+};
+
+// code
+void OpenPokeblockCase(u8 caseId, void (*callback)(void))
+{
+ sPokeblockMenu = Alloc(sizeof(*sPokeblockMenu));
+ sPokeblockMenu->caseId = caseId;
+ sPokeblockMenu->debugCallback = NULL;
+ sPokeblockMenu->unkTaskId = 0xFF;
+ sPokeblockMenu->isSwapping = FALSE;
+ sSavedPokeblockData.callback = callback;
+
+ switch (sPokeblockMenu->caseId)
+ {
+ case PBLOCK_CASE_BATTLE:
+ sPokeblockMenu->pokeblockOptions = sActionsInBattle;
+ sPokeblockMenu->optionsNo = ARRAY_COUNT(sActionsInBattle);
+ break;
+ case PBLOCK_CASE_FEEDER:
+ sPokeblockMenu->pokeblockOptions = sActionsOnPokeblockFeeder;
+ sPokeblockMenu->optionsNo = ARRAY_COUNT(sActionsOnPokeblockFeeder);
+ break;
+ case PBLOCK_CASE_GIVE:
+ sPokeblockMenu->pokeblockOptions = sActionsWhenGivingToLady;
+ sPokeblockMenu->optionsNo = ARRAY_COUNT(sActionsWhenGivingToLady);
+ break;
+ default:
+ sPokeblockMenu->pokeblockOptions = sActionsOnField;
+ sPokeblockMenu->optionsNo = ARRAY_COUNT(sActionsOnField);
+ break;
+ }
+
+ SetMainCallback2(CB2_InitPokeblockMenu);
+}
+
+void OpenPokeblockCaseInBattle(void)
+{
+ OpenPokeblockCase(PBLOCK_CASE_BATTLE, SetCB2ToReshowScreenAfterMenu2);
+}
+
+void OpenPokeblockCaseOnFeeder(void)
+{
+ OpenPokeblockCase(PBLOCK_CASE_FEEDER, c2_exit_to_overworld_2_switch);
+}
+
+static void CB2_PokeblockMenu(void)
+{
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ do_scheduled_bg_tilemap_copies_to_vram();
+ UpdatePaletteFade();
+}
+
+static void VBlankCB_PokeblockMenu(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+void CB2_InitPokeblockMenu(void)
+{
+ while (1)
+ {
+ if (sub_81221EC() == TRUE)
+ break;
+ if (InitPokeblockMenu() == TRUE)
+ break;
+ if (sub_81221AC() == TRUE)
+ break;
+ }
+}
+
+bool8 InitPokeblockMenu(void)
+{
+ u8 taskId;
+
+ switch (gMain.state)
+ {
+ case 0:
+ SetVBlankHBlankCallbacksToNull();
+ clear_scheduled_bg_copies_to_vram();
+ gMain.state++;
+ break;
+ case 1:
+ remove_some_task();
+ gMain.state++;
+ break;
+ case 2:
+ FreeAllSpritePalettes();
+ gMain.state++;
+ break;
+ case 3:
+ ResetPaletteFade();
+ gPaletteFade.bufferTransferDisabled = 1;
+ gMain.state++;
+ break;
+ case 4:
+ ResetSpriteData();
+ gMain.state++;
+ break;
+ case 5:
+ if (sPokeblockMenu->caseId != PBLOCK_CASE_BATTLE)
+ ResetTasks();
+ gMain.state++;
+ break;
+ case 6:
+ HandleInitBackgrounds();
+ sPokeblockMenu->gfxState = 0;
+ gMain.state++;
+ break;
+ case 7:
+ if (!LoadPokeblockMenuGfx())
+ return FALSE;
+ gMain.state++;
+ break;
+ case 8:
+ SetMenuItemsCountAndMaxShowed();
+ sub_81362E0();
+ sub_8136344();
+ gMain.state++;
+ break;
+ case 9:
+ sPokeblockMenu->pokeblockCaseSpriteId = CreatePokeblockCaseSprite(56, 64, 0);
+ gMain.state++;
+ break;
+ case 10:
+ sub_8122344(&sPokeblockMenu->field_E75, FIELD_E75_COUNT);
+ gMain.state++;
+ break;
+ case 11:
+ HandlePokeblockMenuCursor(sSavedPokeblockData.lastItemPos, 0x1005);
+ gMain.state++;
+ break;
+ case 12:
+ HandleInitWindows();
+ gMain.state++;
+ break;
+ case 13:
+ HandlePokeblockListMenuItems();
+ gMain.state++;
+ break;
+ case 14:
+ sub_81363BC();
+ gMain.state++;
+ break;
+ case 15:
+ taskId = CreateTask(Task_HandlePokeblockMenuInput, 0);
+ gTasks[taskId].data[0] = ListMenuInit(&gMultiuseListMenuTemplate, sSavedPokeblockData.lastItemPage, sSavedPokeblockData.lastItemPos);
+ gMain.state++;
+ break;
+ case 16:
+ PutPokeblockInfoText();
+ gMain.state++;
+ break;
+ case 17:
+ BlendPalettes(-1, 0x10, 0);
+ gMain.state++;
+ break;
+ case 18:
+ BeginNormalPaletteFade(-1, 0, 0x10, 0, 0);
+ gPaletteFade.bufferTransferDisabled = 0;
+ gMain.state++;
+ break;
+ default:
+ SetVBlankCallback(VBlankCB_PokeblockMenu);
+ SetMainCallback2(CB2_PokeblockMenu);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void HandleInitBackgrounds(void)
+{
+ ResetVramOamAndBgCntRegs();
+ ResetBgsAndClearDma3BusyFlags(0);
+ InitBgsFromTemplates(0, sBgTemplatesForPokeblockMenu, ARRAY_COUNT(sBgTemplatesForPokeblockMenu));
+ SetBgTilemapBuffer(2, sPokeblockMenu->tilemap);
+ ResetAllBgsCoordinates();
+ schedule_bg_copy_tilemap_to_vram(2);
+
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
+
+ ShowBg(0);
+ ShowBg(1);
+ ShowBg(2);
+
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+}
+
+static bool8 LoadPokeblockMenuGfx(void)
+{
+ switch (sPokeblockMenu->gfxState)
+ {
+ case 0:
+ reset_temp_tile_data_buffers();
+ decompress_and_copy_tile_data_to_vram(2, gMenuPokeblock_Gfx, 0, 0, 0);
+ sPokeblockMenu->gfxState++;
+ break;
+ case 1:
+ if (free_temp_tile_data_buffers_if_possible() != TRUE)
+ {
+ LZDecompressWram(gMenuPokeblock_Tilemap, sPokeblockMenu->tilemap);
+ sPokeblockMenu->gfxState++;
+ }
+ break;
+ case 2:
+ LoadCompressedPalette(gMenuPokeblock_Pal, 0, 0xC0);
+ sPokeblockMenu->gfxState++;
+ break;
+ case 3:
+ LoadCompressedObjectPic(&gPokeblockCase_SpriteSheet);
+ sPokeblockMenu->gfxState++;
+ break;
+ case 4:
+ LoadCompressedObjectPalette(&gPokeblockCase_SpritePal);
+ sPokeblockMenu->gfxState++;
+ break;
+ case 5:
+ LoadListMenuArrowsGfx();
+ sPokeblockMenu->gfxState = 0;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void HandleInitWindows(void)
+{
+ u8 i;
+
+ InitWindows(sWindowTemplatesForPokeblockMenu);
+ DeactivateAllTextPrinters();
+ sub_809882C(0, 1, 0xE0);
+ copy_textbox_border_tile_patterns_to_vram(0, 0xA, 0xD0);
+ LoadPalette(gUnknown_0860F074, 0xF0, 0x20);
+
+ for (i = 0; i < ARRAY_COUNT(sWindowTemplatesForPokeblockMenu) - 1; i++)
+ {
+ FillWindowPixelBuffer(i, 0);
+ }
+
+ schedule_bg_copy_tilemap_to_vram(0);
+ schedule_bg_copy_tilemap_to_vram(1);
+}
+
+void PrintOnPokeblockWindow(u8 windowId, const u8 *string, s32 x)
+{
+ AddTextPrinterParametrized2(windowId, 1, x, 1, 0, 0, &sTextColorInPokeblockMenu, 0, string);
+}
+
+static void PutPokeblockInfoText(void)
+{
+ u8 i;
+
+ const u8 *itemName = ItemId_GetItem(ITEM_POKEBLOCK_CASE)->name;
+ PrintOnPokeblockWindow(0, itemName, GetStringCenterAlignXOffset(1, itemName, 0x48));
+
+ PrintOnPokeblockWindow(2, gText_Spicy, 0);
+ PrintOnPokeblockWindow(3, gText_Dry, 0);
+ PrintOnPokeblockWindow(4, gText_Sweet, 0);
+ PrintOnPokeblockWindow(5, gText_Bitter, 0);
+ PrintOnPokeblockWindow(6, gText_Sour, 0);
+
+ for (i = 0; i < 8; i++)
+ {
+ PutWindowTilemap(i);
+ }
+}
+
+void HandlePokeblockListMenuItems(void)
+{
+ u16 i;
+
+ for (i = 0; i < sPokeblockMenu->itemsNo - 1; i++)
+ {
+ PutPokeblockListMenuString(sPokeblockMenu->menuItemsStrings[i], i);
+ sPokeblockMenu->items[i].name = sPokeblockMenu->menuItemsStrings[i];
+ sPokeblockMenu->items[i].id = i;
+ }
+
+ StringCopy(sPokeblockMenu->menuItemsStrings[i], gText_StowCase);
+ sPokeblockMenu->items[i].name = sPokeblockMenu->menuItemsStrings[i];
+ sPokeblockMenu->items[i].id = LIST_B_PRESSED;
+
+ gMultiuseListMenuTemplate = sPokeblockListMenuTemplate;
+ gMultiuseListMenuTemplate.unk_17_0 = 7;
+ gMultiuseListMenuTemplate.totalItems = sPokeblockMenu->itemsNo;
+ gMultiuseListMenuTemplate.items = sPokeblockMenu->items;
+ gMultiuseListMenuTemplate.maxShowed = sPokeblockMenu->maxShowed;
+}
+
+static void PutPokeblockListMenuString(u8 *dst, u16 pkblId)
+{
+ struct Pokeblock *pkblock = &gSaveBlock1Ptr->pokeblocks[pkblId];
+ u8 *txtPtr = StringCopy(dst, gPokeblockNames[pkblock->color]);
+
+ *(txtPtr++) = EXT_CTRL_CODE_BEGIN;
+ *(txtPtr++) = 0x12;
+ *(txtPtr++) = 0x57;
+
+ ConvertIntToDecimalStringN(gStringVar1, GetHighestPokeblocksFlavorLevel(pkblock), STR_CONV_MODE_LEFT_ALIGN, 3);
+ StringExpandPlaceholders(txtPtr, gText_LvVar1);
+}
+
+static void MovePokeblockMenuCursor(u32 pkblId, bool8 arg1, struct ListMenu *arg2)
+{
+ if (arg1 != TRUE)
+ {
+ PlaySE(SE_SELECT);
+ gSprites[sPokeblockMenu->pokeblockCaseSpriteId].callback = sub_8136470;
+ }
+
+ if (!sPokeblockMenu->isSwapping)
+ sub_8135FCC(pkblId);
+}
+
+static void sub_8135FCC(s32 pkblId)
+{
+ u8 i;
+ struct Pokeblock *pokeblock;
+ u16 rectTilemapSrc[2];
+
+ FillWindowPixelBuffer(7, 0);
+
+ if (pkblId != LIST_B_PRESSED)
+ {
+ pokeblock = &gSaveBlock1Ptr->pokeblocks[pkblId];
+ rectTilemapSrc[0] = 0x17;
+ rectTilemapSrc[1] = 0x18;
+ for (i = 0; i < FLAVOR_COUNT; i++)
+ {
+ if (GetPokeblockData(pokeblock, PBLOCK_SPICY + i) > 0)
+ {
+ rectTilemapSrc[0] = (i << 0xC) + 0x17;
+ rectTilemapSrc[1] = (i << 0xC) + 0x18;
+ }
+ else
+ {
+ rectTilemapSrc[0] = 0xF;
+ rectTilemapSrc[1] = 0xF;
+ }
+ CopyToBgTilemapBufferRect(2, rectTilemapSrc, (i / 3 * 6) + 1, (i % 3 * 2) + 13, 1, 2);
+ }
+ ConvertIntToDecimalStringN(gStringVar1, GetPokeblocksFeel(pokeblock), STR_CONV_MODE_RIGHT_ALIGN, 2);
+ PrintOnPokeblockWindow(7, gStringVar1, 4);
+ }
+ else
+ {
+ rectTilemapSrc[0] = 0xF;
+ rectTilemapSrc[1] = 0xF;
+
+ for (i = 0; i < FLAVOR_COUNT; i++)
+ {
+ CopyToBgTilemapBufferRect(2, rectTilemapSrc, (i / 3 * 6) + 1, (i % 3 * 2) + 13, 1, 2);
+ }
+ CopyWindowToVram(7, 2);
+ }
+
+ schedule_bg_copy_tilemap_to_vram(0);
+ schedule_bg_copy_tilemap_to_vram(2);
+}
+
+void HandlePokeblockMenuCursor(u16 cursorPos, u16 arg1)
+{
+ FillBgTilemapBufferRect_Palette0(2, arg1, 0xF, (cursorPos * 2) + 1, 0xE, 2);
+ schedule_bg_copy_tilemap_to_vram(2);
+}
+
+void CompactPokeblockSlots(void)
+{
+ u16 i, j;
+
+ for (i = 0; i < POKEBLOCKS_COUNT - 1; i++)
+ {
+ for (j = i + 1; j < POKEBLOCKS_COUNT; j++)
+ {
+ if (gSaveBlock1Ptr->pokeblocks[i].color == 0)
+ {
+ struct Pokeblock temp = gSaveBlock1Ptr->pokeblocks[i];
+ gSaveBlock1Ptr->pokeblocks[i] = gSaveBlock1Ptr->pokeblocks[j];
+ gSaveBlock1Ptr->pokeblocks[j] = temp;
+ }
+ }
+ }
+}
+
+void SwapSortPokeblocksInternalData(u32 id1, u32 id2)
+{
+ s16 i, count;
+ struct Pokeblock *pokeblocks = gSaveBlock1Ptr->pokeblocks;
+ struct Pokeblock *copyPokeblock1;
+
+ if (id1 == id2)
+ return;
+
+ copyPokeblock1 = Alloc(sizeof(struct Pokeblock));
+ *copyPokeblock1 = pokeblocks[id1];
+
+ if (id2 > id1)
+ {
+ id2--;
+ for (count = id2, i = id1; i < count; i++)
+ pokeblocks[i] = pokeblocks[i + 1];
+ }
+ else
+ {
+ for (count = id2, i = id1; i > count; i--)
+ pokeblocks[i] = pokeblocks[i - 1];
+ }
+
+ pokeblocks[id2] = *copyPokeblock1;
+ Free(copyPokeblock1);
+}
+
+void ResetPokeblockScrollPositions(void)
+{
+ sSavedPokeblockData.lastItemPos = 0;
+ sSavedPokeblockData.lastItemPage = 0;
+}
+
+void SetMenuItemsCountAndMaxShowed(void)
+{
+ u16 i;
+
+ CompactPokeblockSlots();
+
+ for (sPokeblockMenu->itemsNo = 0, i = 0; i < POKEBLOCKS_COUNT; i++)
+ {
+ if (gSaveBlock1Ptr->pokeblocks[i].color != 0)
+ sPokeblockMenu->itemsNo++;
+ }
+
+ sPokeblockMenu->itemsNo++; // STOW CASE menu item
+
+ if (sPokeblockMenu->itemsNo > 9)
+ sPokeblockMenu->maxShowed = 9;
+ else
+ sPokeblockMenu->maxShowed = sPokeblockMenu->itemsNo;
+}
+
+void sub_81362E0(void)
+{
+ if (sSavedPokeblockData.lastItemPage != 0)
+ {
+ if (sSavedPokeblockData.lastItemPage + sPokeblockMenu->maxShowed > sPokeblockMenu->itemsNo)
+ sSavedPokeblockData.lastItemPage = sPokeblockMenu->itemsNo - sPokeblockMenu->maxShowed;
+ }
+
+ if (sSavedPokeblockData.lastItemPage + sSavedPokeblockData.lastItemPos >= sPokeblockMenu->itemsNo)
+ {
+ if (sPokeblockMenu->itemsNo == 0)
+ sSavedPokeblockData.lastItemPos = 0;
+ else
+ sSavedPokeblockData.lastItemPos = sPokeblockMenu->itemsNo - 1;
+ }
+}
+
+void sub_8136344(void)
+{
+ if (sSavedPokeblockData.lastItemPos > 4)
+ {
+ u8 i;
+
+ for (i = 0;
+ i < sSavedPokeblockData.lastItemPos - 4 && sSavedPokeblockData.lastItemPage + sPokeblockMenu->maxShowed != sPokeblockMenu->itemsNo;
+ sSavedPokeblockData.lastItemPos--, sSavedPokeblockData.lastItemPage++, i++);
+ }
+}
+
+void sub_81363BC(void)
+{
+ if (sPokeblockMenu->unkTaskId == 0xFF)
+ {
+ sPokeblockMenu->unkTaskId = AddScrollIndicatorArrowPairParametrized(2, 0xB0, 8, 0x98, sPokeblockMenu->itemsNo - sPokeblockMenu->maxShowed,
+ 0x456, 0x456, &sSavedPokeblockData.lastItemPage);
+ }
+}
+
+void sub_8136418(void)
+{
+ if (sPokeblockMenu->unkTaskId != 0xFF)
+ {
+ RemoveScrollIndicatorArrowPair(sPokeblockMenu->unkTaskId);
+ sPokeblockMenu->unkTaskId = 0xFF;
+ }
+}
+
+u8 CreatePokeblockCaseSprite(s16 x, s16 y, u8 subpriority)
+{
+ return CreateSprite(&sSpriteTemplate_PokeblockCase, x, y, subpriority);
+}
+
+static void sub_8136470(struct Sprite *sprite)
+{
+ if (sprite->data[0] > 1)
+ sprite->data[0] = 0;
+
+ switch (sprite->data[0])
+ {
+ case 0:
+ sprite->oam.affineMode = 1;
+ sprite->affineAnims = sSpriteAffineAnimTable_85B26F0;
+ InitSpriteAffineAnim(sprite);
+ sprite->data[0] = 1;
+ sprite->data[1] = 0;
+ break;
+ case 1:
+ if (++sprite->data[1] > 11)
+ {
+ sprite->oam.affineMode = 0;
+ sprite->data[0] = 0;
+ sprite->data[1] = 0;
+ FreeOamMatrix(sprite->oam.matrixNum);
+ sprite->callback = SpriteCallbackDummy;
+ }
+ break;
+ }
+}
+
+void FadePaletteAndSetTaskToClosePokeblockCase(u8 taskId)
+{
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ gTasks[taskId].func = Task_FreeDataAndExitPokeblockCase;
+}
+
+void Task_FreeDataAndExitPokeblockCase(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ if (!gPaletteFade.active)
+ {
+ if (sPokeblockMenu->caseId == PBLOCK_CASE_FEEDER || sPokeblockMenu->caseId == PBLOCK_CASE_GIVE)
+ gFieldCallback = sub_80AF168;
+
+ sub_81AE6C8(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
+ sub_8136418();
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+
+ if (sPokeblockMenu->debugCallback != NULL)
+ SetMainCallback2(sPokeblockMenu->debugCallback);
+ else
+ SetMainCallback2(sSavedPokeblockData.callback);
+
+ FreeAllWindowBuffers();
+ Free(sPokeblockMenu);
+ DestroyTask(taskId);
+ }
+}
+
+void Task_HandlePokeblockMenuInput(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ if (!gPaletteFade.active && sub_81221EC() != TRUE)
+ {
+ if (gMain.newKeys & SELECT_BUTTON)
+ {
+ sub_81AE860(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
+ if (sSavedPokeblockData.lastItemPage + sSavedPokeblockData.lastItemPos != sPokeblockMenu->itemsNo - 1)
+ {
+ PlaySE(SE_SELECT);
+ HandlePokeblockMenuCursor(sSavedPokeblockData.lastItemPos, 0x2005);
+ data[2] = sSavedPokeblockData.lastItemPage + sSavedPokeblockData.lastItemPos;
+ sPokeblockMenu->isSwapping = TRUE;
+ gTasks[taskId].func = Task_HandlePokeblocksSwapInput;
+ }
+ }
+ else
+ {
+ u16 oldPosition = sSavedPokeblockData.lastItemPos;
+ s32 itemId = ListMenuHandleInputGetItemId(data[0]);
+
+ sub_81AE860(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
+ if (oldPosition != sSavedPokeblockData.lastItemPos)
+ {
+ HandlePokeblockMenuCursor(oldPosition, 5);
+ HandlePokeblockMenuCursor(sSavedPokeblockData.lastItemPos, 0x1005);
+ }
+
+ switch (itemId)
+ {
+ case LIST_NOTHING_CHOSEN:
+ break;
+ case LIST_B_PRESSED:
+ PlaySE(SE_SELECT);
+ gSpecialVar_Result = 0xFFFF;
+ gSpecialVar_ItemId = 0;
+ FadePaletteAndSetTaskToClosePokeblockCase(taskId);
+ break;
+ default:
+ PlaySE(SE_SELECT);
+ gSpecialVar_ItemId = itemId;
+ PutPokeblockOptionsWindow(taskId);
+ break;
+ }
+ }
+ }
+}
+
+static void Task_HandlePokeblocksSwapInput(u8 taskId)
+{
+ s16 *data = gTasks[taskId].data;
+
+ if (sub_81221EC() == TRUE)
+ return;
+
+ if (gMain.newKeys & SELECT_BUTTON)
+ {
+ PlaySE(SE_SELECT);
+ sub_81AE860(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
+ HandlePokeblocksSwap(taskId, FALSE);
+ }
+ else
+ {
+ u16 i = sSavedPokeblockData.lastItemPage;
+ u16 var = sSavedPokeblockData.lastItemPos;
+ s32 itemId = ListMenuHandleInputGetItemId(data[0]);
+
+ sub_81AE860(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
+ if (i != sSavedPokeblockData.lastItemPage || var != sSavedPokeblockData.lastItemPos)
+ {
+ for (i = 0; i < 9; i++)
+ {
+ var = i + sSavedPokeblockData.lastItemPage;
+ if (var == data[2])
+ HandlePokeblockMenuCursor(i, 0x2005);
+ else
+ HandlePokeblockMenuCursor(i, 5);
+ }
+ }
+
+ sub_81223FC(sPokeblockMenu->field_E75, FIELD_E75_COUNT, 0);
+ sub_8122448(sPokeblockMenu->field_E75, FIELD_E75_COUNT, 0x80, (sSavedPokeblockData.lastItemPos * 16) + 8);
+
+ switch (itemId)
+ {
+ case LIST_NOTHING_CHOSEN:
+ break;
+ case LIST_B_PRESSED: // same id as STOW CASE field
+ PlaySE(SE_SELECT);
+ if (gMain.newKeys & A_BUTTON)
+ HandlePokeblocksSwap(taskId, FALSE);
+ else
+ HandlePokeblocksSwap(taskId, TRUE);
+ break;
+ default:
+ PlaySE(SE_SELECT);
+ HandlePokeblocksSwap(taskId, FALSE);
+ break;
+ }
+ }
+}
+
+void HandlePokeblocksSwap(u8 taskId, bool8 noSwap)
+{
+ u8 i;
+ s16 *data = gTasks[taskId].data;
+ u16 swappedFromId = sSavedPokeblockData.lastItemPage + sSavedPokeblockData.lastItemPos;
+
+ sPokeblockMenu->isSwapping = FALSE;
+ sub_81AE6C8(data[0], &sSavedPokeblockData.lastItemPage, &sSavedPokeblockData.lastItemPos);
+
+ if (!noSwap && data[2] != swappedFromId && data[2] != swappedFromId - 1)
+ {
+ SwapSortPokeblocksInternalData(data[2], swappedFromId);
+ HandlePokeblockListMenuItems();
+ }
+
+ if (data[2] < swappedFromId)
+ sSavedPokeblockData.lastItemPos--;
+
+ data[0] = ListMenuInit(&gMultiuseListMenuTemplate, sSavedPokeblockData.lastItemPage, sSavedPokeblockData.lastItemPos);
+ schedule_bg_copy_tilemap_to_vram(0);
+ sub_81223FC(sPokeblockMenu->field_E75, FIELD_E75_COUNT, 1);
+
+ for (i = 0; i < 9; i++)
+ HandlePokeblockMenuCursor(i, 5);
+
+ HandlePokeblockMenuCursor(sSavedPokeblockData.lastItemPos, 0x1005);
+ gTasks[taskId].func = Task_HandlePokeblockMenuInput;
+}
diff --git a/src/pokeblock_feed.c b/src/pokeblock_feed.c
new file mode 100644
index 000000000..ec5f3074f
--- /dev/null
+++ b/src/pokeblock_feed.c
@@ -0,0 +1,1108 @@
+#include "global.h"
+#include "pokeblock.h"
+#include "sprite.h"
+#include "task.h"
+#include "palette.h"
+#include "menu.h"
+#include "malloc.h"
+#include "pokemon.h"
+#include "blend_palette.h"
+#include "main.h"
+#include "menu_helpers.h"
+#include "bg.h"
+#include "gpu_regs.h"
+#include "data2.h"
+#include "decompress.h"
+#include "event_data.h"
+#include "strings.h"
+#include "string_util.h"
+#include "new_menu_helpers.h"
+#include "party_menu.h"
+#include "m4a.h"
+#include "sound.h"
+#include "trig.h"
+#include "graphics.h"
+#include "battle.h" // to get rid of once gMonSpritesGfxPtr is put elsewhere
+
+struct PokeblockFeedStruct
+{
+ struct Sprite *monSpritePtr;
+ struct Sprite savedMonSprite;
+ u8 tilemapBuffer[0x808];
+ s16 field_850[0x200];
+ s16 field_C50[0x200];
+ u8 field_1050;
+ u8 animId;
+ u8 field_1052;
+ bool8 noMonFlip;
+ u16 species;
+ u16 field_1056;
+ u16 field_1058;
+ u8 nature;
+ u8 monSpriteId_;
+ u8 field_105C;
+ u8 monSpriteId;
+ u8 pokeblockCaseSpriteId;
+ u8 pokeblockSpriteId;
+ s16 field_1060[15];
+ s16 loadGfxState;
+ u8 unused;
+};
+
+extern u16 gSpecialVar_ItemId;
+extern struct MusicPlayerInfo gMPlay_BGM;
+extern struct SpriteTemplate gUnknown_0202499C;
+
+extern const u8 gBattleTerrainPalette_Frontier[];
+extern const u8 gBattleTerrainTiles_Building[];
+extern const u8 gUnknown_08D9BA44[];
+extern const struct CompressedSpriteSheet gMonFrontPicTable[];
+extern const u16 gUnknown_0860F074[];
+
+extern bool8 sub_81221EC(void);
+extern void sub_806A068(u16, u8);
+extern void sub_809882C(u8, u16, u8);
+
+// this file's functions
+static void HandleInitBackgrounds(void);
+static void HandleInitWindows(void);
+static void LaunchPokeblockFeedTask(void);
+static void SetPokeblockSpritePal(u8 pokeblockCaseId);
+static void sub_817A5CC(void);
+static void sub_8148108(u8 spriteId, bool8 a1);
+static void DoPokeblockCaseThrowEffect(u8 spriteId, bool8 arg1);
+static void PrepareMonToMoveToPokeblock(u8 spriteId);
+static void Task_HandleMonAtePokeblock(u8 taskId);
+static void Task_PaletteFadeToReturn(u8 taskId);
+static void sub_817A634(void);
+static void sub_817A468(struct Sprite *sprite);
+static void sub_817AB68(void);
+static void sub_817AA54(void);
+static bool8 sub_817A91C(void);
+static bool8 FreeMonSpriteOamMatrix(void);
+static bool8 sub_817A9E4(void);
+static bool8 LoadMonAndSceneGfx(struct Pokemon *mon);
+static u8 CreatePokeblockSprite(void);
+static u8 CreatePokeblockCaseSpriteForFeeding(void);
+static u8 CreateMonSprite(struct Pokemon *mon);
+static void SpriteCB_ThrownPokeblock(struct Sprite* sprite);
+
+// ram variables
+EWRAM_DATA static struct PokeblockFeedStruct *sPokeblockFeed = NULL;
+EWRAM_DATA static struct CompressedSpritePalette sPokeblockSpritePal = {0};
+
+// const rom data
+static const u8 sNatureToMonPokeblockAnim[][2] =
+{
+ { 0, 0 }, // HARDY
+ { 3, 0 }, // LONELY
+ { 4, 1 }, // BRAVE
+ { 5, 0 }, // ADAMANT
+ { 10, 0 }, // NAUGHTY
+ { 13, 0 }, // BOLD
+ { 15, 0 }, // DOCILE
+ { 16, 2 }, // RELAXED
+ { 18, 0 }, // IMPISH
+ { 19, 0 }, // LAX
+ { 20, 0 }, // TIMID
+ { 25, 0 }, // HASTY
+ { 27, 3 }, // SERIOUS
+ { 28, 0 }, // JOLLY
+ { 29, 0 }, // NAIVE
+ { 33, 4 }, // MODEST
+ { 36, 0 }, // MILD
+ { 37, 0 }, // QUIET
+ { 39, 0 }, // BASHFUL
+ { 42, 0 }, // RASH
+ { 45, 0 }, // CALM
+ { 46, 5 }, // GENTLE
+ { 47, 6 }, // SASSY
+ { 48, 0 }, // CAREFUL
+ { 53, 0 }, // QUIRKY
+};
+
+static const s16 sMonPokeblockAnims[][10] =
+{
+ // HARDY
+ { 0, 4, 0, 8, 24, 0, 0, 0, 12, 0},
+ { 0, 4, 0, 16, 24, 0, 0, 0, 12, 0},
+ { 0, 4, 0, 32, 32, 0, 0, 0, 16, 1},
+
+ // LONELY
+ { 0, 3, 6, 0, 48, 0, 0, 0, 24, 1},
+
+ // BRAVE
+ { 64, 16, -24, 0, 32, 0, 0, 0, 0, 1},
+
+ // ADAMANT
+ { 0, 4, 8, 0, 16, 0, -8, 0, 0, 0},
+ { 0, 0, 0, 0, 16, 0, 0, 0, 0, 0},
+ { 0, 4, 8, 0, 16, 0, -8, 0, 0, 0},
+ { 0, 0, 0, 0, 16, 0, 0, 0, 0, 0},
+ { 0, 4, -16, 0, 4, 0, 16, 0, 0, 1},
+
+ // NAUGHTY
+ { 0, 3, 6, 0, 12, 0, 0, 0, 6, 0},
+ { 0, 3, -6, 0, 12, 0, 0, 0, 6, 0},
+ { 0, 16, 16, 0, 45, 1, 0, 0, 0, 1},
+
+ // BOLD
+ { 0, 16, 0, 24, 32, 0, 0, 0, 16, 0},
+ { 0, 16, 0, 23, 32, 0, 0, 0, 16, 1},
+
+ // DOCILE
+ { 0, 0, 0, 0, 80, 0, 0, 0, 0, 1},
+
+ // RELAXED
+ { 0, 2, 8, 0, 32, 0, 0, 0, 0, 0},
+ { 0, 2, -8, 0, 32, 0, 0, 0, 0, 1},
+
+ // IMPISH
+ { 0, 32, 2, 1, 48, 1, 0, 0, 24, 1},
+
+ // LAX
+ { 0, 2, 16, 16, 128, 0, 0, 0, 0, 1},
+
+ // TIMID
+ { 0, 2, -8, 0, 48, 0, -24, 0, 0, 0},
+ { 0, 0, 0, 0, 8, 0, 0, 0, 0, 0},
+ { 64, 32, 2, 0, 36, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 8, 0, 0, 0, 0, 0},
+ { 0, 2, 8, 0, 48, 0, 24, 0, 0, 1},
+
+ // HASTY
+ { 64, 24, 16, 0, 32, 0, 0, 0, 0, 0},
+ { 0, 28, 2, 1, 32, 1, 0, 0, 16, 1},
+
+ // SERIOUS
+ { 0, 0, 0, 0, 32, 0, 0, 0, 0, 1},
+
+ // JOLLY
+ { 64, 16, -16, 2, 48, 0, 0, 0, 32, 1},
+
+ // NAIVE
+ { 0, 12, -8, 4, 24, 0, 8, 0, 12, 0},
+ { 0, 12, 8, 8, 24, 0, -16, 0, 12, 0},
+ { 0, 12, -8, 16, 24, 0, 16, 0, 12, 0},
+ { 0, 12, 8, 28, 24, 0, -8, 0, 12, 1},
+
+ // MODEST
+ { 0, 0, 0, 0, 8, 0, 0, 0, 0, 0},
+ { 64, 16, -4, 0, 32, 0, 0, 0, 0, 0},
+ { 0, 0, 0, 0, 8, 0, 0, 0, 0, 1},
+
+ // MILD
+ { 128, 4, 0, 8, 64, 0, 0, 0, 0, 1},
+
+ // QUIET
+ { 0, 2, 16, 0, 48, 0, 0, 0, 0, 0},
+ { 128, 2, 16, 0, 48, 0, 0, 0, 0, 1},
+
+ // BASHFUL
+ { 0, 2, -4, 0, 48, 0, -48, 0, 0, 0},
+ { 0, 0, 0, 0, 80, 0, 0, 0, 0, 0},
+ { 0, 2, 8, 0, 24, 0, 48, 0, 0, 1},
+
+ // RASH
+ { 64, 4, 64, 58, 52, 0, -88, 0, 0, 0},
+ { 0, 0, 0, 0, 80, 0, 0, 0, 0, 0},
+ { 0, 24, 80, 0, 32, 0, 88, 0, 0, 1},
+
+ // CALM
+ { 0, 2, 16, 4, 64, 0, 0, 0, 0, 1},
+
+ // GENTLE
+ { 0, 0, 0, 0, 32, 0, 0, 0, 0, 1},
+
+ // SASSY
+ { 0, 0, 0, 0, 42, 0, 0, 0, 0, 1},
+
+ // CAREFUL
+ { 0, 4, 0, 8, 24, 0, 0, 0, 12, 0},
+ { 0, 0, 0, 0, 12, 0, 0, 0, 0, 0},
+ { 0, 4, 0, 12, 24, 0, 0, 0, 12, 0},
+ { 0, 0, 0, 0, 12, 0, 0, 0, 0, 0},
+ { 0, 4, 0, 4, 24, 0, 0, 0, 12, 1},
+
+ // QUIRKY
+ { 0, 4, 16, 12, 64, 0, 0, 0, 0, 0},
+ { 0, -4, 16, 12, 64, 0, 0, 0, 0, 1},
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8411E90[] =
+{
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8411EA0[] =
+{
+ AFFINEANIMCMD_FRAME(0, 0, 12, 1),
+ AFFINEANIMCMD_FRAME(0, 0, 0, 30),
+ AFFINEANIMCMD_FRAME(0, 0, -12, 1),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8411EC0[] =
+{
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0, 0, 12, 1),
+ AFFINEANIMCMD_FRAME(0, 0, 0, 28),
+ AFFINEANIMCMD_FRAME(0, 0, -4, 3),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8411EE8[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 16),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -1, 32),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 16),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8411F08[] =
+{
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 16),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -1, 32),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 16),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8411F30[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -1, 8),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 16),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 8),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8411F50[] =
+{
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -1, 8),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 16),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 8),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8411F78[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -1, 8),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 32),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 8),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8411F98[] =
+{
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -1, 8),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 32),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 8),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8411FC0[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -1, 4),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 24),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 4),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8411FE0[] =
+{
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -1, 4),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 24),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 4),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8412008[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 24),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 16),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -12, 2),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8412028[] =
+{
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 1, 24),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 16),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -12, 2),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd *const sSpriteAffineAnimTable_85F04FC[] =
+{
+ sSpriteAffineAnim_8411E90,
+ sSpriteAffineAnim_8411EA0,
+ sSpriteAffineAnim_8411EE8,
+ sSpriteAffineAnim_8411F30,
+ sSpriteAffineAnim_8411F78,
+ sSpriteAffineAnim_8411FC0,
+ sSpriteAffineAnim_8412008,
+ sSpriteAffineAnim_8411E90,
+ sSpriteAffineAnim_8411E90,
+ sSpriteAffineAnim_8411E90,
+ sSpriteAffineAnim_8411E90,
+ sSpriteAffineAnim_8411EC0,
+ sSpriteAffineAnim_8411F08,
+ sSpriteAffineAnim_8411F50,
+ sSpriteAffineAnim_8411F98,
+ sSpriteAffineAnim_8411FE0,
+ sSpriteAffineAnim_8412028,
+ sSpriteAffineAnim_8411E90,
+ sSpriteAffineAnim_8411E90,
+ sSpriteAffineAnim_8411E90,
+ sSpriteAffineAnim_8411E90,
+};
+
+static const struct BgTemplate sBackgroundTemplates[] =
+{
+ {
+ .bg = 0,
+ .charBaseIndex = 0,
+ .mapBaseIndex = 31,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 0,
+ .baseTile = 0
+ },
+ {
+ .bg = 1,
+ .charBaseIndex = 2,
+ .mapBaseIndex = 30,
+ .screenSize = 0,
+ .paletteMode = 0,
+ .priority = 3,
+ .baseTile = 0
+ }
+};
+
+static const struct WindowTemplate sWindowTemplates[] =
+{
+ {0, 1, 0xF, 0x1C, 4, 0xF, 0xA},
+ DUMMY_WIN_TEMPLATE
+};
+
+static const u8* const sPokeblocksPals[] =
+{
+ gPokeblockRed_Pal,
+ gPokeblockBlue_Pal,
+ gPokeblockPink_Pal,
+ gPokeblockGreen_Pal,
+ gPokeblockYellow_Pal,
+ gPokeblockPurple_Pal,
+ gPokeblockIndigo_Pal,
+ gPokeblockBrown_Pal,
+ gPokeblockLiteBlue_Pal,
+ gPokeblockOlive_Pal,
+ gPokeblockGray_Pal,
+ gPokeblockBlack_Pal,
+ gPokeblockWhite_Pal,
+ gPokeblockGold_Pal
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_84120DC[] =
+{
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd *const sSpriteAffineAnimTable_MonNoFlip[] =
+{
+ sSpriteAffineAnim_84120DC
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_84120F0[] =
+{
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -8, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -8, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -8, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -8, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 8),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 16, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 16, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 16, 1),
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_8412148[] =
+{
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 8, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 8, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 8, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 8, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 8),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -16, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -16, 1),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -16, 1),
+ AFFINEANIMCMD_FRAME(-0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_END
+};
+
+static const union AffineAnimCmd *const sSpriteAffineAnimTable_85F0664[] =
+{
+ sSpriteAffineAnim_84120DC
+};
+
+static const union AffineAnimCmd *const sSpriteAffineAnimTable_85F0668[] =
+{
+ sSpriteAffineAnim_84120F0
+};
+
+static const union AffineAnimCmd *const sSpriteAffineAnimTable_85F066C[] =
+{
+ sSpriteAffineAnim_8412148
+};
+
+static const struct OamData sThrownPokeblockOamData =
+{
+ .y = 0,
+ .affineMode = 3,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 0,
+ .tileNum = 0,
+ .priority = 1,
+ .paletteNum = 0,
+ .affineParam = 0,
+};
+
+static const union AnimCmd sThrownPokeblockSpriteAnim[] =
+{
+ ANIMCMD_FRAME(0, 0),
+ ANIMCMD_END
+};
+
+static const union AnimCmd *const sThrownPokeblockAnimTable[] =
+{
+ sThrownPokeblockSpriteAnim,
+};
+
+static const union AffineAnimCmd sSpriteAffineAnim_84121C0[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(-8, -8, 0, 1),
+ AFFINEANIMCMD_JUMP(1)
+};
+
+static const union AffineAnimCmd *const sThrownPokeblockAffineAnimTable[] =
+{
+ sSpriteAffineAnim_84121C0
+};
+
+static const struct CompressedSpriteSheet sPokeblock_SpriteSheet =
+{
+ gPokeblock_Gfx, 0x20, GFX_TAG_POKEBLOCK
+};
+
+static const struct SpriteTemplate sThrownPokeblockSpriteTemplate =
+{
+ .tileTag = GFX_TAG_POKEBLOCK,
+ .paletteTag = GFX_TAG_POKEBLOCK,
+ .oam = &sThrownPokeblockOamData,
+ .anims = sThrownPokeblockAnimTable,
+ .images = NULL,
+ .affineAnims = sThrownPokeblockAffineAnimTable,
+ .callback = SpriteCB_ThrownPokeblock
+};
+
+// code
+static void CB2_PokeblockFeed(void)
+{
+ RunTasks();
+ AnimateSprites();
+ BuildOamBuffer();
+ do_scheduled_bg_tilemap_copies_to_vram();
+ UpdatePaletteFade();
+}
+
+static void VBlankCB_PokeblockFeed(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+}
+
+static bool8 TransitionToPokeblockFeedScene(void)
+{
+ switch (gMain.state)
+ {
+ case 0:
+ sPokeblockFeed = AllocZeroed(sizeof(*sPokeblockFeed));
+ SetVBlankHBlankCallbacksToNull();
+ clear_scheduled_bg_copies_to_vram();
+ gMain.state++;
+ break;
+ case 1:
+ ResetPaletteFade();
+ gPaletteFade.bufferTransferDisabled = 1;
+ gMain.state++;
+ break;
+ case 2:
+ ResetSpriteData();
+ gMain.state++;
+ break;
+ case 3:
+ FreeAllSpritePalettes();
+ gMain.state++;
+ break;
+ case 4:
+ AllocateMonSpritesGfx();
+ gMain.state++;
+ break;
+ case 5:
+ HandleInitBackgrounds();
+ gMain.state++;
+ break;
+ case 6:
+ HandleInitWindows();
+ gMain.state++;
+ break;
+ case 7:
+ if (LoadMonAndSceneGfx(&gPlayerParty[gPokeblockMonId]))
+ {
+ gMain.state++;
+ }
+ break;
+ case 8:
+ sPokeblockFeed->pokeblockCaseSpriteId = CreatePokeblockCaseSpriteForFeeding();
+ gMain.state++;
+ break;
+ case 9:
+ sPokeblockFeed->monSpriteId = CreateMonSprite(&gPlayerParty[gPokeblockMonId]);
+ gMain.state++;
+ break;
+ case 10:
+ SetWindowBorderStyle(0, 1, 1, 14);
+ gMain.state++;
+ break;
+ case 11:
+ LaunchPokeblockFeedTask();
+ gMain.state++;
+ break;
+ case 12:
+ BlendPalettes(-1, 0x10, 0);
+ gMain.state++;
+ break;
+ case 13:
+ BeginNormalPaletteFade(-1, 0, 0x10, 0, 0);
+ gPaletteFade.bufferTransferDisabled = 0;
+ gMain.state++;
+ break;
+ default:
+ SetVBlankCallback(VBlankCB_PokeblockFeed);
+ SetMainCallback2(CB2_PokeblockFeed);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void CB2_PreparePokeblockFeedScene(void)
+{
+ while (1)
+ {
+ if (sub_81221EC() == TRUE)
+ break;
+ if (TransitionToPokeblockFeedScene() == TRUE)
+ break;
+ if (sub_81221AC() == TRUE)
+ break;
+ }
+}
+
+static void HandleInitBackgrounds(void)
+{
+ ResetVramOamAndBgCntRegs();
+
+ ResetBgsAndClearDma3BusyFlags(0);
+ InitBgsFromTemplates(0, sBackgroundTemplates, ARRAY_COUNT(sBackgroundTemplates));
+ SetBgTilemapBuffer(1, sPokeblockFeed->tilemapBuffer);
+ ResetAllBgsCoordinates();
+ schedule_bg_copy_tilemap_to_vram(1);
+
+ SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
+
+ ShowBg(0);
+ ShowBg(1);
+
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+}
+
+static bool8 LoadMonAndSceneGfx(struct Pokemon *mon)
+{
+ u16 species;
+ u32 personality, trainerId;
+ const struct CompressedSpritePalette *palette;
+
+ switch (sPokeblockFeed->loadGfxState)
+ {
+ case 0:
+ species = GetMonData(mon, MON_DATA_SPECIES2);
+ personality = GetMonData(mon, MON_DATA_PERSONALITY);
+ HandleLoadSpecialPokePic_2(&gMonFrontPicTable[species], gMonSpritesGfxPtr->sprites[1], species, personality);
+ sPokeblockFeed->loadGfxState++;
+ break;
+ case 1:
+ species = GetMonData(mon, MON_DATA_SPECIES2);
+ personality = GetMonData(mon, MON_DATA_PERSONALITY);
+ trainerId = GetMonData(mon, MON_DATA_OT_ID);
+ palette = GetMonSpritePalStructFromOtIdPersonality(species, trainerId, personality);
+
+ LoadCompressedObjectPalette(palette);
+ sub_806A068(palette->tag, 1);
+ sPokeblockFeed->loadGfxState++;
+ break;
+ case 2:
+ LoadCompressedObjectPic(&gPokeblockCase_SpriteSheet);
+ sPokeblockFeed->loadGfxState++;
+ break;
+ case 3:
+ LoadCompressedObjectPalette(&gPokeblockCase_SpritePal);
+ sPokeblockFeed->loadGfxState++;
+ break;
+ case 4:
+ LoadCompressedObjectPic(&sPokeblock_SpriteSheet);
+ sPokeblockFeed->loadGfxState++;
+ break;
+ case 5:
+ SetPokeblockSpritePal(gSpecialVar_ItemId);
+ LoadCompressedObjectPalette(&sPokeblockSpritePal);
+ sPokeblockFeed->loadGfxState++;
+ break;
+ case 6:
+ reset_temp_tile_data_buffers();
+ decompress_and_copy_tile_data_to_vram(1, gBattleTerrainTiles_Building, 0, 0, 0);
+ sPokeblockFeed->loadGfxState++;
+ break;
+ case 7:
+ if (free_temp_tile_data_buffers_if_possible() != TRUE)
+ {
+ LZDecompressWram(gUnknown_08D9BA44, sPokeblockFeed->tilemapBuffer);
+ sPokeblockFeed->loadGfxState++;
+ }
+ break;
+ case 8:
+ LoadCompressedPalette(gBattleTerrainPalette_Frontier, 0x20, 0x60);
+ sPokeblockFeed->loadGfxState = 0;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void HandleInitWindows(void)
+{
+ InitWindows(sWindowTemplates);
+ DeactivateAllTextPrinters();
+ sub_809882C(0, 1, 0xE0);
+ LoadPalette(gUnknown_0860F074, 0xF0, 0x20);
+ FillWindowPixelBuffer(0, 0);
+ PutWindowTilemap(0);
+ schedule_bg_copy_tilemap_to_vram(0);
+}
+
+static void SetPokeblockSpritePal(u8 pokeblockCaseId)
+{
+ u8 colorId = GetPokeblockData(&gSaveBlock1Ptr->pokeblocks[pokeblockCaseId], PBLOCK_COLOR);
+ sPokeblockSpritePal.data = sPokeblocksPals[colorId - 1];
+ sPokeblockSpritePal.tag = GFX_TAG_POKEBLOCK;
+}
+
+// defines for task data fields
+
+#define tFrames data[0]
+#define tData1 data[1]
+
+static void Task_HandlePokeblockFeed(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ switch (gTasks[taskId].tFrames)
+ {
+ case 0:
+ sPokeblockFeed->field_1050 = 0;
+ sPokeblockFeed->field_1058 = 0;
+ sub_817A5CC();
+ break;
+ case 255:
+ DoPokeblockCaseThrowEffect(sPokeblockFeed->pokeblockCaseSpriteId, gTasks[taskId].tData1);
+ break;
+ case 269:
+ sPokeblockFeed->pokeblockSpriteId = CreatePokeblockSprite();
+ break;
+ case 281:
+ PrepareMonToMoveToPokeblock(sPokeblockFeed->monSpriteId);
+ break;
+ case 297:
+ gTasks[taskId].func = Task_HandleMonAtePokeblock;
+ return;
+ }
+
+ if (sPokeblockFeed->field_1058 < sPokeblockFeed->field_1056)
+ sub_817A634();
+ else if (sPokeblockFeed->field_1058 == sPokeblockFeed->field_1056)
+ gTasks[taskId].tFrames = 254;
+
+ sPokeblockFeed->field_1058++;
+ gTasks[taskId].tFrames++;
+ }
+}
+
+static void LaunchPokeblockFeedTask(void)
+{
+ u8 taskId = CreateTask(Task_HandlePokeblockFeed, 0);
+ gTasks[taskId].tFrames = 0;
+ gTasks[taskId].tData1 = 1;
+}
+
+static void Task_WaitForAtePokeblockText(u8 taskId)
+{
+ if (RunTextPrintersRetIsActive(0) != TRUE)
+ gTasks[taskId].func = Task_PaletteFadeToReturn;
+}
+
+static void Task_HandleMonAtePokeblock(u8 taskId)
+{
+ struct Pokemon *mon = &gPlayerParty[gPokeblockMonId];
+ struct Pokeblock *pokeblock = &gSaveBlock1Ptr->pokeblocks[gSpecialVar_ItemId];
+
+ gPokeblockGain = PokeblockGetGain(GetNature(mon), pokeblock);
+ GetMonNickname(mon, gStringVar1);
+ PokeblockCopyName(pokeblock, gStringVar2);
+
+ if (gPokeblockGain == 0)
+ StringExpandPlaceholders(gStringVar4, gText_Var1AteTheVar2);
+ else if (gPokeblockGain > 0)
+ StringExpandPlaceholders(gStringVar4, gText_Var1HappilyAteVar2);
+ else
+ StringExpandPlaceholders(gStringVar4, gText_Var1DisdainfullyAteVar2);
+
+ gTextFlags.flag_0 = 1;
+ AddTextPrinterParametrized(0, 1, gStringVar4, GetPlayerTextSpeed(), NULL, 2, 1, 3);
+ gTasks[taskId].func = Task_WaitForAtePokeblockText;
+}
+
+static void Task_ReturnAfterPaletteFade(u8 taskId)
+{
+ if (!gPaletteFade.active)
+ {
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ m4aMPlayVolumeControl(&gMPlay_BGM, -1, 256);
+ SetMainCallback2(gMain.savedCallback);
+ DestroyTask(taskId);
+ FreeAllWindowBuffers();
+ Free(sPokeblockFeed);
+ FreeMonSpritesGfx();
+ }
+}
+
+static void Task_PaletteFadeToReturn(u8 taskId)
+{
+ BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
+ gTasks[taskId].func = Task_ReturnAfterPaletteFade;
+}
+
+#undef tFrames
+#undef tData1
+
+// defines for mon sprite data fields
+
+#define tDelta data[0]
+#define tDeltaMod data[1]
+#define tSpecies data[2]
+
+static u8 CreateMonSprite(struct Pokemon* mon)
+{
+ u16 species = GetMonData(mon, MON_DATA_SPECIES2);
+ u8 spriteId = CreateSprite(&gUnknown_0202499C, 48, 80, 2);
+
+ sPokeblockFeed->species = species;
+ sPokeblockFeed->monSpriteId_ = spriteId;
+ sPokeblockFeed->nature = GetNature(mon);
+ gSprites[spriteId].tSpecies = species;
+ gSprites[spriteId].callback = SpriteCallbackDummy;
+
+ sPokeblockFeed->noMonFlip = TRUE;
+ if (!IsPokeSpriteNotFlipped(species))
+ {
+ gSprites[spriteId].affineAnims = sSpriteAffineAnimTable_MonNoFlip;
+ gSprites[spriteId].oam.affineMode = 3;
+ CalcCenterToCornerVec(&gSprites[spriteId], gSprites[spriteId].oam.shape, gSprites[spriteId].oam.size, gSprites[spriteId].oam.affineMode);
+ sPokeblockFeed->noMonFlip = FALSE;
+ }
+
+ return spriteId;
+}
+
+static void PrepareMonToMoveToPokeblock(u8 spriteId)
+{
+ gSprites[spriteId].pos1.x = 48;
+ gSprites[spriteId].pos1.y = 80;
+ gSprites[spriteId].tDelta = -8;
+ gSprites[spriteId].tDeltaMod = 1;
+ gSprites[spriteId].callback = sub_817A468;
+}
+
+static void sub_817A468(struct Sprite* sprite)
+{
+ sprite->pos1.x += 4;
+ sprite->pos1.y += sprite->tDelta;
+ sprite->tDelta += sprite->tDeltaMod;
+
+ if (sprite->tDelta == 0)
+ PlayCry1(sprite->tSpecies, 0);
+ if (sprite->tDelta == 9)
+ sprite->callback = SpriteCallbackDummy;
+}
+
+#undef tDelta
+#undef tDeltaMod
+#undef tSpecies
+
+static u8 CreatePokeblockCaseSpriteForFeeding(void)
+{
+ u8 spriteId = CreatePokeblockCaseSprite(188, 100, 2);
+ gSprites[spriteId].oam.affineMode = 1;
+ gSprites[spriteId].affineAnims = sSpriteAffineAnimTable_85F0664;
+ gSprites[spriteId].callback = SpriteCallbackDummy;
+ InitSpriteAffineAnim(&gSprites[spriteId]);
+ return spriteId;
+}
+
+static void DoPokeblockCaseThrowEffect(u8 spriteId, bool8 a1)
+{
+ FreeOamMatrix(gSprites[spriteId].oam.matrixNum);
+ gSprites[spriteId].oam.affineMode = 3;
+
+ if (!a1)
+ gSprites[spriteId].affineAnims = sSpriteAffineAnimTable_85F0668;
+ else
+ gSprites[spriteId].affineAnims = sSpriteAffineAnimTable_85F066C;
+
+ InitSpriteAffineAnim(&gSprites[spriteId]);
+}
+
+// defines for the pokeblock sprite data fields
+#define tDelta data[0]
+#define tDeltaMod data[1]
+
+static u8 CreatePokeblockSprite(void)
+{
+ u8 spriteId = CreateSprite(&sThrownPokeblockSpriteTemplate, 174, 84, 1);
+ gSprites[spriteId].tDelta = -12;
+ gSprites[spriteId].tDeltaMod = 1;
+ return spriteId;
+}
+
+static void SpriteCB_ThrownPokeblock(struct Sprite* sprite)
+{
+ sprite->pos1.x -= 4;
+ sprite->pos1.y += sprite->tDelta;
+ sprite->tDelta += sprite->tDeltaMod;
+ if (sprite->tDelta == 10)
+ DestroySprite(sprite);
+}
+
+#undef tDelta
+#undef tDeltaMod
+
+static void sub_817A5CC(void)
+{
+ u8 animId, i;
+ struct PokeblockFeedStruct *pokeblockFeed;
+
+ pokeblockFeed = sPokeblockFeed;
+ pokeblockFeed->field_1056 = 1;
+ animId = sNatureToMonPokeblockAnim[pokeblockFeed->nature][0];
+ for (i = 0; i < 8; i++, animId++)
+ {
+ pokeblockFeed->field_1056 += sMonPokeblockAnims[animId][4];
+ if (sMonPokeblockAnims[animId][9] == 1)
+ break;
+ }
+}
+
+static void sub_817A634(void)
+{
+ struct PokeblockFeedStruct *pokeblockFeed = sPokeblockFeed;
+
+ switch (pokeblockFeed->field_1050)
+ {
+ case 0:
+ pokeblockFeed->animId = sNatureToMonPokeblockAnim[pokeblockFeed->nature][0];
+ pokeblockFeed->monSpritePtr = &gSprites[pokeblockFeed->monSpriteId_];
+ pokeblockFeed->savedMonSprite = *pokeblockFeed->monSpritePtr;
+ pokeblockFeed->field_1050 = 10;
+ break;
+ case 1 ... 9:
+ break;
+ case 10:
+ sub_817A91C();
+ if (sNatureToMonPokeblockAnim[pokeblockFeed->nature][1] != 0)
+ {
+ pokeblockFeed->monSpritePtr->oam.affineMode = 3;
+ pokeblockFeed->monSpritePtr->oam.matrixNum = 0;
+ pokeblockFeed->monSpritePtr->affineAnims = sSpriteAffineAnimTable_85F04FC;
+ InitSpriteAffineAnim(pokeblockFeed->monSpritePtr);
+ }
+ pokeblockFeed->field_1050 = 50;
+ case 50:
+ if (sNatureToMonPokeblockAnim[pokeblockFeed->nature][1] != 0)
+ {
+ if (!pokeblockFeed->noMonFlip) // double negation, so mon's sprite is flipped
+ StartSpriteAffineAnim(pokeblockFeed->monSpritePtr, sNatureToMonPokeblockAnim[pokeblockFeed->nature][1] + 10);
+ else
+ StartSpriteAffineAnim(pokeblockFeed->monSpritePtr, sNatureToMonPokeblockAnim[pokeblockFeed->nature][1]);
+ }
+ pokeblockFeed->field_1050 = 60;
+ break;
+ case 60:
+ if (sub_817A9E4() == TRUE)
+ {
+ if (pokeblockFeed->field_1060[9] == 0)
+ {
+ pokeblockFeed->animId++;
+ sub_817A91C();
+ pokeblockFeed->field_1050 = 60;
+ }
+ else
+ {
+ FreeOamMatrix(pokeblockFeed->monSpritePtr->oam.matrixNum);
+ pokeblockFeed->field_1050 = 70;
+ }
+ }
+ break;
+ case 70:
+ FreeMonSpriteOamMatrix();
+ pokeblockFeed->animId = 0;
+ pokeblockFeed->field_1050 = 0;
+ break;
+ case 71 ... 90:
+ break;
+ }
+}
+
+static bool8 sub_817A91C(void)
+{
+ struct PokeblockFeedStruct *pokeblockFeed = sPokeblockFeed;
+ u8 i;
+
+ for (i = 0; i < 10; i++)
+ pokeblockFeed->field_1060[i] = sMonPokeblockAnims[pokeblockFeed->animId][i];
+
+ if (pokeblockFeed->field_1060[4] == 0)
+ {
+ return TRUE;
+ }
+ else
+ {
+ pokeblockFeed->field_1060[10] = Sin(pokeblockFeed->field_1060[0], pokeblockFeed->field_1060[2]);
+ pokeblockFeed->field_1060[11] = Cos(pokeblockFeed->field_1060[0], pokeblockFeed->field_1060[3]);
+ pokeblockFeed->field_1060[12] = pokeblockFeed->field_1060[4];
+ pokeblockFeed->field_1060[13] = pokeblockFeed->monSpritePtr->pos2.x;
+ pokeblockFeed->field_1060[14] = pokeblockFeed->monSpritePtr->pos2.y;
+ sub_817AB68();
+ pokeblockFeed->field_1060[4] = pokeblockFeed->field_1060[12];
+ sub_817AA54();
+ pokeblockFeed->field_1060[4] = pokeblockFeed->field_1060[12];
+ return FALSE;
+ }
+}
+
+static bool8 sub_817A9E4(void)
+{
+ u16 var = sPokeblockFeed->field_1060[12] - sPokeblockFeed->field_1060[4];
+
+ sPokeblockFeed->monSpritePtr->pos2.x = sPokeblockFeed->field_850[var];
+ sPokeblockFeed->monSpritePtr->pos2.y = sPokeblockFeed->field_C50[var];
+
+ if (--sPokeblockFeed->field_1060[4] == 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static bool8 FreeMonSpriteOamMatrix(void)
+{
+ FreeSpriteOamMatrix(sPokeblockFeed->monSpritePtr);
+ return FALSE;
+}
+
+static void sub_817AA54(void)
+{
+ struct PokeblockFeedStruct *pokeblockFeed = sPokeblockFeed;
+ u16 i;
+ u16 r8 = pokeblockFeed->field_1060[8];
+ u16 r7 = pokeblockFeed->field_1060[12] - r8;
+ s16 var3 = pokeblockFeed->field_1060[13] + pokeblockFeed->field_1060[6];
+ s16 r9 = pokeblockFeed->field_1060[14] + pokeblockFeed->field_1060[7];
+
+ for (i = 0; i < r7 - 1; i++)
+ {
+ s16 r1 = pokeblockFeed->field_850[r8 + i] - (var3);
+ s16 r4 = pokeblockFeed->field_C50[r8 + i] - r9;
+
+ pokeblockFeed->field_850[r8 + i] -= r1 * (i + 1) / r7;
+ pokeblockFeed->field_C50[r8 + i] -= r4 * (i + 1) / r7;
+ }
+
+ pokeblockFeed->field_850[(r8 + r7) - 1] = var3;
+ pokeblockFeed->field_C50[(r8 + r7) - 1] = r9;
+}
+
+static void sub_817AB68(void)
+{
+ struct PokeblockFeedStruct *pokeblockFeed = sPokeblockFeed;
+ bool8 var_24 = FALSE;
+ s16 r8 = pokeblockFeed->field_1060[13] - pokeblockFeed->field_1060[10];
+ s16 r7 = pokeblockFeed->field_1060[14] - pokeblockFeed->field_1060[11];
+
+ while (1)
+ {
+ u16 r5;
+ u16 r4;
+ u16 var;
+
+ var = abs(pokeblockFeed->field_1060[5]);
+ r5 = var + pokeblockFeed->field_1060[3];
+ pokeblockFeed->field_1060[3] = r5;
+
+ if (pokeblockFeed->field_1060[2] < 0)
+ var_24 = TRUE;
+
+ r4 = pokeblockFeed->field_1060[12] - pokeblockFeed->field_1060[4];
+
+ if (pokeblockFeed->field_1060[4] == 0)
+ break;
+
+ if (!var_24)
+ {
+ pokeblockFeed->field_850[r4] = Sin(pokeblockFeed->field_1060[0], pokeblockFeed->field_1060[2] + r5 / 256) + r8;
+ pokeblockFeed->field_C50[r4] = Cos(pokeblockFeed->field_1060[0], pokeblockFeed->field_1060[3] + r5 / 256) + r7;
+ }
+ else
+ {
+ pokeblockFeed->field_850[r4] = Sin(pokeblockFeed->field_1060[0], pokeblockFeed->field_1060[2] - r5 / 256) + r8;
+ pokeblockFeed->field_C50[r4] = Cos(pokeblockFeed->field_1060[0], pokeblockFeed->field_1060[3] - r5 / 256) + r7;
+ }
+
+ pokeblockFeed->field_1060[0] += pokeblockFeed->field_1060[1];
+ pokeblockFeed->field_1060[0] &= 0xFF;
+ pokeblockFeed->field_1060[4]--;
+ }
+}
diff --git a/src/pokemon_3.c b/src/pokemon_3.c
index a419dd46e..8fb642f5f 100644
--- a/src/pokemon_3.c
+++ b/src/pokemon_3.c
@@ -22,6 +22,7 @@
#include "constants/abilities.h"
#include "pokemon_animation.h"
#include "pokedex.h"
+#include "pokeblock.h"
extern struct BattlePokemon gBattleMons[4];
extern struct BattleEnigmaBerry gEnigmaBerries[4];
@@ -59,7 +60,6 @@ extern const u8 gText_PkmnsXPreventsSwitching[];
extern const struct CompressedSpritePalette gMonPaletteTable[];
extern const struct CompressedSpritePalette gMonShinyPaletteTable[];
extern const u16 gHMMoves[];
-extern const s8 gPokeblockFlavorCompatibilityTable[];
extern const u8 gMonAnimationDelayTable[];
extern const u8 gMonFrontAnimIdsTable[];
@@ -1297,21 +1297,21 @@ bool8 IsPokeSpriteNotFlipped(u16 species)
return gBaseStats[species].noFlip;
}
-s8 GetMonFlavorRelation(struct Pokemon *mon, u8 a2)
+s8 GetMonFlavorRelation(struct Pokemon *mon, u8 flavour)
{
u8 nature = GetNature(mon);
- return gPokeblockFlavorCompatibilityTable[nature * 5 + a2];
+ return gPokeblockFlavorCompatibilityTable[nature * 5 + flavour];
}
-s8 GetFlavorRelationByPersonality(u32 personality, u8 a2)
+s8 GetFlavorRelationByPersonality(u32 personality, u8 flavour)
{
u8 nature = GetNatureFromPersonality(personality);
- return gPokeblockFlavorCompatibilityTable[nature * 5 + a2];
+ return gPokeblockFlavorCompatibilityTable[nature * 5 + flavour];
}
bool8 IsTradedMon(struct Pokemon *mon)
{
- u8 otName[8];
+ u8 otName[OT_NAME_LENGTH + 1];
u32 otId;
GetMonData(mon, MON_DATA_OT_NAME, otName);
otId = GetMonData(mon, MON_DATA_OT_ID, 0);
diff --git a/src/pokemon_summary_screen.c b/src/pokemon_summary_screen.c
index b00979945..ba0c4dde7 100755
--- a/src/pokemon_summary_screen.c
+++ b/src/pokemon_summary_screen.c
@@ -73,7 +73,7 @@ extern void do_scheduled_bg_tilemap_copies_to_vram(void);
extern u8 sub_81221EC();
extern u8 sub_81221AC();
extern void SetVBlankHBlankCallbacksToNull();
-extern void sub_8121DA0();
+extern void ResetVramOamAndBgCntRegs();
extern void clear_scheduled_bg_copies_to_vram();
extern void remove_some_task();
extern void ResetBgsAndClearDma3BusyFlags(u32 leftoverFireRedLeafGreenVariable);
@@ -193,7 +193,7 @@ void sub_81C4A88();
void sub_81C4280();
void sub_81C0510(u8 taskId);
void sub_81C171C(u8 taskId);
-void sub_8121E10();
+void ResetAllBgsCoordinates();
u8 sub_81B205C(struct Pokemon* a);
void sub_81C1DA4(u16 a, s16 b);
void sub_81C1EFC(u16 a, s16 b, u16 c);
@@ -450,7 +450,7 @@ bool8 sub_81BFB10(void)
{
case 0:
SetVBlankHBlankCallbacksToNull();
- sub_8121DA0();
+ ResetVramOamAndBgCntRegs();
clear_scheduled_bg_copies_to_vram();
gMain.state++;
break;
@@ -578,7 +578,7 @@ void sub_81BFE24()
SetBgTilemapBuffer(1, &gUnknown_0203CF1C->unkTilemap2);
SetBgTilemapBuffer(2, &gUnknown_0203CF1C->unkTilemap1);
SetBgTilemapBuffer(3, &gUnknown_0203CF1C->unkTilemap0);
- sub_8121E10();
+ ResetAllBgsCoordinates();
schedule_bg_copy_tilemap_to_vram(1);
schedule_bg_copy_tilemap_to_vram(2);
schedule_bg_copy_tilemap_to_vram(3);
diff --git a/src/safari_zone.c b/src/safari_zone.c
index 19a26dad9..8bd1fffa7 100644
--- a/src/safari_zone.c
+++ b/src/safari_zone.c
@@ -5,6 +5,7 @@
#include "main.h"
#include "battle.h"
#include "string_util.h"
+#include "pokeblock.h"
struct PokeblockFeeder
{
@@ -24,7 +25,6 @@ extern u8 EventScript_2A4B8A[];
extern u8 EventScript_2A4B6F[];
extern u8 EventScript_2A4B4C[];
extern u8 EventScript_2A4B9B[];
-extern const u8* const gPokeblockNames[];
extern void sub_80EE44C(u8, u8);
extern void IncrementGameStat(u8 index);
diff --git a/src/secret_base.c b/src/secret_base.c
index 6d66e6576..6926bd804 100644
--- a/src/secret_base.c
+++ b/src/secret_base.c
@@ -1082,13 +1082,13 @@ void game_continue(u8 taskId)
if (sub_80E9878(i))
{
sub_80E9780(gUnknown_0203A020->names[count], i);
- gUnknown_0203A020->items[count].unk_00 = gUnknown_0203A020->names[count];
- gUnknown_0203A020->items[count].unk_04 = i;
+ gUnknown_0203A020->items[count].name = gUnknown_0203A020->names[count];
+ gUnknown_0203A020->items[count].id = i;
count ++;
}
}
- gUnknown_0203A020->items[count].unk_00 = gText_Cancel;
- gUnknown_0203A020->items[count].unk_04 = -2;
+ gUnknown_0203A020->items[count].name = gText_Cancel;
+ gUnknown_0203A020->items[count].id = -2;
data[0] = count + 1;
if (data[0] < 8)
{
@@ -1098,11 +1098,11 @@ void game_continue(u8 taskId)
{
data[3] = 8;
}
- gUnknown_03006310 = gUnknown_0858D07C;
- gUnknown_03006310.unk_10 = data[6];
- gUnknown_03006310.totalItems = data[0];
- gUnknown_03006310.items = gUnknown_0203A020->items;
- gUnknown_03006310.maxShowed = data[3];
+ gMultiuseListMenuTemplate = gUnknown_0858D07C;
+ gMultiuseListMenuTemplate.unk_10 = data[6];
+ gMultiuseListMenuTemplate.totalItems = data[0];
+ gMultiuseListMenuTemplate.items = gUnknown_0203A020->items;
+ gMultiuseListMenuTemplate.maxShowed = data[3];
}
void sub_80E9DEC(u32 a0, bool8 flag, struct ListMenu *menu)
@@ -1119,7 +1119,7 @@ void sub_80E9E00(u8 taskId)
data = gTasks[taskId].data;
SetStandardWindowBorderStyle(data[6], 0);
- data[5] = ListMenuInit(&gUnknown_03006310, data[2], data[1]);
+ data[5] = ListMenuInit(&gMultiuseListMenuTemplate, data[2], data[1]);
sub_80E9E44(taskId);
schedule_bg_copy_tilemap_to_vram(0);
}
@@ -1138,8 +1138,8 @@ void sub_80E9E90(u8 taskId)
s32 input;
data = gTasks[taskId].data;
- input = ListMenuHandleInput(data[5]);
- get_coro_args_x18_x1A(data[5], &data[2], &data[1]);
+ input = ListMenuHandleInputGetItemId(data[5]);
+ sub_81AE860(data[5], &data[2], &data[1]);
switch (input)
{
case -1:
diff --git a/src/use_pokeblock.c b/src/use_pokeblock.c
new file mode 100644
index 000000000..12f475c93
--- /dev/null
+++ b/src/use_pokeblock.c
@@ -0,0 +1,230 @@
+#include "global.h"
+#include "main.h"
+#include "pokeblock.h"
+#include "malloc.h"
+#include "palette.h"
+#include "pokenav.h"
+#include "unknown_task.h"
+#include "text.h"
+#include "bg.h"
+#include "window.h"
+#include "text_window.h"
+
+struct UsePokeblockSubStruct
+{
+ void (*field_0)(void);
+ void (*callback)(void);
+ struct Pokeblock *pokeblock;
+ struct Pokemon *pokemon;
+ u8 stringBuffer[0x40];
+ u8 field_50;
+ u8 field_51;
+ u8 field_52;
+ u8 field_53;
+ u8 field_54;
+ u8 field_55;
+ u8 field_56;
+ u8 field_57[5];
+ u8 field_5c[5];
+ u8 field_61[5];
+ s16 field_66[5];
+};
+
+struct UsePokeblockStruct
+{
+ u8 field_0[0x7C58];
+ u8 field_7C58[0x378];
+ struct UsePokeblockSubStruct info;
+};
+
+extern u16 gKeyRepeatStartDelay;
+
+// this file's functions
+void sub_816636C(void (*func)(void));
+void sub_8166380(void);
+void sub_816631C(void);
+void sub_81662C0(void);
+void sub_8166564(void);
+void sub_8166304(void);
+void sub_81668F8(void);
+void sub_8167420(void);
+void sub_8167760(void);
+u8 sub_81672E4(u8 arg0);
+bool8 sub_8168328(void);
+bool8 sub_8167930(void);
+void sub_8167608(u8 arg0);
+void sub_8167BA0(u16 arg0, u8 copyToVramMode);
+
+extern const struct BgTemplate gUnknown_085DFCCC[4];
+extern const struct WindowTemplate gUnknown_085DFCDC[];
+
+// ram variables
+EWRAM_DATA struct UsePokeblockSubStruct *gUnknown_0203BC90 = NULL;
+EWRAM_DATA void (*gUnknown_0203BC94)(void) = NULL;
+EWRAM_DATA struct Pokeblock *gUnknown_0203BC98 = NULL;
+EWRAM_DATA u8 gPokeblockMonId = 0;
+EWRAM_DATA s16 gPokeblockGain = 0;
+EWRAM_DATA void *gUnknown_0203BCA0 = NULL;
+EWRAM_DATA void *gUnknown_0203BCA4 = NULL;
+EWRAM_DATA void *gUnknown_0203BCA8 = NULL;
+EWRAM_DATA struct UsePokeblockStruct *gUnknown_0203BCAC = NULL;
+
+// const rom data
+// todo: make it static once the file is decompiled
+
+// code
+void ChooseMonToGivePokeblock(struct Pokeblock *pokeblock, void (*callback)(void))
+{
+ gUnknown_0203BCAC = AllocZeroed(0x806C);
+ gUnknown_0203BC90 = &gUnknown_0203BCAC->info;
+ gUnknown_0203BC90->pokeblock = pokeblock;
+ gUnknown_0203BC90->callback = callback;
+ sub_816636C(sub_8166380);
+ SetMainCallback2(sub_816631C);
+}
+
+void CB2_ReturnAndChooseMonToGivePokeblock(void)
+{
+ gUnknown_0203BCAC = AllocZeroed(0x806C);
+ gUnknown_0203BC90 = &gUnknown_0203BCAC->info;
+ gUnknown_0203BC90->pokeblock = gUnknown_0203BC98;
+ gUnknown_0203BC90->callback = gUnknown_0203BC94;
+ gPokeblockMonId = sub_81672E4(gPokeblockMonId);
+ gUnknown_0203BC90->field_56 = gPokeblockMonId < 4 ? 0 : 1;
+ sub_816636C(sub_8166380);
+ SetMainCallback2(sub_81662C0);
+}
+
+void sub_81662C0(void)
+{
+ gUnknown_0203BC90->field_0();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+ if (gUnknown_0203BC90->field_0 == sub_8166564)
+ {
+ gUnknown_0203BC90->field_50 = 0;
+ SetMainCallback2(sub_8166304);
+ }
+}
+
+void sub_8166304(void)
+{
+ sub_81668F8();
+ AnimateSprites();
+ BuildOamBuffer();
+ UpdatePaletteFade();
+}
+
+void sub_816631C(void)
+{
+ gUnknown_0203BC90->field_0();
+ AnimateSprites();
+ BuildOamBuffer();
+ RunTextPrinters();
+ UpdatePaletteFade();
+}
+
+void sub_8166340(void)
+{
+ LoadOam();
+ ProcessSpriteCopyRequests();
+ TransferPlttBuffer();
+ sub_81D2108(gUnknown_0203BCAC->field_7C58);
+ sub_80BA0A8();
+}
+
+void sub_816636C(void (*func)(void))
+{
+ gUnknown_0203BC90->field_0 = func;
+ gUnknown_0203BC90->field_50 = 0;
+}
+
+void sub_8166380(void)
+{
+ switch (gUnknown_0203BC90->field_50)
+ {
+ case 0:
+ gUnknown_0203BCAC->field_0[0x7B10] = 0xFF;
+ sub_81D1ED4(gUnknown_0203BCAC->field_7C58);
+ gUnknown_0203BC90->field_50++;
+ break;
+ case 1:
+ ResetSpriteData();
+ FreeAllSpritePalettes();
+ gUnknown_0203BC90->field_50++;
+ break;
+ case 2:
+ SetVBlankCallback(NULL);
+ CpuFill32(0, (void*)(VRAM), VRAM_SIZE);
+ gUnknown_0203BC90->field_50++;
+ break;
+ case 3:
+ ResetBgsAndClearDma3BusyFlags(0);
+ InitBgsFromTemplates(0, gUnknown_085DFCCC, ARRAY_COUNT(gUnknown_085DFCCC));
+ InitWindows(gUnknown_085DFCDC);
+ DeactivateAllTextPrinters();
+ sub_809882C(0, 0x97, 0xE0);
+ gUnknown_0203BC90->field_50++;
+ break;
+ case 4:
+ gUnknown_0203BC90->field_50++;
+ break;
+ case 5:
+ if (!sub_8168328())
+ {
+ gUnknown_0203BC90->field_50++;
+ }
+ break;
+ case 6:
+ gKeyRepeatStartDelay = 20;
+ sub_8167420();
+ gUnknown_0203BC90->field_50++;
+ break;
+ case 7:
+ if (!sub_8167930())
+ {
+ gUnknown_0203BC90->field_50++;
+ }
+ break;
+ case 8:
+ sub_8167608(0);
+ sub_8167760();
+ gUnknown_0203BC90->field_50++;
+ break;
+ case 9:
+ if (!sub_81D312C(&gUnknown_0203BCAC->field_0[0x7B0E]))
+ {
+ gUnknown_0203BC90->field_50++;
+ }
+ break;
+ case 10:
+ gUnknown_0203BC90->field_50++;
+ break;
+ case 11:
+ sub_81D2754(gUnknown_0203BCAC->field_7C58, &gUnknown_0203BCAC->field_0[0x7C6C]);
+ sub_81D20AC(gUnknown_0203BCAC->field_7C58);
+ gUnknown_0203BC90->field_50++;
+ break;
+ case 12:
+ if (!sub_81D20BC(gUnknown_0203BCAC->field_7C58))
+ {
+ sub_81D1F84(gUnknown_0203BCAC->field_7C58, &gUnknown_0203BCAC->field_7C58[0x14], &gUnknown_0203BCAC->field_7C58[0x14]);
+ gUnknown_0203BC90->field_50++;
+ }
+ break;
+ case 13:
+ sub_81D2230(gUnknown_0203BCAC->field_7C58);
+ gUnknown_0203BC90->field_50++;
+ break;
+ case 14:
+ PutWindowTilemap(0);
+ PutWindowTilemap(1);
+ sub_8167BA0(0, 1);
+ gUnknown_0203BC90->field_50++;
+ break;
+ case 15:
+ sub_816636C(sub_8166564);
+ break;
+ }
+}