From 35aeff1b6df8efc4e088bd20c71e4243b95c6599 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Fri, 12 Nov 2021 11:07:52 -0500 Subject: Rename pokenav conditions files --- include/pokenav.h | 6 +- ld_script.txt | 10 +- src/pokenav_conditions.c | 628 ++++++++++++++++++++++ src/pokenav_conditions_1.c | 628 ---------------------- src/pokenav_conditions_2.c | 892 -------------------------------- src/pokenav_conditions_3.c | 734 -------------------------- src/pokenav_conditions_gfx.c | 892 ++++++++++++++++++++++++++++++++ src/pokenav_conditions_search_results.c | 734 ++++++++++++++++++++++++++ sym_bss.txt | 2 +- 9 files changed, 2263 insertions(+), 2263 deletions(-) create mode 100644 src/pokenav_conditions.c delete mode 100644 src/pokenav_conditions_1.c delete mode 100644 src/pokenav_conditions_2.c delete mode 100644 src/pokenav_conditions_3.c create mode 100644 src/pokenav_conditions_gfx.c create mode 100644 src/pokenav_conditions_search_results.c diff --git a/include/pokenav.h b/include/pokenav.h index 847d4b7e7..971354633 100644 --- a/include/pokenav.h +++ b/include/pokenav.h @@ -436,7 +436,7 @@ bool32 IsRegionMapLoopedTaskActive(void); void FreeRegionMapSubstruct1(void); void FreeRegionMapSubstruct2(void); -// pokenav_conditions_1.c +// pokenav_conditions.c u32 PokenavCallback_Init_ConditionGraph_Party(void); u32 PokenavCallback_Init_ConditionGraph_Search(void); u32 GetConditionGraphMenuCallback(void); @@ -455,14 +455,14 @@ u16 GetConditionMonDataBuffer(void); void *GetConditionMonPicGfx(u8 id); void *GetConditionMonPal(u8 id); -// pokenav_conditions_2.c +// pokenav_conditions_gfx.c bool32 OpenConditionGraphMenu(void); void CreateConditionGraphMenuLoopedTask(s32); u32 IsConditionGraphMenuLoopedTaskActive(void); void FreeConditionGraphMenuSubstruct2(void); u8 GetMonMarkingsData(void); -// pokenav_conditions_3.c +// pokenav_conditions_search_results.c u32 PokenavCallback_Init_ConditionSearch(void); u32 PokenavCallback_Init_ReturnToMonSearchList(void); u32 GetConditionSearchResultsCallback(void); diff --git a/ld_script.txt b/ld_script.txt index ca0480e0f..c4283265d 100644 --- a/ld_script.txt +++ b/ld_script.txt @@ -316,9 +316,9 @@ SECTIONS { src/pokenav_match_call_1.o(.text); src/pokenav_match_call_2.o(.text); src/pokenav_region_map.o(.text); - src/pokenav_conditions_1.o(.text); - src/pokenav_conditions_2.o(.text); - src/pokenav_conditions_3.o(.text); + src/pokenav_conditions.o(.text); + src/pokenav_conditions_gfx.o(.text); + src/pokenav_conditions_search_results.o(.text); src/pokenav_ribbons_list.o(.text); src/pokenav_ribbons_summary.o(.text); src/pokenav_match_call_data.o(.text); @@ -671,8 +671,8 @@ SECTIONS { src/pokenav_match_call_1.o(.rodata); src/pokenav_match_call_2.o(.rodata); src/pokenav_region_map.o(.rodata); - src/pokenav_conditions_2.o(.rodata); - src/pokenav_conditions_3.o(.rodata); + src/pokenav_conditions_gfx.o(.rodata); + src/pokenav_conditions_search_results.o(.rodata); src/pokenav_ribbons_list.o(.rodata); src/pokenav_ribbons_summary.o(.rodata); src/pokenav_match_call_data.o(.rodata); diff --git a/src/pokenav_conditions.c b/src/pokenav_conditions.c new file mode 100644 index 000000000..fc188db71 --- /dev/null +++ b/src/pokenav_conditions.c @@ -0,0 +1,628 @@ +#include "global.h" +#include "data.h" +#include "decompress.h" +#include "main.h" +#include "menu_specialized.h" +#include "mon_markings.h" +#include "pokenav.h" +#include "pokemon.h" +#include "pokemon_storage_system.h" +#include "sound.h" +#include "string_util.h" +#include "strings.h" +#include "text.h" +#include "constants/songs.h" + +struct Pokenav_ConditionMenu +{ + u32 monPal[NUM_CONDITION_MONS][0x20]; + u8 fill[0x180]; + u32 monPicGfx[NUM_CONDITION_MONS][MON_PIC_SIZE]; + bool8 inSearchMode; + s16 toLoadListIndex; + u32 (*callback)(struct Pokenav_ConditionMenu *); + u8 fill2[0x18]; + u8 locationText[NUM_CONDITION_MONS][24]; + u8 nameText[NUM_CONDITION_MONS][64]; + struct ConditionGraph graph; + u8 numSparkles[NUM_CONDITION_MONS]; + u8 monMarks[NUM_CONDITION_MONS]; + s8 loadId; + s8 nextLoadIdDown; + s8 nextLoadIdUp; + s8 toLoadId; + u8 state; +}; + +static void InitPartyConditionListParameters(void); +static void InitSearchResultsConditionList(void); +static u32 HandleConditionMenuInput(struct Pokenav_ConditionMenu *); +static u32 GetConditionReturnCallback(struct Pokenav_ConditionMenu *); +static u32 OpenMarkingsMenu(struct Pokenav_ConditionMenu *); +static u8 ConditionGraphHandleDpadInput(struct Pokenav_ConditionMenu *); +static u8 SwitchConditionSummaryIndex(bool8); +static void CopyMonNameGenderLocation(s16, u8); +static void GetMonConditionGraphData(s16, u8); +static void ConditionGraphDrawMonPic(s16, u8); + +bool32 PokenavCallback_Init_ConditionGraph_Party(void) +{ + struct Pokenav_ConditionMenu *menu = AllocSubstruct(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU, sizeof(struct Pokenav_ConditionMenu)); + + if (menu == NULL) + return FALSE; + + ConditionGraph_Init(&menu->graph); + InitPartyConditionListParameters(); + gKeyRepeatStartDelay = 20; + menu->callback = HandleConditionMenuInput; + return TRUE; +} + +bool32 PokenavCallback_Init_ConditionGraph_Search(void) +{ + struct Pokenav_ConditionMenu *menu = AllocSubstruct(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU, sizeof(struct Pokenav_ConditionMenu)); + + if (menu == NULL) + return FALSE; + + ConditionGraph_Init(&menu->graph); + InitSearchResultsConditionList(); + gKeyRepeatStartDelay = 20; + menu->callback = HandleConditionMenuInput; + return TRUE; +} + +u32 GetConditionGraphMenuCallback(void) +{ + struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); + + return menu->callback(menu); +} + +static u32 HandleConditionMenuInput(struct Pokenav_ConditionMenu *menu) +{ + struct PokenavSub18 *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); + u32 ret = ConditionGraphHandleDpadInput(menu); + + if (ret == CONDITION_FUNC_NONE) + { + if (JOY_NEW(B_BUTTON)) + { + PlaySE(SE_SELECT); + menu->callback = GetConditionReturnCallback; + ret = CONDITION_FUNC_RETURN; + } + else if (JOY_NEW(A_BUTTON)) + { + if (!menu->inSearchMode) + { + // In Party mode, pressing A only applies to the Cancel button + if (monListPtr->currIndex == monListPtr->listCount - 1) + { + // Cancel + PlaySE(SE_SELECT); + menu->callback = GetConditionReturnCallback; + ret = CONDITION_FUNC_RETURN; + } + } + else + { + // In Search mode pressing A brings up the markings menu + PlaySE(SE_SELECT); + ret = CONDITION_FUNC_ADD_MARKINGS; + menu->callback = OpenMarkingsMenu; + } + } + } + + return ret; +} + +static u32 OpenMarkingsMenu(struct Pokenav_ConditionMenu *menu) +{ + struct PokenavSub18 *monListPtr; + u8 markings; + u32 ret = CONDITION_FUNC_NONE, boxId, monId; + + if (!HandleMonMarkingsMenuInput()) + { + menu->monMarks[menu->loadId] = GetMonMarkingsData(); + monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); + boxId = monListPtr->monData[monListPtr->currIndex].boxId; + monId = monListPtr->monData[monListPtr->currIndex].monId; + markings = menu->monMarks[menu->loadId]; + + if (boxId == TOTAL_BOXES_COUNT) + SetMonData(&gPlayerParty[monId], MON_DATA_MARKINGS, &markings); + else + SetBoxMonDataAt(boxId, monId, MON_DATA_MARKINGS, &markings); + + menu->callback = HandleConditionMenuInput; + ret = CONDITION_FUNC_CLOSE_MARKINGS; + } + + return ret; +} + +static u32 GetConditionReturnCallback(struct Pokenav_ConditionMenu *menu) +{ + if (!menu->inSearchMode) + return POKENAV_CONDITION_MENU; + else + return POKENAV_RETURN_CONDITION_SEARCH; +} + +void FreeConditionGraphMenuSubstruct1(void) +{ + struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); + if (!menu->inSearchMode) + FreePokenavSubstruct(POKENAV_SUBSTRUCT_MON_LIST); + + FreePokenavSubstruct(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); +} + +static u8 ConditionGraphHandleDpadInput(struct Pokenav_ConditionMenu *menu) +{ + struct PokenavSub18 *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); + u8 ret = CONDITION_FUNC_NONE; + + if (JOY_HELD(DPAD_UP)) + { + // Prevent input wrapping in search mode + if (!menu->inSearchMode || monListPtr->currIndex != 0) + { + PlaySE(SE_SELECT); + ret = SwitchConditionSummaryIndex(TRUE); + } + } + else if (JOY_HELD(DPAD_DOWN)) + { + // Prevent input wrapping in search mode + if (!menu->inSearchMode || monListPtr->currIndex < monListPtr->listCount - 1) + { + PlaySE(SE_SELECT); + ret = SwitchConditionSummaryIndex(FALSE); + } + } + + return ret; +} + +static u8 SwitchConditionSummaryIndex(u8 moveUp) +{ + u16 newLoadId; + bool8 wasNotLastMon, isNotLastMon; + struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); + struct PokenavSub18 *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); + + newLoadId = (moveUp) ? menu->nextLoadIdUp : menu->nextLoadIdDown; + ConditionGraph_SetNewPositions(&menu->graph, menu->graph.savedPositions[menu->loadId], menu->graph.savedPositions[newLoadId]); + wasNotLastMon = (monListPtr->currIndex != (IsConditionMenuSearchMode() ? monListPtr->listCount : monListPtr->listCount - 1)); + if (moveUp) + { + menu->nextLoadIdUp = menu->nextLoadIdDown; + menu->nextLoadIdDown = menu->loadId; + menu->loadId = newLoadId; + menu->toLoadId = menu->nextLoadIdUp; + + monListPtr->currIndex = (monListPtr->currIndex == 0) ? monListPtr->listCount - 1 : monListPtr->currIndex - 1; + menu->toLoadListIndex = (monListPtr->currIndex != 0) ? monListPtr->currIndex - 1 : monListPtr->listCount - 1; + } + else + { + menu->nextLoadIdDown = menu->nextLoadIdUp; + menu->nextLoadIdUp = menu->loadId; + menu->loadId = newLoadId; + menu->toLoadId = menu->nextLoadIdDown; + + monListPtr->currIndex = (monListPtr->currIndex < monListPtr->listCount - 1) ? monListPtr->currIndex + 1 : 0; + menu->toLoadListIndex = (monListPtr->currIndex < monListPtr->listCount - 1) ? monListPtr->currIndex + 1 : 0; + } + + isNotLastMon = (monListPtr->currIndex != (IsConditionMenuSearchMode() ? monListPtr->listCount : monListPtr->listCount - 1)); + + if (!wasNotLastMon) + return CONDITION_FUNC_NO_TRANSITION; + else if (!isNotLastMon) + return CONDITION_FUNC_SLIDE_MON_OUT; + else + return CONDITION_FUNC_SLIDE_MON_IN; +} + +bool32 LoadConditionGraphMenuGfx(void) +{ + s32 var; + struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); + struct PokenavSub18 *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); + + switch (menu->state) + { + case 0: + CopyMonNameGenderLocation(monListPtr->currIndex, CONDITION_MON_0); + break; + case 1: + GetMonConditionGraphData(monListPtr->currIndex, CONDITION_MON_0); + break; + case 2: + ConditionGraphDrawMonPic(monListPtr->currIndex, CONDITION_MON_0); + break; + case 3: + if (monListPtr->listCount == 1) + { + menu->loadId = CONDITION_MON_0; + menu->nextLoadIdDown = CONDITION_MON_0; + menu->nextLoadIdUp = CONDITION_MON_0; + menu->state = 0; + return TRUE; + } + else + { + menu->loadId = CONDITION_MON_0; + menu->nextLoadIdDown = CONDITION_MON_1; + menu->nextLoadIdUp = CONDITION_MON_2; + } + break; + // These were probably ternaries just like cases 7-9, but couldn't match it any other way. + case 4: + var = monListPtr->currIndex + 1; + if (var >= monListPtr->listCount) + var = 0; + CopyMonNameGenderLocation(var, CONDITION_MON_1); + break; + case 5: + var = monListPtr->currIndex + 1; + if (var >= monListPtr->listCount) + var = 0; + GetMonConditionGraphData(var, CONDITION_MON_1); + break; + case 6: + var = monListPtr->currIndex + 1; + if (var >= monListPtr->listCount) + var = 0; + ConditionGraphDrawMonPic(var, CONDITION_MON_1); + break; + case 7: + CopyMonNameGenderLocation((monListPtr->currIndex - 1 >= 0) ? monListPtr->currIndex - 1 : monListPtr->listCount - 1, CONDITION_MON_2); + break; + case 8: + GetMonConditionGraphData((monListPtr->currIndex - 1 >= 0) ? monListPtr->currIndex - 1 : monListPtr->listCount - 1, CONDITION_MON_2); + break; + case 9: + ConditionGraphDrawMonPic((monListPtr->currIndex - 1 >= 0) ? monListPtr->currIndex - 1 : monListPtr->listCount - 1, CONDITION_MON_2); + menu->state = 0; + return TRUE; + } + + menu->state++; + return FALSE; +} + +bool32 LoadNextConditionMenuMonData(u8 mode) +{ + struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); + + switch (mode) + { + case CONDITION_LOAD_MON_INFO: + CopyMonNameGenderLocation(menu->toLoadListIndex, menu->toLoadId); + break; + case CONDITION_LOAD_GRAPH: + GetMonConditionGraphData(menu->toLoadListIndex, menu->toLoadId); + break; + case CONDITION_LOAD_MON_PIC: + ConditionGraphDrawMonPic(menu->toLoadListIndex, menu->toLoadId); + return TRUE; + } + + return FALSE; +} + +u8 *CopyStringLeftAlignedToConditionData(u8 *dst, const u8 *src, s16 n) +{ + while (*src != EOS) + *dst++ = *src++, n--; + + while (n-- > 0) + *dst++ = CHAR_SPACE; + + *dst = EOS; + return dst; +} + +static u8 *CopyConditionMonNameGender(u8 *str, u16 listId, bool8 arg3) +{ + u16 boxId, monId, gender, species, level, lvlDigits; + struct BoxPokemon *boxMon; + u8 *txtPtr, *str_; + struct PokenavSub18 *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); + + boxId = monListPtr->monData[listId].boxId; + monId = monListPtr->monData[listId].monId; + *(str++) = EXT_CTRL_CODE_BEGIN; + *(str++) = EXT_CTRL_CODE_COLOR_HIGHLIGHT_SHADOW; + *(str++) = TEXT_COLOR_BLUE; + *(str++) = TEXT_COLOR_TRANSPARENT; + *(str++) = TEXT_COLOR_LIGHT_BLUE; + + if (GetBoxOrPartyMonData(boxId, monId, MON_DATA_IS_EGG, NULL)) + return StringCopyPadded(str, gText_EggNickname, CHAR_SPACE, 12); + + GetBoxOrPartyMonData(boxId, monId, MON_DATA_NICKNAME, str); + StringGetEnd10(str); + species = GetBoxOrPartyMonData(boxId, monId, MON_DATA_SPECIES, NULL); + if (boxId == TOTAL_BOXES_COUNT) + { + level = GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL); + gender = GetMonGender(&gPlayerParty[monId]); + } + else + { + boxMon = GetBoxedMonPtr(boxId, monId); + gender = GetBoxMonGender(boxMon); + level = GetLevelFromBoxMonExp(boxMon); + } + + if ((species == SPECIES_NIDORAN_F || species == SPECIES_NIDORAN_M) && !StringCompare(str, gSpeciesNames[species])) + gender = MON_GENDERLESS; + + str_ = str; // For some reason, a variable is needed to match. + while (*str_ != EOS) + (str_++); + + *(str_++) = EXT_CTRL_CODE_BEGIN; + *(str_++) = EXT_CTRL_CODE_SKIP; + *(str_++) = 60; + switch (gender) + { + default: + *(str_++) = CHAR_SPACER; // Genderless + break; + case MON_MALE: + *(str_++) = EXT_CTRL_CODE_BEGIN; + *(str_++) = EXT_CTRL_CODE_COLOR; + *(str_++) = TEXT_COLOR_RED; + *(str_++) = EXT_CTRL_CODE_BEGIN; + *(str_++) = EXT_CTRL_CODE_SHADOW; + *(str_++) = TEXT_COLOR_LIGHT_RED; + *(str_++) = CHAR_MALE; + break; + case MON_FEMALE: + *(str_++) = EXT_CTRL_CODE_BEGIN; + *(str_++) = EXT_CTRL_CODE_COLOR; + *(str_++) = TEXT_COLOR_GREEN; + *(str_++) = EXT_CTRL_CODE_BEGIN; + *(str_++) = EXT_CTRL_CODE_SHADOW; + *(str_++) = TEXT_COLOR_LIGHT_GREEN; + *(str_++) = CHAR_FEMALE; + break; + } + + *(str_++) = EXT_CTRL_CODE_BEGIN; + *(str_++) = EXT_CTRL_CODE_COLOR_HIGHLIGHT_SHADOW; + *(str_++) = TEXT_COLOR_BLUE; + *(str_++) = TEXT_COLOR_TRANSPARENT; + *(str_++) = TEXT_COLOR_LIGHT_BLUE; + *(str_++) = CHAR_SLASH; + *(str_++) = CHAR_EXTRA_SYMBOL; + *(str_++) = CHAR_LV_2; + txtPtr = str_; + str_ = ConvertIntToDecimalStringN(str_, level, STR_CONV_MODE_LEFT_ALIGN, 3); + lvlDigits = str_ - txtPtr; + *(str_++) = CHAR_SPACE; + if (!arg3) + { + lvlDigits = 3 - lvlDigits; + while (lvlDigits-- != 0) + *(str_++) = CHAR_SPACE; + } + + *str_ = EOS; + return str_; +} + +static void CopyMonNameGenderLocation(s16 listId, u8 loadId) +{ + u16 boxId, i; + struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); + struct PokenavSub18 *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); + + if (listId != (IsConditionMenuSearchMode() ? monListPtr->listCount : monListPtr->listCount - 1)) + { + CopyConditionMonNameGender(menu->nameText[loadId], listId, FALSE); + boxId = monListPtr->monData[listId].boxId; + menu->locationText[loadId][0] = EXT_CTRL_CODE_BEGIN; + menu->locationText[loadId][1] = EXT_CTRL_CODE_COLOR_HIGHLIGHT_SHADOW; + menu->locationText[loadId][2] = TEXT_COLOR_BLUE; + menu->locationText[loadId][3] = TEXT_COLOR_TRANSPARENT; + menu->locationText[loadId][4] = TEXT_COLOR_LIGHT_BLUE; + if (boxId == TOTAL_BOXES_COUNT) + CopyStringLeftAlignedToConditionData(&menu->locationText[loadId][5], gText_InParty, BOX_NAME_LENGTH); + else + CopyStringLeftAlignedToConditionData(&menu->locationText[loadId][5], GetBoxNamePtr(boxId), BOX_NAME_LENGTH); + } + else + { + for (i = 0; i < 12; i++) + menu->nameText[loadId][i] = CHAR_SPACE; + menu->nameText[loadId][i] = EOS; + + for (i = 0; i < BOX_NAME_LENGTH; i++) + menu->locationText[loadId][i] = CHAR_SPACE; + menu->locationText[loadId][i] = EOS; + } +} + +static void InitPartyConditionListParameters(void) +{ + u16 i, count; + struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); + struct PokenavSub18 *monListPtr = AllocSubstruct(POKENAV_SUBSTRUCT_MON_LIST, sizeof(struct PokenavSub18)); + + menu->inSearchMode = FALSE; + for (i = 0, count = 0; i < CalculatePlayerPartyCount(); i++) + { + if (!GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG)) + { + monListPtr->monData[count].boxId = TOTAL_BOXES_COUNT; + monListPtr->monData[count].monId = i; + monListPtr->monData[count].data = 0; + count++; + } + } + + monListPtr->monData[count].boxId = 0; + monListPtr->monData[count].monId = 0; + monListPtr->monData[count].data = 0; + monListPtr->currIndex = 0; + monListPtr->listCount = count + 1; + menu->state = 0; +} + +static void InitSearchResultsConditionList(void) +{ + struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); + menu->inSearchMode = TRUE; + menu->state = 0; +} + +static void GetMonConditionGraphData(s16 listId, u8 loadId) +{ + u16 boxId, monId, i; + struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); + struct PokenavSub18 *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); + + if (listId != (IsConditionMenuSearchMode() ? monListPtr->listCount : monListPtr->listCount - 1)) + { + boxId = monListPtr->monData[listId].boxId; + monId = monListPtr->monData[listId].monId; + menu->graph.conditions[loadId][CONDITION_COOL] = GetBoxOrPartyMonData(boxId, monId, MON_DATA_COOL, NULL); + menu->graph.conditions[loadId][CONDITION_TOUGH] = GetBoxOrPartyMonData(boxId, monId, MON_DATA_TOUGH, NULL); + menu->graph.conditions[loadId][CONDITION_SMART] = GetBoxOrPartyMonData(boxId, monId, MON_DATA_SMART, NULL); + menu->graph.conditions[loadId][CONDITION_CUTE] = GetBoxOrPartyMonData(boxId, monId, MON_DATA_CUTE, NULL); + menu->graph.conditions[loadId][CONDITION_BEAUTY] = GetBoxOrPartyMonData(boxId, monId, MON_DATA_BEAUTY, NULL); + menu->numSparkles[loadId] = GET_NUM_CONDITION_SPARKLES(GetBoxOrPartyMonData(boxId, monId, MON_DATA_SHEEN, NULL)); + menu->monMarks[loadId] = GetBoxOrPartyMonData(boxId, monId, MON_DATA_MARKINGS, NULL); + ConditionGraph_CalcPositions(menu->graph.conditions[loadId], menu->graph.savedPositions[loadId]); + } + else + { + // Set empty graph point + for (i = 0; i < CONDITION_COUNT; i++) + { + menu->graph.conditions[loadId][i] = 0; + menu->graph.savedPositions[loadId][i].x = CONDITION_GRAPH_CENTER_X; + menu->graph.savedPositions[loadId][i].y = CONDITION_GRAPH_CENTER_Y; + } + } +} + +static void ConditionGraphDrawMonPic(s16 listId, u8 loadId) +{ + u16 boxId, monId, species; + u32 personality, tid; + struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); + struct PokenavSub18 *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); + + if (listId == (IsConditionMenuSearchMode() ? monListPtr->listCount : monListPtr->listCount - 1)) + return; + + boxId = monListPtr->monData[listId].boxId; + monId = monListPtr->monData[listId].monId; + species = GetBoxOrPartyMonData(boxId, monId, MON_DATA_SPECIES2, NULL); + tid = GetBoxOrPartyMonData(boxId, monId, MON_DATA_OT_ID, NULL); + personality = GetBoxOrPartyMonData(boxId, monId, MON_DATA_PERSONALITY, NULL); + LoadSpecialPokePic(&gMonFrontPicTable[species], menu->monPicGfx[loadId], species, personality, TRUE); + LZ77UnCompWram(GetMonSpritePalFromSpeciesAndPersonality(species, tid, personality), menu->monPal[loadId]); +} + +u16 GetMonListCount(void) +{ + struct PokenavSub18 *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); + return monListPtr->listCount; +} + +u16 GetConditionGraphCurrentListIndex(void) +{ + struct PokenavSub18 *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); + return monListPtr->currIndex; +} + +struct ConditionGraph *GetConditionGraphPtr(void) +{ + struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); + return &menu->graph; +} + +u8 GetConditionGraphMenuCurrentLoadIndex(void) +{ + struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); + return menu->loadId; +} + +u8 GetConditionGraphMenuToLoadListIndex(void) +{ + struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); + return menu->toLoadListIndex; +} + +void *GetConditionMonPicGfx(u8 loadId) +{ + struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); + return menu->monPicGfx[loadId]; +} + +void *GetConditionMonPal(u8 loadId) +{ + struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); + return menu->monPal[loadId]; +} + +u8 GetConditionGraphMenuToLoadId(void) +{ + struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); + return menu->toLoadId; +} + +u8 *GetConditionMonNameText(u8 loadId) +{ + struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); + return menu->nameText[loadId]; +} + +u8 *GetConditionMonLocationText(u8 loadId) +{ + struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); + return menu->locationText[loadId]; +} + +u16 GetConditionMonDataBuffer(void) +{ + struct PokenavSub18 *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); + return monListPtr->monData[monListPtr->currIndex].data; +} + +bool32 IsConditionMenuSearchMode(void) +{ + struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); + if (menu->inSearchMode == TRUE) + return TRUE; + else + return FALSE; +} + +// Markings are only shown in search mode +u8 TryGetMonMarkId(void) +{ + struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); + if (menu->inSearchMode == TRUE) + return menu->monMarks[menu->loadId]; + else + return 0; +} + +u8 GetNumConditionMonSparkles(void) +{ + struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); + return menu->numSparkles[menu->loadId]; +} diff --git a/src/pokenav_conditions_1.c b/src/pokenav_conditions_1.c deleted file mode 100644 index fc188db71..000000000 --- a/src/pokenav_conditions_1.c +++ /dev/null @@ -1,628 +0,0 @@ -#include "global.h" -#include "data.h" -#include "decompress.h" -#include "main.h" -#include "menu_specialized.h" -#include "mon_markings.h" -#include "pokenav.h" -#include "pokemon.h" -#include "pokemon_storage_system.h" -#include "sound.h" -#include "string_util.h" -#include "strings.h" -#include "text.h" -#include "constants/songs.h" - -struct Pokenav_ConditionMenu -{ - u32 monPal[NUM_CONDITION_MONS][0x20]; - u8 fill[0x180]; - u32 monPicGfx[NUM_CONDITION_MONS][MON_PIC_SIZE]; - bool8 inSearchMode; - s16 toLoadListIndex; - u32 (*callback)(struct Pokenav_ConditionMenu *); - u8 fill2[0x18]; - u8 locationText[NUM_CONDITION_MONS][24]; - u8 nameText[NUM_CONDITION_MONS][64]; - struct ConditionGraph graph; - u8 numSparkles[NUM_CONDITION_MONS]; - u8 monMarks[NUM_CONDITION_MONS]; - s8 loadId; - s8 nextLoadIdDown; - s8 nextLoadIdUp; - s8 toLoadId; - u8 state; -}; - -static void InitPartyConditionListParameters(void); -static void InitSearchResultsConditionList(void); -static u32 HandleConditionMenuInput(struct Pokenav_ConditionMenu *); -static u32 GetConditionReturnCallback(struct Pokenav_ConditionMenu *); -static u32 OpenMarkingsMenu(struct Pokenav_ConditionMenu *); -static u8 ConditionGraphHandleDpadInput(struct Pokenav_ConditionMenu *); -static u8 SwitchConditionSummaryIndex(bool8); -static void CopyMonNameGenderLocation(s16, u8); -static void GetMonConditionGraphData(s16, u8); -static void ConditionGraphDrawMonPic(s16, u8); - -bool32 PokenavCallback_Init_ConditionGraph_Party(void) -{ - struct Pokenav_ConditionMenu *menu = AllocSubstruct(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU, sizeof(struct Pokenav_ConditionMenu)); - - if (menu == NULL) - return FALSE; - - ConditionGraph_Init(&menu->graph); - InitPartyConditionListParameters(); - gKeyRepeatStartDelay = 20; - menu->callback = HandleConditionMenuInput; - return TRUE; -} - -bool32 PokenavCallback_Init_ConditionGraph_Search(void) -{ - struct Pokenav_ConditionMenu *menu = AllocSubstruct(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU, sizeof(struct Pokenav_ConditionMenu)); - - if (menu == NULL) - return FALSE; - - ConditionGraph_Init(&menu->graph); - InitSearchResultsConditionList(); - gKeyRepeatStartDelay = 20; - menu->callback = HandleConditionMenuInput; - return TRUE; -} - -u32 GetConditionGraphMenuCallback(void) -{ - struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); - - return menu->callback(menu); -} - -static u32 HandleConditionMenuInput(struct Pokenav_ConditionMenu *menu) -{ - struct PokenavSub18 *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); - u32 ret = ConditionGraphHandleDpadInput(menu); - - if (ret == CONDITION_FUNC_NONE) - { - if (JOY_NEW(B_BUTTON)) - { - PlaySE(SE_SELECT); - menu->callback = GetConditionReturnCallback; - ret = CONDITION_FUNC_RETURN; - } - else if (JOY_NEW(A_BUTTON)) - { - if (!menu->inSearchMode) - { - // In Party mode, pressing A only applies to the Cancel button - if (monListPtr->currIndex == monListPtr->listCount - 1) - { - // Cancel - PlaySE(SE_SELECT); - menu->callback = GetConditionReturnCallback; - ret = CONDITION_FUNC_RETURN; - } - } - else - { - // In Search mode pressing A brings up the markings menu - PlaySE(SE_SELECT); - ret = CONDITION_FUNC_ADD_MARKINGS; - menu->callback = OpenMarkingsMenu; - } - } - } - - return ret; -} - -static u32 OpenMarkingsMenu(struct Pokenav_ConditionMenu *menu) -{ - struct PokenavSub18 *monListPtr; - u8 markings; - u32 ret = CONDITION_FUNC_NONE, boxId, monId; - - if (!HandleMonMarkingsMenuInput()) - { - menu->monMarks[menu->loadId] = GetMonMarkingsData(); - monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); - boxId = monListPtr->monData[monListPtr->currIndex].boxId; - monId = monListPtr->monData[monListPtr->currIndex].monId; - markings = menu->monMarks[menu->loadId]; - - if (boxId == TOTAL_BOXES_COUNT) - SetMonData(&gPlayerParty[monId], MON_DATA_MARKINGS, &markings); - else - SetBoxMonDataAt(boxId, monId, MON_DATA_MARKINGS, &markings); - - menu->callback = HandleConditionMenuInput; - ret = CONDITION_FUNC_CLOSE_MARKINGS; - } - - return ret; -} - -static u32 GetConditionReturnCallback(struct Pokenav_ConditionMenu *menu) -{ - if (!menu->inSearchMode) - return POKENAV_CONDITION_MENU; - else - return POKENAV_RETURN_CONDITION_SEARCH; -} - -void FreeConditionGraphMenuSubstruct1(void) -{ - struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); - if (!menu->inSearchMode) - FreePokenavSubstruct(POKENAV_SUBSTRUCT_MON_LIST); - - FreePokenavSubstruct(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); -} - -static u8 ConditionGraphHandleDpadInput(struct Pokenav_ConditionMenu *menu) -{ - struct PokenavSub18 *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); - u8 ret = CONDITION_FUNC_NONE; - - if (JOY_HELD(DPAD_UP)) - { - // Prevent input wrapping in search mode - if (!menu->inSearchMode || monListPtr->currIndex != 0) - { - PlaySE(SE_SELECT); - ret = SwitchConditionSummaryIndex(TRUE); - } - } - else if (JOY_HELD(DPAD_DOWN)) - { - // Prevent input wrapping in search mode - if (!menu->inSearchMode || monListPtr->currIndex < monListPtr->listCount - 1) - { - PlaySE(SE_SELECT); - ret = SwitchConditionSummaryIndex(FALSE); - } - } - - return ret; -} - -static u8 SwitchConditionSummaryIndex(u8 moveUp) -{ - u16 newLoadId; - bool8 wasNotLastMon, isNotLastMon; - struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); - struct PokenavSub18 *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); - - newLoadId = (moveUp) ? menu->nextLoadIdUp : menu->nextLoadIdDown; - ConditionGraph_SetNewPositions(&menu->graph, menu->graph.savedPositions[menu->loadId], menu->graph.savedPositions[newLoadId]); - wasNotLastMon = (monListPtr->currIndex != (IsConditionMenuSearchMode() ? monListPtr->listCount : monListPtr->listCount - 1)); - if (moveUp) - { - menu->nextLoadIdUp = menu->nextLoadIdDown; - menu->nextLoadIdDown = menu->loadId; - menu->loadId = newLoadId; - menu->toLoadId = menu->nextLoadIdUp; - - monListPtr->currIndex = (monListPtr->currIndex == 0) ? monListPtr->listCount - 1 : monListPtr->currIndex - 1; - menu->toLoadListIndex = (monListPtr->currIndex != 0) ? monListPtr->currIndex - 1 : monListPtr->listCount - 1; - } - else - { - menu->nextLoadIdDown = menu->nextLoadIdUp; - menu->nextLoadIdUp = menu->loadId; - menu->loadId = newLoadId; - menu->toLoadId = menu->nextLoadIdDown; - - monListPtr->currIndex = (monListPtr->currIndex < monListPtr->listCount - 1) ? monListPtr->currIndex + 1 : 0; - menu->toLoadListIndex = (monListPtr->currIndex < monListPtr->listCount - 1) ? monListPtr->currIndex + 1 : 0; - } - - isNotLastMon = (monListPtr->currIndex != (IsConditionMenuSearchMode() ? monListPtr->listCount : monListPtr->listCount - 1)); - - if (!wasNotLastMon) - return CONDITION_FUNC_NO_TRANSITION; - else if (!isNotLastMon) - return CONDITION_FUNC_SLIDE_MON_OUT; - else - return CONDITION_FUNC_SLIDE_MON_IN; -} - -bool32 LoadConditionGraphMenuGfx(void) -{ - s32 var; - struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); - struct PokenavSub18 *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); - - switch (menu->state) - { - case 0: - CopyMonNameGenderLocation(monListPtr->currIndex, CONDITION_MON_0); - break; - case 1: - GetMonConditionGraphData(monListPtr->currIndex, CONDITION_MON_0); - break; - case 2: - ConditionGraphDrawMonPic(monListPtr->currIndex, CONDITION_MON_0); - break; - case 3: - if (monListPtr->listCount == 1) - { - menu->loadId = CONDITION_MON_0; - menu->nextLoadIdDown = CONDITION_MON_0; - menu->nextLoadIdUp = CONDITION_MON_0; - menu->state = 0; - return TRUE; - } - else - { - menu->loadId = CONDITION_MON_0; - menu->nextLoadIdDown = CONDITION_MON_1; - menu->nextLoadIdUp = CONDITION_MON_2; - } - break; - // These were probably ternaries just like cases 7-9, but couldn't match it any other way. - case 4: - var = monListPtr->currIndex + 1; - if (var >= monListPtr->listCount) - var = 0; - CopyMonNameGenderLocation(var, CONDITION_MON_1); - break; - case 5: - var = monListPtr->currIndex + 1; - if (var >= monListPtr->listCount) - var = 0; - GetMonConditionGraphData(var, CONDITION_MON_1); - break; - case 6: - var = monListPtr->currIndex + 1; - if (var >= monListPtr->listCount) - var = 0; - ConditionGraphDrawMonPic(var, CONDITION_MON_1); - break; - case 7: - CopyMonNameGenderLocation((monListPtr->currIndex - 1 >= 0) ? monListPtr->currIndex - 1 : monListPtr->listCount - 1, CONDITION_MON_2); - break; - case 8: - GetMonConditionGraphData((monListPtr->currIndex - 1 >= 0) ? monListPtr->currIndex - 1 : monListPtr->listCount - 1, CONDITION_MON_2); - break; - case 9: - ConditionGraphDrawMonPic((monListPtr->currIndex - 1 >= 0) ? monListPtr->currIndex - 1 : monListPtr->listCount - 1, CONDITION_MON_2); - menu->state = 0; - return TRUE; - } - - menu->state++; - return FALSE; -} - -bool32 LoadNextConditionMenuMonData(u8 mode) -{ - struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); - - switch (mode) - { - case CONDITION_LOAD_MON_INFO: - CopyMonNameGenderLocation(menu->toLoadListIndex, menu->toLoadId); - break; - case CONDITION_LOAD_GRAPH: - GetMonConditionGraphData(menu->toLoadListIndex, menu->toLoadId); - break; - case CONDITION_LOAD_MON_PIC: - ConditionGraphDrawMonPic(menu->toLoadListIndex, menu->toLoadId); - return TRUE; - } - - return FALSE; -} - -u8 *CopyStringLeftAlignedToConditionData(u8 *dst, const u8 *src, s16 n) -{ - while (*src != EOS) - *dst++ = *src++, n--; - - while (n-- > 0) - *dst++ = CHAR_SPACE; - - *dst = EOS; - return dst; -} - -static u8 *CopyConditionMonNameGender(u8 *str, u16 listId, bool8 arg3) -{ - u16 boxId, monId, gender, species, level, lvlDigits; - struct BoxPokemon *boxMon; - u8 *txtPtr, *str_; - struct PokenavSub18 *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); - - boxId = monListPtr->monData[listId].boxId; - monId = monListPtr->monData[listId].monId; - *(str++) = EXT_CTRL_CODE_BEGIN; - *(str++) = EXT_CTRL_CODE_COLOR_HIGHLIGHT_SHADOW; - *(str++) = TEXT_COLOR_BLUE; - *(str++) = TEXT_COLOR_TRANSPARENT; - *(str++) = TEXT_COLOR_LIGHT_BLUE; - - if (GetBoxOrPartyMonData(boxId, monId, MON_DATA_IS_EGG, NULL)) - return StringCopyPadded(str, gText_EggNickname, CHAR_SPACE, 12); - - GetBoxOrPartyMonData(boxId, monId, MON_DATA_NICKNAME, str); - StringGetEnd10(str); - species = GetBoxOrPartyMonData(boxId, monId, MON_DATA_SPECIES, NULL); - if (boxId == TOTAL_BOXES_COUNT) - { - level = GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL); - gender = GetMonGender(&gPlayerParty[monId]); - } - else - { - boxMon = GetBoxedMonPtr(boxId, monId); - gender = GetBoxMonGender(boxMon); - level = GetLevelFromBoxMonExp(boxMon); - } - - if ((species == SPECIES_NIDORAN_F || species == SPECIES_NIDORAN_M) && !StringCompare(str, gSpeciesNames[species])) - gender = MON_GENDERLESS; - - str_ = str; // For some reason, a variable is needed to match. - while (*str_ != EOS) - (str_++); - - *(str_++) = EXT_CTRL_CODE_BEGIN; - *(str_++) = EXT_CTRL_CODE_SKIP; - *(str_++) = 60; - switch (gender) - { - default: - *(str_++) = CHAR_SPACER; // Genderless - break; - case MON_MALE: - *(str_++) = EXT_CTRL_CODE_BEGIN; - *(str_++) = EXT_CTRL_CODE_COLOR; - *(str_++) = TEXT_COLOR_RED; - *(str_++) = EXT_CTRL_CODE_BEGIN; - *(str_++) = EXT_CTRL_CODE_SHADOW; - *(str_++) = TEXT_COLOR_LIGHT_RED; - *(str_++) = CHAR_MALE; - break; - case MON_FEMALE: - *(str_++) = EXT_CTRL_CODE_BEGIN; - *(str_++) = EXT_CTRL_CODE_COLOR; - *(str_++) = TEXT_COLOR_GREEN; - *(str_++) = EXT_CTRL_CODE_BEGIN; - *(str_++) = EXT_CTRL_CODE_SHADOW; - *(str_++) = TEXT_COLOR_LIGHT_GREEN; - *(str_++) = CHAR_FEMALE; - break; - } - - *(str_++) = EXT_CTRL_CODE_BEGIN; - *(str_++) = EXT_CTRL_CODE_COLOR_HIGHLIGHT_SHADOW; - *(str_++) = TEXT_COLOR_BLUE; - *(str_++) = TEXT_COLOR_TRANSPARENT; - *(str_++) = TEXT_COLOR_LIGHT_BLUE; - *(str_++) = CHAR_SLASH; - *(str_++) = CHAR_EXTRA_SYMBOL; - *(str_++) = CHAR_LV_2; - txtPtr = str_; - str_ = ConvertIntToDecimalStringN(str_, level, STR_CONV_MODE_LEFT_ALIGN, 3); - lvlDigits = str_ - txtPtr; - *(str_++) = CHAR_SPACE; - if (!arg3) - { - lvlDigits = 3 - lvlDigits; - while (lvlDigits-- != 0) - *(str_++) = CHAR_SPACE; - } - - *str_ = EOS; - return str_; -} - -static void CopyMonNameGenderLocation(s16 listId, u8 loadId) -{ - u16 boxId, i; - struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); - struct PokenavSub18 *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); - - if (listId != (IsConditionMenuSearchMode() ? monListPtr->listCount : monListPtr->listCount - 1)) - { - CopyConditionMonNameGender(menu->nameText[loadId], listId, FALSE); - boxId = monListPtr->monData[listId].boxId; - menu->locationText[loadId][0] = EXT_CTRL_CODE_BEGIN; - menu->locationText[loadId][1] = EXT_CTRL_CODE_COLOR_HIGHLIGHT_SHADOW; - menu->locationText[loadId][2] = TEXT_COLOR_BLUE; - menu->locationText[loadId][3] = TEXT_COLOR_TRANSPARENT; - menu->locationText[loadId][4] = TEXT_COLOR_LIGHT_BLUE; - if (boxId == TOTAL_BOXES_COUNT) - CopyStringLeftAlignedToConditionData(&menu->locationText[loadId][5], gText_InParty, BOX_NAME_LENGTH); - else - CopyStringLeftAlignedToConditionData(&menu->locationText[loadId][5], GetBoxNamePtr(boxId), BOX_NAME_LENGTH); - } - else - { - for (i = 0; i < 12; i++) - menu->nameText[loadId][i] = CHAR_SPACE; - menu->nameText[loadId][i] = EOS; - - for (i = 0; i < BOX_NAME_LENGTH; i++) - menu->locationText[loadId][i] = CHAR_SPACE; - menu->locationText[loadId][i] = EOS; - } -} - -static void InitPartyConditionListParameters(void) -{ - u16 i, count; - struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); - struct PokenavSub18 *monListPtr = AllocSubstruct(POKENAV_SUBSTRUCT_MON_LIST, sizeof(struct PokenavSub18)); - - menu->inSearchMode = FALSE; - for (i = 0, count = 0; i < CalculatePlayerPartyCount(); i++) - { - if (!GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG)) - { - monListPtr->monData[count].boxId = TOTAL_BOXES_COUNT; - monListPtr->monData[count].monId = i; - monListPtr->monData[count].data = 0; - count++; - } - } - - monListPtr->monData[count].boxId = 0; - monListPtr->monData[count].monId = 0; - monListPtr->monData[count].data = 0; - monListPtr->currIndex = 0; - monListPtr->listCount = count + 1; - menu->state = 0; -} - -static void InitSearchResultsConditionList(void) -{ - struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); - menu->inSearchMode = TRUE; - menu->state = 0; -} - -static void GetMonConditionGraphData(s16 listId, u8 loadId) -{ - u16 boxId, monId, i; - struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); - struct PokenavSub18 *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); - - if (listId != (IsConditionMenuSearchMode() ? monListPtr->listCount : monListPtr->listCount - 1)) - { - boxId = monListPtr->monData[listId].boxId; - monId = monListPtr->monData[listId].monId; - menu->graph.conditions[loadId][CONDITION_COOL] = GetBoxOrPartyMonData(boxId, monId, MON_DATA_COOL, NULL); - menu->graph.conditions[loadId][CONDITION_TOUGH] = GetBoxOrPartyMonData(boxId, monId, MON_DATA_TOUGH, NULL); - menu->graph.conditions[loadId][CONDITION_SMART] = GetBoxOrPartyMonData(boxId, monId, MON_DATA_SMART, NULL); - menu->graph.conditions[loadId][CONDITION_CUTE] = GetBoxOrPartyMonData(boxId, monId, MON_DATA_CUTE, NULL); - menu->graph.conditions[loadId][CONDITION_BEAUTY] = GetBoxOrPartyMonData(boxId, monId, MON_DATA_BEAUTY, NULL); - menu->numSparkles[loadId] = GET_NUM_CONDITION_SPARKLES(GetBoxOrPartyMonData(boxId, monId, MON_DATA_SHEEN, NULL)); - menu->monMarks[loadId] = GetBoxOrPartyMonData(boxId, monId, MON_DATA_MARKINGS, NULL); - ConditionGraph_CalcPositions(menu->graph.conditions[loadId], menu->graph.savedPositions[loadId]); - } - else - { - // Set empty graph point - for (i = 0; i < CONDITION_COUNT; i++) - { - menu->graph.conditions[loadId][i] = 0; - menu->graph.savedPositions[loadId][i].x = CONDITION_GRAPH_CENTER_X; - menu->graph.savedPositions[loadId][i].y = CONDITION_GRAPH_CENTER_Y; - } - } -} - -static void ConditionGraphDrawMonPic(s16 listId, u8 loadId) -{ - u16 boxId, monId, species; - u32 personality, tid; - struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); - struct PokenavSub18 *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); - - if (listId == (IsConditionMenuSearchMode() ? monListPtr->listCount : monListPtr->listCount - 1)) - return; - - boxId = monListPtr->monData[listId].boxId; - monId = monListPtr->monData[listId].monId; - species = GetBoxOrPartyMonData(boxId, monId, MON_DATA_SPECIES2, NULL); - tid = GetBoxOrPartyMonData(boxId, monId, MON_DATA_OT_ID, NULL); - personality = GetBoxOrPartyMonData(boxId, monId, MON_DATA_PERSONALITY, NULL); - LoadSpecialPokePic(&gMonFrontPicTable[species], menu->monPicGfx[loadId], species, personality, TRUE); - LZ77UnCompWram(GetMonSpritePalFromSpeciesAndPersonality(species, tid, personality), menu->monPal[loadId]); -} - -u16 GetMonListCount(void) -{ - struct PokenavSub18 *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); - return monListPtr->listCount; -} - -u16 GetConditionGraphCurrentListIndex(void) -{ - struct PokenavSub18 *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); - return monListPtr->currIndex; -} - -struct ConditionGraph *GetConditionGraphPtr(void) -{ - struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); - return &menu->graph; -} - -u8 GetConditionGraphMenuCurrentLoadIndex(void) -{ - struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); - return menu->loadId; -} - -u8 GetConditionGraphMenuToLoadListIndex(void) -{ - struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); - return menu->toLoadListIndex; -} - -void *GetConditionMonPicGfx(u8 loadId) -{ - struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); - return menu->monPicGfx[loadId]; -} - -void *GetConditionMonPal(u8 loadId) -{ - struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); - return menu->monPal[loadId]; -} - -u8 GetConditionGraphMenuToLoadId(void) -{ - struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); - return menu->toLoadId; -} - -u8 *GetConditionMonNameText(u8 loadId) -{ - struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); - return menu->nameText[loadId]; -} - -u8 *GetConditionMonLocationText(u8 loadId) -{ - struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); - return menu->locationText[loadId]; -} - -u16 GetConditionMonDataBuffer(void) -{ - struct PokenavSub18 *monListPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); - return monListPtr->monData[monListPtr->currIndex].data; -} - -bool32 IsConditionMenuSearchMode(void) -{ - struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); - if (menu->inSearchMode == TRUE) - return TRUE; - else - return FALSE; -} - -// Markings are only shown in search mode -u8 TryGetMonMarkId(void) -{ - struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); - if (menu->inSearchMode == TRUE) - return menu->monMarks[menu->loadId]; - else - return 0; -} - -u8 GetNumConditionMonSparkles(void) -{ - struct Pokenav_ConditionMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU); - return menu->numSparkles[menu->loadId]; -} diff --git a/src/pokenav_conditions_2.c b/src/pokenav_conditions_2.c deleted file mode 100644 index cecba800c..000000000 --- a/src/pokenav_conditions_2.c +++ /dev/null @@ -1,892 +0,0 @@ -#include "global.h" -#include "bg.h" -#include "window.h" -#include "pokenav.h" -#include "decompress.h" -#include "gpu_regs.h" -#include "graphics.h" -#include "menu.h" -#include "menu_specialized.h" -#include "mon_markings.h" -#include "palette.h" -#include "pokenav.h" -#include "scanline_effect.h" -#include "string_util.h" -#include "strings.h" -#include "text.h" - -static u32 LoopedTask_TransitionMons(s32); -static u32 LoopedTask_ExitConditionGraphMenu(s32); -static u32 LoopedTask_MoveCursorNoTransition(s32); -static u32 LoopedTask_SlideMonOut(s32); -static u32 LoopedTask_OpenMonMarkingsWindow(s32); -static u32 LoopedTask_CloseMonMarkingsWindow(s32); - -static u8 sInitialLoadId; // Never read - -const u16 gConditionGraphData_Pal[] = INCBIN_U16("graphics/pokenav/condition/graph_data.gbapal"); -const u16 gConditionText_Pal[] = INCBIN_U16("graphics/pokenav/condition/text.gbapal"); -static const u32 sConditionGraphData_Gfx[] = INCBIN_U32("graphics/pokenav/condition/graph_data.4bpp.lz"); -static const u32 sConditionGraphData_Tilemap[] = INCBIN_U32("graphics/pokenav/condition/graph_data.bin.lz"); -static const u16 sMonMarkings_Pal[] = INCBIN_U16("graphics/pokenav/condition/mon_markings.gbapal"); - -static const struct BgTemplate sMenuBgTemplates[3] = -{ - { - .bg = 1, - .charBaseIndex = 1, - .mapBaseIndex = 0x1F, - .screenSize = 0, - .paletteMode = 0, - .priority = 1, - .baseTile = 0 - }, - { - .bg = 2, - .charBaseIndex = 3, - .mapBaseIndex = 0x1D, - .screenSize = 0, - .paletteMode = 0, - .priority = 2, - .baseTile = 0 - }, - { - .bg = 3, - .charBaseIndex = 2, - .mapBaseIndex = 0x1E, - .screenSize = 0, - .paletteMode = 0, - .priority = 3, - .baseTile = 0 - } -}; - -static const struct WindowTemplate sMonNameGenderWindowTemplate = -{ - .bg = 1, - .tilemapLeft = 13, - .tilemapTop = 1, - .width = 13, - .height = 4, - .paletteNum = 15, - .baseBlock = 2 -}; - -static const struct WindowTemplate sListIndexWindowTemplate = -{ - .bg = 1, - .tilemapLeft = 1, - .tilemapTop = 6, - .width = 7, - .height = 2, - .paletteNum = 15, - .baseBlock = 0x36 -}; - -static const struct WindowTemplate sUnusedWindowTemplate1 = -{ - .bg = 1, - .tilemapLeft = 1, - .tilemapTop = 0x1C, - .width = 5, - .height = 2, - .paletteNum = 15, - .baseBlock = 0x44 -}; - -static const struct WindowTemplate sUnusedWindowTemplate2 = -{ - .bg = 1, - .tilemapLeft = 13, - .tilemapTop = 0x1C, - .width = 3, - .height = 2, - .paletteNum = 15, - .baseBlock = 0x44 -}; - -static const LoopedTask sLoopedTaskFuncs[] = -{ - [CONDITION_FUNC_NONE] = NULL, - [CONDITION_FUNC_SLIDE_MON_IN] = LoopedTask_TransitionMons, - [CONDITION_FUNC_RETURN] = LoopedTask_ExitConditionGraphMenu, - [CONDITION_FUNC_NO_TRANSITION] = LoopedTask_MoveCursorNoTransition, - [CONDITION_FUNC_SLIDE_MON_OUT] = LoopedTask_SlideMonOut, - [CONDITION_FUNC_ADD_MARKINGS] = LoopedTask_OpenMonMarkingsWindow, - [CONDITION_FUNC_CLOSE_MARKINGS] = LoopedTask_CloseMonMarkingsWindow -}; - -struct Pokenav_ConditionMenuGfx -{ - u32 loopedTaskId; - u8 tilemapBuffers[3][BG_SCREEN_SIZE]; - u8 filler[2]; - u8 partyPokeballSpriteIds[PARTY_SIZE + 1]; - u32 (*callback)(void); - s16 monTransitionX; - u8 monPicSpriteId; - u16 monPalIndex; - u16 monGfxTileStart; - void *monGfxPtr; - u8 nameGenderWindowId; - u8 listIndexWindowId; - u8 unusedWindowId1; - u8 unusedWindowId2; - struct MonMarkingsMenu marksMenu; - struct Sprite *monMarksSprite; - struct Sprite *conditionSparkleSprites[MAX_CONDITION_SPARKLES]; - u8 windowModeState; - u8 filler2[0xFA3]; -}; - -extern s8 GetConditionGraphMenuCurrentLoadIndex(void); // This function's declaration here is s8 vs. u8 in pokenav_conditions_1.c - -static u32 LoopedTask_OpenConditionGraphMenu(s32); -static u32 GetConditionGraphMenuLoopedTaskActive(void); -static void CreateConditionMonPic(u8); -static void CreateMonMarkingsOrPokeballIndicators(void); -static void CopyUnusedConditionWindowsToVram(void); -static bool32 UpdateConditionGraphMenuWindows(u8, u16, bool8); -static void VBlankCB_PokenavConditionGraph(void); -static void DoConditionGraphEnterTransition(void); -static void DoConditionGraphExitTransition(void); -static void SetExitVBlank(void); -static void ToggleGraphData(bool8); - -bool32 OpenConditionGraphMenu(void) -{ - struct Pokenav_ConditionMenuGfx *menu = AllocSubstruct(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX, sizeof(struct Pokenav_ConditionMenuGfx)); - - if (menu == NULL) - return FALSE; - - menu->monPicSpriteId = SPRITE_NONE; - menu->loopedTaskId = CreateLoopedTask(LoopedTask_OpenConditionGraphMenu, 1); - menu->callback = GetConditionGraphMenuLoopedTaskActive; - menu->windowModeState = 0; - return TRUE; -} - -void CreateConditionGraphMenuLoopedTask(s32 id) -{ - struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); - menu->loopedTaskId = CreateLoopedTask(sLoopedTaskFuncs[id], 1); - menu->callback = GetConditionGraphMenuLoopedTaskActive; -} - -u32 IsConditionGraphMenuLoopedTaskActive(void) -{ - struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); - return menu->callback(); -} - -static u32 GetConditionGraphMenuLoopedTaskActive(void) -{ - struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); - return IsLoopedTaskActive(menu->loopedTaskId); -} - -static u32 LoopedTask_OpenConditionGraphMenu(s32 state) -{ - struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); - - switch (state) - { - case 0: - if (LoadConditionGraphMenuGfx() != TRUE) - return LT_PAUSE; - return LT_INC_AND_PAUSE; - case 1: - InitBgTemplates(sMenuBgTemplates, ARRAY_COUNT(sMenuBgTemplates)); - ChangeBgX(1, 0, BG_COORD_SET); - ChangeBgY(1, 0, BG_COORD_SET); - ChangeBgX(2, 0, BG_COORD_SET); - ChangeBgY(2, 0, BG_COORD_SET); - ChangeBgX(3, 0, BG_COORD_SET); - ChangeBgY(3, 0, BG_COORD_SET); - SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON | DISPCNT_WIN1_ON | DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON | DISPCNT_BG3_ON); - SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG2 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG3); - SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(11, 4)); - DecompressAndCopyTileDataToVram(3, gPokenavCondition_Gfx, 0, 0, 0); - return LT_INC_AND_PAUSE; - case 2: - if (FreeTempTileDataBuffersIfPossible()) - return LT_PAUSE; - DecompressAndCopyTileDataToVram(2, sConditionGraphData_Gfx, 0, 0, 0); - return LT_INC_AND_PAUSE; - case 3: - if (FreeTempTileDataBuffersIfPossible()) - return LT_PAUSE; - - LZ77UnCompVram(gPokenavCondition_Tilemap, menu->tilemapBuffers[0]); - SetBgTilemapBuffer(3, menu->tilemapBuffers[0]); - if (IsConditionMenuSearchMode() == TRUE) - CopyToBgTilemapBufferRect(3, gPokenavOptions_Tilemap, 0, 5, 9, 4); - - CopyBgTilemapBufferToVram(3); - CopyPaletteIntoBufferUnfaded(gPokenavCondition_Pal, 0x10, 0x20); - CopyPaletteIntoBufferUnfaded(gConditionText_Pal, 0xF0, 0x20); - menu->monTransitionX = -80; - return LT_INC_AND_PAUSE; - case 4: - if (FreeTempTileDataBuffersIfPossible()) - return LT_PAUSE; - - LZ77UnCompVram(sConditionGraphData_Tilemap, menu->tilemapBuffers[2]); - SetBgTilemapBuffer(2, menu->tilemapBuffers[2]); - CopyBgTilemapBufferToVram(2); - CopyPaletteIntoBufferUnfaded(gConditionGraphData_Pal, 0x30, 0x20); - ConditionGraph_InitWindow(2); - return LT_INC_AND_PAUSE; - case 5: - BgDmaFill(1, 0, 0, 1); - BgDmaFill(1, 17, 1, 1); - CpuFill32(0, menu->tilemapBuffers[1], BG_SCREEN_SIZE); - SetBgTilemapBuffer(1, menu->tilemapBuffers[1]); - return LT_INC_AND_PAUSE; - case 6: - if (FreeTempTileDataBuffersIfPossible()) - return LT_PAUSE; - - menu->nameGenderWindowId = AddWindow(&sMonNameGenderWindowTemplate); - if (IsConditionMenuSearchMode() == TRUE) - { - menu->listIndexWindowId = AddWindow(&sListIndexWindowTemplate); - menu->unusedWindowId1 = AddWindow(&sUnusedWindowTemplate1); - menu->unusedWindowId2 = AddWindow(&sUnusedWindowTemplate2); - } - DeactivateAllTextPrinters(); - return LT_INC_AND_PAUSE; - case 7: - CreateConditionMonPic(0); - return LT_INC_AND_PAUSE; - case 8: - CreateMonMarkingsOrPokeballIndicators(); - return LT_INC_AND_PAUSE; - case 9: - if (IsConditionMenuSearchMode() == TRUE) - CopyUnusedConditionWindowsToVram(); - return LT_INC_AND_PAUSE; - case 10: - UpdateConditionGraphMenuWindows(0, GetConditionGraphMenuCurrentLoadIndex(), TRUE); - return LT_INC_AND_PAUSE; - case 11: - UpdateConditionGraphMenuWindows(1, GetConditionGraphMenuCurrentLoadIndex(), TRUE); - return LT_INC_AND_PAUSE; - case 12: - UpdateConditionGraphMenuWindows(2, GetConditionGraphMenuCurrentLoadIndex(), TRUE); - return LT_INC_AND_PAUSE; - case 13: - if (UpdateConditionGraphMenuWindows(3, GetConditionGraphMenuCurrentLoadIndex(), TRUE) != TRUE) - return LT_PAUSE; - PutWindowTilemap(menu->nameGenderWindowId); - if (IsConditionMenuSearchMode() == TRUE) - { - PutWindowTilemap(menu->listIndexWindowId); - PutWindowTilemap(menu->unusedWindowId1); - PutWindowTilemap(menu->unusedWindowId2); - } - return LT_INC_AND_PAUSE; - case 14: - ShowBg(1); - HideBg(2); - ShowBg(3); - if (IsConditionMenuSearchMode() == TRUE) - PrintHelpBarText(HELPBAR_CONDITION_MON_STATUS); - return LT_INC_AND_PAUSE; - case 15: - PokenavFadeScreen(1); - if (!IsConditionMenuSearchMode()) - { - LoadLeftHeaderGfxForIndex(POKENAV_GFX_PARTY_MENU); - ShowLeftHeaderGfx(POKENAV_GFX_CONDITION_MENU, TRUE, 0); - ShowLeftHeaderGfx(POKENAV_GFX_PARTY_MENU, TRUE, 0); - } - return LT_INC_AND_PAUSE; - case 16: - if (IsPaletteFadeActive()) - return LT_PAUSE; - if (!IsConditionMenuSearchMode() && AreLeftHeaderSpritesMoving()) - return LT_PAUSE; - SetVBlankCallback_(VBlankCB_PokenavConditionGraph); - return LT_INC_AND_PAUSE; - case 17: - DoConditionGraphEnterTransition(); - ConditionGraph_InitResetScanline(GetConditionGraphPtr()); - return LT_INC_AND_PAUSE; - case 18: - if (ConditionGraph_ResetScanline(GetConditionGraphPtr())) - return LT_PAUSE; - return LT_INC_AND_PAUSE; - case 19: - ToggleGraphData(TRUE); - return LT_INC_AND_PAUSE; - case 20: - if (!ConditionMenu_UpdateMonEnter(GetConditionGraphPtr(), &menu->monTransitionX)) - { - ResetConditionSparkleSprites(menu->conditionSparkleSprites); - if (IsConditionMenuSearchMode() == TRUE || GetConditionGraphCurrentListIndex() != GetMonListCount()) - CreateConditionSparkleSprites(menu->conditionSparkleSprites, menu->monPicSpriteId, GetNumConditionMonSparkles()); - - return LT_FINISH; - } - return LT_PAUSE; - } - - return LT_FINISH; -} - -static u32 LoopedTask_ExitConditionGraphMenu(s32 state) -{ - struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); - - switch (state) - { - case 0: - DoConditionGraphExitTransition(); - DestroyConditionSparkleSprites(menu->conditionSparkleSprites); - return LT_INC_AND_CONTINUE; - case 1: - if (ConditionMenu_UpdateMonExit(GetConditionGraphPtr(), &menu->monTransitionX)) - return 2; - ToggleGraphData(FALSE); - return LT_INC_AND_CONTINUE; - case 2: - PokenavFadeScreen(0); - if (!IsConditionMenuSearchMode()) - SlideMenuHeaderDown(); - return LT_INC_AND_PAUSE; - case 3: - if (IsPaletteFadeActive() || MainMenuLoopedTaskIsBusy()) - return LT_PAUSE; - FreeConditionSparkles(menu->conditionSparkleSprites); - HideBg(1); - HideBg(2); - HideBg(3); - return LT_INC_AND_CONTINUE; - } - - return LT_FINISH; -} - -static u32 LoopedTask_TransitionMons(s32 state) -{ - struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); - struct ConditionGraph *graph = GetConditionGraphPtr(); - - switch (state) - { - case 0: - LoadNextConditionMenuMonData(CONDITION_LOAD_MON_INFO); - return LT_INC_AND_CONTINUE; - case 1: - LoadNextConditionMenuMonData(CONDITION_LOAD_GRAPH); - return LT_INC_AND_CONTINUE; - case 2: - LoadNextConditionMenuMonData(CONDITION_LOAD_MON_PIC); - DestroyConditionSparkleSprites(menu->conditionSparkleSprites); - return LT_INC_AND_CONTINUE; - case 3: - ConditionGraph_TryUpdate(graph); - return LT_INC_AND_CONTINUE; - case 4: - if (!MoveConditionMonOffscreen(&menu->monTransitionX)) - { - CreateConditionMonPic(GetConditionGraphMenuCurrentLoadIndex()); - return LT_INC_AND_CONTINUE; - } - return LT_PAUSE; - case 5: - UpdateConditionGraphMenuWindows(0, GetConditionGraphMenuCurrentLoadIndex(), FALSE); - return LT_INC_AND_CONTINUE; - case 6: - UpdateConditionGraphMenuWindows(1, GetConditionGraphMenuCurrentLoadIndex(), FALSE); - return LT_INC_AND_CONTINUE; - case 7: - UpdateConditionGraphMenuWindows(2, GetConditionGraphMenuCurrentLoadIndex(), FALSE); - return LT_INC_AND_CONTINUE; - case 8: - if (UpdateConditionGraphMenuWindows(3, GetConditionGraphMenuCurrentLoadIndex(), FALSE) == TRUE) - return LT_INC_AND_CONTINUE; - return LT_PAUSE; - case 9: - graph = GetConditionGraphPtr(); - if (!ConditionMenu_UpdateMonEnter(graph, &menu->monTransitionX)) - { - ResetConditionSparkleSprites(menu->conditionSparkleSprites); - if (IsConditionMenuSearchMode() != TRUE && GetConditionGraphCurrentListIndex() == GetMonListCount()) - return LT_INC_AND_CONTINUE; - - CreateConditionSparkleSprites(menu->conditionSparkleSprites, menu->monPicSpriteId, GetNumConditionMonSparkles()); - return LT_INC_AND_CONTINUE; - } - return LT_PAUSE; - } - - return LT_FINISH; -} - -static u32 LoopedTask_MoveCursorNoTransition(s32 state) -{ - struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); - - switch (state) - { - case 0: - LoadNextConditionMenuMonData(CONDITION_LOAD_MON_INFO); - return LT_INC_AND_CONTINUE; - case 1: - LoadNextConditionMenuMonData(CONDITION_LOAD_GRAPH); - return LT_INC_AND_CONTINUE; - case 2: - LoadNextConditionMenuMonData(CONDITION_LOAD_MON_PIC); - return LT_INC_AND_CONTINUE; - case 3: - CreateConditionMonPic(GetConditionGraphMenuCurrentLoadIndex()); - return LT_INC_AND_CONTINUE; - case 4: - UpdateConditionGraphMenuWindows(0, GetConditionGraphMenuCurrentLoadIndex(), FALSE); - return LT_INC_AND_CONTINUE; - case 5: - UpdateConditionGraphMenuWindows(1, GetConditionGraphMenuCurrentLoadIndex(), FALSE); - return LT_INC_AND_CONTINUE; - case 6: - UpdateConditionGraphMenuWindows(2, GetConditionGraphMenuCurrentLoadIndex(), FALSE); - return LT_INC_AND_CONTINUE; - case 7: - if (UpdateConditionGraphMenuWindows(3, GetConditionGraphMenuCurrentLoadIndex(), FALSE) == TRUE) - return LT_INC_AND_CONTINUE; - return LT_PAUSE; - case 8: - if (!ConditionMenu_UpdateMonEnter(GetConditionGraphPtr(), &menu->monTransitionX)) - { - ResetConditionSparkleSprites(menu->conditionSparkleSprites); - CreateConditionSparkleSprites(menu->conditionSparkleSprites, menu->monPicSpriteId, GetNumConditionMonSparkles()); - return LT_INC_AND_CONTINUE; - } - return LT_PAUSE; - } - - return LT_FINISH; -} - -static u32 LoopedTask_SlideMonOut(s32 state) -{ - struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); - - switch (state) - { - case 0: - LoadNextConditionMenuMonData(CONDITION_LOAD_MON_INFO); - return LT_INC_AND_CONTINUE; - case 1: - LoadNextConditionMenuMonData(CONDITION_LOAD_GRAPH); - return LT_INC_AND_CONTINUE; - case 2: - LoadNextConditionMenuMonData(CONDITION_LOAD_MON_PIC); - DestroyConditionSparkleSprites(menu->conditionSparkleSprites); - return LT_INC_AND_CONTINUE; - case 3: - if (!ConditionMenu_UpdateMonExit(GetConditionGraphPtr(), &menu->monTransitionX)) - return LT_INC_AND_CONTINUE; - return LT_PAUSE; - case 4: - UpdateConditionGraphMenuWindows(0, GetConditionGraphMenuCurrentLoadIndex(), FALSE); - return LT_INC_AND_CONTINUE; - case 5: - UpdateConditionGraphMenuWindows(1, GetConditionGraphMenuCurrentLoadIndex(), FALSE); - return LT_INC_AND_CONTINUE; - case 6: - UpdateConditionGraphMenuWindows(2, GetConditionGraphMenuCurrentLoadIndex(), FALSE); - return LT_INC_AND_CONTINUE; - case 7: - if (UpdateConditionGraphMenuWindows(3, GetConditionGraphMenuCurrentLoadIndex(), FALSE) == TRUE) - return LT_INC_AND_CONTINUE; - return LT_PAUSE; - } - - return LT_FINISH; -} - -static u32 LoopedTask_OpenMonMarkingsWindow(s32 state) -{ - switch (state) - { - case 0: - OpenMonMarkingsMenu(TryGetMonMarkId(), 176, 32); - return LT_INC_AND_CONTINUE; - case 1: - PrintHelpBarText(HELPBAR_CONDITION_MARKINGS); - return LT_INC_AND_CONTINUE; - case 2: - if (WaitForHelpBar() == TRUE) - return LT_PAUSE; - return LT_INC_AND_CONTINUE; - } - - return LT_FINISH; -} - -static u32 LoopedTask_CloseMonMarkingsWindow(s32 state) -{ - switch (state) - { - case 0: - FreeMonMarkingsMenu(); - return LT_INC_AND_CONTINUE; - case 1: - PrintHelpBarText(HELPBAR_CONDITION_MON_STATUS); - return LT_INC_AND_CONTINUE; - case 2: - if (WaitForHelpBar() == TRUE) - return LT_PAUSE; - return LT_INC_AND_CONTINUE; - } - - return LT_FINISH; -} - -static u8 *UnusedPrintNumberString(u8 *dst, u16 num) -{ - u8 *txtPtr = ConvertIntToDecimalStringN(dst, num, STR_CONV_MODE_RIGHT_ALIGN, 4); - txtPtr = StringCopy(txtPtr, gText_Number2); - - return txtPtr; -} - -static bool32 UpdateConditionGraphMenuWindows(u8 mode, u16 bufferIndex, bool8 winMode) -{ - u8 text[32]; - const u8 *str; - struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); - - switch (mode) - { - case 0: - FillWindowPixelBuffer(menu->nameGenderWindowId, 0); - if (IsConditionMenuSearchMode() == TRUE) - FillWindowPixelBuffer(menu->listIndexWindowId, 0); - break; - case 1: - if (GetConditionGraphCurrentListIndex() != GetMonListCount() - 1 || IsConditionMenuSearchMode() == TRUE) - { - str = GetConditionMonNameText(bufferIndex); - AddTextPrinterParameterized(menu->nameGenderWindowId, FONT_NORMAL, str, 0, 1, 0, NULL); - } - break; - case 2: - if (IsConditionMenuSearchMode() == TRUE) - { - str = GetConditionMonLocationText(bufferIndex); - AddTextPrinterParameterized(menu->nameGenderWindowId, FONT_NORMAL, str, 0, 17, 0, NULL); - text[0] = EXT_CTRL_CODE_BEGIN; - text[1] = EXT_CTRL_CODE_COLOR_HIGHLIGHT_SHADOW; - text[2] = TEXT_COLOR_BLUE; - text[3] = TEXT_COLOR_TRANSPARENT; - text[4] = TEXT_COLOR_LIGHT_BLUE; - StringCopy(&text[5], gText_Number2); - AddTextPrinterParameterized(menu->listIndexWindowId, FONT_NORMAL, text, 4, 1, 0, NULL); - ConvertIntToDecimalStringN(&text[5], GetConditionMonDataBuffer(), STR_CONV_MODE_RIGHT_ALIGN, 4); - AddTextPrinterParameterized(menu->listIndexWindowId, FONT_NORMAL, text, 28, 1, 0, NULL); - } - break; - case 3: - switch (menu->windowModeState) - { - case 0: - if (winMode) - CopyWindowToVram(menu->nameGenderWindowId, COPYWIN_FULL); - else - CopyWindowToVram(menu->nameGenderWindowId, COPYWIN_GFX); - - if (IsConditionMenuSearchMode() == TRUE) - { - menu->windowModeState++; - return FALSE; - } - else - { - menu->windowModeState = 0; - return TRUE; - } - case 1: - if (winMode) - CopyWindowToVram(menu->listIndexWindowId, COPYWIN_FULL); - else - CopyWindowToVram(menu->listIndexWindowId, COPYWIN_GFX); - - menu->windowModeState = 0; - return TRUE; - } - } - - return FALSE; -} - -static void CopyUnusedConditionWindowsToVram(void) -{ - struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); - - CopyWindowToVram(menu->unusedWindowId1, COPYWIN_FULL); - CopyWindowToVram(menu->unusedWindowId2, COPYWIN_FULL); -} - -static void SpriteCB_PartyPokeball(struct Sprite *sprite) -{ - if (sprite->data[0] == GetConditionGraphCurrentListIndex()) - StartSpriteAnim(sprite, CONDITION_ICON_SELECTED); - else - StartSpriteAnim(sprite, CONDITION_ICON_UNSELECTED); -} - -void HighlightCurrentPartyIndexPokeball(struct Sprite *sprite) -{ - if (GetConditionGraphCurrentListIndex() == GetMonListCount() - 1) - sprite->oam.paletteNum = IndexOfSpritePaletteTag(TAG_CONDITION_BALL); - else - sprite->oam.paletteNum = IndexOfSpritePaletteTag(TAG_CONDITION_CANCEL); -} - -void MonMarkingsCallback(struct Sprite *sprite) -{ - StartSpriteAnim(sprite, TryGetMonMarkId()); -} - -static void CreateMonMarkingsOrPokeballIndicators(void) -{ - struct SpriteSheet sprSheets[4]; - struct SpriteTemplate sprTemplate; - struct SpritePalette sprPals[3]; - struct SpriteSheet sprSheet; - struct Sprite *sprite; - u16 i, spriteId; - struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); - - LoadConditionSelectionIcons(sprSheets, &sprTemplate, sprPals); - if (IsConditionMenuSearchMode() == TRUE) - { - // Search Mode, load markings menu - menu->marksMenu.baseTileTag = TAG_CONDITION_MARKINGS_MENU; - menu->marksMenu.basePaletteTag = TAG_CONDITION_MARKINGS_MENU; - InitMonMarkingsMenu(&menu->marksMenu); - BufferMonMarkingsMenuTiles(); - sprite = CreateMonMarkingAllCombosSprite(TAG_CONDITION_MON_MARKINGS, TAG_CONDITION_MON_MARKINGS, sMonMarkings_Pal); - sprite->oam.priority = 3; - sprite->x = 192; - sprite->y = 32; - sprite->callback = MonMarkingsCallback; - menu->monMarksSprite = sprite; - PokenavFillPalette(IndexOfSpritePaletteTag(TAG_CONDITION_MON_MARKINGS), 0); - } - else - { - // Party Mode, load Pokéball selection icons - LoadSpriteSheets(sprSheets); - Pokenav_AllocAndLoadPalettes(sprPals); - - // Add icons for occupied slots - for (i = 0; i < GetMonListCount() - 1; i++) - { - spriteId = CreateSprite(&sprTemplate, 226, (i * 20) + 8, 0); - if (spriteId != MAX_SPRITES) - { - menu->partyPokeballSpriteIds[i] = spriteId; - gSprites[spriteId].data[0] = i; - gSprites[spriteId].callback = SpriteCB_PartyPokeball; - } - else - { - menu->partyPokeballSpriteIds[i] = SPRITE_NONE; - } - } - - // Add icons for empty slots - sprTemplate.tileTag = TAG_CONDITION_BALL_PLACEHOLDER; - sprTemplate.callback = SpriteCallbackDummy; - for (; i < PARTY_SIZE; i++) - { - spriteId = CreateSprite(&sprTemplate, 230, (i * 20) + 8, 0); - if (spriteId != MAX_SPRITES) - { - menu->partyPokeballSpriteIds[i] = spriteId; - gSprites[spriteId].oam.size = 0; - } - else - { - menu->partyPokeballSpriteIds[i] = SPRITE_NONE; - } - } - - // Add cancel icon - sprTemplate.tileTag = TAG_CONDITION_CANCEL; - sprTemplate.callback = HighlightCurrentPartyIndexPokeball; - spriteId = CreateSprite(&sprTemplate, 222, (i * 20) + 8, 0); - if (spriteId != MAX_SPRITES) - { - menu->partyPokeballSpriteIds[i] = spriteId; - gSprites[spriteId].oam.shape = SPRITE_SHAPE(32x16); - gSprites[spriteId].oam.size = SPRITE_SIZE(32x16); - } - else - { - menu->partyPokeballSpriteIds[i] = SPRITE_NONE; - } - } - - LoadConditionSparkle(&sprSheet, &sprPals[0]); - LoadSpriteSheet(&sprSheet); - sprPals[1].data = NULL; - Pokenav_AllocAndLoadPalettes(sprPals); -} - -static void FreeConditionMenuGfx(struct Pokenav_ConditionMenuGfx *menu) -{ - u8 i; - - if (IsConditionMenuSearchMode() == TRUE) - { - DestroySprite(menu->monMarksSprite); - FreeSpriteTilesByTag(TAG_CONDITION_MARKINGS_MENU); - FreeSpriteTilesByTag(TAG_CONDITION_MON_MARKINGS); - FreeSpritePaletteByTag(TAG_CONDITION_MARKINGS_MENU); - FreeSpritePaletteByTag(TAG_CONDITION_MON_MARKINGS); - } - else - { - for (i = 0; i < PARTY_SIZE + 1; i++) - DestroySprite(&gSprites[menu->partyPokeballSpriteIds[i]]); - - FreeSpriteTilesByTag(TAG_CONDITION_BALL); - FreeSpriteTilesByTag(TAG_CONDITION_CANCEL); - FreeSpriteTilesByTag(TAG_CONDITION_BALL_PLACEHOLDER); - FreeSpritePaletteByTag(TAG_CONDITION_BALL); - FreeSpritePaletteByTag(TAG_CONDITION_CANCEL); - } - - if (menu->monPicSpriteId != SPRITE_NONE) - { - DestroySprite(&gSprites[menu->monPicSpriteId]); - FreeSpriteTilesByTag(TAG_CONDITION_MON); - FreeSpritePaletteByTag(TAG_CONDITION_MON); - } -} - -void FreeConditionGraphMenuSubstruct2(void) -{ - struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); - - RemoveWindow(menu->nameGenderWindowId); - if (IsConditionMenuSearchMode() == TRUE) - { - RemoveWindow(menu->listIndexWindowId); - RemoveWindow(menu->unusedWindowId1); - RemoveWindow(menu->unusedWindowId2); - } - else - { - SetLeftHeaderSpritesInvisibility(); - } - - SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_BG0_ON | DISPCNT_OBJ_1D_MAP); - FreeConditionMenuGfx(menu); - SetExitVBlank(); - FreePokenavSubstruct(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); -} - -void MonPicGfxSpriteCallback(struct Sprite *sprite) -{ - struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); - sprite->x = menu->monTransitionX + 38; -} - -static void CreateConditionMonPic(u8 id) -{ - struct SpriteTemplate sprTemplate; - struct SpriteSheet sprSheet; - struct SpritePalette sprPal; - u8 spriteId; - struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); - - if (menu->monPicSpriteId == SPRITE_NONE) - { - LoadConditionMonPicTemplate(&sprSheet, &sprTemplate, &sprPal); - sprSheet.data = GetConditionMonPicGfx(id); - sprPal.data = GetConditionMonPal(id); - menu->monPalIndex = LoadSpritePalette(&sprPal); - menu->monGfxTileStart = LoadSpriteSheet(&sprSheet); - spriteId = CreateSprite(&sprTemplate, 38, 104, 0); - menu->monPicSpriteId = spriteId; - if (spriteId == MAX_SPRITES) - { - FreeSpriteTilesByTag(TAG_CONDITION_MON); - FreeSpritePaletteByTag(TAG_CONDITION_MON); - menu->monPicSpriteId = SPRITE_NONE; - } - else - { - menu->monPicSpriteId = spriteId; - gSprites[menu->monPicSpriteId].callback = MonPicGfxSpriteCallback; - menu->monGfxPtr = (void*)VRAM + BG_VRAM_SIZE + (menu->monGfxTileStart * 32); - menu->monPalIndex = (menu->monPalIndex * 16) + 0x100; - } - } - else - { - DmaCopy16Defvars(3, GetConditionMonPicGfx(id), menu->monGfxPtr, MON_PIC_SIZE); - LoadPalette(GetConditionMonPal(id), menu->monPalIndex, 0x20); - } -} - -static void VBlankCB_PokenavConditionGraph(void) -{ - struct ConditionGraph *graph = GetConditionGraphPtr(); - LoadOam(); - ProcessSpriteCopyRequests(); - TransferPlttBuffer(); - ConditionGraph_Draw(graph); - ScanlineEffect_InitHBlankDmaTransfer(); -} - -static void SetExitVBlank(void) -{ - SetPokenavVBlankCallback(); -} - -static void ToggleGraphData(bool8 showBg) -{ - if (showBg) - ShowBg(2); - else - HideBg(2); -} - -static void DoConditionGraphEnterTransition(void) -{ - struct ConditionGraph *graph = GetConditionGraphPtr(); - u8 id = GetConditionGraphMenuCurrentLoadIndex(); - - sInitialLoadId = id; - ConditionGraph_SetNewPositions(graph, graph->savedPositions[CONDITION_GRAPH_LOAD_MAX - 1], graph->savedPositions[id]); - ConditionGraph_TryUpdate(graph); -} - -// Transition the graph back to empty before exiting. -// This is skipped if the player is in party mode and the cursor -// is on Cancel, in which case the graph is already empty. -static void DoConditionGraphExitTransition(void) -{ - struct ConditionGraph *graph = GetConditionGraphPtr(); - - if (IsConditionMenuSearchMode() || GetConditionGraphCurrentListIndex() != GetMonListCount() - 1) - ConditionGraph_SetNewPositions(graph, graph->savedPositions[GetConditionGraphMenuCurrentLoadIndex()], graph->savedPositions[CONDITION_GRAPH_LOAD_MAX - 1]); -} - -u8 GetMonMarkingsData(void) -{ - struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); - - if (IsConditionMenuSearchMode() == 1) - return menu->marksMenu.markings; - else - return 0; -} diff --git a/src/pokenav_conditions_3.c b/src/pokenav_conditions_3.c deleted file mode 100644 index d9bd2273f..000000000 --- a/src/pokenav_conditions_3.c +++ /dev/null @@ -1,734 +0,0 @@ -#include "global.h" -#include "pokenav.h" -#include "bg.h" -#include "menu.h" -#include "window.h" -#include "sound.h" -#include "dynamic_placeholder_text_util.h" -#include "strings.h" -#include "string_util.h" -#include "international_string_util.h" -#include "constants/songs.h" - -enum -{ - CONDITION_SEARCH_FUNC_NONE, - CONDITION_SEARCH_FUNC_MOVE_UP, - CONDITION_SEARCH_FUNC_MOVE_DOWN, - CONDITION_SEARCH_FUNC_PAGE_UP, - CONDITION_SEARCH_FUNC_PAGE_DOWN, - CONDITION_SEARCH_FUNC_EXIT, - CONDITION_SEARCH_FUNC_SELECT_MON, -}; - -struct Pokenav_SearchResults -{ - u32 (*callback)(struct Pokenav_SearchResults *); - u32 loopedTaskId; - u8 fill1[4]; - s32 boxId; - s32 monId; - u32 conditionDataId; - bool32 returnFromGraph; - bool32 saveResultsList; - struct PokenavSub18 *monList; -}; - -struct Pokenav_SearchResultsGfx -{ - bool32 (*callback)(void); - u32 loopedTaskId; - u16 winid; - bool32 fromGraph; - u8 buff[BG_SCREEN_SIZE]; -}; // size: 0x810 - -static u32 HandleConditionSearchInput_WaitSetup(struct Pokenav_SearchResults *); -static u32 HandleConditionSearchInput(struct Pokenav_SearchResults *); -static u32 OpenConditionGraphFromSearchList(struct Pokenav_SearchResults *); -static u32 ReturnToConditionSearchList(struct Pokenav_SearchResults *); -static u32 GetConditionSearchLoopedTask(s32); -static u32 BuildPartyMonSearchResults(s32); -static u32 InitBoxMonSearchResults(s32); -static u32 BuildBoxMonSearchResults(s32); -static u32 ConvertConditionsToListRanks(s32); -static u32 LoopedTask_MoveSearchListCursorUp(s32); -static u32 LoopedTask_MoveSearchListCursorDown(s32); -static u32 LoopedTask_MoveSearchListPageUp(s32); -static u32 LoopedTask_MoveSearchListPageDown(s32); -static u32 LoopedTask_ExitConditionSearchMenu(s32); -static u32 LoopedTask_SelectSearchResult(s32); -static void InsertMonListItem(struct Pokenav_SearchResults *, struct PokenavMonList *); -static bool32 GetSearchResultCurrentLoopedTaskActive(void); -static u32 LoopedTask_OpenConditionSearchResults(s32); -static void AddSearchResultListMenuWindow(struct Pokenav_SearchResultsGfx *); -static void PrintSearchResultListMenuItems(struct Pokenav_SearchResultsGfx *); -static void InitConditionSearchListMenuTemplate(void); -static void PrintSearchMonListItem(struct PokenavMonList *, u8 *); - -static const u32 sSearchMonDataIds[] = {MON_DATA_COOL, MON_DATA_BEAUTY, MON_DATA_CUTE, MON_DATA_SMART, MON_DATA_TOUGH}; - -static const LoopedTask sConditionSearchLoopedTaskFuncs[] = -{ - BuildPartyMonSearchResults, - InitBoxMonSearchResults, - BuildBoxMonSearchResults, - ConvertConditionsToListRanks -}; - -static const u16 sConditionSearchResultFramePal[] = INCBIN_U16("graphics/pokenav/condition/search_results.gbapal"); -static const u32 sConditionSearchResultTiles[] = INCBIN_U32("graphics/pokenav/condition/search_results.4bpp.lz"); -static const u32 sConditionSearchResultTilemap[] = INCBIN_U32("graphics/pokenav/condition/search_results.bin.lz"); -static const u16 sListBg_Pal[] = INCBIN_U16("graphics/pokenav/condition/search_results_list.gbapal"); - -static const struct BgTemplate sConditionSearchResultBgTemplates[] = -{ - { - .bg = 1, - .charBaseIndex = 1, - .mapBaseIndex = 0x06, - .screenSize = 0, - .paletteMode = 0, - .priority = 2, - .baseTile = 0 - }, { - .bg = 2, - .charBaseIndex = 2, - .mapBaseIndex = 0x07, - .screenSize = 0, - .paletteMode = 0, - .priority = 3, - .baseTile = 0 - } -}; - -static const LoopedTask sSearchResultLoopTaskFuncs[] = -{ - [CONDITION_SEARCH_FUNC_NONE] = NULL, - [CONDITION_SEARCH_FUNC_MOVE_UP] = LoopedTask_MoveSearchListCursorUp, - [CONDITION_SEARCH_FUNC_MOVE_DOWN] = LoopedTask_MoveSearchListCursorDown, - [CONDITION_SEARCH_FUNC_PAGE_UP] = LoopedTask_MoveSearchListPageUp, - [CONDITION_SEARCH_FUNC_PAGE_DOWN] = LoopedTask_MoveSearchListPageDown, - [CONDITION_SEARCH_FUNC_EXIT] = LoopedTask_ExitConditionSearchMenu, - [CONDITION_SEARCH_FUNC_SELECT_MON] = LoopedTask_SelectSearchResult -}; - -static const struct WindowTemplate sSearchResultListMenuWindowTemplate = -{ - .bg = 1, - .tilemapLeft = 1, - .tilemapTop = 6, - .width = 7, - .height = 2, - .paletteNum = 1, - .baseBlock = 20 -}; - -static const u8 sText_MaleSymbol[] = _("{COLOR_HIGHLIGHT_SHADOW}{LIGHT_RED}{WHITE}{GREEN}♂{COLOR_HIGHLIGHT_SHADOW}{DARK_GRAY}{WHITE}{LIGHT_GRAY}"); -static const u8 sText_FemaleSymbol[] = _("{COLOR_HIGHLIGHT_SHADOW}{LIGHT_GREEN}{WHITE}{BLUE}♀{COLOR_HIGHLIGHT_SHADOW}{DARK_GRAY}{WHITE}{LIGHT_GRAY}"); -static const u8 sText_NoGenderSymbol[] = _("{UNK_SPACER}"); - -bool32 PokenavCallback_Init_ConditionSearch(void) -{ - struct Pokenav_SearchResults *menu = AllocSubstruct(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS, sizeof(struct Pokenav_SearchResults)); - if (menu == NULL) - return FALSE; - - menu->monList = AllocSubstruct(POKENAV_SUBSTRUCT_MON_LIST, sizeof(struct PokenavSub18)); - if (menu->monList == NULL) - return FALSE; - - menu->callback = HandleConditionSearchInput_WaitSetup; - menu->loopedTaskId = CreateLoopedTask(GetConditionSearchLoopedTask, 1); - menu->returnFromGraph = FALSE; - menu->conditionDataId = sSearchMonDataIds[GetSelectedConditionSearch()]; - return TRUE; -} - -// return to search results from condition graph -bool32 PokenavCallback_Init_ReturnToMonSearchList(void) -{ - struct Pokenav_SearchResults *menu = AllocSubstruct(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS, sizeof(struct Pokenav_SearchResults)); - if (menu == NULL) - return FALSE; - - menu->monList = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); - menu->callback = HandleConditionSearchInput; - menu->returnFromGraph = TRUE; - menu->conditionDataId = sSearchMonDataIds[GetSelectedConditionSearch()]; - return TRUE; -} - -u32 GetConditionSearchResultsCallback(void) -{ - struct Pokenav_SearchResults *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); - return menu->callback(menu); -} - -void FreeSearchResultSubstruct1(void) -{ - struct Pokenav_SearchResults *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); - if (!menu->saveResultsList) - FreePokenavSubstruct(POKENAV_SUBSTRUCT_MON_LIST); - FreePokenavSubstruct(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); -} - -static bool32 HandleConditionSearchInput_WaitSetup(struct Pokenav_SearchResults *menu) -{ - if (!IsLoopedTaskActive(menu->loopedTaskId)) - menu->callback = HandleConditionSearchInput; - return FALSE; -} - -static u32 HandleConditionSearchInput(struct Pokenav_SearchResults *menu) -{ - if (JOY_REPEAT(DPAD_UP)) - return CONDITION_SEARCH_FUNC_MOVE_UP; - else if (JOY_REPEAT(DPAD_DOWN)) - return CONDITION_SEARCH_FUNC_MOVE_DOWN; - else if (JOY_NEW(DPAD_LEFT)) - return CONDITION_SEARCH_FUNC_PAGE_UP; - else if (JOY_NEW(DPAD_RIGHT)) - return CONDITION_SEARCH_FUNC_PAGE_DOWN; - else if (JOY_NEW(B_BUTTON)) - { - // Exiting back to main search menu - menu->saveResultsList = FALSE; - menu->callback = ReturnToConditionSearchList; - return CONDITION_SEARCH_FUNC_EXIT; - } - else if (JOY_NEW(A_BUTTON)) - { - // Entering graph menu - menu->monList->currIndex = GetSelectedPokenavListIndex(); - menu->saveResultsList = TRUE; - menu->callback = OpenConditionGraphFromSearchList; - return CONDITION_SEARCH_FUNC_SELECT_MON; - } - else - return CONDITION_SEARCH_FUNC_NONE; -} - -static u32 ReturnToConditionSearchList(struct Pokenav_SearchResults *menu) -{ - return POKENAV_CONDITION_SEARCH_MENU; -} - -static u32 OpenConditionGraphFromSearchList(struct Pokenav_SearchResults *menu) -{ - return POKENAV_CONDITION_GRAPH_SEARCH; -} - -static u32 GetReturningFromGraph(void) -{ - struct Pokenav_SearchResults *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); - return menu->returnFromGraph; -} - -static struct PokenavMonList * GetSearchResultsMonDataList(void) -{ - struct Pokenav_SearchResults * menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); - return menu->monList->monData; -} - -static u16 GetSearchResultsMonListCount(void) -{ - struct Pokenav_SearchResults * menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); - return menu->monList->listCount; -} - -// data below has been set by ConvertConditionsToListRanks -static s32 GetSearchResultsSelectedMonRank(void) -{ - struct Pokenav_SearchResults * menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); - s32 i = GetSelectedPokenavListIndex(); - return menu->monList->monData[i].data; -} - -static u16 GetSearchResultsCurrentListIndex(void) -{ - struct Pokenav_SearchResults * menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); - return menu->monList->currIndex; -} - -static u32 GetConditionSearchLoopedTask(s32 state) -{ - return sConditionSearchLoopedTaskFuncs[state](state); -} - -static u32 BuildPartyMonSearchResults(s32 state) -{ - s32 i; - struct PokenavMonList item; - struct Pokenav_SearchResults * menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); - - menu->monList->listCount = 0; - menu->monList->currIndex = 0; - item.boxId = TOTAL_BOXES_COUNT; - for (i = 0; i < PARTY_SIZE; i++) - { - struct Pokemon * pokemon = &gPlayerParty[i]; - if (!GetMonData(pokemon, MON_DATA_SANITY_HAS_SPECIES)) - return LT_INC_AND_CONTINUE; - if (!GetMonData(pokemon, MON_DATA_SANITY_IS_EGG)) - { - item.monId = i; - item.data = GetMonData(pokemon, menu->conditionDataId); - InsertMonListItem(menu, &item); - } - } - - return LT_INC_AND_CONTINUE; -} - -static u32 InitBoxMonSearchResults(s32 state) -{ - struct Pokenav_SearchResults * menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); - menu->monId = 0; - menu->boxId = 0; - return LT_INC_AND_CONTINUE; -} - -static u32 BuildBoxMonSearchResults(s32 state) -{ - struct Pokenav_SearchResults * menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); - s32 boxId = menu->boxId; - s32 monId = menu->monId; - s32 boxCount = 0; - struct PokenavMonList item; - - while (boxId < TOTAL_BOXES_COUNT) - { - while (monId < IN_BOX_COUNT) - { - if (CheckBoxMonSanityAt(boxId, monId)) - { - item.boxId = boxId; - item.monId = monId; - item.data = GetBoxMonDataAt(boxId, monId, menu->conditionDataId); - InsertMonListItem(menu, &item); - } - boxCount++; - monId++; - if (boxCount > TOTAL_BOXES_COUNT) - { - menu->boxId = boxId; - menu->monId = monId; - return LT_CONTINUE; - } - } - monId = 0; - boxId++; - } - - return LT_INC_AND_CONTINUE; -} - -// Data below is initially set by BuildPartyMonSearchResults / BuildBoxMonSearchResults, and -// is the Pokémon's condition value for the condition they are sorted by. -// The condition value in data is then overwritten with their ranking. -static u32 ConvertConditionsToListRanks(s32 state) -{ - struct Pokenav_SearchResults * menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); - s32 listCount = menu->monList->listCount; - s32 prevCondition = menu->monList->monData[0].data; - s32 i; - menu->monList->monData[0].data = 1; - for (i = 1; i < listCount; i++) - { - if (menu->monList->monData[i].data == prevCondition) - { - // Same condition value as prev, share rank - menu->monList->monData[i].data = menu->monList->monData[i - 1].data; - } - else - { - prevCondition = menu->monList->monData[i].data; - menu->monList->monData[i].data = i + 1; - } - } - menu->returnFromGraph = TRUE; - return LT_FINISH; -} - -static void InsertMonListItem(struct Pokenav_SearchResults *menu, struct PokenavMonList *item) -{ - u32 left = 0; - u32 right = menu->monList->listCount; - u32 insertionIdx = left + (right - left) / 2; - - while (right != insertionIdx) - { - if (item->data > menu->monList->monData[insertionIdx].data) - right = insertionIdx; - else - left = insertionIdx + 1; - insertionIdx = left + (right - left) / 2; - } - for (right = menu->monList->listCount; right > insertionIdx; right--) - menu->monList->monData[right] = menu->monList->monData[right - 1]; - menu->monList->monData[insertionIdx] = *item; - menu->monList->listCount++; -} - -bool32 OpenConditionSearchResults(void) -{ - struct Pokenav_SearchResultsGfx *gfx = AllocSubstruct(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX, sizeof(struct Pokenav_SearchResultsGfx)); - if (gfx == NULL) - return FALSE; - gfx->loopedTaskId = CreateLoopedTask(LoopedTask_OpenConditionSearchResults, 1); - gfx->callback = GetSearchResultCurrentLoopedTaskActive; - gfx->fromGraph = FALSE; - return TRUE; -} - -bool32 OpenConditionSearchListFromGraph(void) -{ - struct Pokenav_SearchResultsGfx *gfx = AllocSubstruct(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX, sizeof(struct Pokenav_SearchResultsGfx)); - if (gfx == NULL) - return FALSE; - gfx->loopedTaskId = CreateLoopedTask(LoopedTask_OpenConditionSearchResults, 1); - gfx->callback = GetSearchResultCurrentLoopedTaskActive; - gfx->fromGraph = TRUE; - return TRUE; -} - -void CreateSearchResultsLoopedTask(s32 idx) -{ - struct Pokenav_SearchResultsGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX); - gfx->loopedTaskId = CreateLoopedTask(sSearchResultLoopTaskFuncs[idx], 1); - gfx->callback = GetSearchResultCurrentLoopedTaskActive; -} - -bool32 IsSearchResultLoopedTaskActive(void) -{ - struct Pokenav_SearchResultsGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX); - return gfx->callback(); -} - -bool32 GetSearchResultCurrentLoopedTaskActive(void) -{ - struct Pokenav_SearchResultsGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX); - return IsLoopedTaskActive(gfx->loopedTaskId); -} - -void FreeSearchResultSubstruct2(void) -{ - struct Pokenav_SearchResultsGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX); - sub_81C8234(); - RemoveWindow(gfx->winid); - FreePokenavSubstruct(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX); -} - -static u32 LoopedTask_OpenConditionSearchResults(s32 state) -{ - struct Pokenav_SearchResultsGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX); - switch (state) - { - case 0: - InitBgTemplates(sConditionSearchResultBgTemplates, ARRAY_COUNT(sConditionSearchResultBgTemplates)); - DecompressAndCopyTileDataToVram(1, sConditionSearchResultTiles, 0, 0, 0); - SetBgTilemapBuffer(1, gfx->buff); - CopyToBgTilemapBuffer(1, sConditionSearchResultTilemap, 0, 0); - CopyBgTilemapBufferToVram(1); - CopyPaletteIntoBufferUnfaded(sConditionSearchResultFramePal, 0x10, 0x20); - CopyBgTilemapBufferToVram(1); - return LT_INC_AND_PAUSE; - case 1: - if (FreeTempTileDataBuffersIfPossible()) - return LT_PAUSE; - if (!GetReturningFromGraph()) - return LT_PAUSE; - return LT_INC_AND_PAUSE; - case 2: - if (FreeTempTileDataBuffersIfPossible()) - return LT_PAUSE; - CopyPaletteIntoBufferUnfaded(sListBg_Pal, 0x20, 32); - InitConditionSearchListMenuTemplate(); - return LT_INC_AND_PAUSE; - case 3: - if (sub_81C8224()) - return LT_PAUSE; - AddSearchResultListMenuWindow(gfx); - PrintHelpBarText(HELPBAR_CONDITION_MON_LIST); - return LT_INC_AND_PAUSE; - case 4: - if (FreeTempTileDataBuffersIfPossible()) - return LT_PAUSE; - ChangeBgX(1, 0, BG_COORD_SET); - ChangeBgY(1, 0, BG_COORD_SET); - ShowBg(1); - ShowBg(2); - HideBg(3); - if (!gfx->fromGraph) - { - u8 searchGfxId = GetSelectedConditionSearch() + POKENAV_MENUITEM_CONDITION_SEARCH_COOL; - LoadLeftHeaderGfxForIndex(searchGfxId); - ShowLeftHeaderGfx(searchGfxId, 1, 0); - ShowLeftHeaderGfx(POKENAV_GFX_CONDITION_MENU, 1, 0); - } - PokenavFadeScreen(1); - return LT_INC_AND_PAUSE; - case 5: - if (IsPaletteFadeActive()) - return LT_PAUSE; - if (AreLeftHeaderSpritesMoving()) - return LT_PAUSE; - break; - } - return LT_FINISH; -} - -static u32 LoopedTask_MoveSearchListCursorUp(s32 state) -{ - struct Pokenav_SearchResultsGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX); - switch (state) - { - case 0: - switch (MatchCall_MoveCursorUp()) - { - case 0: - return LT_FINISH; - case 1: - PlaySE(SE_SELECT); - return LT_SET_STATE(2); - case 2: - PlaySE(SE_SELECT); - break; - } - return LT_INC_AND_PAUSE; - case 1: - if (IsMonListLoopedTaskActive()) - return LT_PAUSE; - // fallthrough - case 2: - PrintSearchResultListMenuItems(gfx); - return LT_INC_AND_PAUSE; - case 3: - if (IsDma3ManagerBusyWithBgCopy()) - return LT_PAUSE; - break; - } - return LT_FINISH; -} - -static u32 LoopedTask_MoveSearchListCursorDown(s32 state) -{ - struct Pokenav_SearchResultsGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX); - switch (state) - { - case 0: - switch (MatchCall_MoveCursorDown()) - { - case 0: - return LT_FINISH; - case 1: - PlaySE(SE_SELECT); - return LT_SET_STATE(2); - case 2: - PlaySE(SE_SELECT); - break; - } - return LT_INC_AND_PAUSE; - case 1: - if (IsMonListLoopedTaskActive()) - return LT_PAUSE; - // fallthrough - case 2: - PrintSearchResultListMenuItems(gfx); - return LT_INC_AND_PAUSE; - case 3: - if (IsDma3ManagerBusyWithBgCopy()) - return LT_PAUSE; - break; - } - return LT_FINISH; -} - -static u32 LoopedTask_MoveSearchListPageUp(s32 state) -{ - struct Pokenav_SearchResultsGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX); - switch (state) - { - case 0: - switch (MatchCall_PageUp()) - { - case 0: - return LT_FINISH; - case 1: - PlaySE(SE_SELECT); - return LT_SET_STATE(2); - case 2: - PlaySE(SE_SELECT); - break; - } - return LT_INC_AND_PAUSE; - case 1: - if (IsMonListLoopedTaskActive()) - return LT_PAUSE; - // fallthrough - case 2: - PrintSearchResultListMenuItems(gfx); - return LT_INC_AND_PAUSE; - case 3: - if (IsDma3ManagerBusyWithBgCopy()) - return LT_PAUSE; - break; - } - return LT_FINISH; -} - -static u32 LoopedTask_MoveSearchListPageDown(s32 state) -{ - struct Pokenav_SearchResultsGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX); - switch (state) - { - case 0: - switch (MatchCall_PageDown()) - { - case 0: - return LT_FINISH; - case 1: - PlaySE(SE_SELECT); - return LT_SET_STATE(2); - case 2: - PlaySE(SE_SELECT); - break; - } - return LT_INC_AND_PAUSE; - case 1: - if (IsMonListLoopedTaskActive()) - return LT_PAUSE; - // fallthrough - case 2: - PrintSearchResultListMenuItems(gfx); - return LT_INC_AND_PAUSE; - case 3: - if (IsDma3ManagerBusyWithBgCopy()) - return LT_PAUSE; - break; - } - return LT_FINISH; -} - -static u32 LoopedTask_ExitConditionSearchMenu(s32 state) -{ - switch (state) - { - case 0: - PlaySE(SE_SELECT); - PokenavFadeScreen(0); - SlideMenuHeaderDown(); - return LT_INC_AND_PAUSE; - case 1: - if (IsPaletteFadeActive()) - return LT_PAUSE; - if (MainMenuLoopedTaskIsBusy()) - return LT_PAUSE; - SetLeftHeaderSpritesInvisibility(); - break; - } - return LT_FINISH; -} - -static u32 LoopedTask_SelectSearchResult(s32 state) -{ - switch (state) - { - case 0: - PlaySE(SE_SELECT); - PokenavFadeScreen(0); - return LT_INC_AND_PAUSE; - case 1: - if (IsPaletteFadeActive()) - return LT_PAUSE; - break; - } - return LT_FINISH; -} - -static void AddSearchResultListMenuWindow(struct Pokenav_SearchResultsGfx *gfx) -{ - gfx->winid = AddWindow(&sSearchResultListMenuWindowTemplate); - PutWindowTilemap(gfx->winid); - CopyWindowToVram(gfx->winid, COPYWIN_MAP); - PrintSearchResultListMenuItems(gfx); -} - -static void PrintSearchResultListMenuItems(struct Pokenav_SearchResultsGfx *gfx) -{ - s32 rank = GetSearchResultsSelectedMonRank(); - DynamicPlaceholderTextUtil_Reset(); - DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, gStringVar1); - *gStringVar1 = EOS; - DynamicPlaceholderTextUtil_ExpandPlaceholders(gStringVar2, gText_NumberIndex); - AddTextPrinterParameterized(gfx->winid, FONT_NORMAL, gStringVar2, 4, 1, TEXT_SKIP_DRAW, NULL); - ConvertIntToDecimalStringN(gStringVar1, rank, STR_CONV_MODE_RIGHT_ALIGN, 3); - AddTextPrinterParameterized(gfx->winid, FONT_NORMAL, gStringVar1, 34, 1, TEXT_SKIP_DRAW, NULL); - CopyWindowToVram(gfx->winid, COPYWIN_GFX); -} - -static void InitConditionSearchListMenuTemplate(void) -{ - struct PokenavListTemplate template; - - template.list.monList = GetSearchResultsMonDataList(); - template.count = GetSearchResultsMonListCount(); - template.unk8 = 4; - template.unk6 = GetSearchResultsCurrentListIndex(); - template.item_X = 13; - template.windowWidth = 17; - template.listTop = 1; - template.maxShowed = 8; - template.fillValue = 2; - template.fontId = FONT_NORMAL; - template.listFunc.printMonFunc = PrintSearchMonListItem; - template.unk14 = NULL; - sub_81C81D4(&sConditionSearchResultBgTemplates[1], &template, 0); -} - -static void PrintSearchMonListItem(struct PokenavMonList * item, u8 * dest) -{ - u8 gender; - u8 level; - u8 * s; - const u8 * genderStr; - - // Mon is in party - if (item->boxId == TOTAL_BOXES_COUNT) - { - struct Pokemon * mon = &gPlayerParty[item->monId]; - gender = GetMonGender(mon); - level = GetLevelFromMonExp(mon); - GetMonData(mon, MON_DATA_NICKNAME, gStringVar3); - } - // Mon is in PC - else - { - struct BoxPokemon * mon = GetBoxedMonPtr(item->boxId, item->monId); - gender = GetBoxMonGender(mon); - level = GetLevelFromBoxMonExp(mon); - GetBoxMonData(mon, MON_DATA_NICKNAME, gStringVar3); - } - - StringGetEnd10(gStringVar3); - dest = GetStringClearToWidth(dest, FONT_NORMAL, gStringVar3, 60); - switch (gender) - { - default: - genderStr = sText_NoGenderSymbol; - break; - case MON_MALE: - genderStr = sText_MaleSymbol; - break; - case MON_FEMALE: - genderStr = sText_FemaleSymbol; - break; - } - s = StringCopy(gStringVar1, genderStr); - *s++ = CHAR_SLASH; - *s++ = CHAR_EXTRA_SYMBOL; - *s++ = CHAR_LV_2; - ConvertIntToDecimalStringN(s, level, STR_CONV_MODE_LEFT_ALIGN, 3); - GetStringClearToWidth(dest, FONT_NORMAL, gStringVar1, 40); -} diff --git a/src/pokenav_conditions_gfx.c b/src/pokenav_conditions_gfx.c new file mode 100644 index 000000000..a1593983d --- /dev/null +++ b/src/pokenav_conditions_gfx.c @@ -0,0 +1,892 @@ +#include "global.h" +#include "bg.h" +#include "window.h" +#include "pokenav.h" +#include "decompress.h" +#include "gpu_regs.h" +#include "graphics.h" +#include "menu.h" +#include "menu_specialized.h" +#include "mon_markings.h" +#include "palette.h" +#include "pokenav.h" +#include "scanline_effect.h" +#include "string_util.h" +#include "strings.h" +#include "text.h" + +static u32 LoopedTask_TransitionMons(s32); +static u32 LoopedTask_ExitConditionGraphMenu(s32); +static u32 LoopedTask_MoveCursorNoTransition(s32); +static u32 LoopedTask_SlideMonOut(s32); +static u32 LoopedTask_OpenMonMarkingsWindow(s32); +static u32 LoopedTask_CloseMonMarkingsWindow(s32); + +static u8 sInitialLoadId; // Never read + +const u16 gConditionGraphData_Pal[] = INCBIN_U16("graphics/pokenav/condition/graph_data.gbapal"); +const u16 gConditionText_Pal[] = INCBIN_U16("graphics/pokenav/condition/text.gbapal"); +static const u32 sConditionGraphData_Gfx[] = INCBIN_U32("graphics/pokenav/condition/graph_data.4bpp.lz"); +static const u32 sConditionGraphData_Tilemap[] = INCBIN_U32("graphics/pokenav/condition/graph_data.bin.lz"); +static const u16 sMonMarkings_Pal[] = INCBIN_U16("graphics/pokenav/condition/mon_markings.gbapal"); + +static const struct BgTemplate sMenuBgTemplates[3] = +{ + { + .bg = 1, + .charBaseIndex = 1, + .mapBaseIndex = 0x1F, + .screenSize = 0, + .paletteMode = 0, + .priority = 1, + .baseTile = 0 + }, + { + .bg = 2, + .charBaseIndex = 3, + .mapBaseIndex = 0x1D, + .screenSize = 0, + .paletteMode = 0, + .priority = 2, + .baseTile = 0 + }, + { + .bg = 3, + .charBaseIndex = 2, + .mapBaseIndex = 0x1E, + .screenSize = 0, + .paletteMode = 0, + .priority = 3, + .baseTile = 0 + } +}; + +static const struct WindowTemplate sMonNameGenderWindowTemplate = +{ + .bg = 1, + .tilemapLeft = 13, + .tilemapTop = 1, + .width = 13, + .height = 4, + .paletteNum = 15, + .baseBlock = 2 +}; + +static const struct WindowTemplate sListIndexWindowTemplate = +{ + .bg = 1, + .tilemapLeft = 1, + .tilemapTop = 6, + .width = 7, + .height = 2, + .paletteNum = 15, + .baseBlock = 0x36 +}; + +static const struct WindowTemplate sUnusedWindowTemplate1 = +{ + .bg = 1, + .tilemapLeft = 1, + .tilemapTop = 0x1C, + .width = 5, + .height = 2, + .paletteNum = 15, + .baseBlock = 0x44 +}; + +static const struct WindowTemplate sUnusedWindowTemplate2 = +{ + .bg = 1, + .tilemapLeft = 13, + .tilemapTop = 0x1C, + .width = 3, + .height = 2, + .paletteNum = 15, + .baseBlock = 0x44 +}; + +static const LoopedTask sLoopedTaskFuncs[] = +{ + [CONDITION_FUNC_NONE] = NULL, + [CONDITION_FUNC_SLIDE_MON_IN] = LoopedTask_TransitionMons, + [CONDITION_FUNC_RETURN] = LoopedTask_ExitConditionGraphMenu, + [CONDITION_FUNC_NO_TRANSITION] = LoopedTask_MoveCursorNoTransition, + [CONDITION_FUNC_SLIDE_MON_OUT] = LoopedTask_SlideMonOut, + [CONDITION_FUNC_ADD_MARKINGS] = LoopedTask_OpenMonMarkingsWindow, + [CONDITION_FUNC_CLOSE_MARKINGS] = LoopedTask_CloseMonMarkingsWindow +}; + +struct Pokenav_ConditionMenuGfx +{ + u32 loopedTaskId; + u8 tilemapBuffers[3][BG_SCREEN_SIZE]; + u8 filler[2]; + u8 partyPokeballSpriteIds[PARTY_SIZE + 1]; + u32 (*callback)(void); + s16 monTransitionX; + u8 monPicSpriteId; + u16 monPalIndex; + u16 monGfxTileStart; + void *monGfxPtr; + u8 nameGenderWindowId; + u8 listIndexWindowId; + u8 unusedWindowId1; + u8 unusedWindowId2; + struct MonMarkingsMenu marksMenu; + struct Sprite *monMarksSprite; + struct Sprite *conditionSparkleSprites[MAX_CONDITION_SPARKLES]; + u8 windowModeState; + u8 filler2[0xFA3]; +}; + +extern s8 GetConditionGraphMenuCurrentLoadIndex(void); // This function's declaration here is s8 vs. u8 in pokenav_conditions.c + +static u32 LoopedTask_OpenConditionGraphMenu(s32); +static u32 GetConditionGraphMenuLoopedTaskActive(void); +static void CreateConditionMonPic(u8); +static void CreateMonMarkingsOrPokeballIndicators(void); +static void CopyUnusedConditionWindowsToVram(void); +static bool32 UpdateConditionGraphMenuWindows(u8, u16, bool8); +static void VBlankCB_PokenavConditionGraph(void); +static void DoConditionGraphEnterTransition(void); +static void DoConditionGraphExitTransition(void); +static void SetExitVBlank(void); +static void ToggleGraphData(bool8); + +bool32 OpenConditionGraphMenu(void) +{ + struct Pokenav_ConditionMenuGfx *menu = AllocSubstruct(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX, sizeof(struct Pokenav_ConditionMenuGfx)); + + if (menu == NULL) + return FALSE; + + menu->monPicSpriteId = SPRITE_NONE; + menu->loopedTaskId = CreateLoopedTask(LoopedTask_OpenConditionGraphMenu, 1); + menu->callback = GetConditionGraphMenuLoopedTaskActive; + menu->windowModeState = 0; + return TRUE; +} + +void CreateConditionGraphMenuLoopedTask(s32 id) +{ + struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); + menu->loopedTaskId = CreateLoopedTask(sLoopedTaskFuncs[id], 1); + menu->callback = GetConditionGraphMenuLoopedTaskActive; +} + +u32 IsConditionGraphMenuLoopedTaskActive(void) +{ + struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); + return menu->callback(); +} + +static u32 GetConditionGraphMenuLoopedTaskActive(void) +{ + struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); + return IsLoopedTaskActive(menu->loopedTaskId); +} + +static u32 LoopedTask_OpenConditionGraphMenu(s32 state) +{ + struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); + + switch (state) + { + case 0: + if (LoadConditionGraphMenuGfx() != TRUE) + return LT_PAUSE; + return LT_INC_AND_PAUSE; + case 1: + InitBgTemplates(sMenuBgTemplates, ARRAY_COUNT(sMenuBgTemplates)); + ChangeBgX(1, 0, BG_COORD_SET); + ChangeBgY(1, 0, BG_COORD_SET); + ChangeBgX(2, 0, BG_COORD_SET); + ChangeBgY(2, 0, BG_COORD_SET); + ChangeBgX(3, 0, BG_COORD_SET); + ChangeBgY(3, 0, BG_COORD_SET); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON | DISPCNT_WIN1_ON | DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON | DISPCNT_BG3_ON); + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG2 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG3); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(11, 4)); + DecompressAndCopyTileDataToVram(3, gPokenavCondition_Gfx, 0, 0, 0); + return LT_INC_AND_PAUSE; + case 2: + if (FreeTempTileDataBuffersIfPossible()) + return LT_PAUSE; + DecompressAndCopyTileDataToVram(2, sConditionGraphData_Gfx, 0, 0, 0); + return LT_INC_AND_PAUSE; + case 3: + if (FreeTempTileDataBuffersIfPossible()) + return LT_PAUSE; + + LZ77UnCompVram(gPokenavCondition_Tilemap, menu->tilemapBuffers[0]); + SetBgTilemapBuffer(3, menu->tilemapBuffers[0]); + if (IsConditionMenuSearchMode() == TRUE) + CopyToBgTilemapBufferRect(3, gPokenavOptions_Tilemap, 0, 5, 9, 4); + + CopyBgTilemapBufferToVram(3); + CopyPaletteIntoBufferUnfaded(gPokenavCondition_Pal, 0x10, 0x20); + CopyPaletteIntoBufferUnfaded(gConditionText_Pal, 0xF0, 0x20); + menu->monTransitionX = -80; + return LT_INC_AND_PAUSE; + case 4: + if (FreeTempTileDataBuffersIfPossible()) + return LT_PAUSE; + + LZ77UnCompVram(sConditionGraphData_Tilemap, menu->tilemapBuffers[2]); + SetBgTilemapBuffer(2, menu->tilemapBuffers[2]); + CopyBgTilemapBufferToVram(2); + CopyPaletteIntoBufferUnfaded(gConditionGraphData_Pal, 0x30, 0x20); + ConditionGraph_InitWindow(2); + return LT_INC_AND_PAUSE; + case 5: + BgDmaFill(1, 0, 0, 1); + BgDmaFill(1, 17, 1, 1); + CpuFill32(0, menu->tilemapBuffers[1], BG_SCREEN_SIZE); + SetBgTilemapBuffer(1, menu->tilemapBuffers[1]); + return LT_INC_AND_PAUSE; + case 6: + if (FreeTempTileDataBuffersIfPossible()) + return LT_PAUSE; + + menu->nameGenderWindowId = AddWindow(&sMonNameGenderWindowTemplate); + if (IsConditionMenuSearchMode() == TRUE) + { + menu->listIndexWindowId = AddWindow(&sListIndexWindowTemplate); + menu->unusedWindowId1 = AddWindow(&sUnusedWindowTemplate1); + menu->unusedWindowId2 = AddWindow(&sUnusedWindowTemplate2); + } + DeactivateAllTextPrinters(); + return LT_INC_AND_PAUSE; + case 7: + CreateConditionMonPic(0); + return LT_INC_AND_PAUSE; + case 8: + CreateMonMarkingsOrPokeballIndicators(); + return LT_INC_AND_PAUSE; + case 9: + if (IsConditionMenuSearchMode() == TRUE) + CopyUnusedConditionWindowsToVram(); + return LT_INC_AND_PAUSE; + case 10: + UpdateConditionGraphMenuWindows(0, GetConditionGraphMenuCurrentLoadIndex(), TRUE); + return LT_INC_AND_PAUSE; + case 11: + UpdateConditionGraphMenuWindows(1, GetConditionGraphMenuCurrentLoadIndex(), TRUE); + return LT_INC_AND_PAUSE; + case 12: + UpdateConditionGraphMenuWindows(2, GetConditionGraphMenuCurrentLoadIndex(), TRUE); + return LT_INC_AND_PAUSE; + case 13: + if (UpdateConditionGraphMenuWindows(3, GetConditionGraphMenuCurrentLoadIndex(), TRUE) != TRUE) + return LT_PAUSE; + PutWindowTilemap(menu->nameGenderWindowId); + if (IsConditionMenuSearchMode() == TRUE) + { + PutWindowTilemap(menu->listIndexWindowId); + PutWindowTilemap(menu->unusedWindowId1); + PutWindowTilemap(menu->unusedWindowId2); + } + return LT_INC_AND_PAUSE; + case 14: + ShowBg(1); + HideBg(2); + ShowBg(3); + if (IsConditionMenuSearchMode() == TRUE) + PrintHelpBarText(HELPBAR_CONDITION_MON_STATUS); + return LT_INC_AND_PAUSE; + case 15: + PokenavFadeScreen(1); + if (!IsConditionMenuSearchMode()) + { + LoadLeftHeaderGfxForIndex(POKENAV_GFX_PARTY_MENU); + ShowLeftHeaderGfx(POKENAV_GFX_CONDITION_MENU, TRUE, 0); + ShowLeftHeaderGfx(POKENAV_GFX_PARTY_MENU, TRUE, 0); + } + return LT_INC_AND_PAUSE; + case 16: + if (IsPaletteFadeActive()) + return LT_PAUSE; + if (!IsConditionMenuSearchMode() && AreLeftHeaderSpritesMoving()) + return LT_PAUSE; + SetVBlankCallback_(VBlankCB_PokenavConditionGraph); + return LT_INC_AND_PAUSE; + case 17: + DoConditionGraphEnterTransition(); + ConditionGraph_InitResetScanline(GetConditionGraphPtr()); + return LT_INC_AND_PAUSE; + case 18: + if (ConditionGraph_ResetScanline(GetConditionGraphPtr())) + return LT_PAUSE; + return LT_INC_AND_PAUSE; + case 19: + ToggleGraphData(TRUE); + return LT_INC_AND_PAUSE; + case 20: + if (!ConditionMenu_UpdateMonEnter(GetConditionGraphPtr(), &menu->monTransitionX)) + { + ResetConditionSparkleSprites(menu->conditionSparkleSprites); + if (IsConditionMenuSearchMode() == TRUE || GetConditionGraphCurrentListIndex() != GetMonListCount()) + CreateConditionSparkleSprites(menu->conditionSparkleSprites, menu->monPicSpriteId, GetNumConditionMonSparkles()); + + return LT_FINISH; + } + return LT_PAUSE; + } + + return LT_FINISH; +} + +static u32 LoopedTask_ExitConditionGraphMenu(s32 state) +{ + struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); + + switch (state) + { + case 0: + DoConditionGraphExitTransition(); + DestroyConditionSparkleSprites(menu->conditionSparkleSprites); + return LT_INC_AND_CONTINUE; + case 1: + if (ConditionMenu_UpdateMonExit(GetConditionGraphPtr(), &menu->monTransitionX)) + return 2; + ToggleGraphData(FALSE); + return LT_INC_AND_CONTINUE; + case 2: + PokenavFadeScreen(0); + if (!IsConditionMenuSearchMode()) + SlideMenuHeaderDown(); + return LT_INC_AND_PAUSE; + case 3: + if (IsPaletteFadeActive() || MainMenuLoopedTaskIsBusy()) + return LT_PAUSE; + FreeConditionSparkles(menu->conditionSparkleSprites); + HideBg(1); + HideBg(2); + HideBg(3); + return LT_INC_AND_CONTINUE; + } + + return LT_FINISH; +} + +static u32 LoopedTask_TransitionMons(s32 state) +{ + struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); + struct ConditionGraph *graph = GetConditionGraphPtr(); + + switch (state) + { + case 0: + LoadNextConditionMenuMonData(CONDITION_LOAD_MON_INFO); + return LT_INC_AND_CONTINUE; + case 1: + LoadNextConditionMenuMonData(CONDITION_LOAD_GRAPH); + return LT_INC_AND_CONTINUE; + case 2: + LoadNextConditionMenuMonData(CONDITION_LOAD_MON_PIC); + DestroyConditionSparkleSprites(menu->conditionSparkleSprites); + return LT_INC_AND_CONTINUE; + case 3: + ConditionGraph_TryUpdate(graph); + return LT_INC_AND_CONTINUE; + case 4: + if (!MoveConditionMonOffscreen(&menu->monTransitionX)) + { + CreateConditionMonPic(GetConditionGraphMenuCurrentLoadIndex()); + return LT_INC_AND_CONTINUE; + } + return LT_PAUSE; + case 5: + UpdateConditionGraphMenuWindows(0, GetConditionGraphMenuCurrentLoadIndex(), FALSE); + return LT_INC_AND_CONTINUE; + case 6: + UpdateConditionGraphMenuWindows(1, GetConditionGraphMenuCurrentLoadIndex(), FALSE); + return LT_INC_AND_CONTINUE; + case 7: + UpdateConditionGraphMenuWindows(2, GetConditionGraphMenuCurrentLoadIndex(), FALSE); + return LT_INC_AND_CONTINUE; + case 8: + if (UpdateConditionGraphMenuWindows(3, GetConditionGraphMenuCurrentLoadIndex(), FALSE) == TRUE) + return LT_INC_AND_CONTINUE; + return LT_PAUSE; + case 9: + graph = GetConditionGraphPtr(); + if (!ConditionMenu_UpdateMonEnter(graph, &menu->monTransitionX)) + { + ResetConditionSparkleSprites(menu->conditionSparkleSprites); + if (IsConditionMenuSearchMode() != TRUE && GetConditionGraphCurrentListIndex() == GetMonListCount()) + return LT_INC_AND_CONTINUE; + + CreateConditionSparkleSprites(menu->conditionSparkleSprites, menu->monPicSpriteId, GetNumConditionMonSparkles()); + return LT_INC_AND_CONTINUE; + } + return LT_PAUSE; + } + + return LT_FINISH; +} + +static u32 LoopedTask_MoveCursorNoTransition(s32 state) +{ + struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); + + switch (state) + { + case 0: + LoadNextConditionMenuMonData(CONDITION_LOAD_MON_INFO); + return LT_INC_AND_CONTINUE; + case 1: + LoadNextConditionMenuMonData(CONDITION_LOAD_GRAPH); + return LT_INC_AND_CONTINUE; + case 2: + LoadNextConditionMenuMonData(CONDITION_LOAD_MON_PIC); + return LT_INC_AND_CONTINUE; + case 3: + CreateConditionMonPic(GetConditionGraphMenuCurrentLoadIndex()); + return LT_INC_AND_CONTINUE; + case 4: + UpdateConditionGraphMenuWindows(0, GetConditionGraphMenuCurrentLoadIndex(), FALSE); + return LT_INC_AND_CONTINUE; + case 5: + UpdateConditionGraphMenuWindows(1, GetConditionGraphMenuCurrentLoadIndex(), FALSE); + return LT_INC_AND_CONTINUE; + case 6: + UpdateConditionGraphMenuWindows(2, GetConditionGraphMenuCurrentLoadIndex(), FALSE); + return LT_INC_AND_CONTINUE; + case 7: + if (UpdateConditionGraphMenuWindows(3, GetConditionGraphMenuCurrentLoadIndex(), FALSE) == TRUE) + return LT_INC_AND_CONTINUE; + return LT_PAUSE; + case 8: + if (!ConditionMenu_UpdateMonEnter(GetConditionGraphPtr(), &menu->monTransitionX)) + { + ResetConditionSparkleSprites(menu->conditionSparkleSprites); + CreateConditionSparkleSprites(menu->conditionSparkleSprites, menu->monPicSpriteId, GetNumConditionMonSparkles()); + return LT_INC_AND_CONTINUE; + } + return LT_PAUSE; + } + + return LT_FINISH; +} + +static u32 LoopedTask_SlideMonOut(s32 state) +{ + struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); + + switch (state) + { + case 0: + LoadNextConditionMenuMonData(CONDITION_LOAD_MON_INFO); + return LT_INC_AND_CONTINUE; + case 1: + LoadNextConditionMenuMonData(CONDITION_LOAD_GRAPH); + return LT_INC_AND_CONTINUE; + case 2: + LoadNextConditionMenuMonData(CONDITION_LOAD_MON_PIC); + DestroyConditionSparkleSprites(menu->conditionSparkleSprites); + return LT_INC_AND_CONTINUE; + case 3: + if (!ConditionMenu_UpdateMonExit(GetConditionGraphPtr(), &menu->monTransitionX)) + return LT_INC_AND_CONTINUE; + return LT_PAUSE; + case 4: + UpdateConditionGraphMenuWindows(0, GetConditionGraphMenuCurrentLoadIndex(), FALSE); + return LT_INC_AND_CONTINUE; + case 5: + UpdateConditionGraphMenuWindows(1, GetConditionGraphMenuCurrentLoadIndex(), FALSE); + return LT_INC_AND_CONTINUE; + case 6: + UpdateConditionGraphMenuWindows(2, GetConditionGraphMenuCurrentLoadIndex(), FALSE); + return LT_INC_AND_CONTINUE; + case 7: + if (UpdateConditionGraphMenuWindows(3, GetConditionGraphMenuCurrentLoadIndex(), FALSE) == TRUE) + return LT_INC_AND_CONTINUE; + return LT_PAUSE; + } + + return LT_FINISH; +} + +static u32 LoopedTask_OpenMonMarkingsWindow(s32 state) +{ + switch (state) + { + case 0: + OpenMonMarkingsMenu(TryGetMonMarkId(), 176, 32); + return LT_INC_AND_CONTINUE; + case 1: + PrintHelpBarText(HELPBAR_CONDITION_MARKINGS); + return LT_INC_AND_CONTINUE; + case 2: + if (WaitForHelpBar() == TRUE) + return LT_PAUSE; + return LT_INC_AND_CONTINUE; + } + + return LT_FINISH; +} + +static u32 LoopedTask_CloseMonMarkingsWindow(s32 state) +{ + switch (state) + { + case 0: + FreeMonMarkingsMenu(); + return LT_INC_AND_CONTINUE; + case 1: + PrintHelpBarText(HELPBAR_CONDITION_MON_STATUS); + return LT_INC_AND_CONTINUE; + case 2: + if (WaitForHelpBar() == TRUE) + return LT_PAUSE; + return LT_INC_AND_CONTINUE; + } + + return LT_FINISH; +} + +static u8 *UnusedPrintNumberString(u8 *dst, u16 num) +{ + u8 *txtPtr = ConvertIntToDecimalStringN(dst, num, STR_CONV_MODE_RIGHT_ALIGN, 4); + txtPtr = StringCopy(txtPtr, gText_Number2); + + return txtPtr; +} + +static bool32 UpdateConditionGraphMenuWindows(u8 mode, u16 bufferIndex, bool8 winMode) +{ + u8 text[32]; + const u8 *str; + struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); + + switch (mode) + { + case 0: + FillWindowPixelBuffer(menu->nameGenderWindowId, 0); + if (IsConditionMenuSearchMode() == TRUE) + FillWindowPixelBuffer(menu->listIndexWindowId, 0); + break; + case 1: + if (GetConditionGraphCurrentListIndex() != GetMonListCount() - 1 || IsConditionMenuSearchMode() == TRUE) + { + str = GetConditionMonNameText(bufferIndex); + AddTextPrinterParameterized(menu->nameGenderWindowId, FONT_NORMAL, str, 0, 1, 0, NULL); + } + break; + case 2: + if (IsConditionMenuSearchMode() == TRUE) + { + str = GetConditionMonLocationText(bufferIndex); + AddTextPrinterParameterized(menu->nameGenderWindowId, FONT_NORMAL, str, 0, 17, 0, NULL); + text[0] = EXT_CTRL_CODE_BEGIN; + text[1] = EXT_CTRL_CODE_COLOR_HIGHLIGHT_SHADOW; + text[2] = TEXT_COLOR_BLUE; + text[3] = TEXT_COLOR_TRANSPARENT; + text[4] = TEXT_COLOR_LIGHT_BLUE; + StringCopy(&text[5], gText_Number2); + AddTextPrinterParameterized(menu->listIndexWindowId, FONT_NORMAL, text, 4, 1, 0, NULL); + ConvertIntToDecimalStringN(&text[5], GetConditionMonDataBuffer(), STR_CONV_MODE_RIGHT_ALIGN, 4); + AddTextPrinterParameterized(menu->listIndexWindowId, FONT_NORMAL, text, 28, 1, 0, NULL); + } + break; + case 3: + switch (menu->windowModeState) + { + case 0: + if (winMode) + CopyWindowToVram(menu->nameGenderWindowId, COPYWIN_FULL); + else + CopyWindowToVram(menu->nameGenderWindowId, COPYWIN_GFX); + + if (IsConditionMenuSearchMode() == TRUE) + { + menu->windowModeState++; + return FALSE; + } + else + { + menu->windowModeState = 0; + return TRUE; + } + case 1: + if (winMode) + CopyWindowToVram(menu->listIndexWindowId, COPYWIN_FULL); + else + CopyWindowToVram(menu->listIndexWindowId, COPYWIN_GFX); + + menu->windowModeState = 0; + return TRUE; + } + } + + return FALSE; +} + +static void CopyUnusedConditionWindowsToVram(void) +{ + struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); + + CopyWindowToVram(menu->unusedWindowId1, COPYWIN_FULL); + CopyWindowToVram(menu->unusedWindowId2, COPYWIN_FULL); +} + +static void SpriteCB_PartyPokeball(struct Sprite *sprite) +{ + if (sprite->data[0] == GetConditionGraphCurrentListIndex()) + StartSpriteAnim(sprite, CONDITION_ICON_SELECTED); + else + StartSpriteAnim(sprite, CONDITION_ICON_UNSELECTED); +} + +void HighlightCurrentPartyIndexPokeball(struct Sprite *sprite) +{ + if (GetConditionGraphCurrentListIndex() == GetMonListCount() - 1) + sprite->oam.paletteNum = IndexOfSpritePaletteTag(TAG_CONDITION_BALL); + else + sprite->oam.paletteNum = IndexOfSpritePaletteTag(TAG_CONDITION_CANCEL); +} + +void MonMarkingsCallback(struct Sprite *sprite) +{ + StartSpriteAnim(sprite, TryGetMonMarkId()); +} + +static void CreateMonMarkingsOrPokeballIndicators(void) +{ + struct SpriteSheet sprSheets[4]; + struct SpriteTemplate sprTemplate; + struct SpritePalette sprPals[3]; + struct SpriteSheet sprSheet; + struct Sprite *sprite; + u16 i, spriteId; + struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); + + LoadConditionSelectionIcons(sprSheets, &sprTemplate, sprPals); + if (IsConditionMenuSearchMode() == TRUE) + { + // Search Mode, load markings menu + menu->marksMenu.baseTileTag = TAG_CONDITION_MARKINGS_MENU; + menu->marksMenu.basePaletteTag = TAG_CONDITION_MARKINGS_MENU; + InitMonMarkingsMenu(&menu->marksMenu); + BufferMonMarkingsMenuTiles(); + sprite = CreateMonMarkingAllCombosSprite(TAG_CONDITION_MON_MARKINGS, TAG_CONDITION_MON_MARKINGS, sMonMarkings_Pal); + sprite->oam.priority = 3; + sprite->x = 192; + sprite->y = 32; + sprite->callback = MonMarkingsCallback; + menu->monMarksSprite = sprite; + PokenavFillPalette(IndexOfSpritePaletteTag(TAG_CONDITION_MON_MARKINGS), 0); + } + else + { + // Party Mode, load Pokéball selection icons + LoadSpriteSheets(sprSheets); + Pokenav_AllocAndLoadPalettes(sprPals); + + // Add icons for occupied slots + for (i = 0; i < GetMonListCount() - 1; i++) + { + spriteId = CreateSprite(&sprTemplate, 226, (i * 20) + 8, 0); + if (spriteId != MAX_SPRITES) + { + menu->partyPokeballSpriteIds[i] = spriteId; + gSprites[spriteId].data[0] = i; + gSprites[spriteId].callback = SpriteCB_PartyPokeball; + } + else + { + menu->partyPokeballSpriteIds[i] = SPRITE_NONE; + } + } + + // Add icons for empty slots + sprTemplate.tileTag = TAG_CONDITION_BALL_PLACEHOLDER; + sprTemplate.callback = SpriteCallbackDummy; + for (; i < PARTY_SIZE; i++) + { + spriteId = CreateSprite(&sprTemplate, 230, (i * 20) + 8, 0); + if (spriteId != MAX_SPRITES) + { + menu->partyPokeballSpriteIds[i] = spriteId; + gSprites[spriteId].oam.size = 0; + } + else + { + menu->partyPokeballSpriteIds[i] = SPRITE_NONE; + } + } + + // Add cancel icon + sprTemplate.tileTag = TAG_CONDITION_CANCEL; + sprTemplate.callback = HighlightCurrentPartyIndexPokeball; + spriteId = CreateSprite(&sprTemplate, 222, (i * 20) + 8, 0); + if (spriteId != MAX_SPRITES) + { + menu->partyPokeballSpriteIds[i] = spriteId; + gSprites[spriteId].oam.shape = SPRITE_SHAPE(32x16); + gSprites[spriteId].oam.size = SPRITE_SIZE(32x16); + } + else + { + menu->partyPokeballSpriteIds[i] = SPRITE_NONE; + } + } + + LoadConditionSparkle(&sprSheet, &sprPals[0]); + LoadSpriteSheet(&sprSheet); + sprPals[1].data = NULL; + Pokenav_AllocAndLoadPalettes(sprPals); +} + +static void FreeConditionMenuGfx(struct Pokenav_ConditionMenuGfx *menu) +{ + u8 i; + + if (IsConditionMenuSearchMode() == TRUE) + { + DestroySprite(menu->monMarksSprite); + FreeSpriteTilesByTag(TAG_CONDITION_MARKINGS_MENU); + FreeSpriteTilesByTag(TAG_CONDITION_MON_MARKINGS); + FreeSpritePaletteByTag(TAG_CONDITION_MARKINGS_MENU); + FreeSpritePaletteByTag(TAG_CONDITION_MON_MARKINGS); + } + else + { + for (i = 0; i < PARTY_SIZE + 1; i++) + DestroySprite(&gSprites[menu->partyPokeballSpriteIds[i]]); + + FreeSpriteTilesByTag(TAG_CONDITION_BALL); + FreeSpriteTilesByTag(TAG_CONDITION_CANCEL); + FreeSpriteTilesByTag(TAG_CONDITION_BALL_PLACEHOLDER); + FreeSpritePaletteByTag(TAG_CONDITION_BALL); + FreeSpritePaletteByTag(TAG_CONDITION_CANCEL); + } + + if (menu->monPicSpriteId != SPRITE_NONE) + { + DestroySprite(&gSprites[menu->monPicSpriteId]); + FreeSpriteTilesByTag(TAG_CONDITION_MON); + FreeSpritePaletteByTag(TAG_CONDITION_MON); + } +} + +void FreeConditionGraphMenuSubstruct2(void) +{ + struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); + + RemoveWindow(menu->nameGenderWindowId); + if (IsConditionMenuSearchMode() == TRUE) + { + RemoveWindow(menu->listIndexWindowId); + RemoveWindow(menu->unusedWindowId1); + RemoveWindow(menu->unusedWindowId2); + } + else + { + SetLeftHeaderSpritesInvisibility(); + } + + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_BG0_ON | DISPCNT_OBJ_1D_MAP); + FreeConditionMenuGfx(menu); + SetExitVBlank(); + FreePokenavSubstruct(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); +} + +void MonPicGfxSpriteCallback(struct Sprite *sprite) +{ + struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); + sprite->x = menu->monTransitionX + 38; +} + +static void CreateConditionMonPic(u8 id) +{ + struct SpriteTemplate sprTemplate; + struct SpriteSheet sprSheet; + struct SpritePalette sprPal; + u8 spriteId; + struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); + + if (menu->monPicSpriteId == SPRITE_NONE) + { + LoadConditionMonPicTemplate(&sprSheet, &sprTemplate, &sprPal); + sprSheet.data = GetConditionMonPicGfx(id); + sprPal.data = GetConditionMonPal(id); + menu->monPalIndex = LoadSpritePalette(&sprPal); + menu->monGfxTileStart = LoadSpriteSheet(&sprSheet); + spriteId = CreateSprite(&sprTemplate, 38, 104, 0); + menu->monPicSpriteId = spriteId; + if (spriteId == MAX_SPRITES) + { + FreeSpriteTilesByTag(TAG_CONDITION_MON); + FreeSpritePaletteByTag(TAG_CONDITION_MON); + menu->monPicSpriteId = SPRITE_NONE; + } + else + { + menu->monPicSpriteId = spriteId; + gSprites[menu->monPicSpriteId].callback = MonPicGfxSpriteCallback; + menu->monGfxPtr = (void*)VRAM + BG_VRAM_SIZE + (menu->monGfxTileStart * 32); + menu->monPalIndex = (menu->monPalIndex * 16) + 0x100; + } + } + else + { + DmaCopy16Defvars(3, GetConditionMonPicGfx(id), menu->monGfxPtr, MON_PIC_SIZE); + LoadPalette(GetConditionMonPal(id), menu->monPalIndex, 0x20); + } +} + +static void VBlankCB_PokenavConditionGraph(void) +{ + struct ConditionGraph *graph = GetConditionGraphPtr(); + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); + ConditionGraph_Draw(graph); + ScanlineEffect_InitHBlankDmaTransfer(); +} + +static void SetExitVBlank(void) +{ + SetPokenavVBlankCallback(); +} + +static void ToggleGraphData(bool8 showBg) +{ + if (showBg) + ShowBg(2); + else + HideBg(2); +} + +static void DoConditionGraphEnterTransition(void) +{ + struct ConditionGraph *graph = GetConditionGraphPtr(); + u8 id = GetConditionGraphMenuCurrentLoadIndex(); + + sInitialLoadId = id; + ConditionGraph_SetNewPositions(graph, graph->savedPositions[CONDITION_GRAPH_LOAD_MAX - 1], graph->savedPositions[id]); + ConditionGraph_TryUpdate(graph); +} + +// Transition the graph back to empty before exiting. +// This is skipped if the player is in party mode and the cursor +// is on Cancel, in which case the graph is already empty. +static void DoConditionGraphExitTransition(void) +{ + struct ConditionGraph *graph = GetConditionGraphPtr(); + + if (IsConditionMenuSearchMode() || GetConditionGraphCurrentListIndex() != GetMonListCount() - 1) + ConditionGraph_SetNewPositions(graph, graph->savedPositions[GetConditionGraphMenuCurrentLoadIndex()], graph->savedPositions[CONDITION_GRAPH_LOAD_MAX - 1]); +} + +u8 GetMonMarkingsData(void) +{ + struct Pokenav_ConditionMenuGfx *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_GRAPH_MENU_GFX); + + if (IsConditionMenuSearchMode() == 1) + return menu->marksMenu.markings; + else + return 0; +} diff --git a/src/pokenav_conditions_search_results.c b/src/pokenav_conditions_search_results.c new file mode 100644 index 000000000..d9bd2273f --- /dev/null +++ b/src/pokenav_conditions_search_results.c @@ -0,0 +1,734 @@ +#include "global.h" +#include "pokenav.h" +#include "bg.h" +#include "menu.h" +#include "window.h" +#include "sound.h" +#include "dynamic_placeholder_text_util.h" +#include "strings.h" +#include "string_util.h" +#include "international_string_util.h" +#include "constants/songs.h" + +enum +{ + CONDITION_SEARCH_FUNC_NONE, + CONDITION_SEARCH_FUNC_MOVE_UP, + CONDITION_SEARCH_FUNC_MOVE_DOWN, + CONDITION_SEARCH_FUNC_PAGE_UP, + CONDITION_SEARCH_FUNC_PAGE_DOWN, + CONDITION_SEARCH_FUNC_EXIT, + CONDITION_SEARCH_FUNC_SELECT_MON, +}; + +struct Pokenav_SearchResults +{ + u32 (*callback)(struct Pokenav_SearchResults *); + u32 loopedTaskId; + u8 fill1[4]; + s32 boxId; + s32 monId; + u32 conditionDataId; + bool32 returnFromGraph; + bool32 saveResultsList; + struct PokenavSub18 *monList; +}; + +struct Pokenav_SearchResultsGfx +{ + bool32 (*callback)(void); + u32 loopedTaskId; + u16 winid; + bool32 fromGraph; + u8 buff[BG_SCREEN_SIZE]; +}; // size: 0x810 + +static u32 HandleConditionSearchInput_WaitSetup(struct Pokenav_SearchResults *); +static u32 HandleConditionSearchInput(struct Pokenav_SearchResults *); +static u32 OpenConditionGraphFromSearchList(struct Pokenav_SearchResults *); +static u32 ReturnToConditionSearchList(struct Pokenav_SearchResults *); +static u32 GetConditionSearchLoopedTask(s32); +static u32 BuildPartyMonSearchResults(s32); +static u32 InitBoxMonSearchResults(s32); +static u32 BuildBoxMonSearchResults(s32); +static u32 ConvertConditionsToListRanks(s32); +static u32 LoopedTask_MoveSearchListCursorUp(s32); +static u32 LoopedTask_MoveSearchListCursorDown(s32); +static u32 LoopedTask_MoveSearchListPageUp(s32); +static u32 LoopedTask_MoveSearchListPageDown(s32); +static u32 LoopedTask_ExitConditionSearchMenu(s32); +static u32 LoopedTask_SelectSearchResult(s32); +static void InsertMonListItem(struct Pokenav_SearchResults *, struct PokenavMonList *); +static bool32 GetSearchResultCurrentLoopedTaskActive(void); +static u32 LoopedTask_OpenConditionSearchResults(s32); +static void AddSearchResultListMenuWindow(struct Pokenav_SearchResultsGfx *); +static void PrintSearchResultListMenuItems(struct Pokenav_SearchResultsGfx *); +static void InitConditionSearchListMenuTemplate(void); +static void PrintSearchMonListItem(struct PokenavMonList *, u8 *); + +static const u32 sSearchMonDataIds[] = {MON_DATA_COOL, MON_DATA_BEAUTY, MON_DATA_CUTE, MON_DATA_SMART, MON_DATA_TOUGH}; + +static const LoopedTask sConditionSearchLoopedTaskFuncs[] = +{ + BuildPartyMonSearchResults, + InitBoxMonSearchResults, + BuildBoxMonSearchResults, + ConvertConditionsToListRanks +}; + +static const u16 sConditionSearchResultFramePal[] = INCBIN_U16("graphics/pokenav/condition/search_results.gbapal"); +static const u32 sConditionSearchResultTiles[] = INCBIN_U32("graphics/pokenav/condition/search_results.4bpp.lz"); +static const u32 sConditionSearchResultTilemap[] = INCBIN_U32("graphics/pokenav/condition/search_results.bin.lz"); +static const u16 sListBg_Pal[] = INCBIN_U16("graphics/pokenav/condition/search_results_list.gbapal"); + +static const struct BgTemplate sConditionSearchResultBgTemplates[] = +{ + { + .bg = 1, + .charBaseIndex = 1, + .mapBaseIndex = 0x06, + .screenSize = 0, + .paletteMode = 0, + .priority = 2, + .baseTile = 0 + }, { + .bg = 2, + .charBaseIndex = 2, + .mapBaseIndex = 0x07, + .screenSize = 0, + .paletteMode = 0, + .priority = 3, + .baseTile = 0 + } +}; + +static const LoopedTask sSearchResultLoopTaskFuncs[] = +{ + [CONDITION_SEARCH_FUNC_NONE] = NULL, + [CONDITION_SEARCH_FUNC_MOVE_UP] = LoopedTask_MoveSearchListCursorUp, + [CONDITION_SEARCH_FUNC_MOVE_DOWN] = LoopedTask_MoveSearchListCursorDown, + [CONDITION_SEARCH_FUNC_PAGE_UP] = LoopedTask_MoveSearchListPageUp, + [CONDITION_SEARCH_FUNC_PAGE_DOWN] = LoopedTask_MoveSearchListPageDown, + [CONDITION_SEARCH_FUNC_EXIT] = LoopedTask_ExitConditionSearchMenu, + [CONDITION_SEARCH_FUNC_SELECT_MON] = LoopedTask_SelectSearchResult +}; + +static const struct WindowTemplate sSearchResultListMenuWindowTemplate = +{ + .bg = 1, + .tilemapLeft = 1, + .tilemapTop = 6, + .width = 7, + .height = 2, + .paletteNum = 1, + .baseBlock = 20 +}; + +static const u8 sText_MaleSymbol[] = _("{COLOR_HIGHLIGHT_SHADOW}{LIGHT_RED}{WHITE}{GREEN}♂{COLOR_HIGHLIGHT_SHADOW}{DARK_GRAY}{WHITE}{LIGHT_GRAY}"); +static const u8 sText_FemaleSymbol[] = _("{COLOR_HIGHLIGHT_SHADOW}{LIGHT_GREEN}{WHITE}{BLUE}♀{COLOR_HIGHLIGHT_SHADOW}{DARK_GRAY}{WHITE}{LIGHT_GRAY}"); +static const u8 sText_NoGenderSymbol[] = _("{UNK_SPACER}"); + +bool32 PokenavCallback_Init_ConditionSearch(void) +{ + struct Pokenav_SearchResults *menu = AllocSubstruct(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS, sizeof(struct Pokenav_SearchResults)); + if (menu == NULL) + return FALSE; + + menu->monList = AllocSubstruct(POKENAV_SUBSTRUCT_MON_LIST, sizeof(struct PokenavSub18)); + if (menu->monList == NULL) + return FALSE; + + menu->callback = HandleConditionSearchInput_WaitSetup; + menu->loopedTaskId = CreateLoopedTask(GetConditionSearchLoopedTask, 1); + menu->returnFromGraph = FALSE; + menu->conditionDataId = sSearchMonDataIds[GetSelectedConditionSearch()]; + return TRUE; +} + +// return to search results from condition graph +bool32 PokenavCallback_Init_ReturnToMonSearchList(void) +{ + struct Pokenav_SearchResults *menu = AllocSubstruct(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS, sizeof(struct Pokenav_SearchResults)); + if (menu == NULL) + return FALSE; + + menu->monList = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST); + menu->callback = HandleConditionSearchInput; + menu->returnFromGraph = TRUE; + menu->conditionDataId = sSearchMonDataIds[GetSelectedConditionSearch()]; + return TRUE; +} + +u32 GetConditionSearchResultsCallback(void) +{ + struct Pokenav_SearchResults *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); + return menu->callback(menu); +} + +void FreeSearchResultSubstruct1(void) +{ + struct Pokenav_SearchResults *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); + if (!menu->saveResultsList) + FreePokenavSubstruct(POKENAV_SUBSTRUCT_MON_LIST); + FreePokenavSubstruct(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); +} + +static bool32 HandleConditionSearchInput_WaitSetup(struct Pokenav_SearchResults *menu) +{ + if (!IsLoopedTaskActive(menu->loopedTaskId)) + menu->callback = HandleConditionSearchInput; + return FALSE; +} + +static u32 HandleConditionSearchInput(struct Pokenav_SearchResults *menu) +{ + if (JOY_REPEAT(DPAD_UP)) + return CONDITION_SEARCH_FUNC_MOVE_UP; + else if (JOY_REPEAT(DPAD_DOWN)) + return CONDITION_SEARCH_FUNC_MOVE_DOWN; + else if (JOY_NEW(DPAD_LEFT)) + return CONDITION_SEARCH_FUNC_PAGE_UP; + else if (JOY_NEW(DPAD_RIGHT)) + return CONDITION_SEARCH_FUNC_PAGE_DOWN; + else if (JOY_NEW(B_BUTTON)) + { + // Exiting back to main search menu + menu->saveResultsList = FALSE; + menu->callback = ReturnToConditionSearchList; + return CONDITION_SEARCH_FUNC_EXIT; + } + else if (JOY_NEW(A_BUTTON)) + { + // Entering graph menu + menu->monList->currIndex = GetSelectedPokenavListIndex(); + menu->saveResultsList = TRUE; + menu->callback = OpenConditionGraphFromSearchList; + return CONDITION_SEARCH_FUNC_SELECT_MON; + } + else + return CONDITION_SEARCH_FUNC_NONE; +} + +static u32 ReturnToConditionSearchList(struct Pokenav_SearchResults *menu) +{ + return POKENAV_CONDITION_SEARCH_MENU; +} + +static u32 OpenConditionGraphFromSearchList(struct Pokenav_SearchResults *menu) +{ + return POKENAV_CONDITION_GRAPH_SEARCH; +} + +static u32 GetReturningFromGraph(void) +{ + struct Pokenav_SearchResults *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); + return menu->returnFromGraph; +} + +static struct PokenavMonList * GetSearchResultsMonDataList(void) +{ + struct Pokenav_SearchResults * menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); + return menu->monList->monData; +} + +static u16 GetSearchResultsMonListCount(void) +{ + struct Pokenav_SearchResults * menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); + return menu->monList->listCount; +} + +// data below has been set by ConvertConditionsToListRanks +static s32 GetSearchResultsSelectedMonRank(void) +{ + struct Pokenav_SearchResults * menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); + s32 i = GetSelectedPokenavListIndex(); + return menu->monList->monData[i].data; +} + +static u16 GetSearchResultsCurrentListIndex(void) +{ + struct Pokenav_SearchResults * menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); + return menu->monList->currIndex; +} + +static u32 GetConditionSearchLoopedTask(s32 state) +{ + return sConditionSearchLoopedTaskFuncs[state](state); +} + +static u32 BuildPartyMonSearchResults(s32 state) +{ + s32 i; + struct PokenavMonList item; + struct Pokenav_SearchResults * menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); + + menu->monList->listCount = 0; + menu->monList->currIndex = 0; + item.boxId = TOTAL_BOXES_COUNT; + for (i = 0; i < PARTY_SIZE; i++) + { + struct Pokemon * pokemon = &gPlayerParty[i]; + if (!GetMonData(pokemon, MON_DATA_SANITY_HAS_SPECIES)) + return LT_INC_AND_CONTINUE; + if (!GetMonData(pokemon, MON_DATA_SANITY_IS_EGG)) + { + item.monId = i; + item.data = GetMonData(pokemon, menu->conditionDataId); + InsertMonListItem(menu, &item); + } + } + + return LT_INC_AND_CONTINUE; +} + +static u32 InitBoxMonSearchResults(s32 state) +{ + struct Pokenav_SearchResults * menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); + menu->monId = 0; + menu->boxId = 0; + return LT_INC_AND_CONTINUE; +} + +static u32 BuildBoxMonSearchResults(s32 state) +{ + struct Pokenav_SearchResults * menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); + s32 boxId = menu->boxId; + s32 monId = menu->monId; + s32 boxCount = 0; + struct PokenavMonList item; + + while (boxId < TOTAL_BOXES_COUNT) + { + while (monId < IN_BOX_COUNT) + { + if (CheckBoxMonSanityAt(boxId, monId)) + { + item.boxId = boxId; + item.monId = monId; + item.data = GetBoxMonDataAt(boxId, monId, menu->conditionDataId); + InsertMonListItem(menu, &item); + } + boxCount++; + monId++; + if (boxCount > TOTAL_BOXES_COUNT) + { + menu->boxId = boxId; + menu->monId = monId; + return LT_CONTINUE; + } + } + monId = 0; + boxId++; + } + + return LT_INC_AND_CONTINUE; +} + +// Data below is initially set by BuildPartyMonSearchResults / BuildBoxMonSearchResults, and +// is the Pokémon's condition value for the condition they are sorted by. +// The condition value in data is then overwritten with their ranking. +static u32 ConvertConditionsToListRanks(s32 state) +{ + struct Pokenav_SearchResults * menu = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS); + s32 listCount = menu->monList->listCount; + s32 prevCondition = menu->monList->monData[0].data; + s32 i; + menu->monList->monData[0].data = 1; + for (i = 1; i < listCount; i++) + { + if (menu->monList->monData[i].data == prevCondition) + { + // Same condition value as prev, share rank + menu->monList->monData[i].data = menu->monList->monData[i - 1].data; + } + else + { + prevCondition = menu->monList->monData[i].data; + menu->monList->monData[i].data = i + 1; + } + } + menu->returnFromGraph = TRUE; + return LT_FINISH; +} + +static void InsertMonListItem(struct Pokenav_SearchResults *menu, struct PokenavMonList *item) +{ + u32 left = 0; + u32 right = menu->monList->listCount; + u32 insertionIdx = left + (right - left) / 2; + + while (right != insertionIdx) + { + if (item->data > menu->monList->monData[insertionIdx].data) + right = insertionIdx; + else + left = insertionIdx + 1; + insertionIdx = left + (right - left) / 2; + } + for (right = menu->monList->listCount; right > insertionIdx; right--) + menu->monList->monData[right] = menu->monList->monData[right - 1]; + menu->monList->monData[insertionIdx] = *item; + menu->monList->listCount++; +} + +bool32 OpenConditionSearchResults(void) +{ + struct Pokenav_SearchResultsGfx *gfx = AllocSubstruct(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX, sizeof(struct Pokenav_SearchResultsGfx)); + if (gfx == NULL) + return FALSE; + gfx->loopedTaskId = CreateLoopedTask(LoopedTask_OpenConditionSearchResults, 1); + gfx->callback = GetSearchResultCurrentLoopedTaskActive; + gfx->fromGraph = FALSE; + return TRUE; +} + +bool32 OpenConditionSearchListFromGraph(void) +{ + struct Pokenav_SearchResultsGfx *gfx = AllocSubstruct(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX, sizeof(struct Pokenav_SearchResultsGfx)); + if (gfx == NULL) + return FALSE; + gfx->loopedTaskId = CreateLoopedTask(LoopedTask_OpenConditionSearchResults, 1); + gfx->callback = GetSearchResultCurrentLoopedTaskActive; + gfx->fromGraph = TRUE; + return TRUE; +} + +void CreateSearchResultsLoopedTask(s32 idx) +{ + struct Pokenav_SearchResultsGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX); + gfx->loopedTaskId = CreateLoopedTask(sSearchResultLoopTaskFuncs[idx], 1); + gfx->callback = GetSearchResultCurrentLoopedTaskActive; +} + +bool32 IsSearchResultLoopedTaskActive(void) +{ + struct Pokenav_SearchResultsGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX); + return gfx->callback(); +} + +bool32 GetSearchResultCurrentLoopedTaskActive(void) +{ + struct Pokenav_SearchResultsGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX); + return IsLoopedTaskActive(gfx->loopedTaskId); +} + +void FreeSearchResultSubstruct2(void) +{ + struct Pokenav_SearchResultsGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX); + sub_81C8234(); + RemoveWindow(gfx->winid); + FreePokenavSubstruct(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX); +} + +static u32 LoopedTask_OpenConditionSearchResults(s32 state) +{ + struct Pokenav_SearchResultsGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX); + switch (state) + { + case 0: + InitBgTemplates(sConditionSearchResultBgTemplates, ARRAY_COUNT(sConditionSearchResultBgTemplates)); + DecompressAndCopyTileDataToVram(1, sConditionSearchResultTiles, 0, 0, 0); + SetBgTilemapBuffer(1, gfx->buff); + CopyToBgTilemapBuffer(1, sConditionSearchResultTilemap, 0, 0); + CopyBgTilemapBufferToVram(1); + CopyPaletteIntoBufferUnfaded(sConditionSearchResultFramePal, 0x10, 0x20); + CopyBgTilemapBufferToVram(1); + return LT_INC_AND_PAUSE; + case 1: + if (FreeTempTileDataBuffersIfPossible()) + return LT_PAUSE; + if (!GetReturningFromGraph()) + return LT_PAUSE; + return LT_INC_AND_PAUSE; + case 2: + if (FreeTempTileDataBuffersIfPossible()) + return LT_PAUSE; + CopyPaletteIntoBufferUnfaded(sListBg_Pal, 0x20, 32); + InitConditionSearchListMenuTemplate(); + return LT_INC_AND_PAUSE; + case 3: + if (sub_81C8224()) + return LT_PAUSE; + AddSearchResultListMenuWindow(gfx); + PrintHelpBarText(HELPBAR_CONDITION_MON_LIST); + return LT_INC_AND_PAUSE; + case 4: + if (FreeTempTileDataBuffersIfPossible()) + return LT_PAUSE; + ChangeBgX(1, 0, BG_COORD_SET); + ChangeBgY(1, 0, BG_COORD_SET); + ShowBg(1); + ShowBg(2); + HideBg(3); + if (!gfx->fromGraph) + { + u8 searchGfxId = GetSelectedConditionSearch() + POKENAV_MENUITEM_CONDITION_SEARCH_COOL; + LoadLeftHeaderGfxForIndex(searchGfxId); + ShowLeftHeaderGfx(searchGfxId, 1, 0); + ShowLeftHeaderGfx(POKENAV_GFX_CONDITION_MENU, 1, 0); + } + PokenavFadeScreen(1); + return LT_INC_AND_PAUSE; + case 5: + if (IsPaletteFadeActive()) + return LT_PAUSE; + if (AreLeftHeaderSpritesMoving()) + return LT_PAUSE; + break; + } + return LT_FINISH; +} + +static u32 LoopedTask_MoveSearchListCursorUp(s32 state) +{ + struct Pokenav_SearchResultsGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX); + switch (state) + { + case 0: + switch (MatchCall_MoveCursorUp()) + { + case 0: + return LT_FINISH; + case 1: + PlaySE(SE_SELECT); + return LT_SET_STATE(2); + case 2: + PlaySE(SE_SELECT); + break; + } + return LT_INC_AND_PAUSE; + case 1: + if (IsMonListLoopedTaskActive()) + return LT_PAUSE; + // fallthrough + case 2: + PrintSearchResultListMenuItems(gfx); + return LT_INC_AND_PAUSE; + case 3: + if (IsDma3ManagerBusyWithBgCopy()) + return LT_PAUSE; + break; + } + return LT_FINISH; +} + +static u32 LoopedTask_MoveSearchListCursorDown(s32 state) +{ + struct Pokenav_SearchResultsGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX); + switch (state) + { + case 0: + switch (MatchCall_MoveCursorDown()) + { + case 0: + return LT_FINISH; + case 1: + PlaySE(SE_SELECT); + return LT_SET_STATE(2); + case 2: + PlaySE(SE_SELECT); + break; + } + return LT_INC_AND_PAUSE; + case 1: + if (IsMonListLoopedTaskActive()) + return LT_PAUSE; + // fallthrough + case 2: + PrintSearchResultListMenuItems(gfx); + return LT_INC_AND_PAUSE; + case 3: + if (IsDma3ManagerBusyWithBgCopy()) + return LT_PAUSE; + break; + } + return LT_FINISH; +} + +static u32 LoopedTask_MoveSearchListPageUp(s32 state) +{ + struct Pokenav_SearchResultsGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX); + switch (state) + { + case 0: + switch (MatchCall_PageUp()) + { + case 0: + return LT_FINISH; + case 1: + PlaySE(SE_SELECT); + return LT_SET_STATE(2); + case 2: + PlaySE(SE_SELECT); + break; + } + return LT_INC_AND_PAUSE; + case 1: + if (IsMonListLoopedTaskActive()) + return LT_PAUSE; + // fallthrough + case 2: + PrintSearchResultListMenuItems(gfx); + return LT_INC_AND_PAUSE; + case 3: + if (IsDma3ManagerBusyWithBgCopy()) + return LT_PAUSE; + break; + } + return LT_FINISH; +} + +static u32 LoopedTask_MoveSearchListPageDown(s32 state) +{ + struct Pokenav_SearchResultsGfx *gfx = GetSubstructPtr(POKENAV_SUBSTRUCT_CONDITION_SEARCH_RESULTS_GFX); + switch (state) + { + case 0: + switch (MatchCall_PageDown()) + { + case 0: + return LT_FINISH; + case 1: + PlaySE(SE_SELECT); + return LT_SET_STATE(2); + case 2: + PlaySE(SE_SELECT); + break; + } + return LT_INC_AND_PAUSE; + case 1: + if (IsMonListLoopedTaskActive()) + return LT_PAUSE; + // fallthrough + case 2: + PrintSearchResultListMenuItems(gfx); + return LT_INC_AND_PAUSE; + case 3: + if (IsDma3ManagerBusyWithBgCopy()) + return LT_PAUSE; + break; + } + return LT_FINISH; +} + +static u32 LoopedTask_ExitConditionSearchMenu(s32 state) +{ + switch (state) + { + case 0: + PlaySE(SE_SELECT); + PokenavFadeScreen(0); + SlideMenuHeaderDown(); + return LT_INC_AND_PAUSE; + case 1: + if (IsPaletteFadeActive()) + return LT_PAUSE; + if (MainMenuLoopedTaskIsBusy()) + return LT_PAUSE; + SetLeftHeaderSpritesInvisibility(); + break; + } + return LT_FINISH; +} + +static u32 LoopedTask_SelectSearchResult(s32 state) +{ + switch (state) + { + case 0: + PlaySE(SE_SELECT); + PokenavFadeScreen(0); + return LT_INC_AND_PAUSE; + case 1: + if (IsPaletteFadeActive()) + return LT_PAUSE; + break; + } + return LT_FINISH; +} + +static void AddSearchResultListMenuWindow(struct Pokenav_SearchResultsGfx *gfx) +{ + gfx->winid = AddWindow(&sSearchResultListMenuWindowTemplate); + PutWindowTilemap(gfx->winid); + CopyWindowToVram(gfx->winid, COPYWIN_MAP); + PrintSearchResultListMenuItems(gfx); +} + +static void PrintSearchResultListMenuItems(struct Pokenav_SearchResultsGfx *gfx) +{ + s32 rank = GetSearchResultsSelectedMonRank(); + DynamicPlaceholderTextUtil_Reset(); + DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, gStringVar1); + *gStringVar1 = EOS; + DynamicPlaceholderTextUtil_ExpandPlaceholders(gStringVar2, gText_NumberIndex); + AddTextPrinterParameterized(gfx->winid, FONT_NORMAL, gStringVar2, 4, 1, TEXT_SKIP_DRAW, NULL); + ConvertIntToDecimalStringN(gStringVar1, rank, STR_CONV_MODE_RIGHT_ALIGN, 3); + AddTextPrinterParameterized(gfx->winid, FONT_NORMAL, gStringVar1, 34, 1, TEXT_SKIP_DRAW, NULL); + CopyWindowToVram(gfx->winid, COPYWIN_GFX); +} + +static void InitConditionSearchListMenuTemplate(void) +{ + struct PokenavListTemplate template; + + template.list.monList = GetSearchResultsMonDataList(); + template.count = GetSearchResultsMonListCount(); + template.unk8 = 4; + template.unk6 = GetSearchResultsCurrentListIndex(); + template.item_X = 13; + template.windowWidth = 17; + template.listTop = 1; + template.maxShowed = 8; + template.fillValue = 2; + template.fontId = FONT_NORMAL; + template.listFunc.printMonFunc = PrintSearchMonListItem; + template.unk14 = NULL; + sub_81C81D4(&sConditionSearchResultBgTemplates[1], &template, 0); +} + +static void PrintSearchMonListItem(struct PokenavMonList * item, u8 * dest) +{ + u8 gender; + u8 level; + u8 * s; + const u8 * genderStr; + + // Mon is in party + if (item->boxId == TOTAL_BOXES_COUNT) + { + struct Pokemon * mon = &gPlayerParty[item->monId]; + gender = GetMonGender(mon); + level = GetLevelFromMonExp(mon); + GetMonData(mon, MON_DATA_NICKNAME, gStringVar3); + } + // Mon is in PC + else + { + struct BoxPokemon * mon = GetBoxedMonPtr(item->boxId, item->monId); + gender = GetBoxMonGender(mon); + level = GetLevelFromBoxMonExp(mon); + GetBoxMonData(mon, MON_DATA_NICKNAME, gStringVar3); + } + + StringGetEnd10(gStringVar3); + dest = GetStringClearToWidth(dest, FONT_NORMAL, gStringVar3, 60); + switch (gender) + { + default: + genderStr = sText_NoGenderSymbol; + break; + case MON_MALE: + genderStr = sText_MaleSymbol; + break; + case MON_FEMALE: + genderStr = sText_FemaleSymbol; + break; + } + s = StringCopy(gStringVar1, genderStr); + *s++ = CHAR_SLASH; + *s++ = CHAR_EXTRA_SYMBOL; + *s++ = CHAR_LV_2; + ConvertIntToDecimalStringN(s, level, STR_CONV_MODE_LEFT_ALIGN, 3); + GetStringClearToWidth(dest, FONT_NORMAL, gStringVar1, 40); +} diff --git a/sym_bss.txt b/sym_bss.txt index 8724f02d7..75da960bf 100644 --- a/sym_bss.txt +++ b/sym_bss.txt @@ -50,7 +50,7 @@ .include "src/multiboot.o" .include "src/mirage_tower.o" .include "src/berry_fix_program.o" - .include "src/pokenav_conditions_2.o" + .include "src/pokenav_conditions_gfx.o" .include "src/pokenav_ribbons_summary.o" .include "src/ereader_helpers.o" .include "src/faraway_island.o" -- cgit v1.2.3