diff options
Diffstat (limited to 'src/pokenav_main_menu.c')
-rw-r--r-- | src/pokenav_main_menu.c | 990 |
1 files changed, 990 insertions, 0 deletions
diff --git a/src/pokenav_main_menu.c b/src/pokenav_main_menu.c new file mode 100644 index 000000000..a7ea1b7dc --- /dev/null +++ b/src/pokenav_main_menu.c @@ -0,0 +1,990 @@ +#include "global.h" +#include "pokenav.h" +#include "constants/songs.h" +#include "sound.h" +#include "constants/rgb.h" +#include "palette.h" +#include "bg.h" +#include "window.h" +#include "strings.h" +#include "graphics.h" +#include "decompress.h" +#include "gpu_regs.h" +#include "menu.h" +#include "dma3.h" + +enum +{ + NAVGEAR_GFX_MAIN_MENU, + NAVGEAR_GFX_CONDITION_MENU, + NAVGEAR_GFX_RIBBONS_MENU, + NAVGEAR_GFX_MATCH_CALL_MENU, + + // One of these is for the zoomed-in map, and the other is for the + // zoomed-out map. Don't know which is which yet. + NAVGEAR_GFX_MAP_MENU_UNK0, + NAVGEAR_GFX_MAP_MENU_UNK1, + + NAVGEAR_GFX_PARTY_MENU, + NAVGEAR_GFX_SEARCH_MENU, + NAVGEAR_GFX_COOL_MENU, + NAVGEAR_GFX_BEAUTY_MENU, + NAVGEAR_GFX_CUTE_MENU, + NAVGEAR_GFX_SMART_MENU, + NAVGEAR_GFX_TOUGH_MENU, + + NAVGEAR_GFX_MENUS_END +}; + +#define NAVGEAR_GFX_SUBMENUS_START NAVGEAR_GFX_PARTY_MENU + +struct PokenavMainMenuResources +{ + void (*unk0)(u32); + u32 (*unk4)(void); + u32 unk8; + u32 currentTaskId; + u32 unk10; + u32 unk14; + struct Sprite *spinningNavgear; + struct Sprite *leftHeaderSprites[2]; + struct Sprite *submenuLeftHeaderSprites[2]; + u8 tilemapBuffer[0x800]; +}; + +// This struct uses a 32bit tag, and doesn't have a size field. +// Needed to match LoadLeftHeaderGfxForSubMenu. +struct CompressedSpriteSheetNoSize +{ + const u32 *data; // LZ77 compressed palette data + u32 tag; +}; + +extern void sub_81CAADC(void); +void CleanupPokenavMainMenuResources(void); +void LoadLeftHeaderGfxForSubMenu(u32 arg0); +void LoadLeftHeaderGfxForMenu(u32 arg0); +void HideLeftHeaderSubmenuSprites(bool32 arg0); +void HideLeftHeaderSprites(bool32 arg0); +void ShowLeftHeaderSprites(u32 arg0, bool32 arg1); +void ShowLeftHeaderSubmenuSprites(u32 arg0, bool32 arg1); +void MoveLeftHeader(struct Sprite *sprite, s32 arg1, s32 arg2, s32 arg3); +void SpriteCB_MoveLeftHeader(struct Sprite *sprite); +void InitPokenavMainMenuResources(void); +void InitHoenMapHeaderSprites(void); +void sub_81C7B74(void); +void CopyPaletteIntoBufferUnfaded(const u16 *palette, u32 a1, u32 a2); +u32 LoopedTask_ScrollMenuHeaderDown(s32 a0); +u32 LoopedTask_ScrollMenuHeaderUp(s32 a0); +void sub_81C7BF8(u32 a0); + + +void SpriteCB_SpinningNavgear(struct Sprite* sprite); +u32 LoopedTask_InitPokenavMenu(s32 a0); + +const u16 gSpinningNavgearPaletteData[] = INCBIN_U16("graphics/pokenav/icon2.gbapal"); +const u32 gSpinningNavgearGfx[] = INCBIN_U32("graphics/pokenav/icon2.4bpp.lz"); +const u32 gUnused_SpinningNavgearGfx2[] = INCBIN_U32("graphics/pokenav/icon2_unused.4bpp.lz"); + +const struct BgTemplate gPokenavMainMenuBgTemplates[] = +{ + { + .bg = 0, + .charBaseIndex = 0, + .mapBaseIndex = 5, + .screenSize = 0, + .paletteMode = 0, + .priority = 0, + .baseTile = 0, + } +}; + +const struct WindowTemplate gUnknown_0861FA08[2] = +{ + { + .bg = 0, + .tilemapLeft = 1, + .tilemapTop = 22, + .width = 16, + .height = 2, + .paletteNum = 0, + .baseBlock = 0x36, + }, + { + .bg = 0xFF, + .tilemapLeft = 0, + .tilemapTop = 0, + .width = 0, + .height = 0, + .paletteNum = 0, + .baseBlock = 0, + }, +}; + +const u8 *const (sMenuButtonReminders[12]) = +{ + gText_Navgear_ClearButtonList, + gText_NavgearMap_ZoomedOutButtons, + gText_NavgearMap_ZoomedInButtons, + gText_NavgearCondition_MonListButtons, + gText_NavgearCondition_MonStatusButtons, + gText_NavgearCondition_MarkingButtons, + gText_NavgearMatchCall_TrainerListButtons, + gText_NavgearMatchCall_CallMenuButtons, + gText_NavgearMatchCall_CheckTrainerButtons, + gText_NavgearRibbons_MonListButtons, + gText_NavgearRibbons_RibbonListButtons, + gText_NavgearRibbons_RibbonCheckButtons, +}; + +const u8 gMenuButtonReminderColor[4] = +{ + 4, 1, 2, 0 +}; + +static const struct CompressedSpriteSheet gSpinningNavgearSpriteSheet[] = +{ + { + .data = gSpinningNavgearGfx, + .size = 0x1000, + .tag = 0, + } +}; + +static const struct SpritePalette gSpinningNavgearPalette[] = +{ + { + .data = gSpinningNavgearPaletteData, + .tag = 0, + }, + {} +}; + +static const struct CompressedSpriteSheet sPokenavHoenMapLeftHeaderSpriteSheet = +{ + .data = gPokenavLeftHeaderHoennMap_Gfx, + .size = 0xC00, + .tag = 2 +}; + +static const struct CompressedSpriteSheet sPokenavMenuLeftHeaderSpriteSheets[] = +{ + [NAVGEAR_GFX_MAIN_MENU] = { + .data = gPokenavLeftHeaderMainMenu_Gfx, + .size = 0x20, + .tag = 3 + }, + [NAVGEAR_GFX_CONDITION_MENU] = { + .data = gPokenavLeftHeaderCondition_Gfx, + .size = 0x20, + .tag = 1 + }, + [NAVGEAR_GFX_RIBBONS_MENU] = { + .data = gPokenavLeftHeaderRibbons_Gfx, + .size = 0x20, + .tag = 2 + }, + [NAVGEAR_GFX_MATCH_CALL_MENU] = { + .data = gPokenavLeftHeaderMatchCall_Gfx, + .size = 0x20, + .tag = 4 + }, + [NAVGEAR_GFX_MAP_MENU_UNK0] = { + .data = gPokenavLeftHeaderHoennMap_Gfx, + .size = 0x20, + .tag = 0 + }, + [NAVGEAR_GFX_MAP_MENU_UNK1] = { + .data = gPokenavLeftHeaderHoennMap_Gfx, + .size = 0x40, + .tag = 0 + } +}; + +static const struct CompressedSpriteSheetNoSize sPokenavSubMenuLeftHeaderSpriteSheets[] = +{ + [NAVGEAR_GFX_PARTY_MENU - NAVGEAR_GFX_SUBMENUS_START] = { + .data = gPokenavLeftHeaderParty_Gfx, + .tag = 1 + }, + [NAVGEAR_GFX_SEARCH_MENU - NAVGEAR_GFX_SUBMENUS_START] = { + .data = gPokenavLeftHeaderSearch_Gfx, + .tag = 1 + }, + [NAVGEAR_GFX_COOL_MENU - NAVGEAR_GFX_SUBMENUS_START] = { + .data = gPokenavLeftHeaderCool_Gfx, + .tag = 4 + }, + [NAVGEAR_GFX_BEAUTY_MENU - NAVGEAR_GFX_SUBMENUS_START] = { + .data = gPokenavLeftHeaderBeauty_Gfx, + .tag = 1 + }, + [NAVGEAR_GFX_CUTE_MENU - NAVGEAR_GFX_SUBMENUS_START] = { + .data = gPokenavLeftHeaderCute_Gfx, + .tag = 2 + }, + [NAVGEAR_GFX_SMART_MENU - NAVGEAR_GFX_SUBMENUS_START] = { + .data = gPokenavLeftHeaderSmart_Gfx, + .tag = 0 + }, + [NAVGEAR_GFX_TOUGH_MENU - NAVGEAR_GFX_SUBMENUS_START] = { + .data = gPokenavLeftHeaderTough_Gfx, + .tag = 0 + } +}; + +static const struct OamData sSpinningNavgearSpriteOam = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, // FIXME: Use SPRITE_SHAPE + .x = 0, + .matrixNum = 0, + .size = 2, // FIXME: Use SPRITE_SIZE + .tileNum = 0, + .priority = 0, + .paletteNum = 0, + .affineParam = 0 +}; + +static const union AnimCmd sSpinningNavgearAnims[] = +{ + ANIMCMD_FRAME(0, 8), + ANIMCMD_FRAME(16, 8), + ANIMCMD_FRAME(32, 8), + ANIMCMD_FRAME(48, 8), + ANIMCMD_FRAME(64, 8), + ANIMCMD_FRAME(80, 8), + ANIMCMD_FRAME(96, 8), + ANIMCMD_FRAME(112, 8), + ANIMCMD_JUMP(0) +}; + +static const union AnimCmd *const sSpinningNavgearAnimTable[] = +{ + sSpinningNavgearAnims +}; + +static const struct SpriteTemplate sSpinningNavgearSpriteTemplate = +{ + .tileTag = 0, + .paletteTag = 0, + .oam = &sSpinningNavgearSpriteOam, + .anims = sSpinningNavgearAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCB_SpinningNavgear +}; + +static const struct OamData sPokenavLeftHeaderHoenMapSpriteOam = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 1, + .x = 0, + .matrixNum = 0, + .size = 3, + .tileNum = 0, + .priority = 1, + .paletteNum = 0, + .affineParam = 0 +}; + +static const struct OamData sUnknown_0861FB24 = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 1, + .x = 0, + .matrixNum = 0, + .size = 2, + .tileNum = 0, + .priority = 1, + .paletteNum = 0, + .affineParam = 0 +}; + +static const struct SpriteTemplate sPokenavLeftHeaderHoenMapSpriteTemplate = +{ + .tileTag = 2, + .paletteTag = 1, + .oam = &sPokenavLeftHeaderHoenMapSpriteOam, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy +}; + +static const struct SpriteTemplate sUnknown_0861FB44 = +{ + .tileTag = 2, + .paletteTag = 2, + .oam = &sUnknown_0861FB24, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy +}; + +bool32 InitPokenavMainMenu(void) +{ + struct PokenavMainMenuResources *structPtr; + + structPtr = AllocSubstruct(0, sizeof(struct PokenavMainMenuResources)); + if (structPtr == NULL) + return FALSE; + + ResetSpriteData(); + FreeAllSpritePalettes(); + structPtr->currentTaskId = CreateLoopedTask(LoopedTask_InitPokenavMenu, 1); + return TRUE; +} + +u32 PokenavMainMenuLoopedTaskIsActive(void) +{ + struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0); + return IsLoopedTaskActive(structPtr->currentTaskId); +} + +void ShutdownPokenav(void) +{ + PlaySE(SE_PN_OFF); + sub_81CAADC(); + BeginNormalPaletteFade(0xFFFFFFFF, -1, 0, 16, RGB_BLACK); +} + +bool32 WaitForPokenavShutdownFade(void) +{ + if (!gPaletteFade.active) + { + sub_81C99D4(); + CleanupPokenavMainMenuResources(); + FreeAllWindowBuffers(); + return FALSE; + } + + return TRUE; +} + +u32 LoopedTask_InitPokenavMenu(s32 a0) +{ + struct PokenavMainMenuResources *structPtr; + + switch (a0) + { + case 0: + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); + FreeAllWindowBuffers(); + ResetBgsAndClearDma3BusyFlags(0); + InitBgsFromTemplates(0, gPokenavMainMenuBgTemplates, ARRAY_COUNT(gPokenavMainMenuBgTemplates)); + ResetBgPositions(); + reset_temp_tile_data_buffers(); + return LT_INC_AND_CONTINUE; + case 1: + structPtr = GetSubstructPtr(0); + decompress_and_copy_tile_data_to_vram(0, &gPokenavHeader_Gfx, 0, 0, 0); + SetBgTilemapBuffer(0, structPtr->tilemapBuffer); + CopyToBgTilemapBuffer(0, &gPokenavHeader_Tilemap, 0, 0); + CopyPaletteIntoBufferUnfaded(gPokenavHeader_Pal, 0, 0x20); + CopyBgTilemapBufferToVram(0); + return LT_INC_AND_PAUSE; + case 2: + if (free_temp_tile_data_buffers_if_possible()) + return LT_PAUSE; + + sub_81C7B74(); + return LT_INC_AND_PAUSE; + case 3: + if (IsDma3ManagerBusyWithBgCopy()) + return LT_PAUSE; + + InitPokenavMainMenuResources(); + InitHoenMapHeaderSprites(); + ShowBg(0); + return LT_FINISH; + default: + return LT_FINISH; + } +} + +void sub_81C7834(void *func1, void *func2) // Fix types later. +{ + struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0); + structPtr->unk0 = func1; + structPtr->unk4 = func2; + structPtr->unk8 = 0; +} + +void sub_81C7850(u32 a0) +{ + struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0); + structPtr->unk8 = 0; + structPtr->unk0(a0); +} + +u32 sub_81C786C(void) +{ + struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0); + return structPtr->unk4(); +} + +void sub_81C7880(void) +{ + struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0); + structPtr->currentTaskId = CreateLoopedTask(LoopedTask_ScrollMenuHeaderDown, 4); +} + +void sub_81C78A0(void) +{ + struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0); + structPtr->currentTaskId = CreateLoopedTask(LoopedTask_ScrollMenuHeaderUp, 4); +} + +bool32 MainMenuLoopedTaskIsBusy(void) +{ + struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0); + return IsLoopedTaskActive(structPtr->currentTaskId); +} + +u32 LoopedTask_ScrollMenuHeaderDown(s32 a0) +{ + switch (a0) + { + default: + return LT_FINISH; + case 1: + return LT_INC_AND_PAUSE; + case 0: + return LT_INC_AND_PAUSE; + case 2: + if (ChangeBgY(0, 384, 1) >= 0x2000u) + { + ChangeBgY(0, 0x2000, 0); + return LT_FINISH; + } + + return LT_PAUSE; + } +} + +u32 LoopedTask_ScrollMenuHeaderUp(s32 a0) +{ + if (ChangeBgY(0, 384, 2) <= 0) + { + ChangeBgY(0, 0, 0); + return 4; + } + return 2; +} + +void CopyPaletteIntoBufferUnfaded(const u16 *palette, u32 bufferOffset, u32 size) +{ + CpuCopy16(palette, gPlttBufferUnfaded + bufferOffset, size); +} + +void Pokenav_AllocAndLoadPalettes(const struct SpritePalette *palettes) +{ + const struct SpritePalette *current; + u32 index; + + for (current = palettes; current->data != NULL; current++) + { + index = AllocSpritePalette(current->tag); + if (index == 0xFF) + { + break; + } + else + { + index = (index * 16) + 0x100; + CopyPaletteIntoBufferUnfaded(current->data, index, 0x20); + } + } +} + +void sub_81C7990(u32 a0, u16 a1) +{ + CpuFill16(a1, gPlttBufferFaded + 0x100 + (a0 * 16), 16 * sizeof(u16)); +} + +__attribute__((naked)) +void sub_81C79BC(u16 *a0, u16 *a1, u32 a2, u32 a3, u32 a4, u32 a5) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0xC\n\ + str r0, [sp]\n\ + str r1, [sp, 0x4]\n\ + mov r10, r2\n\ + str r3, [sp, 0x8]\n\ + ldr r0, [sp, 0x2C]\n\ + cmp r0, 0\n\ + bne _081C79E4\n\ + ldr r2, =0x001fffff\n\ + mov r1, r10\n\ + ands r2, r1\n\ + ldr r0, [sp]\n\ + b _081C79F4\n\ + .pool\n\ +_081C79E4:\n\ + ldr r2, [sp, 0x2C]\n\ + ldr r0, [sp, 0x8]\n\ + cmp r2, r0\n\ + blt _081C7A00\n\ + ldr r2, =0x001fffff\n\ + mov r1, r10\n\ + ands r2, r1\n\ + ldr r0, [sp, 0x4]\n\ +_081C79F4:\n\ + ldr r1, [sp, 0x30]\n\ + bl CpuSet\n\ + b _081C7AAE\n\ + .pool\n\ +_081C7A00:\n\ + movs r2, 0x1\n\ + negs r2, r2\n\ + add r10, r2\n\ + b _081C7AA6\n\ +_081C7A08:\n\ + ldr r1, [sp]\n\ + ldrh r0, [r1]\n\ + movs r2, 0x1F\n\ + mov r9, r2\n\ + mov r1, r9\n\ + ands r1, r0\n\ + mov r9, r1\n\ + lsls r0, 16\n\ + lsrs r2, r0, 21\n\ + movs r1, 0x1F\n\ + ands r1, r2\n\ + mov r8, r1\n\ + lsrs r7, r0, 26\n\ + movs r2, 0x1F\n\ + ands r7, r2\n\ + ldr r0, [sp, 0x4]\n\ + ldrh r4, [r0]\n\ + movs r0, 0x1F\n\ + ands r0, r4\n\ + mov r1, r9\n\ + subs r0, r1\n\ + lsls r0, 8\n\ + ldr r1, [sp, 0x8]\n\ + bl __divsi3\n\ + ldr r2, [sp, 0x2C]\n\ + adds r6, r0, 0\n\ + muls r6, r2\n\ + asrs r6, 8\n\ + lsls r4, 16\n\ + lsrs r0, r4, 21\n\ + movs r1, 0x1F\n\ + ands r0, r1\n\ + mov r2, r8\n\ + subs r0, r2\n\ + lsls r0, 8\n\ + ldr r1, [sp, 0x8]\n\ + bl __divsi3\n\ + ldr r1, [sp, 0x2C]\n\ + adds r5, r0, 0\n\ + muls r5, r1\n\ + asrs r5, 8\n\ + lsrs r4, 26\n\ + movs r2, 0x1F\n\ + ands r4, r2\n\ + subs r4, r7\n\ + lsls r4, 8\n\ + adds r0, r4, 0\n\ + ldr r1, [sp, 0x8]\n\ + bl __divsi3\n\ + ldr r1, [sp, 0x2C]\n\ + muls r0, r1\n\ + asrs r0, 8\n\ + add r6, r9\n\ + movs r2, 0x1F\n\ + ands r6, r2\n\ + add r5, r8\n\ + ands r5, r2\n\ + adds r0, r7, r0\n\ + ands r0, r2\n\ + lsls r0, 10\n\ + lsls r5, 5\n\ + orrs r0, r5\n\ + orrs r0, r6\n\ + ldr r1, [sp, 0x30]\n\ + strh r0, [r1]\n\ + ldr r2, [sp]\n\ + adds r2, 0x2\n\ + str r2, [sp]\n\ + ldr r0, [sp, 0x4]\n\ + adds r0, 0x2\n\ + str r0, [sp, 0x4]\n\ + adds r1, 0x2\n\ + str r1, [sp, 0x30]\n\ + movs r1, 0x1\n\ + negs r1, r1\n\ + add r10, r1\n\ +_081C7AA6:\n\ + movs r0, 0x1\n\ + negs r0, r0\n\ + cmp r10, r0\n\ + bne _081C7A08\n\ +_081C7AAE:\n\ + add sp, 0xC\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .syntax divided"); +} + +void sub_81C7AC0(s32 a0) +{ + struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0); + + switch (a0) + { + case 0: + BeginNormalPaletteFade(structPtr->unk14, -2, 0, 16, RGB_BLACK); + break; + case 1: + BeginNormalPaletteFade(structPtr->unk14, -2, 16, 0, RGB_BLACK); + break; + case 2: + BeginNormalPaletteFade(0xFFFFFFFF, -2, 0, 16, RGB_BLACK); + break; + case 3: + BeginNormalPaletteFade(0xFFFFFFFF, -2, 16, 0, RGB_BLACK); + break; + } +} + +bool32 IsPaletteFadeActive(void) +{ + return gPaletteFade.active; +} + +void sub_81C7B40(void) +{ + BlendPalettes(0xFFFEFFFE, 16, RGB_BLACK); +} + +void InitBgTemplates(const struct BgTemplate *templates, s32 count) +{ + s32 i; + + for (i = 0; i < count; i++) + InitBgFromTemplate(templates++); +} + +void sub_81C7B74(void) +{ + struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0); + + InitWindows(&gUnknown_0861FA08[0]); + structPtr->unk10 = 0; + sub_81C7BF8(structPtr->unk10); + PutWindowTilemap(structPtr->unk10); + CopyWindowToVram(structPtr->unk10, 3); // TODO: Use a defined constant here. +} + +void sub_81C7BA4(u32 a0) +{ + struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0); + + sub_81C7BF8(structPtr->unk10); + AddTextPrinterParameterized3(structPtr->unk10, 1, 0, 1, gMenuButtonReminderColor, 0, sMenuButtonReminders[a0]); +} + +bool32 IsDma3ManagerBusyWithBgCopy_(void) +{ + return IsDma3ManagerBusyWithBgCopy(); +} + +void sub_81C7BF8(u32 windowId) +{ + FillWindowPixelBuffer(windowId, PIXEL_FILL(4)); + FillWindowPixelRect(windowId, PIXEL_FILL(5), 0, 0, 0x80, 1); +} + +void InitPokenavMainMenuResources(void) +{ + s32 i; + u8 spriteId; + struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0); + + for (i = 0; i < ARRAY_COUNT(gSpinningNavgearSpriteSheet); i++) + LoadCompressedSpriteSheet(&gSpinningNavgearSpriteSheet[i]); + + Pokenav_AllocAndLoadPalettes(gSpinningNavgearPalette); + structPtr->unk14 = ~1 & ~(0x10000 << IndexOfSpritePaletteTag(0)); + spriteId = CreateSprite(&sSpinningNavgearSpriteTemplate, 220, 12, 0); + structPtr->spinningNavgear = &gSprites[spriteId]; +} + +void CleanupPokenavMainMenuResources(void) +{ + struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0); + + DestroySprite(structPtr->spinningNavgear); + FreeSpriteTilesByTag(0); + FreeSpritePaletteByTag(0); +} + +void SpriteCB_SpinningNavgear(struct Sprite *sprite) +{ + // If the background starts scrolling, follow it. + sprite->pos2.y = (GetBgY(0) / 256u) * -1; +} + +struct Sprite *PauseSpinningNavgearSprite(void) +{ + struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0); + + structPtr->spinningNavgear->callback = SpriteCallbackDummy; + return structPtr->spinningNavgear; +} + +void ResumeSpinningNavgearSprite(void) +{ + struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0); + + structPtr->spinningNavgear->pos1.x = 220; + structPtr->spinningNavgear->pos1.y = 12; + structPtr->spinningNavgear->callback = SpriteCB_SpinningNavgear; + structPtr->spinningNavgear->invisible = FALSE; + structPtr->spinningNavgear->oam.priority = 0; + structPtr->spinningNavgear->subpriority = 0; +} + +void InitHoenMapHeaderSprites(void) +{ + s32 i, spriteId; + struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0); + + LoadCompressedSpriteSheet(&sPokenavHoenMapLeftHeaderSpriteSheet); + AllocSpritePalette(1); + AllocSpritePalette(2); + for (i = 0; i < (s32)ARRAY_COUNT(structPtr->leftHeaderSprites); i++) + { + spriteId = CreateSprite(&sPokenavLeftHeaderHoenMapSpriteTemplate, 0, 0, 1); + structPtr->leftHeaderSprites[i] = &gSprites[spriteId]; + structPtr->leftHeaderSprites[i]->invisible = TRUE; + structPtr->leftHeaderSprites[i]->pos2.x = i * 64; + + spriteId = CreateSprite(&sUnknown_0861FB44, 0, 0, 2); + structPtr->submenuLeftHeaderSprites[i] = &gSprites[spriteId]; + structPtr->submenuLeftHeaderSprites[i]->invisible = TRUE; + structPtr->submenuLeftHeaderSprites[i]->pos2.x = i * 32; + structPtr->submenuLeftHeaderSprites[i]->pos2.y = 18; + structPtr->submenuLeftHeaderSprites[i]->oam.tileNum += (i * 8) + 64; + } +} + +void LoadLeftHeaderGfxForIndex(u32 arg0) +{ + if (arg0 < NAVGEAR_GFX_SUBMENUS_START) + LoadLeftHeaderGfxForMenu(arg0); + else + LoadLeftHeaderGfxForSubMenu(arg0 - NAVGEAR_GFX_SUBMENUS_START); +} + +void sub_81C7E14(u32 arg0) +{ + struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0); + + if (arg0 == 4) + structPtr->leftHeaderSprites[1]->oam.tileNum = GetSpriteTileStartByTag(2) + 32; + else + structPtr->leftHeaderSprites[1]->oam.tileNum = GetSpriteTileStartByTag(2) + 64; +} + +void LoadLeftHeaderGfxForMenu(u32 index) +{ + struct PokenavMainMenuResources *structPtr; + u32 size, tag; + + if (index >= NAVGEAR_GFX_SUBMENUS_START) + return; + + structPtr = GetSubstructPtr(0); + tag = sPokenavMenuLeftHeaderSpriteSheets[index].tag; + size = GetDecompressedDataSize(sPokenavMenuLeftHeaderSpriteSheets[index].data); + LoadPalette(&gPokenavLeftHeader_Pal[tag * 16], (IndexOfSpritePaletteTag(1) * 16) + 0x100, 0x20); + LZ77UnCompWram(sPokenavMenuLeftHeaderSpriteSheets[index].data, gDecompressionBuffer); + RequestDma3Copy(gDecompressionBuffer, (void *)VRAM + 0x10000 + (GetSpriteTileStartByTag(2) * 32), size, 1); + structPtr->leftHeaderSprites[1]->oam.tileNum = GetSpriteTileStartByTag(2) + sPokenavMenuLeftHeaderSpriteSheets[index].size; + + if (index == NAVGEAR_GFX_MAP_MENU_UNK0 || index == NAVGEAR_GFX_MAP_MENU_UNK1) + structPtr->leftHeaderSprites[1]->pos2.x = 56; + else + structPtr->leftHeaderSprites[1]->pos2.x = 64; +} + +void LoadLeftHeaderGfxForSubMenu(u32 arg0) +{ + u32 size, tag; + + if (arg0 >= NAVGEAR_GFX_MENUS_END - NAVGEAR_GFX_SUBMENUS_START) + return; + + tag = sPokenavSubMenuLeftHeaderSpriteSheets[arg0].tag; + size = GetDecompressedDataSize(sPokenavSubMenuLeftHeaderSpriteSheets[arg0].data); + LoadPalette(&gPokenavLeftHeader_Pal[tag * 16], (IndexOfSpritePaletteTag(2) * 16) + 0x100, 0x20); + LZ77UnCompWram(sPokenavSubMenuLeftHeaderSpriteSheets[arg0].data, &gDecompressionBuffer[0x1000]); + RequestDma3Copy(&gDecompressionBuffer[0x1000], (void *)VRAM + 0x10800 + (GetSpriteTileStartByTag(2) * 32), size, 1); +} + +void sub_81C7FA0(u32 arg0, bool32 arg1, bool32 arg2) +{ + u32 var; + + if (!arg1) + var = 0x30; + else + var = 0x10; + + if (arg0 < 6) + ShowLeftHeaderSprites(var, arg2); + else + ShowLeftHeaderSubmenuSprites(var, arg2); +} + +void sub_81C7FC4(u32 arg0, bool32 arg1) +{ + if (arg0 < 6) + HideLeftHeaderSprites(arg1); + else + HideLeftHeaderSubmenuSprites(arg1); +} + +void sub_81C7FDC(void) +{ + s32 i; + struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0); + + for (i = 0; i < (s32)ARRAY_COUNT(structPtr->leftHeaderSprites); i++) + { + structPtr->leftHeaderSprites[i]->invisible = TRUE; + structPtr->submenuLeftHeaderSprites[i]->invisible = TRUE; + } +} + +bool32 sub_81C8010(void) +{ + struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0); + + if (structPtr->leftHeaderSprites[0]->callback == SpriteCallbackDummy && structPtr->submenuLeftHeaderSprites[0]->callback == SpriteCallbackDummy) + return FALSE; + else + return TRUE; +} + +void ShowLeftHeaderSprites(u32 startY, bool32 isOnRightSide) +{ + s32 start, end, i; + struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0); + + if (!isOnRightSide) + start = -96, end = 32; + else + start = 256, end = 160; + + for (i = 0; i < (s32)ARRAY_COUNT(structPtr->leftHeaderSprites); i++) + { + structPtr->leftHeaderSprites[i]->pos1.y = startY; + MoveLeftHeader(structPtr->leftHeaderSprites[i], start, end, 12); + } +} + +void ShowLeftHeaderSubmenuSprites(u32 startY, bool32 isOnRightSide) +{ + s32 start, end, i; + struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0); + + if (!isOnRightSide) + start = -96, end = 16; + else + start = 256, end = 192; + + for (i = 0; i < (s32)ARRAY_COUNT(structPtr->submenuLeftHeaderSprites); i++) + { + structPtr->submenuLeftHeaderSprites[i]->pos1.y = startY; + MoveLeftHeader(structPtr->submenuLeftHeaderSprites[i], start, end, 12); + } +} + +void HideLeftHeaderSprites(bool32 isOnRightSide) +{ + s32 start, end, i; + struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0); + + if (!isOnRightSide) + start = 32, end = -96; + else + start = 192, end = 256; + + for (i = 0; i < (s32)ARRAY_COUNT(structPtr->leftHeaderSprites); i++) + { + MoveLeftHeader(structPtr->leftHeaderSprites[i], start, end, 12); + } +} + +void HideLeftHeaderSubmenuSprites(bool32 isOnRightSide) +{ + s32 start, end, i; + struct PokenavMainMenuResources *structPtr = GetSubstructPtr(0); + + if (!isOnRightSide) + start = 16, end = -96; + else + start = 192, end = 256; + + for (i = 0; i < (s32)ARRAY_COUNT(structPtr->submenuLeftHeaderSprites); i++) + { + MoveLeftHeader(structPtr->submenuLeftHeaderSprites[i], start, end, 12); + } +} + +void MoveLeftHeader(struct Sprite *sprite, s32 startX, s32 endX, s32 duration) +{ + sprite->pos1.x = startX; + sprite->data[0] = startX * 16; + sprite->data[1] = (endX - startX) * 16 / duration; + sprite->data[2] = duration; + sprite->data[7] = endX; + sprite->callback = SpriteCB_MoveLeftHeader; +} + +void SpriteCB_MoveLeftHeader(struct Sprite *sprite) +{ + if (sprite->data[2] != 0) + { + sprite->data[2]--; + sprite->data[0] += sprite->data[1]; + sprite->pos1.x = sprite->data[0] >> 4; + if (sprite->pos1.x < -16 || sprite->pos1.x > 256) + sprite->invisible = TRUE; + else + sprite->invisible = FALSE; + } + else + { + sprite->pos1.x = sprite->data[7]; + sprite->callback = SpriteCallbackDummy; + } +} |