pokeemerald/src/pokenav_ribbons_summary.c

1271 lines
43 KiB
C
Raw Normal View History

2019-05-26 12:42:01 +02:00
#include "global.h"
#include "decompress.h"
#include "dynamic_placeholder_text_util.h"
2019-08-04 13:53:00 +02:00
#include "graphics.h"
2019-05-26 12:42:01 +02:00
#include "international_string_util.h"
#include "pokenav.h"
2019-08-04 13:53:00 +02:00
#include "sound.h"
2019-05-26 12:42:01 +02:00
#include "sprite.h"
#include "string_util.h"
2019-08-04 13:53:00 +02:00
#include "strings.h"
2019-05-26 12:42:01 +02:00
#include "text.h"
#include "trainer_pokemon_sprites.h"
#include "window.h"
2019-08-04 13:53:00 +02:00
#include "constants/songs.h"
2019-05-26 12:42:01 +02:00
2020-10-10 16:17:34 -06:00
enum
{
RIBBONS_SUMMARY_FUNC_NONE,
RIBBONS_SUMMARY_FUNC_SWITCH_MONS,
2020-10-10 16:17:34 -06:00
RIBBONS_SUMMARY_FUNC_SELECT_RIBBON,
RIBBONS_SUMMARY_FUNC_EXPANDED_CURSOR_MOVE,
RIBBONS_SUMMARY_FUNC_EXPANDED_CANCEL,
RIBBONS_SUMMARY_FUNC_EXIT,
};
#define GFXTAG_RIBBON_ICONS_BIG 9
#define PALTAG_RIBBON_ICONS_1 15
#define PALTAG_RIBBON_ICONS_2 16
#define PALTAG_RIBBON_ICONS_3 17
#define PALTAG_RIBBON_ICONS_4 18
#define PALTAG_RIBBON_ICONS_5 19
#define RIBBONS_PER_ROW 9
#define GIFT_RIBBON_ROW (1 + (FIRST_GIFT_RIBBON / RIBBONS_PER_ROW)) // Gift ribbons start on a new row after the normal ribbons.
#define GIFT_RIBBON_START_POS (RIBBONS_PER_ROW * GIFT_RIBBON_ROW)
#define MON_SPRITE_X_ON 40
#define MON_SPRITE_X_OFF -32
#define MON_SPRITE_Y 104
2021-11-09 12:50:35 -05:00
struct Pokenav_RibbonsSummaryList
2019-05-26 12:42:01 +02:00
{
u8 unused1[8];
2021-11-12 20:24:14 -05:00
struct PokenavMonList *monList;
u16 selectedPos;
u16 normalRibbonLastRowStart;
u16 numNormalRibbons;
u16 numGiftRibbons;
u32 ribbonIds[FIRST_GIFT_RIBBON];
u32 giftRibbonIds[NUM_GIFT_RIBBONS];
u32 unused2;
2021-11-09 12:50:35 -05:00
u32 (*callback)(struct Pokenav_RibbonsSummaryList *);
2019-05-26 12:42:01 +02:00
};
2021-11-09 12:50:35 -05:00
struct Pokenav_RibbonsSummaryMenu
2019-05-26 12:42:01 +02:00
{
2020-10-10 16:17:34 -06:00
u32 (*callback)(void);
2019-08-04 13:53:00 +02:00
u32 loopedTaskId;
2020-10-10 16:17:34 -06:00
u16 nameWindowId;
u16 ribbonCountWindowId;
u16 listIdxWindowId;
u16 unusedWindowId;
2020-10-10 16:17:34 -06:00
u16 monSpriteId;
struct Sprite *bigRibbonSprite;
u32 unused;
2019-08-04 13:53:00 +02:00
u8 tilemapBuffers[2][BG_SCREEN_SIZE];
2019-05-26 12:42:01 +02:00
};
// Used for the initial drawing of the ribbons
static u32 sRibbonDraw_Total;
static u32 sRibbonDraw_Current;
2021-11-09 12:50:35 -05:00
static void PrintCurrentMonRibbonCount(struct Pokenav_RibbonsSummaryMenu *);
static void PrintRibbbonsSummaryMonInfo(struct Pokenav_RibbonsSummaryMenu *);
static void PrintRibbonsMonListIndex(struct Pokenav_RibbonsSummaryMenu *);
static void ZoomOutSelectedRibbon(struct Pokenav_RibbonsSummaryMenu *);
static void UpdateAndZoomInSelectedRibbon(struct Pokenav_RibbonsSummaryMenu *);
static void PrintRibbonNameAndDescription(struct Pokenav_RibbonsSummaryMenu *);
static void ResetSpritesAndDrawMonFrontPic(struct Pokenav_RibbonsSummaryMenu *);
static void AddRibbonListIndexWindow(struct Pokenav_RibbonsSummaryMenu *);
static void DestroyRibbonsMonFrontPic(struct Pokenav_RibbonsSummaryMenu *);
static void SlideMonSpriteOff(struct Pokenav_RibbonsSummaryMenu *);
static void SlideMonSpriteOn(struct Pokenav_RibbonsSummaryMenu *);
static void AddRibbonCountWindow(struct Pokenav_RibbonsSummaryMenu *);
static void CreateBigRibbonSprite(struct Pokenav_RibbonsSummaryMenu *);
static void AddRibbonSummaryMonNameWindow(struct Pokenav_RibbonsSummaryMenu *);
static void DrawAllRibbonsSmall(struct Pokenav_RibbonsSummaryMenu *);
static bool32 IsRibbonAnimating(struct Pokenav_RibbonsSummaryMenu *);
static bool32 IsMonSpriteAnimating(struct Pokenav_RibbonsSummaryMenu *);
static void GetMonRibbons(struct Pokenav_RibbonsSummaryList *);
static u32 HandleExpandedRibbonInput(struct Pokenav_RibbonsSummaryList *);
static u32 RibbonsSummaryHandleInput(struct Pokenav_RibbonsSummaryList *);
static u32 ReturnToRibbonsListFromSummary(struct Pokenav_RibbonsSummaryList *);
static bool32 TrySelectRibbonUp(struct Pokenav_RibbonsSummaryList *);
static bool32 TrySelectRibbonRight(struct Pokenav_RibbonsSummaryList *);
static bool32 TrySelectRibbonLeft(struct Pokenav_RibbonsSummaryList *);
static bool32 TrySelectRibbonDown(struct Pokenav_RibbonsSummaryList *);
static bool32 GetCurrentLoopedTaskActive(void);
static u32 GetRibbonsSummaryCurrentIndex(void);
static u32 GetRibbonsSummaryMonListCount(void);
static u16 DrawRibbonsMonFrontPic(s32, s32);
static void StartMonSpriteSlide(struct Sprite *, s32, s32, s32);
static void SpriteCB_MonSpriteSlide(struct Sprite *);
static void ClearRibbonsSummaryBg(void);
static void BufferSmallRibbonGfxData(u16 *, u32);
static void DrawRibbonSmall(u32, u32);
static void SpriteCB_WaitForRibbonAnimation(struct Sprite *);
static u32 LoopedTask_OpenRibbonsSummaryMenu(s32);
static u32 LoopedTask_SwitchRibbonsSummaryMon(s32);
static u32 LoopedTask_ExpandSelectedRibbon(s32);
static u32 LoopedTask_MoveRibbonsCursorExpanded(s32);
static u32 LoopedTask_ShrinkExpandedRibbon(s32);
static u32 LoopedTask_ExitRibbonsSummaryMenu(s32);
2019-07-19 22:57:33 -04:00
2019-08-04 13:53:00 +02:00
struct
{
u8 numBits; // The number of bits needed to represent numRibbons
u8 numRibbons; // Never read. The contest ribbons have 4 (1 for each rank), the rest are just 1 ribbon
u8 ribbonId;
bool8 isGiftRibbon;
} static const sRibbonData[] =
{
{1, 1, CHAMPION_RIBBON, FALSE},
{3, 4, COOL_RIBBON_NORMAL, FALSE},
{3, 4, BEAUTY_RIBBON_NORMAL, FALSE},
{3, 4, CUTE_RIBBON_NORMAL, FALSE},
{3, 4, SMART_RIBBON_NORMAL, FALSE},
{3, 4, TOUGH_RIBBON_NORMAL, FALSE},
{1, 1, WINNING_RIBBON, FALSE},
{1, 1, VICTORY_RIBBON, FALSE},
{1, 1, ARTIST_RIBBON, FALSE},
{1, 1, EFFORT_RIBBON, FALSE},
{1, 1, MARINE_RIBBON, TRUE},
{1, 1, LAND_RIBBON, TRUE},
{1, 1, SKY_RIBBON, TRUE},
{1, 1, COUNTRY_RIBBON, TRUE},
{1, 1, NATIONAL_RIBBON, TRUE},
{1, 1, EARTH_RIBBON, TRUE},
{1, 1, WORLD_RIBBON, TRUE}
2019-07-19 22:57:33 -04:00
};
#include "data/text/ribbon_descriptions.h"
#include "data/text/gift_ribbon_descriptions.h"
static const u16 sRibbonIcons1_Pal[] = INCBIN_U16("graphics/pokenav/ribbons/icons1.gbapal");
static const u16 sRibbonIcons2_Pal[] = INCBIN_U16("graphics/pokenav/ribbons/icons2.gbapal");
static const u16 sRibbonIcons3_Pal[] = INCBIN_U16("graphics/pokenav/ribbons/icons3.gbapal");
static const u16 sRibbonIcons4_Pal[] = INCBIN_U16("graphics/pokenav/ribbons/icons4.gbapal");
static const u16 sRibbonIcons5_Pal[] = INCBIN_U16("graphics/pokenav/ribbons/icons5.gbapal");
static const u16 sMonInfo_Pal[] = INCBIN_U16("graphics/pokenav/ribbons/mon_info.gbapal"); // palette for Pokémon's name/gender/level text
static const u32 sRibbonIconsSmall_Gfx[] = INCBIN_U32("graphics/pokenav/ribbons/icons.4bpp.lz");
static const u32 sRibbonIconsBig_Gfx[] = INCBIN_U32("graphics/pokenav/ribbons/icons_big.4bpp.lz");
2019-07-19 22:57:33 -04:00
static const struct BgTemplate sBgTemplates[] =
2019-07-19 22:57:33 -04:00
{
{
.bg = 1,
.charBaseIndex = 3,
.mapBaseIndex = 0x07,
.screenSize = 0,
.paletteMode = 0,
.priority = 1,
.baseTile = 0
},
{
.bg = 2,
.charBaseIndex = 1,
.mapBaseIndex = 0x06,
.screenSize = 0,
.paletteMode = 0,
.priority = 2,
.baseTile = 0
}
};
2020-10-10 16:17:34 -06:00
static const LoopedTask sRibbonsSummaryMenuLoopTaskFuncs[] =
2019-07-19 22:57:33 -04:00
{
[RIBBONS_SUMMARY_FUNC_NONE] = NULL,
[RIBBONS_SUMMARY_FUNC_SWITCH_MONS] = LoopedTask_SwitchRibbonsSummaryMon,
[RIBBONS_SUMMARY_FUNC_SELECT_RIBBON] = LoopedTask_ExpandSelectedRibbon,
2020-10-10 16:17:34 -06:00
[RIBBONS_SUMMARY_FUNC_EXPANDED_CURSOR_MOVE] = LoopedTask_MoveRibbonsCursorExpanded,
[RIBBONS_SUMMARY_FUNC_EXPANDED_CANCEL] = LoopedTask_ShrinkExpandedRibbon,
[RIBBONS_SUMMARY_FUNC_EXIT] = LoopedTask_ExitRibbonsSummaryMenu
2019-07-19 22:57:33 -04:00
};
2019-05-26 12:42:01 +02:00
2020-10-10 16:17:34 -06:00
bool32 PokenavCallback_Init_RibbonsSummaryMenu(void)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
struct Pokenav_RibbonsSummaryList *list = AllocSubstruct(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_LIST, sizeof(struct Pokenav_RibbonsSummaryList));
if (list == NULL)
2019-08-04 13:53:00 +02:00
return FALSE;
2021-11-09 12:50:35 -05:00
list->monList = GetSubstructPtr(POKENAV_SUBSTRUCT_MON_LIST);
if (list->monList == NULL)
2019-08-04 13:53:00 +02:00
return FALSE;
2021-11-09 12:50:35 -05:00
GetMonRibbons(list);
list->callback = RibbonsSummaryHandleInput;
2019-08-04 13:53:00 +02:00
gKeyRepeatContinueDelay = 3;
gKeyRepeatStartDelay = 10;
return TRUE;
}
2020-10-10 16:17:34 -06:00
u32 GetRibbonsSummaryMenuCallback(void)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
struct Pokenav_RibbonsSummaryList *list = GetSubstructPtr(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_LIST);
return list->callback(list);
2019-08-04 13:53:00 +02:00
}
2020-10-10 16:17:34 -06:00
void FreeRibbonsSummaryScreen1(void)
2019-08-04 13:53:00 +02:00
{
2020-10-10 16:17:34 -06:00
FreePokenavSubstruct(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_LIST);
2019-08-04 13:53:00 +02:00
}
// Handles input when a specific ribbon is not currently selected
2021-11-09 12:50:35 -05:00
static u32 RibbonsSummaryHandleInput(struct Pokenav_RibbonsSummaryList *list)
2019-08-04 13:53:00 +02:00
{
// Handle Up/Down movement to select a new Pokémon to show ribbons for
2021-11-09 12:50:35 -05:00
if (JOY_REPEAT(DPAD_UP) && list->monList->currIndex != 0)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
list->monList->currIndex--;
list->selectedPos = 0;
GetMonRibbons(list);
return RIBBONS_SUMMARY_FUNC_SWITCH_MONS;
2019-08-04 13:53:00 +02:00
}
2021-11-09 12:50:35 -05:00
if (JOY_REPEAT(DPAD_DOWN) && list->monList->currIndex < list->monList->listCount - 1)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
list->monList->currIndex++;
list->selectedPos = 0;
GetMonRibbons(list);
return RIBBONS_SUMMARY_FUNC_SWITCH_MONS;
2019-08-04 13:53:00 +02:00
}
2020-09-04 21:11:55 -04:00
if (JOY_NEW(A_BUTTON))
2019-08-04 13:53:00 +02:00
{
// Enter ribbon selection
2021-11-09 12:50:35 -05:00
list->callback = HandleExpandedRibbonInput;
2020-10-10 16:17:34 -06:00
return RIBBONS_SUMMARY_FUNC_SELECT_RIBBON;
2019-08-04 13:53:00 +02:00
}
2020-09-04 21:11:55 -04:00
if (JOY_NEW(B_BUTTON))
2019-08-04 13:53:00 +02:00
{
// Exit ribbon summary menu
2021-11-09 12:50:35 -05:00
list->callback = ReturnToRibbonsListFromSummary;
2020-10-10 16:17:34 -06:00
return RIBBONS_SUMMARY_FUNC_EXIT;
2019-08-04 13:53:00 +02:00
}
2020-10-10 16:17:34 -06:00
return RIBBONS_SUMMARY_FUNC_NONE;
2019-08-04 13:53:00 +02:00
}
// Handles input when a ribbon is selected
2021-11-09 12:50:35 -05:00
static u32 HandleExpandedRibbonInput(struct Pokenav_RibbonsSummaryList *list)
2019-08-04 13:53:00 +02:00
{
// Handle movement while a ribbon is selected
2021-11-09 12:50:35 -05:00
if (JOY_REPEAT(DPAD_UP) && TrySelectRibbonUp(list))
2020-10-10 16:17:34 -06:00
return RIBBONS_SUMMARY_FUNC_EXPANDED_CURSOR_MOVE;
2021-11-09 12:50:35 -05:00
if (JOY_REPEAT(DPAD_DOWN) && TrySelectRibbonDown(list))
2020-10-10 16:17:34 -06:00
return RIBBONS_SUMMARY_FUNC_EXPANDED_CURSOR_MOVE;
2021-11-09 12:50:35 -05:00
if (JOY_REPEAT(DPAD_LEFT) && TrySelectRibbonLeft(list))
2020-10-10 16:17:34 -06:00
return RIBBONS_SUMMARY_FUNC_EXPANDED_CURSOR_MOVE;
2021-11-09 12:50:35 -05:00
if (JOY_REPEAT(DPAD_RIGHT) && TrySelectRibbonRight(list))
2020-10-10 16:17:34 -06:00
return RIBBONS_SUMMARY_FUNC_EXPANDED_CURSOR_MOVE;
2020-09-04 21:11:55 -04:00
if (JOY_NEW(B_BUTTON))
2019-08-04 13:53:00 +02:00
{
// Exit ribbon selection
2021-11-09 12:50:35 -05:00
list->callback = RibbonsSummaryHandleInput;
2020-10-10 16:17:34 -06:00
return RIBBONS_SUMMARY_FUNC_EXPANDED_CANCEL;
2019-08-04 13:53:00 +02:00
}
2020-10-10 16:17:34 -06:00
return RIBBONS_SUMMARY_FUNC_NONE;
2019-08-04 13:53:00 +02:00
}
2021-11-09 12:50:35 -05:00
static u32 ReturnToRibbonsListFromSummary(struct Pokenav_RibbonsSummaryList *list)
2019-08-04 13:53:00 +02:00
{
2020-10-10 16:17:34 -06:00
return POKENAV_RIBBONS_RETURN_TO_MON_LIST;
2019-08-04 13:53:00 +02:00
}
2021-11-09 12:50:35 -05:00
static bool32 TrySelectRibbonUp(struct Pokenav_RibbonsSummaryList *list)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
if (list->selectedPos < FIRST_GIFT_RIBBON)
2019-08-04 13:53:00 +02:00
{
// In normal ribbons, try to move up a row
2021-11-09 12:50:35 -05:00
if (list->selectedPos < RIBBONS_PER_ROW)
2019-08-04 13:53:00 +02:00
return FALSE;
2021-11-09 12:50:35 -05:00
list->selectedPos -= RIBBONS_PER_ROW;
2019-08-04 13:53:00 +02:00
return TRUE;
}
2021-11-09 12:50:35 -05:00
if (list->numNormalRibbons != 0)
2019-08-04 13:53:00 +02:00
{
// In gift ribbons, try to move up into normal ribbons
// If there's > 1 row of gift ribbons (not normally possible)
// it's impossible to move up between them
2021-11-09 12:50:35 -05:00
u32 ribbonPos = list->selectedPos - GIFT_RIBBON_START_POS;
list->selectedPos = ribbonPos + list->normalRibbonLastRowStart;
if (list->selectedPos >= list->numNormalRibbons)
list->selectedPos = list->numNormalRibbons - 1;
2019-08-04 13:53:00 +02:00
return TRUE;
}
return FALSE;
}
2021-11-09 12:50:35 -05:00
static bool32 TrySelectRibbonDown(struct Pokenav_RibbonsSummaryList *list)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
if (list->selectedPos >= FIRST_GIFT_RIBBON)
2019-08-04 13:53:00 +02:00
return FALSE;
2021-11-09 12:50:35 -05:00
if (list->selectedPos < list->normalRibbonLastRowStart)
2019-08-04 13:53:00 +02:00
{
// Not in last row of normal ribbons, advance to next row
2021-11-09 12:50:35 -05:00
list->selectedPos += RIBBONS_PER_ROW;
if (list->selectedPos >= list->numNormalRibbons)
list->selectedPos = list->numNormalRibbons - 1;
2019-08-04 13:53:00 +02:00
return TRUE;
}
2021-11-09 12:50:35 -05:00
if (list->numGiftRibbons != 0)
2019-08-04 13:53:00 +02:00
{
// In/beyond last of row of normal ribbons and gift ribbons present, move down to gift ribbon row
2021-11-09 12:50:35 -05:00
int ribbonPos = list->selectedPos - list->normalRibbonLastRowStart;
if (ribbonPos >= list->numGiftRibbons)
ribbonPos = list->numGiftRibbons - 1;
2019-08-04 13:53:00 +02:00
2021-11-09 12:50:35 -05:00
list->selectedPos = ribbonPos + GIFT_RIBBON_START_POS;
2019-08-04 13:53:00 +02:00
return TRUE;
}
return FALSE;
}
2021-11-09 12:50:35 -05:00
static bool32 TrySelectRibbonLeft(struct Pokenav_RibbonsSummaryList *list)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
u16 column = list->selectedPos % RIBBONS_PER_ROW;
if (column != 0)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
list->selectedPos--;
2019-08-04 13:53:00 +02:00
return TRUE;
}
return FALSE;
}
2021-11-09 12:50:35 -05:00
static bool32 TrySelectRibbonRight(struct Pokenav_RibbonsSummaryList *list)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
int column = list->selectedPos % RIBBONS_PER_ROW;
2019-08-04 13:53:00 +02:00
if (column >= RIBBONS_PER_ROW - 1)
2019-08-04 13:53:00 +02:00
return FALSE;
2021-11-09 12:50:35 -05:00
if (list->selectedPos < GIFT_RIBBON_START_POS)
2019-08-04 13:53:00 +02:00
{
// Move right in normal ribbon row
2021-11-09 12:50:35 -05:00
if (list->selectedPos < list->numNormalRibbons - 1)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
list->selectedPos++;
2019-08-04 13:53:00 +02:00
return TRUE;
}
}
else
{
// Move right in gift ribbon row
2021-11-09 12:50:35 -05:00
if (column < list->numGiftRibbons - 1)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
list->selectedPos++;
2019-08-04 13:53:00 +02:00
return TRUE;
}
}
return FALSE;
}
static u32 GetRibbonsSummaryCurrentIndex(void)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
struct Pokenav_RibbonsSummaryList *list = GetSubstructPtr(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_LIST);
return list->monList->currIndex;
2019-08-04 13:53:00 +02:00
}
static u32 GetRibbonsSummaryMonListCount(void)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
struct Pokenav_RibbonsSummaryList *list = GetSubstructPtr(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_LIST);
return list->monList->listCount;
2019-08-04 13:53:00 +02:00
}
static void GetMonNicknameLevelGender(u8 *nick, u8 *level, u8 *gender)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
struct Pokenav_RibbonsSummaryList *list = GetSubstructPtr(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_LIST);
2021-11-12 20:24:14 -05:00
struct PokenavMonList *mons = list->monList;
struct PokenavMonListItem *monInfo = &mons->monData[mons->currIndex];
2019-08-04 13:53:00 +02:00
if (monInfo->boxId == TOTAL_BOXES_COUNT)
{
// Get info for party mon
2019-08-04 13:53:00 +02:00
struct Pokemon *mon = &gPlayerParty[monInfo->monId];
GetMonData(mon, MON_DATA_NICKNAME, nick);
*level = GetLevelFromMonExp(mon);
*gender = GetMonGender(mon);
}
else
{
// Get info for PC box mon
2019-08-04 13:53:00 +02:00
struct BoxPokemon *boxMon = GetBoxedMonPtr(monInfo->boxId, monInfo->monId);
*gender = GetBoxMonGender(boxMon);
*level = GetLevelFromBoxMonExp(boxMon);
GetBoxMonData(boxMon, MON_DATA_NICKNAME, nick);
}
StringGet_Nickname(nick);
2019-08-04 13:53:00 +02:00
}
static void GetMonSpeciesPersonalityOtId(u16 *species, u32 *personality, u32 *otId)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
struct Pokenav_RibbonsSummaryList *list = GetSubstructPtr(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_LIST);
2021-11-12 20:24:14 -05:00
struct PokenavMonList *mons = list->monList;
struct PokenavMonListItem *monInfo = &mons->monData[mons->currIndex];
2019-08-04 13:53:00 +02:00
if (monInfo->boxId == TOTAL_BOXES_COUNT)
{
// Get info for party mon
2019-08-04 13:53:00 +02:00
struct Pokemon *mon = &gPlayerParty[monInfo->monId];
*species = GetMonData(mon, MON_DATA_SPECIES);
*personality = GetMonData(mon, MON_DATA_PERSONALITY);
*otId = GetMonData(mon, MON_DATA_OT_ID);
}
else
{
// Get info for PC box mon
2019-08-04 13:53:00 +02:00
struct BoxPokemon *boxMon = GetBoxedMonPtr(monInfo->boxId, monInfo->monId);
*species = GetBoxMonData(boxMon, MON_DATA_SPECIES);
*personality = GetBoxMonData(boxMon, MON_DATA_PERSONALITY);
*otId = GetBoxMonData(boxMon, MON_DATA_OT_ID);
}
}
static u32 GetCurrMonRibbonCount(void)
{
2021-11-09 12:50:35 -05:00
struct Pokenav_RibbonsSummaryList *list = GetSubstructPtr(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_LIST);
2021-11-12 20:24:14 -05:00
struct PokenavMonList *mons = list->monList;
struct PokenavMonListItem *monInfo = &mons->monData[mons->currIndex];
2019-08-04 13:53:00 +02:00
if (monInfo->boxId == TOTAL_BOXES_COUNT)
return GetMonData(&gPlayerParty[monInfo->monId], MON_DATA_RIBBON_COUNT);
else
return GetBoxMonDataAt(monInfo->boxId, monInfo->monId, MON_DATA_RIBBON_COUNT);
}
2021-11-09 12:50:35 -05:00
static void GetMonRibbons(struct Pokenav_RibbonsSummaryList *list)
2019-08-04 13:53:00 +02:00
{
u32 ribbonFlags;
2019-08-04 13:53:00 +02:00
s32 i, j;
2021-11-12 20:24:14 -05:00
struct PokenavMonList *mons = list->monList;
struct PokenavMonListItem *monInfo = &mons->monData[mons->currIndex];
2019-08-04 13:53:00 +02:00
if (monInfo->boxId == TOTAL_BOXES_COUNT)
ribbonFlags = GetMonData(&gPlayerParty[monInfo->monId], MON_DATA_RIBBONS);
2019-08-04 13:53:00 +02:00
else
ribbonFlags = GetBoxMonDataAt(monInfo->boxId, monInfo->monId, MON_DATA_RIBBONS);
2019-08-04 13:53:00 +02:00
2021-11-09 12:50:35 -05:00
list->numNormalRibbons = 0;
list->numGiftRibbons = 0;
for (i = 0; i < ARRAY_COUNT(sRibbonData); i++)
2019-08-04 13:53:00 +02:00
{
// For all non-contest ribbons, numRibbons will be 1 if they have it, 0 if they don't
// For contest ribbons, numRibbons will be 0-4
s32 numRibbons = ((1 << sRibbonData[i].numBits) - 1) & ribbonFlags;
if (!sRibbonData[i].isGiftRibbon)
2019-08-04 13:53:00 +02:00
{
for (j = 0; j < numRibbons; j++)
2021-11-09 12:50:35 -05:00
list->ribbonIds[list->numNormalRibbons++] = sRibbonData[i].ribbonId + j;
2019-08-04 13:53:00 +02:00
}
else
{
for (j = 0; j < numRibbons; j++)
2021-11-09 12:50:35 -05:00
list->giftRibbonIds[list->numGiftRibbons++] = sRibbonData[i].ribbonId + j;
2019-08-04 13:53:00 +02:00
}
ribbonFlags >>= sRibbonData[i].numBits;
2019-08-04 13:53:00 +02:00
}
2021-11-09 12:50:35 -05:00
if (list->numNormalRibbons != 0)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
list->normalRibbonLastRowStart = ((list->numNormalRibbons - 1) / RIBBONS_PER_ROW) * RIBBONS_PER_ROW;
list->selectedPos = 0;
2019-08-04 13:53:00 +02:00
}
else
{
// There are no normal ribbons, move cursor to first gift ribbon
2021-11-09 12:50:35 -05:00
list->normalRibbonLastRowStart = 0;
list->selectedPos = GIFT_RIBBON_START_POS;
2019-08-04 13:53:00 +02:00
}
}
static u32 *GetNormalRibbonIds(u32 *size)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
struct Pokenav_RibbonsSummaryList *list = GetSubstructPtr(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_LIST);
*size = list->numNormalRibbons;
return list->ribbonIds;
2019-08-04 13:53:00 +02:00
}
static u32 *GetGiftRibbonIds(u32 *size)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
struct Pokenav_RibbonsSummaryList *list = GetSubstructPtr(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_LIST);
*size = list->numGiftRibbons;
return list->giftRibbonIds;
2019-08-04 13:53:00 +02:00
}
static u16 GetSelectedPosition(void)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
struct Pokenav_RibbonsSummaryList *list = GetSubstructPtr(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_LIST);
return list->selectedPos;
2019-08-04 13:53:00 +02:00
}
static u32 GetRibbonId(void)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
struct Pokenav_RibbonsSummaryList *list = GetSubstructPtr(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_LIST);
int ribbonPos = list->selectedPos;
if (ribbonPos < FIRST_GIFT_RIBBON)
2021-11-09 12:50:35 -05:00
return list->ribbonIds[ribbonPos];
2019-08-04 13:53:00 +02:00
else
2021-11-09 12:50:35 -05:00
return list->giftRibbonIds[ribbonPos - GIFT_RIBBON_START_POS];
2019-08-04 13:53:00 +02:00
}
2020-10-10 16:17:34 -06:00
bool32 OpenRibbonsSummaryMenu(void)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
struct Pokenav_RibbonsSummaryMenu *menu = AllocSubstruct(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_MENU, sizeof(struct Pokenav_RibbonsSummaryMenu));
if (menu == NULL)
2019-08-04 13:53:00 +02:00
return FALSE;
2021-11-09 12:50:35 -05:00
menu->loopedTaskId = CreateLoopedTask(LoopedTask_OpenRibbonsSummaryMenu, 1);
menu->callback = GetCurrentLoopedTaskActive;
2019-08-04 13:53:00 +02:00
return TRUE;
}
2020-10-10 16:17:34 -06:00
void CreateRibbonsSummaryLoopedTask(s32 id)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
struct Pokenav_RibbonsSummaryMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_MENU);
menu->loopedTaskId = CreateLoopedTask(sRibbonsSummaryMenuLoopTaskFuncs[id], 1);
menu->callback = GetCurrentLoopedTaskActive;
2019-08-04 13:53:00 +02:00
}
2020-10-10 16:17:34 -06:00
u32 IsRibbonsSummaryLoopedTaskActive(void)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
struct Pokenav_RibbonsSummaryMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_MENU);
return menu->callback();
2019-08-04 13:53:00 +02:00
}
2020-10-10 16:17:34 -06:00
void FreeRibbonsSummaryScreen2(void)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
struct Pokenav_RibbonsSummaryMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_MENU);
RemoveWindow(menu->ribbonCountWindowId);
RemoveWindow(menu->nameWindowId);
RemoveWindow(menu->listIdxWindowId);
#ifndef BUGFIX
2021-11-09 12:50:35 -05:00
RemoveWindow(menu->unusedWindowId); // Removing window, but window id is never set
#endif
2021-11-09 12:50:35 -05:00
DestroyRibbonsMonFrontPic(menu);
FreeSpriteTilesByTag(GFXTAG_RIBBON_ICONS_BIG);
FreeSpritePaletteByTag(PALTAG_RIBBON_ICONS_1);
FreeSpritePaletteByTag(PALTAG_RIBBON_ICONS_2);
FreeSpritePaletteByTag(PALTAG_RIBBON_ICONS_3);
FreeSpritePaletteByTag(PALTAG_RIBBON_ICONS_4);
FreeSpritePaletteByTag(PALTAG_RIBBON_ICONS_5);
2021-11-09 12:50:35 -05:00
FreeSpriteOamMatrix(menu->bigRibbonSprite);
DestroySprite(menu->bigRibbonSprite);
2020-10-10 16:17:34 -06:00
FreePokenavSubstruct(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_MENU);
2019-08-04 13:53:00 +02:00
}
static bool32 GetCurrentLoopedTaskActive(void)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
struct Pokenav_RibbonsSummaryMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_MENU);
return IsLoopedTaskActive(menu->loopedTaskId);
2019-08-04 13:53:00 +02:00
}
static u32 LoopedTask_OpenRibbonsSummaryMenu(s32 state)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
struct Pokenav_RibbonsSummaryMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_MENU);
2019-08-04 13:53:00 +02:00
switch (state)
{
case 0:
InitBgTemplates(sBgTemplates, ARRAY_COUNT(sBgTemplates));
DecompressAndCopyTileDataToVram(2, gPokenavRibbonsSummaryBg_Gfx, 0, 0, 0);
2021-11-09 12:50:35 -05:00
SetBgTilemapBuffer(2, menu->tilemapBuffers[0]);
CopyToBgTilemapBuffer(2, gPokenavRibbonsSummaryBg_Tilemap, 0, 0);
CopyPaletteIntoBufferUnfaded(gPokenavRibbonsSummaryBg_Pal, 0x10, 0x20);
2019-08-04 13:53:00 +02:00
CopyBgTilemapBufferToVram(2);
return LT_INC_AND_PAUSE;
case 1:
2020-05-14 01:37:09 -07:00
if (!FreeTempTileDataBuffersIfPossible())
2019-08-04 13:53:00 +02:00
{
2021-11-03 23:20:59 -04:00
BgDmaFill(1, 0, 0, 1);
2020-05-14 01:37:09 -07:00
DecompressAndCopyTileDataToVram(1, sRibbonIconsSmall_Gfx, 0, 1, 0);
2021-11-09 12:50:35 -05:00
SetBgTilemapBuffer(1, menu->tilemapBuffers[1]);
2019-08-04 13:53:00 +02:00
FillBgTilemapBufferRect_Palette0(1, 0, 0, 0, 32, 20);
CopyPaletteIntoBufferUnfaded(sRibbonIcons1_Pal, 0x20, 0xA0);
CopyPaletteIntoBufferUnfaded(sMonInfo_Pal, 0xA0, 0x20);
2019-08-04 13:53:00 +02:00
CopyBgTilemapBufferToVram(1);
return LT_INC_AND_PAUSE;
}
return LT_PAUSE;
case 2:
2020-05-14 01:37:09 -07:00
if (!FreeTempTileDataBuffersIfPossible())
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
AddRibbonCountWindow(menu);
2019-08-04 13:53:00 +02:00
return LT_INC_AND_PAUSE;
}
return LT_PAUSE;
case 3:
2020-05-14 01:37:09 -07:00
if (!FreeTempTileDataBuffersIfPossible())
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
AddRibbonSummaryMonNameWindow(menu);
2019-08-04 13:53:00 +02:00
return LT_INC_AND_PAUSE;
}
return LT_PAUSE;
case 4:
2020-05-14 01:37:09 -07:00
if (!FreeTempTileDataBuffersIfPossible())
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
AddRibbonListIndexWindow(menu);
2019-08-04 13:53:00 +02:00
return LT_INC_AND_PAUSE;
}
return LT_PAUSE;
case 5:
if (!IsDma3ManagerBusyWithBgCopy())
{
CopyBgTilemapBufferToVram(2);
return LT_INC_AND_PAUSE;
}
return LT_PAUSE;
case 6:
if (!IsDma3ManagerBusyWithBgCopy())
{
2021-11-09 12:50:35 -05:00
ResetSpritesAndDrawMonFrontPic(menu);
2019-08-04 13:53:00 +02:00
return LT_INC_AND_CONTINUE;
}
return LT_PAUSE;
case 7:
2021-11-09 12:50:35 -05:00
DrawAllRibbonsSmall(menu);
2019-12-07 04:08:21 -05:00
PrintHelpBarText(HELPBAR_RIBBONS_LIST);
2019-08-04 13:53:00 +02:00
return LT_INC_AND_PAUSE;
case 8:
if (!IsDma3ManagerBusyWithBgCopy())
{
2021-11-09 12:50:35 -05:00
CreateBigRibbonSprite(menu);
2021-11-03 23:02:06 -04:00
ChangeBgX(1, 0, BG_COORD_SET);
ChangeBgY(1, 0, BG_COORD_SET);
ChangeBgX(2, 0, BG_COORD_SET);
ChangeBgY(2, 0, BG_COORD_SET);
2019-08-04 13:53:00 +02:00
ShowBg(1);
ShowBg(2);
HideBg(3);
2021-11-12 17:28:06 -05:00
PokenavFadeScreen(POKENAV_FADE_FROM_BLACK);
2019-08-04 13:53:00 +02:00
return LT_INC_AND_PAUSE;
}
return LT_PAUSE;
case 9:
if (IsPaletteFadeActive())
return LT_PAUSE;
}
return LT_FINISH;
}
static u32 LoopedTask_ExitRibbonsSummaryMenu(s32 state)
2019-08-04 13:53:00 +02:00
{
switch (state)
{
case 0:
PlaySE(SE_SELECT);
2021-11-12 17:28:06 -05:00
PokenavFadeScreen(POKENAV_FADE_TO_BLACK);
2019-08-04 13:53:00 +02:00
return LT_INC_AND_PAUSE;
case 1:
if (IsPaletteFadeActive())
return LT_PAUSE;
return LT_FINISH;
}
return LT_FINISH;
}
static u32 LoopedTask_SwitchRibbonsSummaryMon(s32 state)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
struct Pokenav_RibbonsSummaryMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_MENU);
2019-08-04 13:53:00 +02:00
switch (state)
{
case 0:
PlaySE(SE_SELECT);
2021-11-09 12:50:35 -05:00
SlideMonSpriteOff(menu);
2019-08-04 13:53:00 +02:00
return LT_INC_AND_PAUSE;
case 1:
2021-11-09 12:50:35 -05:00
if (!IsMonSpriteAnimating(menu))
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
PrintRibbbonsSummaryMonInfo(menu);
2019-08-04 13:53:00 +02:00
return LT_INC_AND_CONTINUE;
}
return LT_PAUSE;
case 2:
2021-11-09 12:50:35 -05:00
DrawAllRibbonsSmall(menu);
2019-08-04 13:53:00 +02:00
return LT_INC_AND_CONTINUE;
case 3:
2021-11-09 12:50:35 -05:00
PrintRibbonsMonListIndex(menu);
2019-08-04 13:53:00 +02:00
return LT_INC_AND_CONTINUE;
case 4:
2021-11-09 12:50:35 -05:00
PrintCurrentMonRibbonCount(menu);
2019-08-04 13:53:00 +02:00
return LT_INC_AND_CONTINUE;
case 5:
if (!IsDma3ManagerBusyWithBgCopy())
{
2021-11-09 12:50:35 -05:00
SlideMonSpriteOn(menu);
2019-08-04 13:53:00 +02:00
return LT_INC_AND_PAUSE;
}
return LT_PAUSE;
case 6:
2021-11-09 12:50:35 -05:00
if (IsMonSpriteAnimating(menu))
2019-08-04 13:53:00 +02:00
return LT_PAUSE;
}
return LT_FINISH;
}
static u32 LoopedTask_ExpandSelectedRibbon(s32 state)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
struct Pokenav_RibbonsSummaryMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_MENU);
2019-08-04 13:53:00 +02:00
switch (state)
{
case 0:
PlaySE(SE_SELECT);
2021-11-09 12:50:35 -05:00
UpdateAndZoomInSelectedRibbon(menu);
2019-08-04 13:53:00 +02:00
return LT_INC_AND_PAUSE;
case 1:
2021-11-09 12:50:35 -05:00
if (!IsRibbonAnimating(menu))
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
PrintRibbonNameAndDescription(menu);
2019-12-07 04:08:21 -05:00
PrintHelpBarText(HELPBAR_RIBBONS_CHECK);
2019-08-04 13:53:00 +02:00
return LT_INC_AND_PAUSE;
}
return LT_PAUSE;
case 2:
if (IsDma3ManagerBusyWithBgCopy())
return LT_PAUSE;
}
return LT_FINISH;
}
static u32 LoopedTask_MoveRibbonsCursorExpanded(s32 state)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
struct Pokenav_RibbonsSummaryMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_MENU);
2019-08-04 13:53:00 +02:00
switch (state)
{
case 0:
PlaySE(SE_SELECT);
2021-11-09 12:50:35 -05:00
ZoomOutSelectedRibbon(menu);
2019-08-04 13:53:00 +02:00
return LT_INC_AND_PAUSE;
case 1:
2021-11-09 12:50:35 -05:00
if (!IsRibbonAnimating(menu))
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
UpdateAndZoomInSelectedRibbon(menu);
2019-08-04 13:53:00 +02:00
return LT_INC_AND_PAUSE;
}
return LT_PAUSE;
case 2:
2021-11-09 12:50:35 -05:00
if (!IsRibbonAnimating(menu))
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
PrintRibbonNameAndDescription(menu);
2019-08-04 13:53:00 +02:00
return LT_INC_AND_PAUSE;
}
return LT_PAUSE;
case 3:
if (IsDma3ManagerBusyWithBgCopy())
return LT_PAUSE;
}
return LT_FINISH;
}
static u32 LoopedTask_ShrinkExpandedRibbon(s32 state)
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
struct Pokenav_RibbonsSummaryMenu *menu = GetSubstructPtr(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_MENU);
2019-08-04 13:53:00 +02:00
switch (state)
{
case 0:
PlaySE(SE_SELECT);
2021-11-09 12:50:35 -05:00
ZoomOutSelectedRibbon(menu);
2019-08-04 13:53:00 +02:00
return LT_INC_AND_PAUSE;
case 1:
2021-11-09 12:50:35 -05:00
if (!IsRibbonAnimating(menu))
2019-08-04 13:53:00 +02:00
{
2021-11-09 12:50:35 -05:00
PrintCurrentMonRibbonCount(menu);
2019-12-07 04:08:21 -05:00
PrintHelpBarText(HELPBAR_RIBBONS_LIST);
2019-08-04 13:53:00 +02:00
return LT_INC_AND_PAUSE;
}
return LT_PAUSE;
case 2:
if (IsDma3ManagerBusyWithBgCopy())
return LT_PAUSE;
}
return LT_FINISH;
}
2020-10-10 16:17:34 -06:00
static const struct WindowTemplate sRibbonCountWindowTemplate =
2019-05-26 12:42:01 +02:00
{
.bg = 2,
.tilemapLeft = 12,
.tilemapTop = 13,
.width = 16,
.height = 4,
.paletteNum = 1,
.baseBlock = 0x14,
};
2021-11-09 12:50:35 -05:00
static void AddRibbonCountWindow(struct Pokenav_RibbonsSummaryMenu *menu)
2019-05-26 12:42:01 +02:00
{
2021-11-09 12:50:35 -05:00
menu->ribbonCountWindowId = AddWindow(&sRibbonCountWindowTemplate);
PutWindowTilemap(menu->ribbonCountWindowId);
PrintCurrentMonRibbonCount(menu);
2019-05-26 12:42:01 +02:00
}
2021-11-09 12:50:35 -05:00
static void PrintCurrentMonRibbonCount(struct Pokenav_RibbonsSummaryMenu *menu)
2019-05-26 12:42:01 +02:00
{
2021-04-09 22:39:34 -04:00
u8 color[] = {TEXT_COLOR_RED, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_GRAY};
2019-05-26 12:42:01 +02:00
2019-08-04 13:53:00 +02:00
ConvertIntToDecimalStringN(gStringVar1, GetCurrMonRibbonCount(), STR_CONV_MODE_LEFT_ALIGN, 2);
2019-05-26 12:42:01 +02:00
DynamicPlaceholderTextUtil_Reset();
DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, gStringVar1);
DynamicPlaceholderTextUtil_ExpandPlaceholders(gStringVar4, gText_RibbonsF700);
2021-11-09 12:50:35 -05:00
FillWindowPixelBuffer(menu->ribbonCountWindowId, PIXEL_FILL(4));
AddTextPrinterParameterized3(menu->ribbonCountWindowId, FONT_NORMAL, 0, 1, color, TEXT_SKIP_DRAW, gStringVar4);
CopyWindowToVram(menu->ribbonCountWindowId, COPYWIN_GFX);
2019-05-26 12:42:01 +02:00
}
2021-11-09 12:50:35 -05:00
static void PrintRibbonNameAndDescription(struct Pokenav_RibbonsSummaryMenu *menu)
2019-05-26 12:42:01 +02:00
{
s32 i;
u32 ribbonId = GetRibbonId();
2021-04-09 22:39:34 -04:00
u8 color[] = {TEXT_COLOR_RED, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_GRAY};
2019-05-26 12:42:01 +02:00
2021-11-09 12:50:35 -05:00
FillWindowPixelBuffer(menu->ribbonCountWindowId, PIXEL_FILL(4));
if (ribbonId < FIRST_GIFT_RIBBON)
2019-05-26 12:42:01 +02:00
{
// Print normal ribbon name/description
2019-05-26 12:42:01 +02:00
for (i = 0; i < 2; i++)
2021-11-09 12:50:35 -05:00
AddTextPrinterParameterized3(menu->ribbonCountWindowId, FONT_NORMAL, 0, (i * 16) + 1, color, TEXT_SKIP_DRAW, gRibbonDescriptionPointers[ribbonId][i]);
2019-05-26 12:42:01 +02:00
}
else
{
// ribbonId here is one of the 'gift' ribbon slots, used to read
// its actual value from giftRibbons to determine which specific
// gift ribbon it is
ribbonId = gSaveBlock1Ptr->giftRibbons[ribbonId - FIRST_GIFT_RIBBON];
// If 0, this gift ribbon slot is unoccupied
2019-05-26 12:42:01 +02:00
if (ribbonId == 0)
return;
// Print gift ribbon name/description
2019-05-26 12:42:01 +02:00
ribbonId--;
for (i = 0; i < 2; i++)
2021-11-09 12:50:35 -05:00
AddTextPrinterParameterized3(menu->ribbonCountWindowId, FONT_NORMAL, 0, (i * 16) + 1, color, TEXT_SKIP_DRAW, gGiftRibbonDescriptionPointers[ribbonId][i]);
2019-05-26 12:42:01 +02:00
}
2021-11-09 12:50:35 -05:00
CopyWindowToVram(menu->ribbonCountWindowId, COPYWIN_GFX);
2019-05-26 12:42:01 +02:00
}
2020-10-10 16:17:34 -06:00
static const struct WindowTemplate sRibbonSummaryMonNameWindowTemplate =
2019-05-26 12:42:01 +02:00
{
.bg = 2,
.tilemapLeft = 14,
.tilemapTop = 1,
.width = 13,
.height = 2,
.paletteNum = 10,
.baseBlock = 0x54,
};
2021-11-09 12:50:35 -05:00
static void AddRibbonSummaryMonNameWindow(struct Pokenav_RibbonsSummaryMenu *menu)
2019-05-26 12:42:01 +02:00
{
2021-11-09 12:50:35 -05:00
menu->nameWindowId = AddWindow(&sRibbonSummaryMonNameWindowTemplate);
PutWindowTilemap(menu->nameWindowId);
PrintRibbbonsSummaryMonInfo(menu);
2019-05-26 12:42:01 +02:00
}
2021-04-09 22:39:34 -04:00
static const u8 sMaleIconString[] = _("{COLOR_HIGHLIGHT_SHADOW}{LIGHT_RED}{WHITE}{GREEN}♂{COLOR_HIGHLIGHT_SHADOW}{DARK_GRAY}{WHITE}{LIGHT_GRAY}");
static const u8 sFemaleIconString[] = _("{COLOR_HIGHLIGHT_SHADOW}{LIGHT_GREEN}{WHITE}{BLUE}♀{COLOR_HIGHLIGHT_SHADOW}{DARK_GRAY}{WHITE}{LIGHT_GRAY}");
2019-05-26 12:42:01 +02:00
static const u8 sGenderlessIconString[] = _("{UNK_SPACER}");
2021-11-09 12:50:35 -05:00
static void PrintRibbbonsSummaryMonInfo(struct Pokenav_RibbonsSummaryMenu *menu)
2019-05-26 12:42:01 +02:00
{
const u8 *genderTxt;
u8 *txtPtr;
u8 level, gender;
2021-11-09 12:50:35 -05:00
u16 windowId = menu->nameWindowId;
2019-05-26 12:42:01 +02:00
FillWindowPixelBuffer(windowId, PIXEL_FILL(1));
GetMonNicknameLevelGender(gStringVar3, &level, &gender);
AddTextPrinterParameterized(windowId, FONT_NORMAL, gStringVar3, 0, 1, TEXT_SKIP_DRAW, NULL);
2019-05-26 12:42:01 +02:00
switch (gender)
{
case MON_MALE:
genderTxt = sMaleIconString;
break;
case MON_FEMALE:
genderTxt = sFemaleIconString;
break;
default:
genderTxt = sGenderlessIconString;
break;
}
txtPtr = StringCopy(gStringVar1, genderTxt);
*(txtPtr++) = CHAR_SLASH;
2020-08-10 23:50:49 -04:00
*(txtPtr++) = CHAR_EXTRA_SYMBOL;
2020-02-01 00:25:50 -05:00
*(txtPtr++) = CHAR_LV_2;
2019-05-26 12:42:01 +02:00
ConvertIntToDecimalStringN(txtPtr, level, STR_CONV_MODE_LEFT_ALIGN, 3);
AddTextPrinterParameterized(windowId, FONT_NORMAL, gStringVar1, 60, 1, TEXT_SKIP_DRAW, NULL);
2021-11-03 15:29:18 -04:00
CopyWindowToVram(windowId, COPYWIN_GFX);
2019-05-26 12:42:01 +02:00
}
2020-10-10 16:17:34 -06:00
static const struct WindowTemplate sRibbonMonListIndexWindowTemplate[] =
2019-05-26 12:42:01 +02:00
{
{
.bg = 2,
.tilemapLeft = 1,
.tilemapTop = 5,
.width = 7,
.height = 2,
.paletteNum = 1,
.baseBlock = 0x6E,
},
{},
};
2021-11-09 12:50:35 -05:00
static void AddRibbonListIndexWindow(struct Pokenav_RibbonsSummaryMenu *menu)
2019-05-26 12:42:01 +02:00
{
2021-11-09 12:50:35 -05:00
menu->listIdxWindowId = AddWindow(sRibbonMonListIndexWindowTemplate);
FillWindowPixelBuffer(menu->listIdxWindowId, PIXEL_FILL(1));
PutWindowTilemap(menu->listIdxWindowId);
PrintRibbonsMonListIndex(menu);
2019-05-26 12:42:01 +02:00
}
2021-11-09 12:50:35 -05:00
static void PrintRibbonsMonListIndex(struct Pokenav_RibbonsSummaryMenu *menu)
2019-05-26 12:42:01 +02:00
{
s32 x;
u8 *txtPtr;
2020-10-10 16:17:34 -06:00
u32 id = GetRibbonsSummaryCurrentIndex() + 1;
u32 count = GetRibbonsSummaryMonListCount();
2019-05-26 12:42:01 +02:00
txtPtr = ConvertIntToDecimalStringN(gStringVar1, id, STR_CONV_MODE_RIGHT_ALIGN, 3);
*(txtPtr++) = CHAR_SLASH;
ConvertIntToDecimalStringN(txtPtr, count, STR_CONV_MODE_RIGHT_ALIGN, 3);
2021-10-30 16:47:37 -04:00
x = GetStringCenterAlignXOffset(FONT_NORMAL, gStringVar1, 56);
2021-11-09 12:50:35 -05:00
AddTextPrinterParameterized(menu->listIdxWindowId, FONT_NORMAL, gStringVar1, x, 1, TEXT_SKIP_DRAW, NULL);
CopyWindowToVram(menu->listIdxWindowId, COPYWIN_GFX);
2019-05-26 12:42:01 +02:00
}
2021-11-09 12:50:35 -05:00
static void ResetSpritesAndDrawMonFrontPic(struct Pokenav_RibbonsSummaryMenu *menu)
2019-05-26 12:42:01 +02:00
{
u16 species;
u32 personality, otId;
GetMonSpeciesPersonalityOtId(&species, &personality, &otId);
2019-05-26 12:42:01 +02:00
ResetAllPicSprites();
2021-11-09 12:50:35 -05:00
menu->monSpriteId = DrawRibbonsMonFrontPic(MON_SPRITE_X_ON, MON_SPRITE_Y);
2020-10-10 16:17:34 -06:00
PokenavFillPalette(15, 0);
2019-05-26 12:42:01 +02:00
}
2021-11-09 12:50:35 -05:00
static void DestroyRibbonsMonFrontPic(struct Pokenav_RibbonsSummaryMenu *menu)
2019-05-26 12:42:01 +02:00
{
2021-11-09 12:50:35 -05:00
FreeAndDestroyMonPicSprite(menu->monSpriteId);
2019-05-26 12:42:01 +02:00
}
// x and y arguments are ignored
// y is always given as MON_SPRITE_Y
// x is given as either MON_SPRITE_X_ON or MON_SPRITE_X_OFF (but ignored and MON_SPRITE_X_ON is used)
static u16 DrawRibbonsMonFrontPic(s32 x, s32 y)
2019-05-26 12:42:01 +02:00
{
u16 species, spriteId;
u32 personality, otId;
GetMonSpeciesPersonalityOtId(&species, &personality, &otId);
spriteId = CreateMonPicSprite(species, otId, personality, TRUE, MON_SPRITE_X_ON, MON_SPRITE_Y, 15, TAG_NONE);
2019-05-26 12:42:01 +02:00
gSprites[spriteId].oam.priority = 0;
return spriteId;
}
2021-11-09 12:50:35 -05:00
static void SlideMonSpriteOff(struct Pokenav_RibbonsSummaryMenu *menu)
2019-05-26 12:42:01 +02:00
{
2021-11-09 12:50:35 -05:00
StartMonSpriteSlide(&gSprites[menu->monSpriteId], MON_SPRITE_X_ON, MON_SPRITE_X_OFF, 6);
2019-05-26 12:42:01 +02:00
}
2021-11-09 12:50:35 -05:00
static void SlideMonSpriteOn(struct Pokenav_RibbonsSummaryMenu *menu)
2019-05-26 12:42:01 +02:00
{
// Switch to new mon sprite
2021-11-09 12:50:35 -05:00
FreeAndDestroyMonPicSprite(menu->monSpriteId);
menu->monSpriteId = DrawRibbonsMonFrontPic(MON_SPRITE_X_OFF, MON_SPRITE_Y);
// Slide on
2021-11-09 12:50:35 -05:00
StartMonSpriteSlide(&gSprites[menu->monSpriteId], MON_SPRITE_X_OFF, MON_SPRITE_X_ON, 6);
2019-05-26 12:42:01 +02:00
}
// Is Pokémon summary sprite still sliding off/on
2021-11-09 12:50:35 -05:00
static bool32 IsMonSpriteAnimating(struct Pokenav_RibbonsSummaryMenu *menu)
2019-05-26 12:42:01 +02:00
{
2021-11-09 12:50:35 -05:00
return (gSprites[menu->monSpriteId].callback != SpriteCallbackDummy);
2019-05-26 12:42:01 +02:00
}
#define sCurrX data[0]
#define sMoveIncr data[1]
#define sTime data[2]
#define sDestX data[3]
static void StartMonSpriteSlide(struct Sprite *sprite, s32 startX, s32 destX, s32 time)
2019-05-26 12:42:01 +02:00
{
u32 delta = destX - startX;
2019-05-26 12:42:01 +02:00
2021-07-07 09:11:52 -04:00
sprite->x = startX;
sprite->sCurrX = startX << 4;
sprite->sMoveIncr = (delta << 4) / time;
sprite->sTime = time;
sprite->sDestX = destX;
2019-05-26 12:42:01 +02:00
sprite->callback = SpriteCB_MonSpriteSlide;
2019-05-26 12:42:01 +02:00
}
static void SpriteCB_MonSpriteSlide(struct Sprite *sprite)
2019-05-26 12:42:01 +02:00
{
if (sprite->sTime != 0)
2019-05-26 12:42:01 +02:00
{
sprite->sTime--;
sprite->sCurrX += sprite->sMoveIncr;
2021-07-07 09:11:52 -04:00
sprite->x = sprite->sCurrX >> 4;
if (sprite->x <= MON_SPRITE_X_OFF)
2019-05-26 12:42:01 +02:00
sprite->invisible = TRUE;
else
sprite->invisible = FALSE;
}
else
{
2021-07-07 09:11:52 -04:00
sprite->x = sprite->sDestX;
2019-05-26 12:42:01 +02:00
sprite->callback = SpriteCallbackDummy;
}
}
#undef sCurrX
#undef sMoveIncr
#undef sTime
#undef sDestX
2021-11-09 12:50:35 -05:00
static void DrawAllRibbonsSmall(struct Pokenav_RibbonsSummaryMenu *menu)
2019-05-26 12:42:01 +02:00
{
u32 *ribbonIds;
2019-05-26 12:42:01 +02:00
ClearRibbonsSummaryBg();
2019-05-26 12:42:01 +02:00
ribbonIds = GetNormalRibbonIds(&sRibbonDraw_Total);
for (sRibbonDraw_Current = 0; sRibbonDraw_Current < sRibbonDraw_Total; sRibbonDraw_Current++)
DrawRibbonSmall(sRibbonDraw_Current, *(ribbonIds++));
2019-05-26 12:42:01 +02:00
ribbonIds = GetGiftRibbonIds(&sRibbonDraw_Total);
for (sRibbonDraw_Current = 0; sRibbonDraw_Current < sRibbonDraw_Total; sRibbonDraw_Current++)
DrawRibbonSmall(sRibbonDraw_Current + GIFT_RIBBON_START_POS, *(ribbonIds++));
2019-05-26 12:42:01 +02:00
CopyBgTilemapBufferToVram(1);
}
// Redundant, the same FillBg is called in LoopedTask_OpenRibbonsSummaryMenu
static void ClearRibbonsSummaryBg(void)
2019-05-26 12:42:01 +02:00
{
FillBgTilemapBufferRect_Palette0(1, 0, 0, 0, 32, 20);
}
static void DrawRibbonSmall(u32 i, u32 ribbonId)
2019-05-26 12:42:01 +02:00
{
u16 bgData[4];
u32 destX = (i % RIBBONS_PER_ROW) * 2 + 11;
u32 destY = (i / RIBBONS_PER_ROW) * 2 + 4;
2019-05-26 12:42:01 +02:00
BufferSmallRibbonGfxData(bgData, ribbonId);
2019-05-26 12:42:01 +02:00
CopyToBgTilemapBufferRect(1, bgData, destX, destY, 2, 2);
}
// Below correspond to a ribbon icon in ribbons/icons.png and ribbons/icons_big.png; 0 at top, 11 at bottom
enum {
RIBBONGFX_CHAMPION,
RIBBONGFX_CONTEST_NORMAL,
RIBBONGFX_CONTEST_SUPER,
RIBBONGFX_CONTEST_HYPER,
RIBBONGFX_CONTEST_MASTER,
RIBBONGFX_WINNING,
RIBBONGFX_VICTORY,
RIBBONGFX_ARTIST,
RIBBONGFX_EFFORT,
RIBBONGFX_GIFT_1,
RIBBONGFX_GIFT_2,
RIBBONGFX_GIFT_3,
};
#define TO_PAL_OFFSET(palNum)((palNum) - PALTAG_RIBBON_ICONS_1)
2019-05-26 12:42:01 +02:00
struct
{
u16 tileNumOffset;
u16 palNumOffset;
} static const sRibbonGfxData[] =
{
[CHAMPION_RIBBON] = { RIBBONGFX_CHAMPION, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_1)},
[COOL_RIBBON_NORMAL] = { RIBBONGFX_CONTEST_NORMAL, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_1)},
[COOL_RIBBON_SUPER] = { RIBBONGFX_CONTEST_SUPER, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_1)},
[COOL_RIBBON_HYPER] = { RIBBONGFX_CONTEST_HYPER, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_1)},
[COOL_RIBBON_MASTER] = { RIBBONGFX_CONTEST_MASTER, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_1)},
[BEAUTY_RIBBON_NORMAL] = { RIBBONGFX_CONTEST_NORMAL, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_2)},
[BEAUTY_RIBBON_SUPER] = { RIBBONGFX_CONTEST_SUPER, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_2)},
[BEAUTY_RIBBON_HYPER] = { RIBBONGFX_CONTEST_HYPER, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_2)},
[BEAUTY_RIBBON_MASTER] = { RIBBONGFX_CONTEST_MASTER, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_2)},
[CUTE_RIBBON_NORMAL] = { RIBBONGFX_CONTEST_NORMAL, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_3)},
[CUTE_RIBBON_SUPER] = { RIBBONGFX_CONTEST_SUPER, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_3)},
[CUTE_RIBBON_HYPER] = { RIBBONGFX_CONTEST_HYPER, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_3)},
[CUTE_RIBBON_MASTER] = { RIBBONGFX_CONTEST_MASTER, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_3)},
[SMART_RIBBON_NORMAL] = { RIBBONGFX_CONTEST_NORMAL, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_4)},
[SMART_RIBBON_SUPER] = { RIBBONGFX_CONTEST_SUPER, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_4)},
[SMART_RIBBON_HYPER] = { RIBBONGFX_CONTEST_HYPER, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_4)},
[SMART_RIBBON_MASTER] = { RIBBONGFX_CONTEST_MASTER, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_4)},
[TOUGH_RIBBON_NORMAL] = { RIBBONGFX_CONTEST_NORMAL, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_5)},
[TOUGH_RIBBON_SUPER] = { RIBBONGFX_CONTEST_SUPER, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_5)},
[TOUGH_RIBBON_HYPER] = { RIBBONGFX_CONTEST_HYPER, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_5)},
[TOUGH_RIBBON_MASTER] = { RIBBONGFX_CONTEST_MASTER, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_5)},
[WINNING_RIBBON] = { RIBBONGFX_WINNING, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_1)},
[VICTORY_RIBBON] = { RIBBONGFX_VICTORY, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_1)},
[ARTIST_RIBBON] = { RIBBONGFX_ARTIST, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_2)},
[EFFORT_RIBBON] = { RIBBONGFX_EFFORT, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_3)},
[MARINE_RIBBON] = { RIBBONGFX_GIFT_1, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_2)},
[LAND_RIBBON] = { RIBBONGFX_GIFT_1, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_4)},
[SKY_RIBBON] = { RIBBONGFX_GIFT_1, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_5)},
[COUNTRY_RIBBON] = { RIBBONGFX_GIFT_2, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_4)},
[NATIONAL_RIBBON] = { RIBBONGFX_GIFT_2, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_5)},
[EARTH_RIBBON] = { RIBBONGFX_GIFT_3, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_1)},
[WORLD_RIBBON] = { RIBBONGFX_GIFT_3, TO_PAL_OFFSET(PALTAG_RIBBON_ICONS_2)},
2019-05-26 12:42:01 +02:00
};
#undef TO_PAL_OFFSET
static void BufferSmallRibbonGfxData(u16 *dst, u32 ribbonId)
2019-05-26 12:42:01 +02:00
{
u16 palNum = sRibbonGfxData[ribbonId].palNumOffset + 2;
u16 tileNum = (sRibbonGfxData[ribbonId].tileNumOffset * 2) + 1;
2019-05-26 12:42:01 +02:00
dst[0] = tileNum | (palNum << 12);
dst[1] = tileNum | (palNum << 12) | 0x400;
dst[2] = (tileNum + 1) | (palNum << 12);
dst[3] = (tileNum + 1) | (palNum << 12) | 0x400;
2019-05-26 12:42:01 +02:00
}
static const struct CompressedSpriteSheet sSpriteSheet_RibbonIconsBig =
2019-05-26 12:42:01 +02:00
{
sRibbonIconsBig_Gfx, 0x1800, GFXTAG_RIBBON_ICONS_BIG
2019-05-26 12:42:01 +02:00
};
static const struct SpritePalette sSpritePalettes_RibbonIcons[] =
2019-05-26 12:42:01 +02:00
{
{sRibbonIcons1_Pal, PALTAG_RIBBON_ICONS_1},
{sRibbonIcons2_Pal, PALTAG_RIBBON_ICONS_2},
{sRibbonIcons3_Pal, PALTAG_RIBBON_ICONS_3},
{sRibbonIcons4_Pal, PALTAG_RIBBON_ICONS_4},
{sRibbonIcons5_Pal, PALTAG_RIBBON_ICONS_5},
2019-05-26 12:42:01 +02:00
{},
};
static const struct OamData sOamData_RibbonIconBig =
2019-05-26 12:42:01 +02:00
{
.y = 0,
.affineMode = ST_OAM_AFFINE_NORMAL,
.objMode = ST_OAM_OBJ_NORMAL,
2022-07-29 21:27:39 -04:00
.mosaic = FALSE,
.bpp = ST_OAM_4BPP,
2019-05-26 12:42:01 +02:00
.shape = SPRITE_SHAPE(32x32),
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(32x32),
.tileNum = 0,
.priority = 1,
.paletteNum = 0,
.affineParam = 0
};
static const union AffineAnimCmd sAffineAnim_RibbonIconBig_Normal[] =
2019-05-26 12:42:01 +02:00
{
AFFINEANIMCMD_FRAME(128, 128, 0, 0),
AFFINEANIMCMD_END
};
static const union AffineAnimCmd sAffineAnim_RibbonIconBig_ZoomIn[] =
2019-05-26 12:42:01 +02:00
{
AFFINEANIMCMD_FRAME(128, 128, 0, 0),
AFFINEANIMCMD_FRAME(32, 32, 0, 4),
AFFINEANIMCMD_END
};
static const union AffineAnimCmd sAffineAnim_RibbonIconBig_ZoomOut[] =
2019-05-26 12:42:01 +02:00
{
AFFINEANIMCMD_FRAME(256, 256, 0, 0),
AFFINEANIMCMD_FRAME(-32, -32, 0, 4),
AFFINEANIMCMD_END
};
enum {
RIBBONANIM_NORMAL,
RIBBONANIM_ZOOM_IN,
RIBBONANIM_ZOOM_OUT,
};
static const union AffineAnimCmd *const sAffineAnims_RibbonIconBig[] =
2019-05-26 12:42:01 +02:00
{
[RIBBONANIM_NORMAL] = sAffineAnim_RibbonIconBig_Normal,
[RIBBONANIM_ZOOM_IN] = sAffineAnim_RibbonIconBig_ZoomIn,
[RIBBONANIM_ZOOM_OUT] = sAffineAnim_RibbonIconBig_ZoomOut
2019-05-26 12:42:01 +02:00
};
static const struct SpriteTemplate sSpriteTemplate_RibbonIconBig =
2019-05-26 12:42:01 +02:00
{
.tileTag = GFXTAG_RIBBON_ICONS_BIG,
.paletteTag = PALTAG_RIBBON_ICONS_1,
.oam = &sOamData_RibbonIconBig,
2019-05-26 12:42:01 +02:00
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = sAffineAnims_RibbonIconBig,
2019-05-26 12:42:01 +02:00
.callback = SpriteCallbackDummy,
};
// Create dummy sprite to be used for the zoomed in version of the selected ribbon
2021-11-09 12:50:35 -05:00
static void CreateBigRibbonSprite(struct Pokenav_RibbonsSummaryMenu *menu)
2019-05-26 12:42:01 +02:00
{
u8 spriteId;
LoadCompressedSpriteSheet(&sSpriteSheet_RibbonIconsBig);
Pokenav_AllocAndLoadPalettes(sSpritePalettes_RibbonIcons);
2019-05-26 12:42:01 +02:00
spriteId = CreateSprite(&sSpriteTemplate_RibbonIconBig, 0, 0, 0);
2021-11-09 12:50:35 -05:00
menu->bigRibbonSprite = &gSprites[spriteId];
menu->bigRibbonSprite->invisible = TRUE;
2019-05-26 12:42:01 +02:00
}
#define sInvisibleWhenDone data[0]
2021-11-09 12:50:35 -05:00
static void UpdateAndZoomInSelectedRibbon(struct Pokenav_RibbonsSummaryMenu *menu)
2019-05-26 12:42:01 +02:00
{
u32 ribbonId;
s32 position = GetSelectedPosition();
s32 x = (position % RIBBONS_PER_ROW) * 16 + 96;
s32 y = (position / RIBBONS_PER_ROW) * 16 + 40;
2021-11-09 12:50:35 -05:00
menu->bigRibbonSprite->x = x;
menu->bigRibbonSprite->y = y;
// Set new selected ribbon's gfx data
ribbonId = GetRibbonId();
2021-11-09 12:50:35 -05:00
menu->bigRibbonSprite->oam.tileNum = (sRibbonGfxData[ribbonId].tileNumOffset * 16) + GetSpriteTileStartByTag(GFXTAG_RIBBON_ICONS_BIG);
menu->bigRibbonSprite->oam.paletteNum = IndexOfSpritePaletteTag(sRibbonGfxData[ribbonId].palNumOffset + PALTAG_RIBBON_ICONS_1);
// Start zoom in animation
2021-11-09 12:50:35 -05:00
StartSpriteAffineAnim(menu->bigRibbonSprite, RIBBONANIM_ZOOM_IN);
menu->bigRibbonSprite->invisible = FALSE;
menu->bigRibbonSprite->sInvisibleWhenDone = FALSE;
menu->bigRibbonSprite->callback = SpriteCB_WaitForRibbonAnimation;
2019-05-26 12:42:01 +02:00
}
// Start animation to zoom out of selected ribbon
2021-11-09 12:50:35 -05:00
static void ZoomOutSelectedRibbon(struct Pokenav_RibbonsSummaryMenu *menu)
2019-05-26 12:42:01 +02:00
{
2021-11-09 12:50:35 -05:00
menu->bigRibbonSprite->sInvisibleWhenDone = TRUE;
StartSpriteAffineAnim(menu->bigRibbonSprite, RIBBONANIM_ZOOM_OUT);
menu->bigRibbonSprite->callback = SpriteCB_WaitForRibbonAnimation;
2019-05-26 12:42:01 +02:00
}
2021-11-09 12:50:35 -05:00
static bool32 IsRibbonAnimating(struct Pokenav_RibbonsSummaryMenu *menu)
2019-05-26 12:42:01 +02:00
{
2021-11-09 12:50:35 -05:00
return (menu->bigRibbonSprite->callback != SpriteCallbackDummy);
2019-05-26 12:42:01 +02:00
}
static void SpriteCB_WaitForRibbonAnimation(struct Sprite *sprite)
2019-05-26 12:42:01 +02:00
{
if (sprite->affineAnimEnded)
{
sprite->invisible = sprite->sInvisibleWhenDone;
2019-05-26 12:42:01 +02:00
sprite->callback = SpriteCallbackDummy;
}
}