From d2a760afdbb4555e0b831598491e5fe1f410251d Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 18 Jun 2020 18:01:32 -0400 Subject: Rename contest_link_80FC4F4, 80F57C4, and 81D9DE4 --- include/contest_link.h | 13 + include/contest_link_80F57C4.h | 12 - include/contest_link_80FC4F4.h | 13 - include/contest_util.h | 12 + ld_script.txt | 10 +- src/contest.c | 4 +- src/contest_link.c | 549 ++++++++ src/contest_link_80F57C4.c | 2533 ------------------------------------- src/contest_link_80FC4F4.c | 548 -------- src/contest_link_81D9DE4.c | 331 ----- src/contest_link_util.c | 331 +++++ src/contest_util.c | 2533 +++++++++++++++++++++++++++++++++++++ src/scrcmd.c | 2 +- src/script_pokemon_util_80F87D8.c | 2 +- sym_ewram.txt | 2 +- 15 files changed, 3448 insertions(+), 3447 deletions(-) create mode 100644 include/contest_link.h delete mode 100644 include/contest_link_80F57C4.h delete mode 100644 include/contest_link_80FC4F4.h create mode 100644 include/contest_util.h create mode 100644 src/contest_link.c delete mode 100644 src/contest_link_80F57C4.c delete mode 100644 src/contest_link_80FC4F4.c delete mode 100644 src/contest_link_81D9DE4.c create mode 100644 src/contest_link_util.c create mode 100644 src/contest_util.c diff --git a/include/contest_link.h b/include/contest_link.h new file mode 100644 index 000000000..4344d55ad --- /dev/null +++ b/include/contest_link.h @@ -0,0 +1,13 @@ +#ifndef GUARD_CONTEST_LINK_H +#define GUARD_CONTEST_LINK_H + +void sub_80FCC88(u8); +void sub_80FCC88(u8); +void sub_80FCACC(u8); +void sub_80FC580(u8); +void sub_80FC6BC(u8); +void sub_80FC804(u8); +void sub_80FCE48(u8); +void sub_80FC894(u8); + +#endif //GUARD_CONTEST_LINK_H diff --git a/include/contest_link_80F57C4.h b/include/contest_link_80F57C4.h deleted file mode 100644 index 8bbc0f14b..000000000 --- a/include/contest_link_80F57C4.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef GUARD_CONTEST_LINK_80F57C4_H -#define GUARD_CONTEST_LINK_80F57C4_H - -void BufferContestantTrainerName(void); -void BufferContestantMonNickname(void); -void StartContest(void); -void BufferContestantMonSpecies(void); -void ShowContestResults(void); -void ContestLinkTransfer(u8); -void sub_80FC998(u8 taskId); - -#endif // GUARD_CONTEST_LINK_80F57C4_H diff --git a/include/contest_link_80FC4F4.h b/include/contest_link_80FC4F4.h deleted file mode 100644 index a3f118798..000000000 --- a/include/contest_link_80FC4F4.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef GUARD_CONTEST_LINK_80FC4F4_H -#define GUARD_CONTEST_LINK_80FC4F4_H - -void sub_80FCC88(u8); -void sub_80FCC88(u8); -void sub_80FCACC(u8); -void sub_80FC580(u8); -void sub_80FC6BC(u8); -void sub_80FC804(u8); -void sub_80FCE48(u8); -void sub_80FC894(u8); - -#endif //GUARD_CONTEST_LINK_80FC4F4_H diff --git a/include/contest_util.h b/include/contest_util.h new file mode 100644 index 000000000..c0d8df031 --- /dev/null +++ b/include/contest_util.h @@ -0,0 +1,12 @@ +#ifndef GUARD_CONTEST_UTIL_H +#define GUARD_CONTEST_UTIL_H + +void BufferContestantTrainerName(void); +void BufferContestantMonNickname(void); +void StartContest(void); +void BufferContestantMonSpecies(void); +void ShowContestResults(void); +void ContestLinkTransfer(u8); +void sub_80FC998(u8 taskId); + +#endif // GUARD_CONTEST_UTIL_H diff --git a/ld_script.txt b/ld_script.txt index d22c4a0ce..fb4d86300 100644 --- a/ld_script.txt +++ b/ld_script.txt @@ -168,7 +168,7 @@ SECTIONS { src/record_mixing.o(.text); src/secret_base.o(.text); src/tv.o(.text); - src/contest_link_80F57C4.o(.text); + src/contest_util.o(.text); src/script_pokemon_util_80F87D8.o(.text); src/field_poison.o(.text); src/pokemon_size_record.o(.text); @@ -176,7 +176,7 @@ SECTIONS { src/field_special_scene.o(.text); src/rotating_gate.o(.text); src/safari_zone.o(.text); - src/contest_link_80FC4F4.o(.text); + src/contest_link.o(.text); src/item_use.o(.text); src/battle_anim_effects_1.o(.text); src/battle_anim_effects_2.o(.text); @@ -328,7 +328,7 @@ SECTIONS { src/trainer_hill.o(.text); src/rayquaza_scene.o(.text); src/walda_phrase.o(.text); - src/contest_link_81D9DE4.o(.text); + src/contest_link_util.o(.text); src/gym_leader_rematch.o(.text); src/unk_transition.o(.text); src/international_string_util.o(.text); @@ -542,13 +542,13 @@ SECTIONS { src/record_mixing.o(.rodata); src/secret_base.o(.rodata); src/tv.o(.rodata); - src/contest_link_80F57C4.o(.rodata); + src/contest_util.o(.rodata); src/script_pokemon_util_80F87D8.o(.rodata); src/pokemon_size_record.o(.rodata) src/fldeff_misc.o(.rodata); src/field_special_scene.o(.rodata); src/rotating_gate.o(.rodata); - src/contest_link_80FC4F4.o(.rodata); + src/contest_link.o(.rodata); src/item_use.o(.rodata); src/battle_anim_effects_1.o(.rodata); src/battle_anim_effects_2.o(.rodata); diff --git a/src/contest.c b/src/contest.c index a43b87679..314ebb381 100644 --- a/src/contest.c +++ b/src/contest.c @@ -31,14 +31,14 @@ #include "tv.h" #include "scanline_effect.h" #include "util.h" -#include "contest_link_80F57C4.h" +#include "contest_util.h" #include "dma3.h" #include "battle_message.h" #include "event_scripts.h" #include "event_data.h" #include "strings.h" #include "contest_effect.h" -#include "contest_link_80FC4F4.h" +#include "contest_link.h" #include "script_pokemon_util_80F87D8.h" #include "international_string_util.h" #include "data.h" diff --git a/src/contest_link.c b/src/contest_link.c new file mode 100644 index 000000000..30ce9e391 --- /dev/null +++ b/src/contest_link.c @@ -0,0 +1,549 @@ +#include "global.h" +#include "contest.h" +#include "decompress.h" +#include "event_data.h" +#include "link.h" +#include "pokemon.h" +#include "random.h" +#include "task.h" +#include "contest_link.h" +#include "constants/flags.h" + +static void sub_80FC5C0(u8); +static void sub_80FC5DC(u8); + +bool32 sub_80FC4F4(void *src, u16 size) +{ + memcpy(gDecompressionBuffer, src, size); + if (SendBlock(bitmask_all_link_players_but_self(), gDecompressionBuffer, size)) + return TRUE; + else + return FALSE; +} + +bool8 sub_80FC530(u8 arg0) +{ + u8 mask = (1 << arg0); + if (!(GetBlockReceivedStatus() & mask)) + { + return FALSE; + } + else + { + ResetBlockReceivedFlag(arg0); + return TRUE; + } +} + +bool8 sub_80FC55C(void) +{ + if (GetBlockReceivedStatus() == sub_800A9D8()) + { + ResetBlockReceivedFlags(); + return TRUE; + } + else + { + return FALSE; + } +} + +void sub_80FC580(u8 taskId) +{ + u8 i; + + for (i = 0; i < 4; i++) + gBlockRecvBuffer[i][0] = 0xFF; + + gTasks[taskId].data[0] = 0; + gTasks[taskId].func = sub_80FC5C0; +} + +static void sub_80FC5C0(u8 taskId) +{ + gTasks[taskId].func = sub_80FC5DC; +} + +static void sub_80FC5DC(u8 taskId) +{ + int i; + + if (!gReceivedRemoteLinkPlayers) + return; + + gContestPlayerMonIndex = GetMultiplayerId(); + gNumLinkContestPlayers = GetLinkPlayerCount(); + gLinkContestFlags = LINK_CONTEST_FLAG_IS_LINK; + if (gWirelessCommType == 1) + gLinkContestFlags = LINK_CONTEST_FLAG_IS_LINK | LINK_CONTEST_FLAG_IS_WIRELESS; + + for (i = 0; i < gNumLinkContestPlayers && (u32)(gLinkPlayers[i].version & 0xFF) - 1 > VERSION_RUBY - 1; i++) + ; + + if (i < gNumLinkContestPlayers) + gLinkContestFlags |= LINK_CONTEST_FLAG_HAS_RS_PLAYER; + + SwitchTaskToFollowupFunc(taskId); +} + +bool32 sub_80FC670(s16 *arg0) +{ + if (gLinkContestFlags & LINK_CONTEST_FLAG_HAS_RS_PLAYER) + return TRUE; + + switch (*arg0) + { + case 0: + if (IsLinkTaskFinished()) + { + sub_800ADF8(); + (*arg0)++; + } + return FALSE; + case 1: + (*arg0)++; + return FALSE; + default: + if (IsLinkTaskFinished() != TRUE) + return FALSE; + else + return TRUE; + } +} + +void sub_80FC6BC(u8 taskId) +{ + int i; + + if (!sub_80FC670(&gTasks[taskId].data[12])) + return; + + switch (gTasks[taskId].data[0]) + { + case 0: + if (GetMultiplayerId() == 0) + { + if (IsLinkTaskFinished()) + { + memcpy(gBlockSendBuffer, &gContestMons[gContestPlayerMonIndex], sizeof(struct ContestPokemon)); + gTasks[taskId].data[0] = 10; + } + } + else + { + memcpy(gBlockSendBuffer, &gContestMons[gContestPlayerMonIndex], sizeof(struct ContestPokemon)); + gTasks[taskId].data[0] = 1; + } + break; + case 1: + if (sub_80FC55C()) + { + for (i = 0; i < gNumLinkContestPlayers; i++) + { + memcpy(&gContestMons[i], gBlockRecvBuffer[i], sizeof(struct ContestPokemon)); + sub_80DFA08(&gContestMons[i], gLinkPlayers[i].language); + } + + gTasks[taskId].data[0]++; + } + break; + case 10: + if (++gTasks[taskId].data[11] > 300) + { + sub_800A4D8(2); + gTasks[taskId].data[0] = 1; + } + break; + default: + gTasks[taskId].data[0] = 0; + gTasks[taskId].data[11] = 0; + gTasks[taskId].data[12] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + } +} + +void sub_80FC804(u8 taskId) +{ + switch (gTasks[taskId].data[0]) + { + case 0: + if (GetMultiplayerId() == 0) + { + if (IsLinkTaskFinished() && sub_80FC4F4(&gRngValue, sizeof(gRngValue)) == TRUE) + gTasks[taskId].data[0]++; + } + else + { + gTasks[taskId].data[0]++; + } + break; + case 1: + if (sub_80FC530(0)) + { + memcpy(&gRngValue, gBlockRecvBuffer[0], sizeof(gRngValue)); + memcpy(&gContestRngValue, gBlockRecvBuffer[0], sizeof(gContestRngValue)); + gTasks[taskId].data[0]++; + } + break; + default: + gTasks[taskId].data[0] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + } +} + +void sub_80FC894(u8 taskId) +{ + int i; + + if (!sub_80FC670(&gTasks[taskId].data[12])) + return; + + switch (gTasks[taskId].data[0]) + { + case 0: + gBlockSendBuffer[0] = gTasks[taskId].data[9]; + if (GetMultiplayerId() == 0) + { + if (IsLinkTaskFinished()) + gTasks[taskId].data[0] = 10; + } + else + { + gTasks[taskId].data[0]++; + } + break; + case 1: + if (sub_80FC55C()) + { + for (i = 0; i < gNumLinkContestPlayers; i++) + gTasks[taskId].data[i + 1] = gBlockRecvBuffer[i][0]; + + gTasks[taskId].data[0]++; + } + break; + case 10: + if (++gTasks[taskId].data[11] > 10) + { + sub_800A4D8(2); + gTasks[taskId].data[0] = 1; + } + break; + default: + gTasks[taskId].data[0] = 0; + gTasks[taskId].data[11] = 0; + gTasks[taskId].data[12] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + } +} + +void sub_80FC998(u8 taskId) +{ + switch (gTasks[taskId].data[0]) + { + case 0: + if (IsLinkTaskFinished()) + { + if (sub_80FC4F4(&gContestPlayerMonIndex, sizeof(gContestPlayerMonIndex)) == TRUE) + gTasks[taskId].data[0]++; + } + break; + case 1: + if (sub_80FC55C()) + gTasks[taskId].data[0]++; + break; + default: + gTasks[taskId].data[0] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + } +} + +void sub_80FC9F8(u8 taskId) +{ + int i; + + switch (gTasks[taskId].data[0]) + { + case 0: + if (IsLinkTaskFinished()) + { + if (sub_80FC4F4(&eContestantStatus[gContestPlayerMonIndex].currMove, sizeof(eContestantStatus[gContestPlayerMonIndex].currMove)) == TRUE) + gTasks[taskId].data[0]++; + } + break; + case 1: + if (sub_80FC55C()) + { + for (i = 0; i < gNumLinkContestPlayers; i++) + eContestantStatus[i].currMove = gBlockRecvBuffer[i][0]; + + gTasks[taskId].data[0]++; + } + break; + default: + gTasks[taskId].data[0] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + } +} + +void sub_80FCACC(u8 taskId) +{ + switch (gTasks[taskId].data[0]) + { + case 0: + if (IsLinkTaskFinished()) + { + if (sub_80FC4F4(gContestMonTotalPoints, sizeof(gContestMonTotalPoints)) == 1) + gTasks[taskId].data[0]++; + } + break; + case 1: + if (sub_80FC55C()) + { + memcpy(gContestMonTotalPoints, gBlockRecvBuffer[gUnknown_02039F2B], sizeof(gContestMonTotalPoints)); + gTasks[taskId].data[0]++; + } + break; + case 2: + case 5: + case 8: + case 11: + if (gTasks[taskId].data[1]++ > 10) + { + gTasks[taskId].data[1] = 0; + gTasks[taskId].data[0]++; + } + break; + case 3: + if (IsLinkTaskFinished()) + { + if (sub_80FC4F4(gUnknown_02039F10, sizeof(gUnknown_02039F10)) == 1) + gTasks[taskId].data[0]++; + } + break; + case 4: + if (sub_80FC55C()) + { + memcpy(gUnknown_02039F10, gBlockRecvBuffer[gUnknown_02039F2B], sizeof(gUnknown_02039F10)); + gTasks[taskId].data[0]++; + } + break; + case 6: + if (IsLinkTaskFinished()) + { + if (sub_80FC4F4(gContestMonRound2Points, sizeof(gContestMonRound2Points)) == 1) + gTasks[taskId].data[0]++; + } + break; + case 7: + if (sub_80FC55C()) + { + memcpy(gContestMonRound2Points, gBlockRecvBuffer[gUnknown_02039F2B], sizeof(gContestMonRound2Points)); + gTasks[taskId].data[0]++; + } + break; + case 9: + if (IsLinkTaskFinished()) + { + if (sub_80FC4F4(gContestFinalStandings, sizeof(gContestFinalStandings)) == 1) + gTasks[taskId].data[0]++; + } + break; + case 10: + if (sub_80FC55C()) + { + memcpy(gContestFinalStandings, gBlockRecvBuffer[gUnknown_02039F2B], sizeof(gContestFinalStandings)); + gTasks[taskId].data[0]++; + } + break; + default: + gTasks[taskId].data[0] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + } +} + +void sub_80FCC88(u8 taskId) +{ + switch (gTasks[taskId].data[0]) + { + case 0: + if (IsLinkTaskFinished()) + { + if (sub_80FC4F4(eContestantStatus, 4 * sizeof(struct ContestantStatus)) == 1) + gTasks[taskId].data[0]++; + } + break; + case 1: + if (sub_80FC55C()) + { + memcpy(eContestantStatus, gBlockRecvBuffer[gUnknown_02039F2B], 4 * sizeof(struct ContestantStatus)); + gTasks[taskId].data[0]++; + } + break; + case 2: + case 5: + case 8: + case 11: + if (gTasks[taskId].data[1]++ > 10) + { + gTasks[taskId].data[1] = 0; + gTasks[taskId].data[0]++; + } + break; + case 3: + if (IsLinkTaskFinished()) + { + if (sub_80FC4F4(gContestResources->field_8, sizeof(struct UnknownContestStruct7)) == 1) + gTasks[taskId].data[0]++; + } + break; + case 4: + if (sub_80FC55C()) + { + memcpy(gContestResources->field_8, gBlockRecvBuffer[gUnknown_02039F2B], sizeof(struct UnknownContestStruct7)); + gTasks[taskId].data[0]++; + } + break; + case 6: + if (IsLinkTaskFinished()) + { + if (sub_80FC4F4(gContestResources->field_10, sizeof(struct UnknownContestStruct5)) == 1) + gTasks[taskId].data[0]++; + } + break; + case 7: + if (sub_80FC55C()) + { + memcpy(gContestResources->field_10, gBlockRecvBuffer[gUnknown_02039F2B], sizeof(struct UnknownContestStruct5)); + gTasks[taskId].data[0]++; + } + break; + case 9: + if (IsLinkTaskFinished()) + { + if (sub_80FC4F4(gContestantTurnOrder, sizeof(gContestantTurnOrder)) == 1) + gTasks[taskId].data[0]++; + } + break; + case 10: + if (sub_80FC55C()) + { + memcpy(gContestantTurnOrder, gBlockRecvBuffer[gUnknown_02039F2B], sizeof(gContestantTurnOrder)); + gTasks[taskId].data[0]++; + } + break; + default: + gTasks[taskId].data[0] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + } +} + +void sub_80FCE48(u8 taskId) +{ + int i; + + if (!sub_80FC670(&gTasks[taskId].data[12])) + return; + + switch (gTasks[taskId].data[0]) + { + case 0: + gBlockSendBuffer[0] = 0x6E; + if (GetMultiplayerId() == 0) + { + if (IsLinkTaskFinished()) + gTasks[taskId].data[0] = 10; + } + else + { + gTasks[taskId].data[0]++; + } + break; + case 1: + if (sub_80FC55C()) + { + for (i = 0; i < 4; i++) + gTasks[taskId].data[i + 5] = gBlockRecvBuffer[i][0]; + + gTasks[taskId].data[0]++; + } + break; + case 10: + if (++gTasks[taskId].data[11] > 10) + { + sub_800A4D8(2); + gTasks[taskId].data[0] = 1; + } + break; + default: + gTasks[taskId].data[0] = 0; + gTasks[taskId].data[11] = 0; + gTasks[taskId].data[12] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + } +} + +void sub_80FCF40(u8 taskId) +{ + if (!sub_80FC670(&gTasks[taskId].data[12])) + return; + + switch (gTasks[taskId].data[0]) + { + case 0: + if (IsLinkTaskFinished()) + { + if (sub_80FC4F4(gContestMonConditions, sizeof(gContestMonConditions)) == 1) + gTasks[taskId].data[0]++; + } + break; + case 1: + if (sub_80FC55C()) + { + memcpy(gContestMonConditions, gBlockRecvBuffer[gUnknown_02039F2B], sizeof(gContestMonConditions)); + gTasks[taskId].data[0]++; + } + break; + default: + gTasks[taskId].data[0] = 0; + gTasks[taskId].data[12] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + } +} + +void sub_80FCFD0(u8 taskId) +{ + if (!sub_80FC670(&gTasks[taskId].data[12])) + return; + + switch (gTasks[taskId].data[0]) + { + case 0: + if (IsLinkTaskFinished()) + { + if (sub_80FC4F4(gContestantTurnOrder, sizeof(gContestantTurnOrder)) == 1) + gTasks[taskId].data[0]++; + } + break; + case 1: + if (sub_80FC55C()) + { + memcpy(gContestantTurnOrder, gBlockRecvBuffer[gUnknown_02039F2B], sizeof(gContestantTurnOrder)); + gTasks[taskId].data[0]++; + } + break; + default: + gTasks[taskId].data[0] = 0; + gTasks[taskId].data[12] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + } +} diff --git a/src/contest_link_80F57C4.c b/src/contest_link_80F57C4.c deleted file mode 100644 index 8434c3eac..000000000 --- a/src/contest_link_80F57C4.c +++ /dev/null @@ -1,2533 +0,0 @@ -#include "global.h" -#include "malloc.h" -#include "battle.h" -#include "battle_gfx_sfx_util.h" -#include "bg.h" -#include "contest.h" -#include "contest_link_80F57C4.h" -#include "contest_link_80FC4F4.h" -#include "data.h" -#include "decompress.h" -#include "dma3.h" -#include "event_data.h" -#include "field_specials.h" -#include "gpu_regs.h" -#include "graphics.h" -#include "international_string_util.h" -#include "link.h" -#include "link_rfu.h" -#include "load_save.h" -#include "main.h" -#include "overworld.h" -#include "palette.h" -#include "pokedex.h" -#include "pokemon.h" -#include "pokemon_icon.h" -#include "random.h" -#include "save.h" -#include "scanline_effect.h" -#include "script.h" -#include "sound.h" -#include "string_util.h" -#include "strings.h" -#include "task.h" -#include "text.h" -#include "trig.h" -#include "tv.h" -#include "util.h" -#include "window.h" -#include "constants/field_specials.h" -#include "constants/game_stat.h" -#include "constants/rgb.h" -#include "constants/songs.h" -#include "constants/tv.h" -#include "constants/vars.h" -#include "contest.h" - -enum { - SLIDING_TEXT_OFFSCREEN, - SLIDING_TEXT_ENTERING, - SLIDING_TEXT_ARRIVED, - SLIDING_TEXT_EXITING, -}; - -enum { - SLIDING_MON_ENTERED = 1, - SLIDING_MON_EXITED, -}; - -#define GET_CONTEST_WINNER_ID(i) { for ((i) = 0; (i) < CONTESTANT_COUNT && gContestFinalStandings[(i)] != 0; (i)++); } - -#define TAG_CONFETTI 3017 - -#define MAX_BAR_LENGTH 87 - -struct ContestResultsInternal -{ - u8 slidingTextBoxSpriteId; - u8 linkTextBoxSpriteId; - u8 showResultsTaskId; - u8 highlightWinnerTaskId; - u8 slidingTextBoxState; - u8 numStandingsPrinted; - u8 winnerMonSlidingState; - u8 confettiCount; - u8 winnerMonSpriteId; - bool8 destroyConfetti; - bool8 pointsFlashing; - s16 unkC[CONTESTANT_COUNT]; - u8 numBarsUpdating; -}; - -struct ContestMonResults -{ - int relativePreliminaryPoints; - int relativeRound2Points; - u32 barLengthPreliminary; - u32 barLengthRound2; - bool8 lostPoints; - u8 numStars; - u8 numHearts; -}; - -struct ContestResults -{ - struct ContestResultsInternal *data; - struct ContestMonResults (*monResults)[CONTESTANT_COUNT]; - u8 *unusedBg; // Allocated/freed, never used - u8 *tilemapBuffers[4]; - u8 *unused; // Allocated/freed, never used -}; - -static EWRAM_DATA struct ContestResults *sContestResults = NULL; - -static void LoadAllContestMonIconPalettes(void); -static void LoadContestResultsTilemaps(void); -static u8 GetNumPreliminaryPoints(u8, bool8); -static s8 GetNumRound2Points(u8, bool8); -static void AddContestTextPrinter(int, u8 *, int); -static void AllocContestResults(void); -static void FreeContestResults(void); -static void LoadAllContestMonIcons(u8, u8); -static void LoadContestResultSprites(void); -static void TryCreateWirelessSprites(void); -static void Task_StartShowContestResults(u8 taskId); -static void CB2_StartShowContestResults(void); -static void Task_ShowContestResults(u8); -static void CB2_ShowContestResults(void); -static void VBlankCB_ShowContestResults(void); -static void Task_SlideContestResultsBg(u8); -static void Task_WaitForLinkPartnersBeforeResults(u8); -static void sub_80F5F14(u8); -static void sub_80F5F30(u8); -static void Task_AnnouncePreliminaryResults(u8); -static void Task_FlashStarsAndHearts(u8); -static void Task_ShowPreliminaryResults(u8); -static void Task_AnnounceRound2Results(u8); -static void Task_ShowRound2Results(u8); -static void Task_AnnounceWinner(u8); -static void Task_DrawFinalStandingNumber(u8); -static void Task_StartHighlightWinnersBox(u8); -static void Task_HighlightWinnersBox(u8); -static void Task_ShowWinnerMonBanner(u8); -static void Task_SetSeenWinnerMon(u8); -static void Task_TryDisconnectLinkPartners(u8); -static void Task_WaitForLinkPartnersDisconnect(u8); -static void Task_TrySetContestInterviewData(u8); -static void Task_EndShowContestResults(u8); -static void CalculateContestantsResultData(void); -static void ShowLinkResultsTextBox(const u8 *); -static void HideLinkResultsTextBox(void); -static s32 DrawResultsTextWindow(const u8 *, u8); -static void StartTextBoxSlideIn(s16, u16, u16, u16); -static void UpdateContestResultBars(bool8, u8); -static void Task_UpdateContestResultBar(u8); -static void StartTextBoxSlideOut(u16); -static void BounceMonIconInBox(u8, u8); -static void Task_BounceMonIconInBox(u8); -static void SpriteCB_WinnerMonSlideIn(struct Sprite *); -static void SpriteCB_WinnerMonSlideOut(struct Sprite *); -static void Task_CreateConfetti(u8); -static void SpriteCB_TextBoxSlideIn(struct Sprite *); -static void SpriteCB_TextBoxSlideOut(struct Sprite *); -static void SpriteCB_EndTextBoxSlideIn(struct Sprite *); -static void sub_80F8508(u8); -static void sub_80F8568(u8); -static void sub_80F8584(u8); -static void sub_80F85A0(u8); -static void sub_80F85BC(u8); -static void sub_80F86B8(u8); -static void sub_80F878C(u8); -static void sub_80F87B4(u8); -static void SpriteCB_Confetti(struct Sprite *sprite); - -static const u16 sUnknown_0858D6B0[] = INCBIN_U16("graphics/unknown/unknown_58D6B0.gbapal"); -static const u8 sUnknown_0858D6D0[] = INCBIN_U8("graphics/unknown/unknown_58D6D0.4bpp"); -static const u16 sMiscBlank_Pal[] = INCBIN_U16("graphics/interface/blank.gbapal"); - -static const struct OamData sOamData_858D7F0 = -{ - .y = 0, - .affineMode = ST_OAM_AFFINE_OFF, - .objMode = ST_OAM_OBJ_NORMAL, - .mosaic = 0, - .bpp = ST_OAM_4BPP, - .shape = SPRITE_SHAPE(64x32), - .x = 0, - .matrixNum = 0, - .size = SPRITE_SIZE(64x32), - .tileNum = 0, - .priority = 3, - .paletteNum = 2, - .affineParam = 0, -}; - -static const struct SpriteTemplate sSpriteTemplate_858D7F8 = -{ - .tileTag = 3009, - .paletteTag = 3009, - .oam = &sOamData_858D7F0, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy -}; - -static const struct SpriteSheet sUnknown_0858D810[] = -{ - { .data = gMiscBlank_Gfx, .size = 0x400, .tag = 3009 }, - { .data = gMiscBlank_Gfx, .size = 0x400, .tag = 3010 }, - { .data = gMiscBlank_Gfx, .size = 0x400, .tag = 3011 }, - { .data = gMiscBlank_Gfx, .size = 0x400, .tag = 3012 }, - { .data = gMiscBlank_Gfx, .size = 0x400, .tag = 3013 }, - { .data = gMiscBlank_Gfx, .size = 0x400, .tag = 3014 }, - { .data = gMiscBlank_Gfx, .size = 0x400, .tag = 3015 }, - { .data = gMiscBlank_Gfx, .size = 0x400, .tag = 3016 }, -}; - -static const struct SpritePalette sUnknown_0858D850 = -{ - .data = sMiscBlank_Pal, - .tag = 3009, -}; - -static const struct OamData sOamData_Confetti = -{ - .y = 0, - .affineMode = ST_OAM_AFFINE_OFF, - .objMode = ST_OAM_OBJ_NORMAL, - .mosaic = 0, - .bpp = ST_OAM_4BPP, - .shape = SPRITE_SHAPE(8x8), - .x = 0, - .matrixNum = 0, - .size = SPRITE_SIZE(8x8), - .tileNum = 0, - .priority = 0, - .paletteNum = 0, - .affineParam = 0, -}; - -static const struct SpriteTemplate sSpriteTemplate_Confetti = -{ - .tileTag = TAG_CONFETTI, - .paletteTag = TAG_CONFETTI, - .oam = &sOamData_Confetti, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_Confetti -}; - -static const struct CompressedSpriteSheet sSpriteSheet_Confetti = -{ - .data = gConfetti_Gfx, - .size = 0x220, - .tag = TAG_CONFETTI -}; - - -static const struct CompressedSpritePalette sSpritePalette_Confetti = -{ - .data = gConfetti_Pal, - .tag = TAG_CONFETTI -}; - -static const struct BgTemplate sBgTemplates[] = -{ - { - .bg = 0, - .charBaseIndex = 0, - .mapBaseIndex = 30, - .screenSize = 0, - .paletteMode = 0, - .priority = 0, - .baseTile = 0, - }, - { - .bg = 1, - .charBaseIndex = 0, - .mapBaseIndex = 24, - .screenSize = 0, - .paletteMode = 0, - .priority = 3, - .baseTile = 0, - }, - { - .bg = 2, - .charBaseIndex = 0, - .mapBaseIndex = 28, - .screenSize = 0, - .paletteMode = 0, - .priority = 3, - .baseTile = 0, - }, - { - .bg = 3, - .charBaseIndex = 0, - .mapBaseIndex = 26, - .screenSize = 0, - .paletteMode = 0, - .priority = 3, - .baseTile = 0, - } -}; - -static const struct WindowTemplate sWindowTemplates[] = -{ - { - .bg = 1, - .tilemapLeft = 7, - .tilemapTop = 4, - .width = 12, - .height = 2, - .paletteNum = 15, - .baseBlock = 770 - }, - { - .bg = 1, - .tilemapLeft = 7, - .tilemapTop = 7, - .width = 12, - .height = 2, - .paletteNum = 15, - .baseBlock = 794 - }, - { - .bg = 1, - .tilemapLeft = 7, - .tilemapTop = 10, - .width = 12, - .height = 2, - .paletteNum = 15, - .baseBlock = 818 - }, - { - .bg = 1, - .tilemapLeft = 7, - .tilemapTop = 13, - .width = 12, - .height = 2, - .paletteNum = 15, - .baseBlock = 842 - }, - DUMMY_WIN_TEMPLATE, -}; - -static const struct OamData sUnknown_0858D8C0 = -{ - .y = 0, - .affineMode = ST_OAM_AFFINE_OFF, - .objMode = ST_OAM_OBJ_NORMAL, - .mosaic = 0, - .bpp = ST_OAM_4BPP, - .shape = SPRITE_SHAPE(16x16), - .x = 0, - .matrixNum = 0, - .size = SPRITE_SIZE(16x16), - .tileNum = 0, - .priority = 0, - .paletteNum = 0, - .affineParam = 0, -}; - - -static const struct SpriteTemplate sSpriteTemplate_858D8C8 = -{ - .tileTag = 22222, - .paletteTag = 0, - .oam = &sUnknown_0858D8C0, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy -}; - -static const struct SpriteSheet sUnknown_0858D8E0 = -{ - .data = gMiscBlank_Gfx, - .size = 0x200, - .tag = 22222 -}; - -static const u8 sContestLinkTextColors[4] = {TEXT_COLOR_WHITE, TEXT_DYNAMIC_COLOR_6, TEXT_DYNAMIC_COLOR_5}; - - -static void InitContestResultsDisplay(void) -{ - int i; - - SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP); - ResetBgsAndClearDma3BusyFlags(0); - InitBgsFromTemplates(0, sBgTemplates, ARRAY_COUNT(sBgTemplates)); - for (i = 0; i < (int)ARRAY_COUNT(sContestResults->tilemapBuffers); i++) - SetBgTilemapBuffer(i, sContestResults->tilemapBuffers[i]); - - InitWindows(sWindowTemplates); - DeactivateAllTextPrinters(); - SetGpuReg(REG_OFFSET_MOSAIC, 0); - SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR); - SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG1 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR); - SetGpuReg(REG_OFFSET_WIN0H, 0); - SetGpuReg(REG_OFFSET_WIN0V, 0); - SetGpuReg(REG_OFFSET_WIN1H, 0); - SetGpuReg(REG_OFFSET_WIN1V, 0); - SetGpuReg(REG_OFFSET_BLDCNT, 0); - SetGpuReg(REG_OFFSET_BLDALPHA, 0); - SetGpuReg(REG_OFFSET_BLDY, 0); - SetGpuReg(REG_OFFSET_BG0HOFS, 0); - SetGpuReg(REG_OFFSET_BG0VOFS, 0); - SetGpuReg(REG_OFFSET_BG1HOFS, 0); - SetGpuReg(REG_OFFSET_BG1VOFS, 0); - SetGpuReg(REG_OFFSET_BG2HOFS, 0); - SetGpuReg(REG_OFFSET_BG2VOFS, 0); - SetGpuReg(REG_OFFSET_BG3HOFS, 0); - SetGpuReg(REG_OFFSET_BG3VOFS, 0); - SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG_ALL_ON | DISPCNT_OBJ_ON | DISPCNT_WIN0_ON | DISPCNT_WIN1_ON | DISPCNT_OBJWIN_ON); - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - gBattle_BG1_X = 0; - gBattle_BG1_Y = 0; - gBattle_BG2_X = 0; - gBattle_BG2_Y = 0; - gBattle_BG3_X = 0; - gBattle_BG3_Y = 0; - gBattle_WIN0H = 0; - gBattle_WIN0V = 0; - gBattle_WIN1H = 0; - gBattle_WIN1V = 0; -} - -static void LoadContestResultsBgGfx(void) -{ - int i, j; - s8 numStars, round2Points; - u16 tile1, tile2; - - LZDecompressVram(gContestResults_Gfx, (void *)BG_CHAR_ADDR(0)); - CopyToBgTilemapBuffer(3, gUnknown_08C1A12C, 0, 0); - CopyToBgTilemapBuffer(2, gUnknown_08C1A000, 0, 0); - CopyToBgTilemapBuffer(0, gUnknown_08C19EEC, 0, 0); - LoadContestResultsTilemaps(); - LoadCompressedPalette(gContestResults_Pal, 0, 0x200); - LoadPalette(sUnknown_0858D6B0, 0xF0, 0x20); - - for (i = 0; i < CONTESTANT_COUNT; i++) - { - numStars = GetNumPreliminaryPoints(i, TRUE); - round2Points = GetNumRound2Points(i, TRUE); - for (j = 0; j < 10; j++) - { - tile1 = 0x60B2; - if (j < numStars) - tile1 += 2; - - // Abs of round2Points is number of hearts - if (j < abs(round2Points)) - { - tile2 = 0x60A4; - if (round2Points < 0) - tile2 += 2; - } - else - { - tile2 = 0x60A2; - } - - FillBgTilemapBufferRect_Palette0(1, tile1, j + 19, i * 3 + 5, 1, 1); - FillBgTilemapBufferRect_Palette0(1, tile2, j + 19, i * 3 + 6, 1, 1); - } - } - - CopyBgTilemapBufferToVram(0); - CopyBgTilemapBufferToVram(1); - CopyBgTilemapBufferToVram(2); - CopyBgTilemapBufferToVram(3); - ShowBg(0); - ShowBg(1); - ShowBg(2); - ShowBg(3); -} - -static void LoadContestMonName(u8 monIndex) -{ - struct ContestPokemon *mon = &gContestMons[monIndex]; - u8 *str = gDisplayedStringBattle; - if (monIndex == gContestPlayerMonIndex) - str = StringCopy(gDisplayedStringBattle, gText_ColorDarkGrey); - - StringCopy(str, mon->nickname); - AddContestTextPrinter(monIndex, gDisplayedStringBattle, 0); - StringCopy(str, gText_Slash); - StringAppend(str, mon->trainerName); - AddContestTextPrinter(monIndex, gDisplayedStringBattle, 50); -} - -static void LoadAllContestMonNames(void) -{ - int i; - - for (i = 0; i < CONTESTANT_COUNT; i++) - LoadContestMonName(i); - - CopyBgTilemapBufferToVram(1); -} - -static void CB2_StartShowContestResults(void) -{ - gPaletteFade.bufferTransferDisabled = TRUE; - SetVBlankCallback(NULL); - AllocContestResults(); - InitContestResultsDisplay(); - ScanlineEffect_Clear(); - ResetPaletteFade(); - ResetSpriteData(); - ResetTasks(); - FreeAllSpritePalettes(); - LoadContestResultsBgGfx(); - LoadAllContestMonIconPalettes(); - LoadAllContestMonIcons(0, TRUE); - LoadAllContestMonNames(); - memset(sContestResults->data, 0, sizeof(*sContestResults->data)); - memset(sContestResults->monResults, 0, sizeof(*sContestResults->monResults)); - LoadContestResultSprites(); - TryCreateWirelessSprites(); - BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK); - gPaletteFade.bufferTransferDisabled = FALSE; - sContestResults->data->showResultsTaskId = CreateTask(Task_ShowContestResults, 5); - SetMainCallback2(CB2_ShowContestResults); - gBattle_WIN1H = 0x00F0; - gBattle_WIN1V = 0x80A0; - CreateTask(Task_SlideContestResultsBg, 20); - CalculateContestantsResultData(); - if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_WIRELESS) - gPaletteFade.bufferTransferDisabled = TRUE; - else - PlayBGM(MUS_CON_K); - - SetVBlankCallback(VBlankCB_ShowContestResults); -} - -static void CB2_ShowContestResults(void) -{ - AnimateSprites(); - BuildOamBuffer(); - RunTasks(); - UpdatePaletteFade(); - CopyBgTilemapBufferToVram(1); - CopyBgTilemapBufferToVram(2); -} - -static void VBlankCB_ShowContestResults(void) -{ - SetGpuReg(REG_OFFSET_BG0HOFS, gBattle_BG0_X); - SetGpuReg(REG_OFFSET_BG0VOFS, gBattle_BG0_Y); - SetGpuReg(REG_OFFSET_BG1HOFS, gBattle_BG1_X); - SetGpuReg(REG_OFFSET_BG1VOFS, gBattle_BG1_Y); - SetGpuReg(REG_OFFSET_BG2HOFS, gBattle_BG2_X); - SetGpuReg(REG_OFFSET_BG2VOFS, gBattle_BG2_Y); - SetGpuReg(REG_OFFSET_BG3HOFS, gBattle_BG3_X); - SetGpuReg(REG_OFFSET_BG3VOFS, gBattle_BG3_Y); - SetGpuReg(REG_OFFSET_WIN0H, gBattle_WIN0H); - SetGpuReg(REG_OFFSET_WIN0V, gBattle_WIN0V); - SetGpuReg(REG_OFFSET_WIN1H, gBattle_WIN1H); - SetGpuReg(REG_OFFSET_WIN1V, gBattle_WIN1V); - LoadOam(); - ProcessSpriteCopyRequests(); - TransferPlttBuffer(); - ScanlineEffect_InitHBlankDmaTransfer(); -} - -#define tState data[0] -#define tTimer data[1] -#define tCounter data[2] - -static void Task_ShowContestResults(u8 taskId) -{ - u16 var; - - if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK) - { - switch (gTasks[taskId].tState) - { - case 0: - SaveLinkContestResults(); - if (gContestFinalStandings[gContestPlayerMonIndex] == 0) - { - IncrementGameStat(GAME_STAT_WON_LINK_CONTEST); - gSpecialVar_0x8005 = TVSHOW_CONTEST_LIVE_UPDATES; - InterviewBefore(); - if (gSpecialVar_Result != TRUE) - InterviewAfter(); - } - - TryGainNewFanFromCounter(FANCOUNTER_FINISHED_CONTEST); - sub_80DEDA8(gSpecialVar_ContestRank); - sub_80DEDA8(0xFE); - gUnknown_02039F5C = TRUE; - gUnknown_02039F5D = sub_80DEFA8(0xFE, 0); - var = VarGet(VAR_CONTEST_HALL_STATE); - VarSet(VAR_CONTEST_HALL_STATE, 0); - SetContinueGameWarpStatusToDynamicWarp(); - TrySavingData(SAVE_LINK); - ClearContinueGameWarpStatus2(); - VarSet(VAR_CONTEST_HALL_STATE, var); - gTasks[taskId].tState++; - break; - case 1: - gTasks[taskId].tState++; - if (!(gLinkContestFlags & LINK_CONTEST_FLAG_IS_WIRELESS)) - gTasks[taskId].tState = 100; - break; - case 2: - if (IsLinkTaskFinished()) - { - sub_800ADF8(); - gTasks[taskId].tState++; - } - return; - case 3: - if (IsLinkTaskFinished() == TRUE) - { - PlayBGM(MUS_CON_K); - gPaletteFade.bufferTransferDisabled = FALSE; - gTasks[taskId].tState++; - break; - } - return; - } - } - - if (!gPaletteFade.active) - { - gTasks[taskId].tState = 0; - if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK) - { - ShowLinkResultsTextBox(gText_CommunicationStandby); - gTasks[taskId].func = Task_WaitForLinkPartnersBeforeResults; - } - else - { - IncrementGameStat(GAME_STAT_ENTERED_CONTEST); - if (gContestFinalStandings[gContestPlayerMonIndex] == 0) - IncrementGameStat(GAME_STAT_WON_CONTEST); - - sub_80DEDA8(gSpecialVar_ContestRank); - sub_80DEDA8(0xFE); - gUnknown_02039F5C = TRUE; - gUnknown_02039F5D = sub_80DEFA8(0xFE, 0); - TryGainNewFanFromCounter(FANCOUNTER_FINISHED_CONTEST); - gTasks[taskId].func = Task_AnnouncePreliminaryResults; - } - } -} - -static void Task_WaitForLinkPartnersBeforeResults(u8 taskId) -{ - if (gReceivedRemoteLinkPlayers) - { - CreateTask(sub_80F5F14, 0); - gTasks[taskId].func = TaskDummy; - } -} - -static void sub_80F5F14(u8 taskId) -{ - SetTaskFuncWithFollowupFunc(taskId, sub_80FC998, sub_80F5F30); -} - -static void sub_80F5F30(u8 taskId) -{ - if (IsLinkTaskFinished()) - { - DestroyTask(taskId); - gTasks[sContestResults->data->showResultsTaskId].func = Task_AnnouncePreliminaryResults; - HideLinkResultsTextBox(); - } -} - -static void Task_AnnouncePreliminaryResults(u8 taskId) -{ - s16 x; - - if (gTasks[taskId].tState == 0) - { - CreateTask(Task_FlashStarsAndHearts, 20); - x = DrawResultsTextWindow(gText_AnnouncingResults, sContestResults->data->slidingTextBoxSpriteId); - StartTextBoxSlideIn(x, 144, 120, 1088); - gTasks[taskId].tState++; - } - else if (gTasks[taskId].tState == 1) - { - // Wait for "Announcing Results" text to leave - if (sContestResults->data->slidingTextBoxState == SLIDING_TEXT_OFFSCREEN) - { - gTasks[taskId].tTimer = 0; - gTasks[taskId].tState++; - } - } - else if (gTasks[taskId].tState == 2) - { - if (++gTasks[taskId].tTimer == 21) - { - gTasks[taskId].tTimer = 0; - gTasks[taskId].tState++; - } - } - else if (gTasks[taskId].tState == 3) - { - x = DrawResultsTextWindow(gText_PreliminaryResults, sContestResults->data->slidingTextBoxSpriteId); - StartTextBoxSlideIn(x, 144, -1, 1088); - gTasks[taskId].tState++; - } - else if (gTasks[taskId].tState == 4) - { - if (sContestResults->data->slidingTextBoxState == SLIDING_TEXT_ARRIVED) - { - gTasks[taskId].tState = 0; - gTasks[taskId].func = Task_ShowPreliminaryResults; - } - } -} - -static void Task_ShowPreliminaryResults(u8 taskId) -{ - switch (gTasks[taskId].tState) - { - case 0: - if (!sContestResults->data->pointsFlashing) - { - UpdateContestResultBars(FALSE, gTasks[taskId].tCounter++); - if (sContestResults->data->numBarsUpdating == 0) - gTasks[taskId].tState = 2; - else - gTasks[taskId].tState++; - } - break; - case 1: - if (sContestResults->data->numBarsUpdating == 0) - gTasks[taskId].tState = 0; - break; - case 2: - StartTextBoxSlideOut(1088); - gTasks[taskId].tState = 0; - gTasks[taskId].tCounter = 0; - gTasks[taskId].func = Task_AnnounceRound2Results; - break; - } -} - -static void Task_AnnounceRound2Results(u8 taskId) -{ - s16 x; - - if (sContestResults->data->slidingTextBoxState == SLIDING_TEXT_OFFSCREEN) - { - if (++gTasks[taskId].tTimer == 21) - { - gTasks[taskId].tTimer = 0; - x = DrawResultsTextWindow(gText_Round2Results, sContestResults->data->slidingTextBoxSpriteId); - StartTextBoxSlideIn(x, 144, -1, 1088); - } - } - else if (sContestResults->data->slidingTextBoxState == SLIDING_TEXT_ARRIVED) - { - gTasks[taskId].func = Task_ShowRound2Results; - } -} - -static void Task_ShowRound2Results(u8 taskId) -{ - switch (gTasks[taskId].tState) - { - case 0: - if (!sContestResults->data->pointsFlashing) - { - UpdateContestResultBars(TRUE, gTasks[taskId].tCounter++); - if (sContestResults->data->numBarsUpdating == 0) - gTasks[taskId].tState = 2; - else - gTasks[taskId].tState++; - } - break; - case 1: - if (sContestResults->data->numBarsUpdating == 0) - gTasks[taskId].tState = 0; - break; - case 2: - StartTextBoxSlideOut(1088); - gTasks[taskId].tState = 0; - gTasks[taskId].func = Task_AnnounceWinner; - break; - } -} - -// Task data for Task_DrawFinalStandingNumber -#define tFinalStanding data[0] -#define tMonIndex data[1] - -static void Task_AnnounceWinner(u8 taskId) -{ - int i; - switch (gTasks[taskId].tState) - { - case 0: - if (sContestResults->data->slidingTextBoxState == SLIDING_TEXT_OFFSCREEN) - gTasks[taskId].tState++; - break; - case 1: - if (++gTasks[taskId].tTimer == 31) - { - gTasks[taskId].tTimer = 0; - gTasks[taskId].tState++; - } - break; - case 2: - for (i = 0; i < CONTESTANT_COUNT; i++) - { - u8 newTaskId = CreateTask(Task_DrawFinalStandingNumber, 10); - gTasks[newTaskId].tFinalStanding = gContestFinalStandings[i]; - gTasks[newTaskId].tMonIndex = i; - } - gTasks[taskId].tState++; - break; - case 3: - if (sContestResults->data->numStandingsPrinted == CONTESTANT_COUNT) - { - if (++gTasks[taskId].tTimer == 31) - { - gTasks[taskId].tTimer = 0; - CreateTask(Task_StartHighlightWinnersBox, 10); - gTasks[taskId].tState++; - GET_CONTEST_WINNER_ID(i); - BounceMonIconInBox(i, 14); - } - } - break; - case 4: - if (++gTasks[taskId].tTimer == 21) - { - u8 winnerTextBuffer[100]; - s16 x; - gTasks[taskId].tTimer = 0; - GET_CONTEST_WINNER_ID(i); - StringCopy(gStringVar1, gContestMons[i].trainerName); - sub_81DB5AC(gStringVar1); - StringCopy(gStringVar2, gContestMons[i].nickname); - StringExpandPlaceholders(winnerTextBuffer, gText_ContestantsMonWon); - x = DrawResultsTextWindow(winnerTextBuffer, sContestResults->data->slidingTextBoxSpriteId); - StartTextBoxSlideIn(x, 144, -1, 1088); - gTasks[taskId].tState++; - } - break; - case 5: - gTasks[taskId].tState = 0; - gTasks[taskId].func = Task_ShowWinnerMonBanner; - break; - } -} - -static void Task_ShowWinnerMonBanner(u8 taskId) -{ - int i; - u8 spriteId; - u16 species; - u32 otId; - u32 personality; - const struct CompressedSpritePalette *pokePal; - - switch (gTasks[taskId].tState) - { - case 0: - gBattle_WIN0H = 0x00F0; - gBattle_WIN0V = 0x5050; - - GET_CONTEST_WINNER_ID(i); - species = gContestMons[i].species; - personality = gContestMons[i].personality; - otId = gContestMons[i].otId; - if (i == gContestPlayerMonIndex) - { - HandleLoadSpecialPokePic_2( - &gMonFrontPicTable[species], - gMonSpritesGfxPtr->sprites[1], - species, - personality); - } - else - { - HandleLoadSpecialPokePic_DontHandleDeoxys( - &gMonFrontPicTable[species], - gMonSpritesGfxPtr->sprites[1], - species, - personality); - } - - pokePal = GetMonSpritePalStructFromOtIdPersonality(species, otId, personality); - LoadCompressedSpritePalette(pokePal); - SetMultiuseSpriteTemplateToPokemon(species, B_POSITION_OPPONENT_LEFT); - gMultiuseSpriteTemplate.paletteTag = pokePal->tag; - spriteId = CreateSprite(&gMultiuseSpriteTemplate, 272, 80, 10); - gSprites[spriteId].data[1] = species; - gSprites[spriteId].oam.priority = 0; - gSprites[spriteId].callback = SpriteCB_WinnerMonSlideIn; - sContestResults->data->winnerMonSpriteId = spriteId; - LoadCompressedSpriteSheet(&sSpriteSheet_Confetti); - LoadCompressedSpritePalette(&sSpritePalette_Confetti); - CreateTask(Task_CreateConfetti, 10); - gTasks[taskId].tState++; - break; - case 1: - if (++gTasks[taskId].data[3] == 1) - { - u8 counter; - gTasks[taskId].data[3] = 0; - gTasks[taskId].tCounter += 2; - if (gTasks[taskId].tCounter > 32) - gTasks[taskId].tCounter = 32; - - counter = gTasks[taskId].tCounter; - gBattle_WIN0V = ((80 - counter) << 8) | (80 + counter); - if (counter == 32) - gTasks[taskId].tState++; - } - break; - case 2: - if (sContestResults->data->winnerMonSlidingState == SLIDING_MON_ENTERED) - gTasks[taskId].tState++; - break; - case 3: - if (++gTasks[taskId].tTimer == 121) - { - gTasks[taskId].tTimer = 0; - gSprites[sContestResults->data->winnerMonSpriteId].callback = SpriteCB_WinnerMonSlideOut; - gTasks[taskId].tState++; - } - break; - case 4: - if (sContestResults->data->winnerMonSlidingState == SLIDING_MON_EXITED) - { - u8 top = (gBattle_WIN0V >> 8); - top += 2; - if (top > 80) - top = 80; - - gBattle_WIN0V = (top << 8) | (160 - top); - if (top == 80) - gTasks[taskId].tState++; - } - break; - case 5: - if (sContestResults->data->winnerMonSlidingState == SLIDING_MON_EXITED) - { - sContestResults->data->destroyConfetti = TRUE; - gTasks[taskId].tState = 0; - gTasks[taskId].func = Task_SetSeenWinnerMon; - } - break; - } -} - -static void Task_SetSeenWinnerMon(u8 taskId) -{ - int i, nationalDexNum; - - if (JOY_NEW(A_BUTTON)) - { - if (!(gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK)) - { - for (i = 0; i < CONTESTANT_COUNT; i++) - { - nationalDexNum = SpeciesToNationalPokedexNum(gContestMons[i].species); - GetSetPokedexFlag(nationalDexNum, FLAG_SET_SEEN); - } - } - - gTasks[taskId].data[10] = 0; - gTasks[taskId].func = Task_TryDisconnectLinkPartners; - } -} - -static void Task_TryDisconnectLinkPartners(u8 taskId) -{ - if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK) - { - if (!gTasks[taskId].data[10]) - { - ShowLinkResultsTextBox(gText_CommunicationStandby); - sub_800AC34(); - gTasks[taskId].func = Task_WaitForLinkPartnersDisconnect; - } - } - else - { - gTasks[taskId].func = Task_TrySetContestInterviewData; - } -} - -static void Task_WaitForLinkPartnersDisconnect(u8 taskId) -{ - if (!gReceivedRemoteLinkPlayers) - { - if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_WIRELESS) - DestroyWirelessStatusIndicatorSprite(); - - HideLinkResultsTextBox(); - gTasks[taskId].func = Task_TrySetContestInterviewData; - } -} - -static void Task_TrySetContestInterviewData(u8 taskId) -{ - if (!(gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK)) - BravoTrainerPokemonProfile_BeforeInterview2(gContestFinalStandings[gContestPlayerMonIndex]); - - BeginHardwarePaletteFade(0xFF, 0, 0, 16, 0); - gTasks[taskId].func = Task_EndShowContestResults; -} - -static void Task_EndShowContestResults(u8 taskId) -{ - if (!gPaletteFade.active) - { - if (gTasks[taskId].tTimer == 0) - { - DestroyTask(sContestResults->data->highlightWinnerTaskId); - BlendPalettes(0x0000FFFF, 16, RGB_BLACK); - gTasks[taskId].tTimer++; - } - else if (gTasks[taskId].tTimer == 1) - { - BlendPalettes(0xFFFF0000, 16, RGB_BLACK); - gTasks[taskId].tTimer++; - } - else - { - SetGpuReg(REG_OFFSET_BLDCNT, 0); - SetGpuReg(REG_OFFSET_BLDY, 0); - DestroyTask(taskId); - FreeAllWindowBuffers(); - SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic); - FreeContestResults(); - } - } -} - -#undef tState -#undef tTimer -#undef tCounter - -static void Task_SlideContestResultsBg(u8 taskId) -{ - gBattle_BG3_X += 2; - gBattle_BG3_Y += 1; - if (gBattle_BG3_X > 255) - gBattle_BG3_X -= 255; - if (gBattle_BG3_Y > 255) - gBattle_BG3_Y -= 255; -} - -#define tDelay data[0] -#define tCoeff data[1] -#define tDecreasing data[2] - -static void Task_FlashStarsAndHearts(u8 taskId) -{ - if (++gTasks[taskId].tDelay == 2) - { - gTasks[taskId].tDelay = 0; - if (!gTasks[taskId].tDecreasing) - gTasks[taskId].tCoeff++; - else - gTasks[taskId].tCoeff--; - - if (gTasks[taskId].tCoeff == 16) - gTasks[taskId].tDecreasing = TRUE; - else if (gTasks[taskId].tCoeff == 0) - gTasks[taskId].tDecreasing = FALSE; - - BlendPalette(0x6B, 1, gTasks[taskId].tCoeff, RGB(30, 22, 11)); - BlendPalette(0x68, 1, gTasks[taskId].tCoeff, RGB_WHITE); - BlendPalette(0x6E, 1, gTasks[taskId].tCoeff, RGB(30, 29, 29)); - } - - if (gTasks[taskId].tCoeff == 0) - sContestResults->data->pointsFlashing = FALSE; - else - sContestResults->data->pointsFlashing = TRUE; -} - -static void LoadContestMonIcon(u16 species, u8 monIndex, u8 srcOffset, u8 useDmaNow, u32 personality) -{ - const u8 *iconPtr; - u16 var0, var1, frameNum; - - if (monIndex == gContestPlayerMonIndex) - frameNum = 1; - else - frameNum = 0; - - iconPtr = GetMonIconPtr(species, personality, frameNum); - iconPtr += srcOffset * 0x200 + 0x80; - if (useDmaNow) - { - RequestDma3Copy(iconPtr, (void *)BG_CHAR_ADDR(1) + monIndex * 0x200, 0x180, 1); - var0 = ((monIndex + 10) << 12); - var1 = (monIndex * 0x10 + 0x200); - WriteSequenceToBgTilemapBuffer(1, var1 | var0, 3, monIndex * 3 + 4, 4, 3, 17, 1); - } - else - { - RequestDma3Copy(iconPtr, (void *)BG_CHAR_ADDR(1) + monIndex * 0x200, 0x180, 1); - } -} - -static void LoadAllContestMonIcons(u8 srcOffset, bool8 useDmaNow) -{ - int i; - - for (i = 0; i < CONTESTANT_COUNT; i++) - LoadContestMonIcon(gContestMons[i].species, i, srcOffset, useDmaNow, gContestMons[i].personality); -} - -static void LoadAllContestMonIconPalettes(void) -{ - int i, species; - - for (i = 0; i < CONTESTANT_COUNT; i++) - { - species = gContestMons[i].species; - LoadPalette(gMonIconPalettes[gMonIconPaletteIndices[GetIconSpecies(species, 0)]], i * 0x10 + 0xA0, 0x20); - } -} - -static void TryCreateWirelessSprites(void) -{ - u16 sheet; - u8 spriteId; - - if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_WIRELESS) - { - LoadWirelessStatusIndicatorSpriteGfx(); - CreateWirelessStatusIndicatorSprite(8, 8); - gSprites[gWirelessStatusIndicatorSpriteId].subpriority = 1; - sheet = LoadSpriteSheet(&sUnknown_0858D8E0); - RequestDma3Fill(0xFFFFFFFF, (void *)BG_CHAR_ADDR(4) + sheet * 0x20, 0x80, 1); - spriteId = CreateSprite(&sSpriteTemplate_858D8C8, 8, 8, 0); - gSprites[spriteId].oam.objMode = ST_OAM_OBJ_WINDOW; - } -} - -// Functionally equivalent, the same except compiler generated variables from -// src are placed on different stack positions. - -#ifdef NONMATCHING -static s32 DrawResultsTextWindow(const u8 *text, u8 spriteId) -{ - u8 *windowTilesPtr; - u16 windowId; - int origWidth; - struct WindowTemplate windowTemplate; - int strWidth; - u8 *spriteTilePtrs[4]; - u8 *dst; - int i; - struct Sprite *sprite; - const u8 *src; // The culprit. - - memset(&windowTemplate, 0, sizeof(windowTemplate)); - windowTemplate.width = 30; - windowTemplate.height = 2; - windowId = AddWindow(&windowTemplate); - FillWindowPixelBuffer(windowId, PIXEL_FILL(1)); - - origWidth = GetStringWidth(1, text, 0); - strWidth = (origWidth + 9) / 8; - if (strWidth > 30) - strWidth = 30; - - AddTextPrinterParameterized3(windowId, 1, (strWidth * 8 - origWidth) / 2, 1, sContestLinkTextColors, -1, text); - windowTilesPtr = (u8 *)(GetWindowAttribute(windowId, WINDOW_TILE_DATA)); - src = (u8 *)(sUnknown_0858D6D0); - - sprite = &gSprites[spriteId]; - spriteTilePtrs[0] = (u8 *)(sprite->oam.tileNum * 32 + VRAM + 0x10000); - - for (i = 1; i < 4; i++) - spriteTilePtrs[i] = (void*)(gSprites[sprite->data[i - 1]].oam.tileNum * 32 + VRAM + 0x10000); - - for (i = 0; i < 4; i++) - CpuFill32(0, spriteTilePtrs[i], 0x400); - - dst = spriteTilePtrs[0]; - CpuCopy32(src, dst, 0x20); - CpuCopy32(src + 128, dst + 0x100, 0x20); - CpuCopy32(src + 128, dst + 0x200, 0x20); - CpuCopy32(src + 64, dst + 0x300, 0x20); - - for (i = 0; i < strWidth; i++) - { - dst = &spriteTilePtrs[(i + 1) / 8][((i + 1) % 8) * 32]; - CpuCopy32(src + 192, dst, 0x20); - CpuCopy32(windowTilesPtr, dst + 0x100, 0x20); - CpuCopy32(windowTilesPtr + 960, dst + 0x200, 0x20); - CpuCopy32(src + 224, dst + 0x300, 0x20); - windowTilesPtr += 0x20; - } - - dst = &spriteTilePtrs[(i + 1) / 8][((i + 1) % 8) * 32]; - CpuCopy32(src + 32, dst, 0x20); - CpuCopy32(src + 160, dst + 0x100, 0x20); - CpuCopy32(src + 160, dst + 0x200, 0x20); - CpuCopy32(src + 96, dst + 0x300, 0x20); - RemoveWindow(windowId); - - return (240 - (strWidth + 2) * 8) / 2; -} - -#else -NAKED -static s32 DrawResultsTextWindow(const u8 *text, u8 spriteId) -{ - asm_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, 0x44\n\ - adds r5, r0, 0\n\ - lsls r1, 24\n\ - lsrs r7, r1, 24\n\ - add r4, sp, 0x20\n\ - adds r0, r4, 0\n\ - movs r1, 0\n\ - movs r2, 0x8\n\ - bl memset\n\ - movs r0, 0x1E\n\ - strb r0, [r4, 0x3]\n\ - movs r0, 0x2\n\ - strb r0, [r4, 0x4]\n\ - adds r0, r4, 0\n\ - bl AddWindow\n\ - lsls r6, r0, 24\n\ - lsrs r4, r6, 24\n\ - adds r0, r4, 0\n\ - movs r1, 0x11\n\ - bl FillWindowPixelBuffer\n\ - movs r0, 0x1\n\ - adds r1, r5, 0\n\ - movs r2, 0\n\ - bl GetStringWidth\n\ - adds r2, r0, 0\n\ - adds r2, 0x9\n\ - cmp r2, 0\n\ - bge _080F6BC4\n\ - adds r2, 0x7\n\ -_080F6BC4:\n\ - asrs r2, 3\n\ - mov r10, r2\n\ - cmp r2, 0x1E\n\ - ble _080F6BD0\n\ - movs r1, 0x1E\n\ - mov r10, r1\n\ -_080F6BD0:\n\ - mov r1, r10\n\ - lsls r2, r1, 3\n\ - subs r2, r0\n\ - lsrs r0, r2, 31\n\ - adds r2, r0\n\ - asrs r2, 1\n\ - lsls r2, 24\n\ - lsrs r2, 24\n\ - ldr r0, =sContestLinkTextColors\n\ - str r0, [sp]\n\ - movs r0, 0x1\n\ - negs r0, r0\n\ - str r0, [sp, 0x4]\n\ - str r5, [sp, 0x8]\n\ - adds r0, r4, 0\n\ - movs r1, 0x1\n\ - movs r3, 0x1\n\ - bl AddTextPrinterParameterized3\n\ - adds r0, r4, 0\n\ - movs r1, 0x7\n\ - bl GetWindowAttribute\n\ - mov r9, r0\n\ - ldr r2, =sUnknown_0858D6D0\n\ - mov r8, r2\n\ - lsls r1, r7, 4\n\ - adds r1, r7\n\ - lsls r1, 2\n\ - ldr r3, =gSprites\n\ - adds r1, r3\n\ - ldrh r0, [r1, 0x4]\n\ - lsls r0, 22\n\ - lsrs r0, 17\n\ - ldr r2, =0x06010000\n\ - adds r0, r2\n\ - str r0, [sp, 0xC]\n\ - str r6, [sp, 0x38]\n\ - mov r7, sp\n\ - adds r7, 0x1C\n\ - str r7, [sp, 0x2C]\n\ - mov r0, r10\n\ - adds r0, 0x2\n\ - str r0, [sp, 0x30]\n\ - movs r5, 0\n\ - add r7, sp, 0x10\n\ - mov r12, r7\n\ - adds r6, r1, 0\n\ - adds r6, 0x2E\n\ - movs r4, 0x2\n\ -_080F6C34:\n\ - adds r0, r6, r5\n\ - movs r7, 0\n\ - ldrsh r1, [r0, r7]\n\ - lsls r0, r1, 4\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r3\n\ - ldrh r0, [r0, 0x4]\n\ - lsls r0, 22\n\ - lsrs r0, 17\n\ - adds r0, r2\n\ - mov r1, r12\n\ - adds r1, 0x4\n\ - mov r12, r1\n\ - subs r1, 0x4\n\ - stm r1!, {r0}\n\ - adds r5, 0x2\n\ - subs r4, 0x1\n\ - cmp r4, 0\n\ - bge _080F6C34\n\ - mov r7, r8\n\ - adds r7, 0x80\n\ - mov r2, r8\n\ - adds r2, 0x40\n\ - str r2, [sp, 0x28]\n\ - mov r0, r8\n\ - adds r0, 0x20\n\ - str r0, [sp, 0x3C]\n\ - mov r1, r8\n\ - adds r1, 0xA0\n\ - str r1, [sp, 0x40]\n\ - adds r2, 0x20\n\ - str r2, [sp, 0x34]\n\ - add r5, sp, 0xC\n\ - movs r6, 0\n\ - movs r4, 0x3\n\ -_080F6C7C:\n\ - str r6, [sp, 0x1C]\n\ - ldm r5!, {r1}\n\ - ldr r0, [sp, 0x2C]\n\ - ldr r2, =0x05000100\n\ - bl CpuSet\n\ - subs r4, 0x1\n\ - cmp r4, 0\n\ - bge _080F6C7C\n\ - ldr r5, [sp, 0xC]\n\ - ldr r6, =0x04000008\n\ - mov r0, r8\n\ - adds r1, r5, 0\n\ - adds r2, r6, 0\n\ - bl CpuSet\n\ - movs r0, 0x80\n\ - lsls r0, 1\n\ - adds r1, r5, r0\n\ - adds r0, r7, 0\n\ - adds r2, r6, 0\n\ - bl CpuSet\n\ - movs r2, 0x80\n\ - lsls r2, 2\n\ - adds r1, r5, r2\n\ - adds r0, r7, 0\n\ - adds r2, r6, 0\n\ - bl CpuSet\n\ - movs r7, 0xC0\n\ - lsls r7, 2\n\ - adds r1, r5, r7\n\ - ldr r0, [sp, 0x28]\n\ - adds r2, r6, 0\n\ - bl CpuSet\n\ - movs r4, 0\n\ - cmp r4, r10\n\ - bge _080F6D32\n\ - adds r7, r6, 0\n\ -_080F6CCE:\n\ - adds r6, r4, 0x1\n\ - adds r0, r6, 0\n\ - cmp r6, 0\n\ - bge _080F6CDA\n\ - adds r0, r4, 0\n\ - adds r0, 0x8\n\ -_080F6CDA:\n\ - asrs r0, 3\n\ - lsls r1, r0, 2\n\ - add r1, sp\n\ - adds r1, 0xC\n\ - lsls r0, 3\n\ - subs r0, r6, r0\n\ - lsls r0, 5\n\ - ldr r1, [r1]\n\ - adds r5, r1, r0\n\ - mov r0, r8\n\ - adds r0, 0xC0\n\ - adds r1, r5, 0\n\ - adds r2, r7, 0\n\ - bl CpuSet\n\ - movs r0, 0x80\n\ - lsls r0, 1\n\ - adds r1, r5, r0\n\ - mov r0, r9\n\ - adds r2, r7, 0\n\ - bl CpuSet\n\ - movs r0, 0xF0\n\ - lsls r0, 2\n\ - add r0, r9\n\ - movs r2, 0x80\n\ - lsls r2, 2\n\ - adds r1, r5, r2\n\ - adds r2, r7, 0\n\ - bl CpuSet\n\ - movs r0, 0xC0\n\ - lsls r0, 2\n\ - adds r1, r5, r0\n\ - mov r0, r8\n\ - adds r0, 0xE0\n\ - adds r2, r7, 0\n\ - bl CpuSet\n\ - movs r1, 0x20\n\ - add r9, r1\n\ - adds r4, r6, 0\n\ - cmp r4, r10\n\ - blt _080F6CCE\n\ -_080F6D32:\n\ - adds r2, r4, 0x1\n\ - adds r0, r2, 0\n\ - cmp r2, 0\n\ - bge _080F6D3E\n\ - adds r0, r4, 0\n\ - adds r0, 0x8\n\ -_080F6D3E:\n\ - asrs r0, 3\n\ - lsls r1, r0, 2\n\ - add r1, sp\n\ - adds r1, 0xC\n\ - lsls r0, 3\n\ - subs r0, r2, r0\n\ - lsls r0, 5\n\ - ldr r1, [r1]\n\ - adds r5, r1, r0\n\ - ldr r4, =0x04000008\n\ - ldr r0, [sp, 0x3C]\n\ - adds r1, r5, 0\n\ - adds r2, r4, 0\n\ - bl CpuSet\n\ - movs r2, 0x80\n\ - lsls r2, 1\n\ - adds r1, r5, r2\n\ - ldr r0, [sp, 0x40]\n\ - adds r2, r4, 0\n\ - bl CpuSet\n\ - movs r7, 0x80\n\ - lsls r7, 2\n\ - adds r1, r5, r7\n\ - ldr r0, [sp, 0x40]\n\ - adds r2, r4, 0\n\ - bl CpuSet\n\ - movs r0, 0xC0\n\ - lsls r0, 2\n\ - adds r1, r5, r0\n\ - ldr r0, [sp, 0x34]\n\ - adds r2, r4, 0\n\ - bl CpuSet\n\ - ldr r1, [sp, 0x38]\n\ - lsrs r0, r1, 24\n\ - bl RemoveWindow\n\ - ldr r2, [sp, 0x30]\n\ - lsls r1, r2, 3\n\ - movs r0, 0xF0\n\ - subs r0, r1\n\ - asrs r0, 1\n\ - add sp, 0x44\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r1}\n\ - bx r1\n\ - .pool"); -} -#endif // NONMATCHING - -static void LoadContestResultSprites(void) -{ - int i; - struct SpriteTemplate template; - u8 spriteIds[ARRAY_COUNT(sUnknown_0858D810)]; - - template = sSpriteTemplate_858D7F8; - for (i = 0; i < (int)ARRAY_COUNT(sUnknown_0858D810); i++) - LoadSpriteSheet(&sUnknown_0858D810[i]); - - LoadSpritePalette(&sUnknown_0858D850); - for (i = 0; i < (int)ARRAY_COUNT(sUnknown_0858D810); i++) - { - spriteIds[i] = CreateSprite(&template, 272, 144, 10); - template.tileTag++; - } - - gSprites[spriteIds[0]].data[0] = spriteIds[1]; - gSprites[spriteIds[0]].data[1] = spriteIds[2]; - gSprites[spriteIds[0]].data[2] = spriteIds[3]; - - gSprites[spriteIds[4]].data[0] = spriteIds[5]; - gSprites[spriteIds[4]].data[1] = spriteIds[6]; - gSprites[spriteIds[4]].data[2] = spriteIds[7]; - - sContestResults->data->slidingTextBoxSpriteId = spriteIds[0]; - sContestResults->data->slidingTextBoxState = SLIDING_TEXT_OFFSCREEN; - sContestResults->data->linkTextBoxSpriteId = spriteIds[4]; - HideLinkResultsTextBox(); -} - -#define sTargetX data[4] -#define sSlideOutTimer data[5] -#define sSlideIncrement data[6] -#define sDistance data[7] - -// If slideOutTimer is -1, it will not automatically slide out -static void StartTextBoxSlideIn(s16 x, u16 y, u16 slideOutTimer, u16 slideIncrement) -{ - struct Sprite *sprite = &gSprites[sContestResults->data->slidingTextBoxSpriteId]; - sprite->pos1.x = 272; - sprite->pos1.y = y; - sprite->pos2.x = 0; - sprite->pos2.y = 0; - sprite->sTargetX = x + 32; - sprite->sSlideOutTimer = slideOutTimer; - sprite->sSlideIncrement = slideIncrement; - sprite->sDistance = 0; - sprite->callback = SpriteCB_TextBoxSlideIn; - sContestResults->data->slidingTextBoxState = SLIDING_TEXT_ENTERING; -} - -static void StartTextBoxSlideOut(u16 slideIncrement) -{ - struct Sprite *sprite = &gSprites[sContestResults->data->slidingTextBoxSpriteId]; - sprite->pos1.x += sprite->pos2.x; - sprite->pos1.y += sprite->pos2.y; - sprite->pos2.y = 0; - sprite->pos2.x = 0; - sprite->sSlideIncrement = slideIncrement; - sprite->sDistance = 0; - sprite->callback = SpriteCB_TextBoxSlideOut; - sContestResults->data->slidingTextBoxState = SLIDING_TEXT_EXITING; -} - -static void EndTextBoxSlideOut(struct Sprite *sprite) -{ - sprite->pos1.x = 272; - sprite->pos1.y = 144; - sprite->pos2.y = 0; - sprite->pos2.x = 0; - sprite->callback = SpriteCallbackDummy; - sContestResults->data->slidingTextBoxState = SLIDING_TEXT_OFFSCREEN; -} - -static void SpriteCB_TextBoxSlideIn(struct Sprite *sprite) -{ - int i; - - s16 delta = sprite->sDistance + sprite->sSlideIncrement; - sprite->pos1.x -= delta >> 8; - sprite->sDistance += sprite->sSlideIncrement; - sprite->sDistance &= 0xFF; - - // Prevent overshooting target - if (sprite->pos1.x < sprite->sTargetX) - sprite->pos1.x = sprite->sTargetX; - - for (i = 0; i < 3; i++) - { - struct Sprite *sprite2 = &gSprites[sprite->data[i]]; - sprite2->pos1.x = sprite->pos1.x + sprite->pos2.x + (i + 1) * 64; - } - - if (sprite->pos1.x == sprite->sTargetX) - sprite->callback = SpriteCB_EndTextBoxSlideIn; -} - -static void SpriteCB_EndTextBoxSlideIn(struct Sprite *sprite) -{ - sContestResults->data->slidingTextBoxState = SLIDING_TEXT_ARRIVED; - if ((u16)sprite->sSlideOutTimer != 0xFFFF) - { - if (--sprite->sSlideOutTimer == -1) - StartTextBoxSlideOut(sprite->sSlideIncrement); - } -} - -static void SpriteCB_TextBoxSlideOut(struct Sprite *sprite) -{ - int i; - s16 delta; - - delta = sprite->sDistance + sprite->sSlideIncrement; - sprite->pos1.x -= delta >> 8; - sprite->sDistance += sprite->sSlideIncrement; - sprite->sDistance &= 0xFF; - for (i = 0; i < 3; i++) - { - struct Sprite *sprite2 = &gSprites[sprite->data[i]]; - sprite2->pos1.x = sprite->pos1.x + sprite->pos2.x + (i + 1) * 64; - } - - if (sprite->pos1.x + sprite->pos2.x < -224) - EndTextBoxSlideOut(sprite); -} - -static void ShowLinkResultsTextBox(const u8 *text) -{ - int i; - u16 x; - struct Sprite *sprite; - - x = DrawResultsTextWindow(text, sContestResults->data->linkTextBoxSpriteId); - sprite = &gSprites[sContestResults->data->linkTextBoxSpriteId]; - sprite->pos1.x = x + 32; - sprite->pos1.y = 80; - sprite->invisible = FALSE; - for (i = 0; i < 3; i++) - { - gSprites[sprite->data[i]].pos1.x = sprite->pos1.x + sprite->pos2.x + (i + 1) * 64; - gSprites[sprite->data[i]].pos1.y = sprite->pos1.y; - gSprites[sprite->data[i]].invisible = FALSE; - } - - gBattle_WIN0H = 0x00F0; - gBattle_WIN0V = ((sprite->pos1.y - 16) << 8) | (sprite->pos1.y + 16); - SetGpuReg(REG_OFFSET_WININ, WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR - | WININ_WIN0_BG1 | WININ_WIN0_BG2 | WININ_WIN0_BG3 | WININ_WIN0_OBJ | WININ_WIN0_CLR); -} - -static void HideLinkResultsTextBox(void) -{ - int i; - struct Sprite *sprite; - - sprite = &gSprites[sContestResults->data->linkTextBoxSpriteId]; - sprite->invisible = TRUE; - for (i = 0; i < 3; i++) - gSprites[sprite->data[i]].invisible = TRUE; - - gBattle_WIN0H = 0; - gBattle_WIN0V = 0; - SetGpuReg(REG_OFFSET_WIN0H, gBattle_WIN0H); - SetGpuReg(REG_OFFSET_WIN0V, gBattle_WIN0V); - SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR - | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR); -} - -static void LoadContestResultsTilemaps(void) -{ - u8 palette; - int x, y; - - x = 5; - y = 1; - if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK) - { - CopyToBgTilemapBufferRect(2, gLinkContestResults_Tilemap, 5, 1, 5, 2); - x = 10; - } - else if (gSpecialVar_ContestRank == CONTEST_RANK_NORMAL) - { - CopyToBgTilemapBufferRect(2, gNormalContestResults_Tilemap, 5, 1, 10, 2); - x = 15; - } - else if (gSpecialVar_ContestRank == CONTEST_RANK_SUPER) - { - CopyToBgTilemapBufferRect(2, gSuperContestResults_Tilemap, 5, 1, 10, 2); - x = 15; - } - else if (gSpecialVar_ContestRank == CONTEST_RANK_HYPER) - { - CopyToBgTilemapBufferRect(2, gHyperContestResults_Tilemap, 5, 1, 10, 2); - x = 15; - } - else // CONTEST_RANK_MASTER - { - CopyToBgTilemapBufferRect(2, gMasterContestResults_Tilemap, 5, 1, 10, 2); - x = 15; - } - - if (gSpecialVar_ContestCategory == CONTEST_CATEGORY_COOL) - { - palette = 0; - CopyToBgTilemapBufferRect(2, gCoolContestResults_Tilemap, x, y, 5, 2); - } - else if (gSpecialVar_ContestCategory == CONTEST_CATEGORY_BEAUTY) - { - palette = 1; - CopyToBgTilemapBufferRect(2, gBeautyContestResults_Tilemap, x, y, 5, 2); - } - else if (gSpecialVar_ContestCategory == CONTEST_CATEGORY_CUTE) - { - palette = 2; - CopyToBgTilemapBufferRect(2, gCuteContestResults_Tilemap, x, y, 5, 2); - } - else if (gSpecialVar_ContestCategory == CONTEST_CATEGORY_SMART) - { - palette = 3; - CopyToBgTilemapBufferRect(2, gSmartContestResults_Tilemap, x, y, 5, 2); - } - else // CONTEST_CATEGORY_TOUGH - { - palette = 4; - CopyToBgTilemapBufferRect(2, gToughContestResults_Tilemap, x, y, 5, 2); - } - - x += 5; - CopyToBgTilemapBufferRect(2, gContestResults_Tilemap, x, y, 6, 2); - CopyToBgTilemapBufferRect_ChangePalette(2, sContestResults->tilemapBuffers[2], 0, 0, 32, 4, palette); -} - -// Represented on results board as stars -static u8 GetNumPreliminaryPoints(u8 monIndex, bool8 capPoints) -{ - u32 condition = gContestMonConditions[monIndex] << 16; - u32 numStars = condition / 0x3F; - - if (numStars & 0xFFFF) - numStars += 0x10000; - - numStars >>= 16; - if (numStars == 0 && condition) - numStars = 1; - - if (capPoints && numStars > 10) - numStars = 10; - - return numStars; -} - -// Represented on results board as hearts -static s8 GetNumRound2Points(u8 monIndex, bool8 capPoints) -{ - u32 r4, numHearts; - s16 results; - s8 points; - - results = gContestMonRound2Points[monIndex]; - if (results < 0) - r4 = -results << 16; - else - r4 = results << 16; - - numHearts = r4 / 80; - if (numHearts & 0xFFFF) - numHearts += 0x10000; - - numHearts >>= 16; - if (numHearts == 0 && r4 != 0) - numHearts = 1; - - if (capPoints && numHearts > 10) - numHearts = 10; - - if (gContestMonRound2Points[monIndex] < 0) - points = -numHearts; - else - points = numHearts; - - return points; -} - -#define tState data[10] - -static void Task_DrawFinalStandingNumber(u8 taskId) -{ - u16 firstTileNum; - - if (gTasks[taskId].tState == 0) - { - gTasks[taskId].data[11] = (3 - gTasks[taskId].tFinalStanding) * 40; - gTasks[taskId].tState++; - } - else if (gTasks[taskId].tState == 1) - { - if (--gTasks[taskId].data[11] == -1) - { - firstTileNum = gTasks[taskId].tFinalStanding * 2 + 0x5043; - WriteSequenceToBgTilemapBuffer(2, firstTileNum, 1, gTasks[taskId].tMonIndex * 3 + 5, 2, 1, 17, 1); - WriteSequenceToBgTilemapBuffer(2, firstTileNum + 0x10, 1, gTasks[taskId].tMonIndex * 3 + 6, 2, 1, 17, 1); - sContestResults->data->numStandingsPrinted++; - DestroyTask(taskId); - PlaySE(SE_JYUNI); - } - } -} - -#undef tFinalStanding -#undef tMonIndex -#undef tState - -static void Task_StartHighlightWinnersBox(u8 taskId) -{ - int i; - GET_CONTEST_WINNER_ID(i); - CopyToBgTilemapBufferRect_ChangePalette(2, i * 0xC0 + 0x100 + sContestResults->tilemapBuffers[2], 0, i * 3 + 4, 32, 3, 9); - gTasks[taskId].data[10] = i; - gTasks[taskId].data[12] = 1; - gTasks[taskId].func = Task_HighlightWinnersBox; - sContestResults->data->highlightWinnerTaskId = taskId; -} - -static void Task_HighlightWinnersBox(u8 taskId) -{ - if (++gTasks[taskId].data[11] == 1) - { - gTasks[taskId].data[11] = 0; - BlendPalette(0x91, 1, gTasks[taskId].data[12], RGB(13, 28, 27)); - if (gTasks[taskId].data[13] == 0) - { - if (++gTasks[taskId].data[12] == 16) - gTasks[taskId].data[13] = 1; - } - else - { - if (--gTasks[taskId].data[12] == 0) - gTasks[taskId].data[13] = 0; - } - } -} - -static void SpriteCB_WinnerMonSlideIn(struct Sprite *sprite) -{ - if (sprite->data[0] < 10) - { - if (++sprite->data[0] == 10) - { - PlayCry1(sprite->data[1], 0); - sprite->data[1] = 0; - } - } - else - { - s16 delta = sprite->data[1] + 0x600; - sprite->pos1.x -= delta >> 8; - sprite->data[1] += 0x600; - sprite->data[1] &= 0xFF; - if (sprite->pos1.x < 120) - sprite->pos1.x = 120; - - if (sprite->pos1.x == 120) - { - sprite->callback = SpriteCallbackDummy; - sprite->data[1] = 0; - sContestResults->data->winnerMonSlidingState = SLIDING_MON_ENTERED; - } - } -} - -static void SpriteCB_WinnerMonSlideOut(struct Sprite *sprite) -{ - s16 delta = sprite->data[1] + 0x600; - sprite->pos1.x -= delta >> 8; - sprite->data[1] += + 0x600; - sprite->data[1] &= 0xFF; - if (sprite->pos1.x < -32) - { - sprite->callback = SpriteCallbackDummy; - sprite->invisible = TRUE; - sContestResults->data->winnerMonSlidingState = SLIDING_MON_EXITED; - } -} - -static void Task_CreateConfetti(u8 taskId) -{ - if (++gTasks[taskId].data[0] == 5) - { - gTasks[taskId].data[0] = 0; - if (sContestResults->data->confettiCount < 40) - { - u8 spriteId = CreateSprite(&sSpriteTemplate_Confetti, (Random() % 240) - 20, 44, 5); - gSprites[spriteId].data[0] = Random() % 512; - gSprites[spriteId].data[1] = (Random() % 24) + 16; - gSprites[spriteId].data[2] = (Random() % 256) + 48; - gSprites[spriteId].oam.tileNum += Random() % 17; - sContestResults->data->confettiCount++; - } - } - - if (sContestResults->data->destroyConfetti) - DestroyTask(taskId); -} - -static void SpriteCB_Confetti(struct Sprite *sprite) -{ - s16 delta; - - sprite->data[3] += sprite->data[0]; - sprite->pos2.x = Sin(sprite->data[3] >> 8, sprite->data[1]); - delta = sprite->data[4] + sprite->data[2]; - sprite->pos1.x += delta >> 8; - sprite->data[4] += sprite->data[2]; - sprite->data[4] &= 0xff; - - sprite->pos1.y++; - if (sContestResults->data->destroyConfetti) - sprite->invisible = TRUE; - - if (sprite->pos1.x > 248 || sprite->pos1.y > 116) - { - DestroySprite(sprite); - sContestResults->data->confettiCount--; - } -} - -#define tMonIndex data[0] -#define tNumFrames data[1] -#define tSpecies data[2] -#define tTimer data[10] -#define tBounced data[11] - -static void BounceMonIconInBox(u8 monIndex, u8 numFrames) -{ - u8 taskId = CreateTask(Task_BounceMonIconInBox, 8); - gTasks[taskId].tMonIndex = monIndex; - gTasks[taskId].tNumFrames = numFrames; - gTasks[taskId].tSpecies = gContestMons[monIndex].species; -} - -static void Task_BounceMonIconInBox(u8 taskId) -{ - u8 monIndex = gTasks[taskId].tMonIndex; - if (gTasks[taskId].tTimer++ == gTasks[taskId].tNumFrames) - { - gTasks[taskId].tTimer = 0; - LoadContestMonIcon(gTasks[taskId].tSpecies, monIndex, gTasks[taskId].tBounced, FALSE, gContestMons[monIndex].personality); - gTasks[taskId].tBounced ^= 1; - } -} - -#undef tMonIndex -#undef tNumFrames -#undef tSpecies -#undef tTimer -#undef tBounced - -static void CalculateContestantsResultData(void) -{ - int i, relativePoints; - u32 barLength; - s16 highestPoints; - s8 round2Points; - - highestPoints = gContestMonTotalPoints[0]; - for (i = 1; i < CONTESTANT_COUNT; i++) - { - if (highestPoints < gContestMonTotalPoints[i]) - highestPoints = gContestMonTotalPoints[i]; - } - - if (highestPoints < 0) - { - highestPoints = gContestMonTotalPoints[0]; - for (i = 1; i < CONTESTANT_COUNT; i++) - { - if (highestPoints > gContestMonTotalPoints[i]) - highestPoints = gContestMonTotalPoints[i]; - } - } - - for (i = 0; i < CONTESTANT_COUNT; i++) - { - relativePoints = (gContestMonConditions[i] * 1000) / abs(highestPoints); - if (relativePoints % 10 > 4) - relativePoints += 10; - (*sContestResults->monResults)[i].relativePreliminaryPoints = relativePoints / 10; - - relativePoints = (abs(gContestMonRound2Points[i]) * 1000) / abs(highestPoints); - if (relativePoints % 10 > 4) - relativePoints += 10; - (*sContestResults->monResults)[i].relativeRound2Points = relativePoints / 10; - - if (gContestMonRound2Points[i] < 0) - (*sContestResults->monResults)[i].lostPoints = TRUE; - - barLength = ((*sContestResults->monResults)[i].relativePreliminaryPoints * 0x5800) / 100; - if ((barLength & 0xFF) > 0x7F) - barLength += 0x100; - (*sContestResults->monResults)[i].barLengthPreliminary = barLength >> 8; - - barLength = ((*sContestResults->monResults)[i].relativeRound2Points * 0x5800) / 100; - if ((barLength & 0xFF) > 0x7F) - barLength += 0x100; - (*sContestResults->monResults)[i].barLengthRound2 = barLength >> 8; - - (*sContestResults->monResults)[i].numStars = GetNumPreliminaryPoints(i, TRUE); - round2Points = GetNumRound2Points(i, TRUE); - (*sContestResults->monResults)[i].numHearts = abs(round2Points); - - if (gContestFinalStandings[i]) - { - s16 barLengthPreliminary = (*sContestResults->monResults)[i].barLengthPreliminary; - s16 barLengthRound2 = (*sContestResults->monResults)[i].barLengthRound2; - - if ((*sContestResults->monResults)[i].lostPoints) - barLengthRound2 *= -1; - - if (barLengthPreliminary + barLengthRound2 == MAX_BAR_LENGTH + 1) - { - if (barLengthRound2 > 0) - (*sContestResults->monResults)[i].barLengthRound2--; - else if (barLengthPreliminary > 0) - (*sContestResults->monResults)[i].barLengthPreliminary--; - } - } - } -} - -#define tMonId data[0] -#define tTarget data[1] -#define tDecreasing data[2] - -static void UpdateContestResultBars(bool8 isRound2, u8 numUpdates) -{ - int i, taskId; - u32 target; - u8 numIncreasing = 0, numDecreasing = 0; - - if (!isRound2) - { - for (i = 0; i < CONTESTANT_COUNT; i++) - { - u8 numStars = (*sContestResults->monResults)[i].numStars; - if (numUpdates < numStars) - { - FillBgTilemapBufferRect_Palette0(1, 0x60B3, ((19 + numStars) - numUpdates) - 1, i * 3 + 5, 1, 1); - taskId = CreateTask(Task_UpdateContestResultBar, 10); - - target = (((*sContestResults->monResults)[i].barLengthPreliminary << 16) / (*sContestResults->monResults)[i].numStars) * (numUpdates + 1); - if ((target & 0xFFFF) > 0x7FFF) - target += 0x10000; - - gTasks[taskId].tMonId = i; - gTasks[taskId].tTarget = target >> 16; - sContestResults->data->numBarsUpdating++; - numIncreasing++; - } - } - } - else - { - for (i = 0; i < CONTESTANT_COUNT; i++) - { - s8 numHearts = (*sContestResults->monResults)[i].numHearts; - u32 tile = (*sContestResults->monResults)[i].lostPoints ? 0x60A5 : 0x60A3; - if (numUpdates < numHearts) - { - FillBgTilemapBufferRect_Palette0(1, tile, ((19 + numHearts) - numUpdates) - 1, i * 3 + 6, 1, 1); - taskId = CreateTask(Task_UpdateContestResultBar, 10); - - target = (((*sContestResults->monResults)[i].barLengthRound2 << 16) / (*sContestResults->monResults)[i].numHearts) * (numUpdates + 1); - if ((target & 0xFFFF) > 0x7FFF) - target += 0x10000; - - gTasks[taskId].tMonId = i; - if ((*sContestResults->monResults)[i].lostPoints) - { - gTasks[taskId].tDecreasing = TRUE; - numDecreasing++; - } - else - { - numIncreasing++; - } - - if ((*sContestResults->monResults)[i].lostPoints) - gTasks[taskId].tTarget = -(target >> 16) + (*sContestResults->monResults)[i].barLengthPreliminary; - else - gTasks[taskId].tTarget = (target >> 16) + (*sContestResults->monResults)[i].barLengthPreliminary; - - sContestResults->data->numBarsUpdating++; - } - } - } - - if (numDecreasing) - PlaySE(SE_BOO); - if (numIncreasing) - PlaySE(SE_PIN); -} - -static void Task_UpdateContestResultBar(u8 taskId) -{ - int i; - bool32 minMaxReached = FALSE; - bool32 targetReached = FALSE; - u8 monId = gTasks[taskId].tMonId; - s16 target = gTasks[taskId].tTarget; - s16 decreasing = gTasks[taskId].tDecreasing; - - if (decreasing) - { - if (sContestResults->data->unkC[monId] <= 0) - minMaxReached = TRUE; - } - else - { - if (sContestResults->data->unkC[monId] > MAX_BAR_LENGTH) - minMaxReached = TRUE; - } - - if (sContestResults->data->unkC[monId] == target) - targetReached = TRUE; - - if (!targetReached) - { - if (minMaxReached) - sContestResults->data->unkC[monId] = target; - else if (decreasing) - sContestResults->data->unkC[monId] = sContestResults->data->unkC[monId] - 1; - else - sContestResults->data->unkC[monId] = sContestResults->data->unkC[monId] + 1; - } - - if (!minMaxReached && !targetReached) - { - u8 var0; - u16 tileNum; - for (i = 0; i < 11; i++) - { - if (sContestResults->data->unkC[monId] >= (i + 1) * 8) - var0 = 8; - else if (sContestResults->data->unkC[monId] >= i * 8) - var0 = sContestResults->data->unkC[monId] % 8; - else - var0 = 0; - - if (var0 < 4) - tileNum = 0x504C + var0; - else - tileNum = 0x5057 + var0; - - FillBgTilemapBufferRect_Palette0(2, tileNum, i + 7, monId * 3 + 6, 1, 1); - } - } - - if (targetReached) - { - sContestResults->data->numBarsUpdating--; - DestroyTask(taskId); - } -} - -#undef tMonId -#undef tTarget -#undef tDecreasing - -static void AllocContestResults(void) -{ - sContestResults = AllocZeroed(sizeof(*sContestResults)); - sContestResults->data = AllocZeroed(sizeof(*sContestResults->data)); - sContestResults->monResults = AllocZeroed(sizeof(*sContestResults->monResults)); - sContestResults->unusedBg = AllocZeroed(BG_SCREEN_SIZE); - sContestResults->tilemapBuffers[0] = AllocZeroed(BG_SCREEN_SIZE); - sContestResults->tilemapBuffers[1] = AllocZeroed(BG_SCREEN_SIZE); - sContestResults->tilemapBuffers[2] = AllocZeroed(BG_SCREEN_SIZE); - sContestResults->tilemapBuffers[3] = AllocZeroed(BG_SCREEN_SIZE); - sContestResults->unused = AllocZeroed(0x1000); - AllocateMonSpritesGfx(); -} - -static void FreeContestResults(void) -{ - FREE_AND_SET_NULL(sContestResults->data); - FREE_AND_SET_NULL(sContestResults->monResults); - FREE_AND_SET_NULL(sContestResults->unusedBg); - FREE_AND_SET_NULL(sContestResults->tilemapBuffers[0]); - FREE_AND_SET_NULL(sContestResults->tilemapBuffers[1]); - FREE_AND_SET_NULL(sContestResults->tilemapBuffers[2]); - FREE_AND_SET_NULL(sContestResults->tilemapBuffers[3]); - FREE_AND_SET_NULL(sContestResults->unused); - FREE_AND_SET_NULL(sContestResults); - FreeMonSpritesGfx(); -} - -static void AddContestTextPrinter(int windowId, u8 *str, int x) -{ - struct TextPrinterTemplate textPrinter; - textPrinter.currentChar = str; - textPrinter.windowId = windowId; - textPrinter.fontId = 7; - textPrinter.x = x; - textPrinter.y = 2; - textPrinter.currentX = x; - textPrinter.currentY = 2; - textPrinter.letterSpacing = 0; - textPrinter.lineSpacing = 0; - textPrinter.unk = 0; - textPrinter.fgColor = 1; - textPrinter.bgColor = 0; - textPrinter.shadowColor = 8; - AddTextPrinter(&textPrinter, 0, NULL); - PutWindowTilemap(windowId); -} - -void TryEnterContestMon(void) -{ - u8 eligibility = GetContestEntryEligibility(&gPlayerParty[gContestMonPartyIndex]); - - // Nonzero eligibility can still be non-eligibile, if mon is fainted or egg - if (eligibility) - { - sub_80DAB8C(gSpecialVar_ContestCategory, gSpecialVar_ContestRank); - sub_80DB09C(gSpecialVar_ContestCategory); - } - - gSpecialVar_Result = eligibility; -} - -u16 HasMonWonThisContestBefore(void) -{ - u16 hasRankRibbon = FALSE; - struct Pokemon *mon = &gPlayerParty[gContestMonPartyIndex]; - switch (gSpecialVar_ContestCategory) - { - case CONTEST_CATEGORY_COOL: - if (GetMonData(mon, MON_DATA_COOL_RIBBON) > gSpecialVar_ContestRank) - hasRankRibbon = TRUE; - break; - case CONTEST_CATEGORY_BEAUTY: - if (GetMonData(mon, MON_DATA_BEAUTY_RIBBON) > gSpecialVar_ContestRank) - hasRankRibbon = TRUE; - break; - case CONTEST_CATEGORY_CUTE: - if (GetMonData(mon, MON_DATA_CUTE_RIBBON) > gSpecialVar_ContestRank) - hasRankRibbon = TRUE; - break; - case CONTEST_CATEGORY_SMART: - if (GetMonData(mon, MON_DATA_SMART_RIBBON) > gSpecialVar_ContestRank) - hasRankRibbon = TRUE; - break; - case CONTEST_CATEGORY_TOUGH: - if (GetMonData(mon, MON_DATA_TOUGH_RIBBON) > gSpecialVar_ContestRank) - hasRankRibbon = TRUE; - break; - } - - return hasRankRibbon; -} - -void GiveMonContestRibbon(void) -{ - u8 ribbonData; - - if (gContestFinalStandings[gContestPlayerMonIndex] != 0) - return; - - switch (gSpecialVar_ContestCategory) - { - case CONTEST_CATEGORY_COOL: - ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_COOL_RIBBON); - if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4) - { - ribbonData++; - SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_COOL_RIBBON, &ribbonData); - if (GetRibbonCount(&gPlayerParty[gContestMonPartyIndex]) > NUM_CUTIES_RIBBONS) - TryPutSpotTheCutiesOnAir(&gPlayerParty[gContestMonPartyIndex], MON_DATA_COOL_RIBBON); - } - break; - case CONTEST_CATEGORY_BEAUTY: - ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_BEAUTY_RIBBON); - if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4) - { - ribbonData++; - SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_BEAUTY_RIBBON, &ribbonData); - if (GetRibbonCount(&gPlayerParty[gContestMonPartyIndex]) > NUM_CUTIES_RIBBONS) - TryPutSpotTheCutiesOnAir(&gPlayerParty[gContestMonPartyIndex], MON_DATA_BEAUTY_RIBBON); - } - break; - case CONTEST_CATEGORY_CUTE: - ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_CUTE_RIBBON); - if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4) - { - ribbonData++; - SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_CUTE_RIBBON, &ribbonData); - if (GetRibbonCount(&gPlayerParty[gContestMonPartyIndex]) > NUM_CUTIES_RIBBONS) - TryPutSpotTheCutiesOnAir(&gPlayerParty[gContestMonPartyIndex], MON_DATA_CUTE_RIBBON); - } - break; - case CONTEST_CATEGORY_SMART: - ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_SMART_RIBBON); - if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4) - { - ribbonData++; - SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_SMART_RIBBON, &ribbonData); - if (GetRibbonCount(&gPlayerParty[gContestMonPartyIndex]) > NUM_CUTIES_RIBBONS) - TryPutSpotTheCutiesOnAir(&gPlayerParty[gContestMonPartyIndex], MON_DATA_SMART_RIBBON); - } - break; - case CONTEST_CATEGORY_TOUGH: - ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_TOUGH_RIBBON); - if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4) - { - ribbonData++; - SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_TOUGH_RIBBON, &ribbonData); - if (GetRibbonCount(&gPlayerParty[gContestMonPartyIndex]) > NUM_CUTIES_RIBBONS) - TryPutSpotTheCutiesOnAir(&gPlayerParty[gContestMonPartyIndex], MON_DATA_TOUGH_RIBBON); - } - break; - } -} - -void BufferContestantTrainerName(void) -{ - StringCopy(gStringVar1, gContestMons[gSpecialVar_0x8006].trainerName); - sub_81DB5AC(gStringVar1); -} - -void BufferContestantMonNickname(void) -{ - StringCopy(gStringVar3, gContestMons[gSpecialVar_0x8006].nickname); -} - -// Unused script special -void GetContestMonConditionRanking(void) -{ - u8 i, rank; - - for (i = 0, rank = 0; i < CONTESTANT_COUNT; i++) - { - if (gContestMonConditions[gSpecialVar_0x8006] < gContestMonConditions[i]) - rank++; - } - - gSpecialVar_0x8004 = rank; -} - -void GetContestMonCondition(void) -{ - gSpecialVar_0x8004 = gContestMonConditions[gSpecialVar_0x8006]; -} - -void GetContestWinnerId(void) -{ - u8 i; - GET_CONTEST_WINNER_ID(i); - gSpecialVar_0x8005 = i; -} - -void BufferContestWinnerTrainerName(void) -{ - u8 i; - GET_CONTEST_WINNER_ID(i); - StringCopy(gStringVar3, gContestMons[i].trainerName); - sub_81DB5AC(gStringVar3); -} - -void BufferContestWinnerMonName(void) -{ - u8 i; - GET_CONTEST_WINNER_ID(i); - StringCopy(gStringVar1, gContestMons[i].nickname); -} - -void CB2_SetStartContestCallback(void) -{ - SetMainCallback2(CB2_StartContest); -} - -static void Task_StartContest(u8 taskId) -{ - if (!gPaletteFade.active) - { - DestroyTask(taskId); - SetMainCallback2(CB2_SetStartContestCallback); - } -} - -void StartContest(void) -{ - ScriptContext2_Enable(); - CreateTask(Task_StartContest, 10); - BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); -} - -void BufferContestantMonSpecies(void) -{ - gSpecialVar_0x8004 = gContestMons[gSpecialVar_0x8006].species; -} - -static void Task_StartShowContestResults(u8 taskId) -{ - if (!gPaletteFade.active) - { - DestroyTask(taskId); - SetMainCallback2(CB2_StartShowContestResults); - } -} - -void ShowContestResults(void) -{ - ScriptContext2_Enable(); - CreateTask(Task_StartShowContestResults, 10); - BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); -} - -void GetContestPlayerId(void) -{ - gSpecialVar_0x8004 = gContestPlayerMonIndex; -} - -void ContestLinkTransfer(u8 taskId) -{ - u8 newTaskId; - ScriptContext2_Enable(); - newTaskId = CreateTask(sub_80FC580, 0); - SetTaskFuncWithFollowupFunc(newTaskId, sub_80FC580, sub_80F8508); - gTasks[newTaskId].data[9] = taskId; -} - -static void sub_80F8508(u8 taskId) -{ - if (gLinkContestFlags & LINK_CONTEST_FLAG_HAS_RS_PLAYER) - { - sub_80DA8C8(gContestMonPartyIndex); - SetTaskFuncWithFollowupFunc(taskId, sub_80FC6BC, sub_80F8568); - } - else - { - sub_80DA8C8(gContestMonPartyIndex); - gTasks[taskId].func = sub_81D9DE4; - } -} - -static void sub_80F8568(u8 taskId) -{ - SetTaskFuncWithFollowupFunc(taskId, sub_80FC804, sub_80F8584); -} - -static void sub_80F8584(u8 taskId) -{ - SetTaskFuncWithFollowupFunc(taskId, sub_80FCE48, sub_80F85A0); -} - -static void sub_80F85A0(u8 taskId) -{ - SetTaskFuncWithFollowupFunc(taskId, sub_80FC894, sub_80F85BC); -} - -static void sub_80F85BC(u8 taskId) -{ - u8 i; - u8 sp0[4]; - u8 sp4[4]; - - memset(sp0, 0, sizeof(sp0)); - memset(sp4, 0, sizeof(sp4)); - - for (i = 0; i < gNumLinkContestPlayers; i++) - sp0[i] = gTasks[taskId].data[i + 1]; - - for (i = 0; i < gNumLinkContestPlayers;) - { - i++; - if (i >= gNumLinkContestPlayers || sp0[0] != sp0[i]) - break; - } - - if (i == gNumLinkContestPlayers) - gSpecialVar_0x8004 = 0; - else - gSpecialVar_0x8004 = 1; - - for (i = 0; i < gNumLinkContestPlayers; i++) - sp4[i] = gTasks[taskId].data[i + 5]; - - gUnknown_02039F2B = sub_80F86E0(sp4); - sub_80DB09C(gSpecialVar_ContestCategory); - SetTaskFuncWithFollowupFunc(taskId, sub_80FCF40, sub_80F86B8); -} - -static void sub_80F86B8(u8 taskId) -{ - SortContestants(FALSE); - SetTaskFuncWithFollowupFunc(taskId, sub_80FCFD0, sub_80F8714); -} - -u8 sub_80F86E0(u8 *arg0) -{ - int i; - u8 result = 0; - - for (i = 1; i < gNumLinkContestPlayers; i++) - { - if (arg0[result] < arg0[i]) - result = i; - } - - return result; -} - -void sub_80F8714(u8 taskId) -{ - int i; - - if (gSpecialVar_0x8004 == 1) - { - if (IsLinkTaskFinished()) - gTasks[taskId].func = sub_80F878C; - } - else - { - for (i = 0; i < CONTESTANT_COUNT; i++) - StringGetEnd10(gContestMons[i].nickname); - - DestroyTask(taskId); - SetDynamicWarp(0, gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, -1); - ScriptContext2_Disable(); - EnableBothScriptContexts(); - } -} - -static void sub_80F878C(u8 taskId) -{ - sub_800AC34(); - gTasks[taskId].func = sub_80F87B4; -} - -static void sub_80F87B4(u8 taskId) -{ - if (!gReceivedRemoteLinkPlayers) - { - DestroyTask(taskId); - ScriptContext2_Disable(); - EnableBothScriptContexts(); - } -} diff --git a/src/contest_link_80FC4F4.c b/src/contest_link_80FC4F4.c deleted file mode 100644 index e17f62485..000000000 --- a/src/contest_link_80FC4F4.c +++ /dev/null @@ -1,548 +0,0 @@ -#include "global.h" -#include "contest.h" -#include "decompress.h" -#include "event_data.h" -#include "link.h" -#include "pokemon.h" -#include "random.h" -#include "task.h" -#include "constants/flags.h" - -static void sub_80FC5C0(u8); -static void sub_80FC5DC(u8); - -bool32 sub_80FC4F4(void *src, u16 size) -{ - memcpy(gDecompressionBuffer, src, size); - if (SendBlock(bitmask_all_link_players_but_self(), gDecompressionBuffer, size)) - return TRUE; - else - return FALSE; -} - -bool8 sub_80FC530(u8 arg0) -{ - u8 mask = (1 << arg0); - if (!(GetBlockReceivedStatus() & mask)) - { - return FALSE; - } - else - { - ResetBlockReceivedFlag(arg0); - return TRUE; - } -} - -bool8 sub_80FC55C(void) -{ - if (GetBlockReceivedStatus() == sub_800A9D8()) - { - ResetBlockReceivedFlags(); - return TRUE; - } - else - { - return FALSE; - } -} - -void sub_80FC580(u8 taskId) -{ - u8 i; - - for (i = 0; i < 4; i++) - gBlockRecvBuffer[i][0] = 0xFF; - - gTasks[taskId].data[0] = 0; - gTasks[taskId].func = sub_80FC5C0; -} - -static void sub_80FC5C0(u8 taskId) -{ - gTasks[taskId].func = sub_80FC5DC; -} - -static void sub_80FC5DC(u8 taskId) -{ - int i; - - if (!gReceivedRemoteLinkPlayers) - return; - - gContestPlayerMonIndex = GetMultiplayerId(); - gNumLinkContestPlayers = GetLinkPlayerCount(); - gLinkContestFlags = LINK_CONTEST_FLAG_IS_LINK; - if (gWirelessCommType == 1) - gLinkContestFlags = LINK_CONTEST_FLAG_IS_LINK | LINK_CONTEST_FLAG_IS_WIRELESS; - - for (i = 0; i < gNumLinkContestPlayers && (u32)(gLinkPlayers[i].version & 0xFF) - 1 > VERSION_RUBY - 1; i++) - ; - - if (i < gNumLinkContestPlayers) - gLinkContestFlags |= LINK_CONTEST_FLAG_HAS_RS_PLAYER; - - SwitchTaskToFollowupFunc(taskId); -} - -bool32 sub_80FC670(s16 *arg0) -{ - if (gLinkContestFlags & LINK_CONTEST_FLAG_HAS_RS_PLAYER) - return TRUE; - - switch (*arg0) - { - case 0: - if (IsLinkTaskFinished()) - { - sub_800ADF8(); - (*arg0)++; - } - return FALSE; - case 1: - (*arg0)++; - return FALSE; - default: - if (IsLinkTaskFinished() != TRUE) - return FALSE; - else - return TRUE; - } -} - -void sub_80FC6BC(u8 taskId) -{ - int i; - - if (!sub_80FC670(&gTasks[taskId].data[12])) - return; - - switch (gTasks[taskId].data[0]) - { - case 0: - if (GetMultiplayerId() == 0) - { - if (IsLinkTaskFinished()) - { - memcpy(gBlockSendBuffer, &gContestMons[gContestPlayerMonIndex], sizeof(struct ContestPokemon)); - gTasks[taskId].data[0] = 10; - } - } - else - { - memcpy(gBlockSendBuffer, &gContestMons[gContestPlayerMonIndex], sizeof(struct ContestPokemon)); - gTasks[taskId].data[0] = 1; - } - break; - case 1: - if (sub_80FC55C()) - { - for (i = 0; i < gNumLinkContestPlayers; i++) - { - memcpy(&gContestMons[i], gBlockRecvBuffer[i], sizeof(struct ContestPokemon)); - sub_80DFA08(&gContestMons[i], gLinkPlayers[i].language); - } - - gTasks[taskId].data[0]++; - } - break; - case 10: - if (++gTasks[taskId].data[11] > 300) - { - sub_800A4D8(2); - gTasks[taskId].data[0] = 1; - } - break; - default: - gTasks[taskId].data[0] = 0; - gTasks[taskId].data[11] = 0; - gTasks[taskId].data[12] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - } -} - -void sub_80FC804(u8 taskId) -{ - switch (gTasks[taskId].data[0]) - { - case 0: - if (GetMultiplayerId() == 0) - { - if (IsLinkTaskFinished() && sub_80FC4F4(&gRngValue, sizeof(gRngValue)) == TRUE) - gTasks[taskId].data[0]++; - } - else - { - gTasks[taskId].data[0]++; - } - break; - case 1: - if (sub_80FC530(0)) - { - memcpy(&gRngValue, gBlockRecvBuffer[0], sizeof(gRngValue)); - memcpy(&gContestRngValue, gBlockRecvBuffer[0], sizeof(gContestRngValue)); - gTasks[taskId].data[0]++; - } - break; - default: - gTasks[taskId].data[0] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - } -} - -void sub_80FC894(u8 taskId) -{ - int i; - - if (!sub_80FC670(&gTasks[taskId].data[12])) - return; - - switch (gTasks[taskId].data[0]) - { - case 0: - gBlockSendBuffer[0] = gTasks[taskId].data[9]; - if (GetMultiplayerId() == 0) - { - if (IsLinkTaskFinished()) - gTasks[taskId].data[0] = 10; - } - else - { - gTasks[taskId].data[0]++; - } - break; - case 1: - if (sub_80FC55C()) - { - for (i = 0; i < gNumLinkContestPlayers; i++) - gTasks[taskId].data[i + 1] = gBlockRecvBuffer[i][0]; - - gTasks[taskId].data[0]++; - } - break; - case 10: - if (++gTasks[taskId].data[11] > 10) - { - sub_800A4D8(2); - gTasks[taskId].data[0] = 1; - } - break; - default: - gTasks[taskId].data[0] = 0; - gTasks[taskId].data[11] = 0; - gTasks[taskId].data[12] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - } -} - -void sub_80FC998(u8 taskId) -{ - switch (gTasks[taskId].data[0]) - { - case 0: - if (IsLinkTaskFinished()) - { - if (sub_80FC4F4(&gContestPlayerMonIndex, sizeof(gContestPlayerMonIndex)) == TRUE) - gTasks[taskId].data[0]++; - } - break; - case 1: - if (sub_80FC55C()) - gTasks[taskId].data[0]++; - break; - default: - gTasks[taskId].data[0] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - } -} - -void sub_80FC9F8(u8 taskId) -{ - int i; - - switch (gTasks[taskId].data[0]) - { - case 0: - if (IsLinkTaskFinished()) - { - if (sub_80FC4F4(&eContestantStatus[gContestPlayerMonIndex].currMove, sizeof(eContestantStatus[gContestPlayerMonIndex].currMove)) == TRUE) - gTasks[taskId].data[0]++; - } - break; - case 1: - if (sub_80FC55C()) - { - for (i = 0; i < gNumLinkContestPlayers; i++) - eContestantStatus[i].currMove = gBlockRecvBuffer[i][0]; - - gTasks[taskId].data[0]++; - } - break; - default: - gTasks[taskId].data[0] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - } -} - -void sub_80FCACC(u8 taskId) -{ - switch (gTasks[taskId].data[0]) - { - case 0: - if (IsLinkTaskFinished()) - { - if (sub_80FC4F4(gContestMonTotalPoints, sizeof(gContestMonTotalPoints)) == 1) - gTasks[taskId].data[0]++; - } - break; - case 1: - if (sub_80FC55C()) - { - memcpy(gContestMonTotalPoints, gBlockRecvBuffer[gUnknown_02039F2B], sizeof(gContestMonTotalPoints)); - gTasks[taskId].data[0]++; - } - break; - case 2: - case 5: - case 8: - case 11: - if (gTasks[taskId].data[1]++ > 10) - { - gTasks[taskId].data[1] = 0; - gTasks[taskId].data[0]++; - } - break; - case 3: - if (IsLinkTaskFinished()) - { - if (sub_80FC4F4(gUnknown_02039F10, sizeof(gUnknown_02039F10)) == 1) - gTasks[taskId].data[0]++; - } - break; - case 4: - if (sub_80FC55C()) - { - memcpy(gUnknown_02039F10, gBlockRecvBuffer[gUnknown_02039F2B], sizeof(gUnknown_02039F10)); - gTasks[taskId].data[0]++; - } - break; - case 6: - if (IsLinkTaskFinished()) - { - if (sub_80FC4F4(gContestMonRound2Points, sizeof(gContestMonRound2Points)) == 1) - gTasks[taskId].data[0]++; - } - break; - case 7: - if (sub_80FC55C()) - { - memcpy(gContestMonRound2Points, gBlockRecvBuffer[gUnknown_02039F2B], sizeof(gContestMonRound2Points)); - gTasks[taskId].data[0]++; - } - break; - case 9: - if (IsLinkTaskFinished()) - { - if (sub_80FC4F4(gContestFinalStandings, sizeof(gContestFinalStandings)) == 1) - gTasks[taskId].data[0]++; - } - break; - case 10: - if (sub_80FC55C()) - { - memcpy(gContestFinalStandings, gBlockRecvBuffer[gUnknown_02039F2B], sizeof(gContestFinalStandings)); - gTasks[taskId].data[0]++; - } - break; - default: - gTasks[taskId].data[0] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - } -} - -void sub_80FCC88(u8 taskId) -{ - switch (gTasks[taskId].data[0]) - { - case 0: - if (IsLinkTaskFinished()) - { - if (sub_80FC4F4(eContestantStatus, 4 * sizeof(struct ContestantStatus)) == 1) - gTasks[taskId].data[0]++; - } - break; - case 1: - if (sub_80FC55C()) - { - memcpy(eContestantStatus, gBlockRecvBuffer[gUnknown_02039F2B], 4 * sizeof(struct ContestantStatus)); - gTasks[taskId].data[0]++; - } - break; - case 2: - case 5: - case 8: - case 11: - if (gTasks[taskId].data[1]++ > 10) - { - gTasks[taskId].data[1] = 0; - gTasks[taskId].data[0]++; - } - break; - case 3: - if (IsLinkTaskFinished()) - { - if (sub_80FC4F4(gContestResources->field_8, sizeof(struct UnknownContestStruct7)) == 1) - gTasks[taskId].data[0]++; - } - break; - case 4: - if (sub_80FC55C()) - { - memcpy(gContestResources->field_8, gBlockRecvBuffer[gUnknown_02039F2B], sizeof(struct UnknownContestStruct7)); - gTasks[taskId].data[0]++; - } - break; - case 6: - if (IsLinkTaskFinished()) - { - if (sub_80FC4F4(gContestResources->field_10, sizeof(struct UnknownContestStruct5)) == 1) - gTasks[taskId].data[0]++; - } - break; - case 7: - if (sub_80FC55C()) - { - memcpy(gContestResources->field_10, gBlockRecvBuffer[gUnknown_02039F2B], sizeof(struct UnknownContestStruct5)); - gTasks[taskId].data[0]++; - } - break; - case 9: - if (IsLinkTaskFinished()) - { - if (sub_80FC4F4(gContestantTurnOrder, sizeof(gContestantTurnOrder)) == 1) - gTasks[taskId].data[0]++; - } - break; - case 10: - if (sub_80FC55C()) - { - memcpy(gContestantTurnOrder, gBlockRecvBuffer[gUnknown_02039F2B], sizeof(gContestantTurnOrder)); - gTasks[taskId].data[0]++; - } - break; - default: - gTasks[taskId].data[0] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - } -} - -void sub_80FCE48(u8 taskId) -{ - int i; - - if (!sub_80FC670(&gTasks[taskId].data[12])) - return; - - switch (gTasks[taskId].data[0]) - { - case 0: - gBlockSendBuffer[0] = 0x6E; - if (GetMultiplayerId() == 0) - { - if (IsLinkTaskFinished()) - gTasks[taskId].data[0] = 10; - } - else - { - gTasks[taskId].data[0]++; - } - break; - case 1: - if (sub_80FC55C()) - { - for (i = 0; i < 4; i++) - gTasks[taskId].data[i + 5] = gBlockRecvBuffer[i][0]; - - gTasks[taskId].data[0]++; - } - break; - case 10: - if (++gTasks[taskId].data[11] > 10) - { - sub_800A4D8(2); - gTasks[taskId].data[0] = 1; - } - break; - default: - gTasks[taskId].data[0] = 0; - gTasks[taskId].data[11] = 0; - gTasks[taskId].data[12] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - } -} - -void sub_80FCF40(u8 taskId) -{ - if (!sub_80FC670(&gTasks[taskId].data[12])) - return; - - switch (gTasks[taskId].data[0]) - { - case 0: - if (IsLinkTaskFinished()) - { - if (sub_80FC4F4(gContestMonConditions, sizeof(gContestMonConditions)) == 1) - gTasks[taskId].data[0]++; - } - break; - case 1: - if (sub_80FC55C()) - { - memcpy(gContestMonConditions, gBlockRecvBuffer[gUnknown_02039F2B], sizeof(gContestMonConditions)); - gTasks[taskId].data[0]++; - } - break; - default: - gTasks[taskId].data[0] = 0; - gTasks[taskId].data[12] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - } -} - -void sub_80FCFD0(u8 taskId) -{ - if (!sub_80FC670(&gTasks[taskId].data[12])) - return; - - switch (gTasks[taskId].data[0]) - { - case 0: - if (IsLinkTaskFinished()) - { - if (sub_80FC4F4(gContestantTurnOrder, sizeof(gContestantTurnOrder)) == 1) - gTasks[taskId].data[0]++; - } - break; - case 1: - if (sub_80FC55C()) - { - memcpy(gContestantTurnOrder, gBlockRecvBuffer[gUnknown_02039F2B], sizeof(gContestantTurnOrder)); - gTasks[taskId].data[0]++; - } - break; - default: - gTasks[taskId].data[0] = 0; - gTasks[taskId].data[12] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - } -} diff --git a/src/contest_link_81D9DE4.c b/src/contest_link_81D9DE4.c deleted file mode 100644 index 8060b6cdc..000000000 --- a/src/contest_link_81D9DE4.c +++ /dev/null @@ -1,331 +0,0 @@ -#include "global.h" -#include "contest.h" -#include "event_data.h" -#include "link.h" -#include "random.h" -#include "task.h" - -static void sub_81D9F14(u8); -static void sub_81D9F30(u8); -static void sub_81D9F4C(u8); -static void sub_81D9F68(u8); -static void sub_81DA10C(u8); -static void sub_81DA138(u8); -static void sub_81DA160(u8); -static void sub_81DA244(u8); -static void sub_81DA2E8(u8); -static void sub_81DA3B8(u8); -static void sub_81DA488(u8); - -void sub_81D9DE4(u8 taskId) -{ - int gameCleared; - - switch (gTasks[taskId].data[9]) - { - case 0: - gHighestRibbonRank = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_COOL_RIBBON); - break; - case 1: - gHighestRibbonRank = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_BEAUTY_RIBBON); - break; - case 2: - gHighestRibbonRank = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_CUTE_RIBBON); - break; - case 3: - gHighestRibbonRank = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_SMART_RIBBON); - break; - case 4: - default: - gHighestRibbonRank = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_TOUGH_RIBBON); - break; - } - - gContestMons[gContestPlayerMonIndex].unk2C[0] = gHighestRibbonRank; - gameCleared = FlagGet(FLAG_SYS_GAME_CLEAR) > 0; - gContestMons[gContestPlayerMonIndex].unk2C[1] = gameCleared; - SetTaskFuncWithFollowupFunc(taskId, sub_81DA160, sub_81D9F14); -} - -static void sub_81D9F14(u8 taskId) -{ - SetTaskFuncWithFollowupFunc(taskId, sub_81DA244, sub_81D9F30); -} - -static void sub_81D9F30(u8 taskId) -{ - SetTaskFuncWithFollowupFunc(taskId, sub_81DA2E8, sub_81D9F4C); -} - -static void sub_81D9F4C(u8 taskId) -{ - SetTaskFuncWithFollowupFunc(taskId, sub_81DA3B8, sub_81D9F68); -} - -static void sub_81D9F68(u8 taskId) -{ - u8 i; - u8 rank; - int gameCleared; - u8 data1[4]; - u8 data2[4]; - - memset(data1, 0, sizeof(data1)); - memset(data2, 0, sizeof(data2)); - - for (i = 0; i < gNumLinkContestPlayers; i++) - data1[i] = gTasks[taskId].data[i + 1]; - - i = 0; - if (i < gNumLinkContestPlayers) - { - while (++i < gNumLinkContestPlayers) - { - if (data1[0] != data1[i]) - break; - } - } - - if (i == gNumLinkContestPlayers) - gSpecialVar_0x8004 = 0; - else - gSpecialVar_0x8004 = 1; - - for (i = 0; i < gNumLinkContestPlayers; i++) - data2[i] = gTasks[taskId].data[i + 5]; - - if (gNumLinkContestPlayers != 4 && GetMultiplayerId() == 0) - { - rank = gContestMons[0].unk2C[0]; - for (i = 1; i < gNumLinkContestPlayers; i++) - { - if (rank < gContestMons[i].unk2C[0]) - rank = gContestMons[i].unk2C[0]; - } - - if (rank) - rank--; - - gameCleared = 1; - for (i = 0; i < gNumLinkContestPlayers; i++) - { - if (!gContestMons[i].unk2C[1]) - { - gameCleared = 0; - break; - } - } - - sub_80DACBC(data1[0], rank, gameCleared); - } - - gUnknown_02039F2B = sub_80F86E0(data2); - if (gNumLinkContestPlayers < 4) - SetTaskFuncWithFollowupFunc(taskId, sub_81DA488, sub_81DA10C); - else - gTasks[taskId].func = sub_81DA10C; -} - -static void sub_81DA10C(u8 taskId) -{ - sub_80DB09C(gSpecialVar_ContestCategory); - SetTaskFuncWithFollowupFunc(taskId, sub_80FCF40, sub_81DA138); -} - -static void sub_81DA138(u8 taskId) -{ - SortContestants(FALSE); - SetTaskFuncWithFollowupFunc(taskId, sub_80FCFD0, sub_80F8714); -} - -static void sub_81DA160(u8 taskId) -{ - int i; - - if (!sub_80FC670(&gTasks[taskId].data[12])) - return; - - switch (gTasks[taskId].data[0]) - { - default: - gTasks[taskId].data[0] = 0; - gTasks[taskId].data[12] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - case 0: - if (IsLinkTaskFinished()) - { - if (sub_80FC4F4(&gContestMons[gContestPlayerMonIndex], sizeof(struct ContestPokemon)) == 1) - gTasks[taskId].data[0]++; - } - break; - case 1: - if (sub_80FC55C()) - { - for (i = 0; i < gNumLinkContestPlayers; i++) - { - memcpy(&gContestMons[i], gBlockRecvBuffer[i], sizeof(struct ContestPokemon)); - sub_80DFA08(&gContestMons[i], gLinkPlayers[i].language); - } - - gTasks[taskId].data[0]++; - } - break; - } -} - -static void sub_81DA244(u8 taskId) -{ - if (!sub_80FC670(&gTasks[taskId].data[12])) - return; - - switch (gTasks[taskId].data[0]) - { - default: - gTasks[taskId].data[0] = 0; - gTasks[taskId].data[12] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - case 0: - if (GetMultiplayerId() == 0) - { - if (!IsLinkTaskFinished()) - return; - - if (sub_80FC4F4(&gRngValue, sizeof(gRngValue)) == 1) - gTasks[taskId].data[0]++; - } - else - { - gTasks[taskId].data[0]++; - } - break; - case 1: - if (sub_80FC530(0)) - { - memcpy(&gRngValue, gBlockRecvBuffer[0], sizeof(gRngValue)); - memcpy(&gContestRngValue, gBlockRecvBuffer[0], sizeof(gContestRngValue)); - gTasks[taskId].data[0]++; - } - break; - } -} - -static void sub_81DA2E8(u8 taskId) -{ - int i; - u16 data[4]; - u16 var0; - - if (!sub_80FC670(&gTasks[taskId].data[12])) - return; - - switch (gTasks[taskId].data[0]) - { - default: - gTasks[taskId].data[0] = 0; - gTasks[taskId].data[12] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - case 0: - if (IsLinkTaskFinished()) - { - var0 = 0x6E; - if (sub_80FC4F4(&var0, sizeof(var0)) == 1) - gTasks[taskId].data[0]++; - } - break; - case 1: - if (sub_80FC55C()) - { - for (i = 0; i < gNumLinkContestPlayers; i++) - { - data[i] = gBlockRecvBuffer[i][0]; - gTasks[taskId].data[i + 5] = data[i]; - } - - gTasks[taskId].data[0]++; - } - break; - } -} - -static void sub_81DA3B8(u8 taskId) -{ - int i; - u16 data[4]; - u16 var0; - - if (!sub_80FC670(&gTasks[taskId].data[12])) - return; - - switch (gTasks[taskId].data[0]) - { - default: - gTasks[taskId].data[0] = 0; - gTasks[taskId].data[12] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - case 0: - if (IsLinkTaskFinished()) - { - var0 = gTasks[taskId].data[9]; - if (sub_80FC4F4(&var0, sizeof(var0)) == 1) - gTasks[taskId].data[0]++; - } - break; - case 1: - if (sub_80FC55C()) - { - for (i = 0; i < gNumLinkContestPlayers; i++) - { - data[i] = gBlockRecvBuffer[i][0]; - gTasks[taskId].data[i + 1] = data[i]; - } - - gTasks[taskId].data[0]++; - } - break; - } -} - -static void sub_81DA488(u8 taskId) -{ - int i; - - if (!sub_80FC670(&gTasks[taskId].data[12])) - return; - - switch (gTasks[taskId].data[0]) - { - default: - gTasks[taskId].data[0] = 0; - gTasks[taskId].data[12] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - case 0: - if (GetMultiplayerId() == 0) - { - if (!IsLinkTaskFinished()) - return; - - if (sub_80FC4F4(&gContestMons[gNumLinkContestPlayers], (4 - gNumLinkContestPlayers) * sizeof(struct ContestPokemon)) == 1) - gTasks[taskId].data[0]++; - } - else - { - gTasks[taskId].data[0]++; - } - break; - case 1: - if (sub_80FC530(0)) - { - memcpy(&gContestMons[gNumLinkContestPlayers], gBlockRecvBuffer[0], (4 - gNumLinkContestPlayers) * sizeof(struct ContestPokemon)); - for (i = gNumLinkContestPlayers; i < 4; i++) - sub_80DFA08(&gContestMons[i], gLinkPlayers[0].language); - - gTasks[taskId].data[0]++; - } - break; - } -} diff --git a/src/contest_link_util.c b/src/contest_link_util.c new file mode 100644 index 000000000..8060b6cdc --- /dev/null +++ b/src/contest_link_util.c @@ -0,0 +1,331 @@ +#include "global.h" +#include "contest.h" +#include "event_data.h" +#include "link.h" +#include "random.h" +#include "task.h" + +static void sub_81D9F14(u8); +static void sub_81D9F30(u8); +static void sub_81D9F4C(u8); +static void sub_81D9F68(u8); +static void sub_81DA10C(u8); +static void sub_81DA138(u8); +static void sub_81DA160(u8); +static void sub_81DA244(u8); +static void sub_81DA2E8(u8); +static void sub_81DA3B8(u8); +static void sub_81DA488(u8); + +void sub_81D9DE4(u8 taskId) +{ + int gameCleared; + + switch (gTasks[taskId].data[9]) + { + case 0: + gHighestRibbonRank = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_COOL_RIBBON); + break; + case 1: + gHighestRibbonRank = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_BEAUTY_RIBBON); + break; + case 2: + gHighestRibbonRank = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_CUTE_RIBBON); + break; + case 3: + gHighestRibbonRank = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_SMART_RIBBON); + break; + case 4: + default: + gHighestRibbonRank = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_TOUGH_RIBBON); + break; + } + + gContestMons[gContestPlayerMonIndex].unk2C[0] = gHighestRibbonRank; + gameCleared = FlagGet(FLAG_SYS_GAME_CLEAR) > 0; + gContestMons[gContestPlayerMonIndex].unk2C[1] = gameCleared; + SetTaskFuncWithFollowupFunc(taskId, sub_81DA160, sub_81D9F14); +} + +static void sub_81D9F14(u8 taskId) +{ + SetTaskFuncWithFollowupFunc(taskId, sub_81DA244, sub_81D9F30); +} + +static void sub_81D9F30(u8 taskId) +{ + SetTaskFuncWithFollowupFunc(taskId, sub_81DA2E8, sub_81D9F4C); +} + +static void sub_81D9F4C(u8 taskId) +{ + SetTaskFuncWithFollowupFunc(taskId, sub_81DA3B8, sub_81D9F68); +} + +static void sub_81D9F68(u8 taskId) +{ + u8 i; + u8 rank; + int gameCleared; + u8 data1[4]; + u8 data2[4]; + + memset(data1, 0, sizeof(data1)); + memset(data2, 0, sizeof(data2)); + + for (i = 0; i < gNumLinkContestPlayers; i++) + data1[i] = gTasks[taskId].data[i + 1]; + + i = 0; + if (i < gNumLinkContestPlayers) + { + while (++i < gNumLinkContestPlayers) + { + if (data1[0] != data1[i]) + break; + } + } + + if (i == gNumLinkContestPlayers) + gSpecialVar_0x8004 = 0; + else + gSpecialVar_0x8004 = 1; + + for (i = 0; i < gNumLinkContestPlayers; i++) + data2[i] = gTasks[taskId].data[i + 5]; + + if (gNumLinkContestPlayers != 4 && GetMultiplayerId() == 0) + { + rank = gContestMons[0].unk2C[0]; + for (i = 1; i < gNumLinkContestPlayers; i++) + { + if (rank < gContestMons[i].unk2C[0]) + rank = gContestMons[i].unk2C[0]; + } + + if (rank) + rank--; + + gameCleared = 1; + for (i = 0; i < gNumLinkContestPlayers; i++) + { + if (!gContestMons[i].unk2C[1]) + { + gameCleared = 0; + break; + } + } + + sub_80DACBC(data1[0], rank, gameCleared); + } + + gUnknown_02039F2B = sub_80F86E0(data2); + if (gNumLinkContestPlayers < 4) + SetTaskFuncWithFollowupFunc(taskId, sub_81DA488, sub_81DA10C); + else + gTasks[taskId].func = sub_81DA10C; +} + +static void sub_81DA10C(u8 taskId) +{ + sub_80DB09C(gSpecialVar_ContestCategory); + SetTaskFuncWithFollowupFunc(taskId, sub_80FCF40, sub_81DA138); +} + +static void sub_81DA138(u8 taskId) +{ + SortContestants(FALSE); + SetTaskFuncWithFollowupFunc(taskId, sub_80FCFD0, sub_80F8714); +} + +static void sub_81DA160(u8 taskId) +{ + int i; + + if (!sub_80FC670(&gTasks[taskId].data[12])) + return; + + switch (gTasks[taskId].data[0]) + { + default: + gTasks[taskId].data[0] = 0; + gTasks[taskId].data[12] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + case 0: + if (IsLinkTaskFinished()) + { + if (sub_80FC4F4(&gContestMons[gContestPlayerMonIndex], sizeof(struct ContestPokemon)) == 1) + gTasks[taskId].data[0]++; + } + break; + case 1: + if (sub_80FC55C()) + { + for (i = 0; i < gNumLinkContestPlayers; i++) + { + memcpy(&gContestMons[i], gBlockRecvBuffer[i], sizeof(struct ContestPokemon)); + sub_80DFA08(&gContestMons[i], gLinkPlayers[i].language); + } + + gTasks[taskId].data[0]++; + } + break; + } +} + +static void sub_81DA244(u8 taskId) +{ + if (!sub_80FC670(&gTasks[taskId].data[12])) + return; + + switch (gTasks[taskId].data[0]) + { + default: + gTasks[taskId].data[0] = 0; + gTasks[taskId].data[12] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + case 0: + if (GetMultiplayerId() == 0) + { + if (!IsLinkTaskFinished()) + return; + + if (sub_80FC4F4(&gRngValue, sizeof(gRngValue)) == 1) + gTasks[taskId].data[0]++; + } + else + { + gTasks[taskId].data[0]++; + } + break; + case 1: + if (sub_80FC530(0)) + { + memcpy(&gRngValue, gBlockRecvBuffer[0], sizeof(gRngValue)); + memcpy(&gContestRngValue, gBlockRecvBuffer[0], sizeof(gContestRngValue)); + gTasks[taskId].data[0]++; + } + break; + } +} + +static void sub_81DA2E8(u8 taskId) +{ + int i; + u16 data[4]; + u16 var0; + + if (!sub_80FC670(&gTasks[taskId].data[12])) + return; + + switch (gTasks[taskId].data[0]) + { + default: + gTasks[taskId].data[0] = 0; + gTasks[taskId].data[12] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + case 0: + if (IsLinkTaskFinished()) + { + var0 = 0x6E; + if (sub_80FC4F4(&var0, sizeof(var0)) == 1) + gTasks[taskId].data[0]++; + } + break; + case 1: + if (sub_80FC55C()) + { + for (i = 0; i < gNumLinkContestPlayers; i++) + { + data[i] = gBlockRecvBuffer[i][0]; + gTasks[taskId].data[i + 5] = data[i]; + } + + gTasks[taskId].data[0]++; + } + break; + } +} + +static void sub_81DA3B8(u8 taskId) +{ + int i; + u16 data[4]; + u16 var0; + + if (!sub_80FC670(&gTasks[taskId].data[12])) + return; + + switch (gTasks[taskId].data[0]) + { + default: + gTasks[taskId].data[0] = 0; + gTasks[taskId].data[12] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + case 0: + if (IsLinkTaskFinished()) + { + var0 = gTasks[taskId].data[9]; + if (sub_80FC4F4(&var0, sizeof(var0)) == 1) + gTasks[taskId].data[0]++; + } + break; + case 1: + if (sub_80FC55C()) + { + for (i = 0; i < gNumLinkContestPlayers; i++) + { + data[i] = gBlockRecvBuffer[i][0]; + gTasks[taskId].data[i + 1] = data[i]; + } + + gTasks[taskId].data[0]++; + } + break; + } +} + +static void sub_81DA488(u8 taskId) +{ + int i; + + if (!sub_80FC670(&gTasks[taskId].data[12])) + return; + + switch (gTasks[taskId].data[0]) + { + default: + gTasks[taskId].data[0] = 0; + gTasks[taskId].data[12] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + case 0: + if (GetMultiplayerId() == 0) + { + if (!IsLinkTaskFinished()) + return; + + if (sub_80FC4F4(&gContestMons[gNumLinkContestPlayers], (4 - gNumLinkContestPlayers) * sizeof(struct ContestPokemon)) == 1) + gTasks[taskId].data[0]++; + } + else + { + gTasks[taskId].data[0]++; + } + break; + case 1: + if (sub_80FC530(0)) + { + memcpy(&gContestMons[gNumLinkContestPlayers], gBlockRecvBuffer[0], (4 - gNumLinkContestPlayers) * sizeof(struct ContestPokemon)); + for (i = gNumLinkContestPlayers; i < 4; i++) + sub_80DFA08(&gContestMons[i], gLinkPlayers[0].language); + + gTasks[taskId].data[0]++; + } + break; + } +} diff --git a/src/contest_util.c b/src/contest_util.c new file mode 100644 index 000000000..22074e1a1 --- /dev/null +++ b/src/contest_util.c @@ -0,0 +1,2533 @@ +#include "global.h" +#include "malloc.h" +#include "battle.h" +#include "battle_gfx_sfx_util.h" +#include "bg.h" +#include "contest.h" +#include "contest_util.h" +#include "contest_link.h" +#include "data.h" +#include "decompress.h" +#include "dma3.h" +#include "event_data.h" +#include "field_specials.h" +#include "gpu_regs.h" +#include "graphics.h" +#include "international_string_util.h" +#include "link.h" +#include "link_rfu.h" +#include "load_save.h" +#include "main.h" +#include "overworld.h" +#include "palette.h" +#include "pokedex.h" +#include "pokemon.h" +#include "pokemon_icon.h" +#include "random.h" +#include "save.h" +#include "scanline_effect.h" +#include "script.h" +#include "sound.h" +#include "string_util.h" +#include "strings.h" +#include "task.h" +#include "text.h" +#include "trig.h" +#include "tv.h" +#include "util.h" +#include "window.h" +#include "constants/field_specials.h" +#include "constants/game_stat.h" +#include "constants/rgb.h" +#include "constants/songs.h" +#include "constants/tv.h" +#include "constants/vars.h" +#include "contest.h" + +enum { + SLIDING_TEXT_OFFSCREEN, + SLIDING_TEXT_ENTERING, + SLIDING_TEXT_ARRIVED, + SLIDING_TEXT_EXITING, +}; + +enum { + SLIDING_MON_ENTERED = 1, + SLIDING_MON_EXITED, +}; + +#define GET_CONTEST_WINNER_ID(i) { for ((i) = 0; (i) < CONTESTANT_COUNT && gContestFinalStandings[(i)] != 0; (i)++); } + +#define TAG_CONFETTI 3017 + +#define MAX_BAR_LENGTH 87 + +struct ContestResultsInternal +{ + u8 slidingTextBoxSpriteId; + u8 linkTextBoxSpriteId; + u8 showResultsTaskId; + u8 highlightWinnerTaskId; + u8 slidingTextBoxState; + u8 numStandingsPrinted; + u8 winnerMonSlidingState; + u8 confettiCount; + u8 winnerMonSpriteId; + bool8 destroyConfetti; + bool8 pointsFlashing; + s16 unkC[CONTESTANT_COUNT]; + u8 numBarsUpdating; +}; + +struct ContestMonResults +{ + int relativePreliminaryPoints; + int relativeRound2Points; + u32 barLengthPreliminary; + u32 barLengthRound2; + bool8 lostPoints; + u8 numStars; + u8 numHearts; +}; + +struct ContestResults +{ + struct ContestResultsInternal *data; + struct ContestMonResults (*monResults)[CONTESTANT_COUNT]; + u8 *unusedBg; // Allocated/freed, never used + u8 *tilemapBuffers[4]; + u8 *unused; // Allocated/freed, never used +}; + +static EWRAM_DATA struct ContestResults *sContestResults = NULL; + +static void LoadAllContestMonIconPalettes(void); +static void LoadContestResultsTilemaps(void); +static u8 GetNumPreliminaryPoints(u8, bool8); +static s8 GetNumRound2Points(u8, bool8); +static void AddContestTextPrinter(int, u8 *, int); +static void AllocContestResults(void); +static void FreeContestResults(void); +static void LoadAllContestMonIcons(u8, u8); +static void LoadContestResultSprites(void); +static void TryCreateWirelessSprites(void); +static void Task_StartShowContestResults(u8 taskId); +static void CB2_StartShowContestResults(void); +static void Task_ShowContestResults(u8); +static void CB2_ShowContestResults(void); +static void VBlankCB_ShowContestResults(void); +static void Task_SlideContestResultsBg(u8); +static void Task_WaitForLinkPartnersBeforeResults(u8); +static void sub_80F5F14(u8); +static void sub_80F5F30(u8); +static void Task_AnnouncePreliminaryResults(u8); +static void Task_FlashStarsAndHearts(u8); +static void Task_ShowPreliminaryResults(u8); +static void Task_AnnounceRound2Results(u8); +static void Task_ShowRound2Results(u8); +static void Task_AnnounceWinner(u8); +static void Task_DrawFinalStandingNumber(u8); +static void Task_StartHighlightWinnersBox(u8); +static void Task_HighlightWinnersBox(u8); +static void Task_ShowWinnerMonBanner(u8); +static void Task_SetSeenWinnerMon(u8); +static void Task_TryDisconnectLinkPartners(u8); +static void Task_WaitForLinkPartnersDisconnect(u8); +static void Task_TrySetContestInterviewData(u8); +static void Task_EndShowContestResults(u8); +static void CalculateContestantsResultData(void); +static void ShowLinkResultsTextBox(const u8 *); +static void HideLinkResultsTextBox(void); +static s32 DrawResultsTextWindow(const u8 *, u8); +static void StartTextBoxSlideIn(s16, u16, u16, u16); +static void UpdateContestResultBars(bool8, u8); +static void Task_UpdateContestResultBar(u8); +static void StartTextBoxSlideOut(u16); +static void BounceMonIconInBox(u8, u8); +static void Task_BounceMonIconInBox(u8); +static void SpriteCB_WinnerMonSlideIn(struct Sprite *); +static void SpriteCB_WinnerMonSlideOut(struct Sprite *); +static void Task_CreateConfetti(u8); +static void SpriteCB_TextBoxSlideIn(struct Sprite *); +static void SpriteCB_TextBoxSlideOut(struct Sprite *); +static void SpriteCB_EndTextBoxSlideIn(struct Sprite *); +static void sub_80F8508(u8); +static void sub_80F8568(u8); +static void sub_80F8584(u8); +static void sub_80F85A0(u8); +static void sub_80F85BC(u8); +static void sub_80F86B8(u8); +static void sub_80F878C(u8); +static void sub_80F87B4(u8); +static void SpriteCB_Confetti(struct Sprite *sprite); + +static const u16 sUnknown_0858D6B0[] = INCBIN_U16("graphics/unknown/unknown_58D6B0.gbapal"); +static const u8 sUnknown_0858D6D0[] = INCBIN_U8("graphics/unknown/unknown_58D6D0.4bpp"); +static const u16 sMiscBlank_Pal[] = INCBIN_U16("graphics/interface/blank.gbapal"); + +static const struct OamData sOamData_858D7F0 = +{ + .y = 0, + .affineMode = ST_OAM_AFFINE_OFF, + .objMode = ST_OAM_OBJ_NORMAL, + .mosaic = 0, + .bpp = ST_OAM_4BPP, + .shape = SPRITE_SHAPE(64x32), + .x = 0, + .matrixNum = 0, + .size = SPRITE_SIZE(64x32), + .tileNum = 0, + .priority = 3, + .paletteNum = 2, + .affineParam = 0, +}; + +static const struct SpriteTemplate sSpriteTemplate_858D7F8 = +{ + .tileTag = 3009, + .paletteTag = 3009, + .oam = &sOamData_858D7F0, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy +}; + +static const struct SpriteSheet sUnknown_0858D810[] = +{ + { .data = gMiscBlank_Gfx, .size = 0x400, .tag = 3009 }, + { .data = gMiscBlank_Gfx, .size = 0x400, .tag = 3010 }, + { .data = gMiscBlank_Gfx, .size = 0x400, .tag = 3011 }, + { .data = gMiscBlank_Gfx, .size = 0x400, .tag = 3012 }, + { .data = gMiscBlank_Gfx, .size = 0x400, .tag = 3013 }, + { .data = gMiscBlank_Gfx, .size = 0x400, .tag = 3014 }, + { .data = gMiscBlank_Gfx, .size = 0x400, .tag = 3015 }, + { .data = gMiscBlank_Gfx, .size = 0x400, .tag = 3016 }, +}; + +static const struct SpritePalette sUnknown_0858D850 = +{ + .data = sMiscBlank_Pal, + .tag = 3009, +}; + +static const struct OamData sOamData_Confetti = +{ + .y = 0, + .affineMode = ST_OAM_AFFINE_OFF, + .objMode = ST_OAM_OBJ_NORMAL, + .mosaic = 0, + .bpp = ST_OAM_4BPP, + .shape = SPRITE_SHAPE(8x8), + .x = 0, + .matrixNum = 0, + .size = SPRITE_SIZE(8x8), + .tileNum = 0, + .priority = 0, + .paletteNum = 0, + .affineParam = 0, +}; + +static const struct SpriteTemplate sSpriteTemplate_Confetti = +{ + .tileTag = TAG_CONFETTI, + .paletteTag = TAG_CONFETTI, + .oam = &sOamData_Confetti, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCB_Confetti +}; + +static const struct CompressedSpriteSheet sSpriteSheet_Confetti = +{ + .data = gConfetti_Gfx, + .size = 0x220, + .tag = TAG_CONFETTI +}; + + +static const struct CompressedSpritePalette sSpritePalette_Confetti = +{ + .data = gConfetti_Pal, + .tag = TAG_CONFETTI +}; + +static const struct BgTemplate sBgTemplates[] = +{ + { + .bg = 0, + .charBaseIndex = 0, + .mapBaseIndex = 30, + .screenSize = 0, + .paletteMode = 0, + .priority = 0, + .baseTile = 0, + }, + { + .bg = 1, + .charBaseIndex = 0, + .mapBaseIndex = 24, + .screenSize = 0, + .paletteMode = 0, + .priority = 3, + .baseTile = 0, + }, + { + .bg = 2, + .charBaseIndex = 0, + .mapBaseIndex = 28, + .screenSize = 0, + .paletteMode = 0, + .priority = 3, + .baseTile = 0, + }, + { + .bg = 3, + .charBaseIndex = 0, + .mapBaseIndex = 26, + .screenSize = 0, + .paletteMode = 0, + .priority = 3, + .baseTile = 0, + } +}; + +static const struct WindowTemplate sWindowTemplates[] = +{ + { + .bg = 1, + .tilemapLeft = 7, + .tilemapTop = 4, + .width = 12, + .height = 2, + .paletteNum = 15, + .baseBlock = 770 + }, + { + .bg = 1, + .tilemapLeft = 7, + .tilemapTop = 7, + .width = 12, + .height = 2, + .paletteNum = 15, + .baseBlock = 794 + }, + { + .bg = 1, + .tilemapLeft = 7, + .tilemapTop = 10, + .width = 12, + .height = 2, + .paletteNum = 15, + .baseBlock = 818 + }, + { + .bg = 1, + .tilemapLeft = 7, + .tilemapTop = 13, + .width = 12, + .height = 2, + .paletteNum = 15, + .baseBlock = 842 + }, + DUMMY_WIN_TEMPLATE, +}; + +static const struct OamData sUnknown_0858D8C0 = +{ + .y = 0, + .affineMode = ST_OAM_AFFINE_OFF, + .objMode = ST_OAM_OBJ_NORMAL, + .mosaic = 0, + .bpp = ST_OAM_4BPP, + .shape = SPRITE_SHAPE(16x16), + .x = 0, + .matrixNum = 0, + .size = SPRITE_SIZE(16x16), + .tileNum = 0, + .priority = 0, + .paletteNum = 0, + .affineParam = 0, +}; + + +static const struct SpriteTemplate sSpriteTemplate_858D8C8 = +{ + .tileTag = 22222, + .paletteTag = 0, + .oam = &sUnknown_0858D8C0, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy +}; + +static const struct SpriteSheet sUnknown_0858D8E0 = +{ + .data = gMiscBlank_Gfx, + .size = 0x200, + .tag = 22222 +}; + +static const u8 sContestLinkTextColors[4] = {TEXT_COLOR_WHITE, TEXT_DYNAMIC_COLOR_6, TEXT_DYNAMIC_COLOR_5}; + + +static void InitContestResultsDisplay(void) +{ + int i; + + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP); + ResetBgsAndClearDma3BusyFlags(0); + InitBgsFromTemplates(0, sBgTemplates, ARRAY_COUNT(sBgTemplates)); + for (i = 0; i < (int)ARRAY_COUNT(sContestResults->tilemapBuffers); i++) + SetBgTilemapBuffer(i, sContestResults->tilemapBuffers[i]); + + InitWindows(sWindowTemplates); + DeactivateAllTextPrinters(); + SetGpuReg(REG_OFFSET_MOSAIC, 0); + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG1 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR); + SetGpuReg(REG_OFFSET_WIN0H, 0); + SetGpuReg(REG_OFFSET_WIN0V, 0); + SetGpuReg(REG_OFFSET_WIN1H, 0); + SetGpuReg(REG_OFFSET_WIN1V, 0); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + SetGpuReg(REG_OFFSET_BLDY, 0); + SetGpuReg(REG_OFFSET_BG0HOFS, 0); + SetGpuReg(REG_OFFSET_BG0VOFS, 0); + SetGpuReg(REG_OFFSET_BG1HOFS, 0); + SetGpuReg(REG_OFFSET_BG1VOFS, 0); + SetGpuReg(REG_OFFSET_BG2HOFS, 0); + SetGpuReg(REG_OFFSET_BG2VOFS, 0); + SetGpuReg(REG_OFFSET_BG3HOFS, 0); + SetGpuReg(REG_OFFSET_BG3VOFS, 0); + SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG_ALL_ON | DISPCNT_OBJ_ON | DISPCNT_WIN0_ON | DISPCNT_WIN1_ON | DISPCNT_OBJWIN_ON); + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + gBattle_BG1_X = 0; + gBattle_BG1_Y = 0; + gBattle_BG2_X = 0; + gBattle_BG2_Y = 0; + gBattle_BG3_X = 0; + gBattle_BG3_Y = 0; + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + gBattle_WIN1H = 0; + gBattle_WIN1V = 0; +} + +static void LoadContestResultsBgGfx(void) +{ + int i, j; + s8 numStars, round2Points; + u16 tile1, tile2; + + LZDecompressVram(gContestResults_Gfx, (void *)BG_CHAR_ADDR(0)); + CopyToBgTilemapBuffer(3, gUnknown_08C1A12C, 0, 0); + CopyToBgTilemapBuffer(2, gUnknown_08C1A000, 0, 0); + CopyToBgTilemapBuffer(0, gUnknown_08C19EEC, 0, 0); + LoadContestResultsTilemaps(); + LoadCompressedPalette(gContestResults_Pal, 0, 0x200); + LoadPalette(sUnknown_0858D6B0, 0xF0, 0x20); + + for (i = 0; i < CONTESTANT_COUNT; i++) + { + numStars = GetNumPreliminaryPoints(i, TRUE); + round2Points = GetNumRound2Points(i, TRUE); + for (j = 0; j < 10; j++) + { + tile1 = 0x60B2; + if (j < numStars) + tile1 += 2; + + // Abs of round2Points is number of hearts + if (j < abs(round2Points)) + { + tile2 = 0x60A4; + if (round2Points < 0) + tile2 += 2; + } + else + { + tile2 = 0x60A2; + } + + FillBgTilemapBufferRect_Palette0(1, tile1, j + 19, i * 3 + 5, 1, 1); + FillBgTilemapBufferRect_Palette0(1, tile2, j + 19, i * 3 + 6, 1, 1); + } + } + + CopyBgTilemapBufferToVram(0); + CopyBgTilemapBufferToVram(1); + CopyBgTilemapBufferToVram(2); + CopyBgTilemapBufferToVram(3); + ShowBg(0); + ShowBg(1); + ShowBg(2); + ShowBg(3); +} + +static void LoadContestMonName(u8 monIndex) +{ + struct ContestPokemon *mon = &gContestMons[monIndex]; + u8 *str = gDisplayedStringBattle; + if (monIndex == gContestPlayerMonIndex) + str = StringCopy(gDisplayedStringBattle, gText_ColorDarkGrey); + + StringCopy(str, mon->nickname); + AddContestTextPrinter(monIndex, gDisplayedStringBattle, 0); + StringCopy(str, gText_Slash); + StringAppend(str, mon->trainerName); + AddContestTextPrinter(monIndex, gDisplayedStringBattle, 50); +} + +static void LoadAllContestMonNames(void) +{ + int i; + + for (i = 0; i < CONTESTANT_COUNT; i++) + LoadContestMonName(i); + + CopyBgTilemapBufferToVram(1); +} + +static void CB2_StartShowContestResults(void) +{ + gPaletteFade.bufferTransferDisabled = TRUE; + SetVBlankCallback(NULL); + AllocContestResults(); + InitContestResultsDisplay(); + ScanlineEffect_Clear(); + ResetPaletteFade(); + ResetSpriteData(); + ResetTasks(); + FreeAllSpritePalettes(); + LoadContestResultsBgGfx(); + LoadAllContestMonIconPalettes(); + LoadAllContestMonIcons(0, TRUE); + LoadAllContestMonNames(); + memset(sContestResults->data, 0, sizeof(*sContestResults->data)); + memset(sContestResults->monResults, 0, sizeof(*sContestResults->monResults)); + LoadContestResultSprites(); + TryCreateWirelessSprites(); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK); + gPaletteFade.bufferTransferDisabled = FALSE; + sContestResults->data->showResultsTaskId = CreateTask(Task_ShowContestResults, 5); + SetMainCallback2(CB2_ShowContestResults); + gBattle_WIN1H = 0x00F0; + gBattle_WIN1V = 0x80A0; + CreateTask(Task_SlideContestResultsBg, 20); + CalculateContestantsResultData(); + if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_WIRELESS) + gPaletteFade.bufferTransferDisabled = TRUE; + else + PlayBGM(MUS_CON_K); + + SetVBlankCallback(VBlankCB_ShowContestResults); +} + +static void CB2_ShowContestResults(void) +{ + AnimateSprites(); + BuildOamBuffer(); + RunTasks(); + UpdatePaletteFade(); + CopyBgTilemapBufferToVram(1); + CopyBgTilemapBufferToVram(2); +} + +static void VBlankCB_ShowContestResults(void) +{ + SetGpuReg(REG_OFFSET_BG0HOFS, gBattle_BG0_X); + SetGpuReg(REG_OFFSET_BG0VOFS, gBattle_BG0_Y); + SetGpuReg(REG_OFFSET_BG1HOFS, gBattle_BG1_X); + SetGpuReg(REG_OFFSET_BG1VOFS, gBattle_BG1_Y); + SetGpuReg(REG_OFFSET_BG2HOFS, gBattle_BG2_X); + SetGpuReg(REG_OFFSET_BG2VOFS, gBattle_BG2_Y); + SetGpuReg(REG_OFFSET_BG3HOFS, gBattle_BG3_X); + SetGpuReg(REG_OFFSET_BG3VOFS, gBattle_BG3_Y); + SetGpuReg(REG_OFFSET_WIN0H, gBattle_WIN0H); + SetGpuReg(REG_OFFSET_WIN0V, gBattle_WIN0V); + SetGpuReg(REG_OFFSET_WIN1H, gBattle_WIN1H); + SetGpuReg(REG_OFFSET_WIN1V, gBattle_WIN1V); + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); + ScanlineEffect_InitHBlankDmaTransfer(); +} + +#define tState data[0] +#define tTimer data[1] +#define tCounter data[2] + +static void Task_ShowContestResults(u8 taskId) +{ + u16 var; + + if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK) + { + switch (gTasks[taskId].tState) + { + case 0: + SaveLinkContestResults(); + if (gContestFinalStandings[gContestPlayerMonIndex] == 0) + { + IncrementGameStat(GAME_STAT_WON_LINK_CONTEST); + gSpecialVar_0x8005 = TVSHOW_CONTEST_LIVE_UPDATES; + InterviewBefore(); + if (gSpecialVar_Result != TRUE) + InterviewAfter(); + } + + TryGainNewFanFromCounter(FANCOUNTER_FINISHED_CONTEST); + sub_80DEDA8(gSpecialVar_ContestRank); + sub_80DEDA8(0xFE); + gUnknown_02039F5C = TRUE; + gUnknown_02039F5D = sub_80DEFA8(0xFE, 0); + var = VarGet(VAR_CONTEST_HALL_STATE); + VarSet(VAR_CONTEST_HALL_STATE, 0); + SetContinueGameWarpStatusToDynamicWarp(); + TrySavingData(SAVE_LINK); + ClearContinueGameWarpStatus2(); + VarSet(VAR_CONTEST_HALL_STATE, var); + gTasks[taskId].tState++; + break; + case 1: + gTasks[taskId].tState++; + if (!(gLinkContestFlags & LINK_CONTEST_FLAG_IS_WIRELESS)) + gTasks[taskId].tState = 100; + break; + case 2: + if (IsLinkTaskFinished()) + { + sub_800ADF8(); + gTasks[taskId].tState++; + } + return; + case 3: + if (IsLinkTaskFinished() == TRUE) + { + PlayBGM(MUS_CON_K); + gPaletteFade.bufferTransferDisabled = FALSE; + gTasks[taskId].tState++; + break; + } + return; + } + } + + if (!gPaletteFade.active) + { + gTasks[taskId].tState = 0; + if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK) + { + ShowLinkResultsTextBox(gText_CommunicationStandby); + gTasks[taskId].func = Task_WaitForLinkPartnersBeforeResults; + } + else + { + IncrementGameStat(GAME_STAT_ENTERED_CONTEST); + if (gContestFinalStandings[gContestPlayerMonIndex] == 0) + IncrementGameStat(GAME_STAT_WON_CONTEST); + + sub_80DEDA8(gSpecialVar_ContestRank); + sub_80DEDA8(0xFE); + gUnknown_02039F5C = TRUE; + gUnknown_02039F5D = sub_80DEFA8(0xFE, 0); + TryGainNewFanFromCounter(FANCOUNTER_FINISHED_CONTEST); + gTasks[taskId].func = Task_AnnouncePreliminaryResults; + } + } +} + +static void Task_WaitForLinkPartnersBeforeResults(u8 taskId) +{ + if (gReceivedRemoteLinkPlayers) + { + CreateTask(sub_80F5F14, 0); + gTasks[taskId].func = TaskDummy; + } +} + +static void sub_80F5F14(u8 taskId) +{ + SetTaskFuncWithFollowupFunc(taskId, sub_80FC998, sub_80F5F30); +} + +static void sub_80F5F30(u8 taskId) +{ + if (IsLinkTaskFinished()) + { + DestroyTask(taskId); + gTasks[sContestResults->data->showResultsTaskId].func = Task_AnnouncePreliminaryResults; + HideLinkResultsTextBox(); + } +} + +static void Task_AnnouncePreliminaryResults(u8 taskId) +{ + s16 x; + + if (gTasks[taskId].tState == 0) + { + CreateTask(Task_FlashStarsAndHearts, 20); + x = DrawResultsTextWindow(gText_AnnouncingResults, sContestResults->data->slidingTextBoxSpriteId); + StartTextBoxSlideIn(x, 144, 120, 1088); + gTasks[taskId].tState++; + } + else if (gTasks[taskId].tState == 1) + { + // Wait for "Announcing Results" text to leave + if (sContestResults->data->slidingTextBoxState == SLIDING_TEXT_OFFSCREEN) + { + gTasks[taskId].tTimer = 0; + gTasks[taskId].tState++; + } + } + else if (gTasks[taskId].tState == 2) + { + if (++gTasks[taskId].tTimer == 21) + { + gTasks[taskId].tTimer = 0; + gTasks[taskId].tState++; + } + } + else if (gTasks[taskId].tState == 3) + { + x = DrawResultsTextWindow(gText_PreliminaryResults, sContestResults->data->slidingTextBoxSpriteId); + StartTextBoxSlideIn(x, 144, -1, 1088); + gTasks[taskId].tState++; + } + else if (gTasks[taskId].tState == 4) + { + if (sContestResults->data->slidingTextBoxState == SLIDING_TEXT_ARRIVED) + { + gTasks[taskId].tState = 0; + gTasks[taskId].func = Task_ShowPreliminaryResults; + } + } +} + +static void Task_ShowPreliminaryResults(u8 taskId) +{ + switch (gTasks[taskId].tState) + { + case 0: + if (!sContestResults->data->pointsFlashing) + { + UpdateContestResultBars(FALSE, gTasks[taskId].tCounter++); + if (sContestResults->data->numBarsUpdating == 0) + gTasks[taskId].tState = 2; + else + gTasks[taskId].tState++; + } + break; + case 1: + if (sContestResults->data->numBarsUpdating == 0) + gTasks[taskId].tState = 0; + break; + case 2: + StartTextBoxSlideOut(1088); + gTasks[taskId].tState = 0; + gTasks[taskId].tCounter = 0; + gTasks[taskId].func = Task_AnnounceRound2Results; + break; + } +} + +static void Task_AnnounceRound2Results(u8 taskId) +{ + s16 x; + + if (sContestResults->data->slidingTextBoxState == SLIDING_TEXT_OFFSCREEN) + { + if (++gTasks[taskId].tTimer == 21) + { + gTasks[taskId].tTimer = 0; + x = DrawResultsTextWindow(gText_Round2Results, sContestResults->data->slidingTextBoxSpriteId); + StartTextBoxSlideIn(x, 144, -1, 1088); + } + } + else if (sContestResults->data->slidingTextBoxState == SLIDING_TEXT_ARRIVED) + { + gTasks[taskId].func = Task_ShowRound2Results; + } +} + +static void Task_ShowRound2Results(u8 taskId) +{ + switch (gTasks[taskId].tState) + { + case 0: + if (!sContestResults->data->pointsFlashing) + { + UpdateContestResultBars(TRUE, gTasks[taskId].tCounter++); + if (sContestResults->data->numBarsUpdating == 0) + gTasks[taskId].tState = 2; + else + gTasks[taskId].tState++; + } + break; + case 1: + if (sContestResults->data->numBarsUpdating == 0) + gTasks[taskId].tState = 0; + break; + case 2: + StartTextBoxSlideOut(1088); + gTasks[taskId].tState = 0; + gTasks[taskId].func = Task_AnnounceWinner; + break; + } +} + +// Task data for Task_DrawFinalStandingNumber +#define tFinalStanding data[0] +#define tMonIndex data[1] + +static void Task_AnnounceWinner(u8 taskId) +{ + int i; + switch (gTasks[taskId].tState) + { + case 0: + if (sContestResults->data->slidingTextBoxState == SLIDING_TEXT_OFFSCREEN) + gTasks[taskId].tState++; + break; + case 1: + if (++gTasks[taskId].tTimer == 31) + { + gTasks[taskId].tTimer = 0; + gTasks[taskId].tState++; + } + break; + case 2: + for (i = 0; i < CONTESTANT_COUNT; i++) + { + u8 newTaskId = CreateTask(Task_DrawFinalStandingNumber, 10); + gTasks[newTaskId].tFinalStanding = gContestFinalStandings[i]; + gTasks[newTaskId].tMonIndex = i; + } + gTasks[taskId].tState++; + break; + case 3: + if (sContestResults->data->numStandingsPrinted == CONTESTANT_COUNT) + { + if (++gTasks[taskId].tTimer == 31) + { + gTasks[taskId].tTimer = 0; + CreateTask(Task_StartHighlightWinnersBox, 10); + gTasks[taskId].tState++; + GET_CONTEST_WINNER_ID(i); + BounceMonIconInBox(i, 14); + } + } + break; + case 4: + if (++gTasks[taskId].tTimer == 21) + { + u8 winnerTextBuffer[100]; + s16 x; + gTasks[taskId].tTimer = 0; + GET_CONTEST_WINNER_ID(i); + StringCopy(gStringVar1, gContestMons[i].trainerName); + sub_81DB5AC(gStringVar1); + StringCopy(gStringVar2, gContestMons[i].nickname); + StringExpandPlaceholders(winnerTextBuffer, gText_ContestantsMonWon); + x = DrawResultsTextWindow(winnerTextBuffer, sContestResults->data->slidingTextBoxSpriteId); + StartTextBoxSlideIn(x, 144, -1, 1088); + gTasks[taskId].tState++; + } + break; + case 5: + gTasks[taskId].tState = 0; + gTasks[taskId].func = Task_ShowWinnerMonBanner; + break; + } +} + +static void Task_ShowWinnerMonBanner(u8 taskId) +{ + int i; + u8 spriteId; + u16 species; + u32 otId; + u32 personality; + const struct CompressedSpritePalette *pokePal; + + switch (gTasks[taskId].tState) + { + case 0: + gBattle_WIN0H = 0x00F0; + gBattle_WIN0V = 0x5050; + + GET_CONTEST_WINNER_ID(i); + species = gContestMons[i].species; + personality = gContestMons[i].personality; + otId = gContestMons[i].otId; + if (i == gContestPlayerMonIndex) + { + HandleLoadSpecialPokePic_2( + &gMonFrontPicTable[species], + gMonSpritesGfxPtr->sprites[1], + species, + personality); + } + else + { + HandleLoadSpecialPokePic_DontHandleDeoxys( + &gMonFrontPicTable[species], + gMonSpritesGfxPtr->sprites[1], + species, + personality); + } + + pokePal = GetMonSpritePalStructFromOtIdPersonality(species, otId, personality); + LoadCompressedSpritePalette(pokePal); + SetMultiuseSpriteTemplateToPokemon(species, B_POSITION_OPPONENT_LEFT); + gMultiuseSpriteTemplate.paletteTag = pokePal->tag; + spriteId = CreateSprite(&gMultiuseSpriteTemplate, 272, 80, 10); + gSprites[spriteId].data[1] = species; + gSprites[spriteId].oam.priority = 0; + gSprites[spriteId].callback = SpriteCB_WinnerMonSlideIn; + sContestResults->data->winnerMonSpriteId = spriteId; + LoadCompressedSpriteSheet(&sSpriteSheet_Confetti); + LoadCompressedSpritePalette(&sSpritePalette_Confetti); + CreateTask(Task_CreateConfetti, 10); + gTasks[taskId].tState++; + break; + case 1: + if (++gTasks[taskId].data[3] == 1) + { + u8 counter; + gTasks[taskId].data[3] = 0; + gTasks[taskId].tCounter += 2; + if (gTasks[taskId].tCounter > 32) + gTasks[taskId].tCounter = 32; + + counter = gTasks[taskId].tCounter; + gBattle_WIN0V = ((80 - counter) << 8) | (80 + counter); + if (counter == 32) + gTasks[taskId].tState++; + } + break; + case 2: + if (sContestResults->data->winnerMonSlidingState == SLIDING_MON_ENTERED) + gTasks[taskId].tState++; + break; + case 3: + if (++gTasks[taskId].tTimer == 121) + { + gTasks[taskId].tTimer = 0; + gSprites[sContestResults->data->winnerMonSpriteId].callback = SpriteCB_WinnerMonSlideOut; + gTasks[taskId].tState++; + } + break; + case 4: + if (sContestResults->data->winnerMonSlidingState == SLIDING_MON_EXITED) + { + u8 top = (gBattle_WIN0V >> 8); + top += 2; + if (top > 80) + top = 80; + + gBattle_WIN0V = (top << 8) | (160 - top); + if (top == 80) + gTasks[taskId].tState++; + } + break; + case 5: + if (sContestResults->data->winnerMonSlidingState == SLIDING_MON_EXITED) + { + sContestResults->data->destroyConfetti = TRUE; + gTasks[taskId].tState = 0; + gTasks[taskId].func = Task_SetSeenWinnerMon; + } + break; + } +} + +static void Task_SetSeenWinnerMon(u8 taskId) +{ + int i, nationalDexNum; + + if (JOY_NEW(A_BUTTON)) + { + if (!(gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK)) + { + for (i = 0; i < CONTESTANT_COUNT; i++) + { + nationalDexNum = SpeciesToNationalPokedexNum(gContestMons[i].species); + GetSetPokedexFlag(nationalDexNum, FLAG_SET_SEEN); + } + } + + gTasks[taskId].data[10] = 0; + gTasks[taskId].func = Task_TryDisconnectLinkPartners; + } +} + +static void Task_TryDisconnectLinkPartners(u8 taskId) +{ + if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK) + { + if (!gTasks[taskId].data[10]) + { + ShowLinkResultsTextBox(gText_CommunicationStandby); + sub_800AC34(); + gTasks[taskId].func = Task_WaitForLinkPartnersDisconnect; + } + } + else + { + gTasks[taskId].func = Task_TrySetContestInterviewData; + } +} + +static void Task_WaitForLinkPartnersDisconnect(u8 taskId) +{ + if (!gReceivedRemoteLinkPlayers) + { + if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_WIRELESS) + DestroyWirelessStatusIndicatorSprite(); + + HideLinkResultsTextBox(); + gTasks[taskId].func = Task_TrySetContestInterviewData; + } +} + +static void Task_TrySetContestInterviewData(u8 taskId) +{ + if (!(gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK)) + BravoTrainerPokemonProfile_BeforeInterview2(gContestFinalStandings[gContestPlayerMonIndex]); + + BeginHardwarePaletteFade(0xFF, 0, 0, 16, 0); + gTasks[taskId].func = Task_EndShowContestResults; +} + +static void Task_EndShowContestResults(u8 taskId) +{ + if (!gPaletteFade.active) + { + if (gTasks[taskId].tTimer == 0) + { + DestroyTask(sContestResults->data->highlightWinnerTaskId); + BlendPalettes(0x0000FFFF, 16, RGB_BLACK); + gTasks[taskId].tTimer++; + } + else if (gTasks[taskId].tTimer == 1) + { + BlendPalettes(0xFFFF0000, 16, RGB_BLACK); + gTasks[taskId].tTimer++; + } + else + { + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDY, 0); + DestroyTask(taskId); + FreeAllWindowBuffers(); + SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic); + FreeContestResults(); + } + } +} + +#undef tState +#undef tTimer +#undef tCounter + +static void Task_SlideContestResultsBg(u8 taskId) +{ + gBattle_BG3_X += 2; + gBattle_BG3_Y += 1; + if (gBattle_BG3_X > 255) + gBattle_BG3_X -= 255; + if (gBattle_BG3_Y > 255) + gBattle_BG3_Y -= 255; +} + +#define tDelay data[0] +#define tCoeff data[1] +#define tDecreasing data[2] + +static void Task_FlashStarsAndHearts(u8 taskId) +{ + if (++gTasks[taskId].tDelay == 2) + { + gTasks[taskId].tDelay = 0; + if (!gTasks[taskId].tDecreasing) + gTasks[taskId].tCoeff++; + else + gTasks[taskId].tCoeff--; + + if (gTasks[taskId].tCoeff == 16) + gTasks[taskId].tDecreasing = TRUE; + else if (gTasks[taskId].tCoeff == 0) + gTasks[taskId].tDecreasing = FALSE; + + BlendPalette(0x6B, 1, gTasks[taskId].tCoeff, RGB(30, 22, 11)); + BlendPalette(0x68, 1, gTasks[taskId].tCoeff, RGB_WHITE); + BlendPalette(0x6E, 1, gTasks[taskId].tCoeff, RGB(30, 29, 29)); + } + + if (gTasks[taskId].tCoeff == 0) + sContestResults->data->pointsFlashing = FALSE; + else + sContestResults->data->pointsFlashing = TRUE; +} + +static void LoadContestMonIcon(u16 species, u8 monIndex, u8 srcOffset, u8 useDmaNow, u32 personality) +{ + const u8 *iconPtr; + u16 var0, var1, frameNum; + + if (monIndex == gContestPlayerMonIndex) + frameNum = 1; + else + frameNum = 0; + + iconPtr = GetMonIconPtr(species, personality, frameNum); + iconPtr += srcOffset * 0x200 + 0x80; + if (useDmaNow) + { + RequestDma3Copy(iconPtr, (void *)BG_CHAR_ADDR(1) + monIndex * 0x200, 0x180, 1); + var0 = ((monIndex + 10) << 12); + var1 = (monIndex * 0x10 + 0x200); + WriteSequenceToBgTilemapBuffer(1, var1 | var0, 3, monIndex * 3 + 4, 4, 3, 17, 1); + } + else + { + RequestDma3Copy(iconPtr, (void *)BG_CHAR_ADDR(1) + monIndex * 0x200, 0x180, 1); + } +} + +static void LoadAllContestMonIcons(u8 srcOffset, bool8 useDmaNow) +{ + int i; + + for (i = 0; i < CONTESTANT_COUNT; i++) + LoadContestMonIcon(gContestMons[i].species, i, srcOffset, useDmaNow, gContestMons[i].personality); +} + +static void LoadAllContestMonIconPalettes(void) +{ + int i, species; + + for (i = 0; i < CONTESTANT_COUNT; i++) + { + species = gContestMons[i].species; + LoadPalette(gMonIconPalettes[gMonIconPaletteIndices[GetIconSpecies(species, 0)]], i * 0x10 + 0xA0, 0x20); + } +} + +static void TryCreateWirelessSprites(void) +{ + u16 sheet; + u8 spriteId; + + if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_WIRELESS) + { + LoadWirelessStatusIndicatorSpriteGfx(); + CreateWirelessStatusIndicatorSprite(8, 8); + gSprites[gWirelessStatusIndicatorSpriteId].subpriority = 1; + sheet = LoadSpriteSheet(&sUnknown_0858D8E0); + RequestDma3Fill(0xFFFFFFFF, (void *)BG_CHAR_ADDR(4) + sheet * 0x20, 0x80, 1); + spriteId = CreateSprite(&sSpriteTemplate_858D8C8, 8, 8, 0); + gSprites[spriteId].oam.objMode = ST_OAM_OBJ_WINDOW; + } +} + +// Functionally equivalent, the same except compiler generated variables from +// src are placed on different stack positions. + +#ifdef NONMATCHING +static s32 DrawResultsTextWindow(const u8 *text, u8 spriteId) +{ + u8 *windowTilesPtr; + u16 windowId; + int origWidth; + struct WindowTemplate windowTemplate; + int strWidth; + u8 *spriteTilePtrs[4]; + u8 *dst; + int i; + struct Sprite *sprite; + const u8 *src; // The culprit. + + memset(&windowTemplate, 0, sizeof(windowTemplate)); + windowTemplate.width = 30; + windowTemplate.height = 2; + windowId = AddWindow(&windowTemplate); + FillWindowPixelBuffer(windowId, PIXEL_FILL(1)); + + origWidth = GetStringWidth(1, text, 0); + strWidth = (origWidth + 9) / 8; + if (strWidth > 30) + strWidth = 30; + + AddTextPrinterParameterized3(windowId, 1, (strWidth * 8 - origWidth) / 2, 1, sContestLinkTextColors, -1, text); + windowTilesPtr = (u8 *)(GetWindowAttribute(windowId, WINDOW_TILE_DATA)); + src = (u8 *)(sUnknown_0858D6D0); + + sprite = &gSprites[spriteId]; + spriteTilePtrs[0] = (u8 *)(sprite->oam.tileNum * 32 + VRAM + 0x10000); + + for (i = 1; i < 4; i++) + spriteTilePtrs[i] = (void*)(gSprites[sprite->data[i - 1]].oam.tileNum * 32 + VRAM + 0x10000); + + for (i = 0; i < 4; i++) + CpuFill32(0, spriteTilePtrs[i], 0x400); + + dst = spriteTilePtrs[0]; + CpuCopy32(src, dst, 0x20); + CpuCopy32(src + 128, dst + 0x100, 0x20); + CpuCopy32(src + 128, dst + 0x200, 0x20); + CpuCopy32(src + 64, dst + 0x300, 0x20); + + for (i = 0; i < strWidth; i++) + { + dst = &spriteTilePtrs[(i + 1) / 8][((i + 1) % 8) * 32]; + CpuCopy32(src + 192, dst, 0x20); + CpuCopy32(windowTilesPtr, dst + 0x100, 0x20); + CpuCopy32(windowTilesPtr + 960, dst + 0x200, 0x20); + CpuCopy32(src + 224, dst + 0x300, 0x20); + windowTilesPtr += 0x20; + } + + dst = &spriteTilePtrs[(i + 1) / 8][((i + 1) % 8) * 32]; + CpuCopy32(src + 32, dst, 0x20); + CpuCopy32(src + 160, dst + 0x100, 0x20); + CpuCopy32(src + 160, dst + 0x200, 0x20); + CpuCopy32(src + 96, dst + 0x300, 0x20); + RemoveWindow(windowId); + + return (240 - (strWidth + 2) * 8) / 2; +} + +#else +NAKED +static s32 DrawResultsTextWindow(const u8 *text, u8 spriteId) +{ + asm_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, 0x44\n\ + adds r5, r0, 0\n\ + lsls r1, 24\n\ + lsrs r7, r1, 24\n\ + add r4, sp, 0x20\n\ + adds r0, r4, 0\n\ + movs r1, 0\n\ + movs r2, 0x8\n\ + bl memset\n\ + movs r0, 0x1E\n\ + strb r0, [r4, 0x3]\n\ + movs r0, 0x2\n\ + strb r0, [r4, 0x4]\n\ + adds r0, r4, 0\n\ + bl AddWindow\n\ + lsls r6, r0, 24\n\ + lsrs r4, r6, 24\n\ + adds r0, r4, 0\n\ + movs r1, 0x11\n\ + bl FillWindowPixelBuffer\n\ + movs r0, 0x1\n\ + adds r1, r5, 0\n\ + movs r2, 0\n\ + bl GetStringWidth\n\ + adds r2, r0, 0\n\ + adds r2, 0x9\n\ + cmp r2, 0\n\ + bge _080F6BC4\n\ + adds r2, 0x7\n\ +_080F6BC4:\n\ + asrs r2, 3\n\ + mov r10, r2\n\ + cmp r2, 0x1E\n\ + ble _080F6BD0\n\ + movs r1, 0x1E\n\ + mov r10, r1\n\ +_080F6BD0:\n\ + mov r1, r10\n\ + lsls r2, r1, 3\n\ + subs r2, r0\n\ + lsrs r0, r2, 31\n\ + adds r2, r0\n\ + asrs r2, 1\n\ + lsls r2, 24\n\ + lsrs r2, 24\n\ + ldr r0, =sContestLinkTextColors\n\ + str r0, [sp]\n\ + movs r0, 0x1\n\ + negs r0, r0\n\ + str r0, [sp, 0x4]\n\ + str r5, [sp, 0x8]\n\ + adds r0, r4, 0\n\ + movs r1, 0x1\n\ + movs r3, 0x1\n\ + bl AddTextPrinterParameterized3\n\ + adds r0, r4, 0\n\ + movs r1, 0x7\n\ + bl GetWindowAttribute\n\ + mov r9, r0\n\ + ldr r2, =sUnknown_0858D6D0\n\ + mov r8, r2\n\ + lsls r1, r7, 4\n\ + adds r1, r7\n\ + lsls r1, 2\n\ + ldr r3, =gSprites\n\ + adds r1, r3\n\ + ldrh r0, [r1, 0x4]\n\ + lsls r0, 22\n\ + lsrs r0, 17\n\ + ldr r2, =0x06010000\n\ + adds r0, r2\n\ + str r0, [sp, 0xC]\n\ + str r6, [sp, 0x38]\n\ + mov r7, sp\n\ + adds r7, 0x1C\n\ + str r7, [sp, 0x2C]\n\ + mov r0, r10\n\ + adds r0, 0x2\n\ + str r0, [sp, 0x30]\n\ + movs r5, 0\n\ + add r7, sp, 0x10\n\ + mov r12, r7\n\ + adds r6, r1, 0\n\ + adds r6, 0x2E\n\ + movs r4, 0x2\n\ +_080F6C34:\n\ + adds r0, r6, r5\n\ + movs r7, 0\n\ + ldrsh r1, [r0, r7]\n\ + lsls r0, r1, 4\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r3\n\ + ldrh r0, [r0, 0x4]\n\ + lsls r0, 22\n\ + lsrs r0, 17\n\ + adds r0, r2\n\ + mov r1, r12\n\ + adds r1, 0x4\n\ + mov r12, r1\n\ + subs r1, 0x4\n\ + stm r1!, {r0}\n\ + adds r5, 0x2\n\ + subs r4, 0x1\n\ + cmp r4, 0\n\ + bge _080F6C34\n\ + mov r7, r8\n\ + adds r7, 0x80\n\ + mov r2, r8\n\ + adds r2, 0x40\n\ + str r2, [sp, 0x28]\n\ + mov r0, r8\n\ + adds r0, 0x20\n\ + str r0, [sp, 0x3C]\n\ + mov r1, r8\n\ + adds r1, 0xA0\n\ + str r1, [sp, 0x40]\n\ + adds r2, 0x20\n\ + str r2, [sp, 0x34]\n\ + add r5, sp, 0xC\n\ + movs r6, 0\n\ + movs r4, 0x3\n\ +_080F6C7C:\n\ + str r6, [sp, 0x1C]\n\ + ldm r5!, {r1}\n\ + ldr r0, [sp, 0x2C]\n\ + ldr r2, =0x05000100\n\ + bl CpuSet\n\ + subs r4, 0x1\n\ + cmp r4, 0\n\ + bge _080F6C7C\n\ + ldr r5, [sp, 0xC]\n\ + ldr r6, =0x04000008\n\ + mov r0, r8\n\ + adds r1, r5, 0\n\ + adds r2, r6, 0\n\ + bl CpuSet\n\ + movs r0, 0x80\n\ + lsls r0, 1\n\ + adds r1, r5, r0\n\ + adds r0, r7, 0\n\ + adds r2, r6, 0\n\ + bl CpuSet\n\ + movs r2, 0x80\n\ + lsls r2, 2\n\ + adds r1, r5, r2\n\ + adds r0, r7, 0\n\ + adds r2, r6, 0\n\ + bl CpuSet\n\ + movs r7, 0xC0\n\ + lsls r7, 2\n\ + adds r1, r5, r7\n\ + ldr r0, [sp, 0x28]\n\ + adds r2, r6, 0\n\ + bl CpuSet\n\ + movs r4, 0\n\ + cmp r4, r10\n\ + bge _080F6D32\n\ + adds r7, r6, 0\n\ +_080F6CCE:\n\ + adds r6, r4, 0x1\n\ + adds r0, r6, 0\n\ + cmp r6, 0\n\ + bge _080F6CDA\n\ + adds r0, r4, 0\n\ + adds r0, 0x8\n\ +_080F6CDA:\n\ + asrs r0, 3\n\ + lsls r1, r0, 2\n\ + add r1, sp\n\ + adds r1, 0xC\n\ + lsls r0, 3\n\ + subs r0, r6, r0\n\ + lsls r0, 5\n\ + ldr r1, [r1]\n\ + adds r5, r1, r0\n\ + mov r0, r8\n\ + adds r0, 0xC0\n\ + adds r1, r5, 0\n\ + adds r2, r7, 0\n\ + bl CpuSet\n\ + movs r0, 0x80\n\ + lsls r0, 1\n\ + adds r1, r5, r0\n\ + mov r0, r9\n\ + adds r2, r7, 0\n\ + bl CpuSet\n\ + movs r0, 0xF0\n\ + lsls r0, 2\n\ + add r0, r9\n\ + movs r2, 0x80\n\ + lsls r2, 2\n\ + adds r1, r5, r2\n\ + adds r2, r7, 0\n\ + bl CpuSet\n\ + movs r0, 0xC0\n\ + lsls r0, 2\n\ + adds r1, r5, r0\n\ + mov r0, r8\n\ + adds r0, 0xE0\n\ + adds r2, r7, 0\n\ + bl CpuSet\n\ + movs r1, 0x20\n\ + add r9, r1\n\ + adds r4, r6, 0\n\ + cmp r4, r10\n\ + blt _080F6CCE\n\ +_080F6D32:\n\ + adds r2, r4, 0x1\n\ + adds r0, r2, 0\n\ + cmp r2, 0\n\ + bge _080F6D3E\n\ + adds r0, r4, 0\n\ + adds r0, 0x8\n\ +_080F6D3E:\n\ + asrs r0, 3\n\ + lsls r1, r0, 2\n\ + add r1, sp\n\ + adds r1, 0xC\n\ + lsls r0, 3\n\ + subs r0, r2, r0\n\ + lsls r0, 5\n\ + ldr r1, [r1]\n\ + adds r5, r1, r0\n\ + ldr r4, =0x04000008\n\ + ldr r0, [sp, 0x3C]\n\ + adds r1, r5, 0\n\ + adds r2, r4, 0\n\ + bl CpuSet\n\ + movs r2, 0x80\n\ + lsls r2, 1\n\ + adds r1, r5, r2\n\ + ldr r0, [sp, 0x40]\n\ + adds r2, r4, 0\n\ + bl CpuSet\n\ + movs r7, 0x80\n\ + lsls r7, 2\n\ + adds r1, r5, r7\n\ + ldr r0, [sp, 0x40]\n\ + adds r2, r4, 0\n\ + bl CpuSet\n\ + movs r0, 0xC0\n\ + lsls r0, 2\n\ + adds r1, r5, r0\n\ + ldr r0, [sp, 0x34]\n\ + adds r2, r4, 0\n\ + bl CpuSet\n\ + ldr r1, [sp, 0x38]\n\ + lsrs r0, r1, 24\n\ + bl RemoveWindow\n\ + ldr r2, [sp, 0x30]\n\ + lsls r1, r2, 3\n\ + movs r0, 0xF0\n\ + subs r0, r1\n\ + asrs r0, 1\n\ + add sp, 0x44\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r1}\n\ + bx r1\n\ + .pool"); +} +#endif // NONMATCHING + +static void LoadContestResultSprites(void) +{ + int i; + struct SpriteTemplate template; + u8 spriteIds[ARRAY_COUNT(sUnknown_0858D810)]; + + template = sSpriteTemplate_858D7F8; + for (i = 0; i < (int)ARRAY_COUNT(sUnknown_0858D810); i++) + LoadSpriteSheet(&sUnknown_0858D810[i]); + + LoadSpritePalette(&sUnknown_0858D850); + for (i = 0; i < (int)ARRAY_COUNT(sUnknown_0858D810); i++) + { + spriteIds[i] = CreateSprite(&template, 272, 144, 10); + template.tileTag++; + } + + gSprites[spriteIds[0]].data[0] = spriteIds[1]; + gSprites[spriteIds[0]].data[1] = spriteIds[2]; + gSprites[spriteIds[0]].data[2] = spriteIds[3]; + + gSprites[spriteIds[4]].data[0] = spriteIds[5]; + gSprites[spriteIds[4]].data[1] = spriteIds[6]; + gSprites[spriteIds[4]].data[2] = spriteIds[7]; + + sContestResults->data->slidingTextBoxSpriteId = spriteIds[0]; + sContestResults->data->slidingTextBoxState = SLIDING_TEXT_OFFSCREEN; + sContestResults->data->linkTextBoxSpriteId = spriteIds[4]; + HideLinkResultsTextBox(); +} + +#define sTargetX data[4] +#define sSlideOutTimer data[5] +#define sSlideIncrement data[6] +#define sDistance data[7] + +// If slideOutTimer is -1, it will not automatically slide out +static void StartTextBoxSlideIn(s16 x, u16 y, u16 slideOutTimer, u16 slideIncrement) +{ + struct Sprite *sprite = &gSprites[sContestResults->data->slidingTextBoxSpriteId]; + sprite->pos1.x = 272; + sprite->pos1.y = y; + sprite->pos2.x = 0; + sprite->pos2.y = 0; + sprite->sTargetX = x + 32; + sprite->sSlideOutTimer = slideOutTimer; + sprite->sSlideIncrement = slideIncrement; + sprite->sDistance = 0; + sprite->callback = SpriteCB_TextBoxSlideIn; + sContestResults->data->slidingTextBoxState = SLIDING_TEXT_ENTERING; +} + +static void StartTextBoxSlideOut(u16 slideIncrement) +{ + struct Sprite *sprite = &gSprites[sContestResults->data->slidingTextBoxSpriteId]; + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.y = 0; + sprite->pos2.x = 0; + sprite->sSlideIncrement = slideIncrement; + sprite->sDistance = 0; + sprite->callback = SpriteCB_TextBoxSlideOut; + sContestResults->data->slidingTextBoxState = SLIDING_TEXT_EXITING; +} + +static void EndTextBoxSlideOut(struct Sprite *sprite) +{ + sprite->pos1.x = 272; + sprite->pos1.y = 144; + sprite->pos2.y = 0; + sprite->pos2.x = 0; + sprite->callback = SpriteCallbackDummy; + sContestResults->data->slidingTextBoxState = SLIDING_TEXT_OFFSCREEN; +} + +static void SpriteCB_TextBoxSlideIn(struct Sprite *sprite) +{ + int i; + + s16 delta = sprite->sDistance + sprite->sSlideIncrement; + sprite->pos1.x -= delta >> 8; + sprite->sDistance += sprite->sSlideIncrement; + sprite->sDistance &= 0xFF; + + // Prevent overshooting target + if (sprite->pos1.x < sprite->sTargetX) + sprite->pos1.x = sprite->sTargetX; + + for (i = 0; i < 3; i++) + { + struct Sprite *sprite2 = &gSprites[sprite->data[i]]; + sprite2->pos1.x = sprite->pos1.x + sprite->pos2.x + (i + 1) * 64; + } + + if (sprite->pos1.x == sprite->sTargetX) + sprite->callback = SpriteCB_EndTextBoxSlideIn; +} + +static void SpriteCB_EndTextBoxSlideIn(struct Sprite *sprite) +{ + sContestResults->data->slidingTextBoxState = SLIDING_TEXT_ARRIVED; + if ((u16)sprite->sSlideOutTimer != 0xFFFF) + { + if (--sprite->sSlideOutTimer == -1) + StartTextBoxSlideOut(sprite->sSlideIncrement); + } +} + +static void SpriteCB_TextBoxSlideOut(struct Sprite *sprite) +{ + int i; + s16 delta; + + delta = sprite->sDistance + sprite->sSlideIncrement; + sprite->pos1.x -= delta >> 8; + sprite->sDistance += sprite->sSlideIncrement; + sprite->sDistance &= 0xFF; + for (i = 0; i < 3; i++) + { + struct Sprite *sprite2 = &gSprites[sprite->data[i]]; + sprite2->pos1.x = sprite->pos1.x + sprite->pos2.x + (i + 1) * 64; + } + + if (sprite->pos1.x + sprite->pos2.x < -224) + EndTextBoxSlideOut(sprite); +} + +static void ShowLinkResultsTextBox(const u8 *text) +{ + int i; + u16 x; + struct Sprite *sprite; + + x = DrawResultsTextWindow(text, sContestResults->data->linkTextBoxSpriteId); + sprite = &gSprites[sContestResults->data->linkTextBoxSpriteId]; + sprite->pos1.x = x + 32; + sprite->pos1.y = 80; + sprite->invisible = FALSE; + for (i = 0; i < 3; i++) + { + gSprites[sprite->data[i]].pos1.x = sprite->pos1.x + sprite->pos2.x + (i + 1) * 64; + gSprites[sprite->data[i]].pos1.y = sprite->pos1.y; + gSprites[sprite->data[i]].invisible = FALSE; + } + + gBattle_WIN0H = 0x00F0; + gBattle_WIN0V = ((sprite->pos1.y - 16) << 8) | (sprite->pos1.y + 16); + SetGpuReg(REG_OFFSET_WININ, WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR + | WININ_WIN0_BG1 | WININ_WIN0_BG2 | WININ_WIN0_BG3 | WININ_WIN0_OBJ | WININ_WIN0_CLR); +} + +static void HideLinkResultsTextBox(void) +{ + int i; + struct Sprite *sprite; + + sprite = &gSprites[sContestResults->data->linkTextBoxSpriteId]; + sprite->invisible = TRUE; + for (i = 0; i < 3; i++) + gSprites[sprite->data[i]].invisible = TRUE; + + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + SetGpuReg(REG_OFFSET_WIN0H, gBattle_WIN0H); + SetGpuReg(REG_OFFSET_WIN0V, gBattle_WIN0V); + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR + | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR); +} + +static void LoadContestResultsTilemaps(void) +{ + u8 palette; + int x, y; + + x = 5; + y = 1; + if (gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK) + { + CopyToBgTilemapBufferRect(2, gLinkContestResults_Tilemap, 5, 1, 5, 2); + x = 10; + } + else if (gSpecialVar_ContestRank == CONTEST_RANK_NORMAL) + { + CopyToBgTilemapBufferRect(2, gNormalContestResults_Tilemap, 5, 1, 10, 2); + x = 15; + } + else if (gSpecialVar_ContestRank == CONTEST_RANK_SUPER) + { + CopyToBgTilemapBufferRect(2, gSuperContestResults_Tilemap, 5, 1, 10, 2); + x = 15; + } + else if (gSpecialVar_ContestRank == CONTEST_RANK_HYPER) + { + CopyToBgTilemapBufferRect(2, gHyperContestResults_Tilemap, 5, 1, 10, 2); + x = 15; + } + else // CONTEST_RANK_MASTER + { + CopyToBgTilemapBufferRect(2, gMasterContestResults_Tilemap, 5, 1, 10, 2); + x = 15; + } + + if (gSpecialVar_ContestCategory == CONTEST_CATEGORY_COOL) + { + palette = 0; + CopyToBgTilemapBufferRect(2, gCoolContestResults_Tilemap, x, y, 5, 2); + } + else if (gSpecialVar_ContestCategory == CONTEST_CATEGORY_BEAUTY) + { + palette = 1; + CopyToBgTilemapBufferRect(2, gBeautyContestResults_Tilemap, x, y, 5, 2); + } + else if (gSpecialVar_ContestCategory == CONTEST_CATEGORY_CUTE) + { + palette = 2; + CopyToBgTilemapBufferRect(2, gCuteContestResults_Tilemap, x, y, 5, 2); + } + else if (gSpecialVar_ContestCategory == CONTEST_CATEGORY_SMART) + { + palette = 3; + CopyToBgTilemapBufferRect(2, gSmartContestResults_Tilemap, x, y, 5, 2); + } + else // CONTEST_CATEGORY_TOUGH + { + palette = 4; + CopyToBgTilemapBufferRect(2, gToughContestResults_Tilemap, x, y, 5, 2); + } + + x += 5; + CopyToBgTilemapBufferRect(2, gContestResults_Tilemap, x, y, 6, 2); + CopyToBgTilemapBufferRect_ChangePalette(2, sContestResults->tilemapBuffers[2], 0, 0, 32, 4, palette); +} + +// Represented on results board as stars +static u8 GetNumPreliminaryPoints(u8 monIndex, bool8 capPoints) +{ + u32 condition = gContestMonConditions[monIndex] << 16; + u32 numStars = condition / 0x3F; + + if (numStars & 0xFFFF) + numStars += 0x10000; + + numStars >>= 16; + if (numStars == 0 && condition) + numStars = 1; + + if (capPoints && numStars > 10) + numStars = 10; + + return numStars; +} + +// Represented on results board as hearts +static s8 GetNumRound2Points(u8 monIndex, bool8 capPoints) +{ + u32 r4, numHearts; + s16 results; + s8 points; + + results = gContestMonRound2Points[monIndex]; + if (results < 0) + r4 = -results << 16; + else + r4 = results << 16; + + numHearts = r4 / 80; + if (numHearts & 0xFFFF) + numHearts += 0x10000; + + numHearts >>= 16; + if (numHearts == 0 && r4 != 0) + numHearts = 1; + + if (capPoints && numHearts > 10) + numHearts = 10; + + if (gContestMonRound2Points[monIndex] < 0) + points = -numHearts; + else + points = numHearts; + + return points; +} + +#define tState data[10] + +static void Task_DrawFinalStandingNumber(u8 taskId) +{ + u16 firstTileNum; + + if (gTasks[taskId].tState == 0) + { + gTasks[taskId].data[11] = (3 - gTasks[taskId].tFinalStanding) * 40; + gTasks[taskId].tState++; + } + else if (gTasks[taskId].tState == 1) + { + if (--gTasks[taskId].data[11] == -1) + { + firstTileNum = gTasks[taskId].tFinalStanding * 2 + 0x5043; + WriteSequenceToBgTilemapBuffer(2, firstTileNum, 1, gTasks[taskId].tMonIndex * 3 + 5, 2, 1, 17, 1); + WriteSequenceToBgTilemapBuffer(2, firstTileNum + 0x10, 1, gTasks[taskId].tMonIndex * 3 + 6, 2, 1, 17, 1); + sContestResults->data->numStandingsPrinted++; + DestroyTask(taskId); + PlaySE(SE_JYUNI); + } + } +} + +#undef tFinalStanding +#undef tMonIndex +#undef tState + +static void Task_StartHighlightWinnersBox(u8 taskId) +{ + int i; + GET_CONTEST_WINNER_ID(i); + CopyToBgTilemapBufferRect_ChangePalette(2, i * 0xC0 + 0x100 + sContestResults->tilemapBuffers[2], 0, i * 3 + 4, 32, 3, 9); + gTasks[taskId].data[10] = i; + gTasks[taskId].data[12] = 1; + gTasks[taskId].func = Task_HighlightWinnersBox; + sContestResults->data->highlightWinnerTaskId = taskId; +} + +static void Task_HighlightWinnersBox(u8 taskId) +{ + if (++gTasks[taskId].data[11] == 1) + { + gTasks[taskId].data[11] = 0; + BlendPalette(0x91, 1, gTasks[taskId].data[12], RGB(13, 28, 27)); + if (gTasks[taskId].data[13] == 0) + { + if (++gTasks[taskId].data[12] == 16) + gTasks[taskId].data[13] = 1; + } + else + { + if (--gTasks[taskId].data[12] == 0) + gTasks[taskId].data[13] = 0; + } + } +} + +static void SpriteCB_WinnerMonSlideIn(struct Sprite *sprite) +{ + if (sprite->data[0] < 10) + { + if (++sprite->data[0] == 10) + { + PlayCry1(sprite->data[1], 0); + sprite->data[1] = 0; + } + } + else + { + s16 delta = sprite->data[1] + 0x600; + sprite->pos1.x -= delta >> 8; + sprite->data[1] += 0x600; + sprite->data[1] &= 0xFF; + if (sprite->pos1.x < 120) + sprite->pos1.x = 120; + + if (sprite->pos1.x == 120) + { + sprite->callback = SpriteCallbackDummy; + sprite->data[1] = 0; + sContestResults->data->winnerMonSlidingState = SLIDING_MON_ENTERED; + } + } +} + +static void SpriteCB_WinnerMonSlideOut(struct Sprite *sprite) +{ + s16 delta = sprite->data[1] + 0x600; + sprite->pos1.x -= delta >> 8; + sprite->data[1] += + 0x600; + sprite->data[1] &= 0xFF; + if (sprite->pos1.x < -32) + { + sprite->callback = SpriteCallbackDummy; + sprite->invisible = TRUE; + sContestResults->data->winnerMonSlidingState = SLIDING_MON_EXITED; + } +} + +static void Task_CreateConfetti(u8 taskId) +{ + if (++gTasks[taskId].data[0] == 5) + { + gTasks[taskId].data[0] = 0; + if (sContestResults->data->confettiCount < 40) + { + u8 spriteId = CreateSprite(&sSpriteTemplate_Confetti, (Random() % 240) - 20, 44, 5); + gSprites[spriteId].data[0] = Random() % 512; + gSprites[spriteId].data[1] = (Random() % 24) + 16; + gSprites[spriteId].data[2] = (Random() % 256) + 48; + gSprites[spriteId].oam.tileNum += Random() % 17; + sContestResults->data->confettiCount++; + } + } + + if (sContestResults->data->destroyConfetti) + DestroyTask(taskId); +} + +static void SpriteCB_Confetti(struct Sprite *sprite) +{ + s16 delta; + + sprite->data[3] += sprite->data[0]; + sprite->pos2.x = Sin(sprite->data[3] >> 8, sprite->data[1]); + delta = sprite->data[4] + sprite->data[2]; + sprite->pos1.x += delta >> 8; + sprite->data[4] += sprite->data[2]; + sprite->data[4] &= 0xff; + + sprite->pos1.y++; + if (sContestResults->data->destroyConfetti) + sprite->invisible = TRUE; + + if (sprite->pos1.x > 248 || sprite->pos1.y > 116) + { + DestroySprite(sprite); + sContestResults->data->confettiCount--; + } +} + +#define tMonIndex data[0] +#define tNumFrames data[1] +#define tSpecies data[2] +#define tTimer data[10] +#define tBounced data[11] + +static void BounceMonIconInBox(u8 monIndex, u8 numFrames) +{ + u8 taskId = CreateTask(Task_BounceMonIconInBox, 8); + gTasks[taskId].tMonIndex = monIndex; + gTasks[taskId].tNumFrames = numFrames; + gTasks[taskId].tSpecies = gContestMons[monIndex].species; +} + +static void Task_BounceMonIconInBox(u8 taskId) +{ + u8 monIndex = gTasks[taskId].tMonIndex; + if (gTasks[taskId].tTimer++ == gTasks[taskId].tNumFrames) + { + gTasks[taskId].tTimer = 0; + LoadContestMonIcon(gTasks[taskId].tSpecies, monIndex, gTasks[taskId].tBounced, FALSE, gContestMons[monIndex].personality); + gTasks[taskId].tBounced ^= 1; + } +} + +#undef tMonIndex +#undef tNumFrames +#undef tSpecies +#undef tTimer +#undef tBounced + +static void CalculateContestantsResultData(void) +{ + int i, relativePoints; + u32 barLength; + s16 highestPoints; + s8 round2Points; + + highestPoints = gContestMonTotalPoints[0]; + for (i = 1; i < CONTESTANT_COUNT; i++) + { + if (highestPoints < gContestMonTotalPoints[i]) + highestPoints = gContestMonTotalPoints[i]; + } + + if (highestPoints < 0) + { + highestPoints = gContestMonTotalPoints[0]; + for (i = 1; i < CONTESTANT_COUNT; i++) + { + if (highestPoints > gContestMonTotalPoints[i]) + highestPoints = gContestMonTotalPoints[i]; + } + } + + for (i = 0; i < CONTESTANT_COUNT; i++) + { + relativePoints = (gContestMonConditions[i] * 1000) / abs(highestPoints); + if (relativePoints % 10 > 4) + relativePoints += 10; + (*sContestResults->monResults)[i].relativePreliminaryPoints = relativePoints / 10; + + relativePoints = (abs(gContestMonRound2Points[i]) * 1000) / abs(highestPoints); + if (relativePoints % 10 > 4) + relativePoints += 10; + (*sContestResults->monResults)[i].relativeRound2Points = relativePoints / 10; + + if (gContestMonRound2Points[i] < 0) + (*sContestResults->monResults)[i].lostPoints = TRUE; + + barLength = ((*sContestResults->monResults)[i].relativePreliminaryPoints * 0x5800) / 100; + if ((barLength & 0xFF) > 0x7F) + barLength += 0x100; + (*sContestResults->monResults)[i].barLengthPreliminary = barLength >> 8; + + barLength = ((*sContestResults->monResults)[i].relativeRound2Points * 0x5800) / 100; + if ((barLength & 0xFF) > 0x7F) + barLength += 0x100; + (*sContestResults->monResults)[i].barLengthRound2 = barLength >> 8; + + (*sContestResults->monResults)[i].numStars = GetNumPreliminaryPoints(i, TRUE); + round2Points = GetNumRound2Points(i, TRUE); + (*sContestResults->monResults)[i].numHearts = abs(round2Points); + + if (gContestFinalStandings[i]) + { + s16 barLengthPreliminary = (*sContestResults->monResults)[i].barLengthPreliminary; + s16 barLengthRound2 = (*sContestResults->monResults)[i].barLengthRound2; + + if ((*sContestResults->monResults)[i].lostPoints) + barLengthRound2 *= -1; + + if (barLengthPreliminary + barLengthRound2 == MAX_BAR_LENGTH + 1) + { + if (barLengthRound2 > 0) + (*sContestResults->monResults)[i].barLengthRound2--; + else if (barLengthPreliminary > 0) + (*sContestResults->monResults)[i].barLengthPreliminary--; + } + } + } +} + +#define tMonId data[0] +#define tTarget data[1] +#define tDecreasing data[2] + +static void UpdateContestResultBars(bool8 isRound2, u8 numUpdates) +{ + int i, taskId; + u32 target; + u8 numIncreasing = 0, numDecreasing = 0; + + if (!isRound2) + { + for (i = 0; i < CONTESTANT_COUNT; i++) + { + u8 numStars = (*sContestResults->monResults)[i].numStars; + if (numUpdates < numStars) + { + FillBgTilemapBufferRect_Palette0(1, 0x60B3, ((19 + numStars) - numUpdates) - 1, i * 3 + 5, 1, 1); + taskId = CreateTask(Task_UpdateContestResultBar, 10); + + target = (((*sContestResults->monResults)[i].barLengthPreliminary << 16) / (*sContestResults->monResults)[i].numStars) * (numUpdates + 1); + if ((target & 0xFFFF) > 0x7FFF) + target += 0x10000; + + gTasks[taskId].tMonId = i; + gTasks[taskId].tTarget = target >> 16; + sContestResults->data->numBarsUpdating++; + numIncreasing++; + } + } + } + else + { + for (i = 0; i < CONTESTANT_COUNT; i++) + { + s8 numHearts = (*sContestResults->monResults)[i].numHearts; + u32 tile = (*sContestResults->monResults)[i].lostPoints ? 0x60A5 : 0x60A3; + if (numUpdates < numHearts) + { + FillBgTilemapBufferRect_Palette0(1, tile, ((19 + numHearts) - numUpdates) - 1, i * 3 + 6, 1, 1); + taskId = CreateTask(Task_UpdateContestResultBar, 10); + + target = (((*sContestResults->monResults)[i].barLengthRound2 << 16) / (*sContestResults->monResults)[i].numHearts) * (numUpdates + 1); + if ((target & 0xFFFF) > 0x7FFF) + target += 0x10000; + + gTasks[taskId].tMonId = i; + if ((*sContestResults->monResults)[i].lostPoints) + { + gTasks[taskId].tDecreasing = TRUE; + numDecreasing++; + } + else + { + numIncreasing++; + } + + if ((*sContestResults->monResults)[i].lostPoints) + gTasks[taskId].tTarget = -(target >> 16) + (*sContestResults->monResults)[i].barLengthPreliminary; + else + gTasks[taskId].tTarget = (target >> 16) + (*sContestResults->monResults)[i].barLengthPreliminary; + + sContestResults->data->numBarsUpdating++; + } + } + } + + if (numDecreasing) + PlaySE(SE_BOO); + if (numIncreasing) + PlaySE(SE_PIN); +} + +static void Task_UpdateContestResultBar(u8 taskId) +{ + int i; + bool32 minMaxReached = FALSE; + bool32 targetReached = FALSE; + u8 monId = gTasks[taskId].tMonId; + s16 target = gTasks[taskId].tTarget; + s16 decreasing = gTasks[taskId].tDecreasing; + + if (decreasing) + { + if (sContestResults->data->unkC[monId] <= 0) + minMaxReached = TRUE; + } + else + { + if (sContestResults->data->unkC[monId] > MAX_BAR_LENGTH) + minMaxReached = TRUE; + } + + if (sContestResults->data->unkC[monId] == target) + targetReached = TRUE; + + if (!targetReached) + { + if (minMaxReached) + sContestResults->data->unkC[monId] = target; + else if (decreasing) + sContestResults->data->unkC[monId] = sContestResults->data->unkC[monId] - 1; + else + sContestResults->data->unkC[monId] = sContestResults->data->unkC[monId] + 1; + } + + if (!minMaxReached && !targetReached) + { + u8 var0; + u16 tileNum; + for (i = 0; i < 11; i++) + { + if (sContestResults->data->unkC[monId] >= (i + 1) * 8) + var0 = 8; + else if (sContestResults->data->unkC[monId] >= i * 8) + var0 = sContestResults->data->unkC[monId] % 8; + else + var0 = 0; + + if (var0 < 4) + tileNum = 0x504C + var0; + else + tileNum = 0x5057 + var0; + + FillBgTilemapBufferRect_Palette0(2, tileNum, i + 7, monId * 3 + 6, 1, 1); + } + } + + if (targetReached) + { + sContestResults->data->numBarsUpdating--; + DestroyTask(taskId); + } +} + +#undef tMonId +#undef tTarget +#undef tDecreasing + +static void AllocContestResults(void) +{ + sContestResults = AllocZeroed(sizeof(*sContestResults)); + sContestResults->data = AllocZeroed(sizeof(*sContestResults->data)); + sContestResults->monResults = AllocZeroed(sizeof(*sContestResults->monResults)); + sContestResults->unusedBg = AllocZeroed(BG_SCREEN_SIZE); + sContestResults->tilemapBuffers[0] = AllocZeroed(BG_SCREEN_SIZE); + sContestResults->tilemapBuffers[1] = AllocZeroed(BG_SCREEN_SIZE); + sContestResults->tilemapBuffers[2] = AllocZeroed(BG_SCREEN_SIZE); + sContestResults->tilemapBuffers[3] = AllocZeroed(BG_SCREEN_SIZE); + sContestResults->unused = AllocZeroed(0x1000); + AllocateMonSpritesGfx(); +} + +static void FreeContestResults(void) +{ + FREE_AND_SET_NULL(sContestResults->data); + FREE_AND_SET_NULL(sContestResults->monResults); + FREE_AND_SET_NULL(sContestResults->unusedBg); + FREE_AND_SET_NULL(sContestResults->tilemapBuffers[0]); + FREE_AND_SET_NULL(sContestResults->tilemapBuffers[1]); + FREE_AND_SET_NULL(sContestResults->tilemapBuffers[2]); + FREE_AND_SET_NULL(sContestResults->tilemapBuffers[3]); + FREE_AND_SET_NULL(sContestResults->unused); + FREE_AND_SET_NULL(sContestResults); + FreeMonSpritesGfx(); +} + +static void AddContestTextPrinter(int windowId, u8 *str, int x) +{ + struct TextPrinterTemplate textPrinter; + textPrinter.currentChar = str; + textPrinter.windowId = windowId; + textPrinter.fontId = 7; + textPrinter.x = x; + textPrinter.y = 2; + textPrinter.currentX = x; + textPrinter.currentY = 2; + textPrinter.letterSpacing = 0; + textPrinter.lineSpacing = 0; + textPrinter.unk = 0; + textPrinter.fgColor = 1; + textPrinter.bgColor = 0; + textPrinter.shadowColor = 8; + AddTextPrinter(&textPrinter, 0, NULL); + PutWindowTilemap(windowId); +} + +void TryEnterContestMon(void) +{ + u8 eligibility = GetContestEntryEligibility(&gPlayerParty[gContestMonPartyIndex]); + + // Nonzero eligibility can still be non-eligibile, if mon is fainted or egg + if (eligibility) + { + sub_80DAB8C(gSpecialVar_ContestCategory, gSpecialVar_ContestRank); + sub_80DB09C(gSpecialVar_ContestCategory); + } + + gSpecialVar_Result = eligibility; +} + +u16 HasMonWonThisContestBefore(void) +{ + u16 hasRankRibbon = FALSE; + struct Pokemon *mon = &gPlayerParty[gContestMonPartyIndex]; + switch (gSpecialVar_ContestCategory) + { + case CONTEST_CATEGORY_COOL: + if (GetMonData(mon, MON_DATA_COOL_RIBBON) > gSpecialVar_ContestRank) + hasRankRibbon = TRUE; + break; + case CONTEST_CATEGORY_BEAUTY: + if (GetMonData(mon, MON_DATA_BEAUTY_RIBBON) > gSpecialVar_ContestRank) + hasRankRibbon = TRUE; + break; + case CONTEST_CATEGORY_CUTE: + if (GetMonData(mon, MON_DATA_CUTE_RIBBON) > gSpecialVar_ContestRank) + hasRankRibbon = TRUE; + break; + case CONTEST_CATEGORY_SMART: + if (GetMonData(mon, MON_DATA_SMART_RIBBON) > gSpecialVar_ContestRank) + hasRankRibbon = TRUE; + break; + case CONTEST_CATEGORY_TOUGH: + if (GetMonData(mon, MON_DATA_TOUGH_RIBBON) > gSpecialVar_ContestRank) + hasRankRibbon = TRUE; + break; + } + + return hasRankRibbon; +} + +void GiveMonContestRibbon(void) +{ + u8 ribbonData; + + if (gContestFinalStandings[gContestPlayerMonIndex] != 0) + return; + + switch (gSpecialVar_ContestCategory) + { + case CONTEST_CATEGORY_COOL: + ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_COOL_RIBBON); + if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4) + { + ribbonData++; + SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_COOL_RIBBON, &ribbonData); + if (GetRibbonCount(&gPlayerParty[gContestMonPartyIndex]) > NUM_CUTIES_RIBBONS) + TryPutSpotTheCutiesOnAir(&gPlayerParty[gContestMonPartyIndex], MON_DATA_COOL_RIBBON); + } + break; + case CONTEST_CATEGORY_BEAUTY: + ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_BEAUTY_RIBBON); + if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4) + { + ribbonData++; + SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_BEAUTY_RIBBON, &ribbonData); + if (GetRibbonCount(&gPlayerParty[gContestMonPartyIndex]) > NUM_CUTIES_RIBBONS) + TryPutSpotTheCutiesOnAir(&gPlayerParty[gContestMonPartyIndex], MON_DATA_BEAUTY_RIBBON); + } + break; + case CONTEST_CATEGORY_CUTE: + ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_CUTE_RIBBON); + if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4) + { + ribbonData++; + SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_CUTE_RIBBON, &ribbonData); + if (GetRibbonCount(&gPlayerParty[gContestMonPartyIndex]) > NUM_CUTIES_RIBBONS) + TryPutSpotTheCutiesOnAir(&gPlayerParty[gContestMonPartyIndex], MON_DATA_CUTE_RIBBON); + } + break; + case CONTEST_CATEGORY_SMART: + ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_SMART_RIBBON); + if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4) + { + ribbonData++; + SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_SMART_RIBBON, &ribbonData); + if (GetRibbonCount(&gPlayerParty[gContestMonPartyIndex]) > NUM_CUTIES_RIBBONS) + TryPutSpotTheCutiesOnAir(&gPlayerParty[gContestMonPartyIndex], MON_DATA_SMART_RIBBON); + } + break; + case CONTEST_CATEGORY_TOUGH: + ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_TOUGH_RIBBON); + if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4) + { + ribbonData++; + SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_TOUGH_RIBBON, &ribbonData); + if (GetRibbonCount(&gPlayerParty[gContestMonPartyIndex]) > NUM_CUTIES_RIBBONS) + TryPutSpotTheCutiesOnAir(&gPlayerParty[gContestMonPartyIndex], MON_DATA_TOUGH_RIBBON); + } + break; + } +} + +void BufferContestantTrainerName(void) +{ + StringCopy(gStringVar1, gContestMons[gSpecialVar_0x8006].trainerName); + sub_81DB5AC(gStringVar1); +} + +void BufferContestantMonNickname(void) +{ + StringCopy(gStringVar3, gContestMons[gSpecialVar_0x8006].nickname); +} + +// Unused script special +void GetContestMonConditionRanking(void) +{ + u8 i, rank; + + for (i = 0, rank = 0; i < CONTESTANT_COUNT; i++) + { + if (gContestMonConditions[gSpecialVar_0x8006] < gContestMonConditions[i]) + rank++; + } + + gSpecialVar_0x8004 = rank; +} + +void GetContestMonCondition(void) +{ + gSpecialVar_0x8004 = gContestMonConditions[gSpecialVar_0x8006]; +} + +void GetContestWinnerId(void) +{ + u8 i; + GET_CONTEST_WINNER_ID(i); + gSpecialVar_0x8005 = i; +} + +void BufferContestWinnerTrainerName(void) +{ + u8 i; + GET_CONTEST_WINNER_ID(i); + StringCopy(gStringVar3, gContestMons[i].trainerName); + sub_81DB5AC(gStringVar3); +} + +void BufferContestWinnerMonName(void) +{ + u8 i; + GET_CONTEST_WINNER_ID(i); + StringCopy(gStringVar1, gContestMons[i].nickname); +} + +void CB2_SetStartContestCallback(void) +{ + SetMainCallback2(CB2_StartContest); +} + +static void Task_StartContest(u8 taskId) +{ + if (!gPaletteFade.active) + { + DestroyTask(taskId); + SetMainCallback2(CB2_SetStartContestCallback); + } +} + +void StartContest(void) +{ + ScriptContext2_Enable(); + CreateTask(Task_StartContest, 10); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); +} + +void BufferContestantMonSpecies(void) +{ + gSpecialVar_0x8004 = gContestMons[gSpecialVar_0x8006].species; +} + +static void Task_StartShowContestResults(u8 taskId) +{ + if (!gPaletteFade.active) + { + DestroyTask(taskId); + SetMainCallback2(CB2_StartShowContestResults); + } +} + +void ShowContestResults(void) +{ + ScriptContext2_Enable(); + CreateTask(Task_StartShowContestResults, 10); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); +} + +void GetContestPlayerId(void) +{ + gSpecialVar_0x8004 = gContestPlayerMonIndex; +} + +void ContestLinkTransfer(u8 taskId) +{ + u8 newTaskId; + ScriptContext2_Enable(); + newTaskId = CreateTask(sub_80FC580, 0); + SetTaskFuncWithFollowupFunc(newTaskId, sub_80FC580, sub_80F8508); + gTasks[newTaskId].data[9] = taskId; +} + +static void sub_80F8508(u8 taskId) +{ + if (gLinkContestFlags & LINK_CONTEST_FLAG_HAS_RS_PLAYER) + { + sub_80DA8C8(gContestMonPartyIndex); + SetTaskFuncWithFollowupFunc(taskId, sub_80FC6BC, sub_80F8568); + } + else + { + sub_80DA8C8(gContestMonPartyIndex); + gTasks[taskId].func = sub_81D9DE4; + } +} + +static void sub_80F8568(u8 taskId) +{ + SetTaskFuncWithFollowupFunc(taskId, sub_80FC804, sub_80F8584); +} + +static void sub_80F8584(u8 taskId) +{ + SetTaskFuncWithFollowupFunc(taskId, sub_80FCE48, sub_80F85A0); +} + +static void sub_80F85A0(u8 taskId) +{ + SetTaskFuncWithFollowupFunc(taskId, sub_80FC894, sub_80F85BC); +} + +static void sub_80F85BC(u8 taskId) +{ + u8 i; + u8 sp0[4]; + u8 sp4[4]; + + memset(sp0, 0, sizeof(sp0)); + memset(sp4, 0, sizeof(sp4)); + + for (i = 0; i < gNumLinkContestPlayers; i++) + sp0[i] = gTasks[taskId].data[i + 1]; + + for (i = 0; i < gNumLinkContestPlayers;) + { + i++; + if (i >= gNumLinkContestPlayers || sp0[0] != sp0[i]) + break; + } + + if (i == gNumLinkContestPlayers) + gSpecialVar_0x8004 = 0; + else + gSpecialVar_0x8004 = 1; + + for (i = 0; i < gNumLinkContestPlayers; i++) + sp4[i] = gTasks[taskId].data[i + 5]; + + gUnknown_02039F2B = sub_80F86E0(sp4); + sub_80DB09C(gSpecialVar_ContestCategory); + SetTaskFuncWithFollowupFunc(taskId, sub_80FCF40, sub_80F86B8); +} + +static void sub_80F86B8(u8 taskId) +{ + SortContestants(FALSE); + SetTaskFuncWithFollowupFunc(taskId, sub_80FCFD0, sub_80F8714); +} + +u8 sub_80F86E0(u8 *arg0) +{ + int i; + u8 result = 0; + + for (i = 1; i < gNumLinkContestPlayers; i++) + { + if (arg0[result] < arg0[i]) + result = i; + } + + return result; +} + +void sub_80F8714(u8 taskId) +{ + int i; + + if (gSpecialVar_0x8004 == 1) + { + if (IsLinkTaskFinished()) + gTasks[taskId].func = sub_80F878C; + } + else + { + for (i = 0; i < CONTESTANT_COUNT; i++) + StringGetEnd10(gContestMons[i].nickname); + + DestroyTask(taskId); + SetDynamicWarp(0, gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, -1); + ScriptContext2_Disable(); + EnableBothScriptContexts(); + } +} + +static void sub_80F878C(u8 taskId) +{ + sub_800AC34(); + gTasks[taskId].func = sub_80F87B4; +} + +static void sub_80F87B4(u8 taskId) +{ + if (!gReceivedRemoteLinkPlayers) + { + DestroyTask(taskId); + ScriptContext2_Disable(); + EnableBothScriptContexts(); + } +} diff --git a/src/scrcmd.c b/src/scrcmd.c index 9c00c3bc8..326d46a56 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -5,7 +5,7 @@ #include "clock.h" #include "coins.h" #include "contest.h" -#include "contest_link_80F57C4.h" +#include "contest_util.h" #include "contest_painting.h" #include "data.h" #include "decoration.h" diff --git a/src/script_pokemon_util_80F87D8.c b/src/script_pokemon_util_80F87D8.c index 62b445a04..a6ab1693b 100755 --- a/src/script_pokemon_util_80F87D8.c +++ b/src/script_pokemon_util_80F87D8.c @@ -3,7 +3,7 @@ #include "battle_gfx_sfx_util.h" #include "berry.h" #include "contest.h" -#include "contest_link_80F57C4.h" +#include "contest_util.h" #include "contest_painting.h" #include "data.h" #include "daycare.h" diff --git a/sym_ewram.txt b/sym_ewram.txt index 58fb0648e..e99d90a1d 100644 --- a/sym_ewram.txt +++ b/sym_ewram.txt @@ -74,7 +74,7 @@ .include "src/record_mixing.o" .include "src/secret_base.o" .include "src/tv.o" - .include "src/contest_link_80F57C4.o" + .include "src/contest_util.o" .include "src/rotating_gate.o" .include "src/safari_zone.o" .include "src/item_use.o" -- cgit v1.2.3