diff options
author | ProjectRevoTPP <projectrevotpp@hotmail.com> | 2017-08-26 21:24:02 -0400 |
---|---|---|
committer | ProjectRevoTPP <projectrevotpp@hotmail.com> | 2017-08-26 21:24:02 -0400 |
commit | 47b9907ec58c55759a95aed1f31e92fb72031a5f (patch) | |
tree | 5a473edae75105a009135ded3d096f133c34d72b /src | |
parent | 613fd1aa059d6894662566049840f3e1fd8cb02e (diff) | |
parent | 1a33ca381de71bb3b4b250a2f3b41b0c15ed5f21 (diff) |
merge
Diffstat (limited to 'src')
-rw-r--r-- | src/battle/battle_10.c | 14 | ||||
-rw-r--r-- | src/battle/battle_2.c | 4 | ||||
-rw-r--r-- | src/battle/battle_5.c | 1579 | ||||
-rw-r--r-- | src/battle/battle_6.c | 24 | ||||
-rw-r--r-- | src/battle/battle_7.c | 136 | ||||
-rw-r--r-- | src/battle/battle_8.c | 14 | ||||
-rw-r--r-- | src/battle/battle_811DA74.c | 22 | ||||
-rw-r--r-- | src/battle/battle_anim_8137220.c | 12 | ||||
-rw-r--r-- | src/battle/battle_setup.c | 4 | ||||
-rw-r--r-- | src/battle/battle_transition.c | 2513 | ||||
-rw-r--r-- | src/battle/reshow_battle_screen.c | 332 | ||||
-rw-r--r-- | src/debug/mori_debug_menu.c | 2 | ||||
-rw-r--r-- | src/engine/link.c | 5 | ||||
-rw-r--r-- | src/engine/main_menu.c | 4 | ||||
-rw-r--r-- | src/field/field_effect.c | 10 | ||||
-rw-r--r-- | src/field/money.c | 2 | ||||
-rw-r--r-- | src/field/pokeblock.c | 45 | ||||
-rw-r--r-- | src/field/shop.c | 1133 | ||||
-rw-r--r-- | src/field/use_pokeblock.c | 266 | ||||
-rw-r--r-- | src/field/wild_encounter.c | 2 | ||||
-rw-r--r-- | src/pokemon/learn_move.c | 1081 | ||||
-rw-r--r-- | src/pokemon/pokeblock_feed.c | 1015 | ||||
-rw-r--r-- | src/scene/berry_blender.c | 3884 | ||||
-rw-r--r-- | src/scene/cute_sketch.c | 164 | ||||
-rw-r--r-- | src/scene/evolution_graphics.c | 613 |
25 files changed, 12505 insertions, 375 deletions
diff --git a/src/battle/battle_10.c b/src/battle/battle_10.c index 0237bab4b..1a01e5383 100644 --- a/src/battle/battle_10.c +++ b/src/battle/battle_10.c @@ -52,7 +52,7 @@ extern u8 gUnknown_0300434C[]; extern u8 sub_8077F68(); extern u8 sub_8079E90(); extern u8 GetBankIdentity(u8); -extern void sub_8031794(struct Pokemon *, u8); +extern void BattleLoadOpponentMonSprite(struct Pokemon *, u8); extern void sub_8037A74(void); extern void sub_8032984(u8, u16); extern void sub_8037E30(void); @@ -696,7 +696,7 @@ void sub_8039294(void) { u16 species = GetMonData(&gEnemyParty[gBattlePartyID[gActiveBank]], MON_DATA_SPECIES); - sub_8031794(&gEnemyParty[gBattlePartyID[gActiveBank]], gActiveBank); + BattleLoadOpponentMonSprite(&gEnemyParty[gBattlePartyID[gActiveBank]], gActiveBank); GetMonSpriteTemplate_803C56C(species, GetBankIdentity(gActiveBank)); gObjectBankIDs[gActiveBank] = CreateSprite( &gUnknown_02024E8C, @@ -726,7 +726,7 @@ void sub_8039430(u8 a, u8 b) gBattlePartyID[a] = gBattleBufferA[a][1]; species = GetMonData(&gEnemyParty[gBattlePartyID[a]], MON_DATA_SPECIES); gUnknown_0300434C[a] = CreateInvisibleSpriteWithCallback(sub_80312F0); - sub_8031794(&gEnemyParty[gBattlePartyID[a]], a); + BattleLoadOpponentMonSprite(&gEnemyParty[gBattlePartyID[a]], a); GetMonSpriteTemplate_803C56C(species, GetBankIdentity(a)); gObjectBankIDs[a] = CreateSprite( &gUnknown_02024E8C, @@ -765,7 +765,7 @@ void sub_8039648(void) switch (ewram17810[gActiveBank].unk4) { case 0: - if (ewram17800[gActiveBank].unk0_2) + if (ewram17800[gActiveBank].substituteSprite) move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 5); ewram17810[gActiveBank].unk4 = 1; break; @@ -834,7 +834,7 @@ void sub_803995C(void) { if (ewram17810[gActiveBank].unk4 == 0) { - if (ewram17800[gActiveBank].unk0_2) + if (ewram17800[gActiveBank].substituteSprite) move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 5); ewram17810[gActiveBank].unk4++; } @@ -909,7 +909,7 @@ void sub_8039B64(void) switch (ewram17810[gActiveBank].unk4) { case 0: - if (ewram17800[gActiveBank].unk0_2 && !ewram17800[gActiveBank].unk0_3) + if (ewram17800[gActiveBank].substituteSprite && !ewram17800[gActiveBank].unk0_3) { ewram17800[gActiveBank].unk0_3 = 1; move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 5); @@ -929,7 +929,7 @@ void sub_8039B64(void) if (!gAnimScriptActive) { sub_80326EC(1); - if ((ewram17800[gActiveBank].unk0_2) && r7 <= 1) + if ((ewram17800[gActiveBank].substituteSprite) && r7 <= 1) { move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 6); ewram17800[gActiveBank].unk0_3 = 0; diff --git a/src/battle/battle_2.c b/src/battle/battle_2.c index 7772444d7..bdd908ea5 100644 --- a/src/battle/battle_2.c +++ b/src/battle/battle_2.c @@ -1347,8 +1347,8 @@ void sub_8010384(struct Sprite *sprite) u16 species; u8 yOffset; - if (ewram17800[r6].unk2 != 0) - species = ewram17800[r6].unk2; + if (ewram17800[r6].transformedSpecies != 0) + species = ewram17800[r6].transformedSpecies; else species = sprite->data2; diff --git a/src/battle/battle_5.c b/src/battle/battle_5.c new file mode 100644 index 000000000..5972c0cb1 --- /dev/null +++ b/src/battle/battle_5.c @@ -0,0 +1,1579 @@ +#include "global.h" +#include "data2.h" +#include "battle.h" +#include "battle_interface.h" +#include "item.h" +#include "items.h" +#include "link.h" +#include "m4a.h" +#include "main.h" +#include "menu_cursor.h" +#include "moves.h" +#include "palette.h" +#include "pokemon.h" +#include "rom3.h" +#include "songs.h" +#include "sound.h" +#include "string_util.h" +#include "task.h" +#include "text.h" +#include "util.h" + +extern u8 gActiveBank; +extern void (*gBattleBankFunc[])(void); +extern bool8 gDoingBattleAnim; +extern u16 gBattleTypeFlags; +extern u32 gBattleExecBuffer; +extern u8 gBattleBufferA[][0x200]; +extern u8 gObjectBankIDs[]; +extern u8 gActionSelectionCursor[]; +extern u8 gMoveSelectionCursor[]; +extern u8 gAbsentBankFlags; +extern u8 gUnknown_03004344; +extern u8 gNoOfAllBanks; +extern u16 gBattlePartyID[]; +//extern const struct BattleMove gBattleMoves[]; +extern u16 gUnknown_030042A0; +extern u16 gUnknown_030042A4; +extern struct Window gUnknown_03004210; +extern const u8 gUnknown_08400D89[]; +extern u8 gUnknown_03004348; +extern struct BattlePokemon gBattleMons[]; +extern MainCallback gPreBattleCallback1; +extern u8 gHealthboxIDs[]; +extern struct MusicPlayerInfo gMPlay_BGM; +extern u8 gUnknown_0300434C[]; +extern u8 gUnknown_0202E8F4; +extern u8 gUnknown_0202E8F5; +extern u8 gUnknown_02038470[]; +extern u16 gScriptItemId; +extern u8 gDisplayedStringBattle[]; +extern const u8 gUnknown_08400CE0[]; + +extern void dp11b_obj_instanciate(u8, u8, s8, s8); +extern u8 GetBankIdentity(u8); +extern u8 GetBankByPlayerAI(u8); +extern void dp11b_obj_free(u8, u8); +extern void sub_8010520(struct Sprite *); +extern void sub_8010574(struct Sprite *); +extern bool8 IsDoubleBattle(); +extern void sub_804777C(); +extern void sub_8141828(); +extern void sub_8094E20(u8); +extern void nullsub_14(void); +extern void sub_80A6DCC(void); +extern void ReshowBattleScreenAfterMenu(void); + +void PlayerHandleGetAttributes(void); +void sub_802ECF0(void); +void PlayerHandleSetAttributes(void); +void sub_802F7CC(void); +void PlayerHandleLoadPokeSprite(void); +void PlayerHandleSendOutPoke(void); +void PlayerHandleReturnPokeToBall(void); +void PlayerHandleTrainerThrow(void); +void PlayerHandleTrainerSlide(void); +void PlayerHandleTrainerSlideBack(void); +void sub_802FE7C(void); +void sub_802FF60(void); +void sub_802FF80(void); +void PlayerHandleBallThrow(void); +void PlayerHandlePuase(void); +void PlayerHandleMoveAnimation(void); +void PlayerHandlePrintString(void); +void PlayerHandlePrintStringPlayerOnly(void); +void sub_803037C(void); +void nullsub_42(void); +void sub_8030468(void); +void PlayerHandleOpenBag(void); +void sub_8030594(void); +void sub_8030674(void); +void PlayerHandleHealthBarUpdate(void); +void PlayerHandleExpBarUpdate(void); +void PlayerHandleStatusIconUpdate(void); +void PlayerHandleStatusAnimation(void); +void PlayerHandleStatusXor(void); +void sub_803097C(void); +void PlayerHandleDMATransfer(void); +void sub_8030A3C(void); +void sub_8030A6C(void); +void sub_8030A78(void); +void sub_8030A8C(void); +void sub_8030AA0(void); +void sub_8030AB4(void); +void sub_8030AC8(void); +void sub_8030AE4(void); +void sub_8030B1C(void); +void sub_8030B34(void); +void PlayerHandleHitAnimation(void); +void sub_8030BCC(void); +void PlayerHandleEffectivenessSound(void); +void sub_8030C1C(void); +void PlayerHandleFaintingCry(void); +void PlayerHandleIntroSlide(void); +void PlayerHandleTrainerBallThrow(void); +void sub_8030FAC(void); +void sub_80310A4(void); +void sub_80310F0(void); +void PlayerHandleSpriteInvisibility(void); +void PlayerHandleBattleAnimation(void); +void PlayerHandleLinkStandbyMsg(void); +void PlayerHandleResetActionMoveSelection(void); +void sub_80312A0(void); +void nullsub_43(void); + +const u8 gString_TurnJP[] = _("ターン"); + +void (*const gPlayerBufferCommands[])(void) = +{ + PlayerHandleGetAttributes, + sub_802ECF0, + PlayerHandleSetAttributes, + sub_802F7CC, + PlayerHandleLoadPokeSprite, + PlayerHandleSendOutPoke, + PlayerHandleReturnPokeToBall, + PlayerHandleTrainerThrow, + PlayerHandleTrainerSlide, + PlayerHandleTrainerSlideBack, + sub_802FE7C, + sub_802FF60, + sub_802FF80, + PlayerHandleBallThrow, + PlayerHandlePuase, + PlayerHandleMoveAnimation, + PlayerHandlePrintString, + PlayerHandlePrintStringPlayerOnly, + sub_803037C, + nullsub_42, + sub_8030468, + PlayerHandleOpenBag, + sub_8030594, + sub_8030674, + PlayerHandleHealthBarUpdate, + PlayerHandleExpBarUpdate, + PlayerHandleStatusIconUpdate, + PlayerHandleStatusAnimation, + PlayerHandleStatusXor, + sub_803097C, + PlayerHandleDMATransfer, + sub_8030A3C, + sub_8030A6C, + sub_8030A78, + sub_8030A8C, + sub_8030AA0, + sub_8030AB4, + sub_8030AC8, + sub_8030AE4, + sub_8030B1C, + sub_8030B34, + PlayerHandleHitAnimation, + sub_8030BCC, + PlayerHandleEffectivenessSound, + sub_8030C1C, + PlayerHandleFaintingCry, + PlayerHandleIntroSlide, + PlayerHandleTrainerBallThrow, + sub_8030FAC, + sub_80310A4, + sub_80310F0, + PlayerHandleSpriteInvisibility, + PlayerHandleBattleAnimation, + PlayerHandleLinkStandbyMsg, + PlayerHandleResetActionMoveSelection, + sub_80312A0, + nullsub_43, +}; + +void PlayerBufferRunCommand(void); +void sub_802C2EC(void); +void sub_802C68C(void); +void sub_802CA60(void); +void sub_802D730(void); +void sub_802DA9C(u8); +void sub_802DB6C(u8); +void sub_802DCB0(u8); +void sub_802DD10(u8); +void sub_802DDC4(u8); +void sub_802DF88(void); +void sub_802E03C(void); +void sub_802E12C(s32, const u8 *); +void sub_802E1B0(void); +void sub_802E220(void); +void sub_802E2D4(void); +void sub_802E3B4(u8, int); +void nullsub_7(u8); +void b_link_standby_message(void); + +void nullsub_91(void) +{ +} + +void SetBankFuncToPlayerBufferRunCommand(void) +{ + gBattleBankFunc[gActiveBank] = PlayerBufferRunCommand; + gDoingBattleAnim = FALSE; +} + +void PlayerBufferExecCompleted(void) +{ + gBattleBankFunc[gActiveBank] = PlayerBufferRunCommand; + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + u8 playerId = GetMultiplayerId(); + + dp01_prepare_buffer_wireless_probably(2, 4, &playerId); + gBattleBufferA[gActiveBank][0] = 0x38; + } + else + { + gBattleExecBuffer &= ~gBitTable[gActiveBank]; + } +} + +void PlayerBufferRunCommand(void) +{ + if (gBattleExecBuffer & gBitTable[gActiveBank]) + { + if (gBattleBufferA[gActiveBank][0] < 0x39) + gPlayerBufferCommands[gBattleBufferA[gActiveBank][0]](); + else + PlayerBufferExecCompleted(); + } +} + +void bx_0802E404(void) +{ + if (gSprites[gObjectBankIDs[gActiveBank]].pos2.x == 0) + PlayerBufferExecCompleted(); +} + +void sub_802C098(void) +{ + u16 itemId = gBattleBufferA[gActiveBank][2] | (gBattleBufferA[gActiveBank][3] << 8); + + dp11b_obj_instanciate(gActiveBank, 1, 7, 1); + dp11b_obj_instanciate(gActiveBank, 0, 7, 1); + if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + DestroyMenuCursor(); + + // Useless switch statement. + switch (gActionSelectionCursor[gActiveBank]) + { + case 0: + dp01_build_cmdbuf_x21_a_bb(1, 0, 0); + break; + case 1: + dp01_build_cmdbuf_x21_a_bb(1, 1, 0); + break; + case 2: + dp01_build_cmdbuf_x21_a_bb(1, 2, 0); + break; + case 3: + dp01_build_cmdbuf_x21_a_bb(1, 3, 0); + break; + } + PlayerBufferExecCompleted(); + } + else if (gMain.newKeys & DPAD_LEFT) + { + if (gActionSelectionCursor[gActiveBank] & 1) + { + PlaySE(SE_SELECT); + nullsub_8(gActionSelectionCursor[gActiveBank]); + gActionSelectionCursor[gActiveBank] ^= 1; + sub_802E3E4(gActionSelectionCursor[gActiveBank], 0); + } + } + else if (gMain.newKeys & DPAD_RIGHT) + { + if (!(gActionSelectionCursor[gActiveBank] & 1)) + { + PlaySE(SE_SELECT); + nullsub_8(gActionSelectionCursor[gActiveBank]); + gActionSelectionCursor[gActiveBank] ^= 1; + sub_802E3E4(gActionSelectionCursor[gActiveBank], 0); + } + } + else if (gMain.newKeys & DPAD_UP) + { + if (gActionSelectionCursor[gActiveBank] & 2) + { + PlaySE(SE_SELECT); + nullsub_8(gActionSelectionCursor[gActiveBank]); + gActionSelectionCursor[gActiveBank] ^= 2; + sub_802E3E4(gActionSelectionCursor[gActiveBank], 0); + } + } + else if (gMain.newKeys & DPAD_DOWN) + { + if (!(gActionSelectionCursor[gActiveBank] & 2)) + { + PlaySE(SE_SELECT); + nullsub_8(gActionSelectionCursor[gActiveBank]); + gActionSelectionCursor[gActiveBank] ^= 2; + sub_802E3E4(gActionSelectionCursor[gActiveBank], 0); + } + } + else if (gMain.newKeys & B_BUTTON) + { + if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + && GetBankIdentity(gActiveBank) == 2 + && !(gAbsentBankFlags & gBitTable[GetBankByPlayerAI(0)]) + && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + { + if (gBattleBufferA[gActiveBank][1] == 1) + { + // Add item to bag if it is a ball + if (itemId <= ITEM_PREMIER_BALL) + AddBagItem(itemId, 1); + else + return; + } + PlaySE(SE_SELECT); + dp01_build_cmdbuf_x21_a_bb(1, 12, 0); + PlayerBufferExecCompleted(); + DestroyMenuCursor(); + } + } + else if (gMain.newKeys & START_BUTTON) + { + sub_804454C(); + } +} + +void unref_sub_802C2B8(void) +{ + dp11b_obj_free(gActiveBank, 1); + dp11b_obj_free(gActiveBank, 0); + gBattleBankFunc[gActiveBank] = sub_802C2EC; +} + +// TODO: fix this function +void sub_802C2EC(void) +{ + u8 arr[4] = {0, 2, 3, 1}; + s32 i; + + dp11b_obj_instanciate(gUnknown_03004344, 1, 15, 1); + i = 0; + if (gNoOfAllBanks != 0) + { + do + { + if (i != gUnknown_03004344) + dp11b_obj_free(i, 1); + i++; + } while (i < gNoOfAllBanks); + } + if (gMain.newKeys & A_BUTTON) + { + DestroyMenuCursor(); + PlaySE(SE_SELECT); + gSprites[gObjectBankIDs[gUnknown_03004344]].callback = sub_8010574; + dp01_build_cmdbuf_x21_a_bb(1, 10, gMoveSelectionCursor[gActiveBank] | (gUnknown_03004344 << 8)); + dp11b_obj_free(gUnknown_03004344, 1); + PlayerBufferExecCompleted(); + } + //_0802C3A8 + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + gSprites[gObjectBankIDs[gUnknown_03004344]].callback = sub_8010574; + gBattleBankFunc[gActiveBank] = sub_802C68C; + dp11b_obj_instanciate(gActiveBank, 1, 7, 1); + dp11b_obj_instanciate(gActiveBank, 0, 7, 1); + dp11b_obj_free(gUnknown_03004344, 1); + } + else if (gMain.newKeys & 0x60) + { + PlaySE(SE_SELECT); + gSprites[gObjectBankIDs[gUnknown_03004344]].callback = sub_8010574; + do + { + u8 var = GetBankIdentity(gUnknown_03004344); + + for (i = 0; i < 4; i++) + { + if (var == arr[i]) + break; + } + do + { + i--; + if (i < 0) + i = 3; + gUnknown_03004344 = GetBankByPlayerAI(arr[i]); + } while(gUnknown_03004344 == gNoOfAllBanks); + i = 0; + switch (GetBankIdentity(gUnknown_03004344)) + { + case 0: + case 2: + if (gActiveBank == gUnknown_03004344) + { + u32 moveId; + + asm("":::"memory"); + moveId = GetMonData(&gPlayerParty[gBattlePartyID[gActiveBank]], MON_DATA_MOVE1 + gMoveSelectionCursor[gActiveBank]); + if (!(gBattleMoves[moveId].target & 2)) + break; + } + i++; + break; + case 1: + case 3: + i++; + } + //_0802C500 + if (gAbsentBankFlags & gBitTable[gUnknown_03004344]) + i = 0; + } while (i == 0); + gSprites[gObjectBankIDs[gUnknown_03004344]].callback = sub_8010520; + } + //_0802C540 + else if (gMain.newKeys & 0x90) + { + PlaySE(SE_SELECT); + gSprites[gObjectBankIDs[gUnknown_03004344]].callback = sub_8010574; + do + { + u8 var = GetBankIdentity(gUnknown_03004344); + + for (i = 0; i < 4; i++) + { + if (var == arr[i]) + break; + } + do + { + i++; + if (i > 3) + i = 0; + gUnknown_03004344 = GetBankByPlayerAI(arr[i]); + } while (gUnknown_03004344 == gNoOfAllBanks); + i = 0; + switch (GetBankIdentity(gUnknown_03004344)) + { + case 0: + case 2: + if (gActiveBank == gUnknown_03004344) + { + u32 moveId; + + asm("":::"memory"); + moveId = GetMonData(&gPlayerParty[gBattlePartyID[gActiveBank]], MON_DATA_MOVE1 + gMoveSelectionCursor[gActiveBank]); + if (!(gBattleMoves[moveId].target & 2)) + break; + } + i++; + break; + case 1: + case 3: + i++; + } + if (gAbsentBankFlags & gBitTable[gUnknown_03004344]) + i = 0; + } while (i == 0); + gSprites[gObjectBankIDs[gUnknown_03004344]].callback = sub_8010520; + } +} + +struct UnknownStruct1 +{ + u16 moves[4]; + u8 pp[4]; + u8 unkC[0x12-0xC]; + u8 unk12; + u8 unk13; + u8 filler14[0x20-0x14]; +}; + +const u8 gUnknown_081FAE80[] = _("{PALETTE 5}{COLOR_HIGHLIGHT_SHADOW WHITE LIGHT_BLUE WHITE2}"); + +void sub_802C68C(void) +{ + u32 r8 = 0; + struct UnknownStruct1 *r6 = (struct UnknownStruct1 *)(gBattleBufferA[gActiveBank] + 4); + + if (gMain.newKeys & A_BUTTON) + { + u32 r4; + + PlaySE(SE_SELECT); + + if (r6->moves[gMoveSelectionCursor[gActiveBank]] == MOVE_CURSE) + r4 = (r6->unk12 != TYPE_GHOST && (r6->unk13 ^ 7)) ? 0x10 : 0; + else + r4 = gBattleMoves[r6->moves[gMoveSelectionCursor[gActiveBank]]].target; + + if (r4 & 0x10) + gUnknown_03004344 = gActiveBank; + else + gUnknown_03004344 = GetBankByPlayerAI((GetBankIdentity(gActiveBank) & 1) ^ 1); + + if (gBattleBufferA[gActiveBank][1] == 0) + { + if ((r4 & 2) && gBattleBufferA[gActiveBank][2] == 0) + r8++; + } + else + { + if (!(r4 & 0x7D)) + r8++; + if (r6->pp[gMoveSelectionCursor[gActiveBank]] == 0) + { + r8 = 0; + } + else if (!(r4 & 0x12) && CountAliveMons(0) <= 1) + { + gUnknown_03004344 = sub_803C434(gActiveBank); + r8 = 0; + } + } + if (r8 == 0) + { + DestroyMenuCursor(); + dp01_build_cmdbuf_x21_a_bb(1, 10, gMoveSelectionCursor[gActiveBank] | (gUnknown_03004344 << 8)); + PlayerBufferExecCompleted(); + } + else + { + gBattleBankFunc[gActiveBank] = sub_802C2EC; + if (r4 & 0x12) + gUnknown_03004344 = gActiveBank; + else if (gAbsentBankFlags & gBitTable[GetBankByPlayerAI(1)]) + gUnknown_03004344 = GetBankByPlayerAI(3); + else + gUnknown_03004344 = GetBankByPlayerAI(1); + gSprites[gObjectBankIDs[gUnknown_03004344]].callback = sub_8010520; + } + } + else if (gMain.newKeys & B_BUTTON) + { + DestroyMenuCursor(); + PlaySE(SE_SELECT); + gUnknown_030042A4 = 0; + gUnknown_030042A0 = 320; + dp01_build_cmdbuf_x21_a_bb(1, 10, 0xFFFF); + PlayerBufferExecCompleted(); + } + else if (gMain.newKeys & DPAD_LEFT) + { + if (gMoveSelectionCursor[gActiveBank] & 1) + { + nullsub_7(gMoveSelectionCursor[gActiveBank]); + gMoveSelectionCursor[gActiveBank] ^= 1; + PlaySE(SE_SELECT); + sub_802E3B4(gMoveSelectionCursor[gActiveBank], 0); + sub_802E220(); + sub_802E2D4(); + } + } + else if (gMain.newKeys & DPAD_RIGHT) + { + if (!(gMoveSelectionCursor[gActiveBank] & 1) + && (gMoveSelectionCursor[gActiveBank] ^ 1) < gUnknown_03004348) + { + nullsub_7(gMoveSelectionCursor[gActiveBank]); + gMoveSelectionCursor[gActiveBank] ^= 1; + PlaySE(SE_SELECT); + sub_802E3B4(gMoveSelectionCursor[gActiveBank], 0); + sub_802E220(); + sub_802E2D4(); + } + } + else if (gMain.newKeys & DPAD_UP) + { + if (gMoveSelectionCursor[gActiveBank] & 2) + { + nullsub_7(gMoveSelectionCursor[gActiveBank]); + gMoveSelectionCursor[gActiveBank] ^= 2; + PlaySE(SE_SELECT); + sub_802E3B4(gMoveSelectionCursor[gActiveBank], 0); + sub_802E220(); + sub_802E2D4(); + } + } + else if (gMain.newKeys & DPAD_DOWN) + { + if (!(gMoveSelectionCursor[gActiveBank] & 2) + && (gMoveSelectionCursor[gActiveBank] ^ 2) < gUnknown_03004348) + { + nullsub_7(gMoveSelectionCursor[gActiveBank]); + gMoveSelectionCursor[gActiveBank] ^= 2; + PlaySE(SE_SELECT); + sub_802E3B4(gMoveSelectionCursor[gActiveBank], 0); + sub_802E220(); + sub_802E2D4(); + } + } + else if (gMain.newKeys & SELECT_BUTTON) + { + if (gUnknown_03004348 > 1 && !(gBattleTypeFlags & BATTLE_TYPE_LINK)) + { + sub_802E12C(gMoveSelectionCursor[gActiveBank], gUnknown_081FAE80); + if (gMoveSelectionCursor[gActiveBank] != 0) + gUnknown_03004344 = 0; + else + gUnknown_03004344 = gMoveSelectionCursor[gActiveBank] + 1; + sub_802E3B4(gUnknown_03004344, 27); + FillWindowRect(&gUnknown_03004210, 0x1016, 0x17, 0x37, 0x1C, 0x3A); + InitWindow(&gUnknown_03004210, gUnknown_08400D89, 0x290, 0x17, 0x37); + sub_8002F44(&gUnknown_03004210); + gBattleBankFunc[gActiveBank] = sub_802CA60; + } + } +} + +extern const u8 gUnknown_08400D49[]; +extern const u8 gUnknown_08400D38[]; + +void sub_802CA60(void) +{ + u8 perMovePPBonuses[4]; + struct + { + u16 moves[4]; + u8 pp[4]; + u8 filler18[8]; // what is this? + } sp0; + //struct UnknownStruct1 sp0; + u8 totalPPBonuses; + + if (gMain.newKeys & (A_BUTTON | SELECT_BUTTON)) + { + PlaySE(SE_SELECT); + if (gMoveSelectionCursor[gActiveBank] != gUnknown_03004344) + { + struct UnknownStruct1 *r9 = (struct UnknownStruct1 *)&gBattleBufferA[gActiveBank][4]; + s32 i; + + i = r9->moves[gMoveSelectionCursor[gActiveBank]]; + r9->moves[gMoveSelectionCursor[gActiveBank]] = r9->moves[gUnknown_03004344]; + r9->moves[gUnknown_03004344] = i; + + i = r9->pp[gMoveSelectionCursor[gActiveBank]]; + r9->pp[gMoveSelectionCursor[gActiveBank]] = r9->pp[gUnknown_03004344]; + r9->pp[gUnknown_03004344] = i; + + i = r9->unkC[gMoveSelectionCursor[gActiveBank]]; + r9->unkC[gMoveSelectionCursor[gActiveBank]] = r9->unkC[gUnknown_03004344]; + r9->unkC[gUnknown_03004344] = i; + + if (gDisableStructs[gActiveBank].unk18_b & gBitTable[gMoveSelectionCursor[gActiveBank]]) + { + gDisableStructs[gActiveBank].unk18_b &= ~gBitTable[gMoveSelectionCursor[gActiveBank]]; + gDisableStructs[gActiveBank].unk18_b |= gBitTable[gUnknown_03004344]; + } + + sub_802E1B0(); + + for (i = 0; i < 4; i++) + perMovePPBonuses[i] = (gBattleMons[gActiveBank].ppBonuses & (3 << (i * 2))) >> (i * 2); + totalPPBonuses = perMovePPBonuses[gMoveSelectionCursor[gActiveBank]]; + perMovePPBonuses[gMoveSelectionCursor[gActiveBank]] = perMovePPBonuses[gUnknown_03004344]; + perMovePPBonuses[gUnknown_03004344] = totalPPBonuses; + + totalPPBonuses = 0; + for (i = 0; i < 4; i++) + totalPPBonuses |= perMovePPBonuses[i] << (i * 2); + gBattleMons[gActiveBank].ppBonuses = totalPPBonuses; + + for (i = 0; i < 4; i++) + { + gBattleMons[gActiveBank].moves[i] = r9->moves[i]; + gBattleMons[gActiveBank].pp[i] = r9->pp[i]; + } + if (!(gBattleMons[gActiveBank].status2 & 0x200000)) + { + for (i = 0; i < 4; i++) + { + sp0.moves[i] = GetMonData(&gPlayerParty[gBattlePartyID[gActiveBank]], MON_DATA_MOVE1 + i); + sp0.pp[i] = GetMonData(&gPlayerParty[gBattlePartyID[gActiveBank]], MON_DATA_PP1 + i); + } + + totalPPBonuses = GetMonData(&gPlayerParty[gBattlePartyID[gActiveBank]], MON_DATA_PP_BONUSES); + for (i = 0; i < 4; i++) + perMovePPBonuses[i] = (totalPPBonuses & (3 << (i * 2))) >> (i * 2); + + i = sp0.moves[gMoveSelectionCursor[gActiveBank]]; + sp0.moves[gMoveSelectionCursor[gActiveBank]] = sp0.moves[gUnknown_03004344]; + sp0.moves[gUnknown_03004344] = i; + + i = sp0.pp[gMoveSelectionCursor[gActiveBank]]; + sp0.pp[gMoveSelectionCursor[gActiveBank]] = sp0.pp[gUnknown_03004344]; + sp0.pp[gUnknown_03004344] = i; + + totalPPBonuses = perMovePPBonuses[gMoveSelectionCursor[gActiveBank]]; + perMovePPBonuses[gMoveSelectionCursor[gActiveBank]] = perMovePPBonuses[gUnknown_03004344]; + perMovePPBonuses[gUnknown_03004344] = totalPPBonuses; + + totalPPBonuses = 0; + for (i = 0; i < 4; i++) + totalPPBonuses |= perMovePPBonuses[i] << (i * 2); + + for (i = 0; i < 4; i++) + { + SetMonData(&gPlayerParty[gBattlePartyID[gActiveBank]], MON_DATA_MOVE1 + i, (u8 *)&sp0.moves[i]); + SetMonData(&gPlayerParty[gBattlePartyID[gActiveBank]], MON_DATA_PP1 + i, &sp0.pp[i]); + } + SetMonData(&gPlayerParty[gBattlePartyID[gActiveBank]], MON_DATA_PP_BONUSES, &totalPPBonuses); + } + } + else + { + sub_802E12C(gUnknown_03004344, gUnknown_08400D49); + } + gBattleBankFunc[gActiveBank] = sub_802C68C; + gMoveSelectionCursor[gActiveBank] = gUnknown_03004344; + sub_802E3B4(gMoveSelectionCursor[gActiveBank], 0); + FillWindowRect(&gUnknown_03004210, 0x1016, 0x17, 0x37, 0x1C, 0x3A); + InitWindow(&gUnknown_03004210, gUnknown_08400D38, 0x290, 0x17, 0x37); + sub_8002F44(&gUnknown_03004210); + sub_802E220(); + sub_802E2D4(); + } + if (gMain.newKeys & (B_BUTTON | SELECT_BUTTON)) + { + PlaySE(SE_SELECT); + nullsub_7(gUnknown_03004344); + sub_802E3B4(gMoveSelectionCursor[gActiveBank], 0); + sub_802E12C(gMoveSelectionCursor[gActiveBank], gUnknown_08400D49); + gBattleBankFunc[gActiveBank] = sub_802C68C; + FillWindowRect(&gUnknown_03004210, 0x1016, 0x17, 0x37, 0x1C, 0x3A); + InitWindow(&gUnknown_03004210, gUnknown_08400D38, 0x290, 0x17, 0x37); + sub_8002F44(&gUnknown_03004210); + sub_802E220(); + sub_802E2D4(); + } + if ((gMain.newKeys & DPAD_LEFT) && (gUnknown_03004344 & 1)) + { + if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBank]) + sub_802E3B4(gMoveSelectionCursor[gActiveBank], 0x1D); + else + nullsub_7(gUnknown_03004344); + gUnknown_03004344 ^= 1; + PlaySE(SE_SELECT); + if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBank]) + sub_802E3B4(gUnknown_03004344, 0); + else + sub_802E3B4(gUnknown_03004344, 0x1B); + } + if ((gMain.newKeys & DPAD_RIGHT) && !(gUnknown_03004344 & 1) && (gUnknown_03004344 ^ 1) < gUnknown_03004348) + { + if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBank]) + sub_802E3B4(gMoveSelectionCursor[gActiveBank], 0x1D); + else + nullsub_7(gUnknown_03004344); + gUnknown_03004344 ^= 1; + PlaySE(SE_SELECT); + if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBank]) + sub_802E3B4(gUnknown_03004344, 0); + else + sub_802E3B4(gUnknown_03004344, 0x1B); + } + if ((gMain.newKeys & DPAD_UP) && (gUnknown_03004344 & 2)) + { + if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBank]) + sub_802E3B4(gMoveSelectionCursor[gActiveBank], 0x1D); + else + nullsub_7(gUnknown_03004344); + gUnknown_03004344 ^= 2; + PlaySE(SE_SELECT); + if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBank]) + sub_802E3B4(gUnknown_03004344, 0); + else + sub_802E3B4(gUnknown_03004344, 0x1B); + } + if ((gMain.newKeys & DPAD_DOWN) && !(gUnknown_03004344 & 2) && (gUnknown_03004344 ^ 2) < gUnknown_03004348) + { + if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBank]) + sub_802E3B4(gMoveSelectionCursor[gActiveBank], 0x1D); + else + nullsub_7(gUnknown_03004344); + gUnknown_03004344 ^= 2; + PlaySE(SE_SELECT); + if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBank]) + sub_802E3B4(gUnknown_03004344, 0); + else + sub_802E3B4(gUnknown_03004344, 0x1B); + } +} + +void sub_802D148(void) +{ + if (gReceivedRemoteLinkPlayers == 0) + { + m4aSongNumStop(SE_HINSI); + gMain.inBattle = FALSE; + gMain.callback1 = gPreBattleCallback1; + SetMainCallback2(c2_8011A1C); + } +} + +void sub_802D18C(void) +{ + if (!gPaletteFade.active) + { + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + sub_800832C(); + gBattleBankFunc[gActiveBank] = sub_802D148; + } + else + { + m4aSongNumStop(SE_HINSI); + gMain.inBattle = FALSE; + gMain.callback1 = gPreBattleCallback1; + SetMainCallback2(gMain.savedCallback); + } + } +} + +void sub_802D204(void) +{ + if (gSprites[gObjectBankIDs[gActiveBank]].callback == SpriteCallbackDummy) + PlayerBufferExecCompleted(); +} + +// duplicate of sub_802D204 +void sub_802D23C(void) +{ + if (gSprites[gObjectBankIDs[gActiveBank]].callback == SpriteCallbackDummy) + PlayerBufferExecCompleted(); +} + +void sub_802D274(void) +{ + if (gSprites[gObjectBankIDs[gActiveBank]].callback == SpriteCallbackDummy) + { + nullsub_10(gSaveBlock2.playerGender); + FreeSpriteOamMatrix(&gSprites[gObjectBankIDs[gActiveBank]]); + DestroySprite(&gSprites[gObjectBankIDs[gActiveBank]]); + PlayerBufferExecCompleted(); + } +} + +void sub_802D2E0(void) +{ + if (--ewram17810[gActiveBank].unk9 == 0xFF) + { + ewram17810[gActiveBank].unk9 = 0; + PlayerBufferExecCompleted(); + } +} + +void sub_802D31C(void) +{ + bool8 r6 = FALSE; + + if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI))) + { + if (gSprites[gHealthboxIDs[gActiveBank]].callback == SpriteCallbackDummy) + r6 = TRUE; + } + else + { + if (gSprites[gHealthboxIDs[gActiveBank]].callback == SpriteCallbackDummy + && gSprites[gHealthboxIDs[gActiveBank ^ 2]].callback == SpriteCallbackDummy) + r6 = TRUE; + } + if (IsCryPlayingOrClearCrySongs()) + r6 = FALSE; + + if (r6 && ewram17810[gActiveBank].unk1_0 && ewram17810[gActiveBank ^ 2].unk1_0) + { + ewram17810[gActiveBank].unk0_7 = 0; + ewram17810[gActiveBank].unk1_0 = 0; + ewram17810[gActiveBank ^ 2].unk0_7 = 0; + ewram17810[gActiveBank ^ 2].unk1_0 = 0; + FreeSpriteTilesByTag(0x27F9); + FreeSpritePaletteByTag(0x27F9); + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + m4aMPlayContinue(&gMPlay_BGM); + else + m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 256); + sub_80324F8(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank); + if (IsDoubleBattle()) + sub_80324F8(&gPlayerParty[gBattlePartyID[gActiveBank ^ 2]], gActiveBank ^ 2); + ewram17810[gActiveBank].unk9 = 3; + gBattleBankFunc[gActiveBank] = sub_802D2E0; + } +} + +void sub_802D500(void) +{ + if (!ewram17810[gActiveBank].unk0_3 && !ewram17810[gActiveBank].unk0_7) + sub_8141828(gActiveBank, &gPlayerParty[gBattlePartyID[gActiveBank]]); + if (!ewram17810[gActiveBank ^ 2].unk0_3 && !ewram17810[gActiveBank ^ 2].unk0_7) + sub_8141828(gActiveBank ^ 2, &gPlayerParty[gBattlePartyID[gActiveBank ^ 2]]); + if (!ewram17810[gActiveBank].unk0_3 && !ewram17810[gActiveBank ^ 2].unk0_3) + { + if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + { + DestroySprite(&gSprites[gUnknown_0300434C[gActiveBank ^ 2]]); + sub_8045A5C( + gHealthboxIDs[gActiveBank ^ 2], + &gPlayerParty[gBattlePartyID[gActiveBank ^ 2]], + 0); + sub_804777C(gActiveBank ^ 2); + sub_8043DFC(gHealthboxIDs[gActiveBank ^ 2]); + } + DestroySprite(&gSprites[gUnknown_0300434C[gActiveBank]]); + sub_8045A5C( + gHealthboxIDs[gActiveBank], + &gPlayerParty[gBattlePartyID[gActiveBank]], + 0); + sub_804777C(gActiveBank); + sub_8043DFC(gHealthboxIDs[gActiveBank]); + ewram17840.unk9_0 = 0; + gBattleBankFunc[gActiveBank] = sub_802D31C; + } +} + +void sub_802D680(void) +{ + if (gSprites[gHealthboxIDs[gActiveBank]].callback == SpriteCallbackDummy + && ewram17810[gActiveBank].unk1_0) + { + ewram17810[gActiveBank].unk0_7 = 0; + ewram17810[gActiveBank].unk1_0 = 0; + FreeSpriteTilesByTag(0x27F9); + FreeSpritePaletteByTag(0x27F9); + if (ewram17800[gActiveBank].substituteSprite) + move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 6); + gBattleBankFunc[gActiveBank] = sub_802D730; + } +} + +void sub_802D730(void) +{ + if (!ewram17810[gActiveBank].unk0_6 && !IsCryPlayingOrClearCrySongs()) + { + m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100); + sub_80324F8(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank); + PlayerBufferExecCompleted(); + } +} + +void sub_802D798(void) +{ + if (!ewram17810[gActiveBank].unk0_3 && !ewram17810[gActiveBank].unk0_7) + sub_8141828(gActiveBank, &gPlayerParty[gBattlePartyID[gActiveBank]]); + if (gSprites[gUnknown_0300434C[gActiveBank]].callback == SpriteCallbackDummy + && !ewram17810[gActiveBank].unk0_3) + { + DestroySprite(&gSprites[gUnknown_0300434C[gActiveBank]]); + sub_8045A5C(gHealthboxIDs[gActiveBank], &gPlayerParty[gBattlePartyID[gActiveBank]], 0); + sub_804777C(gActiveBank); + sub_8043DFC(gHealthboxIDs[gActiveBank]); + sub_8031F88(gActiveBank); + gBattleBankFunc[gActiveBank] = sub_802D680; + } +} + +void c3_0802FDF4(u8 taskId) +{ + if (!IsCryPlayingOrClearCrySongs()) + { + m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100); + DestroyTask(taskId); + } +} + +void bx_t1_healthbar_update(void) +{ + s16 r4 = sub_8045C78(gActiveBank, gHealthboxIDs[gActiveBank], 0, 0); + + sub_8043DFC(gHealthboxIDs[gActiveBank]); + if (r4 != -1) + { + sub_80440EC(gHealthboxIDs[gActiveBank], r4, 0); + } + else + { + sub_80324F8(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank); + PlayerBufferExecCompleted(); + } +} + +void sub_802D90C(void) +{ + if (gUnknown_03004210.state == 0) + PlayerBufferExecCompleted(); +} + +// Rare Candy usage, maybe? +void sub_802D924(u8 taskId) +{ + u32 pkmnIndex = (u8)gTasks[taskId].data[0]; + u8 bank = gTasks[taskId].data[2]; + s16 gainedExp = gTasks[taskId].data[1]; + + if (IsDoubleBattle() == TRUE || pkmnIndex != gBattlePartyID[bank]) + { + struct Pokemon *pkmn = &gPlayerParty[pkmnIndex]; + u16 species = GetMonData(pkmn, MON_DATA_SPECIES); + u8 level = GetMonData(pkmn, MON_DATA_LEVEL); + u32 currExp = GetMonData(pkmn, MON_DATA_EXP); + u32 nextLvlExp = gExperienceTables[gBaseStats[species].growthRate][level + 1]; + + if (currExp + gainedExp >= nextLvlExp) + { + u8 savedActiveBank; + + SetMonData(pkmn, MON_DATA_EXP, (u8 *)&nextLvlExp); + CalculateMonStats(pkmn); + gainedExp -= nextLvlExp - currExp; + savedActiveBank = gActiveBank; + gActiveBank = bank; + dp01_build_cmdbuf_x21_a_bb(1, 11, gainedExp); + gActiveBank = savedActiveBank; + + if (IsDoubleBattle() == TRUE + && ((u16)pkmnIndex == gBattlePartyID[bank] || (u16)pkmnIndex == gBattlePartyID[bank ^ 2])) + gTasks[taskId].func = sub_802DCB0; + else + gTasks[taskId].func = sub_802DDC4; + } + else + { + currExp += gainedExp; + SetMonData(pkmn, MON_DATA_EXP, (u8 *)&currExp); + gBattleBankFunc[bank] = sub_802D90C; + DestroyTask(taskId); + } + } + else + { + gTasks[taskId].func = sub_802DA9C; + } +} + +void sub_802DA9C(u8 taskId) +{ + u8 pkmnIndex = gTasks[taskId].data[0]; + s32 r9 = gTasks[taskId].data[1]; + u8 bank = gTasks[taskId].data[2]; + struct Pokemon *pkmn = &gPlayerParty[pkmnIndex]; + u8 level = GetMonData(pkmn, MON_DATA_LEVEL); + u16 species = GetMonData(pkmn, MON_DATA_SPECIES); + u32 exp = GetMonData(pkmn, MON_DATA_EXP); + u32 currLvlExp = gExperienceTables[gBaseStats[species].growthRate][level]; + u32 expToNextLvl; + + exp -= currLvlExp; + expToNextLvl = gExperienceTables[gBaseStats[species].growthRate][level + 1] - currLvlExp; + sub_8043D84(bank, gHealthboxIDs[bank], expToNextLvl, exp, -r9); + PlaySE(SE_EXP); + gTasks[taskId].func = sub_802DB6C; +} + +#ifdef NONMATCHING +void sub_802DB6C(u8 taskId) +{ + if (gTasks[taskId].data[10] < 13) + { + gTasks[taskId].data[10]++; + } + else + { + u8 r9 = gTasks[taskId].data[0]; + s32 r10 = gTasks[taskId].data[1]; //s16? + u8 r7 = gTasks[taskId].data[2]; + s16 r4; + + r4 = sub_8045C78(r7, gHealthboxIDs[r7], 1, 0); + sub_8043DFC(gHealthboxIDs[r7]); + if (r4 == -1) + { + struct Pokemon *pkmn; + u8 r4; + u32 sp4; + u16 r0; + u32 sp0; + + m4aSongNumStop(SE_EXP); + pkmn = &gPlayerParty[r9]; + r4 = GetMonData(pkmn, MON_DATA_LEVEL); + sp4 = GetMonData(pkmn, MON_DATA_EXP); + r0 = GetMonData(pkmn, MON_DATA_SPECIES); + sp0 = gExperienceTables[gBaseStats[r0].growthRate][r4 + 1]; + if (sp4 + r10 >= sp0) + { + u8 r5; + u32 asdf; + + SetMonData(pkmn, MON_DATA_EXP, (u8 *)&sp0); + CalculateMonStats(pkmn); + //r10 -= sp0 - sp4; + asdf = sp0 - sp4; + //asdf = r10 - (sp0 - sp4); + r10 -= asdf; + r5 = gActiveBank; + gActiveBank = r7; + dp01_build_cmdbuf_x21_a_bb(1, 11, r10); + gActiveBank = r5; + gTasks[taskId].func = sub_802DCB0; + } + else + { + //u32 asdf = sp4 + r10; + sp4 += r10; + SetMonData(pkmn, MON_DATA_EXP, (u8 *)&sp4); + gBattleBankFunc[r7] = sub_802D90C; + DestroyTask(taskId); + } + } + } +} +#else +__attribute__((naked)) +void sub_802DB6C(u8 taskId) +{ + asm_unified("push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0x8\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + mov r8, r0\n\ + ldr r1, _0802DB98 @ =gTasks\n\ + lsls r0, 2\n\ + add r0, r8\n\ + lsls r0, 3\n\ + adds r6, r0, r1\n\ + ldrh r1, [r6, 0x1C]\n\ + movs r2, 0x1C\n\ + ldrsh r0, [r6, r2]\n\ + cmp r0, 0xC\n\ + bgt _0802DB9C\n\ + adds r0, r1, 0x1\n\ + strh r0, [r6, 0x1C]\n\ + b _0802DC98\n\ + .align 2, 0\n\ +_0802DB98: .4byte gTasks\n\ +_0802DB9C:\n\ + ldrb r0, [r6, 0x8]\n\ + mov r9, r0\n\ + ldrh r2, [r6, 0xA]\n\ + mov r10, r2\n\ + ldrb r7, [r6, 0xC]\n\ + ldr r5, _0802DC64 @ =gHealthboxIDs\n\ + adds r5, r7, r5\n\ + ldrb r1, [r5]\n\ + adds r0, r7, 0\n\ + movs r2, 0x1\n\ + movs r3, 0\n\ + bl sub_8045C78\n\ + adds r4, r0, 0\n\ + lsls r4, 16\n\ + lsrs r4, 16\n\ + ldrb r0, [r5]\n\ + bl sub_8043DFC\n\ + lsls r4, 16\n\ + asrs r4, 16\n\ + movs r0, 0x1\n\ + negs r0, r0\n\ + cmp r4, r0\n\ + bne _0802DC98\n\ + movs r0, 0x21\n\ + bl m4aSongNumStop\n\ + movs r0, 0x64\n\ + mov r1, r9\n\ + muls r1, r0\n\ + ldr r0, _0802DC68 @ =gPlayerParty\n\ + adds r5, r1, r0\n\ + adds r0, r5, 0\n\ + movs r1, 0x38\n\ + bl GetMonData\n\ + adds r4, r0, 0\n\ + lsls r4, 24\n\ + lsrs r4, 24\n\ + adds r0, r5, 0\n\ + movs r1, 0x19\n\ + bl GetMonData\n\ + str r0, [sp, 0x4]\n\ + adds r0, r5, 0\n\ + movs r1, 0xB\n\ + bl GetMonData\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + ldr r3, _0802DC6C @ =gExperienceTables\n\ + adds r4, 0x1\n\ + lsls r4, 2\n\ + ldr r2, _0802DC70 @ =gBaseStats\n\ + lsls r1, r0, 3\n\ + subs r1, r0\n\ + lsls r1, 2\n\ + adds r1, r2\n\ + ldrb r1, [r1, 0x13]\n\ + movs r0, 0xCA\n\ + lsls r0, 1\n\ + muls r0, r1\n\ + adds r4, r0\n\ + adds r4, r3\n\ + ldr r1, [r4]\n\ + str r1, [sp]\n\ + mov r2, r10\n\ + lsls r0, r2, 16\n\ + asrs r4, r0, 16\n\ + ldr r0, [sp, 0x4]\n\ + adds r0, r4\n\ + cmp r0, r1\n\ + blt _0802DC7C\n\ + adds r0, r5, 0\n\ + movs r1, 0x19\n\ + mov r2, sp\n\ + bl SetMonData\n\ + adds r0, r5, 0\n\ + bl CalculateMonStats\n\ + ldr r2, [sp]\n\ + add r0, sp, 0x4\n\ + ldrh r0, [r0]\n\ + subs r2, r0\n\ + subs r2, r4, r2\n\ + ldr r4, _0802DC74 @ =gActiveBank\n\ + ldrb r5, [r4]\n\ + strb r7, [r4]\n\ + lsls r2, 16\n\ + lsrs r2, 16\n\ + movs r0, 0x1\n\ + movs r1, 0xB\n\ + bl dp01_build_cmdbuf_x21_a_bb\n\ + strb r5, [r4]\n\ + ldr r0, _0802DC78 @ =sub_802DCB0\n\ + str r0, [r6]\n\ + b _0802DC98\n\ + .align 2, 0\n\ +_0802DC64: .4byte gHealthboxIDs\n\ +_0802DC68: .4byte gPlayerParty\n\ +_0802DC6C: .4byte gExperienceTables\n\ +_0802DC70: .4byte gBaseStats\n\ +_0802DC74: .4byte gActiveBank\n\ +_0802DC78: .4byte sub_802DCB0\n\ +_0802DC7C:\n\ + str r0, [sp, 0x4]\n\ + add r2, sp, 0x4\n\ + adds r0, r5, 0\n\ + movs r1, 0x19\n\ + bl SetMonData\n\ + ldr r1, _0802DCA8 @ =gBattleBankFunc\n\ + lsls r0, r7, 2\n\ + adds r0, r1\n\ + ldr r1, _0802DCAC @ =sub_802D90C\n\ + str r1, [r0]\n\ + mov r0, r8\n\ + bl DestroyTask\n\ +_0802DC98:\n\ + add sp, 0x8\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_0802DCA8: .4byte gBattleBankFunc\n\ +_0802DCAC: .4byte sub_802D90C\n"); +} +#endif + +void sub_802DCB0(u8 taskId) +{ + u8 bank = gTasks[taskId].data[2]; + u8 pkmnIndex = gTasks[taskId].data[0]; + + if (IsDoubleBattle() == TRUE && pkmnIndex == gBattlePartyID[bank ^ 2]) + bank ^= 2; + move_anim_start_t4(bank, bank, bank, 0); + gTasks[taskId].func = sub_802DD10; +} + +void sub_802DD10(u8 taskId) +{ + u8 bank = gTasks[taskId].data[2]; + + if (!ewram17810[bank].unk0_6) + { + u8 pkmnIndex = gTasks[taskId].data[0]; + + GetMonData(&gPlayerParty[pkmnIndex], MON_DATA_LEVEL); // Unused return value + if (IsDoubleBattle() == TRUE && pkmnIndex == gBattlePartyID[bank ^ 2]) + sub_8045A5C(gHealthboxIDs[bank ^ 2], &gPlayerParty[pkmnIndex], 0); + else + sub_8045A5C(gHealthboxIDs[bank], &gPlayerParty[pkmnIndex], 0); + gTasks[taskId].func = sub_802DDC4; + } +} + +void sub_802DDC4(u8 taskId) +{ + u8 pkmnIndex; + u8 bank; + + pkmnIndex = gTasks[taskId].data[0]; + GetMonData(&gPlayerParty[pkmnIndex], MON_DATA_LEVEL); // Unused return value + bank = gTasks[taskId].data[2]; + gBattleBankFunc[bank] = sub_802D90C; + DestroyTask(taskId); +} + +void sub_802DE10(void) +{ + if (gSprites[gObjectBankIDs[gActiveBank]].pos1.y + gSprites[gObjectBankIDs[gActiveBank]].pos2.y > DISPLAY_HEIGHT) + { + u16 species = GetMonData(&gPlayerParty[gBattlePartyID[gActiveBank]], MON_DATA_SPECIES); + + nullsub_9(species); + FreeOamMatrix(gSprites[gObjectBankIDs[gActiveBank]].oam.matrixNum); + DestroySprite(&gSprites[gObjectBankIDs[gActiveBank]]); + sub_8043DB0(gHealthboxIDs[gActiveBank]); + PlayerBufferExecCompleted(); + } +} + +void sub_802DEAC(void) +{ + if (!ewram17810[gActiveBank].unk0_6) + { + FreeSpriteOamMatrix(&gSprites[gObjectBankIDs[gActiveBank]]); + DestroySprite(&gSprites[gObjectBankIDs[gActiveBank]]); + sub_8043DB0(gHealthboxIDs[gActiveBank]); + PlayerBufferExecCompleted(); + } +} + +// Duplicate of sub_802D90C +void sub_802DF18(void) +{ + if (gUnknown_03004210.state == 0) + PlayerBufferExecCompleted(); +} + +void sub_802DF30(void) +{ + if (!gPaletteFade.active) + { + u8 r4; + + gBattleBankFunc[gActiveBank] = sub_802DF88; + r4 = gTasks[gUnknown_0300434C[gActiveBank]].data[0]; + DestroyTask(gUnknown_0300434C[gActiveBank]); + sub_8094E20(r4); + } +} + +void sub_802DF88(void) +{ + if (gMain.callback2 == sub_800F808 && !gPaletteFade.active) + { + if (gUnknown_0202E8F4 == 1) + dp01_build_cmdbuf_x22_a_three_bytes(1, gUnknown_0202E8F5, gUnknown_02038470); + else + dp01_build_cmdbuf_x22_a_three_bytes(1, 6, NULL); + if ((gBattleBufferA[gActiveBank][1] & 0xF) == 1) + b_link_standby_message(); + PlayerBufferExecCompleted(); + } +} + +void sub_802E004(void) +{ + if (!gPaletteFade.active) + { + gBattleBankFunc[gActiveBank] = sub_802E03C; + nullsub_14(); + sub_80A6DCC(); + } +} + +void sub_802E03C(void) +{ + if (gMain.callback2 == sub_800F808 && !gPaletteFade.active) + { + dp01_build_cmdbuf_x23_aa_0(1, gScriptItemId); + PlayerBufferExecCompleted(); + } +} + +void bx_wait_t1(void) +{ + if (!gDoingBattleAnim || !ewram17810[gActiveBank].unk0_6) + PlayerBufferExecCompleted(); +} + +void bx_blink_t1(void) +{ + u8 spriteId = gObjectBankIDs[gActiveBank]; + + if (gSprites[spriteId].data1 == 32) + { + gSprites[spriteId].data1 = 0; + gSprites[spriteId].invisible = FALSE; + gDoingBattleAnim = 0; + PlayerBufferExecCompleted(); + } + else + { + if (((u16)gSprites[spriteId].data1 % 4) == 0) + gSprites[spriteId].invisible ^= 1; + gSprites[spriteId].data1++; + } +} + +void sub_802E12C(s32 a, const u8 *b) +{ + struct UnknownStruct1 *r4 = (struct UnknownStruct1 *)&gBattleBufferA[gActiveBank][4]; + + StringCopy(gDisplayedStringBattle, b); + StringAppend(gDisplayedStringBattle, gMoveNames[r4->moves[a]]); + InitWindow( + &gUnknown_03004210, + gDisplayedStringBattle, + 0x300 + a * 20, + (a & 1) ? 11 : 1, + (a < 2) ? 0x37 : 0x39); + sub_8002F44(&gUnknown_03004210); +} + +void sub_802E1B0(void) +{ + struct UnknownStruct1 *r4 = (struct UnknownStruct1 *)&gBattleBufferA[gActiveBank][4]; + s32 i; + + gUnknown_03004348 = 0; + FillWindowRect(&gUnknown_03004210, 0x1016, 1, 0x37, 0x14, 0x3A); + for (i = 0; i < 4; i++) + { + nullsub_7(i); + sub_802E12C(i, gUnknown_08400D49); + if (r4->moves[i] != 0) + gUnknown_03004348++; + } +} + +void sub_802E220(void) +{ + if (gBattleBufferA[gActiveBank][2] != 1) + { + struct UnknownStruct1 *r4 = (struct UnknownStruct1 *)&gBattleBufferA[gActiveBank][4]; + u8 *str = gDisplayedStringBattle; + + str = StringCopy(str, gUnknown_08400D49); + str[0] = EXT_CTRL_CODE_BEGIN; + str[1] = 0x11; + str[2] = 2; + str += 3; + str[0] = EXT_CTRL_CODE_BEGIN; + str[1] = 0x14; + str[2] = 6; + str += 3; + str = ConvertIntToDecimalStringN(str, r4->pp[gMoveSelectionCursor[gActiveBank]], 1, 2); + *str++ = CHAR_SLASH; + ConvertIntToDecimalStringN(str, r4->unkC[gMoveSelectionCursor[gActiveBank]], 1, 2); + InitWindow(&gUnknown_03004210, gDisplayedStringBattle, 0x2A2, 0x19, 0x37); + sub_8002F44(&gUnknown_03004210); + } +} + +extern const u8 gUnknown_08400D52[]; +extern const u8 gTypeNames[][7]; + +void sub_802E2D4(void) +{ + if (gBattleBufferA[gActiveBank][2] == 1) + { + FillWindowRect(&gUnknown_03004210, 0x1016, 0x17, 0x37, 0x1C, 0x3A); + InitWindow(&gUnknown_03004210, gUnknown_08400D52, 0x290, 0x13, 0x37); + } + else + { + struct UnknownStruct1 *r4 = (struct UnknownStruct1 *)&gBattleBufferA[gActiveBank][4]; + u8 *str = gDisplayedStringBattle; + + str = StringCopy(str, gUnknown_08400D49); + StringCopy(str, gTypeNames[gBattleMoves[r4->moves[gMoveSelectionCursor[gActiveBank]]].type]); + FillWindowRect(&gUnknown_03004210, 0x1016, 0x17, 0x39, 0x1C, 0x3A); + InitWindow(&gUnknown_03004210, gDisplayedStringBattle, 0x2C0, 0x17, 0x39); + } + sub_8002F44(&gUnknown_03004210); +} + +const u8 gUnknown_081FAE89[][2] = +{ + { 8, 120}, + {88, 120}, + { 8, 136}, + {88, 136}, +}; + +const u8 gUnknown_081FAE91[][2] = +{ + {144, 120}, + {190, 120}, + {144, 136}, + {190, 136}, + { 72, 72}, + { 32, 90}, + { 80, 80}, + { 80, 88}, +}; + +void sub_802E3B4(u8 a, int unused) +{ + sub_814A958(0x48); + sub_814A880(gUnknown_081FAE89[a][0], gUnknown_081FAE89[a][1]); +} + +void nullsub_7(u8 a) +{ +} + +void sub_802E3E4(u8 a, int unused) +{ + sub_814A958(0x2A); + sub_814A880(gUnknown_081FAE91[a][0], gUnknown_081FAE91[a][1]); +} + +void nullsub_8(u8 a) +{ +} + +void sub_802E414(void) +{ + SetMainCallback2(ReshowBattleScreenAfterMenu); +} + +void sub_802E424(void) +{ + SetMainCallback2(ReshowBattleScreenAfterMenu); +} + +void sub_802E434(void) +{ + if (!ewram17810[gActiveBank].unk0_4) + PlayerBufferExecCompleted(); +} + +void sub_802E460(void) +{ + if (!ewram17810[gActiveBank].unk0_5) + PlayerBufferExecCompleted(); +} + +void b_link_standby_message(void) +{ + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + gUnknown_030042A4 = 0; + gUnknown_030042A0 = 0; + sub_8002EB0(&gUnknown_03004210, gUnknown_08400CE0, 0x90, 2, 15); + } +} diff --git a/src/battle/battle_6.c b/src/battle/battle_6.c index c833aef5e..e7f152a4b 100644 --- a/src/battle/battle_6.c +++ b/src/battle/battle_6.c @@ -98,7 +98,7 @@ extern void sub_80E43C0(); extern void oamt_add_pos2_onto_pos1(); extern void sub_8078B34(struct Sprite *); extern void oamt_set_x3A_32(); -extern void sub_80318FC(); +extern void BattleLoadPlayerMonSprite(); extern bool8 IsDoubleBattle(void); extern void sub_802D500(void); extern void dp11b_obj_free(); @@ -121,7 +121,7 @@ extern void sub_80105EC(struct Sprite *); extern void sub_802D274(void); extern void sub_802D23C(void); extern u8 GetBankIdentity(u8); -extern void sub_8031AF4(); +extern void LoadPlayerTrainerBankSprite(); extern void sub_80313A0(struct Sprite *); extern void sub_802D204(void); extern u8 sub_8079E90(); @@ -739,7 +739,7 @@ void sub_802F7CC(void) void PlayerHandleLoadPokeSprite(void) { - sub_80318FC(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank); + BattleLoadPlayerMonSprite(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank); gSprites[gObjectBankIDs[gActiveBank]].oam.paletteNum = gActiveBank; gBattleBankFunc[gActiveBank] = bx_0802E404; } @@ -748,7 +748,7 @@ void PlayerHandleSendOutPoke(void) { sub_8032AA8(gActiveBank, gBattleBufferA[gActiveBank][2]); gBattlePartyID[gActiveBank] = gBattleBufferA[gActiveBank][1]; - sub_80318FC(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank); + BattleLoadPlayerMonSprite(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank); gActionSelectionCursor[gActiveBank] = 0; gMoveSelectionCursor[gActiveBank] = 0; sub_802F934(gActiveBank, gBattleBufferA[gActiveBank][2]); @@ -800,7 +800,7 @@ void sub_802FB2C(void) switch (ewram17810[gActiveBank].unk4) { case 0: - if (ewram17800[gActiveBank].unk0_2) + if (ewram17800[gActiveBank].substituteSprite) move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 5); ewram17810[gActiveBank].unk4 = 1; break; @@ -829,7 +829,7 @@ void PlayerHandleTrainerThrow(void) { r7 = 0; } - sub_8031AF4(gSaveBlock2.playerGender, gActiveBank); + LoadPlayerTrainerBankSprite(gSaveBlock2.playerGender, gActiveBank); GetMonSpriteTemplate_803C5A0(gSaveBlock2.playerGender, GetBankIdentity(gActiveBank)); gObjectBankIDs[gActiveBank] = CreateSprite( &gUnknown_02024E8C, @@ -845,7 +845,7 @@ void PlayerHandleTrainerThrow(void) void PlayerHandleTrainerSlide(void) { - sub_8031AF4(gSaveBlock2.playerGender, gActiveBank); + LoadPlayerTrainerBankSprite(gSaveBlock2.playerGender, gActiveBank); GetMonSpriteTemplate_803C5A0(gSaveBlock2.playerGender, GetBankIdentity(gActiveBank)); gObjectBankIDs[gActiveBank] = CreateSprite( &gUnknown_02024E8C, @@ -875,7 +875,7 @@ void sub_802FE7C(void) { if (ewram17810[gActiveBank].unk4 == 0) { - if (ewram17800[gActiveBank].unk0_2) + if (ewram17800[gActiveBank].substituteSprite) move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 5); ewram17810[gActiveBank].unk4++; } @@ -963,7 +963,7 @@ void sub_8030190(void) switch (ewram17810[gActiveBank].unk4) { case 0: - if (ewram17800[gActiveBank].unk0_2 == 1 && ewram17800[gActiveBank].unk0_3 == 0) + if (ewram17800[gActiveBank].substituteSprite == 1 && ewram17800[gActiveBank].unk0_3 == 0) { ewram17800[gActiveBank].unk0_3 = 1; move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 5); @@ -983,7 +983,7 @@ void sub_8030190(void) if (!gAnimScriptActive) { sub_80326EC(1); - if (ewram17800[gActiveBank].unk0_2 == 1 && r7 < 2) + if (ewram17800[gActiveBank].substituteSprite == 1 && r7 < 2) { move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 6); ewram17800[gActiveBank].unk0_3 = 0; @@ -1357,7 +1357,7 @@ void sub_8030E38(struct Sprite *sprite) FreeSpriteOamMatrix(sprite); FreeSpritePaletteByTag(GetSpritePaletteTagByPaletteNum(sprite->oam.paletteNum)); DestroySprite(sprite); - sub_80318FC(&gPlayerParty[gBattlePartyID[r4]], r4); + BattleLoadPlayerMonSprite(&gPlayerParty[gBattlePartyID[r4]], r4); StartSpriteAnim(&gSprites[gObjectBankIDs[r4]], 0); } @@ -1383,7 +1383,7 @@ void task05_08033660(u8 taskId) sub_802F934(gActiveBank, 0); gActiveBank ^= 2; gBattleBufferA[gActiveBank][1] = gBattlePartyID[gActiveBank]; - sub_80318FC(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank); + BattleLoadPlayerMonSprite(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank); sub_802F934(gActiveBank, 0); gActiveBank ^= 2; } diff --git a/src/battle/battle_7.c b/src/battle/battle_7.c index f2838467e..0c4b118b4 100644 --- a/src/battle/battle_7.c +++ b/src/battle/battle_7.c @@ -182,9 +182,9 @@ bool8 move_anim_start_t3(u8 a, u8 b, u8 c, u8 d, u16 e) gBattleMonForms[a] = e & 0x7F; return TRUE; } - if (ewram17800[a].unk0_2 && sub_803163C(d) == 0) + if (ewram17800[a].substituteSprite && sub_803163C(d) == 0) return TRUE; - if (ewram17800[a].unk0_2 && d == 2 && gSprites[gObjectBankIDs[a]].invisible) + if (ewram17800[a].substituteSprite && d == 2 && gSprites[gObjectBankIDs[a]].invisible) { refresh_graphics_maybe(a, 1, gObjectBankIDs[a]); sub_80324E0(a); @@ -273,29 +273,29 @@ bool8 mplay_80342A4(u8 a) return TRUE; } -void sub_8031794(struct Pokemon *pkmn, u8 b) +void BattleLoadOpponentMonSprite(struct Pokemon *pkmn, u8 bank) { u32 personalityValue; u16 species; - u32 r7; + u32 transformPersonality; u32 otId; u8 var; u16 paletteOffset; const u8 *lzPaletteData; personalityValue = GetMonData(pkmn, MON_DATA_PERSONALITY); - if (ewram17800[b].unk2 == 0) + if (ewram17800[bank].transformedSpecies == 0) { species = GetMonData(pkmn, MON_DATA_SPECIES); - r7 = personalityValue; + transformPersonality = personalityValue; } else { - species = ewram17800[b].unk2; - r7 = gPID_perBank[b]; + species = ewram17800[bank].transformedSpecies; + transformPersonality = gPID_perBank[bank]; } otId = GetMonData(pkmn, MON_DATA_OT_ID); - var = GetBankIdentity(b); + var = GetBankIdentity(bank); HandleLoadSpecialPokePic( &gMonFrontPicTable[species], gMonFrontPicCoords[species].coords, @@ -303,29 +303,29 @@ void sub_8031794(struct Pokemon *pkmn, u8 b) 0x02000000, gUnknown_081FAF4C[var], species, - r7); - paletteOffset = 0x100 + b * 16; - if (ewram17800[b].unk2 == 0) + transformPersonality); + paletteOffset = 0x100 + bank * 16; + if (ewram17800[bank].transformedSpecies == 0) lzPaletteData = pokemon_get_pal(pkmn); else lzPaletteData = species_and_otid_get_pal(species, otId, personalityValue); sub_800D238(lzPaletteData, ewram); LoadPalette(ewram, paletteOffset, 0x20); - LoadPalette(ewram, 0x80 + b * 16, 0x20); + LoadPalette(ewram, 0x80 + bank * 16, 0x20); if (species == SPECIES_CASTFORM) { - paletteOffset = 0x100 + b * 16; + paletteOffset = 0x100 + bank * 16; sub_800D238(lzPaletteData, ewram + 0x16400); - LoadPalette(ewram + 0x16400 + gBattleMonForms[b] * 32, paletteOffset, 0x20); + LoadPalette(ewram + 0x16400 + gBattleMonForms[bank] * 32, paletteOffset, 0x20); } - if (ewram17800[b].unk2 != 0) + if (ewram17800[bank].transformedSpecies != 0) { BlendPalette(paletteOffset, 16, 6, 0x7FFF); CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, 32); } } -void sub_80318FC(struct Pokemon *pkmn, u8 b) +void BattleLoadPlayerMonSprite(struct Pokemon *pkmn, u8 bank) { u32 personalityValue; u16 species; @@ -336,18 +336,18 @@ void sub_80318FC(struct Pokemon *pkmn, u8 b) const u8 *lzPaletteData; personalityValue = GetMonData(pkmn, MON_DATA_PERSONALITY); - if (ewram17800[b].unk2 == 0) + if (ewram17800[bank].transformedSpecies == 0) { species = GetMonData(pkmn, MON_DATA_SPECIES); r7 = personalityValue; } else { - species = ewram17800[b].unk2; - r7 = gPID_perBank[b]; + species = ewram17800[bank].transformedSpecies; + r7 = gPID_perBank[bank]; } otId = GetMonData(pkmn, MON_DATA_OT_ID); - var = GetBankIdentity(b); + var = GetBankIdentity(bank); HandleLoadSpecialPokePic( &gMonBackPicTable[species], gMonBackPicCoords[species].coords, @@ -356,21 +356,21 @@ void sub_80318FC(struct Pokemon *pkmn, u8 b) gUnknown_081FAF4C[var], species, r7); - paletteOffset = 0x100 + b * 16; - if (ewram17800[b].unk2 == 0) + paletteOffset = 0x100 + bank * 16; + if (ewram17800[bank].transformedSpecies == 0) lzPaletteData = pokemon_get_pal(pkmn); else lzPaletteData = species_and_otid_get_pal(species, otId, personalityValue); sub_800D238(lzPaletteData, ewram); LoadPalette(ewram, paletteOffset, 0x20); - LoadPalette(ewram, 0x80 + b * 16, 0x20); + LoadPalette(ewram, 0x80 + bank * 16, 0x20); if (species == SPECIES_CASTFORM) { - paletteOffset = 0x100 + b * 16; + paletteOffset = 0x100 + bank * 16; sub_800D238(lzPaletteData, ewram + 0x16400); - LoadPalette(ewram + 0x16400 + gBattleMonForms[b] * 32, paletteOffset, 0x20); + LoadPalette(ewram + 0x16400 + gBattleMonForms[bank] * 32, paletteOffset, 0x20); } - if (ewram17800[b].unk2 != 0) + if (ewram17800[bank].transformedSpecies != 0) { BlendPalette(paletteOffset, 16, 6, 0x7FFF); CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, 32); @@ -405,11 +405,11 @@ void sub_8031A6C(u16 a, u8 b) LoadCompressedObjectPalette(&gTrainerFrontPicPaletteTable[a]); } -void sub_8031AF4(u16 a, u8 b) +void LoadPlayerTrainerBankSprite(u16 a, u8 bank) { u8 status; - status = GetBankIdentity(b); + status = GetBankIdentity(bank); DecompressPicFromTable_2( &gTrainerBackPicTable[a], gTrainerBackPicCoords[a].coords, @@ -417,7 +417,7 @@ void sub_8031AF4(u16 a, u8 b) (void *)0x02000000, gUnknown_081FAF4C[status], 0); - LoadCompressedPalette(gTrainerBackPicPaletteTable[a].data, 0x100 + b * 16, 32); + LoadCompressedPalette(gTrainerBackPicPaletteTable[a].data, 0x100 + bank * 16, 32); } void nullsub_10(int unused) @@ -607,15 +607,15 @@ void sub_8031F24(void) s32 i; for (i = 0; i < gNoOfAllBanks; i++) - ewram17800[i].unk0_0 = gSprites[gObjectBankIDs[i]].invisible; + ewram17800[i].invisible = gSprites[gObjectBankIDs[i]].invisible; } void sub_8031F88(u8 a) { - ewram17800[a].unk0_0 = gSprites[gObjectBankIDs[a]].invisible; + ewram17800[a].invisible = gSprites[gObjectBankIDs[a]].invisible; } -void sub_8031FC4(u8 a, u8 b, bool8 c) +void sub_8031FC4(u8 bank1, u8 bank2, bool8 c) { u16 paletteOffset; u16 species; @@ -626,16 +626,16 @@ void sub_8031FC4(u8 a, u8 b, bool8 c) if (c) { - StartSpriteAnim(&gSprites[gObjectBankIDs[a]], ewram17840.unk0); - paletteOffset = 0x100 + a * 16; + StartSpriteAnim(&gSprites[gObjectBankIDs[bank1]], ewram17840.unk0); + paletteOffset = 0x100 + bank1 * 16; LoadPalette(ewram + 0x16400 + ewram17840.unk0 * 32, paletteOffset, 32); - gBattleMonForms[a] = ewram17840.unk0; - if (ewram17800[a].unk2 != 0) + gBattleMonForms[bank1] = ewram17840.unk0; + if (ewram17800[bank1].transformedSpecies != 0) { BlendPalette(paletteOffset, 16, 6, 0x7FFF); CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, 32); } - gSprites[gObjectBankIDs[a]].pos1.y = sub_8077F68(a); + gSprites[gObjectBankIDs[bank1]].pos1.y = sub_8077F68(bank1); } else { @@ -659,15 +659,15 @@ void sub_8031FC4(u8 a, u8 b, bool8 c) } else { - r10 = GetBankIdentity(a); - if (GetBankSide(b) == 1) - species = GetMonData(&gEnemyParty[gBattlePartyID[b]], MON_DATA_SPECIES); + r10 = GetBankIdentity(bank1); + if (GetBankSide(bank2) == 1) + species = GetMonData(&gEnemyParty[gBattlePartyID[bank2]], MON_DATA_SPECIES); else - species = GetMonData(&gPlayerParty[gBattlePartyID[b]], MON_DATA_SPECIES); - if (GetBankSide(a) == 0) + species = GetMonData(&gPlayerParty[gBattlePartyID[bank2]], MON_DATA_SPECIES); + if (GetBankSide(bank1) == 0) { - personalityValue = GetMonData(&gPlayerParty[gBattlePartyID[a]], MON_DATA_PERSONALITY); - otId = GetMonData(&gPlayerParty[gBattlePartyID[a]], MON_DATA_OT_ID); + personalityValue = GetMonData(&gPlayerParty[gBattlePartyID[bank1]], MON_DATA_PERSONALITY); + otId = GetMonData(&gPlayerParty[gBattlePartyID[bank1]], MON_DATA_OT_ID); HandleLoadSpecialPokePic( &gMonBackPicTable[species], gMonBackPicCoords[species].coords, @@ -675,12 +675,12 @@ void sub_8031FC4(u8 a, u8 b, bool8 c) 0x02000000, gUnknown_081FAF4C[r10], species, - gPID_perBank[a]); + gPID_perBank[bank1]); } else { - personalityValue = GetMonData(&gEnemyParty[gBattlePartyID[a]], MON_DATA_PERSONALITY); - otId = GetMonData(&gEnemyParty[gBattlePartyID[a]], MON_DATA_OT_ID); + personalityValue = GetMonData(&gEnemyParty[gBattlePartyID[bank1]], MON_DATA_PERSONALITY); + otId = GetMonData(&gEnemyParty[gBattlePartyID[bank1]], MON_DATA_OT_ID); HandleLoadSpecialPokePic( &gMonFrontPicTable[species], gMonFrontPicCoords[species].coords, @@ -688,13 +688,13 @@ void sub_8031FC4(u8 a, u8 b, bool8 c) 0x02000000, gUnknown_081FAF4C[r10], species, - gPID_perBank[a]); + gPID_perBank[bank1]); } } src = gUnknown_081FAF4C[r10]; - dst = (void *)(VRAM + 0x10000 + gSprites[gObjectBankIDs[a]].oam.tileNum * 32); + dst = (void *)(VRAM + 0x10000 + gSprites[gObjectBankIDs[bank1]].oam.tileNum * 32); DmaCopy32(3, src, dst, 0x800); - paletteOffset = 0x100 + a * 16; + paletteOffset = 0x100 + bank1 * 16; lzPaletteData = species_and_otid_get_pal(species, otId, personalityValue); sub_800D238(lzPaletteData, ewram); LoadPalette(ewram, paletteOffset, 32); @@ -703,21 +703,21 @@ void sub_8031FC4(u8 a, u8 b, bool8 c) u16 *paletteSrc = (u16 *)(ewram + 0x16400); sub_800D238(lzPaletteData, paletteSrc); - LoadPalette(paletteSrc + gBattleMonForms[b] * 16, paletteOffset, 32); + LoadPalette(paletteSrc + gBattleMonForms[bank2] * 16, paletteOffset, 32); } BlendPalette(paletteOffset, 16, 6, 0x7FFF); CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, 32); if (!IsContest()) { - ewram17800[a].unk2 = species; - gBattleMonForms[a] = gBattleMonForms[b]; + ewram17800[bank1].transformedSpecies = species; + gBattleMonForms[bank1] = gBattleMonForms[bank2]; } - gSprites[gObjectBankIDs[a]].pos1.y = sub_8077F68(a); - StartSpriteAnim(&gSprites[gObjectBankIDs[a]], gBattleMonForms[a]); + gSprites[gObjectBankIDs[bank1]].pos1.y = sub_8077F68(bank1); + StartSpriteAnim(&gSprites[gObjectBankIDs[bank1]], gBattleMonForms[bank1]); } } -void sub_8032350(u8 a, u8 b) +void BattleLoadSubstituteSprite(u8 a, u8 b) { u8 r4; u16 foo; @@ -750,16 +750,16 @@ void sub_8032350(u8 a, u8 b) if (!IsContest()) { if (GetBankSide(a) != 0) - sub_8031794(&gEnemyParty[gBattlePartyID[a]], a); + BattleLoadOpponentMonSprite(&gEnemyParty[gBattlePartyID[a]], a); else - sub_80318FC(&gPlayerParty[gBattlePartyID[a]], a); + BattleLoadPlayerMonSprite(&gPlayerParty[gBattlePartyID[a]], a); } } } void refresh_graphics_maybe(u8 a, u8 b, u8 spriteId) { - sub_8032350(a, b); + BattleLoadSubstituteSprite(a, b); StartSpriteAnim(&gSprites[spriteId], gBattleMonForms[a]); if (b == 0) gSprites[spriteId].pos1.y = sub_8077F7C(a); @@ -770,12 +770,12 @@ void refresh_graphics_maybe(u8 a, u8 b, u8 spriteId) void sub_80324BC(u8 a, u16 b) { if (b == 0xA4) - ewram17800[a].unk0_2 = 1; + ewram17800[a].substituteSprite = 1; } void sub_80324E0(u8 a) { - ewram17800[a].unk0_2 = 0; + ewram17800[a].substituteSprite = 0; } void sub_80324F8(struct Pokemon *pkmn, u8 b) @@ -896,9 +896,9 @@ void sub_80328A4(struct Sprite *sprite) } if (gAnimScriptActive || r7->invisible) invisible = TRUE; - else if (ewram17800[r4].unk2 != 0 && gEnemyMonElevation[ewram17800[r4].unk2] == 0) + else if (ewram17800[r4].transformedSpecies != 0 && gEnemyMonElevation[ewram17800[r4].transformedSpecies] == 0) invisible = TRUE; - if (ewram17800[r4].unk0_2) + if (ewram17800[r4].substituteSprite) invisible = TRUE; sprite->pos1.x = r7->pos1.x; sprite->pos2.x = r7->pos2.x; @@ -914,8 +914,8 @@ void sub_8032984(u8 a, u16 b) { if (GetBankSide(a) != 0) { - if (ewram17800[a].unk2 != 0) - b = ewram17800[a].unk2; + if (ewram17800[a].transformedSpecies != 0) + b = ewram17800[a].transformedSpecies; if (gEnemyMonElevation[b] != 0) gSprites[ewram17810[a].unk7].callback = sub_80328A4; else @@ -953,7 +953,7 @@ void sub_8032A38(void) void sub_8032AA8(u8 a, u8 b) { - ewram17800[a].unk2 = 0; + ewram17800[a].transformedSpecies = 0; gBattleMonForms[a] = 0; if (b == 0) sub_80324E0(a); @@ -1168,7 +1168,7 @@ void sub_8033264(void) { if (gSprites[gHealthboxIDs[gActiveBank]].callback == SpriteCallbackDummy) { - if (ewram17800[gActiveBank].unk0_2) + if (ewram17800[gActiveBank].substituteSprite) move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 6); gBattleBankFunc[gActiveBank] = sub_80332D0; } diff --git a/src/battle/battle_8.c b/src/battle/battle_8.c index 75f10c4b1..44e42d0d6 100644 --- a/src/battle/battle_8.c +++ b/src/battle/battle_8.c @@ -58,7 +58,7 @@ extern u8 sub_8077ABC(); extern u8 sub_8077F68(); extern u8 sub_8079E90(); extern void sub_8033018(void); -extern void sub_8031794(); +extern void BattleLoadOpponentMonSprite(); extern u8 GetBankIdentity(u8); extern void sub_8032984(u8, u16); extern void sub_80333D4(void); @@ -714,7 +714,7 @@ void OpponentHandleLoadPokeSprite(void) { u16 species = GetMonData(&gEnemyParty[gBattlePartyID[gActiveBank]], MON_DATA_SPECIES); - sub_8031794(&gEnemyParty[gBattlePartyID[gActiveBank]], gActiveBank); + BattleLoadOpponentMonSprite(&gEnemyParty[gBattlePartyID[gActiveBank]], gActiveBank); GetMonSpriteTemplate_803C56C(species, GetBankIdentity(gActiveBank)); gObjectBankIDs[gActiveBank] = CreateSprite( &gUnknown_02024E8C, @@ -746,7 +746,7 @@ void sub_803495C(u8 a, u8 b) gBattlePartyID[a] = gBattleBufferA[a][1]; species = GetMonData(&gEnemyParty[gBattlePartyID[a]], MON_DATA_SPECIES); gUnknown_0300434C[a] = CreateInvisibleSpriteWithCallback(sub_80312F0); - sub_8031794(&gEnemyParty[gBattlePartyID[a]], a); + BattleLoadOpponentMonSprite(&gEnemyParty[gBattlePartyID[a]], a); GetMonSpriteTemplate_803C56C(species, GetBankIdentity(a)); gObjectBankIDs[a] = CreateSprite( &gUnknown_02024E8C, @@ -785,7 +785,7 @@ void sub_8034B74(void) switch (ewram17810[gActiveBank].unk4) { case 0: - if (ewram17800[gActiveBank].unk0_2) + if (ewram17800[gActiveBank].substituteSprite) move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 5); ewram17810[gActiveBank].unk4 = 1; break; @@ -876,7 +876,7 @@ void sub_8035030(void) { if (ewram17810[gActiveBank].unk4 == 0) { - if (ewram17800[gActiveBank].unk0_2) + if (ewram17800[gActiveBank].substituteSprite) move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 5); ewram17810[gActiveBank].unk4++; } @@ -951,7 +951,7 @@ void sub_8035238(void) switch (ewram17810[gActiveBank].unk4) { case 0: - if (ewram17800[gActiveBank].unk0_2 && !ewram17800[gActiveBank].unk0_3) + if (ewram17800[gActiveBank].substituteSprite && !ewram17800[gActiveBank].unk0_3) { ewram17800[gActiveBank].unk0_3 = 1; move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 5); @@ -971,7 +971,7 @@ void sub_8035238(void) if (!gAnimScriptActive) { sub_80326EC(1); - if ((ewram17800[gActiveBank].unk0_2) && r7 <= 1) + if ((ewram17800[gActiveBank].substituteSprite) && r7 <= 1) { move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 6); ewram17800[gActiveBank].unk0_3 = 0; diff --git a/src/battle/battle_811DA74.c b/src/battle/battle_811DA74.c index 36a287efc..14f547b82 100644 --- a/src/battle/battle_811DA74.c +++ b/src/battle/battle_811DA74.c @@ -87,12 +87,12 @@ extern void oamt_set_x3A_32(); extern void sub_8078B34(struct Sprite *); extern void sub_80105EC(struct Sprite *); extern s32 sub_803FC34(u16); -extern void sub_8031AF4(); +extern void LoadPlayerTrainerBankSprite(); extern void sub_80313A0(struct Sprite *); extern u8 sub_8046400(); extern void sub_80312F0(struct Sprite *); extern u8 CreateInvisibleSpriteWithCallback(); -extern void sub_80318FC(); +extern void BattleLoadPlayerMonSprite(); extern u8 sub_8077ABC(); extern u8 sub_8077F68(); extern u8 sub_8079E90(); @@ -298,7 +298,7 @@ void sub_811E034(void) { if (gSprites[gHealthboxIDs[gActiveBank]].callback == SpriteCallbackDummy) { - if (ewram17800[gActiveBank].unk0_2) + if (ewram17800[gActiveBank].substituteSprite) move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 6); gBattleBankFunc[gActiveBank] = sub_811E0A0; } @@ -989,7 +989,7 @@ void sub_811F664(void) void sub_811F6D8(void) { - sub_80318FC(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank); + BattleLoadPlayerMonSprite(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank); GetMonSpriteTemplate_803C56C( GetMonData(&gPlayerParty[gBattlePartyID[gActiveBank]], MON_DATA_SPECIES), GetBankIdentity(gActiveBank)); @@ -1009,7 +1009,7 @@ void sub_811F7F4(void) { sub_8032AA8(gActiveBank, gBattleBufferA[gActiveBank][2]); gBattlePartyID[gActiveBank] = gBattleBufferA[gActiveBank][1]; - sub_80318FC(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank); + BattleLoadPlayerMonSprite(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank); sub_811F864(gActiveBank, gBattleBufferA[gActiveBank][2]); gBattleBankFunc[gActiveBank] = sub_811E1BC; } @@ -1059,7 +1059,7 @@ void sub_811FA5C(void) switch (ewram17810[gActiveBank].unk4) { case 0: - if (ewram17800[gActiveBank].unk0_2) + if (ewram17800[gActiveBank].substituteSprite) move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 5); ewram17810[gActiveBank].unk4 = 1; break; @@ -1092,7 +1092,7 @@ void sub_811FAE4(void) xOffset = 0; gender = gLinkPlayers[GetMultiplayerId() ^ 1].gender; } - sub_8031AF4(gender, gActiveBank); + LoadPlayerTrainerBankSprite(gender, gActiveBank); GetMonSpriteTemplate_803C5A0(gender, GetBankIdentity(gActiveBank)); gObjectBankIDs[gActiveBank] = CreateSprite( &gUnknown_02024E8C, @@ -1125,7 +1125,7 @@ void sub_811FCE8(void) { if (ewram17810[gActiveBank].unk4 == 0) { - if (ewram17800[gActiveBank].unk0_2) + if (ewram17800[gActiveBank].substituteSprite) move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 5); ewram17810[gActiveBank].unk4++; } @@ -1200,7 +1200,7 @@ void sub_811FF30(void) switch (ewram17810[gActiveBank].unk4) { case 0: - if (ewram17800[gActiveBank].unk0_2 && !ewram17800[gActiveBank].unk0_3) + if (ewram17800[gActiveBank].substituteSprite && !ewram17800[gActiveBank].unk0_3) { ewram17800[gActiveBank].unk0_3 = 1; move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 5); @@ -1220,7 +1220,7 @@ void sub_811FF30(void) if (!gAnimScriptActive) { sub_80326EC(1); - if ((ewram17800[gActiveBank].unk0_2) && r7 <= 1) + if ((ewram17800[gActiveBank].substituteSprite) && r7 <= 1) { move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 6); ewram17800[gActiveBank].unk0_3 = 0; @@ -1508,7 +1508,7 @@ void sub_812071C(u8 taskId) sub_811F864(gActiveBank, 0); gActiveBank ^= 2; gBattleBufferA[gActiveBank][1] = gBattlePartyID[gActiveBank]; - sub_80318FC(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank); + BattleLoadPlayerMonSprite(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank); sub_811F864(gActiveBank, 0); gActiveBank ^= 2; } diff --git a/src/battle/battle_anim_8137220.c b/src/battle/battle_anim_8137220.c index bb181d5fb..af2b86c17 100644 --- a/src/battle/battle_anim_8137220.c +++ b/src/battle/battle_anim_8137220.c @@ -73,7 +73,7 @@ extern void sub_8043DFC(); extern bool8 IsDoubleBattle(void); extern void c3_0802FDF4(u8); extern void sub_802ECF0(void); -extern void sub_8031AF4(); +extern void LoadPlayerTrainerBankSprite(); extern u8 GetBankIdentity(u8); extern void sub_80313A0(struct Sprite *); extern u8 GetBankByPlayerAI(u8); @@ -981,7 +981,7 @@ void sub_8138CB4(void) void sub_8138D38(void) { - sub_8031AF4(2, gActiveBank); + LoadPlayerTrainerBankSprite(2, gActiveBank); GetMonSpriteTemplate_803C5A0(2, GetBankIdentity(gActiveBank)); gObjectBankIDs[gActiveBank] = CreateSprite( &gUnknown_02024E8C, @@ -996,7 +996,7 @@ void sub_8138D38(void) void sub_8138E04(void) { - sub_8031AF4(2, gActiveBank); + LoadPlayerTrainerBankSprite(2, gActiveBank); GetMonSpriteTemplate_803C5A0(2, GetBankIdentity(gActiveBank)); gObjectBankIDs[gActiveBank] = CreateSprite( &gUnknown_02024E8C, @@ -1081,7 +1081,7 @@ void sub_81390D0(void) switch (ewram17810[gActiveBank].unk4) { case 0: - if (ewram17800[gActiveBank].unk0_2 == 1) + if (ewram17800[gActiveBank].substituteSprite == 1) move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 5); ewram17810[gActiveBank].unk4 = 1; break; @@ -1098,7 +1098,7 @@ void sub_81390D0(void) if (!gAnimScriptActive) { sub_80326EC(1); - if (ewram17800[gActiveBank].unk0_2 == 1) + if (ewram17800[gActiveBank].substituteSprite == 1) move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 6); ewram17810[gActiveBank].unk4 = 3; } @@ -1382,7 +1382,7 @@ void sub_81398BC(u8 bank) { u16 species; - ewram17800[bank].unk2 = 0; + ewram17800[bank].transformedSpecies = 0; gBattlePartyID[bank] = gBattleBufferA[bank][1]; species = GetMonData(&gPlayerParty[gBattlePartyID[bank]], MON_DATA_SPECIES); gUnknown_0300434C[bank] = CreateInvisibleSpriteWithCallback(sub_80312F0); diff --git a/src/battle/battle_setup.c b/src/battle/battle_setup.c index 04674e739..31c127416 100644 --- a/src/battle/battle_setup.c +++ b/src/battle/battle_setup.c @@ -438,7 +438,7 @@ void task01_battle_start(u8 taskId) } break; case 1: - if (sub_811AAE8() == TRUE) + if (IsBattleTransitionDone() == TRUE) { SetMainCallback2(sub_800E7C4); prev_quest_postbuffer_cursor_backup_reset(); @@ -827,7 +827,7 @@ void CB2_StartFirstBattle(void) UpdatePaletteFade(); RunTasks(); - if (sub_811AAE8() == TRUE) + if (IsBattleTransitionDone() == TRUE) { gBattleTypeFlags = BATTLE_TYPE_FIRST_BATTLE; gMain.savedCallback = HandleFirstBattleEnd; diff --git a/src/battle/battle_transition.c b/src/battle/battle_transition.c new file mode 100644 index 000000000..395a38df1 --- /dev/null +++ b/src/battle/battle_transition.c @@ -0,0 +1,2513 @@ +#include "global.h" +#include "battle_transition.h" +#include "main.h" +#include "rom4.h" +#include "task.h" +#include "palette.h" +#include "trig.h" +#include "field_effect.h" +#include "rng.h" +#include "sprite.h" +#include "sound.h" +#include "songs.h" +#include "trainer.h" +#include "field_camera.h" + +void sub_807DE10(void); +void dp12_8087EA4(void); + +extern u8 ewram[]; +extern u16 gUnknown_03005560[]; +extern u16 gUnknown_03004DE0[][0x3C0]; + +extern const struct OamData gFieldOamData_32x32; + +struct TransitionData +{ + vs8 VBlank_DMA; + u16 WININ; + u16 WINOUT; + u16 field_6; + u16 WIN0V; + u16 field_A; + u16 field_C; + u16 BLDCNT; + u16 BLDALPHA; + u16 BLDY; + s16 field_14; + s16 field_16; + s16 field_18; + s16 field_1A; + s16 field_1C; + s16 field_1E; // unused + s16 field_20; + s16 field_22; // unused + s16 data[11]; +}; + +#define TRANSITION_STRUCT (*(struct TransitionData *) (ewram + 0xC000)) +typedef bool8 (*TransitionState)(struct Task* task); +typedef bool8 (*TransitionSpriteCallback)(struct Sprite* sprite); + +// this file's functions +static void LaunchBattleTransitionTask(u8 transitionID); +static void Task_BattleTransitionMain(u8 taskID); +static void Phase1Task_TransitionAll(u8 taskID); +static void Phase2Task_Transition_Blur(u8 taskID); +static void Phase2Task_Transition_Swirl(u8 taskID); +static void Phase2Task_Transition_Shuffle(u8 taskID); +static void Phase2Task_Transition_BigPokeball(u8 taskID); +static void Phase2Task_Transition_PokeballsTrail(u8 taskID); +static void Phase2Task_Transition_Clockwise_BlackFade(u8 taskID); +static void Phase2Task_Transition_Ripple(u8 taskID); +static void Phase2Task_Transition_Wave(u8 taskID); +static void Phase2Task_Transition_Slice(u8 taskID); +static void Phase2Task_Transition_WhiteFade(u8 taskID); +static void Phase2Task_Transition_GridSquares(u8 taskID); +static void Phase2Task_Transition_Shards(u8 taskID); +static void Phase2Task_Transition_Sydney(u8 taskID); +static void Phase2Task_Transition_Phoebe(u8 taskID); +static void Phase2Task_Transition_Glacia(u8 taskID); +static void Phase2Task_Transition_Drake(u8 taskID); +static void Phase2Task_Transition_Steven(u8 taskID); +static bool8 Transition_Phase1(struct Task* task); +static bool8 Transition_WaitForPhase1(struct Task* task); +static bool8 Transition_Phase2(struct Task* task); +static bool8 Transition_WaitForPhase2(struct Task* task); +static void VBlankCB_Phase2_Transition_Swirl(void); +static void HBlankCB_Phase2_Transition_Swirl(void); +static void VBlankCB_Phase2_Transition_Shuffle(void); +static void HBlankCB_Phase2_Transition_Shuffle(void); +static void VBlankCB0_Phase2_Transition_BigPokeball(void); +static void VBlankCB1_Phase2_Transition_BigPokeball(void); +static void VBlankCB_Phase2_Transition_Clockwise_BlackFade(void); +static void VBlankCB_Phase2_Transition_Ripple(void); +static void HBlankCB_Phase2_Transition_Ripple(void); +static void VBlankCB_Phase2_Transition_Wave(void); +static void VBlankCB_Phase2_Transition_Slice(void); +static void HBlankCB_Phase2_Transition_Slice(void); +static void VBlankCB0_Phase2_Transition_WhiteFade(void); +static void VBlankCB1_Phase2_Transition_WhiteFade(void); +static void HBlankCB_Phase2_Transition_WhiteFade(void); +static void VBlankCB0_Phase2_Mugshots(void); +static void VBlankCB1_Phase2_Mugshots(void); +static void HBlankCB_Phase2_Mugshots(void); +static void VBlankCB_Phase2_Transition_Shards(void); +static bool8 Phase2_Transition_Blur_Func1(struct Task* task); +static bool8 Phase2_Transition_Blur_Func2(struct Task* task); +static bool8 Phase2_Transition_Blur_Func3(struct Task* task); +static bool8 Phase2_Transition_Swirl_Func1(struct Task* task); +static bool8 Phase2_Transition_Swirl_Func2(struct Task* task); +static bool8 Phase2_Transition_Shuffle_Func1(struct Task* task); +static bool8 Phase2_Transition_Shuffle_Func2(struct Task* task); +static bool8 Phase2_Transition_BigPokeball_Func1(struct Task* task); +static bool8 Phase2_Transition_BigPokeball_Func2(struct Task* task); +static bool8 Phase2_Transition_BigPokeball_Func3(struct Task* task); +static bool8 Phase2_Transition_BigPokeball_Func4(struct Task* task); +static bool8 Phase2_Transition_BigPokeball_Func5(struct Task* task); +static bool8 Phase2_Transition_BigPokeball_Func6(struct Task* task); +static bool8 Phase2_Transition_PokeballsTrail_Func1(struct Task* task); +static bool8 Phase2_Transition_PokeballsTrail_Func2(struct Task* task); +static bool8 Phase2_Transition_PokeballsTrail_Func3(struct Task* task); +static bool8 Phase2_Transition_Clockwise_BlackFade_Func1(struct Task* task); +static bool8 Phase2_Transition_Clockwise_BlackFade_Func2(struct Task* task); +static bool8 Phase2_Transition_Clockwise_BlackFade_Func3(struct Task* task); +static bool8 Phase2_Transition_Clockwise_BlackFade_Func4(struct Task* task); +static bool8 Phase2_Transition_Clockwise_BlackFade_Func5(struct Task* task); +static bool8 Phase2_Transition_Clockwise_BlackFade_Func6(struct Task* task); +static bool8 Phase2_Transition_Clockwise_BlackFade_Func7(struct Task* task); +static bool8 Phase2_Transition_Ripple_Func1(struct Task* task); +static bool8 Phase2_Transition_Ripple_Func2(struct Task* task); +static bool8 Phase2_Transition_Wave_Func1(struct Task* task); +static bool8 Phase2_Transition_Wave_Func2(struct Task* task); +static bool8 Phase2_Transition_Wave_Func3(struct Task* task); +static bool8 Phase2_Transition_Slice_Func1(struct Task* task); +static bool8 Phase2_Transition_Slice_Func2(struct Task* task); +static bool8 Phase2_Transition_Slice_Func3(struct Task* task); +static bool8 Phase2_Transition_WhiteFade_Func1(struct Task* task); +static bool8 Phase2_Transition_WhiteFade_Func2(struct Task* task); +static bool8 Phase2_Transition_WhiteFade_Func3(struct Task* task); +static bool8 Phase2_Transition_WhiteFade_Func4(struct Task* task); +static bool8 Phase2_Transition_WhiteFade_Func5(struct Task* task); +static bool8 Phase2_Transition_GridSquares_Func1(struct Task* task); +static bool8 Phase2_Transition_GridSquares_Func2(struct Task* task); +static bool8 Phase2_Transition_GridSquares_Func3(struct Task* task); +static bool8 Phase2_Transition_Shards_Func1(struct Task* task); +static bool8 Phase2_Transition_Shards_Func2(struct Task* task); +static bool8 Phase2_Transition_Shards_Func3(struct Task* task); +static bool8 Phase2_Transition_Shards_Func4(struct Task* task); +static bool8 Phase2_Transition_Shards_Func5(struct Task* task); +static bool8 Phase2_Mugshot_Func1(struct Task* task); +static bool8 Phase2_Mugshot_Func2(struct Task* task); +static bool8 Phase2_Mugshot_Func3(struct Task* task); +static bool8 Phase2_Mugshot_Func4(struct Task* task); +static bool8 Phase2_Mugshot_Func5(struct Task* task); +static bool8 Phase2_Mugshot_Func6(struct Task* task); +static bool8 Phase2_Mugshot_Func7(struct Task* task); +static bool8 Phase2_Mugshot_Func8(struct Task* task); +static bool8 Phase2_Mugshot_Func9(struct Task* task); +static bool8 Phase2_Mugshot_Func10(struct Task* task); +static void Phase2Task_MugShotTransition(u8 taskID); +static void Mugshots_CreateOpponentPlayerSprites(struct Task* task); +static void sub_811CA10(s16 spriteID, s16 value); +static void sub_811CA28(s16 spriteID); +static s16 sub_811CA44(s16 spriteID); +static bool8 sub_811C934(struct Sprite* sprite); +static bool8 sub_811C938(struct Sprite* sprite); +static bool8 sub_811C984(struct Sprite* sprite); +static bool8 sub_811C9B8(struct Sprite* sprite); +static bool8 sub_811C9E4(struct Sprite* sprite); +static void CreatePhase1Task(s16 a0, s16 a1, s16 a2, s16 a3, s16 a4); +static bool8 sub_811D52C(void); +static void Phase1_Task_RunFuncs(u8 taskID); +static bool8 Phase1_TransitionAll_Func1(struct Task* task); +static bool8 Phase1_TransitionAll_Func2(struct Task* task); +static void sub_811D658(void); +static void VBlankCB_BattleTransition(void); +static void sub_811D6A8(u16** a0, u16** a1); +static void sub_811D690(u16** a0); +static void sub_811D6D4(void); +static void sub_811D6E8(s16* array, s16 sinAdd, s16 index, s16 indexIncrementer, s16 amplitude, s16 arrSize); +static void sub_811D764(u16* a0, s16 a1, s16 a2, s16 a3); +static void sub_811D8FC(s16* a0, s16 a1, s16 a2, s16 a3, s16 a4, s16 a5, s16 a6); +static bool8 sub_811D978(s16* a0, bool8 a1, bool8 a2); +static void sub_811CFD0(struct Sprite* sprite); +static void sub_811B720(struct Sprite* sprite); +static void sub_811C90C(struct Sprite* sprite); + +// const data + +static const u32 sBigPokeball_Tileset[] = INCBIN_U32("graphics/battle_transitions/big_pokeball.4bpp"); +static const u32 sPokeballTrail_Tileset[] = INCBIN_U32("graphics/battle_transitions/pokeball_trail.4bpp"); +static const u8 sSpriteImage_83FC148[] = INCBIN_U8("graphics/battle_transitions/pokeball.4bpp"); +static const u32 sUnknown_083FC348[] = INCBIN_U32("graphics/battle_transitions/elite_four_bg.4bpp"); +static const u8 sSpriteImage_83FC528[] = INCBIN_U8("graphics/battle_transitions/unused_brendan.4bpp"); +static const u8 sSpriteImage_83FCD28[] = INCBIN_U8("graphics/battle_transitions/unused_lass.4bpp"); +static const u32 sShrinkingBoxTileset[] = INCBIN_U32("graphics/battle_transitions/shrinking_box.4bpp"); + +static struct TransitionData * const sTransitionStructPtr = &TRANSITION_STRUCT; + +static const TaskFunc sPhase1_Tasks[TRANSITIONS_NO] = +{ + [0 ... TRANSITIONS_NO - 1] = &Phase1Task_TransitionAll +}; + +static const TaskFunc sPhase2_Tasks[TRANSITIONS_NO] = +{ + Phase2Task_Transition_Blur, // 0 + Phase2Task_Transition_Swirl, // 1 + Phase2Task_Transition_Shuffle, // 2 + Phase2Task_Transition_BigPokeball, // 3 + Phase2Task_Transition_PokeballsTrail, // 4 + Phase2Task_Transition_Clockwise_BlackFade, // 5 + Phase2Task_Transition_Ripple, // 6 + Phase2Task_Transition_Wave, // 7 + Phase2Task_Transition_Slice, // 8 + Phase2Task_Transition_WhiteFade, // 9 + Phase2Task_Transition_GridSquares, // 10 + Phase2Task_Transition_Shards, // 11 + Phase2Task_Transition_Sydney, // 12 + Phase2Task_Transition_Phoebe, // 13 + Phase2Task_Transition_Glacia, // 14 + Phase2Task_Transition_Drake, // 15 + Phase2Task_Transition_Steven, // 16 +}; + +static const TransitionState sMainTransitionPhases[] = +{ + &Transition_Phase1, + &Transition_WaitForPhase1, + &Transition_Phase2, + &Transition_WaitForPhase2 +}; + +static const TransitionState sPhase2_Transition_Blur_Funcs[] = +{ + Phase2_Transition_Blur_Func1, + Phase2_Transition_Blur_Func2, + Phase2_Transition_Blur_Func3 +}; + +static const TransitionState sPhase2_Transition_Swirl_Funcs[] = +{ + Phase2_Transition_Swirl_Func1, + Phase2_Transition_Swirl_Func2, +}; + +static const TransitionState sPhase2_Transition_Shuffle_Funcs[] = +{ + Phase2_Transition_Shuffle_Func1, + Phase2_Transition_Shuffle_Func2, +}; + +static const TransitionState sPhase2_Transition_BigPokeball_Funcs[] = +{ + Phase2_Transition_BigPokeball_Func1, + Phase2_Transition_BigPokeball_Func2, + Phase2_Transition_BigPokeball_Func3, + Phase2_Transition_BigPokeball_Func4, + Phase2_Transition_BigPokeball_Func5, + Phase2_Transition_BigPokeball_Func6 +}; + +static const TransitionState sPhase2_Transition_PokeballsTrail_Funcs[] = +{ + Phase2_Transition_PokeballsTrail_Func1, + Phase2_Transition_PokeballsTrail_Func2, + Phase2_Transition_PokeballsTrail_Func3 +}; + +static const s16 sUnknown_083FD7E4[2] = {-16, 256}; +static const s16 sUnknown_083FD7E8[5] = {0, 32, 64, 18, 48}; +static const s16 sUnknown_083FD7F2[2] = {8, -8}; + +static const TransitionState sPhase2_Transition_Clockwise_BlackFade_Funcs[] = +{ + Phase2_Transition_Clockwise_BlackFade_Func1, + Phase2_Transition_Clockwise_BlackFade_Func2, + Phase2_Transition_Clockwise_BlackFade_Func3, + Phase2_Transition_Clockwise_BlackFade_Func4, + Phase2_Transition_Clockwise_BlackFade_Func5, + Phase2_Transition_Clockwise_BlackFade_Func6, + Phase2_Transition_Clockwise_BlackFade_Func7 +}; + +static const TransitionState sPhase2_Transition_Ripple_Funcs[] = +{ + Phase2_Transition_Ripple_Func1, + Phase2_Transition_Ripple_Func2 +}; + +static const TransitionState sPhase2_Transition_Wave_Funcs[] = +{ + Phase2_Transition_Wave_Func1, + Phase2_Transition_Wave_Func2, + Phase2_Transition_Wave_Func3 +}; + +static const TransitionState sPhase2_Mugshot_Transition_Funcs[] = +{ + Phase2_Mugshot_Func1, + Phase2_Mugshot_Func2, + Phase2_Mugshot_Func3, + Phase2_Mugshot_Func4, + Phase2_Mugshot_Func5, + Phase2_Mugshot_Func6, + Phase2_Mugshot_Func7, + Phase2_Mugshot_Func8, + Phase2_Mugshot_Func9, + Phase2_Mugshot_Func10 +}; + +static const u8 sMugshotsTrainerPicIDsTable[MUGSHOTS_NO] = {TRAINER_PIC_SIDNEY, TRAINER_PIC_PHOEBE, TRAINER_PIC_GLACIA, TRAINER_PIC_DRAKE, TRAINER_PIC_STEVEN}; +static const s16 sMugshotsOpponentRotationScales[MUGSHOTS_NO][2] = +{ + {0x200, 0x200}, + {0x200, 0x200}, + {0x1B0, 0x1B0}, + {0x1A0, 0x1A0}, + {0x188, 0x188}, +}; +static const s16 sMugshotsOpponentCoords[MUGSHOTS_NO][2] = +{ + {0, 0}, + {0, 0}, + {-4, 4}, + {0, 5}, + {0, 7}, +}; + +static const TransitionSpriteCallback sUnknown_083FD880[] = +{ + sub_811C934, + sub_811C938, + sub_811C984, + sub_811C9B8, + sub_811C934, + sub_811C9E4, + sub_811C934 +}; + +static const s16 sUnknown_083FD89C[2] = {12, -12}; +static const s16 sUnknown_083FD8A0[2] = {-1, 1}; + +static const TransitionState sPhase2_Transition_Slice_Funcs[] = +{ + Phase2_Transition_Slice_Func1, + Phase2_Transition_Slice_Func2, + Phase2_Transition_Slice_Func3 +}; + +static const TransitionState sPhase2_Transition_WhiteFade_Funcs[] = +{ + Phase2_Transition_WhiteFade_Func1, + Phase2_Transition_WhiteFade_Func2, + Phase2_Transition_WhiteFade_Func3, + Phase2_Transition_WhiteFade_Func4, + Phase2_Transition_WhiteFade_Func5 +}; + +static const s16 sUnknown_083FD8C4[8] = {0, 20, 15, 40, 10, 25, 35, 5}; + +static const TransitionState sPhase2_Transition_GridSquares_Funcs[] = +{ + Phase2_Transition_GridSquares_Func1, + Phase2_Transition_GridSquares_Func2, + Phase2_Transition_GridSquares_Func3 +}; + +static const TransitionState sPhase2_Transition_Shards_Funcs[] = +{ + Phase2_Transition_Shards_Func1, + Phase2_Transition_Shards_Func2, + Phase2_Transition_Shards_Func3, + Phase2_Transition_Shards_Func4, + Phase2_Transition_Shards_Func5 +}; + +static const s16 sUnknown_083FD8F4[][5] = +{ + {56, 0, 0, 160, 0}, + {104, 160, 240, 88, 1}, + {240, 72, 56, 0, 1}, + {0, 32, 144, 160, 0}, + {144, 160, 184, 0, 1}, + {56, 0, 168, 160, 0}, + {168, 160, 48, 0, 1}, +}; + +static const s16 sUnknown_083FD93A[] = {8, 4, 2, 1, 1, 1, 0}; + +static const TransitionState sPhase1_TransitionAll_Funcs[] = +{ + Phase1_TransitionAll_Func1, + Phase1_TransitionAll_Func2 +}; + +static const struct SpriteFrameImage sSpriteImageTable_83FD950[] = +{ + sSpriteImage_83FC148, 0x200 +}; + +static const union AnimCmd sSpriteAnim_83FD958[] = +{ + ANIMCMD_FRAME(0, 1), + ANIMCMD_END +}; + +static const union AnimCmd *const sSpriteAnimTable_83FD960[] = +{ + sSpriteAnim_83FD958 +}; + +static const union AffineAnimCmd sSpriteAffineAnim_83FD964[] = +{ + AFFINEANIMCMD_FRAME(0, 0, -4, 1), + AFFINEANIMCMD_JUMP(0) +}; + +static const union AffineAnimCmd sSpriteAffineAnim_83FD974[] = +{ + AFFINEANIMCMD_FRAME(0, 0, 4, 1), + AFFINEANIMCMD_JUMP(0) +}; + +static const union AffineAnimCmd *const sSpriteAffineAnimTable_83FD984[] = +{ + sSpriteAffineAnim_83FD964, + sSpriteAffineAnim_83FD974 +}; + +static const struct SpriteTemplate sSpriteTemplate_83FD98C = +{ + .tileTag = 0xFFFF, + .paletteTag = 4105, + .oam = &gFieldOamData_32x32, + .anims = sSpriteAnimTable_83FD960, + .images = sSpriteImageTable_83FD950, + .affineAnims = sSpriteAffineAnimTable_83FD984, + .callback = sub_811B720 +}; + +static const struct OamData gOamData_83FD9A4 = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = 3, + .tileNum = 0, + .priority = 0, + .paletteNum = 0, + .affineParam = 0, +}; + +static const struct SpriteFrameImage sSpriteImageTable_83FD9AC[] = +{ + sSpriteImage_83FC528, 0x800 +}; + +static const struct SpriteFrameImage sSpriteImageTable_83FD9B4[] = +{ + sSpriteImage_83FCD28, 0x800 +}; + +static const union AnimCmd sSpriteAnim_83FD9BC[] = +{ + ANIMCMD_FRAME(0, 1), + ANIMCMD_END +}; + +static const union AnimCmd *const sSpriteAnimTable_83FD9C4[] = +{ + sSpriteAnim_83FD9BC +}; + +static const struct SpriteTemplate sSpriteTemplate_83FD9C8 = +{ + .tileTag = 0xFFFF, + .paletteTag = 4106, + .oam = &gOamData_83FD9A4, + .anims = sSpriteAnimTable_83FD9C4, + .images = sSpriteImageTable_83FD9AC, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_811C90C +}; + +static const struct SpriteTemplate sSpriteTemplate_83FD9E0 = +{ + .tileTag = 0xFFFF, + .paletteTag = 4106, + .oam = &gOamData_83FD9A4, + .anims = sSpriteAnimTable_83FD9C4, + .images = sSpriteImageTable_83FD9B4, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_811C90C +}; + +static const u16 gFieldEffectObjectPalette10[] = INCBIN_U16("graphics/field_effect_objects/palettes/10.gbapal"); + +const struct SpritePalette gFieldEffectObjectPaletteInfo10 = +{ + gFieldEffectObjectPalette10, 0x1009 +}; + +static const u16 sMugshotPal_Sydney[] = INCBIN_U16("graphics/battle_transitions/sidney_bg.gbapal"); +static const u16 sMugshotPal_Phoebe[] = INCBIN_U16("graphics/battle_transitions/phoebe_bg.gbapal"); +static const u16 sMugshotPal_Glacia[] = INCBIN_U16("graphics/battle_transitions/glacia_bg.gbapal"); +static const u16 sMugshotPal_Drake[] = INCBIN_U16("graphics/battle_transitions/drake_bg.gbapal"); +static const u16 sMugshotPal_Steven[] = INCBIN_U16("graphics/battle_transitions/steven_bg.gbapal"); +static const u16 sMugshotPal_Brendan[] = INCBIN_U16("graphics/battle_transitions/brendan_bg.gbapal"); +static const u16 sMugshotPal_May[] = INCBIN_U16("graphics/battle_transitions/may_bg.gbapal"); + +static const u16 * const sOpponentMugshotsPals[MUGSHOTS_NO] = +{ + sMugshotPal_Sydney, + sMugshotPal_Phoebe, + sMugshotPal_Glacia, + sMugshotPal_Drake, + sMugshotPal_Steven +}; + +static const u16 * const sPlayerMugshotsPals[2] = +{ + sMugshotPal_Brendan, + sMugshotPal_May +}; + +static const u16 sUnusedTrainerPalette[] = INCBIN_U16("graphics/battle_transitions/unused_trainer.gbapal"); +static const struct SpritePalette sSpritePalette_UnusedTrainer = +{ + sUnusedTrainerPalette, 0x100A +}; + +static const u16 sBigPokeball_Tilemap[] = INCBIN_U16("graphics/battle_transitions/big_pokeball_map.bin"); +static const u16 sMugshotsTilemap[] = INCBIN_U16("graphics/battle_transitions/elite_four_bg_map.bin"); + +// actual code starts here + +void sub_811AABC(u8 transitionID) +{ + gMain.callback2 = sub_8054398; + LaunchBattleTransitionTask(transitionID); +} + +void sub_811AAD8(u8 transitionID) +{ + LaunchBattleTransitionTask(transitionID); +} + +#define tState data[0] +#define tTransitionID data[1] +#define tTransitionDone data[15] + +bool8 IsBattleTransitionDone(void) +{ + u8 taskID = FindTaskIdByFunc(Task_BattleTransitionMain); + if (gTasks[taskID].tTransitionDone) + { + DestroyTask(taskID); + return TRUE; + } + else + return FALSE; +} + +static void LaunchBattleTransitionTask(u8 transitionID) +{ + u8 taskID = CreateTask(Task_BattleTransitionMain, 2); + gTasks[taskID].tTransitionID = transitionID; +} + +static void Task_BattleTransitionMain(u8 taskID) +{ + while (sMainTransitionPhases[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Transition_Phase1(struct Task* task) +{ + sub_807DE10(); + CpuCopy32(gPlttBufferFaded, gPlttBufferUnfaded, 0x400); + if (sPhase1_Tasks[task->tTransitionID] != NULL) + { + CreateTask(sPhase1_Tasks[task->tTransitionID], 4); + task->tState++; + return FALSE; + } + else + { + task->tState = 2; + return TRUE; + } +} + +static bool8 Transition_WaitForPhase1(struct Task* task) +{ + if (FindTaskIdByFunc(sPhase1_Tasks[task->tTransitionID]) == 0xFF) + { + task->tState++; + return TRUE; + } + else + return FALSE; +} + +static bool8 Transition_Phase2(struct Task* task) +{ + CreateTask(sPhase2_Tasks[task->tTransitionID], 0); + task->tState++; + return FALSE; +} + +static bool8 Transition_WaitForPhase2(struct Task* task) +{ + task->tTransitionDone = 0; + if (FindTaskIdByFunc(sPhase2_Tasks[task->tTransitionID]) == 0xFF) + task->tTransitionDone = 1; + return FALSE; +} + +static void Phase1Task_TransitionAll(u8 taskID) +{ + if (gTasks[taskID].tState == 0) + { + gTasks[taskID].tState++; + CreatePhase1Task(0, 0, 3, 2, 2); + } + else if (sub_811D52C()) + DestroyTask(taskID); +} + +static void Phase2Task_Transition_Blur(u8 taskID) +{ + while (sPhase2_Transition_Blur_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_Blur_Func1(struct Task* task) +{ + REG_MOSAIC = 0; + REG_BG1CNT |= BGCNT_MOSAIC; + REG_BG2CNT |= BGCNT_MOSAIC; + REG_BG3CNT |= BGCNT_MOSAIC; + task->tState++; + return TRUE; +} + +static bool8 Phase2_Transition_Blur_Func2(struct Task* task) +{ + if (task->data[1] != 0) + task->data[1]--; + else + { + task->data[1] = 4; + if (++task->data[2] == 10) + BeginNormalPaletteFade(-1, -1, 0, 0x10, 0); + REG_MOSAIC = (task->data[2] & 15) * 17; + if (task->data[2] > 14) + task->tState++; + } + return FALSE; +} + +static bool8 Phase2_Transition_Blur_Func3(struct Task* task) +{ + if (!gPaletteFade.active) + { + u8 taskID = FindTaskIdByFunc(Phase2Task_Transition_Blur); + DestroyTask(taskID); + } + return FALSE; +} + +static void Phase2Task_Transition_Swirl(u8 taskID) +{ + while (sPhase2_Transition_Swirl_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_Swirl_Func1(struct Task* task) +{ + u16 savedIME; + + sub_811D658(); + dp12_8087EA4(); + BeginNormalPaletteFade(-1, 4, 0, 0x10, 0); + sub_811D6E8(gUnknown_03005560, TRANSITION_STRUCT.field_14, 0, 2, 0, 160); + + SetVBlankCallback(VBlankCB_Phase2_Transition_Swirl); + SetHBlankCallback(HBlankCB_Phase2_Transition_Swirl); + + savedIME = REG_IME; + REG_IME = 0; + REG_IE |= (INTR_FLAG_VBLANK | INTR_FLAG_HBLANK); + REG_IME = savedIME; + REG_DISPSTAT |= (DISPSTAT_VBLANK_INTR | DISPSTAT_HBLANK_INTR); + + task->tState++; + return FALSE; +} + +static bool8 Phase2_Transition_Swirl_Func2(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + task->data[1] += 4; + task->data[2] += 8; + + sub_811D6E8(gUnknown_03004DE0[0], TRANSITION_STRUCT.field_14, task->data[1], 2, task->data[2], 160); + + if (!gPaletteFade.active) + { + u8 taskID = FindTaskIdByFunc(Phase2Task_Transition_Swirl); + DestroyTask(taskID); + } + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static void VBlankCB_Phase2_Transition_Swirl(void) +{ + VBlankCB_BattleTransition(); + if (TRANSITION_STRUCT.VBlank_DMA) + DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 320); +} + +static void HBlankCB_Phase2_Transition_Swirl(void) +{ + u16 var = gUnknown_03004DE0[1][REG_VCOUNT]; + REG_BG1HOFS = var; + REG_BG2HOFS = var; + REG_BG3HOFS = var; +} + +static void Phase2Task_Transition_Shuffle(u8 taskID) +{ + while (sPhase2_Transition_Shuffle_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_Shuffle_Func1(struct Task* task) +{ + u16 savedIME; + + sub_811D658(); + dp12_8087EA4(); + + BeginNormalPaletteFade(-1, 4, 0, 0x10, 0); + memset(gUnknown_03005560, TRANSITION_STRUCT.field_16, 0x140); + + SetVBlankCallback(VBlankCB_Phase2_Transition_Shuffle); + SetHBlankCallback(HBlankCB_Phase2_Transition_Shuffle); + + savedIME = REG_IME; + REG_IME = 0; + REG_IE |= (INTR_FLAG_VBLANK | INTR_FLAG_HBLANK); + REG_IME = savedIME; + REG_DISPSTAT |= (DISPSTAT_VBLANK_INTR | DISPSTAT_HBLANK_INTR); + + task->tState++; + return FALSE; +} + +static bool8 Phase2_Transition_Shuffle_Func2(struct Task* task) +{ + u8 i; + u16 r3, r4; + + TRANSITION_STRUCT.VBlank_DMA = 0; + r4 = task->data[1]; + r3 = task->data[2] >> 8; + task->data[1] += 4224; + task->data[2] += 384; + + for (i = 0; i < 160; i++, r4 += 4224) + { + u16 var = r4 / 256; + gUnknown_03004DE0[0][i] = TRANSITION_STRUCT.field_16 + Sin(var, r3); + } + + if (!gPaletteFade.active) + DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_Shuffle)); + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static void VBlankCB_Phase2_Transition_Shuffle(void) +{ + VBlankCB_BattleTransition(); + if (TRANSITION_STRUCT.VBlank_DMA) + DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 320); +} + +static void HBlankCB_Phase2_Transition_Shuffle(void) +{ + u16 var = gUnknown_03004DE0[1][REG_VCOUNT]; + REG_BG1VOFS = var; + REG_BG2VOFS = var; + REG_BG3VOFS = var; +} + +static void Phase2Task_Transition_BigPokeball(u8 taskID) +{ + while (sPhase2_Transition_BigPokeball_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_BigPokeball_Func1(struct Task* task) +{ + u16 i; + u16 *dst1, *dst2; + + sub_811D658(); + dp12_8087EA4(); + + task->data[1] = 16; + task->data[2] = 0; + task->data[4] = 0; + task->data[5] = 0x4000; + TRANSITION_STRUCT.WININ = 63; + TRANSITION_STRUCT.WINOUT = 0; + TRANSITION_STRUCT.field_6 = 240; + TRANSITION_STRUCT.WIN0V = 160; + TRANSITION_STRUCT.BLDCNT = 0x3F41; + TRANSITION_STRUCT.BLDALPHA = task->data[1] * 256; // 16 * 256 = 0x1000 + + for (i = 0; i < 160; i++) + { + gUnknown_03005560[i] = 240; + } + + SetVBlankCallback(VBlankCB0_Phase2_Transition_BigPokeball); + + sub_811D6A8(&dst1, & dst2); + CpuFill16(0, dst1, 0x800); + CpuSet(sBigPokeball_Tileset, dst2, 0x2C0); + LoadPalette(gFieldEffectObjectPalette10, 240, 32); + + task->tState++; + return FALSE; +} + +static bool8 Phase2_Transition_BigPokeball_Func2(struct Task* task) +{ + s16 i, j; + u16 *dst1, *dst2; + const u16* BigPokeballMap; + + BigPokeballMap = sBigPokeball_Tilemap; + sub_811D6A8(&dst1, &dst2); + for (i = 0; i < 20; i++) + { + for (j = 0; j < 30; j++, BigPokeballMap++) + { + dst1[i * 32 + j] = *BigPokeballMap | 0xF000; + } + } + sub_811D6E8(gUnknown_03004DE0[0], 0, task->data[4], 132, task->data[5], 160); + + task->tState++; + return TRUE; +} + +static bool8 Phase2_Transition_BigPokeball_Func3(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + if (task->data[3] == 0 || --task->data[3] == 0) + { + task->data[2]++; + task->data[3] = 2; + } + TRANSITION_STRUCT.BLDALPHA = (task->data[1] << 8) | task->data[2]; + if (task->data[2] > 15) + task->tState++; + task->data[4] += 8; + task->data[5] -= 256; + + sub_811D6E8(gUnknown_03004DE0[0], 0, task->data[4], 132, task->data[5] >> 8, 160); + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Transition_BigPokeball_Func4(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + if (task->data[3] == 0 || --task->data[3] == 0) + { + task->data[1]--; + task->data[3] = 2; + } + TRANSITION_STRUCT.BLDALPHA = (task->data[1] << 8) | task->data[2]; + if (task->data[1] == 0) + task->tState++; + task->data[4] += 8; + task->data[5] -= 256; + + sub_811D6E8(gUnknown_03004DE0[0], 0, task->data[4], 132, task->data[5] >> 8, 160); + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Transition_BigPokeball_Func5(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + task->data[4] += 8; + task->data[5] -= 256; + + sub_811D6E8(gUnknown_03004DE0[0], 0, task->data[4], 132, task->data[5] >> 8, 160); + + if (task->data[5] <= 0) + { + task->tState++; + task->data[1] = 160; + task->data[2] = 256; + task->data[3] = 0; + } + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Transition_BigPokeball_Func6(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + if (task->data[2] < 1024) + task->data[2] += 128; + if (task->data[1] != 0) + { + task->data[1] -= (task->data[2] >> 8); + if (task->data[1] < 0) + task->data[1] = 0; + } + sub_811D764(gUnknown_03004DE0[0], 120, 80, task->data[1]); + if (task->data[1] == 0) + { + DmaStop(0); + sub_811D6D4(); + DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_BigPokeball)); + } + if (task->data[3] == 0) + { + task->data[3]++; + SetVBlankCallback(VBlankCB1_Phase2_Transition_BigPokeball); + } + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static void Transition_BigPokeball_Vblank(void) +{ + DmaStop(0); + VBlankCB_BattleTransition(); + if (TRANSITION_STRUCT.VBlank_DMA) + DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 320); + REG_WININ = TRANSITION_STRUCT.WININ; + REG_WINOUT = TRANSITION_STRUCT.WINOUT; + REG_WIN0V = TRANSITION_STRUCT.WIN0V; + REG_BLDCNT = TRANSITION_STRUCT.BLDCNT; + REG_BLDALPHA = TRANSITION_STRUCT.BLDALPHA; +} + +static void VBlankCB0_Phase2_Transition_BigPokeball(void) +{ + Transition_BigPokeball_Vblank(); + DmaSet(0, gUnknown_03005560, ®_BG0HOFS, 0xA2400001); +} + +static void VBlankCB1_Phase2_Transition_BigPokeball(void) +{ + Transition_BigPokeball_Vblank(); + DmaSet(0, gUnknown_03005560, ®_WIN0H, 0xA2400001); +} + +static void Phase2Task_Transition_PokeballsTrail(u8 taskID) +{ + while (sPhase2_Transition_PokeballsTrail_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_PokeballsTrail_Func1(struct Task* task) +{ + u16 *dst1, *dst2; + + sub_811D6A8(&dst1, &dst2); + CpuSet(sPokeballTrail_Tileset, dst2, 0x20); + CpuFill32(0, dst1, 0x800); + LoadPalette(gFieldEffectObjectPalette10, 0xF0, 0x20); + + task->tState++; + return FALSE; +} + +static bool8 Phase2_Transition_PokeballsTrail_Func2(struct Task* task) +{ + s16 i; + s16 rand; + s16 arr0[2]; + s16 arr1[5]; + + memcpy(arr0, sUnknown_083FD7E4, sizeof(sUnknown_083FD7E4)); + memcpy(arr1, sUnknown_083FD7E8, sizeof(sUnknown_083FD7E8)); + rand = Random() & 1; + for (i = 0; i <= 4; i++, rand ^= 1) + { + gUnknown_0202FF84[0] = arr0[rand]; // x + gUnknown_0202FF84[1] = (i * 32) + 16; // y + gUnknown_0202FF84[2] = rand; + gUnknown_0202FF84[3] = arr1[i]; + FieldEffectStart(FLDEFF_POKEBALL); + } + + task->tState++; + return FALSE; +} + +static bool8 Phase2_Transition_PokeballsTrail_Func3(struct Task* task) +{ + if (!FieldEffectActiveListContains(FLDEFF_POKEBALL)) + { + sub_811D6D4(); + DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_PokeballsTrail)); + } + return FALSE; +} + +bool8 FldEff_Pokeball(void) +{ + u8 spriteID = CreateSpriteAtEnd(&sSpriteTemplate_83FD98C, gUnknown_0202FF84[0], gUnknown_0202FF84[1], 0); + gSprites[spriteID].oam.priority = 0; + gSprites[spriteID].oam.affineMode = 1; + gSprites[spriteID].data0 = gUnknown_0202FF84[2]; + gSprites[spriteID].data1 = gUnknown_0202FF84[3]; + gSprites[spriteID].data2 = -1; + InitSpriteAffineAnim(&gSprites[spriteID]); + StartSpriteAffineAnim(&gSprites[spriteID], gUnknown_0202FF84[2]); + return FALSE; +} + +#define SOME_VRAM_STORE(ptr, posY, posX, toStore) \ +{ \ + u32 index = (posY) * 32 + posX; \ + ptr[index] = toStore; \ +} + +static void sub_811B720(struct Sprite* sprite) +{ + s16 arr0[2]; + + memcpy(arr0, sUnknown_083FD7F2, sizeof(sUnknown_083FD7F2)); + if (sprite->data1 != 0) + sprite->data1--; + else + { + if (sprite->pos1.x >= 0 && sprite->pos1.x <= 240) + { + s16 posX = sprite->pos1.x >> 3; + s16 posY = sprite->pos1.y >> 3; + + if (posX != sprite->data2) + { + u32 var; + u16 *ptr; + + sprite->data2 = posX; + var = (((REG_BG0CNT >> 8) & 0x1F) << 11); // r2 + ptr = (u16 *)(VRAM + var); + + SOME_VRAM_STORE(ptr, posY - 2, posX, 0xF001); + SOME_VRAM_STORE(ptr, posY - 1, posX, 0xF001); + SOME_VRAM_STORE(ptr, posY - 0, posX, 0xF001); + SOME_VRAM_STORE(ptr, posY + 1, posX, 0xF001); + } + } + sprite->pos1.x += arr0[sprite->data0]; + if (sprite->pos1.x < -15 || sprite->pos1.x > 255) + FieldEffectStop(sprite, FLDEFF_POKEBALL); + } +} + +static void Phase2Task_Transition_Clockwise_BlackFade(u8 taskID) +{ + while (sPhase2_Transition_Clockwise_BlackFade_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_Clockwise_BlackFade_Func1(struct Task* task) +{ + u16 i; + + sub_811D658(); + dp12_8087EA4(); + + TRANSITION_STRUCT.WININ = 0; + TRANSITION_STRUCT.WINOUT = 63; + TRANSITION_STRUCT.field_6 = -3855; + TRANSITION_STRUCT.WIN0V = 160; + + for (i = 0; i < 160; i++) + { + gUnknown_03005560[i] = 0xF3F4; + } + + SetVBlankCallback(VBlankCB_Phase2_Transition_Clockwise_BlackFade); + TRANSITION_STRUCT.data[4] = 120; + + task->tState++; + return TRUE; +} + +static bool8 Phase2_Transition_Clockwise_BlackFade_Func2(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + + sub_811D8FC(TRANSITION_STRUCT.data, 120, 80, TRANSITION_STRUCT.data[4], -1, 1, 1); + do + { + gUnknown_03004DE0[0][TRANSITION_STRUCT.data[3]] = (TRANSITION_STRUCT.data[2] + 1) | 0x7800; + } while (!sub_811D978(TRANSITION_STRUCT.data, 1, 1)); + + TRANSITION_STRUCT.data[4] += 16; + if (TRANSITION_STRUCT.data[4] >= 240) + { + TRANSITION_STRUCT.data[5] = 0; + task->tState++; + } + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Transition_Clockwise_BlackFade_Func3(struct Task* task) +{ + s16 r1, r3; + vu8 var = 0; + + TRANSITION_STRUCT.VBlank_DMA = 0; + + sub_811D8FC(TRANSITION_STRUCT.data, 120, 80, 240, TRANSITION_STRUCT.data[5], 1, 1); + + while (1) + { + r1 = 120, r3 = TRANSITION_STRUCT.data[2] + 1; + if (TRANSITION_STRUCT.data[5] >= 80) + r1 = TRANSITION_STRUCT.data[2], r3 = 240; + gUnknown_03004DE0[0][TRANSITION_STRUCT.data[3]] = (r3) | (r1 << 8); + if (var != 0) + break; + var = sub_811D978(TRANSITION_STRUCT.data, 1, 1); + } + + TRANSITION_STRUCT.data[5] += 8; + if (TRANSITION_STRUCT.data[5] >= 160) + { + TRANSITION_STRUCT.data[4] = 240; + task->tState++; + } + else + { + while (TRANSITION_STRUCT.data[3] < TRANSITION_STRUCT.data[5]) + { + gUnknown_03004DE0[0][++TRANSITION_STRUCT.data[3]] = (r3) | (r1 << 8); + } + } + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Transition_Clockwise_BlackFade_Func4(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + + sub_811D8FC(TRANSITION_STRUCT.data, 120, 80, TRANSITION_STRUCT.data[4], 160, 1, 1); + do + { + gUnknown_03004DE0[0][TRANSITION_STRUCT.data[3]] = (TRANSITION_STRUCT.data[2] << 8) | 0xF0; + } while (!sub_811D978(TRANSITION_STRUCT.data, 1, 1)); + + TRANSITION_STRUCT.data[4] -= 16; + if (TRANSITION_STRUCT.data[4] <= 0) + { + TRANSITION_STRUCT.data[5] = 160; + task->tState++; + } + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Transition_Clockwise_BlackFade_Func5(struct Task* task) +{ + s16 r1, r2, r3; + vu8 var = 0; + + TRANSITION_STRUCT.VBlank_DMA = 0; + + sub_811D8FC(TRANSITION_STRUCT.data, 120, 80, 0, TRANSITION_STRUCT.data[5], 1, 1); + + while (1) + { + r1 = gUnknown_03004DE0[0][TRANSITION_STRUCT.data[3]] & 0xFF, r2 = TRANSITION_STRUCT.data[2]; + if (TRANSITION_STRUCT.data[5] <= 80) + r2 = 120, r1 = TRANSITION_STRUCT.data[2]; + gUnknown_03004DE0[0][TRANSITION_STRUCT.data[3]] = (r1) | (r2 << 8); + r3 = 0; + if (var != 0) + break; + var = sub_811D978(TRANSITION_STRUCT.data, 1, 1); + } + + TRANSITION_STRUCT.data[5] -= 8; + if (TRANSITION_STRUCT.data[5] <= 0) + { + TRANSITION_STRUCT.data[4] = r3; + task->tState++; + } + else + { + while (TRANSITION_STRUCT.data[3] > TRANSITION_STRUCT.data[5]) + { + gUnknown_03004DE0[0][--TRANSITION_STRUCT.data[3]] = (r1) | (r2 << 8); + } + } + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Transition_Clockwise_BlackFade_Func6(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + + sub_811D8FC(TRANSITION_STRUCT.data, 120, 80, TRANSITION_STRUCT.data[4], 0, 1, 1); + do + { + s16 r2, r3; + + r2 = 120, r3 = TRANSITION_STRUCT.data[2]; + if (TRANSITION_STRUCT.data[2] >= 120) + r2 = 0, r3 = 240; + gUnknown_03004DE0[0][TRANSITION_STRUCT.data[3]] = (r3) | (r2 << 8); + + } while (!sub_811D978(TRANSITION_STRUCT.data, 1, 1)); + + TRANSITION_STRUCT.data[4] += 16; + if (TRANSITION_STRUCT.data[2] > 120) + task->tState++; + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Transition_Clockwise_BlackFade_Func7(struct Task* task) +{ + DmaStop(0); + sub_811D6D4(); + DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_Clockwise_BlackFade)); + return FALSE; +} + +static void VBlankCB_Phase2_Transition_Clockwise_BlackFade(void) +{ + DmaStop(0); + VBlankCB_BattleTransition(); + if (TRANSITION_STRUCT.VBlank_DMA != 0) + DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 320); + REG_WININ = TRANSITION_STRUCT.WININ; + REG_WINOUT = TRANSITION_STRUCT.WINOUT; + REG_WIN0V = TRANSITION_STRUCT.WIN0V; + REG_WIN0H = gUnknown_03004DE0[1][0]; + DmaSet(0, gUnknown_03004DE0[1], ®_WIN0H, 0xA2400001); +} + +static void Phase2Task_Transition_Ripple(u8 taskID) +{ + while (sPhase2_Transition_Ripple_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_Ripple_Func1(struct Task* task) +{ + u8 i; + + sub_811D658(); + dp12_8087EA4(); + + for (i = 0; i < 160; i++) + { + gUnknown_03005560[i] = TRANSITION_STRUCT.field_16; + } + + SetVBlankCallback(VBlankCB_Phase2_Transition_Ripple); + SetHBlankCallback(HBlankCB_Phase2_Transition_Ripple); + + REG_IE |= INTR_FLAG_HBLANK; + REG_DISPSTAT |= DISPSTAT_HBLANK_INTR; + + task->tState++; + return TRUE; +} + +static bool8 Phase2_Transition_Ripple_Func2(struct Task* task) +{ + u8 i; + s16 r3; + u16 r4, r8; + + TRANSITION_STRUCT.VBlank_DMA = 0; + + r3 = task->data[2] >> 8; + r4 = task->data[1]; + r8 = 384; + task->data[1] += 0x400; + if (task->data[2] <= 0x1FFF) + task->data[2] += 0x180; + + for (i = 0; i < 160; i++, r4 += r8) + { + // todo: fix the asm + s16 var = r4 >> 8; + asm(""); + gUnknown_03004DE0[0][i] = TRANSITION_STRUCT.field_16 + Sin(var, r3); + asm(""); + } + + if (++task->data[3] == 81) + { + task->data[4]++; + BeginNormalPaletteFade(-1, -2, 0, 0x10, 0); + } + + if (task->data[4] != 0 && !gPaletteFade.active) + DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_Ripple)); + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static void VBlankCB_Phase2_Transition_Ripple(void) +{ + VBlankCB_BattleTransition(); + if (TRANSITION_STRUCT.VBlank_DMA) + DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 320); +} + +static void HBlankCB_Phase2_Transition_Ripple(void) +{ + u16 var = gUnknown_03004DE0[1][REG_VCOUNT]; + REG_BG1VOFS = var; + REG_BG2VOFS = var; + REG_BG3VOFS = var; +} + +static void Phase2Task_Transition_Wave(u8 taskID) +{ + while (sPhase2_Transition_Wave_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_Wave_Func1(struct Task* task) +{ + u8 i; + + sub_811D658(); + dp12_8087EA4(); + + TRANSITION_STRUCT.WININ = 63; + TRANSITION_STRUCT.WINOUT = 0; + TRANSITION_STRUCT.field_6 = 240; + TRANSITION_STRUCT.WIN0V = 160; + + for (i = 0; i < 160; i++) + { + gUnknown_03004DE0[1][i] = 242; + } + + SetVBlankCallback(VBlankCB_Phase2_Transition_Wave); + + task->tState++; + return TRUE; +} + +static bool8 Phase2_Transition_Wave_Func2(struct Task* task) +{ + u8 i, r5; + u16* toStore; + bool8 nextFunc; + + TRANSITION_STRUCT.VBlank_DMA = 0; + toStore = gUnknown_03004DE0[0]; + r5 = task->data[2]; + task->data[2] += 16; + task->data[1] += 8; + + for (i = 0, nextFunc = TRUE; i < 160; i++, r5 += 4, toStore++) + { + s16 value = task->data[1] + Sin(r5, 40); + if (value < 0) + value = 0; + if (value > 240) + value = 240; + *toStore = (value << 8) | (0xF1); + if (value < 240) + nextFunc = FALSE; + } + if (nextFunc) + task->tState++; + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Transition_Wave_Func3(struct Task* task) +{ + DmaStop(0); + sub_811D6D4(); + DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_Wave)); + return FALSE; +} + +static void VBlankCB_Phase2_Transition_Wave(void) +{ + DmaStop(0); + VBlankCB_BattleTransition(); + if (TRANSITION_STRUCT.VBlank_DMA != 0) + DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 320); + REG_WININ = TRANSITION_STRUCT.WININ; + REG_WINOUT = TRANSITION_STRUCT.WINOUT; + REG_WIN0V = TRANSITION_STRUCT.WIN0V; + DmaSet(0, gUnknown_03004DE0[1], ®_WIN0H, 0xA2400001); +} + +#define tMugshotOpponentID data[13] +#define tMugshotPlayerID data[14] +#define tMugshotID data[15] + +static void Phase2Task_Transition_Sydney(u8 taskID) +{ + gTasks[taskID].tMugshotID = MUGSHOT_SYDNEY; + Phase2Task_MugShotTransition(taskID); +} + +static void Phase2Task_Transition_Phoebe(u8 taskID) +{ + gTasks[taskID].tMugshotID = MUGSHOT_PHOEBE; + Phase2Task_MugShotTransition(taskID); +} + +static void Phase2Task_Transition_Glacia(u8 taskID) +{ + gTasks[taskID].tMugshotID = MUGSHOT_GLACIA; + Phase2Task_MugShotTransition(taskID); +} + +static void Phase2Task_Transition_Drake(u8 taskID) +{ + gTasks[taskID].tMugshotID = MUGSHOT_DRAKE; + Phase2Task_MugShotTransition(taskID); +} + +static void Phase2Task_Transition_Steven(u8 taskID) +{ + gTasks[taskID].tMugshotID = MUGSHOT_STEVEN; + Phase2Task_MugShotTransition(taskID); +} + +static void Phase2Task_MugShotTransition(u8 taskID) +{ + while (sPhase2_Mugshot_Transition_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Mugshot_Func1(struct Task* task) +{ + u8 i; + + sub_811D658(); + dp12_8087EA4(); + Mugshots_CreateOpponentPlayerSprites(task); + + task->data[1] = 0; + task->data[2] = 1; + task->data[3] = 239; + TRANSITION_STRUCT.WININ = 63; + TRANSITION_STRUCT.WINOUT = 62; + TRANSITION_STRUCT.WIN0V = 160; + + for (i = 0; i < 160; i++) + { + gUnknown_03004DE0[1][i] = 0xF0F1; + } + + SetVBlankCallback(VBlankCB0_Phase2_Mugshots); + + task->tState++; + return FALSE; +} + +static bool8 Phase2_Mugshot_Func2(struct Task* task) +{ + s16 i, j; + u16 *dst1, *dst2; + const u16* MugshotsMap; + + MugshotsMap = sMugshotsTilemap; + sub_811D6A8(&dst1, &dst2); + CpuSet(sUnknown_083FC348, dst2, 0xF0); + LoadPalette(sOpponentMugshotsPals[task->tMugshotID], 0xF0, 0x20); + LoadPalette(sPlayerMugshotsPals[gSaveBlock2.playerGender], 0xFA, 0xC); + + for (i = 0; i < 20; i++) + { + for (j = 0; j < 32; j++, MugshotsMap++) + { + dst1[i * 32 + j] = *MugshotsMap | 0xF000; + } + } + + REG_IE |= INTR_FLAG_HBLANK; + REG_DISPSTAT |= DISPSTAT_HBLANK_INTR; + SetHBlankCallback(HBlankCB_Phase2_Mugshots); + task->tState++; + return FALSE; +} + +static bool8 Phase2_Mugshot_Func3(struct Task* task) +{ + u8 i, r5; + u16* toStore; + s16 value; + s32 mergedValue; + + TRANSITION_STRUCT.VBlank_DMA = 0; + + toStore = gUnknown_03004DE0[0]; + r5 = task->data[1]; + task->data[1] += 0x10; + + for (i = 0; i < 80; i++, toStore++, r5 += 0x10) + { + value = task->data[2] + Sin(r5, 0x10); + if (value < 0) + value = 1; + if (value > 0xF0) + value = 0xF0; + *toStore = value; + } + for (; i < 160; i++, toStore++, r5 += 0x10) + { + value = task->data[3] - Sin(r5, 0x10); + if (value < 0) + value = 0; + if (value > 0xEF) + value = 0xEF; + *toStore = (value << 8) | (0xF0); + } + + task->data[2] += 8; + task->data[3] -= 8; + if (task->data[2] > 0xF0) + task->data[2] = 0xF0; + if (task->data[3] < 0) + task->data[3] = 0; + mergedValue = *(s32*)(&task->data[2]); + if (mergedValue == 0xF0) + task->tState++; + + TRANSITION_STRUCT.field_18 -= 8; + TRANSITION_STRUCT.field_1A += 8; + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Mugshot_Func4(struct Task* task) +{ + u8 i; + u16* toStore; + + TRANSITION_STRUCT.VBlank_DMA = 0; + + for (i = 0, toStore = gUnknown_03004DE0[0]; i < 160; i++, toStore++) + { + *toStore = 0xF0; + } + + task->tState++; + task->data[1] = 0; + task->data[2] = 0; + task->data[3] = 0; + TRANSITION_STRUCT.field_18 -= 8; + TRANSITION_STRUCT.field_1A += 8; + + sub_811CA10(task->tMugshotOpponentID, 0); + sub_811CA10(task->tMugshotPlayerID, 1); + sub_811CA28(task->tMugshotOpponentID); + + PlaySE(SE_BT_START); + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Mugshot_Func5(struct Task* task) +{ + TRANSITION_STRUCT.field_18 -= 8; + TRANSITION_STRUCT.field_1A += 8; + if (sub_811CA44(task->tMugshotOpponentID)) + { + task->tState++; + sub_811CA28(task->tMugshotPlayerID); + } + return FALSE; +} + +static bool8 Phase2_Mugshot_Func6(struct Task* task) +{ + TRANSITION_STRUCT.field_18 -= 8; + TRANSITION_STRUCT.field_1A += 8; + if (sub_811CA44(task->tMugshotPlayerID)) + { + TRANSITION_STRUCT.VBlank_DMA = 0; + SetVBlankCallback(NULL); + DmaStop(0); + memset(gUnknown_03004DE0[0], 0, 0x140); + memset(gUnknown_03004DE0[1], 0, 0x140); + REG_WIN0H = 0xF0; + REG_BLDY = 0; + task->tState++; + task->data[3] = 0; + task->data[4] = 0; + TRANSITION_STRUCT.BLDCNT = 0xBF; + SetVBlankCallback(VBlankCB1_Phase2_Mugshots); + } + return FALSE; +} + +static bool8 Phase2_Mugshot_Func7(struct Task* task) +{ + bool32 r6; + + TRANSITION_STRUCT.VBlank_DMA = 0; + r6 = TRUE; + TRANSITION_STRUCT.field_18 -= 8; + TRANSITION_STRUCT.field_1A += 8; + + if (task->data[4] < 0x50) + task->data[4] += 2; + if (task->data[4] > 0x50) + task->data[4] = 0x50; + + if (++task->data[3] & 1) + { + s16 i; + for (i = 0, r6 = FALSE; i <= task->data[4]; i++) + { + s16 index1 = 0x50 - i; + s16 index2 = 0x50 + i; + if (gUnknown_03004DE0[0][index1] <= 15) + { + r6 = TRUE; + gUnknown_03004DE0[0][index1]++; + } + if (gUnknown_03004DE0[0][index2] <= 15) + { + r6 = TRUE; + gUnknown_03004DE0[0][index2]++; + } + } + } + + if (task->data[4] == 0x50 && !r6) + task->tState++; + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Mugshot_Func8(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + BlendPalettes(-1, 0x10, 0x7FFF); + TRANSITION_STRUCT.BLDCNT = 0xFF; + task->data[3] = 0; + + task->tState++; + return TRUE; +} + +static bool8 Phase2_Mugshot_Func9(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + + task->data[3]++; + memset(gUnknown_03004DE0[0], task->data[3], 0x140); + if (task->data[3] > 15) + task->tState++; + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Mugshot_Func10(struct Task* task) +{ + DmaStop(0); + sub_811D6D4(); + DestroyTask(FindTaskIdByFunc(task->func)); + return FALSE; +} + +static void VBlankCB0_Phase2_Mugshots(void) +{ + DmaStop(0); + VBlankCB_BattleTransition(); + if (TRANSITION_STRUCT.VBlank_DMA != 0) + DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 320); + REG_BG0VOFS = TRANSITION_STRUCT.field_1C; + REG_WININ = TRANSITION_STRUCT.WININ; + REG_WINOUT = TRANSITION_STRUCT.WINOUT; + REG_WIN0V = TRANSITION_STRUCT.WIN0V; + DmaSet(0, gUnknown_03004DE0[1], ®_WIN0H, 0xA2400001); +} + +static void VBlankCB1_Phase2_Mugshots(void) +{ + DmaStop(0); + VBlankCB_BattleTransition(); + if (TRANSITION_STRUCT.VBlank_DMA != 0) + DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 320); + REG_BLDCNT = TRANSITION_STRUCT.BLDCNT; + DmaSet(0, gUnknown_03004DE0[1], ®_BLDY, 0xA2400001); +} + +static void HBlankCB_Phase2_Mugshots(void) +{ + if (REG_VCOUNT < 80) + REG_BG0HOFS = TRANSITION_STRUCT.field_18; + else + REG_BG0HOFS = TRANSITION_STRUCT.field_1A; +} + +static void Mugshots_CreateOpponentPlayerSprites(struct Task* task) +{ + struct Sprite *opponentSprite, *playerSprite; + + s16 mugshotID = task->tMugshotID; + task->tMugshotOpponentID = CreateTrainerSprite(sMugshotsTrainerPicIDsTable[mugshotID], + sMugshotsOpponentCoords[mugshotID][0] - 32, + sMugshotsOpponentCoords[mugshotID][1] + 42, + 0, &ewram[0xC03C]); + task->tMugshotPlayerID = CreateTrainerSprite(gSaveBlock2.playerGender, 272, 106, 0, &ewram[0xC03C]); + + opponentSprite = &gSprites[task->tMugshotOpponentID]; + playerSprite = &gSprites[task->tMugshotPlayerID]; + + opponentSprite->callback = sub_811C90C; + playerSprite->callback = sub_811C90C; + + opponentSprite->oam.affineMode = 3; + playerSprite->oam.affineMode = 3; + + opponentSprite->oam.matrixNum = AllocOamMatrix(); + playerSprite->oam.matrixNum = AllocOamMatrix(); + + opponentSprite->oam.shape = 1; + playerSprite->oam.shape = 1; + + opponentSprite->oam.size = 3; + playerSprite->oam.size = 3; + + CalcCenterToCornerVec(opponentSprite, 1, 3, 3); + CalcCenterToCornerVec(playerSprite, 1, 3, 3); + + SetOamMatrixRotationScaling(opponentSprite->oam.matrixNum, sMugshotsOpponentRotationScales[mugshotID][0], sMugshotsOpponentRotationScales[mugshotID][1], 0); + SetOamMatrixRotationScaling(playerSprite->oam.matrixNum, -512, 0x200, 0); +} + +static void sub_811C90C(struct Sprite* sprite) +{ + while (sUnknown_083FD880[sprite->data0](sprite)); +} + +static bool8 sub_811C934(struct Sprite* sprite) +{ + return FALSE; +} + +static bool8 sub_811C938(struct Sprite* sprite) +{ + s16 arr0[2]; + s16 arr1[2]; + + memcpy(arr0, sUnknown_083FD89C, sizeof(sUnknown_083FD89C)); + memcpy(arr1, sUnknown_083FD8A0, sizeof(sUnknown_083FD8A0)); + + sprite->data0++; + sprite->data1 = arr0[sprite->data7]; + sprite->data2 = arr1[sprite->data7]; + return TRUE; +} + +static bool8 sub_811C984(struct Sprite* sprite) +{ + sprite->pos1.x += sprite->data1; + if (sprite->data7 && sprite->pos1.x < 133) + sprite->data0++; + else if (!sprite->data7 && sprite->pos1.x > 103) + sprite->data0++; + return FALSE; +} + +static bool8 sub_811C9B8(struct Sprite* sprite) +{ + sprite->data1 += sprite->data2; + sprite->pos1.x += sprite->data1; + if (sprite->data1 == 0) + { + sprite->data0++; + sprite->data2 = -sprite->data2; + sprite->data6 = 1; + } + return FALSE; +} + +static bool8 sub_811C9E4(struct Sprite* sprite) +{ + sprite->data1 += sprite->data2; + sprite->pos1.x += sprite->data1; + if (sprite->pos1.x < -31 || sprite->pos1.x > 271) + sprite->data0++; + return FALSE; +} + +static void sub_811CA10(s16 spriteID, s16 value) +{ + gSprites[spriteID].data7 = value; +} + +static void sub_811CA28(s16 spriteID) +{ + gSprites[spriteID].data0++; +} + +static s16 sub_811CA44(s16 spriteID) +{ + return gSprites[spriteID].data6; +} + +#undef tMugshotOpponentID +#undef tMugshotPlayerID +#undef tMugshotID + +static void Phase2Task_Transition_Slice(u8 taskID) +{ + while (sPhase2_Transition_Slice_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_Slice_Func1(struct Task* task) +{ + u16 i; + + sub_811D658(); + dp12_8087EA4(); + + task->data[2] = 256; + task->data[3] = 1; + TRANSITION_STRUCT.WININ = 63; + TRANSITION_STRUCT.WINOUT = 0; + TRANSITION_STRUCT.WIN0V = 160; + + for (i = 0; i < 160; i++) + { + gUnknown_03004DE0[1][i] = TRANSITION_STRUCT.field_14; + gUnknown_03004DE0[1][160 + i] = 0xF0; + } + + REG_IE |= INTR_FLAG_HBLANK; + REG_DISPSTAT |= DISPSTAT_HBLANK_INTR; + + SetVBlankCallback(VBlankCB_Phase2_Transition_Slice); + SetHBlankCallback(HBlankCB_Phase2_Transition_Slice); + + task->tState++; + return TRUE; +} + +static bool8 Phase2_Transition_Slice_Func2(struct Task* task) +{ + u16 i; + + TRANSITION_STRUCT.VBlank_DMA = 0; + + task->data[1] += (task->data[2] >> 8); + if (task->data[1] > 0xF0) + task->data[1] = 0xF0; + if (task->data[2] <= 0xFFF) + task->data[2] += task->data[3]; + if (task->data[3] < 128) + task->data[3] <<= 1; // multiplying by two + + for (i = 0; i < 160; i++) + { + u16* storeLoc1 = &gUnknown_03004DE0[0][i]; + u16* storeLoc2 = &gUnknown_03004DE0[0][i + 160]; + if (1 & i) + { + *storeLoc1 = TRANSITION_STRUCT.field_14 + task->data[1]; + *storeLoc2 = 0xF0 - task->data[1]; + } + else + { + *storeLoc1 = TRANSITION_STRUCT.field_14 - task->data[1]; + *storeLoc2 = (task->data[1] << 8) | (0xF1); + } + } + + if (task->data[1] > 0xEF) + task->tState++; + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Transition_Slice_Func3(struct Task* task) +{ + DmaStop(0); + sub_811D6D4(); + DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_Slice)); + return FALSE; +} + +static void VBlankCB_Phase2_Transition_Slice(void) +{ + DmaStop(0); + VBlankCB_BattleTransition(); + REG_WININ = TRANSITION_STRUCT.WININ; + REG_WINOUT = TRANSITION_STRUCT.WINOUT; + REG_WIN0V = TRANSITION_STRUCT.WIN0V; + if (TRANSITION_STRUCT.VBlank_DMA) + DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 640); + DmaSet(0, &gUnknown_03004DE0[1][160], ®_WIN0H, 0xA2400001); +} + +static void HBlankCB_Phase2_Transition_Slice(void) +{ + u16 var = gUnknown_03004DE0[1][REG_VCOUNT]; + REG_BG1HOFS = var; + REG_BG2HOFS = var; + REG_BG3HOFS = var; +} + +static void Phase2Task_Transition_WhiteFade(u8 taskID) +{ + while (sPhase2_Transition_WhiteFade_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_WhiteFade_Func1(struct Task* task) +{ + u16 i; + + sub_811D658(); + dp12_8087EA4(); + + TRANSITION_STRUCT.BLDCNT = 0xBF; + TRANSITION_STRUCT.BLDY = 0; + TRANSITION_STRUCT.WININ = 0x1E; + TRANSITION_STRUCT.WINOUT = 0x3F; + TRANSITION_STRUCT.WIN0V = 0xA0; + + for (i = 0; i < 160; i++) + { + gUnknown_03004DE0[1][i] = 0; + gUnknown_03004DE0[1][i + 160] = 0xF0; + } + + REG_IE |= INTR_FLAG_HBLANK; + REG_DISPSTAT |= DISPSTAT_HBLANK_INTR; + + SetHBlankCallback(HBlankCB_Phase2_Transition_WhiteFade); + SetVBlankCallback(VBlankCB0_Phase2_Transition_WhiteFade); + + task->tState++; + return FALSE; +} + +static bool8 Phase2_Transition_WhiteFade_Func2(struct Task* task) +{ + s16 i, posY; + s16 arr1[8]; + struct Sprite* sprite; + + memcpy(arr1, sUnknown_083FD8C4, sizeof(sUnknown_083FD8C4)); + for (i = 0, posY = 0; i < 8; i++, posY += 0x14) + { + sprite = &gSprites[CreateInvisibleSprite(sub_811CFD0)]; + sprite->pos1.x = 0xF0; + sprite->pos1.y = posY; + sprite->data5 = arr1[i]; + } + sprite->data6++; + + task->tState++; + return FALSE; +} + +static bool8 Phase2_Transition_WhiteFade_Func3(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + if (TRANSITION_STRUCT.field_20 > 7) + { + BlendPalettes(-1, 0x10, 0x7FFF); + task->tState++; + } + return FALSE; +} + +static bool8 Phase2_Transition_WhiteFade_Func4(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + + DmaStop(0); + SetVBlankCallback(0); + SetHBlankCallback(0); + + TRANSITION_STRUCT.field_6 = 0xF0; + TRANSITION_STRUCT.BLDY = 0; + TRANSITION_STRUCT.BLDCNT = 0xFF; + TRANSITION_STRUCT.WININ = 0x3F; + + SetVBlankCallback(VBlankCB1_Phase2_Transition_WhiteFade); + + task->tState++; + return FALSE; +} + +static bool8 Phase2_Transition_WhiteFade_Func5(struct Task* task) +{ + if (++TRANSITION_STRUCT.BLDY > 16) + { + sub_811D6D4(); + DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_WhiteFade)); + } + return FALSE; +} + +static void VBlankCB0_Phase2_Transition_WhiteFade(void) +{ + DmaStop(0); + VBlankCB_BattleTransition(); + REG_BLDCNT = TRANSITION_STRUCT.BLDCNT; + REG_WININ = TRANSITION_STRUCT.WININ; + REG_WINOUT = TRANSITION_STRUCT.WINOUT; + REG_WIN0V = TRANSITION_STRUCT.field_6; + if (TRANSITION_STRUCT.VBlank_DMA) + DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 640); + DmaSet(0, &gUnknown_03004DE0[1][160], ®_WIN0H, 0xA2400001); +} + +static void VBlankCB1_Phase2_Transition_WhiteFade(void) +{ + VBlankCB_BattleTransition(); + REG_BLDY = TRANSITION_STRUCT.BLDY; + REG_BLDCNT = TRANSITION_STRUCT.BLDCNT; + REG_WININ = TRANSITION_STRUCT.WININ; + REG_WINOUT = TRANSITION_STRUCT.WINOUT; + REG_WIN0H = TRANSITION_STRUCT.field_6; + REG_WIN0V = TRANSITION_STRUCT.WIN0V; +} + +static void HBlankCB_Phase2_Transition_WhiteFade(void) +{ + REG_BLDY = gUnknown_03004DE0[1][REG_VCOUNT]; +} + +static void sub_811CFD0(struct Sprite* sprite) +{ + if (sprite->data5) + { + sprite->data5--; + if (sprite->data6) + TRANSITION_STRUCT.VBlank_DMA = 1; + } + else + { + u16 i; + u16* ptr1 = &gUnknown_03004DE0[0][sprite->pos1.y]; + u16* ptr2 = &gUnknown_03004DE0[0][sprite->pos1.y + 160]; + for (i = 0; i < 20; i++) + { + ptr1[i] = sprite->data0 >> 8; + ptr2[i] = (u8)(sprite->pos1.x); + } + if (sprite->pos1.x == 0 && sprite->data0 == 0x1000) + sprite->data1 = 1; + + sprite->pos1.x -= 16; + sprite->data0 += 0x80; + + if (sprite->pos1.x < 0) + sprite->pos1.x = 0; + if (sprite->data0 > 0x1000) + sprite->data0 = 0x1000; + + if (sprite->data6) + TRANSITION_STRUCT.VBlank_DMA = 1; + + if (sprite->data1) + { + if (sprite->data6 == 0 || (TRANSITION_STRUCT.field_20 > 6 && sprite->data2++ > 7)) + { + TRANSITION_STRUCT.field_20++; + DestroySprite(sprite); + } + } + } +} + +static void Phase2Task_Transition_GridSquares(u8 taskID) +{ + while (sPhase2_Transition_GridSquares_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_GridSquares_Func1(struct Task* task) +{ + u16 *dst1, *dst2; + + sub_811D6A8(&dst1, &dst2); + CpuSet(sShrinkingBoxTileset, dst2, 0x10); + CpuFill16(0xF000, dst1, 0x800); + LoadPalette(gFieldEffectObjectPalette10, 0xF0, 0x20); + + task->tState++; + return FALSE; +} + +static bool8 Phase2_Transition_GridSquares_Func2(struct Task* task) +{ + u16* dst1; + + if (task->data[1] == 0) + { + sub_811D690(&dst1); + task->data[1] = 3; + task->data[2]++; + CpuSet(sShrinkingBoxTileset + (task->data[2] * 8), dst1, 0x10); + if (task->data[2] > 0xD) + { + task->tState++; + task->data[1] = 16; + } + } + + task->data[1]--; + return FALSE; +} + +static bool8 Phase2_Transition_GridSquares_Func3(struct Task* task) +{ + if (--task->data[1] == 0) + { + sub_811D6D4(); + DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_GridSquares)); + } + return FALSE; +} + +static void Phase2Task_Transition_Shards(u8 taskID) +{ + while (sPhase2_Transition_Shards_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_Shards_Func1(struct Task* task) +{ + u16 i; + + sub_811D658(); + dp12_8087EA4(); + + TRANSITION_STRUCT.WININ = 0x3F; + TRANSITION_STRUCT.WINOUT = 0; + TRANSITION_STRUCT.WIN0V = 0xA0; + + for (i = 0; i < 160; i++) + { + gUnknown_03004DE0[0][i] = 0xF0; + } + + CpuSet(gUnknown_03004DE0[0], gUnknown_03004DE0[1], 0xA0); + SetVBlankCallback(VBlankCB_Phase2_Transition_Shards); + + task->tState++; + return TRUE; +} + +static bool8 Phase2_Transition_Shards_Func2(struct Task* task) +{ + sub_811D8FC(TRANSITION_STRUCT.data, + sUnknown_083FD8F4[task->data[1]][0], + sUnknown_083FD8F4[task->data[1]][1], + sUnknown_083FD8F4[task->data[1]][2], + sUnknown_083FD8F4[task->data[1]][3], + 1, 1); + task->data[2] = sUnknown_083FD8F4[task->data[1]][4]; + task->tState++; + return TRUE; +} + +static bool8 Phase2_Transition_Shards_Func3(struct Task* task) +{ + s16 i; + bool8 nextFunc; + + TRANSITION_STRUCT.VBlank_DMA = 0; + + for (i = 0, nextFunc = FALSE; i < 16; i++) + { + s16 r3 = gUnknown_03004DE0[0][TRANSITION_STRUCT.data[3]] >> 8; + s16 r4 = gUnknown_03004DE0[0][TRANSITION_STRUCT.data[3]] & 0xFF; + if (task->data[2] == 0) + { + if (r3 < TRANSITION_STRUCT.data[2]) + r3 = TRANSITION_STRUCT.data[2]; + if (r3 > r4) + r3 = r4; + } + else + { + if (r4 > TRANSITION_STRUCT.data[2]) + r4 = TRANSITION_STRUCT.data[2]; + if (r4 <= r3) + r4 = r3; + } + gUnknown_03004DE0[0][TRANSITION_STRUCT.data[3]] = (r4) | (r3 << 8); + if (nextFunc) + { + task->tState++; + break; + } + else + nextFunc = sub_811D978(TRANSITION_STRUCT.data, 1, 1); + } + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Transition_Shards_Func4(struct Task* task) +{ + if (++task->data[1] < 7) + { + task->tState++; + task->data[3] = sUnknown_083FD93A[task->data[1] - 1]; + return TRUE; + } + else + { + DmaStop(0); + sub_811D6D4(); + DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_Shards)); + return FALSE; + } +} + +static bool8 Phase2_Transition_Shards_Func5(struct Task* task) +{ + if (--task->data[3] == 0) + { + task->tState = 1; + return TRUE; + } + else + return FALSE; +} + +static void VBlankCB_Phase2_Transition_Shards(void) +{ + DmaStop(0); + VBlankCB_BattleTransition(); + if (TRANSITION_STRUCT.VBlank_DMA) + DmaCopy16(3, gUnknown_03004DE0[0], gUnknown_03004DE0[1], 320); + REG_WININ = TRANSITION_STRUCT.WININ; + REG_WINOUT = TRANSITION_STRUCT.WINOUT; + REG_WIN0V = TRANSITION_STRUCT.WIN0V; + REG_WIN0H = gUnknown_03004DE0[1][0]; + DmaSet(0, gUnknown_03004DE0[1], ®_WIN0H, 0xA2400001); +} + +static void CreatePhase1Task(s16 a0, s16 a1, s16 a2, s16 a3, s16 a4) +{ + u8 taskID = CreateTask(Phase1_Task_RunFuncs, 3); + gTasks[taskID].data[1] = a0; + gTasks[taskID].data[2] = a1; + gTasks[taskID].data[3] = a2; + gTasks[taskID].data[4] = a3; + gTasks[taskID].data[5] = a4; + gTasks[taskID].data[6] = a0; +} + +static bool8 sub_811D52C(void) +{ + if (FindTaskIdByFunc(Phase1_Task_RunFuncs) == 0xFF) + return TRUE; + else + return FALSE; +} + +static void Phase1_Task_RunFuncs(u8 taskID) +{ + while (sPhase1_TransitionAll_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase1_TransitionAll_Func1(struct Task* task) +{ + if (task->data[6] == 0 || --task->data[6] == 0) + { + task->data[6] = task->data[1]; + task->data[7] += task->data[4]; + if (task->data[7] > 16) + task->data[7] = 16; + BlendPalettes(-1, task->data[7], 0x2D6B); + } + if (task->data[7] > 15) + { + task->tState++; + task->data[6] = task->data[2]; + } + return FALSE; +} + +static bool8 Phase1_TransitionAll_Func2(struct Task* task) +{ + if (task->data[6] == 0 || --task->data[6] == 0) + { + task->data[6] = task->data[2]; + task->data[7] -= task->data[5]; + if (task->data[7] < 0) + task->data[7] = 0; + BlendPalettes(-1, task->data[7], 0x2D6B); + } + if (task->data[7] == 0) + { + if (--task->data[3] == 0) + DestroyTask(FindTaskIdByFunc(Phase1_Task_RunFuncs)); + else + { + task->data[6] = task->data[1]; + task->tState = 0; + } + } + return FALSE; +} + +static void sub_811D658(void) +{ + struct TransitionData* const* dummy = &sTransitionStructPtr; + memset(*dummy, 0, sizeof(struct TransitionData)); + sub_8057B14(&TRANSITION_STRUCT.field_14, &TRANSITION_STRUCT.field_16); +} + +static void VBlankCB_BattleTransition(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +static void sub_811D690(u16** a0) +{ + u16 reg, *vram; + + reg = REG_BG0CNT >> 2; + reg <<= 0xE; + vram = (u16*)(VRAM + reg); + + *a0 = vram; +} + +static void sub_811D6A8(u16** a0, u16** a1) +{ + u16 reg0, reg1, *vram0, *vram1; + + reg0 = REG_BG0CNT >> 8; + reg1 = REG_BG0CNT >> 2; + + reg0 <<= 0xB; + reg1 <<= 0xE; + + vram0 = (u16*)(VRAM + reg0); + *a0 = vram0; + + vram1 = (u16*)(VRAM + reg1); + *a1 = vram1; +} + +static void sub_811D6D4(void) +{ + BlendPalettes(-1, 0x10, 0); +} + +static void sub_811D6E8(s16* array, s16 sinAdd, s16 index, s16 indexIncrementer, s16 amplitude, s16 arrSize) +{ + u8 i; + for (i = 0; arrSize > 0; arrSize--, i++, index += indexIncrementer) + { + array[i] = sinAdd + Sin(0xFF & index, amplitude); + } +} + +static void sub_811D764(u16* array, s16 a1, s16 a2, s16 a3) +{ + s16 i; + + memset(array, 0xA, 160 * sizeof(s16)); + for (i = 0; i < 64; i++) + { + s16 sinResult, cosResult; + s16 toStoreOrr, r2, r3, toStore, r7, r8; + + sinResult = Sin(i, a3); + cosResult = Cos(i, a3); + + toStoreOrr = a1 - sinResult; + toStore = a1 + sinResult; + r7 = a2 - cosResult; + r8 = a2 + cosResult; + + if (toStoreOrr < 0) + toStoreOrr = 0; + if (toStore > 0xF0) + toStore = 0xF0; + if (r7 < 0) + r7 = 0; + if (r8 > 0x9F) + r8 = 0x9F; + + toStore |= (toStoreOrr << 8); + array[r7] = toStore; + array[r8] = toStore; + + cosResult = Cos(i + 1, a3); + r3 = a2 - cosResult; + r2 = a2 + cosResult; + + if (r3 < 0) + r3 = 0; + if (r2 > 0x9F) + r2 = 0x9F; + + while (r7 > r3) + array[--r7] = toStore; + while (r7 < r3) + array[++r7] = toStore; + + while (r8 > r2) + array[--r8] = toStore; + while (r8 < r2) + array[++r8] = toStore; + } +} + +static void sub_811D8FC(s16* data, s16 a1, s16 a2, s16 a3, s16 a4, s16 a5, s16 a6) +{ + data[0] = a1; + data[1] = a2; + data[2] = a1; + data[3] = a2; + data[4] = a3; + data[5] = a4; + data[6] = a5; + data[7] = a6; + data[8] = a3 - a1; + if (data[8] < 0) + { + data[8] = -data[8]; + data[6] = -a5; + } + data[9] = a4 - a2; + if (data[9] < 0) + { + data[9] = -data[9]; + data[7] = -a6; + } + data[10] = 0; +} + +static bool8 sub_811D978(s16* data, bool8 a1, bool8 a2) +{ + u8 var; + if (data[8] > data[9]) + { + data[2] += data[6]; + data[10] += data[9]; + if (data[10] > data[8]) + { + data[3] += data[7]; + data[10] -= data[8]; + } + } + else + { + data[3] += data[7]; + data[10] += data[8]; + if (data[10] > data[9]) + { + data[2] += data[6]; + data[10] -= data[9]; + } + } + var = 0; + if ((data[6] > 0 && data[2] >= data[4]) || (data[6] < 0 && data[2] <= data[4])) + { + var++; + if (a1) + data[2] = data[4]; + } + if ((data[7] > 0 && data[3] >= data[5]) || (data[7] < 0 && data[3] <= data[5])) + { + var++; + if (a2) + data[3] = data[5]; + } + if (var == 2) + return TRUE; + else + return FALSE; +} diff --git a/src/battle/reshow_battle_screen.c b/src/battle/reshow_battle_screen.c new file mode 100644 index 000000000..343c8f183 --- /dev/null +++ b/src/battle/reshow_battle_screen.c @@ -0,0 +1,332 @@ +#include "global.h" +#include "battle.h" +#include "battle_anim.h" +#include "palette.h" +#include "main.h" +#include "unknown_task.h" +#include "text.h" +#include "rom_8077ABC.h" +#include "data2.h" + +extern struct SpriteTemplate gUnknown_02024E8C; +extern struct Window gUnknown_03004210; +extern u16 gUnknown_03004280; +extern u16 gUnknown_03004288; +extern u16 gUnknown_030042A4; +extern u16 gUnknown_030042C0; +extern u16 gUnknown_030041B0; +extern u16 gUnknown_030041B4; +extern u16 gUnknown_030041B8; +extern u16 gUnknown_030042A0; +extern u8 gReservedSpritePaletteCount; +extern u8 gActionSelectionCursor[4]; +extern u8 gBankInMenu; +extern u16 gBattlePartyID[4]; +extern u8 gNoOfAllBanks; +extern u16 gBattleTypeFlags; +extern u8 gObjectBankIDs[4]; +extern u8 gBattleMonForms[4]; +extern u8 gHealthboxIDs[4]; + +bool8 sub_800E414(u8 a0); +bool8 sub_8031C30(u8 a0); +void sub_8031EE8(void); +void sub_80327CC(void); +void sub_8032984(u8 a, u16 b); +void sub_800FCD4(void); +void BattleLoadOpponentMonSprite(struct Pokemon *, u8 bank); +void BattleLoadPlayerMonSprite(struct Pokemon *, u8 bank); +void BattleLoadSubstituteSprite(u8 bank, u8 b); +void LoadPlayerTrainerBankSprite(u16 a0, u8 bank); +u8 sub_8077F7C(u8 bank); +u8 sub_8077F68(u8 bank); +void nullsub_11(u8 healthboxID, u8 a1); +void sub_8043DB0(u8 bank); +u8 battle_make_oam_normal_battle(u8 bank); +u8 battle_make_oam_safari_battle(void); +void sub_8045A5C(u8 healthboxID, struct Pokemon*, u8); +void sub_8043F44(u8 bank); +void sub_8043DFC(u8 healthboxID); + +// this file's functions +static void CB2_ReshowBattleScreenAfterMenu(void); +static bool8 LoadAppropiateBankSprite(u8 bank); +static void sub_807B184(u8 bank); +static void sub_807B508(u8 bank); +static void sub_807B06C(void); + +#define gReshowState ewram[0x1FFFF] +#define gHelperState ewram[0x1FFFE] + +void nullsub_14(void) +{ + +} + +void ReshowBattleScreenAfterMenu(void) +{ + gPaletteFade.bufferTransferDisabled = 1; + SetHBlankCallback(0); + SetVBlankCallback(0); + REG_MOSAIC = 0; + gReshowState = 0; + gHelperState = 0; + SetMainCallback2(CB2_ReshowBattleScreenAfterMenu); +} + +static void CB2_ReshowBattleScreenAfterMenu(void) +{ + switch (gReshowState) + { + case 0: + dp12_8087EA4(); + SetUpWindowConfig(&gWindowConfig_81E6C58); + ResetPaletteFade(); + InitWindowFromConfig(&gUnknown_03004210, &gWindowConfig_81E6C58); + gUnknown_030042A4 = 0; + gUnknown_030042A0 = 0; + gUnknown_030042C0 = 0; + gUnknown_030041B4 = 0; + gUnknown_03004288 = 0; + gUnknown_03004280 = 0; + gUnknown_030041B0 = 0; + gUnknown_030041B8 = 0; + break; + case 1: + { + const u32 zero = 0; + CpuFastSet(&zero, (void*) VRAM, 0x1006000); + } + break; + case 2: + if (!sub_800E414(gHelperState)) + { + gHelperState++; + gReshowState--; + } + else + gHelperState = 0; + break; + case 3: + ResetSpriteData(); + break; + case 4: + FreeAllSpritePalettes(); + gReservedSpritePaletteCount = 4; + break; + case 5: + sub_8031EE8(); + break; + case 6: + if (sub_8031C30(gHelperState)) + gHelperState = 0; + else + { + gHelperState++; + gReshowState--; + } + break; + case 7: + if (!LoadAppropiateBankSprite(0)) + gReshowState--; + break; + case 8: + if (!LoadAppropiateBankSprite(1)) + gReshowState--; + break; + case 9: + if (!LoadAppropiateBankSprite(2)) + gReshowState--; + break; + case 10: + if (!LoadAppropiateBankSprite(3)) + gReshowState--; + break; + case 11: + sub_807B184(0); + break; + case 12: + sub_807B184(1); + break; + case 13: + sub_807B184(2); + break; + case 14: + sub_807B184(3); + break; + case 15: + sub_807B508(0); + break; + case 16: + sub_807B508(1); + break; + case 17: + sub_807B508(2); + break; + case 18: + sub_807B508(3); + break; + case 19: + { + u8 opponentBank; + u16 species; + + sub_80327CC(); + + opponentBank = GetBankByPlayerAI(1); + species = GetMonData(&gEnemyParty[gBattlePartyID[opponentBank]], MON_DATA_SPECIES); + sub_8032984(opponentBank, species); + + if (IsDoubleBattle()) + { + opponentBank = GetBankByPlayerAI(3); + species = GetMonData(&gEnemyParty[gBattlePartyID[opponentBank]], MON_DATA_SPECIES); + sub_8032984(opponentBank, species); + } + sub_802E3E4(gActionSelectionCursor[gBankInMenu], 0); + } + break; + default: + SetHBlankCallback(sub_800FCD4); + SetVBlankCallback(sub_800FCFC); + sub_807B06C(); + BeginHardwarePaletteFade(0xFF, 0, 0x10, 0, 1); + gPaletteFade.bufferTransferDisabled = 0; + SetMainCallback2(sub_800F808); + break; + } + gReshowState++; +} + +static void sub_807B06C(void) +{ + struct BGCntrlBitfield *regBgcnt1, *regBgcnt2; + + sub_800D6D4(); + + regBgcnt1 = (void*)(®_BG1CNT); + regBgcnt1->charBaseBlock = 0; + + regBgcnt2 = (void*)(®_BG2CNT); + regBgcnt2->charBaseBlock = 0; +} + +static bool8 LoadAppropiateBankSprite(u8 bank) +{ + if (bank < gNoOfAllBanks) + { + if (GetBankSide(bank)) + { + if (!ewram17800[bank].substituteSprite) + BattleLoadOpponentMonSprite(&gEnemyParty[gBattlePartyID[bank]], bank); + else + BattleLoadSubstituteSprite(bank, 0); + } + else if (gBattleTypeFlags & BATTLE_TYPE_SAFARI && bank == 0) + LoadPlayerTrainerBankSprite(gSaveBlock2.playerGender, 0); + else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL && bank == 0) + LoadPlayerTrainerBankSprite(2, 0); + else if (!ewram17800[bank].substituteSprite) + BattleLoadPlayerMonSprite(&gPlayerParty[gBattlePartyID[bank]], bank); + else + BattleLoadSubstituteSprite(bank, 0); + + gHelperState = 0; + } + return 1; +} + +static void sub_807B184(u8 bank) +{ + if (bank < gNoOfAllBanks) + { + u8 posY; + + if (ewram17800[bank].substituteSprite) + posY = sub_8077F7C(bank); + else + posY = sub_8077F68(bank); + if (GetBankSide(bank)) + { + if (GetMonData(&gEnemyParty[gBattlePartyID[bank]], MON_DATA_HP) == 0) + return; + GetMonSpriteTemplate_803C56C(GetMonData(&gEnemyParty[gBattlePartyID[bank]], MON_DATA_SPECIES), GetBankIdentity(bank)); + gObjectBankIDs[bank] = CreateSprite(&gUnknown_02024E8C, sub_8077ABC(bank, 2), posY, sub_8079E90(bank)); + gSprites[gObjectBankIDs[bank]].oam.paletteNum = bank; + gSprites[gObjectBankIDs[bank]].callback = SpriteCallbackDummy; + gSprites[gObjectBankIDs[bank]].data0 = bank; + gSprites[gObjectBankIDs[bank]].data2 = GetMonData(&gEnemyParty[gBattlePartyID[bank]], MON_DATA_SPECIES); + StartSpriteAnim(&gSprites[gObjectBankIDs[bank]], gBattleMonForms[bank]); + } + else if (gBattleTypeFlags & BATTLE_TYPE_SAFARI && bank == 0) + { + GetMonSpriteTemplate_803C5A0(gSaveBlock2.playerGender, GetBankIdentity(0)); + gObjectBankIDs[bank] = CreateSprite(&gUnknown_02024E8C, 0x50, + (8 - gTrainerBackPicCoords[gSaveBlock2.playerGender].coords) * 4 + 80, + sub_8079E90(0)); + gSprites[gObjectBankIDs[bank]].oam.paletteNum = bank; + gSprites[gObjectBankIDs[bank]].callback = SpriteCallbackDummy; + gSprites[gObjectBankIDs[bank]].data0 = bank; + } + else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL && bank == 0) + { + GetMonSpriteTemplate_803C5A0(2, GetBankIdentity(0)); + gObjectBankIDs[bank] = CreateSprite(&gUnknown_02024E8C, 0x50, + (8 - gTrainerBackPicCoords[2].coords) * 4 + 80, + sub_8079E90(0)); + gSprites[gObjectBankIDs[bank]].oam.paletteNum = bank; + gSprites[gObjectBankIDs[bank]].callback = SpriteCallbackDummy; + gSprites[gObjectBankIDs[bank]].data0 = bank; + } + else + { + if (GetMonData(&gPlayerParty[gBattlePartyID[bank]], MON_DATA_HP) == 0) + return; + GetMonSpriteTemplate_803C56C(GetMonData(&gPlayerParty[gBattlePartyID[bank]], MON_DATA_SPECIES), GetBankIdentity(bank)); + gObjectBankIDs[bank] = CreateSprite(&gUnknown_02024E8C, sub_8077ABC(bank, 2), posY, sub_8079E90(bank)); + gSprites[gObjectBankIDs[bank]].oam.paletteNum = bank; + gSprites[gObjectBankIDs[bank]].callback = SpriteCallbackDummy; + gSprites[gObjectBankIDs[bank]].data0 = bank; + gSprites[gObjectBankIDs[bank]].data2 = GetMonData(&gPlayerParty[gBattlePartyID[bank]], MON_DATA_SPECIES); + StartSpriteAnim(&gSprites[gObjectBankIDs[bank]], gBattleMonForms[bank]); + } + gSprites[gObjectBankIDs[bank]].invisible = ewram17800[bank].invisible; + } +} + +static void sub_807B508(u8 bank) +{ + if (bank < gNoOfAllBanks) + { + u8 healthboxID; + if (gBattleTypeFlags & BATTLE_TYPE_SAFARI && bank == 0) + healthboxID = battle_make_oam_safari_battle(); + else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL && bank == 0) + return; + else + healthboxID = battle_make_oam_normal_battle(bank); + gHealthboxIDs[bank] = healthboxID; + sub_8043F44(bank); + sub_8043DFC(healthboxID); + if (GetBankSide(bank)) + sub_8045A5C(gHealthboxIDs[bank], &gEnemyParty[gBattlePartyID[bank]], 0); + else if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) + sub_8045A5C(gHealthboxIDs[bank], &gPlayerParty[gBattlePartyID[bank]], 10); + else + sub_8045A5C(gHealthboxIDs[bank], &gPlayerParty[gBattlePartyID[bank]], 0); + if (GetBankIdentity(bank) == 3 || GetBankIdentity(bank) == 2) + nullsub_11(gHealthboxIDs[bank], 1); + else + nullsub_11(gHealthboxIDs[bank], 0); + if (GetBankSide(bank)) + { + if (GetMonData(&gEnemyParty[gBattlePartyID[bank]], MON_DATA_HP) == 0) + sub_8043DB0(healthboxID); + } + else if (!(gBattleTypeFlags & BATTLE_TYPE_SAFARI)) + { + if (GetMonData(&gPlayerParty[gBattlePartyID[bank]], MON_DATA_HP) == 0) + sub_8043DB0(healthboxID); + } + } +} diff --git a/src/debug/mori_debug_menu.c b/src/debug/mori_debug_menu.c index 273191192..4eadaa78b 100644 --- a/src/debug/mori_debug_menu.c +++ b/src/debug/mori_debug_menu.c @@ -134,7 +134,7 @@ s8 MoriDebugMenu_PokeblockCase(void) s32 loopCounter; for (loopCounter = 0; loopCounter <= 39; loopCounter++) - sub_810CA6C(loopCounter); + PokeblockClearIfExists(loopCounter); CloseMenu(); return 1; diff --git a/src/engine/link.c b/src/engine/link.c index 5858ad8bf..850201ccb 100644 --- a/src/engine/link.c +++ b/src/engine/link.c @@ -2,7 +2,6 @@ #include "link.h" #include "battle.h" #include "berry.h" -#include "berry_blender.h" #include "hall_of_fame.h" #include "item_use.h" #include "main.h" @@ -42,6 +41,8 @@ extern u16 gBattleTypeFlags; extern u16 word_3004858; +extern void Blender_SetBankBerryData(u8 bank, u16 itemID); + static void InitLinkTestBG(u8, u8, u8, u8); void InitLinkTestBG_Unused(u8, u8, u8, u8); void LinkTestScreen(); @@ -556,7 +557,7 @@ static void ProcessRecvCmds(u8 unusedParam) sub_8007E24(); break; case 0xAAAB: - sub_80516C4(i, gRecvCmds[1][i]); + Blender_SetBankBerryData(i, gRecvCmds[1][i]); break; case 0xCCCC: #if defined(ENGLISH) diff --git a/src/engine/main_menu.c b/src/engine/main_menu.c index 09fd06d9e..3b616065b 100644 --- a/src/engine/main_menu.c +++ b/src/engine/main_menu.c @@ -1421,14 +1421,14 @@ void AddBirchSpeechObjects(u8 taskId) gTasks[taskId].data[TD_AZURILL_SPRITE_ID] = spriteId; //Create Brendan sprite - spriteId = CreateTrainerSprite_BirchSpeech(0, 120, 60, 0, unk_2000000); + spriteId = CreateTrainerSprite(0, 120, 60, 0, unk_2000000); gSprites[spriteId].callback = nullsub_34; gSprites[spriteId].invisible = 1; gSprites[spriteId].oam.priority = 0; gTasks[taskId].data[TD_BRENDAN_SPRITE_ID] = spriteId; //Create May sprite - spriteId = CreateTrainerSprite_BirchSpeech(1, 120, 60, 0, unk_2000000 + 0x800); + spriteId = CreateTrainerSprite(1, 120, 60, 0, unk_2000000 + 0x800); gSprites[spriteId].callback = nullsub_34; gSprites[spriteId].invisible = 1; gSprites[spriteId].oam.priority = 0; diff --git a/src/field/field_effect.c b/src/field/field_effect.c index 3632d7053..cffed2614 100644 --- a/src/field/field_effect.c +++ b/src/field/field_effect.c @@ -618,13 +618,13 @@ bool8 FieldEffectActiveListContains(u8 id) return FALSE; } -u8 CreateTrainerSprite_BirchSpeech(u8 gender, s16 x, s16 y, u8 subpriority, u8 *buffer) +u8 CreateTrainerSprite(u8 trainerSpriteID, s16 x, s16 y, u8 subpriority, u8 *buffer) { struct SpriteTemplate spriteTemplate; - LoadCompressedObjectPaletteOverrideBuffer(&gTrainerFrontPicPaletteTable[gender], buffer); - LoadCompressedObjectPicOverrideBuffer(&gTrainerFrontPicTable[gender], buffer); - spriteTemplate.tileTag = gTrainerFrontPicTable[gender].tag; - spriteTemplate.paletteTag = gTrainerFrontPicPaletteTable[gender].tag; + LoadCompressedObjectPaletteOverrideBuffer(&gTrainerFrontPicPaletteTable[trainerSpriteID], buffer); + LoadCompressedObjectPicOverrideBuffer(&gTrainerFrontPicTable[trainerSpriteID], buffer); + spriteTemplate.tileTag = gTrainerFrontPicTable[trainerSpriteID].tag; + spriteTemplate.paletteTag = gTrainerFrontPicPaletteTable[trainerSpriteID].tag; spriteTemplate.oam = &gOamData_839F0F4; spriteTemplate.anims = gDummySpriteAnimTable; spriteTemplate.images = NULL; diff --git a/src/field/money.c b/src/field/money.c index 5d9d0b689..67b7eb03f 100644 --- a/src/field/money.c +++ b/src/field/money.c @@ -148,7 +148,7 @@ void sub_80B7AEC(u32 arg0, u8 left, u8 top) } __attribute__((naked)) -void sub_80B7B34(void) +void sub_80B7B34(u8 var1, u8 var2, int var3) { asm(".syntax unified\n\ push {r4-r7,lr}\n\ diff --git a/src/field/pokeblock.c b/src/field/pokeblock.c index 775280f6e..029bb066f 100644 --- a/src/field/pokeblock.c +++ b/src/field/pokeblock.c @@ -25,7 +25,6 @@ #include "sound.h" #include "songs.h" #include "safari_zone.h" -#include "use_pokeblock.h" #include "event_data.h" #include "pokeblock.h" @@ -582,7 +581,7 @@ static void sub_810BDAC(bool8 flag) v0 = ((i % 3) << 6) + 0x1a1 + (i / 3) * 6; if (gUnknown_02039248.unk0 + gUnknown_02039248.unk1 != gUnknown_02039248.unk2) { - if (sub_810CA9C(&gSaveBlock1.pokeblocks[gUnknown_02039248.unk0 + gUnknown_02039248.unk1], i + 1) > 0) + if (GetPokeblockData(&gSaveBlock1.pokeblocks[gUnknown_02039248.unk0 + gUnknown_02039248.unk1], i + 1) > 0) { gBGTilemapBuffers[2][v0] = (i << 12) + 23; gBGTilemapBuffers[2][v0 + 32] = (i << 12) + 24; @@ -894,7 +893,7 @@ static void sub_810C5EC(u8 taskId) static void sub_810C610(u8 taskId) { MenuZeroFillWindowRect(7, 6, 13, 11); - sub_810CA6C((gUnknown_02039248.unk0 + gUnknown_02039248.unk1)); + PokeblockClearIfExists((gUnknown_02039248.unk0 + gUnknown_02039248.unk1)); StringExpandPlaceholders(gStringVar4, gContestStatsText_WasThrownAway); DisplayItemMessageOnField(taskId, gStringVar4, sub_810C704, 0); sub_810BC98(); @@ -942,9 +941,9 @@ static void sub_810C748(u8 taskId) static void sub_810C788(u8 taskId) { - s16 v0 = sub_810CAE4(GetNature(&gEnemyParty[0]), &gSaveBlock1.pokeblocks[gScriptItemId]); + s16 v0 = PokeblockGetGain(GetNature(&gEnemyParty[0]), &gSaveBlock1.pokeblocks[gScriptItemId]); StringCopy(gBattleTextBuff1, gPokeblockNames[gSaveBlock1.pokeblocks[gScriptItemId].color]); - sub_810CA6C(gScriptItemId); + PokeblockClearIfExists(gScriptItemId); gScriptItemId = gSaveBlock1.pokeblocks[gScriptItemId].color << 8; if (v0 == 0) { @@ -967,7 +966,7 @@ static void sub_810C854(u8 taskId) SafariZoneActivatePokeblockFeeder(gScriptItemId); StringCopy(gStringVar1, gPokeblockNames[gSaveBlock1.pokeblocks[gScriptItemId].color]); gScriptResult = gScriptItemId; - sub_810CA6C(gScriptItemId); + PokeblockClearIfExists(gScriptItemId); BeginNormalPaletteFade(-1, 0, 0, 16, 0); gTasks[taskId].func = sub_810C2C8; } @@ -1024,10 +1023,10 @@ u8 sub_810C9B0(struct Pokeblock *pokeblock) { u8 contestStat; u8 maxRating; - u8 rating = sub_810CA9C(pokeblock, 1); + u8 rating = GetPokeblockData(pokeblock, 1); for (contestStat=1; contestStat<5; contestStat++) { - maxRating = sub_810CA9C(pokeblock, contestStat + 1); + maxRating = GetPokeblockData(pokeblock, contestStat + 1); if (rating < maxRating) { rating = maxRating; @@ -1038,7 +1037,7 @@ u8 sub_810C9B0(struct Pokeblock *pokeblock) u8 sub_810C9E8(struct Pokeblock *pokeblock) { - u8 feel = sub_810CA9C(pokeblock, 6); + u8 feel = GetPokeblockData(pokeblock, 6); if (feel > 99) feel = 99; return feel; @@ -1068,7 +1067,7 @@ bool8 sub_810CA34(struct Pokeblock *pokeblock) return TRUE; } -bool8 sub_810CA6C(u8 pokeblockIdx) +bool8 PokeblockClearIfExists(u8 pokeblockIdx) { if (gSaveBlock1.pokeblocks[pokeblockIdx].color == 0) { @@ -1078,33 +1077,33 @@ bool8 sub_810CA6C(u8 pokeblockIdx) return TRUE; } -s16 sub_810CA9C(const struct Pokeblock *pokeblock, u8 field) +s16 GetPokeblockData(const struct Pokeblock *pokeblock, u8 field) { - if (field == 0) + if (field == PBLOCK_COLOR) return pokeblock->color; - if (field == 1) + if (field == PBLOCK_SPICY) return pokeblock->spicy; - if (field == 2) + if (field == PBLOCK_DRY) return pokeblock->dry; - if (field == 3) + if (field == PBLOCK_SWEET) return pokeblock->sweet; - if (field == 4) + if (field == PBLOCK_BITTER) return pokeblock->bitter; - if (field == 5) + if (field == PBLOCK_SOUR) return pokeblock->sour; - if (field == 6) + if (field == PBLOCK_FEEL) return pokeblock->feel; return 0; } -s16 sub_810CAE4(u8 nature, const struct Pokeblock *pokeblock) +s16 PokeblockGetGain(u8 nature, const struct Pokeblock *pokeblock) { u8 flavor; s16 curGain; s16 totalGain = 0; for (flavor=0; flavor<5; flavor++) { - curGain = sub_810CA9C(pokeblock, flavor + 1); + curGain = GetPokeblockData(pokeblock, flavor + 1); if (curGain > 0) { totalGain += curGain * gPokeblockFlavorCompatibilityTable[5 * nature + flavor]; @@ -1113,9 +1112,9 @@ s16 sub_810CAE4(u8 nature, const struct Pokeblock *pokeblock) return totalGain; } -void sub_810CB44(struct Pokeblock *pokeblock, u8 *dest) +void PokeblockCopyName(struct Pokeblock *pokeblock, u8 *dest) { - u8 color = sub_810CA9C(pokeblock, 0); + u8 color = GetPokeblockData(pokeblock, PBLOCK_COLOR); StringCopy(dest, gPokeblockNames[color]); } @@ -1124,7 +1123,7 @@ bool8 sub_810CB68(u8 nature, u8 *dest) u8 flavor; for (flavor=0; flavor<5; flavor++) { - if (sub_810CAE4(nature, &gUnknown_083F7F9C[flavor]) > 0) + if (PokeblockGetGain(nature, &gUnknown_083F7F9C[flavor]) > 0) { StringCopy(dest, gPokeblockNames[flavor + 1]); return TRUE; diff --git a/src/field/shop.c b/src/field/shop.c index d53646a88..6a88f1394 100644 --- a/src/field/shop.c +++ b/src/field/shop.c @@ -16,68 +16,106 @@ #include "task.h" #include "tv.h" #include "unknown_task.h" +#include "field_map_obj.h" +#include "field_player_avatar.h" +#include "fieldmap.h" +#include "item.h" +#include "decoration.h" +#include "items.h" +#include "songs.h" +#include "rom4.h" +#include "decoration_inventory.h" +#include "field_camera.h" -struct UnknownShopStruct -{ - /* 0x0 */ void (* callback) (void); - /* 0x4 */ u16 *itemList; - /* 0x8 */ u8 itemCount; - /* 0x9 */ u8 unk9; - /* 0xA */ u8 unkA; - /* 0xB */ u8 unkB; - /* 0xC */ bool8 unkC; - // unknown size -}; +#define ewram18000 ((u16 *)(ewram + 0x18000)) +#define ewram18300 ((u16 *)(ewram + 0x18300)) -extern struct UnknownShopStruct gUnknown_03000708; -extern struct MenuAction gUnknown_083CC6D0[]; +extern bool8 sub_80A52C4(u8, u8); -extern u8 gUnknown_083CC6E8[]; -extern u8 gUnknown_083CC6EB[]; +extern u8 ewram[]; extern u8 gBuyMenuFrame_Gfx[]; - extern u16 gBuyMenuFrame_Tilemap[]; extern u16 gMenuMoneyPal[16]; -extern u16 gUnknown_083CC710[2]; -u8 CreateShopMenu(bool8 var) +void sub_80B39D0(int var1, int var2, bool32 hasControlCode); +void sub_80B3A70(void); +void sub_80B4378(u8); +void sub_80B43F0(u8); +void Task_ExitBuyMenu(u8); +void sub_80B4470(u8); +void sub_80B2EFC(u8 taskId); +void sub_80B2F30(u8 taskId); +void HandleShopMenuQuit(u8 taskId); +void sub_80B3BF4(u8 taskId); +void sub_80B3D7C(u8 taskId); + +// iwram +static struct MartInfo gMartInfo; + +// ewram +EWRAM_DATA u32 gMartTotalCost = 0; +EWRAM_DATA s16 gUnknown_020386A4[16][4] = {0}; // game freak barely uses 2d arrays wtf? +EWRAM_DATA struct ItemSlot gUnknown_02038724[3] = {0}; // tv.c uses this, so it cant be static +EWRAM_DATA u8 gUnknown_02038730 = 0; +EWRAM_DATA u8 gUnknown_02038731 = 0; + +// rodata +static const struct MenuAction2 gUnknown_083CC6D0[] = +{ + { MartText_Buy, sub_80B2EFC }, + { MartText_Sell, sub_80B2F30 }, + { MartText_Quit2, HandleShopMenuQuit }, +}; + +static const u8 gUnknown_083CC6E8[] = {0, 1, 2}; // BUY SELL EXIT +static const u8 gUnknown_083CC6EB[] = {0, 2}; // BUY EXIT + +static const u16 gUnusedMartArray[] = {0x2, 0x3, 0x4, 0xD, 0x121, 0xE, 0xE, 0xE, 0xE, 0xE, 0xE, 0x0, 0x0}; + +static const struct YesNoFuncTable gUnknown_083CC708[] = +{ + sub_80B3BF4, + sub_80B3D7C +}; + +u8 CreateShopMenu(u8 martType) { ScriptContext2_Enable(); - gUnknown_03000708.unkC = var; - gUnknown_03000708.unk9 = 0; + gMartInfo.martType = martType; + gMartInfo.cursor = 0; - if(var == FALSE) + if (martType == MART_TYPE_0) { - gUnknown_03000708.unkA = 2; + gMartInfo.numChoices = 2; MenuDrawTextWindow(0, 0, 10, 7); - PrintMenuItemsReordered(1, 1, 3, gUnknown_083CC6D0, (u8 *)gUnknown_083CC6E8); + PrintMenuItemsReordered(1, 1, 3, (struct MenuAction *)gUnknown_083CC6D0, (u8 *)gUnknown_083CC6E8); } else { - gUnknown_03000708.unkA = 1; + gMartInfo.numChoices = 1; MenuDrawTextWindow(0, 0, 10, 5); - PrintMenuItemsReordered(1, 1, 2, gUnknown_083CC6D0, (u8 *)gUnknown_083CC6EB); + PrintMenuItemsReordered(1, 1, 2, (struct MenuAction *)gUnknown_083CC6D0, (u8 *)gUnknown_083CC6EB); } - InitMenu(0, 1, 1, gUnknown_03000708.unkA + 1, 0, 9); + InitMenu(0, 1, 1, gMartInfo.numChoices + 1, 0, 9); // add 1 for cancel return CreateTask(sub_80B2E38, 8); } void SetShopMenuCallback(void *callbackPtr) { - gUnknown_03000708.callback = callbackPtr; + gMartInfo.callback = callbackPtr; } void SetShopItemsForSale(u16 *items) { u16 i = 0; - gUnknown_03000708.itemList = items; - gUnknown_03000708.itemCount = 0; + gMartInfo.itemList = items; + gMartInfo.itemCount = 0; - while (gUnknown_03000708.itemList[i]) + while (gMartInfo.itemList[i]) { - gUnknown_03000708.itemCount++; + gMartInfo.itemCount++; i++; } } @@ -86,37 +124,37 @@ void sub_80B2E38(u8 var) { const u8 local = var; - if(gMain.newAndRepeatedKeys & 0x40) + if (gMain.newAndRepeatedKeys & DPAD_UP) { - if(gUnknown_03000708.unk9) + if (gMartInfo.cursor) // can move cursor up? { - PlaySE(0x5); - gUnknown_03000708.unk9 = MoveMenuCursor(-1); + PlaySE(SE_SELECT); + gMartInfo.cursor = MoveMenuCursor(-1); } } - else if(gMain.newAndRepeatedKeys & 0x80) + else if (gMain.newAndRepeatedKeys & DPAD_DOWN) { - if(gUnknown_03000708.unk9 != gUnknown_03000708.unkA) + if (gMartInfo.cursor != gMartInfo.numChoices) // can move cursor down? { - PlaySE(0x5); - gUnknown_03000708.unk9 = MoveMenuCursor(1); + PlaySE(SE_SELECT); + gMartInfo.cursor = MoveMenuCursor(1); } } - else if (gMain.newKeys & 1) + else if (gMain.newKeys & A_BUTTON) { - PlaySE(0x5); - if(!gUnknown_03000708.unkC) + PlaySE(SE_SELECT); + if (gMartInfo.martType == MART_TYPE_0) { - gUnknown_083CC6D0[gUnknown_083CC6E8[gUnknown_03000708.unk9]].func(local); + gUnknown_083CC6D0[gUnknown_083CC6E8[gMartInfo.cursor]].func(local); } else { - gUnknown_083CC6D0[gUnknown_083CC6EB[gUnknown_03000708.unk9]].func(local); + gUnknown_083CC6D0[gUnknown_083CC6EB[gMartInfo.cursor]].func(local); } } - else if(gMain.newKeys & 2) + else if (gMain.newKeys & B_BUTTON) { - PlaySE(0x5); + PlaySE(SE_SELECT); HandleShopMenuQuit(local); } } @@ -141,17 +179,17 @@ void HandleShopMenuQuit(u8 taskId) { HandleDestroyMenuCursors(); MenuZeroFillWindowRect(0, 0, 11, 8); - sub_80BE3BC(); // in tv.s? + sub_80BE3BC(); ScriptContext2_Disable(); DestroyTask(taskId); - if(gUnknown_03000708.callback) - gUnknown_03000708.callback(); // run the callback if it exists. + if (gMartInfo.callback) + gMartInfo.callback(); // run the callback if it exists. } void sub_80B2FA0(u8 taskId) { - if(!gPaletteFade.active) + if (!gPaletteFade.active) { SetMainCallback2((void *)((u16)gTasks[taskId].data[8] << 16 | (u16)gTasks[taskId].data[9])); DestroyTask(taskId); @@ -160,15 +198,15 @@ void sub_80B2FA0(u8 taskId) void ReturnToShopMenuAfterExitingSellMenu(u8 taskId) { - CreateShopMenu(gUnknown_03000708.unkC); + CreateShopMenu(gMartInfo.martType); DestroyTask(taskId); } void Task_ExitSellMenu(u8 taskId) { - if(sub_807D770() == 1) + if (sub_807D770() == 1) { - if(gUnknown_03000708.unkC == 2) + if (gMartInfo.martType == MART_TYPE_2) DisplayItemMessageOnField(taskId, gOtherText_CanIHelpYou, ReturnToShopMenuAfterExitingSellMenu, 0); else DisplayItemMessageOnField(taskId, gOtherText_AnythingElse, ReturnToShopMenuAfterExitingSellMenu, 0); @@ -253,8 +291,8 @@ void BuyMenuDrawGraphics(void) SetUpWindowConfig(&gWindowConfig_81E6DFC); InitMenuWindow(&gWindowConfig_81E6DFC); BuyMenuDrawMapGraphics(); - gUnknown_03000708.unk9 = zero; - gUnknown_03000708.unkB = zero2; + gMartInfo.cursor = zero; + gMartInfo.choicesAbove = zero2; MenuZeroFillWindowRect(0, 0, 0x20, 0x20); sub_80B7C14(gSaveBlock1.money, 0, 0); sub_80B3764(0, 7); @@ -272,9 +310,8 @@ void BuyMenuDrawGraphics(void) void sub_80B3240(void) { - u16 tempArr[2]; + u16 tempArr[2] = {0x41EE, 0x7FFF}; - memcpy(tempArr, gUnknown_083CC710, sizeof(tempArr)); LoadPalette(&tempArr[1], 0xD1, 2); LoadPalette(&tempArr[0], 0xD8, 2); } @@ -283,7 +320,7 @@ void sub_80B3270(void) { sub_80F944C(); - if(gUnknown_03000708.itemCount > 7) + if (gMartInfo.itemCount > 7) { CreateVerticalScrollIndicators(0, 172, 12); CreateVerticalScrollIndicators(1, 172, 148); @@ -293,12 +330,12 @@ void sub_80B3270(void) void sub_80B32A4(void) { - if(gUnknown_03000708.unkB == 0) + if (gMartInfo.choicesAbove == 0) sub_80F979C(0, 1); else sub_80F979C(0, 0); - if(gUnknown_03000708.unkB + 7 >= gUnknown_03000708.itemCount) + if (gMartInfo.choicesAbove + 7 >= gMartInfo.itemCount) sub_80F979C(1, 1); else sub_80F979C(1, 0); @@ -318,13 +355,13 @@ void BuyMenuDrawMapMetatileLayer(u16 *array, s16 offset1, s16 offset2, u16 *arra array[offset1 + offset2 + 33] = array2[3]; } -void BuyMenuDrawMapMetatile(int var1, int var2, u16 *var3, s8 var4) +void BuyMenuDrawMapMetatile(int var1, int var2, u16 *var3, s32 var4) { u8 tempVar4 = var4; s16 offset1 = var1 * 2; s16 offset2 = (var2 * 0x40) + 0x40; - switch(tempVar4) + switch (tempVar4) { case 0: // _080B335C BuyMenuDrawMapMetatileLayer(gBGTilemapBuffers[2], offset1, offset2, var3); @@ -340,3 +377,975 @@ void BuyMenuDrawMapMetatile(int var1, int var2, u16 *var3, s8 var4) break; } } + +void sub_80B33D0(s16 var1, int var2, u16 *var3) +{ + s16 offset1 = var1 * 2; + s16 offset2 = (var2 * 0x40) + 0x40; + + BuyMenuDrawMapMetatileLayer(gBGTilemapBuffers[3], offset1, offset2, var3); + BuyMenuDrawMapMetatileLayer(gBGTilemapBuffers[2], offset1, offset2, var3 + 4); +} + +void sub_80B3420(void) +{ + s16 facingX; + s16 facingY; + s16 x; + s16 y; + + GetXYCoordsOneStepInFrontOfPlayer(&facingX, &facingY); + facingX -= 3; + facingY -= 3; + + for (y = 0; y < 6; y++) + { + for (x = 0; x < 7; x++) + { + u16 metatileId = MapGridGetMetatileIdAt(facingX + x, facingY + y); + + if (y != 5 && x != 6) + { + s32 r3 = MapGridGetMetatileLayerTypeAt(facingX + x, facingY + y); + + if (metatileId < 512) + BuyMenuDrawMapMetatile(x, y, (u16 *)gMapHeader.mapData->primaryTileset->metatiles + metatileId * 8, r3); + else + BuyMenuDrawMapMetatile(x, y, (u16 *)gMapHeader.mapData->secondaryTileset->metatiles + (metatileId - 512) * 8, r3); + } + else + { + if (metatileId < 512) + sub_80B33D0(x, y, (u16 *)gMapHeader.mapData->primaryTileset->metatiles + metatileId * 8); + else + sub_80B33D0(x, y, (u16 *)gMapHeader.mapData->secondaryTileset->metatiles + (metatileId - 512) * 8); + } + + if (y == 0 && x != 0 && x != 6) + sub_80B32EC(gBGTilemapBuffers[1], x * 2, 64); + } + } +} + +void BuyMenuDrawMapGraphics(void) +{ + sub_80F9020(); + sub_80B356C(); + sub_80B368C(); + sub_80B3420(); +} + +void sub_80B356C(void) +{ + s16 facingX; + s16 facingY; + u8 playerHeight; + u8 y; + u8 x; + u8 r8 = 0; + + GetXYCoordsOneStepInFrontOfPlayer(&facingX, &facingY); + playerHeight = PlayerGetZCoord(); + for (y = 0; y < 16; y++) + gUnknown_020386A4[y][MAP_OBJ_ID] = 16; + for (y = 0; y < 5; y++) + { + for (x = 0; x < 7; x++) + { + u8 mapObjId = GetFieldObjectIdByXYZ(facingX - 3 + x, facingY - 2 + y, playerHeight); + + if (mapObjId != 16) + { + gUnknown_020386A4[r8][MAP_OBJ_ID] = mapObjId; + gUnknown_020386A4[r8][X_COORD] = x; + gUnknown_020386A4[r8][Y_COORD] = y; + if (gMapObjects[mapObjId].mapobj_unk_18 == 1) + gUnknown_020386A4[r8][ANIM_NUM] = 0; + if (gMapObjects[mapObjId].mapobj_unk_18 == 2) + gUnknown_020386A4[r8][ANIM_NUM] = 1; + if (gMapObjects[mapObjId].mapobj_unk_18 == 3) + gUnknown_020386A4[r8][ANIM_NUM] = 2; + if (gMapObjects[mapObjId].mapobj_unk_18 == 4) + gUnknown_020386A4[r8][ANIM_NUM] = 3; + r8++; + } + } + } +} + +void sub_80B368C(void) +{ + u8 i; + + for (i = 0; i < 16; i++) // max objects? + { + if (gUnknown_020386A4[i][MAP_OBJ_ID] == 16) + continue; + + StartSpriteAnim(&gSprites[AddPseudoFieldObject( + gMapObjects[gUnknown_020386A4[i][MAP_OBJ_ID]].graphicsId, + SpriteCallbackDummy, + (u16)gUnknown_020386A4[i][X_COORD] * 16 + 8, + (u16)gUnknown_020386A4[i][Y_COORD] * 16 + 32, + 2)], + gUnknown_020386A4[i][ANIM_NUM]); + } +} + +void sub_80B3720(void) +{ + s16 i; + + for (i = 0; i < 0x400; i++) + { + if (ewram18000[i] != 0) + gBGTilemapBuffers[1][i] = ewram18000[i] + 0xC3E0; + } +} + +void sub_80B3764(int var1, int var2) +{ + sub_80B3720(); + sub_80B39D0(var1, var2, 0); + InitMenu(0, 0xE, 0x2, 0x8, gMartInfo.cursor, 0xF); +} + +void sub_80B379C(void) +{ + u16 i, j; + + for (i = 0; i < 8; i++) + for (j = 0; j < 14; j++) + gBGTilemapBuffers[1][32 * (i + 12) + j] = ewram18300[32 * i + j] + 0xC3E0; +} + +void sub_80B37EC(void) +{ + sub_80B3A70(); +} + +void sub_80B37F8(u8 taskId) +{ + u16 itemListIndex = gMartInfo.choicesAbove + gMartInfo.cursor; + u16 itemId = gMartInfo.itemList[itemListIndex]; + u32 price = (ItemId_GetPrice(itemId) >> GetPriceReduction(1)); + + sub_80B7A94(gTasks[taskId].data[1] * price, 6, 6, 11); + gStringVar1[0] = EXT_CTRL_CODE_BEGIN; + gStringVar1[1] = 0x14; + gStringVar1[2] = 0x6; + ConvertIntToDecimalStringN(&gStringVar1[3], gTasks[taskId].data[1], 1, 2); + MenuPrint(gOtherText_xString1, 1, 11); + sub_80A3FA0(gBGTilemapBuffers[1], 1, 11, 12, 2, 0xC3E1); +} + +void sub_80B389C(u16 itemId, u8 var2, bool32 hasControlCode) +{ + u8 *stringPtr = gStringVar1; + + if (hasControlCode != FALSE) + { + stringPtr[0] = EXT_CTRL_CODE_BEGIN; + stringPtr[1] = 0x1; + stringPtr[2] = 0x2; + stringPtr += 3; + } + + CopyItemName(itemId, stringPtr); + + sub_8072A18(&gStringVar1[0], 0x70, var2 << 3, 0x58, 0x1); + stringPtr = gStringVar1; + + if (hasControlCode != FALSE) + stringPtr = &gStringVar1[3]; + + sub_80B79F8(stringPtr, (ItemId_GetPrice(itemId) >> GetPriceReduction(1)), 0x4); + MenuPrint_PixelCoords(&gStringVar1[0], 0xCA, var2 << 3, 1); +} + +void sub_80B3930(u16 itemId, u8 var2, bool32 hasControlCode) +{ + u8 *stringPtr = gStringVar1; + + if (hasControlCode != FALSE) + { + stringPtr[0] = EXT_CTRL_CODE_BEGIN; + stringPtr[1] = 0x1; + stringPtr[2] = 0x2; + stringPtr += 3; + } + + StringCopy(stringPtr, gDecorations[itemId].name); + sub_8072A18(&gStringVar1[0], 0x70, var2 << 3, 0x58, 0x1); + stringPtr = gStringVar1; + + if (hasControlCode != FALSE) + stringPtr = &gStringVar1[3]; + + if (gDecorations[itemId].price == 10000) + { + sub_80B7B34(0x19, var2, hasControlCode); // huh??? + } + else + { + sub_80B79F8(stringPtr, gDecorations[itemId].price, 0x4); + MenuPrint_PixelCoords(&gStringVar1[0], 0xCA, var2 << 3, 0x1); + } +} + +void sub_80B39D0(int var1, int var2, bool32 hasControlCode) +{ + u8 i; + + for (i = var1; i <= var2 && gMartInfo.choicesAbove + i < gMartInfo.itemCount; i++) + { + if (gMartInfo.martType == MART_TYPE_0) + sub_80B389C(gMartInfo.itemList[gMartInfo.choicesAbove + i], (i << 1) + 2, hasControlCode); + else + sub_80B3930(gMartInfo.itemList[gMartInfo.choicesAbove + i], (i << 1) + 2, hasControlCode); + } + + if (i != 8 && gMartInfo.choicesAbove + i == gMartInfo.itemCount) + { + MenuFillWindowRectWithBlankTile(0xE, (i << 1) + 2, 0x1C, (i << 1) + 3); + MenuPrint(gOtherText_CancelNoTerminator, 0xE, (i << 1) + 2); + } +} + +void sub_80B3A70(void) +{ + if (gMartInfo.choicesAbove + gMartInfo.cursor != gMartInfo.itemCount) + { + if (gMartInfo.martType == MART_TYPE_0) + { + sub_8072AB0(ItemId_GetDescription(gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor]), + 0x4, 0x68, 0x68, 0x30, 0); + } + else + sub_8072AB0(gDecorations[gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor]].description, + 0x4, 0x68, 0x68, 0x30, 0); + } + else + { + sub_8072AB0(gOtherText_QuitShopping, 0x4, 0x68, 0x68, 0x30, 0); + } +} + +void sub_80B3AEC(u8 taskId) +{ + if (gMain.newKeys & A_BUTTON || gMain.newKeys & B_BUTTON) + { + sub_80B39D0(gMartInfo.cursor, gMartInfo.cursor, 0); // huh??? + PlaySE(SE_SELECT); + + if (gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor] == ITEM_POKE_BALL && gTasks[taskId].data[1] >= 10 && AddBagItem(ITEM_PREMIER_BALL, 1) == TRUE) + DisplayItemMessageOnField(taskId, gOtherText_FreePremierBall, sub_80B4378, 0xC3E1); + else + sub_80B4378(taskId); + } +} + +void sub_80B3B80(u8 taskId) +{ + IncrementGameStat(0x26); + sub_80B79E0(&gSaveBlock1.money, gMartTotalCost); + PlaySE(SE_REGI); + sub_80B7BEC(gSaveBlock1.money, 0, 0); + gTasks[taskId].func = sub_80B3AEC; +} + +void sub_80B3BD0(u8 taskId) +{ + sub_80B39D0(gMartInfo.cursor, gMartInfo.cursor, 0); // same thing as above? + sub_80B4378(taskId); +} + +void sub_80B3BF4(u8 taskId) +{ + MenuZeroFillWindowRect(0x7, 0x8, 0xD, 0xD); + sub_80A3FA0(gBGTilemapBuffers[1], 8, 9, 4, 4, 0); + sub_80B379C(); + sub_80B3420(); + + if (IsEnoughMoney(gSaveBlock1.money, gMartTotalCost)) + { + if (gMartInfo.martType == MART_TYPE_0) + { + if (AddBagItem(gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor], gTasks[taskId].data[1])) + { + DisplayItemMessageOnField(taskId, gOtherText_HereYouGo, sub_80B3B80, 0xC3E1); + sub_80B4470(taskId); + } + else + DisplayItemMessageOnField(taskId, gOtherText_NoRoomFor, sub_80B3BD0, 0xC3E1); + } + else // a normal mart is only type 0, so types 1 and 2 are decoration marts. + { + if (IsThereStorageSpaceForDecoration(gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor])) + { + if (gMartInfo.martType == MART_TYPE_1) + DisplayItemMessageOnField(taskId, gOtherText_HereYouGo2, sub_80B3B80, 0xC3E1); + else + DisplayItemMessageOnField(taskId, gOtherText_HereYouGo3, sub_80B3B80, 0xC3E1); + } + else + { + StringExpandPlaceholders(gStringVar4, gOtherText_SpaceForIsFull); + DisplayItemMessageOnField(taskId, gStringVar4, sub_80B3BD0, 0xC3E1); + } + } + } + else + DisplayItemMessageOnField(taskId, gOtherText_NotEnoughMoney, sub_80B3BD0, 0xC3E1); +} + +void sub_80B3D38(u8 taskId) +{ + DisplayYesNoMenu(7, 8, 1); + sub_80A3FA0(gBGTilemapBuffers[1], 8, 9, 4, 4, 0xC3E1); + DoYesNoFuncWithChoice(taskId, gUnknown_083CC708); +} + +void sub_80B3D7C(u8 taskId) +{ + sub_80B39D0(gMartInfo.cursor, gMartInfo.cursor, 0); + MenuZeroFillWindowRect(0x7, 0x8, 0xD, 0xD); + sub_80A3FA0(gBGTilemapBuffers[1], 0x8, 0x9, 0x4, 0x4, 0); + sub_80B4378(taskId); +} + +void sub_80B3DC8(u8 taskId) +{ + if (sub_80A52C4(taskId, gMartInfo.curItemCount) == TRUE) + sub_80B37F8(taskId); + + if (gMain.newKeys & A_BUTTON) + { + gMartTotalCost = (ItemId_GetPrice(gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor]) >> GetPriceReduction(1)) * gTasks[taskId].data[1]; // set total cost of your purchase. + MenuZeroFillWindowRect(0, 0xA, 0xD, 0xD); + sub_80A3FA0(gBGTilemapBuffers[1], 0x1, 0xB, 0xC, 0x2, 0); + sub_80B379C(); + sub_80B3420(); + CopyItemName(gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor], gStringVar1); + ConvertIntToDecimalStringN(gStringVar2, gTasks[taskId].data[1], 0, 0x2); + ConvertIntToDecimalStringN(gStringVar3, gMartTotalCost, 0, 0x8); + StringExpandPlaceholders(gStringVar4, gOtherText_ThatWillBe); + DisplayItemMessageOnField(taskId, gStringVar4, sub_80B3D38, 0xC3E1); + } + else if (gMain.newKeys & B_BUTTON) + { + sub_80B39D0(gMartInfo.cursor, gMartInfo.cursor, 0); + sub_80B4378(taskId); + } +} + +void sub_80B3EFC(u8 taskId) +{ + u16 var; + + gTasks[taskId].data[1] = 1; + MenuDrawTextWindow(0, 0xA, 0xD, 0xD); + sub_80B37F8(taskId); + + var = gSaveBlock1.money / (ItemId_GetPrice(gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor]) >> GetPriceReduction(1)); + if (var > 99) + gMartInfo.curItemCount = 99; + else + gMartInfo.curItemCount = var; + + gTasks[taskId].func = sub_80B3DC8; +} + +#ifdef NONMATCHING +void sub_80B3F88(void) +{ + u16 *r1; + u16 *r2; + register u8 *r10 asm("r10"); + s32 i; + s32 j; + struct Window *r8 = &gMenuWindow; + + r1 = r8->tilemap; + r1 += 0x1EF; + r2 = r1; + r2 += 64; + r10 = r8->tileData; + + for (i = 0; i < 14; i++) + { + for (j = 0; j < 15; j++) + { + if ((r1[j] & 0x3FF) <= r8->tileDataStartOffset + 1) + r2[j] = r8->tileDataStartOffset + 1; + else + r2[j] = r1[j] + 0x3C; + } + + r1 -= 32; + r2 -= 32; + } + + { + u8 *r1 = r10 + 0x3A20; + u8 *r2 = r1 + 0x780; + for (i = 0; i < 14; i++) + { + DmaCopy16(3, r1, r2, 0x1E0); + r2 -= 0x3C0; + r1 -= 0x3C0; + } + } +} +#else +__attribute__((naked)) +void sub_80B3F88(void) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0x4\n\ + ldr r0, _080B4020 @ =gMenuWindow\n\ + mov r8, r0\n\ + ldr r1, [r0, 0x28]\n\ + ldr r3, _080B4024 @ =0x000003de\n\ + adds r1, r3\n\ + adds r2, r1, 0\n\ + adds r2, 0x80\n\ + ldr r7, [r0, 0x24]\n\ + mov r10, r7\n\ + ldr r0, _080B4028 @ =0x000003ff\n\ + mov r9, r0\n\ + movs r6, 0xD\n\ +_080B3FAC:\n\ + adds r3, r2, 0\n\ + subs r3, 0x40\n\ + str r3, [sp]\n\ + movs r7, 0x40\n\ + negs r7, r7\n\ + adds r7, r1\n\ + mov r12, r7\n\ + adds r3, r2, 0\n\ + adds r4, r1, 0\n\ + movs r5, 0xE\n\ +_080B3FC0:\n\ + ldrh r2, [r4]\n\ + mov r1, r9\n\ + ands r1, r2\n\ + mov r7, r8\n\ + ldrh r0, [r7, 0x1A]\n\ + adds r0, 0x1\n\ + cmp r1, r0\n\ + ble _080B3FD4\n\ + adds r0, r2, 0\n\ + adds r0, 0x3C\n\ +_080B3FD4:\n\ + strh r0, [r3]\n\ + adds r3, 0x2\n\ + adds r4, 0x2\n\ + subs r5, 0x1\n\ + cmp r5, 0\n\ + bge _080B3FC0\n\ + ldr r2, [sp]\n\ + mov r1, r12\n\ + subs r6, 0x1\n\ + cmp r6, 0\n\ + bge _080B3FAC\n\ + ldr r1, _080B402C @ =0x00003a20\n\ + add r1, r10\n\ + movs r0, 0xF0\n\ + lsls r0, 3\n\ + adds r2, r1, r0\n\ + ldr r3, _080B4030 @ =0x040000d4\n\ + ldr r5, _080B4034 @ =0x800000f0\n\ + ldr r4, _080B4038 @ =0xfffffc40\n\ + movs r6, 0xD\n\ +_080B3FFC:\n\ + str r1, [r3]\n\ + str r2, [r3, 0x4]\n\ + str r5, [r3, 0x8]\n\ + ldr r0, [r3, 0x8]\n\ + adds r2, r4\n\ + adds r1, r4\n\ + subs r6, 0x1\n\ + cmp r6, 0\n\ + bge _080B3FFC\n\ + add sp, 0x4\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_080B4020: .4byte gMenuWindow\n\ +_080B4024: .4byte 0x000003de\n\ +_080B4028: .4byte 0x000003ff\n\ +_080B402C: .4byte 0x00003a20\n\ +_080B4030: .4byte 0x040000d4\n\ +_080B4034: .4byte 0x800000f0\n\ +_080B4038: .4byte 0xfffffc40\n\ + .syntax divided"); +} +#endif + +#ifdef NONMATCHING +void sub_80B403C(void) +{ + u16 *r1; + u16 *r2; + u8 *r10; + s32 i; + s32 j; + struct Window *r8 = &gMenuWindow; + + r1 = r8->tilemap; + r1 += 0x4F; + r2 = r1; + r2 += 64; + r10 = r8->tileData; + + for (i = 0; i < 14; i++) + { + for (j = 0; j < 15; j++) + { + if ((r1[j] & 0x3FF) <= r8->tileDataStartOffset + 1) + r2[j] = r8->tileDataStartOffset + 1; + else + r2[j] = r1[j] + 0x3C; + } + + r1 += 32; + r2 += 32; + } + + { + register u8 *r1 asm("r1") = r10 + 0x960; + register u8 *r2 asm("r2") = r1; + + r1 += 0x780; + for (i = 0; i < 14; i++) + { + DmaCopy16(3, r1, r2, 0x1E0); + r1 += 0x3C0; + r2 += 0x3C0; + } + } +} +#else +__attribute__((naked)) +void sub_80B403C(void) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0x4\n\ + ldr r0, _080B40D8 @ =gMenuWindow\n\ + mov r8, r0\n\ + ldr r2, [r0, 0x28]\n\ + adds r1, r2, 0\n\ + adds r1, 0x9E\n\ + adds r2, r1, 0\n\ + adds r1, 0x80\n\ + ldr r3, [r0, 0x24]\n\ + mov r10, r3\n\ + ldr r7, _080B40DC @ =0x000003ff\n\ + mov r9, r7\n\ + movs r6, 0xD\n\ +_080B4060:\n\ + adds r0, r2, 0\n\ + adds r0, 0x40\n\ + str r0, [sp]\n\ + movs r3, 0x40\n\ + adds r3, r1\n\ + mov r12, r3\n\ + adds r3, r2, 0\n\ + adds r4, r1, 0\n\ + movs r5, 0xE\n\ +_080B4072:\n\ + ldrh r2, [r4]\n\ + mov r1, r9\n\ + ands r1, r2\n\ + mov r7, r8\n\ + ldrh r0, [r7, 0x1A]\n\ + adds r0, 0x1\n\ + cmp r1, r0\n\ + ble _080B4086\n\ + adds r0, r2, 0\n\ + subs r0, 0x3C\n\ +_080B4086:\n\ + strh r0, [r3]\n\ + adds r3, 0x2\n\ + adds r4, 0x2\n\ + subs r5, 0x1\n\ + cmp r5, 0\n\ + bge _080B4072\n\ + ldr r2, [sp]\n\ + mov r1, r12\n\ + subs r6, 0x1\n\ + cmp r6, 0\n\ + bge _080B4060\n\ + movs r1, 0x96\n\ + lsls r1, 4\n\ + add r1, r10\n\ + adds r2, r1, 0\n\ + movs r0, 0xF0\n\ + lsls r0, 3\n\ + adds r1, r0\n\ + ldr r3, _080B40E0 @ =0x040000d4\n\ + ldr r5, _080B40E4 @ =0x800000f0\n\ + movs r4, 0xF0\n\ + lsls r4, 2\n\ + movs r6, 0xD\n\ +_080B40B4:\n\ + str r1, [r3]\n\ + str r2, [r3, 0x4]\n\ + str r5, [r3, 0x8]\n\ + ldr r0, [r3, 0x8]\n\ + adds r2, r4\n\ + adds r1, r4\n\ + subs r6, 0x1\n\ + cmp r6, 0\n\ + bge _080B40B4\n\ + add sp, 0x4\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_080B40D8: .4byte gMenuWindow\n\ +_080B40DC: .4byte 0x000003ff\n\ +_080B40E0: .4byte 0x040000d4\n\ +_080B40E4: .4byte 0x800000f0\n\ + .syntax divided"); +} +#endif + +void sub_80B40E8(u8 taskId) // Mart_DoCursorAction +{ + if (!gPaletteFade.active) + { + if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_UP) // only up can be pressed + { + if (gMartInfo.cursor == 0) + { + if (gMartInfo.choicesAbove == 0) // if there are no choices above, dont bother + return; + + PlaySE(SE_SELECT); + gMartInfo.choicesAbove--; // since cursor is at the top and there are choices above the top, scroll the menu up by updating choicesAbove. + sub_80B3F88(); + sub_80B39D0(0, 0, 0); + sub_80B3A70(); + sub_80B32A4(); + } + else // if the cursor is not 0, choicesAbove cannot be updated yet since the cursor is at the top of the menu, so update cursor. + { + PlaySE(SE_SELECT); + gMartInfo.cursor = MoveMenuCursor(-1); // move cursor up + sub_80B3A70(); + } + } + else if ((gMain.newAndRepeatedKeys & DPAD_ANY) == DPAD_DOWN) // only down can be pressed + { + if (gMartInfo.cursor == 7) // are you at the bottom of the menu? + { + if (gMartInfo.choicesAbove + gMartInfo.cursor == gMartInfo.itemCount) // are you at cancel? + return; + + PlaySE(SE_SELECT); + gMartInfo.choicesAbove++; + sub_80B403C(); + sub_80B39D0(7, 7, 0); + sub_80B3A70(); + sub_80B32A4(); + } + else if (gMartInfo.cursor != gMartInfo.itemCount) + { + PlaySE(SE_SELECT); + gMartInfo.cursor = MoveMenuCursor(1); + sub_80B3A70(); + } + } + else if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + + if (gMartInfo.choicesAbove + gMartInfo.cursor != gMartInfo.itemCount) // did you not hit CANCEL? + { + PauseVerticalScrollIndicator(0); + PauseVerticalScrollIndicator(1); + sub_80F979C(1, 1); + sub_80B39D0(gMartInfo.cursor, gMartInfo.cursor, 1); + HandleDestroyMenuCursors(); + MenuZeroFillWindowRect(0, 0xC, 0xD, 0x13); + + if (gMartInfo.martType == MART_TYPE_0) + { + gMartTotalCost = (ItemId_GetPrice(gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor]) >> GetPriceReduction(1)); // set 1x price + if (!IsEnoughMoney(gSaveBlock1.money, gMartTotalCost)) + { + DisplayItemMessageOnField(taskId, gOtherText_NotEnoughMoney, sub_80B3BD0, 0xC3E1); // tail merge + } + else // _080B42BA + { + CopyItemName(gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor], gStringVar1); + StringExpandPlaceholders(gStringVar4, gOtherText_HowManyYouWant); + DisplayItemMessageOnField(taskId, gStringVar4, sub_80B3EFC, 0xC3E1); + } + } + else // _080B428C + { + gMartTotalCost = gDecorations[gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor]].price; + + if (!IsEnoughMoney(gSaveBlock1.money, gMartTotalCost)) + { + DisplayItemMessageOnField(taskId, gOtherText_NotEnoughMoney, sub_80B3BD0, 0xC3E1); // tail merge + } + else + { + StringCopy(gStringVar1, gDecorations[gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor]].name); + ConvertIntToDecimalStringN(gStringVar2, gMartTotalCost, 0, 0x8); + + if (gMartInfo.martType == MART_TYPE_1) + { + StringExpandPlaceholders(gStringVar4, gOtherText_ThatWillBe2); + } + else + { + StringExpandPlaceholders(gStringVar4, gOtherText_ThatWillBe3); + } + DisplayItemMessageOnField(taskId, gStringVar4, sub_80B3D38, 0xC3E1); + } + } + } + else + sub_80B43F0(taskId); + } + else if (gMain.newKeys & B_BUTTON) // go back to buy/sell/exit menu + { + PlaySE(SE_SELECT); + sub_80B43F0(taskId); + } + } +} + +void sub_80B4378(u8 taskId) +{ + MenuZeroFillWindowRect(0, 0xE, 0x1D, 0x13); + MenuZeroFillWindowRect(0, 0xA, 0xD, 0xD); + sub_80A3FA0(gBGTilemapBuffers[1], 0x1, 0xB, 0xC, 0x2, 0); + sub_80B3420(); + sub_80B3764(6, 7); + sub_80B37EC(); + StartVerticalScrollIndicators(0); + StartVerticalScrollIndicators(1); + sub_80B32A4(); + gTasks[taskId].func = sub_80B40E8; +} + +void sub_80B43F0(u8 taskId) +{ + gFieldCallback = sub_80B3050; + BeginNormalPaletteFade(-1, 0, 0, 0x10, 0); + gTasks[taskId].func = Task_ExitBuyMenu; +} + +void Task_ExitBuyMenu(u8 taskId) +{ + if (!gPaletteFade.active) + { + RemoveMoneyLabelObject(0, 0); + BuyMenuFreeMemory(); + SetMainCallback2(c2_exit_to_overworld_2_switch); + DestroyTask(taskId); + } +} + +void sub_80B4470(u8 taskId) +{ + u16 i; + + for (i = 0; i < 3; i++) + { + if (gUnknown_02038724[i].itemId == gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor] + && gUnknown_02038724[i].quantity != 0) + { + if (gUnknown_02038724[i].quantity + gTasks[taskId].data[1] > 255) + gUnknown_02038724[i].quantity = 255; + else + gUnknown_02038724[i].quantity += gTasks[taskId].data[1]; + return; + } + } + + if (gUnknown_02038730 < 3) + { + gUnknown_02038724[gUnknown_02038730].itemId = gMartInfo.itemList[gMartInfo.choicesAbove + gMartInfo.cursor]; + gUnknown_02038724[gUnknown_02038730].quantity = gTasks[taskId].data[1]; + gUnknown_02038730++; + } +} + +void ClearItemPurchases(void) +{ + gUnknown_02038730 = 0; + ClearItemSlots(gUnknown_02038724, 3); +} + +void CreatePokemartMenu(u16 *itemList) +{ + CreateShopMenu(MART_TYPE_0); + SetShopItemsForSale(itemList); + ClearItemPurchases(); + SetShopMenuCallback(EnableBothScriptContexts); +} + +void CreateDecorationShop1Menu(u16 *itemList) +{ + CreateShopMenu(MART_TYPE_1); + SetShopItemsForSale(itemList); + SetShopMenuCallback(EnableBothScriptContexts); +} + +void CreateDecorationShop2Menu(u16 *itemList) +{ + CreateShopMenu(MART_TYPE_2); + SetShopItemsForSale(itemList); + SetShopMenuCallback(EnableBothScriptContexts); +} + +void sub_80B45B4(u8 taskId, const s16 *list, u16 c) +{ + s16 r5 = gTasks[taskId].data[4] - 1; + s16 r3 = gTasks[taskId].data[5] - 1; + s16 r4 = gTasks[taskId].data[1]; + s16 y; + s16 x; + + if (gTasks[taskId].data[2] == 0) + { + for (y = 0; y < 3; y++) + { + for (x = 0; x < 3; x++) + { + s16 metatileId = MapGridGetMetatileIdAt(r5 + x, r3 + y); + + if (list[r4] == metatileId) + { + if (r4 != 2) + MapGridSetMetatileIdAt(r5 + x, r3 + y, c | list[r4 + 1]); + else + MapGridSetMetatileIdAt(r5 + x, r3 + y, c | list[0]); + } + } + } + } + else + { + for (y = 0; y < 3; y++) + { + for (x = 0; x < 3; x++) + { + s16 metatileId = MapGridGetMetatileIdAt(r5 + x, r3 + y); + + if (list[2 - r4] == metatileId) + { + if (r4 != 2) + MapGridSetMetatileIdAt(r5 + x, r3 + y, c | list[1 - r4]); + else + MapGridSetMetatileIdAt(r5 + x, r3 + y, c | list[2]); + } + } + } + } +} + +static const u16 gUnknown_083CC714[] = {0x284, 0x282, 0x280}; +static const u16 gUnknown_083CC71A[] = {0x285, 0x283, 0x281}; +static const u16 gUnknown_083CC720[] = {0x28C, 0x28A, 0x288}; +static const u16 gUnknown_083CC726[] = {0x28D, 0x28B, 0x289}; +static const u16 gUnknown_083CC72C[] = {0x2A0, 0x2A2, 0x2A4}; +static const u16 gUnknown_083CC732[] = {0x2A1, 0x2A3, 0x2A5}; +static const u16 gUnknown_083CC738[] = {0x2A8, 0x2AA, 0x2AC}; + +void sub_80B4710(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + + data[3] = 1; + + switch (data[0]) + { + case 0: + sub_80B45B4(taskId, gUnknown_083CC714, 0); + break; + case 1: + sub_80B45B4(taskId, gUnknown_083CC71A, 0); + break; + case 2: + sub_80B45B4(taskId, gUnknown_083CC720, 0xC00); + break; + case 3: + sub_80B45B4(taskId, gUnknown_083CC726, 0); + break; + case 4: + sub_80B45B4(taskId, gUnknown_083CC72C, 0xC00); + break; + case 5: + sub_80B45B4(taskId, gUnknown_083CC732, 0); + break; + case 6: + sub_80B45B4(taskId, gUnknown_083CC738, 0); + break; + } + + data[0] = (data[0] + 1) & 7; + if (!data[0]) + { + DrawWholeMapView(); + data[1] = (data[1] + 1) % 3; + data[3] = 0; + } +} + +u8 sub_80B47D8(u16 var) +{ + u8 taskId = CreateTask(sub_80B4710, 0); + s16 *data = gTasks[taskId].data; + + PlayerGetDestCoords(&data[4], &data[5]); + data[0] = 0; + data[1] = 0; + data[2] = var; + sub_80B4710(taskId); + return taskId; +} + +void sub_80B4824(u8 var) +{ + gUnknown_02038731 = sub_80B47D8(var); +} + +void sub_80B483C(void) +{ + DestroyTask(gUnknown_02038731); +} + +bool8 sub_80B4850(void) +{ + if (gTasks[gUnknown_02038731].data[3] == 0 && gTasks[gUnknown_02038731].data[1] == 2) + return FALSE; + else + return TRUE; +} diff --git a/src/field/use_pokeblock.c b/src/field/use_pokeblock.c index 3aa2f1fa5..0c8f59959 100644 --- a/src/field/use_pokeblock.c +++ b/src/field/use_pokeblock.c @@ -1,5 +1,6 @@ // // Created by Scott Norton on 5/31/17. +// Modified by Dizzy Egg on 8/15/17. // #include "global.h" @@ -16,8 +17,6 @@ #include "sound.h" #include "songs.h" #include "pokeblock.h" -#include "pokeblock_feed.h" -#include "use_pokeblock.h" #define GFX_TAG_CONDITIONUPDOWN 0 @@ -29,7 +28,7 @@ const u16 ConditionUpDownPalette[] = INCBIN_U16("graphics/misc/condition_up_down const u32 ConditionUpDownTiles[] = INCBIN_U32("graphics/misc/condition_up_down.4bpp"); #endif -const u32 gUnknown_08406118[] = { +static const u32 sContestStatsMonData[] = { MON_DATA_COOL, MON_DATA_TOUGH, MON_DATA_SMART, @@ -37,11 +36,11 @@ const u32 gUnknown_08406118[] = { MON_DATA_BEAUTY }; -const u8 gUnknown_0840612C[] = { +static const u8 gUnknown_0840612C[] = { 0, 4, 3, 2, 1 }; -const u8 *const gUnknown_08406134[] = { +static const u8 *const sContextStatNames[] = { OtherText_Coolness, OtherText_Toughness, OtherText_Smartness, @@ -49,18 +48,18 @@ const u8 *const gUnknown_08406134[] = { OtherText_Beauty }; -const struct SpriteSheet gSpriteSheet_ConditionUpDown = { +static const struct SpriteSheet gSpriteSheet_ConditionUpDown = { (u8 *)ConditionUpDownTiles, sizeof ConditionUpDownTiles, GFX_TAG_CONDITIONUPDOWN }; -const struct SpritePalette gSpritePalette_ConditionUpDown = { +static const struct SpritePalette gSpritePalette_ConditionUpDown = { ConditionUpDownPalette, GFX_TAG_CONDITIONUPDOWN }; -const s16 gUnknown_08406158[][2] = { +static const s16 gUnknown_08406158[][2] = { {0x9c, 0x1e}, {0x75, 0x35}, {0x75, 0x70}, @@ -68,28 +67,28 @@ const s16 gUnknown_08406158[][2] = { {0xc5, 0x35} }; -const struct OamData gOamData_840616C = { +static const struct OamData gOamData_840616C = { .shape = 1, .size = 2, .priority = 1 }; -const union AnimCmd gSpriteAnim_8406174[] = { +static const union AnimCmd gSpriteAnim_8406174[] = { ANIMCMD_FRAME(0, 5), ANIMCMD_END }; -const union AnimCmd gSpriteAnim_840617C[] = { +static const union AnimCmd gSpriteAnim_840617C[] = { ANIMCMD_FRAME(8, 5), ANIMCMD_END }; -const union AnimCmd *const gSpriteAnimTable_8406184[] = { +static const union AnimCmd *const gSpriteAnimTable_8406184[] = { gSpriteAnim_8406174, gSpriteAnim_840617C }; -const struct SpriteTemplate gSpriteTemplate_840618C = { +static const struct SpriteTemplate gSpriteTemplate_840618C = { GFX_TAG_CONDITIONUPDOWN, GFX_TAG_CONDITIONUPDOWN, &gOamData_840616C, @@ -99,47 +98,44 @@ const struct SpriteTemplate gSpriteTemplate_840618C = { SpriteCallbackDummy }; -asm(".text\n" - ".include \"constants/gba_constants.inc\""); - static EWRAM_DATA struct UnkPokenavStruct_Sub1 *gUnknown_02039304 = NULL; static EWRAM_DATA MainCallback gUnknown_02039308 = NULL; static EWRAM_DATA struct Pokeblock *gUnknown_0203930C = NULL; -EWRAM_DATA u8 gUnknown_02039310 = 0; -EWRAM_DATA s16 gUnknown_02039312 = 0; +EWRAM_DATA u8 gPokeblockMonID = 0; +EWRAM_DATA s16 gPokeblockGain = 0; extern u16 gKeyRepeatStartDelay; extern u16 gScriptItemId; // FIXME: remove after merge of #349 Pokeblock -void launch_c3_walk_stairs_and_run_once(void (*const)(void)); -void sub_81361E4(void); -void sub_813622C(void); -void sub_8136244(void); -void sub_8136264(void); -void sub_8136294(void); -void sub_81365A0(void); -void sub_81365C8(void); -void sub_8136638(void); -void sub_81368A4(void); +static void launch_c3_walk_stairs_and_run_once(void (*const)(void)); +static void sub_81361E4(void); +static void sub_813622C(void); +static void sub_8136244(void); +static void sub_8136264(void); +static void sub_8136294(void); +static void sub_81365A0(void); +static void sub_81365C8(void); +static void sub_8136638(void); +static void sub_81368A4(void); void sub_8089668(void); -void sub_8136B44(void); -u8 sub_81370E4(u8); -void sub_8136BB8(void); -s8 sub_8136C40(void); -bool8 sub_8137058(void); -void sub_8136D60(void); -void sub_8136808(void); -void sub_8136D8C(void); -u8 sub_81370A4(u8); -void sub_81369CC(void); -void sub_8136EF0(void); -void sub_8137138(void); -void sub_8136C6C(void); -bool8 sub_8136D00(void); -void sub_8136DC0(u8 *, u8, s16); -void sub_8136DA0(const u8 *); -void sub_8136F74(struct Pokeblock *, struct Pokemon *); -void sub_81371DC(struct Sprite *); +static void sub_8136B44(void); +static u8 sub_81370E4(u8); +static void sub_8136BB8(void); +static s8 sub_8136C40(void); +static bool8 sub_8137058(void); +static void sub_8136D60(void); +static void sub_8136808(void); +static void sub_8136D8C(void); +static u8 sub_81370A4(u8); +static void sub_81369CC(void); +static void sub_8136EF0(void); +static void sub_8137138(void); +static void sub_8136C6C(void); +static bool8 sub_8136D00(void); +static void Pokeblock_BufferEnhancedStatText(u8 *, u8, s16); +static void Pokeblock_MenuWindowTextPrint(const u8 *); +static void sub_8136F74(struct Pokeblock *, struct Pokemon *); +static void sub_81371DC(struct Sprite *); void sub_8136130(struct Pokeblock *pokeblock, MainCallback callback) { @@ -151,18 +147,18 @@ void sub_8136130(struct Pokeblock *pokeblock, MainCallback callback) SetMainCallback2(sub_8136244); } -void sub_8136174(void) +static void sub_8136174(void) { gUnknown_02039304->pokeblock = gUnknown_0203930C; gUnknown_02039304->callback = gUnknown_02039308; - gUnknown_02039310 = sub_81370E4(gUnknown_02039310); - gUnknown_02039304->unk56 = gUnknown_02039310 < 4 ? 0 : 1; + gPokeblockMonID = sub_81370E4(gPokeblockMonID); + gUnknown_02039304->unk56 = gPokeblockMonID < 4 ? 0 : 1; gUnknown_083DFEC4->unkD162[0] = 2; launch_c3_walk_stairs_and_run_once(sub_8136294); SetMainCallback2(sub_81361E4); } -void sub_81361E4(void) +static void sub_81361E4(void) { gUnknown_02039304->unk0(); AnimateSprites(); @@ -176,7 +172,7 @@ void sub_81361E4(void) } } -void sub_813622C(void) +static void sub_813622C(void) { sub_81368A4(); AnimateSprites(); @@ -184,7 +180,7 @@ void sub_813622C(void) UpdatePaletteFade(); } -void sub_8136244(void) +static void sub_8136244(void) { gUnknown_02039304->unk0(); AnimateSprites(); @@ -192,7 +188,7 @@ void sub_8136244(void) UpdatePaletteFade(); } -void sub_8136264(void) +static void sub_8136264(void) { LoadOam(); ProcessSpriteCopyRequests(); @@ -201,13 +197,13 @@ void sub_8136264(void) sub_8089668(); } -void launch_c3_walk_stairs_and_run_once(void (*const func)(void)) +static void launch_c3_walk_stairs_and_run_once(void (*const func)(void)) { gUnknown_02039304->unk0 = func; gUnknown_02039304->unk50 = 0; } -void sub_8136294(void) +static void sub_8136294(void) { bool32 c1LinkRelatedActive; switch (gUnknown_02039304->unk50) @@ -346,7 +342,7 @@ void sub_8136294(void) } } -void sub_81365A0(void) +static void sub_81365A0(void) { while (!gUnknown_02039304->unk55) { @@ -354,7 +350,7 @@ void sub_81365A0(void) } } -void sub_81365C8(void) +static void sub_81365C8(void) { switch (gUnknown_02039304->unk50) { @@ -374,7 +370,7 @@ void sub_81365C8(void) } } -void sub_8136638(void) +static void sub_8136638(void) { switch (gUnknown_02039304->unk50) { @@ -464,12 +460,12 @@ void sub_8136638(void) } } -void sub_8136808(void) +static void sub_8136808(void) { switch (gUnknown_02039304->unk50) { case 0: - gUnknown_02039310 = sub_81370A4(gUnknown_083DFEC4->unk87DC); + gPokeblockMonID = sub_81370A4(gUnknown_083DFEC4->unk87DC); gUnknown_02039308 = gUnknown_02039304->callback; gUnknown_0203930C = gUnknown_02039304->pokeblock; BeginNormalPaletteFade(-1, 0, 0, 16, 0); @@ -479,18 +475,18 @@ void sub_8136808(void) if (!gPaletteFade.active) { gMain.savedCallback = sub_8136174; - SetMainCallback2(sub_8147ADC); + SetMainCallback2(CB2_PreparePokeblockFeedScene); } break; } } -void sub_81368A4(void) +static void sub_81368A4(void) { switch (gUnknown_02039304->unk50) { case 0: - if (gUnknown_083DFEC4->unk87DC != gUnknown_02039310) + if (gUnknown_083DFEC4->unk87DC != gPokeblockMonID) { sub_80F5060(gUnknown_02039304->unk56); gUnknown_02039304->unk50++; @@ -538,7 +534,7 @@ void sub_81368A4(void) } } -void sub_81369CC(void) +static void sub_81369CC(void) { switch (gUnknown_02039304->unk50) { @@ -578,14 +574,14 @@ void sub_81369CC(void) case 5: if (gMain.newKeys & (A_BUTTON | B_BUTTON) && !sub_8136D00()) { - sub_810CA6C((u8)gScriptItemId); + PokeblockClearIfExists((u8)gScriptItemId); launch_c3_walk_stairs_and_run_once(sub_8136B44); } break; } } -void sub_8136B44(void) +static void sub_8136B44(void) { switch (gUnknown_02039304->unk50) { @@ -609,7 +605,7 @@ void sub_8136B44(void) } } -void sub_8136BB8(void) +static void sub_8136BB8(void) { GetMonData(&gPlayerParty[sub_81370A4(gUnknown_083DFEC4->unk87DC)], MON_DATA_NICKNAME, gUnknown_02039304->stringBuffer); StringGetEnd10(gUnknown_02039304->stringBuffer); @@ -621,7 +617,7 @@ void sub_8136BB8(void) MoveMenuCursor(0); } -s8 sub_8136C40(void) +static s8 sub_8136C40(void) { s8 retval = ProcessMenuInputNoWrap(); if ((u8)(retval + 1) < 3) @@ -632,124 +628,68 @@ s8 sub_8136C40(void) return retval; } -void sub_8136C6C(void) +static void sub_8136C6C(void) { BasicInitMenuWindow(&gWindowConfig_81E709C); MenuDrawTextWindow(0, 16, 29, 19); for (gUnknown_02039304->unk53 = 0; gUnknown_02039304->unk53 < 5 && gUnknown_02039304->unk61[gUnknown_02039304->unk53] == 0; gUnknown_02039304->unk53++); if (gUnknown_02039304->unk53 < 5) { - sub_8136DC0(gUnknown_02039304->stringBuffer, gUnknown_02039304->unk53, gUnknown_02039304->unk61[gUnknown_02039304->unk53]); + Pokeblock_BufferEnhancedStatText(gUnknown_02039304->stringBuffer, gUnknown_02039304->unk53, gUnknown_02039304->unk61[gUnknown_02039304->unk53]); } else { - sub_8136DC0(gUnknown_02039304->stringBuffer, gUnknown_02039304->unk53, 0); + Pokeblock_BufferEnhancedStatText(gUnknown_02039304->stringBuffer, gUnknown_02039304->unk53, 0); } - sub_8136DA0(gUnknown_02039304->stringBuffer); + Pokeblock_MenuWindowTextPrint(gUnknown_02039304->stringBuffer); } -#ifdef NONMATCHING -bool8 sub_8136D00(void) +static bool8 sub_8136D00(void) { while (1) { - if (++gUnknown_02039304->unk53 >= 5) + gUnknown_02039304->unk53++; + if (gUnknown_02039304->unk53 < 5) { - break; + if (gUnknown_02039304->unk61[gUnknown_02039304->unk53] != 0) + break; } - if (gUnknown_02039304->unk61[gUnknown_02039304->unk53] != 0) + else { - sub_8136DC0(gUnknown_02039304->stringBuffer, gUnknown_02039304->unk53, gUnknown_02039304->unk61[gUnknown_02039304->unk53]); - sub_8136DA0(gUnknown_02039304->stringBuffer); - return TRUE; + gUnknown_02039304->unk53 = 5; + return FALSE; } } - gUnknown_02039304->unk53 = 5; - return FALSE; + Pokeblock_BufferEnhancedStatText(gUnknown_02039304->stringBuffer, gUnknown_02039304->unk53, gUnknown_02039304->unk61[gUnknown_02039304->unk53]); + Pokeblock_MenuWindowTextPrint(gUnknown_02039304->stringBuffer); + return TRUE; } -#else -__attribute__((naked)) -bool8 sub_8136D00(void) -{ - asm_unified("\tpush {r4,r5,lr}\n" - "\tldr r4, _08136D30 @ =gUnknown_02039304\n" - "\tadds r3, r4, 0\n" - "\tmovs r5, 0x5\n" - "_08136D08:\n" - "\tldr r0, [r3]\n" - "\tadds r0, 0x53\n" - "\tldrb r1, [r0]\n" - "\tadds r1, 0x1\n" - "\tstrb r1, [r0]\n" - "\tldr r2, [r3]\n" - "\tadds r1, r2, 0\n" - "\tadds r1, 0x53\n" - "\tldrb r0, [r1]\n" - "\tcmp r0, 0x4\n" - "\tbhi _08136D34\n" - "\tadds r0, r2, 0\n" - "\tadds r0, 0x61\n" - "\tldrb r1, [r1]\n" - "\tadds r0, r1\n" - "\tldrb r0, [r0]\n" - "\tcmp r0, 0\n" - "\tbne _08136D3A\n" - "\tb _08136D08\n" - "\t.align 2, 0\n" - "_08136D30: .4byte gUnknown_02039304\n" - "_08136D34:\n" - "\tstrb r5, [r1]\n" - "\tmovs r0, 0\n" - "\tb _08136D5A\n" - "_08136D3A:\n" - "\tldr r2, [r4]\n" - "\tadds r0, r2, 0\n" - "\tadds r0, 0x10\n" - "\tadds r1, r2, 0\n" - "\tadds r1, 0x53\n" - "\tldrb r1, [r1]\n" - "\tadds r2, 0x61\n" - "\tadds r2, r1\n" - "\tldrb r2, [r2]\n" - "\tbl sub_8136DC0\n" - "\tldr r0, [r4]\n" - "\tadds r0, 0x10\n" - "\tbl sub_8136DA0\n" - "\tmovs r0, 0x1\n" - "_08136D5A:\n" - "\tpop {r4,r5}\n" - "\tpop {r1}\n" - "\tbx r1"); -} -#endif -void sub_8136D60(void) +static void sub_8136D60(void) { BasicInitMenuWindow(&gWindowConfig_81E709C); MenuDrawTextWindow(0, 16, 29, 19); MenuPrint(gOtherText_WontEat, 1, 17); } -void sub_8136D8C(void) +static void sub_8136D8C(void) { MenuZeroFillScreen(); BasicInitMenuWindow(&gWindowConfig_81E7080); } -void sub_8136DA0(const u8 *message) +static void Pokeblock_MenuWindowTextPrint(const u8 *message) { MenuDrawTextWindow(0, 16, 29, 19); MenuPrint(message, 1, 17); } #ifdef NONMATCHING -void sub_8136DC0(u8 *dest, u8 a1, s16 a2) +static void Pokeblock_BufferEnhancedStatText(u8 *dest, u8 statID, s16 a2) { - u16 v0 = a2; if (a2 != 0) { - if ((v0 = max(a2, 0)) == 0); - StringCopy(dest, gUnknown_08406134[a1]); + StringCopy(dest, sContextStatNames[statID]); StringAppend(dest, gOtherText_WasEnhanced); } else @@ -759,7 +699,7 @@ void sub_8136DC0(u8 *dest, u8 a1, s16 a2) } #else __attribute__((naked)) -void sub_8136DC0(u8 *dest, u8 a1, s16 a2) +static void Pokeblock_BufferEnhancedStatText(u8 *dest, u8 a1, s16 a2) { asm_unified("\tpush {r4,lr}\n" "\tadds r4, r0, 0\n" @@ -775,7 +715,7 @@ void sub_8136DC0(u8 *dest, u8 a1, s16 a2) "\tmovs r0, 0\n" "_08136DD8:\n" "\tlsls r0, 16\n" - "\tldr r1, _08136DF4 @ =gUnknown_08406134\n" + "\tldr r1, _08136DF4 @ =sContextStatNames\n" "\tlsls r0, r3, 2\n" "\tadds r0, r1\n" "\tldr r1, [r0]\n" @@ -786,7 +726,7 @@ void sub_8136DC0(u8 *dest, u8 a1, s16 a2) "\tbl StringAppend\n" "\tb _08136E04\n" "\t.align 2, 0\n" - "_08136DF4: .4byte gUnknown_08406134\n" + "_08136DF4: .4byte sContextStatNames\n" "_08136DF8: .4byte gOtherText_WasEnhanced\n" "_08136DFC:\n" "\tldr r1, _08136E0C @ =gOtherText_NothingChanged\n" @@ -801,16 +741,16 @@ void sub_8136DC0(u8 *dest, u8 a1, s16 a2) } #endif -void sub_8136E10(struct Pokemon *pokemon, u8 *data) +static void Pokeblock_GetMonContestStats(struct Pokemon *pokemon, u8 *data) { u16 i; for (i=0; i<5; i++) { - data[i] = GetMonData(pokemon, gUnknown_08406118[i]); + data[i] = GetMonData(pokemon, sContestStatsMonData[i]); } } -void sub_8136E40(struct Pokeblock *pokeblock, struct Pokemon *pokemon) +static void sub_8136E40(struct Pokeblock *pokeblock, struct Pokemon *pokemon) { u16 i; s16 cstat; @@ -820,14 +760,14 @@ void sub_8136E40(struct Pokeblock *pokeblock, struct Pokemon *pokemon) sub_8136F74(pokeblock, pokemon); for (i=0; i<5; i++) { - data = GetMonData(pokemon, gUnknown_08406118[i]); + data = GetMonData(pokemon, sContestStatsMonData[i]); cstat = data + gUnknown_02039304->unk66[i]; if (cstat < 0) cstat = 0; if (cstat > 255) cstat = 255; data = cstat; - SetMonData(pokemon, gUnknown_08406118[i], &data); + SetMonData(pokemon, sContestStatsMonData[i], &data); } cstat = (u8)GetMonData(pokemon, MON_DATA_SHEEN); cstat = cstat + pokeblock->feel; @@ -838,21 +778,21 @@ void sub_8136E40(struct Pokeblock *pokeblock, struct Pokemon *pokemon) } } -void sub_8136EF0(void) +static void sub_8136EF0(void) { u16 i; struct Pokemon *pokemon = gPlayerParty; pokemon += gUnknown_083DFEC4->unk893c[gUnknown_083DFEC4->unk87DC].partyIdx; - sub_8136E10(pokemon, gUnknown_02039304->unk57); + Pokeblock_GetMonContestStats(pokemon, gUnknown_02039304->unk57); sub_8136E40(gUnknown_02039304->pokeblock, pokemon); - sub_8136E10(pokemon, gUnknown_02039304->unk5c); + Pokeblock_GetMonContestStats(pokemon, gUnknown_02039304->unk5c); for (i=0; i<5; i++) { gUnknown_02039304->unk61[i] = gUnknown_02039304->unk5c[i] - gUnknown_02039304->unk57[i]; } } -void sub_8136F74(struct Pokeblock *pokeblock, struct Pokemon *pokemon) +static void sub_8136F74(struct Pokeblock *pokeblock, struct Pokemon *pokemon) { s8 direction; s8 i; @@ -864,9 +804,9 @@ void sub_8136F74(struct Pokeblock *pokeblock, struct Pokemon *pokemon) gUnknown_02039304->unk66[2] = pokeblock->bitter; gUnknown_02039304->unk66[3] = pokeblock->sweet; gUnknown_02039304->unk66[4] = pokeblock->dry; - if (gUnknown_02039312 > 0) + if (gPokeblockGain > 0) direction = 1; - else if (gUnknown_02039312 < 0) + else if (gPokeblockGain < 0) direction = -1; else return; @@ -884,7 +824,7 @@ void sub_8136F74(struct Pokeblock *pokeblock, struct Pokemon *pokemon) } } -bool8 sub_8137058(void) +static bool8 sub_8137058(void) { struct Pokemon *pokemon = gPlayerParty; pokemon += gUnknown_083DFEC4->unk893c[gUnknown_083DFEC4->unk87DC].partyIdx; @@ -893,7 +833,7 @@ bool8 sub_8137058(void) return FALSE; } -u8 sub_81370A4(u8 a0) +static u8 sub_81370A4(u8 a0) { u8 i; for (i=0; i<PARTY_SIZE; i++) @@ -908,7 +848,7 @@ u8 sub_81370A4(u8 a0) return 0; } -u8 sub_81370E4(u8 a0) +static u8 sub_81370E4(u8 a0) { u8 ct; u8 i; @@ -927,7 +867,7 @@ u8 sub_8137124(u8 a0) return sub_81370A4(a0); } -void sub_8137138(void) +static void sub_8137138(void) { u16 flavor; u8 spriteidx; @@ -951,7 +891,7 @@ void sub_8137138(void) } } -void sub_81371DC(struct Sprite *sprite) +static void sub_81371DC(struct Sprite *sprite) { if (sprite->data0 <= 5) sprite->pos2.y -= 2; diff --git a/src/field/wild_encounter.c b/src/field/wild_encounter.c index 96f47c067..7001c2eaa 100644 --- a/src/field/wild_encounter.c +++ b/src/field/wild_encounter.c @@ -3161,7 +3161,7 @@ static u8 PickWildMonNature(void) } for (i = 0; i < 25; i++) { - if (sub_810CAE4(natures[i], safariPokeblock) > 0) + if (PokeblockGetGain(natures[i], safariPokeblock) > 0) return natures[i]; } } diff --git a/src/pokemon/learn_move.c b/src/pokemon/learn_move.c new file mode 100644 index 000000000..51de68171 --- /dev/null +++ b/src/pokemon/learn_move.c @@ -0,0 +1,1081 @@ +#include "global.h" +#include "data2.h" +#include "field_fadetransition.h" +#include "main.h" +#include "menu.h" +#include "menu_cursor.h" +#include "palette.h" +#include "pokemon.h" +#include "rom4.h" +#include "script.h" +#include "songs.h" +#include "sound.h" +#include "sprite.h" +#include "string_util.h" +#include "strings.h" +#include "strings2.h" +#include "task.h" +#include "trig.h" + +extern u8 ewram[]; +extern u16 gSpecialVar_0x8004; +extern u16 gSpecialVar_0x8005; +extern u8 gTileBuffer[]; + +struct ContestMove +{ + u8 effect; + u8 contestCategory:3; + u8 comboStarterId; + u8 comboMoves[4]; +}; + +struct ContestEffect +{ + u8 effectType; + u8 appeal; + u8 jam; +}; + +extern const struct ContestMove gContestMoves[]; +extern const struct ContestEffect gContestEffects[]; +extern const struct WindowConfig gWindowConfig_81E6CE4; +extern const struct WindowConfig gWindowConfig_81E7240; +extern const u8 *const gUnknown_083CADD4[]; +extern const u8 *const gMoveDescriptions[]; +extern const u8 gTypeNames[][7]; +extern const u8 *const gUnknown_083CAF70[]; + +#ifdef GERMAN +extern const u8 deuOtherText_ForgotAndLearned[]; +#endif + +extern void sub_809D9F0(struct Pokemon *, u8, u8, void *, u32); + +struct LearnMoveStruct +{ + u8 state; + u8 filler1; + u8 unk2; + u8 spriteIDs[20]; + u8 filler17[1]; + u8 unk18; + u8 unk19; + u8 numMenuChoices; + u8 menuSelection; + u8 unk1C; + bool8 unk1D; + u8 unk1E; + u8 filler1F; + /*0x020*/ u16 movesToLearn[20]; + u8 filler48[0x52-0x48]; + u8 moveNames[6][0x19]; + u8 fillerE8[0x2C3-0xE8]; + bool8 unk2C3; + bool8 showContestInfo; + /*0x2C5*/ u8 partyMon; + u8 unk2C6; +}; + +static struct LearnMoveStruct *sLearnMoveStruct; + +const u16 gDexArrows_Pal[] = INCBIN_U16("graphics/pokedex/arrows.gbapal"); + +const u8 gDexArrows_Gfx[] = INCBIN_U8("graphics/pokedex/arrows.4bpp"); + +const u8 gUnknown_08402CF8[][4] = +{ + { 0, 0, 9, 13}, + {10, 0, 29, 7}, + { 2, 14, 27, 19}, + {10, 8, 29, 13}, +}; + +struct UnknownStruct1 +{ + const u8 *unk0; + u8 unk4; + u8 unk5; + u8 unk6; +}; + +const struct UnknownStruct1 gUnknown_08402D08[][4] = +{ + { + {OtherText_Battle, 1, 1, 0}, + {OtherText_Power, 1, 4, 1}, + {OtherText_Accuracy, 1, 9, 2}, + {NULL, 0, 0, 0}, + }, + { + {OtherText_Contest, 1, 1, 0}, + {OtherText_Appeal, 1, 4, 1}, + {OtherText_Jam, 1, 9, 2}, + {NULL, 0, 0, 0}, + }, +}; + +// XXX: What are these for? +const u32 unkDataFF00FFEF = 0xFF00FFEF; +const u8 *const gTileBuffer_ = gTileBuffer; + +const struct OamData gOamData_8402D50 = {.shape = 0}; +const struct OamData gOamData_8402D58 = {.shape = 2}; +const struct OamData gOamData_8402D60 = {.shape = 1}; + +const union AnimCmd gSpriteAnim_8402D68[] = +{ + ANIMCMD_FRAME(2, 5), + ANIMCMD_END, +}; + +const union AnimCmd gSpriteAnim_8402D70[] = +{ + ANIMCMD_FRAME(0, 5), + ANIMCMD_END, +}; + +const union AnimCmd *const gSpriteAnimTable_8402D78[] = +{ + gSpriteAnim_8402D68, + gSpriteAnim_8402D70, +}; + +const struct SpriteSheet gUnknown_08402D80 = {gDexArrows_Gfx, sizeof(gDexArrows_Gfx), 5525}; +const struct SpritePalette gUnknown_08402D88 = {gDexArrows_Pal, 5526}; + +void sub_8133300(struct Sprite *); +const struct SpriteTemplate gSpriteTemplate_8402D90 = +{ + .tileTag = 5525, + .paletteTag = 5526, + .oam = &gOamData_8402D58, + .anims = gSpriteAnimTable_8402D78, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_8133300, +}; + +const union AnimCmd gSpriteAnim_8402DA8[] = +{ + ANIMCMD_FRAME(4, 5), + ANIMCMD_END, +}; + +const union AnimCmd gSpriteAnim_8402DB0[] = +{ + ANIMCMD_FRAME(6, 5), + ANIMCMD_END, +}; + +const union AnimCmd *const gSpriteAnimTable_8402DB8[] = +{ + gSpriteAnim_8402DA8, + gSpriteAnim_8402DB0, +}; + +const struct SpriteTemplate gSpriteTemplate_8402DC0 = +{ + .tileTag = 5525, + .paletteTag = 5526, + .oam = &gOamData_8402D60, + .anims = gSpriteAnimTable_8402DB8, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_8133300, +}; + +const union AnimCmd gSpriteAnim_8402DD8[] = +{ + ANIMCMD_FRAME(8, 5), + ANIMCMD_END, +}; + +const union AnimCmd gSpriteAnim_8402DE0[] = +{ + ANIMCMD_FRAME(9, 5), + ANIMCMD_END, +}; + +const union AnimCmd gSpriteAnim_8402DE8[] = +{ + ANIMCMD_FRAME(10, 5), + ANIMCMD_END, +}; + +const union AnimCmd gSpriteAnim_8402DF0[] = +{ + ANIMCMD_FRAME(11, 5), + ANIMCMD_END, +}; + +const union AnimCmd *const gSpriteAnimTable_8402DF8[] = +{ + gSpriteAnim_8402DD8, + gSpriteAnim_8402DE0, + gSpriteAnim_8402DE8, + gSpriteAnim_8402DF0, +}; + +const struct SpriteTemplate gSpriteTemplate_8402E08 = +{ + .tileTag = 5525, + .paletteTag = 5526, + .oam = &gOamData_8402D50, + .anims = gSpriteAnimTable_8402DF8, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_8133300, +}; + +const u8 gString_AkitoMori[] = _("あきと"); // programmer Akito Mori? + +void sub_813269C(u8); +void CB2_InitLearnMove(void); +void CB2_LearnMove(void); +void LearnMoveMain(void); +void DrawLearnMoveMenuWindow(void); +void sub_8133030(bool8); +u8 sub_81330E8(void); +void sub_8133140(u8); +u8 sub_8133248(void); +void ClearLearnMoveVars(void); +void sub_8133358(void); +void sub_8133558(void); +void sub_813362C(void); +void sub_8133800(void); +void sub_8133AEC(bool8, int); +void sub_8133CA4(void); + +void VBlankCB_LearnMove(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +void sub_8132670(void) +{ + ScriptContext2_Enable(); + CreateTask(sub_813269C, 10); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0); +} + +void sub_813269C(u8 taskId) +{ + if (!gPaletteFade.active) + { + SetMainCallback2(CB2_InitLearnMove); + gFieldCallback = sub_8080990; + DestroyTask(taskId); + } +} + +void CB2_InitLearnMove(void) +{ + REG_DISPCNT = 0; + ResetSpriteData(); + FreeAllSpritePalettes(); + ResetTasks(); + sLearnMoveStruct = (struct LearnMoveStruct *)(ewram + 0x17000); + ClearLearnMoveVars(); + sLearnMoveStruct->partyMon = gSpecialVar_0x8004; + sub_8133558(); + SetVBlankCallback(VBlankCB_LearnMove); + + SetUpWindowConfig(&gWindowConfig_81E7240); + InitMenuWindow(&gWindowConfig_81E7240); + MenuZeroFillScreen(); + + SetUpWindowConfig(&gWindowConfig_81E6CE4); + InitMenuWindow(&gWindowConfig_81E6CE4); + MenuZeroFillScreen(); + + REG_BG0VOFS = 0; + REG_BG0VOFS = 0; // huh? + REG_BG1HOFS = 0; + REG_BG1HOFS = 0; // huh? + + LoadSpriteSheet(&gUnknown_08402D80); + LoadSpritePalette(&gUnknown_08402D88); + sub_8133358(); + FillPalette(0, 0, 2); + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); + SetMainCallback2(CB2_LearnMove); +} + +void sub_81327A4(void) +{ + ResetSpriteData(); + FreeAllSpritePalettes(); + ResetTasks(); + sLearnMoveStruct = (struct LearnMoveStruct *)(ewram + 0x17000); + sub_8133558(); + sLearnMoveStruct->unk2C6 = gSpecialVar_0x8005; + SetVBlankCallback(VBlankCB_LearnMove); + + SetUpWindowConfig(&gWindowConfig_81E7240); + InitMenuWindow(&gWindowConfig_81E7240); + MenuZeroFillScreen(); + + SetUpWindowConfig(&gWindowConfig_81E6CE4); + InitMenuWindow(&gWindowConfig_81E6CE4); + MenuZeroFillScreen(); + + REG_DISPCNT = 0x1340; + REG_BG0VOFS = 0; + REG_BG0HOFS = 0; + REG_BG1HOFS = 0; + REG_BG1HOFS = 0; // huh? + + LoadSpriteSheet(&gUnknown_08402D80); + LoadSpritePalette(&gUnknown_08402D88); + sub_8133358(); + FillPalette(0, 0, 2); + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); + SetMainCallback2(CB2_LearnMove); +} + +void CB2_LearnMove(void) +{ + LearnMoveMain(); + if (sLearnMoveStruct->unk1D) + { + sLearnMoveStruct->unk1D = FALSE; + sub_814AD7C(0x58, (sLearnMoveStruct->unk18 * 2 + 1) * 8); + } + if (sLearnMoveStruct->unk1E != 0) + { + sLearnMoveStruct->unk1E = 0; + sub_8133800(); + } + if (sLearnMoveStruct->unk2C3) + { + sub_8133AEC(sLearnMoveStruct->showContestInfo, 1); + sLearnMoveStruct->unk2C3 = FALSE; + } + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +void sub_81328E8(const u8 *a) +{ + StringExpandPlaceholders(gStringVar4, a); + MenuPrintMessage(gStringVar4, 3, 15); +} + +void LearnMoveMain(void) +{ + switch (sLearnMoveStruct->state) + { + case 0: + sLearnMoveStruct->state++; + DrawLearnMoveMenuWindow(); + sub_8133030(FALSE); + sub_8133800(); + gSprites[1].pos1.x = 0x48; + sLearnMoveStruct->unk2C3 = TRUE; + BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, 0); + REG_DISPCNT = 0x1340; + break; + case 1: + if (!gPaletteFade.active) + sLearnMoveStruct->state = 4; + break; + case 2: + sLearnMoveStruct->state++; + break; + case 3: + sub_8133030(FALSE); + sub_8133800(); + sLearnMoveStruct->unk2C3 = TRUE; + sLearnMoveStruct->state++; + gSprites[1].pos1.x = 0x48; + break; + case 4: + if (sub_81330E8() == 0) + sub_813362C(); + return; + case 5: + sub_8133140(0); + sub_8133800(); + sLearnMoveStruct->unk2C3 = TRUE; + gSprites[1].pos1.x = 0x48; + sLearnMoveStruct->state++; + break; + case 6: + if (sub_8133248() == 0) + sub_813362C(); + break; + case 8: + if (MenuUpdateWindowText()) + { + DisplayYesNoMenu(21, 7, 1); + sLearnMoveStruct->state++; + } + break; + case 9: + { + s8 selection = ProcessMenuInputNoWrap_(); + + if (selection == 0) + { + sub_8133CA4(); + if (GiveMoveToMon(&gPlayerParty[sLearnMoveStruct->partyMon], sLearnMoveStruct->movesToLearn[sLearnMoveStruct->menuSelection]) != 0xFFFF) + { + sub_81328E8(gOtherText_PokeLearnedMove); + gSpecialVar_0x8004 = 1; + sLearnMoveStruct->state = 31; + } + else + { + sLearnMoveStruct->state = 16; + } + } + else if (selection == -1 || selection == 1) + { + sub_8133CA4(); + if (sLearnMoveStruct->showContestInfo == FALSE) + sLearnMoveStruct->state = 3; + if (sLearnMoveStruct->showContestInfo == TRUE) + sLearnMoveStruct->state = 5; + } + } + break; + case 12: + if (MenuUpdateWindowText()) + { + DisplayYesNoMenu(21, 7, 1); + sLearnMoveStruct->state++; + } + break; + case 13: + { + s8 selection = ProcessMenuInputNoWrap_(); + + if (selection == 0) + { + sub_8133CA4(); + gSpecialVar_0x8004 = selection; + sLearnMoveStruct->state = 14; + } + else if (selection == -1 || selection == 1) + { + sub_8133CA4(); + if (sLearnMoveStruct->showContestInfo == FALSE) + sLearnMoveStruct->state = 3; + if (sLearnMoveStruct->showContestInfo == TRUE) + sLearnMoveStruct->state = 5; + } + } + break; + case 16: + sub_81328E8(gOtherText_DeleteOlderMove); + sLearnMoveStruct->state++; + break; + case 17: + if (MenuUpdateWindowText()) + { + DisplayYesNoMenu(21, 7, 1); + sLearnMoveStruct->state = 18; + } + break; + case 18: + { + s8 var = ProcessMenuInputNoWrap_(); + + if (var == 0) + { + sub_8133CA4(); + sub_81328E8(gOtherText_WhichMoveToForget); + sLearnMoveStruct->state = 19; + } + else if (var == -1 || var == 1) + { + sub_8133CA4(); + sLearnMoveStruct->state = 24; + } + } + break; + case 24: + sub_81328E8(gOtherText_StopLearningMove); + sLearnMoveStruct->state++; + break; + case 25: + if (MenuUpdateWindowText()) + { + sLearnMoveStruct->state = 26; + DisplayYesNoMenu(21, 7, 1); + } + break; + case 26: + { + s8 var = ProcessMenuInputNoWrap_(); + + if (var == 0) + { + sub_8133CA4(); + sLearnMoveStruct->state = 27; + } + else if (var == -1 || var == 1) + { + sub_8133CA4(); + + // What's the point? It gets set to 16, anyway. + if (sLearnMoveStruct->showContestInfo == FALSE) + sLearnMoveStruct->state = 3; + if (sLearnMoveStruct->showContestInfo == TRUE) + sLearnMoveStruct->state = 5; + sLearnMoveStruct->state = 16; + } + } + break; + case 27: + if (MenuUpdateWindowText()) + { + if (sLearnMoveStruct->showContestInfo == FALSE) + sLearnMoveStruct->state = 3; + if (sLearnMoveStruct->showContestInfo == TRUE) + sLearnMoveStruct->state = 5; + } + break; + case 19: + if (MenuUpdateWindowText()) + { + sLearnMoveStruct->state = 20; + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0); + } + break; + case 20: + if (!gPaletteFade.active) + { + sub_809D9F0(gPlayerParty, sLearnMoveStruct->partyMon, gPlayerPartyCount - 1, sub_81327A4, sLearnMoveStruct->movesToLearn[sLearnMoveStruct->menuSelection]); + sLearnMoveStruct->state = 28; + } + break; + case 21: + if (MenuUpdateWindowText()) + sLearnMoveStruct->state = 14; + break; + case 22: + BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, 0); + break; + case 14: + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, 0); + sLearnMoveStruct->state++; + break; + case 15: + if (!gPaletteFade.active) + SetMainCallback2(c2_exit_to_overworld_2_switch); + break; + case 28: + BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, 0); + sLearnMoveStruct->state++; + DrawLearnMoveMenuWindow(); + sub_8133800(); + if (sLearnMoveStruct->showContestInfo == FALSE) + sub_8133030(TRUE); + if (sLearnMoveStruct->showContestInfo == TRUE) + { + gSprites[1].pos1.x = 0x48; + sub_8133140(1); + } + sub_8133AEC(sLearnMoveStruct->showContestInfo, 1); + break; + case 29: + if (!gPaletteFade.active) + { + if (sLearnMoveStruct->unk2C6 == 4) + { + sLearnMoveStruct->state = 24; + } + else + { + u16 moveId = GetMonData(&gPlayerParty[sLearnMoveStruct->partyMon], MON_DATA_MOVE1 + sLearnMoveStruct->unk2C6); + + StringCopy(gStringVar3, gMoveNames[moveId]); + RemoveMonPPBonus(&gPlayerParty[sLearnMoveStruct->partyMon], sLearnMoveStruct->unk2C6); + SetMonMoveSlot(&gPlayerParty[sLearnMoveStruct->partyMon], sLearnMoveStruct->movesToLearn[sLearnMoveStruct->menuSelection], sLearnMoveStruct->unk2C6); + StringCopy(gStringVar2, gMoveNames[sLearnMoveStruct->movesToLearn[sLearnMoveStruct->menuSelection]]); + sub_81328E8(gOtherText_ForgotMove123); + sLearnMoveStruct->state = 30; + gSpecialVar_0x8004 = 1; + } + } + break; + case 30: + if (MenuUpdateWindowText()) + { +#ifdef ENGLISH + sub_81328E8(gOtherText_ForgotOrDidNotLearnMove); +#else + sub_81328E8(deuOtherText_ForgotAndLearned); +#endif + sLearnMoveStruct->state = 31; + PlayFanfare(BGM_FANFA1); + } + break; + case 31: + if (MenuUpdateWindowText()) + { + PlayFanfare(BGM_FANFA1); + sLearnMoveStruct->state = 32; + } + break; + case 32: + if (IsFanfareTaskInactive()) + sLearnMoveStruct->state = 33; + break; + case 33: + if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + sLearnMoveStruct->state = 14; + } + break; + } +} + +void DrawLearnMoveMenuWindow(void) +{ + u32 i; + + BasicInitMenuWindow(&gWindowConfig_81E7240); + for (i = 0; i < 4; i++) + { + MenuDrawTextWindow( + gUnknown_08402CF8[i][0], + gUnknown_08402CF8[i][1], + gUnknown_08402CF8[i][2], + gUnknown_08402CF8[i][3]); + } + BasicInitMenuWindow(&gWindowConfig_81E6CE4); +} + +void sub_8133030(bool8 a) +{ + s32 i; + + gSprites[sLearnMoveStruct->spriteIDs[0]].invisible = FALSE; + gSprites[sLearnMoveStruct->spriteIDs[1]].invisible = FALSE; + + for (i = 0; i < 16; i++) + gSprites[sLearnMoveStruct->spriteIDs[i + 4]].invisible = TRUE; + + for (i = 0; gUnknown_08402D08[0][i].unk0 != NULL; i++) + { + sub_8072C74(gTileBuffer, gUnknown_08402D08[0][i].unk0, 64, 2); + MenuPrint(gTileBuffer, gUnknown_08402D08[0][i].unk4, gUnknown_08402D08[0][i].unk5); + } + + if (!a) + sub_8072AB0(gOtherText_TeachWhichMove, 24, 120, 192, 32, 1); +} + +u8 sub_81330E8(void) +{ + u32 result = (gMain.newKeys & DPAD_LEFT) || (gMain.newKeys & DPAD_RIGHT); + + if (gSaveBlock2.optionsButtonMode == OPTIONS_BUTTON_MODE_LR + && ((gMain.newKeys & L_BUTTON) || (gMain.newKeys & R_BUTTON))) + result++; + + if (result != 0) + { + PlaySE(SE_SELECT); + sLearnMoveStruct->state = 5; + sLearnMoveStruct->showContestInfo = TRUE; + } + + return result; +} + +void sub_8133140(bool8 a) +{ + s32 i; + + gSprites[sLearnMoveStruct->spriteIDs[0]].invisible = FALSE; + gSprites[sLearnMoveStruct->spriteIDs[1]].invisible = FALSE; + + for (i = 0; i < 16; i++) + gSprites[sLearnMoveStruct->spriteIDs[i + 4]].invisible = FALSE; + + for (i = 0; gUnknown_08402D08[0][i].unk0 != NULL; i++) + { + sub_8072C74(gTileBuffer, gUnknown_08402D08[1][i].unk0, 64, 2); + MenuPrint(gTileBuffer, gUnknown_08402D08[1][i].unk4, gUnknown_08402D08[1][i].unk5); + if (i != 0) + { + MenuZeroFillWindowRect( + gUnknown_08402D08[1][i].unk4, + gUnknown_08402D08[1][i].unk5 + 2, + gUnknown_08402D08[1][i].unk4 + 7, + gUnknown_08402D08[1][i].unk5 + 3); + } + } + + if (!a) + sub_8072AB0(gOtherText_TeachWhichMove, 24, 120, 192, 32, 1); +} + +u8 sub_8133248(void) +{ + u32 result = (gMain.newKeys & DPAD_LEFT) || (gMain.newKeys & DPAD_RIGHT); + + if (gSaveBlock2.optionsButtonMode == OPTIONS_BUTTON_MODE_LR + && ((gMain.newKeys & L_BUTTON) || (gMain.newKeys & R_BUTTON))) + result++; + + if (result != 0) + { + PlaySE(SE_SELECT); + sLearnMoveStruct->state = 3; + sLearnMoveStruct->showContestInfo = FALSE; + } + + return result; +} + +void ClearLearnMoveVars(void) +{ + s32 i; + + sLearnMoveStruct->state = 0; + sLearnMoveStruct->unk2 = 0; + sLearnMoveStruct->unk19 = 0; + sLearnMoveStruct->unk18 = 0; + sLearnMoveStruct->unk1C = 0; + sLearnMoveStruct->numMenuChoices = 0; + sLearnMoveStruct->menuSelection = 0; + sLearnMoveStruct->unk1D = FALSE; + sLearnMoveStruct->unk1E = 0; + sLearnMoveStruct->unk2C3 = FALSE; + sLearnMoveStruct->showContestInfo = FALSE; + for (i = 0; i < 20; i++) + sLearnMoveStruct->movesToLearn[i] = 0; +} + +void sub_8133300(struct Sprite *sprite) +{ + s16 var = (sprite->data1 * 10) & 0xFF; + + switch (sprite->data0) + { + case 0: + break; + case 1: + sprite->pos2.x = Sin(var, 3) * sprite->data2; + break; + case 2: + sprite->pos2.y = Sin(var, 1) * sprite->data2; + break; + } + sprite->data1++; +} + +void sub_8133358(void) +{ + s32 i; + + sLearnMoveStruct->spriteIDs[0] = CreateSprite(&gSpriteTemplate_8402D90, 8, 16, 0); + gSprites[sLearnMoveStruct->spriteIDs[0]].data0 = 1; + gSprites[sLearnMoveStruct->spriteIDs[0]].data2 = -1; + + sLearnMoveStruct->spriteIDs[1] = CreateSprite(&gSpriteTemplate_8402D90, 72, 16, 0); + StartSpriteAnim(&gSprites[sLearnMoveStruct->spriteIDs[1]], 1); + gSprites[sLearnMoveStruct->spriteIDs[1]].data0 = 1; + gSprites[sLearnMoveStruct->spriteIDs[1]].data2 = 1; + + sLearnMoveStruct->spriteIDs[2] = CreateSprite(&gSpriteTemplate_8402DC0, 160, 4, 0); + StartSpriteAnim(&gSprites[sLearnMoveStruct->spriteIDs[2]], 1); + gSprites[sLearnMoveStruct->spriteIDs[2]].data0 = 2; + gSprites[sLearnMoveStruct->spriteIDs[2]].data2 = -1; + + sLearnMoveStruct->spriteIDs[3] = CreateSprite(&gSpriteTemplate_8402DC0, 160, 60, 0); + gSprites[sLearnMoveStruct->spriteIDs[3]].data0 = 2; + gSprites[sLearnMoveStruct->spriteIDs[3]].data2 = 1; + + for (i = 0; i < 8; i++) + { + sLearnMoveStruct->spriteIDs[i + 4] = CreateSprite(&gSpriteTemplate_8402E08, (i - (i / 4) * 4) * 8 + 0x1C, (i / 4) * 8 + 0x34, 0); + StartSpriteAnim(&gSprites[sLearnMoveStruct->spriteIDs[i + 4]], 2); + } + + for (i = 0; i < 8; i++) + { + sLearnMoveStruct->spriteIDs[i + 12] = CreateSprite(&gSpriteTemplate_8402E08, (i - (i / 4) * 4) * 8 + 0x1C, (i / 4) * 8 + 0x5C, 0); + StartSpriteAnim(&gSprites[sLearnMoveStruct->spriteIDs[i + 12]], 2); + } + + for (i = 0; i < 20; i++) + gSprites[sLearnMoveStruct->spriteIDs[i]].invisible = TRUE; + + CreateBlendedOutlineCursor(16, 0xFFFF, 12, 0x2D9F, 18); +} + +void sub_8133558(void) +{ + s32 i; + u8 nickname[POKEMON_NAME_LENGTH + 1]; + + sLearnMoveStruct->numMenuChoices = GetMoveRelearnerMoves(&gPlayerParty[sLearnMoveStruct->partyMon], sLearnMoveStruct->movesToLearn); + for (i = 0; i < sLearnMoveStruct->numMenuChoices; i++) + StringCopy(sLearnMoveStruct->moveNames[i], gMoveNames[sLearnMoveStruct->movesToLearn[i]]); + GetMonData(&gPlayerParty[sLearnMoveStruct->partyMon], MON_DATA_NICKNAME, nickname); + StringCopy10(gStringVar1, nickname); + StringCopy(sLearnMoveStruct->moveNames[sLearnMoveStruct->numMenuChoices], gUnknownText_Exit); + sLearnMoveStruct->numMenuChoices++; +} + +void sub_813360C(s8 delta) +{ + sLearnMoveStruct->unk1C = sLearnMoveStruct->unk18; + sLearnMoveStruct->unk18 += delta; + sLearnMoveStruct->unk1D = TRUE; +} + +void sub_813362C(void) +{ + if (gMain.newAndRepeatedKeys & DPAD_UP) + { + if (sLearnMoveStruct->menuSelection != 0) + { + PlaySE(SE_SELECT); + sLearnMoveStruct->menuSelection--; + sLearnMoveStruct->unk2C3 = TRUE; + if (sLearnMoveStruct->unk18 != 0) + { + sub_813360C(-1); + } + else if (sLearnMoveStruct->unk19 != 0) + { + sLearnMoveStruct->unk19--; + sLearnMoveStruct->unk1E++; + } + } + } + else if (gMain.newAndRepeatedKeys & DPAD_DOWN) + { + if (sLearnMoveStruct->menuSelection < sLearnMoveStruct->numMenuChoices - 1) + { + PlaySE(SE_SELECT); + sLearnMoveStruct->menuSelection++; + sLearnMoveStruct->unk2C3 = TRUE; + if (sLearnMoveStruct->unk18 != 2) + { + sub_813360C(1); + } + else if (sLearnMoveStruct->unk19 != sLearnMoveStruct->numMenuChoices - 3) + { + sLearnMoveStruct->unk19++; + sLearnMoveStruct->unk1E++; + } + } + } + else if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + if (sLearnMoveStruct->menuSelection != sLearnMoveStruct->numMenuChoices - 1) + { + sLearnMoveStruct->state = 8; + StringCopy(gStringVar2, sLearnMoveStruct->moveNames[sLearnMoveStruct->menuSelection]); + StringExpandPlaceholders(gStringVar4, gOtherText_TeachSpecificMove); + MenuPrintMessage(gStringVar4, 3, 15); + } + else + { + StringExpandPlaceholders(gStringVar4, gOtherText_GiveUpTeachingMove); + MenuPrintMessage(gStringVar4, 3, 15); + sLearnMoveStruct->state = 12; + } + } + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + sLearnMoveStruct->state = 12; + StringExpandPlaceholders(gStringVar4, gOtherText_GiveUpTeachingMove); + MenuPrintMessage(gStringVar4, 3, 15); + } + if (sLearnMoveStruct->numMenuChoices > 3) + { + gSprites[2].invisible = FALSE; + gSprites[3].invisible = FALSE; + if (sLearnMoveStruct->unk19 == 0) + gSprites[2].invisible = TRUE; + else if (sLearnMoveStruct->unk19 == sLearnMoveStruct->numMenuChoices - 3) + gSprites[3].invisible = TRUE; + } +} + +void sub_8133800(void) +{ + u8 r6 = sLearnMoveStruct->unk19; + u8 *str = gTileBuffer; + s32 i; + + for (i = 0; i < 3; i++) + { + if (r6 >= sLearnMoveStruct->numMenuChoices) + { + str = sub_8072C74(str, gEmptyString_81E72B0, 0x90, 0); + } + else if (r6 == sLearnMoveStruct->numMenuChoices - 1) + { + str = sub_8072C74(str, gUnknownText_Exit, 0x90, 0); + } + else + { + u16 moveId = sLearnMoveStruct->movesToLearn[r6]; + + if (sLearnMoveStruct->showContestInfo) + str = sub_8072C74(str, gUnknown_083CAF70[gContestMoves[moveId].contestCategory], 0x27, 0); + else + str = sub_8072C74(str, gTypeNames[gBattleMoves[moveId].type], 0x27, 0); + + str = sub_8072C74(str, sLearnMoveStruct->moveNames[r6], 0x72, 0); + + str[0] = CHAR_P; + str[1] = CHAR_P; + str[2] = CHAR_SLASH; + str += 3; + + str = sub_8072C14(str, gBattleMoves[moveId].pp, 0x90, 0); + } + *str++ = CHAR_NEWLINE; + r6++; + } + *str = EOS; + MenuPrint(gTileBuffer, 11, 1); + sub_813360C(0); +} + +const u8 gUnknown_08402E24[7][3] = +{ + {11, 1, 1}, + { 3, 6, 2}, + {24, 1, 3}, + { 3, 11, 4}, + { 5, 4, 5}, + { 3, 6, 6}, + { 3, 11, 7}, +}; + +const u8 gUnknown_08402E39[] = {0, 1, 2, 3}; +const u8 gUnknown_08402E3D[] = {4, 5, 6}; + +void PrintMoveInfo(u16 moveId, const u8 *b) +{ + u8 str[0x34]; + u8 numHearts; + u8 i; + + StringCopy(str, gExpandedPlaceholder_Empty); + switch (b[2]) + { + case 1: + break; + case 2: + if (gBattleMoves[moveId].power < 2) + sub_8072C74(str, gOtherText_ThreeDashes2, 32, 2); + else + sub_8072C14(str, gBattleMoves[moveId].power, 32, 2); + MenuPrint(str, b[0], b[1]); + break; + case 4: + if (gBattleMoves[moveId].accuracy == 0) + sub_8072C74(str, gOtherText_ThreeDashes2, 32, 2); + else + sub_8072C14(str, gBattleMoves[moveId].accuracy, 32, 2); + MenuPrint(str, b[0], b[1]); + break; + case 6: + MenuZeroFillWindowRect(b[0], b[1], b[0], b[1] + 1); + numHearts = gContestEffects[gContestMoves[moveId].effect].appeal / 10; + if (numHearts == 255) + numHearts = 0; + for (i = 0; i < 8; i++) + { + if (i < numHearts) + StartSpriteAnim(&gSprites[sLearnMoveStruct->spriteIDs[i + 4]], 1); + else + StartSpriteAnim(&gSprites[sLearnMoveStruct->spriteIDs[i + 4]], 0); + } + break; + case 7: + MenuZeroFillWindowRect(b[0], b[1], b[0], b[1] + 1); + numHearts = gContestEffects[gContestMoves[moveId].effect].jam / 10; + if (numHearts == 255) + numHearts = 0; + for (i = 0; i < 8; i++) + { + if (i < numHearts) + StartSpriteAnim(&gSprites[sLearnMoveStruct->spriteIDs[i + 12]], 3); + else + StartSpriteAnim(&gSprites[sLearnMoveStruct->spriteIDs[i + 12]], 2); + } + break; + } +} + +void sub_8133AEC(bool8 contestInfo, int unused) +{ + u16 i; + + if (sLearnMoveStruct->menuSelection != sLearnMoveStruct->numMenuChoices - 1) + { + u16 moveId = sLearnMoveStruct->movesToLearn[sLearnMoveStruct->menuSelection]; + + if (contestInfo) + { + for (i = 0; i < 16; i++) + gSprites[sLearnMoveStruct->spriteIDs[i + 4]].invisible = FALSE; + for (i = 0; i < 3; i++) + PrintMoveInfo(moveId, gUnknown_08402E24[gUnknown_08402E3D[i]]); + sub_8072AB0(gUnknown_083CADD4[gContestMoves[moveId].effect], 0x58, 0x48, 0x90, 32, 1); + } + else + { + u8 var; + + for (i = 0; i < 4; i++) + PrintMoveInfo(moveId, gUnknown_08402E24[gUnknown_08402E39[i]]); + var = sub_8072A18(gMoveDescriptions[moveId - 1], 0x58, 0x48, 0x90, 1); + if (var < 2) + { + u8 r1 = var * 2 + 9; + + MenuFillWindowRectWithBlankTile(11, r1, 28, 12); + } + } + } + else + { + if (contestInfo) + { + MenuZeroFillWindowRect(gUnknown_08402E24[5][0], gUnknown_08402E24[5][1], gUnknown_08402E24[5][0], gUnknown_08402E24[5][1] + 1); + MenuZeroFillWindowRect(gUnknown_08402E24[6][0], gUnknown_08402E24[6][1], gUnknown_08402E24[6][0], gUnknown_08402E24[6][1] + 1); + for (i = 0; i < 16; i++) + gSprites[sLearnMoveStruct->spriteIDs[i + 4]].invisible = TRUE; + } + else + { + MenuZeroFillWindowRect(gUnknown_08402E24[1][0], gUnknown_08402E24[1][1], gUnknown_08402E24[1][0] + 3, gUnknown_08402E24[1][1] + 1); + MenuZeroFillWindowRect(gUnknown_08402E24[3][0], gUnknown_08402E24[3][1], gUnknown_08402E24[3][0] + 3, gUnknown_08402E24[3][1] + 1); + } + MenuZeroFillWindowRect(11, 9, 28, 12); + } +} + +void sub_8133CA4(void) +{ + MenuZeroFillWindowRect(21, 7, 27, 12); + sub_8133AEC(sLearnMoveStruct->showContestInfo, 0); +} diff --git a/src/pokemon/pokeblock_feed.c b/src/pokemon/pokeblock_feed.c new file mode 100644 index 000000000..8dc2f47de --- /dev/null +++ b/src/pokemon/pokeblock_feed.c @@ -0,0 +1,1015 @@ +#include "global.h" +#include "task.h" +#include "palette.h" +#include "main.h" +#include "menu_helpers.h" +#include "text.h" +#include "text_window.h" +#include "menu.h" +#include "rom4.h" +#include "decompress.h" +#include "data2.h" +#include "sprite.h" +#include "item_use.h" +#include "pokeblock.h" +#include "party_menu.h" +#include "strings.h" +#include "string_util.h" +#include "m4a.h" +#include "field_effect.h" +#include "sound.h" +#include "trig.h" + +extern u8 ewram[]; +extern struct MusicPlayerInfo gMPlay_BGM; +extern u8 gPokeblockMonID; +extern s16 gPokeblockGain; + +extern const u8 gPokeblockRed_Pal[]; +extern const u8 gPokeblockBlue_Pal[]; +extern const u8 gPokeblockPink_Pal[]; +extern const u8 gPokeblockGreen_Pal[]; +extern const u8 gPokeblockYellow_Pal[]; +extern const u8 gPokeblockPurple_Pal[]; +extern const u8 gPokeblockIndigo_Pal[]; +extern const u8 gPokeblockBrown_Pal[]; +extern const u8 gPokeblockLiteBlue_Pal[]; +extern const u8 gPokeblockOlive_Pal[]; +extern const u8 gPokeblockGray_Pal[]; +extern const u8 gPokeblockBlack_Pal[]; +extern const u8 gPokeblockWhite_Pal[]; +extern const u8 gPokeblockGold_Pal[]; +extern const u8 gPokeblock_Gfx[]; +extern const u8 gBattleTerrainTiles_Building[]; +extern const u8 gUnknown_08E782FC[]; +extern const u8 gBattleTerrainPalette_BattleTower[]; +extern const struct CompressedSpriteSheet gUnknown_083F7F74; +extern const struct CompressedSpritePalette gUnknown_083F7F7C; + +bool8 sub_8040A3C(u16 species); + +// this file's functions +static void sub_8147B04(void); +static void sub_81481DC(void); +static void sub_814825C(void); +static u8 sub_81480B4(void); +static u8 CreatePokeblockSprite(void); +static u8 PokeblockFeed_CreatePokeSprite(struct Pokemon* mon); +static bool8 sub_8147B20(struct Pokemon* mon); +static void LaunchPokeblockFeedTask(u8); +static void sub_8148044(u8); +static void sub_8148078(struct Sprite* sprite); +static void Task_PrintAtePokeblockText(u8 taskID); +static void Task_PaletteFadeToReturn(u8 taskID); +static void SetPokeblockFeedSpritePal(u8); +static void sub_8148108(u8, bool8); +static bool8 sub_8148540(void); +static bool8 sub_81485CC(void); +static bool8 FreePokeSpriteMatrix(void); +void sub_8148710(void); +static void SpriteCB_ThrownPokeblock(struct Sprite* sprite); +static void sub_814862C(void); + +// EWRAM +EWRAM_DATA static struct CompressedSpritePalette sPokeblockFeedSpritePal = {0}; + +// IWRAM common +struct Sprite* gPokeblockFeedPokeSprite; +u16 gPokeblockFeedMonSpecies; +bool8 gPokeblockMonNotFlipped; +u8 gPokeblockFeedMonSpriteID; +u8 gPokeblockFeedMonNature; +u16 gUnknown_03005F34; +u8 gPokeblockFeedUnused0; +u8 gUnknown_03005F3C; +u8 gUnknown_03005F40; +struct Sprite gPokeblockFeedPokeSpriteCopy; +u16 gUnknown_03005F94; +s16 gUnknown_03005FA0[24]; + +// rodata + +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_8412050[] = +{ + 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 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_84120EC[] = +{ + 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_84121A0[] = +{ + sSpriteAffineAnim_84120DC +}; + +static const union AffineAnimCmd *const sSpriteAffineAnimTable_84121A4[] = +{ + sSpriteAffineAnim_84120F0 +}; + +static const union AffineAnimCmd *const sSpriteAffineAnimTable_84121A8[] = +{ + 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 sUnknown_084121DC = +{ + gPokeblock_Gfx, 0x20, 14818 +}; + +static const struct SpriteTemplate sThrownPokeblockSpriteTemplate = +{ + .tileTag = 14818, + .paletteTag = 14818, + .oam = &sThrownPokeblockOamData, + .anims = sThrownPokeblockAnimTable, + .images = NULL, + .affineAnims = sThrownPokeblockAffineAnimTable, + .callback = SpriteCB_ThrownPokeblock +}; + +// code + +static void CB2_PokeblockFeed(void) +{ + AnimateSprites(); + BuildOamBuffer(); + RunTasks(); + UpdatePaletteFade(); +} + +static void VBlankCB_PokeblockFeed(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +static bool8 TransitionToPokeblockFeedScene(void) +{ + switch (gMain.state) + { + case 0: + sub_80F9438(); + sub_80F9368(); + sub_8147B04(); + 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: + SetUpWindowConfig(&gWindowConfig_81E6E50); + gMain.state++; + break; + case 5: + MultistepInitMenuWindowBegin(&gWindowConfig_81E6E50); + gMain.state++; + break; + case 6: + if (MultistepInitMenuWindowContinue()) + { + ewram[0x1FFFF] = 0; + gMain.state++; + } + break; + case 7: + if (sub_8147B20(&gPlayerParty[gPokeblockMonID])) + { + gMain.state++; + } + break; + case 8: + ewram[0x1FFFD] = sub_81480B4(); + gMain.state++; + break; + case 9: + ewram[0x1FFFE] = PokeblockFeed_CreatePokeSprite(&gPlayerParty[gPokeblockMonID]); + gMain.state++; + break; + case 10: + MenuDrawTextWindow(0, 14, 29, 19); + gMain.state++; + break; + case 11: + if (sub_8055870() != 1) + { + gMain.state++; + } + break; + case 12: + { + u16 savedIME = REG_IME; + REG_IME = 0; + REG_IE |= 1; + REG_IME = savedIME; + REG_DISPSTAT |= 8; + SetVBlankCallback(VBlankCB_PokeblockFeed); + gMain.state++; + } + case 13: + BeginNormalPaletteFade(-1, 0, 0x10, 0, 0); + gPaletteFade.bufferTransferDisabled = 0; + SetMainCallback2(CB2_PokeblockFeed); + return TRUE; + } + return FALSE; +} + +void CB2_PreparePokeblockFeedScene(void) +{ + while (1) + { + if (TransitionToPokeblockFeedScene() == 1) + { + LaunchPokeblockFeedTask(1); + break; + } + if (sub_80F9344() == 1) + break; + } +} + +static void sub_8147B04(void) +{ + REG_BG1CNT = 0x1D02l; + REG_DISPCNT = 0x1340; +} + +static bool8 sub_8147B20(struct Pokemon* mon) +{ + u16 species; + u32 PiD, TiD; + switch (ewram[0x1FFFF]) + { + case 0: + species = GetMonData(mon, MON_DATA_SPECIES2); + PiD = GetMonData(mon, MON_DATA_PERSONALITY); + HandleLoadSpecialPokePic(&gMonFrontPicTable[species], gMonFrontPicCoords[species].coords, gMonFrontPicCoords[species].y_offset, 0x2000000, gUnknown_081FAF4C[1], species, PiD); + ewram[0x1FFFF]++; + break; + case 1: + { + const struct CompressedSpritePalette* palette; + + species = GetMonData(mon, MON_DATA_SPECIES2); + PiD = GetMonData(mon, MON_DATA_PERSONALITY); + TiD = GetMonData(mon, MON_DATA_OT_ID); + palette = sub_80409C8(species, TiD, PiD); + LoadCompressedObjectPalette(palette); + GetMonSpriteTemplate_803C56C(palette->tag, 1); + ewram[0x1FFFF]++; + } + break; + case 2: + LoadCompressedObjectPic(&gUnknown_083F7F74); + ewram[0x1FFFF]++; + break; + case 3: + LoadCompressedObjectPalette(&gUnknown_083F7F7C); + ewram[0x1FFFF]++; + break; + case 4: + LoadCompressedObjectPic(&sUnknown_084121DC); + ewram[0x1FFFF]++; + break; + case 5: + SetPokeblockFeedSpritePal(gScriptItemId); + LoadCompressedObjectPalette(&sPokeblockFeedSpritePal); + ewram[0x1FFFF]++; + break; + case 6: + LZDecompressVram(gBattleTerrainTiles_Building, (void*)(VRAM)); + ewram[0x1FFFF]++; + break; + case 7: + LZDecompressVram(gUnknown_08E782FC, (void*)(VRAM + 0xE800)); + ewram[0x1FFFF]++; + break; + case 8: + LoadCompressedPalette(gBattleTerrainPalette_BattleTower, 0x20, 0x60); + ewram[0x1FFFF] = 0; + return TRUE; + } + return FALSE; +} + +static void SetPokeblockFeedSpritePal(u8 pkbID) +{ + u8 color = GetPokeblockData(&gSaveBlock1.pokeblocks[pkbID], PBLOCK_COLOR); + sPokeblockFeedSpritePal.data = sPokeblocksPals[color - 1]; + sPokeblockFeedSpritePal.tag = 0x39E2; +} + +static void sub_8147CC8(u8 taskID) +{ + if (!gPaletteFade.active) + { + switch (gTasks[taskID].data[0]) + { + case 0: + gUnknown_03005F3C = 0; + gUnknown_03005F94 = 0; + sub_81481DC(); + break; + case 255: + sub_8148108(ewram[0x1FFFD], gTasks[taskID].data[1]); + break; + case 269: + ewram[0x1FFFC] = CreatePokeblockSprite(); + break; + case 281: + sub_8148044(ewram[0x1FFFE]); + break; + case 297: + gTasks[taskID].func = Task_PrintAtePokeblockText; + return; + } + if (gUnknown_03005F94 < gUnknown_03005F34) + sub_814825C(); + else if (gUnknown_03005F94 == gUnknown_03005F34) + gTasks[taskID].data[0] = 254; + + gUnknown_03005F94++; + gTasks[taskID].data[0]++; + } +} + +static void LaunchPokeblockFeedTask(u8 a0) +{ + u8 taskID = CreateTask(sub_8147CC8, 0); + gTasks[taskID].data[0] = 0; + gTasks[taskID].data[1] = a0; +} + +static void Task_WaitForAtePokeblockText(u8 taskID) +{ + if (MenuUpdateWindowText() == 1) + gTasks[taskID].func = Task_PaletteFadeToReturn; +} + +static void Task_PrintAtePokeblockText(u8 taskID) +{ + struct Pokemon* mon = &gPlayerParty[gPokeblockMonID]; + struct Pokeblock* pokeblock = &gSaveBlock1.pokeblocks[gScriptItemId]; + + gPokeblockGain = PokeblockGetGain(GetNature(mon), pokeblock); + GetMonNickname(mon, gStringVar1); + PokeblockCopyName(pokeblock, gStringVar2); + + if (gPokeblockGain == 0) + StringExpandPlaceholders(gStringVar4, gContestStatsText_NormallyAte); + else if (gPokeblockGain > 0) + StringExpandPlaceholders(gStringVar4, gContestStatsText_HappilyAte); + else + StringExpandPlaceholders(gStringVar4, gContestStatsText_DisdainfullyAte); + + MenuPrintMessage(gStringVar4, 1, 15); + gTasks[taskID].func = Task_WaitForAtePokeblockText; +} + +static void Task_ReturnAfterPaletteFade(u8 taskID) +{ + if (!gPaletteFade.active) + { + m4aMPlayVolumeControl(&gMPlay_BGM, -1, 256); + SetMainCallback2(gMain.savedCallback); + DestroyTask(taskID); + } +} + +static void Task_PaletteFadeToReturn(u8 taskID) +{ + BeginNormalPaletteFade(-1, 0, 0, 0x10, 0); + gTasks[taskID].func = Task_ReturnAfterPaletteFade; +} + +static u8 PokeblockFeed_CreatePokeSprite(struct Pokemon* mon) +{ + u16 species = GetMonData(mon, MON_DATA_SPECIES2); + u8 spriteID = CreateSprite(&gUnknown_02024E8C, 48, 80, 2); + + gPokeblockFeedMonSpecies = species; + gPokeblockFeedMonSpriteID = spriteID; + gPokeblockFeedMonNature = GetNature(mon); + gSprites[spriteID].data2 = species; + gSprites[spriteID].callback = SpriteCallbackDummy; + gPokeblockMonNotFlipped = 1; + if (!sub_8040A3C(species)) + { + gSprites[spriteID].affineAnims = sSpriteAffineAnimTable_84120EC; + gSprites[spriteID].oam.affineMode = 3; + CalcCenterToCornerVec(&gSprites[spriteID], gSprites[spriteID].oam.shape, gSprites[spriteID].oam.size, gSprites[spriteID].oam.affineMode); + gPokeblockMonNotFlipped = 0; + } + return spriteID; +} + +static void sub_8148044(u8 spriteID) +{ + gSprites[spriteID].pos1.x = 48; + gSprites[spriteID].pos1.y = 80; + gSprites[spriteID].data0 = -8; + gSprites[spriteID].data1 = 1; + gSprites[spriteID].callback = sub_8148078; +} + +static void sub_8148078(struct Sprite* sprite) +{ + sprite->pos1.x += 4; + sprite->pos1.y += sprite->data0; + sprite->data0 += sprite->data1; + if (sprite->data0 == 0) + PlayCry1(sprite->data2, 0); + if (sprite->data0 == 9) + sprite->callback = SpriteCallbackDummy; +} + +static u8 sub_81480B4(void) +{ + u8 spriteID = sub_810BA50(188, 100, 2); + gSprites[spriteID].oam.affineMode = 1; + gSprites[spriteID].affineAnims = sSpriteAffineAnimTable_84121A0; + gSprites[spriteID].callback = SpriteCallbackDummy; + InitSpriteAffineAnim(&gSprites[spriteID]); + return spriteID; +} + +static void sub_8148108(u8 spriteID, bool8 a1) +{ + FreeOamMatrix(gSprites[spriteID].oam.matrixNum); + gSprites[spriteID].oam.affineMode = 3; + if (!a1) + gSprites[spriteID].affineAnims = sSpriteAffineAnimTable_84121A4; + else + gSprites[spriteID].affineAnims = sSpriteAffineAnimTable_84121A8; + InitSpriteAffineAnim(&gSprites[spriteID]); +} + +static u8 CreatePokeblockSprite(void) +{ + u8 spriteID = CreateSprite(&sThrownPokeblockSpriteTemplate, 174, 84, 1); + gSprites[spriteID].data0 = -12; + gSprites[spriteID].data1 = 1; + return spriteID; +} + +static void SpriteCB_ThrownPokeblock(struct Sprite* sprite) +{ + sprite->pos1.x -= 4; + sprite->pos1.y += sprite->data0; + sprite->data0 += sprite->data1; + if (sprite->data0 == 10) + DestroySprite(sprite); +} + +static void sub_81481DC(void) +{ + u8 animID, i; + + gUnknown_03005F34 = 1; + animID = sNatureToMonPokeblockAnim[gPokeblockFeedMonNature][0]; + for (i = 0; i < 8; i++, animID++) + { + gUnknown_03005F34 += sMonPokeblockAnims[animID][4]; + if (sMonPokeblockAnims[animID][9] == 1) + break; + } +} + +static void sub_814825C(void) +{ + switch (gUnknown_03005F3C) + { + case 0: + gUnknown_03005F40 = sNatureToMonPokeblockAnim[gPokeblockFeedMonNature][0]; + gPokeblockFeedPokeSprite = &gSprites[gPokeblockFeedMonSpriteID]; + gPokeblockFeedPokeSpriteCopy = *gPokeblockFeedPokeSprite; + gUnknown_03005F3C = 10; + break; + case 1 ... 9: + break; + case 10: + sub_8148540(); + if (sNatureToMonPokeblockAnim[gPokeblockFeedMonNature][1] != 0) + { + gPokeblockFeedPokeSprite->oam.affineMode = 3; + gPokeblockFeedPokeSprite->oam.matrixNum = 0; + gPokeblockFeedPokeSprite->affineAnims = sSpriteAffineAnimTable_8412050; + InitSpriteAffineAnim(gPokeblockFeedPokeSprite); + } + gUnknown_03005F3C = 50; + case 50: + if (sNatureToMonPokeblockAnim[gPokeblockFeedMonNature][1] != 0) + { + if (gPokeblockMonNotFlipped == 0) + StartSpriteAffineAnim(gPokeblockFeedPokeSprite, sNatureToMonPokeblockAnim[gPokeblockFeedMonNature][1] + 10); + else + StartSpriteAffineAnim(gPokeblockFeedPokeSprite, sNatureToMonPokeblockAnim[gPokeblockFeedMonNature][1]); + } + gUnknown_03005F3C = 60; + break; + case 60: + if (sub_81485CC() == 1) + { + if (gUnknown_03005FA0[9] == 0) + { + gUnknown_03005F40++; + sub_8148540(); + gUnknown_03005F3C = 60; + } + else + { + FreeOamMatrix(gPokeblockFeedPokeSprite->oam.matrixNum); + gUnknown_03005F3C = 70; + } + } + break; + case 70: + FreePokeSpriteMatrix(); + gUnknown_03005F40 = 0; + gUnknown_03005F3C = 0; + break; + case 71 ... 90: + break; + } +} + +static bool8 sub_8148540(void) +{ + u8 i; + for (i = 0; i < 10; i++) + gUnknown_03005FA0[i] = sMonPokeblockAnims[gUnknown_03005F40][i]; + if (gUnknown_03005FA0[4] == 0) + return TRUE; + else + { + gUnknown_03005FA0[10] = Sin(gUnknown_03005FA0[0], gUnknown_03005FA0[2]); + gUnknown_03005FA0[11] = Cos(gUnknown_03005FA0[0], gUnknown_03005FA0[3]); + gUnknown_03005FA0[12] = gUnknown_03005FA0[4]; + gUnknown_03005FA0[13] = gPokeblockFeedPokeSprite->pos2.x; + gUnknown_03005FA0[14] = gPokeblockFeedPokeSprite->pos2.y; + sub_8148710(); + gUnknown_03005FA0[4] = gUnknown_03005FA0[12]; + sub_814862C(); + gUnknown_03005FA0[4] = gUnknown_03005FA0[12]; + return FALSE; + } +} + +#define ewram1D000 ((u16 *)(ewram + 0x1D000)) +#define ewram1D400 ((u16 *)(ewram + 0x1D400)) + +static bool8 sub_81485CC(void) +{ + u16 var = gUnknown_03005FA0[12] - gUnknown_03005FA0[4]; + + gPokeblockFeedPokeSprite->pos2.x = ewram1D000[var]; + gPokeblockFeedPokeSprite->pos2.y = ewram1D400[var]; + + if (--gUnknown_03005FA0[4] == 0) + return TRUE; + else + return FALSE; +} + +static bool8 FreePokeSpriteMatrix(void) +{ + FreeSpriteOamMatrix(gPokeblockFeedPokeSprite); + return FALSE; +} + +static void sub_814862C(void) +{ + u16 i; + u16 r8 = gUnknown_03005FA0[8]; + u16 r7 = gUnknown_03005FA0[12] - r8; + s16 var3 = gUnknown_03005FA0[13] + gUnknown_03005FA0[6]; + s16 r9 = gUnknown_03005FA0[14] + gUnknown_03005FA0[7]; + + for (i = 0; i < r7 - 1; i++) + { + s16* r3 = &ewram1D000[r8 + i]; + s16 r1 = *r3 - (var3); + + s16* r5 = &ewram1D400[r8 + i]; + s16 r4 = *r5 - r9; + + *r3 -= r1 * (i + 1) / r7; + *r5 -= r4 * (i + 1) / r7; + } + + ewram1D000[(r8 + r7) - 1] = var3; + ewram1D400[(r8 + r7) - 1] = r9; +} + +void sub_8148710(void) +{ + bool8 var_24 = FALSE; + s16 r8 = gUnknown_03005FA0[13] - gUnknown_03005FA0[10]; + s16 r7 = gUnknown_03005FA0[14] - gUnknown_03005FA0[11]; + while (1) + { + u16 r5; + u16 r4; + u16 var; + + var = abs(gUnknown_03005FA0[5]); + r5 = var + gUnknown_03005FA0[3]; + gUnknown_03005FA0[3] = r5; + + if (gUnknown_03005FA0[2] < 0) + var_24 = TRUE; + + r4 = gUnknown_03005FA0[12] - gUnknown_03005FA0[4]; + + if (gUnknown_03005FA0[4] == 0) + break; + + if (!var_24) + { + ewram1D000[r4] = Sin(gUnknown_03005FA0[0], gUnknown_03005FA0[2] + r5 / 256) + r8; + ewram1D400[r4] = Cos(gUnknown_03005FA0[0], gUnknown_03005FA0[3] + r5 / 256) + r7; + } + else + { + ewram1D000[r4] = Sin(gUnknown_03005FA0[0], gUnknown_03005FA0[2] - r5 / 256) + r8; + ewram1D400[r4] = Cos(gUnknown_03005FA0[0], gUnknown_03005FA0[3] - r5 / 256) + r7; + } + + gUnknown_03005FA0[0] += gUnknown_03005FA0[1]; + gUnknown_03005FA0[0] &= 0xFF; + gUnknown_03005FA0[4]--; + } +} diff --git a/src/scene/berry_blender.c b/src/scene/berry_blender.c new file mode 100644 index 000000000..f54c6271d --- /dev/null +++ b/src/scene/berry_blender.c @@ -0,0 +1,3884 @@ +#include "global.h" +#include "decompress.h" +#include "palette.h" +#include "event_data.h" +#include "main.h" +#include "text_window.h" +#include "menu.h" +#include "strings2.h" +#include "sound.h" +#include "songs.h" +#include "berry.h" +#include "string_util.h" +#include "link.h" +#include "task.h" +#include "rom4.h" +#include "item.h" +#include "items.h" +#include "rng.h" +#include "save.h" +#include "menu_cursor.h" +#include "trig.h" +#include "pokeblock.h" + +//needed to match Blender_ControlHitPitch +struct MusicPlayerInfo +{ + struct SongHeader *songHeader; + u32 status; + u8 trackCount; + u8 priority; + u8 cmd; + u8 unk_B; + u32 clock; + u8 gap[8]; + u8 *memAccArea; + u16 tempoD; + u16 tempoU; + u16 tempoI; + u16 tempoC; + u16 fadeOI; + u16 fadeOC; + u16 fadeOV; + struct MusicPlayerTrack *tracks; + struct ToneData *tone; + u32 ident; + u32 func; + u32 intp; +}; + +#define BLENDER_SCORE_BEST 0 +#define BLENDER_SCORE_GOOD 1 +#define BLENDER_SCORE_MISS 2 + +#define BLENDER_MAX_PLAYERS 4 +#define BLENDER_SCORES_NO 3 + +#define FLAVOUR_SPICY 0 +#define FLAVOUR_DRY 1 +#define FLAVOUR_SWEET 2 +#define FLAVOUR_BITTER 3 +#define FLAVOUR_SOUR 4 + +struct BlenderBerry +{ + u16 itemID; + u8 name[7]; + u8 flavours[5]; + u8 smoothness; +}; + +struct BerryBlenderData +{ + u8 field_0; + u8 field_1; + struct Window field_4; + u8 field_35; + u8 field_36; + u8 field_37; + u8 field_38; + u8 field_39; + u8 field_3A; + u8 field_3B; + u8 field_3C; + u8 field_3D; + u8 field_3E; + u8 field_3F; + u8 field_40; + u8 field_41; + u8 field_42; + u8 field_43; + u8 field_44; + u8 field_45; + u8 field_46; + u8 field_47; + u8 field_48; + u8 field_49; + u8 field_4A; + u8 field_4B; + u8 field_4C; + u8 field_4D; + u16 field_4E; + u8 scoreIconIDs[3]; + u16 arrowPos; + s16 field_56; + s16 field_58; + u16 max_RPM; + u8 SyncArrowSpriteID[BLENDER_MAX_PLAYERS]; + u8 SyncArrowSprite2ID[BLENDER_MAX_PLAYERS]; + u8 field_64; + u8 field_65; + u8 field_66; + u8 field_67; + u8 field_68; + u8 field_69; + u8 field_6A; + u8 field_6B; + u8 field_6C; + u8 field_6D; + u8 field_6E; + u8 field_6F; + u16 field_70[BLENDER_MAX_PLAYERS]; + u16 field_78; + u16 field_7A; + u16 field_7C; + u8 field_7E; + u8 field_7F; + u16 chosenItemID[BLENDER_MAX_PLAYERS]; + u8 playersNo; + u8 field_89; + u8 field_8A; + u8 field_8B; + u8 field_8C; + u8 field_8D; + u8 field_8E; + u8 field_8F; + u8 field_90; + u8 field_91; + u8 field_92; + u8 field_93; + u16 field_94; + u8 field_96; + u8 field_97; + u8 field_98; + u8 field_99; + u16 field_9A[BLENDER_MAX_PLAYERS]; + u16 field_A2[BLENDER_MAX_PLAYERS]; + u8 field_AA; + u8 stringVar[129]; + u32 gameFrameTime; + s32 framesToWait; + u32 field_134; + u8 field_138; + u8 field_139; + u8 field_13A; + u8 field_13B; + u8 field_13C; + u8 field_13D; + u16 field_13E; + u16 field_140; + u16 field_142; + s16 field_144; + s16 field_146; + u8 field_148[3]; + u8 field_14B; + u16 scores[BLENDER_MAX_PLAYERS][3]; + u8 playerPlaces[BLENDER_MAX_PLAYERS]; + struct BgAffineDstData field_168; + u16 field_178; + struct BlenderBerry blendedBerries[BLENDER_MAX_PLAYERS]; + u32 field_1BC; + u16 field_1C0; + u16 field_1C2; + u32 field_1C4; +}; + +struct BlenderDebug +{ + s8 cursorPos; + s8 berries[4]; + struct Pokeblock pokeblock; + u8 field_10; + u8 spicy; + u8 dry; + u8 sweet; + u8 bitter; + u8 sour; + u8 feel; + s8 field_17; + s8 field_18; + s8 field_19; + s16 BPM; +}; + +// other files functions +void m4aMPlayPitchControl(struct MusicPlayerInfo *mplayInfo, u16 trackBits, s16 pitch); +void m4aMPlayTempoControl(struct MusicPlayerInfo *mplayInfo, u16 tempo); +void m4aMPlayStop(struct MusicPlayerInfo *mplayInfo); +void sub_80A6978(void); +u8 sub_80A7DEC(u8 berryId, u8 x, u8 y, bool8 animate); +void sub_814A880(u8 a1, u8 a2); +u8 sub_814A5C0(u8 a1, u16 a2, u8 a3, u16 a4, u8 a5); +s8 sub_810CA00(void); +bool8 sub_810CA34(struct Pokeblock *pokeblock); +#ifdef GERMAN +extern void de_sub_8073110(); +#endif + +extern struct MusicPlayerInfo gMPlay_SE2; +extern struct MusicPlayerInfo gMPlay_BGM; +extern u8 ewram[]; +extern u16 gScriptItemId; +extern u8 gUnknown_020297ED; +extern u8 byte_3002A68; + +extern const u8 gUnknown_08E6C100[]; +extern const u8 gUnknown_08E6C920[]; +extern const u8 gUnknown_08E6D354[]; +extern const struct WindowConfig gWindowConfig_81E6F68; +extern const u8 *const gPokeblockNames[]; +extern const struct Berry gBerries[]; + +extern const u8 gBerryBlenderArrowTiles[]; +extern const u8 gBerryBlenderMarubatsuTiles[]; +extern const u8 gBerryBlenderParticlesTiles[]; +extern const u8 gBerryBlenderCountdownNumbersTiles[]; +extern const u8 gBerryBlenderStartTiles[]; +extern const u16 gBerryBlenderMiscPalette[]; +extern const u16 gBerryBlenderArrowPalette[]; + +// ewram +static EWRAM_DATA u8 gUnknown_020297DC = 0; +static EWRAM_DATA u32 gUnknown_020297E0 = 0; +static EWRAM_DATA u32 gUnknown_020297E4 = 0; +static EWRAM_DATA u8 gUnknown_020297E8 = 0; + +// iwram common +u16 gUnknown_03004830; +u8 gInGameOpponentsNo; +u16 gUnknown_03004840[10]; +struct BerryBlenderData* gBerryBlenderData; + +// iwram bss +IWRAM_DATA s16 gUnknown_03000510[8]; +IWRAM_DATA s16 gUnknown_03000520[6]; +IWRAM_DATA s16 gUnknown_0300052C; +IWRAM_DATA s16 gUnknown_0300052E; +IWRAM_DATA s32 gUnknown_03000530[6]; +IWRAM_DATA s32 gUnknown_03000548[5]; +IWRAM_DATA u32 gUnknown_0300055C; +IWRAM_DATA struct BlenderDebug sBlenderDebug; + +// this file's functions +void Blender_SetBankBerryData(u8 bank, u16 itemID); + +static void sub_80514A4(void); +static void sub_80514F0(void); +static void sub_804E56C(void); +static void Blender_SetPlayerNamesLocal(u8 NoOfOpponents); +static void sub_8051474(void); +static void sub_804E9F8(void); +static void sub_804F378(void); +static void sub_8051414(struct BgAffineDstData *dest); +static void sub_804F238(void); +static void sub_80501FC(void); +static bool8 sub_8051B8C(void); +static void sub_804F2A8(void); +static void sub_804F81C(void); +static void sub_805156C(void); +void sub_8051684(struct Sprite* sprite); +static void sub_8051AC8(s16* a0, u16 a1); +static void sub_805194C(u16 a0, u16 a1); +static void sub_8051A3C(u16 a0); +static void sub_8051B18(void); +static void sub_805123C(void); +static void sub_8050954(void); +static bool8 Blender_PrintBlendingRanking(void); +static bool8 Blender_PrintBlendingResults(void); +static void sub_80510E8(void); +static void sub_8050E30(void); +static void sub_805197C(u16 a0, u16 a1); +static void Blender_PrintMadePokeblockString(struct Pokeblock* pokeblock, u8* dst); +static void sub_8052BD0(u8 taskID); +static void sub_8052AF8(void); +static void sub_804F8C8(u8 taskID); +static void sub_804F9F4(u8 taskID); +static void sub_804FB1C(u8 taskID); +static void sub_8051C04(struct Sprite* sprite); +static void sub_8051650(struct Sprite* sprite); +static void sub_805181C(struct Sprite* sprite); +static void sub_80518CC(struct Sprite* sprite); + +// const data +static const u16 sBlenderCenterPal[] = INCBIN_U16("graphics/berry_blender/center.gbapal"); +static const u8 sBlenderCenterMap[] = INCBIN_U8("graphics/berry_blender/center_map.bin"); +static const u16 sBlenderOuterPal[] = INCBIN_U16("graphics/berry_blender/outer.gbapal"); + +// unreferenced pals? +static const u16 sUnknownPal_0[] = INCBIN_U16("graphics/unused/unknown/821604C.gbapal"); +static const u16 sUnknownArray_1[224] = {0}; + +// unreferenced Japanese strings +static const u8 sUnknownJpnString0[] = _("▶"); +static const u8 sUnknownJpnString1[] = _(" "); +static const u8 sUnknownJpnString2[] = _("カッコイ"); // "cool" (missing an イ at the end) +static const u8 sUnknownJpnString3[] = _("カワイイ"); // "cute" +static const u8 sUnknownJpnString4[] = _("ウツクシ"); // "beautiful" (missing an イ at the end) +static const u8 sUnknownJpnString5[] = _("カシコイ"); // "smart" +static const u8 sUnknownJpnString6[] = _("タクマシ"); // "tough" (missing an イ at the end) + +static const u8 gUnknown_08216249[] = _("\p"); + +// unreferenced; These appear to be the first names of four people who worked on the game. +static const u8 sUnknownJpnString7[10] = _("てつじ"); // Tetsuji (Ohta) +static const u8 sUnknownJpnString8[10] = _("あきと"); // Akito (Mori) +static const u8 sUnknownJpnString9[10] = _("シゲル"); // Shigeru (Ohmori) +static const u8 sUnknownJpnString10[10] = _("ヨシノリ"); // Yoshinori (Matsuda) + +static const u8 sUnknownText_2Pok[] = _("2Pok"); +static const u8 sUnknownText_3Pok[] = _("3Pok"); +static const u8 sUnknownText_4Pok[] = _("4Pok"); +static const u8* const gUnknown_08216284[] = +{ + sUnknownText_2Pok, sUnknownText_3Pok, sUnknownText_4Pok +}; + +// unreferenced player strings +static const u8 sUnknown1PString[4] = _("1P"); +static const u8 sUnknown2PString[4] = _("2P"); +static const u8 sUnknown3PString[4] = _("3P"); +static const u8 sUnknown4PString[4] = _("4P"); + +#ifdef ENGLISH +static const u8 sBlenderOpponentName1[] = _("MISTER"); +static const u8 sBlenderOpponentName2[] = _("LADDIE"); +static const u8 sBlenderOpponentName3[] = _("LASSIE"); +#else // GERMAN +static const u8 sBlenderOpponentName1[] = _("OPI"); +static const u8 sBlenderOpponentName2[] = _("KUMPEL"); +static const u8 sBlenderOpponentName3[] = _("TUSSI"); +#endif // ENGLISH +static const u8* const sBlenderOpponentsNames[] = +{ + sBlenderOpponentName1, sBlenderOpponentName2, sBlenderOpponentName3 +}; + +static const u8 sRedColorString[] = _("{COLOR RED}"); +static const u8 sNewLineString_0[] = _("\n"); +static const u8 sSpaceString_0[] = _(" "); + +static const s8 gUnknown_082162CC[][2] = +{ + {-1, -1}, {1, -1}, {-1, 1}, {1, 1} +}; + +static const u8 gUnknown_082162D4[][2] = +{ + {2, 6}, {23, 6}, {2, 12}, {23, 12}, {1, 6}, {22, 6}, {1, 12}, {22, 12} +}; + +static const u8 sBlenderSyncArrowsPos[][2] = +{ + {72, 32}, {168, 32}, {72, 128}, {168, 128} +}; + +static const u8 gUnknown_082162EC[3][4] = +{ + {-1, 0, 1, -1}, {-1, 0, 1, 2}, {0, 1, 2, 3} +}; + +static const u16 gUnknown_082162F8[] = {0, 0xC000, 0x4000, 0x8000}; +static const u8 gUnknown_08216300[] = {1, 1, 0}; +static const u8 gUnknown_08216303[] = {32, 224, 96, 160, 0}; + +static const TaskFunc gUnknown_08216308[] = +{ + sub_804F8C8, sub_804F9F4, sub_804FB1C +}; + +static const struct OamData sOamData_8216314 = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = 2, + .tileNum = 0, + .priority = 1, + .paletteNum = 0, + .affineParam = 0, +}; + +static const union AnimCmd sSpriteAnim_821631C[] = +{ + ANIMCMD_FRAME(16, 5, 1, 1), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_8216324[] = +{ + ANIMCMD_FRAME(16, 5, .vFlip = TRUE), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_821632C[] = +{ + ANIMCMD_FRAME(16, 5, .hFlip = TRUE), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_8216334[] = +{ + ANIMCMD_FRAME(16, 5, 0, 0), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_821633C[] = +{ + ANIMCMD_FRAME(48, 2, 1, 1), + ANIMCMD_FRAME(32, 5, 1, 1), + ANIMCMD_FRAME(48, 3, 1, 1), + ANIMCMD_FRAME(16, 5, 1, 1), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_8216350[] = +{ + ANIMCMD_FRAME(48, 2, .vFlip = TRUE), + ANIMCMD_FRAME(32, 5, .vFlip = TRUE), + ANIMCMD_FRAME(48, 3, .vFlip = TRUE), + ANIMCMD_FRAME(16, 5, .vFlip = TRUE), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_8216364[] = +{ + ANIMCMD_FRAME(48, 2, .hFlip = TRUE), + ANIMCMD_FRAME(32, 5, .hFlip = TRUE), + ANIMCMD_FRAME(48, 3, .hFlip = TRUE), + ANIMCMD_FRAME(16, 5, .hFlip = TRUE), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_8216378[] = +{ + ANIMCMD_FRAME(48, 2, 0, 0), + ANIMCMD_FRAME(32, 5, 0, 0), + ANIMCMD_FRAME(48, 3, 0, 0), + ANIMCMD_FRAME(16, 5, 0, 0), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_821638C[] = +{ + ANIMCMD_FRAME(0, 5, 1, 1), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_8216394[] = +{ + ANIMCMD_FRAME(0, 5, .vFlip = TRUE), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_821639C[] = +{ + ANIMCMD_FRAME(0, 5, .hFlip = TRUE), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_82163A4[] = +{ + ANIMCMD_FRAME(0, 5, 0, 0), + ANIMCMD_END +}; + +static const union AnimCmd *const sSpriteAnimTable_82163AC[] = +{ + sSpriteAnim_821631C, + sSpriteAnim_8216324, + sSpriteAnim_821632C, + sSpriteAnim_8216334, + sSpriteAnim_821633C, + sSpriteAnim_8216350, + sSpriteAnim_8216364, + sSpriteAnim_8216378, + sSpriteAnim_821638C, + sSpriteAnim_8216394, + sSpriteAnim_821639C, + sSpriteAnim_82163A4 +}; + +static const struct SpriteSheet gUnknown_082163DC = +{ + gBerryBlenderArrowTiles, 0x800, 46545 +}; + +static const struct SpritePalette gUnknown_082163E4 = +{ + gBerryBlenderMiscPalette, 46546 +}; + +static const struct SpritePalette gUnknown_082163EC = +{ + gBerryBlenderArrowPalette, 12312 +}; + +static const struct SpriteTemplate sBlenderSyncArrow_SpriteTemplate = +{ + .tileTag = 46545, + .paletteTag = 12312, + .oam = &sOamData_8216314, + .anims = sSpriteAnimTable_82163AC, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_8051C04 +}; + +static const struct OamData sOamData_821640C = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = 1, + .tileNum = 0, + .priority = 0, + .paletteNum = 0, + .affineParam = 0, +}; + +static const union AnimCmd sSpriteAnim_8216414[] = +{ + ANIMCMD_FRAME(0, 20), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_821641C[] = +{ + ANIMCMD_FRAME(4, 20, 1, 0), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_8216424[] = +{ + ANIMCMD_FRAME(8, 4), + ANIMCMD_FRAME(12, 4), + ANIMCMD_FRAME(8, 4), + ANIMCMD_FRAME(12, 4), + ANIMCMD_FRAME(8, 4), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_821643C[] = +{ + ANIMCMD_FRAME(8, 4), + ANIMCMD_END +}; + +static const union AnimCmd *const sSpriteAnimTable_8216444[] = +{ + sSpriteAnim_8216414, + sSpriteAnim_821641C, + sSpriteAnim_8216424, + sSpriteAnim_821643C, +}; + +static const struct SpriteSheet gUnknown_08216454 = +{ + gBerryBlenderMarubatsuTiles, 0x200, 48888 +}; + +static const struct SpriteTemplate sSpriteTemplate_821645C = +{ + .tileTag = 48888, + .paletteTag = 46546, + .oam = &sOamData_821640C, + .anims = sSpriteAnimTable_8216444, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_8051650 +}; + +static const struct OamData sOamData_8216474 = +{ + .y = 0, + .affineMode = 0, + .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 sSpriteAnim_821647C[] = +{ + ANIMCMD_FRAME(0, 3), + ANIMCMD_FRAME(1, 4), + ANIMCMD_FRAME(3, 5), + ANIMCMD_FRAME(1, 4), + ANIMCMD_FRAME(0, 3), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_8216494[] = +{ + ANIMCMD_FRAME(0, 3), + ANIMCMD_FRAME(2, 4), + ANIMCMD_FRAME(4, 5), + ANIMCMD_FRAME(2, 4), + ANIMCMD_FRAME(0, 3), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_82164AC[] = +{ + ANIMCMD_FRAME(0, 2), + ANIMCMD_FRAME(1, 2), + ANIMCMD_FRAME(2, 2), + ANIMCMD_FRAME(4, 4), + ANIMCMD_FRAME(3, 3), + ANIMCMD_FRAME(2, 2), + ANIMCMD_FRAME(1, 2), + ANIMCMD_FRAME(0, 2), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_82164D0[] = +{ + ANIMCMD_FRAME(5, 5, 1, 1), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_82164D8[] = +{ + ANIMCMD_FRAME(6, 5, 1, 1), + ANIMCMD_END +}; + +static const union AnimCmd *const sSpriteAnimTable_82164E0[] = +{ + sSpriteAnim_821647C, + sSpriteAnim_8216494, + sSpriteAnim_82164AC, + sSpriteAnim_82164D0, + sSpriteAnim_82164D8, +}; + +static const struct SpriteSheet gUnknown_082164F4 = +{ + gBerryBlenderParticlesTiles, 0xE0, 23456 +}; + +static const struct SpriteTemplate sSpriteTemplate_82164FC = +{ + .tileTag = 23456, + .paletteTag = 46546, + .oam = &sOamData_8216474, + .anims = sSpriteAnimTable_82164E0, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy +}; + +static const struct OamData sOamData_8216514 = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = 2, + .tileNum = 0, + .priority = 1, + .paletteNum = 0, + .affineParam = 0, +}; + +static const union AnimCmd sSpriteAnim_821651C[] = +{ + ANIMCMD_FRAME(32, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_8216524[] = +{ + ANIMCMD_FRAME(16, 30), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_821652C[] = +{ + ANIMCMD_FRAME(0, 30), + ANIMCMD_END +}; + +static const union AnimCmd *const sSpriteAnimTable_8216534[] = +{ + sSpriteAnim_821651C, + sSpriteAnim_8216524, + sSpriteAnim_821652C, +}; + +static const struct SpriteSheet gUnknown_08216540 = +{ + gBerryBlenderCountdownNumbersTiles, 0x600, 12345 +}; + +static const struct SpriteTemplate sSpriteTemplate_8216548 = +{ + .tileTag = 12345, + .paletteTag = 46546, + .oam = &sOamData_8216514, + .anims = sSpriteAnimTable_8216534, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_805181C +}; + +static const struct OamData sOamData_8216560 = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 1, + .x = 0, + .matrixNum = 0, + .size = 3, + .tileNum = 0, + .priority = 1, + .paletteNum = 0, + .affineParam = 0, +}; + +static const union AnimCmd sSpriteAnim_8216568[] = +{ + ANIMCMD_FRAME(0, 30), + ANIMCMD_END +}; + +static const union AnimCmd *const sSpriteAnimTable_8216570[] = +{ + sSpriteAnim_8216568, +}; + +static const struct SpriteSheet gUnknown_08216574 = +{ + gBerryBlenderStartTiles, 0x400, 12346 +}; + +static const struct SpriteTemplate sSpriteTemplate_821657C = +{ + .tileTag = 12346, + .paletteTag = 46546, + .oam = &sOamData_8216560, + .anims = sSpriteAnimTable_8216570, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80518CC +}; + +static const s16 gUnknown_08216594[][5] = +{ + {-10, 20, 10, 2, 1}, + {250, 20, 10, -2, 1}, + {-10, 140, 10, 2, -1}, + {250, 140, 10, -2, -1}, +}; + +static const u8 gUnknown_082165BC[][3] = +{ + {4, 3, 2}, {0, 4, 3}, {1, 0, 4}, {2, 1, 0}, {3, 2, 1}, {0, 2, 3}, {1, 3, 4}, {2, 4, 0}, {3, 0, 1}, {4, 1, 2}, +}; + +static const u8 gUnknown_082165DA[] = {1, 1, 2, 3, 4}; +static const u8 gUnknown_082165DF[] = {0x1C, 0x16, 0x13, 0x1A, 0x19, 0x0E, 0x0D, 0x0B, 0x07, 0x15}; +static const u8 gUnknown_082165E9[] = {6, 6, 6, 6, 5}; +static const u8 gUnknown_082165EE[] = {3, 3, 3, 2, 2}; +static const u8 gUnknown_082165F3[] = {3, 3, 3, 3, 2}; + +static const u8 sText_Space[] = _(" "); +static const u8 sText_BPM[] = _("BPM"); +static const u8 sText_Dash[] = _("-"); +static const u8 sNewLineString_1[] = _("\n"); +static const u8 sNewLineString_2[] = _("\n"); + +static void Blender_ControlHitPitch(void) +{ + m4aMPlayPitchControl(&gMPlay_SE2, 0xFFFF, (gBerryBlenderData->field_56 - 128) * 2); +} + +static void VBlankCB0_BerryBlender(void) +{ + sub_80514A4(); + sub_80514F0(); + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +static void VBlankCB1_BerryBlender(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +static bool8 sub_804E2EC(void) +{ + switch (gBerryBlenderData->field_1) + { + case 0: + sub_800D238(gUnknown_08E6C100, &ewram[0x10000]); + gBerryBlenderData->field_1++; + break; + case 1: + { + const void* offsetRead = sBlenderCenterMap; + void* offsetWrite = (void*)(VRAM + 0x4000); + + DmaCopy16(3, offsetRead, offsetWrite, 0x400); + LoadPalette(sBlenderCenterPal, 0, 0x100); + gBerryBlenderData->field_1++; + } + break; + case 2: + { + void* offsetRead = &ewram[0x10000]; + void* offsetWrite = (void*)(VRAM); + u32 size = 0x2000; + while (TRUE) + { + DmaCopy16(3, offsetRead, offsetWrite, 0x1000); + offsetRead += 0x1000; + offsetWrite += 0x1000; + size -= 0x1000; + if (size <= 0x1000) + { + DmaCopy16(3, offsetRead, offsetWrite, size); + break; + } + } + gBerryBlenderData->field_1++; + } + break; + case 3: + sub_800D238(gUnknown_08E6C920, &ewram[0x10000]); + gBerryBlenderData->field_1++; + break; + case 4: + sub_800D238(gUnknown_08E6D354, &ewram[0x13000]); + gBerryBlenderData->field_1++; + break; + case 5: + { + void* offsetRead = &ewram[0x10000]; + void* offsetWrite = (void*)(VRAM + 0xE000); + + DmaCopy16(3, offsetRead, offsetWrite, 0x1000); + gBerryBlenderData->field_1++; + } + break; + case 6: + { + void* offsetRead = &ewram[0x11000]; + void* offsetWrite = (void*)(VRAM + 0xF000); + + DmaCopy16(3, offsetRead, offsetWrite, 0x1000); + gBerryBlenderData->field_1++; + } + break; + case 7: + { + u16 i; + u16* palStore = (u16*)(&ewram[0x13000]); + void* offsetRead; + void* offsetWrite; + + for (i = 0; i < 640; i++) + { + *(palStore + i) |= 0x100; + } + offsetRead = &ewram[0x13000]; + offsetWrite = (void*)(VRAM + 0x6000); + DmaCopy16(3, offsetRead, offsetWrite, 0x500); + LoadPalette(sBlenderOuterPal, 0x80, 0x20); + gBerryBlenderData->field_1++; + } + break; + case 8: + LoadSpriteSheet(&gUnknown_082163DC); + LoadSpriteSheet(&gUnknown_082164F4); + LoadSpriteSheet(&gUnknown_08216454); + gBerryBlenderData->field_1++; + break; + case 9: + LoadSpriteSheet(&gUnknown_08216540); + LoadSpriteSheet(&gUnknown_08216574); + LoadSpritePalette(&gUnknown_082163EC); + LoadSpritePalette(&gUnknown_082163E4); + gBerryBlenderData->field_1 = 0; + return TRUE; + } + return FALSE; +} + +static void sub_804E4FC(void) +{ + REG_DISPCNT = 0x1341; + REG_BG2CNT = 0x4880; + REG_BG1CNT = 0xC0D; + REG_BG0HOFS = 0; + REG_BG0VOFS = 0; + REG_BG1HOFS = 0; + REG_BG1VOFS = 0; +} + +void sub_804E538(void) +{ + u8* field6F; //this temp value is needed to match + + gBerryBlenderData = (struct BerryBlenderData*)(&ewram[0x18000]); + + field6F = &gBerryBlenderData->field_6F; + gBerryBlenderData->field_0 = 0; + *field6F = 0; + + Blender_SetPlayerNamesLocal(gSpecialVar_0x8004); + SetMainCallback2(sub_804E56C); +} + +static void sub_804E56C(void) +{ + s32 i; + switch (gBerryBlenderData->field_0) + { + case 0: + REG_DISPCNT = 0; + ResetSpriteData(); + FreeAllSpritePalettes(); + SetVBlankCallback(NULL); + SetUpWindowConfig(&gWindowConfig_81E6F68); + InitMenuWindow(&gWindowConfig_81E6F68); + gBerryBlenderData->field_0++; + gBerryBlenderData->field_140 = 0; + gBerryBlenderData->field_13E = 0; + gBerryBlenderData->field_142 = 0x50; + gBerryBlenderData->field_144 = 0; + gBerryBlenderData->field_146 = 0; + gBerryBlenderData->field_1 = 0; + sub_8051474(); + break; + case 1: + if (sub_804E2EC()) + { + for (i = 0; i < BLENDER_MAX_PLAYERS; i++) + { + gBerryBlenderData->SyncArrowSpriteID[i] = CreateSprite(&sBlenderSyncArrow_SpriteTemplate, sBlenderSyncArrowsPos[i][0], sBlenderSyncArrowsPos[i][1], 1); + StartSpriteAnim(&gSprites[gBerryBlenderData->SyncArrowSpriteID[i]], i + 8); + } + SetVBlankCallback(VBlankCB0_BerryBlender); + gBerryBlenderData->field_0++; + } + break; + case 2: + BeginNormalPaletteFade(-1, 0, 0x10, 0, 0); + sub_8051474(); + gBerryBlenderData->field_0++; + break; + case 3: + sub_804E4FC(); + if (!gPaletteFade.active) + { + gBerryBlenderData->field_0++; + } + break; + case 4: + MenuDrawTextWindow(0, 14, 29, 19); + MenuPrintMessage(gOtherText_BlenderChooseBerry, 1, 15); + gBerryBlenderData->field_0++; + break; + case 5: + if (MenuUpdateWindowText()) + { + gBerryBlenderData->field_0++; + BeginNormalPaletteFade(-1, 0, 0, 0x10, 0); + } + break; + case 6: + if (!gPaletteFade.active) + { + sub_80A6978(); + gBerryBlenderData->field_0 = 0; + } + break; + } + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +void sub_804E738(struct Sprite* sprite) +{ + sprite->data1 += sprite->data6; + sprite->data2 -= sprite->data4; + sprite->data2 += sprite->data7; + sprite->data0 += sprite->data7; + sprite->data4--; + + if (sprite->data0 < sprite->data2) + { + sprite->data3 = sprite->data4 = sprite->data3 - 1; + if (++sprite->data5 > 3) + DestroySprite(sprite); + else + PlaySE(SE_TB_KARA); + } + sprite->pos1.x = sprite->data1; + sprite->pos1.y = sprite->data2; +} + +void sub_804E794(struct Sprite* sprite, s16 a2, s16 a3, s16 a4, s16 a5, s16 a6) +{ + sprite->data0 = a3; + sprite->data1 = a2; + sprite->data2 = a3; + sprite->data3 = a4; + sprite->data4 = 10; + sprite->data5 = 0; + sprite->data6 = a5; + sprite->data7 = a6; + sprite->callback = sub_804E738; +} + +static void sub_804E7C0(u16 a0, u8 a1) +{ + u8 spriteID = sub_80A7DEC(a0 + 123, 0, 80, a1 & 1); + sub_804E794(&gSprites[spriteID], gUnknown_08216594[a1][0], gUnknown_08216594[a1][1], gUnknown_08216594[a1][2], gUnknown_08216594[a1][3], gUnknown_08216594[a1][4]); +} + +static void Blender_CopyBerryData(struct BlenderBerry* berry, u16 itemID) +{ + const struct Berry *berryInfo = GetBerryInfo(itemID + 124); + berry->itemID = itemID; + StringCopy(berry->name, berryInfo->name); + berry->flavours[FLAVOUR_SPICY] = berryInfo->spicy; + berry->flavours[FLAVOUR_DRY] = berryInfo->dry; + berry->flavours[FLAVOUR_SWEET] = berryInfo->sweet; + berry->flavours[FLAVOUR_BITTER] = berryInfo->bitter; + berry->flavours[FLAVOUR_SOUR] = berryInfo->sour; + berry->smoothness = berryInfo->smoothness; +} + +static void Blender_SetPlayerNamesLocal(u8 NoOfOpponents) +{ + int i; + if (NoOfOpponents) + { + for (i = 0; i < 4; i++) + gLinkPlayers[i].language = GAME_LANGUAGE; + } + switch (NoOfOpponents) + { + case 0: + gInGameOpponentsNo = 0; + break; + case 1: + gInGameOpponentsNo = 1; + gBerryBlenderData->playersNo = 2; + StringCopy(gLinkPlayers[0].name, gSaveBlock2.playerName); + StringCopy(gLinkPlayers[1].name, sBlenderOpponentsNames[0]); + break; + case 2: + gInGameOpponentsNo = 2; + gBerryBlenderData->playersNo = 3; + StringCopy(gLinkPlayers[0].name, gSaveBlock2.playerName); + StringCopy(gLinkPlayers[1].name, sBlenderOpponentsNames[0]); + StringCopy(gLinkPlayers[2].name, sBlenderOpponentsNames[1]); + break; + case 3: + gInGameOpponentsNo = 3; + gBerryBlenderData->playersNo = 4; + StringCopy(gLinkPlayers[0].name, gSaveBlock2.playerName); + StringCopy(gLinkPlayers[1].name, sBlenderOpponentsNames[0]); + StringCopy(gLinkPlayers[2].name, sBlenderOpponentsNames[1]); + StringCopy(gLinkPlayers[3].name, sBlenderOpponentsNames[2]); + break; + } +} + +void sub_804E990(void) +{ + s32 i; + + REG_DISPCNT = 0; + gBerryBlenderData = (struct BerryBlenderData*)(&ewram[0x18000]); + gBerryBlenderData->field_0 = 0; + gBerryBlenderData->field_134 = 0; + for (i = 0; i < BLENDER_MAX_PLAYERS; i++) + { + gBerryBlenderData->chosenItemID[i] = 0; + } + Blender_SetPlayerNamesLocal(gSpecialVar_0x8004); + if (gSpecialVar_0x8004 == 0) + SetMainCallback2(sub_804E9F8); + else + SetMainCallback2(sub_804F378); +} + +static void sub_804E9F8(void) +{ + int i, j; + switch (gBerryBlenderData->field_0) + { + case 0: + ResetSpriteData(); + FreeAllSpritePalettes(); + ResetTasks(); + SetVBlankCallback(VBlankCB0_BerryBlender); + SetUpWindowConfig(&gWindowConfig_81E6F68); + InitMenuWindow(&gWindowConfig_81E6F68); + gLinkType = 0x4422; + gBerryBlenderData->field_0++; + gBerryBlenderData->field_4E = 0; + gBerryBlenderData->field_7E = 0; + gBerryBlenderData->field_144 = 0; + gBerryBlenderData->field_146 = 0; + for (i = 0; i < BLENDER_MAX_PLAYERS; i++) + { + gBerryBlenderData->field_70[i] = 0; + for (j = 0; j < 3; j++) + { + gBerryBlenderData->scores[i][j] = 0; + } + } + gBerryBlenderData->field_7C = 0; + gBerryBlenderData->field_56 = 0; + gBerryBlenderData->arrowPos = 0; + gBerryBlenderData->max_RPM = 0; + gBerryBlenderData->field_1 = 0; + break; + case 1: + if (sub_804E2EC()) + { + gBerryBlenderData->field_0++; + sub_8051474(); + } + break; + case 2: + for (i = 0; i < BLENDER_MAX_PLAYERS; i++) + { + gBerryBlenderData->SyncArrowSprite2ID[i] = CreateSprite(&sBlenderSyncArrow_SpriteTemplate, sBlenderSyncArrowsPos[i][0], sBlenderSyncArrowsPos[i][1], 1); + StartSpriteAnim(&gSprites[gBerryBlenderData->SyncArrowSprite2ID[i]], i + 8); + } + gBerryBlenderData->field_0++; + break; + case 3: + BeginNormalPaletteFade(-1, 0, 0x10, 0, 0); + gBerryBlenderData->field_0++; + break; + case 4: + sub_804E4FC(); + if (!gPaletteFade.active) + { + gBerryBlenderData->field_0++; + } + break; + case 5: + MenuDrawTextWindow(0, 13, 29, 19); + MenuPrint(gOtherText_LinkStandby3, 1, 14); + gBerryBlenderData->field_0 = 8; + gBerryBlenderData->framesToWait = 0; + break; + case 8: + gBerryBlenderData->field_0++; + gBerryBlenderData->field_13C = 0; + Blender_CopyBerryData(&gBerryBlenderData->blendedBerries[0], gScriptItemId); + memcpy(gBlockSendBuffer, &gBerryBlenderData->blendedBerries[0], sizeof(struct BlenderBerry)); + sub_80084A4(); + gBerryBlenderData->framesToWait = 0; + break; + case 9: + if (sub_8007ECC()) + { + ResetBlockReceivedFlags(); + if (GetMultiplayerId() == 0) + sub_8007E9C(4); + gBerryBlenderData->field_0++; + } + break; + case 10: + if (++gBerryBlenderData->framesToWait > 20) + { + MenuZeroFillScreen(); + if (GetBlockReceivedStatus() == sub_8008198()) + { + for (i = 0; i < GetLinkPlayerCount(); i++) + { + memcpy(&gBerryBlenderData->blendedBerries[i], &gBlockRecvBuffer[i][0], sizeof(struct BlenderBerry)); + gBerryBlenderData->chosenItemID[i] = gBerryBlenderData->blendedBerries[i].itemID; + } + ResetBlockReceivedFlags(); + gBerryBlenderData->field_0++; + } + } + break; + case 11: + gBerryBlenderData->playersNo = GetLinkPlayerCount(); + for (i = 0; i < BLENDER_MAX_PLAYERS; i++) + { + if (gBerryBlenderData->field_13C == gUnknown_082162EC[gBerryBlenderData->playersNo - 2][i]) + { + sub_804E7C0(gBerryBlenderData->chosenItemID[gBerryBlenderData->field_13C], i); + break; + } + } + gBerryBlenderData->framesToWait = 0; + gBerryBlenderData->field_0++; + gBerryBlenderData->field_13C++; + break; + case 12: + if (++gBerryBlenderData->framesToWait > 60) + { + if (gBerryBlenderData->field_13C >= gBerryBlenderData->playersNo) + { + gBerryBlenderData->field_0++; + gBerryBlenderData->arrowPos = gUnknown_082162F8[gUnknown_08216300[gBerryBlenderData->playersNo - 2]] - 22528; + } + else + gBerryBlenderData->field_0--; + gBerryBlenderData->framesToWait = 0; + } + break; + case 13: + if (sub_8007ECC()) + { + gBerryBlenderData->field_0++; + sub_8051414(&gBerryBlenderData->field_168); + } + break; + case 14: + REG_DISPCNT |= 0x400; + gBerryBlenderData->arrowPos += 0x200; + gBerryBlenderData->field_142 += 4; + if (gBerryBlenderData->field_142 > 255) + { + gBerryBlenderData->field_0++; + gBerryBlenderData->field_142 = 256; + gBerryBlenderData->arrowPos = gUnknown_082162F8[gUnknown_08216300[gBerryBlenderData->playersNo - 2]]; + REG_BG2CNT = 0x4882; + gBerryBlenderData->framesToWait = 0; + sub_804F238(); + sub_804F2A8(); + } + sub_8051414(&gBerryBlenderData->field_168); + break; + case 15: + if (sub_8051B8C()) + { + gBerryBlenderData->framesToWait = 0; + gBerryBlenderData->field_0++; + } + sub_8051414(&gBerryBlenderData->field_168); + break; + case 16: + CreateSprite(&sSpriteTemplate_8216548, 120, -16, 3); + gBerryBlenderData->field_0++; + break; + case 18: + gBerryBlenderData->field_0++; + break; + case 19: + sub_80084A4(); + gBerryBlenderData->field_0++; + break; + case 20: + if (sub_8007ECC()) + { + sub_8007E24(); + gBerryBlenderData->field_0++; + } + break; + case 21: + gBerryBlenderData->field_56 = 128; + gBerryBlenderData->gameFrameTime = 0; + SetMainCallback2(sub_80501FC); + if (GetCurrentMapMusic() != 403) + { + gBerryBlenderData->field_178 = GetCurrentMapMusic(); + } + PlayBGM(BGM_CYCLING); + break; + case 100: + MenuDrawTextWindow(0, 13, 29, 19); + MenuPrintMessage(gOtherText_LinkNotFound, 1, 15); + gBerryBlenderData->field_0++; + break; + case 101: + if (MenuUpdateWindowText()) + gBerryBlenderData->field_0++; + break; + case 102: + if (!gPaletteFade.active) + SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); + break; + } + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +static void sub_804F0F4(void) +{ + REG_DISPCNT = 0; + + ResetSpriteData(); + FreeAllSpritePalettes(); + ResetTasks(); + + SetVBlankCallback(VBlankCB0_BerryBlender); + + SetUpWindowConfig(&gWindowConfig_81E6F68); + InitMenuWindow(&gWindowConfig_81E6F68); + + gLinkType = 0x4422; + + gBerryBlenderData->field_4E = 0; + gBerryBlenderData->field_56 = 0; + gBerryBlenderData->arrowPos = 0; + gBerryBlenderData->max_RPM = 0; + gBerryBlenderData->field_144 = 0; + gBerryBlenderData->field_146 = 0; + gBerryBlenderData->field_0++; +} + +static u8 sub_804F16C(u16 arrowPos, u8 a1) +{ + u32 var1 = (arrowPos / 256) + 24; + u8 arrID = gBerryBlenderData->field_A2[a1]; + u32 var2 = gUnknown_08216303[arrID]; + + if (var1 >= var2 && var1 < var2 + 48) + { + if (var1 >= var2 + 20 && var1 < var2 + 28) + return 2; + else + return 1; + } + else + return 0; +} + +static void sub_804F1BC(u16 itemID, u8 a1, struct BlenderBerry* berry) +{ + u16 r4 = 0; + u16 i; + if (itemID == ITEM_ENIGMA_BERRY) + { + for (i = 0; i < 5; i++) + { + if (berry->flavours[r4] > berry->flavours[i]) + r4 = i; + } + r4 += 5; + } + else + { + r4 = itemID - 133; + if (r4 >= 5) + r4 = (r4 % 5) + 5; + } + for (i = 0; i < a1 - 1; i++) + { + Blender_SetBankBerryData(i + 1, gUnknown_082165BC[r4][i] + 133); + } +} + +static void sub_804F238(void) +{ + s32 i, j; + for (i = 0; i < BLENDER_MAX_PLAYERS; i++) + { + gBerryBlenderData->field_A2[i] = 0xFF; + gBerryBlenderData->field_9A[i] = gUnknown_082162EC[gBerryBlenderData->playersNo - 2][i]; + } + for (j = 0; j < BLENDER_MAX_PLAYERS; j++) + { + for (i = 0; i < BLENDER_MAX_PLAYERS; i++) + { + if (gBerryBlenderData->field_9A[i] == j) + gBerryBlenderData->field_A2[j] = i; + } + } +} + +static void sub_804F2A8(void) +{ + int i; + for (i = 0; i < BLENDER_MAX_PLAYERS; i++) + { + if (gBerryBlenderData->field_9A[i] != 0xFF) + { + u8* stringPtr = gStringVar1; + + gBerryBlenderData->SyncArrowSpriteID[gBerryBlenderData->field_9A[i]] = gBerryBlenderData->SyncArrowSprite2ID[i]; + StartSpriteAnim(&gSprites[gBerryBlenderData->SyncArrowSpriteID[gBerryBlenderData->field_9A[i]]], i); + if (GetMultiplayerId() == gBerryBlenderData->field_9A[i]) + stringPtr = StringCopy(stringPtr, sRedColorString); + StringCopy(stringPtr, gLinkPlayers[gBerryBlenderData->field_9A[i]].name); + MenuPrint_PixelCoords(gStringVar1, gUnknown_082162D4[i][0] * 8 + 1, gUnknown_082162D4[i][1] * 8, 1); + } + } +} + +static void sub_804F378(void) +{ + s32 i, j; + switch (gBerryBlenderData->field_0) + { + case 0: + sub_804F0F4(); + Blender_SetBankBerryData(0, gScriptItemId); + Blender_CopyBerryData(&gBerryBlenderData->blendedBerries[0], gScriptItemId); + sub_804F1BC(gScriptItemId, gBerryBlenderData->playersNo, &gBerryBlenderData->blendedBerries[0]); + for (i = 0; i < BLENDER_MAX_PLAYERS; i++) + { + gBerryBlenderData->field_70[i] = 0; + for (j = 0; j < 3; j++) + { + gBerryBlenderData->scores[i][j] = 0; + } + } + gBerryBlenderData->field_7C = 0; + gBerryBlenderData->field_1 = 0; + break; + case 1: + if (sub_804E2EC()) + { + gBerryBlenderData->field_0++; + sub_8051474(); + } + break; + case 2: + for (i = 0; i < BLENDER_MAX_PLAYERS; i++) + { + gBerryBlenderData->SyncArrowSprite2ID[i] = CreateSprite(&sBlenderSyncArrow_SpriteTemplate, sBlenderSyncArrowsPos[i][0], sBlenderSyncArrowsPos[i][1], 1); + StartSpriteAnim(&gSprites[gBerryBlenderData->SyncArrowSprite2ID[i]], i + 8); + } + gBerryBlenderData->field_0++; + break; + case 3: + BeginNormalPaletteFade(-1, 0, 0x10, 0, 0); + gBerryBlenderData->field_0++; + gBerryBlenderData->framesToWait = 0; + break; + case 4: + if (++gBerryBlenderData->framesToWait == 2) + sub_804E4FC(); + if (!gPaletteFade.active) + gBerryBlenderData->field_0 = 8; + break; + case 8: + gBerryBlenderData->field_0 = 11; + gBerryBlenderData->field_13C = 0; + break; + case 11: + for (i = 0; i < BLENDER_MAX_PLAYERS; i++) + { + u32 var = gUnknown_082162EC[gBerryBlenderData->playersNo - 2][i]; + if (gBerryBlenderData->field_13C == var) + { + sub_804E7C0(gBerryBlenderData->chosenItemID[gBerryBlenderData->field_13C], i); + break; + } + } + gBerryBlenderData->framesToWait = 0; + gBerryBlenderData->field_0++; + gBerryBlenderData->field_13C++; + break; + case 12: + if (++gBerryBlenderData->framesToWait > 60) + { + if (gBerryBlenderData->field_13C >= gBerryBlenderData->playersNo) + { + gBerryBlenderData->arrowPos = gUnknown_082162F8[gUnknown_08216300[gBerryBlenderData->playersNo - 2]] - 22528; + gBerryBlenderData->field_0++; + } + else + gBerryBlenderData->field_0--; + gBerryBlenderData->framesToWait = 0; + } + break; + case 13: + gBerryBlenderData->field_0++; + sub_804F238(); + PlaySE(SE_RU_HYUU); + sub_8051414(&gBerryBlenderData->field_168); + break; + case 14: + REG_DISPCNT |= 0x400; + gBerryBlenderData->arrowPos += 0x200; + gBerryBlenderData->field_142 += 4; + if (gBerryBlenderData->field_142 > 255) + { + gBerryBlenderData->field_0++; + gBerryBlenderData->field_142 = 256; + gBerryBlenderData->arrowPos = gUnknown_082162F8[gUnknown_08216300[gBerryBlenderData->playersNo - 2]]; + REG_BG2CNT = 0x4882; + gBerryBlenderData->framesToWait = 0; + PlaySE(SE_TRACK_DOOR);; + sub_804F2A8(); + } + sub_8051414(&gBerryBlenderData->field_168); + break; + case 15: + if (sub_8051B8C()) + { + gBerryBlenderData->field_0++; + } + sub_8051414(&gBerryBlenderData->field_168); + break; + case 16: + CreateSprite(&sSpriteTemplate_8216548, 120, -16, 3); + gBerryBlenderData->field_0++; + break; + case 18: + gBerryBlenderData->field_0++; + break; + case 19: + gBerryBlenderData->field_0++; + break; + case 20: + gBerryBlenderData->field_0++; + break; + case 21: + sub_804F81C(); + gBerryBlenderData->field_56 = 128; + gBerryBlenderData->gameFrameTime = 0; + gBerryBlenderData->field_14B = 0; + gBerryBlenderData->field_7E = 0; + SetMainCallback2(sub_80501FC); + + for (i = 0; i < gSpecialVar_0x8004; i++) + { + gBerryBlenderData->field_148[i] = CreateTask(gUnknown_08216308[i], 10 + i); + } + + if (GetCurrentMapMusic() != 403) + { + gBerryBlenderData->field_178 = GetCurrentMapMusic(); + } + PlayBGM(BGM_CYCLING); + PlaySE(SE_MOTER); + Blender_ControlHitPitch(); + break; + } + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +static void sub_804F81C(void) +{ + s32 i; + for (i = 0; i < 4; i++) + { + gSendCmd[0] = 0; + gSendCmd[2] = 0; + gRecvCmds[0][i] = 0; + gRecvCmds[2][i] = 0; + } +} + +static void sub_804F844(u8 taskID) +{ + if(++gTasks[taskID].data[0] > gTasks[taskID].data[1]) + { + gRecvCmds[2][gTasks[taskID].data[2]] = 0x2345; + DestroyTask(taskID); + } +} + +static void sub_804F890(u8 a0, u8 a1) +{ + u8 taskID = CreateTask(sub_804F844, 80); + gTasks[taskID].data[1] = a1; + gTasks[taskID].data[2] = a0; +} + +static void sub_804F8C8(u8 taskID) +{ + if (sub_804F16C(gBerryBlenderData->arrowPos, 1) == 2) + { + if (gTasks[taskID].data[0] == 0) + { + if (gBerryBlenderData->field_14B == 0) + { + u8 rand = Random() / 655; + if (gBerryBlenderData->field_56 < 500) + { + if (rand > 75) + gRecvCmds[2][1] = 0x4523; + else + gRecvCmds[2][1] = 0x5432; + gRecvCmds[2][1] = 0x5432; // ??? + } + else if (gBerryBlenderData->field_56 < 1500) + { + if (rand > 80) + gRecvCmds[2][1] = 0x4523; + else + { + u8 value = rand - 21; + if (value < 60) + gRecvCmds[2][1] = 0x5432; + else if (rand < 10) + sub_804F890(1, 5); + } + } + else if (rand <= 90) + { + u8 value = rand - 71; + if (value < 20) + gRecvCmds[2][1] = 0x5432; + else if (rand < 30) + sub_804F890(1, 5); + } + else + gRecvCmds[2][1] = 0x4523; + } + else + gRecvCmds[2][1] = 0x4523; + + gTasks[taskID].data[0] = 1; + } + } + else + gTasks[taskID].data[0] = 0; +} + +static void sub_804F9F4(u8 taskID) +{ + u32 var1 = (gBerryBlenderData->arrowPos + 0x1800) & 0xFFFF; + u32 var2 = gBerryBlenderData->field_A2[2] & 0xFF; + if ((var1 >> 8) > gUnknown_08216303[var2] + 20 && (var1 >> 8) < gUnknown_08216303[var2] + 40) + { + if (gTasks[taskID].data[0] == 0) + { + if (gBerryBlenderData->field_14B == 0) + { + u8 rand = Random() / 655; + if (gBerryBlenderData->field_56 < 500) + { + if (rand > 66) + gRecvCmds[2][2] = 0x4523; + else + gRecvCmds[2][2] = 0x5432; + } + else + { + u8 value; + if (rand > 65) + gRecvCmds[2][2] = 0x4523; + value = rand - 41; + if (value < 25) + gRecvCmds[2][2] = 0x5432; + if (rand < 10) + sub_804F890(2, 5); + } + + gTasks[taskID].data[0] = 1; + } + else + { + gRecvCmds[2][2] = 0x4523; + gTasks[taskID].data[0] = 1; + } + } + } + else + gTasks[taskID].data[0] = 0; +} + +static void sub_804FB1C(u8 taskID) +{ + u32 var1, var2; + + var1 = (gBerryBlenderData->arrowPos + 0x1800) & 0xFFFF; + var2 = gBerryBlenderData->field_A2[3] & 0xFF; + if ((var1 >> 8) > gUnknown_08216303[var2] + 20 && (var1 >> 8) < gUnknown_08216303[var2] + 40) + { + if (gTasks[taskID].data[0] == 0) + { + if (gBerryBlenderData->field_14B == 0) + { + u8 rand = (Random() / 655); + if (gBerryBlenderData->field_56 < 500) + { + if (rand > 88) + gRecvCmds[2][3] = 0x4523; + else + gRecvCmds[2][3] = 0x5432; + } + else + { + if (rand > 60) + gRecvCmds[2][3] = 0x4523; + else + { + s8 value = rand - 56; // makes me wonder what the original code was + u8 value2 = value; + if (value2 < 5) + gRecvCmds[2][3] = 0x5432; + } + if (rand < 5) + sub_804F890(3, 5); + } + gTasks[taskID].data[0] = 1; + } + else + { + gRecvCmds[2][3] = 0x4523; + gTasks[taskID].data[0] = 1; + } + } + } + else + gTasks[taskID].data[0] = 0; +} + +static void sub_804FC48(u16 a0, u8 a1) +{ + u8 spriteID; + + spriteID = CreateSprite(&sSpriteTemplate_821645C, + sBlenderSyncArrowsPos[a1][0] - (10 * gUnknown_082162CC[a1][0]), + sBlenderSyncArrowsPos[a1][1] - (10 * gUnknown_082162CC[a1][1]), + 1); + if (a0 == 0x4523) + { + StartSpriteAnim(&gSprites[spriteID], 2); + gSprites[spriteID].callback = sub_8051684; + PlaySE(SE_RU_GASHIN); + } + else if (a0 == 0x5432) + { + StartSpriteAnim(&gSprites[spriteID], 0); + PlaySE(SE_SEIKAI); + } + else if (a0 == 0x2345) + { + StartSpriteAnim(&gSprites[spriteID], 1); + PlaySE(SE_HAZURE); + } + sub_805156C(); +} + +static void sub_804FD30(u16 a0) +{ + Blender_ControlHitPitch(); + switch (a0) + { + case 0x4523: + if (gBerryBlenderData->field_56 < 1500) + gBerryBlenderData->field_56 += (384 / gUnknown_082165DA[gBerryBlenderData->playersNo]); + else + { + gBerryBlenderData->field_56 += (128 / gUnknown_082165DA[gBerryBlenderData->playersNo]); + sub_8051AC8(&gBerryBlenderData->field_144, (gBerryBlenderData->field_56 / 100) - 10); + sub_8051AC8(&gBerryBlenderData->field_146, (gBerryBlenderData->field_56 / 100) - 10); + } + break; + case 0x5432: + if (gBerryBlenderData->field_56 < 1500) + gBerryBlenderData->field_56 += (256 / gUnknown_082165DA[gBerryBlenderData->playersNo]); + break; + case 0x2345: + gBerryBlenderData->field_56 -= (256 / gUnknown_082165DA[gBerryBlenderData->playersNo]); + if (gBerryBlenderData->field_56 < 128) + gBerryBlenderData->field_56 = 128; + break; + } +} + +static void sub_804FE70(void) +{ + s32 i; + + if (gSpecialVar_0x8004 != 0) + { + if (gSendCmd[2] != 0) + { + gRecvCmds[2][0] = gSendCmd[2]; + gRecvCmds[0][0] = 0x4444; + gSendCmd[2] = 0; + } + for (i = 1; i < 4; i++) + { + if (gRecvCmds[2][i] != 0) + gRecvCmds[0][i] = 0x4444; + } + } + for (i = 0; i < gBerryBlenderData->playersNo; i++) + { + if (gRecvCmds[0][i] == 0x4444) + { + u32 var = gBerryBlenderData->field_A2[i]; + if (gRecvCmds[2][i] == 0x4523) + { + sub_804FD30(0x4523); + gBerryBlenderData->field_13E += (gBerryBlenderData->field_56 / 55); + if (gBerryBlenderData->field_13E >= 1000) + gBerryBlenderData->field_13E = 1000; + sub_804FC48(0x4523, var); + gBerryBlenderData->scores[i][BLENDER_SCORE_BEST]++; + } + else if (gRecvCmds[2][i] == 0x5432) + { + sub_804FD30(0x5432); + gBerryBlenderData->field_13E += (gBerryBlenderData->field_56 / 70); + sub_804FC48(0x5432, var); + gBerryBlenderData->scores[i][BLENDER_SCORE_GOOD]++; + } + else if (gRecvCmds[2][i] == 0x2345) + { + sub_804FC48(0x2345, var); + sub_804FD30(0x2345); + if (gBerryBlenderData->field_4.win_field_F > 1000) + gBerryBlenderData->field_13E = 1000; + if (gBerryBlenderData->scores[i][BLENDER_SCORE_MISS] < 999) + gBerryBlenderData->scores[i][BLENDER_SCORE_MISS]++; + } + if (gRecvCmds[2][i] == 0x2345 || gRecvCmds[2][i] == 0x4523 || gRecvCmds[2][i] == 0x5432) + { + if (gBerryBlenderData->field_56 > 1500) + m4aMPlayTempoControl(&gMPlay_BGM, ((gBerryBlenderData->field_56 - 750) / 20) + 256); + else + m4aMPlayTempoControl(&gMPlay_BGM, 256); + } + } + } + if (gSpecialVar_0x8004 != 0) + { + for (i = 0; i < gBerryBlenderData->playersNo; i++) + { + gRecvCmds[0][i] = 0; + gRecvCmds[2][i] = 0; + } + } +} + +static void sub_80500A8(void) +{ + bool8 A_pressed = 0; + u8 var2 = gBerryBlenderData->field_A2[GetMultiplayerId()]; + if (gBerryBlenderData->field_6F == 0) + { + if (gSaveBlock2.optionsButtonMode == OPTIONS_BUTTON_MODE_L_EQUALS_A && gMain.newKeys & A_BUTTON) + A_pressed = ((gMain.heldKeysRaw & (A_BUTTON | L_BUTTON)) != (A_BUTTON | L_BUTTON)); + else if (gMain.newKeys & A_BUTTON) + A_pressed = 1; + if (A_pressed) + { + u8 var3; + StartSpriteAnim(&gSprites[gBerryBlenderData->SyncArrowSpriteID[gBerryBlenderData->field_9A[var2]]], var2 + 4); + var3 = sub_804F16C(gBerryBlenderData->arrowPos, GetMultiplayerId()); + if (var3 == 2) + gSendCmd[2] = 0x4523; + else if (var3 == 1) + gSendCmd[2] = 0x5432; + else + gSendCmd[2] = 0x2345; + } + } + if (++gBerryBlenderData->field_7E > 5) + { + if (gBerryBlenderData->field_56 > 128) + gBerryBlenderData->field_56--; + gBerryBlenderData->field_7E = 0; + } + if (gUnknown_020297ED && gMain.newKeys & L_BUTTON) + gBerryBlenderData->field_14B ^= 1; +} + +static void sub_80501FC(void) +{ + sub_8051474(); + if (gBerryBlenderData->gameFrameTime < (99 * 60 * 60) + (59 * 60)) // game time can't be longer than 99 minutes and 59 seconds, can't print 3 digits + gBerryBlenderData->gameFrameTime++; + sub_80500A8(); + SetLinkDebugValues((u16)(gBerryBlenderData->field_56), gBerryBlenderData->field_13E); + sub_804FE70(); + sub_805194C(gBerryBlenderData->field_13E, 1000); + sub_8051A3C(gBerryBlenderData->field_56); + sub_8051B18(); + sub_805123C(); + if (gBerryBlenderData->field_6F == 0 && gBerryBlenderData->field_140 >= 1000) + { + gBerryBlenderData->field_13E = 1000; + gBerryBlenderData->field_6F = 1; + SetMainCallback2(sub_8050954); + } + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +static bool8 sub_80502A4(struct BlenderBerry* berries, u8 index1, u8 index2) +{ + if (berries[index1].itemID != berries[index2].itemID + || (StringCompare(berries[index1].name, berries[index2].name) == 0 + && (berries[index1].flavours[0] == berries[index2].flavours[0] + && berries[index1].flavours[1] == berries[index2].flavours[1] + && berries[index1].flavours[2] == berries[index2].flavours[2] + && berries[index1].flavours[3] == berries[index2].flavours[3] + && berries[index1].flavours[4] == berries[index2].flavours[4] + && berries[index1].smoothness == berries[index2].smoothness))) + return TRUE; + else + return FALSE; +} + +u32 Blender_GetPokeblockColor(struct BlenderBerry* berries, s16* a1, u8 playersNo, u8 a3) +{ + s16 vars[5]; + s32 i; + s32 r6; + u8 r2; + + for (i = 0; i <= 5; i++) // bug, writing one index too far + vars[i] = a1[i]; + r6 = 0; + for (i = 0; i < 5; i++) + { + if (vars[i] == 0) + r6++; + } + if (r6 == 5 || a3 > 3) + return 12; + for (i = 0; i < playersNo; i++) + { + for (r6 = 0; r6 < playersNo; r6++) + { + if (berries[i].itemID == berries[r6].itemID && i != r6 + && (berries[i].itemID != ITEM_ENIGMA_BERRY || sub_80502A4(berries, i, r6))) + return 12; + } + } + r2 = 0; + for (r2 = 0, i = 0; i < 5; i++) + { + if (vars[i] > 0) + r2++; + } + if (r2 > 3) + return 13; + if (r2 == 3) + return 11; + for (i = 0; i < 5; i++) + { + if (vars[i] > 50) + return 14; + } + if (r2 == 1 && vars[0] > 0) + return 1; + if (r2 == 1 && vars[1] > 0) + return 2; + if (r2 == 1 && vars[2] > 0) + return 3; + if (r2 == 1 && vars[3] > 0) + return 4; + if (r2 == 1 && vars[4] > 0) + return 5; + if (r2 == 2) + { + s32 var = 0; + for (i = 0; i < 5; i++) + { + if (vars[i] > 0) + gUnknown_03000520[var++] = i; + } + if (vars[gUnknown_03000520[0]] >= vars[gUnknown_03000520[1]]) + { + if (gUnknown_03000520[0] == 0) + return (gUnknown_03000520[1] << 16) | 6; + if (gUnknown_03000520[0] == 1) + return (gUnknown_03000520[1] << 16) | 7; + if (gUnknown_03000520[0] == 2) + return (gUnknown_03000520[1] << 16) | 8; + if (gUnknown_03000520[0] == 3) + return (gUnknown_03000520[1] << 16) | 9; + if (gUnknown_03000520[0] == 4) + return (gUnknown_03000520[1] << 16) | 10; + } + else + { + if (gUnknown_03000520[1] == 0) + return (gUnknown_03000520[0] << 16) | 6; + if (gUnknown_03000520[1] == 1) + return (gUnknown_03000520[0] << 16) | 7; + if (gUnknown_03000520[1] == 2) + return (gUnknown_03000520[0] << 16) | 8; + if (gUnknown_03000520[1] == 3) + return (gUnknown_03000520[0] << 16) | 9; + if (gUnknown_03000520[1] == 4) + return (gUnknown_03000520[0] << 16) | 10; + } + } + return 0; +} + +static void sub_80504F0(s16 value) +{ + gUnknown_0300052C = value; +} + +s16 unref_sub_80504FC(void) +{ + return gUnknown_0300052C; +} + +static void sub_8050508(s16 value) +{ + gUnknown_0300052E = value; +} + +s16 unref_sub_8050514(void) +{ + return gUnknown_0300052E; +} + +#ifdef NONMATCHING + +static void Blender_CalculatePokeblock(struct BlenderBerry* berries, struct Pokeblock* pokeblock, u8 playersNo, u8* flavours, u16 maxRPM) +{ + s32 i; + s32 j; + s32 savedEntry; + s32 var3; + s32 var4; + u32 var6; + s32 var11; + u16 rand; + + for (i = 0; i < 6; i++) + gUnknown_03000510[i] = 0; + for (i = 0; i < playersNo; i++) + { + for (j = 0; j < 5; j++) + gUnknown_03000510[j] += berries[i].flavours[j]; + } + + savedEntry = gUnknown_03000510[0]; + gUnknown_03000510[0] -= gUnknown_03000510[1]; + gUnknown_03000510[1] -= gUnknown_03000510[2]; + gUnknown_03000510[2] -= gUnknown_03000510[3]; + gUnknown_03000510[3] -= gUnknown_03000510[4]; + gUnknown_03000510[4] -= savedEntry; + + var6 = 0; + for (i = 0; i < 6; i++) + { + if (gUnknown_03000510[i] < 0) + { + gUnknown_03000510[i] = 0; + var6++; + } + } + for (i = 0; i < 5; i++) + { + if (gUnknown_03000510[i] > 0) + { + if (gUnknown_03000510[i] < var6) + gUnknown_03000510[i] = 0; + else + gUnknown_03000510[i] -= var6; + } + } + for (i = 0; i < 5; i++) + { + gUnknown_03000530[i] = gUnknown_03000510[i]; + } + + var11 = maxRPM / 333 + 100; + gUnknown_0300055C = ((var11)); + + for (i = 0; i < 5; i++) + { + var3 = gUnknown_03000510[i]; + var3 = ((var11) * var3) / 10; + var4 = var3 % 10; + var3 /= 10; + if (var4 > 4) + var3++; + gUnknown_03000510[i] = var3; + } + for (i = 0; i < 5; i++) + { + gUnknown_03000548[i] = gUnknown_03000510[i]; + } + pokeblock->color = Blender_GetPokeblockColor(berries, &gUnknown_03000510[0], playersNo, var6); + gUnknown_03000510[5] = (gUnknown_03000510[5] / playersNo) - playersNo; + if (gUnknown_03000510[5] < 0) + gUnknown_03000510[5] = 0; + if (pokeblock->color == 12) + { + rand = Random() % 10; + for (i = 0; i < 6; i++) + { + if ((gUnknown_082165DF[rand] >> i) & 1) + gUnknown_03000510[i] = 2; + else + gUnknown_03000510[i] = 0; + } + } + for (i = 0; i < 6; i++) + { + if (gUnknown_03000510[i] > 255) + gUnknown_03000510[i] = 255; + } + pokeblock->spicy = gUnknown_03000510[0]; + pokeblock->dry = gUnknown_03000510[1]; + pokeblock->sweet = gUnknown_03000510[2]; + pokeblock->bitter = gUnknown_03000510[3]; + pokeblock->sour = gUnknown_03000510[4]; + pokeblock->feel = gUnknown_03000510[5]; + for (i = 0; i < 6; i++) + { + flavours[i] = gUnknown_03000510[i]; + } +} + +#else +__attribute__((naked)) +static void Blender_CalculatePokeblock(struct BlenderBerry* berries, struct Pokeblock* pokeblock, u8 a2, u8* flavours, u16 a4) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0x10\n\ + str r0, [sp]\n\ + mov r8, r1\n\ + str r3, [sp, 0x4]\n\ + ldr r0, [sp, 0x30]\n\ + lsls r2, 24\n\ + lsrs r2, 24\n\ + mov r9, r2\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + str r0, [sp, 0x8]\n\ + ldr r7, _080505DC @ =gUnknown_03000510\n\ + adds r2, r7, 0\n\ + movs r1, 0\n\ + adds r0, r7, 0\n\ + adds r0, 0xA\n\ +_0805054A:\n\ + strh r1, [r0]\n\ + subs r0, 0x2\n\ + cmp r0, r2\n\ + bge _0805054A\n\ + movs r6, 0\n\ + cmp r6, r9\n\ + bge _08050580\n\ + ldr r0, _080505DC @ =gUnknown_03000510\n\ + mov r12, r0\n\ + ldr r5, [sp]\n\ + adds r5, 0x9\n\ +_08050560:\n\ + movs r3, 0\n\ + adds r4, r5, 0\n\ + mov r2, r12\n\ +_08050566:\n\ + adds r1, r4, r3\n\ + ldrh r0, [r2]\n\ + ldrb r1, [r1]\n\ + adds r0, r1\n\ + strh r0, [r2]\n\ + adds r2, 0x2\n\ + adds r3, 0x1\n\ + cmp r3, 0x5\n\ + ble _08050566\n\ + adds r5, 0x10\n\ + adds r6, 0x1\n\ + cmp r6, r9\n\ + blt _08050560\n\ +_08050580:\n\ + movs r1, 0\n\ + ldrsh r3, [r7, r1]\n\ + ldrh r0, [r7]\n\ + ldrh r1, [r7, 0x2]\n\ + subs r0, r1\n\ + strh r0, [r7]\n\ + ldrh r0, [r7, 0x4]\n\ + subs r1, r0\n\ + strh r1, [r7, 0x2]\n\ + ldrh r1, [r7, 0x6]\n\ + subs r0, r1\n\ + strh r0, [r7, 0x4]\n\ + ldrh r0, [r7, 0x8]\n\ + subs r1, r0\n\ + strh r1, [r7, 0x6]\n\ + subs r0, r3\n\ + strh r0, [r7, 0x8]\n\ + movs r3, 0\n\ + movs r2, 0\n\ + adds r1, r7, 0\n\ + movs r6, 0x4\n\ +_080505AA:\n\ + movs r4, 0\n\ + ldrsh r0, [r1, r4]\n\ + cmp r0, 0\n\ + bge _080505B6\n\ + strh r2, [r1]\n\ + adds r3, 0x1\n\ +_080505B6:\n\ + adds r1, 0x2\n\ + subs r6, 0x1\n\ + cmp r6, 0\n\ + bge _080505AA\n\ + lsls r0, r3, 24\n\ + lsrs r0, 24\n\ + mov r10, r0\n\ + movs r4, 0\n\ + ldr r1, _080505DC @ =gUnknown_03000510\n\ + movs r6, 0x4\n\ +_080505CA:\n\ + ldrh r2, [r1]\n\ + movs r5, 0\n\ + ldrsh r0, [r1, r5]\n\ + cmp r0, 0\n\ + ble _080505E4\n\ + cmp r0, r3\n\ + bge _080505E0\n\ + strh r4, [r1]\n\ + b _080505E4\n\ + .align 2, 0\n\ +_080505DC: .4byte gUnknown_03000510\n\ +_080505E0:\n\ + subs r0, r2, r3\n\ + strh r0, [r1]\n\ +_080505E4:\n\ + adds r1, 0x2\n\ + subs r6, 0x1\n\ + cmp r6, 0\n\ + bge _080505CA\n\ + ldr r1, _080506C4 @ =gUnknown_03000510\n\ + ldr r2, _080506C8 @ =gUnknown_03000530\n\ + movs r6, 0x4\n\ +_080505F2:\n\ + movs r3, 0\n\ + ldrsh r0, [r1, r3]\n\ + stm r2!, {r0}\n\ + adds r1, 0x2\n\ + subs r6, 0x1\n\ + cmp r6, 0\n\ + bge _080505F2\n\ + ldr r1, _080506CC @ =0x0000014d\n\ + ldr r0, [sp, 0x8]\n\ + bl __udivsi3\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + adds r3, r0, 0\n\ + adds r3, 0x64\n\ + ldr r4, _080506D0 @ =gUnknown_0300055C\n\ + str r3, [r4]\n\ + movs r6, 0x4\n\ +_08050616:\n\ + movs r0, 0\n\ + ldrsh r5, [r7, r0]\n\ + adds r0, r5, 0\n\ + muls r0, r3\n\ + movs r1, 0xA\n\ + str r3, [sp, 0xC]\n\ + bl __divsi3\n\ + adds r5, r0, 0\n\ + movs r1, 0xA\n\ + bl __modsi3\n\ + adds r4, r0, 0\n\ + adds r0, r5, 0\n\ + movs r1, 0xA\n\ + bl __divsi3\n\ + adds r5, r0, 0\n\ + ldr r3, [sp, 0xC]\n\ + cmp r4, 0x4\n\ + ble _08050642\n\ + adds r5, 0x1\n\ +_08050642:\n\ + strh r5, [r7]\n\ + adds r7, 0x2\n\ + subs r6, 0x1\n\ + cmp r6, 0\n\ + bge _08050616\n\ + ldr r1, _080506C4 @ =gUnknown_03000510\n\ + ldr r2, _080506D4 @ =gUnknown_03000548\n\ + movs r6, 0x4\n\ +_08050652:\n\ + movs r3, 0\n\ + ldrsh r0, [r1, r3]\n\ + stm r2!, {r0}\n\ + adds r1, 0x2\n\ + subs r6, 0x1\n\ + cmp r6, 0\n\ + bge _08050652\n\ + ldr r4, _080506C4 @ =gUnknown_03000510\n\ + ldr r0, [sp]\n\ + adds r1, r4, 0\n\ + mov r2, r9\n\ + mov r3, r10\n\ + bl Blender_GetPokeblockColor\n\ + mov r5, r8\n\ + strb r0, [r5]\n\ + movs r1, 0xA\n\ + ldrsh r0, [r4, r1]\n\ + mov r1, r9\n\ + bl __divsi3\n\ + mov r3, r9\n\ + subs r0, r3\n\ + strh r0, [r4, 0xA]\n\ + lsls r0, 16\n\ + cmp r0, 0\n\ + bge _0805068C\n\ + movs r0, 0\n\ + strh r0, [r4, 0xA]\n\ +_0805068C:\n\ + mov r5, r8\n\ + ldrb r0, [r5]\n\ + cmp r0, 0xC\n\ + bne _080506E6\n\ + bl Random\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + movs r1, 0xA\n\ + bl __umodsi3\n\ + lsls r0, 16\n\ + lsrs r3, r0, 16\n\ + movs r6, 0\n\ + ldr r0, _080506D8 @ =gUnknown_082165DF\n\ + adds r0, r3, r0\n\ + ldrb r0, [r0]\n\ + adds r1, r4, 0\n\ + movs r4, 0x1\n\ + movs r3, 0x2\n\ +_080506B4:\n\ + adds r2, r0, 0\n\ + asrs r2, r6\n\ + ands r2, r4\n\ + cmp r2, 0\n\ + beq _080506DC\n\ + strh r3, [r1]\n\ + b _080506DE\n\ + .align 2, 0\n\ +_080506C4: .4byte gUnknown_03000510\n\ +_080506C8: .4byte gUnknown_03000530\n\ +_080506CC: .4byte 0x0000014d\n\ +_080506D0: .4byte gUnknown_0300055C\n\ +_080506D4: .4byte gUnknown_03000548\n\ +_080506D8: .4byte gUnknown_082165DF\n\ +_080506DC:\n\ + strh r2, [r1]\n\ +_080506DE:\n\ + adds r1, 0x2\n\ + adds r6, 0x1\n\ + cmp r6, 0x4\n\ + ble _080506B4\n\ +_080506E6:\n\ + ldr r7, _08050740 @ =gUnknown_03000510\n\ + movs r2, 0xFF\n\ + adds r1, r7, 0\n\ + movs r6, 0x5\n\ +_080506EE:\n\ + movs r3, 0\n\ + ldrsh r0, [r1, r3]\n\ + cmp r0, 0xFF\n\ + ble _080506F8\n\ + strh r2, [r1]\n\ +_080506F8:\n\ + adds r1, 0x2\n\ + subs r6, 0x1\n\ + cmp r6, 0\n\ + bge _080506EE\n\ + ldrh r0, [r7]\n\ + mov r4, r8\n\ + strb r0, [r4, 0x1]\n\ + ldrh r0, [r7, 0x2]\n\ + strb r0, [r4, 0x2]\n\ + ldrh r0, [r7, 0x4]\n\ + strb r0, [r4, 0x3]\n\ + ldrh r0, [r7, 0x6]\n\ + strb r0, [r4, 0x4]\n\ + ldrh r0, [r7, 0x8]\n\ + strb r0, [r4, 0x5]\n\ + ldrh r0, [r7, 0xA]\n\ + strb r0, [r4, 0x6]\n\ + movs r6, 0\n\ + adds r2, r7, 0\n\ +_0805071E:\n\ + ldr r5, [sp, 0x4]\n\ + adds r1, r5, r6\n\ + ldrh r0, [r2]\n\ + strb r0, [r1]\n\ + adds r2, 0x2\n\ + adds r6, 0x1\n\ + cmp r6, 0x5\n\ + ble _0805071E\n\ + add sp, 0x10\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08050740: .4byte gUnknown_03000510\n\ + .syntax divided"); +} + +#endif // NONMATCHING + +static void BlenderDebug_CalculatePokeblock(struct BlenderBerry* berries, struct Pokeblock* pokeblock, u8 playersNo, u8* flavours, u16 a4) +{ + Blender_CalculatePokeblock(berries, pokeblock, playersNo, flavours, a4); +} + +static void sub_8050760(void) +{ + u32 frames = (u16)(gBerryBlenderData->gameFrameTime); + u16 max_RPM = gBerryBlenderData->max_RPM; + s16 var = 0; + + if (frames < 900) + var = 5; + else if ((u16)(frames - 900) < 600) + var = 4; + else if ((u16)(frames - 1500) < 600) + var = 3; + else if ((u16)(frames - 2100) < 900) + var = 2; + else if ((u16)(frames - 3300) < 300) + var = 1; + sub_8050508(var); + + var = 0; + if (max_RPM <= 64) + { + if (max_RPM >= 50 && max_RPM < 100) + var = -1; + else if (max_RPM >= 100 && max_RPM < 150) + var = -2; + else if (max_RPM >= 150 && max_RPM < 200) + var = -3; + else if (max_RPM >= 200 && max_RPM < 250) + var = -4; + else if (max_RPM >= 250 && max_RPM < 300) + var = -5; + else if (max_RPM >= 350 && max_RPM < 400) + var = -6; + else if (max_RPM >= 400 && max_RPM < 450) + var = -7; + else if (max_RPM >= 500 && max_RPM < 550) + var = -8; + else if (max_RPM >= 550 && max_RPM < 600) + var = -9; + else if (max_RPM >= 600) + var = -10; + } + sub_80504F0(var); +} + +static void sub_80508D4(u8 value) +{ + gBerryBlenderData->field_AA = value; + sub_814A880(192, (gBerryBlenderData->field_AA * 16) + 72); +} + +static void sub_80508FC(void) +{ + gBerryBlenderData->field_AA = 0; + MenuDrawTextWindow(23, 8, 28, 13); + sub_814A5C0(0, -1, 12, 0x2D9F, 32); + MenuPrint(gOtherText_YesNoTerminating, 24, 9); + sub_80508D4(gBerryBlenderData->field_AA); +} + +static void sub_8050954(void) +{ + u8 i; + u8 multiplayerID; // unused + + sub_8051474(); + multiplayerID = GetMultiplayerId(); + switch (gBerryBlenderData->field_6F) + { + case 1: + ClearLinkCallback(); + m4aMPlayTempoControl(&gMPlay_BGM, 256); + for (i = 0; i < gSpecialVar_0x8004; i++) + { + DestroyTask(gBerryBlenderData->field_148[i]); + } + gBerryBlenderData->field_6F++; + break; + case 2: + gBerryBlenderData->field_56 -= 32; + if (gBerryBlenderData->field_56 <= 0) + { + gBerryBlenderData->field_56 = 0; + if (gReceivedRemoteLinkPlayers != 0) + gBerryBlenderData->field_6F++; + else + gBerryBlenderData->field_6F = 5; + gBerryBlenderData->field_0 = 0; + m4aMPlayStop(&gMPlay_SE2); + } + Blender_ControlHitPitch(); + break; + case 3: + if (/*multiplayerID != 0*/ GetMultiplayerId() != 0) + gBerryBlenderData->field_6F++; + else if (sub_8007ECC()) + { + gBerryBlenderData->field_1BC = gBerryBlenderData->gameFrameTime; + gBerryBlenderData->field_1C0 = gBerryBlenderData->max_RPM; + SendBlock(0, &gBerryBlenderData->field_1BC, 40); + gBerryBlenderData->field_6F++; + } + break; + case 4: + if (GetBlockReceivedStatus()) + { + u32* ptr = ((u32*)(&gBlockRecvBuffer[0][0])); + gBerryBlenderData->max_RPM = gBlockRecvBuffer[0][2]; + gBerryBlenderData->gameFrameTime = *ptr; + gBerryBlenderData->field_6F++; + ResetBlockReceivedFlags(); + } + break; + case 5: + if (Blender_PrintBlendingRanking()) + gBerryBlenderData->field_6F++; + break; + case 6: + if (Blender_PrintBlendingResults()) + { + if (gInGameOpponentsNo == 0) + IncrementGameStat(34); + else + IncrementGameStat(33); + gBerryBlenderData->field_6F++; + } + break; + case 7: + gBerryBlenderData->field_6F++; + MenuDrawTextWindow(0, 14, 29, 19); + MenuPrintMessage(gOtherText_BlendAnotherBerryPrompt, 1, 15); + break; + case 8: + if (MenuUpdateWindowText()) + gBerryBlenderData->field_6F++; + break; + case 9: + gBerryBlenderData->field_AA = 0; + sub_80508FC(); + gBerryBlenderData->field_6F++; + break; + case 10: + if (gMain.newKeys & DPAD_UP) + { + if (gBerryBlenderData->field_AA != 0) + PlaySE(SE_SELECT); + sub_80508D4(0); + } + else if (gMain.newKeys & DPAD_DOWN) + { + if (gBerryBlenderData->field_AA != 1) + PlaySE(SE_SELECT); + sub_80508D4(1); + } + else if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + gBerryBlenderData->field_6F++; + } + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + gBerryBlenderData->field_6F++; + sub_80508D4(1); + } + break; + case 11: + gSendCmd[0] = 0x2FFF; + if (gBerryBlenderData->field_AA == 0) + { + if (IsBagPocketNonEmpty(BAG_BERRIES) == FALSE) // is empty + { + gBerryBlenderData->field_7C = 2; + gSendCmd[1] = 0x9999; + } + else if (sub_810CA00() == -1) + { + gBerryBlenderData->field_7C = 3; + gSendCmd[1] = 0xAAAA; + } + else + { + gBerryBlenderData->field_7C = 0; + gSendCmd[1] = 0x7779; + } + gBerryBlenderData->field_6F++; + } + else + { + gBerryBlenderData->field_7C = 1; + gSendCmd[1] = 0x8888; + gBerryBlenderData->field_6F++; + } + break; + case 12: + if (gInGameOpponentsNo) + { + SetMainCallback2(sub_80510E8); + gBerryBlenderData->field_6F = 0; + gBerryBlenderData->field_0 = 0; + } + else + { + MenuPrintMessage(gOtherText_LinkStandby3, 1, 15); + gBerryBlenderData->field_6F++; + } + break; + case 13: + if (MenuUpdateWindowText()) + { + SetMainCallback2(sub_8050E30); + gBerryBlenderData->field_6F = 0; + gBerryBlenderData->field_0 = 0; + } + break; + } + sub_8051B18(); + sub_8051A3C(gBerryBlenderData->field_56); + sub_805123C(); + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +bool8 sub_8050CE8(void) +{ + switch (gBerryBlenderData->field_1C4) + { + case 0: + sub_80084A4(); + gBerryBlenderData->field_1C4 = 1; + gBerryBlenderData->framesToWait = 0; + break; + case 1: + if (sub_8007ECC()) + { + gBerryBlenderData->field_1C4++; + gSoftResetDisabled = TRUE; + } + break; + case 2: + sub_8125E2C(); + gBerryBlenderData->field_1C4++; + gBerryBlenderData->framesToWait = 0; + break; + case 3: + if (++gBerryBlenderData->framesToWait == 10) + { + sub_80084A4(); + gBerryBlenderData->field_1C4++; + } + break; + case 4: + if (sub_8007ECC()) + { + if (sub_8125E6C()) + gBerryBlenderData->field_1C4 = 5; + else + { + gBerryBlenderData->framesToWait = 0; + gBerryBlenderData->field_1C4 = 3; + } + } + break; + case 5: + gBerryBlenderData->field_1C4++; + gBerryBlenderData->framesToWait = 0; + break; + case 6: + if (++gBerryBlenderData->framesToWait > 5) + { + gSoftResetDisabled = FALSE; + return TRUE; + } + break; + } + return FALSE; +} + +static void sub_8050E30(void) +{ + switch (gBerryBlenderData->field_6F) + { + case 0: + if (gBerryBlenderData->field_70[0] == 0x2222) + gBerryBlenderData->field_6F = 5; + else if (gBerryBlenderData->field_70[0] == 0x1111) + { + if (gBerryBlenderData->field_78 == 0x9999) + gBerryBlenderData->field_6F = 2; + else if (gBerryBlenderData->field_78 == 0xAAAA) + gBerryBlenderData->field_6F = 1; + else + gBerryBlenderData->field_6F = 5; + } + break; + case 1: + gBerryBlenderData->field_6F = 3; + DestroyMenuCursor(); + MenuZeroFillWindowRect(23, 8, 28, 13); +#ifdef ENGLISH + StringCopy(gStringVar4, gLinkPlayers[gBerryBlenderData->field_7A].name); + StringAppend(gStringVar4, gOtherText_OtherCaseIsFull); +#else + StringCopy(gStringVar4, gOtherText_OtherCaseIsFull); + de_sub_8073110(gStringVar4, gLinkPlayers[gBerryBlenderData->field_7A].name); +#endif + MenuPrintMessage(gStringVar4, 1, 15); + break; + case 2: + gBerryBlenderData->field_6F++; + DestroyMenuCursor(); + MenuZeroFillWindowRect(23, 8, 28, 13); +#ifdef ENGLISH + StringCopy(gStringVar4, gLinkPlayers[gBerryBlenderData->field_7A].name); + StringAppend(gStringVar4, gOtherText_NoBerriesForBlend); +#else + StringCopy(gStringVar4, gOtherText_NoBerriesForBlend); + de_sub_8073110(gStringVar4, gLinkPlayers[gBerryBlenderData->field_7A].name); +#endif + MenuPrintMessage(gStringVar4, 1, 15); + break; + case 3: + if (MenuUpdateWindowText()) + { + gBerryBlenderData->framesToWait = 0; + gBerryBlenderData->field_6F++; + } + break; + case 4: + if (++gBerryBlenderData->framesToWait > 60) + gBerryBlenderData->field_6F = 5; + break; + case 5: + MenuDrawTextWindow(0, 14, 29, 19); + MenuPrint(gMultiText_Saving, 2, 15); + sub_80084A4(); + gBerryBlenderData->field_6F++; + break; + case 6: + if (sub_8007ECC()) + { + gBerryBlenderData->framesToWait = 0; + gBerryBlenderData->field_6F++; + gBerryBlenderData->field_1C4 = 0; + } + break; + case 7: + if (sub_8050CE8()) + { + PlaySE(SE_SAVE); + gBerryBlenderData->field_6F++; + } + break; + case 8: + gBerryBlenderData->field_6F++; + sub_80084A4(); + break; + case 9: + if (sub_8007ECC()) + { + BeginNormalPaletteFade(-1, 0, 0, 0x10, 0); + gBerryBlenderData->field_6F++; + } + break; + case 10: + if (!gPaletteFade.active) + { + if (gBerryBlenderData->field_70[0] == 0x2222) + SetMainCallback2(sub_804E538); + else + { + gBerryBlenderData->framesToWait = 0; + gBerryBlenderData->field_6F++; + } + } + break; + case 11: + if (++gBerryBlenderData->framesToWait > 30) + { + sub_800832C(); + gBerryBlenderData->field_6F++; + } + break; + case 12: + if (gReceivedRemoteLinkPlayers == 0) + SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); + break; + } + + sub_805123C(); + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +static void sub_80510E8(void) +{ + switch (gBerryBlenderData->field_6F) + { + case 0: + if (gBerryBlenderData->field_7C < 2) + gBerryBlenderData->field_6F = 9; + if (gBerryBlenderData->field_7C == 2) + gBerryBlenderData->field_6F = 2; + if (gBerryBlenderData->field_7C == 3) + gBerryBlenderData->field_6F =1; + break; + case 1: + gBerryBlenderData->field_6F = 3; + DestroyMenuCursor(); + MenuZeroFillWindowRect(23, 8, 28, 13); + MenuPrintMessage(gOtherText_CaseIsFull, 1, 15); + break; + case 2: + gBerryBlenderData->field_6F++; + DestroyMenuCursor(); + MenuZeroFillWindowRect(23, 8, 28, 13); + MenuPrintMessage(gOtherText_OutOfBerries, 1, 15); + break; + case 3: + if (MenuUpdateWindowText()) + gBerryBlenderData->field_6F = 9; + break; + case 9: + BeginFastPaletteFade(3); + gBerryBlenderData->field_6F++; + break; + case 10: + if (!gPaletteFade.active) + { + if (gBerryBlenderData->field_7C == 0) + SetMainCallback2(sub_804E538); + else + SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); + } + break; + } + + sub_805123C(); + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +static void sub_805123C(void) +{ + if (gReceivedRemoteLinkPlayers) + { + if (gRecvCmds[0][0] == 0x2FFF) + { + if (gRecvCmds[1][0] == 0x1111) + { + switch (gRecvCmds[2][0]) + { + case 0x8888: + gBerryBlenderData->field_78 = 0x8888; + gBerryBlenderData->field_7A = gRecvCmds[3][0]; + break; + case 0x9999: + gBerryBlenderData->field_78 = 0x9999; + gBerryBlenderData->field_7A = gRecvCmds[3][0]; + break; + case 0xAAAA: + gBerryBlenderData->field_78 = 0xAAAA; + gBerryBlenderData->field_7A = gRecvCmds[3][0]; + break; + } + gBerryBlenderData->field_70[0] = 0x1111; + } + else if (gRecvCmds[1][0] == 0x2222) + gBerryBlenderData->field_70[0] = 0x2222; + } + if (GetMultiplayerId() == 0 && gBerryBlenderData->field_70[0] != 0x1111 && gBerryBlenderData->field_70[0] != 0x2222) + { + u8 i; + for (i = 0; i < GetLinkPlayerCount(); i++) + { + if (gRecvCmds[0][i] == 0x2FFF) + { + switch (gRecvCmds[1][i]) + { + case 0x8888: + gBerryBlenderData->field_70[i] = 0x8888; + break; + case 0x7779: + gBerryBlenderData->field_70[i] = 0x7779; + break; + case 0x9999: + gBerryBlenderData->field_70[i] = 0x9999; + break; + case 0xAAAA: + gBerryBlenderData->field_70[i] = 0xAAAA; + break; + } + } + } + for (i = 0; i < GetLinkPlayerCount(); i++) + { + if (gBerryBlenderData->field_70[i] == 0) + break; + } + if (i == GetLinkPlayerCount()) + { + for (i = 0; i < GetLinkPlayerCount(); i++) + { + if (gBerryBlenderData->field_70[i] != 0x7779) + break; + } + gSendCmd[0] = 0x2FFF; + if (i == GetLinkPlayerCount()) + gSendCmd[1] = 0x2222; + else + { + gSendCmd[1] = 0x1111; + gSendCmd[2] = gBerryBlenderData->field_70[i]; + gSendCmd[3] = i; + } + } + } + } +} + +static void sub_8051414(struct BgAffineDstData *dest) +{ + struct BgAffineSrcData affineSrc; + affineSrc.texX = 30720; + affineSrc.texY = 20480; + affineSrc.scrX = 120 - gBerryBlenderData->field_144; + affineSrc.scrY = 80 - gBerryBlenderData->field_146; + affineSrc.sx = gBerryBlenderData->field_142; + affineSrc.sy = gBerryBlenderData->field_142; + affineSrc.alpha = gBerryBlenderData->arrowPos; + BgAffineSet(&affineSrc, dest, 1); +} + +static void sub_8051474(void) +{ + gBerryBlenderData->field_58 = gBerryBlenderData->arrowPos; + gBerryBlenderData->arrowPos += gBerryBlenderData->field_56; + sub_8051414(&gBerryBlenderData->field_168); +} + +static void sub_80514A4(void) +{ + REG_BG2PA = gBerryBlenderData->field_168.pa; + REG_BG2PB = gBerryBlenderData->field_168.pb; + REG_BG2PC = gBerryBlenderData->field_168.pc; + REG_BG2PD = gBerryBlenderData->field_168.pd; + REG_BG2X = gBerryBlenderData->field_168.dx; + REG_BG2Y = gBerryBlenderData->field_168.dy; +} + +static void sub_80514F0(void) +{ + REG_BG1HOFS = gBerryBlenderData->field_144; + REG_BG1VOFS = gBerryBlenderData->field_146; + REG_BG0HOFS = gBerryBlenderData->field_144; + REG_BG0VOFS = gBerryBlenderData->field_146; +} + +void sub_8051524(struct Sprite* sprite) +{ + sprite->data2 += sprite->data0; + sprite->data3 += sprite->data1; + sprite->pos2.x = sprite->data2 / 8; + sprite->pos2.y = sprite->data3 / 8; + if (sprite->animEnded) + DestroySprite(sprite); +} + +static void sub_805156C(void) +{ + s32 limit = (Random() % 2) + 1; + s32 i; + + for (i = 0; i < limit; i++) + { + u16 rand; + s32 x, y; + u8 spriteID; + + rand = gBerryBlenderData->arrowPos + (Random() % 20); + + x = gSineTable[(rand & 0xFF) + 64] / 4; + y = gSineTable[(rand & 0xFF)] / 4; + + spriteID = CreateSprite(&sSpriteTemplate_82164FC, x + 120, y + 80, 1); + gSprites[spriteID].data0 = 16 - (Random() % 32); + gSprites[spriteID].data1 = 16 - (Random() % 32); + + gSprites[spriteID].callback = sub_8051524; + } +} + +static void sub_8051650(struct Sprite* sprite) +{ + sprite->data0++; + sprite->pos2.y = -(sprite->data0 / 3); + if (sprite->animEnded) + DestroySprite(sprite); +} + +void sub_8051684(struct Sprite* sprite) +{ + sprite->data0++; + sprite->pos2.y = -(sprite->data0 * 2); + if (sprite->pos2.y < -12) + sprite->pos2.y = -12; + if (sprite->animEnded) + DestroySprite(sprite); +} + +void Blender_SetBankBerryData(u8 bank, u16 itemID) +{ + gBerryBlenderData->chosenItemID[bank] = itemID; + Blender_CopyBerryData(&gBerryBlenderData->blendedBerries[bank], itemID); +} + +void unref_sub_80516F8(u8 taskID) +{ + struct Task* task = &gTasks[taskID]; + if (gReceivedRemoteLinkPlayers) + { + s32 i; + if (GetMultiplayerId() == 0) + { + if (++task->data[0] > 120) + task->data[0] = 0; + if (task->data[0] == 100) + { + ZeroFillWindowRect(&gBerryBlenderData->field_4, 0, 0, 16, 20); + MenuDrawTextWindow(4, 4, 10, 12); + for (i = 0; i < 3; i++) + { + if (gLinkPlayers[i + 1].trainerId != 0) + MenuPrint(gUnknown_08216284[i], 5, (2 * i) + 5); + MenuDrawTextWindow(0, 13, 29, 19); + MenuPrint(gOtherText_PressAToStart, 1, 15); + } + } + if (gMain.newKeys & A_BUTTON) + { + sub_8007E4C(); + DestroyTask(taskID); + } + } + else + { + if (task->data[0] == 10) + MenuPrint(gOtherText_PleaseWait, 3, 10); + if (++task->data[0] > 120) + task->data[0] = 0; + if (byte_3002A68 > 4 && gReceivedRemoteLinkPlayers == 1) + DestroyTask(taskID); + } + } +} + +static void sub_805181C(struct Sprite* sprite) +{ + switch (sprite->data0) + { + case 0: + sprite->data1 += 8; + if (sprite->data1 > 88) + { + sprite->data1 = 88; + sprite->data0++; + PlaySE(SE_KON); + } + break; + case 1: + sprite->data2 += 1; + if (sprite->data2 > 20) + { + sprite->data0++; + sprite->data2 = 0; + } + break; + case 2: + sprite->data1 += 4; + if (sprite->data1 > 176) + { + if (++sprite->data3 == 3) + { + DestroySprite(sprite); + CreateSprite(&sSpriteTemplate_821657C, 120, -20, 2); + } + else + { + sprite->data0 = 0; + sprite->data1 = -16; + StartSpriteAnim(sprite, sprite->data3); + } + } + break; + } + sprite->pos2.y = sprite->data1; +} + +static void sub_80518CC(struct Sprite* sprite) +{ + switch (sprite->data0) + { + case 0: + sprite->data1 += 8; + if (sprite->data1 > 92) + { + sprite->data1 = 92; + sprite->data0++; + PlaySE(SE_PIN); + } + break; + case 1: + sprite->data2 += 1; + if (sprite->data2 > 20) + sprite->data0++; + break; + case 2: + sprite->data1 += 4; + if (sprite->data1 > 176) + { + gBerryBlenderData->field_0++; + DestroySprite(sprite); + } + break; + } + sprite->pos2.y = sprite->data1; +} + +static void sub_805194C(u16 a0, u16 a1) +{ + if (gBerryBlenderData->field_140 < a0) + { + gBerryBlenderData->field_140 += 2; + sub_805197C(gBerryBlenderData->field_140, a1); + } +} + +static void sub_805197C(u16 a0, u16 a1) +{ + s32 var1, var2, var3, var4; + u16* vram; + + vram = (u16*)(VRAM + 0x6000); + var1 = (a0 * 64) / a1; + var2 = var1 / 8; + for (var4 = 0; var4 < var2; var4++) + { + vram[11 + var4] = 0x81E9; + vram[43 + var4] = 0x81F9; + } + var3 = var1 % 8; + if (var3 != 0) + { + vram[11 + var4] = var3 - 32287; + vram[43 + var4] = var3 - 32271; + var4++; + } + for (; var4 < 8; var4++) + { + vram[11 + var4] = 33249; + vram[43 + var4] = 33249 + 16; + } +} + +static u32 sub_8051A1C(u16 a0) +{ + return 360000 * a0 / 0x10000; +} + +static void sub_8051A3C(u16 a0) +{ + u8 i; + u8 palAdders[5]; + + u32 var = sub_8051A1C(a0); + if (gBerryBlenderData->max_RPM < var) + gBerryBlenderData->max_RPM = var; + for (i = 0; i < 5; i++) + { + palAdders[i] = var % 10; + var /= 10; + } + *((u16*)(VRAM + 0x6458)) = palAdders[4] + 0x8172; + *((u16*)(VRAM + 0x645A)) = palAdders[3] + 0x8172; + *((u16*)(VRAM + 0x645C)) = palAdders[2] + 0x8172; + *((u16*)(VRAM + 0x6460)) = palAdders[1] + 0x8172; + *((u16*)(VRAM + 0x6462)) = palAdders[0] + 0x8172; +} + +static void sub_8051AC8(s16* a0, u16 a1) +{ + if (*a0 == 0) + *a0 = (Random() % a1) - (a1 / 2); +} + +static void sub_8051AF4(s16* a0) +{ + if (*a0 < 0 ) + (*a0)++; + if (*a0 > 0 ) + (*a0)--; +} + +static void sub_8051B18(void) +{ + sub_8051AF4(&gBerryBlenderData->field_144); + sub_8051AF4(&gBerryBlenderData->field_146); +} + +static void sub_8051B40(s16* a0, u16 a1) +{ + s32 var; + if (a1 < 10) + var = 16; + else + var = 8; + if (*a0 == 0) + *a0 = (Random() % var) - (var / 2); + else + { + if (*a0 < 0) + (*a0)++; + if (*a0 > 0) + (*a0)--; + } +} + +static bool8 sub_8051B8C(void) +{ + if (gBerryBlenderData->framesToWait == 0) + { + gBerryBlenderData->field_144 = 0; + gBerryBlenderData->field_146 = 0; + } + gBerryBlenderData->framesToWait++; + sub_8051B40(&gBerryBlenderData->field_144, gBerryBlenderData->framesToWait); + sub_8051B40(&gBerryBlenderData->field_146, gBerryBlenderData->framesToWait); + if (gBerryBlenderData->framesToWait == 20) + { + gBerryBlenderData->field_144 = 0; + gBerryBlenderData->field_146 = 0; + return TRUE; + } + else + return FALSE; +} + +static void sub_8051C04(struct Sprite* sprite) +{ + sprite->pos2.x = -(gBerryBlenderData->field_144); + sprite->pos2.y = -(gBerryBlenderData->field_146); +} + +static void Blender_TrySettingRecord(void) +{ + if (gSaveBlock1.berryBlenderRecords[gBerryBlenderData->playersNo - 2] < gBerryBlenderData->max_RPM) + gSaveBlock1.berryBlenderRecords[gBerryBlenderData->playersNo - 2] = gBerryBlenderData->max_RPM; +} + +static bool8 Blender_PrintBlendingResults(void) +{ + u16 i; + + struct Pokeblock pokeblock; + u8 flavours[6]; + u8 text[2][10]; + u16 berryIDs[4]; // unused + + switch (gBerryBlenderData->field_0) + { + case 0: + gBerryBlenderData->field_0++; + gBerryBlenderData->framesToWait = 17; + break; + case 1: + gBerryBlenderData->framesToWait -= 10; + if (gBerryBlenderData->framesToWait < 0) + { + gBerryBlenderData->framesToWait = 0; + gBerryBlenderData->field_0++; + } + break; + case 2: + if (++gBerryBlenderData->framesToWait > 20) + { + for (i = 0; i < 3; i++) + DestroySprite(&gSprites[gBerryBlenderData->scoreIconIDs[i]]); + gBerryBlenderData->framesToWait = 0; + gBerryBlenderData->field_0++; + } + break; + case 3: + { + u8* textPtr; + u16 secondsPassed, minutes, seconds; + + MenuDrawTextWindow(4, 2, 25, 17); + sub_8072BD8(gOtherText_ResultsOfBlending, 5, 3, 160); + for (i = 0; i < gBerryBlenderData->playersNo; i++) + { + u8 place = gBerryBlenderData->playerPlaces[i]; + textPtr = text[0]; + + StringCopy(textPtr, gBerryBlenderData->blendedBerries[place].name); + ConvertInternationalString(textPtr, gLinkPlayers[place].language); +#ifdef ENGLISH + StringAppend(textPtr, gOtherText_Berry); +#else + de_sub_8073174(textPtr, gOtherText_Berry); +#endif + textPtr = gBerryBlenderData->stringVar; + textPtr = ConvertIntToDecimalString(textPtr, i + 1); + textPtr[0] = CHAR_SPACE; + textPtr[1] = CHAR_PERIOD; + textPtr[2] = CHAR_SPACE; + textPtr += 3; + textPtr = sub_8072C74(textPtr, gLinkPlayers[place].name, 88, 0); + sub_8072C74(textPtr, text[0], 157, 0); + MenuPrint(gBerryBlenderData->stringVar, 5, gUnknown_082165E9[gBerryBlenderData->playersNo] + (i * gUnknown_082165EE[gBerryBlenderData->playersNo])); + } + ConvertIntToDecimalStringN(text[0], gBerryBlenderData->max_RPM % 100, 2, 2); + textPtr = gBerryBlenderData->stringVar; + textPtr = StringCopy(textPtr, gOtherText_MaxSpeed); + textPtr = sub_8072C14(textPtr, gBerryBlenderData->max_RPM / 100, 121, 1); + +#ifdef ENGLISH + textPtr[0] = CHAR_SPACE; + textPtr[1] = CHAR_PERIOD; + textPtr[2] = CHAR_SPACE; + textPtr += 3; + textPtr = sub_8072C74(textPtr, text[0], 142, 1); +#else + *textPtr++ = CHAR_COMMA; + textPtr = sub_8072C74(textPtr, text[0], 136, 1); +#endif + StringCopy(textPtr, gOtherText_RPM); + MenuPrint(gBerryBlenderData->stringVar, 5, 13); + + secondsPassed = gBerryBlenderData->gameFrameTime / 60; + seconds = secondsPassed % 60; + minutes = secondsPassed / 60; + ConvertIntToDecimalStringN(text[0], minutes, 2, 2); + ConvertIntToDecimalStringN(text[1], seconds, 2, 2); + textPtr = gBerryBlenderData->stringVar; + textPtr = StringCopy(textPtr, gOtherText_RequiredTime); + +#ifdef ENGLISH + textPtr = sub_8072C74(textPtr, text[0], 102, 1); +#else + textPtr = sub_8072C74(textPtr, text[0], 99, 1); +#endif + textPtr = StringAppend(textPtr, gOtherText_Min); + + textPtr = sub_8072C74(textPtr, text[1], 136, 1); + StringCopy(textPtr, gOtherText_Sec); + + MenuPrint(gBerryBlenderData->stringVar, 5, 15); + + gBerryBlenderData->framesToWait = 0; + gBerryBlenderData->field_0++; + } + break; + case 4: + if (gMain.newKeys & A_BUTTON) + gBerryBlenderData->field_0++; + break; + case 5: + MenuZeroFillScreen(); + MenuDrawTextWindow(0, 14, 29, 19); + for (i = 0; i < BLENDER_MAX_PLAYERS; i++) + { + if (gBerryBlenderData->chosenItemID[i] != 0) + berryIDs[i] = gBerryBlenderData->chosenItemID[i] - 133; + } + sub_8050760(); + Blender_CalculatePokeblock(gBerryBlenderData->blendedBerries, &pokeblock, gBerryBlenderData->playersNo, flavours, gBerryBlenderData->max_RPM); + Blender_PrintMadePokeblockString(&pokeblock, gBerryBlenderData->stringVar); + CreateTask(sub_8052BD0, 6); + MenuPrintMessage(gBerryBlenderData->stringVar, 1, 15); + RemoveBagItem(gScriptItemId, 1); + sub_810CA34(&pokeblock); + gBerryBlenderData->field_0++; + break; + case 6: + if (MenuUpdateWindowText()) + { + Blender_TrySettingRecord(); + return TRUE; + } + break; + } + return FALSE; +} + +static void Blender_PrintMadePokeblockString(struct Pokeblock* pokeblock, u8* dst) +{ + u8 text[12]; + u8 flavourLvl, feel; + + dst[0] = EOS; + StringCopy(dst, gPokeblockNames[pokeblock->color]); +#ifdef ENGLISH + StringAppend(dst, gOtherText_PokeBlockMade); +#else + de_sub_8073174(dst, gOtherText_PokeBlockMade); +#endif + StringAppend(dst, sNewLineString_0); + + flavourLvl = sub_810C9B0(pokeblock); + feel = sub_810C9E8(pokeblock); + + StringAppend(dst, gOtherText_BlockLevelIs); + ConvertIntToDecimalStringN(text, flavourLvl, 0, 3); + StringAppend(dst, text); + + StringAppend(dst, gOtherText_BlockFeelIs); + ConvertIntToDecimalStringN(text, feel, 0, 3); + StringAppend(dst, text); + + StringAppend(dst, gOtherText_Period); + StringAppend(dst, gUnknown_08216249); +} + +static void Blender_SortBasedOnPoints(u8* places, u8 playersNum, u32* scores) +{ + s32 i, j; + for (i = 0; i < playersNum; i++) + { + for (j = 0; j < playersNum; j++) + { + if (scores[places[i]] > scores[places[j]]) + { + u8 temp = places[i]; + places[i] = places[j]; + places[j] = temp; + } + } + } +} + +static void Blender_SortScores(void) +{ + u8 i; + u8 places[4]; + u32 points[4]; + + for (i = 0; i < gBerryBlenderData->playersNo; i++) + places[i] = i; + for (i = 0; i < gBerryBlenderData->playersNo; i++) + { + points[i] = 1000000 * gBerryBlenderData->scores[i][BLENDER_SCORE_BEST]; + points[i] += 1000 * gBerryBlenderData->scores[i][BLENDER_SCORE_GOOD]; + points[i] += 1000 - gBerryBlenderData->scores[i][BLENDER_SCORE_MISS]; + } + Blender_SortBasedOnPoints(places, gBerryBlenderData->playersNo, points); + for (i = 0; i < gBerryBlenderData->playersNo; i++) + gBerryBlenderData->playerPlaces[i] = places[i]; +} + +static bool8 Blender_PrintBlendingRanking(void) +{ + u16 i; + switch (gBerryBlenderData->field_0) + { + case 0: + gBerryBlenderData->field_0++; + gBerryBlenderData->framesToWait = 255; + break; + case 1: + gBerryBlenderData->framesToWait -= 10; + if (gBerryBlenderData->framesToWait < 0) + { + gBerryBlenderData->framesToWait = 0; + gBerryBlenderData->field_0++; + } + break; + case 2: + if (++gBerryBlenderData->framesToWait > 20) + { + gBerryBlenderData->framesToWait = 0; + gBerryBlenderData->field_0++; + } + break; + case 3: + MenuDrawTextWindow(4, 2, 25, 17); + sub_8072BD8(gOtherText_Ranking, 5, 3, 160); + + gBerryBlenderData->scoreIconIDs[BLENDER_SCORE_BEST] = CreateSprite(&sSpriteTemplate_821645C, 140, 52, 0); + gSprites[gBerryBlenderData->scoreIconIDs[BLENDER_SCORE_BEST]].callback = SpriteCallbackDummy; + StartSpriteAnim(&gSprites[gBerryBlenderData->scoreIconIDs[BLENDER_SCORE_BEST]], 3); + + gBerryBlenderData->scoreIconIDs[BLENDER_SCORE_GOOD] = CreateSprite(&sSpriteTemplate_821645C, 164, 52, 0); + gSprites[gBerryBlenderData->scoreIconIDs[BLENDER_SCORE_GOOD]].callback = SpriteCallbackDummy; + + gBerryBlenderData->scoreIconIDs[BLENDER_SCORE_MISS] = CreateSprite(&sSpriteTemplate_821645C, 188, 52, 0); + gSprites[gBerryBlenderData->scoreIconIDs[BLENDER_SCORE_MISS]].callback = SpriteCallbackDummy; + StartSpriteAnim(&gSprites[gBerryBlenderData->scoreIconIDs[BLENDER_SCORE_MISS]], 1); + + Blender_SortScores(); + + for (i = 0; i < gBerryBlenderData->playersNo; i++) + { + u8 place = gBerryBlenderData->playerPlaces[i]; + u8* txtPtr = gBerryBlenderData->stringVar; + + txtPtr[0] = EXT_CTRL_CODE_BEGIN; + txtPtr[1] = 0x13; + txtPtr[2] = 4; + txtPtr += 3; + + txtPtr = ConvertIntToDecimalString(txtPtr, i + 1); + + txtPtr[0] = CHAR_SPACE; + txtPtr[1] = CHAR_PERIOD; + txtPtr[2] = CHAR_SPACE; + txtPtr += 3; + + txtPtr = StringCopy(txtPtr, gLinkPlayers[place].name); + + txtPtr = sub_8072C14(txtPtr, gBerryBlenderData->scores[place][BLENDER_SCORE_BEST], 108, 1); + txtPtr = sub_8072C14(txtPtr, gBerryBlenderData->scores[place][BLENDER_SCORE_GOOD], 132, 1); + txtPtr = sub_8072C14(txtPtr, gBerryBlenderData->scores[place][BLENDER_SCORE_MISS], 156, 1); + + MenuPrint(gBerryBlenderData->stringVar, 5, i * gUnknown_082165F3[gBerryBlenderData->playersNo] + 8); + } + gBerryBlenderData->framesToWait = 0; + gBerryBlenderData->field_0++; + break; + case 4: + if (++gBerryBlenderData->framesToWait > 20) + gBerryBlenderData->field_0++; + break; + case 5: + if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + gBerryBlenderData->field_0++; + } + break; + case 6: + gBerryBlenderData->field_0 = 0; + return TRUE; + } + return FALSE; +} + +// debug menu goes here + +void unref_sub_80524BC(void) +{ + ResetSpriteData(); + FreeAllSpritePalettes(); + ResetTasks(); + SetVBlankCallback(VBlankCB1_BerryBlender); + SetUpWindowConfig(&gWindowConfig_81E6CE4); + InitMenuWindow(&gWindowConfig_81E6CE4); + SeedRng(gMain.vblankCounter1); + REG_DISPCNT = 0x1540; + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); + sBlenderDebug.BPM = 8000; + sBlenderDebug.field_10++; + SetMainCallback2(sub_8052AF8); +} + +static void BlenderDebug_PrintBerryData(void) +{ + u8 text[128]; + u8 i; + + StringCopy(text, sText_BPM); + MenuPrint(text, 2, 0); + + ConvertIntToDecimalStringN(text, sBlenderDebug.BPM / 100, 2, 3); + MenuPrint(text, 6, 0); + + for (i = 0; i < 4; i++) + { + u8 var; + + if (sBlenderDebug.cursorPos == i) + { + text[0] = 0xEF; + CopyItemName(sBlenderDebug.berries[i] + 133, &text[1]); + } + else + { + CopyItemName(sBlenderDebug.berries[i] + 133, &text[0]); + text[6] = CHAR_SPACE; + text[7] = EOS; + } + var = (i * 3) + 3; + MenuPrint(text, 2, var); + + ConvertIntToDecimalStringN(&text[0], gBerries[sBlenderDebug.berries[i]].spicy, 2, 2); + StringAppend(text, sText_Space); + + ConvertIntToDecimalStringN(&text[3], gBerries[sBlenderDebug.berries[i]].dry, 2, 2); + StringAppend(text, sText_Space); + + ConvertIntToDecimalStringN(&text[6], gBerries[sBlenderDebug.berries[i]].sweet, 2, 2); + StringAppend(text, sText_Space); + + ConvertIntToDecimalStringN(&text[9], gBerries[sBlenderDebug.berries[i]].bitter, 2, 2); + StringAppend(text, sText_Space); + + ConvertIntToDecimalStringN(&text[12], gBerries[sBlenderDebug.berries[i]].sour, 2, 2); + StringAppend(text, sText_Space); + + ConvertIntToDecimalStringN(&text[15], gBerries[sBlenderDebug.berries[i]].smoothness, 2, 2); + + text[17] = EOS; + MenuPrint(text, 7, var); + } + if (sBlenderDebug.pokeblock.color != 0) + { + StringCopy(text, gPokeblockNames[sBlenderDebug.pokeblock.color]); + MenuPrint(text, 2, 15); + + ConvertIntToHexStringN(&text[0], sBlenderDebug.spicy, 2, 2); + StringAppend(text, sText_Space); + + ConvertIntToHexStringN(&text[3], sBlenderDebug.dry, 2, 2); + StringAppend(text, sText_Space); + + ConvertIntToHexStringN(&text[6], sBlenderDebug.sweet, 2, 2); + StringAppend(text, sText_Space); + + ConvertIntToHexStringN(&text[9], sBlenderDebug.bitter, 2, 2); + StringAppend(text, sText_Space); + + ConvertIntToHexStringN(&text[12], sBlenderDebug.sour, 2, 2); + StringAppend(text, sText_Space); + + ConvertIntToHexStringN(&text[15], sBlenderDebug.feel, 2, 2); + + text[17] = EOS; + MenuPrint(text, 7, 17); + } +} + +static void sub_80527BC(void) +{ + u8 text[70]; + u8 buffer[10]; + u16 i; + + if (gUnknown_020297DC == 1) + { + u16 j; + for (j = 0; j < 10; j++) + gUnknown_03004840[j] = 0; + gUnknown_03004830 = Random(); + gUnknown_020297E0 = 0; + gUnknown_020297DC = 2; + for (i = 0; i < 200; i++) + ewram[i] = 0; + gUnknown_020297E8 = 0; + } + for (i = 0; i < 100; i++) + { + if (((Random() >> 15) & 1) == gUnknown_020297E8) + gUnknown_020297E0++; + else + { + u16* ewramPtr = ((u16*)(ewram)); + ewramPtr[gUnknown_020297E4] = gUnknown_020297E0; + gUnknown_020297E4++; + gUnknown_020297E0 = 0; + gUnknown_020297E8 ^= 1; + } + } + text[0] = EOS; + + ConvertIntToHexStringN(buffer, gUnknown_03004830, 2, 8); + StringAppend(text, buffer); + StringAppend(text, sText_Space); + + ConvertIntToHexStringN(buffer, gUnknown_020297E0, 2, 8); + StringAppend(text, buffer); + StringAppend(text, sNewLineString_1); + + if (gUnknown_020297DC == 3) + { + ConvertIntToHexStringN(buffer, gUnknown_020297E4, 2, 16); + StringAppend(text, buffer); + gUnknown_020297DC = 0; + } + + MenuPrint(text, 2, 15); +} + +static void sub_8052918(void) +{ + if (gMain.newKeys & R_BUTTON) + { + sBlenderDebug.BPM += 1000; + if (sBlenderDebug.BPM > 30000) + sBlenderDebug.BPM = 1000; + sBlenderDebug.field_10++; + } + if (gMain.newKeys & L_BUTTON) + { + sBlenderDebug.BPM -= 1000; + if (sBlenderDebug.BPM < 0) + sBlenderDebug.BPM = 30000; + sBlenderDebug.field_10++; + } + if (gMain.newKeys & DPAD_UP) + { + sBlenderDebug.cursorPos -= 1; + if (sBlenderDebug.cursorPos < 0) + sBlenderDebug.cursorPos = 3; + sBlenderDebug.field_10++; + } + if (gMain.newKeys & DPAD_DOWN) + { + sBlenderDebug.cursorPos += 1; + if (sBlenderDebug.cursorPos > 3) + sBlenderDebug.cursorPos = 0; + sBlenderDebug.field_10++; + } + if (gMain.newKeys & DPAD_LEFT) + { + if (--sBlenderDebug.berries[sBlenderDebug.cursorPos] < 0) + sBlenderDebug.berries[sBlenderDebug.cursorPos] = 42; + sBlenderDebug.field_10++; + } + if (gMain.newKeys & DPAD_RIGHT) + { + if (++sBlenderDebug.berries[sBlenderDebug.cursorPos] > 42) + sBlenderDebug.berries[sBlenderDebug.cursorPos] = 0; + sBlenderDebug.field_10++; + } + if (gMain.newKeys & A_BUTTON) + { + u16 berryIDs[4]; + struct BlenderBerry berries[4]; + + u16 i, notEnigma = 0; + for (i = 0; i < 4; i++) + { + if (sBlenderDebug.berries[i] != 42) + { + notEnigma++; + berryIDs[i] = sBlenderDebug.berries[i]; + Blender_CopyBerryData(&berries[i], sBlenderDebug.berries[i] + 133); + } + else + break; + } + if (notEnigma > 1) + { + BlenderDebug_CalculatePokeblock(berries, &sBlenderDebug.pokeblock, notEnigma, &sBlenderDebug.spicy, sBlenderDebug.BPM); + sBlenderDebug.field_10++; + } + else + sBlenderDebug.pokeblock.color = 0xFF; + } + if (sBlenderDebug.field_10) + { + BlenderDebug_PrintBerryData(); + sBlenderDebug.field_10 = 0; + } + if (gMain.newKeys & SELECT_BUTTON && gUnknown_020297DC == 0) + { + gUnknown_020297DC++; + gUnknown_020297E0 = 0; + SeedRng(gMain.vblankCounter1); + } + if (gUnknown_020297DC != 0) + sub_80527BC(); +} + +static void sub_8052AF8(void) +{ + sub_8052918(); + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +// debug menu ends +// blender record window begins + +void ShowBerryBlenderRecordWindow(void) +{ + u8 text[30]; + s32 i; + + MenuDrawTextWindow(6, 3, 23, 16); + MenuPrint(gMultiText_BerryBlenderMaxSpeedRecord, 8, 4); + MenuPrint(gMultiText_2P3P4P, 8, 9); + + for (i = 0; i < 3; i++) + { + u32 record = gSaveBlock1.berryBlenderRecords[i]; + u8* txtPtr = sub_8072C14(text, record / 100, 18, 1); + +#ifdef ENGLISH + txtPtr[0] = CHAR_SPACE; + txtPtr[1] = CHAR_PERIOD; + txtPtr[2] = CHAR_SPACE; + txtPtr += 3; +#else + *txtPtr++ = CHAR_COMMA; +#endif + + txtPtr = ConvertIntToDecimalStringN(txtPtr, record % 100, 2, 2); + StringAppend(txtPtr, gOtherText_RPM); + MenuPrint(text, 15, i * 2 + 9); + } +} + +static void sub_8052BD0(u8 taskID) +{ + if (gTasks[taskID].data[0] == 0) + { + PlayFanfare(BGM_FANFA1); + gTasks[taskID].data[0]++; + } + if (IsFanfareTaskInactive()) + { + PlayBGM(gBerryBlenderData->field_178); + DestroyTask(taskID); + } +} diff --git a/src/scene/cute_sketch.c b/src/scene/cute_sketch.c new file mode 100644 index 000000000..5317bc334 --- /dev/null +++ b/src/scene/cute_sketch.c @@ -0,0 +1,164 @@ +#include "global.h" +#include "cute_sketch.h" +#include "contest_painting.h" + +extern u16 (*gUnknown_03005DEC)[][32]; +extern u8 gUnknown_03005E00; +extern u8 gUnknown_03005DFC; +extern u8 gUnknown_03005DF8; +extern u8 gUnknown_03005DF0; +extern u8 gUnknown_03005E04; +extern u8 gUnknown_03005DF4; + +extern u8 gUnknown_03005DE8; + +// this file's functions +void sub_80FCAA4(void); +void sub_80FCB5C(void); +void sub_80FCD54(void); +void sub_80FCEA4(void); +void sub_80FCCBC(void); +void sub_80FD06C(void); +void sub_80FD114(void); +void sub_80FCF3C(void); +void sub_80FCAC4(void); +void sub_80FCC18(u8); +void sub_80FC92C(u8); +void sub_80FC9E4(u8); +void sub_80FD1C8(u16); +u16 sub_80FD39C(u16*); +u16 sub_80FD68C(u16*, u16*, u16*); + +void sub_80FC7A0(struct Unk03005E20* info) +{ + gUnknown_03005DEC = info->var_4; + gUnknown_03005E00 = info->var_1F; + gUnknown_03005DE8 = info->var_19; + gUnknown_03005DFC = info->var_1A; + gUnknown_03005DF8 = info->var_1B; + gUnknown_03005DF0 = info->var_1C; + gUnknown_03005E04 = info->var_1D; + gUnknown_03005DF4 = info->var_1E; + switch (info->var_0) + { + case 2: + sub_80FCAA4(); + break; + case 8: + sub_80FCB5C(); + break; + case 9: + sub_80FCD54(); + sub_80FCC18(gUnknown_03005E00); + break; + case 10: + sub_80FCD54(); + sub_80FCEA4(); + sub_80FCCBC(); + case 31: + sub_80FCEA4(); + break; + case 11: + sub_80FCD54(); + sub_80FD06C(); + sub_80FD06C(); + sub_80FD114(); + sub_80FCCBC(); + break; + case 13: + sub_80FCF3C(); + break; + case 30: + sub_80FCD54(); + break; + case 32: + sub_80FD06C(); + break; + case 33: + sub_80FD114(); + break; + case 6: + sub_80FCAC4(); + sub_80FC92C(3); + break; + case 36: + sub_80FCD54(); + sub_80FD06C(); + sub_80FD114(); + sub_80FCCBC(); + sub_80FCB5C(); + sub_80FCB5C(); + sub_80FC92C(2); + sub_80FC9E4(4); + break; + } +} + +#define RGB2(r, g, b) (((b) << 10) | ((g) << 5) | (r)) + +void sub_80FC92C(u8 a0) // it changes palette someway somehow... .__. +{ + u8 i, j; + for (i = 0; i < gUnknown_03005DF0; i++) + { + u16* var2 = &(*gUnknown_03005DEC)[0][(gUnknown_03005DFC + i) * gUnknown_03005E04]; + u16* pal = &var2[gUnknown_03005DE8]; + for (j = 0; j < gUnknown_03005DF8; j++, pal++) + { + if (!(0x8000 & *pal)) + { + u8 val = (31 & *pal); + val += a0; + if (val > 31) + val = 31; + + *pal = RGB2(val, val, val); + } + } + } +} + +void sub_80FC9E4(u8 a0) +{ + u8 i, j; + for (i = 0; i < gUnknown_03005DF0; i++) + { + u16* var2 = &(*gUnknown_03005DEC)[0][(gUnknown_03005DFC + i) * gUnknown_03005E04]; + u16* pal = &var2[gUnknown_03005DE8]; + for (j = 0; j < gUnknown_03005DF8; j++, pal++) + { + if (!(0x8000 & *pal)) + { + u8 val = (31 & *pal); + if (val > 31 - a0) + val = 31 - (a0 >> 1); + + *pal = RGB2(val, val, val); + } + } + } +} + +void sub_80FCAA4(void) +{ + u32 i; + for (i = 0; i < 3200; i++) + sub_80FD1C8(i); +} + +void sub_80FCAC4(void) +{ + u8 i, j; + for (i = 0; i < gUnknown_03005DF0; i++) + { + u16* var2 = &(*gUnknown_03005DEC)[0][(gUnknown_03005DFC + i) * gUnknown_03005E04]; + u16* pal = &var2[gUnknown_03005DE8]; + for (j = 0; j < gUnknown_03005DF8; j++, pal++) + { + if (!(0x8000 & *pal)) + { + *pal = sub_80FD39C(pal); + } + } + } +} diff --git a/src/scene/evolution_graphics.c b/src/scene/evolution_graphics.c new file mode 100644 index 000000000..a47e63a59 --- /dev/null +++ b/src/scene/evolution_graphics.c @@ -0,0 +1,613 @@ +#include "global.h" +#include "sprite.h" +#include "trig.h" +#include "rng.h" +#include "decompress.h" +#include "task.h" +#include "sound.h" +#include "songs.h" +#include "palette.h" + +// this file's functions +static void EvoSparkle_DummySpriteCb(struct Sprite* sprite); +static void EvoTask_BeginPreSet1_FadeAndPlaySE(u8 taskID); +static void EvoTask_CreatePreEvoSparkleSet1(u8 taskID); +static void EvoTask_WaitForPre1SparklesToGoUp(u8 taskID); +static void EvoTask_BeginPreSparklesSet2(u8 taskID); +static void EvoTask_CreatePreEvoSparklesSet2(u8 taskID); +static void EvoTask_DestroyPreSet2Task(u8 taskID); +static void EvoTask_BeginPostSparklesSet1(u8 taskID); +static void EvoTask_CreatePostEvoSparklesSet1(u8 taskID); +static void EvoTask_DestroyPostSet1Task(u8 taskID); +static void EvoTask_BeginPostSparklesSet2_AndFlash(u8 taskID); +static void EvoTask_CreatePostEvoSparklesSet2_AndFlash(u8 taskID); +static void EvoTask_BeginPostSparklesSet2_AndFlash_Trade(u8 taskID); +static void EvoTask_CreatePostEvoSparklesSet2_AndFlash_Trade(u8 taskID); +static void EvoTask_DestroyPostSet2AndFlashTask(u8 taskID); + +static void sub_8149FC8(u8 taskID); +static void sub_8149FEC(u8 taskID); +static void PreEvoVisible_PostEvoInvisible_KillTask(u8 taskID); +static void PreEvoInVisible_PostEvoVisible_KillTask(u8 taskID); +static void sub_814A03C(u8 taskID); + +// const data +static const u16 sEvoSparklePalette[] = INCBIN_U16("graphics/misc/evo_sparkle.gbapal"); +static const u8 sEvoSparkleTiles[] = INCBIN_U8("graphics/misc/evo_sparkle.4bpp.lz"); + +static const struct CompressedSpriteSheet sEvoSparkleSpriteSheets[] = +{ + {sEvoSparkleTiles, 0x20, 1001}, + {NULL, 0, 0} +}; +static const struct SpritePalette sEvoSparkleSpritePals[] = +{ + {sEvoSparklePalette, 1001}, + {NULL, 0} +}; + +static const struct OamData sOamData_EvoSparkle = +{ + .y = 160, + .affineMode = 0, + .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 sSpriteAnim_EvoSparkle[] = +{ + ANIMCMD_FRAME(0, 8), + ANIMCMD_END +}; + +static const union AnimCmd *const sSpriteAnimTable_EvoSparkle[] = +{ + sSpriteAnim_EvoSparkle, +}; + +static const struct SpriteTemplate sEvoSparkleSpriteTemplate = +{ + .tileTag = 1001, + .paletteTag = 1001, + .oam = &sOamData_EvoSparkle, + .anims = sSpriteAnimTable_EvoSparkle, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = EvoSparkle_DummySpriteCb +}; + +static const s16 sEvoSparkleMatricies[] = +{ + 0x3C0, 0x380, 0x340, 0x300, 0x2C0, 0x280, 0x240, 0x200, 0x1C0, + 0x180, 0x140, 0x100, -4, 0x10, -3, 0x30, -2, 0x50, + -1, 0x70, 0x1, 0x70, 0x2, 0x50, 0x3, 0x30, 0x4, 0x10 +}; + +// code + +static void EvoSparkle_DummySpriteCb(struct Sprite* sprite) +{ + +} + +static void SetEvoSparklesMatrices(void) +{ + u16 i; + for (i = 0; i < 12; i++) + { + SetOamMatrix(20 + i, sEvoSparkleMatricies[i], 0, 0, sEvoSparkleMatricies[i]); + } +} + +static void SpriteCB_PreEvoSparkleSet1(struct Sprite* sprite) +{ + if (sprite->pos1.y > 8) + { + u8 matrixNum; + + sprite->pos1.y = 88 - (sprite->data7 * sprite->data7) / 80; + sprite->pos2.y = Sin((u8)(sprite->data6), sprite->data5) / 4; + sprite->pos2.x = Cos((u8)(sprite->data6), sprite->data5); + sprite->data6 += 4; + if (sprite->data7 & 1) + sprite->data5--; + sprite->data7++; + if (sprite->pos2.y > 0) + sprite->subpriority = 1; + else + sprite->subpriority = 20; + matrixNum = sprite->data5 / 4 + 20; + if (matrixNum > 31) + matrixNum = 31; + sprite->oam.matrixNum = matrixNum; + } + else + DestroySprite(sprite); +} + +static void CreatePreEvoSparkleSet1(u8 arg0) +{ + u8 spriteID = CreateSprite(&sEvoSparkleSpriteTemplate, 120, 88, 0); + if (spriteID != MAX_SPRITES) + { + gSprites[spriteID].data5 = 48; + gSprites[spriteID].data6 = arg0; + gSprites[spriteID].data7 = 0; + gSprites[spriteID].oam.affineMode = 1; + gSprites[spriteID].oam.matrixNum = 31; + gSprites[spriteID].callback = SpriteCB_PreEvoSparkleSet1; + } +} + +static void SpriteCB_PreEvoSparkleSet2(struct Sprite* sprite) +{ + if (sprite->pos1.y < 88) + { + sprite->pos1.y = 8 + (sprite->data7 * sprite->data7) / 5; + sprite->pos2.y = Sin((u8)(sprite->data6), sprite->data5) / 4; + sprite->pos2.x = Cos((u8)(sprite->data6), sprite->data5); + sprite->data5 = 8 + Sin((u8)(sprite->data7 * 4), 40); + sprite->data7++; + } + else + DestroySprite(sprite); +} + +static void CreatePreEvoSparkleSet2(u8 arg0) +{ + u8 spriteID = CreateSprite(&sEvoSparkleSpriteTemplate, 120, 8, 0); + if (spriteID != MAX_SPRITES) + { + gSprites[spriteID].data5 = 8; + gSprites[spriteID].data6 = arg0; + gSprites[spriteID].data7 = 0; + gSprites[spriteID].oam.affineMode = 1; + gSprites[spriteID].oam.matrixNum = 25; + gSprites[spriteID].subpriority = 1; + gSprites[spriteID].callback = SpriteCB_PreEvoSparkleSet2; + } +} + +static void SpriteCB_PostEvoSparkleSet1(struct Sprite* sprite) +{ + if (sprite->data5 > 8) + { + sprite->pos2.y = Sin((u8)(sprite->data6), sprite->data5); + sprite->pos2.x = Cos((u8)(sprite->data6), sprite->data5); + sprite->data5 -= sprite->data3; + sprite->data6 += 4; + } + else + DestroySprite(sprite); +} + +static void CreatePostEvoSparkleSet1(u8 arg0, u8 arg1) +{ + u8 spriteID = CreateSprite(&sEvoSparkleSpriteTemplate, 120, 56, 0); + if (spriteID != MAX_SPRITES) + { + gSprites[spriteID].data3 = arg1; + gSprites[spriteID].data5 = 120; + gSprites[spriteID].data6 = arg0; + gSprites[spriteID].data7 = 0; + gSprites[spriteID].oam.affineMode = 1; + gSprites[spriteID].oam.matrixNum = 31; + gSprites[spriteID].subpriority = 1; + gSprites[spriteID].callback = SpriteCB_PostEvoSparkleSet1; + } +} + +static void SpriteCB_PostEvoSparkleSet2(struct Sprite* sprite) +{ + if (!(sprite->data7 & 3)) + sprite->pos1.y++; + if (sprite->data6 < 128) + { + u8 matrixNum; + + sprite->pos2.y = -Sin((u8)(sprite->data6), sprite->data5); + sprite->pos1.x = 120 + (sprite->data3 * sprite->data7) / 3; + sprite->data6++; + matrixNum = 31 - (sprite->data6 * 12 / 128); + if (sprite->data6 > 64) + sprite->subpriority = 1; + else + { + sprite->invisible = 0; + sprite->subpriority = 20; + if (sprite->data6 > 112 && sprite->data6 & 1) + sprite->invisible = 1; + } + if (matrixNum < 20) + matrixNum = 20; + sprite->oam.matrixNum = matrixNum; + sprite->data7++; + } + else + DestroySprite(sprite); +} + +static void CreatePostEvoSparkleSet2(u8 arg0) +{ + u8 spriteID = CreateSprite(&sEvoSparkleSpriteTemplate, 120, 56, 0); + if (spriteID != MAX_SPRITES) + { + gSprites[spriteID].data3 = 3 - (Random() % 7); + gSprites[spriteID].data5 = 48 + (Random() & 0x3F); + gSprites[spriteID].data7 = 0; + gSprites[spriteID].oam.affineMode = 1; + gSprites[spriteID].oam.matrixNum = 31; + gSprites[spriteID].subpriority = 20; + gSprites[spriteID].callback = SpriteCB_PostEvoSparkleSet2; + } +} + +void LoadEvoSparkleSpriteAndPal(void) +{ + LoadCompressedObjectPic(&sEvoSparkleSpriteSheets[0]); + LoadSpritePalettes(sEvoSparkleSpritePals); +} + +#define tFrameCounter data[15] + +u8 LaunchTask_PreEvoSparklesSet1(u16 arg0) +{ + u8 taskID = CreateTask(EvoTask_BeginPreSet1_FadeAndPlaySE, 0); + gTasks[taskID].data[1] = arg0; + return taskID; +} + +static void EvoTask_BeginPreSet1_FadeAndPlaySE(u8 taskID) +{ + SetEvoSparklesMatrices(); + gTasks[taskID].tFrameCounter = 0; + BeginNormalPaletteFade(3 << gTasks[taskID].data[1], 0xA, 0, 0x10, 0x7FFF); + gTasks[taskID].func = EvoTask_CreatePreEvoSparkleSet1; + PlaySE(SE_W025); +} + +static void EvoTask_CreatePreEvoSparkleSet1(u8 taskID) +{ + if (gTasks[taskID].tFrameCounter < 64) + { + if (!(gTasks[taskID].tFrameCounter & 7)) + { + u8 i; + for (i = 0; i < 4; i++) + CreatePreEvoSparkleSet1((0x78 & gTasks[taskID].tFrameCounter) * 2 + i * 64); + } + gTasks[taskID].tFrameCounter++; + } + else + { + gTasks[taskID].tFrameCounter = 96; + gTasks[taskID].func = EvoTask_WaitForPre1SparklesToGoUp; + } +} + +static void EvoTask_WaitForPre1SparklesToGoUp(u8 taskID) +{ + if (gTasks[taskID].tFrameCounter != 0) + gTasks[taskID].tFrameCounter--; + else + DestroyTask(taskID); +} + +u8 LaunchTask_PreEvoSparklesSet2(void) +{ + return CreateTask(EvoTask_BeginPreSparklesSet2, 0); +} + +static void EvoTask_BeginPreSparklesSet2(u8 taskID) +{ + SetEvoSparklesMatrices(); + gTasks[taskID].tFrameCounter = 0; + gTasks[taskID].func = EvoTask_CreatePreEvoSparklesSet2; + PlaySE(SE_W062B); +} + +static void EvoTask_CreatePreEvoSparklesSet2(u8 taskID) +{ + if (gTasks[taskID].tFrameCounter < 96) + { + if (gTasks[taskID].tFrameCounter < 6) + { + u8 i; + for (i = 0; i < 9; i++) + CreatePreEvoSparkleSet2(i * 16); + } + gTasks[taskID].tFrameCounter++; + } + else + gTasks[taskID].func = EvoTask_DestroyPreSet2Task; +} + +static void EvoTask_DestroyPreSet2Task(u8 taskID) +{ + DestroyTask(taskID); +} + +u8 LaunchTask_PostEvoSparklesSet1(void) +{ + return CreateTask(EvoTask_BeginPostSparklesSet1, 0); +} + +static void EvoTask_BeginPostSparklesSet1(u8 taskID) +{ + SetEvoSparklesMatrices(); + gTasks[taskID].tFrameCounter = 0; + gTasks[taskID].func = EvoTask_CreatePostEvoSparklesSet1; + PlaySE(SE_REAPOKE); +} + +static void EvoTask_CreatePostEvoSparklesSet1(u8 taskID) +{ + if (gTasks[taskID].tFrameCounter < 48) + { + if (gTasks[taskID].tFrameCounter == 0) + { + u8 i; + for (i = 0; i < 16; i++) + CreatePostEvoSparkleSet1(i * 16, 4); + } + if (gTasks[taskID].tFrameCounter == 32) + { + u8 i; + for (i = 0; i < 16; i++) + CreatePostEvoSparkleSet1(i * 16, 8); + } + gTasks[taskID].tFrameCounter++; + } + else + gTasks[taskID].func = EvoTask_DestroyPostSet1Task; +} + +static void EvoTask_DestroyPostSet1Task(u8 taskID) +{ + DestroyTask(taskID); +} + +u8 LaunchTask_PostEvoSparklesSet2AndFlash(u16 arg0) +{ + u8 taskID = CreateTask(EvoTask_BeginPostSparklesSet2_AndFlash, 0); + gTasks[taskID].data[2] = arg0; + return taskID; +} + +static void EvoTask_BeginPostSparklesSet2_AndFlash(u8 taskID) +{ + SetEvoSparklesMatrices(); + gTasks[taskID].tFrameCounter = 0; + CpuSet(&gPlttBufferFaded[0x20], &gPlttBufferUnfaded[0x20], 0x30); + BeginNormalPaletteFade(0xFFF9001C, 0, 0, 0x10, 0x7FFF); + gTasks[taskID].func = EvoTask_CreatePostEvoSparklesSet2_AndFlash; + PlaySE(SE_W080); +} + +static void EvoTask_CreatePostEvoSparklesSet2_AndFlash(u8 taskID) +{ + if (gTasks[taskID].tFrameCounter < 128) + { + u8 i; + switch (gTasks[taskID].tFrameCounter) + { + default: + if (gTasks[taskID].tFrameCounter < 50) + CreatePostEvoSparkleSet2(Random() & 7); + break; + case 0: + for (i = 0; i < 8; i++) + CreatePostEvoSparkleSet2(i); + break; + case 32: + BeginNormalPaletteFade(0xFFFF001C, 0x10, 0x10, 0, 0x7FFF); + break; + } + gTasks[taskID].tFrameCounter++; + } + else + gTasks[taskID].func = EvoTask_DestroyPostSet2AndFlashTask; +} + +static void EvoTask_DestroyPostSet2AndFlashTask(u8 taskID) +{ + if (!gPaletteFade.active) + DestroyTask(taskID); +} + +u8 LaunchTask_PostEvoSparklesSet2AndFlash_Trade(u16 arg0) +{ + u8 taskID = CreateTask(EvoTask_BeginPostSparklesSet2_AndFlash_Trade, 0); + gTasks[taskID].data[2] = arg0; + return taskID; +} + +static void EvoTask_BeginPostSparklesSet2_AndFlash_Trade(u8 taskID) +{ + SetEvoSparklesMatrices(); + gTasks[taskID].tFrameCounter = 0; + CpuSet(&gPlttBufferFaded[0x20], &gPlttBufferUnfaded[0x20], 0x30); + BeginNormalPaletteFade(0xFFF90001, 0, 0, 0x10, 0x7FFF); + gTasks[taskID].func = EvoTask_CreatePostEvoSparklesSet2_AndFlash_Trade; + PlaySE(SE_W080); +} + +static void EvoTask_CreatePostEvoSparklesSet2_AndFlash_Trade(u8 taskID) +{ + if (gTasks[taskID].tFrameCounter < 128) + { + u8 i; + switch (gTasks[taskID].tFrameCounter) + { + default: + if (gTasks[taskID].tFrameCounter < 50) + CreatePostEvoSparkleSet2(Random() & 7); + break; + case 0: + for (i = 0; i < 8; i++) + CreatePostEvoSparkleSet2(i); + break; + case 32: + BeginNormalPaletteFade(0xFFFF0001, 0x10, 0x10, 0, 0x7FFF); + break; + } + gTasks[taskID].tFrameCounter++; + } + else + gTasks[taskID].func = EvoTask_DestroyPostSet2AndFlashTask; +} + +#undef tFrameCounter + +static void PokeEvoSprite_DummySpriteCB(struct Sprite* sprite) +{ + +} + +#define tPreEvoSpriteID data[1] +#define tPostEvoSpriteID data[2] +#define tEvoStopped data[8] + +u8 sub_8149E7C(u8 preEvoSpriteID, u8 postEvoSpriteID) +{ + u16 i; + u16 stack[16]; + u8 taskID; + s32 toDiv; + + for (i = 0; i < 16; i++) + stack[i] = 0x7FFF; + + taskID = CreateTask(sub_8149FC8, 0); + gTasks[taskID].tPreEvoSpriteID = preEvoSpriteID; + gTasks[taskID].tPostEvoSpriteID = postEvoSpriteID; + gTasks[taskID].data[3] = 256; + gTasks[taskID].data[4] = 16; + + toDiv = 65536; + SetOamMatrix(30, 256, 0, 0, 256); + SetOamMatrix(31, toDiv / gTasks[taskID].data[4], 0, 0, toDiv / gTasks[taskID].data[4]); + + gSprites[preEvoSpriteID].callback = PokeEvoSprite_DummySpriteCB; + gSprites[preEvoSpriteID].oam.affineMode = 1; + gSprites[preEvoSpriteID].oam.matrixNum = 30; + gSprites[preEvoSpriteID].invisible = 0; + CpuSet(stack, &gPlttBufferFaded[0x100 + (gSprites[preEvoSpriteID].oam.paletteNum * 16)], 16); + + gSprites[postEvoSpriteID].callback = PokeEvoSprite_DummySpriteCB; + gSprites[postEvoSpriteID].oam.affineMode = 1; + gSprites[postEvoSpriteID].oam.matrixNum = 31; + gSprites[postEvoSpriteID].invisible = 0; + CpuSet(stack, &gPlttBufferFaded[0x100 + (gSprites[postEvoSpriteID].oam.paletteNum * 16)], 16); + + gTasks[taskID].tEvoStopped = FALSE; + return taskID; +} + +static void sub_8149FC8(u8 taskID) +{ + gTasks[taskID].data[5] = 0; + gTasks[taskID].data[6] = 8; + gTasks[taskID].func = sub_8149FEC; +} + +static void sub_8149FEC(u8 taskID) +{ + if (gTasks[taskID].tEvoStopped) + PreEvoVisible_PostEvoInvisible_KillTask(taskID); + else if (gTasks[taskID].data[6] == 128) + PreEvoInVisible_PostEvoVisible_KillTask(taskID); + else + { + gTasks[taskID].data[6] += 2; + gTasks[taskID].data[5] ^= 1; + gTasks[taskID].func = sub_814A03C; + } +} + +static void sub_814A03C(u8 taskID) +{ + if (gTasks[taskID].tEvoStopped) + gTasks[taskID].func = PreEvoVisible_PostEvoInvisible_KillTask; + else + { + u16 oamMatrixArg; + u8 r6 = 0; + if (gTasks[taskID].data[5] == 0) + { + if (gTasks[taskID].data[3] < 256 - gTasks[taskID].data[6]) + gTasks[taskID].data[3] += gTasks[taskID].data[6]; + else + { + gTasks[taskID].data[3] = 256; + r6++; + } + if (gTasks[taskID].data[4] > 16 + gTasks[taskID].data[6]) + gTasks[taskID].data[4] -= gTasks[taskID].data[6]; + else + { + gTasks[taskID].data[4] = 16; + r6++; + } + } + else + { + if (gTasks[taskID].data[4] < 256 - gTasks[taskID].data[6]) + gTasks[taskID].data[4] += gTasks[taskID].data[6]; + else + { + gTasks[taskID].data[4] = 256; + r6++; + } + if (gTasks[taskID].data[3] > 16 + gTasks[taskID].data[6]) + gTasks[taskID].data[3] -= gTasks[taskID].data[6]; + else + { + gTasks[taskID].data[3] = 16; + r6++; + } + } + oamMatrixArg = 65536 / gTasks[taskID].data[3]; + SetOamMatrix(30, oamMatrixArg, 0, 0, oamMatrixArg); + + oamMatrixArg = 65536 / gTasks[taskID].data[4]; + SetOamMatrix(31, oamMatrixArg, 0, 0, oamMatrixArg); + if (r6 == 2) + gTasks[taskID].func = sub_8149FEC; + } +} + +static void PreEvoInVisible_PostEvoVisible_KillTask(u8 taskID) +{ + gSprites[gTasks[taskID].tPreEvoSpriteID].oam.affineMode = 0; + gSprites[gTasks[taskID].tPreEvoSpriteID].oam.matrixNum = 0; + gSprites[gTasks[taskID].tPreEvoSpriteID].invisible = 1; + + gSprites[gTasks[taskID].tPostEvoSpriteID].oam.affineMode = 0; + gSprites[gTasks[taskID].tPostEvoSpriteID].oam.matrixNum = 0; + gSprites[gTasks[taskID].tPostEvoSpriteID].invisible = 0; + + DestroyTask(taskID); +} + +static void PreEvoVisible_PostEvoInvisible_KillTask(u8 taskID) +{ + gSprites[gTasks[taskID].tPreEvoSpriteID].oam.affineMode = 0; + gSprites[gTasks[taskID].tPreEvoSpriteID].oam.matrixNum = 0; + gSprites[gTasks[taskID].tPreEvoSpriteID].invisible = 0; + + gSprites[gTasks[taskID].tPostEvoSpriteID].oam.affineMode = 0; + gSprites[gTasks[taskID].tPostEvoSpriteID].oam.matrixNum = 0; + gSprites[gTasks[taskID].tPostEvoSpriteID].invisible = 1; + + DestroyTask(taskID); +} |