From 4275cf4b9033c6a4350057169af49fdcfa4a097a Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 15 Nov 2021 01:23:27 -0500 Subject: Rename pokenav match call files --- src/pokenav_match_call_1.c | 521 ----------------- src/pokenav_match_call_2.c | 1301 ----------------------------------------- src/pokenav_match_call_gfx.c | 1301 +++++++++++++++++++++++++++++++++++++++++ src/pokenav_match_call_list.c | 521 +++++++++++++++++ 4 files changed, 1822 insertions(+), 1822 deletions(-) delete mode 100755 src/pokenav_match_call_1.c delete mode 100755 src/pokenav_match_call_2.c create mode 100755 src/pokenav_match_call_gfx.c create mode 100755 src/pokenav_match_call_list.c (limited to 'src') diff --git a/src/pokenav_match_call_1.c b/src/pokenav_match_call_1.c deleted file mode 100755 index d56cfdb62..000000000 --- a/src/pokenav_match_call_1.c +++ /dev/null @@ -1,521 +0,0 @@ -#include "global.h" -#include "battle_setup.h" -#include "data.h" -#include "event_data.h" -#include "gym_leader_rematch.h" -#include "international_string_util.h" -#include "main.h" -#include "match_call.h" -#include "overworld.h" -#include "pokemon.h" -#include "pokenav.h" -#include "sound.h" -#include "string_util.h" -#include "strings.h" -#include "constants/songs.h" - -struct Pokenav_MatchCallMenu -{ - u16 optionCursorPos; - u16 maxOptionId; - const u8 *matchCallOptions; - u16 headerId; - u16 numRegistered; - u16 numSpecialTrainers; - bool32 initFinished; - u32 loopedTaskId; - u32 (*callback)(struct Pokenav_MatchCallMenu*); - struct PokenavMatchCallEntry matchCallEntries[MAX_REMATCH_ENTRIES - 1]; -}; - -static u32 CB2_HandleMatchCallInput(struct Pokenav_MatchCallMenu *); -static u32 GetExitMatchCallMenuId(struct Pokenav_MatchCallMenu *); -static u32 CB2_HandleMatchCallOptionsInput(struct Pokenav_MatchCallMenu *); -static u32 CB2_HandleCheckPageInput(struct Pokenav_MatchCallMenu *); -static u32 CB2_HandleCallExitInput(struct Pokenav_MatchCallMenu *); -static u32 LoopedTask_BuildMatchCallList(s32); -static bool32 ShouldDoNearbyMessage(void); - -#include "data/text/match_call_messages.h" - -static const u8 sMatchCallOptionsNoCheckPage[] = -{ - MATCH_CALL_OPTION_CALL, - MATCH_CALL_OPTION_CANCEL -}; - -static const u8 sMatchCallOptionsHasCheckPage[] = -{ - MATCH_CALL_OPTION_CALL, - MATCH_CALL_OPTION_CHECK, - MATCH_CALL_OPTION_CANCEL -}; - -bool32 PokenavCallback_Init_MatchCall(void) -{ - struct Pokenav_MatchCallMenu *state = AllocSubstruct(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN, sizeof(struct Pokenav_MatchCallMenu)); - if (!state) - return FALSE; - - state->callback = CB2_HandleMatchCallInput; - state->headerId = 0; - state->initFinished = FALSE; - state->loopedTaskId = CreateLoopedTask(LoopedTask_BuildMatchCallList, 1); - return TRUE; -} - -u32 GetMatchCallCallback(void) -{ - struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); - return state->callback(state); -} - -void FreeMatchCallSubstruct1(void) -{ - FreePokenavSubstruct(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); -} - -static u32 CB2_HandleMatchCallInput(struct Pokenav_MatchCallMenu *state) -{ - int selection; - - if (JOY_REPEAT(DPAD_UP)) - return POKENAV_MC_FUNC_UP; - if (JOY_REPEAT(DPAD_DOWN)) - return POKENAV_MC_FUNC_DOWN; - if (JOY_REPEAT(DPAD_LEFT)) - return POKENAV_MC_FUNC_PG_UP; - if (JOY_REPEAT(DPAD_RIGHT)) - return POKENAV_MC_FUNC_PG_DOWN; - - if (JOY_NEW(A_BUTTON)) - { - state->callback = CB2_HandleMatchCallOptionsInput; - state->optionCursorPos = 0; - selection = PokenavList_GetSelectedIndex(); - - if (!state->matchCallEntries[selection].isSpecialTrainer || MatchCall_HasCheckPage(state->matchCallEntries[selection].headerId)) - { - state->matchCallOptions = sMatchCallOptionsHasCheckPage; - state->maxOptionId = ARRAY_COUNT(sMatchCallOptionsHasCheckPage) - 1; - } - else - { - state->matchCallOptions = sMatchCallOptionsNoCheckPage; - state->maxOptionId = ARRAY_COUNT(sMatchCallOptionsNoCheckPage) - 1; - } - - return POKENAV_MC_FUNC_SELECT; - } - - if (JOY_NEW(B_BUTTON)) - { - if (GetPokenavMode() != POKENAV_MODE_FORCE_CALL_READY) - { - state->callback = GetExitMatchCallMenuId; - return POKENAV_MC_FUNC_EXIT; - } - else - { - // Cant exit Match Call menu before calling Mr Stone during tutorial - PlaySE(SE_FAILURE); - } - } - - return POKENAV_MC_FUNC_NONE; -} - -static u32 GetExitMatchCallMenuId(struct Pokenav_MatchCallMenu *state) -{ - return POKENAV_MAIN_MENU_CURSOR_ON_MATCH_CALL; -} - -static u32 CB2_HandleMatchCallOptionsInput(struct Pokenav_MatchCallMenu *state) -{ - if (JOY_NEW(DPAD_UP) && state->optionCursorPos) - { - state->optionCursorPos--; - return POKENAV_MC_FUNC_MOVE_OPTIONS_CURSOR; - } - - if (JOY_NEW(DPAD_DOWN) && state->optionCursorPos < state->maxOptionId) - { - state->optionCursorPos++; - return POKENAV_MC_FUNC_MOVE_OPTIONS_CURSOR; - } - - if (JOY_NEW(A_BUTTON)) - { - switch (state->matchCallOptions[state->optionCursorPos]) - { - case MATCH_CALL_OPTION_CANCEL: - state->callback = CB2_HandleMatchCallInput; - return POKENAV_MC_FUNC_CANCEL; - case MATCH_CALL_OPTION_CALL: - if (GetPokenavMode() == POKENAV_MODE_FORCE_CALL_READY) - SetPokenavMode(POKENAV_MODE_FORCE_CALL_EXIT); - - state->callback = CB2_HandleCallExitInput; - if (ShouldDoNearbyMessage()) - return POKENAV_MC_FUNC_NEARBY_MSG; - - return POKENAV_MC_FUNC_CALL_MSG; - case MATCH_CALL_OPTION_CHECK: - state->callback = CB2_HandleCheckPageInput; - return POKENAV_MC_FUNC_SHOW_CHECK_PAGE; - } - } - - if (JOY_NEW(B_BUTTON)) - { - state->callback = CB2_HandleMatchCallInput; - return POKENAV_MC_FUNC_CANCEL; - } - - return POKENAV_MC_FUNC_NONE; -} - -static u32 CB2_HandleCheckPageInput(struct Pokenav_MatchCallMenu *state) -{ - if (JOY_REPEAT(DPAD_UP)) - return POKENAV_MC_FUNC_CHECK_PAGE_UP; - if (JOY_REPEAT(DPAD_DOWN)) - return POKENAV_MC_FUNC_CHECK_PAGE_DOWN; - - if (JOY_NEW(B_BUTTON)) - { - state->callback = CB2_HandleMatchCallInput; - return POKENAV_MC_FUNC_EXIT_CHECK_PAGE; - } - - return POKENAV_MC_FUNC_NONE; -} - -static u32 CB2_HandleCallExitInput(struct Pokenav_MatchCallMenu *state) -{ - if (JOY_NEW(A_BUTTON | B_BUTTON)) - { - state->callback = CB2_HandleMatchCallInput; - return POKENAV_MC_FUNC_EXIT_CALL; - } - - return POKENAV_MC_FUNC_NONE; -} - -static u32 LoopedTask_BuildMatchCallList(s32 taskState) -{ - int i, j; - struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); - switch (taskState) - { - case 0: - state->headerId = 0; - state->numRegistered = 0; - return LT_INC_AND_CONTINUE; - case 1: - // Load special trainers (e.g. Rival, gym leaders) - for (i = 0, j = state->headerId; i < 30; i++, j++) - { - if (MatchCall_GetEnabled(j)) - { - state->matchCallEntries[state->numRegistered].headerId = j; - state->matchCallEntries[state->numRegistered].isSpecialTrainer = TRUE; - state->matchCallEntries[state->numRegistered].mapSec = MatchCall_GetMapSec(j); - state->numRegistered++; - } - - if (++state->headerId >= MC_HEADER_COUNT) - { - state->numSpecialTrainers = state->headerId; - state->headerId = 0; - return LT_INC_AND_CONTINUE; - } - } - - return LT_CONTINUE; - case 2: - // Load normal trainers - for (i = 0, j = state->headerId; i < 30; i++, j++) - { - if (!MatchCall_HasRematchId(state->headerId) && IsRematchEntryRegistered(state->headerId)) - { - state->matchCallEntries[state->numRegistered].headerId = state->headerId; - state->matchCallEntries[state->numRegistered].isSpecialTrainer = FALSE; - state->matchCallEntries[state->numRegistered].mapSec = GetMatchTableMapSectionId(j); - state->numRegistered++; - } - - if (++state->headerId > REMATCH_TABLE_ENTRIES - 1) - return LT_INC_AND_CONTINUE; - } - - return LT_CONTINUE; - case 3: - state->initFinished = TRUE; - break; - } - - return LT_FINISH; -} - -bool32 IsRematchEntryRegistered(int rematchIndex) -{ - if (rematchIndex < REMATCH_TABLE_ENTRIES) - return FlagGet(FLAG_MATCH_CALL_REGISTERED + rematchIndex); - - return FALSE; -} - -int IsMatchCallListInitFinished(void) -{ - struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); - return state->initFinished; -} - -int GetNumberRegistered(void) -{ - struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); - return state->numRegistered; -} - -// Unused -static int GetNumSpecialTrainers(void) -{ - struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); - return state->numSpecialTrainers; -} - -// Unused -static int GetNumNormalTrainers(void) -{ - struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); - return state->numRegistered - state->numSpecialTrainers; -} - -// Unused -static int GetNormalTrainerHeaderId(int index) -{ - struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); - index += state->numSpecialTrainers; - if (index >= state->numRegistered) - return REMATCH_TABLE_ENTRIES; - - return state->matchCallEntries[index].headerId; -} - -struct PokenavMatchCallEntry *GetMatchCallList(void) -{ - struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); - return state->matchCallEntries; -} - -u16 GetMatchCallMapSec(int index) -{ - struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); - return state->matchCallEntries[index].mapSec; -} - -bool32 ShouldDrawRematchPokeballIcon(int index) -{ - struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); - if (!state->matchCallEntries[index].isSpecialTrainer) - index = state->matchCallEntries[index].headerId; - else - index = MatchCall_GetRematchTableIdx(state->matchCallEntries[index].headerId); - - if (index == REMATCH_TABLE_ENTRIES) - return FALSE; - - return gSaveBlock1Ptr->trainerRematches[index] != 0; -} - -int GetMatchCallTrainerPic(int index) -{ - int headerId; - struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); - if (!state->matchCallEntries[index].isSpecialTrainer) - { - index = GetTrainerIdxByRematchIdx(state->matchCallEntries[index].headerId); - return gTrainers[index].trainerPic; - } - - headerId = state->matchCallEntries[index].headerId; - index = MatchCall_GetRematchTableIdx(headerId); - if (index != REMATCH_TABLE_ENTRIES) - { - index = GetTrainerIdxByRematchIdx(index); - return gTrainers[index].trainerPic; - } - - index = MatchCall_GetOverrideFacilityClass(headerId); - return gFacilityClassToPicIndex[index]; -} - -const u8 *GetMatchCallMessageText(int index, bool8 *newRematchRequest) -{ - struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); - *newRematchRequest = FALSE; - if (!Overworld_MapTypeAllowsTeleportAndFly(gMapHeader.mapType)) - return gText_CallCantBeMadeHere; - - if (!state->matchCallEntries[index].isSpecialTrainer) - *newRematchRequest = SelectMatchCallMessage(GetTrainerIdxByRematchIdx(state->matchCallEntries[index].headerId), gStringVar4); - else - MatchCall_GetMessage(state->matchCallEntries[index].headerId, gStringVar4); - - return gStringVar4; -} - -const u8 *GetMatchCallFlavorText(int index, int checkPageEntry) -{ - int rematchId; - struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); - if (state->matchCallEntries[index].isSpecialTrainer) - { - rematchId = MatchCall_GetRematchTableIdx(state->matchCallEntries[index].headerId); - if (rematchId == REMATCH_TABLE_ENTRIES) - return MatchCall_GetOverrideFlavorText(state->matchCallEntries[index].headerId, checkPageEntry); - } - else - { - rematchId = state->matchCallEntries[index].headerId; - } - - return gMatchCallFlavorTexts[rematchId][checkPageEntry]; -} - -u16 GetMatchCallOptionCursorPos(void) -{ - struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); - return state->optionCursorPos; -} - -u16 GetMatchCallOptionId(int optionId) -{ - struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); - if (state->maxOptionId < optionId) - return MATCH_CALL_OPTION_COUNT; - - return state->matchCallOptions[optionId]; -} - -void BufferMatchCallNameAndDesc(struct PokenavMatchCallEntry *matchCallEntry, u8 *str) -{ - const u8 *trainerName; - const u8 *className; - if (!matchCallEntry->isSpecialTrainer) - { - int index = GetTrainerIdxByRematchIdx(matchCallEntry->headerId); - const struct Trainer *trainer = &gTrainers[index]; - int class = trainer->trainerClass; - className = gTrainerClassNames[class]; - trainerName = trainer->trainerName; - } - else - { - MatchCall_GetNameAndDesc(matchCallEntry->headerId, &className, &trainerName); - } - - if (className && trainerName) - { - u8 *str2 = GetStringClearToWidth(str, FONT_NARROW, className, 69); - GetStringClearToWidth(str2, FONT_NARROW, trainerName, 51); - } - else - { - GetStringClearToWidth(str, FONT_NARROW, NULL, 120); - } -} - -u8 GetMatchTableMapSectionId(int rematchIndex) -{ - int mapGroup = gRematchTable[rematchIndex].mapGroup; - int mapNum = gRematchTable[rematchIndex].mapNum; - return Overworld_GetMapHeaderByGroupAndId(mapGroup, mapNum)->regionMapSectionId; -} - -int GetIndexDeltaOfNextCheckPageDown(int index) -{ - struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); - int count = 1; - while (++index < state->numRegistered) - { - if (!state->matchCallEntries[index].isSpecialTrainer) - return count; - if (MatchCall_HasCheckPage(state->matchCallEntries[index].headerId)) - return count; - - count++; - } - - return 0; -} - -int GetIndexDeltaOfNextCheckPageUp(int index) -{ - struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); - int count = -1; - while (--index >= 0) - { - if (!state->matchCallEntries[index].isSpecialTrainer) - return count; - if (MatchCall_HasCheckPage(state->matchCallEntries[index].headerId)) - return count; - - count--; - } - - return 0; -} - -// Unused -static bool32 HasRematchEntry(void) -{ - int i; - - for (i = 0; i < REMATCH_TABLE_ENTRIES; i++) - { - if (IsRematchEntryRegistered(i) && gSaveBlock1Ptr->trainerRematches[i]) - return TRUE; - } - - for (i = 0; i < MC_HEADER_COUNT; i++) - { - if (MatchCall_GetEnabled(i)) - { - int index = MatchCall_GetRematchTableIdx(i); - if (gSaveBlock1Ptr->trainerRematches[index]) - return TRUE; - } - } - - return FALSE; -} - -static bool32 ShouldDoNearbyMessage(void) -{ - struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); - int selection = PokenavList_GetSelectedIndex(); - if (!state->matchCallEntries[selection].isSpecialTrainer) - { - if (GetMatchCallMapSec(selection) == gMapHeader.regionMapSectionId) - { - if (!gSaveBlock1Ptr->trainerRematches[state->matchCallEntries[selection].headerId]) - return TRUE; - } - } - else - { - if (state->matchCallEntries[selection].headerId == MC_HEADER_WATTSON) - { - if (GetMatchCallMapSec(selection) == gMapHeader.regionMapSectionId - && FlagGet(FLAG_BADGE05_GET) == TRUE) - { - if (!FlagGet(FLAG_WATTSON_REMATCH_AVAILABLE)) - return TRUE; - } - } - } - - return FALSE; -} diff --git a/src/pokenav_match_call_2.c b/src/pokenav_match_call_2.c deleted file mode 100755 index d7e9476f9..000000000 --- a/src/pokenav_match_call_2.c +++ /dev/null @@ -1,1301 +0,0 @@ -#include "global.h" -#include "bg.h" -#include "data.h" -#include "decompress.h" -#include "dma3.h" -#include "international_string_util.h" -#include "main.h" -#include "match_call.h" -#include "menu.h" -#include "overworld.h" -#include "palette.h" -#include "pokenav.h" -#include "region_map.h" -#include "sound.h" -#include "sprite.h" -#include "string_util.h" -#include "strings.h" -#include "task.h" -#include "text.h" -#include "text_window.h" -#include "trig.h" -#include "window.h" -#include "constants/game_stat.h" -#include "constants/region_map_sections.h" -#include "constants/songs.h" - -#define GFXTAG_CURSOR 7 -#define GFXTAG_TRAINER_PIC 8 -#define PALTAG_CURSOR 12 -#define PALTAG_TRAINER_PIC 13 - -struct Pokenav_MatchCallGfx -{ - bool32 (*isTaskActiveCB)(void); - u32 loopTaskId; - u8 filler8[6]; - bool8 unkE; - bool8 newRematchRequest; - u16 locWindowId; - u16 infoBoxWindowId; - u16 msgBoxWindowId; - s16 pageDelta; - u8 unused18; - u8 unused19; - u16 trainerPicPalOffset; - struct Sprite *optionsCursorSprite; - struct Sprite *trainerPicSprite; - u8 bgTilemapBuffer1[BG_SCREEN_SIZE]; - u8 unusedTilemapBuffer[BG_SCREEN_SIZE]; - u8 bgTilemapBuffer2[BG_SCREEN_SIZE]; - u8 *trainerPicGfxPtr; - u8 trainerPicGfx[0x800]; - u8 trainerPicPal[0x20]; -}; - -static bool32 GetCurrentLoopedTaskActive(void); -static u32 LoopedTask_OpenMatchCall(s32); -static void CreateMatchCallList(void); -static void DestroyMatchCallList(void); -static void FreeMatchCallSprites(void); -static void LoadCallWindowAndFade(struct Pokenav_MatchCallGfx *); -static void DrawMatchCallLeftColumnWindows(struct Pokenav_MatchCallGfx *); -static void UpdateMatchCallInfoBox(struct Pokenav_MatchCallGfx *); -static void PrintMatchCallLocation(struct Pokenav_MatchCallGfx *, int); -static void AllocMatchCallSprites(void); -static void SetPokeballIconsFlashing(bool32); -static void PrintMatchCallSelectionOptions(struct Pokenav_MatchCallGfx *); -static bool32 ShowOptionsCursor(struct Pokenav_MatchCallGfx *); -static void UpdateCursorGfxPos(struct Pokenav_MatchCallGfx *, int); -static bool32 IsDma3ManagerBusyWithBgCopy1(struct Pokenav_MatchCallGfx *); -static void UpdateWindowsReturnToTrainerList(struct Pokenav_MatchCallGfx *); -static void DrawMsgBoxForMatchCallMsg(struct Pokenav_MatchCallGfx *); -static bool32 IsDma3ManagerBusyWithBgCopy2(struct Pokenav_MatchCallGfx *); -static void PrintCallingDots(struct Pokenav_MatchCallGfx *); -static bool32 WaitForCallingDotsText(struct Pokenav_MatchCallGfx *); -static void PrintMatchCallMessage(struct Pokenav_MatchCallGfx *); -static bool32 WaitForMatchCallMessageText(struct Pokenav_MatchCallGfx *); -static void DrawMsgBoxForCloseByMsg(struct Pokenav_MatchCallGfx *); -static void PrintTrainerIsCloseBy(struct Pokenav_MatchCallGfx *); -static bool32 WaitForTrainerIsCloseByText(struct Pokenav_MatchCallGfx *); -static void EraseCallMessageBox(struct Pokenav_MatchCallGfx *); -static bool32 WaitForCallMessageBoxErase(struct Pokenav_MatchCallGfx *); -static void UpdateWindowsToShowCheckPage(struct Pokenav_MatchCallGfx *); -static void LoadCheckPageTrainerPic(struct Pokenav_MatchCallGfx *); -static bool32 WaitForTrainerPic(struct Pokenav_MatchCallGfx *); -static void TrainerPicSlideOffscreen(struct Pokenav_MatchCallGfx *); -static void Task_FlashPokeballIcons(u8); -static void TryDrawRematchPokeballIcon(u16, u32, u32); -static void PrintNumberRegisteredLabel(u16); -static void PrintNumberRegistered(u16); -static void PrintNumberOfBattlesLabel(u16); -static void PrintNumberOfBattles(u16); -static void PrintMatchCallInfoLabel(u16, const u8 *, int); -static void PrintMatchCallInfoNumber(u16, const u8 *, int); -static void CreateOptionsCursorSprite(struct Pokenav_MatchCallGfx *, int); -static void CloseMatchCallSelectOptionsWindow(struct Pokenav_MatchCallGfx *); -static struct Sprite *CreateTrainerPicSprite(void); -static void SpriteCB_TrainerPicSlideOnscreen(struct Sprite *); -static void SpriteCB_TrainerPicSlideOffscreen(struct Sprite *); -static void SpriteCB_OptionsCursor(struct Sprite *); -static u32 MatchCallListCursorDown(s32); -static u32 MatchCallListCursorUp(s32); -static u32 MatchCallListPageDown(s32); -static u32 MatchCallListPageUp(s32); -static u32 SelectMatchCallEntry(s32); -static u32 MoveMatchCallOptionsCursor(s32); -static u32 CancelMatchCallSelection(s32); -static u32 DoMatchCallMessage(s32); -static u32 DoTrainerCloseByMessage(s32); -static u32 CloseMatchCallMessage(s32); -static u32 ShowCheckPage(s32); -static u32 ShowCheckPageUp(s32); -static u32 ShowCheckPageDown(s32); -static u32 ExitCheckPage(s32); -static u32 ExitMatchCall(s32); - -static const u16 sMatchCallUI_Pal[] = INCBIN_U16("graphics/pokenav/match_call/ui.gbapal"); -static const u32 sMatchCallUI_Gfx[] = INCBIN_U32("graphics/pokenav/match_call/ui.4bpp.lz"); -static const u32 sMatchCallUI_Tilemap[] = INCBIN_U32("graphics/pokenav/match_call/ui.bin.lz"); -static const u16 sOptionsCursor_Pal[] = INCBIN_U16("graphics/pokenav/match_call/options_cursor.gbapal"); -static const u32 sOptionsCursor_Gfx[] = INCBIN_U32("graphics/pokenav/match_call/options_cursor.4bpp.lz"); -static const u16 sCallWindow_Pal[] = INCBIN_U16("graphics/pokenav/match_call/call_window.gbapal"); -static const u16 sListWindow_Pal[] = INCBIN_U16("graphics/pokenav/match_call/list_window.gbapal"); -static const u16 sPokeball_Pal[] = INCBIN_U16("graphics/pokenav/match_call/pokeball.gbapal"); -static const u32 sPokeball_Gfx[] = INCBIN_U32("graphics/pokenav/match_call/pokeball.4bpp.lz"); - -static const struct BgTemplate sMatchCallBgTemplates[3] = -{ - { - .bg = 1, - .charBaseIndex = 3, - .mapBaseIndex = 0x1F, - .screenSize = 0, - .paletteMode = 0, - .priority = 1, - .baseTile = 0 - }, - { - .bg = 2, - .charBaseIndex = 2, - .mapBaseIndex = 0x06, - .screenSize = 0, - .paletteMode = 0, - .priority = 2, - .baseTile = 0x80 - }, - { - .bg = 3, - .charBaseIndex = 1, - .mapBaseIndex = 0x07, - .screenSize = 0, - .paletteMode = 0, - .priority = 3, - .baseTile = 0 - } -}; - -static const LoopedTask sMatchCallLoopTaskFuncs[] = -{ - [POKENAV_MC_FUNC_NONE] = NULL, - [POKENAV_MC_FUNC_DOWN] = MatchCallListCursorDown, - [POKENAV_MC_FUNC_UP] = MatchCallListCursorUp, - [POKENAV_MC_FUNC_PG_DOWN] = MatchCallListPageDown, - [POKENAV_MC_FUNC_PG_UP] = MatchCallListPageUp, - [POKENAV_MC_FUNC_SELECT] = SelectMatchCallEntry, - [POKENAV_MC_FUNC_MOVE_OPTIONS_CURSOR] = MoveMatchCallOptionsCursor, - [POKENAV_MC_FUNC_CANCEL] = CancelMatchCallSelection, - [POKENAV_MC_FUNC_CALL_MSG] = DoMatchCallMessage, - [POKENAV_MC_FUNC_NEARBY_MSG] = DoTrainerCloseByMessage, - [POKENAV_MC_FUNC_EXIT_CALL] = CloseMatchCallMessage, - [POKENAV_MC_FUNC_SHOW_CHECK_PAGE] = ShowCheckPage, - [POKENAV_MC_FUNC_CHECK_PAGE_UP] = ShowCheckPageUp, - [POKENAV_MC_FUNC_CHECK_PAGE_DOWN] = ShowCheckPageDown, - [POKENAV_MC_FUNC_EXIT_CHECK_PAGE] = ExitCheckPage, - [POKENAV_MC_FUNC_EXIT] = ExitMatchCall -}; - -static const struct WindowTemplate sMatchCallLocationWindowTemplate = -{ - .bg = 2, - .tilemapLeft = 0, - .tilemapTop = 5, - .width = 11, - .height = 2, - .paletteNum = 2, - .baseBlock = 16 -}; - -static const struct WindowTemplate sMatchCallInfoBoxWindowTemplate = -{ - .bg = 2, - .tilemapLeft = 0, - .tilemapTop = 9, - .width = 11, - .height = 8, - .paletteNum = 2, - .baseBlock = 38 -}; - -static const u8 *const sMatchCallOptionTexts[MATCH_CALL_OPTION_COUNT] = -{ - [MATCH_CALL_OPTION_CALL] = gText_Call, - [MATCH_CALL_OPTION_CHECK] = gText_Check, - [MATCH_CALL_OPTION_CANCEL] = gText_Cancel6 -}; - -// The series of 5 dots that appear when someone is called with Match Call -static const u8 sText_CallingDots[] = _("·{PAUSE 4}·{PAUSE 4}·{PAUSE 4}·{PAUSE 4}·\p"); - -static const struct WindowTemplate sCallMsgBoxWindowTemplate = -{ - .bg = 1, - .tilemapLeft = 1, - .tilemapTop = 12, - .width = 28, - .height = 4, - .paletteNum = 1, - .baseBlock = 10 -}; - -static const struct CompressedSpriteSheet sOptionsCursorSpriteSheets[1] = -{ - {sOptionsCursor_Gfx, 0x40, GFXTAG_CURSOR} -}; - -static const struct SpritePalette sOptionsCursorSpritePalettes[2] = -{ - {sOptionsCursor_Pal, PALTAG_CURSOR} -}; - -static const struct OamData sOptionsCursorOamData = -{ - .y = 0, - .affineMode = ST_OAM_AFFINE_OFF, - .objMode = ST_OAM_OBJ_NORMAL, - .bpp = ST_OAM_4BPP, - .shape = SPRITE_SHAPE(8x16), - .x = 0, - .size = SPRITE_SIZE(8x16), - .tileNum = 0, - .priority = 1, - .paletteNum = 0, -}; - -static const struct SpriteTemplate sOptionsCursorSpriteTemplate = -{ - .tileTag = GFXTAG_CURSOR, - .paletteTag = PALTAG_CURSOR, - .oam = &sOptionsCursorOamData, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_OptionsCursor, -}; - -static const struct OamData sTrainerPicOamData = -{ - .y = 0, - .affineMode = ST_OAM_AFFINE_OFF, - .objMode = ST_OAM_OBJ_NORMAL, - .bpp = ST_OAM_4BPP, - .shape = SPRITE_SHAPE(64x64), - .x = 0, - .size = SPRITE_SIZE(64x64), - .tileNum = 0, - .priority = 1, - .paletteNum = 0, -}; - -static const struct SpriteTemplate sTrainerPicSpriteTemplate = -{ - .tileTag = GFXTAG_TRAINER_PIC, - .paletteTag = PALTAG_TRAINER_PIC, - .oam = &sTrainerPicOamData, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, -}; - -bool32 OpenMatchCall(void) -{ - struct Pokenav_MatchCallGfx *gfx = AllocSubstruct(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN, sizeof(struct Pokenav_MatchCallGfx)); - if (!gfx) - return FALSE; - - gfx->unused19 = 0; - gfx->loopTaskId = CreateLoopedTask(LoopedTask_OpenMatchCall, 1); - gfx->isTaskActiveCB = GetCurrentLoopedTaskActive; - return TRUE; -} - -void CreateMatchCallLoopedTask(s32 index) -{ - struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); - gfx->loopTaskId = CreateLoopedTask(sMatchCallLoopTaskFuncs[index], 1); - gfx->isTaskActiveCB = GetCurrentLoopedTaskActive; -} - -bool32 IsMatchCallLoopedTaskActive(void) -{ - struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); - return gfx->isTaskActiveCB(); -} - -void FreeMatchCallSubstruct2(void) -{ - struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); - FreeMatchCallSprites(); - DestroyMatchCallList(); - RemoveWindow(gfx->infoBoxWindowId); - RemoveWindow(gfx->locWindowId); - RemoveWindow(gfx->msgBoxWindowId); - FreePokenavSubstruct(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); -} - -static bool32 GetCurrentLoopedTaskActive(void) -{ - struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); - return IsLoopedTaskActive(gfx->loopTaskId); -} - -static u32 LoopedTask_OpenMatchCall(s32 state) -{ - struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); - switch (state) - { - case 0: - InitBgTemplates(sMatchCallBgTemplates, ARRAY_COUNT(sMatchCallBgTemplates)); - ChangeBgX(2, 0, BG_COORD_SET); - ChangeBgY(2, 0, BG_COORD_SET); - DecompressAndCopyTileDataToVram(2, sMatchCallUI_Gfx, 0, 0, 0); - SetBgTilemapBuffer(2, gfx->bgTilemapBuffer2); - CopyToBgTilemapBuffer(2, sMatchCallUI_Tilemap, 0, 0); - CopyBgTilemapBufferToVram(2); - CopyPaletteIntoBufferUnfaded(sMatchCallUI_Pal, 0x20, 0x20); - CopyBgTilemapBufferToVram(2); - return LT_INC_AND_PAUSE; - case 1: - if (FreeTempTileDataBuffersIfPossible()) - return LT_PAUSE; - - BgDmaFill(1, 0, 0, 1); - SetBgTilemapBuffer(1, gfx->bgTilemapBuffer1); - FillBgTilemapBufferRect_Palette0(1, 0x1000, 0, 0, 32, 20); - CopyPaletteIntoBufferUnfaded(sCallWindow_Pal, 0x10, 0x20); - CopyBgTilemapBufferToVram(1); - return LT_INC_AND_PAUSE; - case 2: - if (FreeTempTileDataBuffersIfPossible()) - return LT_PAUSE; - - LoadCallWindowAndFade(gfx); - DecompressAndCopyTileDataToVram(3, sPokeball_Gfx, 0, 0, 0); - CopyPaletteIntoBufferUnfaded(sListWindow_Pal, 0x30, 0x20); - CopyPaletteIntoBufferUnfaded(sPokeball_Pal, 0x50, 0x20); - return LT_INC_AND_PAUSE; - case 3: - if (FreeTempTileDataBuffersIfPossible() || !IsMatchCallListInitFinished()) - return LT_PAUSE; - - CreateMatchCallList(); - return LT_INC_AND_PAUSE; - case 4: - if (IsCreatePokenavListTaskActive()) - return LT_PAUSE; - - DrawMatchCallLeftColumnWindows(gfx); - return LT_INC_AND_PAUSE; - case 5: - UpdateMatchCallInfoBox(gfx); - PrintMatchCallLocation(gfx, 0); - return LT_INC_AND_PAUSE; - case 6: - ChangeBgX(1, 0, BG_COORD_SET); - ChangeBgY(1, 0, BG_COORD_SET); - ShowBg(2); - ShowBg(3); - ShowBg(1); - AllocMatchCallSprites(); - LoadLeftHeaderGfxForIndex(3); - ShowLeftHeaderGfx(POKENAV_GFX_MATCH_CALL_MENU, 1, 0); - PokenavFadeScreen(POKENAV_FADE_FROM_BLACK); - return LT_INC_AND_PAUSE; - case 7: - if (IsPaletteFadeActive() || AreLeftHeaderSpritesMoving()) - return LT_PAUSE; - - SetPokeballIconsFlashing(TRUE); - return LT_FINISH; - default: - return LT_FINISH; - } -} - -static u32 MatchCallListCursorDown(s32 state) -{ - struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); - switch (state) - { - case 0: - switch (PokenavList_MoveCursorDown()) - { - case 0: - break; - case 1: - PlaySE(SE_SELECT); - return LT_SET_STATE(2); - case 2: - PlaySE(SE_SELECT); - // fall through - default: - return LT_INC_AND_PAUSE; - } - break; - case 1: - if (PokenavList_IsMoveWindowTaskActive()) - return LT_PAUSE; - - PrintMatchCallLocation(gfx, 0); - return LT_INC_AND_PAUSE; - case 2: - PrintMatchCallLocation(gfx, 0); - return LT_INC_AND_PAUSE; - case 3: - if (IsDma3ManagerBusyWithBgCopy()) - return LT_PAUSE; - break; - } - return LT_FINISH; -} - -static u32 MatchCallListCursorUp(s32 state) -{ - struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); - switch (state) - { - case 0: - switch (PokenavList_MoveCursorUp()) - { - case 0: - break; - case 1: - PlaySE(SE_SELECT); - return LT_SET_STATE(2); - case 2: - PlaySE(SE_SELECT); - // fall through - default: - return LT_INC_AND_PAUSE; - } - break; - case 1: - if (PokenavList_IsMoveWindowTaskActive()) - return LT_PAUSE; - - PrintMatchCallLocation(gfx, 0); - return LT_INC_AND_PAUSE; - case 2: - PrintMatchCallLocation(gfx, 0); - return LT_INC_AND_PAUSE; - case 3: - if (IsDma3ManagerBusyWithBgCopy()) - return LT_PAUSE; - break; - } - return LT_FINISH; -} - -static u32 MatchCallListPageDown(s32 state) -{ - struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); - switch (state) - { - case 0: - switch (PokenavList_PageDown()) - { - case 0: - break; - case 1: - PlaySE(SE_SELECT); - return LT_SET_STATE(2); - case 2: - PlaySE(SE_SELECT); - // fall through - default: - return LT_INC_AND_PAUSE; - } - break; - case 1: - if (PokenavList_IsMoveWindowTaskActive()) - return LT_PAUSE; - - PrintMatchCallLocation(gfx, 0); - return LT_INC_AND_PAUSE; - case 2: - PrintMatchCallLocation(gfx, 0); - return LT_INC_AND_PAUSE; - case 3: - if (IsDma3ManagerBusyWithBgCopy()) - return LT_PAUSE; - break; - } - return LT_FINISH; -} - -static u32 MatchCallListPageUp(s32 state) -{ - struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); - switch (state) - { - case 0: - switch (PokenavList_PageUp()) - { - case 0: - break; - case 1: - PlaySE(SE_SELECT); - return LT_SET_STATE(2); - case 2: - PlaySE(SE_SELECT); - // fall through - default: - return LT_INC_AND_PAUSE; - } - break; - case 1: - if (PokenavList_IsMoveWindowTaskActive()) - return LT_PAUSE; - - PrintMatchCallLocation(gfx, 0); - return LT_INC_AND_PAUSE; - case 2: - PrintMatchCallLocation(gfx, 0); - return LT_INC_AND_PAUSE; - case 3: - if (IsDma3ManagerBusyWithBgCopy()) - return LT_PAUSE; - break; - } - return LT_FINISH; -} - -static u32 SelectMatchCallEntry(s32 state) -{ - struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); - switch (state) - { - case 0: - PlaySE(SE_SELECT); - PrintMatchCallSelectionOptions(gfx); - PrintHelpBarText(HELPBAR_MC_CALL_MENU); - return LT_INC_AND_PAUSE; - case 1: - if (ShowOptionsCursor(gfx)) - return LT_PAUSE; - break; - } - - return LT_FINISH; -} - -static u32 MoveMatchCallOptionsCursor(s32 state) -{ - struct Pokenav_MatchCallGfx *gfx; - u16 cursorPos; - - PlaySE(SE_SELECT); - gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); - cursorPos = GetMatchCallOptionCursorPos(); - UpdateCursorGfxPos(gfx, cursorPos); - return LT_FINISH; -} - -static u32 CancelMatchCallSelection(s32 state) -{ - struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); - switch (state) - { - case 0: - PlaySE(SE_SELECT); - UpdateWindowsReturnToTrainerList(gfx); - PrintHelpBarText(HELPBAR_MC_TRAINER_LIST); - return LT_INC_AND_PAUSE; - case 1: - if (IsDma3ManagerBusyWithBgCopy1(gfx)) - return LT_PAUSE; - break; - } - - return LT_FINISH; -} - -static u32 DoMatchCallMessage(s32 state) -{ - struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); - switch (state) - { - case 0: - PokenavList_ToggleVerticalArrows(TRUE); - DrawMsgBoxForMatchCallMsg(gfx); - return LT_INC_AND_PAUSE; - case 1: - if (IsDma3ManagerBusyWithBgCopy2(gfx)) - return LT_PAUSE; - - PrintCallingDots(gfx); - PlaySE(SE_POKENAV_CALL); - gfx->unkE = 0; - return LT_INC_AND_PAUSE; - case 2: - if (WaitForCallingDotsText(gfx)) - return LT_PAUSE; - - PrintMatchCallMessage(gfx); - return LT_INC_AND_PAUSE; - case 3: - if (WaitForMatchCallMessageText(gfx)) - return LT_PAUSE; - break; - } - - return LT_FINISH; -} - -static u32 DoTrainerCloseByMessage(s32 state) -{ - struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); - switch (state) - { - case 0: - PlaySE(SE_SELECT); - DrawMsgBoxForCloseByMsg(gfx); - PokenavList_ToggleVerticalArrows(TRUE); - gfx->unkE = 1; - return LT_INC_AND_PAUSE; - case 1: - if (IsDma3ManagerBusyWithBgCopy2(gfx)) - return LT_PAUSE; - - PrintTrainerIsCloseBy(gfx); - return LT_INC_AND_PAUSE; - case 2: - if (WaitForTrainerIsCloseByText(gfx)) - return LT_PAUSE; - break; - } - - return LT_FINISH; -} - -static u32 CloseMatchCallMessage(s32 state) -{ - struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); - u32 result = LT_INC_AND_PAUSE; - - switch (state) - { - case 0: - if (!gfx->unkE) - PlaySE(SE_POKENAV_HANG_UP); - - PlaySE(SE_SELECT); - break; - case 1: - EraseCallMessageBox(gfx); - break; - case 2: - if (WaitForCallMessageBoxErase(gfx)) - result = LT_PAUSE; - break; - case 3: - UpdateWindowsReturnToTrainerList(gfx); - break; - case 4: - if (IsDma3ManagerBusyWithBgCopy1(gfx)) - result = LT_PAUSE; - - PrintHelpBarText(HELPBAR_MC_TRAINER_LIST); - break; - case 5: - if (WaitForHelpBar()) - { - result = LT_PAUSE; - } - else - { - if (gfx->newRematchRequest) - { - // This call was a new rematch request, - // add the Pokéball icon to their entry - PokenavList_DrawCurrentItemIcon(); - result = LT_INC_AND_CONTINUE; - } - else - { - PokenavList_ToggleVerticalArrows(FALSE); - result = LT_FINISH; - } - } - break; - case 6: - if (IsDma3ManagerBusyWithBgCopy()) - { - result = LT_PAUSE; - } - else - { - PokenavList_ToggleVerticalArrows(FALSE); - result = LT_FINISH; - } - break; - } - - return result; -} - -static u32 ShowCheckPage(s32 state) -{ - struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); - switch (state) - { - case 0: - PlaySE(SE_SELECT); - PokenavList_EraseListForCheckPage(); - UpdateWindowsToShowCheckPage(gfx); - return LT_INC_AND_PAUSE; - case 1: - if (PokenavList_IsTaskActive() || IsDma3ManagerBusyWithBgCopy1(gfx)) - return LT_PAUSE; - - PrintHelpBarText(HELPBAR_MC_CHECK_PAGE); - return LT_INC_AND_PAUSE; - case 2: - PrintCheckPageInfo(0); - LoadCheckPageTrainerPic(gfx); - return LT_INC_AND_PAUSE; - case 3: - if (PokenavList_IsTaskActive() || WaitForTrainerPic(gfx) || WaitForHelpBar()) - return LT_PAUSE; - break; - } - - return LT_FINISH; -} - -static u32 ShowCheckPageDown(s32 state) -{ - int topId; - int delta; - struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); - switch (state) - { - case 0: - topId = PokenavList_GetTopIndex(); - delta = GetIndexDeltaOfNextCheckPageDown(topId); - if (delta) - { - PlaySE(SE_SELECT); - gfx->pageDelta = delta; - TrainerPicSlideOffscreen(gfx); - return LT_INC_AND_PAUSE; - } - break; - case 1: - if (WaitForTrainerPic(gfx)) - return LT_PAUSE; - - PrintMatchCallLocation(gfx, gfx->pageDelta); - return LT_INC_AND_PAUSE; - case 2: - PrintCheckPageInfo(gfx->pageDelta); - return LT_INC_AND_PAUSE; - case 3: - LoadCheckPageTrainerPic(gfx); - return LT_INC_AND_PAUSE; - case 4: - if (PokenavList_IsTaskActive() || WaitForTrainerPic(gfx)) - return LT_PAUSE; - break; - } - - return LT_FINISH; -} - -static u32 ExitCheckPage(s32 state) -{ - struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); - switch (state) - { - case 0: - PlaySE(SE_SELECT); - TrainerPicSlideOffscreen(gfx); - PokenavList_ReshowListFromCheckPage(); - return LT_INC_AND_PAUSE; - case 1: - if (PokenavList_IsTaskActive() || WaitForTrainerPic(gfx)) - return LT_PAUSE; - - PrintHelpBarText(HELPBAR_MC_TRAINER_LIST); - UpdateMatchCallInfoBox(gfx); - return LT_INC_AND_PAUSE; - case 2: - if (IsDma3ManagerBusyWithBgCopy()) - return LT_PAUSE; - break; - } - - return LT_FINISH; -} - -static u32 ShowCheckPageUp(s32 state) -{ - int topId; - int delta; - struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); - switch (state) - { - case 0: - topId = PokenavList_GetTopIndex(); - delta = GetIndexDeltaOfNextCheckPageUp(topId); - if (delta) - { - PlaySE(SE_SELECT); - gfx->pageDelta = delta; - TrainerPicSlideOffscreen(gfx); - return LT_INC_AND_PAUSE; - } - break; - case 1: - if (WaitForTrainerPic(gfx)) - return LT_PAUSE; - - PrintMatchCallLocation(gfx, gfx->pageDelta); - return LT_INC_AND_PAUSE; - case 2: - PrintCheckPageInfo(gfx->pageDelta); - return LT_INC_AND_PAUSE; - case 3: - LoadCheckPageTrainerPic(gfx); - return LT_INC_AND_PAUSE; - case 4: - if (PokenavList_IsTaskActive() || WaitForTrainerPic(gfx)) - return LT_PAUSE; - break; - } - - return LT_FINISH; -} - -static u32 ExitMatchCall(s32 state) -{ - switch (state) - { - case 0: - PlaySE(SE_SELECT); - SetPokeballIconsFlashing(FALSE); - PokenavFadeScreen(POKENAV_FADE_TO_BLACK); - SlideMenuHeaderDown(); - return LT_INC_AND_PAUSE; - case 1: - if (IsPaletteFadeActive() || MainMenuLoopedTaskIsBusy()) - return LT_PAUSE; - - SetLeftHeaderSpritesInvisibility(); - break; - } - - return LT_FINISH; -} - -static void CreateMatchCallList(void) -{ - struct PokenavListTemplate template; - template.list = (struct PokenavListItem *)GetMatchCallList(); - template.count = GetNumberRegistered(); - template.itemSize = sizeof(struct PokenavListItem); - template.startIndex = 0; - template.item_X = 13; - template.windowWidth = 16; - template.listTop = 1; - template.maxShowed = 8; - template.fillValue = 3; - template.fontId = FONT_NARROW; - template.bufferItemFunc = (PokenavListBufferItemFunc)BufferMatchCallNameAndDesc; - template.iconDrawFunc = TryDrawRematchPokeballIcon; - CreatePokenavList(&sMatchCallBgTemplates[2], &template, 2); - CreateTask(Task_FlashPokeballIcons, 7); -} - -static void DestroyMatchCallList(void) -{ - DestroyPokenavList(); - DestroyTask(FindTaskIdByFunc(Task_FlashPokeballIcons)); -} - -#define tSinIdx data[0] -#define tSinVal data[1] -#define tActive data[15] - -static void SetPokeballIconsFlashing(bool32 active) -{ - u8 taskId = FindTaskIdByFunc(Task_FlashPokeballIcons); - if (taskId != TASK_NONE) - gTasks[taskId].tActive = active; -} - -static void Task_FlashPokeballIcons(u8 taskId) -{ - s16 *data = gTasks[taskId].data; - if (tActive) - { - tSinIdx += 4; - tSinIdx &= 0x7F; - tSinVal = gSineTable[tSinIdx] >> 4; - PokenavCopyPalette(sPokeball_Pal, &sPokeball_Pal[0x10], 0x10, 0x10, tSinVal, &gPlttBufferUnfaded[0x50]); - if (!gPaletteFade.active) - CpuCopy32(&gPlttBufferUnfaded[0x50], &gPlttBufferFaded[0x50], 0x20); - } -} - -#undef tSinIdx -#undef tSinVal -#undef tActive - -enum { - POKEBALL_ICON_TOP = 0x5000, - POKEBALL_ICON_BOTTOM, - POKEBALL_ICON_EMPTY, -}; - -static void TryDrawRematchPokeballIcon(u16 windowId, u32 rematchId, u32 tileOffset) -{ - u8 bg = GetWindowAttribute(windowId, WINDOW_BG); - u16 *tilemap = GetBgTilemapBuffer(bg); - tilemap += tileOffset * 64 + 0x1D; - if (ShouldDrawRematchPokeballIcon(rematchId)) - { - tilemap[0] = POKEBALL_ICON_TOP; - tilemap[0x20] = POKEBALL_ICON_BOTTOM; - } - else - { - tilemap[0] = POKEBALL_ICON_EMPTY; - tilemap[0x20] = POKEBALL_ICON_EMPTY; - } -} - -void ClearRematchPokeballIcon(u16 windowId, u32 tileOffset) -{ - u8 bg = GetWindowAttribute(windowId, WINDOW_BG); - u16 *tilemap = GetBgTilemapBuffer(bg); - tilemap += tileOffset * 64 + 0x1D; - tilemap[0] = POKEBALL_ICON_EMPTY; - tilemap[0x20] = POKEBALL_ICON_EMPTY; -} - -static void DrawMatchCallLeftColumnWindows(struct Pokenav_MatchCallGfx *gfx) -{ - gfx->locWindowId = AddWindow(&sMatchCallLocationWindowTemplate); - gfx->infoBoxWindowId = AddWindow(&sMatchCallInfoBoxWindowTemplate); - FillWindowPixelBuffer(gfx->locWindowId, PIXEL_FILL(1)); - PutWindowTilemap(gfx->locWindowId); - FillWindowPixelBuffer(gfx->infoBoxWindowId, PIXEL_FILL(1)); - PutWindowTilemap(gfx->infoBoxWindowId); - CopyWindowToVram(gfx->locWindowId, COPYWIN_MAP); -} - -static void UpdateMatchCallInfoBox(struct Pokenav_MatchCallGfx *gfx) -{ - FillWindowPixelBuffer(gfx->infoBoxWindowId, PIXEL_FILL(1)); - PrintNumberRegisteredLabel(gfx->infoBoxWindowId); - PrintNumberRegistered(gfx->infoBoxWindowId); - PrintNumberOfBattlesLabel(gfx->infoBoxWindowId); - PrintNumberOfBattles(gfx->infoBoxWindowId); - CopyWindowToVram(gfx->infoBoxWindowId, COPYWIN_GFX); -} - -static void PrintNumberRegisteredLabel(u16 windowId) -{ - PrintMatchCallInfoLabel(windowId, gText_NumberRegistered, 0); -} - -static void PrintNumberRegistered(u16 windowId) -{ - u8 str[3]; - ConvertIntToDecimalStringN(str, GetNumberRegistered(), STR_CONV_MODE_LEFT_ALIGN, 3); - PrintMatchCallInfoNumber(windowId, str, 1); -} - -static void PrintNumberOfBattlesLabel(u16 windowId) -{ - PrintMatchCallInfoLabel(windowId, gText_NumberOfBattles, 2); -} - -static void PrintNumberOfBattles(u16 windowId) -{ - u8 str[5]; - int numTrainerBattles = GetGameStat(GAME_STAT_TRAINER_BATTLES); - if (numTrainerBattles > 99999) - numTrainerBattles = 99999; - - ConvertIntToDecimalStringN(str, numTrainerBattles, STR_CONV_MODE_LEFT_ALIGN, 5); - PrintMatchCallInfoNumber(windowId, str, 3); -} - -static void PrintMatchCallInfoLabel(u16 windowId, const u8 *str, int top) -{ - int y = top * 16 + 1; - AddTextPrinterParameterized(windowId, FONT_NARROW, str, 2, y, TEXT_SKIP_DRAW, NULL); -} - -static void PrintMatchCallInfoNumber(u16 windowId, const u8 *str, int top) -{ - int x = GetStringRightAlignXOffset(FONT_NARROW, str, 86); - int y = top * 16 + 1; - AddTextPrinterParameterized(windowId, FONT_NARROW, str, x, y, TEXT_SKIP_DRAW, NULL); -} - -static void PrintMatchCallLocation(struct Pokenav_MatchCallGfx *gfx, int delta) -{ - u8 mapName[32]; - int x; - int index = PokenavList_GetSelectedIndex() + delta; - int mapSec = GetMatchCallMapSec(index); - if (mapSec != MAPSEC_NONE) - GetMapName(mapName, mapSec, 0); - else - StringCopy(mapName, gText_Unknown); - - x = GetStringCenterAlignXOffset(FONT_NARROW, mapName, 88); - FillWindowPixelBuffer(gfx->locWindowId, PIXEL_FILL(1)); - AddTextPrinterParameterized(gfx->locWindowId, FONT_NARROW, mapName, x, 1, 0, NULL); -} - -static void PrintMatchCallSelectionOptions(struct Pokenav_MatchCallGfx *gfx) -{ - u32 i; - - FillWindowPixelBuffer(gfx->infoBoxWindowId, PIXEL_FILL(1)); - for (i = 0; i < MATCH_CALL_OPTION_COUNT; i++) - { - int optionText = GetMatchCallOptionId(i); - if (optionText == MATCH_CALL_OPTION_COUNT) - break; - - AddTextPrinterParameterized(gfx->infoBoxWindowId, FONT_NARROW, sMatchCallOptionTexts[optionText], 16, i * 16 + 1, TEXT_SKIP_DRAW, NULL); - } - - CopyWindowToVram(gfx->infoBoxWindowId, COPYWIN_GFX); -} - -static bool32 ShowOptionsCursor(struct Pokenav_MatchCallGfx *gfx) -{ - if (!IsDma3ManagerBusyWithBgCopy()) - { - CreateOptionsCursorSprite(gfx, GetMatchCallOptionCursorPos()); - return FALSE; - } - - return TRUE; -} - -static void UpdateWindowsReturnToTrainerList(struct Pokenav_MatchCallGfx *gfx) -{ - CloseMatchCallSelectOptionsWindow(gfx); - UpdateMatchCallInfoBox(gfx); -} - -static bool32 IsDma3ManagerBusyWithBgCopy1(struct Pokenav_MatchCallGfx *gfx) -{ - return IsDma3ManagerBusyWithBgCopy(); -} - -static void UpdateWindowsToShowCheckPage(struct Pokenav_MatchCallGfx *gfx) -{ - CloseMatchCallSelectOptionsWindow(gfx); - FillWindowPixelBuffer(gfx->infoBoxWindowId, PIXEL_FILL(1)); - CopyWindowToVram(gfx->infoBoxWindowId, COPYWIN_GFX); -} - -static void LoadCallWindowAndFade(struct Pokenav_MatchCallGfx *gfx) -{ - gfx->msgBoxWindowId = AddWindow(&sCallMsgBoxWindowTemplate); - LoadMatchCallWindowGfx(gfx->msgBoxWindowId, 1, 4); - FadeToBlackExceptPrimary(); -} - -static void DrawMsgBoxForMatchCallMsg(struct Pokenav_MatchCallGfx *gfx) -{ - struct Sprite *sprite; - LoadMatchCallWindowGfx(gfx->msgBoxWindowId, 1, 4); - DrawMatchCallTextBoxBorder(gfx->msgBoxWindowId, 1, 4); - FillWindowPixelBuffer(gfx->msgBoxWindowId, PIXEL_FILL(1)); - PutWindowTilemap(gfx->msgBoxWindowId); - CopyWindowToVram(gfx->msgBoxWindowId, COPYWIN_FULL); - sprite = GetSpinningPokenavSprite(); - sprite->x = 24; - sprite->y = 112; - sprite->y2 = 0; -} - -static void DrawMsgBoxForCloseByMsg(struct Pokenav_MatchCallGfx *gfx) -{ - LoadUserWindowBorderGfx(gfx->msgBoxWindowId, 1, 0x40); - DrawTextBorderOuter(gfx->msgBoxWindowId, 1, 4); - FillWindowPixelBuffer(gfx->msgBoxWindowId, PIXEL_FILL(1)); - PutWindowTilemap(gfx->msgBoxWindowId); - CopyWindowToVram(gfx->msgBoxWindowId, COPYWIN_FULL); -} - -static bool32 IsDma3ManagerBusyWithBgCopy2(struct Pokenav_MatchCallGfx *gfx) -{ - return IsDma3ManagerBusyWithBgCopy(); -} - -static void PrintCallingDots(struct Pokenav_MatchCallGfx *gfx) -{ - AddTextPrinterParameterized(gfx->msgBoxWindowId, FONT_NORMAL, sText_CallingDots, 32, 1, 1, NULL); -} - -static bool32 WaitForCallingDotsText(struct Pokenav_MatchCallGfx *gfx) -{ - RunTextPrinters(); - return IsTextPrinterActive(gfx->msgBoxWindowId); -} - -static void PrintTrainerIsCloseBy(struct Pokenav_MatchCallGfx *gfx) -{ - AddTextPrinterParameterized(gfx->msgBoxWindowId, FONT_NORMAL, gText_TrainerCloseBy, 0, 1, 1, NULL); -} - -static bool32 WaitForTrainerIsCloseByText(struct Pokenav_MatchCallGfx *gfx) -{ - RunTextPrinters(); - return IsTextPrinterActive(gfx->msgBoxWindowId); -} - -static void PrintMatchCallMessage(struct Pokenav_MatchCallGfx *gfx) -{ - int index = PokenavList_GetSelectedIndex(); - const u8 *str = GetMatchCallMessageText(index, &gfx->newRematchRequest); - u8 speed = GetPlayerTextSpeedDelay(); - AddTextPrinterParameterized(gfx->msgBoxWindowId, FONT_NORMAL, str, 32, 1, speed, NULL); -} - -static bool32 WaitForMatchCallMessageText(struct Pokenav_MatchCallGfx *gfx) -{ - if (JOY_HELD(A_BUTTON)) - gTextFlags.canABSpeedUpPrint = TRUE; - else - gTextFlags.canABSpeedUpPrint = FALSE; - - RunTextPrinters(); - return IsTextPrinterActive(gfx->msgBoxWindowId); -} - -static void EraseCallMessageBox(struct Pokenav_MatchCallGfx *gfx) -{ - HideSpinningPokenavSprite(); - FillBgTilemapBufferRect_Palette0(1, 0, 0, 0, 32, 20); - CopyBgTilemapBufferToVram(1); -} - -static bool32 WaitForCallMessageBoxErase(struct Pokenav_MatchCallGfx *gfx) -{ - return IsDma3ManagerBusyWithBgCopy(); -} - -static void AllocMatchCallSprites(void) -{ - int i; - u8 paletteNum; - struct SpriteSheet spriteSheet; - struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); - - // Load options cursor gfx - for (i = 0; i < ARRAY_COUNT(sOptionsCursorSpriteSheets); i++) - LoadCompressedSpriteSheet(&sOptionsCursorSpriteSheets[i]); - Pokenav_AllocAndLoadPalettes(sOptionsCursorSpritePalettes); - gfx->optionsCursorSprite = NULL; - - // Load trainer pic gfx - spriteSheet.data = gfx->trainerPicGfx; - spriteSheet.size = sizeof(gfx->trainerPicGfx); - spriteSheet.tag = GFXTAG_TRAINER_PIC; - gfx->trainerPicGfxPtr = (u8 *)OBJ_VRAM0 + LoadSpriteSheet(&spriteSheet) * 0x20; - paletteNum = AllocSpritePalette(PALTAG_TRAINER_PIC); - gfx->trainerPicPalOffset = 0x100 + paletteNum * 0x10; - gfx->trainerPicSprite = CreateTrainerPicSprite(); - gfx->trainerPicSprite->invisible = TRUE; -} - -static void FreeMatchCallSprites(void) -{ - struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); - if (gfx->optionsCursorSprite) - DestroySprite(gfx->optionsCursorSprite); - if (gfx->trainerPicSprite) - DestroySprite(gfx->trainerPicSprite); - - FreeSpriteTilesByTag(GFXTAG_TRAINER_PIC); - FreeSpriteTilesByTag(GFXTAG_CURSOR); - FreeSpritePaletteByTag(PALTAG_CURSOR); - FreeSpritePaletteByTag(PALTAG_TRAINER_PIC); -} - -static void CreateOptionsCursorSprite(struct Pokenav_MatchCallGfx *gfx, int top) -{ - if (!gfx->optionsCursorSprite) - { - u8 spriteId = CreateSprite(&sOptionsCursorSpriteTemplate, 4, 80, 5); - gfx->optionsCursorSprite = &gSprites[spriteId]; - UpdateCursorGfxPos(gfx, top); - } -} - -static void CloseMatchCallSelectOptionsWindow(struct Pokenav_MatchCallGfx *gfx) -{ - DestroySprite(gfx->optionsCursorSprite); - gfx->optionsCursorSprite = NULL; -} - -static void UpdateCursorGfxPos(struct Pokenav_MatchCallGfx *gfx, int top) -{ - gfx->optionsCursorSprite->y2 = top * 16; -} - -static void SpriteCB_OptionsCursor(struct Sprite *sprite) -{ - if (++sprite->data[0] > 3) - { - sprite->data[0] = 0; - sprite->x2 = (sprite->x2 + 1) & 7; - } -} - -static struct Sprite *CreateTrainerPicSprite(void) -{ - u8 spriteId = CreateSprite(&sTrainerPicSpriteTemplate, 44, 104, 6); - return &gSprites[spriteId]; -} - -static void LoadCheckPageTrainerPic(struct Pokenav_MatchCallGfx *gfx) -{ - u16 cursor; - int trainerPic = GetMatchCallTrainerPic(PokenavList_GetSelectedIndex()); - if (trainerPic >= 0) - { - DecompressPicFromTable(&gTrainerFrontPicTable[trainerPic], gfx->trainerPicGfx, SPECIES_NONE); - LZ77UnCompWram(gTrainerFrontPicPaletteTable[trainerPic].data, gfx->trainerPicPal); - cursor = RequestDma3Copy(gfx->trainerPicGfx, gfx->trainerPicGfxPtr, sizeof(gfx->trainerPicGfx), 1); - LoadPalette(gfx->trainerPicPal, gfx->trainerPicPalOffset, sizeof(gfx->trainerPicPal)); - gfx->trainerPicSprite->data[0] = 0; - gfx->trainerPicSprite->data[7] = cursor; - gfx->trainerPicSprite->callback = SpriteCB_TrainerPicSlideOnscreen; - } -} - -static void TrainerPicSlideOffscreen(struct Pokenav_MatchCallGfx *gfx) -{ - gfx->trainerPicSprite->callback = SpriteCB_TrainerPicSlideOffscreen; -} - -static bool32 WaitForTrainerPic(struct Pokenav_MatchCallGfx *gfx) -{ - return gfx->trainerPicSprite->callback != SpriteCallbackDummy; -} - -static void SpriteCB_TrainerPicSlideOnscreen(struct Sprite *sprite) -{ - switch (sprite->data[0]) - { - case 0: - if (CheckForSpaceForDma3Request(sprite->data[7]) != -1) - { - sprite->x2 = -80; - sprite->invisible = FALSE; - sprite->data[0]++; - } - break; - case 1: - sprite->x2 += 8; - if (sprite->x2 >= 0) - { - sprite->x2 = 0; - sprite->callback = SpriteCallbackDummy; - } - break; - } -} - -static void SpriteCB_TrainerPicSlideOffscreen(struct Sprite *sprite) -{ - sprite->x2 -= 8; - if (sprite->x2 <= -80) - { - sprite->invisible = TRUE; - sprite->callback = SpriteCallbackDummy; - } -} diff --git a/src/pokenav_match_call_gfx.c b/src/pokenav_match_call_gfx.c new file mode 100755 index 000000000..056ab2f1d --- /dev/null +++ b/src/pokenav_match_call_gfx.c @@ -0,0 +1,1301 @@ +#include "global.h" +#include "bg.h" +#include "data.h" +#include "decompress.h" +#include "dma3.h" +#include "international_string_util.h" +#include "main.h" +#include "match_call.h" +#include "menu.h" +#include "overworld.h" +#include "palette.h" +#include "pokenav.h" +#include "region_map.h" +#include "sound.h" +#include "sprite.h" +#include "string_util.h" +#include "strings.h" +#include "task.h" +#include "text.h" +#include "text_window.h" +#include "trig.h" +#include "window.h" +#include "constants/game_stat.h" +#include "constants/region_map_sections.h" +#include "constants/songs.h" + +#define GFXTAG_CURSOR 7 +#define GFXTAG_TRAINER_PIC 8 +#define PALTAG_CURSOR 12 +#define PALTAG_TRAINER_PIC 13 + +struct Pokenav_MatchCallGfx +{ + bool32 (*isTaskActiveCB)(void); + u32 loopTaskId; + u8 filler8[6]; + bool8 skipHangUpSE; + bool8 newRematchRequest; + u16 locWindowId; + u16 infoBoxWindowId; + u16 msgBoxWindowId; + s16 pageDelta; + u8 unused18; + u8 unused19; + u16 trainerPicPalOffset; + struct Sprite *optionsCursorSprite; + struct Sprite *trainerPicSprite; + u8 bgTilemapBuffer1[BG_SCREEN_SIZE]; + u8 unusedTilemapBuffer[BG_SCREEN_SIZE]; + u8 bgTilemapBuffer2[BG_SCREEN_SIZE]; + u8 *trainerPicGfxPtr; + u8 trainerPicGfx[0x800]; + u8 trainerPicPal[0x20]; +}; + +static bool32 GetCurrentLoopedTaskActive(void); +static u32 LoopedTask_OpenMatchCall(s32); +static void CreateMatchCallList(void); +static void DestroyMatchCallList(void); +static void FreeMatchCallSprites(void); +static void LoadCallWindowAndFade(struct Pokenav_MatchCallGfx *); +static void DrawMatchCallLeftColumnWindows(struct Pokenav_MatchCallGfx *); +static void UpdateMatchCallInfoBox(struct Pokenav_MatchCallGfx *); +static void PrintMatchCallLocation(struct Pokenav_MatchCallGfx *, int); +static void AllocMatchCallSprites(void); +static void SetPokeballIconsFlashing(bool32); +static void PrintMatchCallSelectionOptions(struct Pokenav_MatchCallGfx *); +static bool32 ShowOptionsCursor(struct Pokenav_MatchCallGfx *); +static void UpdateCursorGfxPos(struct Pokenav_MatchCallGfx *, int); +static bool32 IsDma3ManagerBusyWithBgCopy1(struct Pokenav_MatchCallGfx *); +static void UpdateWindowsReturnToTrainerList(struct Pokenav_MatchCallGfx *); +static void DrawMsgBoxForMatchCallMsg(struct Pokenav_MatchCallGfx *); +static bool32 IsDma3ManagerBusyWithBgCopy2(struct Pokenav_MatchCallGfx *); +static void PrintCallingDots(struct Pokenav_MatchCallGfx *); +static bool32 WaitForCallingDotsText(struct Pokenav_MatchCallGfx *); +static void PrintMatchCallMessage(struct Pokenav_MatchCallGfx *); +static bool32 WaitForMatchCallMessageText(struct Pokenav_MatchCallGfx *); +static void DrawMsgBoxForCloseByMsg(struct Pokenav_MatchCallGfx *); +static void PrintTrainerIsCloseBy(struct Pokenav_MatchCallGfx *); +static bool32 WaitForTrainerIsCloseByText(struct Pokenav_MatchCallGfx *); +static void EraseCallMessageBox(struct Pokenav_MatchCallGfx *); +static bool32 WaitForCallMessageBoxErase(struct Pokenav_MatchCallGfx *); +static void UpdateWindowsToShowCheckPage(struct Pokenav_MatchCallGfx *); +static void LoadCheckPageTrainerPic(struct Pokenav_MatchCallGfx *); +static bool32 WaitForTrainerPic(struct Pokenav_MatchCallGfx *); +static void TrainerPicSlideOffscreen(struct Pokenav_MatchCallGfx *); +static void Task_FlashPokeballIcons(u8); +static void TryDrawRematchPokeballIcon(u16, u32, u32); +static void PrintNumberRegisteredLabel(u16); +static void PrintNumberRegistered(u16); +static void PrintNumberOfBattlesLabel(u16); +static void PrintNumberOfBattles(u16); +static void PrintMatchCallInfoLabel(u16, const u8 *, int); +static void PrintMatchCallInfoNumber(u16, const u8 *, int); +static void CreateOptionsCursorSprite(struct Pokenav_MatchCallGfx *, int); +static void CloseMatchCallSelectOptionsWindow(struct Pokenav_MatchCallGfx *); +static struct Sprite *CreateTrainerPicSprite(void); +static void SpriteCB_TrainerPicSlideOnscreen(struct Sprite *); +static void SpriteCB_TrainerPicSlideOffscreen(struct Sprite *); +static void SpriteCB_OptionsCursor(struct Sprite *); +static u32 MatchCallListCursorDown(s32); +static u32 MatchCallListCursorUp(s32); +static u32 MatchCallListPageDown(s32); +static u32 MatchCallListPageUp(s32); +static u32 SelectMatchCallEntry(s32); +static u32 MoveMatchCallOptionsCursor(s32); +static u32 CancelMatchCallSelection(s32); +static u32 DoMatchCallMessage(s32); +static u32 DoTrainerCloseByMessage(s32); +static u32 CloseMatchCallMessage(s32); +static u32 ShowCheckPage(s32); +static u32 ShowCheckPageUp(s32); +static u32 ShowCheckPageDown(s32); +static u32 ExitCheckPage(s32); +static u32 ExitMatchCall(s32); + +static const u16 sMatchCallUI_Pal[] = INCBIN_U16("graphics/pokenav/match_call/ui.gbapal"); +static const u32 sMatchCallUI_Gfx[] = INCBIN_U32("graphics/pokenav/match_call/ui.4bpp.lz"); +static const u32 sMatchCallUI_Tilemap[] = INCBIN_U32("graphics/pokenav/match_call/ui.bin.lz"); +static const u16 sOptionsCursor_Pal[] = INCBIN_U16("graphics/pokenav/match_call/options_cursor.gbapal"); +static const u32 sOptionsCursor_Gfx[] = INCBIN_U32("graphics/pokenav/match_call/options_cursor.4bpp.lz"); +static const u16 sCallWindow_Pal[] = INCBIN_U16("graphics/pokenav/match_call/call_window.gbapal"); +static const u16 sListWindow_Pal[] = INCBIN_U16("graphics/pokenav/match_call/list_window.gbapal"); +static const u16 sPokeball_Pal[] = INCBIN_U16("graphics/pokenav/match_call/pokeball.gbapal"); +static const u32 sPokeball_Gfx[] = INCBIN_U32("graphics/pokenav/match_call/pokeball.4bpp.lz"); + +static const struct BgTemplate sMatchCallBgTemplates[3] = +{ + { + .bg = 1, + .charBaseIndex = 3, + .mapBaseIndex = 0x1F, + .screenSize = 0, + .paletteMode = 0, + .priority = 1, + .baseTile = 0 + }, + { + .bg = 2, + .charBaseIndex = 2, + .mapBaseIndex = 0x06, + .screenSize = 0, + .paletteMode = 0, + .priority = 2, + .baseTile = 0x80 + }, + { + .bg = 3, + .charBaseIndex = 1, + .mapBaseIndex = 0x07, + .screenSize = 0, + .paletteMode = 0, + .priority = 3, + .baseTile = 0 + } +}; + +static const LoopedTask sMatchCallLoopTaskFuncs[] = +{ + [POKENAV_MC_FUNC_NONE] = NULL, + [POKENAV_MC_FUNC_DOWN] = MatchCallListCursorDown, + [POKENAV_MC_FUNC_UP] = MatchCallListCursorUp, + [POKENAV_MC_FUNC_PG_DOWN] = MatchCallListPageDown, + [POKENAV_MC_FUNC_PG_UP] = MatchCallListPageUp, + [POKENAV_MC_FUNC_SELECT] = SelectMatchCallEntry, + [POKENAV_MC_FUNC_MOVE_OPTIONS_CURSOR] = MoveMatchCallOptionsCursor, + [POKENAV_MC_FUNC_CANCEL] = CancelMatchCallSelection, + [POKENAV_MC_FUNC_CALL_MSG] = DoMatchCallMessage, + [POKENAV_MC_FUNC_NEARBY_MSG] = DoTrainerCloseByMessage, + [POKENAV_MC_FUNC_EXIT_CALL] = CloseMatchCallMessage, + [POKENAV_MC_FUNC_SHOW_CHECK_PAGE] = ShowCheckPage, + [POKENAV_MC_FUNC_CHECK_PAGE_UP] = ShowCheckPageUp, + [POKENAV_MC_FUNC_CHECK_PAGE_DOWN] = ShowCheckPageDown, + [POKENAV_MC_FUNC_EXIT_CHECK_PAGE] = ExitCheckPage, + [POKENAV_MC_FUNC_EXIT] = ExitMatchCall +}; + +static const struct WindowTemplate sMatchCallLocationWindowTemplate = +{ + .bg = 2, + .tilemapLeft = 0, + .tilemapTop = 5, + .width = 11, + .height = 2, + .paletteNum = 2, + .baseBlock = 16 +}; + +static const struct WindowTemplate sMatchCallInfoBoxWindowTemplate = +{ + .bg = 2, + .tilemapLeft = 0, + .tilemapTop = 9, + .width = 11, + .height = 8, + .paletteNum = 2, + .baseBlock = 38 +}; + +static const u8 *const sMatchCallOptionTexts[MATCH_CALL_OPTION_COUNT] = +{ + [MATCH_CALL_OPTION_CALL] = gText_Call, + [MATCH_CALL_OPTION_CHECK] = gText_Check, + [MATCH_CALL_OPTION_CANCEL] = gText_Cancel6 +}; + +// The series of 5 dots that appear when someone is called with Match Call +static const u8 sText_CallingDots[] = _("·{PAUSE 4}·{PAUSE 4}·{PAUSE 4}·{PAUSE 4}·\p"); + +static const struct WindowTemplate sCallMsgBoxWindowTemplate = +{ + .bg = 1, + .tilemapLeft = 1, + .tilemapTop = 12, + .width = 28, + .height = 4, + .paletteNum = 1, + .baseBlock = 10 +}; + +static const struct CompressedSpriteSheet sOptionsCursorSpriteSheets[1] = +{ + {sOptionsCursor_Gfx, 0x40, GFXTAG_CURSOR} +}; + +static const struct SpritePalette sOptionsCursorSpritePalettes[2] = +{ + {sOptionsCursor_Pal, PALTAG_CURSOR} +}; + +static const struct OamData sOptionsCursorOamData = +{ + .y = 0, + .affineMode = ST_OAM_AFFINE_OFF, + .objMode = ST_OAM_OBJ_NORMAL, + .bpp = ST_OAM_4BPP, + .shape = SPRITE_SHAPE(8x16), + .x = 0, + .size = SPRITE_SIZE(8x16), + .tileNum = 0, + .priority = 1, + .paletteNum = 0, +}; + +static const struct SpriteTemplate sOptionsCursorSpriteTemplate = +{ + .tileTag = GFXTAG_CURSOR, + .paletteTag = PALTAG_CURSOR, + .oam = &sOptionsCursorOamData, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCB_OptionsCursor, +}; + +static const struct OamData sTrainerPicOamData = +{ + .y = 0, + .affineMode = ST_OAM_AFFINE_OFF, + .objMode = ST_OAM_OBJ_NORMAL, + .bpp = ST_OAM_4BPP, + .shape = SPRITE_SHAPE(64x64), + .x = 0, + .size = SPRITE_SIZE(64x64), + .tileNum = 0, + .priority = 1, + .paletteNum = 0, +}; + +static const struct SpriteTemplate sTrainerPicSpriteTemplate = +{ + .tileTag = GFXTAG_TRAINER_PIC, + .paletteTag = PALTAG_TRAINER_PIC, + .oam = &sTrainerPicOamData, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, +}; + +bool32 OpenMatchCall(void) +{ + struct Pokenav_MatchCallGfx *gfx = AllocSubstruct(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN, sizeof(struct Pokenav_MatchCallGfx)); + if (!gfx) + return FALSE; + + gfx->unused19 = 0; + gfx->loopTaskId = CreateLoopedTask(LoopedTask_OpenMatchCall, 1); + gfx->isTaskActiveCB = GetCurrentLoopedTaskActive; + return TRUE; +} + +void CreateMatchCallLoopedTask(s32 index) +{ + struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); + gfx->loopTaskId = CreateLoopedTask(sMatchCallLoopTaskFuncs[index], 1); + gfx->isTaskActiveCB = GetCurrentLoopedTaskActive; +} + +bool32 IsMatchCallLoopedTaskActive(void) +{ + struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); + return gfx->isTaskActiveCB(); +} + +void FreeMatchCallSubstruct2(void) +{ + struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); + FreeMatchCallSprites(); + DestroyMatchCallList(); + RemoveWindow(gfx->infoBoxWindowId); + RemoveWindow(gfx->locWindowId); + RemoveWindow(gfx->msgBoxWindowId); + FreePokenavSubstruct(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); +} + +static bool32 GetCurrentLoopedTaskActive(void) +{ + struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); + return IsLoopedTaskActive(gfx->loopTaskId); +} + +static u32 LoopedTask_OpenMatchCall(s32 state) +{ + struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); + switch (state) + { + case 0: + InitBgTemplates(sMatchCallBgTemplates, ARRAY_COUNT(sMatchCallBgTemplates)); + ChangeBgX(2, 0, BG_COORD_SET); + ChangeBgY(2, 0, BG_COORD_SET); + DecompressAndCopyTileDataToVram(2, sMatchCallUI_Gfx, 0, 0, 0); + SetBgTilemapBuffer(2, gfx->bgTilemapBuffer2); + CopyToBgTilemapBuffer(2, sMatchCallUI_Tilemap, 0, 0); + CopyBgTilemapBufferToVram(2); + CopyPaletteIntoBufferUnfaded(sMatchCallUI_Pal, 0x20, 0x20); + CopyBgTilemapBufferToVram(2); + return LT_INC_AND_PAUSE; + case 1: + if (FreeTempTileDataBuffersIfPossible()) + return LT_PAUSE; + + BgDmaFill(1, 0, 0, 1); + SetBgTilemapBuffer(1, gfx->bgTilemapBuffer1); + FillBgTilemapBufferRect_Palette0(1, 0x1000, 0, 0, 32, 20); + CopyPaletteIntoBufferUnfaded(sCallWindow_Pal, 0x10, 0x20); + CopyBgTilemapBufferToVram(1); + return LT_INC_AND_PAUSE; + case 2: + if (FreeTempTileDataBuffersIfPossible()) + return LT_PAUSE; + + LoadCallWindowAndFade(gfx); + DecompressAndCopyTileDataToVram(3, sPokeball_Gfx, 0, 0, 0); + CopyPaletteIntoBufferUnfaded(sListWindow_Pal, 0x30, 0x20); + CopyPaletteIntoBufferUnfaded(sPokeball_Pal, 0x50, 0x20); + return LT_INC_AND_PAUSE; + case 3: + if (FreeTempTileDataBuffersIfPossible() || !IsMatchCallListInitFinished()) + return LT_PAUSE; + + CreateMatchCallList(); + return LT_INC_AND_PAUSE; + case 4: + if (IsCreatePokenavListTaskActive()) + return LT_PAUSE; + + DrawMatchCallLeftColumnWindows(gfx); + return LT_INC_AND_PAUSE; + case 5: + UpdateMatchCallInfoBox(gfx); + PrintMatchCallLocation(gfx, 0); + return LT_INC_AND_PAUSE; + case 6: + ChangeBgX(1, 0, BG_COORD_SET); + ChangeBgY(1, 0, BG_COORD_SET); + ShowBg(2); + ShowBg(3); + ShowBg(1); + AllocMatchCallSprites(); + LoadLeftHeaderGfxForIndex(3); + ShowLeftHeaderGfx(POKENAV_GFX_MATCH_CALL_MENU, 1, 0); + PokenavFadeScreen(POKENAV_FADE_FROM_BLACK); + return LT_INC_AND_PAUSE; + case 7: + if (IsPaletteFadeActive() || AreLeftHeaderSpritesMoving()) + return LT_PAUSE; + + SetPokeballIconsFlashing(TRUE); + return LT_FINISH; + default: + return LT_FINISH; + } +} + +static u32 MatchCallListCursorDown(s32 state) +{ + struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); + switch (state) + { + case 0: + switch (PokenavList_MoveCursorDown()) + { + case 0: + break; + case 1: + PlaySE(SE_SELECT); + return LT_SET_STATE(2); + case 2: + PlaySE(SE_SELECT); + // fall through + default: + return LT_INC_AND_PAUSE; + } + break; + case 1: + if (PokenavList_IsMoveWindowTaskActive()) + return LT_PAUSE; + + PrintMatchCallLocation(gfx, 0); + return LT_INC_AND_PAUSE; + case 2: + PrintMatchCallLocation(gfx, 0); + return LT_INC_AND_PAUSE; + case 3: + if (IsDma3ManagerBusyWithBgCopy()) + return LT_PAUSE; + break; + } + return LT_FINISH; +} + +static u32 MatchCallListCursorUp(s32 state) +{ + struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); + switch (state) + { + case 0: + switch (PokenavList_MoveCursorUp()) + { + case 0: + break; + case 1: + PlaySE(SE_SELECT); + return LT_SET_STATE(2); + case 2: + PlaySE(SE_SELECT); + // fall through + default: + return LT_INC_AND_PAUSE; + } + break; + case 1: + if (PokenavList_IsMoveWindowTaskActive()) + return LT_PAUSE; + + PrintMatchCallLocation(gfx, 0); + return LT_INC_AND_PAUSE; + case 2: + PrintMatchCallLocation(gfx, 0); + return LT_INC_AND_PAUSE; + case 3: + if (IsDma3ManagerBusyWithBgCopy()) + return LT_PAUSE; + break; + } + return LT_FINISH; +} + +static u32 MatchCallListPageDown(s32 state) +{ + struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); + switch (state) + { + case 0: + switch (PokenavList_PageDown()) + { + case 0: + break; + case 1: + PlaySE(SE_SELECT); + return LT_SET_STATE(2); + case 2: + PlaySE(SE_SELECT); + // fall through + default: + return LT_INC_AND_PAUSE; + } + break; + case 1: + if (PokenavList_IsMoveWindowTaskActive()) + return LT_PAUSE; + + PrintMatchCallLocation(gfx, 0); + return LT_INC_AND_PAUSE; + case 2: + PrintMatchCallLocation(gfx, 0); + return LT_INC_AND_PAUSE; + case 3: + if (IsDma3ManagerBusyWithBgCopy()) + return LT_PAUSE; + break; + } + return LT_FINISH; +} + +static u32 MatchCallListPageUp(s32 state) +{ + struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); + switch (state) + { + case 0: + switch (PokenavList_PageUp()) + { + case 0: + break; + case 1: + PlaySE(SE_SELECT); + return LT_SET_STATE(2); + case 2: + PlaySE(SE_SELECT); + // fall through + default: + return LT_INC_AND_PAUSE; + } + break; + case 1: + if (PokenavList_IsMoveWindowTaskActive()) + return LT_PAUSE; + + PrintMatchCallLocation(gfx, 0); + return LT_INC_AND_PAUSE; + case 2: + PrintMatchCallLocation(gfx, 0); + return LT_INC_AND_PAUSE; + case 3: + if (IsDma3ManagerBusyWithBgCopy()) + return LT_PAUSE; + break; + } + return LT_FINISH; +} + +static u32 SelectMatchCallEntry(s32 state) +{ + struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); + switch (state) + { + case 0: + PlaySE(SE_SELECT); + PrintMatchCallSelectionOptions(gfx); + PrintHelpBarText(HELPBAR_MC_CALL_MENU); + return LT_INC_AND_PAUSE; + case 1: + if (ShowOptionsCursor(gfx)) + return LT_PAUSE; + break; + } + + return LT_FINISH; +} + +static u32 MoveMatchCallOptionsCursor(s32 state) +{ + struct Pokenav_MatchCallGfx *gfx; + u16 cursorPos; + + PlaySE(SE_SELECT); + gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); + cursorPos = GetMatchCallOptionCursorPos(); + UpdateCursorGfxPos(gfx, cursorPos); + return LT_FINISH; +} + +static u32 CancelMatchCallSelection(s32 state) +{ + struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); + switch (state) + { + case 0: + PlaySE(SE_SELECT); + UpdateWindowsReturnToTrainerList(gfx); + PrintHelpBarText(HELPBAR_MC_TRAINER_LIST); + return LT_INC_AND_PAUSE; + case 1: + if (IsDma3ManagerBusyWithBgCopy1(gfx)) + return LT_PAUSE; + break; + } + + return LT_FINISH; +} + +static u32 DoMatchCallMessage(s32 state) +{ + struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); + switch (state) + { + case 0: + PokenavList_ToggleVerticalArrows(TRUE); + DrawMsgBoxForMatchCallMsg(gfx); + return LT_INC_AND_PAUSE; + case 1: + if (IsDma3ManagerBusyWithBgCopy2(gfx)) + return LT_PAUSE; + + PrintCallingDots(gfx); + PlaySE(SE_POKENAV_CALL); + gfx->skipHangUpSE = FALSE; + return LT_INC_AND_PAUSE; + case 2: + if (WaitForCallingDotsText(gfx)) + return LT_PAUSE; + + PrintMatchCallMessage(gfx); + return LT_INC_AND_PAUSE; + case 3: + if (WaitForMatchCallMessageText(gfx)) + return LT_PAUSE; + break; + } + + return LT_FINISH; +} + +static u32 DoTrainerCloseByMessage(s32 state) +{ + struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); + switch (state) + { + case 0: + PlaySE(SE_SELECT); + DrawMsgBoxForCloseByMsg(gfx); + PokenavList_ToggleVerticalArrows(TRUE); + gfx->skipHangUpSE = TRUE; + return LT_INC_AND_PAUSE; + case 1: + if (IsDma3ManagerBusyWithBgCopy2(gfx)) + return LT_PAUSE; + + PrintTrainerIsCloseBy(gfx); + return LT_INC_AND_PAUSE; + case 2: + if (WaitForTrainerIsCloseByText(gfx)) + return LT_PAUSE; + break; + } + + return LT_FINISH; +} + +static u32 CloseMatchCallMessage(s32 state) +{ + struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); + u32 result = LT_INC_AND_PAUSE; + + switch (state) + { + case 0: + if (!gfx->skipHangUpSE) + PlaySE(SE_POKENAV_HANG_UP); + + PlaySE(SE_SELECT); + break; + case 1: + EraseCallMessageBox(gfx); + break; + case 2: + if (WaitForCallMessageBoxErase(gfx)) + result = LT_PAUSE; + break; + case 3: + UpdateWindowsReturnToTrainerList(gfx); + break; + case 4: + if (IsDma3ManagerBusyWithBgCopy1(gfx)) + result = LT_PAUSE; + + PrintHelpBarText(HELPBAR_MC_TRAINER_LIST); + break; + case 5: + if (WaitForHelpBar()) + { + result = LT_PAUSE; + } + else + { + if (gfx->newRematchRequest) + { + // This call was a new rematch request, + // add the Pokéball icon to their entry + PokenavList_DrawCurrentItemIcon(); + result = LT_INC_AND_CONTINUE; + } + else + { + PokenavList_ToggleVerticalArrows(FALSE); + result = LT_FINISH; + } + } + break; + case 6: + if (IsDma3ManagerBusyWithBgCopy()) + { + result = LT_PAUSE; + } + else + { + PokenavList_ToggleVerticalArrows(FALSE); + result = LT_FINISH; + } + break; + } + + return result; +} + +static u32 ShowCheckPage(s32 state) +{ + struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); + switch (state) + { + case 0: + PlaySE(SE_SELECT); + PokenavList_EraseListForCheckPage(); + UpdateWindowsToShowCheckPage(gfx); + return LT_INC_AND_PAUSE; + case 1: + if (PokenavList_IsTaskActive() || IsDma3ManagerBusyWithBgCopy1(gfx)) + return LT_PAUSE; + + PrintHelpBarText(HELPBAR_MC_CHECK_PAGE); + return LT_INC_AND_PAUSE; + case 2: + PrintCheckPageInfo(0); + LoadCheckPageTrainerPic(gfx); + return LT_INC_AND_PAUSE; + case 3: + if (PokenavList_IsTaskActive() || WaitForTrainerPic(gfx) || WaitForHelpBar()) + return LT_PAUSE; + break; + } + + return LT_FINISH; +} + +static u32 ShowCheckPageDown(s32 state) +{ + int topId; + int delta; + struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); + switch (state) + { + case 0: + topId = PokenavList_GetTopIndex(); + delta = GetIndexDeltaOfNextCheckPageDown(topId); + if (delta) + { + PlaySE(SE_SELECT); + gfx->pageDelta = delta; + TrainerPicSlideOffscreen(gfx); + return LT_INC_AND_PAUSE; + } + break; + case 1: + if (WaitForTrainerPic(gfx)) + return LT_PAUSE; + + PrintMatchCallLocation(gfx, gfx->pageDelta); + return LT_INC_AND_PAUSE; + case 2: + PrintCheckPageInfo(gfx->pageDelta); + return LT_INC_AND_PAUSE; + case 3: + LoadCheckPageTrainerPic(gfx); + return LT_INC_AND_PAUSE; + case 4: + if (PokenavList_IsTaskActive() || WaitForTrainerPic(gfx)) + return LT_PAUSE; + break; + } + + return LT_FINISH; +} + +static u32 ExitCheckPage(s32 state) +{ + struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); + switch (state) + { + case 0: + PlaySE(SE_SELECT); + TrainerPicSlideOffscreen(gfx); + PokenavList_ReshowListFromCheckPage(); + return LT_INC_AND_PAUSE; + case 1: + if (PokenavList_IsTaskActive() || WaitForTrainerPic(gfx)) + return LT_PAUSE; + + PrintHelpBarText(HELPBAR_MC_TRAINER_LIST); + UpdateMatchCallInfoBox(gfx); + return LT_INC_AND_PAUSE; + case 2: + if (IsDma3ManagerBusyWithBgCopy()) + return LT_PAUSE; + break; + } + + return LT_FINISH; +} + +static u32 ShowCheckPageUp(s32 state) +{ + int topId; + int delta; + struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); + switch (state) + { + case 0: + topId = PokenavList_GetTopIndex(); + delta = GetIndexDeltaOfNextCheckPageUp(topId); + if (delta) + { + PlaySE(SE_SELECT); + gfx->pageDelta = delta; + TrainerPicSlideOffscreen(gfx); + return LT_INC_AND_PAUSE; + } + break; + case 1: + if (WaitForTrainerPic(gfx)) + return LT_PAUSE; + + PrintMatchCallLocation(gfx, gfx->pageDelta); + return LT_INC_AND_PAUSE; + case 2: + PrintCheckPageInfo(gfx->pageDelta); + return LT_INC_AND_PAUSE; + case 3: + LoadCheckPageTrainerPic(gfx); + return LT_INC_AND_PAUSE; + case 4: + if (PokenavList_IsTaskActive() || WaitForTrainerPic(gfx)) + return LT_PAUSE; + break; + } + + return LT_FINISH; +} + +static u32 ExitMatchCall(s32 state) +{ + switch (state) + { + case 0: + PlaySE(SE_SELECT); + SetPokeballIconsFlashing(FALSE); + PokenavFadeScreen(POKENAV_FADE_TO_BLACK); + SlideMenuHeaderDown(); + return LT_INC_AND_PAUSE; + case 1: + if (IsPaletteFadeActive() || MainMenuLoopedTaskIsBusy()) + return LT_PAUSE; + + SetLeftHeaderSpritesInvisibility(); + break; + } + + return LT_FINISH; +} + +static void CreateMatchCallList(void) +{ + struct PokenavListTemplate template; + template.list = (struct PokenavListItem *)GetMatchCallList(); + template.count = GetNumberRegistered(); + template.itemSize = sizeof(struct PokenavListItem); + template.startIndex = 0; + template.item_X = 13; + template.windowWidth = 16; + template.listTop = 1; + template.maxShowed = 8; + template.fillValue = 3; + template.fontId = FONT_NARROW; + template.bufferItemFunc = (PokenavListBufferItemFunc)BufferMatchCallNameAndDesc; + template.iconDrawFunc = TryDrawRematchPokeballIcon; + CreatePokenavList(&sMatchCallBgTemplates[2], &template, 2); + CreateTask(Task_FlashPokeballIcons, 7); +} + +static void DestroyMatchCallList(void) +{ + DestroyPokenavList(); + DestroyTask(FindTaskIdByFunc(Task_FlashPokeballIcons)); +} + +#define tSinIdx data[0] +#define tSinVal data[1] +#define tActive data[15] + +static void SetPokeballIconsFlashing(bool32 active) +{ + u8 taskId = FindTaskIdByFunc(Task_FlashPokeballIcons); + if (taskId != TASK_NONE) + gTasks[taskId].tActive = active; +} + +static void Task_FlashPokeballIcons(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + if (tActive) + { + tSinIdx += 4; + tSinIdx &= 0x7F; + tSinVal = gSineTable[tSinIdx] >> 4; + PokenavCopyPalette(sPokeball_Pal, &sPokeball_Pal[0x10], 0x10, 0x10, tSinVal, &gPlttBufferUnfaded[0x50]); + if (!gPaletteFade.active) + CpuCopy32(&gPlttBufferUnfaded[0x50], &gPlttBufferFaded[0x50], 0x20); + } +} + +#undef tSinIdx +#undef tSinVal +#undef tActive + +enum { + POKEBALL_ICON_TOP = 0x5000, + POKEBALL_ICON_BOTTOM, + POKEBALL_ICON_EMPTY, +}; + +static void TryDrawRematchPokeballIcon(u16 windowId, u32 rematchId, u32 tileOffset) +{ + u8 bg = GetWindowAttribute(windowId, WINDOW_BG); + u16 *tilemap = GetBgTilemapBuffer(bg); + tilemap += tileOffset * 64 + 0x1D; + if (ShouldDrawRematchPokeballIcon(rematchId)) + { + tilemap[0] = POKEBALL_ICON_TOP; + tilemap[0x20] = POKEBALL_ICON_BOTTOM; + } + else + { + tilemap[0] = POKEBALL_ICON_EMPTY; + tilemap[0x20] = POKEBALL_ICON_EMPTY; + } +} + +void ClearRematchPokeballIcon(u16 windowId, u32 tileOffset) +{ + u8 bg = GetWindowAttribute(windowId, WINDOW_BG); + u16 *tilemap = GetBgTilemapBuffer(bg); + tilemap += tileOffset * 64 + 0x1D; + tilemap[0] = POKEBALL_ICON_EMPTY; + tilemap[0x20] = POKEBALL_ICON_EMPTY; +} + +static void DrawMatchCallLeftColumnWindows(struct Pokenav_MatchCallGfx *gfx) +{ + gfx->locWindowId = AddWindow(&sMatchCallLocationWindowTemplate); + gfx->infoBoxWindowId = AddWindow(&sMatchCallInfoBoxWindowTemplate); + FillWindowPixelBuffer(gfx->locWindowId, PIXEL_FILL(1)); + PutWindowTilemap(gfx->locWindowId); + FillWindowPixelBuffer(gfx->infoBoxWindowId, PIXEL_FILL(1)); + PutWindowTilemap(gfx->infoBoxWindowId); + CopyWindowToVram(gfx->locWindowId, COPYWIN_MAP); +} + +static void UpdateMatchCallInfoBox(struct Pokenav_MatchCallGfx *gfx) +{ + FillWindowPixelBuffer(gfx->infoBoxWindowId, PIXEL_FILL(1)); + PrintNumberRegisteredLabel(gfx->infoBoxWindowId); + PrintNumberRegistered(gfx->infoBoxWindowId); + PrintNumberOfBattlesLabel(gfx->infoBoxWindowId); + PrintNumberOfBattles(gfx->infoBoxWindowId); + CopyWindowToVram(gfx->infoBoxWindowId, COPYWIN_GFX); +} + +static void PrintNumberRegisteredLabel(u16 windowId) +{ + PrintMatchCallInfoLabel(windowId, gText_NumberRegistered, 0); +} + +static void PrintNumberRegistered(u16 windowId) +{ + u8 str[3]; + ConvertIntToDecimalStringN(str, GetNumberRegistered(), STR_CONV_MODE_LEFT_ALIGN, 3); + PrintMatchCallInfoNumber(windowId, str, 1); +} + +static void PrintNumberOfBattlesLabel(u16 windowId) +{ + PrintMatchCallInfoLabel(windowId, gText_NumberOfBattles, 2); +} + +static void PrintNumberOfBattles(u16 windowId) +{ + u8 str[5]; + int numTrainerBattles = GetGameStat(GAME_STAT_TRAINER_BATTLES); + if (numTrainerBattles > 99999) + numTrainerBattles = 99999; + + ConvertIntToDecimalStringN(str, numTrainerBattles, STR_CONV_MODE_LEFT_ALIGN, 5); + PrintMatchCallInfoNumber(windowId, str, 3); +} + +static void PrintMatchCallInfoLabel(u16 windowId, const u8 *str, int top) +{ + int y = top * 16 + 1; + AddTextPrinterParameterized(windowId, FONT_NARROW, str, 2, y, TEXT_SKIP_DRAW, NULL); +} + +static void PrintMatchCallInfoNumber(u16 windowId, const u8 *str, int top) +{ + int x = GetStringRightAlignXOffset(FONT_NARROW, str, 86); + int y = top * 16 + 1; + AddTextPrinterParameterized(windowId, FONT_NARROW, str, x, y, TEXT_SKIP_DRAW, NULL); +} + +static void PrintMatchCallLocation(struct Pokenav_MatchCallGfx *gfx, int delta) +{ + u8 mapName[32]; + int x; + int index = PokenavList_GetSelectedIndex() + delta; + int mapSec = GetMatchCallMapSec(index); + if (mapSec != MAPSEC_NONE) + GetMapName(mapName, mapSec, 0); + else + StringCopy(mapName, gText_Unknown); + + x = GetStringCenterAlignXOffset(FONT_NARROW, mapName, 88); + FillWindowPixelBuffer(gfx->locWindowId, PIXEL_FILL(1)); + AddTextPrinterParameterized(gfx->locWindowId, FONT_NARROW, mapName, x, 1, 0, NULL); +} + +static void PrintMatchCallSelectionOptions(struct Pokenav_MatchCallGfx *gfx) +{ + u32 i; + + FillWindowPixelBuffer(gfx->infoBoxWindowId, PIXEL_FILL(1)); + for (i = 0; i < MATCH_CALL_OPTION_COUNT; i++) + { + int optionText = GetMatchCallOptionId(i); + if (optionText == MATCH_CALL_OPTION_COUNT) + break; + + AddTextPrinterParameterized(gfx->infoBoxWindowId, FONT_NARROW, sMatchCallOptionTexts[optionText], 16, i * 16 + 1, TEXT_SKIP_DRAW, NULL); + } + + CopyWindowToVram(gfx->infoBoxWindowId, COPYWIN_GFX); +} + +static bool32 ShowOptionsCursor(struct Pokenav_MatchCallGfx *gfx) +{ + if (!IsDma3ManagerBusyWithBgCopy()) + { + CreateOptionsCursorSprite(gfx, GetMatchCallOptionCursorPos()); + return FALSE; + } + + return TRUE; +} + +static void UpdateWindowsReturnToTrainerList(struct Pokenav_MatchCallGfx *gfx) +{ + CloseMatchCallSelectOptionsWindow(gfx); + UpdateMatchCallInfoBox(gfx); +} + +static bool32 IsDma3ManagerBusyWithBgCopy1(struct Pokenav_MatchCallGfx *gfx) +{ + return IsDma3ManagerBusyWithBgCopy(); +} + +static void UpdateWindowsToShowCheckPage(struct Pokenav_MatchCallGfx *gfx) +{ + CloseMatchCallSelectOptionsWindow(gfx); + FillWindowPixelBuffer(gfx->infoBoxWindowId, PIXEL_FILL(1)); + CopyWindowToVram(gfx->infoBoxWindowId, COPYWIN_GFX); +} + +static void LoadCallWindowAndFade(struct Pokenav_MatchCallGfx *gfx) +{ + gfx->msgBoxWindowId = AddWindow(&sCallMsgBoxWindowTemplate); + LoadMatchCallWindowGfx(gfx->msgBoxWindowId, 1, 4); + FadeToBlackExceptPrimary(); +} + +static void DrawMsgBoxForMatchCallMsg(struct Pokenav_MatchCallGfx *gfx) +{ + struct Sprite *sprite; + LoadMatchCallWindowGfx(gfx->msgBoxWindowId, 1, 4); + DrawMatchCallTextBoxBorder(gfx->msgBoxWindowId, 1, 4); + FillWindowPixelBuffer(gfx->msgBoxWindowId, PIXEL_FILL(1)); + PutWindowTilemap(gfx->msgBoxWindowId); + CopyWindowToVram(gfx->msgBoxWindowId, COPYWIN_FULL); + sprite = GetSpinningPokenavSprite(); + sprite->x = 24; + sprite->y = 112; + sprite->y2 = 0; +} + +static void DrawMsgBoxForCloseByMsg(struct Pokenav_MatchCallGfx *gfx) +{ + LoadUserWindowBorderGfx(gfx->msgBoxWindowId, 1, 0x40); + DrawTextBorderOuter(gfx->msgBoxWindowId, 1, 4); + FillWindowPixelBuffer(gfx->msgBoxWindowId, PIXEL_FILL(1)); + PutWindowTilemap(gfx->msgBoxWindowId); + CopyWindowToVram(gfx->msgBoxWindowId, COPYWIN_FULL); +} + +static bool32 IsDma3ManagerBusyWithBgCopy2(struct Pokenav_MatchCallGfx *gfx) +{ + return IsDma3ManagerBusyWithBgCopy(); +} + +static void PrintCallingDots(struct Pokenav_MatchCallGfx *gfx) +{ + AddTextPrinterParameterized(gfx->msgBoxWindowId, FONT_NORMAL, sText_CallingDots, 32, 1, 1, NULL); +} + +static bool32 WaitForCallingDotsText(struct Pokenav_MatchCallGfx *gfx) +{ + RunTextPrinters(); + return IsTextPrinterActive(gfx->msgBoxWindowId); +} + +static void PrintTrainerIsCloseBy(struct Pokenav_MatchCallGfx *gfx) +{ + AddTextPrinterParameterized(gfx->msgBoxWindowId, FONT_NORMAL, gText_TrainerCloseBy, 0, 1, 1, NULL); +} + +static bool32 WaitForTrainerIsCloseByText(struct Pokenav_MatchCallGfx *gfx) +{ + RunTextPrinters(); + return IsTextPrinterActive(gfx->msgBoxWindowId); +} + +static void PrintMatchCallMessage(struct Pokenav_MatchCallGfx *gfx) +{ + int index = PokenavList_GetSelectedIndex(); + const u8 *str = GetMatchCallMessageText(index, &gfx->newRematchRequest); + u8 speed = GetPlayerTextSpeedDelay(); + AddTextPrinterParameterized(gfx->msgBoxWindowId, FONT_NORMAL, str, 32, 1, speed, NULL); +} + +static bool32 WaitForMatchCallMessageText(struct Pokenav_MatchCallGfx *gfx) +{ + if (JOY_HELD(A_BUTTON)) + gTextFlags.canABSpeedUpPrint = TRUE; + else + gTextFlags.canABSpeedUpPrint = FALSE; + + RunTextPrinters(); + return IsTextPrinterActive(gfx->msgBoxWindowId); +} + +static void EraseCallMessageBox(struct Pokenav_MatchCallGfx *gfx) +{ + HideSpinningPokenavSprite(); + FillBgTilemapBufferRect_Palette0(1, 0, 0, 0, 32, 20); + CopyBgTilemapBufferToVram(1); +} + +static bool32 WaitForCallMessageBoxErase(struct Pokenav_MatchCallGfx *gfx) +{ + return IsDma3ManagerBusyWithBgCopy(); +} + +static void AllocMatchCallSprites(void) +{ + int i; + u8 paletteNum; + struct SpriteSheet spriteSheet; + struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); + + // Load options cursor gfx + for (i = 0; i < ARRAY_COUNT(sOptionsCursorSpriteSheets); i++) + LoadCompressedSpriteSheet(&sOptionsCursorSpriteSheets[i]); + Pokenav_AllocAndLoadPalettes(sOptionsCursorSpritePalettes); + gfx->optionsCursorSprite = NULL; + + // Load trainer pic gfx + spriteSheet.data = gfx->trainerPicGfx; + spriteSheet.size = sizeof(gfx->trainerPicGfx); + spriteSheet.tag = GFXTAG_TRAINER_PIC; + gfx->trainerPicGfxPtr = (u8 *)OBJ_VRAM0 + LoadSpriteSheet(&spriteSheet) * 0x20; + paletteNum = AllocSpritePalette(PALTAG_TRAINER_PIC); + gfx->trainerPicPalOffset = 0x100 + paletteNum * 0x10; + gfx->trainerPicSprite = CreateTrainerPicSprite(); + gfx->trainerPicSprite->invisible = TRUE; +} + +static void FreeMatchCallSprites(void) +{ + struct Pokenav_MatchCallGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_OPEN); + if (gfx->optionsCursorSprite) + DestroySprite(gfx->optionsCursorSprite); + if (gfx->trainerPicSprite) + DestroySprite(gfx->trainerPicSprite); + + FreeSpriteTilesByTag(GFXTAG_TRAINER_PIC); + FreeSpriteTilesByTag(GFXTAG_CURSOR); + FreeSpritePaletteByTag(PALTAG_CURSOR); + FreeSpritePaletteByTag(PALTAG_TRAINER_PIC); +} + +static void CreateOptionsCursorSprite(struct Pokenav_MatchCallGfx *gfx, int top) +{ + if (!gfx->optionsCursorSprite) + { + u8 spriteId = CreateSprite(&sOptionsCursorSpriteTemplate, 4, 80, 5); + gfx->optionsCursorSprite = &gSprites[spriteId]; + UpdateCursorGfxPos(gfx, top); + } +} + +static void CloseMatchCallSelectOptionsWindow(struct Pokenav_MatchCallGfx *gfx) +{ + DestroySprite(gfx->optionsCursorSprite); + gfx->optionsCursorSprite = NULL; +} + +static void UpdateCursorGfxPos(struct Pokenav_MatchCallGfx *gfx, int top) +{ + gfx->optionsCursorSprite->y2 = top * 16; +} + +static void SpriteCB_OptionsCursor(struct Sprite *sprite) +{ + if (++sprite->data[0] > 3) + { + sprite->data[0] = 0; + sprite->x2 = (sprite->x2 + 1) & 7; + } +} + +static struct Sprite *CreateTrainerPicSprite(void) +{ + u8 spriteId = CreateSprite(&sTrainerPicSpriteTemplate, 44, 104, 6); + return &gSprites[spriteId]; +} + +static void LoadCheckPageTrainerPic(struct Pokenav_MatchCallGfx *gfx) +{ + u16 cursor; + int trainerPic = GetMatchCallTrainerPic(PokenavList_GetSelectedIndex()); + if (trainerPic >= 0) + { + DecompressPicFromTable(&gTrainerFrontPicTable[trainerPic], gfx->trainerPicGfx, SPECIES_NONE); + LZ77UnCompWram(gTrainerFrontPicPaletteTable[trainerPic].data, gfx->trainerPicPal); + cursor = RequestDma3Copy(gfx->trainerPicGfx, gfx->trainerPicGfxPtr, sizeof(gfx->trainerPicGfx), 1); + LoadPalette(gfx->trainerPicPal, gfx->trainerPicPalOffset, sizeof(gfx->trainerPicPal)); + gfx->trainerPicSprite->data[0] = 0; + gfx->trainerPicSprite->data[7] = cursor; + gfx->trainerPicSprite->callback = SpriteCB_TrainerPicSlideOnscreen; + } +} + +static void TrainerPicSlideOffscreen(struct Pokenav_MatchCallGfx *gfx) +{ + gfx->trainerPicSprite->callback = SpriteCB_TrainerPicSlideOffscreen; +} + +static bool32 WaitForTrainerPic(struct Pokenav_MatchCallGfx *gfx) +{ + return gfx->trainerPicSprite->callback != SpriteCallbackDummy; +} + +static void SpriteCB_TrainerPicSlideOnscreen(struct Sprite *sprite) +{ + switch (sprite->data[0]) + { + case 0: + if (CheckForSpaceForDma3Request(sprite->data[7]) != -1) + { + sprite->x2 = -80; + sprite->invisible = FALSE; + sprite->data[0]++; + } + break; + case 1: + sprite->x2 += 8; + if (sprite->x2 >= 0) + { + sprite->x2 = 0; + sprite->callback = SpriteCallbackDummy; + } + break; + } +} + +static void SpriteCB_TrainerPicSlideOffscreen(struct Sprite *sprite) +{ + sprite->x2 -= 8; + if (sprite->x2 <= -80) + { + sprite->invisible = TRUE; + sprite->callback = SpriteCallbackDummy; + } +} diff --git a/src/pokenav_match_call_list.c b/src/pokenav_match_call_list.c new file mode 100755 index 000000000..d56cfdb62 --- /dev/null +++ b/src/pokenav_match_call_list.c @@ -0,0 +1,521 @@ +#include "global.h" +#include "battle_setup.h" +#include "data.h" +#include "event_data.h" +#include "gym_leader_rematch.h" +#include "international_string_util.h" +#include "main.h" +#include "match_call.h" +#include "overworld.h" +#include "pokemon.h" +#include "pokenav.h" +#include "sound.h" +#include "string_util.h" +#include "strings.h" +#include "constants/songs.h" + +struct Pokenav_MatchCallMenu +{ + u16 optionCursorPos; + u16 maxOptionId; + const u8 *matchCallOptions; + u16 headerId; + u16 numRegistered; + u16 numSpecialTrainers; + bool32 initFinished; + u32 loopedTaskId; + u32 (*callback)(struct Pokenav_MatchCallMenu*); + struct PokenavMatchCallEntry matchCallEntries[MAX_REMATCH_ENTRIES - 1]; +}; + +static u32 CB2_HandleMatchCallInput(struct Pokenav_MatchCallMenu *); +static u32 GetExitMatchCallMenuId(struct Pokenav_MatchCallMenu *); +static u32 CB2_HandleMatchCallOptionsInput(struct Pokenav_MatchCallMenu *); +static u32 CB2_HandleCheckPageInput(struct Pokenav_MatchCallMenu *); +static u32 CB2_HandleCallExitInput(struct Pokenav_MatchCallMenu *); +static u32 LoopedTask_BuildMatchCallList(s32); +static bool32 ShouldDoNearbyMessage(void); + +#include "data/text/match_call_messages.h" + +static const u8 sMatchCallOptionsNoCheckPage[] = +{ + MATCH_CALL_OPTION_CALL, + MATCH_CALL_OPTION_CANCEL +}; + +static const u8 sMatchCallOptionsHasCheckPage[] = +{ + MATCH_CALL_OPTION_CALL, + MATCH_CALL_OPTION_CHECK, + MATCH_CALL_OPTION_CANCEL +}; + +bool32 PokenavCallback_Init_MatchCall(void) +{ + struct Pokenav_MatchCallMenu *state = AllocSubstruct(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN, sizeof(struct Pokenav_MatchCallMenu)); + if (!state) + return FALSE; + + state->callback = CB2_HandleMatchCallInput; + state->headerId = 0; + state->initFinished = FALSE; + state->loopedTaskId = CreateLoopedTask(LoopedTask_BuildMatchCallList, 1); + return TRUE; +} + +u32 GetMatchCallCallback(void) +{ + struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); + return state->callback(state); +} + +void FreeMatchCallSubstruct1(void) +{ + FreePokenavSubstruct(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); +} + +static u32 CB2_HandleMatchCallInput(struct Pokenav_MatchCallMenu *state) +{ + int selection; + + if (JOY_REPEAT(DPAD_UP)) + return POKENAV_MC_FUNC_UP; + if (JOY_REPEAT(DPAD_DOWN)) + return POKENAV_MC_FUNC_DOWN; + if (JOY_REPEAT(DPAD_LEFT)) + return POKENAV_MC_FUNC_PG_UP; + if (JOY_REPEAT(DPAD_RIGHT)) + return POKENAV_MC_FUNC_PG_DOWN; + + if (JOY_NEW(A_BUTTON)) + { + state->callback = CB2_HandleMatchCallOptionsInput; + state->optionCursorPos = 0; + selection = PokenavList_GetSelectedIndex(); + + if (!state->matchCallEntries[selection].isSpecialTrainer || MatchCall_HasCheckPage(state->matchCallEntries[selection].headerId)) + { + state->matchCallOptions = sMatchCallOptionsHasCheckPage; + state->maxOptionId = ARRAY_COUNT(sMatchCallOptionsHasCheckPage) - 1; + } + else + { + state->matchCallOptions = sMatchCallOptionsNoCheckPage; + state->maxOptionId = ARRAY_COUNT(sMatchCallOptionsNoCheckPage) - 1; + } + + return POKENAV_MC_FUNC_SELECT; + } + + if (JOY_NEW(B_BUTTON)) + { + if (GetPokenavMode() != POKENAV_MODE_FORCE_CALL_READY) + { + state->callback = GetExitMatchCallMenuId; + return POKENAV_MC_FUNC_EXIT; + } + else + { + // Cant exit Match Call menu before calling Mr Stone during tutorial + PlaySE(SE_FAILURE); + } + } + + return POKENAV_MC_FUNC_NONE; +} + +static u32 GetExitMatchCallMenuId(struct Pokenav_MatchCallMenu *state) +{ + return POKENAV_MAIN_MENU_CURSOR_ON_MATCH_CALL; +} + +static u32 CB2_HandleMatchCallOptionsInput(struct Pokenav_MatchCallMenu *state) +{ + if (JOY_NEW(DPAD_UP) && state->optionCursorPos) + { + state->optionCursorPos--; + return POKENAV_MC_FUNC_MOVE_OPTIONS_CURSOR; + } + + if (JOY_NEW(DPAD_DOWN) && state->optionCursorPos < state->maxOptionId) + { + state->optionCursorPos++; + return POKENAV_MC_FUNC_MOVE_OPTIONS_CURSOR; + } + + if (JOY_NEW(A_BUTTON)) + { + switch (state->matchCallOptions[state->optionCursorPos]) + { + case MATCH_CALL_OPTION_CANCEL: + state->callback = CB2_HandleMatchCallInput; + return POKENAV_MC_FUNC_CANCEL; + case MATCH_CALL_OPTION_CALL: + if (GetPokenavMode() == POKENAV_MODE_FORCE_CALL_READY) + SetPokenavMode(POKENAV_MODE_FORCE_CALL_EXIT); + + state->callback = CB2_HandleCallExitInput; + if (ShouldDoNearbyMessage()) + return POKENAV_MC_FUNC_NEARBY_MSG; + + return POKENAV_MC_FUNC_CALL_MSG; + case MATCH_CALL_OPTION_CHECK: + state->callback = CB2_HandleCheckPageInput; + return POKENAV_MC_FUNC_SHOW_CHECK_PAGE; + } + } + + if (JOY_NEW(B_BUTTON)) + { + state->callback = CB2_HandleMatchCallInput; + return POKENAV_MC_FUNC_CANCEL; + } + + return POKENAV_MC_FUNC_NONE; +} + +static u32 CB2_HandleCheckPageInput(struct Pokenav_MatchCallMenu *state) +{ + if (JOY_REPEAT(DPAD_UP)) + return POKENAV_MC_FUNC_CHECK_PAGE_UP; + if (JOY_REPEAT(DPAD_DOWN)) + return POKENAV_MC_FUNC_CHECK_PAGE_DOWN; + + if (JOY_NEW(B_BUTTON)) + { + state->callback = CB2_HandleMatchCallInput; + return POKENAV_MC_FUNC_EXIT_CHECK_PAGE; + } + + return POKENAV_MC_FUNC_NONE; +} + +static u32 CB2_HandleCallExitInput(struct Pokenav_MatchCallMenu *state) +{ + if (JOY_NEW(A_BUTTON | B_BUTTON)) + { + state->callback = CB2_HandleMatchCallInput; + return POKENAV_MC_FUNC_EXIT_CALL; + } + + return POKENAV_MC_FUNC_NONE; +} + +static u32 LoopedTask_BuildMatchCallList(s32 taskState) +{ + int i, j; + struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); + switch (taskState) + { + case 0: + state->headerId = 0; + state->numRegistered = 0; + return LT_INC_AND_CONTINUE; + case 1: + // Load special trainers (e.g. Rival, gym leaders) + for (i = 0, j = state->headerId; i < 30; i++, j++) + { + if (MatchCall_GetEnabled(j)) + { + state->matchCallEntries[state->numRegistered].headerId = j; + state->matchCallEntries[state->numRegistered].isSpecialTrainer = TRUE; + state->matchCallEntries[state->numRegistered].mapSec = MatchCall_GetMapSec(j); + state->numRegistered++; + } + + if (++state->headerId >= MC_HEADER_COUNT) + { + state->numSpecialTrainers = state->headerId; + state->headerId = 0; + return LT_INC_AND_CONTINUE; + } + } + + return LT_CONTINUE; + case 2: + // Load normal trainers + for (i = 0, j = state->headerId; i < 30; i++, j++) + { + if (!MatchCall_HasRematchId(state->headerId) && IsRematchEntryRegistered(state->headerId)) + { + state->matchCallEntries[state->numRegistered].headerId = state->headerId; + state->matchCallEntries[state->numRegistered].isSpecialTrainer = FALSE; + state->matchCallEntries[state->numRegistered].mapSec = GetMatchTableMapSectionId(j); + state->numRegistered++; + } + + if (++state->headerId > REMATCH_TABLE_ENTRIES - 1) + return LT_INC_AND_CONTINUE; + } + + return LT_CONTINUE; + case 3: + state->initFinished = TRUE; + break; + } + + return LT_FINISH; +} + +bool32 IsRematchEntryRegistered(int rematchIndex) +{ + if (rematchIndex < REMATCH_TABLE_ENTRIES) + return FlagGet(FLAG_MATCH_CALL_REGISTERED + rematchIndex); + + return FALSE; +} + +int IsMatchCallListInitFinished(void) +{ + struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); + return state->initFinished; +} + +int GetNumberRegistered(void) +{ + struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); + return state->numRegistered; +} + +// Unused +static int GetNumSpecialTrainers(void) +{ + struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); + return state->numSpecialTrainers; +} + +// Unused +static int GetNumNormalTrainers(void) +{ + struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); + return state->numRegistered - state->numSpecialTrainers; +} + +// Unused +static int GetNormalTrainerHeaderId(int index) +{ + struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); + index += state->numSpecialTrainers; + if (index >= state->numRegistered) + return REMATCH_TABLE_ENTRIES; + + return state->matchCallEntries[index].headerId; +} + +struct PokenavMatchCallEntry *GetMatchCallList(void) +{ + struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); + return state->matchCallEntries; +} + +u16 GetMatchCallMapSec(int index) +{ + struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); + return state->matchCallEntries[index].mapSec; +} + +bool32 ShouldDrawRematchPokeballIcon(int index) +{ + struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); + if (!state->matchCallEntries[index].isSpecialTrainer) + index = state->matchCallEntries[index].headerId; + else + index = MatchCall_GetRematchTableIdx(state->matchCallEntries[index].headerId); + + if (index == REMATCH_TABLE_ENTRIES) + return FALSE; + + return gSaveBlock1Ptr->trainerRematches[index] != 0; +} + +int GetMatchCallTrainerPic(int index) +{ + int headerId; + struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); + if (!state->matchCallEntries[index].isSpecialTrainer) + { + index = GetTrainerIdxByRematchIdx(state->matchCallEntries[index].headerId); + return gTrainers[index].trainerPic; + } + + headerId = state->matchCallEntries[index].headerId; + index = MatchCall_GetRematchTableIdx(headerId); + if (index != REMATCH_TABLE_ENTRIES) + { + index = GetTrainerIdxByRematchIdx(index); + return gTrainers[index].trainerPic; + } + + index = MatchCall_GetOverrideFacilityClass(headerId); + return gFacilityClassToPicIndex[index]; +} + +const u8 *GetMatchCallMessageText(int index, bool8 *newRematchRequest) +{ + struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); + *newRematchRequest = FALSE; + if (!Overworld_MapTypeAllowsTeleportAndFly(gMapHeader.mapType)) + return gText_CallCantBeMadeHere; + + if (!state->matchCallEntries[index].isSpecialTrainer) + *newRematchRequest = SelectMatchCallMessage(GetTrainerIdxByRematchIdx(state->matchCallEntries[index].headerId), gStringVar4); + else + MatchCall_GetMessage(state->matchCallEntries[index].headerId, gStringVar4); + + return gStringVar4; +} + +const u8 *GetMatchCallFlavorText(int index, int checkPageEntry) +{ + int rematchId; + struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); + if (state->matchCallEntries[index].isSpecialTrainer) + { + rematchId = MatchCall_GetRematchTableIdx(state->matchCallEntries[index].headerId); + if (rematchId == REMATCH_TABLE_ENTRIES) + return MatchCall_GetOverrideFlavorText(state->matchCallEntries[index].headerId, checkPageEntry); + } + else + { + rematchId = state->matchCallEntries[index].headerId; + } + + return gMatchCallFlavorTexts[rematchId][checkPageEntry]; +} + +u16 GetMatchCallOptionCursorPos(void) +{ + struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); + return state->optionCursorPos; +} + +u16 GetMatchCallOptionId(int optionId) +{ + struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); + if (state->maxOptionId < optionId) + return MATCH_CALL_OPTION_COUNT; + + return state->matchCallOptions[optionId]; +} + +void BufferMatchCallNameAndDesc(struct PokenavMatchCallEntry *matchCallEntry, u8 *str) +{ + const u8 *trainerName; + const u8 *className; + if (!matchCallEntry->isSpecialTrainer) + { + int index = GetTrainerIdxByRematchIdx(matchCallEntry->headerId); + const struct Trainer *trainer = &gTrainers[index]; + int class = trainer->trainerClass; + className = gTrainerClassNames[class]; + trainerName = trainer->trainerName; + } + else + { + MatchCall_GetNameAndDesc(matchCallEntry->headerId, &className, &trainerName); + } + + if (className && trainerName) + { + u8 *str2 = GetStringClearToWidth(str, FONT_NARROW, className, 69); + GetStringClearToWidth(str2, FONT_NARROW, trainerName, 51); + } + else + { + GetStringClearToWidth(str, FONT_NARROW, NULL, 120); + } +} + +u8 GetMatchTableMapSectionId(int rematchIndex) +{ + int mapGroup = gRematchTable[rematchIndex].mapGroup; + int mapNum = gRematchTable[rematchIndex].mapNum; + return Overworld_GetMapHeaderByGroupAndId(mapGroup, mapNum)->regionMapSectionId; +} + +int GetIndexDeltaOfNextCheckPageDown(int index) +{ + struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); + int count = 1; + while (++index < state->numRegistered) + { + if (!state->matchCallEntries[index].isSpecialTrainer) + return count; + if (MatchCall_HasCheckPage(state->matchCallEntries[index].headerId)) + return count; + + count++; + } + + return 0; +} + +int GetIndexDeltaOfNextCheckPageUp(int index) +{ + struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); + int count = -1; + while (--index >= 0) + { + if (!state->matchCallEntries[index].isSpecialTrainer) + return count; + if (MatchCall_HasCheckPage(state->matchCallEntries[index].headerId)) + return count; + + count--; + } + + return 0; +} + +// Unused +static bool32 HasRematchEntry(void) +{ + int i; + + for (i = 0; i < REMATCH_TABLE_ENTRIES; i++) + { + if (IsRematchEntryRegistered(i) && gSaveBlock1Ptr->trainerRematches[i]) + return TRUE; + } + + for (i = 0; i < MC_HEADER_COUNT; i++) + { + if (MatchCall_GetEnabled(i)) + { + int index = MatchCall_GetRematchTableIdx(i); + if (gSaveBlock1Ptr->trainerRematches[index]) + return TRUE; + } + } + + return FALSE; +} + +static bool32 ShouldDoNearbyMessage(void) +{ + struct Pokenav_MatchCallMenu *state = GetSubstructPtr(POKENAV_SUBSTRUCT_MATCH_CALL_MAIN); + int selection = PokenavList_GetSelectedIndex(); + if (!state->matchCallEntries[selection].isSpecialTrainer) + { + if (GetMatchCallMapSec(selection) == gMapHeader.regionMapSectionId) + { + if (!gSaveBlock1Ptr->trainerRematches[state->matchCallEntries[selection].headerId]) + return TRUE; + } + } + else + { + if (state->matchCallEntries[selection].headerId == MC_HEADER_WATTSON) + { + if (GetMatchCallMapSec(selection) == gMapHeader.regionMapSectionId + && FlagGet(FLAG_BADGE05_GET) == TRUE) + { + if (!FlagGet(FLAG_WATTSON_REMATCH_AVAILABLE)) + return TRUE; + } + } + } + + return FALSE; +} -- cgit v1.2.3