From c779d03b3e9032254bbd7a08f4c9203e14373933 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 15 Nov 2021 00:21:40 -0500 Subject: Rename pokenav_match_call_ui --- src/pokenav_list.c | 1011 +++++++++++++++++++++++++++++++++++++++++++ src/pokenav_match_call_ui.c | 1011 ------------------------------------------- 2 files changed, 1011 insertions(+), 1011 deletions(-) create mode 100644 src/pokenav_list.c delete mode 100644 src/pokenav_match_call_ui.c (limited to 'src') diff --git a/src/pokenav_list.c b/src/pokenav_list.c new file mode 100644 index 000000000..bdba1d2c0 --- /dev/null +++ b/src/pokenav_list.c @@ -0,0 +1,1011 @@ +#include "global.h" +#include "pokenav.h" +#include "window.h" +#include "strings.h" +#include "text.h" +#include "bg.h" +#include "menu.h" +#include "decompress.h" +#include "international_string_util.h" + +#define GFXTAG_ARROW 10 +#define PALTAG_ARROW 20 + +struct PokenavListMenuWindow { + u8 bg; + u8 fillValue; + u8 x; + u8 y; + u8 width; + u8 fontId; + u16 tileOffset; + u16 windowId; + u16 unkA; + u16 numPrinted; + u16 numToPrint; +}; + +struct PokenavListWindowState { + // The index of the element at the top of the window. + u16 windowTopIndex; + u16 listLength; + u16 entriesOffscreen; + // The index of the cursor, relative to the top of the window. + u16 selectedIndexOffset; + u16 entriesOnscreen; + u32 listItemSize; + void * listPtr; +}; + +struct PokenavListSub +{ + struct PokenavListMenuWindow listWindow; + u32 unk10; + u32 printIndex; + u32 itemSize; + void * listPtr; + s32 startBgY; + s32 endBgY; + u32 loopedTaskId; + s32 moveDelta; + u32 bgMoveType; + PokenavListBufferItemFunc bufferItemFunc; + void (*iconDrawFunc)(u16, u32, u32); + struct Sprite *rightArrow; + struct Sprite *upArrow; + struct Sprite *downArrow; + u8 itemTextBuffer[64]; +}; + +struct PokenavList +{ + struct PokenavListSub list; + u8 tilemapBuffer[BG_SCREEN_SIZE]; + struct PokenavListWindowState windowState; + s32 eraseIndex; + u32 loopedTaskId; +}; + +static void InitPokenavListBg(struct PokenavList *); +static bool32 CopyPokenavListMenuTemplate(struct PokenavListSub *, const struct BgTemplate *, struct PokenavListTemplate *, s32); +static void InitPokenavListWindowState(struct PokenavListWindowState *, struct PokenavListTemplate *); +static void SpriteCB_UpArrow(struct Sprite *); +static void SpriteCB_DownArrow(struct Sprite *); +static void SpriteCB_RightArrow(struct Sprite *); +static void ToggleListArrows(struct PokenavListSub *, u32); +static void DestroyListArrows(struct PokenavListSub *); +static void CreateListArrowSprites(struct PokenavListWindowState *, struct PokenavListSub *); +static void LoadListArrowGfx(void); +static void PrintMatchCallFlavorText(struct PokenavListWindowState *, struct PokenavListSub *, u32); +static void PrintMatchCallFieldNames(struct PokenavListSub *, u32); +static void PrintMatchCallListTrainerName(struct PokenavListWindowState *, struct PokenavListSub *); +static void PrintCheckPageTrainerName(struct PokenavListWindowState *, struct PokenavListSub *); +static void EraseListEntry(struct PokenavListMenuWindow *, s32, s32); +static void CreateMoveListWindowTask(s32, struct PokenavListSub *); +static void PrintListItems(void *, u32, u32, u32, u32, struct PokenavListSub *); +static void InitListItems(struct PokenavListWindowState *, struct PokenavListSub *); +static void InitPokenavListWindow(struct PokenavListMenuWindow *); +static u32 LoopedTask_CreatePokenavList(s32); +static bool32 IsPrintListItemsTaskActive(void); +static u32 LoopedTask_PrintListItems(s32); +static u32 LoopedTask_MoveListWindow(s32); +static u32 LoopedTask_EraseListForCheckPage(s32); +static u32 LoopedTask_ReshowListFromCheckPage(s32); +static u32 LoopedTask_PrintCheckPageInfo(s32); + +static const u16 sListArrow_Pal[] = INCBIN_U16("graphics/pokenav/list_arrows.gbapal"); +static const u32 sListArrow_Gfx[] = INCBIN_U32("graphics/pokenav/list_arrows.4bpp.lz"); + +static EWRAM_DATA u32 sMoveWindowDownIndex = 0; // Read, but pointlessly + +bool32 CreatePokenavList(const struct BgTemplate *bgTemplate, struct PokenavListTemplate *listTemplate, s32 tileOffset) +{ + struct PokenavList *structPtr = AllocSubstruct(POKENAV_SUBSTRUCT_LIST, sizeof(struct PokenavList)); + if (structPtr == NULL) + return FALSE; + + InitPokenavListWindowState(&structPtr->windowState, listTemplate); + if (!CopyPokenavListMenuTemplate(&structPtr->list, bgTemplate, listTemplate, tileOffset)) + return FALSE; + + CreateLoopedTask(LoopedTask_CreatePokenavList, 6); + return TRUE; +} + +bool32 IsCreatePokenavListTaskActive(void) +{ + return FuncIsActiveLoopedTask(LoopedTask_CreatePokenavList); +} + +void DestroyPokenavList(void) +{ + struct PokenavList *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); + DestroyListArrows(&structPtr->list); + RemoveWindow(structPtr->list.listWindow.windowId); + FreePokenavSubstruct(POKENAV_SUBSTRUCT_LIST); +} + +static u32 LoopedTask_CreatePokenavList(s32 state) +{ + struct PokenavList *structPtr; + + if (IsDma3ManagerBusyWithBgCopy()) + return LT_PAUSE; + + structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); + + switch (state) + { + case 0: + InitPokenavListBg(structPtr); + return LT_INC_AND_PAUSE; + case 1: + InitPokenavListWindow(&structPtr->list.listWindow); + return LT_INC_AND_PAUSE; + case 2: + InitListItems(&structPtr->windowState, &structPtr->list); + return LT_INC_AND_PAUSE; + case 3: + if (IsPrintListItemsTaskActive()) + { + return LT_PAUSE; + } + else + { + LoadListArrowGfx(); + return LT_INC_AND_CONTINUE; + } + case 4: + CreateListArrowSprites(&structPtr->windowState, &structPtr->list); + return LT_FINISH; + default: + return LT_FINISH; + } +} + +static void InitPokenavListBg(struct PokenavList *a0) +{ + u16 tileNum = (a0->list.listWindow.fillValue << 12) | a0->list.listWindow.tileOffset; + BgDmaFill(a0->list.listWindow.bg, PIXEL_FILL(1), a0->list.listWindow.tileOffset, 1); + BgDmaFill(a0->list.listWindow.bg, PIXEL_FILL(4), a0->list.listWindow.tileOffset + 1, 1); + SetBgTilemapBuffer(a0->list.listWindow.bg, a0->tilemapBuffer); + FillBgTilemapBufferRect_Palette0(a0->list.listWindow.bg, tileNum, 0, 0, 32, 32); + ChangeBgY(a0->list.listWindow.bg, 0, BG_COORD_SET); + ChangeBgX(a0->list.listWindow.bg, 0, BG_COORD_SET); + ChangeBgY(a0->list.listWindow.bg, a0->list.listWindow.y << 11, BG_COORD_SUB); + CopyBgTilemapBufferToVram(a0->list.listWindow.bg); +} + +static void InitPokenavListWindow(struct PokenavListMenuWindow *listWindow) +{ + FillWindowPixelBuffer(listWindow->windowId, PIXEL_FILL(1)); + PutWindowTilemap(listWindow->windowId); + CopyWindowToVram(listWindow->windowId, COPYWIN_MAP); +} + +static void InitListItems(struct PokenavListWindowState *windowState, struct PokenavListSub *a1) +{ + s32 numToPrint = windowState->listLength - windowState->windowTopIndex; + if (numToPrint > windowState->entriesOnscreen) + numToPrint = windowState->entriesOnscreen; + + PrintListItems(windowState->listPtr, windowState->windowTopIndex, numToPrint, windowState->listItemSize, 0, a1); +} + +static void PrintListItems(void * listPtr, u32 topIndex, u32 numItems, u32 itemSize, u32 a4, struct PokenavListSub *list) +{ + if (numItems == 0) + return; + + list->listPtr = listPtr + topIndex * itemSize; + list->itemSize = itemSize; + list->listWindow.numPrinted = 0; + list->listWindow.numToPrint = numItems; + list->printIndex = topIndex; + list->unk10 = a4; + CreateLoopedTask(LoopedTask_PrintListItems, 5); +} + +static bool32 IsPrintListItemsTaskActive(void) +{ + return FuncIsActiveLoopedTask(LoopedTask_PrintListItems); +} + +static u32 LoopedTask_PrintListItems(s32 state) +{ + u32 row; + struct PokenavListSub *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); + + switch (state) + { + case 0: + row = (structPtr->listWindow.unkA + structPtr->listWindow.numPrinted + structPtr->unk10) & 0xF; + structPtr->bufferItemFunc(structPtr->listPtr, structPtr->itemTextBuffer); + if (structPtr->iconDrawFunc != NULL) + structPtr->iconDrawFunc(structPtr->listWindow.windowId, structPtr->printIndex, row); + + AddTextPrinterParameterized(structPtr->listWindow.windowId, structPtr->listWindow.fontId, structPtr->itemTextBuffer, 8, (row << 4) + 1, TEXT_SKIP_DRAW, NULL); + if (++structPtr->listWindow.numPrinted >= structPtr->listWindow.numToPrint) + { + // Finished printing items. If icons were being drawn, draw the + // window tilemap and graphics. Otherwise just do the graphics + if (structPtr->iconDrawFunc != NULL) + CopyWindowToVram(structPtr->listWindow.windowId, COPYWIN_FULL); + else + CopyWindowToVram(structPtr->listWindow.windowId, COPYWIN_GFX); + return LT_INC_AND_PAUSE; + } + else + { + structPtr->listPtr += structPtr->itemSize; + structPtr->printIndex++; + return LT_CONTINUE; + } + case 1: + if (IsDma3ManagerBusyWithBgCopy()) + return LT_PAUSE; + return LT_FINISH; + } + return LT_FINISH; +} + +static bool32 ShouldShowUpArrow(void) +{ + struct PokenavList *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); + + return (structPtr->windowState.windowTopIndex != 0); +} + +static bool32 ShouldShowDownArrow(void) +{ + struct PokenavList *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); + struct PokenavListWindowState *subPtr = &structPtr->windowState; + + return (subPtr->windowTopIndex + subPtr->entriesOnscreen < subPtr->listLength); +} + +static void MoveListWindow(s32 delta, bool32 printItems) +{ + struct PokenavList *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); + struct PokenavListWindowState *subPtr = &structPtr->windowState; + + if (delta < 0) + { + if (subPtr->windowTopIndex + delta < 0) + delta = -1 * subPtr->windowTopIndex; + if (printItems) + PrintListItems(subPtr->listPtr, subPtr->windowTopIndex + delta, delta * -1, subPtr->listItemSize, delta, &structPtr->list); + } + else if (printItems) + { + s32 index = sMoveWindowDownIndex = subPtr->windowTopIndex + subPtr->entriesOnscreen; + if (index + delta >= subPtr->listLength) + delta = subPtr->listLength - index; + + PrintListItems(subPtr->listPtr, index, delta, subPtr->listItemSize, subPtr->entriesOnscreen, &structPtr->list); + } + + CreateMoveListWindowTask(delta, &structPtr->list); + subPtr->windowTopIndex += delta; +} + +static void CreateMoveListWindowTask(s32 delta, struct PokenavListSub *list) +{ + list->startBgY = GetBgY(list->listWindow.bg); + list->endBgY = list->startBgY + (delta << 12); + if (delta > 0) + list->bgMoveType = BG_COORD_ADD; + else + list->bgMoveType = BG_COORD_SUB; + list->moveDelta = delta; + list->loopedTaskId = CreateLoopedTask(LoopedTask_MoveListWindow, 6); +} + +static u32 LoopedTask_MoveListWindow(s32 state) +{ + s32 oldY, newY; + bool32 finished; + struct PokenavList *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); + struct PokenavListSub *subPtr = &structPtr->list; + + switch (state) + { + case 0: + if (!IsPrintListItemsTaskActive()) + return LT_INC_AND_CONTINUE; + return LT_PAUSE; + case 1: + finished = FALSE; + oldY = GetBgY(subPtr->listWindow.bg); + newY = ChangeBgY(subPtr->listWindow.bg, 0x1000, subPtr->bgMoveType); + if (subPtr->bgMoveType == BG_COORD_SUB) + { + if ((oldY > subPtr->endBgY || oldY <= subPtr->startBgY) && newY <= subPtr->endBgY) + finished = TRUE; + } + else // BG_COORD_ADD + { + if ((oldY < subPtr->endBgY || oldY >= subPtr->startBgY) && newY >= subPtr->endBgY) + finished = TRUE; + } + + if (finished) + { + subPtr->listWindow.unkA = (subPtr->listWindow.unkA + subPtr->moveDelta) & 0xF; + ChangeBgY(subPtr->listWindow.bg, subPtr->endBgY, BG_COORD_SET); + return LT_FINISH; + } + return LT_PAUSE; + } + return LT_FINISH; +} + +bool32 PokenavList_IsMoveWindowTaskActive(void) +{ + struct PokenavList *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); + return IsLoopedTaskActive(structPtr->list.loopedTaskId); +} + +static struct PokenavListWindowState *GetPokenavListWindowState(void) +{ + struct PokenavList *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); + return &structPtr->windowState; +} + +int PokenavList_MoveCursorUp(void) +{ + struct PokenavListWindowState *structPtr = GetPokenavListWindowState(); + + if (structPtr->selectedIndexOffset != 0) + { + structPtr->selectedIndexOffset--; + return 1; + } + if (ShouldShowUpArrow()) + { + MoveListWindow(-1, TRUE); + return 2; + } + return 0; +} + +int PokenavList_MoveCursorDown(void) +{ + struct PokenavListWindowState *structPtr = GetPokenavListWindowState(); + + if (structPtr->windowTopIndex + structPtr->selectedIndexOffset >= structPtr->listLength - 1) + return 0; + if (structPtr->selectedIndexOffset < structPtr->entriesOnscreen - 1) + { + structPtr->selectedIndexOffset++; + return 1; + } + if (ShouldShowDownArrow()) + { + MoveListWindow(1, TRUE); + return 2; + } + return 0; +} + +int PokenavList_PageUp(void) +{ + s32 scroll; + struct PokenavListWindowState *structPtr = GetPokenavListWindowState(); + + if (ShouldShowUpArrow()) + { + if (structPtr->windowTopIndex >= structPtr->entriesOnscreen) + scroll = structPtr->entriesOnscreen; + else + scroll = structPtr->windowTopIndex; + MoveListWindow(scroll * -1, TRUE); + return 2; + } + else if (structPtr->selectedIndexOffset != 0) + { + structPtr->selectedIndexOffset = 0; + return 1; + } + return 0; +} + +int PokenavList_PageDown(void) +{ + struct PokenavListWindowState *structPtr = GetPokenavListWindowState(); + + if (ShouldShowDownArrow()) + { + s32 windowBottomIndex = structPtr->windowTopIndex + structPtr->entriesOnscreen; + s32 scroll = structPtr->entriesOffscreen - structPtr->windowTopIndex; + + if (windowBottomIndex <= structPtr->entriesOffscreen) + scroll = structPtr->entriesOnscreen; + MoveListWindow(scroll, TRUE); + return 2; + } + else + { + s32 cursor, lastVisibleIndex; + if (structPtr->listLength >= structPtr->entriesOnscreen) + { + cursor = structPtr->selectedIndexOffset; + lastVisibleIndex = structPtr->entriesOnscreen; + } + else + { + cursor = structPtr->selectedIndexOffset; + lastVisibleIndex = structPtr->listLength; + } + lastVisibleIndex -= 1; + if (cursor >= lastVisibleIndex) + return 0; + + structPtr->selectedIndexOffset = lastVisibleIndex; + return 1; + } +} + +u32 PokenavList_GetSelectedIndex(void) +{ + struct PokenavListWindowState *structPtr = GetPokenavListWindowState(); + + return structPtr->windowTopIndex + structPtr->selectedIndexOffset; +} + +u32 PokenavList_GetTopIndex(void) +{ + struct PokenavListWindowState *structPtr = GetPokenavListWindowState(); + + return structPtr->windowTopIndex; +} + +void PokenavList_EraseListForCheckPage(void) +{ + struct PokenavList *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); + structPtr->eraseIndex = 0; + structPtr->loopedTaskId = CreateLoopedTask(LoopedTask_EraseListForCheckPage, 6); +} + +void PrintCheckPageInfo(s16 delta) +{ + struct PokenavList *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); + structPtr->windowState.windowTopIndex += delta; + structPtr->eraseIndex = 0; + structPtr->loopedTaskId = CreateLoopedTask(LoopedTask_PrintCheckPageInfo, 6); +} + +void PokenavList_ReshowListFromCheckPage(void) +{ + struct PokenavList *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); + structPtr->eraseIndex = 0; + structPtr->loopedTaskId = CreateLoopedTask(LoopedTask_ReshowListFromCheckPage, 6); +} + +bool32 PokenavList_IsTaskActive(void) +{ + struct PokenavList *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); + return IsLoopedTaskActive(structPtr->loopedTaskId); +} + +void PokenavList_DrawCurrentItemIcon(void) +{ + struct PokenavList *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); + struct PokenavListWindowState *subPtr = &structPtr->windowState; + structPtr->list.iconDrawFunc(structPtr->list.listWindow.windowId, subPtr->windowTopIndex + subPtr->selectedIndexOffset, (structPtr->list.listWindow.unkA + subPtr->selectedIndexOffset) & 0xF); + CopyWindowToVram(structPtr->list.listWindow.windowId, COPYWIN_MAP); +} + +static u32 LoopedTask_EraseListForCheckPage(s32 state) +{ + struct PokenavList *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); + + switch (state) + { + case 0: + ToggleListArrows(&structPtr->list, 1); + // fall-through + case 1: + if (structPtr->eraseIndex != structPtr->windowState.selectedIndexOffset) + EraseListEntry(&structPtr->list.listWindow, structPtr->eraseIndex, 1); + + structPtr->eraseIndex++; + return LT_INC_AND_PAUSE; + case 2: + if (!IsDma3ManagerBusyWithBgCopy()) + { + if (structPtr->eraseIndex != structPtr->windowState.entriesOnscreen) + return LT_SET_STATE(1); + if (structPtr->windowState.selectedIndexOffset != 0) + EraseListEntry(&structPtr->list.listWindow, structPtr->eraseIndex, structPtr->windowState.selectedIndexOffset); + + return LT_INC_AND_PAUSE; + } + return LT_PAUSE; + case 3: + if (!IsDma3ManagerBusyWithBgCopy()) + { + if (structPtr->windowState.selectedIndexOffset != 0) + { + MoveListWindow(structPtr->windowState.selectedIndexOffset, FALSE); + return LT_INC_AND_PAUSE; + } + return LT_FINISH; + } + return LT_PAUSE; + case 4: + if (PokenavList_IsMoveWindowTaskActive()) + return LT_PAUSE; + + structPtr->windowState.selectedIndexOffset = 0; + return LT_FINISH; + } + return LT_FINISH; +} + +static u32 LoopedTask_PrintCheckPageInfo(s32 state) +{ + struct PokenavList *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); + if (IsDma3ManagerBusyWithBgCopy()) + return LT_PAUSE; + + switch (state) + { + case 0: + PrintCheckPageTrainerName(&structPtr->windowState, &structPtr->list); + break; + case 1: + PrintMatchCallFieldNames(&structPtr->list, 0); + break; + case 2: + PrintMatchCallFlavorText(&structPtr->windowState, &structPtr->list, CHECK_PAGE_STRATEGY); + break; + case 3: + PrintMatchCallFieldNames(&structPtr->list, 1); + break; + case 4: + PrintMatchCallFlavorText(&structPtr->windowState, &structPtr->list, CHECK_PAGE_POKEMON); + break; + case 5: + PrintMatchCallFieldNames(&structPtr->list, 2); + break; + case 6: + PrintMatchCallFlavorText(&structPtr->windowState, &structPtr->list, CHECK_PAGE_INTRO_1); + break; + case 7: + PrintMatchCallFlavorText(&structPtr->windowState, &structPtr->list, CHECK_PAGE_INTRO_2); + break; + default: + return LT_FINISH; + } + return LT_INC_AND_PAUSE; +} + +static u32 LoopedTask_ReshowListFromCheckPage(s32 state) +{ + struct PokenavList *structPtr; + struct PokenavListWindowState *windowState; + struct PokenavListSub *subPtr0; + s32 r5, *ptr; + + if (IsDma3ManagerBusyWithBgCopy()) + return LT_PAUSE; + + structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); + windowState = &structPtr->windowState; + subPtr0 = &structPtr->list; + + switch (state) + { + case 0: + // Rewrite the name of the trainer whose check page was just being viewed. + // This is done to erase the red background it had. + PrintMatchCallListTrainerName(windowState, subPtr0); + return LT_INC_AND_PAUSE; + case 1: + ptr = &structPtr->eraseIndex; + if (++(*ptr) < structPtr->windowState.entriesOnscreen) + { + EraseListEntry(&subPtr0->listWindow, *ptr, 1); + return LT_PAUSE; + } + + *ptr = 0; + if (windowState->listLength <= windowState->entriesOnscreen) + { + if (windowState->windowTopIndex != 0) + { + s32 r4 = windowState->windowTopIndex; + r5 = -r4; + EraseListEntry(&subPtr0->listWindow, r5, r4); + windowState->selectedIndexOffset = r4; + *ptr = r5; + return LT_INC_AND_PAUSE; + } + } + else + { + if (windowState->windowTopIndex + windowState->entriesOnscreen > windowState->listLength) + { + s32 r4 = windowState->windowTopIndex + windowState->entriesOnscreen - windowState->listLength; + r5 = -r4; + EraseListEntry(&subPtr0->listWindow, r5, r4); + windowState->selectedIndexOffset = r4; + *ptr = r5; + return LT_INC_AND_PAUSE; + } + } + return LT_SET_STATE(4); + case 2: + MoveListWindow(structPtr->eraseIndex, FALSE); + return LT_INC_AND_PAUSE; + case 3: + if (!PokenavList_IsMoveWindowTaskActive()) + { + structPtr->eraseIndex = 0; + return LT_INC_AND_CONTINUE; + } + return LT_PAUSE; + case 4: + PrintListItems(windowState->listPtr, windowState->windowTopIndex + structPtr->eraseIndex, 1, windowState->listItemSize, structPtr->eraseIndex, &structPtr->list); + return LT_INC_AND_PAUSE; + case 5: + if (IsPrintListItemsTaskActive()) + return LT_PAUSE; + if (++structPtr->eraseIndex >= windowState->listLength || structPtr->eraseIndex >= windowState->entriesOnscreen) + return LT_INC_AND_CONTINUE; + return LT_SET_STATE(4); + case 6: + ToggleListArrows(subPtr0, 0); + return LT_FINISH; + } + + return LT_FINISH; +} + +static void EraseListEntry(struct PokenavListMenuWindow *listWindow, s32 a1, s32 a2) +{ + u8 *tileData = (u8*)GetWindowAttribute(listWindow->windowId, WINDOW_TILE_DATA); + u32 width = listWindow->width * 64; + + a1 = (listWindow->unkA + a1) & 0xF; + if (a1 + a2 <= 16) + { + CpuFastFill8(PIXEL_FILL(1), tileData + a1 * width, a2 * width); + CopyWindowToVram(listWindow->windowId, COPYWIN_GFX); + } + else + { + u32 v3 = 16 - a1; + u32 v4 = a2 - v3; + + CpuFastFill8(PIXEL_FILL(1), tileData + a1 * width, v3 * width); + CpuFastFill8(PIXEL_FILL(1), tileData, v4 * width); + CopyWindowToVram(listWindow->windowId, COPYWIN_GFX); + } + + for (a2--; a2 != -1; a1 = (a1 + 1) & 0xF, a2--) + ClearRematchPokeballIcon(listWindow->windowId, a1); + + CopyWindowToVram(listWindow->windowId, COPYWIN_MAP); +} + +// Pointless +static void SetListMarginTile(struct PokenavListMenuWindow *listWindow, bool32 draw) +{ + u16 var; + u16 *tilemapBuffer = (u16*)GetBgTilemapBuffer(GetWindowAttribute(listWindow->windowId, WINDOW_BG)); + tilemapBuffer += (listWindow->unkA << 6) + listWindow->x - 1; + + if (draw) + var = (listWindow->fillValue << 12) | (listWindow->tileOffset + 1); + else + var = (listWindow->fillValue << 12) | (listWindow->tileOffset); + + tilemapBuffer[0] = var; + tilemapBuffer[0x20] = var; +} + +// Print the trainer's name and title at the top of their check page +static void PrintCheckPageTrainerName(struct PokenavListWindowState *state, struct PokenavListSub *list) +{ + u8 colors[3] = {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_RED}; + + list->bufferItemFunc(state->listPtr + state->listItemSize * state->windowTopIndex, list->itemTextBuffer); + list->iconDrawFunc(list->listWindow.windowId, state->windowTopIndex, list->listWindow.unkA); + FillWindowPixelRect(list->listWindow.windowId, PIXEL_FILL(4), 0, list->listWindow.unkA * 16, list->listWindow.width * 8, 16); + AddTextPrinterParameterized3(list->listWindow.windowId, list->listWindow.fontId, 8, (list->listWindow.unkA * 16) + 1, colors, TEXT_SKIP_DRAW, list->itemTextBuffer); + SetListMarginTile(&list->listWindow, TRUE); + CopyWindowRectToVram(list->listWindow.windowId, COPYWIN_FULL, 0, list->listWindow.unkA * 2, list->listWindow.width, 2); +} + +// Print the trainer's name and title for the list (to replace the check page name and title, which has a red background) +static void PrintMatchCallListTrainerName(struct PokenavListWindowState *state, struct PokenavListSub *list) +{ + list->bufferItemFunc(state->listPtr + state->listItemSize * state->windowTopIndex, list->itemTextBuffer); + FillWindowPixelRect(list->listWindow.windowId, PIXEL_FILL(1), 0, list->listWindow.unkA * 16, list->listWindow.width * 8, 16); + AddTextPrinterParameterized(list->listWindow.windowId, list->listWindow.fontId, list->itemTextBuffer, 8, list->listWindow.unkA * 16 + 1, TEXT_SKIP_DRAW, NULL); + SetListMarginTile(&list->listWindow, FALSE); + CopyWindowToVram(list->listWindow.windowId, COPYWIN_FULL); +} + +static void PrintMatchCallFieldNames(struct PokenavListSub *list, u32 fieldId) +{ + const u8 *fieldNames[] = { + gText_PokenavMatchCall_Strategy, + gText_PokenavMatchCall_TrainerPokemon, + gText_PokenavMatchCall_SelfIntroduction + }; + u8 colors[3] = {TEXT_COLOR_WHITE, TEXT_COLOR_RED, TEXT_COLOR_LIGHT_RED}; + u32 top = (list->listWindow.unkA + 1 + (fieldId * 2)) & 0xF; + + FillWindowPixelRect(list->listWindow.windowId, PIXEL_FILL(1), 0, top << 4, list->listWindow.width, 16); + AddTextPrinterParameterized3(list->listWindow.windowId, FONT_NARROW, 2, (top << 4) + 1, colors, TEXT_SKIP_DRAW, fieldNames[fieldId]); + CopyWindowRectToVram(list->listWindow.windowId, COPYWIN_GFX, 0, top << 1, list->listWindow.width, 2); +} + +static void PrintMatchCallFlavorText(struct PokenavListWindowState *a0, struct PokenavListSub *list, u32 checkPageEntry) +{ + // lines 1, 3, and 5 are the field names printed by PrintMatchCallFieldNames + static const u8 lineOffsets[CHECK_PAGE_ENTRY_COUNT] = { + [CHECK_PAGE_STRATEGY] = 2, + [CHECK_PAGE_POKEMON] = 4, + [CHECK_PAGE_INTRO_1] = 6, + [CHECK_PAGE_INTRO_2] = 7 + }; + + u32 r6 = (list->listWindow.unkA + lineOffsets[checkPageEntry]) & 0xF; + const u8 *str = GetMatchCallFlavorText(a0->windowTopIndex, checkPageEntry); + + if (str != NULL) + { + FillWindowTilesByRow(list->listWindow.windowId, 1, r6 * 2, list->listWindow.width - 1, 2); + AddTextPrinterParameterized(list->listWindow.windowId, FONT_NARROW, str, 2, (r6 << 4) + 1, TEXT_SKIP_DRAW, NULL); + CopyWindowRectToVram(list->listWindow.windowId, COPYWIN_GFX, 0, r6 * 2, list->listWindow.width, 2); + } +} + +static const struct CompressedSpriteSheet sListArrowSpriteSheets[] = +{ + { + .data = sListArrow_Gfx, + .size = 0xC0, + .tag = GFXTAG_ARROW + } +}; + +static const struct SpritePalette sListArrowPalettes[] = +{ + { + .data = sListArrow_Pal, + .tag = PALTAG_ARROW + }, + {} +}; + +static const struct OamData sOamData_RightArrow = +{ + .y = 0, + .affineMode = ST_OAM_AFFINE_OFF, + .objMode = ST_OAM_OBJ_NORMAL, + .bpp = ST_OAM_4BPP, + .shape = SPRITE_SHAPE(8x16), + .x = 0, + .size = SPRITE_SIZE(8x16), + .tileNum = 0, + .priority = 2, + .paletteNum = 0 +}; + +static const struct SpriteTemplate sSpriteTemplate_RightArrow = +{ + .tileTag = GFXTAG_ARROW, + .paletteTag = PALTAG_ARROW, + .oam = &sOamData_RightArrow, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCB_RightArrow +}; + +static const struct OamData sOamData_UpDownArrow = +{ + .y = 0, + .affineMode = ST_OAM_AFFINE_OFF, + .objMode = ST_OAM_OBJ_NORMAL, + .bpp = ST_OAM_4BPP, + .shape = SPRITE_SHAPE(16x8), + .x = 0, + .size = SPRITE_SIZE(16x8), + .tileNum = 0, + .priority = 2, + .paletteNum = 0 +}; + +static const struct SpriteTemplate sSpriteTemplate_UpDownArrow = +{ + .tileTag = GFXTAG_ARROW, + .paletteTag = PALTAG_ARROW, + .oam = &sOamData_UpDownArrow, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy +}; + +static void LoadListArrowGfx(void) +{ + u32 i; + const struct CompressedSpriteSheet *ptr; + + for (i = 0, ptr = sListArrowSpriteSheets; i < ARRAY_COUNT(sListArrowSpriteSheets); ptr++, i++) + LoadCompressedSpriteSheet(ptr); + + Pokenav_AllocAndLoadPalettes(sListArrowPalettes); +} + +static void CreateListArrowSprites(struct PokenavListWindowState *windowState, struct PokenavListSub *list) +{ + u32 spriteId; + s16 x; + + spriteId = CreateSprite(&sSpriteTemplate_RightArrow, list->listWindow.x * 8 + 3, (list->listWindow.y + 1) * 8, 7); + list->rightArrow = &gSprites[spriteId]; + + x = list->listWindow.x * 8 + (list->listWindow.width - 1) * 4; + spriteId = CreateSprite(&sSpriteTemplate_UpDownArrow, x, list->listWindow.y * 8 + windowState->entriesOnscreen * 16, 7); + list->downArrow = &gSprites[spriteId]; + list->downArrow->oam.tileNum += 2; + list->downArrow->callback = SpriteCB_DownArrow; + + spriteId = CreateSprite(&sSpriteTemplate_UpDownArrow, x, list->listWindow.y * 8, 7); + list->upArrow = &gSprites[spriteId]; + list->upArrow->oam.tileNum += 4; + list->upArrow->callback = SpriteCB_UpArrow; +} + +static void DestroyListArrows(struct PokenavListSub *list) +{ + DestroySprite(list->rightArrow); + DestroySprite(list->upArrow); + DestroySprite(list->downArrow); + FreeSpriteTilesByTag(GFXTAG_ARROW); + FreeSpritePaletteByTag(PALTAG_ARROW); +} + +static void ToggleListArrows(struct PokenavListSub *list, bool32 invisible) +{ + if (invisible) + { + list->rightArrow->callback = SpriteCallbackDummy; + list->upArrow->callback = SpriteCallbackDummy; + list->downArrow->callback = SpriteCallbackDummy; + } + else + { + list->rightArrow->callback = SpriteCB_RightArrow; + list->upArrow->callback = SpriteCB_UpArrow; + list->downArrow->callback = SpriteCB_DownArrow; + } + list->rightArrow->invisible = invisible; + list->upArrow->invisible = invisible; + list->downArrow->invisible = invisible; +} + +static void SpriteCB_RightArrow(struct Sprite *sprite) +{ + struct PokenavList *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); + sprite->y2 = structPtr->windowState.selectedIndexOffset << 4; +} + +#define sTimer data[0] +#define sOffset data[1] +#define sInvisible data[7] + +static void SpriteCB_DownArrow(struct Sprite *sprite) +{ + if (!sprite->sInvisible && ShouldShowDownArrow()) + sprite->invisible = FALSE; + else + sprite->invisible = TRUE; + + if (++sprite->sTimer > 3) + { + s16 offset; + + sprite->sTimer = 0; + offset = (sprite->sOffset + 1) & 7; + sprite->sOffset = offset; + sprite->y2 = offset; + } +} + +static void SpriteCB_UpArrow(struct Sprite *sprite) +{ + if (!sprite->sInvisible && ShouldShowUpArrow()) + sprite->invisible = FALSE; + else + sprite->invisible = TRUE; + + if (++sprite->sTimer > 3) + { + s16 offset; + + sprite->sTimer = 0; + offset = (sprite->sOffset + 1) & 7; + sprite->sOffset = offset; + sprite->y2 = -1 * offset; + } +} + +void PokenavList_ToggleVerticalArrows(bool32 invisible) +{ + struct PokenavList *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); + structPtr->list.upArrow->sInvisible = invisible; + structPtr->list.downArrow->sInvisible = invisible; +} + +#undef sTimer +#undef sOffset +#undef sInvisible + +static void InitPokenavListWindowState(struct PokenavListWindowState *dst, struct PokenavListTemplate *template) +{ + dst->listPtr = template->list; + dst->windowTopIndex = template->startIndex; + dst->listLength = template->count; + dst->listItemSize = template->itemSize; + dst->entriesOnscreen = template->maxShowed; + if (dst->entriesOnscreen >= dst->listLength) + { + dst->windowTopIndex = 0; + dst->entriesOffscreen = 0; + dst->selectedIndexOffset = template->startIndex; + } + else + { + dst->entriesOffscreen = dst->listLength - dst->entriesOnscreen; + if (dst->windowTopIndex + dst->entriesOnscreen > dst->listLength) + { + dst->selectedIndexOffset = dst->windowTopIndex + dst->entriesOnscreen - dst->listLength; + dst->windowTopIndex = template->startIndex - dst->selectedIndexOffset; + } + else + { + dst->selectedIndexOffset = 0; + } + } +} + +static bool32 CopyPokenavListMenuTemplate(struct PokenavListSub *dest, const struct BgTemplate *bgTemplate, struct PokenavListTemplate *template, s32 tileOffset) +{ + struct WindowTemplate window; + + dest->listWindow.bg = bgTemplate->bg; + dest->listWindow.tileOffset = tileOffset; + dest->bufferItemFunc = template->bufferItemFunc; + dest->iconDrawFunc = template->iconDrawFunc; + dest->listWindow.fillValue = template->fillValue; + dest->listWindow.x = template->item_X; + dest->listWindow.y = template->listTop; + dest->listWindow.width = template->windowWidth; + dest->listWindow.fontId = template->fontId; + + window.bg = bgTemplate->bg; + window.tilemapLeft = template->item_X; + window.tilemapTop = 0; + window.width = template->windowWidth; + window.height = 32; + window.paletteNum = template->fillValue; + window.baseBlock = tileOffset + 2; + + dest->listWindow.windowId = AddWindow(&window); + if (dest->listWindow.windowId == WINDOW_NONE) + return FALSE; + + dest->listWindow.unkA = 0; + dest->rightArrow = NULL; + dest->upArrow = NULL; + dest->downArrow = NULL; + return 1; +} diff --git a/src/pokenav_match_call_ui.c b/src/pokenav_match_call_ui.c deleted file mode 100644 index 97437e3cd..000000000 --- a/src/pokenav_match_call_ui.c +++ /dev/null @@ -1,1011 +0,0 @@ -#include "global.h" -#include "pokenav.h" -#include "window.h" -#include "strings.h" -#include "text.h" -#include "bg.h" -#include "menu.h" -#include "decompress.h" -#include "international_string_util.h" - -#define GFXTAG_ARROW 10 -#define PALTAG_ARROW 20 - -struct PokenavListMenuWindow { - u8 bg; - u8 fillValue; - u8 x; - u8 y; - u8 width; - u8 fontId; - u16 tileOffset; - u16 windowId; - u16 unkA; - u16 numPrinted; - u16 numToPrint; -}; - -struct PokenavListWindowState { - // The index of the element at the top of the window. - u16 windowTopIndex; - u16 listLength; - u16 entriesOffscreen; - // The index of the cursor, relative to the top of the window. - u16 selectedIndexOffset; - u16 entriesOnscreen; - u32 listItemSize; - void * listPtr; -}; - -struct PokenavSub17Substruct -{ - struct PokenavListMenuWindow listWindow; - u32 unk10; - u32 printIndex; - u32 itemSize; - void * listPtr; - s32 startBgY; - s32 endBgY; - u32 loopedTaskId; - s32 moveDelta; - u32 bgMoveType; - PokenavListBufferItemFunc bufferItemFunc; - void (*iconDrawFunc)(u16, u32, u32); - struct Sprite *rightArrow; - struct Sprite *upArrow; - struct Sprite *downArrow; - u8 itemTextBuffer[64]; -}; - -struct PokenavSub17 -{ - struct PokenavSub17Substruct list; - u8 tilemapBuffer[BG_SCREEN_SIZE]; - struct PokenavListWindowState windowState; - s32 eraseIndex; - u32 loopedTaskId; -}; - -static void InitPokenavListBg(struct PokenavSub17 *); -static bool32 CopyPokenavListMenuTemplate(struct PokenavSub17Substruct *, const struct BgTemplate *, struct PokenavListTemplate *, s32); -static void InitPokenavListWindowState(struct PokenavListWindowState *, struct PokenavListTemplate *); -static void SpriteCB_UpArrow(struct Sprite *); -static void SpriteCB_DownArrow(struct Sprite *); -static void SpriteCB_RightArrow(struct Sprite *); -static void ToggleListArrows(struct PokenavSub17Substruct *, u32); -static void DestroyListArrows(struct PokenavSub17Substruct *); -static void CreateListArrowSprites(struct PokenavListWindowState *, struct PokenavSub17Substruct *); -static void LoadListArrowGfx(void); -static void PrintMatchCallFlavorText(struct PokenavListWindowState *, struct PokenavSub17Substruct *, u32); -static void PrintMatchCallFieldNames(struct PokenavSub17Substruct *, u32); -static void PrintMatchCallListTrainerName(struct PokenavListWindowState *, struct PokenavSub17Substruct *); -static void PrintCheckPageTrainerName(struct PokenavListWindowState *, struct PokenavSub17Substruct *); -static void EraseListEntry(struct PokenavListMenuWindow *, s32, s32); -static void CreateMoveListWindowTask(s32, struct PokenavSub17Substruct *); -static void PrintListItems(void *, u32, u32, u32, u32, struct PokenavSub17Substruct *); -static void InitListItems(struct PokenavListWindowState *, struct PokenavSub17Substruct *); -static void InitPokenavListWindow(struct PokenavListMenuWindow *); -static u32 LoopedTask_CreatePokenavList(s32); -static bool32 IsPrintListItemsTaskActive(void); -static u32 LoopedTask_PrintListItems(s32); -static u32 LoopedTask_MoveListWindow(s32); -static u32 LoopedTask_EraseListForCheckPage(s32); -static u32 LoopedTask_ReshowListFromCheckPage(s32); -static u32 LoopedTask_PrintCheckPageInfo(s32); - -static const u16 sListArrow_Pal[] = INCBIN_U16("graphics/pokenav/list_arrows.gbapal"); -static const u32 sListArrow_Gfx[] = INCBIN_U32("graphics/pokenav/list_arrows.4bpp.lz"); - -static EWRAM_DATA u32 sMoveWindowDownIndex = 0; // Read, but pointlessly - -bool32 CreatePokenavList(const struct BgTemplate *bgTemplate, struct PokenavListTemplate *listTemplate, s32 tileOffset) -{ - struct PokenavSub17 *structPtr = AllocSubstruct(POKENAV_SUBSTRUCT_LIST, sizeof(struct PokenavSub17)); - if (structPtr == NULL) - return FALSE; - - InitPokenavListWindowState(&structPtr->windowState, listTemplate); - if (!CopyPokenavListMenuTemplate(&structPtr->list, bgTemplate, listTemplate, tileOffset)) - return FALSE; - - CreateLoopedTask(LoopedTask_CreatePokenavList, 6); - return TRUE; -} - -bool32 IsCreatePokenavListTaskActive(void) -{ - return FuncIsActiveLoopedTask(LoopedTask_CreatePokenavList); -} - -void DestroyPokenavList(void) -{ - struct PokenavSub17 *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); - DestroyListArrows(&structPtr->list); - RemoveWindow(structPtr->list.listWindow.windowId); - FreePokenavSubstruct(POKENAV_SUBSTRUCT_LIST); -} - -static u32 LoopedTask_CreatePokenavList(s32 state) -{ - struct PokenavSub17 *structPtr; - - if (IsDma3ManagerBusyWithBgCopy()) - return LT_PAUSE; - - structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); - - switch (state) - { - case 0: - InitPokenavListBg(structPtr); - return LT_INC_AND_PAUSE; - case 1: - InitPokenavListWindow(&structPtr->list.listWindow); - return LT_INC_AND_PAUSE; - case 2: - InitListItems(&structPtr->windowState, &structPtr->list); - return LT_INC_AND_PAUSE; - case 3: - if (IsPrintListItemsTaskActive()) - { - return LT_PAUSE; - } - else - { - LoadListArrowGfx(); - return LT_INC_AND_CONTINUE; - } - case 4: - CreateListArrowSprites(&structPtr->windowState, &structPtr->list); - return LT_FINISH; - default: - return LT_FINISH; - } -} - -static void InitPokenavListBg(struct PokenavSub17 *a0) -{ - u16 tileNum = (a0->list.listWindow.fillValue << 12) | a0->list.listWindow.tileOffset; - BgDmaFill(a0->list.listWindow.bg, PIXEL_FILL(1), a0->list.listWindow.tileOffset, 1); - BgDmaFill(a0->list.listWindow.bg, PIXEL_FILL(4), a0->list.listWindow.tileOffset + 1, 1); - SetBgTilemapBuffer(a0->list.listWindow.bg, a0->tilemapBuffer); - FillBgTilemapBufferRect_Palette0(a0->list.listWindow.bg, tileNum, 0, 0, 32, 32); - ChangeBgY(a0->list.listWindow.bg, 0, BG_COORD_SET); - ChangeBgX(a0->list.listWindow.bg, 0, BG_COORD_SET); - ChangeBgY(a0->list.listWindow.bg, a0->list.listWindow.y << 11, BG_COORD_SUB); - CopyBgTilemapBufferToVram(a0->list.listWindow.bg); -} - -static void InitPokenavListWindow(struct PokenavListMenuWindow *listWindow) -{ - FillWindowPixelBuffer(listWindow->windowId, PIXEL_FILL(1)); - PutWindowTilemap(listWindow->windowId); - CopyWindowToVram(listWindow->windowId, COPYWIN_MAP); -} - -static void InitListItems(struct PokenavListWindowState *windowState, struct PokenavSub17Substruct *a1) -{ - s32 numToPrint = windowState->listLength - windowState->windowTopIndex; - if (numToPrint > windowState->entriesOnscreen) - numToPrint = windowState->entriesOnscreen; - - PrintListItems(windowState->listPtr, windowState->windowTopIndex, numToPrint, windowState->listItemSize, 0, a1); -} - -static void PrintListItems(void * listPtr, u32 topIndex, u32 numItems, u32 itemSize, u32 a4, struct PokenavSub17Substruct *list) -{ - if (numItems == 0) - return; - - list->listPtr = listPtr + topIndex * itemSize; - list->itemSize = itemSize; - list->listWindow.numPrinted = 0; - list->listWindow.numToPrint = numItems; - list->printIndex = topIndex; - list->unk10 = a4; - CreateLoopedTask(LoopedTask_PrintListItems, 5); -} - -static bool32 IsPrintListItemsTaskActive(void) -{ - return FuncIsActiveLoopedTask(LoopedTask_PrintListItems); -} - -static u32 LoopedTask_PrintListItems(s32 state) -{ - u32 row; - struct PokenavSub17Substruct *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); - - switch (state) - { - case 0: - row = (structPtr->listWindow.unkA + structPtr->listWindow.numPrinted + structPtr->unk10) & 0xF; - structPtr->bufferItemFunc(structPtr->listPtr, structPtr->itemTextBuffer); - if (structPtr->iconDrawFunc != NULL) - structPtr->iconDrawFunc(structPtr->listWindow.windowId, structPtr->printIndex, row); - - AddTextPrinterParameterized(structPtr->listWindow.windowId, structPtr->listWindow.fontId, structPtr->itemTextBuffer, 8, (row << 4) + 1, TEXT_SKIP_DRAW, NULL); - if (++structPtr->listWindow.numPrinted >= structPtr->listWindow.numToPrint) - { - // Finished printing items. If icons were being drawn, draw the - // window tilemap and graphics. Otherwise just do the graphics - if (structPtr->iconDrawFunc != NULL) - CopyWindowToVram(structPtr->listWindow.windowId, COPYWIN_FULL); - else - CopyWindowToVram(structPtr->listWindow.windowId, COPYWIN_GFX); - return LT_INC_AND_PAUSE; - } - else - { - structPtr->listPtr += structPtr->itemSize; - structPtr->printIndex++; - return LT_CONTINUE; - } - case 1: - if (IsDma3ManagerBusyWithBgCopy()) - return LT_PAUSE; - return LT_FINISH; - } - return LT_FINISH; -} - -static bool32 ShouldShowUpArrow(void) -{ - struct PokenavSub17 *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); - - return (structPtr->windowState.windowTopIndex != 0); -} - -static bool32 ShouldShowDownArrow(void) -{ - struct PokenavSub17 *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); - struct PokenavListWindowState *subPtr = &structPtr->windowState; - - return (subPtr->windowTopIndex + subPtr->entriesOnscreen < subPtr->listLength); -} - -static void MoveListWindow(s32 delta, bool32 printItems) -{ - struct PokenavSub17 *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); - struct PokenavListWindowState *subPtr = &structPtr->windowState; - - if (delta < 0) - { - if (subPtr->windowTopIndex + delta < 0) - delta = -1 * subPtr->windowTopIndex; - if (printItems) - PrintListItems(subPtr->listPtr, subPtr->windowTopIndex + delta, delta * -1, subPtr->listItemSize, delta, &structPtr->list); - } - else if (printItems) - { - s32 index = sMoveWindowDownIndex = subPtr->windowTopIndex + subPtr->entriesOnscreen; - if (index + delta >= subPtr->listLength) - delta = subPtr->listLength - index; - - PrintListItems(subPtr->listPtr, index, delta, subPtr->listItemSize, subPtr->entriesOnscreen, &structPtr->list); - } - - CreateMoveListWindowTask(delta, &structPtr->list); - subPtr->windowTopIndex += delta; -} - -static void CreateMoveListWindowTask(s32 delta, struct PokenavSub17Substruct *list) -{ - list->startBgY = GetBgY(list->listWindow.bg); - list->endBgY = list->startBgY + (delta << 12); - if (delta > 0) - list->bgMoveType = BG_COORD_ADD; - else - list->bgMoveType = BG_COORD_SUB; - list->moveDelta = delta; - list->loopedTaskId = CreateLoopedTask(LoopedTask_MoveListWindow, 6); -} - -static u32 LoopedTask_MoveListWindow(s32 state) -{ - s32 oldY, newY; - bool32 finished; - struct PokenavSub17 *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); - struct PokenavSub17Substruct *subPtr = &structPtr->list; - - switch (state) - { - case 0: - if (!IsPrintListItemsTaskActive()) - return LT_INC_AND_CONTINUE; - return LT_PAUSE; - case 1: - finished = FALSE; - oldY = GetBgY(subPtr->listWindow.bg); - newY = ChangeBgY(subPtr->listWindow.bg, 0x1000, subPtr->bgMoveType); - if (subPtr->bgMoveType == BG_COORD_SUB) - { - if ((oldY > subPtr->endBgY || oldY <= subPtr->startBgY) && newY <= subPtr->endBgY) - finished = TRUE; - } - else // BG_COORD_ADD - { - if ((oldY < subPtr->endBgY || oldY >= subPtr->startBgY) && newY >= subPtr->endBgY) - finished = TRUE; - } - - if (finished) - { - subPtr->listWindow.unkA = (subPtr->listWindow.unkA + subPtr->moveDelta) & 0xF; - ChangeBgY(subPtr->listWindow.bg, subPtr->endBgY, BG_COORD_SET); - return LT_FINISH; - } - return LT_PAUSE; - } - return LT_FINISH; -} - -bool32 PokenavList_IsMoveWindowTaskActive(void) -{ - struct PokenavSub17 *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); - return IsLoopedTaskActive(structPtr->list.loopedTaskId); -} - -static struct PokenavListWindowState *GetPokenavListWindowState(void) -{ - struct PokenavSub17 *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); - return &structPtr->windowState; -} - -int PokenavList_MoveCursorUp(void) -{ - struct PokenavListWindowState *structPtr = GetPokenavListWindowState(); - - if (structPtr->selectedIndexOffset != 0) - { - structPtr->selectedIndexOffset--; - return 1; - } - if (ShouldShowUpArrow()) - { - MoveListWindow(-1, TRUE); - return 2; - } - return 0; -} - -int PokenavList_MoveCursorDown(void) -{ - struct PokenavListWindowState *structPtr = GetPokenavListWindowState(); - - if (structPtr->windowTopIndex + structPtr->selectedIndexOffset >= structPtr->listLength - 1) - return 0; - if (structPtr->selectedIndexOffset < structPtr->entriesOnscreen - 1) - { - structPtr->selectedIndexOffset++; - return 1; - } - if (ShouldShowDownArrow()) - { - MoveListWindow(1, TRUE); - return 2; - } - return 0; -} - -int PokenavList_PageUp(void) -{ - s32 scroll; - struct PokenavListWindowState *structPtr = GetPokenavListWindowState(); - - if (ShouldShowUpArrow()) - { - if (structPtr->windowTopIndex >= structPtr->entriesOnscreen) - scroll = structPtr->entriesOnscreen; - else - scroll = structPtr->windowTopIndex; - MoveListWindow(scroll * -1, TRUE); - return 2; - } - else if (structPtr->selectedIndexOffset != 0) - { - structPtr->selectedIndexOffset = 0; - return 1; - } - return 0; -} - -int PokenavList_PageDown(void) -{ - struct PokenavListWindowState *structPtr = GetPokenavListWindowState(); - - if (ShouldShowDownArrow()) - { - s32 windowBottomIndex = structPtr->windowTopIndex + structPtr->entriesOnscreen; - s32 scroll = structPtr->entriesOffscreen - structPtr->windowTopIndex; - - if (windowBottomIndex <= structPtr->entriesOffscreen) - scroll = structPtr->entriesOnscreen; - MoveListWindow(scroll, TRUE); - return 2; - } - else - { - s32 cursor, lastVisibleIndex; - if (structPtr->listLength >= structPtr->entriesOnscreen) - { - cursor = structPtr->selectedIndexOffset; - lastVisibleIndex = structPtr->entriesOnscreen; - } - else - { - cursor = structPtr->selectedIndexOffset; - lastVisibleIndex = structPtr->listLength; - } - lastVisibleIndex -= 1; - if (cursor >= lastVisibleIndex) - return 0; - - structPtr->selectedIndexOffset = lastVisibleIndex; - return 1; - } -} - -u32 PokenavList_GetSelectedIndex(void) -{ - struct PokenavListWindowState *structPtr = GetPokenavListWindowState(); - - return structPtr->windowTopIndex + structPtr->selectedIndexOffset; -} - -u32 PokenavList_GetTopIndex(void) -{ - struct PokenavListWindowState *structPtr = GetPokenavListWindowState(); - - return structPtr->windowTopIndex; -} - -void PokenavList_EraseListForCheckPage(void) -{ - struct PokenavSub17 *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); - structPtr->eraseIndex = 0; - structPtr->loopedTaskId = CreateLoopedTask(LoopedTask_EraseListForCheckPage, 6); -} - -void PrintCheckPageInfo(s16 delta) -{ - struct PokenavSub17 *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); - structPtr->windowState.windowTopIndex += delta; - structPtr->eraseIndex = 0; - structPtr->loopedTaskId = CreateLoopedTask(LoopedTask_PrintCheckPageInfo, 6); -} - -void PokenavList_ReshowListFromCheckPage(void) -{ - struct PokenavSub17 *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); - structPtr->eraseIndex = 0; - structPtr->loopedTaskId = CreateLoopedTask(LoopedTask_ReshowListFromCheckPage, 6); -} - -bool32 PokenavList_IsTaskActive(void) -{ - struct PokenavSub17 *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); - return IsLoopedTaskActive(structPtr->loopedTaskId); -} - -void PokenavList_DrawCurrentItemIcon(void) -{ - struct PokenavSub17 *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); - struct PokenavListWindowState *subPtr = &structPtr->windowState; - structPtr->list.iconDrawFunc(structPtr->list.listWindow.windowId, subPtr->windowTopIndex + subPtr->selectedIndexOffset, (structPtr->list.listWindow.unkA + subPtr->selectedIndexOffset) & 0xF); - CopyWindowToVram(structPtr->list.listWindow.windowId, COPYWIN_MAP); -} - -static u32 LoopedTask_EraseListForCheckPage(s32 state) -{ - struct PokenavSub17 *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); - - switch (state) - { - case 0: - ToggleListArrows(&structPtr->list, 1); - // fall-through - case 1: - if (structPtr->eraseIndex != structPtr->windowState.selectedIndexOffset) - EraseListEntry(&structPtr->list.listWindow, structPtr->eraseIndex, 1); - - structPtr->eraseIndex++; - return LT_INC_AND_PAUSE; - case 2: - if (!IsDma3ManagerBusyWithBgCopy()) - { - if (structPtr->eraseIndex != structPtr->windowState.entriesOnscreen) - return LT_SET_STATE(1); - if (structPtr->windowState.selectedIndexOffset != 0) - EraseListEntry(&structPtr->list.listWindow, structPtr->eraseIndex, structPtr->windowState.selectedIndexOffset); - - return LT_INC_AND_PAUSE; - } - return LT_PAUSE; - case 3: - if (!IsDma3ManagerBusyWithBgCopy()) - { - if (structPtr->windowState.selectedIndexOffset != 0) - { - MoveListWindow(structPtr->windowState.selectedIndexOffset, FALSE); - return LT_INC_AND_PAUSE; - } - return LT_FINISH; - } - return LT_PAUSE; - case 4: - if (PokenavList_IsMoveWindowTaskActive()) - return LT_PAUSE; - - structPtr->windowState.selectedIndexOffset = 0; - return LT_FINISH; - } - return LT_FINISH; -} - -static u32 LoopedTask_PrintCheckPageInfo(s32 state) -{ - struct PokenavSub17 *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); - if (IsDma3ManagerBusyWithBgCopy()) - return LT_PAUSE; - - switch (state) - { - case 0: - PrintCheckPageTrainerName(&structPtr->windowState, &structPtr->list); - break; - case 1: - PrintMatchCallFieldNames(&structPtr->list, 0); - break; - case 2: - PrintMatchCallFlavorText(&structPtr->windowState, &structPtr->list, CHECK_PAGE_STRATEGY); - break; - case 3: - PrintMatchCallFieldNames(&structPtr->list, 1); - break; - case 4: - PrintMatchCallFlavorText(&structPtr->windowState, &structPtr->list, CHECK_PAGE_POKEMON); - break; - case 5: - PrintMatchCallFieldNames(&structPtr->list, 2); - break; - case 6: - PrintMatchCallFlavorText(&structPtr->windowState, &structPtr->list, CHECK_PAGE_INTRO_1); - break; - case 7: - PrintMatchCallFlavorText(&structPtr->windowState, &structPtr->list, CHECK_PAGE_INTRO_2); - break; - default: - return LT_FINISH; - } - return LT_INC_AND_PAUSE; -} - -static u32 LoopedTask_ReshowListFromCheckPage(s32 state) -{ - struct PokenavSub17 *structPtr; - struct PokenavListWindowState *windowState; - struct PokenavSub17Substruct *subPtr0; - s32 r5, *ptr; - - if (IsDma3ManagerBusyWithBgCopy()) - return LT_PAUSE; - - structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); - windowState = &structPtr->windowState; - subPtr0 = &structPtr->list; - - switch (state) - { - case 0: - // Rewrite the name of the trainer whose check page was just being viewed. - // This is done to erase the red background it had. - PrintMatchCallListTrainerName(windowState, subPtr0); - return LT_INC_AND_PAUSE; - case 1: - ptr = &structPtr->eraseIndex; - if (++(*ptr) < structPtr->windowState.entriesOnscreen) - { - EraseListEntry(&subPtr0->listWindow, *ptr, 1); - return LT_PAUSE; - } - - *ptr = 0; - if (windowState->listLength <= windowState->entriesOnscreen) - { - if (windowState->windowTopIndex != 0) - { - s32 r4 = windowState->windowTopIndex; - r5 = -r4; - EraseListEntry(&subPtr0->listWindow, r5, r4); - windowState->selectedIndexOffset = r4; - *ptr = r5; - return LT_INC_AND_PAUSE; - } - } - else - { - if (windowState->windowTopIndex + windowState->entriesOnscreen > windowState->listLength) - { - s32 r4 = windowState->windowTopIndex + windowState->entriesOnscreen - windowState->listLength; - r5 = -r4; - EraseListEntry(&subPtr0->listWindow, r5, r4); - windowState->selectedIndexOffset = r4; - *ptr = r5; - return LT_INC_AND_PAUSE; - } - } - return LT_SET_STATE(4); - case 2: - MoveListWindow(structPtr->eraseIndex, FALSE); - return LT_INC_AND_PAUSE; - case 3: - if (!PokenavList_IsMoveWindowTaskActive()) - { - structPtr->eraseIndex = 0; - return LT_INC_AND_CONTINUE; - } - return LT_PAUSE; - case 4: - PrintListItems(windowState->listPtr, windowState->windowTopIndex + structPtr->eraseIndex, 1, windowState->listItemSize, structPtr->eraseIndex, &structPtr->list); - return LT_INC_AND_PAUSE; - case 5: - if (IsPrintListItemsTaskActive()) - return LT_PAUSE; - if (++structPtr->eraseIndex >= windowState->listLength || structPtr->eraseIndex >= windowState->entriesOnscreen) - return LT_INC_AND_CONTINUE; - return LT_SET_STATE(4); - case 6: - ToggleListArrows(subPtr0, 0); - return LT_FINISH; - } - - return LT_FINISH; -} - -static void EraseListEntry(struct PokenavListMenuWindow *listWindow, s32 a1, s32 a2) -{ - u8 *tileData = (u8*)GetWindowAttribute(listWindow->windowId, WINDOW_TILE_DATA); - u32 width = listWindow->width * 64; - - a1 = (listWindow->unkA + a1) & 0xF; - if (a1 + a2 <= 16) - { - CpuFastFill8(PIXEL_FILL(1), tileData + a1 * width, a2 * width); - CopyWindowToVram(listWindow->windowId, COPYWIN_GFX); - } - else - { - u32 v3 = 16 - a1; - u32 v4 = a2 - v3; - - CpuFastFill8(PIXEL_FILL(1), tileData + a1 * width, v3 * width); - CpuFastFill8(PIXEL_FILL(1), tileData, v4 * width); - CopyWindowToVram(listWindow->windowId, COPYWIN_GFX); - } - - for (a2--; a2 != -1; a1 = (a1 + 1) & 0xF, a2--) - ClearRematchPokeballIcon(listWindow->windowId, a1); - - CopyWindowToVram(listWindow->windowId, COPYWIN_MAP); -} - -// Pointless -static void SetListMarginTile(struct PokenavListMenuWindow *listWindow, bool32 draw) -{ - u16 var; - u16 *tilemapBuffer = (u16*)GetBgTilemapBuffer(GetWindowAttribute(listWindow->windowId, WINDOW_BG)); - tilemapBuffer += (listWindow->unkA << 6) + listWindow->x - 1; - - if (draw) - var = (listWindow->fillValue << 12) | (listWindow->tileOffset + 1); - else - var = (listWindow->fillValue << 12) | (listWindow->tileOffset); - - tilemapBuffer[0] = var; - tilemapBuffer[0x20] = var; -} - -// Print the trainer's name and title at the top of their check page -static void PrintCheckPageTrainerName(struct PokenavListWindowState *state, struct PokenavSub17Substruct *list) -{ - u8 colors[3] = {TEXT_COLOR_TRANSPARENT, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_RED}; - - list->bufferItemFunc(state->listPtr + state->listItemSize * state->windowTopIndex, list->itemTextBuffer); - list->iconDrawFunc(list->listWindow.windowId, state->windowTopIndex, list->listWindow.unkA); - FillWindowPixelRect(list->listWindow.windowId, PIXEL_FILL(4), 0, list->listWindow.unkA * 16, list->listWindow.width * 8, 16); - AddTextPrinterParameterized3(list->listWindow.windowId, list->listWindow.fontId, 8, (list->listWindow.unkA * 16) + 1, colors, TEXT_SKIP_DRAW, list->itemTextBuffer); - SetListMarginTile(&list->listWindow, TRUE); - CopyWindowRectToVram(list->listWindow.windowId, COPYWIN_FULL, 0, list->listWindow.unkA * 2, list->listWindow.width, 2); -} - -// Print the trainer's name and title for the list (to replace the check page name and title, which has a red background) -static void PrintMatchCallListTrainerName(struct PokenavListWindowState *state, struct PokenavSub17Substruct *list) -{ - list->bufferItemFunc(state->listPtr + state->listItemSize * state->windowTopIndex, list->itemTextBuffer); - FillWindowPixelRect(list->listWindow.windowId, PIXEL_FILL(1), 0, list->listWindow.unkA * 16, list->listWindow.width * 8, 16); - AddTextPrinterParameterized(list->listWindow.windowId, list->listWindow.fontId, list->itemTextBuffer, 8, list->listWindow.unkA * 16 + 1, TEXT_SKIP_DRAW, NULL); - SetListMarginTile(&list->listWindow, FALSE); - CopyWindowToVram(list->listWindow.windowId, COPYWIN_FULL); -} - -static void PrintMatchCallFieldNames(struct PokenavSub17Substruct *list, u32 fieldId) -{ - const u8 *fieldNames[] = { - gText_PokenavMatchCall_Strategy, - gText_PokenavMatchCall_TrainerPokemon, - gText_PokenavMatchCall_SelfIntroduction - }; - u8 colors[3] = {TEXT_COLOR_WHITE, TEXT_COLOR_RED, TEXT_COLOR_LIGHT_RED}; - u32 top = (list->listWindow.unkA + 1 + (fieldId * 2)) & 0xF; - - FillWindowPixelRect(list->listWindow.windowId, PIXEL_FILL(1), 0, top << 4, list->listWindow.width, 16); - AddTextPrinterParameterized3(list->listWindow.windowId, FONT_NARROW, 2, (top << 4) + 1, colors, TEXT_SKIP_DRAW, fieldNames[fieldId]); - CopyWindowRectToVram(list->listWindow.windowId, COPYWIN_GFX, 0, top << 1, list->listWindow.width, 2); -} - -static void PrintMatchCallFlavorText(struct PokenavListWindowState *a0, struct PokenavSub17Substruct *list, u32 checkPageEntry) -{ - // lines 1, 3, and 5 are the field names printed by PrintMatchCallFieldNames - static const u8 lineOffsets[CHECK_PAGE_ENTRY_COUNT] = { - [CHECK_PAGE_STRATEGY] = 2, - [CHECK_PAGE_POKEMON] = 4, - [CHECK_PAGE_INTRO_1] = 6, - [CHECK_PAGE_INTRO_2] = 7 - }; - - u32 r6 = (list->listWindow.unkA + lineOffsets[checkPageEntry]) & 0xF; - const u8 *str = GetMatchCallFlavorText(a0->windowTopIndex, checkPageEntry); - - if (str != NULL) - { - FillWindowTilesByRow(list->listWindow.windowId, 1, r6 * 2, list->listWindow.width - 1, 2); - AddTextPrinterParameterized(list->listWindow.windowId, FONT_NARROW, str, 2, (r6 << 4) + 1, TEXT_SKIP_DRAW, NULL); - CopyWindowRectToVram(list->listWindow.windowId, COPYWIN_GFX, 0, r6 * 2, list->listWindow.width, 2); - } -} - -static const struct CompressedSpriteSheet sListArrowSpriteSheets[] = -{ - { - .data = sListArrow_Gfx, - .size = 0xC0, - .tag = GFXTAG_ARROW - } -}; - -static const struct SpritePalette sListArrowPalettes[] = -{ - { - .data = sListArrow_Pal, - .tag = PALTAG_ARROW - }, - {} -}; - -static const struct OamData sOamData_RightArrow = -{ - .y = 0, - .affineMode = ST_OAM_AFFINE_OFF, - .objMode = ST_OAM_OBJ_NORMAL, - .bpp = ST_OAM_4BPP, - .shape = SPRITE_SHAPE(8x16), - .x = 0, - .size = SPRITE_SIZE(8x16), - .tileNum = 0, - .priority = 2, - .paletteNum = 0 -}; - -static const struct SpriteTemplate sSpriteTemplate_RightArrow = -{ - .tileTag = GFXTAG_ARROW, - .paletteTag = PALTAG_ARROW, - .oam = &sOamData_RightArrow, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_RightArrow -}; - -static const struct OamData sOamData_UpDownArrow = -{ - .y = 0, - .affineMode = ST_OAM_AFFINE_OFF, - .objMode = ST_OAM_OBJ_NORMAL, - .bpp = ST_OAM_4BPP, - .shape = SPRITE_SHAPE(16x8), - .x = 0, - .size = SPRITE_SIZE(16x8), - .tileNum = 0, - .priority = 2, - .paletteNum = 0 -}; - -static const struct SpriteTemplate sSpriteTemplate_UpDownArrow = -{ - .tileTag = GFXTAG_ARROW, - .paletteTag = PALTAG_ARROW, - .oam = &sOamData_UpDownArrow, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy -}; - -static void LoadListArrowGfx(void) -{ - u32 i; - const struct CompressedSpriteSheet *ptr; - - for (i = 0, ptr = sListArrowSpriteSheets; i < ARRAY_COUNT(sListArrowSpriteSheets); ptr++, i++) - LoadCompressedSpriteSheet(ptr); - - Pokenav_AllocAndLoadPalettes(sListArrowPalettes); -} - -static void CreateListArrowSprites(struct PokenavListWindowState *windowState, struct PokenavSub17Substruct *list) -{ - u32 spriteId; - s16 x; - - spriteId = CreateSprite(&sSpriteTemplate_RightArrow, list->listWindow.x * 8 + 3, (list->listWindow.y + 1) * 8, 7); - list->rightArrow = &gSprites[spriteId]; - - x = list->listWindow.x * 8 + (list->listWindow.width - 1) * 4; - spriteId = CreateSprite(&sSpriteTemplate_UpDownArrow, x, list->listWindow.y * 8 + windowState->entriesOnscreen * 16, 7); - list->downArrow = &gSprites[spriteId]; - list->downArrow->oam.tileNum += 2; - list->downArrow->callback = SpriteCB_DownArrow; - - spriteId = CreateSprite(&sSpriteTemplate_UpDownArrow, x, list->listWindow.y * 8, 7); - list->upArrow = &gSprites[spriteId]; - list->upArrow->oam.tileNum += 4; - list->upArrow->callback = SpriteCB_UpArrow; -} - -static void DestroyListArrows(struct PokenavSub17Substruct *list) -{ - DestroySprite(list->rightArrow); - DestroySprite(list->upArrow); - DestroySprite(list->downArrow); - FreeSpriteTilesByTag(GFXTAG_ARROW); - FreeSpritePaletteByTag(PALTAG_ARROW); -} - -static void ToggleListArrows(struct PokenavSub17Substruct *list, bool32 invisible) -{ - if (invisible) - { - list->rightArrow->callback = SpriteCallbackDummy; - list->upArrow->callback = SpriteCallbackDummy; - list->downArrow->callback = SpriteCallbackDummy; - } - else - { - list->rightArrow->callback = SpriteCB_RightArrow; - list->upArrow->callback = SpriteCB_UpArrow; - list->downArrow->callback = SpriteCB_DownArrow; - } - list->rightArrow->invisible = invisible; - list->upArrow->invisible = invisible; - list->downArrow->invisible = invisible; -} - -static void SpriteCB_RightArrow(struct Sprite *sprite) -{ - struct PokenavSub17 *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); - sprite->y2 = structPtr->windowState.selectedIndexOffset << 4; -} - -#define sTimer data[0] -#define sOffset data[1] -#define sInvisible data[7] - -static void SpriteCB_DownArrow(struct Sprite *sprite) -{ - if (!sprite->sInvisible && ShouldShowDownArrow()) - sprite->invisible = FALSE; - else - sprite->invisible = TRUE; - - if (++sprite->sTimer > 3) - { - s16 offset; - - sprite->sTimer = 0; - offset = (sprite->sOffset + 1) & 7; - sprite->sOffset = offset; - sprite->y2 = offset; - } -} - -static void SpriteCB_UpArrow(struct Sprite *sprite) -{ - if (!sprite->sInvisible && ShouldShowUpArrow()) - sprite->invisible = FALSE; - else - sprite->invisible = TRUE; - - if (++sprite->sTimer > 3) - { - s16 offset; - - sprite->sTimer = 0; - offset = (sprite->sOffset + 1) & 7; - sprite->sOffset = offset; - sprite->y2 = -1 * offset; - } -} - -void PokenavList_ToggleVerticalArrows(bool32 invisible) -{ - struct PokenavSub17 *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_LIST); - structPtr->list.upArrow->sInvisible = invisible; - structPtr->list.downArrow->sInvisible = invisible; -} - -#undef sTimer -#undef sOffset -#undef sInvisible - -static void InitPokenavListWindowState(struct PokenavListWindowState *dst, struct PokenavListTemplate *template) -{ - dst->listPtr = template->list; - dst->windowTopIndex = template->startIndex; - dst->listLength = template->count; - dst->listItemSize = template->itemSize; - dst->entriesOnscreen = template->maxShowed; - if (dst->entriesOnscreen >= dst->listLength) - { - dst->windowTopIndex = 0; - dst->entriesOffscreen = 0; - dst->selectedIndexOffset = template->startIndex; - } - else - { - dst->entriesOffscreen = dst->listLength - dst->entriesOnscreen; - if (dst->windowTopIndex + dst->entriesOnscreen > dst->listLength) - { - dst->selectedIndexOffset = dst->windowTopIndex + dst->entriesOnscreen - dst->listLength; - dst->windowTopIndex = template->startIndex - dst->selectedIndexOffset; - } - else - { - dst->selectedIndexOffset = 0; - } - } -} - -static bool32 CopyPokenavListMenuTemplate(struct PokenavSub17Substruct *dest, const struct BgTemplate *bgTemplate, struct PokenavListTemplate *template, s32 tileOffset) -{ - struct WindowTemplate window; - - dest->listWindow.bg = bgTemplate->bg; - dest->listWindow.tileOffset = tileOffset; - dest->bufferItemFunc = template->bufferItemFunc; - dest->iconDrawFunc = template->iconDrawFunc; - dest->listWindow.fillValue = template->fillValue; - dest->listWindow.x = template->item_X; - dest->listWindow.y = template->listTop; - dest->listWindow.width = template->windowWidth; - dest->listWindow.fontId = template->fontId; - - window.bg = bgTemplate->bg; - window.tilemapLeft = template->item_X; - window.tilemapTop = 0; - window.width = template->windowWidth; - window.height = 32; - window.paletteNum = template->fillValue; - window.baseBlock = tileOffset + 2; - - dest->listWindow.windowId = AddWindow(&window); - if (dest->listWindow.windowId == WINDOW_NONE) - return FALSE; - - dest->listWindow.unkA = 0; - dest->rightArrow = NULL; - dest->upArrow = NULL; - dest->downArrow = NULL; - return 1; -} -- cgit v1.2.3