diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/battle_controller_safari.c | 7 | ||||
-rw-r--r-- | src/berry_blender.c | 2 | ||||
-rw-r--r-- | src/daycare.c | 9 | ||||
-rw-r--r-- | src/decoration.c | 24 | ||||
-rw-r--r-- | src/lilycove_lady.c | 2 | ||||
-rw-r--r-- | src/new_game.c | 3 | ||||
-rw-r--r-- | src/pokeblock.c | 1017 | ||||
-rw-r--r-- | src/pokeblock_feed.c | 1108 | ||||
-rw-r--r-- | src/pokemon_3.c | 12 | ||||
-rwxr-xr-x | src/pokemon_summary_screen.c | 8 | ||||
-rw-r--r-- | src/safari_zone.c | 2 | ||||
-rw-r--r-- | src/secret_base.c | 24 | ||||
-rw-r--r-- | src/use_pokeblock.c | 230 |
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; + } +} |