mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-28 12:44:18 +01:00
850 lines
24 KiB
C
850 lines
24 KiB
C
#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"
|
|
|
|
struct Pokenav_MainMenu
|
|
{
|
|
void (*loopTask)(u32);
|
|
u32 (*isLoopTaskActiveFunc)(void);
|
|
u32 unused;
|
|
u32 currentTaskId;
|
|
u32 helpBarWindowId;
|
|
u32 palettes;
|
|
struct Sprite *spinningPokenav;
|
|
struct Sprite *leftHeaderSprites[2];
|
|
struct Sprite *submenuLeftHeaderSprites[2];
|
|
u8 tilemapBuffer[BG_SCREEN_SIZE];
|
|
};
|
|
|
|
// 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;
|
|
};
|
|
|
|
static void CleanupPokenavMainMenuResources(void);
|
|
static void LoadLeftHeaderGfxForSubMenu(u32);
|
|
static void LoadLeftHeaderGfxForMenu(u32);
|
|
static void HideLeftHeaderSubmenuSprites(bool32);
|
|
static void HideLeftHeaderSprites(bool32);
|
|
static void ShowLeftHeaderSprites(u32, bool32);
|
|
static void ShowLeftHeaderSubmenuSprites(u32, bool32);
|
|
static void MoveLeftHeader(struct Sprite *, s32, s32, s32);
|
|
static void SpriteCB_MoveLeftHeader(struct Sprite *);
|
|
static void InitPokenavMainMenuResources(void);
|
|
static void CreateLeftHeaderSprites(void);
|
|
static void InitHelpBar(void);
|
|
static u32 LoopedTask_SlideMenuHeaderUp(s32);
|
|
static u32 LoopedTask_SlideMenuHeaderDown(s32);
|
|
static void DrawHelpBar(u32);
|
|
static void SpriteCB_SpinningPokenav(struct Sprite*);
|
|
static u32 LoopedTask_InitPokenavMenu(s32);
|
|
|
|
static const u16 sSpinningPokenav_Pal[] = INCBIN_U16("graphics/pokenav/nav_icon.gbapal");
|
|
static const u32 sSpinningPokenav_Gfx[] = INCBIN_U32("graphics/pokenav/nav_icon.4bpp.lz");
|
|
static const u32 sBlueLightCopy[] = INCBIN_U32("graphics/pokenav/blue_light.4bpp.lz"); // Unused copy of sMatchCallBlueLightTiles
|
|
|
|
const struct BgTemplate gPokenavMainMenuBgTemplates[] =
|
|
{
|
|
{
|
|
.bg = 0,
|
|
.charBaseIndex = 0,
|
|
.mapBaseIndex = 5,
|
|
.screenSize = 0,
|
|
.paletteMode = 0,
|
|
.priority = 0,
|
|
.baseTile = 0,
|
|
}
|
|
};
|
|
|
|
static const struct WindowTemplate sHelpBarWindowTemplate[] =
|
|
{
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 1,
|
|
.tilemapTop = 22,
|
|
.width = 16,
|
|
.height = 2,
|
|
.paletteNum = 0,
|
|
.baseBlock = 0x36,
|
|
},
|
|
DUMMY_WIN_TEMPLATE
|
|
};
|
|
|
|
static const u8 *const sHelpBarTexts[HELPBAR_COUNT] =
|
|
{
|
|
[HELPBAR_NONE] = gText_Pokenav_ClearButtonList,
|
|
[HELPBAR_MAP_ZOOMED_OUT] = gText_PokenavMap_ZoomedOutButtons,
|
|
[HELPBAR_MAP_ZOOMED_IN] = gText_PokenavMap_ZoomedInButtons,
|
|
[HELPBAR_CONDITION_MON_LIST] = gText_PokenavCondition_MonListButtons,
|
|
[HELPBAR_CONDITION_MON_STATUS] = gText_PokenavCondition_MonStatusButtons,
|
|
[HELPBAR_CONDITION_MARKINGS] = gText_PokenavCondition_MarkingButtons,
|
|
[HELPBAR_MC_TRAINER_LIST] = gText_PokenavMatchCall_TrainerListButtons,
|
|
[HELPBAR_MC_CALL_MENU] = gText_PokenavMatchCall_CallMenuButtons,
|
|
[HELPBAR_MC_CHECK_PAGE] = gText_PokenavMatchCall_CheckTrainerButtons,
|
|
[HELPBAR_RIBBONS_MON_LIST] = gText_PokenavRibbons_MonListButtons,
|
|
[HELPBAR_RIBBONS_LIST] = gText_PokenavRibbons_RibbonListButtons,
|
|
[HELPBAR_RIBBONS_CHECK] = gText_PokenavRibbons_RibbonCheckButtons,
|
|
};
|
|
|
|
static const u8 sHelpBarTextColors[3] =
|
|
{
|
|
TEXT_COLOR_RED, TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY
|
|
};
|
|
|
|
static const struct CompressedSpriteSheet gSpinningPokenavSpriteSheet[] =
|
|
{
|
|
{
|
|
.data = sSpinningPokenav_Gfx,
|
|
.size = 0x1000,
|
|
.tag = 0,
|
|
}
|
|
};
|
|
|
|
static const struct SpritePalette gSpinningNavgearPalettes[] =
|
|
{
|
|
{
|
|
.data = sSpinningPokenav_Pal,
|
|
.tag = 0,
|
|
},
|
|
{}
|
|
};
|
|
|
|
static const struct CompressedSpriteSheet sMenuLeftHeaderSpriteSheet =
|
|
{
|
|
.data = gPokenavLeftHeaderHoennMap_Gfx, // Hoenn map is the first of the headers listed
|
|
.size = 0xC00,
|
|
.tag = 2
|
|
};
|
|
|
|
static const struct CompressedSpriteSheet sMenuLeftHeaderSpriteSheets[] =
|
|
{
|
|
[POKENAV_GFX_MAIN_MENU] = {
|
|
.data = gPokenavLeftHeaderMainMenu_Gfx,
|
|
.size = 0x20,
|
|
.tag = 3
|
|
},
|
|
[POKENAV_GFX_CONDITION_MENU] = {
|
|
.data = gPokenavLeftHeaderCondition_Gfx,
|
|
.size = 0x20,
|
|
.tag = 1
|
|
},
|
|
[POKENAV_GFX_RIBBONS_MENU] = {
|
|
.data = gPokenavLeftHeaderRibbons_Gfx,
|
|
.size = 0x20,
|
|
.tag = 2
|
|
},
|
|
[POKENAV_GFX_MATCH_CALL_MENU] = {
|
|
.data = gPokenavLeftHeaderMatchCall_Gfx,
|
|
.size = 0x20,
|
|
.tag = 4
|
|
},
|
|
[POKENAV_GFX_MAP_MENU_ZOOMED_OUT] = {
|
|
.data = gPokenavLeftHeaderHoennMap_Gfx,
|
|
.size = 0x20,
|
|
.tag = 0
|
|
},
|
|
[POKENAV_GFX_MAP_MENU_ZOOMED_IN] = {
|
|
.data = gPokenavLeftHeaderHoennMap_Gfx,
|
|
.size = 0x40,
|
|
.tag = 0
|
|
}
|
|
};
|
|
|
|
static const struct CompressedSpriteSheetNoSize sPokenavSubMenuLeftHeaderSpriteSheets[] =
|
|
{
|
|
[POKENAV_GFX_PARTY_MENU - POKENAV_GFX_SUBMENUS_START] = {
|
|
.data = gPokenavLeftHeaderParty_Gfx,
|
|
.tag = 1
|
|
},
|
|
[POKENAV_GFX_SEARCH_MENU - POKENAV_GFX_SUBMENUS_START] = {
|
|
.data = gPokenavLeftHeaderSearch_Gfx,
|
|
.tag = 1
|
|
},
|
|
[POKENAV_GFX_COOL_MENU - POKENAV_GFX_SUBMENUS_START] = {
|
|
.data = gPokenavLeftHeaderCool_Gfx,
|
|
.tag = 4
|
|
},
|
|
[POKENAV_GFX_BEAUTY_MENU - POKENAV_GFX_SUBMENUS_START] = {
|
|
.data = gPokenavLeftHeaderBeauty_Gfx,
|
|
.tag = 1
|
|
},
|
|
[POKENAV_GFX_CUTE_MENU - POKENAV_GFX_SUBMENUS_START] = {
|
|
.data = gPokenavLeftHeaderCute_Gfx,
|
|
.tag = 2
|
|
},
|
|
[POKENAV_GFX_SMART_MENU - POKENAV_GFX_SUBMENUS_START] = {
|
|
.data = gPokenavLeftHeaderSmart_Gfx,
|
|
.tag = 0
|
|
},
|
|
[POKENAV_GFX_TOUGH_MENU - POKENAV_GFX_SUBMENUS_START] = {
|
|
.data = gPokenavLeftHeaderTough_Gfx,
|
|
.tag = 0
|
|
}
|
|
};
|
|
|
|
static const struct OamData sSpinningPokenavSpriteOam =
|
|
{
|
|
.y = 0,
|
|
.affineMode = ST_OAM_AFFINE_OFF,
|
|
.objMode = ST_OAM_OBJ_NORMAL,
|
|
.bpp = ST_OAM_4BPP,
|
|
.shape = SPRITE_SHAPE(32x32),
|
|
.x = 0,
|
|
.size = SPRITE_SIZE(32x32),
|
|
.tileNum = 0,
|
|
.priority = 0,
|
|
.paletteNum = 0,
|
|
};
|
|
|
|
static const union AnimCmd sSpinningPokenavAnims[] =
|
|
{
|
|
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 sSpinningPokenavAnimTable[] =
|
|
{
|
|
sSpinningPokenavAnims
|
|
};
|
|
|
|
static const struct SpriteTemplate sSpinningPokenavSpriteTemplate =
|
|
{
|
|
.tileTag = 0,
|
|
.paletteTag = 0,
|
|
.oam = &sSpinningPokenavSpriteOam,
|
|
.anims = sSpinningPokenavAnimTable,
|
|
.images = NULL,
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
|
.callback = SpriteCB_SpinningPokenav
|
|
};
|
|
|
|
static const struct OamData sOamData_LeftHeader =
|
|
{
|
|
.y = 0,
|
|
.affineMode = ST_OAM_AFFINE_OFF,
|
|
.objMode = ST_OAM_OBJ_NORMAL,
|
|
.bpp = ST_OAM_4BPP,
|
|
.shape = SPRITE_SHAPE(64x32),
|
|
.x = 0,
|
|
.size = SPRITE_SIZE(64x32),
|
|
.tileNum = 0,
|
|
.priority = 1,
|
|
.paletteNum = 0,
|
|
};
|
|
|
|
static const struct OamData sOamData_SubmenuLeftHeader =
|
|
{
|
|
.y = 0,
|
|
.affineMode = ST_OAM_AFFINE_OFF,
|
|
.objMode = ST_OAM_OBJ_NORMAL,
|
|
.bpp = ST_OAM_4BPP,
|
|
.shape = SPRITE_SHAPE(32x16),
|
|
.x = 0,
|
|
.matrixNum = 0,
|
|
.size = SPRITE_SIZE(32x16),
|
|
.tileNum = 0,
|
|
.priority = 1,
|
|
.paletteNum = 0,
|
|
};
|
|
|
|
static const struct SpriteTemplate sLeftHeaderSpriteTemplate =
|
|
{
|
|
.tileTag = 2,
|
|
.paletteTag = 1,
|
|
.oam = &sOamData_LeftHeader,
|
|
.anims = gDummySpriteAnimTable,
|
|
.images = NULL,
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
|
.callback = SpriteCallbackDummy
|
|
};
|
|
|
|
static const struct SpriteTemplate sSubmenuLeftHeaderSpriteTemplate =
|
|
{
|
|
.tileTag = 2,
|
|
.paletteTag = 2,
|
|
.oam = &sOamData_SubmenuLeftHeader,
|
|
.anims = gDummySpriteAnimTable,
|
|
.images = NULL,
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
|
.callback = SpriteCallbackDummy
|
|
};
|
|
|
|
bool32 InitPokenavMainMenu(void)
|
|
{
|
|
struct Pokenav_MainMenu *menu;
|
|
|
|
menu = AllocSubstruct(POKENAV_SUBSTRUCT_MAIN_MENU, sizeof(struct Pokenav_MainMenu));
|
|
if (menu == NULL)
|
|
return FALSE;
|
|
|
|
ResetSpriteData();
|
|
FreeAllSpritePalettes();
|
|
menu->currentTaskId = CreateLoopedTask(LoopedTask_InitPokenavMenu, 1);
|
|
return TRUE;
|
|
}
|
|
|
|
u32 PokenavMainMenuLoopedTaskIsActive(void)
|
|
{
|
|
struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
return IsLoopedTaskActive(menu->currentTaskId);
|
|
}
|
|
|
|
void ShutdownPokenav(void)
|
|
{
|
|
PlaySE(SE_POKENAV_OFF);
|
|
ResetBldCnt_();
|
|
BeginNormalPaletteFade(PALETTES_ALL, -1, 0, 16, RGB_BLACK);
|
|
}
|
|
|
|
bool32 WaitForPokenavShutdownFade(void)
|
|
{
|
|
if (!gPaletteFade.active)
|
|
{
|
|
FreeMenuHandlerSubstruct2();
|
|
CleanupPokenavMainMenuResources();
|
|
FreeAllWindowBuffers();
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static u32 LoopedTask_InitPokenavMenu(s32 state)
|
|
{
|
|
struct Pokenav_MainMenu *menu;
|
|
|
|
switch (state)
|
|
{
|
|
case 0:
|
|
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
|
|
FreeAllWindowBuffers();
|
|
ResetBgsAndClearDma3BusyFlags(0);
|
|
InitBgsFromTemplates(0, gPokenavMainMenuBgTemplates, ARRAY_COUNT(gPokenavMainMenuBgTemplates));
|
|
ResetBgPositions();
|
|
ResetTempTileDataBuffers();
|
|
return LT_INC_AND_CONTINUE;
|
|
case 1:
|
|
menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
DecompressAndCopyTileDataToVram(0, &gPokenavHeader_Gfx, 0, 0, 0);
|
|
SetBgTilemapBuffer(0, menu->tilemapBuffer);
|
|
CopyToBgTilemapBuffer(0, &gPokenavHeader_Tilemap, 0, 0);
|
|
CopyPaletteIntoBufferUnfaded(gPokenavHeader_Pal, 0, 0x20);
|
|
CopyBgTilemapBufferToVram(0);
|
|
return LT_INC_AND_PAUSE;
|
|
case 2:
|
|
if (FreeTempTileDataBuffersIfPossible())
|
|
return LT_PAUSE;
|
|
|
|
InitHelpBar();
|
|
return LT_INC_AND_PAUSE;
|
|
case 3:
|
|
if (IsDma3ManagerBusyWithBgCopy())
|
|
return LT_PAUSE;
|
|
|
|
InitPokenavMainMenuResources();
|
|
CreateLeftHeaderSprites();
|
|
ShowBg(0);
|
|
return LT_FINISH;
|
|
default:
|
|
return LT_FINISH;
|
|
}
|
|
}
|
|
|
|
void SetActiveMenuLoopTasks(void *createLoopTask, void *isLoopTaskActive) // Fix types later.
|
|
{
|
|
struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
menu->loopTask = createLoopTask;
|
|
menu->isLoopTaskActiveFunc = isLoopTaskActive;
|
|
menu->unused = 0;
|
|
}
|
|
|
|
void RunMainMenuLoopedTask(u32 state)
|
|
{
|
|
struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
menu->unused = 0;
|
|
menu->loopTask(state);
|
|
}
|
|
|
|
u32 IsActiveMenuLoopTaskActive(void)
|
|
{
|
|
struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
return menu->isLoopTaskActiveFunc();
|
|
}
|
|
|
|
void SlideMenuHeaderUp(void)
|
|
{
|
|
struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
menu->currentTaskId = CreateLoopedTask(LoopedTask_SlideMenuHeaderUp, 4);
|
|
}
|
|
|
|
void SlideMenuHeaderDown(void)
|
|
{
|
|
struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
menu->currentTaskId = CreateLoopedTask(LoopedTask_SlideMenuHeaderDown, 4);
|
|
}
|
|
|
|
bool32 MainMenuLoopedTaskIsBusy(void)
|
|
{
|
|
struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
return IsLoopedTaskActive(menu->currentTaskId);
|
|
}
|
|
|
|
static u32 LoopedTask_SlideMenuHeaderUp(s32 state)
|
|
{
|
|
switch (state)
|
|
{
|
|
default:
|
|
return LT_FINISH;
|
|
case 1:
|
|
return LT_INC_AND_PAUSE;
|
|
case 0:
|
|
return LT_INC_AND_PAUSE;
|
|
case 2:
|
|
if (ChangeBgY(0, 384, BG_COORD_ADD) >= 0x2000u)
|
|
{
|
|
ChangeBgY(0, 0x2000, BG_COORD_SET);
|
|
return LT_FINISH;
|
|
}
|
|
|
|
return LT_PAUSE;
|
|
}
|
|
}
|
|
|
|
static u32 LoopedTask_SlideMenuHeaderDown(s32 state)
|
|
{
|
|
if (ChangeBgY(0, 384, BG_COORD_SUB) <= 0)
|
|
{
|
|
ChangeBgY(0, 0, BG_COORD_SET);
|
|
return LT_FINISH;
|
|
}
|
|
return LT_PAUSE;
|
|
}
|
|
|
|
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 PokenavFillPalette(u32 palIndex, u16 fillValue)
|
|
{
|
|
CpuFill16(fillValue, gPlttBufferFaded + 0x100 + (palIndex * 16), 16 * sizeof(u16));
|
|
}
|
|
|
|
void PokenavCopyPalette(const u16 *src, const u16 *dest, int size, int a3, int a4, u16 *palette)
|
|
{
|
|
if (a4 == 0)
|
|
{
|
|
CpuCopy16(src, palette, size * 2);
|
|
}
|
|
else if (a4 >= a3)
|
|
{
|
|
CpuCopy16(dest, palette, size * 2);
|
|
}
|
|
else
|
|
{
|
|
int r, g, b;
|
|
int r1, g1, b1;
|
|
while (size--)
|
|
{
|
|
r = GET_R(*src);
|
|
g = GET_G(*src);
|
|
b = GET_B(*src);
|
|
|
|
r1 = ((((GET_R(*dest) << 8) - (r << 8)) / a3) * a4) >> 8;
|
|
g1 = ((((GET_G(*dest) << 8) - (g << 8)) / a3) * a4) >> 8;
|
|
b1 = ((((GET_B(*dest) << 8) - (b << 8)) / a3) * a4) >> 8;
|
|
|
|
r = (r + r1) & 0x1F; //_RGB(r + r1, g + g1, b + b1); doesn't match
|
|
g = (g + g1) & 0x1F;
|
|
b = (b + b1) & 0x1F;
|
|
|
|
*palette = RGB2(r, g, b);
|
|
|
|
src++, dest++;
|
|
palette++;
|
|
}
|
|
}
|
|
}
|
|
|
|
void PokenavFadeScreen(s32 fadeType)
|
|
{
|
|
struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
switch (fadeType)
|
|
{
|
|
case POKENAV_FADE_TO_BLACK:
|
|
BeginNormalPaletteFade(menu->palettes, -2, 0, 16, RGB_BLACK);
|
|
break;
|
|
case POKENAV_FADE_FROM_BLACK:
|
|
BeginNormalPaletteFade(menu->palettes, -2, 16, 0, RGB_BLACK);
|
|
break;
|
|
case POKENAV_FADE_TO_BLACK_ALL:
|
|
BeginNormalPaletteFade(PALETTES_ALL, -2, 0, 16, RGB_BLACK);
|
|
break;
|
|
case POKENAV_FADE_FROM_BLACK_ALL:
|
|
BeginNormalPaletteFade(PALETTES_ALL, -2, 16, 0, RGB_BLACK);
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool32 IsPaletteFadeActive(void)
|
|
{
|
|
return gPaletteFade.active;
|
|
}
|
|
|
|
// Excludes the first obj and bg palettes
|
|
void FadeToBlackExceptPrimary(void)
|
|
{
|
|
BlendPalettes(PALETTES_ALL & ~(1 << 16 | 1), 16, RGB_BLACK);
|
|
}
|
|
|
|
void InitBgTemplates(const struct BgTemplate *templates, int count)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < count; i++)
|
|
InitBgFromTemplate(templates++);
|
|
}
|
|
|
|
static void InitHelpBar(void)
|
|
{
|
|
struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
InitWindows(&sHelpBarWindowTemplate[0]);
|
|
menu->helpBarWindowId = 0;
|
|
DrawHelpBar(menu->helpBarWindowId);
|
|
PutWindowTilemap(menu->helpBarWindowId);
|
|
CopyWindowToVram(menu->helpBarWindowId, COPYWIN_FULL);
|
|
}
|
|
|
|
void PrintHelpBarText(u32 textId)
|
|
{
|
|
struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
DrawHelpBar(menu->helpBarWindowId);
|
|
AddTextPrinterParameterized3(menu->helpBarWindowId, FONT_NORMAL, 0, 1, sHelpBarTextColors, 0, sHelpBarTexts[textId]);
|
|
}
|
|
|
|
bool32 WaitForHelpBar(void)
|
|
{
|
|
return IsDma3ManagerBusyWithBgCopy();
|
|
}
|
|
|
|
static void DrawHelpBar(u32 windowId)
|
|
{
|
|
FillWindowPixelBuffer(windowId, PIXEL_FILL(4));
|
|
FillWindowPixelRect(windowId, PIXEL_FILL(5), 0, 0, 0x80, 1);
|
|
}
|
|
|
|
static void InitPokenavMainMenuResources(void)
|
|
{
|
|
s32 i;
|
|
u8 spriteId;
|
|
struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
for (i = 0; i < ARRAY_COUNT(gSpinningPokenavSpriteSheet); i++)
|
|
LoadCompressedSpriteSheet(&gSpinningPokenavSpriteSheet[i]);
|
|
|
|
Pokenav_AllocAndLoadPalettes(gSpinningNavgearPalettes);
|
|
menu->palettes = ~1 & ~(0x10000 << IndexOfSpritePaletteTag(0));
|
|
spriteId = CreateSprite(&sSpinningPokenavSpriteTemplate, 220, 12, 0);
|
|
menu->spinningPokenav = &gSprites[spriteId];
|
|
}
|
|
|
|
static void CleanupPokenavMainMenuResources(void)
|
|
{
|
|
struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
DestroySprite(menu->spinningPokenav);
|
|
FreeSpriteTilesByTag(0);
|
|
FreeSpritePaletteByTag(0);
|
|
}
|
|
|
|
static void SpriteCB_SpinningPokenav(struct Sprite *sprite)
|
|
{
|
|
// If the background starts scrolling, follow it.
|
|
sprite->y2 = (GetBgY(0) / 256u) * -1;
|
|
}
|
|
|
|
struct Sprite *GetSpinningPokenavSprite(void)
|
|
{
|
|
struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
menu->spinningPokenav->callback = SpriteCallbackDummy;
|
|
return menu->spinningPokenav;
|
|
}
|
|
|
|
void HideSpinningPokenavSprite(void)
|
|
{
|
|
struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
// Move sprite so it's no longer visible
|
|
menu->spinningPokenav->x = 220;
|
|
menu->spinningPokenav->y = 12;
|
|
menu->spinningPokenav->callback = SpriteCB_SpinningPokenav;
|
|
menu->spinningPokenav->invisible = FALSE;
|
|
menu->spinningPokenav->oam.priority = 0;
|
|
menu->spinningPokenav->subpriority = 0;
|
|
}
|
|
|
|
static void CreateLeftHeaderSprites(void)
|
|
{
|
|
s32 i, spriteId;
|
|
struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
LoadCompressedSpriteSheet(&sMenuLeftHeaderSpriteSheet);
|
|
AllocSpritePalette(1);
|
|
AllocSpritePalette(2);
|
|
for (i = 0; i < (s32)ARRAY_COUNT(menu->leftHeaderSprites); i++)
|
|
{
|
|
// Create main left header
|
|
spriteId = CreateSprite(&sLeftHeaderSpriteTemplate, 0, 0, 1);
|
|
menu->leftHeaderSprites[i] = &gSprites[spriteId];
|
|
menu->leftHeaderSprites[i]->invisible = TRUE;
|
|
menu->leftHeaderSprites[i]->x2 = i * 64;
|
|
|
|
// Create submenu left header
|
|
spriteId = CreateSprite(&sSubmenuLeftHeaderSpriteTemplate, 0, 0, 2);
|
|
menu->submenuLeftHeaderSprites[i] = &gSprites[spriteId];
|
|
menu->submenuLeftHeaderSprites[i]->invisible = TRUE;
|
|
menu->submenuLeftHeaderSprites[i]->x2 = i * 32;
|
|
menu->submenuLeftHeaderSprites[i]->y2 = 18;
|
|
menu->submenuLeftHeaderSprites[i]->oam.tileNum += (i * 8) + 64;
|
|
}
|
|
}
|
|
|
|
void LoadLeftHeaderGfxForIndex(u32 menuGfxId)
|
|
{
|
|
if (menuGfxId < POKENAV_GFX_SUBMENUS_START)
|
|
LoadLeftHeaderGfxForMenu(menuGfxId);
|
|
else
|
|
LoadLeftHeaderGfxForSubMenu(menuGfxId - POKENAV_GFX_SUBMENUS_START);
|
|
}
|
|
|
|
void UpdateRegionMapRightHeaderTiles(u32 menuGfxId)
|
|
{
|
|
struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
if (menuGfxId == POKENAV_GFX_MAP_MENU_ZOOMED_OUT)
|
|
menu->leftHeaderSprites[1]->oam.tileNum = GetSpriteTileStartByTag(2) + 32;
|
|
else
|
|
menu->leftHeaderSprites[1]->oam.tileNum = GetSpriteTileStartByTag(2) + 64;
|
|
}
|
|
|
|
static void LoadLeftHeaderGfxForMenu(u32 menuGfxId)
|
|
{
|
|
struct Pokenav_MainMenu *menu;
|
|
u32 size, tag;
|
|
|
|
if (menuGfxId >= POKENAV_GFX_SUBMENUS_START)
|
|
return;
|
|
|
|
menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
tag = sMenuLeftHeaderSpriteSheets[menuGfxId].tag;
|
|
size = GetDecompressedDataSize(sMenuLeftHeaderSpriteSheets[menuGfxId].data);
|
|
LoadPalette(&gPokenavLeftHeader_Pal[tag * 16], (IndexOfSpritePaletteTag(1) * 16) + 0x100, 0x20);
|
|
LZ77UnCompWram(sMenuLeftHeaderSpriteSheets[menuGfxId].data, gDecompressionBuffer);
|
|
RequestDma3Copy(gDecompressionBuffer, (void *)OBJ_VRAM0 + (GetSpriteTileStartByTag(2) * 32), size, 1);
|
|
menu->leftHeaderSprites[1]->oam.tileNum = GetSpriteTileStartByTag(2) + sMenuLeftHeaderSpriteSheets[menuGfxId].size;
|
|
|
|
if (menuGfxId == POKENAV_GFX_MAP_MENU_ZOOMED_OUT || menuGfxId == POKENAV_GFX_MAP_MENU_ZOOMED_IN)
|
|
menu->leftHeaderSprites[1]->x2 = 56;
|
|
else
|
|
menu->leftHeaderSprites[1]->x2 = 64;
|
|
}
|
|
|
|
static void LoadLeftHeaderGfxForSubMenu(u32 menuGfxId)
|
|
{
|
|
u32 size, tag;
|
|
|
|
if (menuGfxId >= POKENAV_GFX_MENUS_END - POKENAV_GFX_SUBMENUS_START)
|
|
return;
|
|
|
|
tag = sPokenavSubMenuLeftHeaderSpriteSheets[menuGfxId].tag;
|
|
size = GetDecompressedDataSize(sPokenavSubMenuLeftHeaderSpriteSheets[menuGfxId].data);
|
|
LoadPalette(&gPokenavLeftHeader_Pal[tag * 16], (IndexOfSpritePaletteTag(2) * 16) + 0x100, 0x20);
|
|
LZ77UnCompWram(sPokenavSubMenuLeftHeaderSpriteSheets[menuGfxId].data, &gDecompressionBuffer[0x1000]);
|
|
RequestDma3Copy(&gDecompressionBuffer[0x1000], (void *)OBJ_VRAM0 + 0x800 + (GetSpriteTileStartByTag(2) * 32), size, 1);
|
|
}
|
|
|
|
void ShowLeftHeaderGfx(u32 menuGfxId, bool32 isMain, bool32 isOnRightSide)
|
|
{
|
|
u32 tileTop;
|
|
|
|
if (!isMain)
|
|
tileTop = 0x30;
|
|
else
|
|
tileTop = 0x10;
|
|
|
|
if (menuGfxId < POKENAV_GFX_SUBMENUS_START)
|
|
ShowLeftHeaderSprites(tileTop, isOnRightSide);
|
|
else
|
|
ShowLeftHeaderSubmenuSprites(tileTop, isOnRightSide);
|
|
}
|
|
|
|
void HideMainOrSubMenuLeftHeader(u32 id, bool32 onRightSide)
|
|
{
|
|
if (id < POKENAV_GFX_PARTY_MENU)
|
|
HideLeftHeaderSprites(onRightSide);
|
|
else
|
|
HideLeftHeaderSubmenuSprites(onRightSide);
|
|
}
|
|
|
|
void SetLeftHeaderSpritesInvisibility(void)
|
|
{
|
|
s32 i;
|
|
struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
for (i = 0; i < (s32)ARRAY_COUNT(menu->leftHeaderSprites); i++)
|
|
{
|
|
menu->leftHeaderSprites[i]->invisible = TRUE;
|
|
menu->submenuLeftHeaderSprites[i]->invisible = TRUE;
|
|
}
|
|
}
|
|
|
|
bool32 AreLeftHeaderSpritesMoving(void)
|
|
{
|
|
struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
if (menu->leftHeaderSprites[0]->callback == SpriteCallbackDummy && menu->submenuLeftHeaderSprites[0]->callback == SpriteCallbackDummy)
|
|
return FALSE;
|
|
else
|
|
return TRUE;
|
|
}
|
|
|
|
static void ShowLeftHeaderSprites(u32 startY, bool32 isOnRightSide)
|
|
{
|
|
s32 start, end, i;
|
|
struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
if (!isOnRightSide)
|
|
start = -96, end = 32;
|
|
else
|
|
start = 256, end = 160;
|
|
|
|
for (i = 0; i < (s32)ARRAY_COUNT(menu->leftHeaderSprites); i++)
|
|
{
|
|
menu->leftHeaderSprites[i]->y = startY;
|
|
MoveLeftHeader(menu->leftHeaderSprites[i], start, end, 12);
|
|
}
|
|
}
|
|
|
|
static void ShowLeftHeaderSubmenuSprites(u32 startY, bool32 isOnRightSide)
|
|
{
|
|
s32 start, end, i;
|
|
struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
if (!isOnRightSide)
|
|
start = -96, end = 16;
|
|
else
|
|
start = 256, end = 192;
|
|
|
|
for (i = 0; i < (s32)ARRAY_COUNT(menu->submenuLeftHeaderSprites); i++)
|
|
{
|
|
menu->submenuLeftHeaderSprites[i]->y = startY;
|
|
MoveLeftHeader(menu->submenuLeftHeaderSprites[i], start, end, 12);
|
|
}
|
|
}
|
|
|
|
static void HideLeftHeaderSprites(bool32 isOnRightSide)
|
|
{
|
|
s32 start, end, i;
|
|
struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
if (!isOnRightSide)
|
|
start = 32, end = -96;
|
|
else
|
|
start = 192, end = 256;
|
|
|
|
for (i = 0; i < (s32)ARRAY_COUNT(menu->leftHeaderSprites); i++)
|
|
{
|
|
MoveLeftHeader(menu->leftHeaderSprites[i], start, end, 12);
|
|
}
|
|
}
|
|
|
|
static void HideLeftHeaderSubmenuSprites(bool32 isOnRightSide)
|
|
{
|
|
s32 start, end, i;
|
|
struct Pokenav_MainMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
if (!isOnRightSide)
|
|
start = 16, end = -96;
|
|
else
|
|
start = 192, end = 256;
|
|
|
|
for (i = 0; i < (s32)ARRAY_COUNT(menu->submenuLeftHeaderSprites); i++)
|
|
{
|
|
MoveLeftHeader(menu->submenuLeftHeaderSprites[i], start, end, 12);
|
|
}
|
|
}
|
|
|
|
static void MoveLeftHeader(struct Sprite *sprite, s32 startX, s32 endX, s32 duration)
|
|
{
|
|
sprite->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;
|
|
}
|
|
|
|
static void SpriteCB_MoveLeftHeader(struct Sprite *sprite)
|
|
{
|
|
if (sprite->data[2] != 0)
|
|
{
|
|
sprite->data[2]--;
|
|
sprite->data[0] += sprite->data[1];
|
|
sprite->x = sprite->data[0] >> 4;
|
|
if (sprite->x < -16 || sprite->x > 256)
|
|
sprite->invisible = TRUE;
|
|
else
|
|
sprite->invisible = FALSE;
|
|
}
|
|
else
|
|
{
|
|
sprite->x = sprite->data[7];
|
|
sprite->callback = SpriteCallbackDummy;
|
|
}
|
|
}
|