summaryrefslogtreecommitdiff
path: root/src/pokenav_conditions_gfx.c
diff options
context:
space:
mode:
authorGriffinR <griffin.g.richards@gmail.com>2021-11-12 11:07:52 -0500
committerGriffinR <griffin.g.richards@gmail.com>2021-11-12 11:07:52 -0500
commit35aeff1b6df8efc4e088bd20c71e4243b95c6599 (patch)
tree73b1fcc5f06730fb25ee578520393d77edd50143 /src/pokenav_conditions_gfx.c
parentf5152094a9521222e64f003785662295ad8931e7 (diff)
Rename pokenav conditions files
Diffstat (limited to 'src/pokenav_conditions_gfx.c')
-rw-r--r--src/pokenav_conditions_gfx.c892
1 files changed, 892 insertions, 0 deletions
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;
+}