mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-29 13:50:42 +01:00
847 lines
24 KiB
C
847 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 PokenavMainMenuResources
|
|
{
|
|
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[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;
|
|
};
|
|
|
|
static void CleanupPokenavMainMenuResources(void);
|
|
static void LoadLeftHeaderGfxForSubMenu(u32 arg0);
|
|
static void LoadLeftHeaderGfxForMenu(u32 index);
|
|
static void HideLeftHeaderSubmenuSprites(bool32 isOnRightSide);
|
|
static void HideLeftHeaderSprites(bool32 isOnRightSide);
|
|
static void ShowLeftHeaderSprites(u32 startY, bool32 isOnRightSide);
|
|
static void ShowLeftHeaderSubmenuSprites(u32 startY, bool32 isOnRightSide);
|
|
static void MoveLeftHeader(struct Sprite *sprite, s32 startX, s32 endX, s32 duration);
|
|
static void SpriteCB_MoveLeftHeader(struct Sprite *sprite);
|
|
static void InitPokenavMainMenuResources(void);
|
|
static void InitHoennMapHeaderSprites(void);
|
|
static void InitHelpBar(void);
|
|
static u32 LoopedTask_SlideMenuHeaderUp(s32 a0);
|
|
static u32 LoopedTask_SlideMenuHeaderDown(s32 a0);
|
|
static void DrawHelpBar(u32 windowId);
|
|
static void SpriteCB_SpinningPokenav(struct Sprite* sprite);
|
|
static u32 LoopedTask_InitPokenavMenu(s32 a0);
|
|
|
|
const u16 gSpinningPokenavPaletteData[] = INCBIN_U16("graphics/pokenav/icon2.gbapal");
|
|
const u32 gSpinningPokenavGfx[] = INCBIN_U32("graphics/pokenav/icon2.4bpp.lz");
|
|
const u32 gUnused_SpinningPokenavGfx2[] = 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,
|
|
}
|
|
};
|
|
|
|
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 = gSpinningPokenavGfx,
|
|
.size = 0x1000,
|
|
.tag = 0,
|
|
}
|
|
};
|
|
|
|
static const struct SpritePalette gSpinningNavgearPalettes[] =
|
|
{
|
|
{
|
|
.data = gSpinningPokenavPaletteData,
|
|
.tag = 0,
|
|
},
|
|
{}
|
|
};
|
|
|
|
static const struct CompressedSpriteSheet sPokenavHoennMapLeftHeaderSpriteSheet =
|
|
{
|
|
.data = gPokenavLeftHeaderHoennMap_Gfx,
|
|
.size = 0xC00,
|
|
.tag = 2
|
|
};
|
|
|
|
static const struct CompressedSpriteSheet sPokenavMenuLeftHeaderSpriteSheets[] =
|
|
{
|
|
[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 sPokenavLeftHeaderHoennMapSpriteOam =
|
|
{
|
|
.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 sUnknown_0861FB24 =
|
|
{
|
|
.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 sPokenavLeftHeaderHoennMapSpriteTemplate =
|
|
{
|
|
.tileTag = 2,
|
|
.paletteTag = 1,
|
|
.oam = &sPokenavLeftHeaderHoennMapSpriteOam,
|
|
.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(POKENAV_SUBSTRUCT_MAIN_MENU, 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(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
return IsLoopedTaskActive(structPtr->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 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();
|
|
ResetTempTileDataBuffers();
|
|
return LT_INC_AND_CONTINUE;
|
|
case 1:
|
|
structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
DecompressAndCopyTileDataToVram(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 (FreeTempTileDataBuffersIfPossible())
|
|
return LT_PAUSE;
|
|
|
|
InitHelpBar();
|
|
return LT_INC_AND_PAUSE;
|
|
case 3:
|
|
if (IsDma3ManagerBusyWithBgCopy())
|
|
return LT_PAUSE;
|
|
|
|
InitPokenavMainMenuResources();
|
|
InitHoennMapHeaderSprites();
|
|
ShowBg(0);
|
|
return LT_FINISH;
|
|
default:
|
|
return LT_FINISH;
|
|
}
|
|
}
|
|
|
|
void SetActiveMenuLoopTasks(void *createLoopTask, void *isLoopTaskActive) // Fix types later.
|
|
{
|
|
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
structPtr->loopTask = createLoopTask;
|
|
structPtr->isLoopTaskActiveFunc = isLoopTaskActive;
|
|
structPtr->unused = 0;
|
|
}
|
|
|
|
void RunMainMenuLoopedTask(u32 a0)
|
|
{
|
|
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
structPtr->unused = 0;
|
|
structPtr->loopTask(a0);
|
|
}
|
|
|
|
u32 IsActiveMenuLoopTaskActive(void)
|
|
{
|
|
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
return structPtr->isLoopTaskActiveFunc();
|
|
}
|
|
|
|
void SlideMenuHeaderUp(void)
|
|
{
|
|
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
structPtr->currentTaskId = CreateLoopedTask(LoopedTask_SlideMenuHeaderUp, 4);
|
|
}
|
|
|
|
void SlideMenuHeaderDown(void)
|
|
{
|
|
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
structPtr->currentTaskId = CreateLoopedTask(LoopedTask_SlideMenuHeaderDown, 4);
|
|
}
|
|
|
|
bool32 MainMenuLoopedTaskIsBusy(void)
|
|
{
|
|
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
return IsLoopedTaskActive(structPtr->currentTaskId);
|
|
}
|
|
|
|
static u32 LoopedTask_SlideMenuHeaderUp(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;
|
|
}
|
|
}
|
|
|
|
static u32 LoopedTask_SlideMenuHeaderDown(s32 a0)
|
|
{
|
|
if (ChangeBgY(0, 384, 2) <= 0)
|
|
{
|
|
ChangeBgY(0, 0, 0);
|
|
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; I have to assign the value of ((r + r1) & 0x1F) to r
|
|
g = (g + g1) & 0x1F; //See above
|
|
b = (b + b1) & 0x1F; //See above
|
|
|
|
*palette = RGB2(r, g, b); //See above comment
|
|
|
|
src++, dest++;
|
|
palette++;
|
|
}
|
|
}
|
|
}
|
|
|
|
void PokenavFadeScreen(s32 fadeType)
|
|
{
|
|
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
switch (fadeType)
|
|
{
|
|
case 0:
|
|
BeginNormalPaletteFade(structPtr->palettes, -2, 0, 16, RGB_BLACK);
|
|
break;
|
|
case 1:
|
|
BeginNormalPaletteFade(structPtr->palettes, -2, 16, 0, RGB_BLACK);
|
|
break;
|
|
case 2:
|
|
BeginNormalPaletteFade(PALETTES_ALL, -2, 0, 16, RGB_BLACK);
|
|
break;
|
|
case 3:
|
|
BeginNormalPaletteFade(PALETTES_ALL, -2, 16, 0, RGB_BLACK);
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool32 IsPaletteFadeActive(void)
|
|
{
|
|
return gPaletteFade.active;
|
|
}
|
|
|
|
void sub_81C7B40(void)
|
|
{
|
|
BlendPalettes(PALETTES_ALL & ~(0x10000 | 0x1), 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 PokenavMainMenuResources *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
InitWindows(&sHelpBarWindowTemplate[0]);
|
|
structPtr->helpBarWindowId = 0;
|
|
DrawHelpBar(structPtr->helpBarWindowId);
|
|
PutWindowTilemap(structPtr->helpBarWindowId);
|
|
CopyWindowToVram(structPtr->helpBarWindowId, 3); // TODO: Use a defined constant here.
|
|
}
|
|
|
|
void PrintHelpBarText(u32 textId)
|
|
{
|
|
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
DrawHelpBar(structPtr->helpBarWindowId);
|
|
AddTextPrinterParameterized3(structPtr->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 PokenavMainMenuResources *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
for (i = 0; i < ARRAY_COUNT(gSpinningPokenavSpriteSheet); i++)
|
|
LoadCompressedSpriteSheet(&gSpinningPokenavSpriteSheet[i]);
|
|
|
|
Pokenav_AllocAndLoadPalettes(gSpinningNavgearPalettes);
|
|
structPtr->palettes = ~1 & ~(0x10000 << IndexOfSpritePaletteTag(0));
|
|
spriteId = CreateSprite(&sSpinningPokenavSpriteTemplate, 220, 12, 0);
|
|
structPtr->spinningPokenav = &gSprites[spriteId];
|
|
}
|
|
|
|
static void CleanupPokenavMainMenuResources(void)
|
|
{
|
|
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
DestroySprite(structPtr->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 *PauseSpinningPokenavSprite(void)
|
|
{
|
|
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
structPtr->spinningPokenav->callback = SpriteCallbackDummy;
|
|
return structPtr->spinningPokenav;
|
|
}
|
|
|
|
void ResumeSpinningPokenavSprite(void)
|
|
{
|
|
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
structPtr->spinningPokenav->x = 220;
|
|
structPtr->spinningPokenav->y = 12;
|
|
structPtr->spinningPokenav->callback = SpriteCB_SpinningPokenav;
|
|
structPtr->spinningPokenav->invisible = FALSE;
|
|
structPtr->spinningPokenav->oam.priority = 0;
|
|
structPtr->spinningPokenav->subpriority = 0;
|
|
}
|
|
|
|
static void InitHoennMapHeaderSprites(void)
|
|
{
|
|
s32 i, spriteId;
|
|
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
LoadCompressedSpriteSheet(&sPokenavHoennMapLeftHeaderSpriteSheet);
|
|
AllocSpritePalette(1);
|
|
AllocSpritePalette(2);
|
|
for (i = 0; i < (s32)ARRAY_COUNT(structPtr->leftHeaderSprites); i++)
|
|
{
|
|
spriteId = CreateSprite(&sPokenavLeftHeaderHoennMapSpriteTemplate, 0, 0, 1);
|
|
structPtr->leftHeaderSprites[i] = &gSprites[spriteId];
|
|
structPtr->leftHeaderSprites[i]->invisible = TRUE;
|
|
structPtr->leftHeaderSprites[i]->x2 = i * 64;
|
|
|
|
spriteId = CreateSprite(&sUnknown_0861FB44, 0, 0, 2);
|
|
structPtr->submenuLeftHeaderSprites[i] = &gSprites[spriteId];
|
|
structPtr->submenuLeftHeaderSprites[i]->invisible = TRUE;
|
|
structPtr->submenuLeftHeaderSprites[i]->x2 = i * 32;
|
|
structPtr->submenuLeftHeaderSprites[i]->y2 = 18;
|
|
structPtr->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 PokenavMainMenuResources *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
if (menuGfxId == POKENAV_GFX_MAP_MENU_ZOOMED_OUT)
|
|
structPtr->leftHeaderSprites[1]->oam.tileNum = GetSpriteTileStartByTag(2) + 32;
|
|
else
|
|
structPtr->leftHeaderSprites[1]->oam.tileNum = GetSpriteTileStartByTag(2) + 64;
|
|
}
|
|
|
|
static void LoadLeftHeaderGfxForMenu(u32 menuGfxId)
|
|
{
|
|
struct PokenavMainMenuResources *structPtr;
|
|
u32 size, tag;
|
|
|
|
if (menuGfxId >= POKENAV_GFX_SUBMENUS_START)
|
|
return;
|
|
|
|
structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
tag = sPokenavMenuLeftHeaderSpriteSheets[menuGfxId].tag;
|
|
size = GetDecompressedDataSize(sPokenavMenuLeftHeaderSpriteSheets[menuGfxId].data);
|
|
LoadPalette(&gPokenavLeftHeader_Pal[tag * 16], (IndexOfSpritePaletteTag(1) * 16) + 0x100, 0x20);
|
|
LZ77UnCompWram(sPokenavMenuLeftHeaderSpriteSheets[menuGfxId].data, gDecompressionBuffer);
|
|
RequestDma3Copy(gDecompressionBuffer, (void *)OBJ_VRAM0 + (GetSpriteTileStartByTag(2) * 32), size, 1);
|
|
structPtr->leftHeaderSprites[1]->oam.tileNum = GetSpriteTileStartByTag(2) + sPokenavMenuLeftHeaderSpriteSheets[menuGfxId].size;
|
|
|
|
if (menuGfxId == POKENAV_GFX_MAP_MENU_ZOOMED_OUT || menuGfxId == POKENAV_GFX_MAP_MENU_ZOOMED_IN)
|
|
structPtr->leftHeaderSprites[1]->x2 = 56;
|
|
else
|
|
structPtr->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 PokenavMainMenuResources *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
for (i = 0; i < (s32)ARRAY_COUNT(structPtr->leftHeaderSprites); i++)
|
|
{
|
|
structPtr->leftHeaderSprites[i]->invisible = TRUE;
|
|
structPtr->submenuLeftHeaderSprites[i]->invisible = TRUE;
|
|
}
|
|
}
|
|
|
|
bool32 AreLeftHeaderSpritesMoving(void)
|
|
{
|
|
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
if (structPtr->leftHeaderSprites[0]->callback == SpriteCallbackDummy && structPtr->submenuLeftHeaderSprites[0]->callback == SpriteCallbackDummy)
|
|
return FALSE;
|
|
else
|
|
return TRUE;
|
|
}
|
|
|
|
static void ShowLeftHeaderSprites(u32 startY, bool32 isOnRightSide)
|
|
{
|
|
s32 start, end, i;
|
|
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
if (!isOnRightSide)
|
|
start = -96, end = 32;
|
|
else
|
|
start = 256, end = 160;
|
|
|
|
for (i = 0; i < (s32)ARRAY_COUNT(structPtr->leftHeaderSprites); i++)
|
|
{
|
|
structPtr->leftHeaderSprites[i]->y = startY;
|
|
MoveLeftHeader(structPtr->leftHeaderSprites[i], start, end, 12);
|
|
}
|
|
}
|
|
|
|
static void ShowLeftHeaderSubmenuSprites(u32 startY, bool32 isOnRightSide)
|
|
{
|
|
s32 start, end, i;
|
|
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
if (!isOnRightSide)
|
|
start = -96, end = 16;
|
|
else
|
|
start = 256, end = 192;
|
|
|
|
for (i = 0; i < (s32)ARRAY_COUNT(structPtr->submenuLeftHeaderSprites); i++)
|
|
{
|
|
structPtr->submenuLeftHeaderSprites[i]->y = startY;
|
|
MoveLeftHeader(structPtr->submenuLeftHeaderSprites[i], start, end, 12);
|
|
}
|
|
}
|
|
|
|
static void HideLeftHeaderSprites(bool32 isOnRightSide)
|
|
{
|
|
s32 start, end, i;
|
|
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
static void HideLeftHeaderSubmenuSprites(bool32 isOnRightSide)
|
|
{
|
|
s32 start, end, i;
|
|
struct PokenavMainMenuResources *structPtr = GetSubstructPtr(POKENAV_SUBSTRUCT_MAIN_MENU);
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|