pokeemerald/src/pokedex.c

5698 lines
168 KiB
C
Raw Normal View History

2017-12-21 22:56:20 +01:00
#include "global.h"
2018-11-27 05:00:38 +01:00
#include "battle_main.h"
2017-12-22 18:43:41 +01:00
#include "bg.h"
2019-04-04 23:53:06 +02:00
#include "data.h"
2018-11-14 01:01:50 +01:00
#include "decompress.h"
2018-02-16 00:20:19 +01:00
#include "event_data.h"
2018-11-14 01:01:50 +01:00
#include "gpu_regs.h"
#include "graphics.h"
#include "international_string_util.h"
2018-03-30 22:48:30 +02:00
#include "main.h"
#include "malloc.h"
2018-03-30 22:48:30 +02:00
#include "menu.h"
2018-11-14 01:01:50 +01:00
#include "m4a.h"
#include "overworld.h"
#include "palette.h"
#include "pokedex.h"
2018-05-01 02:41:17 +02:00
#include "pokedex_area_screen.h"
#include "pokedex_cry_screen.h"
2018-11-14 01:01:50 +01:00
#include "scanline_effect.h"
#include "sound.h"
#include "sprite.h"
#include "string_util.h"
2018-05-01 02:41:17 +02:00
#include "strings.h"
2018-11-14 01:01:50 +01:00
#include "task.h"
#include "text_window.h"
#include "trainer_pokemon_sprites.h"
#include "trig.h"
#include "window.h"
#include "constants/rgb.h"
#include "constants/songs.h"
#include "constants/species.h"
2018-03-30 22:48:30 +02:00
2020-03-08 18:24:22 +01:00
enum
{
PAGE_MAIN,
PAGE_INFO,
PAGE_SEARCH,
PAGE_SEARCH_RESULTS,
PAGE_UNK,
PAGE_AREA,
PAGE_CRY,
PAGE_SIZE
};
enum
{
AREA_SCREEN,
CRY_SCREEN,
SIZE_SCREEN,
CANCEL_SCREEN,
SCREEN_COUNT
};
enum
{
SEARCH_NAME,
SEARCH_COLOR,
SEARCH_TYPE_LEFT,
SEARCH_TYPE_RIGHT,
SEARCH_ORDER,
SEARCH_MODE,
SEARCH_OK,
SEARCH_COUNT
};
enum
{
SEARCH_TOPBAR_SEARCH,
SEARCH_TOPBAR_SHIFT,
SEARCH_TOPBAR_CANCEL,
SEARCH_TOPBAR_COUNT
};
enum
{
ORDER_NUMERICAL,
ORDER_ALPHABETICAL,
ORDER_HEAVIEST,
ORDER_LIGHTEST,
ORDER_TALLEST,
ORDER_SMALLEST
};
enum
{
NAME_ABC = 1,
NAME_DEF,
NAME_GHI,
NAME_JKL,
NAME_MNO,
NAME_PQR,
NAME_STU,
NAME_VWX,
NAME_YZ,
};
// For scrolling search parameter
#define MAX_SEARCH_PARAM_ON_SCREEN 6
#define MAX_SEARCH_PARAM_CURSOR_POS (MAX_SEARCH_PARAM_ON_SCREEN - 1)
#define MAX_MONS_ON_SCREEN 4
#define LIST_SCROLL_STEP 16
#define POKEBALL_ROTATION_TOP 64
#define POKEBALL_ROTATION_BOTTOM (POKEBALL_ROTATION_TOP - 16)
2018-11-19 01:03:14 +01:00
// EWRAM
2018-12-03 15:58:25 +01:00
static EWRAM_DATA struct PokedexView *sPokedexView = NULL;
2020-03-08 18:24:22 +01:00
static EWRAM_DATA u16 sLastSelectedPokemon = 0;
static EWRAM_DATA u8 sPokeBallRotation = 0;
2018-12-03 15:58:25 +01:00
static EWRAM_DATA struct PokedexListItem *sPokedexListItem = NULL;
2018-02-16 00:20:19 +01:00
2018-11-19 01:03:14 +01:00
// IWRAM common
// This is written to, but never read.
2019-02-18 07:33:41 +01:00
u8 gUnusedPokedexU8;
2020-03-08 18:24:22 +01:00
void (*gPokedexVBlankCB)(void);
2018-05-01 02:41:17 +02:00
2020-03-08 18:24:22 +01:00
struct SearchOptionText
2018-05-10 09:30:42 +02:00
{
2018-12-05 16:09:19 +01:00
const u8 *description;
const u8 *title;
2018-05-10 09:30:42 +02:00
};
2020-03-08 18:24:22 +01:00
struct SearchOption
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
const struct SearchOptionText *texts;
u8 taskDataCursorPos;
u8 taskDataScrollOffset;
2020-01-03 02:35:35 +01:00
u16 numOptions;
2018-05-10 09:30:42 +02:00
};
2020-03-08 18:24:22 +01:00
struct SearchMenuTopBarItem
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
const u8 *description;
u8 highlightX;
u8 highlightY;
u8 highlightWidth;
2018-05-10 09:30:42 +02:00
};
2020-03-08 18:24:22 +01:00
struct SearchMenuItem
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
const u8 *description;
u8 titleBgX;
u8 titleBgY;
u8 titleBgWidth;
u8 selectionBgX;
u8 selectionBgY;
u8 selectionBgWidth;
2018-05-10 09:30:42 +02:00
};
2018-03-30 22:48:30 +02:00
extern struct MusicPlayerInfo gMPlayInfo_BGM;
2018-02-16 00:20:19 +01:00
struct PokedexListItem
{
u16 dexNum;
u16 seen:1;
u16 owned:1;
};
struct PokedexView
{
2020-03-08 18:24:22 +01:00
struct PokedexListItem pokedexList[NATIONAL_DEX_COUNT + 1];
2018-02-16 00:20:19 +01:00
u16 pokemonListCount;
u16 selectedPokemon;
2020-03-08 18:24:22 +01:00
u16 selectedPokemonBackup;
2018-02-16 00:20:19 +01:00
u16 dexMode;
2020-03-08 18:24:22 +01:00
u16 dexModeBackup;
2018-02-16 00:20:19 +01:00
u16 dexOrder;
2020-03-08 18:24:22 +01:00
u16 dexOrderBackup;
2018-12-03 15:58:25 +01:00
u16 seenCount;
u16 ownCount;
2020-03-08 18:24:22 +01:00
u16 monSpriteIds[MAX_MONS_ON_SCREEN];
2018-02-16 00:20:19 +01:00
u16 selectedMonSpriteId;
2020-03-08 18:24:22 +01:00
u16 pokeBallRotationStep;
u16 pokeBallRotationBackup;
u8 pokeBallRotation;
2018-12-05 01:15:22 +01:00
u8 initialVOffset;
2020-03-08 18:24:22 +01:00
u8 scrollTimer;
u8 scrollDirection;
s16 listVOffset;
s16 listMovingVOffset;
u16 scrollMonIncrement;
u16 maxScrollTimer;
u16 scrollSpeed;
u16 unkArr1[4]; // Cleared, never read
u8 filler[8];
u8 currentPage;
u8 currentPageBackup;
bool8 isSearchResults:1;
2018-02-16 00:20:19 +01:00
u8 selectedScreen;
2020-03-08 18:24:22 +01:00
u8 screenSwitchState;
u8 menuIsOpen;
u16 menuCursorPos;
2018-02-16 00:20:19 +01:00
s16 menuY; //Menu Y position (inverted because we use REG_BG0VOFS for this)
2020-03-08 18:24:22 +01:00
u8 unkArr2[8]; // Cleared, never read
u8 unkArr3[8]; // Cleared, never read
2018-05-01 02:41:17 +02:00
};
2017-12-22 18:43:41 +01:00
// this file's functions
2020-03-08 18:24:22 +01:00
static void CB2_Pokedex(void);
static void Task_OpenPokedexMainPage(u8);
static void Task_HandlePokedexInput(u8);
static void Task_WaitForScroll(u8);
static void Task_HandlePokedexStartMenuInput(u8);
static void Task_OpenInfoScreenAfterMonMovement(u8);
static void Task_WaitForExitInfoScreen(u8);
static void Task_WaitForExitSearch(u8);
static void Task_ClosePokedex(u8);
static void Task_OpenSearchResults(u8);
static void Task_HandleSearchResultsInput(u8);
static void Task_WaitForSearchResultsScroll(u8);
static void Task_HandleSearchResultsStartMenuInput(u8);
static void Task_OpenSearchResultsInfoScreenAfterMonMovement(u8);
static void Task_WaitForExitSearchResultsInfoScreen(u8);
static void Task_ReturnToPokedexFromSearchResults(u8);
static void Task_ClosePokedexFromSearchResultsStartMenu(u8);
static bool8 LoadPokedexListPage(u8);
static void LoadPokedexBgPalette(bool8);
2020-01-03 02:35:35 +01:00
static void FreeWindowAndBgBuffers(void);
2020-03-08 18:24:22 +01:00
static void CreatePokedexList(u8, u8);
2018-12-05 01:15:22 +01:00
static void CreateMonDexNum(u16, u8, u8, u16);
static void CreateCaughtBall(u16, u8, u8, u16);
static u8 CreateMonName(u16, u8, u8);
2020-01-03 02:35:35 +01:00
static void ClearMonListEntry(u8 x, u8 y, u16 unused);
2020-03-08 18:24:22 +01:00
static void CreateMonSpritesAtPos(u16, u16);
static bool8 UpdateDexListScroll(u8, u8, u8);
static u16 TryDoPokedexScroll(u16, u16);
2020-01-03 02:35:35 +01:00
static void UpdateSelectedMonSpriteId(void);
2020-03-08 18:24:22 +01:00
static bool8 TryDoInfoScreenScroll(void);
2020-01-03 02:35:35 +01:00
static u8 ClearMonSprites(void);
2020-03-08 18:24:22 +01:00
static u16 GetPokemonSpriteToDisplay(u16);
static u32 CreatePokedexMonSprite(u16, s16, s16);
2018-12-03 15:58:25 +01:00
static void CreateInterfaceSprites(u8);
2020-03-08 18:24:22 +01:00
static void SpriteCB_MoveMonForInfoScreen(struct Sprite *sprite);
2018-12-05 01:15:22 +01:00
static void SpriteCB_Scrollbar(struct Sprite *sprite);
2020-03-08 18:24:22 +01:00
static void SpriteCB_ScrollArrow(struct Sprite *sprite);
static void SpriteCB_DexListInterfaceText(struct Sprite *sprite);
static void SpriteCB_RotatingPokeBall(struct Sprite *sprite);
static void SpriteCB_SeenOwnInfo(struct Sprite *sprite);
static void SpriteCB_DexListStartMenuCursor(struct Sprite *sprite);
static void SpriteCB_PokedexListMonSprite(struct Sprite *sprite);
static u8 LoadInfoScreen(struct PokedexListItem*, u8 monSpriteId);
static bool8 IsInfoScreenScrolling(u8);
static u8 sub_80BE9F8(struct PokedexListItem*, u8);
static void Task_LoadInfoScreen(u8);
static void Task_HandleInfoScreenInput(u8);
static void Task_SwitchScreensFromInfoScreen(u8);
static void Task_LoadInfoScreenWaitForFade(u8);
static void Task_ExitInfoScreen(u8);
static void Task_LoadAreaScreen(u8);
static void Task_WaitForAreaScreenInput(u8 taskId);
static void Task_SwitchScreensFromAreaScreen(u8);
static void Task_LoadCryScreen(u8);
static void Task_HandleCryScreenInput(u8);
static void Task_SwitchScreensFromCryScreen(u8);
static void LoadPlayArrowPalette(bool8);
static void Task_LoadSizeScreen(u8);
static void Task_HandleSizeScreenInput(u8);
static void Task_SwitchScreensFromSizeScreen(u8);
static void LoadScreenSelectBarMain(u16);
static void LoadScreenSelectBarSubmenu(u16);
static void HighlightScreenSelectBarItem(u8, u16);
static void HighlightSubmenuScreenSelectBarItem(u8, u16);
static void Task_DisplayCaughtMonDexPage(u8);
static void Task_HandleCaughtMonPageInput(u8);
static void Task_ExitCaughtMonPage(u8);
static void SpriteCB_SlideCaughtMonToCenter(struct Sprite *sprite);
2019-12-06 03:20:18 +01:00
static void PrintMonInfo(u32 num, u32, u32 owned, u32 newEntry);
static void PrintMonHeight(u16 height, u8 left, u8 top);
static void PrintMonWeight(u16 weight, u8 left, u8 top);
2019-12-06 15:44:23 +01:00
static void ResetOtherVideoRegisters(u16);
2020-03-08 18:24:22 +01:00
static u8 PrintCryScreenSpeciesName(u8, u16, u8, u8);
2019-12-06 03:20:18 +01:00
static void PrintFootprint(u8 windowId, u16 dexNum);
2020-03-08 18:24:22 +01:00
static u16 CreateSizeScreenTrainerPic(u16, s16, s16, s8);
static u16 GetNextPosition(u8, u16, u16, u16);
static u8 LoadSearchMenu(void);
static void Task_LoadSearchMenu(u8);
static void Task_SwitchToSearchMenuTopBar(u8);
static void Task_HandleSearchTopBarInput(u8);
static void Task_SwitchToSearchMenu(u8);
static void Task_HandleSearchMenuInput(u8);
static void Task_StartPokedexSearch(u8);
static void Task_WaitAndCompleteSearch(u8);
static void Task_SearchCompleteWaitForInput(u8);
static void Task_SelectSearchMenuItem(u8);
static void Task_HandleSearchParameterInput(u8);
static void Task_ExitSearch(u8);
static void Task_ExitSearchWaitForFade(u8);
static void HighlightSelectedSearchTopBarItem(u8);
static void HighlightSelectedSearchMenuItem(u8, u8);
static void PrintSelectedSearchParameters(u8);
static void DrawOrEraseSearchParameterBox(bool8);
static void PrintSearchParameterText(u8);
2020-01-03 02:35:35 +01:00
static u8 GetSearchModeSelection(u8 taskId, u8 option);
2020-03-08 18:24:22 +01:00
static void SetDefaultSearchModeAndOrder(u8);
static void CreateSearchParameterScrollArrows(u8);
static void EraseAndPrintSearchTextBox(const u8*);
static void EraseSelectorArrow(u32);
static void PrintSelectorArrow(u32);
static void PrintSearchParameterTitle(u32, const u8*);
static void ClearSearchParameterBoxText(void);
2017-12-22 18:43:41 +01:00
// const rom data
2018-12-03 16:10:41 +01:00
#include "data/pokemon/pokedex_orders.h"
2017-12-21 22:56:20 +01:00
2020-03-08 18:24:22 +01:00
static const struct OamData sOamData_ScrollBar =
2017-12-21 22:56:20 +01:00
{
.y = 160,
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
2017-12-21 22:56:20 +01:00
.mosaic = 0,
.bpp = ST_OAM_4BPP,
.shape = SPRITE_SHAPE(8x8),
2017-12-21 22:56:20 +01:00
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(8x8),
2017-12-21 22:56:20 +01:00
.tileNum = 0,
.priority = 1,
.paletteNum = 0,
2017-12-22 18:43:41 +01:00
.affineParam = 0
2017-12-21 22:56:20 +01:00
};
2017-12-22 18:43:41 +01:00
2020-03-08 18:24:22 +01:00
static const struct OamData sOamData_ScrollArrow =
2017-12-21 22:56:20 +01:00
{
.y = 160,
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
2017-12-21 22:56:20 +01:00
.mosaic = 0,
.bpp = ST_OAM_4BPP,
.shape = SPRITE_SHAPE(16x8),
2017-12-21 22:56:20 +01:00
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(16x8),
2017-12-21 22:56:20 +01:00
.tileNum = 0,
.priority = 0,
.paletteNum = 0,
2017-12-22 18:43:41 +01:00
.affineParam = 0
2017-12-21 22:56:20 +01:00
};
2017-12-22 18:43:41 +01:00
2020-03-08 18:24:22 +01:00
static const struct OamData sOamData_InterfaceText =
2017-12-21 22:56:20 +01:00
{
.y = 160,
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
2017-12-21 22:56:20 +01:00
.mosaic = 0,
.bpp = ST_OAM_4BPP,
.shape = SPRITE_SHAPE(32x16),
2017-12-21 22:56:20 +01:00
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(32x16),
2017-12-21 22:56:20 +01:00
.tileNum = 0,
.priority = 0,
.paletteNum = 0,
2017-12-22 18:43:41 +01:00
.affineParam = 0
2017-12-21 22:56:20 +01:00
};
2017-12-22 18:43:41 +01:00
2020-03-08 18:24:22 +01:00
static const struct OamData sOamData_RotatingPokeBall =
2017-12-21 22:56:20 +01:00
{
.y = 160,
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_WINDOW,
2017-12-21 22:56:20 +01:00
.mosaic = 0,
.bpp = ST_OAM_4BPP,
.shape = SPRITE_SHAPE(32x32),
2017-12-21 22:56:20 +01:00
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(32x32),
2017-12-21 22:56:20 +01:00
.tileNum = 0,
.priority = 1,
.paletteNum = 0,
2017-12-22 18:43:41 +01:00
.affineParam = 0
2017-12-21 22:56:20 +01:00
};
2017-12-22 18:43:41 +01:00
2020-03-08 18:24:22 +01:00
static const struct OamData sOamData_SeenOwnText =
2017-12-21 22:56:20 +01:00
{
.y = 160,
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
2017-12-21 22:56:20 +01:00
.mosaic = 0,
.bpp = ST_OAM_4BPP,
.shape = SPRITE_SHAPE(64x32),
2017-12-21 22:56:20 +01:00
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(64x32),
2017-12-21 22:56:20 +01:00
.tileNum = 0,
.priority = 0,
.paletteNum = 0,
2017-12-22 18:43:41 +01:00
.affineParam = 0
2017-12-21 22:56:20 +01:00
};
2017-12-22 18:43:41 +01:00
2020-03-08 18:24:22 +01:00
static const struct OamData sOamData_Dex8x16 =
2017-12-21 22:56:20 +01:00
{
.y = 160,
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
2017-12-21 22:56:20 +01:00
.mosaic = 0,
.bpp = ST_OAM_4BPP,
.shape = SPRITE_SHAPE(8x16),
2017-12-21 22:56:20 +01:00
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(8x16),
2017-12-21 22:56:20 +01:00
.tileNum = 0,
.priority = 0,
.paletteNum = 0,
2017-12-22 18:43:41 +01:00
.affineParam = 0
2017-12-21 22:56:20 +01:00
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_ScrollBar[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(3, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_ScrollArrow[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(1, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_RotatingPokeBall[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(16, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_StartButton[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(48, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_SearchText[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(40, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_SelectButton[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(32, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_MenuText[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(56, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_SeenText[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(64, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_OwnText[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(96, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_HoennText[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(160, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_NationalText[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(168, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_HoennSeenOwnDigit0[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(128, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_HoennSeenOwnDigit1[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(130, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_HoennSeenOwnDigit2[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(132, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_HoennSeenOwnDigit3[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(134, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_HoennSeenOwnDigit4[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(136, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_HoennSeenOwnDigit5[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(138, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_HoennSeenOwnDigit6[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(140, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_HoennSeenOwnDigit7[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(142, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_HoennSeenOwnDigit8[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(144, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_HoennSeenOwnDigit9[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(146, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_NationalSeenOwnDigit0[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(176, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_NationalSeenOwnDigit1[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(178, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_NationalSeenOwnDigit2[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(180, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_NationalSeenOwnDigit3[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(182, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_NationalSeenOwnDigit4[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(184, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_NationalSeenOwnDigit5[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(186, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_NationalSeenOwnDigit6[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(188, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_NationalSeenOwnDigit7[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(190, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_NationalSeenOwnDigit8[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(192, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_NationalSeenOwnDigit9[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(194, 30),
ANIMCMD_END
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd sSpriteAnim_DexListStartMenuCursor[] =
2017-12-21 22:56:20 +01:00
{
ANIMCMD_FRAME(4, 30),
ANIMCMD_END
};
2017-12-22 18:43:41 +01:00
2020-03-08 18:24:22 +01:00
static const union AnimCmd *const sSpriteAnimTable_ScrollBar[] =
2017-12-22 18:43:41 +01:00
{
2020-03-08 18:24:22 +01:00
sSpriteAnim_ScrollBar
2017-12-22 18:43:41 +01:00
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd *const sSpriteAnimTable_ScrollArrow[] =
2017-12-22 18:43:41 +01:00
{
2020-03-08 18:24:22 +01:00
sSpriteAnim_ScrollArrow
2017-12-22 18:43:41 +01:00
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd *const sSpriteAnimTable_RotatingPokeBall[] =
2017-12-22 18:43:41 +01:00
{
2020-03-08 18:24:22 +01:00
sSpriteAnim_RotatingPokeBall
2017-12-22 18:43:41 +01:00
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd *const sSpriteAnimTable_InterfaceText[] =
2017-12-22 18:43:41 +01:00
{
2020-03-08 18:24:22 +01:00
sSpriteAnim_StartButton,
sSpriteAnim_SearchText,
sSpriteAnim_SelectButton,
sSpriteAnim_MenuText
2017-12-22 18:43:41 +01:00
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd *const sSpriteAnimTable_SeenOwnText[] =
2017-12-22 18:43:41 +01:00
{
2020-03-08 18:24:22 +01:00
sSpriteAnim_SeenText,
sSpriteAnim_OwnText
2017-12-22 18:43:41 +01:00
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd *const sSpriteAnimTable_HoennNationalText[] =
2017-12-22 18:43:41 +01:00
{
2020-03-08 18:24:22 +01:00
sSpriteAnim_HoennText,
sSpriteAnim_NationalText
2017-12-22 18:43:41 +01:00
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd *const sSpriteAnimTable_HoennSeenOwnNumber[] =
{
sSpriteAnim_HoennSeenOwnDigit0,
sSpriteAnim_HoennSeenOwnDigit1,
sSpriteAnim_HoennSeenOwnDigit2,
sSpriteAnim_HoennSeenOwnDigit3,
sSpriteAnim_HoennSeenOwnDigit4,
sSpriteAnim_HoennSeenOwnDigit5,
sSpriteAnim_HoennSeenOwnDigit6,
sSpriteAnim_HoennSeenOwnDigit7,
sSpriteAnim_HoennSeenOwnDigit8,
sSpriteAnim_HoennSeenOwnDigit9
2017-12-22 18:43:41 +01:00
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd *const sSpriteAnimTable_NationalSeenOwnNumber[] =
{
sSpriteAnim_NationalSeenOwnDigit0,
sSpriteAnim_NationalSeenOwnDigit1,
sSpriteAnim_NationalSeenOwnDigit2,
sSpriteAnim_NationalSeenOwnDigit3,
sSpriteAnim_NationalSeenOwnDigit4,
sSpriteAnim_NationalSeenOwnDigit5,
sSpriteAnim_NationalSeenOwnDigit6,
sSpriteAnim_NationalSeenOwnDigit7,
sSpriteAnim_NationalSeenOwnDigit8,
sSpriteAnim_NationalSeenOwnDigit9
2017-12-22 18:43:41 +01:00
};
2020-03-08 18:24:22 +01:00
static const union AnimCmd *const sSpriteAnimTable_DexListStartMenuCursor[] =
2017-12-22 18:43:41 +01:00
{
2020-03-08 18:24:22 +01:00
sSpriteAnim_DexListStartMenuCursor
2017-12-22 18:43:41 +01:00
};
#define TAG_DEX_INTERFACE 4096 // Tile and pal tag used for all interface sprites.
2018-12-03 15:58:25 +01:00
static const struct SpriteTemplate sScrollBarSpriteTemplate =
2017-12-22 18:43:41 +01:00
{
.tileTag = TAG_DEX_INTERFACE,
.paletteTag = TAG_DEX_INTERFACE,
2020-03-08 18:24:22 +01:00
.oam = &sOamData_ScrollBar,
.anims = sSpriteAnimTable_ScrollBar,
2017-12-22 18:43:41 +01:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2018-12-05 01:15:22 +01:00
.callback = SpriteCB_Scrollbar,
2017-12-22 18:43:41 +01:00
};
2020-03-08 18:24:22 +01:00
static const struct SpriteTemplate sScrollArrowSpriteTemplate =
2017-12-22 18:43:41 +01:00
{
.tileTag = TAG_DEX_INTERFACE,
.paletteTag = TAG_DEX_INTERFACE,
2020-03-08 18:24:22 +01:00
.oam = &sOamData_ScrollArrow,
.anims = sSpriteAnimTable_ScrollArrow,
2017-12-22 18:43:41 +01:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2020-03-08 18:24:22 +01:00
.callback = SpriteCB_ScrollArrow,
2017-12-22 18:43:41 +01:00
};
2018-12-03 15:58:25 +01:00
static const struct SpriteTemplate sInterfaceTextSpriteTemplate =
2017-12-22 18:43:41 +01:00
{
.tileTag = TAG_DEX_INTERFACE,
.paletteTag = TAG_DEX_INTERFACE,
2020-03-08 18:24:22 +01:00
.oam = &sOamData_InterfaceText,
.anims = sSpriteAnimTable_InterfaceText,
2017-12-22 18:43:41 +01:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2020-03-08 18:24:22 +01:00
.callback = SpriteCB_DexListInterfaceText,
2017-12-22 18:43:41 +01:00
};
2020-03-08 18:24:22 +01:00
static const struct SpriteTemplate sRotatingPokeBallSpriteTemplate =
2017-12-22 18:43:41 +01:00
{
.tileTag = TAG_DEX_INTERFACE,
.paletteTag = TAG_DEX_INTERFACE,
2020-03-08 18:24:22 +01:00
.oam = &sOamData_RotatingPokeBall,
.anims = sSpriteAnimTable_RotatingPokeBall,
2017-12-22 18:43:41 +01:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2020-03-08 18:24:22 +01:00
.callback = SpriteCB_RotatingPokeBall,
2017-12-22 18:43:41 +01:00
};
2018-12-03 15:58:25 +01:00
static const struct SpriteTemplate sSeenOwnTextSpriteTemplate =
2017-12-22 18:43:41 +01:00
{
.tileTag = TAG_DEX_INTERFACE,
.paletteTag = TAG_DEX_INTERFACE,
2020-03-08 18:24:22 +01:00
.oam = &sOamData_SeenOwnText,
.anims = sSpriteAnimTable_SeenOwnText,
2017-12-22 18:43:41 +01:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2020-03-08 18:24:22 +01:00
.callback = SpriteCB_SeenOwnInfo,
2017-12-22 18:43:41 +01:00
};
2020-03-08 18:24:22 +01:00
static const struct SpriteTemplate sHoennNationalTextSpriteTemplate =
2017-12-22 18:43:41 +01:00
{
.tileTag = TAG_DEX_INTERFACE,
.paletteTag = TAG_DEX_INTERFACE,
2020-03-08 18:24:22 +01:00
.oam = &sOamData_InterfaceText,
.anims = sSpriteAnimTable_HoennNationalText,
2017-12-22 18:43:41 +01:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2020-03-08 18:24:22 +01:00
.callback = SpriteCB_SeenOwnInfo,
2017-12-22 18:43:41 +01:00
};
2020-03-08 18:24:22 +01:00
static const struct SpriteTemplate sHoennDexSeenOwnNumberSpriteTemplate =
2017-12-22 18:43:41 +01:00
{
.tileTag = TAG_DEX_INTERFACE,
.paletteTag = TAG_DEX_INTERFACE,
2020-03-08 18:24:22 +01:00
.oam = &sOamData_Dex8x16,
.anims = sSpriteAnimTable_HoennSeenOwnNumber,
2017-12-22 18:43:41 +01:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2020-03-08 18:24:22 +01:00
.callback = SpriteCB_SeenOwnInfo,
2017-12-22 18:43:41 +01:00
};
2020-03-08 18:24:22 +01:00
static const struct SpriteTemplate sNationalDexSeenOwnNumberSpriteTemplate =
2017-12-22 18:43:41 +01:00
{
.tileTag = TAG_DEX_INTERFACE,
.paletteTag = TAG_DEX_INTERFACE,
2020-03-08 18:24:22 +01:00
.oam = &sOamData_Dex8x16,
.anims = sSpriteAnimTable_NationalSeenOwnNumber,
2017-12-22 18:43:41 +01:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2020-03-08 18:24:22 +01:00
.callback = SpriteCB_SeenOwnInfo,
2017-12-22 18:43:41 +01:00
};
2020-03-08 18:24:22 +01:00
static const struct SpriteTemplate sDexListStartMenuCursorSpriteTemplate =
2017-12-22 18:43:41 +01:00
{
.tileTag = TAG_DEX_INTERFACE,
.paletteTag = TAG_DEX_INTERFACE,
2020-03-08 18:24:22 +01:00
.oam = &sOamData_Dex8x16,
.anims = sSpriteAnimTable_DexListStartMenuCursor,
2017-12-22 18:43:41 +01:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2020-03-08 18:24:22 +01:00
.callback = SpriteCB_DexListStartMenuCursor,
2017-12-22 18:43:41 +01:00
};
2018-12-03 15:58:25 +01:00
static const struct CompressedSpriteSheet sInterfaceSpriteSheet[] =
2017-12-22 18:43:41 +01:00
{
{gPokedexInterface_Gfx, 0x2000, TAG_DEX_INTERFACE},
2017-12-22 18:43:41 +01:00
{0}
};
2018-12-03 15:58:25 +01:00
static const struct SpritePalette sInterfaceSpritePalette[] =
2017-12-22 18:43:41 +01:00
{
{gPokedexBgHoenn_Pal, TAG_DEX_INTERFACE},
2017-12-22 18:43:41 +01:00
{0}
};
2020-03-08 18:24:22 +01:00
// By scroll speed. Last element of each unused
static const u8 sScrollMonIncrements[] = {4, 8, 16, 32, 32};
static const u8 sScrollTimers[] = {8, 4, 2, 1, 1};
2017-12-22 18:43:41 +01:00
2019-11-20 00:54:00 +01:00
static const struct BgTemplate sPokedex_BgTemplate[] =
2017-12-22 18:43:41 +01:00
{
{
.bg = 0,
.charBaseIndex = 0,
.mapBaseIndex = 12,
.screenSize = 0,
.paletteMode = 0,
.priority = 0,
.baseTile = 0
},
{
.bg = 1,
.charBaseIndex = 0,
.mapBaseIndex = 13,
.screenSize = 0,
.paletteMode = 0,
.priority = 1,
.baseTile = 0
},
{
.bg = 2,
.charBaseIndex = 2,
.mapBaseIndex = 14,
.screenSize = 0,
.paletteMode = 0,
.priority = 2,
.baseTile = 0
},
{
.bg = 3,
.charBaseIndex = 0,
.mapBaseIndex = 15,
.screenSize = 0,
.paletteMode = 0,
.priority = 3,
.baseTile = 0
}
};
2018-12-03 15:58:25 +01:00
static const struct WindowTemplate sPokemonList_WindowTemplate[] =
2017-12-22 18:43:41 +01:00
{
2018-11-27 05:00:38 +01:00
{
.bg = 2,
.tilemapLeft = 0,
.tilemapTop = 0,
.width = 32,
.height = 32,
.paletteNum = 0,
.baseBlock = 1,
},
2017-12-22 18:43:41 +01:00
DUMMY_WIN_TEMPLATE
};
2018-12-03 15:58:25 +01:00
static const u8 sText_No000[] = _("{NO}000");
2020-03-08 18:24:22 +01:00
static const u8 sCaughtBall_Gfx[] = INCBIN_U8("graphics/pokedex/caught_ball.4bpp");
2018-11-27 05:00:38 +01:00
static const u8 sText_TenDashes[] = _("----------");
2018-11-27 12:37:29 +01:00
ALIGNED(4) static const u8 gExpandedPlaceholder_PokedexDescription[] = _("");
2018-11-27 05:00:38 +01:00
#include "data/pokemon/pokedex_text.h"
#include "data/pokemon/pokedex_entries.h"
2020-03-08 18:24:22 +01:00
static const u16 sSizeScreenSilhouette_Pal[] = INCBIN_U16("graphics/pokedex/size_silhouette.gbapal");
2018-11-27 05:00:38 +01:00
2019-11-20 00:54:00 +01:00
static const struct BgTemplate sInfoScreen_BgTemplate[] =
2018-11-27 05:00:38 +01:00
{
{
.bg = 0,
.charBaseIndex = 2,
.mapBaseIndex = 12,
.screenSize = 0,
.paletteMode = 0,
.priority = 3,
.baseTile = 0
},
{
.bg = 1,
.charBaseIndex = 0,
.mapBaseIndex = 13,
.screenSize = 0,
.paletteMode = 0,
.priority = 0,
.baseTile = 0
},
{
.bg = 2,
.charBaseIndex = 2,
.mapBaseIndex = 14,
.screenSize = 0,
.paletteMode = 0,
.priority = 1,
.baseTile = 0
},
{
.bg = 3,
.charBaseIndex = 0,
.mapBaseIndex = 15,
.screenSize = 0,
.paletteMode = 0,
.priority = 2,
.baseTile = 0
}
};
2019-11-20 00:54:00 +01:00
#define WIN_INFO 0
#define WIN_FOOTPRINT 1
#define WIN_CRY_WAVE 2
#define WIN_VU_METER 3
static const struct WindowTemplate sInfoScreen_WindowTemplates[] =
2018-11-27 05:00:38 +01:00
{
[WIN_INFO] =
2020-03-08 18:24:22 +01:00
{
2018-11-27 05:00:38 +01:00
.bg = 2,
.tilemapLeft = 0,
.tilemapTop = 0,
.width = 32,
.height = 20,
.paletteNum = 0,
2020-03-08 18:24:22 +01:00
.baseBlock = 1,
2018-11-27 05:00:38 +01:00
},
[WIN_FOOTPRINT] =
2020-03-08 18:24:22 +01:00
{
2018-11-27 05:00:38 +01:00
.bg = 2,
.tilemapLeft = 25,
.tilemapTop = 8,
.width = 2,
.height = 2,
.paletteNum = 15,
2020-03-08 18:24:22 +01:00
.baseBlock = 641,
2018-11-27 05:00:38 +01:00
},
[WIN_CRY_WAVE] =
2020-03-08 18:24:22 +01:00
{
2018-11-27 05:00:38 +01:00
.bg = 0,
.tilemapLeft = 0,
.tilemapTop = 12,
.width = 32,
.height = 7,
.paletteNum = 8,
2020-03-08 18:24:22 +01:00
.baseBlock = 645,
2018-11-27 05:00:38 +01:00
},
[WIN_VU_METER] =
2020-03-08 18:24:22 +01:00
{
2018-11-27 05:00:38 +01:00
.bg = 2,
.tilemapLeft = 18,
.tilemapTop = 3,
.width = 10,
.height = 8,
.paletteNum = 9,
2020-03-08 18:24:22 +01:00
.baseBlock = 869,
2018-11-27 05:00:38 +01:00
},
DUMMY_WIN_TEMPLATE
};
2019-11-20 00:54:00 +01:00
static const struct BgTemplate sNewEntryInfoScreen_BgTemplate[] =
2018-11-27 05:00:38 +01:00
{
{
.bg = 2,
.charBaseIndex = 2,
.mapBaseIndex = 14,
.screenSize = 0,
.paletteMode = 0,
.priority = 2,
.baseTile = 0
},
{
.bg = 3,
.charBaseIndex = 1,
.mapBaseIndex = 15,
.screenSize = 0,
.paletteMode = 0,
.priority = 3,
.baseTile = 0
},
};
2019-11-20 00:54:00 +01:00
static const struct WindowTemplate sNewEntryInfoScreen_WindowTemplates[] =
2018-11-27 05:00:38 +01:00
{
[WIN_INFO] =
2020-03-08 18:24:22 +01:00
{
2018-11-27 05:00:38 +01:00
.bg = 2,
.tilemapLeft = 0,
.tilemapTop = 0,
.width = 32,
.height = 20,
.paletteNum = 0,
2020-03-08 18:24:22 +01:00
.baseBlock = 1,
2018-11-27 05:00:38 +01:00
},
[WIN_FOOTPRINT] =
2020-03-08 18:24:22 +01:00
{
2018-11-27 05:00:38 +01:00
.bg = 2,
.tilemapLeft = 25,
.tilemapTop = 8,
.width = 2,
.height = 2,
.paletteNum = 15,
2020-03-08 18:24:22 +01:00
.baseBlock = 641,
2018-11-27 05:00:38 +01:00
},
DUMMY_WIN_TEMPLATE
};
static const u8 sText_TenDashes2[] = _("----------");
#include "data/pokemon_graphics/footprint_table.h"
2020-03-08 18:24:22 +01:00
// First character in range followed by number of characters in range for upper and lowercase
static const u8 sLetterSearchRanges[][4] =
{
{}, // Name not specified, shouldn't be reached
[NAME_ABC] = {CHAR_A, 3, CHAR_a, 3},
[NAME_DEF] = {CHAR_D, 3, CHAR_d, 3},
[NAME_GHI] = {CHAR_G, 3, CHAR_g, 3},
[NAME_JKL] = {CHAR_J, 3, CHAR_j, 3},
[NAME_MNO] = {CHAR_M, 3, CHAR_m, 3},
[NAME_PQR] = {CHAR_P, 3, CHAR_p, 3},
[NAME_STU] = {CHAR_S, 3, CHAR_s, 3},
[NAME_VWX] = {CHAR_V, 3, CHAR_v, 3},
[NAME_YZ] = {CHAR_Y, 2, CHAR_y, 2},
2018-11-27 05:00:38 +01:00
};
2020-03-08 18:24:22 +01:00
#define LETTER_IN_RANGE_UPPER(letter, range) \
((letter) >= sLetterSearchRanges[range][0] \
&& (letter) < sLetterSearchRanges[range][0] + sLetterSearchRanges[range][1]) \
#define LETTER_IN_RANGE_LOWER(letter, range) \
((letter) >= sLetterSearchRanges[range][2] \
&& (letter) < sLetterSearchRanges[range][2] + sLetterSearchRanges[range][3]) \
static const struct SearchMenuTopBarItem sSearchMenuTopBarItems[SEARCH_TOPBAR_COUNT] =
2018-11-27 05:00:38 +01:00
{
[SEARCH_TOPBAR_SEARCH] =
2018-11-27 05:00:38 +01:00
{
2020-03-08 18:24:22 +01:00
.description = gText_SearchForPkmnBasedOnParameters,
.highlightX = 0,
.highlightY = 0,
.highlightWidth = 5,
2018-11-27 05:00:38 +01:00
},
[SEARCH_TOPBAR_SHIFT] =
2018-11-27 05:00:38 +01:00
{
2020-03-08 18:24:22 +01:00
.description = gText_SwitchPokedexListings,
.highlightX = 6,
.highlightY = 0,
.highlightWidth = 5,
2018-11-27 05:00:38 +01:00
},
[SEARCH_TOPBAR_CANCEL] =
2018-11-27 05:00:38 +01:00
{
2020-03-08 18:24:22 +01:00
.description = gText_ReturnToPokedex,
.highlightX = 12,
.highlightY = 0,
.highlightWidth = 5,
2018-11-27 05:00:38 +01:00
},
};
2020-03-08 18:24:22 +01:00
static const struct SearchMenuItem sSearchMenuItems[SEARCH_COUNT] =
2018-11-27 05:00:38 +01:00
{
[SEARCH_NAME] =
2018-11-27 05:00:38 +01:00
{
2020-03-08 18:24:22 +01:00
.description = gText_ListByFirstLetter,
.titleBgX = 0,
.titleBgY = 2,
.titleBgWidth = 5,
.selectionBgX = 5,
.selectionBgY = 2,
.selectionBgWidth = 12,
2018-11-27 05:00:38 +01:00
},
[SEARCH_COLOR] =
2020-03-08 18:24:22 +01:00
{
.description = gText_ListByBodyColor,
.titleBgX = 0,
.titleBgY = 4,
.titleBgWidth = 5,
.selectionBgX = 5,
.selectionBgY = 4,
.selectionBgWidth = 12,
},
[SEARCH_TYPE_LEFT] =
2020-03-08 18:24:22 +01:00
{
.description = gText_ListByType,
.titleBgX = 0,
.titleBgY = 6,
.titleBgWidth = 5,
.selectionBgX = 5,
.selectionBgY = 6,
.selectionBgWidth = 6,
2018-11-27 05:00:38 +01:00
},
[SEARCH_TYPE_RIGHT] =
2020-03-08 18:24:22 +01:00
{
.description = gText_ListByType,
.titleBgX = 0,
.titleBgY = 6,
.titleBgWidth = 5,
.selectionBgX = 11,
.selectionBgY = 6,
.selectionBgWidth = 6,
},
[SEARCH_ORDER] =
2020-03-08 18:24:22 +01:00
{
.description = gText_SelectPokedexListingMode,
.titleBgX = 0,
.titleBgY = 8,
.titleBgWidth = 5,
.selectionBgX = 5,
.selectionBgY = 8,
.selectionBgWidth = 12,
},
[SEARCH_MODE] =
2020-03-08 18:24:22 +01:00
{
.description = gText_SelectPokedexMode,
.titleBgX = 0,
.titleBgY = 10,
.titleBgWidth = 5,
.selectionBgX = 5,
.selectionBgY = 10,
.selectionBgWidth = 12,
},
[SEARCH_OK] =
2020-03-08 18:24:22 +01:00
{
.description = gText_ExecuteSearchSwitch,
.titleBgX = 0,
.titleBgY = 12,
.titleBgWidth = 5,
.selectionBgX = 0,
.selectionBgY = 0,
.selectionBgWidth = 0,
},
};
// Left, Right, Up, Down
static const u8 sSearchMovementMap_SearchNatDex[SEARCH_COUNT][4] =
{
[SEARCH_NAME] =
2018-11-27 05:00:38 +01:00
{
0xFF,
0xFF,
0xFF,
2020-03-08 18:24:22 +01:00
SEARCH_COLOR
2018-11-27 05:00:38 +01:00
},
[SEARCH_COLOR] =
2018-11-27 05:00:38 +01:00
{
0xFF,
0xFF,
SEARCH_NAME,
2020-03-08 18:24:22 +01:00
SEARCH_TYPE_LEFT
},
[SEARCH_TYPE_LEFT] =
{
0xFF,
SEARCH_TYPE_RIGHT,
SEARCH_COLOR,
2020-03-08 18:24:22 +01:00
SEARCH_ORDER
2018-11-27 05:00:38 +01:00
},
[SEARCH_TYPE_RIGHT] =
{ SEARCH_TYPE_LEFT,
0xFF,
SEARCH_COLOR,
2020-03-08 18:24:22 +01:00
SEARCH_ORDER
},
[SEARCH_ORDER] =
2018-11-27 05:00:38 +01:00
{
0xFF,
0xFF,
SEARCH_TYPE_LEFT,
2020-03-08 18:24:22 +01:00
SEARCH_MODE
2018-11-27 05:00:38 +01:00
},
[SEARCH_MODE] =
2018-11-27 05:00:38 +01:00
{
0xFF,
0xFF,
SEARCH_ORDER,
2020-03-08 18:24:22 +01:00
SEARCH_OK
2018-11-27 05:00:38 +01:00
},
[SEARCH_OK] =
2018-11-27 05:00:38 +01:00
{
0xFF,
0xFF,
SEARCH_MODE,
2020-03-08 18:24:22 +01:00
0xFF
2018-11-27 05:00:38 +01:00
},
};
2020-03-08 18:24:22 +01:00
// Left, Right, Up, Down
static const u8 sSearchMovementMap_ShiftNatDex[SEARCH_COUNT][4] =
2018-11-27 05:00:38 +01:00
{
[SEARCH_NAME] =
2020-03-08 18:24:22 +01:00
{
0xFF,
0xFF,
0xFF,
2020-03-08 18:24:22 +01:00
0xFF
},
[SEARCH_COLOR] =
2020-03-08 18:24:22 +01:00
{
0xFF,
0xFF,
0xFF,
2020-03-08 18:24:22 +01:00
0xFF
},
[SEARCH_TYPE_LEFT] =
2020-03-08 18:24:22 +01:00
{
0xFF,
0xFF,
0xFF,
2020-03-08 18:24:22 +01:00
0xFF
},
[SEARCH_TYPE_RIGHT] =
2020-03-08 18:24:22 +01:00
{
0xFF,
0xFF,
0xFF,
2020-03-08 18:24:22 +01:00
0xFF
},
[SEARCH_ORDER] =
2020-03-08 18:24:22 +01:00
{
0xFF,
0xFF,
0xFF,
2020-03-08 18:24:22 +01:00
SEARCH_MODE
},
[SEARCH_MODE] =
2020-03-08 18:24:22 +01:00
{
0xFF,
0xFF,
SEARCH_ORDER,
2020-03-08 18:24:22 +01:00
SEARCH_OK
},
[SEARCH_OK] =
2020-03-08 18:24:22 +01:00
{
0xFF,
0xFF,
SEARCH_MODE,
2020-03-08 18:24:22 +01:00
0xFF
},
2018-11-27 05:00:38 +01:00
};
2020-03-08 18:24:22 +01:00
// Left, Right, Up, Down
static const u8 sSearchMovementMap_SearchHoennDex[SEARCH_COUNT][4] =
2018-11-27 05:00:38 +01:00
{
[SEARCH_NAME] =
2020-03-08 18:24:22 +01:00
{
0xFF,
0xFF,
0xFF,
2020-03-08 18:24:22 +01:00
SEARCH_COLOR
},
[SEARCH_COLOR] =
2020-03-08 18:24:22 +01:00
{
0xFF,
0xFF,
SEARCH_NAME,
2020-03-08 18:24:22 +01:00
SEARCH_TYPE_LEFT
},
[SEARCH_TYPE_LEFT] =
2020-03-08 18:24:22 +01:00
{
0xFF,
SEARCH_TYPE_RIGHT,
SEARCH_COLOR,
2020-03-08 18:24:22 +01:00
SEARCH_ORDER
},
[SEARCH_TYPE_RIGHT] =
{ SEARCH_TYPE_LEFT,
0xFF,
SEARCH_COLOR,
2020-03-08 18:24:22 +01:00
SEARCH_ORDER
},
[SEARCH_ORDER] =
{
0xFF,
0xFF,
SEARCH_TYPE_LEFT,
2020-03-08 18:24:22 +01:00
SEARCH_OK
},
[SEARCH_MODE] =
2020-03-08 18:24:22 +01:00
{
0xFF,
0xFF,
0xFF,
2020-03-08 18:24:22 +01:00
0xFF
},
[SEARCH_OK] =
2020-03-08 18:24:22 +01:00
{
0xFF,
0xFF,
SEARCH_ORDER,
2020-03-08 18:24:22 +01:00
0xFF
},
2018-11-27 05:00:38 +01:00
};
2020-03-08 18:24:22 +01:00
// Left, Right, Up, Down
static const u8 sSearchMovementMap_ShiftHoennDex[SEARCH_COUNT][4] =
2018-11-27 05:00:38 +01:00
{
[SEARCH_NAME] =
2020-03-08 18:24:22 +01:00
{
0xFF,
0xFF,
0xFF,
2020-03-08 18:24:22 +01:00
0xFF
},
[SEARCH_COLOR] =
{
0xFF,
0xFF,
0xFF,
2020-03-08 18:24:22 +01:00
0xFF
},
[SEARCH_TYPE_LEFT] =
2020-03-08 18:24:22 +01:00
{
0xFF,
0xFF,
0xFF,
2020-03-08 18:24:22 +01:00
0xFF
},
[SEARCH_TYPE_RIGHT] =
2020-03-08 18:24:22 +01:00
{
0xFF,
0xFF,
0xFF,
2020-03-08 18:24:22 +01:00
0xFF
},
[SEARCH_ORDER] =
2020-03-08 18:24:22 +01:00
{
0xFF,
0xFF,
0xFF,
2020-03-08 18:24:22 +01:00
SEARCH_OK
},
[SEARCH_MODE] =
2020-03-08 18:24:22 +01:00
{
0xFF,
0xFF,
0xFF,
2020-03-08 18:24:22 +01:00
0xFF
},
[SEARCH_OK] =
2020-03-08 18:24:22 +01:00
{
0xFF,
0xFF,
SEARCH_ORDER,
2020-03-08 18:24:22 +01:00
0xFF
},
2018-11-27 05:00:38 +01:00
};
2020-03-08 18:24:22 +01:00
static const struct SearchOptionText sDexModeOptions[] =
2018-11-27 05:00:38 +01:00
{
2020-03-08 18:24:22 +01:00
[DEX_MODE_HOENN] = {gText_DexHoennDescription, gText_DexHoennTitle},
[DEX_MODE_NATIONAL] = {gText_DexNatDescription, gText_DexNatTitle},
{},
2018-11-27 05:00:38 +01:00
};
2020-03-08 18:24:22 +01:00
static const struct SearchOptionText sDexOrderOptions[] =
2018-11-27 05:00:38 +01:00
{
2020-03-08 18:24:22 +01:00
[ORDER_NUMERICAL] = {gText_DexSortNumericalDescription, gText_DexSortNumericalTitle},
[ORDER_ALPHABETICAL] = {gText_DexSortAtoZDescription, gText_DexSortAtoZTitle},
[ORDER_HEAVIEST] = {gText_DexSortHeaviestDescription, gText_DexSortHeaviestTitle},
[ORDER_LIGHTEST] = {gText_DexSortLightestDescription, gText_DexSortLightestTitle},
[ORDER_TALLEST] = {gText_DexSortTallestDescription, gText_DexSortTallestTitle},
[ORDER_SMALLEST] = {gText_DexSortSmallestDescription, gText_DexSortSmallestTitle},
{},
2018-11-27 05:00:38 +01:00
};
2020-03-08 18:24:22 +01:00
static const struct SearchOptionText sDexSearchNameOptions[] =
2018-12-05 16:09:19 +01:00
{
{gText_DexEmptyString, gText_DexSearchDontSpecify},
2020-03-08 18:24:22 +01:00
[NAME_ABC] = {gText_DexEmptyString, gText_DexSearchAlphaABC},
[NAME_DEF] = {gText_DexEmptyString, gText_DexSearchAlphaDEF},
[NAME_GHI] = {gText_DexEmptyString, gText_DexSearchAlphaGHI},
[NAME_JKL] = {gText_DexEmptyString, gText_DexSearchAlphaJKL},
[NAME_MNO] = {gText_DexEmptyString, gText_DexSearchAlphaMNO},
[NAME_PQR] = {gText_DexEmptyString, gText_DexSearchAlphaPQR},
[NAME_STU] = {gText_DexEmptyString, gText_DexSearchAlphaSTU},
[NAME_VWX] = {gText_DexEmptyString, gText_DexSearchAlphaVWX},
[NAME_YZ] = {gText_DexEmptyString, gText_DexSearchAlphaYZ},
{},
2018-11-27 05:00:38 +01:00
};
2020-03-08 18:24:22 +01:00
static const struct SearchOptionText sDexSearchColorOptions[] =
2018-12-05 16:09:19 +01:00
{
{gText_DexEmptyString, gText_DexSearchDontSpecify},
2020-03-08 18:24:22 +01:00
[BODY_COLOR_RED + 1] = {gText_DexEmptyString, gText_DexSearchColorRed},
[BODY_COLOR_BLUE + 1] = {gText_DexEmptyString, gText_DexSearchColorBlue},
[BODY_COLOR_YELLOW + 1] = {gText_DexEmptyString, gText_DexSearchColorYellow},
[BODY_COLOR_GREEN + 1] = {gText_DexEmptyString, gText_DexSearchColorGreen},
[BODY_COLOR_BLACK + 1] = {gText_DexEmptyString, gText_DexSearchColorBlack},
[BODY_COLOR_BROWN + 1] = {gText_DexEmptyString, gText_DexSearchColorBrown},
[BODY_COLOR_PURPLE + 1] = {gText_DexEmptyString, gText_DexSearchColorPurple},
[BODY_COLOR_GRAY + 1] = {gText_DexEmptyString, gText_DexSearchColorGray},
[BODY_COLOR_WHITE + 1] = {gText_DexEmptyString, gText_DexSearchColorWhite},
[BODY_COLOR_PINK + 1] = {gText_DexEmptyString, gText_DexSearchColorPink},
{},
2018-11-27 05:00:38 +01:00
};
2020-03-08 18:24:22 +01:00
static const struct SearchOptionText sDexSearchTypeOptions[] =
2018-12-05 16:09:19 +01:00
{
{gText_DexEmptyString, gText_DexSearchTypeNone},
{gText_DexEmptyString, gTypeNames[TYPE_NORMAL]},
{gText_DexEmptyString, gTypeNames[TYPE_FIGHTING]},
{gText_DexEmptyString, gTypeNames[TYPE_FLYING]},
{gText_DexEmptyString, gTypeNames[TYPE_POISON]},
{gText_DexEmptyString, gTypeNames[TYPE_GROUND]},
{gText_DexEmptyString, gTypeNames[TYPE_ROCK]},
{gText_DexEmptyString, gTypeNames[TYPE_BUG]},
{gText_DexEmptyString, gTypeNames[TYPE_GHOST]},
{gText_DexEmptyString, gTypeNames[TYPE_STEEL]},
{gText_DexEmptyString, gTypeNames[TYPE_FIRE]},
{gText_DexEmptyString, gTypeNames[TYPE_WATER]},
{gText_DexEmptyString, gTypeNames[TYPE_GRASS]},
{gText_DexEmptyString, gTypeNames[TYPE_ELECTRIC]},
{gText_DexEmptyString, gTypeNames[TYPE_PSYCHIC]},
{gText_DexEmptyString, gTypeNames[TYPE_ICE]},
{gText_DexEmptyString, gTypeNames[TYPE_DRAGON]},
{gText_DexEmptyString, gTypeNames[TYPE_DARK]},
2020-03-08 18:24:22 +01:00
{},
2018-11-27 05:00:38 +01:00
};
2020-01-03 02:35:35 +01:00
static const u8 sPokedexModes[] = {DEX_MODE_HOENN, DEX_MODE_NATIONAL};
2020-03-08 18:24:22 +01:00
static const u8 sOrderOptions[] =
{
ORDER_NUMERICAL,
ORDER_ALPHABETICAL,
ORDER_HEAVIEST,
ORDER_LIGHTEST,
ORDER_TALLEST,
ORDER_SMALLEST,
2020-01-03 02:35:35 +01:00
};
2020-03-08 18:24:22 +01:00
static const u8 sDexSearchTypeIds[] =
2020-01-03 02:35:35 +01:00
{
2018-12-05 16:09:19 +01:00
TYPE_NONE,
TYPE_NORMAL,
TYPE_FIGHTING,
TYPE_FLYING,
TYPE_POISON,
TYPE_GROUND,
TYPE_ROCK,
TYPE_BUG,
TYPE_GHOST,
TYPE_STEEL,
TYPE_FIRE,
TYPE_WATER,
TYPE_GRASS,
TYPE_ELECTRIC,
TYPE_PSYCHIC,
TYPE_ICE,
TYPE_DRAGON,
TYPE_DARK,
};
2018-11-27 05:00:38 +01:00
2020-03-08 18:24:22 +01:00
// Number pairs are the task data for tracking the cursor pos and scroll offset of each option list
// See task data defines above Task_LoadSearchMenu
static const struct SearchOption sSearchOptions[] =
2018-11-27 05:00:38 +01:00
{
2020-03-08 18:24:22 +01:00
[SEARCH_NAME] = {sDexSearchNameOptions, 6, 7, ARRAY_COUNT(sDexSearchNameOptions) - 1},
[SEARCH_COLOR] = {sDexSearchColorOptions, 8, 9, ARRAY_COUNT(sDexSearchColorOptions) - 1},
[SEARCH_TYPE_LEFT] = {sDexSearchTypeOptions, 10, 11, ARRAY_COUNT(sDexSearchTypeOptions) - 1},
[SEARCH_TYPE_RIGHT] = {sDexSearchTypeOptions, 12, 13, ARRAY_COUNT(sDexSearchTypeOptions) - 1},
[SEARCH_ORDER] = {sDexOrderOptions, 4, 5, ARRAY_COUNT(sDexOrderOptions) - 1},
[SEARCH_MODE] = {sDexModeOptions, 2, 3, ARRAY_COUNT(sDexModeOptions) - 1},
2018-11-27 05:00:38 +01:00
};
2019-11-20 00:54:00 +01:00
static const struct BgTemplate sSearchMenu_BgTemplate[] =
2018-11-27 05:00:38 +01:00
{
{
.bg = 0,
.charBaseIndex = 2,
.mapBaseIndex = 12,
.screenSize = 0,
.paletteMode = 0,
.priority = 0,
.baseTile = 0
},
{
.bg = 1,
.charBaseIndex = 0,
.mapBaseIndex = 13,
.screenSize = 0,
.paletteMode = 0,
.priority = 1,
.baseTile = 0
},
{
.bg = 2,
.charBaseIndex = 2,
.mapBaseIndex = 14,
.screenSize = 0,
.paletteMode = 0,
.priority = 2,
.baseTile = 0
},
{
.bg = 3,
.charBaseIndex = 0,
.mapBaseIndex = 15,
.screenSize = 0,
.paletteMode = 0,
.priority = 3,
.baseTile = 0
}
};
2019-11-20 00:54:00 +01:00
static const struct WindowTemplate sSearchMenu_WindowTemplate[] =
2018-11-27 05:00:38 +01:00
{
{
.bg = 2,
.tilemapLeft = 0,
.tilemapTop = 0,
.width = 32,
.height = 20,
.paletteNum = 0,
.baseBlock = 0x0001,
},
DUMMY_WIN_TEMPLATE
};
2018-03-30 22:48:30 +02:00
2018-02-16 00:20:19 +01:00
// .text
void ResetPokedex(void)
{
u16 i;
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
sLastSelectedPokemon = 0;
sPokeBallRotation = POKEBALL_ROTATION_TOP;
2019-02-18 07:33:41 +01:00
gUnusedPokedexU8 = 0;
gSaveBlock2Ptr->pokedex.mode = DEX_MODE_HOENN;
2018-02-16 00:20:19 +01:00
gSaveBlock2Ptr->pokedex.order = 0;
gSaveBlock2Ptr->pokedex.nationalMagic = 0;
gSaveBlock2Ptr->pokedex.unknown2 = 0;
gSaveBlock2Ptr->pokedex.unownPersonality = 0;
gSaveBlock2Ptr->pokedex.spindaPersonality = 0;
gSaveBlock2Ptr->pokedex.unknown3 = 0;
DisableNationalPokedex();
for (i = 0; i < DEX_FLAGS_NO; i++)
{
gSaveBlock2Ptr->pokedex.owned[i] = 0;
gSaveBlock2Ptr->pokedex.seen[i] = 0;
gSaveBlock1Ptr->seen1[i] = 0;
gSaveBlock1Ptr->seen2[i] = 0;
}
}
void ResetPokedexScrollPositions(void)
2018-02-16 00:20:19 +01:00
{
2020-03-08 18:24:22 +01:00
sLastSelectedPokemon = 0;
sPokeBallRotation = POKEBALL_ROTATION_TOP;
2018-02-16 00:20:19 +01:00
}
2020-03-08 18:24:22 +01:00
static void VBlankCB_Pokedex(void)
2018-02-16 00:20:19 +01:00
{
LoadOam();
ProcessSpriteCopyRequests();
TransferPlttBuffer();
}
2018-12-03 15:58:25 +01:00
static void ResetPokedexView(struct PokedexView *pokedexView)
2018-02-16 00:20:19 +01:00
{
u16 i;
for (i = 0; i < NATIONAL_DEX_COUNT; i++)
{
2019-01-13 12:12:27 +01:00
pokedexView->pokedexList[i].dexNum = 0xFFFF;
2020-03-08 18:24:22 +01:00
pokedexView->pokedexList[i].seen = FALSE;
pokedexView->pokedexList[i].owned = FALSE;
2018-02-16 00:20:19 +01:00
}
2020-03-08 18:24:22 +01:00
pokedexView->pokedexList[NATIONAL_DEX_COUNT].dexNum = 0;
pokedexView->pokedexList[NATIONAL_DEX_COUNT].seen = FALSE;
pokedexView->pokedexList[NATIONAL_DEX_COUNT].owned = FALSE;
2018-02-16 00:20:19 +01:00
pokedexView->pokemonListCount = 0;
pokedexView->selectedPokemon = 0;
2020-03-08 18:24:22 +01:00
pokedexView->selectedPokemonBackup = 0;
pokedexView->dexMode = DEX_MODE_HOENN;
pokedexView->dexModeBackup = DEX_MODE_HOENN;
pokedexView->dexOrder = ORDER_NUMERICAL;
pokedexView->dexOrderBackup = ORDER_NUMERICAL;
2018-12-03 15:58:25 +01:00
pokedexView->seenCount = 0;
pokedexView->ownCount = 0;
2020-03-08 18:24:22 +01:00
for (i = 0; i < MAX_MONS_ON_SCREEN; i++)
2020-01-03 02:35:35 +01:00
pokedexView->monSpriteIds[i] = 0xFFFF;
2020-03-08 18:24:22 +01:00
pokedexView->pokeBallRotationStep = 0;
pokedexView->pokeBallRotationBackup = 0;
pokedexView->pokeBallRotation = 0;
2018-12-05 01:15:22 +01:00
pokedexView->initialVOffset = 0;
2020-03-08 18:24:22 +01:00
pokedexView->scrollTimer = 0;
pokedexView->scrollDirection = 0;
pokedexView->listVOffset = 0;
pokedexView->listMovingVOffset = 0;
pokedexView->scrollMonIncrement = 0;
pokedexView->maxScrollTimer = 0;
pokedexView->scrollSpeed = 0;
for (i = 0; i < ARRAY_COUNT(pokedexView->unkArr1); i++)
pokedexView->unkArr1[i] = 0;
pokedexView->currentPage = PAGE_MAIN;
pokedexView->currentPageBackup = PAGE_MAIN;
pokedexView->isSearchResults = FALSE;
pokedexView->selectedScreen = AREA_SCREEN;
pokedexView->screenSwitchState = 0;
2018-02-16 00:20:19 +01:00
pokedexView->menuIsOpen = 0;
pokedexView->menuCursorPos = 0;
pokedexView->menuY = 0;
2020-03-08 18:24:22 +01:00
for (i = 0; i < ARRAY_COUNT(pokedexView->unkArr2); i++)
pokedexView->unkArr2[i] = 0;
for (i = 0; i < ARRAY_COUNT(pokedexView->unkArr3); i++)
pokedexView->unkArr3[i] = 0;
2018-02-16 00:20:19 +01:00
}
2018-03-30 22:48:30 +02:00
2020-03-08 18:24:22 +01:00
void CB2_OpenPokedex(void)
2018-03-30 22:48:30 +02:00
{
u8 *addr;
u32 size;
2018-08-19 01:06:10 +02:00
2018-03-30 22:48:30 +02:00
switch (gMain.state)
{
2020-03-08 18:24:22 +01:00
case 0:
default:
SetVBlankCallback(NULL);
ResetOtherVideoRegisters(0);
DmaFillLarge16(3, 0, (u8 *)VRAM, VRAM_SIZE, 0x1000);
DmaClear32(3, OAM, OAM_SIZE);
DmaClear16(3, PLTT, PLTT_SIZE);
gMain.state = 1;
break;
case 1:
ScanlineEffect_Stop();
ResetTasks();
ResetSpriteData();
ResetPaletteFade();
FreeAllSpritePalettes();
gReservedSpritePaletteCount = 8;
ResetAllPicSprites();
gMain.state++;
break;
case 2:
sPokedexView = AllocZeroed(sizeof(struct PokedexView));
ResetPokedexView(sPokedexView);
CreateTask(Task_OpenPokedexMainPage, 0);
sPokedexView->dexMode = gSaveBlock2Ptr->pokedex.mode;
if (!IsNationalPokedexEnabled())
sPokedexView->dexMode = DEX_MODE_HOENN;
sPokedexView->dexOrder = gSaveBlock2Ptr->pokedex.order;
sPokedexView->selectedPokemon = sLastSelectedPokemon;
sPokedexView->pokeBallRotation = sPokeBallRotation;
sPokedexView->selectedScreen = AREA_SCREEN;
if (!IsNationalPokedexEnabled())
{
sPokedexView->seenCount = GetHoennPokedexCount(FLAG_GET_SEEN);
sPokedexView->ownCount = GetHoennPokedexCount(FLAG_GET_CAUGHT);
}
else
{
sPokedexView->seenCount = GetNationalPokedexCount(FLAG_GET_SEEN);
sPokedexView->ownCount = GetNationalPokedexCount(FLAG_GET_CAUGHT);
}
sPokedexView->initialVOffset = 8;
gMain.state++;
break;
case 3:
EnableInterrupts(1);
SetVBlankCallback(VBlankCB_Pokedex);
SetMainCallback2(CB2_Pokedex);
CreatePokedexList(sPokedexView->dexMode, sPokedexView->dexOrder);
m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x80);
break;
2018-03-30 22:48:30 +02:00
}
}
2020-03-08 18:24:22 +01:00
static void CB2_Pokedex(void)
2018-03-30 22:48:30 +02:00
{
RunTasks();
AnimateSprites();
BuildOamBuffer();
UpdatePaletteFade();
}
2020-03-08 18:24:22 +01:00
void Task_OpenPokedexMainPage(u8 taskId)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
sPokedexView->isSearchResults = FALSE;
if (LoadPokedexListPage(PAGE_MAIN))
gTasks[taskId].func = Task_HandlePokedexInput;
2018-03-30 22:48:30 +02:00
}
2020-03-08 18:24:22 +01:00
#define tTaskId data[0]
static void Task_HandlePokedexInput(u8 taskId)
2018-03-30 22:48:30 +02:00
{
2018-12-03 15:58:25 +01:00
SetGpuReg(REG_OFFSET_BG0VOFS, sPokedexView->menuY);
2018-08-19 01:06:10 +02:00
2018-12-03 15:58:25 +01:00
if (sPokedexView->menuY)
2018-03-30 22:48:30 +02:00
{
2018-12-03 15:58:25 +01:00
sPokedexView->menuY -= 8;
2018-03-30 22:48:30 +02:00
}
else
{
2018-12-03 15:58:25 +01:00
if ((gMain.newKeys & A_BUTTON) && sPokedexView->pokedexList[sPokedexView->selectedPokemon].seen)
2018-03-30 22:48:30 +02:00
{
2020-01-03 02:35:35 +01:00
UpdateSelectedMonSpriteId();
2018-12-03 15:58:25 +01:00
BeginNormalPaletteFade(~(1 << (gSprites[sPokedexView->selectedMonSpriteId].oam.paletteNum + 16)), 0, 0, 0x10, RGB_BLACK);
2020-03-08 18:24:22 +01:00
gSprites[sPokedexView->selectedMonSpriteId].callback = SpriteCB_MoveMonForInfoScreen;
gTasks[taskId].func = Task_OpenInfoScreenAfterMonMovement;
2018-03-30 22:48:30 +02:00
PlaySE(SE_PIN);
2020-01-03 02:35:35 +01:00
FreeWindowAndBgBuffers();
2018-03-30 22:48:30 +02:00
}
else if (gMain.newKeys & START_BUTTON)
{
2018-12-03 15:58:25 +01:00
sPokedexView->menuY = 0;
2020-03-08 18:24:22 +01:00
sPokedexView->menuIsOpen = TRUE;
2018-12-03 15:58:25 +01:00
sPokedexView->menuCursorPos = 0;
2020-03-08 18:24:22 +01:00
gTasks[taskId].func = Task_HandlePokedexStartMenuInput;
2018-03-30 22:48:30 +02:00
PlaySE(SE_SELECT);
}
else if (gMain.newKeys & SELECT_BUTTON)
{
PlaySE(SE_SELECT);
2018-05-31 13:08:24 +02:00
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK);
2020-03-08 18:24:22 +01:00
gTasks[taskId].tTaskId = LoadSearchMenu();
sPokedexView->screenSwitchState = 0;
sPokedexView->pokeBallRotationBackup = sPokedexView->pokeBallRotation;
sPokedexView->selectedPokemonBackup = sPokedexView->selectedPokemon;
sPokedexView->dexModeBackup = sPokedexView->dexMode;
sPokedexView->dexOrderBackup = sPokedexView->dexOrder;
gTasks[taskId].func = Task_WaitForExitSearch;
2018-03-30 22:48:30 +02:00
PlaySE(SE_PC_LOGIN);
2020-01-03 02:35:35 +01:00
FreeWindowAndBgBuffers();
2018-03-30 22:48:30 +02:00
}
else if (gMain.newKeys & B_BUTTON)
{
2018-05-31 13:08:24 +02:00
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK);
2020-03-08 18:24:22 +01:00
gTasks[taskId].func = Task_ClosePokedex;
2018-03-30 22:48:30 +02:00
PlaySE(SE_PC_OFF);
}
else
{
//Handle D-pad
2020-03-08 18:24:22 +01:00
sPokedexView->selectedPokemon = TryDoPokedexScroll(sPokedexView->selectedPokemon, 0xE);
if (sPokedexView->scrollTimer)
gTasks[taskId].func = Task_WaitForScroll;
2018-03-30 22:48:30 +02:00
}
}
}
2020-03-08 18:24:22 +01:00
static void Task_WaitForScroll(u8 taskId)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
if (UpdateDexListScroll(sPokedexView->scrollDirection, sPokedexView->scrollMonIncrement, sPokedexView->maxScrollTimer))
gTasks[taskId].func = Task_HandlePokedexInput;
2018-03-30 22:48:30 +02:00
}
2020-03-08 18:24:22 +01:00
static void Task_HandlePokedexStartMenuInput(u8 taskId)
2018-03-30 22:48:30 +02:00
{
2018-12-03 15:58:25 +01:00
SetGpuReg(REG_OFFSET_BG0VOFS, sPokedexView->menuY);
2018-03-30 22:48:30 +02:00
//If menu is not open, slide it up, on screen
2018-12-03 15:58:25 +01:00
if (sPokedexView->menuY != 80)
2018-05-31 13:08:24 +02:00
{
2018-12-03 15:58:25 +01:00
sPokedexView->menuY += 8;
2018-05-31 13:08:24 +02:00
}
2018-03-30 22:48:30 +02:00
else
{
if (gMain.newKeys & A_BUTTON)
{
2018-12-03 15:58:25 +01:00
switch (sPokedexView->menuCursorPos)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
case 0: //BACK TO LIST
default:
gMain.newKeys |= START_BUTTON; //Exit menu
break;
case 1: //LIST TOP
sPokedexView->selectedPokemon = 0;
sPokedexView->pokeBallRotation = POKEBALL_ROTATION_TOP;
ClearMonSprites();
CreateMonSpritesAtPos(sPokedexView->selectedPokemon, 0xE);
gMain.newKeys |= START_BUTTON; //Exit menu
break;
case 2: //LIST BOTTOM
sPokedexView->selectedPokemon = sPokedexView->pokemonListCount - 1;
sPokedexView->pokeBallRotation = sPokedexView->pokemonListCount * 16 + POKEBALL_ROTATION_BOTTOM;
ClearMonSprites();
CreateMonSpritesAtPos(sPokedexView->selectedPokemon, 0xE);
gMain.newKeys |= START_BUTTON; //Exit menu
break;
case 3: //CLOSE POKEDEX
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK);
gTasks[taskId].func = Task_ClosePokedex;
PlaySE(SE_PC_OFF);
break;
2018-03-30 22:48:30 +02:00
}
}
//Exit menu when Start or B is pressed
if (gMain.newKeys & (START_BUTTON | B_BUTTON))
{
2020-03-08 18:24:22 +01:00
sPokedexView->menuIsOpen = FALSE;
gTasks[taskId].func = Task_HandlePokedexInput;
2018-03-30 22:48:30 +02:00
PlaySE(SE_SELECT);
}
2018-12-03 15:58:25 +01:00
else if ((gMain.newAndRepeatedKeys & DPAD_UP) && sPokedexView->menuCursorPos != 0)
2018-03-30 22:48:30 +02:00
{
2018-12-03 15:58:25 +01:00
sPokedexView->menuCursorPos--;
2018-03-30 22:48:30 +02:00
PlaySE(SE_SELECT);
}
2020-03-08 18:24:22 +01:00
else if ((gMain.newAndRepeatedKeys & DPAD_DOWN) && sPokedexView->menuCursorPos < 3)
2018-03-30 22:48:30 +02:00
{
2018-12-03 15:58:25 +01:00
sPokedexView->menuCursorPos++;
2018-03-30 22:48:30 +02:00
PlaySE(SE_SELECT);
}
}
}
2020-03-08 18:24:22 +01:00
static void Task_OpenInfoScreenAfterMonMovement(u8 taskId)
2018-03-30 22:48:30 +02:00
{
2018-12-03 15:58:25 +01:00
if (gSprites[sPokedexView->selectedMonSpriteId].pos1.x == 48 && gSprites[sPokedexView->selectedMonSpriteId].pos1.y == 56)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
sPokedexView->currentPageBackup = sPokedexView->currentPage;
gTasks[taskId].tTaskId = LoadInfoScreen(&sPokedexView->pokedexList[sPokedexView->selectedPokemon], sPokedexView->selectedMonSpriteId);
gTasks[taskId].func = Task_WaitForExitInfoScreen;
2018-03-30 22:48:30 +02:00
}
}
2020-03-08 18:24:22 +01:00
static void Task_WaitForExitInfoScreen(u8 taskId)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
if (gTasks[gTasks[taskId].tTaskId].isActive)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
if (sPokedexView->currentPage == PAGE_INFO && !IsInfoScreenScrolling(gTasks[taskId].tTaskId) && TryDoInfoScreenScroll())
sub_80BE9F8(&sPokedexView->pokedexList[sPokedexView->selectedPokemon], gTasks[taskId].tTaskId);
2018-03-30 22:48:30 +02:00
}
else
{
2020-03-08 18:24:22 +01:00
sLastSelectedPokemon = sPokedexView->selectedPokemon;
sPokeBallRotation = sPokedexView->pokeBallRotation;
gTasks[taskId].func = Task_OpenPokedexMainPage;
2018-03-30 22:48:30 +02:00
}
}
2020-03-08 18:24:22 +01:00
static void Task_WaitForExitSearch(u8 taskId)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
if (!gTasks[gTasks[taskId].tTaskId].isActive)
2018-03-30 22:48:30 +02:00
{
2020-01-03 02:35:35 +01:00
ClearMonSprites();
2020-03-08 18:24:22 +01:00
// Search produced results
if (sPokedexView->screenSwitchState != 0)
2018-03-30 22:48:30 +02:00
{
2018-12-03 15:58:25 +01:00
sPokedexView->selectedPokemon = 0;
2020-03-08 18:24:22 +01:00
sPokedexView->pokeBallRotation = POKEBALL_ROTATION_TOP;
gTasks[taskId].func = Task_OpenSearchResults;
2018-03-30 22:48:30 +02:00
}
2020-03-08 18:24:22 +01:00
// Search didn't produce results
2018-03-30 22:48:30 +02:00
else
{
2020-03-08 18:24:22 +01:00
sPokedexView->pokeBallRotation = sPokedexView->pokeBallRotationBackup;
sPokedexView->selectedPokemon = sPokedexView->selectedPokemonBackup;
sPokedexView->dexMode = sPokedexView->dexModeBackup;
2018-03-30 22:48:30 +02:00
if (!IsNationalPokedexEnabled())
2018-12-03 15:58:25 +01:00
sPokedexView->dexMode = DEX_MODE_HOENN;
2020-03-08 18:24:22 +01:00
sPokedexView->dexOrder = sPokedexView->dexOrderBackup;
gTasks[taskId].func = Task_OpenPokedexMainPage;
2018-03-30 22:48:30 +02:00
}
}
}
2020-03-08 18:24:22 +01:00
static void Task_ClosePokedex(u8 taskId)
2018-03-30 22:48:30 +02:00
{
if (!gPaletteFade.active)
{
gSaveBlock2Ptr->pokedex.mode = sPokedexView->dexMode;
2018-03-30 22:48:30 +02:00
if (!IsNationalPokedexEnabled())
gSaveBlock2Ptr->pokedex.mode = DEX_MODE_HOENN;
2018-12-03 15:58:25 +01:00
gSaveBlock2Ptr->pokedex.order = sPokedexView->dexOrder;
2020-01-03 02:35:35 +01:00
ClearMonSprites();
FreeWindowAndBgBuffers();
2018-03-30 22:48:30 +02:00
DestroyTask(taskId);
SetMainCallback2(CB2_ReturnToFieldWithOpenMenu);
m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x100);
2018-12-03 15:58:25 +01:00
Free(sPokedexView);
2018-03-30 22:48:30 +02:00
}
}
2020-03-08 18:24:22 +01:00
static void Task_OpenSearchResults(u8 taskId)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
sPokedexView->isSearchResults = TRUE;
if (LoadPokedexListPage(PAGE_SEARCH_RESULTS))
gTasks[taskId].func = Task_HandleSearchResultsInput;
2018-03-30 22:48:30 +02:00
}
2020-03-08 18:24:22 +01:00
static void Task_HandleSearchResultsInput(u8 taskId)
2018-03-30 22:48:30 +02:00
{
2018-12-03 15:58:25 +01:00
SetGpuReg(REG_OFFSET_BG0VOFS, sPokedexView->menuY);
2018-03-30 22:48:30 +02:00
2018-12-03 15:58:25 +01:00
if (sPokedexView->menuY)
2018-03-30 22:48:30 +02:00
{
2018-12-03 15:58:25 +01:00
sPokedexView->menuY -= 8;
2018-03-30 22:48:30 +02:00
}
else
{
2018-12-03 15:58:25 +01:00
if ((gMain.newKeys & A_BUTTON) && sPokedexView->pokedexList[sPokedexView->selectedPokemon].seen)
2018-03-30 22:48:30 +02:00
{
u32 a;
2020-01-03 02:35:35 +01:00
UpdateSelectedMonSpriteId();
2018-12-03 15:58:25 +01:00
a = (1 << (gSprites[sPokedexView->selectedMonSpriteId].oam.paletteNum + 16));
2020-03-08 18:24:22 +01:00
gSprites[sPokedexView->selectedMonSpriteId].callback = SpriteCB_MoveMonForInfoScreen;
2018-03-30 22:48:30 +02:00
BeginNormalPaletteFade(~a, 0, 0, 0x10, RGB_BLACK);
2020-03-08 18:24:22 +01:00
gTasks[taskId].func = Task_OpenSearchResultsInfoScreenAfterMonMovement;
2018-03-30 22:48:30 +02:00
PlaySE(SE_PIN);
2020-01-03 02:35:35 +01:00
FreeWindowAndBgBuffers();
2018-03-30 22:48:30 +02:00
}
else if (gMain.newKeys & START_BUTTON)
{
2018-12-03 15:58:25 +01:00
sPokedexView->menuY = 0;
2020-03-08 18:24:22 +01:00
sPokedexView->menuIsOpen = TRUE;
2018-12-03 15:58:25 +01:00
sPokedexView->menuCursorPos = 0;
2020-03-08 18:24:22 +01:00
gTasks[taskId].func = Task_HandleSearchResultsStartMenuInput;
2018-03-30 22:48:30 +02:00
PlaySE(SE_SELECT);
}
else if (gMain.newKeys & SELECT_BUTTON)
{
2018-05-31 13:08:24 +02:00
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK);
2020-03-08 18:24:22 +01:00
gTasks[taskId].tTaskId = LoadSearchMenu();
sPokedexView->screenSwitchState = 0;
gTasks[taskId].func = Task_WaitForExitSearch;
2018-03-30 22:48:30 +02:00
PlaySE(SE_PC_LOGIN);
2020-01-03 02:35:35 +01:00
FreeWindowAndBgBuffers();
2018-03-30 22:48:30 +02:00
}
else if (gMain.newKeys & B_BUTTON)
{
2018-05-31 13:08:24 +02:00
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK);
2020-03-08 18:24:22 +01:00
gTasks[taskId].func = Task_ReturnToPokedexFromSearchResults;
2018-03-30 22:48:30 +02:00
PlaySE(SE_PC_OFF);
}
else
{
//Handle D-pad
2020-03-08 18:24:22 +01:00
sPokedexView->selectedPokemon = TryDoPokedexScroll(sPokedexView->selectedPokemon, 0xE);
if (sPokedexView->scrollTimer)
gTasks[taskId].func = Task_WaitForSearchResultsScroll;
2018-03-30 22:48:30 +02:00
}
}
}
2020-03-08 18:24:22 +01:00
static void Task_WaitForSearchResultsScroll(u8 taskId)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
if (UpdateDexListScroll(sPokedexView->scrollDirection, sPokedexView->scrollMonIncrement, sPokedexView->maxScrollTimer))
gTasks[taskId].func = Task_HandleSearchResultsInput;
2018-03-30 22:48:30 +02:00
}
2020-03-08 18:24:22 +01:00
static void Task_HandleSearchResultsStartMenuInput(u8 taskId)
2018-03-30 22:48:30 +02:00
{
2018-12-03 15:58:25 +01:00
SetGpuReg(REG_OFFSET_BG0VOFS, sPokedexView->menuY);
2018-03-30 22:48:30 +02:00
2018-12-03 15:58:25 +01:00
if (sPokedexView->menuY != 96)
2018-03-30 22:48:30 +02:00
{
2018-12-03 15:58:25 +01:00
sPokedexView->menuY += 8;
2018-03-30 22:48:30 +02:00
}
else
{
if (gMain.newKeys & A_BUTTON)
{
2018-12-03 15:58:25 +01:00
switch (sPokedexView->menuCursorPos)
2018-03-30 22:48:30 +02:00
{
case 0: //BACK TO LIST
2020-03-08 18:24:22 +01:00
default:
gMain.newKeys |= START_BUTTON;
break;
case 1: //LIST TOP
sPokedexView->selectedPokemon = 0;
sPokedexView->pokeBallRotation = POKEBALL_ROTATION_TOP;
ClearMonSprites();
CreateMonSpritesAtPos(sPokedexView->selectedPokemon, 0xE);
gMain.newKeys |= START_BUTTON;
break;
case 2: //LIST BOTTOM
sPokedexView->selectedPokemon = sPokedexView->pokemonListCount - 1;
sPokedexView->pokeBallRotation = sPokedexView->pokemonListCount * 16 + POKEBALL_ROTATION_BOTTOM;
ClearMonSprites();
CreateMonSpritesAtPos(sPokedexView->selectedPokemon, 0xE);
gMain.newKeys |= START_BUTTON;
break;
case 3: //BACK TO POKEDEX
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK);
gTasks[taskId].func = Task_ReturnToPokedexFromSearchResults;
PlaySE(SE_TRACK_DOOR);
break;
case 4: //CLOSE POKEDEX
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK);
gTasks[taskId].func = Task_ClosePokedexFromSearchResultsStartMenu;
PlaySE(SE_PC_OFF);
break;
2018-03-30 22:48:30 +02:00
}
}
//Exit menu when Start or B is pressed
if (gMain.newKeys & (START_BUTTON | B_BUTTON))
{
2020-03-08 18:24:22 +01:00
sPokedexView->menuIsOpen = FALSE;
gTasks[taskId].func = Task_HandleSearchResultsInput;
2018-03-30 22:48:30 +02:00
PlaySE(SE_SELECT);
}
2018-12-03 15:58:25 +01:00
else if ((gMain.newAndRepeatedKeys & DPAD_UP) && sPokedexView->menuCursorPos)
2018-03-30 22:48:30 +02:00
{
2018-12-03 15:58:25 +01:00
sPokedexView->menuCursorPos--;
2018-03-30 22:48:30 +02:00
PlaySE(SE_SELECT);
}
2020-03-08 18:24:22 +01:00
else if ((gMain.newAndRepeatedKeys & DPAD_DOWN) && sPokedexView->menuCursorPos < 4)
2018-03-30 22:48:30 +02:00
{
2018-12-03 15:58:25 +01:00
sPokedexView->menuCursorPos++;
2018-03-30 22:48:30 +02:00
PlaySE(SE_SELECT);
}
}
}
2020-03-08 18:24:22 +01:00
static void Task_OpenSearchResultsInfoScreenAfterMonMovement(u8 taskId)
2018-03-30 22:48:30 +02:00
{
2018-12-03 15:58:25 +01:00
if (gSprites[sPokedexView->selectedMonSpriteId].pos1.x == 48 && gSprites[sPokedexView->selectedMonSpriteId].pos1.y == 56)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
sPokedexView->currentPageBackup = sPokedexView->currentPage;
gTasks[taskId].tTaskId = LoadInfoScreen(&sPokedexView->pokedexList[sPokedexView->selectedPokemon], sPokedexView->selectedMonSpriteId);
2018-12-03 15:58:25 +01:00
sPokedexView->selectedMonSpriteId = -1;
2020-03-08 18:24:22 +01:00
gTasks[taskId].func = Task_WaitForExitSearchResultsInfoScreen;
2018-03-30 22:48:30 +02:00
}
}
2020-03-08 18:24:22 +01:00
static void Task_WaitForExitSearchResultsInfoScreen(u8 taskId)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
if (gTasks[gTasks[taskId].tTaskId].isActive)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
if (sPokedexView->currentPage == PAGE_INFO && !IsInfoScreenScrolling(gTasks[taskId].tTaskId) && TryDoInfoScreenScroll())
sub_80BE9F8(&sPokedexView->pokedexList[sPokedexView->selectedPokemon], gTasks[taskId].tTaskId);
2018-03-30 22:48:30 +02:00
}
else
{
2020-03-08 18:24:22 +01:00
gTasks[taskId].func = Task_OpenSearchResults;
2018-03-30 22:48:30 +02:00
}
}
2020-03-08 18:24:22 +01:00
static void Task_ReturnToPokedexFromSearchResults(u8 taskId)
2018-03-30 22:48:30 +02:00
{
if (!gPaletteFade.active)
{
2020-03-08 18:24:22 +01:00
sPokedexView->pokeBallRotation = sPokedexView->pokeBallRotationBackup;
sPokedexView->selectedPokemon = sPokedexView->selectedPokemonBackup;
sPokedexView->dexMode = sPokedexView->dexModeBackup;
2018-03-30 22:48:30 +02:00
if (!IsNationalPokedexEnabled())
2018-12-03 15:58:25 +01:00
sPokedexView->dexMode = DEX_MODE_HOENN;
2020-03-08 18:24:22 +01:00
sPokedexView->dexOrder = sPokedexView->dexOrderBackup;
gTasks[taskId].func = Task_OpenPokedexMainPage;
2020-01-03 02:35:35 +01:00
ClearMonSprites();
FreeWindowAndBgBuffers();
2018-03-30 22:48:30 +02:00
}
}
2020-03-08 18:24:22 +01:00
static void Task_ClosePokedexFromSearchResultsStartMenu(u8 taskId)
2018-03-30 22:48:30 +02:00
{
if (!gPaletteFade.active)
{
2020-03-08 18:24:22 +01:00
sPokedexView->pokeBallRotation = sPokedexView->pokeBallRotationBackup;
sPokedexView->selectedPokemon = sPokedexView->selectedPokemonBackup;
sPokedexView->dexMode = sPokedexView->dexModeBackup;
2018-03-30 22:48:30 +02:00
if (!IsNationalPokedexEnabled())
2018-12-03 15:58:25 +01:00
sPokedexView->dexMode = DEX_MODE_HOENN;
2020-03-08 18:24:22 +01:00
sPokedexView->dexOrder = sPokedexView->dexOrderBackup;
gTasks[taskId].func = Task_ClosePokedex;
2018-03-30 22:48:30 +02:00
}
}
2020-03-08 18:24:22 +01:00
#undef tTaskId
// For loading main pokedex page or pokedex search results
static bool8 LoadPokedexListPage(u8 page)
2018-03-30 22:48:30 +02:00
{
switch (gMain.state)
{
2020-03-08 18:24:22 +01:00
case 0:
default:
if (gPaletteFade.active)
return 0;
SetVBlankCallback(NULL);
sPokedexView->currentPage = page;
ResetOtherVideoRegisters(0);
SetGpuReg(REG_OFFSET_BG2VOFS, sPokedexView->initialVOffset);
ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, sPokedex_BgTemplate, ARRAY_COUNT(sPokedex_BgTemplate));
SetBgTilemapBuffer(3, AllocZeroed(0x800));
SetBgTilemapBuffer(2, AllocZeroed(0x800));
SetBgTilemapBuffer(1, AllocZeroed(0x800));
SetBgTilemapBuffer(0, AllocZeroed(0x800));
DecompressAndLoadBgGfxUsingHeap(3, gPokedexMenu_Gfx, 0x2000, 0, 0);
CopyToBgTilemapBuffer(1, gPokedexList_Tilemap, 0, 0);
CopyToBgTilemapBuffer(3, gPokedexListUnderlay_Tilemap, 0, 0);
if (page == PAGE_MAIN)
CopyToBgTilemapBuffer(0, gPokedexStartMenuMain_Tilemap, 0, 0x280);
else
CopyToBgTilemapBuffer(0, gPokedexStartMenuSearchResults_Tilemap, 0, 0x280);
ResetPaletteFade();
if (page == PAGE_MAIN)
sPokedexView->isSearchResults = FALSE;
else
sPokedexView->isSearchResults = TRUE;
LoadPokedexBgPalette(sPokedexView->isSearchResults);
InitWindows(sPokemonList_WindowTemplate);
DeactivateAllTextPrinters();
PutWindowTilemap(0);
CopyWindowToVram(0, 3);
gMain.state = 1;
break;
case 1:
ResetSpriteData();
FreeAllSpritePalettes();
gReservedSpritePaletteCount = 8;
LoadCompressedSpriteSheet(&sInterfaceSpriteSheet[0]);
LoadSpritePalettes(sInterfaceSpritePalette);
CreateInterfaceSprites(page);
gMain.state++;
break;
case 2:
gMain.state++;
break;
case 3:
if (page == PAGE_MAIN)
CreatePokedexList(sPokedexView->dexMode, sPokedexView->dexOrder);
CreateMonSpritesAtPos(sPokedexView->selectedPokemon, 0xE);
sPokedexView->menuIsOpen = FALSE;
sPokedexView->menuY = 0;
CopyBgTilemapBufferToVram(0);
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(3);
gMain.state++;
break;
case 4:
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, RGB_BLACK);
SetVBlankCallback(VBlankCB_Pokedex);
gMain.state++;
break;
case 5:
SetGpuReg(REG_OFFSET_WININ, 0x3F3F);
SetGpuReg(REG_OFFSET_WINOUT, 0x1D3F);
SetGpuReg(REG_OFFSET_WIN0H, 0);
SetGpuReg(REG_OFFSET_WIN0V, 0);
SetGpuReg(REG_OFFSET_WIN1H, 0);
SetGpuReg(REG_OFFSET_WIN1V, 0);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
SetGpuReg(REG_OFFSET_BLDY, 0);
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON | DISPCNT_OBJWIN_ON);
ShowBg(0);
ShowBg(1);
ShowBg(2);
ShowBg(3);
gMain.state++;
break;
case 6:
if (!gPaletteFade.active)
{
gMain.state = 0;
return TRUE;
}
break;
2018-03-30 22:48:30 +02:00
}
return FALSE;
}
2020-03-08 18:24:22 +01:00
static void LoadPokedexBgPalette(bool8 isSearchResults)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
if (isSearchResults == TRUE)
LoadPalette(gPokedexSearchResults_Pal + 1, 1, 0xBE);
2018-03-30 22:48:30 +02:00
else if (!IsNationalPokedexEnabled())
2020-03-08 18:24:22 +01:00
LoadPalette(gPokedexBgHoenn_Pal + 1, 1, 0xBE);
2018-03-30 22:48:30 +02:00
else
2020-03-08 18:24:22 +01:00
LoadPalette(gPokedexBgNational_Pal + 1, 1, 0xBE);
2018-03-30 22:48:30 +02:00
LoadPalette(GetOverworldTextboxPalettePtr(), 0xF0, 32);
}
2020-01-03 02:35:35 +01:00
static void FreeWindowAndBgBuffers(void)
2018-03-30 22:48:30 +02:00
{
void* tilemapBuffer;
2018-08-19 01:06:10 +02:00
2018-03-30 22:48:30 +02:00
FreeAllWindowBuffers();
tilemapBuffer = GetBgTilemapBuffer(0);
if (tilemapBuffer)
Free(tilemapBuffer);
tilemapBuffer = GetBgTilemapBuffer(1);
if (tilemapBuffer)
Free(tilemapBuffer);
tilemapBuffer = GetBgTilemapBuffer(2);
if (tilemapBuffer)
Free(tilemapBuffer);
tilemapBuffer = GetBgTilemapBuffer(3);
if (tilemapBuffer)
Free(tilemapBuffer);
}
2020-03-08 18:24:22 +01:00
static void CreatePokedexList(u8 dexMode, u8 order)
2018-03-30 22:48:30 +02:00
{
u16 vars[3]; //I have no idea why three regular variables are stored in an array, but whatever.
#define temp_dexCount vars[0]
#define temp_isHoennDex vars[1]
#define temp_dexNum vars[2]
2018-03-30 22:48:30 +02:00
s16 i;
2018-08-19 01:06:10 +02:00
2018-12-03 15:58:25 +01:00
sPokedexView->pokemonListCount = 0;
2018-03-30 22:48:30 +02:00
switch (dexMode)
{
2020-03-08 18:24:22 +01:00
default:
case DEX_MODE_HOENN:
temp_dexCount = HOENN_DEX_COUNT;
temp_isHoennDex = TRUE;
break;
case DEX_MODE_NATIONAL:
if (IsNationalPokedexEnabled())
{
temp_dexCount = NATIONAL_DEX_COUNT;
temp_isHoennDex = FALSE;
}
else
{
temp_dexCount = HOENN_DEX_COUNT;
temp_isHoennDex = TRUE;
2020-03-08 18:24:22 +01:00
}
break;
2018-03-30 22:48:30 +02:00
}
2020-03-08 18:24:22 +01:00
switch (order)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
case ORDER_NUMERICAL:
if (temp_isHoennDex)
{
for (i = 0; i < temp_dexCount; i++)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
temp_dexNum = HoennToNationalOrder(i + 1);
sPokedexView->pokedexList[i].dexNum = temp_dexNum;
sPokedexView->pokedexList[i].seen = GetSetPokedexFlag(temp_dexNum, FLAG_GET_SEEN);
sPokedexView->pokedexList[i].owned = GetSetPokedexFlag(temp_dexNum, FLAG_GET_CAUGHT);
if (sPokedexView->pokedexList[i].seen)
sPokedexView->pokemonListCount = i + 1;
2018-03-30 22:48:30 +02:00
}
2020-03-08 18:24:22 +01:00
}
else
{
s16 r5, r10;
for (i = 0, r5 = 0, r10 = 0; i < temp_dexCount; i++)
2020-03-08 18:24:22 +01:00
{
temp_dexNum = i + 1;
if (GetSetPokedexFlag(temp_dexNum, FLAG_GET_SEEN))
r10 = 1;
if (r10)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
sPokedexView->pokedexList[r5].dexNum = temp_dexNum;
sPokedexView->pokedexList[r5].seen = GetSetPokedexFlag(temp_dexNum, FLAG_GET_SEEN);
sPokedexView->pokedexList[r5].owned = GetSetPokedexFlag(temp_dexNum, FLAG_GET_CAUGHT);
if (sPokedexView->pokedexList[r5].seen)
sPokedexView->pokemonListCount = r5 + 1;
r5++;
2018-03-30 22:48:30 +02:00
}
}
2020-03-08 18:24:22 +01:00
}
break;
case ORDER_ALPHABETICAL:
for (i = 0; i < NUM_SPECIES - 1; i++)
{
temp_dexNum = gPokedexOrder_Alphabetical[i];
2018-03-30 22:48:30 +02:00
2020-03-08 18:24:22 +01:00
if (NationalToHoennOrder(temp_dexNum) <= temp_dexCount && GetSetPokedexFlag(temp_dexNum, FLAG_GET_SEEN))
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
sPokedexView->pokedexList[sPokedexView->pokemonListCount].dexNum = temp_dexNum;
sPokedexView->pokedexList[sPokedexView->pokemonListCount].seen = TRUE;
sPokedexView->pokedexList[sPokedexView->pokemonListCount].owned = GetSetPokedexFlag(temp_dexNum, FLAG_GET_CAUGHT);
sPokedexView->pokemonListCount++;
2018-03-30 22:48:30 +02:00
}
2020-03-08 18:24:22 +01:00
}
break;
case ORDER_HEAVIEST:
for (i = NATIONAL_DEX_COUNT - 1; i >= 0; i--)
{
temp_dexNum = gPokedexOrder_Weight[i];
if (NationalToHoennOrder(temp_dexNum) <= temp_dexCount && GetSetPokedexFlag(temp_dexNum, FLAG_GET_CAUGHT))
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
sPokedexView->pokedexList[sPokedexView->pokemonListCount].dexNum = temp_dexNum;
sPokedexView->pokedexList[sPokedexView->pokemonListCount].seen = TRUE;
sPokedexView->pokedexList[sPokedexView->pokemonListCount].owned = TRUE;
sPokedexView->pokemonListCount++;
}
}
break;
case ORDER_LIGHTEST:
for (i = 0; i < NATIONAL_DEX_COUNT; i++)
{
temp_dexNum = gPokedexOrder_Weight[i];
2018-03-30 22:48:30 +02:00
2020-03-08 18:24:22 +01:00
if (NationalToHoennOrder(temp_dexNum) <= temp_dexCount && GetSetPokedexFlag(temp_dexNum, FLAG_GET_CAUGHT))
{
sPokedexView->pokedexList[sPokedexView->pokemonListCount].dexNum = temp_dexNum;
sPokedexView->pokedexList[sPokedexView->pokemonListCount].seen = TRUE;
sPokedexView->pokedexList[sPokedexView->pokemonListCount].owned = TRUE;
sPokedexView->pokemonListCount++;
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
}
break;
case ORDER_TALLEST:
for (i = NATIONAL_DEX_COUNT - 1; i >= 0; i--)
{
temp_dexNum = gPokedexOrder_Height[i];
if (NationalToHoennOrder(temp_dexNum) <= temp_dexCount && GetSetPokedexFlag(temp_dexNum, FLAG_GET_CAUGHT))
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
sPokedexView->pokedexList[sPokedexView->pokemonListCount].dexNum = temp_dexNum;
sPokedexView->pokedexList[sPokedexView->pokemonListCount].seen = TRUE;
sPokedexView->pokedexList[sPokedexView->pokemonListCount].owned = TRUE;
sPokedexView->pokemonListCount++;
}
}
break;
case ORDER_SMALLEST:
for (i = 0; i < NATIONAL_DEX_COUNT; i++)
{
temp_dexNum = gPokedexOrder_Height[i];
2018-05-10 09:30:42 +02:00
2020-03-08 18:24:22 +01:00
if (NationalToHoennOrder(temp_dexNum) <= temp_dexCount && GetSetPokedexFlag(temp_dexNum, FLAG_GET_CAUGHT))
{
sPokedexView->pokedexList[sPokedexView->pokemonListCount].dexNum = temp_dexNum;
sPokedexView->pokedexList[sPokedexView->pokemonListCount].seen = TRUE;
sPokedexView->pokedexList[sPokedexView->pokemonListCount].owned = TRUE;
sPokedexView->pokemonListCount++;
2018-03-30 22:48:30 +02:00
}
2020-03-08 18:24:22 +01:00
}
break;
2018-03-30 22:48:30 +02:00
}
2018-12-03 15:58:25 +01:00
for (i = sPokedexView->pokemonListCount; i < NATIONAL_DEX_COUNT; i++)
2018-03-30 22:48:30 +02:00
{
2019-01-13 12:12:27 +01:00
sPokedexView->pokedexList[i].dexNum = 0xFFFF;
sPokedexView->pokedexList[i].seen = FALSE;
sPokedexView->pokedexList[i].owned = FALSE;
2018-03-30 22:48:30 +02:00
}
}
2018-12-05 01:15:22 +01:00
static void PrintMonDexNumAndName(u8 windowId, u8 fontId, const u8* str, u8 left, u8 top)
2018-03-30 22:48:30 +02:00
{
2018-07-08 02:20:01 +02:00
u8 color[3];
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
color[0] = TEXT_COLOR_TRANSPARENT;
color[1] = TEXT_DYNAMIC_COLOR_6;
color[2] = TEXT_COLOR_LIGHT_GREY;
AddTextPrinterParameterized4(windowId, fontId, left * 8, (top * 8) + 1, 0, 0, color, -1, str);
2018-03-30 22:48:30 +02:00
}
2020-03-08 18:24:22 +01:00
// u16 ignored is passed but never used
static void CreateMonListEntry(u8 position, u16 b, u16 ignored)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
s16 entryNum;
2018-03-30 22:48:30 +02:00
u16 i;
2020-03-08 18:24:22 +01:00
u16 vOffset;
2018-03-30 22:48:30 +02:00
2020-03-08 18:24:22 +01:00
switch (position)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
case 0: // Initial
default:
entryNum = b - 5;
for (i = 0; i <= 10; i++)
{
if (entryNum < 0 || entryNum >= NATIONAL_DEX_COUNT || sPokedexView->pokedexList[entryNum].dexNum == 0xFFFF)
{
ClearMonListEntry(17, i * 2, ignored);
}
else
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
ClearMonListEntry(17, i * 2, ignored);
if (sPokedexView->pokedexList[entryNum].seen)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
CreateMonDexNum(entryNum, 0x12, i * 2, ignored);
CreateCaughtBall(sPokedexView->pokedexList[entryNum].owned, 0x11, i * 2, ignored);
CreateMonName(sPokedexView->pokedexList[entryNum].dexNum, 0x16, i * 2);
2018-03-30 22:48:30 +02:00
}
else
{
2020-03-08 18:24:22 +01:00
CreateMonDexNum(entryNum, 0x12, i * 2, ignored);
CreateCaughtBall(FALSE, 0x11, i * 2, ignored);
CreateMonName(0, 0x16, i * 2);
2018-03-30 22:48:30 +02:00
}
}
2020-03-08 18:24:22 +01:00
entryNum++;
}
break;
case 1: // Up
entryNum = b - 5;
if (entryNum < 0 || entryNum >= NATIONAL_DEX_COUNT || sPokedexView->pokedexList[entryNum].dexNum == 0xFFFF)
{
ClearMonListEntry(17, sPokedexView->listVOffset * 2, ignored);
}
else
{
ClearMonListEntry(17, sPokedexView->listVOffset * 2, ignored);
if (sPokedexView->pokedexList[entryNum].seen)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
CreateMonDexNum(entryNum, 18, sPokedexView->listVOffset * 2, ignored);
CreateCaughtBall(sPokedexView->pokedexList[entryNum].owned, 0x11, sPokedexView->listVOffset * 2, ignored);
CreateMonName(sPokedexView->pokedexList[entryNum].dexNum, 0x16, sPokedexView->listVOffset * 2);
2018-03-30 22:48:30 +02:00
}
else
{
2020-03-08 18:24:22 +01:00
CreateMonDexNum(entryNum, 18, sPokedexView->listVOffset * 2, ignored);
CreateCaughtBall(FALSE, 17, sPokedexView->listVOffset * 2, ignored);
CreateMonName(0, 0x16, sPokedexView->listVOffset * 2);
}
}
break;
case 2: // Down
entryNum = b + 5;
vOffset = sPokedexView->listVOffset + 10;
if (vOffset >= LIST_SCROLL_STEP)
vOffset -= LIST_SCROLL_STEP;
if (entryNum < 0 || entryNum >= NATIONAL_DEX_COUNT || sPokedexView->pokedexList[entryNum].dexNum == 0xFFFF)
ClearMonListEntry(17, vOffset * 2, ignored);
else
{
ClearMonListEntry(17, vOffset * 2, ignored);
if (sPokedexView->pokedexList[entryNum].seen)
{
CreateMonDexNum(entryNum, 18, vOffset * 2, ignored);
CreateCaughtBall(sPokedexView->pokedexList[entryNum].owned, 0x11, vOffset * 2, ignored);
CreateMonName(sPokedexView->pokedexList[entryNum].dexNum, 0x16, vOffset * 2);
2018-03-30 22:48:30 +02:00
}
else
{
2020-03-08 18:24:22 +01:00
CreateMonDexNum(entryNum, 18, vOffset * 2, ignored);
CreateCaughtBall(FALSE, 0x11, vOffset * 2, ignored);
CreateMonName(0, 0x16, vOffset * 2);
2018-03-30 22:48:30 +02:00
}
2020-03-08 18:24:22 +01:00
}
break;
2018-03-30 22:48:30 +02:00
}
CopyWindowToVram(0, 2);
}
2020-03-08 18:24:22 +01:00
static void CreateMonDexNum(u16 entryNum, u8 left, u8 top, u16 unused)
2018-03-30 22:48:30 +02:00
{
u8 text[6];
2020-03-08 18:24:22 +01:00
u16 dexNum;
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
memcpy(text, sText_No000, ARRAY_COUNT(text));
dexNum = sPokedexView->pokedexList[entryNum].dexNum;
2018-12-03 15:58:25 +01:00
if (sPokedexView->dexMode == DEX_MODE_HOENN)
2020-03-08 18:24:22 +01:00
dexNum = NationalToHoennOrder(dexNum);
text[2] = CHAR_0 + dexNum / 100;
text[3] = CHAR_0 + (dexNum % 100) / 10;
text[4] = CHAR_0 + (dexNum % 100) % 10;
2018-12-05 01:15:22 +01:00
PrintMonDexNumAndName(0, 7, text, left, top);
2018-03-30 22:48:30 +02:00
}
2020-03-08 18:24:22 +01:00
static void CreateCaughtBall(bool16 owned, u8 x, u8 y, u16 unused)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
if (owned)
BlitBitmapToWindow(0, sCaughtBall_Gfx, x * 8, y * 8, 8, 16);
2018-03-30 22:48:30 +02:00
else
FillWindowPixelRect(0, PIXEL_FILL(0), x * 8, y * 8, 8, 16);
2018-03-30 22:48:30 +02:00
}
2018-12-05 01:15:22 +01:00
static u8 CreateMonName(u16 num, u8 left, u8 top)
2018-03-30 22:48:30 +02:00
{
const u8* str;
2018-08-19 01:06:10 +02:00
2018-03-30 22:48:30 +02:00
num = NationalPokedexNumToSpecies(num);
if (num)
str = gSpeciesNames[num];
else
str = sText_TenDashes;
2018-12-05 01:15:22 +01:00
PrintMonDexNumAndName(0, 7, str, left, top);
2018-03-30 22:48:30 +02:00
return StringLength(str);
}
2020-01-03 02:35:35 +01:00
static void ClearMonListEntry(u8 x, u8 y, u16 unused)
2018-03-30 22:48:30 +02:00
{
FillWindowPixelRect(0, PIXEL_FILL(0), x * 8, y * 8, 0x60, 16);
2018-03-30 22:48:30 +02:00
}
2020-03-08 18:24:22 +01:00
// u16 ignored is passed but never used
static void CreateMonSpritesAtPos(u16 selectedMon, u16 ignored)
2018-03-30 22:48:30 +02:00
{
u8 i;
2020-03-08 18:24:22 +01:00
u16 dexNum;
2018-03-30 22:48:30 +02:00
u8 spriteId;
2018-08-19 01:06:10 +02:00
2018-03-30 22:48:30 +02:00
gPaletteFade.bufferTransferDisabled = TRUE;
2020-03-08 18:24:22 +01:00
for (i = 0; i < MAX_MONS_ON_SCREEN; i++)
2020-01-03 02:35:35 +01:00
sPokedexView->monSpriteIds[i] = 0xFFFF;
2018-12-03 15:58:25 +01:00
sPokedexView->selectedMonSpriteId = 0xFFFF;
2018-03-30 22:48:30 +02:00
2020-03-08 18:24:22 +01:00
// Create top mon sprite
dexNum = GetPokemonSpriteToDisplay(selectedMon - 1);
if (dexNum != 0xFFFF)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
spriteId = CreatePokedexMonSprite(dexNum, 0x60, 0x50);
gSprites[spriteId].callback = SpriteCB_PokedexListMonSprite;
2018-03-30 22:48:30 +02:00
gSprites[spriteId].data[5] = -32;
}
2020-03-08 18:24:22 +01:00
// Create mid mon sprite
dexNum = GetPokemonSpriteToDisplay(selectedMon);
if (dexNum != 0xFFFF)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
spriteId = CreatePokedexMonSprite(dexNum, 0x60, 0x50);
gSprites[spriteId].callback = SpriteCB_PokedexListMonSprite;
2018-03-30 22:48:30 +02:00
gSprites[spriteId].data[5] = 0;
}
2020-03-08 18:24:22 +01:00
// Create bottom mon sprite
dexNum = GetPokemonSpriteToDisplay(selectedMon + 1);
if (dexNum != 0xFFFF)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
spriteId = CreatePokedexMonSprite(dexNum, 0x60, 0x50);
gSprites[spriteId].callback = SpriteCB_PokedexListMonSprite;
2018-03-30 22:48:30 +02:00
gSprites[spriteId].data[5] = 32;
}
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
CreateMonListEntry(0, selectedMon, ignored);
2018-12-05 01:15:22 +01:00
SetGpuReg(REG_OFFSET_BG2VOFS, sPokedexView->initialVOffset);
2018-03-30 22:48:30 +02:00
2020-03-08 18:24:22 +01:00
sPokedexView->listVOffset = 0;
sPokedexView->listMovingVOffset = 0;
2018-08-19 01:06:10 +02:00
2018-03-30 22:48:30 +02:00
gPaletteFade.bufferTransferDisabled = FALSE;
}
2020-03-08 18:24:22 +01:00
static bool8 UpdateDexListScroll(u8 direction, u8 monMoveIncrement, u8 scrollTimerMax)
2018-03-30 22:48:30 +02:00
{
u16 i;
2020-03-08 18:24:22 +01:00
u8 step;
2018-03-30 22:48:30 +02:00
2020-03-08 18:24:22 +01:00
if (sPokedexView->scrollTimer)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
sPokedexView->scrollTimer--;
switch (direction)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
case 1: // Up
for (i = 0; i < MAX_MONS_ON_SCREEN; i++)
{
if (sPokedexView->monSpriteIds[i] != 0xFFFF)
gSprites[sPokedexView->monSpriteIds[i]].data[5] += monMoveIncrement;
}
step = LIST_SCROLL_STEP * (scrollTimerMax - sPokedexView->scrollTimer) / scrollTimerMax;
SetGpuReg(REG_OFFSET_BG2VOFS, sPokedexView->initialVOffset + sPokedexView->listMovingVOffset * LIST_SCROLL_STEP - step);
sPokedexView->pokeBallRotation -= sPokedexView->pokeBallRotationStep;
break;
case 2: // Down
for (i = 0; i < MAX_MONS_ON_SCREEN; i++)
{
if (sPokedexView->monSpriteIds[i] != 0xFFFF)
gSprites[sPokedexView->monSpriteIds[i]].data[5] -= monMoveIncrement;
}
step = LIST_SCROLL_STEP * (scrollTimerMax - sPokedexView->scrollTimer) / scrollTimerMax;
SetGpuReg(REG_OFFSET_BG2VOFS, sPokedexView->initialVOffset + sPokedexView->listMovingVOffset * LIST_SCROLL_STEP + step);
sPokedexView->pokeBallRotation += sPokedexView->pokeBallRotationStep;
break;
2018-03-30 22:48:30 +02:00
}
return FALSE;
}
else
{
2020-03-08 18:24:22 +01:00
SetGpuReg(REG_OFFSET_BG2VOFS, sPokedexView->initialVOffset + sPokedexView->listVOffset * LIST_SCROLL_STEP);
2018-03-30 22:48:30 +02:00
return TRUE;
}
}
2020-03-08 18:24:22 +01:00
static void CreateScrollingPokemonSprite(u8 direction, u16 selectedMon)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
u16 dexNum;
2018-03-30 22:48:30 +02:00
u8 spriteId;
2020-03-08 18:24:22 +01:00
sPokedexView->listMovingVOffset = sPokedexView->listVOffset;
2018-12-03 15:58:25 +01:00
switch (direction)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
case 1: // up
dexNum = GetPokemonSpriteToDisplay(selectedMon - 1);
if (dexNum != 0xFFFF)
{
spriteId = CreatePokedexMonSprite(dexNum, 0x60, 0x50);
gSprites[spriteId].callback = SpriteCB_PokedexListMonSprite;
gSprites[spriteId].data[5] = -64;
}
if (sPokedexView->listVOffset > 0)
sPokedexView->listVOffset--;
else
sPokedexView->listVOffset = LIST_SCROLL_STEP - 1;
break;
case 2: // down
dexNum = GetPokemonSpriteToDisplay(selectedMon + 1);
if (dexNum != 0xFFFF)
{
spriteId = CreatePokedexMonSprite(dexNum, 0x60, 0x50);
gSprites[spriteId].callback = SpriteCB_PokedexListMonSprite;
gSprites[spriteId].data[5] = 64;
}
if (sPokedexView->listVOffset < LIST_SCROLL_STEP - 1)
sPokedexView->listVOffset++;
else
sPokedexView->listVOffset = 0;
break;
2018-03-30 22:48:30 +02:00
}
}
2020-03-08 18:24:22 +01:00
// u16 ignored is passed but never used
static u16 TryDoPokedexScroll(u16 selectedMon, u16 ignored)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
u8 scrollTimer;
u8 scrollMonIncrement;
2018-03-30 22:48:30 +02:00
u8 i;
2020-03-08 18:24:22 +01:00
u16 startingPos;
u8 scrollDir = 0;
2018-08-19 01:06:10 +02:00
2018-12-03 15:58:25 +01:00
if ((gMain.heldKeys & DPAD_UP) && (selectedMon > 0))
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
scrollDir = 1;
selectedMon = GetNextPosition(1, selectedMon, 0, sPokedexView->pokemonListCount - 1);
CreateScrollingPokemonSprite(1, selectedMon);
CreateMonListEntry(1, selectedMon, ignored);
2018-03-30 22:48:30 +02:00
PlaySE(SE_Z_SCROLL);
}
2018-12-03 15:58:25 +01:00
else if ((gMain.heldKeys & DPAD_DOWN) && (selectedMon < sPokedexView->pokemonListCount - 1))
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
scrollDir = 2;
selectedMon = GetNextPosition(0, selectedMon, 0, sPokedexView->pokemonListCount - 1);
CreateScrollingPokemonSprite(2, selectedMon);
CreateMonListEntry(2, selectedMon, ignored);
2018-03-30 22:48:30 +02:00
PlaySE(SE_Z_SCROLL);
}
2018-12-03 15:58:25 +01:00
else if ((gMain.newKeys & DPAD_LEFT) && (selectedMon > 0))
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
startingPos = selectedMon;
2018-08-19 01:06:10 +02:00
2018-03-30 22:48:30 +02:00
for (i = 0; i < 7; i++)
2020-03-08 18:24:22 +01:00
selectedMon = GetNextPosition(1, selectedMon, 0, sPokedexView->pokemonListCount - 1);
sPokedexView->pokeBallRotation += 16 * (selectedMon - startingPos);
2020-01-03 02:35:35 +01:00
ClearMonSprites();
2020-03-08 18:24:22 +01:00
CreateMonSpritesAtPos(selectedMon, 0xE);
2018-03-30 22:48:30 +02:00
PlaySE(SE_Z_PAGE);
}
2018-12-03 15:58:25 +01:00
else if ((gMain.newKeys & DPAD_RIGHT) && (selectedMon < sPokedexView->pokemonListCount - 1))
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
startingPos = selectedMon;
2018-03-30 22:48:30 +02:00
for (i = 0; i < 7; i++)
2020-03-08 18:24:22 +01:00
selectedMon = GetNextPosition(0, selectedMon, 0, sPokedexView->pokemonListCount - 1);
sPokedexView->pokeBallRotation += 16 * (selectedMon - startingPos);
2020-01-03 02:35:35 +01:00
ClearMonSprites();
2020-03-08 18:24:22 +01:00
CreateMonSpritesAtPos(selectedMon, 0xE);
2018-03-30 22:48:30 +02:00
PlaySE(SE_Z_PAGE);
}
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
if (scrollDir == 0)
2018-03-30 22:48:30 +02:00
{
2020-03-08 18:24:22 +01:00
// Left/right input just snaps up/down, no scrolling
sPokedexView->scrollSpeed = 0;
2018-12-03 15:58:25 +01:00
return selectedMon;
2018-03-30 22:48:30 +02:00
}
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
scrollMonIncrement = sScrollMonIncrements[sPokedexView->scrollSpeed / 4];
scrollTimer = sScrollTimers[sPokedexView->scrollSpeed / 4];
sPokedexView->scrollTimer = scrollTimer;
sPokedexView->maxScrollTimer = scrollTimer;
sPokedexView->scrollMonIncrement = scrollMonIncrement;
sPokedexView->scrollDirection = scrollDir;
sPokedexView->pokeBallRotationStep = scrollMonIncrement / 2;
UpdateDexListScroll(sPokedexView->scrollDirection, sPokedexView->scrollMonIncrement, sPokedexView->maxScrollTimer);
if (sPokedexView->scrollSpeed < 12)
sPokedexView->scrollSpeed++;
2018-12-03 15:58:25 +01:00
return selectedMon;
2018-03-30 22:48:30 +02:00
}
2018-05-01 02:41:17 +02:00
2020-01-03 02:35:35 +01:00
static void UpdateSelectedMonSpriteId(void)
2018-05-01 02:41:17 +02:00
{
u16 i;
2020-03-08 18:24:22 +01:00
for (i = 0; i < MAX_MONS_ON_SCREEN; i++)
2018-05-01 02:41:17 +02:00
{
2020-01-03 02:35:35 +01:00
u16 spriteId = sPokedexView->monSpriteIds[i];
2018-05-01 02:41:17 +02:00
if (gSprites[spriteId].pos2.x == 0 && gSprites[spriteId].pos2.y == 0 && spriteId != 0xFFFF)
2018-12-03 15:58:25 +01:00
sPokedexView->selectedMonSpriteId = spriteId;
2018-05-01 02:41:17 +02:00
}
}
2020-03-08 18:24:22 +01:00
static bool8 TryDoInfoScreenScroll(void)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
u16 nextPokemon;
u16 selectedPokemon = sPokedexView->selectedPokemon;
2018-05-01 02:41:17 +02:00
2020-03-08 18:24:22 +01:00
if ((gMain.newKeys & DPAD_UP) && selectedPokemon)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
nextPokemon = selectedPokemon;
while (nextPokemon != 0)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
nextPokemon = GetNextPosition(1, nextPokemon, 0, sPokedexView->pokemonListCount - 1);
2018-05-01 02:41:17 +02:00
2020-03-08 18:24:22 +01:00
if (sPokedexView->pokedexList[nextPokemon].seen)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
selectedPokemon = nextPokemon;
2018-05-01 02:41:17 +02:00
break;
}
}
2020-03-08 18:24:22 +01:00
if (sPokedexView->selectedPokemon == selectedPokemon)
2018-05-01 02:41:17 +02:00
return FALSE;
else
{
2020-03-08 18:24:22 +01:00
sPokedexView->selectedPokemon = selectedPokemon;
sPokedexView->pokeBallRotation -= 16;
2018-05-01 02:41:17 +02:00
return TRUE;
}
}
2020-03-08 18:24:22 +01:00
else if ((gMain.newKeys & DPAD_DOWN) && selectedPokemon < sPokedexView->pokemonListCount - 1)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
nextPokemon = selectedPokemon;
while (nextPokemon < sPokedexView->pokemonListCount - 1)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
nextPokemon = GetNextPosition(0, nextPokemon, 0, sPokedexView->pokemonListCount - 1);
2018-05-01 02:41:17 +02:00
2020-03-08 18:24:22 +01:00
if (sPokedexView->pokedexList[nextPokemon].seen)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
selectedPokemon = nextPokemon;
2018-05-01 02:41:17 +02:00
break;
}
}
2020-03-08 18:24:22 +01:00
if (sPokedexView->selectedPokemon == selectedPokemon)
2018-05-01 02:41:17 +02:00
return FALSE;
else
{
2020-03-08 18:24:22 +01:00
sPokedexView->selectedPokemon = selectedPokemon;
sPokedexView->pokeBallRotation += 16;
2018-05-01 02:41:17 +02:00
return TRUE;
}
}
return FALSE;
}
2020-01-03 02:35:35 +01:00
static u8 ClearMonSprites(void)
2018-05-01 02:41:17 +02:00
{
u16 i;
2020-03-08 18:24:22 +01:00
for (i = 0; i < MAX_MONS_ON_SCREEN; i++)
2018-05-01 02:41:17 +02:00
{
2020-01-03 02:35:35 +01:00
if (sPokedexView->monSpriteIds[i] != 0xFFFF)
2018-05-01 02:41:17 +02:00
{
2020-01-03 02:35:35 +01:00
FreeAndDestroyMonPicSprite(sPokedexView->monSpriteIds[i]);
sPokedexView->monSpriteIds[i] = 0xFFFF;
2018-05-01 02:41:17 +02:00
}
}
return FALSE;
}
2020-03-08 18:24:22 +01:00
static u16 GetPokemonSpriteToDisplay(u16 species)
2018-05-01 02:41:17 +02:00
{
if (species >= NATIONAL_DEX_COUNT || sPokedexView->pokedexList[species].dexNum == 0xFFFF)
2018-05-01 02:41:17 +02:00
return 0xFFFF;
else if (sPokedexView->pokedexList[species].seen)
return sPokedexView->pokedexList[species].dexNum;
2018-05-01 02:41:17 +02:00
else
return 0;
}
2020-03-08 18:24:22 +01:00
static u32 CreatePokedexMonSprite(u16 num, s16 x, s16 y)
2018-05-01 02:41:17 +02:00
{
u8 i;
2020-03-08 18:24:22 +01:00
for (i = 0; i < MAX_MONS_ON_SCREEN; i++)
2018-05-01 02:41:17 +02:00
{
2020-01-03 02:35:35 +01:00
if (sPokedexView->monSpriteIds[i] == 0xFFFF)
2018-05-01 02:41:17 +02:00
{
u8 spriteId = CreateMonSpriteFromNationalDexNumber(num, x, y, i);
2018-05-01 02:41:17 +02:00
gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL;
2018-05-01 02:41:17 +02:00
gSprites[spriteId].oam.priority = 3;
gSprites[spriteId].data[0] = 0;
gSprites[spriteId].data[1] = i;
2018-07-08 02:20:01 +02:00
gSprites[spriteId].data[2] = NationalPokedexNumToSpecies(num);
2020-01-03 02:35:35 +01:00
sPokedexView->monSpriteIds[i] = spriteId;
2018-05-01 02:41:17 +02:00
return spriteId;
}
}
return 0xFFFF;
}
2020-03-08 18:24:22 +01:00
#define sIsDownArrow data[1]
static void CreateInterfaceSprites(u8 page)
2018-05-01 02:41:17 +02:00
{
u8 spriteId;
2020-03-08 18:24:22 +01:00
u16 digitNum;
// Scroll arrows
spriteId = CreateSprite(&sScrollArrowSpriteTemplate, 184, 4, 0);
gSprites[spriteId].sIsDownArrow = FALSE;
spriteId = CreateSprite(&sScrollArrowSpriteTemplate, 184, 156, 0);
gSprites[spriteId].sIsDownArrow = TRUE;
2018-05-01 02:41:17 +02:00
gSprites[spriteId].vFlip = TRUE;
2018-12-03 15:58:25 +01:00
CreateSprite(&sScrollBarSpriteTemplate, 230, 20, 0);
2020-03-08 18:24:22 +01:00
// Start button
2018-12-03 15:58:25 +01:00
CreateSprite(&sInterfaceTextSpriteTemplate, 16, 120, 0);
2020-03-08 18:24:22 +01:00
// Menu text
2018-12-03 15:58:25 +01:00
spriteId = CreateSprite(&sInterfaceTextSpriteTemplate, 48, 120, 0);
2018-05-01 02:41:17 +02:00
StartSpriteAnim(&gSprites[spriteId], 3);
2020-03-08 18:24:22 +01:00
// Select button
2018-12-03 15:58:25 +01:00
spriteId = CreateSprite(&sInterfaceTextSpriteTemplate, 16, 144, 0);
2018-05-01 02:41:17 +02:00
StartSpriteAnim(&gSprites[spriteId], 2);
gSprites[spriteId].data[2] = 0x80;
2020-03-08 18:24:22 +01:00
// Search text
2018-12-03 15:58:25 +01:00
spriteId = CreateSprite(&sInterfaceTextSpriteTemplate, 48, 144, 0);
2018-05-01 02:41:17 +02:00
StartSpriteAnim(&gSprites[spriteId], 1);
2020-03-08 18:24:22 +01:00
spriteId = CreateSprite(&sRotatingPokeBallSpriteTemplate, 0, 80, 2);
gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL;
2018-05-01 02:41:17 +02:00
gSprites[spriteId].oam.matrixNum = 30;
2020-03-08 18:24:22 +01:00
gSprites[spriteId].data[0] = 30;
2018-05-01 02:41:17 +02:00
gSprites[spriteId].data[1] = 0;
2020-03-08 18:24:22 +01:00
spriteId = CreateSprite(&sRotatingPokeBallSpriteTemplate, 0, 80, 2);
gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL;
2018-05-01 02:41:17 +02:00
gSprites[spriteId].oam.matrixNum = 31;
2020-03-08 18:24:22 +01:00
gSprites[spriteId].data[0] = 31;
gSprites[spriteId].data[1] = 128;
2018-05-01 02:41:17 +02:00
2020-03-08 18:24:22 +01:00
if (page == PAGE_MAIN)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
bool32 drawNextDigit;
2018-08-19 01:06:10 +02:00
2018-05-01 02:41:17 +02:00
if (!IsNationalPokedexEnabled())
{
2020-03-08 18:24:22 +01:00
// Seen text
2018-12-03 15:58:25 +01:00
CreateSprite(&sSeenOwnTextSpriteTemplate, 32, 40, 1);
2020-03-08 18:24:22 +01:00
// Own text
2018-12-03 15:58:25 +01:00
spriteId = CreateSprite(&sSeenOwnTextSpriteTemplate, 32, 72, 1);
2018-05-01 02:41:17 +02:00
StartSpriteAnim(&gSprites[spriteId], 1);
2020-03-08 18:24:22 +01:00
// Seen value - 100s
drawNextDigit = FALSE;
spriteId = CreateSprite(&sHoennDexSeenOwnNumberSpriteTemplate, 24, 48, 1);
digitNum = sPokedexView->seenCount / 100;
StartSpriteAnim(&gSprites[spriteId], digitNum);
if (digitNum != 0)
drawNextDigit = TRUE;
2018-05-01 02:41:17 +02:00
else
gSprites[spriteId].invisible = TRUE;
2020-03-08 18:24:22 +01:00
// Seen value - 10s
spriteId = CreateSprite(&sHoennDexSeenOwnNumberSpriteTemplate, 32, 48, 1);
digitNum = (sPokedexView->seenCount % 100) / 10;
if (digitNum != 0 || drawNextDigit)
StartSpriteAnim(&gSprites[spriteId], digitNum);
2018-05-01 02:41:17 +02:00
else
gSprites[spriteId].invisible = TRUE;
2020-03-08 18:24:22 +01:00
// Seen value - 1s
spriteId = CreateSprite(&sHoennDexSeenOwnNumberSpriteTemplate, 40, 48, 1);
digitNum = (sPokedexView->seenCount % 100) % 10;
StartSpriteAnim(&gSprites[spriteId], digitNum);
2020-03-08 18:24:22 +01:00
// Owned value - 100s
drawNextDigit = FALSE;
spriteId = CreateSprite(&sHoennDexSeenOwnNumberSpriteTemplate, 24, 80, 1);
digitNum = sPokedexView->ownCount / 100;
StartSpriteAnim(&gSprites[spriteId], digitNum);
if (digitNum != 0)
drawNextDigit = TRUE;
2018-05-01 02:41:17 +02:00
else
gSprites[spriteId].invisible = TRUE;
2020-03-08 18:24:22 +01:00
// Owned value - 10s
spriteId = CreateSprite(&sHoennDexSeenOwnNumberSpriteTemplate, 32, 80, 1);
digitNum = (sPokedexView->ownCount % 100) / 10;
if (digitNum != 0 || drawNextDigit)
StartSpriteAnim(&gSprites[spriteId], digitNum);
2018-05-01 02:41:17 +02:00
else
gSprites[spriteId].invisible = TRUE;
2020-03-08 18:24:22 +01:00
// Owned value - 1s
spriteId = CreateSprite(&sHoennDexSeenOwnNumberSpriteTemplate, 40, 80, 1);
digitNum = (sPokedexView->ownCount % 100) % 10;
StartSpriteAnim(&gSprites[spriteId], digitNum);
2018-05-01 02:41:17 +02:00
}
else
{
2020-03-08 18:24:22 +01:00
u16 seenOwnedCount;
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
// Seen text
2018-12-03 15:58:25 +01:00
CreateSprite(&sSeenOwnTextSpriteTemplate, 32, 40, 1);
2020-03-08 18:24:22 +01:00
// Own text
2018-12-03 15:58:25 +01:00
spriteId = CreateSprite(&sSeenOwnTextSpriteTemplate, 32, 76, 1);
2018-05-01 02:41:17 +02:00
StartSpriteAnim(&gSprites[spriteId], 1);
2020-03-08 18:24:22 +01:00
// Hoenn text (seen)
CreateSprite(&sHoennNationalTextSpriteTemplate, 17, 45, 1);
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
// National text (seen)
spriteId = CreateSprite(&sHoennNationalTextSpriteTemplate, 17, 55, 1);
2018-05-01 02:41:17 +02:00
StartSpriteAnim(&gSprites[spriteId], 1);
2020-03-08 18:24:22 +01:00
// Hoenn text (own)
CreateSprite(&sHoennNationalTextSpriteTemplate, 17, 81, 1);
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
// National text (own)
spriteId = CreateSprite(&sHoennNationalTextSpriteTemplate, 17, 91, 1);
2018-05-01 02:41:17 +02:00
StartSpriteAnim(&gSprites[spriteId], 1);
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
// Hoenn seen value - 100s
seenOwnedCount = GetHoennPokedexCount(FLAG_GET_SEEN);
drawNextDigit = FALSE;
spriteId = CreateSprite(&sNationalDexSeenOwnNumberSpriteTemplate, 40, 45, 1);
digitNum = seenOwnedCount / 100;
StartSpriteAnim(&gSprites[spriteId], digitNum);
if (digitNum != 0)
drawNextDigit = TRUE;
2018-05-01 02:41:17 +02:00
else
gSprites[spriteId].invisible = TRUE;
2020-03-08 18:24:22 +01:00
// Hoenn seen value - 10s
spriteId = CreateSprite(&sNationalDexSeenOwnNumberSpriteTemplate, 48, 45, 1);
digitNum = (seenOwnedCount % 100) / 10;
if (digitNum != 0 || drawNextDigit)
StartSpriteAnim(&gSprites[spriteId], digitNum);
2018-05-01 02:41:17 +02:00
else
gSprites[spriteId].invisible = TRUE;
2020-03-08 18:24:22 +01:00
// Hoenn seen value - 1s
spriteId = CreateSprite(&sNationalDexSeenOwnNumberSpriteTemplate, 56, 45, 1);
digitNum = (seenOwnedCount % 100) % 10;
StartSpriteAnim(&gSprites[spriteId], digitNum);
// National seen value - 100s
drawNextDigit = FALSE;
spriteId = CreateSprite(&sNationalDexSeenOwnNumberSpriteTemplate, 40, 55, 1);
digitNum = sPokedexView->seenCount / 100;
StartSpriteAnim(&gSprites[spriteId], digitNum);
if (digitNum != 0)
drawNextDigit = TRUE;
2018-05-01 02:41:17 +02:00
else
gSprites[spriteId].invisible = TRUE;
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
// National seen value - 10s
spriteId = CreateSprite(&sNationalDexSeenOwnNumberSpriteTemplate, 48, 55, 1);
digitNum = (sPokedexView->seenCount % 100) / 10;
if (digitNum != 0 || drawNextDigit)
StartSpriteAnim(&gSprites[spriteId], digitNum);
2018-05-01 02:41:17 +02:00
else
gSprites[spriteId].invisible = TRUE;
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
// National seen value - 1s
spriteId = CreateSprite(&sNationalDexSeenOwnNumberSpriteTemplate, 56, 55, 1);
digitNum = (sPokedexView->seenCount % 100) % 10;
StartSpriteAnim(&gSprites[spriteId], digitNum);
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
seenOwnedCount = GetHoennPokedexCount(FLAG_GET_CAUGHT);
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
// Hoenn owned value - 100s
drawNextDigit = FALSE;
spriteId = CreateSprite(&sNationalDexSeenOwnNumberSpriteTemplate, 40, 81, 1);
digitNum = seenOwnedCount / 100;
StartSpriteAnim(&gSprites[spriteId], digitNum);
if (digitNum != 0)
drawNextDigit = TRUE;
2018-05-01 02:41:17 +02:00
else
gSprites[spriteId].invisible = TRUE;
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
// Hoenn owned value - 10s
spriteId = CreateSprite(&sNationalDexSeenOwnNumberSpriteTemplate, 48, 81, 1);
digitNum = (seenOwnedCount % 100) / 10;
if (digitNum != 0 || drawNextDigit)
StartSpriteAnim(&gSprites[spriteId], digitNum);
2018-05-01 02:41:17 +02:00
else
gSprites[spriteId].invisible = TRUE;
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
// Hoenn owned value - 1s
spriteId = CreateSprite(&sNationalDexSeenOwnNumberSpriteTemplate, 56, 81, 1);
digitNum = (seenOwnedCount % 100) % 10;
StartSpriteAnim(&gSprites[spriteId], digitNum);
// National owned value - 100s
drawNextDigit = FALSE;
spriteId = CreateSprite(&sNationalDexSeenOwnNumberSpriteTemplate, 40, 91, 1);
digitNum = sPokedexView->ownCount / 100;
StartSpriteAnim(&gSprites[spriteId], digitNum);
if (digitNum != 0)
drawNextDigit = TRUE;
2018-05-01 02:41:17 +02:00
else
gSprites[spriteId].invisible = TRUE;
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
// National owned value - 10s
spriteId = CreateSprite(&sNationalDexSeenOwnNumberSpriteTemplate, 48, 91, 1);
digitNum = (sPokedexView->ownCount % 100) / 10;
if (digitNum != 0 || drawNextDigit)
StartSpriteAnim(&gSprites[spriteId], digitNum);
2018-05-01 02:41:17 +02:00
else
gSprites[spriteId].invisible = TRUE;
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
// National owned value - 1s
spriteId = CreateSprite(&sNationalDexSeenOwnNumberSpriteTemplate, 56, 91, 1);
digitNum = (sPokedexView->ownCount % 100) % 10;
StartSpriteAnim(&gSprites[spriteId], digitNum);
2018-05-01 02:41:17 +02:00
}
2020-03-08 18:24:22 +01:00
spriteId = CreateSprite(&sDexListStartMenuCursorSpriteTemplate, 136, 96, 1);
2018-05-01 02:41:17 +02:00
gSprites[spriteId].invisible = TRUE;
}
2020-03-08 18:24:22 +01:00
else // PAGE_SEARCH_RESULTS
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
spriteId = CreateSprite(&sDexListStartMenuCursorSpriteTemplate, 136, 80, 1);
2018-05-01 02:41:17 +02:00
gSprites[spriteId].invisible = TRUE;
}
}
2020-03-08 18:24:22 +01:00
static void SpriteCB_EndMoveMonForInfoScreen(struct Sprite *sprite)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
// Once mon is done moving there's nothing left to do
2018-05-01 02:41:17 +02:00
}
2020-03-08 18:24:22 +01:00
static void SpriteCB_SeenOwnInfo(struct Sprite *sprite)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
if (sPokedexView->currentPage != PAGE_MAIN)
2018-05-01 02:41:17 +02:00
DestroySprite(sprite);
}
2020-03-08 18:24:22 +01:00
void SpriteCB_MoveMonForInfoScreen(struct Sprite *sprite)
2018-05-01 02:41:17 +02:00
{
sprite->oam.priority = 0;
sprite->oam.affineMode = ST_OAM_AFFINE_OFF;
2018-05-01 02:41:17 +02:00
sprite->pos2.x = 0;
sprite->pos2.y = 0;
if (sprite->pos1.x != 48 || sprite->pos1.y != 56)
{
if (sprite->pos1.x > 48)
sprite->pos1.x--;
if (sprite->pos1.x < 48)
sprite->pos1.x++;
if (sprite->pos1.y > 56)
sprite->pos1.y--;
if (sprite->pos1.y < 56)
sprite->pos1.y++;
}
else
{
2020-03-08 18:24:22 +01:00
sprite->callback = SpriteCB_EndMoveMonForInfoScreen;
2018-05-01 02:41:17 +02:00
}
}
2020-03-08 18:24:22 +01:00
static void SpriteCB_PokedexListMonSprite(struct Sprite *sprite)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
u8 monId = sprite->data[1];
2018-05-01 02:41:17 +02:00
2020-03-08 18:24:22 +01:00
if (sPokedexView->currentPage != PAGE_MAIN && sPokedexView->currentPage != PAGE_SEARCH_RESULTS)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
FreeAndDestroyMonPicSprite(sPokedexView->monSpriteIds[monId]);
sPokedexView->monSpriteIds[monId] = 0xFFFF;
2018-05-01 02:41:17 +02:00
}
else
{
u32 var;
sprite->pos2.y = gSineTable[(u8)sprite->data[5]] * 76 / 256;
2020-03-08 18:24:22 +01:00
var = 0x10000 / gSineTable[sprite->data[5] + 64];
2018-05-01 02:41:17 +02:00
if (var > 0xFFFF)
var = 0xFFFF;
SetOamMatrix(sprite->data[1] + 1, 0x100, 0, 0, var);
2020-03-08 18:24:22 +01:00
sprite->oam.matrixNum = monId + 1;
2018-05-01 02:41:17 +02:00
if (sprite->data[5] > -64 && sprite->data[5] < 64)
{
sprite->invisible = FALSE;
sprite->data[0] = 1;
}
else
{
sprite->invisible = TRUE;
}
if ((sprite->data[5] <= -64 || sprite->data[5] >= 64) && sprite->data[0] != 0)
{
2020-03-08 18:24:22 +01:00
FreeAndDestroyMonPicSprite(sPokedexView->monSpriteIds[monId]);
sPokedexView->monSpriteIds[monId] = 0xFFFF;
2018-05-01 02:41:17 +02:00
}
}
}
2018-12-05 01:15:22 +01:00
static void SpriteCB_Scrollbar(struct Sprite *sprite)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
if (sPokedexView->currentPage != PAGE_MAIN && sPokedexView->currentPage != PAGE_SEARCH_RESULTS)
2018-05-01 02:41:17 +02:00
DestroySprite(sprite);
else
2018-12-03 15:58:25 +01:00
sprite->pos2.y = sPokedexView->selectedPokemon * 120 / (sPokedexView->pokemonListCount - 1);
2018-05-01 02:41:17 +02:00
}
2020-03-08 18:24:22 +01:00
static void SpriteCB_ScrollArrow(struct Sprite *sprite)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
if (sPokedexView->currentPage != PAGE_MAIN && sPokedexView->currentPage != PAGE_SEARCH_RESULTS)
2018-05-01 02:41:17 +02:00
{
DestroySprite(sprite);
}
else
{
u8 r0;
2020-03-08 18:24:22 +01:00
if (sprite->sIsDownArrow)
2018-05-01 02:41:17 +02:00
{
2018-12-03 15:58:25 +01:00
if (sPokedexView->selectedPokemon == sPokedexView->pokemonListCount - 1)
2018-05-01 02:41:17 +02:00
sprite->invisible = TRUE;
else
sprite->invisible = FALSE;
r0 = sprite->data[2];
}
else
{
2018-12-03 15:58:25 +01:00
if (sPokedexView->selectedPokemon == 0)
2018-05-01 02:41:17 +02:00
sprite->invisible = TRUE;
else
sprite->invisible = FALSE;
r0 = sprite->data[2] - 128;
}
sprite->pos2.y = gSineTable[r0] / 64;
sprite->data[2] = sprite->data[2] + 8;
2020-03-08 18:24:22 +01:00
if (sPokedexView->menuIsOpen == FALSE && sPokedexView->menuY == 0 && sprite->invisible == FALSE)
2018-05-01 02:41:17 +02:00
sprite->invisible = FALSE;
else
sprite->invisible = TRUE;
}
}
2020-03-08 18:24:22 +01:00
static void SpriteCB_DexListInterfaceText(struct Sprite *sprite)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
if (sPokedexView->currentPage != PAGE_MAIN && sPokedexView->currentPage != PAGE_SEARCH_RESULTS)
2018-05-01 02:41:17 +02:00
DestroySprite(sprite);
}
2020-03-08 18:24:22 +01:00
static void SpriteCB_RotatingPokeBall(struct Sprite *sprite)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
if (sPokedexView->currentPage != PAGE_MAIN && sPokedexView->currentPage != PAGE_SEARCH_RESULTS)
2018-05-01 02:41:17 +02:00
{
DestroySprite(sprite);
}
else
{
u8 val;
s16 r3;
s16 r0;
2020-03-08 18:24:22 +01:00
val = sPokedexView->pokeBallRotation + sprite->data[1];
2018-05-01 02:41:17 +02:00
r3 = gSineTable[val];
2020-03-08 18:24:22 +01:00
r0 = gSineTable[val + 64];
2018-05-01 02:41:17 +02:00
SetOamMatrix(sprite->data[0], r0, r3, -r3, r0);
2020-03-08 18:24:22 +01:00
val = sPokedexView->pokeBallRotation + (sprite->data[1] + 64);
2018-05-01 02:41:17 +02:00
r3 = gSineTable[val];
2020-03-08 18:24:22 +01:00
r0 = gSineTable[val + 64];
2018-05-01 02:41:17 +02:00
sprite->pos2.x = r0 * 40 / 256;
sprite->pos2.y = r3 * 40 / 256;
}
}
2020-03-08 18:24:22 +01:00
static void SpriteCB_DexListStartMenuCursor(struct Sprite *sprite)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
if (sPokedexView->currentPage != PAGE_MAIN && sPokedexView->currentPage != PAGE_SEARCH_RESULTS)
2018-05-01 02:41:17 +02:00
{
DestroySprite(sprite);
}
else
{
2020-03-08 18:24:22 +01:00
u16 r1 = sPokedexView->currentPage == PAGE_MAIN ? 80 : 96;
2018-05-01 02:41:17 +02:00
2020-03-08 18:24:22 +01:00
if (sPokedexView->menuIsOpen && sPokedexView->menuY == r1)
2018-05-01 02:41:17 +02:00
{
sprite->invisible = FALSE;
2018-12-03 15:58:25 +01:00
sprite->pos2.y = sPokedexView->menuCursorPos * 16;
2018-05-01 02:41:17 +02:00
sprite->pos2.x = gSineTable[(u8)sprite->data[2]] / 64;
sprite->data[2] += 8;
}
else
{
sprite->invisible = TRUE;
}
}
}
2020-03-08 18:24:22 +01:00
static void PrintInfoScreenText(const u8* str, u8 left, u8 top)
2018-05-01 02:41:17 +02:00
{
2018-07-08 02:20:01 +02:00
u8 color[3];
2020-03-08 18:24:22 +01:00
color[0] = TEXT_COLOR_TRANSPARENT;
color[1] = TEXT_DYNAMIC_COLOR_6;
color[2] = TEXT_COLOR_LIGHT_GREY;
2018-08-19 01:06:10 +02:00
AddTextPrinterParameterized4(0, 1, left, top, 0, 0, color, -1, str);
2018-05-01 02:41:17 +02:00
}
2019-11-20 00:54:00 +01:00
#define tMonSpriteId data[4]
2020-03-08 18:24:22 +01:00
static u8 LoadInfoScreen(struct PokedexListItem* item, u8 monSpriteId)
2018-05-01 02:41:17 +02:00
{
u8 taskId;
2018-08-19 01:06:10 +02:00
2018-12-03 15:58:25 +01:00
sPokedexListItem = item;
2020-03-08 18:24:22 +01:00
taskId = CreateTask(Task_LoadInfoScreen, 0);
2018-05-01 02:41:17 +02:00
gTasks[taskId].data[0] = 0;
gTasks[taskId].data[1] = 1;
gTasks[taskId].data[2] = 0;
gTasks[taskId].data[3] = 0;
2019-11-20 00:54:00 +01:00
gTasks[taskId].tMonSpriteId = monSpriteId;
2018-05-01 02:41:17 +02:00
gTasks[taskId].data[5] = 255;
ResetBgsAndClearDma3BusyFlags(0);
2020-03-08 18:24:22 +01:00
InitBgsFromTemplates(0, sInfoScreen_BgTemplate, ARRAY_COUNT(sInfoScreen_BgTemplate));
2018-05-01 02:41:17 +02:00
SetBgTilemapBuffer(3, AllocZeroed(0x800));
SetBgTilemapBuffer(2, AllocZeroed(0x800));
SetBgTilemapBuffer(1, AllocZeroed(0x800));
SetBgTilemapBuffer(0, AllocZeroed(0x800));
2019-11-20 00:54:00 +01:00
InitWindows(sInfoScreen_WindowTemplates);
2018-05-01 02:41:17 +02:00
DeactivateAllTextPrinters();
2018-08-19 01:06:10 +02:00
2018-05-01 02:41:17 +02:00
return taskId;
}
2020-03-08 18:24:22 +01:00
static bool8 IsInfoScreenScrolling(u8 taskId)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
if (gTasks[taskId].data[0] == 0 && gTasks[taskId].func == Task_HandleInfoScreenInput)
2018-05-01 02:41:17 +02:00
return FALSE;
else
return TRUE;
}
2020-03-08 18:24:22 +01:00
static u8 sub_80BE9F8(struct PokedexListItem *item, u8 taskId)
2018-05-01 02:41:17 +02:00
{
2018-12-03 15:58:25 +01:00
sPokedexListItem = item;
2020-03-08 18:24:22 +01:00
gTasks[taskId].data[0] = 1;
gTasks[taskId].data[1] = 0;
gTasks[taskId].data[2] = 0;
gTasks[taskId].data[3] = 0;
return taskId;
2018-05-01 02:41:17 +02:00
}
2020-03-08 18:24:22 +01:00
static void Task_LoadInfoScreen(u8 taskId)
2018-05-01 02:41:17 +02:00
{
switch (gMain.state)
{
2020-03-08 18:24:22 +01:00
case 0:
default:
if (!gPaletteFade.active)
{
u16 r2;
sPokedexView->currentPage = PAGE_INFO;
gPokedexVBlankCB = gMain.vblankCallback;
SetVBlankCallback(NULL);
r2 = 0;
if (gTasks[taskId].data[1] != 0)
r2 += DISPCNT_OBJ_ON;
if (gTasks[taskId].data[2] != 0)
r2 |= DISPCNT_BG1_ON;
ResetOtherVideoRegisters(r2);
gMain.state = 1;
}
break;
case 1:
DecompressAndLoadBgGfxUsingHeap(3, gPokedexMenu_Gfx, 0x2000, 0, 0);
CopyToBgTilemapBuffer(3, gPokedexInfoScreen_Tilemap, 0, 0);
FillWindowPixelBuffer(WIN_INFO, PIXEL_FILL(0));
PutWindowTilemap(WIN_INFO);
PutWindowTilemap(WIN_FOOTPRINT);
PrintFootprint(WIN_FOOTPRINT, sPokedexListItem->dexNum);
CopyWindowToVram(WIN_FOOTPRINT, 2);
gMain.state++;
break;
case 2:
LoadScreenSelectBarMain(0xD);
HighlightScreenSelectBarItem(sPokedexView->selectedScreen, 0xD);
LoadPokedexBgPalette(sPokedexView->isSearchResults);
gMain.state++;
break;
case 3:
gMain.state++;
break;
case 4:
PrintMonInfo(sPokedexListItem->dexNum, sPokedexView->dexMode == DEX_MODE_HOENN ? FALSE : TRUE, sPokedexListItem->owned, 0);
if (!sPokedexListItem->owned)
LoadPalette(gPlttBufferUnfaded + 1, 0x31, 0x1E);
CopyWindowToVram(WIN_INFO, 3);
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(3);
gMain.state++;
break;
case 5:
if (gTasks[taskId].data[1] == 0)
{
gTasks[taskId].tMonSpriteId = (u16)CreateMonSpriteFromNationalDexNumber(sPokedexListItem->dexNum, 48, 56, 0);
gSprites[gTasks[taskId].tMonSpriteId].oam.priority = 0;
}
gMain.state++;
break;
case 6:
{
u32 preservedPalettes = 0;
if (gTasks[taskId].data[2] != 0)
preservedPalettes = 0x14; // each bit represents a palette index
if (gTasks[taskId].data[1] != 0)
preservedPalettes |= (1 << (gSprites[gTasks[taskId].tMonSpriteId].oam.paletteNum + 16));
BeginNormalPaletteFade(~preservedPalettes, 0, 16, 0, RGB_BLACK);
SetVBlankCallback(gPokedexVBlankCB);
2018-05-01 02:41:17 +02:00
gMain.state++;
2020-03-08 18:24:22 +01:00
}
break;
case 7:
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
SetGpuReg(REG_OFFSET_BLDY, 0);
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON);
HideBg(0);
ShowBg(1);
ShowBg(2);
ShowBg(3);
gMain.state++;
break;
case 8:
if (!gPaletteFade.active)
{
2018-05-01 02:41:17 +02:00
gMain.state++;
2020-03-08 18:24:22 +01:00
if (gTasks[taskId].data[3] == 0)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
StopCryAndClearCrySongs();
PlayCry2(NationalPokedexNumToSpecies(sPokedexListItem->dexNum), 0, 0x7D, 0xA);
2018-05-01 02:41:17 +02:00
}
2020-03-08 18:24:22 +01:00
else
2018-05-01 02:41:17 +02:00
{
gMain.state++;
}
2020-03-08 18:24:22 +01:00
}
break;
case 9:
if (!IsCryPlayingOrClearCrySongs())
2018-05-01 02:41:17 +02:00
gMain.state++;
2020-03-08 18:24:22 +01:00
break;
case 10:
gTasks[taskId].data[0] = 0;
gTasks[taskId].data[1] = 0;
gTasks[taskId].data[2] = 1;
gTasks[taskId].data[3] = 1;
gTasks[taskId].func = Task_HandleInfoScreenInput;
gMain.state = 0;
break;
2018-05-01 02:41:17 +02:00
}
}
2020-03-08 18:24:22 +01:00
static void FreeInfoScreenWindowAndBgBuffers(void)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
void *tilemapBuffer;
2018-05-01 02:41:17 +02:00
FreeAllWindowBuffers();
2020-03-08 18:24:22 +01:00
tilemapBuffer = GetBgTilemapBuffer(0);
if (tilemapBuffer)
Free(tilemapBuffer);
tilemapBuffer = GetBgTilemapBuffer(1);
if (tilemapBuffer)
Free(tilemapBuffer);
tilemapBuffer = GetBgTilemapBuffer(2);
if (tilemapBuffer)
Free(tilemapBuffer);
tilemapBuffer = GetBgTilemapBuffer(3);
if (tilemapBuffer)
Free(tilemapBuffer);
}
static void Task_HandleInfoScreenInput(u8 taskId)
2018-05-01 02:41:17 +02:00
{
if (gTasks[taskId].data[0] != 0)
{
2020-03-08 18:24:22 +01:00
// Scroll up/down
2018-05-31 13:08:24 +02:00
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK);
2020-03-08 18:24:22 +01:00
gTasks[taskId].func = Task_LoadInfoScreenWaitForFade;
2018-05-01 02:41:17 +02:00
PlaySE(SE_Z_SCROLL);
return;
}
if (gMain.newKeys & B_BUTTON)
{
2018-05-31 13:08:24 +02:00
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK);
2020-03-08 18:24:22 +01:00
gTasks[taskId].func = Task_ExitInfoScreen;
2018-05-01 02:41:17 +02:00
PlaySE(SE_PC_OFF);
return;
}
if (gMain.newKeys & A_BUTTON)
{
2018-12-03 15:58:25 +01:00
switch (sPokedexView->selectedScreen)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
case AREA_SCREEN:
BeginNormalPaletteFade(0xFFFFFFEB, 0, 0, 16, RGB_BLACK);
sPokedexView->screenSwitchState = 1;
gTasks[taskId].func = Task_SwitchScreensFromInfoScreen;
PlaySE(SE_PIN);
break;
case CRY_SCREEN:
BeginNormalPaletteFade(0xFFFFFFEB, 0, 0, 0x10, RGB_BLACK);
sPokedexView->screenSwitchState = 2;
gTasks[taskId].func = Task_SwitchScreensFromInfoScreen;
PlaySE(SE_PIN);
break;
case SIZE_SCREEN:
if (!sPokedexListItem->owned)
{
PlaySE(SE_HAZURE);
}
else
{
2018-05-31 13:08:24 +02:00
BeginNormalPaletteFade(0xFFFFFFEB, 0, 0, 0x10, RGB_BLACK);
2020-03-08 18:24:22 +01:00
sPokedexView->screenSwitchState = 3;
gTasks[taskId].func = Task_SwitchScreensFromInfoScreen;
2018-05-10 09:30:42 +02:00
PlaySE(SE_PIN);
2020-03-08 18:24:22 +01:00
}
break;
case CANCEL_SCREEN:
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK);
gTasks[taskId].func = Task_ExitInfoScreen;
PlaySE(SE_PC_OFF);
break;
2018-05-01 02:41:17 +02:00
}
return;
}
if (((gMain.newKeys & DPAD_LEFT)
|| ((gMain.newKeys & L_BUTTON) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_LR))
2018-12-03 15:58:25 +01:00
&& sPokedexView->selectedScreen > 0)
2018-05-01 02:41:17 +02:00
{
2018-12-03 15:58:25 +01:00
sPokedexView->selectedScreen--;
2020-03-08 18:24:22 +01:00
HighlightScreenSelectBarItem(sPokedexView->selectedScreen, 0xD);
2018-05-01 02:41:17 +02:00
PlaySE(SE_Z_PAGE);
return;
}
if (((gMain.newKeys & DPAD_RIGHT)
|| ((gMain.newKeys & R_BUTTON) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_LR))
2020-03-08 18:24:22 +01:00
&& sPokedexView->selectedScreen < CANCEL_SCREEN)
2018-05-01 02:41:17 +02:00
{
2018-12-03 15:58:25 +01:00
sPokedexView->selectedScreen++;
2020-03-08 18:24:22 +01:00
HighlightScreenSelectBarItem(sPokedexView->selectedScreen, 0xD);
2018-05-01 02:41:17 +02:00
PlaySE(SE_Z_PAGE);
return;
}
}
2020-03-08 18:24:22 +01:00
static void Task_SwitchScreensFromInfoScreen(u8 taskId)
2018-05-01 02:41:17 +02:00
{
if (!gPaletteFade.active)
{
2019-11-20 00:54:00 +01:00
FreeAndDestroyMonPicSprite(gTasks[taskId].tMonSpriteId);
2020-03-08 18:24:22 +01:00
switch (sPokedexView->screenSwitchState)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
case 1:
default:
gTasks[taskId].func = Task_LoadAreaScreen;
break;
case 2:
gTasks[taskId].func = Task_LoadCryScreen;
break;
case 3:
gTasks[taskId].func = Task_LoadSizeScreen;
break;
2018-05-01 02:41:17 +02:00
}
}
}
2020-03-08 18:24:22 +01:00
static void Task_LoadInfoScreenWaitForFade(u8 taskId)
2018-05-01 02:41:17 +02:00
{
if (!gPaletteFade.active)
{
2019-11-20 00:54:00 +01:00
FreeAndDestroyMonPicSprite(gTasks[taskId].tMonSpriteId);
2020-03-08 18:24:22 +01:00
gTasks[taskId].func = Task_LoadInfoScreen;
2018-05-01 02:41:17 +02:00
}
}
2020-03-08 18:24:22 +01:00
static void Task_ExitInfoScreen(u8 taskId)
2018-05-01 02:41:17 +02:00
{
if (!gPaletteFade.active)
{
2019-11-20 00:54:00 +01:00
FreeAndDestroyMonPicSprite(gTasks[taskId].tMonSpriteId);
2020-03-08 18:24:22 +01:00
FreeInfoScreenWindowAndBgBuffers();
2018-05-01 02:41:17 +02:00
DestroyTask(taskId);
}
}
2020-03-08 18:24:22 +01:00
static void Task_LoadAreaScreen(u8 taskId)
2018-05-01 02:41:17 +02:00
{
switch (gMain.state)
{
2020-03-08 18:24:22 +01:00
case 0:
default:
if (!gPaletteFade.active)
{
sPokedexView->currentPage = PAGE_AREA;
gPokedexVBlankCB = gMain.vblankCallback;
SetVBlankCallback(NULL);
ResetOtherVideoRegisters(DISPCNT_BG1_ON);
sPokedexView->selectedScreen = AREA_SCREEN;
gMain.state = 1;
}
break;
case 1:
LoadScreenSelectBarSubmenu(0xD);
HighlightSubmenuScreenSelectBarItem(0, 0xD);
LoadPokedexBgPalette(sPokedexView->isSearchResults);
SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_SCREENBASE(13) | BGCNT_16COLOR | BGCNT_TXT256x256);
gMain.state++;
break;
case 2:
ShowPokedexAreaScreen(NationalPokedexNumToSpecies(sPokedexListItem->dexNum), &sPokedexView->screenSwitchState);
SetVBlankCallback(gPokedexVBlankCB);
sPokedexView->screenSwitchState = 0;
gMain.state = 0;
gTasks[taskId].func = Task_WaitForAreaScreenInput;
break;
2018-05-01 02:41:17 +02:00
}
}
2020-03-08 18:24:22 +01:00
static void Task_WaitForAreaScreenInput(u8 taskId)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
// See Task_HandlePokedexAreaScreenInput() in pokedex_area_screen.c
if (sPokedexView->screenSwitchState != 0)
gTasks[taskId].func = Task_SwitchScreensFromAreaScreen;
2018-05-01 02:41:17 +02:00
}
2020-03-08 18:24:22 +01:00
static void Task_SwitchScreensFromAreaScreen(u8 taskId)
2018-05-01 02:41:17 +02:00
{
if (!gPaletteFade.active)
{
2020-03-08 18:24:22 +01:00
switch (sPokedexView->screenSwitchState)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
case 1:
default:
gTasks[taskId].func = Task_LoadInfoScreen;
break;
case 2:
gTasks[taskId].func = Task_LoadCryScreen;
break;
2018-05-01 02:41:17 +02:00
}
}
}
2020-03-08 18:24:22 +01:00
static void Task_LoadCryScreen(u8 taskId)
2018-05-01 02:41:17 +02:00
{
switch (gMain.state)
{
2020-03-08 18:24:22 +01:00
case 0:
default:
if (!gPaletteFade.active)
{
m4aMPlayStop(&gMPlayInfo_BGM);
sPokedexView->currentPage = PAGE_CRY;
gPokedexVBlankCB = gMain.vblankCallback;
SetVBlankCallback(NULL);
ResetOtherVideoRegisters(DISPCNT_BG1_ON);
sPokedexView->selectedScreen = CRY_SCREEN;
gMain.state = 1;
}
break;
case 1:
DecompressAndLoadBgGfxUsingHeap(3, &gPokedexMenu_Gfx, 0x2000, 0, 0);
CopyToBgTilemapBuffer(3, &gPokedexCryScreen_Tilemap, 0, 0);
FillWindowPixelBuffer(WIN_INFO, PIXEL_FILL(0));
PutWindowTilemap(WIN_INFO);
PutWindowTilemap(WIN_VU_METER);
PutWindowTilemap(WIN_CRY_WAVE);
gMain.state++;
break;
case 2:
LoadScreenSelectBarSubmenu(0xD);
HighlightSubmenuScreenSelectBarItem(1, 0xD);
LoadPokedexBgPalette(sPokedexView->isSearchResults);
gMain.state++;
break;
case 3:
ResetPaletteFade();
gMain.state++;
break;
case 4:
PrintInfoScreenText(gText_CryOf, 82, 33);
PrintCryScreenSpeciesName(0, sPokedexListItem->dexNum, 82, 49);
gMain.state++;
break;
case 5:
gTasks[taskId].tMonSpriteId = CreateMonSpriteFromNationalDexNumber(sPokedexListItem->dexNum, 48, 56, 0);
gSprites[gTasks[taskId].tMonSpriteId].oam.priority = 0;
gDexCryScreenState = 0;
gMain.state++;
break;
case 6:
{
2020-03-10 19:02:03 +01:00
struct CryScreenWindow waveformWindow;
waveformWindow.unk0 = 0x4020;
waveformWindow.unk2 = 31;
waveformWindow.paletteNo = 8;
waveformWindow.yPos = 30;
waveformWindow.xPos = 12;
if (LoadCryWaveformWindow(&waveformWindow, 2))
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
gMain.state++;
gDexCryScreenState = 0;
2018-05-01 02:41:17 +02:00
}
2020-03-08 18:24:22 +01:00
}
break;
case 7:
{
2020-03-10 19:02:03 +01:00
struct CryScreenWindow cryMeter;
2020-03-08 18:24:22 +01:00
2020-03-10 19:02:03 +01:00
cryMeter.paletteNo = 9;
cryMeter.xPos = 18;
cryMeter.yPos = 3;
if (LoadCryMeter(&cryMeter, 3))
2020-03-08 18:24:22 +01:00
gMain.state++;
CopyWindowToVram(WIN_VU_METER, 2);
CopyWindowToVram(WIN_INFO, 3);
CopyBgTilemapBufferToVram(0);
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(3);
}
break;
case 8:
BeginNormalPaletteFade(0xFFFFFFEB, 0, 0x10, 0, RGB_BLACK);
SetVBlankCallback(gPokedexVBlankCB);
gMain.state++;
break;
case 9:
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
SetGpuReg(REG_OFFSET_BLDY, 0);
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON);
ShowBg(0);
ShowBg(1);
ShowBg(2);
ShowBg(3);
gMain.state++;
break;
case 10:
sPokedexView->screenSwitchState = 0;
gMain.state = 0;
gTasks[taskId].func = Task_HandleCryScreenInput;
break;
2018-05-01 02:41:17 +02:00
}
}
2020-03-08 18:24:22 +01:00
static void Task_HandleCryScreenInput(u8 taskId)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
UpdateCryWaveformWindow(2);
2018-05-01 02:41:17 +02:00
if (IsCryPlaying())
2020-03-08 18:24:22 +01:00
LoadPlayArrowPalette(TRUE);
2018-05-01 02:41:17 +02:00
else
2020-03-08 18:24:22 +01:00
LoadPlayArrowPalette(FALSE);
2018-05-01 02:41:17 +02:00
if (gMain.newKeys & A_BUTTON)
{
2020-03-08 18:24:22 +01:00
LoadPlayArrowPalette(TRUE);
CryScreenPlayButton(NationalPokedexNumToSpecies(sPokedexListItem->dexNum));
2018-05-01 02:41:17 +02:00
return;
}
else if (!gPaletteFade.active)
{
if (gMain.newKeys & B_BUTTON)
{
2018-05-31 13:08:24 +02:00
BeginNormalPaletteFade(0xFFFFFFEB, 0, 0, 0x10, RGB_BLACK);
2018-05-01 02:41:17 +02:00
m4aMPlayContinue(&gMPlayInfo_BGM);
2020-03-08 18:24:22 +01:00
sPokedexView->screenSwitchState = 1;
gTasks[taskId].func = Task_SwitchScreensFromCryScreen;
2018-05-01 02:41:17 +02:00
PlaySE(SE_PC_OFF);
return;
}
if ((gMain.newKeys & DPAD_LEFT)
|| ((gMain.newKeys & L_BUTTON) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_LR))
{
2018-05-31 13:08:24 +02:00
BeginNormalPaletteFade(0xFFFFFFEB, 0, 0, 0x10, RGB_BLACK);
2018-05-01 02:41:17 +02:00
m4aMPlayContinue(&gMPlayInfo_BGM);
2020-03-08 18:24:22 +01:00
sPokedexView->screenSwitchState = 2;
gTasks[taskId].func = Task_SwitchScreensFromCryScreen;
2018-05-01 02:41:17 +02:00
PlaySE(SE_Z_PAGE);
return;
}
if ((gMain.newKeys & DPAD_RIGHT)
|| ((gMain.newKeys & R_BUTTON) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_LR))
{
2018-12-03 15:58:25 +01:00
if (!sPokedexListItem->owned)
2018-05-01 02:41:17 +02:00
{
PlaySE(SE_HAZURE);
}
else
{
2018-05-31 13:08:24 +02:00
BeginNormalPaletteFade(0xFFFFFFEB, 0, 0, 0x10, RGB_BLACK);
2018-05-01 02:41:17 +02:00
m4aMPlayContinue(&gMPlayInfo_BGM);
2020-03-08 18:24:22 +01:00
sPokedexView->screenSwitchState = 3;
gTasks[taskId].func = Task_SwitchScreensFromCryScreen;
2018-05-01 02:41:17 +02:00
PlaySE(SE_Z_PAGE);
}
return;
}
}
}
2020-03-08 18:24:22 +01:00
static void Task_SwitchScreensFromCryScreen(u8 taskId)
2018-05-01 02:41:17 +02:00
{
if (!gPaletteFade.active)
{
2020-03-08 18:24:22 +01:00
FreeCryScreen();
2019-11-20 00:54:00 +01:00
FreeAndDestroyMonPicSprite(gTasks[taskId].tMonSpriteId);
2020-03-08 18:24:22 +01:00
switch (sPokedexView->screenSwitchState)
2018-05-01 02:41:17 +02:00
{
2018-05-10 09:30:42 +02:00
default:
case 1:
2020-03-08 18:24:22 +01:00
gTasks[taskId].func = Task_LoadInfoScreen;
2018-05-10 09:30:42 +02:00
break;
2020-03-08 18:24:22 +01:00
case 2:
gTasks[taskId].func = Task_LoadAreaScreen;
2018-05-10 09:30:42 +02:00
break;
2020-03-08 18:24:22 +01:00
case 3:
gTasks[taskId].func = Task_LoadSizeScreen;
2018-05-10 09:30:42 +02:00
break;
2020-03-08 18:24:22 +01:00
}
}
}
static void LoadPlayArrowPalette(bool8 cryPlaying)
{
u16 color;
if (cryPlaying)
color = RGB(18, 28, 0);
else
color = RGB(15, 21, 0);
LoadPalette(&color, 0x5D, 2);
}
static void Task_LoadSizeScreen(u8 taskId)
{
u8 spriteId;
switch (gMain.state)
{
default:
case 0:
if (!gPaletteFade.active)
{
sPokedexView->currentPage = PAGE_SIZE;
gPokedexVBlankCB = gMain.vblankCallback;
SetVBlankCallback(NULL);
ResetOtherVideoRegisters(DISPCNT_BG1_ON);
sPokedexView->selectedScreen = SIZE_SCREEN;
gMain.state = 1;
}
break;
case 1:
DecompressAndLoadBgGfxUsingHeap(3, gPokedexMenu_Gfx, 0x2000, 0, 0);
CopyToBgTilemapBuffer(3, gPokedexSizeScreen_Tilemap, 0, 0);
FillWindowPixelBuffer(WIN_INFO, PIXEL_FILL(0));
PutWindowTilemap(WIN_INFO);
gMain.state++;
break;
case 2:
LoadScreenSelectBarSubmenu(0xD);
HighlightSubmenuScreenSelectBarItem(2, 0xD);
LoadPokedexBgPalette(sPokedexView->isSearchResults);
gMain.state++;
break;
case 3:
{
u8 string[64];
StringCopy(string, gText_SizeComparedTo);
StringAppend(string, gSaveBlock2Ptr->playerName);
PrintInfoScreenText(string, GetStringCenterAlignXOffset(1, string, 0xF0), 0x79);
gMain.state++;
}
break;
case 4:
ResetPaletteFade();
gMain.state++;
break;
case 5:
spriteId = CreateSizeScreenTrainerPic(PlayerGenderToFrontTrainerPicId(gSaveBlock2Ptr->playerGender), 152, 56, 0);
gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL;
gSprites[spriteId].oam.matrixNum = 1;
gSprites[spriteId].oam.priority = 0;
gSprites[spriteId].pos2.y = gPokedexEntries[sPokedexListItem->dexNum].trainerOffset;
SetOamMatrix(1, gPokedexEntries[sPokedexListItem->dexNum].trainerScale, 0, 0, gPokedexEntries[sPokedexListItem->dexNum].trainerScale);
LoadPalette(sSizeScreenSilhouette_Pal, (gSprites[spriteId].oam.paletteNum + 16) * 16, 0x20);
gTasks[taskId].data[5] = spriteId;
gMain.state++;
break;
case 6:
spriteId = CreateMonSpriteFromNationalDexNumber(sPokedexListItem->dexNum, 88, 56, 1);
gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_NORMAL;
gSprites[spriteId].oam.matrixNum = 2;
gSprites[spriteId].oam.priority = 0;
gSprites[spriteId].pos2.y = gPokedexEntries[sPokedexListItem->dexNum].pokemonOffset;
SetOamMatrix(2, gPokedexEntries[sPokedexListItem->dexNum].pokemonScale, 0, 0, gPokedexEntries[sPokedexListItem->dexNum].pokemonScale);
LoadPalette(sSizeScreenSilhouette_Pal, (gSprites[spriteId].oam.paletteNum + 16) * 16, 0x20);
gTasks[taskId].tMonSpriteId = spriteId;
CopyWindowToVram(WIN_INFO, 3);
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(3);
gMain.state++;
break;
case 7:
BeginNormalPaletteFade(0xFFFFFFEB, 0, 0x10, 0, RGB_BLACK);
SetVBlankCallback(gPokedexVBlankCB);
gMain.state++;
break;
case 8:
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
SetGpuReg(REG_OFFSET_BLDY, 0);
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON);
HideBg(0);
ShowBg(1);
ShowBg(2);
ShowBg(3);
gMain.state++;
break;
case 9:
if (!gPaletteFade.active)
{
sPokedexView->screenSwitchState = 0;
gMain.state = 0;
gTasks[taskId].func = Task_HandleSizeScreenInput;
}
break;
2018-05-01 02:41:17 +02:00
}
}
2020-03-08 18:24:22 +01:00
static void Task_HandleSizeScreenInput(u8 taskId)
2018-05-01 02:41:17 +02:00
{
if (gMain.newKeys & B_BUTTON)
{
2018-05-31 13:08:24 +02:00
BeginNormalPaletteFade(0xFFFFFFEB, 0, 0, 0x10, RGB_BLACK);
2020-03-08 18:24:22 +01:00
sPokedexView->screenSwitchState = 1;
gTasks[taskId].func = Task_SwitchScreensFromSizeScreen;
2018-05-01 02:41:17 +02:00
PlaySE(SE_PC_OFF);
}
else if ((gMain.newKeys & DPAD_LEFT)
|| ((gMain.newKeys & L_BUTTON) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_LR))
{
2018-05-31 13:08:24 +02:00
BeginNormalPaletteFade(0xFFFFFFEB, 0, 0, 0x10, RGB_BLACK);
2020-03-08 18:24:22 +01:00
sPokedexView->screenSwitchState = 2;
gTasks[taskId].func = Task_SwitchScreensFromSizeScreen;
2018-05-01 02:41:17 +02:00
PlaySE(SE_Z_PAGE);
}
}
2020-03-08 18:24:22 +01:00
static void Task_SwitchScreensFromSizeScreen(u8 taskId)
2018-05-01 02:41:17 +02:00
{
if (!gPaletteFade.active)
{
2019-11-20 00:54:00 +01:00
FreeAndDestroyMonPicSprite(gTasks[taskId].tMonSpriteId);
2018-08-19 01:06:10 +02:00
FreeAndDestroyTrainerPicSprite(gTasks[taskId].data[5]);
2020-03-08 18:24:22 +01:00
switch (sPokedexView->screenSwitchState)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
default:
case 1:
gTasks[taskId].func = Task_LoadInfoScreen;
break;
case 2:
gTasks[taskId].func = Task_LoadCryScreen;
break;
2018-05-01 02:41:17 +02:00
}
}
}
2020-03-08 18:24:22 +01:00
#undef tMonSpriteId
static void LoadScreenSelectBarMain(u16 unused)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
CopyToBgTilemapBuffer(1, gPokedexScreenSelectBarMain_Tilemap, 0, 0);
2018-05-01 02:41:17 +02:00
}
2020-03-08 18:24:22 +01:00
static void LoadScreenSelectBarSubmenu(u16 unused)
2018-05-01 02:41:17 +02:00
{
2020-03-08 18:24:22 +01:00
CopyToBgTilemapBuffer(1, gPokedexScreenSelectBarSubmenu_Tilemap, 0, 0);
2018-05-01 02:41:17 +02:00
}
2020-04-01 19:03:25 +02:00
2020-03-08 18:24:22 +01:00
static void HighlightScreenSelectBarItem(u8 selectedScreen, u16 unused)
2018-05-01 02:41:17 +02:00
{
u8 i;
u8 j;
2018-05-10 09:30:42 +02:00
u16* ptr = GetBgTilemapBuffer(1);
2020-03-08 18:24:22 +01:00
for (i = 0; i < SCREEN_COUNT; i++)
2018-05-01 02:41:17 +02:00
{
2018-05-10 09:30:42 +02:00
u8 row = (i * 7) + 1;
2020-04-02 14:30:31 +02:00
u16 newPalette;
2018-05-10 09:30:42 +02:00
2020-04-02 14:30:31 +02:00
do
{
newPalette = 0x4000;
if (i == selectedScreen)
newPalette = 0x2000;
} while (0);
2018-05-10 09:30:42 +02:00
for (j = 0; j < 7; j++)
{
ptr[row + j] = (ptr[row + j] % 0x1000) | newPalette;
ptr[row + j + 0x20] = (ptr[row + j + 0x20] % 0x1000) | newPalette;
}
}
CopyBgTilemapBufferToVram(1);
}
2020-03-08 18:24:22 +01:00
static void HighlightSubmenuScreenSelectBarItem(u8 a, u16 b)
2018-05-10 09:30:42 +02:00
{
u8 i;
u8 j;
u16* ptr = GetBgTilemapBuffer(1);
for (i = 0; i < 4; i++)
{
u8 row = i * 7 + 1;
u32 newPalette;
do
2020-04-01 19:03:36 +02:00
{
if (i == a || i == 3)
newPalette = 0x2000;
else
newPalette = 0x4000;
} while (0);
2018-05-10 09:30:42 +02:00
2018-05-01 02:41:17 +02:00
for (j = 0; j < 7; j++)
{
2018-05-10 09:30:42 +02:00
ptr[row + j] = (ptr[row + j] % 0x1000) | newPalette;
ptr[row + j + 0x20] = (ptr[row + j + 0x20] % 0x1000) | newPalette;
2018-05-01 02:41:17 +02:00
}
}
CopyBgTilemapBufferToVram(1);
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
#define tState data[0]
#define tDexNum data[1]
#define tPalTimer data[2]
#define tMonSpriteId data[3]
#define tOtIdLo data[12]
#define tOtIdHi data[13]
#define tPersonalityLo data[14]
#define tPersonalityHi data[15]
u8 DisplayCaughtMonDexPage(u16 dexNum, u32 otId, u32 personality)
{
u8 taskId = CreateTask(Task_DisplayCaughtMonDexPage, 0);
gTasks[taskId].tState = 0;
gTasks[taskId].tDexNum = dexNum;
gTasks[taskId].tOtIdLo = otId;
gTasks[taskId].tOtIdHi = otId >> 16;
gTasks[taskId].tPersonalityLo = personality;
gTasks[taskId].tPersonalityHi = personality >> 16;
2018-05-10 09:30:42 +02:00
return taskId;
}
2020-03-08 18:24:22 +01:00
static void Task_DisplayCaughtMonDexPage(u8 taskId)
2018-05-10 09:30:42 +02:00
{
u8 spriteId;
2020-03-08 18:24:22 +01:00
u16 dexNum = gTasks[taskId].tDexNum;
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
switch (gTasks[taskId].tState)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
case 0:
default:
if (!gPaletteFade.active)
{
gPokedexVBlankCB = gMain.vblankCallback;
SetVBlankCallback(NULL);
ResetOtherVideoRegisters(DISPCNT_BG0_ON);
ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, sNewEntryInfoScreen_BgTemplate, ARRAY_COUNT(sNewEntryInfoScreen_BgTemplate));
SetBgTilemapBuffer(3, AllocZeroed(0x800));
SetBgTilemapBuffer(2, AllocZeroed(0x800));
InitWindows(sNewEntryInfoScreen_WindowTemplates);
DeactivateAllTextPrinters();
gTasks[taskId].tState = 1;
}
break;
case 1:
DecompressAndLoadBgGfxUsingHeap(3, gPokedexMenu_Gfx, 0x2000, 0, 0);
CopyToBgTilemapBuffer(3, gPokedexInfoScreen_Tilemap, 0, 0);
FillWindowPixelBuffer(WIN_INFO, PIXEL_FILL(0));
PutWindowTilemap(WIN_INFO);
PutWindowTilemap(WIN_FOOTPRINT);
PrintFootprint(WIN_FOOTPRINT, gTasks[taskId].tDexNum);
CopyWindowToVram(WIN_FOOTPRINT, 2);
ResetPaletteFade();
LoadPokedexBgPalette(FALSE);
gTasks[taskId].tState++;
break;
case 2:
gTasks[taskId].tState++;
break;
case 3:
PrintMonInfo(dexNum, IsNationalPokedexEnabled(), 1, 1);
CopyWindowToVram(WIN_INFO, 3);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(3);
gTasks[taskId].tState++;
break;
case 4:
spriteId = CreateMonSpriteFromNationalDexNumber(dexNum, 48, 56, 0);
gSprites[spriteId].oam.priority = 0;
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, RGB_BLACK);
SetVBlankCallback(gPokedexVBlankCB);
gTasks[taskId].tMonSpriteId = spriteId;
gTasks[taskId].tState++;
break;
case 5:
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
SetGpuReg(REG_OFFSET_BLDY, 0);
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON);
ShowBg(2);
ShowBg(3);
gTasks[taskId].tState++;
break;
case 6:
if (!gPaletteFade.active)
{
PlayCry1(NationalPokedexNumToSpecies(dexNum), 0);
gTasks[taskId].tPalTimer = 0;
gTasks[taskId].func = Task_HandleCaughtMonPageInput;
}
break;
2018-05-10 09:30:42 +02:00
}
}
2020-03-08 18:24:22 +01:00
static void Task_HandleCaughtMonPageInput(u8 taskId)
2018-05-10 09:30:42 +02:00
{
if (gMain.newKeys & (A_BUTTON | B_BUTTON))
{
BeginNormalPaletteFade(0x0000FFFF, 0, 0, 16, RGB_BLACK);
2020-03-08 18:24:22 +01:00
gSprites[gTasks[taskId].tMonSpriteId].callback = SpriteCB_SlideCaughtMonToCenter;
gTasks[taskId].func = Task_ExitCaughtMonPage;
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
// Flicker caught screen color
else if (++gTasks[taskId].tPalTimer & 16)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
LoadPalette(gPokedexBgHoenn_Pal + 1, 0x31, 14);
2018-05-10 09:30:42 +02:00
}
else
{
2020-03-08 18:24:22 +01:00
LoadPalette(gPokedexCaughtScreen_Pal + 1, 0x31, 14);
2018-05-10 09:30:42 +02:00
}
}
2020-03-08 18:24:22 +01:00
static void Task_ExitCaughtMonPage(u8 taskId)
2018-05-10 09:30:42 +02:00
{
if (!gPaletteFade.active)
{
u16 species;
u32 otId;
u32 personality;
u8 paletteNum;
2018-10-21 09:24:57 +02:00
const u32 *lzPaletteData;
2018-05-10 09:30:42 +02:00
void *buffer;
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON);
FreeAllWindowBuffers();
buffer = GetBgTilemapBuffer(2);
if (buffer)
Free(buffer);
buffer = GetBgTilemapBuffer(3);
if (buffer)
Free(buffer);
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
species = NationalPokedexNumToSpecies(gTasks[taskId].tDexNum);
otId = ((u16)gTasks[taskId].tOtIdHi << 16) | (u16)gTasks[taskId].tOtIdLo;
personality = ((u16)gTasks[taskId].tPersonalityHi << 16) | (u16)gTasks[taskId].tPersonalityLo;
paletteNum = gSprites[gTasks[taskId].tMonSpriteId].oam.paletteNum;
2019-07-25 18:56:08 +02:00
lzPaletteData = GetMonSpritePalFromSpeciesAndPersonality(species, otId, personality);
2018-05-10 09:30:42 +02:00
LoadCompressedPalette(lzPaletteData, 0x100 | paletteNum * 16, 32);
DestroyTask(taskId);
}
}
2020-03-08 18:24:22 +01:00
static void SpriteCB_SlideCaughtMonToCenter(struct Sprite *sprite)
2018-05-10 09:30:42 +02:00
{
if (sprite->pos1.x < 0x78)
sprite->pos1.x += 2;
if (sprite->pos1.x > 0x78)
sprite->pos1.x -= 2;
if (sprite->pos1.y < 0x50)
sprite->pos1.y += 1;
if (sprite->pos1.y > 0x50)
sprite->pos1.y -= 1;
}
2020-03-08 18:24:22 +01:00
#undef tState
#undef tDexNum
#undef tPalTimer
#undef tMonSpriteId
#undef tOtIdLo
#undef tOtIdHi
#undef tPersonalityLo
#undef tPersonalityHi
// u32 value is re-used, but passed as a bool that's TRUE if national dex is enabled
2019-12-06 03:20:18 +01:00
static void PrintMonInfo(u32 num, u32 value, u32 owned, u32 newEntry)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
u8 str[16];
u8 str2[32];
2018-05-10 09:30:42 +02:00
u16 natNum;
2020-03-08 18:24:22 +01:00
const u8 *name;
const u8 *category;
const u8 *description;
2018-08-19 01:06:10 +02:00
2019-12-06 03:20:18 +01:00
if (newEntry)
2020-03-08 18:24:22 +01:00
PrintInfoScreenText(gText_PokedexRegistration, GetStringCenterAlignXOffset(1, gText_PokedexRegistration, 0xF0), 0);
2018-07-08 02:20:01 +02:00
if (value == 0)
value = NationalToHoennOrder(num);
2018-05-10 09:30:42 +02:00
else
2018-07-08 02:20:01 +02:00
value = num;
2019-12-10 19:48:20 +01:00
ConvertIntToDecimalStringN(StringCopy(str, gText_NumberClear01), value, STR_CONV_MODE_LEADING_ZEROS, 3);
2020-03-08 18:24:22 +01:00
PrintInfoScreenText(str, 0x60, 0x19);
2018-05-10 09:30:42 +02:00
natNum = NationalPokedexNumToSpecies(num);
if (natNum)
2020-03-08 18:24:22 +01:00
name = gSpeciesNames[natNum];
2018-05-10 09:30:42 +02:00
else
2020-03-08 18:24:22 +01:00
name = sText_TenDashes2;
PrintInfoScreenText(name, 0x84, 0x19);
2019-12-06 03:20:18 +01:00
if (owned)
2018-05-10 09:30:42 +02:00
{
CopyMonCategoryText(num, str2);
2020-03-08 18:24:22 +01:00
category = str2;
2018-05-10 09:30:42 +02:00
}
else
{
2020-03-08 18:24:22 +01:00
category = gText_5MarksPokemon;
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
PrintInfoScreenText(category, 0x64, 0x29);
PrintInfoScreenText(gText_HTHeight, 0x60, 0x39);
PrintInfoScreenText(gText_WTWeight, 0x60, 0x49);
2019-12-06 03:20:18 +01:00
if (owned)
2018-05-10 09:30:42 +02:00
{
2019-12-06 03:20:18 +01:00
PrintMonHeight(gPokedexEntries[num].height, 0x81, 0x39);
PrintMonWeight(gPokedexEntries[num].weight, 0x81, 0x49);
2018-05-10 09:30:42 +02:00
}
else
{
2020-03-08 18:24:22 +01:00
PrintInfoScreenText(gText_UnkHeight, 0x81, 0x39);
PrintInfoScreenText(gText_UnkWeight, 0x81, 0x49);
2018-05-10 09:30:42 +02:00
}
2019-12-06 03:20:18 +01:00
if (owned)
2020-03-08 18:24:22 +01:00
description = gPokedexEntries[num].description;
2018-05-10 09:30:42 +02:00
else
2020-03-08 18:24:22 +01:00
description = gExpandedPlaceholder_PokedexDescription;
PrintInfoScreenText(description, GetStringCenterAlignXOffset(1, description, 0xF0), 0x5F);
2018-05-10 09:30:42 +02:00
}
2019-12-06 03:20:18 +01:00
static void PrintMonHeight(u16 height, u8 left, u8 top)
2018-05-10 09:30:42 +02:00
{
u8 buffer[16];
u32 inches, feet;
u8 i = 0;
inches = (height * 10000) / 254;
if (inches % 10 >= 5)
inches += 10;
feet = inches / 120;
inches = (inches - (feet * 120)) / 10;
buffer[i++] = EXT_CTRL_CODE_BEGIN;
buffer[i++] = 0x13;
if (feet / 10 == 0)
{
buffer[i++] = 18;
buffer[i++] = feet + CHAR_0;
}
else
{
buffer[i++] = 12;
buffer[i++] = feet / 10 + CHAR_0;
buffer[i++] = (feet % 10) + CHAR_0;
}
2019-04-11 12:05:56 +02:00
buffer[i++] = CHAR_SGL_QUOT_RIGHT;
2018-05-10 09:30:42 +02:00
buffer[i++] = (inches / 10) + CHAR_0;
buffer[i++] = (inches % 10) + CHAR_0;
2019-04-11 12:05:56 +02:00
buffer[i++] = CHAR_DBL_QUOT_RIGHT;
2018-05-10 09:30:42 +02:00
buffer[i++] = EOS;
2020-03-08 18:24:22 +01:00
PrintInfoScreenText(buffer, left, top);
2018-05-10 09:30:42 +02:00
}
2019-12-06 03:20:18 +01:00
static void PrintMonWeight(u16 weight, u8 left, u8 top)
2018-05-10 09:30:42 +02:00
{
2020-04-01 19:30:18 +02:00
#ifndef NONMATCHING
asm("":::"r9");
{
#endif
2018-05-10 09:30:42 +02:00
u8 buffer[16];
bool8 output;
2019-04-11 12:05:56 +02:00
u8 i = 0;
u32 lbs = (weight * 100000) / 4536;
2018-05-10 09:30:42 +02:00
2019-04-11 12:05:56 +02:00
if (lbs % 10u >= 5)
2018-05-10 09:30:42 +02:00
lbs += 10;
output = FALSE;
buffer[i] = (lbs / 100000) + CHAR_0;
if (buffer[i] == CHAR_0)
{
buffer[i++] = 0x77;
}
else
{
output = TRUE;
i++;
}
2019-04-11 12:05:56 +02:00
lbs %= 100000;
2018-05-10 09:30:42 +02:00
buffer[i] = (lbs / 10000) + CHAR_0;
2019-04-11 12:05:56 +02:00
if (buffer[i] == CHAR_0 && !output)
2018-05-10 09:30:42 +02:00
{
buffer[i++] = 0x77;
}
else
{
output = TRUE;
i++;
}
2019-04-11 12:05:56 +02:00
lbs %= 10000;
2018-05-10 09:30:42 +02:00
buffer[i] = (lbs / 1000) + CHAR_0;
2019-04-11 12:05:56 +02:00
if (buffer[i] == CHAR_0 && !output)
2018-05-10 09:30:42 +02:00
{
buffer[i++] = 0x77;
}
else
{
i++;
}
2019-04-11 12:05:56 +02:00
lbs %= 1000;
2018-05-10 09:30:42 +02:00
buffer[i++] = (lbs / 100) + CHAR_0;
2019-04-11 12:05:56 +02:00
lbs %= 100;
2018-05-10 09:30:42 +02:00
buffer[i++] = CHAR_PERIOD;
buffer[i++] = (lbs / 10) + CHAR_0;
buffer[i++] = CHAR_SPACE;
buffer[i++] = CHAR_l;
buffer[i++] = CHAR_b;
buffer[i++] = CHAR_s;
buffer[i++] = CHAR_PERIOD;
buffer[i++] = EOS;
2020-03-08 18:24:22 +01:00
PrintInfoScreenText(buffer, left, top);
2020-04-01 19:30:18 +02:00
#ifndef NONMATCHING
2018-05-10 09:30:42 +02:00
}
#endif
2020-04-01 19:30:18 +02:00
}
2018-05-10 09:30:42 +02:00
2019-12-06 03:20:18 +01:00
const u8 *GetPokedexCategoryName(u16 dexNum) // unused
2018-05-10 09:30:42 +02:00
{
return gPokedexEntries[dexNum].categoryName;
}
u16 GetPokedexHeightWeight(u16 dexNum, u8 data)
{
switch (data)
{
case 0: // height
return gPokedexEntries[dexNum].height;
case 1: // weight
return gPokedexEntries[dexNum].weight;
default:
return 1;
2018-05-10 09:30:42 +02:00
}
}
s8 GetSetPokedexFlag(u16 nationalDexNo, u8 caseID)
{
u8 index;
u8 bit;
u8 mask;
s8 retVal;
nationalDexNo--;
index = nationalDexNo / 8;
bit = nationalDexNo % 8;
mask = 1 << bit;
retVal = 0;
switch (caseID)
{
2019-01-19 23:04:33 +01:00
case FLAG_GET_SEEN:
if (gSaveBlock2Ptr->pokedex.seen[index] & mask)
{
if ((gSaveBlock2Ptr->pokedex.seen[index] & mask) == (gSaveBlock1Ptr->seen1[index] & mask)
&& (gSaveBlock2Ptr->pokedex.seen[index] & mask) == (gSaveBlock1Ptr->seen2[index] & mask))
retVal = 1;
else
2018-05-10 09:30:42 +02:00
{
2019-01-19 23:04:33 +01:00
gSaveBlock2Ptr->pokedex.seen[index] &= ~mask;
gSaveBlock1Ptr->seen1[index] &= ~mask;
gSaveBlock1Ptr->seen2[index] &= ~mask;
retVal = 0;
2018-05-10 09:30:42 +02:00
}
2019-01-19 23:04:33 +01:00
}
break;
case FLAG_GET_CAUGHT:
if (gSaveBlock2Ptr->pokedex.owned[index] & mask)
{
if ((gSaveBlock2Ptr->pokedex.owned[index] & mask) == (gSaveBlock2Ptr->pokedex.seen[index] & mask)
&& (gSaveBlock2Ptr->pokedex.owned[index] & mask) == (gSaveBlock1Ptr->seen1[index] & mask)
&& (gSaveBlock2Ptr->pokedex.owned[index] & mask) == (gSaveBlock1Ptr->seen2[index] & mask))
retVal = 1;
else
2018-05-10 09:30:42 +02:00
{
2019-01-19 23:04:33 +01:00
gSaveBlock2Ptr->pokedex.owned[index] &= ~mask;
gSaveBlock2Ptr->pokedex.seen[index] &= ~mask;
gSaveBlock1Ptr->seen1[index] &= ~mask;
gSaveBlock1Ptr->seen2[index] &= ~mask;
retVal = 0;
2018-05-10 09:30:42 +02:00
}
2019-01-19 23:04:33 +01:00
}
break;
case FLAG_SET_SEEN:
gSaveBlock2Ptr->pokedex.seen[index] |= mask;
gSaveBlock1Ptr->seen1[index] |= mask;
gSaveBlock1Ptr->seen2[index] |= mask;
break;
case FLAG_SET_CAUGHT:
gSaveBlock2Ptr->pokedex.owned[index] |= mask;
break;
2018-05-10 09:30:42 +02:00
}
return retVal;
}
u16 GetNationalPokedexCount(u8 caseID)
{
u16 count = 0;
u16 i;
for (i = 0; i < NATIONAL_DEX_COUNT; i++)
{
switch (caseID)
{
2019-01-19 23:04:33 +01:00
case FLAG_GET_SEEN:
if (GetSetPokedexFlag(i + 1, FLAG_GET_SEEN))
count++;
break;
case FLAG_GET_CAUGHT:
if (GetSetPokedexFlag(i + 1, FLAG_GET_CAUGHT))
count++;
break;
2018-05-10 09:30:42 +02:00
}
}
return count;
}
u16 GetHoennPokedexCount(u8 caseID)
{
u16 count = 0;
u16 i;
for (i = 0; i < HOENN_DEX_COUNT; i++)
2018-05-10 09:30:42 +02:00
{
switch (caseID)
{
2019-01-19 23:04:33 +01:00
case FLAG_GET_SEEN:
if (GetSetPokedexFlag(HoennToNationalOrder(i + 1), FLAG_GET_SEEN))
count++;
break;
case FLAG_GET_CAUGHT:
if (GetSetPokedexFlag(HoennToNationalOrder(i + 1), FLAG_GET_CAUGHT))
count++;
break;
2018-05-10 09:30:42 +02:00
}
}
return count;
}
u16 GetKantoPokedexCount(u8 caseID)
2018-05-10 09:30:42 +02:00
{
u16 count = 0;
u16 i;
for (i = 0; i < KANTO_DEX_COUNT; i++)
2018-05-10 09:30:42 +02:00
{
switch (caseID)
{
case FLAG_GET_SEEN:
if (GetSetPokedexFlag(i + 1, FLAG_GET_SEEN))
count++;
break;
case FLAG_GET_CAUGHT:
if (GetSetPokedexFlag(i + 1, FLAG_GET_CAUGHT))
count++;
break;
2018-05-10 09:30:42 +02:00
}
}
return count;
}
2019-01-19 23:04:33 +01:00
bool16 HasAllHoennMons(void)
2018-05-10 09:30:42 +02:00
{
u16 i;
2020-03-08 18:24:22 +01:00
// -2 excludes Jirachi and Deoxys
for (i = 0; i < HOENN_DEX_COUNT - 2; i++)
2018-05-10 09:30:42 +02:00
{
if (!GetSetPokedexFlag(HoennToNationalOrder(i + 1), FLAG_GET_CAUGHT))
return FALSE;
}
return TRUE;
}
bool8 HasAllKantoMons(void)
2018-05-10 09:30:42 +02:00
{
u16 i;
2020-03-08 18:24:22 +01:00
// -1 excludes Mew
for (i = 0; i < KANTO_DEX_COUNT - 1; i++)
2018-05-10 09:30:42 +02:00
{
if (!GetSetPokedexFlag(i + 1, FLAG_GET_CAUGHT))
return FALSE;
}
return TRUE;
}
bool16 HasAllMons(void)
2018-05-10 09:30:42 +02:00
{
u16 i;
2020-03-08 18:24:22 +01:00
// -1 excludes Mew
for (i = 0; i < KANTO_DEX_COUNT - 1; i++)
2018-05-10 09:30:42 +02:00
{
2018-12-16 00:39:48 +01:00
if (!GetSetPokedexFlag(i + 1, FLAG_GET_CAUGHT))
return FALSE;
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
// -3 excludes Lugia, Ho-Oh, and Celebi
for (i = KANTO_DEX_COUNT; i < JOHTO_DEX_COUNT - 3; i++)
2018-05-10 09:30:42 +02:00
{
2018-12-16 00:39:48 +01:00
if (!GetSetPokedexFlag(i + 1, FLAG_GET_CAUGHT))
return FALSE;
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
// -2 excludes Jirachi and Deoxys
for (i = JOHTO_DEX_COUNT; i < NATIONAL_DEX_COUNT - 2; i++)
2018-05-10 09:30:42 +02:00
{
2018-12-16 00:39:48 +01:00
if (!GetSetPokedexFlag(i + 1, FLAG_GET_CAUGHT))
return FALSE;
2018-05-10 09:30:42 +02:00
}
return TRUE;
2018-05-10 09:30:42 +02:00
}
2019-12-06 15:44:23 +01:00
static void ResetOtherVideoRegisters(u16 a)
2018-05-10 09:30:42 +02:00
{
2018-05-31 13:08:24 +02:00
if (!(a & DISPCNT_BG0_ON))
2018-05-10 09:30:42 +02:00
{
2018-05-31 13:08:24 +02:00
ClearGpuRegBits(0, DISPCNT_BG0_ON);
2018-05-10 09:30:42 +02:00
SetGpuReg(REG_OFFSET_BG0CNT, 0);
SetGpuReg(REG_OFFSET_BG0HOFS, 0);
SetGpuReg(REG_OFFSET_BG0VOFS, 0);
}
2018-05-31 13:08:24 +02:00
if (!(a & DISPCNT_BG1_ON))
2018-05-10 09:30:42 +02:00
{
2018-05-31 13:08:24 +02:00
ClearGpuRegBits(0, DISPCNT_BG1_ON);
2018-05-10 09:30:42 +02:00
SetGpuReg(REG_OFFSET_BG1CNT, 0);
SetGpuReg(REG_OFFSET_BG1HOFS, 0);
SetGpuReg(REG_OFFSET_BG1VOFS, 0);
}
2018-05-31 13:08:24 +02:00
if (!(a & DISPCNT_BG2_ON))
2018-05-10 09:30:42 +02:00
{
2018-05-31 13:08:24 +02:00
ClearGpuRegBits(0, DISPCNT_BG2_ON);
2018-05-10 09:30:42 +02:00
SetGpuReg(REG_OFFSET_BG2CNT, 0);
SetGpuReg(REG_OFFSET_BG2HOFS, 0);
SetGpuReg(REG_OFFSET_BG2VOFS, 0);
}
2018-05-31 13:08:24 +02:00
if (!(a & DISPCNT_BG3_ON))
2018-05-10 09:30:42 +02:00
{
2018-05-31 13:08:24 +02:00
ClearGpuRegBits(0, DISPCNT_BG3_ON);
2018-05-10 09:30:42 +02:00
SetGpuReg(REG_OFFSET_BG3CNT, 0);
SetGpuReg(REG_OFFSET_BG3HOFS, 0);
SetGpuReg(REG_OFFSET_BG3VOFS, 0);
}
2018-05-31 13:08:24 +02:00
if (!(a & DISPCNT_OBJ_ON))
2018-05-10 09:30:42 +02:00
{
2018-05-31 13:08:24 +02:00
ClearGpuRegBits(0, DISPCNT_OBJ_ON);
2018-05-10 09:30:42 +02:00
ResetSpriteData();
FreeAllSpritePalettes();
gReservedSpritePaletteCount = 8;
}
}
2020-03-08 18:24:22 +01:00
static void PrintInfoSubMenuText(u8 windowId, const u8 *str, u8 left, u8 top)
2018-05-10 09:30:42 +02:00
{
2018-07-08 02:20:01 +02:00
u8 color[3];
2020-03-08 18:24:22 +01:00
color[0] = TEXT_COLOR_TRANSPARENT;
color[1] = TEXT_DYNAMIC_COLOR_6;
color[2] = TEXT_COLOR_LIGHT_GREY;
2018-08-19 01:06:10 +02:00
AddTextPrinterParameterized4(windowId, 1, left, top, 0, 0, color, -1, str);
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
static void UnusedPrintNum(u8 windowId, u16 num, u8 left, u8 top)
2018-05-10 09:30:42 +02:00
{
u8 str[4];
2020-03-08 18:24:22 +01:00
str[0] = CHAR_0 + num / 100;
str[1] = CHAR_0 + (num % 100) / 10;
str[2] = CHAR_0 + (num % 100) % 10;
2018-05-10 09:30:42 +02:00
str[3] = EOS;
2020-03-08 18:24:22 +01:00
PrintInfoSubMenuText(windowId, str, left, top);
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
static u8 PrintCryScreenSpeciesName(u8 windowId, u16 num, u8 left, u8 top)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
u8 str[POKEMON_NAME_LENGTH + 1];
2018-05-10 09:30:42 +02:00
u8 i;
2020-03-08 18:24:22 +01:00
for (i = 0; i < ARRAY_COUNT(str); i++)
2018-05-10 09:30:42 +02:00
str[i] = EOS;
num = NationalPokedexNumToSpecies(num);
switch (num)
{
2020-03-08 18:24:22 +01:00
default:
for (i = 0; gSpeciesNames[num][i] != EOS && i < POKEMON_NAME_LENGTH; i++)
str[i] = gSpeciesNames[num][i];
break;
case 0:
for (i = 0; i < 5; i++)
str[i] = CHAR_HYPHEN;
break;
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
PrintInfoSubMenuText(windowId, str, left, top);
2018-05-10 09:30:42 +02:00
return i;
}
2020-03-08 18:24:22 +01:00
static void UnusedPrintMonName(u8 windowId, const u8* name, u8 left, u8 top)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
u8 str[POKEMON_NAME_LENGTH + 1];
2018-05-10 09:30:42 +02:00
u8 i;
2020-03-08 18:24:22 +01:00
u8 nameLength;
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
for (i = 0; i < ARRAY_COUNT(str); i++)
str[i] = CHAR_SPACE;
for (nameLength = 0; name[nameLength] != CHAR_SPACE && nameLength < ARRAY_COUNT(str); nameLength++)
2018-05-10 09:30:42 +02:00
;
2020-03-08 18:24:22 +01:00
for (i = 0; i < nameLength; i++)
str[ARRAY_COUNT(str) - nameLength + i] = name[i];
2020-07-11 16:22:34 +02:00
#ifdef UBFIX
str[ARRAY_COUNT(str) - 1] = EOS;
#else
2020-03-08 18:24:22 +01:00
str[ARRAY_COUNT(str)] = EOS;
2020-07-11 16:22:34 +02:00
#endif
2020-03-08 18:24:22 +01:00
PrintInfoSubMenuText(windowId, str, left, top);
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
static void UnusedPrintDecimalNum(u8 windowId, u16 b, u8 left, u8 top)
2018-05-10 09:30:42 +02:00
{
u8 str[6];
bool8 outputted = FALSE;
u8 result;
result = b / 1000;
if (result == 0)
{
str[0] = 0x77;
outputted = FALSE;
}
else
{
str[0] = CHAR_0 + result;
outputted = TRUE;
}
result = (b % 1000) / 100;
if (result == 0 && !outputted)
{
str[1] = 0x77;
outputted = FALSE;
}
else
{
str[1] = CHAR_0 + result;
outputted = TRUE;
}
str[2] = CHAR_0 + ((b % 1000) % 100) / 10;
str[3] = CHAR_PERIOD;
str[4] = CHAR_0 + ((b % 1000) % 100) % 10;
str[5] = EOS;
2020-03-08 18:24:22 +01:00
PrintInfoSubMenuText(windowId, str, left, top);
2018-05-10 09:30:42 +02:00
}
2019-12-06 03:20:18 +01:00
static void PrintFootprint(u8 windowId, u16 dexNum)
2018-05-10 09:30:42 +02:00
{
u8 image[32 * 4];
2019-12-06 03:20:18 +01:00
const u8 * r12 = gMonFootprintTable[NationalPokedexNumToSpecies(dexNum)];
2018-05-10 09:30:42 +02:00
u16 r5 = 0;
u16 i;
u16 j;
for (i = 0; i < 32; i++)
{
u8 r3 = r12[i];
for (j = 0; j < 4; j++)
{
u8 value = ((r3 >> (2 * j)) & 1 ? 2 : 0);
if ((2 << (2 * j)) & r3)
value |= 0x20;
image[r5] = value;
r5++;
}
}
2018-07-08 02:20:01 +02:00
CopyToWindowPixelBuffer(windowId, image, sizeof(image), 0);
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
// Unused
2018-05-10 09:30:42 +02:00
void sub_80C0DC0(u16 a, u16 b)
{
*(u16 *)(VRAM + a * 0x800 + 0x232) = 0xF000 + b + 0;
*(u16 *)(VRAM + a * 0x800 + 0x234) = 0xF000 + b + 1;
*(u16 *)(VRAM + a * 0x800 + 0x272) = 0xF000 + b + 2;
*(u16 *)(VRAM + a * 0x800 + 0x274) = 0xF000 + b + 3;
}
2020-03-08 18:24:22 +01:00
static u16 GetNextPosition(u8 direction, u16 position, u16 min, u16 max)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
switch (direction)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
case 1: // Up/Left
if (position > min)
position--;
break;
case 0: // Down/Right
if (position < max)
position++;
break;
case 3: // Up/Left with loop (unused)
if (position > min)
position--;
else
position = max;
break;
case 2: // Down/Right with loop (unused)
if (position < max)
position++;
else
position = min;
break;
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
return position;
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
// Unown and Spinda use the personality of the first seen individual of that species
// All others use personality 0
static u32 GetPokedexMonPersonality(u16 species)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
if (species == SPECIES_UNOWN || species == SPECIES_SPINDA)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
if (species == SPECIES_UNOWN)
2018-05-10 09:30:42 +02:00
return gSaveBlock2Ptr->pokedex.unownPersonality;
else
return gSaveBlock2Ptr->pokedex.spindaPersonality;
}
else
{
return 0;
}
}
u16 CreateMonSpriteFromNationalDexNumber(u16 nationalNum, s16 x, s16 y, u16 paletteSlot)
2018-05-10 09:30:42 +02:00
{
nationalNum = NationalPokedexNumToSpecies(nationalNum);
2020-03-08 18:24:22 +01:00
return CreateMonPicSprite_HandleDeoxys(nationalNum, SHINY_ODDS, GetPokedexMonPersonality(nationalNum), TRUE, x, y, paletteSlot, 0xFFFF);
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
static u16 CreateSizeScreenTrainerPic(u16 species, s16 x, s16 y, s8 paletteSlot)
2018-05-10 09:30:42 +02:00
{
2018-08-19 01:06:10 +02:00
return CreateTrainerPicSprite(species, TRUE, x, y, paletteSlot, 0xFFFF);
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
static int DoPokedexSearch(u8 dexMode, u8 order, u8 abcGroup, u8 bodyColor, u8 type1, u8 type2)
2018-05-10 09:30:42 +02:00
{
u16 species;
u16 i;
u16 resultsCount;
u8 types[2];
2020-03-08 18:24:22 +01:00
CreatePokedexList(dexMode, order);
2018-05-10 09:30:42 +02:00
for (i = 0, resultsCount = 0; i < NATIONAL_DEX_COUNT; i++)
{
2018-12-03 15:58:25 +01:00
if (sPokedexView->pokedexList[i].seen)
2018-05-10 09:30:42 +02:00
{
2018-12-03 15:58:25 +01:00
sPokedexView->pokedexList[resultsCount] = sPokedexView->pokedexList[i];
2018-05-10 09:30:42 +02:00
resultsCount++;
}
}
2018-12-03 15:58:25 +01:00
sPokedexView->pokemonListCount = resultsCount;
2018-05-10 09:30:42 +02:00
// Search by name
if (abcGroup != 0xFF)
{
2018-12-03 15:58:25 +01:00
for (i = 0, resultsCount = 0; i < sPokedexView->pokemonListCount; i++)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
u8 firstLetter;
2018-05-10 09:30:42 +02:00
2018-12-03 15:58:25 +01:00
species = NationalPokedexNumToSpecies(sPokedexView->pokedexList[i].dexNum);
2020-03-08 18:24:22 +01:00
firstLetter = gSpeciesNames[species][0];
if (LETTER_IN_RANGE_UPPER(firstLetter, abcGroup) || LETTER_IN_RANGE_LOWER(firstLetter, abcGroup))
2018-05-10 09:30:42 +02:00
{
2018-12-03 15:58:25 +01:00
sPokedexView->pokedexList[resultsCount] = sPokedexView->pokedexList[i];
2018-05-10 09:30:42 +02:00
resultsCount++;
}
}
2018-12-03 15:58:25 +01:00
sPokedexView->pokemonListCount = resultsCount;
2018-05-10 09:30:42 +02:00
}
// Search by body color
if (bodyColor != 0xFF)
{
2018-12-03 15:58:25 +01:00
for (i = 0, resultsCount = 0; i < sPokedexView->pokemonListCount; i++)
2018-05-10 09:30:42 +02:00
{
2018-12-03 15:58:25 +01:00
species = NationalPokedexNumToSpecies(sPokedexView->pokedexList[i].dexNum);
2018-05-10 09:30:42 +02:00
if (bodyColor == gBaseStats[species].bodyColor)
{
2018-12-03 15:58:25 +01:00
sPokedexView->pokedexList[resultsCount] = sPokedexView->pokedexList[i];
2018-05-10 09:30:42 +02:00
resultsCount++;
}
}
2018-12-03 15:58:25 +01:00
sPokedexView->pokemonListCount = resultsCount;
2018-05-10 09:30:42 +02:00
}
// Search by type
2018-12-05 16:09:19 +01:00
if (type1 != TYPE_NONE || type2 != TYPE_NONE)
2018-05-10 09:30:42 +02:00
{
2018-12-05 16:09:19 +01:00
if (type1 == TYPE_NONE)
2018-05-10 09:30:42 +02:00
{
type1 = type2;
2018-12-05 16:09:19 +01:00
type2 = TYPE_NONE;
2018-05-10 09:30:42 +02:00
}
2018-12-05 16:09:19 +01:00
if (type2 == TYPE_NONE)
2018-05-10 09:30:42 +02:00
{
2018-12-03 15:58:25 +01:00
for (i = 0, resultsCount = 0; i < sPokedexView->pokemonListCount; i++)
2018-05-10 09:30:42 +02:00
{
2018-12-03 15:58:25 +01:00
if (sPokedexView->pokedexList[i].owned)
2018-05-10 09:30:42 +02:00
{
2018-12-03 15:58:25 +01:00
species = NationalPokedexNumToSpecies(sPokedexView->pokedexList[i].dexNum);
2018-05-10 09:30:42 +02:00
types[0] = gBaseStats[species].type1;
types[1] = gBaseStats[species].type2;
if (types[0] == type1 || types[1] == type1)
{
2018-12-03 15:58:25 +01:00
sPokedexView->pokedexList[resultsCount] = sPokedexView->pokedexList[i];
2018-05-10 09:30:42 +02:00
resultsCount++;
}
}
}
}
else
{
2018-12-03 15:58:25 +01:00
for (i = 0, resultsCount = 0; i < sPokedexView->pokemonListCount; i++)
2018-05-10 09:30:42 +02:00
{
2018-12-03 15:58:25 +01:00
if (sPokedexView->pokedexList[i].owned)
2018-05-10 09:30:42 +02:00
{
2018-12-03 15:58:25 +01:00
species = NationalPokedexNumToSpecies(sPokedexView->pokedexList[i].dexNum);
2018-05-10 09:30:42 +02:00
types[0] = gBaseStats[species].type1;
types[1] = gBaseStats[species].type2;
if ((types[0] == type1 && types[1] == type2) || (types[0] == type2 && types[1] == type1))
{
2018-12-03 15:58:25 +01:00
sPokedexView->pokedexList[resultsCount] = sPokedexView->pokedexList[i];
2018-05-10 09:30:42 +02:00
resultsCount++;
}
}
}
}
2018-12-03 15:58:25 +01:00
sPokedexView->pokemonListCount = resultsCount;
2018-05-10 09:30:42 +02:00
}
2018-12-03 15:58:25 +01:00
if (sPokedexView->pokemonListCount != 0)
2018-05-10 09:30:42 +02:00
{
2018-12-03 15:58:25 +01:00
for (i = sPokedexView->pokemonListCount; i < NATIONAL_DEX_COUNT; i++)
2018-05-10 09:30:42 +02:00
{
2018-12-03 15:58:25 +01:00
sPokedexView->pokedexList[i].dexNum = 0xFFFF;
sPokedexView->pokedexList[i].seen = FALSE;
sPokedexView->pokedexList[i].owned = FALSE;
2018-05-10 09:30:42 +02:00
}
}
return resultsCount;
}
2020-03-08 18:24:22 +01:00
static u8 LoadSearchMenu(void)
2018-05-10 09:30:42 +02:00
{
2019-11-20 00:54:00 +01:00
return CreateTask(Task_LoadSearchMenu, 0);
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
static void PrintSearchText(const u8 *str, u32 x, u32 y)
2018-05-10 09:30:42 +02:00
{
2018-07-08 02:20:01 +02:00
u8 color[3];
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
color[0] = TEXT_COLOR_TRANSPARENT;
color[1] = TEXT_DYNAMIC_COLOR_6;
color[2] = TEXT_COLOR_DARK_GREY;
AddTextPrinterParameterized4(0, 1, x, y, 0, 0, color, -1, str);
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
static void ClearSearchMenuRect(u32 x, u32 y, u32 width, u32 height)
2018-05-10 09:30:42 +02:00
{
FillWindowPixelRect(0, PIXEL_FILL(0), x, y, width, height);
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
// Search task data
#define tTopBarItem data[0]
#define tMenuItem data[1]
#define tCursorPos_Mode data[2]
#define tScrollOffset_Mode data[3]
#define tCursorPos_Order data[4]
#define tScrollOffset_Order data[5]
#define tCursorPos_Name data[6]
#define tScrollOffset_Name data[7]
#define tCursorPos_Color data[8]
#define tScrollOffset_Color data[9]
#define tCursorPos_TypeLeft data[10]
#define tScrollOffset_TypeLeft data[11]
#define tCursorPos_TypeRight data[12]
#define tScrollOffset_TypeRight data[13]
#define tCursorPos data[14]
#define tScrollOffset data[15]
static void Task_LoadSearchMenu(u8 taskId)
2018-05-10 09:30:42 +02:00
{
u16 i;
switch (gMain.state)
{
2020-03-08 18:24:22 +01:00
default:
case 0:
if (!gPaletteFade.active)
{
sPokedexView->currentPage = PAGE_SEARCH;
ResetOtherVideoRegisters(0);
ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, sSearchMenu_BgTemplate, ARRAY_COUNT(sSearchMenu_BgTemplate));
SetBgTilemapBuffer(3, AllocZeroed(0x800));
SetBgTilemapBuffer(2, AllocZeroed(0x800));
SetBgTilemapBuffer(1, AllocZeroed(0x800));
SetBgTilemapBuffer(0, AllocZeroed(0x800));
InitWindows(sSearchMenu_WindowTemplate);
DeactivateAllTextPrinters();
PutWindowTilemap(0);
DecompressAndLoadBgGfxUsingHeap(3, gPokedexSearchMenu_Gfx, 0x2000, 0, 0);
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
if (!IsNationalPokedexEnabled())
CopyToBgTilemapBuffer(3, gPokedexSearchMenuHoenn_Tilemap, 0, 0);
else
CopyToBgTilemapBuffer(3, gPokedexSearchMenuNational_Tilemap, 0, 0);
LoadPalette(gPokedexSearchMenu_Pal + 1, 1, 0x7E);
gMain.state = 1;
}
break;
case 1:
LoadCompressedSpriteSheet(sInterfaceSpriteSheet);
LoadSpritePalettes(sInterfaceSpritePalette);
CreateSearchParameterScrollArrows(taskId);
for (i = 0; i < NUM_TASK_DATA; i++)
gTasks[taskId].data[i] = 0;
SetDefaultSearchModeAndOrder(taskId);
HighlightSelectedSearchTopBarItem(SEARCH_TOPBAR_SEARCH);
PrintSelectedSearchParameters(taskId);
CopyWindowToVram(0, 3);
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(3);
gMain.state++;
break;
case 2:
BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK);
gMain.state++;
break;
case 3:
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
SetGpuReg(REG_OFFSET_BLDY, 0);
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON);
HideBg(0);
ShowBg(1);
ShowBg(2);
ShowBg(3);
gMain.state++;
break;
case 4:
if (!gPaletteFade.active)
{
gTasks[taskId].func = Task_SwitchToSearchMenuTopBar;
gMain.state = 0;
}
break;
2018-05-10 09:30:42 +02:00
}
}
2020-03-08 18:24:22 +01:00
static void FreeSearchWindowAndBgBuffers(void)
2018-05-10 09:30:42 +02:00
{
void* tilemapBuffer;
2018-08-19 01:06:10 +02:00
2018-05-10 09:30:42 +02:00
FreeAllWindowBuffers();
tilemapBuffer = GetBgTilemapBuffer(0);
if (tilemapBuffer)
Free(tilemapBuffer);
tilemapBuffer = GetBgTilemapBuffer(1);
if (tilemapBuffer)
Free(tilemapBuffer);
tilemapBuffer = GetBgTilemapBuffer(2);
if (tilemapBuffer)
Free(tilemapBuffer);
tilemapBuffer = GetBgTilemapBuffer(3);
if (tilemapBuffer)
Free(tilemapBuffer);
}
2020-03-08 18:24:22 +01:00
static void Task_SwitchToSearchMenuTopBar(u8 taskId)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
HighlightSelectedSearchTopBarItem(gTasks[taskId].tTopBarItem);
PrintSelectedSearchParameters(taskId);
2018-05-10 09:30:42 +02:00
CopyWindowToVram(0, 2);
CopyBgTilemapBufferToVram(3);
2020-03-08 18:24:22 +01:00
gTasks[taskId].func = Task_HandleSearchTopBarInput;
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
static void Task_HandleSearchTopBarInput(u8 taskId)
2018-05-10 09:30:42 +02:00
{
if (gMain.newKeys & B_BUTTON)
{
PlaySE(SE_PC_OFF);
2020-03-08 18:24:22 +01:00
gTasks[taskId].func = Task_ExitSearch;
2018-05-10 09:30:42 +02:00
return;
}
if (gMain.newKeys & A_BUTTON)
{
2020-03-08 18:24:22 +01:00
switch (gTasks[taskId].tTopBarItem)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
case SEARCH_TOPBAR_SEARCH:
PlaySE(SE_PIN);
gTasks[taskId].tMenuItem = SEARCH_NAME;
gTasks[taskId].func = Task_SwitchToSearchMenu;
break;
case SEARCH_TOPBAR_SHIFT:
PlaySE(SE_PIN);
gTasks[taskId].tMenuItem = SEARCH_ORDER;
gTasks[taskId].func = Task_SwitchToSearchMenu;
break;
case SEARCH_TOPBAR_CANCEL:
PlaySE(SE_PC_OFF);
gTasks[taskId].func = Task_ExitSearch;
break;
2018-05-10 09:30:42 +02:00
}
return;
}
2020-03-08 18:24:22 +01:00
if ((gMain.newKeys & DPAD_LEFT) && gTasks[taskId].tTopBarItem > SEARCH_TOPBAR_SEARCH)
2018-05-10 09:30:42 +02:00
{
PlaySE(SE_Z_PAGE);
2020-03-08 18:24:22 +01:00
gTasks[taskId].tTopBarItem--;
HighlightSelectedSearchTopBarItem(gTasks[taskId].tTopBarItem);
2018-05-10 09:30:42 +02:00
CopyWindowToVram(0, 2);
CopyBgTilemapBufferToVram(3);
}
2020-03-08 18:24:22 +01:00
if ((gMain.newKeys & DPAD_RIGHT) && gTasks[taskId].tTopBarItem < SEARCH_TOPBAR_CANCEL)
2018-05-10 09:30:42 +02:00
{
PlaySE(SE_Z_PAGE);
2020-03-08 18:24:22 +01:00
gTasks[taskId].tTopBarItem++;
HighlightSelectedSearchTopBarItem(gTasks[taskId].tTopBarItem);
2018-05-10 09:30:42 +02:00
CopyWindowToVram(0, 2);
CopyBgTilemapBufferToVram(3);
}
}
2020-03-08 18:24:22 +01:00
static void Task_SwitchToSearchMenu(u8 taskId)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
HighlightSelectedSearchMenuItem(gTasks[taskId].tTopBarItem, gTasks[taskId].tMenuItem);
PrintSelectedSearchParameters(taskId);
2018-05-10 09:30:42 +02:00
CopyWindowToVram(0, 2);
CopyBgTilemapBufferToVram(3);
2020-03-08 18:24:22 +01:00
gTasks[taskId].func = Task_HandleSearchMenuInput;
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
// Input for main search menu
static void Task_HandleSearchMenuInput(u8 taskId)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
const u8 (*movementMap)[4];
2018-05-10 09:30:42 +02:00
2020-03-08 18:24:22 +01:00
if (gTasks[taskId].tTopBarItem != SEARCH_TOPBAR_SEARCH)
2018-05-10 09:30:42 +02:00
{
if (!IsNationalPokedexEnabled())
2020-03-08 18:24:22 +01:00
movementMap = sSearchMovementMap_ShiftHoennDex;
2018-05-10 09:30:42 +02:00
else
2020-03-08 18:24:22 +01:00
movementMap = sSearchMovementMap_ShiftNatDex;
2018-05-10 09:30:42 +02:00
}
else
{
if (!IsNationalPokedexEnabled())
2020-03-08 18:24:22 +01:00
movementMap = sSearchMovementMap_SearchHoennDex;
2018-05-10 09:30:42 +02:00
else
2020-03-08 18:24:22 +01:00
movementMap = sSearchMovementMap_SearchNatDex;
2018-05-10 09:30:42 +02:00
}
if (gMain.newKeys & B_BUTTON)
{
PlaySE(SE_BOWA);
2020-03-08 18:24:22 +01:00
SetDefaultSearchModeAndOrder(taskId);
gTasks[taskId].func = Task_SwitchToSearchMenuTopBar;
2018-05-10 09:30:42 +02:00
return;
}
if (gMain.newKeys & A_BUTTON)
{
2020-03-08 18:24:22 +01:00
if (gTasks[taskId].tMenuItem == SEARCH_OK)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
if (gTasks[taskId].tTopBarItem != SEARCH_TOPBAR_SEARCH)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
sPokeBallRotation = POKEBALL_ROTATION_TOP;
sPokedexView->pokeBallRotationBackup = POKEBALL_ROTATION_TOP;
sLastSelectedPokemon = 0;
sPokedexView->selectedPokemonBackup = 0;
gSaveBlock2Ptr->pokedex.mode = GetSearchModeSelection(taskId, SEARCH_MODE);
2018-05-10 09:30:42 +02:00
if (!IsNationalPokedexEnabled())
gSaveBlock2Ptr->pokedex.mode = DEX_MODE_HOENN;
2020-03-08 18:24:22 +01:00
sPokedexView->dexModeBackup = gSaveBlock2Ptr->pokedex.mode;
2020-01-03 02:35:35 +01:00
gSaveBlock2Ptr->pokedex.order = GetSearchModeSelection(taskId, SEARCH_ORDER);
2020-03-08 18:24:22 +01:00
sPokedexView->dexOrderBackup = gSaveBlock2Ptr->pokedex.order;
2018-05-10 09:30:42 +02:00
PlaySE(SE_PC_OFF);
2020-03-08 18:24:22 +01:00
gTasks[taskId].func = Task_ExitSearch;
2018-05-10 09:30:42 +02:00
}
else
{
2020-03-08 18:24:22 +01:00
EraseAndPrintSearchTextBox(gText_SearchingPleaseWait);
gTasks[taskId].func = Task_StartPokedexSearch;
2018-05-10 09:30:42 +02:00
PlaySE(SE_Z_SEARCH);
CopyWindowToVram(0, 2);
}
}
else
{
PlaySE(SE_PIN);
2020-03-08 18:24:22 +01:00
gTasks[taskId].func = Task_SelectSearchMenuItem;
2018-05-10 09:30:42 +02:00
}
return;
}
2020-03-08 18:24:22 +01:00
if ((gMain.newKeys & DPAD_LEFT) && movementMap[gTasks[taskId].tMenuItem][0] != 0xFF)
2018-05-10 09:30:42 +02:00
{
PlaySE(SE_SELECT);
2020-03-08 18:24:22 +01:00
gTasks[taskId].tMenuItem = movementMap[gTasks[taskId].tMenuItem][0];
HighlightSelectedSearchMenuItem(gTasks[taskId].tTopBarItem, gTasks[taskId].tMenuItem);
2018-05-10 09:30:42 +02:00
CopyWindowToVram(0, 2);
CopyBgTilemapBufferToVram(3);
}
2020-03-08 18:24:22 +01:00
if ((gMain.newKeys & DPAD_RIGHT) && movementMap[gTasks[taskId].tMenuItem][1] != 0xFF)
2018-05-10 09:30:42 +02:00
{
PlaySE(SE_SELECT);
2020-03-08 18:24:22 +01:00
gTasks[taskId].tMenuItem = movementMap[gTasks[taskId].tMenuItem][1];
HighlightSelectedSearchMenuItem(gTasks[taskId].tTopBarItem, gTasks[taskId].tMenuItem);
2018-05-10 09:30:42 +02:00
CopyWindowToVram(0, 2);
CopyBgTilemapBufferToVram(3);
}
2020-03-08 18:24:22 +01:00
if ((gMain.newKeys & DPAD_UP) && movementMap[gTasks[taskId].tMenuItem][2] != 0xFF)
2018-05-10 09:30:42 +02:00
{
PlaySE(SE_SELECT);
2020-03-08 18:24:22 +01:00
gTasks[taskId].tMenuItem = movementMap[gTasks[taskId].tMenuItem][2];
HighlightSelectedSearchMenuItem(gTasks[taskId].tTopBarItem, gTasks[taskId].tMenuItem);
2018-05-10 09:30:42 +02:00
CopyWindowToVram(0, 2);
CopyBgTilemapBufferToVram(3);
}
2020-03-08 18:24:22 +01:00
if ((gMain.newKeys & DPAD_DOWN) && movementMap[gTasks[taskId].tMenuItem][3] != 0xFF)
2018-05-10 09:30:42 +02:00
{
PlaySE(SE_SELECT);
2020-03-08 18:24:22 +01:00
gTasks[taskId].tMenuItem = movementMap[gTasks[taskId].tMenuItem][3];
HighlightSelectedSearchMenuItem(gTasks[taskId].tTopBarItem, gTasks[taskId].tMenuItem);
2018-05-10 09:30:42 +02:00
CopyWindowToVram(0, 2);
CopyBgTilemapBufferToVram(3);
}
}
2020-03-08 18:24:22 +01:00
static void Task_StartPokedexSearch(u8 taskId)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
u8 dexMode = GetSearchModeSelection(taskId, SEARCH_MODE);
u8 order = GetSearchModeSelection(taskId, SEARCH_ORDER);
2020-01-03 02:35:35 +01:00
u8 abcGroup = GetSearchModeSelection(taskId, SEARCH_NAME);
u8 bodyColor = GetSearchModeSelection(taskId, SEARCH_COLOR);
2020-03-08 18:24:22 +01:00
u8 type1 = GetSearchModeSelection(taskId, SEARCH_TYPE_LEFT);
u8 type2 = GetSearchModeSelection(taskId, SEARCH_TYPE_RIGHT);
2018-05-10 09:30:42 +02:00
2020-03-08 18:24:22 +01:00
DoPokedexSearch(dexMode, order, abcGroup, bodyColor, type1, type2);
gTasks[taskId].func = Task_WaitAndCompleteSearch;
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
static void Task_WaitAndCompleteSearch(u8 taskId)
2018-05-10 09:30:42 +02:00
{
if (!IsSEPlaying())
{
2018-12-03 15:58:25 +01:00
if (sPokedexView->pokemonListCount != 0)
2018-05-10 09:30:42 +02:00
{
PlaySE(SE_SEIKAI);
2020-03-08 18:24:22 +01:00
EraseAndPrintSearchTextBox(gText_SearchCompleted);
2018-05-10 09:30:42 +02:00
}
else
{
PlaySE(SE_HAZURE);
2020-03-08 18:24:22 +01:00
EraseAndPrintSearchTextBox(gText_NoMatchingPkmnWereFound);
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
gTasks[taskId].func = Task_SearchCompleteWaitForInput;
2018-05-10 09:30:42 +02:00
CopyWindowToVram(0, 2);
}
}
2020-03-08 18:24:22 +01:00
static void Task_SearchCompleteWaitForInput(u8 taskId)
2018-05-10 09:30:42 +02:00
{
if (gMain.newKeys & A_BUTTON)
{
2018-12-03 15:58:25 +01:00
if (sPokedexView->pokemonListCount != 0)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
// Return to dex list and show search results
sPokedexView->screenSwitchState = 1;
sPokedexView->dexMode = GetSearchModeSelection(taskId, SEARCH_MODE);
2020-01-03 02:35:35 +01:00
sPokedexView->dexOrder = GetSearchModeSelection(taskId, SEARCH_ORDER);
2020-03-08 18:24:22 +01:00
gTasks[taskId].func = Task_ExitSearch;
2018-05-10 09:30:42 +02:00
PlaySE(SE_PC_OFF);
}
else
{
2020-03-08 18:24:22 +01:00
gTasks[taskId].func = Task_SwitchToSearchMenu;
2018-05-10 09:30:42 +02:00
PlaySE(SE_BOWA);
}
}
}
2020-03-08 18:24:22 +01:00
static void Task_SelectSearchMenuItem(u8 taskId)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
u8 menuItem;
u16 *cursorPos;
u16 *scrollOffset;
2018-05-10 09:30:42 +02:00
2020-03-08 18:24:22 +01:00
DrawOrEraseSearchParameterBox(FALSE);
menuItem = (u16)gTasks[taskId].tMenuItem;
cursorPos = (u16*)&gTasks[taskId].data[sSearchOptions[menuItem].taskDataCursorPos];
scrollOffset = (u16*)&gTasks[taskId].data[sSearchOptions[menuItem].taskDataScrollOffset];
2020-03-08 18:24:22 +01:00
gTasks[taskId].tCursorPos = *cursorPos;
gTasks[taskId].tScrollOffset = *scrollOffset;
PrintSearchParameterText(taskId);
PrintSelectorArrow(*cursorPos);
gTasks[taskId].func = Task_HandleSearchParameterInput;
2018-05-10 09:30:42 +02:00
CopyWindowToVram(0, 2);
CopyBgTilemapBufferToVram(3);
}
2020-03-08 18:24:22 +01:00
// Input for scrolling parameter box in right column
static void Task_HandleSearchParameterInput(u8 taskId)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
u8 menuItem;
const struct SearchOptionText *texts;
u16 *cursorPos;
u16 *scrollOffset;
u16 maxOption;
bool8 moved;
2018-05-10 09:30:42 +02:00
2020-03-08 18:24:22 +01:00
menuItem = gTasks[taskId].tMenuItem;
texts = sSearchOptions[menuItem].texts;
cursorPos = &gTasks[taskId].data[sSearchOptions[menuItem].taskDataCursorPos];
scrollOffset = &gTasks[taskId].data[sSearchOptions[menuItem].taskDataScrollOffset];
maxOption = sSearchOptions[menuItem].numOptions - 1;
2018-05-10 09:30:42 +02:00
if (gMain.newKeys & A_BUTTON)
{
PlaySE(SE_PIN);
2020-03-08 18:24:22 +01:00
ClearSearchParameterBoxText();
DrawOrEraseSearchParameterBox(TRUE);
gTasks[taskId].func = Task_SwitchToSearchMenu;
2018-05-10 09:30:42 +02:00
CopyWindowToVram(0, 2);
CopyBgTilemapBufferToVram(3);
return;
}
if (gMain.newKeys & B_BUTTON)
{
PlaySE(SE_BOWA);
2020-03-08 18:24:22 +01:00
ClearSearchParameterBoxText();
DrawOrEraseSearchParameterBox(TRUE);
*cursorPos = gTasks[taskId].tCursorPos;
*scrollOffset = gTasks[taskId].tScrollOffset;
gTasks[taskId].func = Task_SwitchToSearchMenu;
2018-05-10 09:30:42 +02:00
CopyWindowToVram(0, 2);
CopyBgTilemapBufferToVram(3);
return;
}
2020-03-08 18:24:22 +01:00
moved = FALSE;
2018-05-10 09:30:42 +02:00
if (gMain.newAndRepeatedKeys & DPAD_UP)
{
2020-03-08 18:24:22 +01:00
if (*cursorPos != 0)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
// Move cursor up
EraseSelectorArrow(*cursorPos);
(*cursorPos)--;
PrintSelectorArrow(*cursorPos);
moved = TRUE;
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
else if (*scrollOffset != 0)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
// Scroll up
(*scrollOffset)--;
PrintSearchParameterText(taskId);
PrintSelectorArrow(*cursorPos);
moved = TRUE;
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
if (moved)
2018-05-10 09:30:42 +02:00
{
PlaySE(SE_SELECT);
2020-03-08 18:24:22 +01:00
EraseAndPrintSearchTextBox(texts[*cursorPos + *scrollOffset].description);
2018-05-10 09:30:42 +02:00
CopyWindowToVram(0, 2);
}
return;
}
if (gMain.newAndRepeatedKeys & DPAD_DOWN)
{
2020-03-08 18:24:22 +01:00
if (*cursorPos < MAX_SEARCH_PARAM_CURSOR_POS && *cursorPos < maxOption)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
// Move cursor down
EraseSelectorArrow(*cursorPos);
(*cursorPos)++;
PrintSelectorArrow(*cursorPos);
moved = TRUE;
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
else if (maxOption > MAX_SEARCH_PARAM_CURSOR_POS && *scrollOffset < maxOption - MAX_SEARCH_PARAM_CURSOR_POS)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
// Scroll down
(*scrollOffset)++;
PrintSearchParameterText(taskId);
PrintSelectorArrow(5);
moved = TRUE;
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
if (moved)
2018-05-10 09:30:42 +02:00
{
PlaySE(SE_SELECT);
2020-03-08 18:24:22 +01:00
EraseAndPrintSearchTextBox(texts[*cursorPos + *scrollOffset].description);
2018-05-10 09:30:42 +02:00
CopyWindowToVram(0, 2);
}
return;
}
}
2020-03-08 18:24:22 +01:00
static void Task_ExitSearch(u8 taskId)
2018-05-10 09:30:42 +02:00
{
2018-05-31 13:08:24 +02:00
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK);
2020-03-08 18:24:22 +01:00
gTasks[taskId].func = Task_ExitSearchWaitForFade;
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
static void Task_ExitSearchWaitForFade(u8 taskId)
2018-05-10 09:30:42 +02:00
{
if (!gPaletteFade.active)
{
2020-03-08 18:24:22 +01:00
FreeSearchWindowAndBgBuffers();
2018-05-10 09:30:42 +02:00
DestroyTask(taskId);
}
}
#ifdef NONMATCHING
// This doesn't match because gcc flips the naming of the r7 and r6
// registers. It also does one of the additions backwards.
2020-03-08 18:24:22 +01:00
void SetSearchRectHighlight(u8 flags, u8 x, u8 y, u8 width)
2018-05-10 09:30:42 +02:00
{
u16 i;
u16* ptr = GetBgTilemapBuffer(3);
u16* temp;
2020-03-08 18:24:22 +01:00
for (i = 0; i < width; i++)
2018-05-10 09:30:42 +02:00
{
// This addition is supposed to be done in this order; however,
2020-03-08 18:24:22 +01:00
// gcc will always do it in ptr + (y * 32) order.
temp = (y * 32) + ptr;
temp[x + i] %= 0x1000;
temp[x + i] |= flags * 0x1000;
2018-05-10 09:30:42 +02:00
2020-03-08 18:24:22 +01:00
temp[x + i + 32] %= 0x1000;
temp[x + i + 32] |= flags * 0x1000;
2018-05-10 09:30:42 +02:00
}
}
#else
__attribute__((naked))
2020-03-08 18:24:22 +01:00
void SetSearchRectHighlight(u8 flags, u8 x, u8 y, u8 width)
2018-05-10 09:30:42 +02:00
{
asm(".syntax unified\n\
push {r4-r7,lr}\n\
mov r7, r8\n\
push {r7}\n\
adds r4, r3, 0\n\
lsls r0, 24\n\
lsrs r6, r0, 24\n\
lsls r1, 24\n\
lsrs r1, 24\n\
mov r8, r1\n\
lsls r2, 24\n\
lsrs r5, r2, 24\n\
lsls r4, 24\n\
lsrs r4, 24\n\
movs r0, 0x3\n\
bl GetBgTilemapBuffer\n\
adds r2, r0, 0\n\
movs r3, 0\n\
cmp r3, r4\n\
bcs _080C1DEC\n\
lsls r0, r5, 6\n\
adds r7, r0, r2\n\
ldr r5, =0x00000fff\n\
lsls r2, r6, 12\n\
2018-05-10 09:30:42 +02:00
_080C1DC8:\n\
mov r0, r8\n\
adds r1, r0, r3\n\
lsls r1, 1\n\
adds r1, r7\n\
ldrh r0, [r1]\n\
ands r0, r5\n\
orrs r0, r2\n\
strh r0, [r1]\n\
adds r1, 0x40\n\
ldrh r0, [r1]\n\
ands r0, r5\n\
orrs r0, r2\n\
strh r0, [r1]\n\
adds r0, r3, 0x1\n\
lsls r0, 16\n\
lsrs r3, r0, 16\n\
cmp r3, r4\n\
bcc _080C1DC8\n\
2018-05-10 09:30:42 +02:00
_080C1DEC:\n\
pop {r3}\n\
mov r8, r3\n\
pop {r4-r7}\n\
pop {r0}\n\
bx r0\n\
.pool\n\
2018-05-10 09:30:42 +02:00
.syntax divided\n");
}
#endif
2020-03-08 18:24:22 +01:00
#define SEARCH_BG_SEARCH SEARCH_TOPBAR_SEARCH
#define SEARCH_BG_SHIFT SEARCH_TOPBAR_SHIFT
#define SEARCH_BG_CANCEL SEARCH_TOPBAR_CANCEL
#define SEARCH_BG_NAME (SEARCH_NAME + SEARCH_TOPBAR_COUNT)
#define SEARCH_BG_COLOR (SEARCH_COLOR + SEARCH_TOPBAR_COUNT)
#define SEARCH_BG_TYPE_SELECTION_LEFT (SEARCH_TYPE_LEFT + SEARCH_TOPBAR_COUNT)
#define SEARCH_BG_TYPE_SELECTION_RIGHT (SEARCH_TYPE_RIGHT + SEARCH_TOPBAR_COUNT)
#define SEARCH_BG_ORDER (SEARCH_ORDER + SEARCH_TOPBAR_COUNT)
#define SEARCH_BG_MODE (SEARCH_MODE + SEARCH_TOPBAR_COUNT)
#define SEARCH_BG_OK (SEARCH_OK + SEARCH_TOPBAR_COUNT)
#define SEARCH_BG_TYPE_TITLE (SEARCH_COUNT + SEARCH_TOPBAR_COUNT)
static void DrawSearchMenuItemBgHighlight(u8 searchBg, bool8 unselected, bool8 disabled)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
u8 highlightFlags = (unselected & 1) | ((disabled & 1) << 1);
2018-05-10 09:30:42 +02:00
2020-03-08 18:24:22 +01:00
switch (searchBg)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
case SEARCH_BG_SEARCH:
case SEARCH_BG_SHIFT:
case SEARCH_BG_CANCEL:
SetSearchRectHighlight(highlightFlags, sSearchMenuTopBarItems[searchBg].highlightX, sSearchMenuTopBarItems[searchBg].highlightY, sSearchMenuTopBarItems[searchBg].highlightWidth);
break;
case SEARCH_BG_NAME:
case SEARCH_BG_COLOR:
case SEARCH_BG_ORDER:
case SEARCH_BG_MODE:
SetSearchRectHighlight(highlightFlags, sSearchMenuItems[searchBg - SEARCH_TOPBAR_COUNT].titleBgX, sSearchMenuItems[searchBg - SEARCH_TOPBAR_COUNT].titleBgY, sSearchMenuItems[searchBg - SEARCH_TOPBAR_COUNT].titleBgWidth);
// fall through, draw selectionBg for above
case SEARCH_BG_TYPE_SELECTION_LEFT:
case SEARCH_BG_TYPE_SELECTION_RIGHT:
SetSearchRectHighlight(highlightFlags, sSearchMenuItems[searchBg - SEARCH_TOPBAR_COUNT].selectionBgX, sSearchMenuItems[searchBg - SEARCH_TOPBAR_COUNT].selectionBgY, sSearchMenuItems[searchBg - SEARCH_TOPBAR_COUNT].selectionBgWidth);
break;
case SEARCH_BG_TYPE_TITLE:
SetSearchRectHighlight(highlightFlags, sSearchMenuItems[SEARCH_TYPE_LEFT].titleBgX, sSearchMenuItems[SEARCH_TYPE_LEFT].titleBgY, sSearchMenuItems[SEARCH_TYPE_LEFT].titleBgWidth);
break;
case SEARCH_BG_OK:
if (!IsNationalPokedexEnabled())
SetSearchRectHighlight(highlightFlags, sSearchMenuItems[searchBg - SEARCH_TOPBAR_COUNT].titleBgX, sSearchMenuItems[searchBg - SEARCH_TOPBAR_COUNT].titleBgY - 2, sSearchMenuItems[searchBg - SEARCH_TOPBAR_COUNT].titleBgWidth);
else
SetSearchRectHighlight(highlightFlags, sSearchMenuItems[searchBg - SEARCH_TOPBAR_COUNT].titleBgX, sSearchMenuItems[searchBg - SEARCH_TOPBAR_COUNT].titleBgY, sSearchMenuItems[searchBg - SEARCH_TOPBAR_COUNT].titleBgWidth);
break;
2018-05-10 09:30:42 +02:00
}
}
2020-03-08 18:24:22 +01:00
static void SetInitialSearchMenuBgHighlights(u8 topBarItem)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
switch (topBarItem)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
case SEARCH_TOPBAR_SEARCH:
DrawSearchMenuItemBgHighlight(SEARCH_BG_SEARCH, FALSE, FALSE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_SHIFT, TRUE, FALSE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_CANCEL, TRUE, FALSE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_NAME, TRUE, FALSE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_COLOR, TRUE, FALSE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_TYPE_TITLE, TRUE, FALSE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_TYPE_SELECTION_LEFT, TRUE, FALSE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_TYPE_SELECTION_RIGHT, TRUE, FALSE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_ORDER, TRUE, FALSE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_MODE, TRUE, FALSE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_OK, TRUE, FALSE);
break;
case SEARCH_TOPBAR_SHIFT:
DrawSearchMenuItemBgHighlight(SEARCH_BG_SEARCH, TRUE, FALSE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_SHIFT, FALSE, FALSE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_CANCEL, TRUE, FALSE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_NAME, TRUE, TRUE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_COLOR, TRUE, TRUE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_TYPE_TITLE, TRUE, TRUE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_TYPE_SELECTION_LEFT, TRUE, TRUE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_TYPE_SELECTION_RIGHT, TRUE, TRUE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_ORDER, TRUE, FALSE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_MODE, TRUE, FALSE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_OK, TRUE, FALSE);
break;
case SEARCH_TOPBAR_CANCEL:
DrawSearchMenuItemBgHighlight(SEARCH_BG_SEARCH, TRUE, FALSE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_SHIFT, TRUE, FALSE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_CANCEL, FALSE, FALSE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_NAME, TRUE, TRUE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_COLOR, TRUE, TRUE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_TYPE_TITLE, TRUE, TRUE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_TYPE_SELECTION_LEFT, TRUE, TRUE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_TYPE_SELECTION_RIGHT, TRUE, TRUE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_ORDER, TRUE, TRUE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_MODE, TRUE, TRUE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_OK, TRUE, TRUE);
break;
2018-05-10 09:30:42 +02:00
}
}
2020-03-08 18:24:22 +01:00
static void HighlightSelectedSearchTopBarItem(u8 topBarItem)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
SetInitialSearchMenuBgHighlights(topBarItem);
EraseAndPrintSearchTextBox(sSearchMenuTopBarItems[topBarItem].description);
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
static void HighlightSelectedSearchMenuItem(u8 topBarItem, u8 menuItem)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
SetInitialSearchMenuBgHighlights(topBarItem);
switch (menuItem)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
case SEARCH_NAME:
DrawSearchMenuItemBgHighlight(SEARCH_BG_NAME, FALSE, FALSE);
break;
case SEARCH_COLOR:
DrawSearchMenuItemBgHighlight(SEARCH_BG_COLOR, FALSE, FALSE);
break;
case SEARCH_TYPE_LEFT:
DrawSearchMenuItemBgHighlight(SEARCH_BG_TYPE_TITLE, FALSE, FALSE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_TYPE_SELECTION_LEFT, FALSE, FALSE);
break;
case SEARCH_TYPE_RIGHT:
DrawSearchMenuItemBgHighlight(SEARCH_BG_TYPE_TITLE, FALSE, FALSE);
DrawSearchMenuItemBgHighlight(SEARCH_BG_TYPE_SELECTION_RIGHT, FALSE, FALSE);
break;
case SEARCH_ORDER:
DrawSearchMenuItemBgHighlight(SEARCH_BG_ORDER, FALSE, FALSE);
break;
case SEARCH_MODE:
DrawSearchMenuItemBgHighlight(SEARCH_BG_MODE, FALSE, FALSE);
break;
case SEARCH_OK:
DrawSearchMenuItemBgHighlight(SEARCH_BG_OK, FALSE, FALSE);
break;
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
EraseAndPrintSearchTextBox(sSearchMenuItems[menuItem].description);
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
// Prints the currently selected search parameters in the search menu selection boxes
static void PrintSelectedSearchParameters(u8 taskId)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
u16 searchParamId;
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
ClearSearchMenuRect(40, 16, 96, 80);
2018-05-10 09:30:42 +02:00
2020-03-08 18:24:22 +01:00
searchParamId = gTasks[taskId].tCursorPos_Name + gTasks[taskId].tScrollOffset_Name;
PrintSearchText(sDexSearchNameOptions[searchParamId].title, 0x2D, 0x11);
2018-08-19 01:06:10 +02:00
2020-03-08 18:24:22 +01:00
searchParamId = gTasks[taskId].tCursorPos_Color + gTasks[taskId].tScrollOffset_Color;
PrintSearchText(sDexSearchColorOptions[searchParamId].title, 0x2D, 0x21);
2018-05-10 09:30:42 +02:00
2020-03-08 18:24:22 +01:00
searchParamId = gTasks[taskId].tCursorPos_TypeLeft + gTasks[taskId].tScrollOffset_TypeLeft;
PrintSearchText(sDexSearchTypeOptions[searchParamId].title, 0x2D, 0x31);
2018-05-10 09:30:42 +02:00
2020-03-08 18:24:22 +01:00
searchParamId = gTasks[taskId].tCursorPos_TypeRight + gTasks[taskId].tScrollOffset_TypeRight;
PrintSearchText(sDexSearchTypeOptions[searchParamId].title, 0x5D, 0x31);
2018-05-10 09:30:42 +02:00
2020-03-08 18:24:22 +01:00
searchParamId = gTasks[taskId].tCursorPos_Order + gTasks[taskId].tScrollOffset_Order;
PrintSearchText(sDexOrderOptions[searchParamId].title, 0x2D, 0x41);
2018-05-10 09:30:42 +02:00
if (IsNationalPokedexEnabled())
{
2020-03-08 18:24:22 +01:00
searchParamId = gTasks[taskId].tCursorPos_Mode + gTasks[taskId].tScrollOffset_Mode;
PrintSearchText(sDexModeOptions[searchParamId].title, 0x2D, 0x51);
2018-05-10 09:30:42 +02:00
}
}
2020-03-08 18:24:22 +01:00
static void DrawOrEraseSearchParameterBox(bool8 erase)
2018-05-10 09:30:42 +02:00
{
u16 i;
u16 j;
u16* ptr = GetBgTilemapBuffer(3);
2020-03-08 18:24:22 +01:00
if (!erase)
2018-05-10 09:30:42 +02:00
{
*(ptr + 0x11) = 0xC0B;
for (i = 0x12; i < 0x1F; i++)
*(ptr + i) = 0x80D;
for (j = 1; j < 13; j++)
{
*(ptr + 0x11 + j * 32) = 0x40A;
for (i = 0x12; i < 0x1F; i++)
*(ptr + j * 32 + i) = 2;
}
*(ptr + 0x1B1) = 0x40B;
for (i = 0x12; i < 0x1F; i++)
*(ptr + 0x1A0 + i) = 0xD;
}
else
{
for (j = 0; j < 14; j++)
{
for (i = 0x11; i < 0x1E; i++)
{
*(ptr + j * 32 + i) = 0x4F;
}
}
}
}
2020-03-08 18:24:22 +01:00
// Prints the currently viewable search parameter titles in the right-hand text box
// and the currently selected search parameter description in the bottom text box
static void PrintSearchParameterText(u8 taskId)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
const struct SearchOptionText *texts = sSearchOptions[gTasks[taskId].tMenuItem].texts;
const u16 *cursorPos = &gTasks[taskId].data[sSearchOptions[gTasks[taskId].tMenuItem].taskDataCursorPos];
const u16 *scrollOffset = &gTasks[taskId].data[sSearchOptions[gTasks[taskId].tMenuItem].taskDataScrollOffset];
2018-05-10 09:30:42 +02:00
u16 i;
u16 j;
2020-03-08 18:24:22 +01:00
ClearSearchParameterBoxText();
for (i = 0, j = *scrollOffset; i < MAX_SEARCH_PARAM_ON_SCREEN && texts[j].title != NULL; i++, j++)
PrintSearchParameterTitle(i, texts[j].title);
EraseAndPrintSearchTextBox(texts[*cursorPos + *scrollOffset].description);
2018-05-10 09:30:42 +02:00
}
2020-01-03 02:35:35 +01:00
static u8 GetSearchModeSelection(u8 taskId, u8 option)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
const u16 *cursorPos = &gTasks[taskId].data[sSearchOptions[option].taskDataCursorPos];
const u16 *scrollOffset = &gTasks[taskId].data[sSearchOptions[option].taskDataScrollOffset];
u16 id = *cursorPos + *scrollOffset;
2018-05-10 09:30:42 +02:00
2020-01-03 02:35:35 +01:00
switch (option)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
default:
return 0;
case SEARCH_MODE:
return sPokedexModes[id];
case SEARCH_ORDER:
return sOrderOptions[id];
case SEARCH_NAME:
if (id == 0)
return 0xFF;
else
return id;
case SEARCH_COLOR:
if (id == 0)
return 0xFF;
else
return id - 1;
case SEARCH_TYPE_LEFT:
case SEARCH_TYPE_RIGHT:
return sDexSearchTypeIds[id];
2018-05-10 09:30:42 +02:00
}
}
2020-03-08 18:24:22 +01:00
static void SetDefaultSearchModeAndOrder(u8 taskId)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
u16 selected;
2018-05-10 09:30:42 +02:00
2020-03-08 18:24:22 +01:00
switch (sPokedexView->dexModeBackup)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
default:
case DEX_MODE_HOENN:
selected = DEX_MODE_HOENN;
break;
case DEX_MODE_NATIONAL:
selected = DEX_MODE_NATIONAL;
break;
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
gTasks[taskId].tCursorPos_Mode = selected;
2018-05-10 09:30:42 +02:00
2020-03-08 18:24:22 +01:00
switch (sPokedexView->dexOrderBackup)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
default:
case ORDER_NUMERICAL:
selected = ORDER_NUMERICAL;
break;
case ORDER_ALPHABETICAL:
selected = ORDER_ALPHABETICAL;
break;
case ORDER_HEAVIEST:
selected = ORDER_HEAVIEST;
break;
case ORDER_LIGHTEST:
selected = ORDER_LIGHTEST;
break;
case ORDER_TALLEST:
selected = ORDER_TALLEST;
break;
case ORDER_SMALLEST:
selected = ORDER_SMALLEST;
break;
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
gTasks[taskId].tCursorPos_Order = selected;
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
static bool8 SearchParamCantScrollUp(u8 taskId)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
u8 menuItem = gTasks[taskId].tMenuItem;
const u16 *scrollOffset = &gTasks[taskId].data[sSearchOptions[menuItem].taskDataScrollOffset];
u16 lastOption = sSearchOptions[menuItem].numOptions - 1;
2018-05-10 09:30:42 +02:00
2020-03-08 18:24:22 +01:00
if (lastOption > MAX_SEARCH_PARAM_CURSOR_POS && *scrollOffset != 0)
2018-05-10 09:30:42 +02:00
return FALSE;
else
return TRUE;
}
2020-03-08 18:24:22 +01:00
static bool8 SearchParamCantScrollDown(u8 taskId)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
u8 menuItem = gTasks[taskId].tMenuItem;
const u16 *scrollOffset = &gTasks[taskId].data[sSearchOptions[menuItem].taskDataScrollOffset];
u16 lastOption = sSearchOptions[menuItem].numOptions - 1;
2018-05-10 09:30:42 +02:00
2020-03-08 18:24:22 +01:00
if (lastOption > MAX_SEARCH_PARAM_CURSOR_POS && *scrollOffset < lastOption - MAX_SEARCH_PARAM_CURSOR_POS)
2018-05-10 09:30:42 +02:00
return FALSE;
else
return TRUE;
}
2020-03-08 18:24:22 +01:00
#define sTaskId data[0]
static void SpriteCB_SearchParameterScrollArrow(struct Sprite *sprite)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
if (gTasks[sprite->sTaskId].func == Task_HandleSearchParameterInput)
2018-05-10 09:30:42 +02:00
{
u8 val;
2020-03-08 18:24:22 +01:00
if (sprite->sIsDownArrow)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
if (SearchParamCantScrollDown(sprite->sTaskId))
2018-05-10 09:30:42 +02:00
sprite->invisible = TRUE;
else
sprite->invisible = FALSE;
}
else
{
2020-03-08 18:24:22 +01:00
if (SearchParamCantScrollUp(sprite->sTaskId))
2018-05-10 09:30:42 +02:00
sprite->invisible = TRUE;
else
sprite->invisible = FALSE;
}
2020-03-08 18:24:22 +01:00
val = sprite->data[2] + sprite->sIsDownArrow * 128;
2018-05-10 09:30:42 +02:00
sprite->pos2.y = gSineTable[val] / 128;
sprite->data[2] += 8;
}
else
{
sprite->invisible = TRUE;
}
}
2020-03-08 18:24:22 +01:00
static void CreateSearchParameterScrollArrows(u8 taskId)
2018-05-10 09:30:42 +02:00
{
u8 spriteId;
2020-03-08 18:24:22 +01:00
spriteId = CreateSprite(&sScrollArrowSpriteTemplate, 184, 4, 0);
gSprites[spriteId].sTaskId = taskId;
gSprites[spriteId].sIsDownArrow = FALSE;
gSprites[spriteId].callback = SpriteCB_SearchParameterScrollArrow;
2018-05-10 09:30:42 +02:00
2020-03-08 18:24:22 +01:00
spriteId = CreateSprite(&sScrollArrowSpriteTemplate, 184, 108, 0);
gSprites[spriteId].sTaskId = taskId;
gSprites[spriteId].sIsDownArrow = TRUE;
2018-05-10 09:30:42 +02:00
gSprites[spriteId].vFlip = TRUE;
2020-03-08 18:24:22 +01:00
gSprites[spriteId].callback = SpriteCB_SearchParameterScrollArrow;
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
#undef sTaskId
#undef sIsDownArrow
static void EraseAndPrintSearchTextBox(const u8* str)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
ClearSearchMenuRect(8, 120, 224, 32);
PrintSearchText(str, 8, 121);
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
static void EraseSelectorArrow(u32 y)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
ClearSearchMenuRect(144, y * 16 + 8, 8, 16);
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
static void PrintSelectorArrow(u32 y)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
PrintSearchText(gText_SelectorArrow, 144, y * 16 + 9);
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
static void PrintSearchParameterTitle(u32 y, const u8* str)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
PrintSearchText(str, 152, y * 16 + 9);
2018-05-10 09:30:42 +02:00
}
2020-03-08 18:24:22 +01:00
static void ClearSearchParameterBoxText(void)
2018-05-10 09:30:42 +02:00
{
2020-03-08 18:24:22 +01:00
ClearSearchMenuRect(144, 8, 96, 96);
2018-05-10 09:30:42 +02:00
}