pokefirered/src/pokedex_screen.c
cawtds 395e4d0cb6 seperated kanto dex from national dex
included cross generational evolutions in kanto dex
removed debug prints
2024-04-27 02:03:51 +02:00

3461 lines
122 KiB
C

#include "global.h"
#include "gflib.h"
#include "graphics.h"
#include "m4a.h"
#include "scanline_effect.h"
#include "task.h"
#include "new_menu_helpers.h"
#include "event_data.h"
#include "help_system.h"
#include "menu_indicators.h"
#include "overworld.h"
#include "strings.h"
#include "menu.h"
#include "pokedex_screen.h"
#include "data.h"
#include "pokedex.h"
#include "trainer_pokemon_sprites.h"
#include "decompress.h"
#include "constants/songs.h"
#include "constants/sound.h"
#include "pokedex_area_markers.h"
#include "field_specials.h"
#define TAG_AREA_MARKERS 2001
enum TextMode {
TEXT_LEFT,
TEXT_CENTER,
TEXT_RIGHT
};
struct PokedexScreenData
{
u8 taskId;
u8 state;
u8 data[2];
u8 areaMarkersTaskId;
u32 unlockedCategories;
u32 modeSelectInput;
u16 modeSelectItemsAbove;
u16 modeSelectCursorPos;
u8 modeSelectWindowId;
u8 selectionIconWindowId;
u8 dexCountsWindowId;
u8 modeSelectListMenuId;
u16 pageSpecies[4];
u8 categoryMonWindowIds[4];
u8 categoryMonInfoWindowIds[4];
u8 category;
u8 firstPageInCategory;
u8 lastPageInCategory;
u8 pageNum;
u8 numMonsOnPage;
u8 categoryCursorPosInPage;
u8 categoryPageSelectionCursorTimer;
u8 parentOfCategoryMenu;
u32 characteristicMenuInput;
u16 kantoOrderMenuItemsAbove;
u16 kantoOrderMenuCursorPos;
u16 characteristicOrderMenuItemsAbove;
u16 characteristicOrderMenuCursorPos;
u16 nationalOrderMenuItemsAbove;
u16 nationalOrderMenuCursorPos;
u8 numericalOrderWindowId;
u8 orderedListMenuTaskId;
u8 dexOrderId;
struct ListMenuItem * listItems;
u16 orderedDexCount;
u8 windowIds[0x10];
u16 dexSpecies;
u16 * bgBufsMem;
u8 scrollArrowsTaskId;
u8 categoryPageCursorTaskId;
u16 modeSelectCursorPosBak;
u8 unlockedSeviiAreas;
u16 numSeenKanto;
u16 numOwnedKanto;
u16 numSeenNational;
u16 numOwnedNational;
};
struct PokedexScreenWindowGfx
{
const u32 * tiles;
const u16 * pal;
};
struct PokedexCategoryPage
{
const u16 * species;
u8 count;
};
EWRAM_DATA static struct PokedexScreenData * sPokedexScreenData = NULL;
static void Task_PokedexScreen(u8 taskId);
static void DexScreen_InitGfxForTopMenu(void);
static void Task_DexScreen_NumericalOrder(u8 taskId);
static void DexScreen_InitGfxForNumericalOrderList(void);
static void Task_DexScreen_CharacteristicOrder(u8 taskId);
static void DexScreen_CreateCharacteristicListMenu(void);
static u16 DexScreen_CountMonsInOrderedList(u8 orderIdx);
static void DexScreen_InitListMenuForOrderedList(const struct ListMenuTemplate * template, u8 order);
static u8 DexScreen_CreateDexOrderScrollArrows(void);
static void DexScreen_DestroyDexOrderListMenu(u8 order);
static void Task_DexScreen_CategorySubmenu(u8 taskId);
static u8 DexScreen_CreateCategoryMenuScrollArrows(void);
static int DexScreen_InputHandler_GetShoulderInput(void);
static void Task_DexScreen_ShowMonPage(u8 taskId);
static bool32 DexScreen_TryScrollMonsVertical(u8 direction);
static void DexScreen_RemoveWindow(u8 *windowId_p);
static void DexScreen_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 *str, u8 x, u8 y, u8 colorIdx);
static void DexScreen_PrintNum3RightAlign(u8 windowId, u8 fontId, u16 num, u8 x, u8 y, u8 colorIdx);
static void DexScreen_PrintMonDexNo(u8 windowId, u8 fontId, u16 species, u8 x, u8 y);
static u16 DexScreen_GetDexCount(u8 caseId, bool8 whichDex);
static void DexScreen_PrintControlInfo(const u8 *src);
static void DexScreen_DestroyCategoryPageMonIconAndInfoWindows(void);
static bool8 DexScreen_CreateCategoryListGfx(bool8 justRegistered);
static void DexScreen_CreateCategoryPageSelectionCursor(u8 cursorPos);
static void DexScreen_UpdateCategoryPageCursorObject(u8 taskId, u8 cursorPos, u8 numMonsInPage);
static bool8 DexScreen_FlipCategoryPageInDirection(u8 direction);
void DexScreen_DexPageZoomEffectFrame(u8 bg, u8 scale);
static u8 DexScreen_DrawMonDexPage(bool8 justRegistered);
u8 RemoveDexPageWindows(void);
u8 DexScreen_DrawMonAreaPage(void);
static bool8 DexScreen_IsPageUnlocked(u8 category, u8 pageNum);
static bool8 DexScreen_IsCategoryUnlocked(u8 category);
static u8 DexScreen_GetPageLimitsForCategory(u8 category);
static bool8 DexScreen_LookUpCategoryBySpecies(u16 species);
u8 DexScreen_DestroyAreaScreenResources(void);
void DexScreen_CreateCategoryPageSpeciesList(u8 category, u8 pageNum);
static u8 DexScreen_PageNumberToRenderablePages(u16 page);
void DexScreen_InputHandler_StartToCry(void);
void DexScreen_PrintStringWithAlignment(const u8 *str, s32 mode);
static void MoveCursorFunc_DexModeSelect(s32 itemIndex, bool8 onInit, struct ListMenu *list);
static void ItemPrintFunc_DexModeSelect(u8 windowId, u32 itemId, u8 y);
static void ItemPrintFunc_OrderedListMenu(u8 windowId, u32 itemId, u8 y);
static void Task_DexScreen_RegisterNonKantoMonBeforeNationalDex(u8 taskId);
static void Task_DexScreen_RegisterMonToPokedex(u8 taskId);
#include "data/pokemon_graphics/footprint_table.h"
const u32 sCategoryMonInfoBgTiles[] = INCBIN_U32("graphics/pokedex/mini_page.4bpp.lz");
const u32 sKantoDexTiles[] = INCBIN_U32("graphics/pokedex/kanto_dex_bgtiles.4bpp.lz");
const u32 sNatDexTiles[] = INCBIN_U32("graphics/pokedex/national_dex_bgtiles.4bpp.lz");
const u16 sKantoDexPalette[0x100] = INCBIN_U16("graphics/pokedex/kanto_dex_bgpals.gbapal");
const u16 sDexScreen_CategoryCursorPals[] = {
RGB(24, 22, 17), RGB(26, 24, 20),
RGB(26, 20, 15), RGB(27, 23, 19),
RGB(28, 18, 15), RGB(28, 22, 19),
RGB(30, 16, 13), RGB(29, 21, 18),
RGB(28, 18, 15), RGB(28, 22, 19),
RGB(26, 20, 15), RGB(27, 23, 19)
};
const u16 sNationalDexPalette[0x100] = INCBIN_U16("graphics/pokedex/national_dex_bgpals.gbapal");
const u32 sTopMenuIconTiles_Cave[] = INCBIN_U32("graphics/pokedex/cat_icon_cave.4bpp.lz");
const u32 sTopMenuIconTiles_Urban[] = INCBIN_U32("graphics/pokedex/cat_icon_urban.4bpp.lz");
const u32 sTopMenuSelectionIconTiles_Cancel[] = INCBIN_U32("graphics/pokedex/cat_icon_cancel.4bpp.lz");
const u32 sTopMenuIconTiles_Forest[] = INCBIN_U32("graphics/pokedex/cat_icon_forest.4bpp.lz");
const u32 sTopMenuIconTiles_Grassland[] = INCBIN_U32("graphics/pokedex/cat_icon_grassland.4bpp.lz");
const u32 sTopMenuIconTiles_QuestionMark[] = INCBIN_U32("graphics/pokedex/cat_icon_qmark.4bpp.lz");
const u32 sTopMenuIconTiles_Mountain[] = INCBIN_U32("graphics/pokedex/cat_icon_mountain.4bpp.lz");
const u32 sTopMenuIconTiles_Rare[] = INCBIN_U32("graphics/pokedex/cat_icon_rare.4bpp.lz");
const u32 sTopMenuIconTiles_Sea[] = INCBIN_U32("graphics/pokedex/cat_icon_sea.4bpp.lz");
const u32 sTopMenuIconTiles_Numerical[] = INCBIN_U32("graphics/pokedex/cat_icon_numerical.4bpp.lz");
const u32 sTopMenuIconTiles_RoughTerrain[] = INCBIN_U32("graphics/pokedex/cat_icon_rough_terrain.4bpp.lz");
const u32 sTopMenuIconTiles_WatersEdge[] = INCBIN_U32("graphics/pokedex/cat_icon_waters_edge.4bpp.lz");
const u32 sTopMenuIconTiles_Type[] = INCBIN_U32("graphics/pokedex/cat_icon_type.4bpp.lz");
const u32 sTopMenuIconTiles_Lightest[] = INCBIN_U32("graphics/pokedex/cat_icon_lightest.4bpp.lz");
const u32 sTopMenuIconTiles_Smallest[] = INCBIN_U32("graphics/pokedex/cat_icon_smallest.4bpp.lz");
const u16 sTopMenuIconPals_Cave[] = INCBIN_U16("graphics/pokedex/cat_icon_cave.gbapal");
const u16 sTopMenuIconPals_Urban[] = INCBIN_U16("graphics/pokedex/cat_icon_urban.gbapal");
const u16 sTopMenuSelectionIconPals_Cancel[] = INCBIN_U16("graphics/pokedex/cat_icon_cancel.gbapal");
const u16 sTopMenuIconPals_Forest[] = INCBIN_U16("graphics/pokedex/cat_icon_forest.gbapal");
const u16 sTopMenuIconPals_Grassland[] = INCBIN_U16("graphics/pokedex/cat_icon_grassland.gbapal");
const u16 sTopMenuIconPals_QuestionMark[] = INCBIN_U16("graphics/pokedex/cat_icon_qmark.gbapal");
const u16 sTopMenuIconPals_Mountain[] = INCBIN_U16("graphics/pokedex/cat_icon_mountain.gbapal");
const u16 sTopMenuIconPals_Rare[] = INCBIN_U16("graphics/pokedex/cat_icon_rare.gbapal");
const u16 sTopMenuIconPals_Sea[] = INCBIN_U16("graphics/pokedex/cat_icon_sea.gbapal");
const u16 sTopMenuIconPals_Numerical[] = INCBIN_U16("graphics/pokedex/cat_icon_numerical.gbapal");
const u16 sTopMenuIconPals_RoughTerrain[] = INCBIN_U16("graphics/pokedex/cat_icon_rough_terrain.gbapal");
const u16 sTopMenuIconPals_WatersEdge[] = INCBIN_U16("graphics/pokedex/cat_icon_waters_edge.gbapal");
const u16 sTopMenuIconPals_Type[] = INCBIN_U16("graphics/pokedex/cat_icon_type.gbapal");
const u16 sTopMenuIconPals_Lightest[] = INCBIN_U16("graphics/pokedex/cat_icon_lightest.gbapal");
const u16 sTopMenuIconPals_Smallest[] = INCBIN_U16("graphics/pokedex/cat_icon_smallest.gbapal");
const u8 sDexScreen_CaughtIcon[] = INCBIN_U8("graphics/pokedex/caught_marker.4bpp");
const u32 sTilemap_AreaMap_Kanto[] = INCBIN_U32("graphics/pokedex/map_kanto.4bpp.lz");
const u32 sTilemap_AreaMap_OneIsland[] = INCBIN_U32("graphics/pokedex/map_one_island.4bpp.lz");
const u32 sTilemap_AreaMap_TwoIsland[] = INCBIN_U32("graphics/pokedex/map_two_island.4bpp.lz");
const u32 sTilemap_AreaMap_ThreeIsland[] = INCBIN_U32("graphics/pokedex/map_three_island.4bpp.lz");
const u32 sTilemap_AreaMap_FourIsland[] = INCBIN_U32("graphics/pokedex/map_four_island.4bpp.lz");
const u32 sTilemap_AreaMap_FiveIsland[] = INCBIN_U32("graphics/pokedex/map_five_island.4bpp.lz");
const u32 sTilemap_AreaMap_SixIsland[] = INCBIN_U32("graphics/pokedex/map_six_island.4bpp.lz");
const u32 sTilemap_AreaMap_SevenIsland[] = INCBIN_U32("graphics/pokedex/map_seven_island.4bpp.lz");
const u16 sBlitTiles_WideEllipse[] = INCBIN_U16("graphics/pokedex/blit_wide_ellipse.4bpp");
#include "data/pokemon/pokedex_orders.h"
static const u8 gExpandedPlaceholder_PokedexDescription[] = _("");
#include "data/pokemon/pokedex_text.h"
#include "data/pokemon/pokedex_entries.h"
static const struct BgTemplate sBgTemplates[] = {
{
.bg = 0,
.charBaseIndex = 0,
.mapBaseIndex = 5,
.screenSize = 0,
.paletteMode = 0,
.priority = 0,
.baseTile = 0x0000
},
{
.bg = 1,
.charBaseIndex = 2,
.mapBaseIndex = 4,
.screenSize = 0,
.paletteMode = 0,
.priority = 1,
.baseTile = 0x0000
},
{
.bg = 2,
.charBaseIndex = 2,
.mapBaseIndex = 6,
.screenSize = 0,
.paletteMode = 0,
.priority = 2,
.baseTile = 0x0000
},
{
.bg = 3,
.charBaseIndex = 0,
.mapBaseIndex = 7,
.screenSize = 0,
.paletteMode = 0,
.priority = 3,
.baseTile = 0x0000
},
};
static const struct WindowTemplate sWindowTemplates[] = {
{
.bg = 0,
.tilemapLeft = 0,
.tilemapTop = 0,
.width = 30,
.height = 2,
.paletteNum = 15,
.baseBlock = 0x03c4
},
{
.bg = 0,
.tilemapLeft = 0,
.tilemapTop = 18,
.width = 30,
.height = 2,
.paletteNum = 15,
.baseBlock = 0x0388
},
{
.bg = 255,
.tilemapLeft = 0,
.tilemapTop = 0,
.width = 0,
.height = 0,
.paletteNum = 0,
.baseBlock = 0x0000
},
};
static const struct PokedexScreenData sDexScreenDataInitialState = {
.modeSelectItemsAbove = 1,
.modeSelectWindowId = -1,
.selectionIconWindowId = -1,
.dexCountsWindowId = -1,
.pageSpecies = {-1, -1, -1, -1},
.categoryMonWindowIds = {-1, -1, -1, -1},
.categoryMonInfoWindowIds = {-1, -1, -1, -1},
.numericalOrderWindowId = -1,
.windowIds = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
.scrollArrowsTaskId = -1,
.categoryPageCursorTaskId = -1,
};
static const struct WindowTemplate sWindowTemplate_ModeSelect = {
.bg = 1,
.tilemapLeft = 1,
.tilemapTop = 2,
.width = 20,
.height = 16,
.paletteNum = 0,
.baseBlock = 0x0008
};
static const struct WindowTemplate sWindowTemplate_SelectionIcon = {
.bg = 1,
.tilemapLeft = 21,
.tilemapTop = 11,
.width = 8,
.height = 6,
.paletteNum = 1,
.baseBlock = 0x0148
};
static const struct WindowTemplate sWindowTemplate_DexCounts = {
.bg = 1,
.tilemapLeft = 21,
.tilemapTop = 2,
.width = 9,
.height = 9,
.paletteNum = 0,
.baseBlock = 0x0178
};
static const struct ListMenuItem sListMenuItems_KantoDexModeSelect[] = {
{gText_PokemonList, LIST_HEADER},
{gText_NumericalMode, DEX_MODE(NUMERICAL_KANTO)},
{gText_PokemonHabitats, LIST_HEADER},
{gText_DexCategory_GrasslandPkmn, DEX_CATEGORY_GRASSLAND},
{gText_DexCategory_ForestPkmn, DEX_CATEGORY_FOREST},
{gText_DexCategory_WatersEdgePkmn, DEX_CATEGORY_WATERS_EDGE},
{gText_DexCategory_SeaPkmn, DEX_CATEGORY_SEA},
{gText_DexCategory_CavePkmn, DEX_CATEGORY_CAVE},
{gText_DexCategory_MountainPkmn, DEX_CATEGORY_MOUNTAIN},
{gText_DexCategory_RoughTerrainPkmn, DEX_CATEGORY_ROUGH_TERRAIN},
{gText_DexCategory_UrbanPkmn, DEX_CATEGORY_URBAN},
{gText_DexCategory_RarePkmn, DEX_CATEGORY_RARE},
{gText_Search, LIST_HEADER},
{gText_AToZMode, DEX_MODE(ATOZ)},
{gText_TypeMode, DEX_MODE(TYPE)},
{gText_LightestMode, DEX_MODE(LIGHTEST)},
{gText_SmallestMode, DEX_MODE(SMALLEST)},
{gText_PokedexOther, LIST_HEADER},
{gText_ClosePokedex, LIST_CANCEL},
};
static const struct ListMenuTemplate sListMenuTemplate_KantoDexModeSelect = {
.items = sListMenuItems_KantoDexModeSelect,
.moveCursorFunc = MoveCursorFunc_DexModeSelect,
.itemPrintFunc = ItemPrintFunc_DexModeSelect,
.totalItems = NELEMS(sListMenuItems_KantoDexModeSelect),
.maxShowed = 9,
.windowId = 0,
.header_X = 0,
.item_X = 12,
.cursor_X = 4,
.upText_Y = 2,
.cursorPal = 1,
.fillValue = 0,
.cursorShadowPal = 3,
.lettersSpacing = 1,
.itemVerticalPadding = 0,
.scrollMultiple = 0,
.fontId = FONT_NORMAL,
.cursorKind = 0,
};
static const struct ListMenuItem sListMenuItems_NatDexModeSelect[] = {
{gText_PokemonList, LIST_HEADER},
{gText_NumericalModeKanto, DEX_MODE(NUMERICAL_KANTO)},
{gText_NumericalModeNational, DEX_MODE(NUMERICAL_NATIONAL)},
{gText_PokemonHabitats, LIST_HEADER},
{gText_DexCategory_GrasslandPkmn, DEX_CATEGORY_GRASSLAND},
{gText_DexCategory_ForestPkmn, DEX_CATEGORY_FOREST},
{gText_DexCategory_WatersEdgePkmn, DEX_CATEGORY_WATERS_EDGE},
{gText_DexCategory_SeaPkmn, DEX_CATEGORY_SEA},
{gText_DexCategory_CavePkmn, DEX_CATEGORY_CAVE},
{gText_DexCategory_MountainPkmn, DEX_CATEGORY_MOUNTAIN},
{gText_DexCategory_RoughTerrainPkmn, DEX_CATEGORY_ROUGH_TERRAIN},
{gText_DexCategory_UrbanPkmn, DEX_CATEGORY_URBAN},
{gText_DexCategory_RarePkmn, DEX_CATEGORY_RARE},
{gText_Search, LIST_HEADER},
{gText_AToZMode, DEX_MODE(ATOZ)},
{gText_TypeMode, DEX_MODE(TYPE)},
{gText_LightestMode, DEX_MODE(LIGHTEST)},
{gText_SmallestMode, DEX_MODE(SMALLEST)},
{gText_PokedexOther, LIST_HEADER},
{gText_ClosePokedex, LIST_CANCEL},
};
static const struct ListMenuTemplate sListMenuTemplate_NatDexModeSelect = {
.items = sListMenuItems_NatDexModeSelect,
.moveCursorFunc = MoveCursorFunc_DexModeSelect,
.itemPrintFunc = ItemPrintFunc_DexModeSelect,
.totalItems = NELEMS(sListMenuItems_NatDexModeSelect),
.maxShowed = 9,
.windowId = 0,
.header_X = 0,
.item_X = 12,
.cursor_X = 4,
.upText_Y = 2,
.cursorPal = 1,
.fillValue = 0,
.cursorShadowPal = 3,
.lettersSpacing = 1,
.itemVerticalPadding = 0,
.scrollMultiple = 0,
.fontId = FONT_NORMAL,
.cursorKind = 0,
};
static const struct ScrollArrowsTemplate sScrollArrowsTemplate_KantoDex = {
.firstArrowType = 2,
.firstX = 200,
.firstY = 19,
.secondArrowType = 3,
.secondX = 200,
.secondY = 141,
.fullyUpThreshold = 0,
.fullyDownThreshold = 10,
.tileTag = 2000,
.palTag = 0xFFFF,
.palNum = 1
};
static const struct ScrollArrowsTemplate sScrollArrowsTemplate_NatDex = {
.firstArrowType = 2,
.firstX = 200,
.firstY = 19,
.secondArrowType = 3,
.secondX = 200,
.secondY = 141,
.fullyUpThreshold = 0,
.fullyDownThreshold = 11,
.tileTag = 2000,
.palTag = 0xFFFF,
.palNum = 1
};
static const struct PokedexScreenWindowGfx sTopMenuSelectionIconGfxPtrs[] = {
[DEX_CATEGORY_GRASSLAND] = {
.tiles = sTopMenuIconTiles_Grassland,
.pal = sTopMenuIconPals_Grassland
},
[DEX_CATEGORY_FOREST] = {
.tiles = sTopMenuIconTiles_Forest,
.pal = sTopMenuIconPals_Forest
},
[DEX_CATEGORY_WATERS_EDGE] = {
.tiles = sTopMenuIconTiles_WatersEdge,
.pal = sTopMenuIconPals_WatersEdge
},
[DEX_CATEGORY_SEA] = {
.tiles = sTopMenuIconTiles_Sea,
.pal = sTopMenuIconPals_Sea
},
[DEX_CATEGORY_CAVE] = {
.tiles = sTopMenuIconTiles_Cave,
.pal = sTopMenuIconPals_Cave
},
[DEX_CATEGORY_MOUNTAIN] = {
.tiles = sTopMenuIconTiles_Mountain,
.pal = sTopMenuIconPals_Mountain
},
[DEX_CATEGORY_ROUGH_TERRAIN] = {
.tiles = sTopMenuIconTiles_RoughTerrain,
.pal = sTopMenuIconPals_RoughTerrain
},
[DEX_CATEGORY_URBAN] = {
.tiles = sTopMenuIconTiles_Urban,
.pal = sTopMenuIconPals_Urban
},
[DEX_CATEGORY_RARE] = {
.tiles = sTopMenuIconTiles_Rare,
.pal = sTopMenuIconPals_Rare
},
[DEX_MODE(NUMERICAL_KANTO)] = {
.tiles = sTopMenuIconTiles_Numerical,
.pal = sTopMenuIconPals_Numerical
},
[DEX_MODE(ATOZ)] = {
.tiles = gDexScreen_TopMenuIconTiles_AtoZ,
.pal = gDexScreen_TopMenuIconPals_AtoZ
},
[DEX_MODE(TYPE)] = {
.tiles = sTopMenuIconTiles_Type,
.pal = sTopMenuIconPals_Type
},
[DEX_MODE(LIGHTEST)] = {
.tiles = sTopMenuIconTiles_Lightest,
.pal = sTopMenuIconPals_Lightest
},
[DEX_MODE(SMALLEST)] = {
.tiles = sTopMenuIconTiles_Smallest,
.pal = sTopMenuIconPals_Smallest
},
[DEX_MODE(NUMERICAL_NATIONAL)] = {
.tiles = sTopMenuIconTiles_Numerical,
.pal = sTopMenuIconPals_Numerical
},
};
static const struct WindowTemplate sWindowTemplate_OrderedListMenu = {
.bg = 1,
.tilemapLeft = 2,
.tilemapTop = 2,
.width = 23,
.height = 16,
.paletteNum = 0,
.baseBlock = 0x0008
};
static const struct ListMenuTemplate sListMenuTemplate_OrderedListMenu = {
.items = sListMenuItems_KantoDexModeSelect,
.moveCursorFunc = ListMenuDefaultCursorMoveFunc,
.itemPrintFunc = ItemPrintFunc_OrderedListMenu,
.totalItems = 0,
.maxShowed = 9,
.windowId = 0,
.header_X = 0,
.item_X = 56,
.cursor_X = 4,
.upText_Y = 2,
.cursorPal = 1,
.fillValue = 0,
.cursorShadowPal = 3,
.lettersSpacing = 1,
.itemVerticalPadding = 0,
.scrollMultiple = 1,
.fontId = FONT_NORMAL,
.cursorKind = 0,
};
static const struct ListMenuWindowRect sListMenuRects_OrderedList[] = {
{
.x = 0,
.y = 0,
.width = 5,
.height = 16,
.palNum = 0
}, {
.x = 5,
.y = 0,
.width = 2,
.height = 16,
.palNum = 1
}, {
.x = 7,
.y = 0,
.width = 8,
.height = 16,
.palNum = 0
}, {
.x = 15,
.y = 0,
.width = 8,
.height = 16,
.palNum = 2,
}, {
.x = 0xFF,
.y = 0xFF,
.width = 0xFF,
.height = 0xFF,
.palNum = 0xFF
}
};
static const struct ScrollArrowsTemplate sDexOrderScrollArrowsTemplate = {
.firstArrowType = 2,
.firstX = 200,
.firstY = 19,
.secondArrowType = 3,
.secondX = 200,
.secondY = 141,
.fullyUpThreshold = 0,
.fullyDownThreshold = 0,
.tileTag = 2000,
.palTag = 0xFFFF,
.palNum = 1,
};
static const struct WindowTemplate sWindowTemplate_CategoryMonIcon = {
.bg = 2,
.tilemapLeft = 0,
.tilemapTop = 0,
.width = 8,
.height = 8,
.paletteNum = 0,
.baseBlock = 0x0000
};
static const struct WindowTemplate sWindowTemplate_CategoryMonInfo = {
.bg = 1,
.tilemapLeft = 0,
.tilemapTop = 0,
.width = 8,
.height = 5,
.paletteNum = 0,
.baseBlock = 0x0000
};
const struct WindowTemplate sWindowTemplate_DexEntry_MonPic = {
.bg = 1,
.tilemapLeft = 19,
.tilemapTop = 3,
.width = 8,
.height = 8,
.paletteNum = 9,
.baseBlock = 0x01a8
};
const struct WindowTemplate sWindowTemplate_DexEntry_SpeciesStats = {
.bg = 1,
.tilemapLeft = 2,
.tilemapTop = 3,
.width = 13,
.height = 8,
.paletteNum = 0,
.baseBlock = 0x01e8
};
const struct WindowTemplate sWindowTemplate_DexEntry_FlavorText = {
.bg = 1,
.tilemapLeft = 0,
.tilemapTop = 11,
.width = 30,
.height = 7,
.paletteNum = 0,
.baseBlock = 0x0250
};
const struct WindowTemplate sWindowTemplate_AreaMap_MonIcon = {
.bg = 2,
.tilemapLeft = 1,
.tilemapTop = 2,
.width = 4,
.height = 4,
.paletteNum = 10,
.baseBlock = 0x01a8
};
const struct WindowTemplate sWindowTemplate_AreaMap_SpeciesName = {
.bg = 2,
.tilemapLeft = 5,
.tilemapTop = 2,
.width = 8,
.height = 3,
.paletteNum = 0,
.baseBlock = 0x01b8
};
const struct WindowTemplate sWindowTemplate_AreaMap_Size = {
.bg = 2,
.tilemapLeft = 2,
.tilemapTop = 7,
.width = 10,
.height = 2,
.paletteNum = 0,
.baseBlock = 0x01d0
};
const struct WindowTemplate sWindowTemplate_AreaMap_Area = {
.bg = 2,
.tilemapLeft = 18,
.tilemapTop = 2,
.width = 10,
.height = 2,
.paletteNum = 0,
.baseBlock = 0x01e4
};
const struct WindowTemplate sWindowTemplate_AreaMap_MonTypes = {
.bg = 2,
.tilemapLeft = 5,
.tilemapTop = 5,
.width = 8,
.height = 2,
.paletteNum = 11,
.baseBlock = 0x01f8
};
const struct WindowTemplate sWindowTemplate_AreaMap_Kanto = {
.bg = 2,
.tilemapLeft = 17,
.tilemapTop = 4,
.width = 12,
.height = 9,
.paletteNum = 0,
.baseBlock = 0x0208
};
static const struct WindowTemplate sWindowTemplate_AreaMap_OneIsland = {
.bg = 2,
.tilemapLeft = 13,
.tilemapTop = 4,
.width = 4,
.height = 3,
.paletteNum = 0,
.baseBlock = 0x0274
};
static const struct WindowTemplate sWindowTemplate_AreaMap_TwoIsland = {
.bg = 2,
.tilemapLeft = 13,
.tilemapTop = 7,
.width = 4,
.height = 3,
.paletteNum = 0,
.baseBlock = 0x0280
};
static const struct WindowTemplate sWindowTemplate_AreaMap_ThreeIsland = {
.bg = 2,
.tilemapLeft = 13,
.tilemapTop = 10,
.width = 4,
.height = 3,
.paletteNum = 0,
.baseBlock = 0x028c
};
static const struct WindowTemplate sWindowTemplate_AreaMap_FourIsland = {
.bg = 2,
.tilemapLeft = 13,
.tilemapTop = 13,
.width = 4,
.height = 4,
.paletteNum = 0,
.baseBlock = 0x0298
};
static const struct WindowTemplate sWindowTemplate_AreaMap_FiveIsland = {
.bg = 2,
.tilemapLeft = 17,
.tilemapTop = 13,
.width = 4,
.height = 4,
.paletteNum = 0,
.baseBlock = 0x02a8
};
static const struct WindowTemplate sWindowTemplate_AreaMap_SixIsland = {
.bg = 2,
.tilemapLeft = 21,
.tilemapTop = 13,
.width = 4,
.height = 4,
.paletteNum = 0,
.baseBlock = 0x02b8
};
static const struct WindowTemplate sWindowTemplate_AreaMap_SevenIsland = {
.bg = 2,
.tilemapLeft = 25,
.tilemapTop = 13,
.width = 4,
.height = 4,
.paletteNum = 0,
.baseBlock = 0x02c8
};
struct {
const struct WindowTemplate * window;
const u32 * tiles;
} const sAreaMapStructs_SeviiIslands[] = {
{&sWindowTemplate_AreaMap_OneIsland, sTilemap_AreaMap_OneIsland},
{&sWindowTemplate_AreaMap_TwoIsland, sTilemap_AreaMap_TwoIsland},
{&sWindowTemplate_AreaMap_ThreeIsland, sTilemap_AreaMap_ThreeIsland},
{&sWindowTemplate_AreaMap_FourIsland, sTilemap_AreaMap_FourIsland},
{&sWindowTemplate_AreaMap_FiveIsland, sTilemap_AreaMap_FiveIsland},
{&sWindowTemplate_AreaMap_SixIsland, sTilemap_AreaMap_SixIsland},
{&sWindowTemplate_AreaMap_SevenIsland, sTilemap_AreaMap_SevenIsland},
};
static const u16 sCategoryPageIconWindowBg[] = INCBIN_U16("graphics/pokedex/page_icon_tilemap.bin");
// Circular window x/y; Rectangular window x/y
static const u8 sPageIconCoords_1Mon[1][4] = {
{11, 3, 11, 11},
};
static const u8 sPageIconCoords_2Mons[2][4] = {
{ 3, 3, 11, 3},
{18, 9, 10, 11},
};
static const u8 sPageIconCoords_3Mons[3][4] = {
{ 1, 2, 9, 2},
{11, 9, 3, 11},
{21, 3, 21, 11}
};
static const u8 sPageIconCoords_4Mons[4][4] = {
{ 0, 2, 6, 3},
{ 7, 10, 0, 12},
{15, 10, 22, 11},
{22, 2, 15, 4}
};
const u8 (*const sCategoryPageIconCoords[])[4] = {
sPageIconCoords_1Mon,
sPageIconCoords_2Mons,
sPageIconCoords_3Mons,
sPageIconCoords_4Mons,
};
static const u8 *const sDexCategoryNamePtrs[] = {
gText_DexCategory_GrasslandPkmn,
gText_DexCategory_ForestPkmn,
gText_DexCategory_WatersEdgePkmn,
gText_DexCategory_SeaPkmn,
gText_DexCategory_CavePkmn,
gText_DexCategory_MountainPkmn,
gText_DexCategory_RoughTerrainPkmn,
gText_DexCategory_UrbanPkmn,
gText_DexCategory_RarePkmn,
};
const u16 sPalette_Silhouette[] = INCBIN_U16("graphics/pokedex/silhouette_sprite_pal.gbapal");
static const u8 sDexScreenPageTurnColumns[][30] = {
{30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},
{ 5, 11, 17, 23, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},
{ 2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},
{ 2, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},
{ 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},
{ 1, 2, 3, 4, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 19, 20, 21, 23, 24, 25, 27, 28, 29, 30, 30, 30, 30, 30, 30, 30},
{ 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 25, 26, 27, 28, 29, 30, 30, 30, 30},
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 30, 30},
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30},
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29},
};
static const struct ScrollArrowsTemplate sScrollArrowsTemplate_CategoryMenu = {
.firstArrowType = 0,
.firstX = 16,
.firstY = 80,
.secondArrowType = 1,
.secondX = 224,
.secondY = 80,
.fullyUpThreshold = 0,
.fullyDownThreshold = 0,
.tileTag = 2000,
.palTag = 0xFFFF,
.palNum = 1,
};
const struct CursorStruct sCursorStruct_CategoryPage = {
.left = 0,
.top = 160,
.rowWidth = 64,
.rowHeight = 40,
.tileTag = 2002,
.palTag = 0xFFFF,
.palNum = 4,
};
#include "data/pokemon/pokedex_categories.h"
void VBlankCB(void)
{
LoadOam();
ProcessSpriteCopyRequests();
TransferPlttBuffer();
}
void CB2_PokedexScreen(void)
{
if (!gPaletteFade.active || IsDma3ManagerBusyWithBgCopy())
{
RunTasks();
RunTextPrinters();
AnimateSprites();
BuildOamBuffer();
}
else
{
UpdatePaletteFade();
}
}
void DexScreen_LoadResources(void)
{
bool8 natDex;
u8 taskId;
natDex = IsNationalPokedexEnabled();
m4aSoundVSyncOff();
SetVBlankCallback(NULL);
ResetPaletteFade();
ResetSpriteData();
ResetTasks();
ScanlineEffect_Stop();
ResetBgsAndClearDma3BusyFlags(TRUE);
InitBgsFromTemplates(0, sBgTemplates, NELEMS(sBgTemplates));
SetBgTilemapBuffer(3, (u16 *)Alloc(BG_SCREEN_SIZE));
SetBgTilemapBuffer(2, (u16 *)Alloc(BG_SCREEN_SIZE));
SetBgTilemapBuffer(1, (u16 *)Alloc(BG_SCREEN_SIZE));
SetBgTilemapBuffer(0, (u16 *)Alloc(BG_SCREEN_SIZE));
if (natDex)
DecompressAndLoadBgGfxUsingHeap(3, (void *)sNatDexTiles, BG_SCREEN_SIZE, 0, 0);
else
DecompressAndLoadBgGfxUsingHeap(3, (void *)sKantoDexTiles, BG_SCREEN_SIZE, 0, 0);
InitWindows(sWindowTemplates);
DeactivateAllTextPrinters();
m4aSoundVSyncOn();
SetVBlankCallback(VBlankCB);
EnableInterrupts(INTR_FLAG_VBLANK);
taskId = CreateTask(Task_PokedexScreen, 0);
sPokedexScreenData = Alloc(sizeof(struct PokedexScreenData));
*sPokedexScreenData = sDexScreenDataInitialState;
sPokedexScreenData->taskId = taskId;
sPokedexScreenData->listItems = Alloc(NATIONAL_DEX_COUNT * sizeof(struct ListMenuItem));
sPokedexScreenData->numSeenNational = DexScreen_GetDexCount(FLAG_GET_SEEN, 1);
sPokedexScreenData->numOwnedNational = DexScreen_GetDexCount(FLAG_GET_CAUGHT, 1);
sPokedexScreenData->numSeenKanto = DexScreen_GetDexCount(FLAG_GET_SEEN, 0);
sPokedexScreenData->numOwnedKanto = DexScreen_GetDexCount(FLAG_GET_CAUGHT, 0);
SetBGMVolume_SuppressHelpSystemReduction(0x80);
ChangeBgX(0, 0, 0);
ChangeBgY(0, 0, 0);
ChangeBgX(1, 0, 0);
ChangeBgY(1, 0, 0);
ChangeBgX(2, 0, 0);
ChangeBgY(2, 0, 0);
ChangeBgX(3, 0, 0);
ChangeBgY(3, 0, 0);
gPaletteFade.bufferTransferDisabled = TRUE;
if (natDex)
LoadPalette(sNationalDexPalette, BG_PLTT_ID(0), sizeof(sNationalDexPalette));
else
LoadPalette(sKantoDexPalette, BG_PLTT_ID(0), sizeof(sKantoDexPalette));
FillBgTilemapBufferRect(3, 0x001, 0, 0, 32, 32, 0);
FillBgTilemapBufferRect(2, 0x000, 0, 0, 32, 32, 17);
FillBgTilemapBufferRect(1, 0x000, 0, 0, 32, 32, 17);
FillBgTilemapBufferRect(0, 0x003, 0, 0, 32, 2, 15);
FillBgTilemapBufferRect(0, 0x000, 0, 2, 32, 16, 17);
FillBgTilemapBufferRect(0, 0x003, 0, 18, 32, 2, 15);
}
void CB2_OpenPokedexFromStartMenu(void)
{
DexScreen_LoadResources();
ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON | DISPCNT_WIN1_ON);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
SetGpuReg(REG_OFFSET_BLDY, 0);
SetMainCallback2(CB2_PokedexScreen);
SetHelpContext(HELPCONTEXT_POKEDEX);
}
#define FREE_IF_NOT_NULL(ptr0) ({ void *ptr = (ptr0); if (ptr) Free(ptr); })
bool8 DoClosePokedex(void)
{
switch (gMain.state)
{
case 0:
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
gMain.state++;
return FALSE;
case 1:
if (!gPaletteFade.active)
gMain.state = 2;
else
UpdatePaletteFade();
return FALSE;
case 2:
FREE_IF_NOT_NULL(sPokedexScreenData->listItems);
FREE_IF_NOT_NULL(sPokedexScreenData);
FreeAllWindowBuffers();
FREE_IF_NOT_NULL(GetBgTilemapBuffer(0));
FREE_IF_NOT_NULL(GetBgTilemapBuffer(1));
FREE_IF_NOT_NULL(GetBgTilemapBuffer(2));
FREE_IF_NOT_NULL(GetBgTilemapBuffer(3));
BGMVolumeMax_EnableHelpSystemReduction();
break;
}
return TRUE;
}
void CB2_ClosePokedex(void)
{
if (DoClosePokedex())
{
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON | DISPCNT_WIN1_ON);
SetMainCallback2(CB2_ReturnToFieldWithOpenMenu);
}
}
static void Task_PokedexScreen(u8 taskId)
{
int i;
switch (sPokedexScreenData->state)
{
case 0:
sPokedexScreenData->unlockedCategories = 0;
for (i = 0; i < 9; i++)
sPokedexScreenData->unlockedCategories |= (DexScreen_IsCategoryUnlocked(i) << i);
sPokedexScreenData->state = 2;
break;
case 1:
RemoveScrollIndicatorArrowPair(sPokedexScreenData->scrollArrowsTaskId);
DexScreen_RemoveWindow(&sPokedexScreenData->modeSelectWindowId);
DexScreen_RemoveWindow(&sPokedexScreenData->selectionIconWindowId);
DexScreen_RemoveWindow(&sPokedexScreenData->dexCountsWindowId);
SetMainCallback2(CB2_ClosePokedex);
DestroyTask(taskId);
break;
case 2:
DexScreen_InitGfxForTopMenu();
sPokedexScreenData->state = 3;
break;
case 3:
CopyBgTilemapBufferToVram(3);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(0);
sPokedexScreenData->state = 4;
break;
case 4:
ShowBg(3);
ShowBg(2);
ShowBg(1);
ShowBg(0);
if (gPaletteFade.bufferTransferDisabled)
{
gPaletteFade.bufferTransferDisabled = FALSE;
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0, RGB_WHITEALPHA);
}
else
BeginNormalPaletteFade(~0x8000, 0, 16, 0, RGB_WHITEALPHA);
sPokedexScreenData->state = 5;
break;
case 5:
ListMenuGetScrollAndRow(sPokedexScreenData->modeSelectListMenuId, &sPokedexScreenData->modeSelectCursorPosBak, NULL);
if (IsNationalPokedexEnabled())
sPokedexScreenData->scrollArrowsTaskId = AddScrollIndicatorArrowPair(&sScrollArrowsTemplate_NatDex, &sPokedexScreenData->modeSelectCursorPosBak);
else
sPokedexScreenData->scrollArrowsTaskId = AddScrollIndicatorArrowPair(&sScrollArrowsTemplate_KantoDex, &sPokedexScreenData->modeSelectCursorPosBak);
sPokedexScreenData->state = 6;
break;
case 6:
sPokedexScreenData->modeSelectInput = ListMenu_ProcessInput(sPokedexScreenData->modeSelectListMenuId);
ListMenuGetScrollAndRow(sPokedexScreenData->modeSelectListMenuId, &sPokedexScreenData->modeSelectCursorPosBak, NULL);
if (JOY_NEW(A_BUTTON))
{
switch (sPokedexScreenData->modeSelectInput)
{
case LIST_CANCEL:
sPokedexScreenData->state = 1;
break;
case DEX_CATEGORY_GRASSLAND:
case DEX_CATEGORY_FOREST:
case DEX_CATEGORY_WATERS_EDGE:
case DEX_CATEGORY_SEA:
case DEX_CATEGORY_CAVE:
case DEX_CATEGORY_MOUNTAIN:
case DEX_CATEGORY_ROUGH_TERRAIN:
case DEX_CATEGORY_URBAN:
case DEX_CATEGORY_RARE:
if (DexScreen_IsCategoryUnlocked(sPokedexScreenData->modeSelectInput))
{
RemoveScrollIndicatorArrowPair(sPokedexScreenData->scrollArrowsTaskId);
sPokedexScreenData->category = sPokedexScreenData->modeSelectInput;
BeginNormalPaletteFade(~0x8000, 0, 0, 16, RGB_WHITEALPHA);
sPokedexScreenData->state = 7;
}
break;
case DEX_MODE(NUMERICAL_KANTO):
case DEX_MODE(NUMERICAL_NATIONAL):
RemoveScrollIndicatorArrowPair(sPokedexScreenData->scrollArrowsTaskId);
sPokedexScreenData->dexOrderId = sPokedexScreenData->modeSelectInput - DEX_CATEGORY_COUNT;
BeginNormalPaletteFade(~0x8000, 0, 0, 16, RGB_WHITEALPHA);
sPokedexScreenData->state = 9;
break;
case DEX_MODE(ATOZ):
case DEX_MODE(TYPE):
case DEX_MODE(LIGHTEST):
case DEX_MODE(SMALLEST):
RemoveScrollIndicatorArrowPair(sPokedexScreenData->scrollArrowsTaskId);
sPokedexScreenData->dexOrderId = sPokedexScreenData->modeSelectInput - DEX_CATEGORY_COUNT;
sPokedexScreenData->characteristicOrderMenuItemsAbove = sPokedexScreenData->characteristicOrderMenuCursorPos = 0;
BeginNormalPaletteFade(~0x8000, 0, 0, 16, RGB_WHITEALPHA);
sPokedexScreenData->state = 8;
break;
}
break;
}
if (JOY_NEW(B_BUTTON))
{
sPokedexScreenData->state = 1;
}
break;
case 7:
DestroyListMenuTask(sPokedexScreenData->modeSelectListMenuId, &sPokedexScreenData->modeSelectCursorPos, &sPokedexScreenData->modeSelectItemsAbove);
FillBgTilemapBufferRect_Palette0(1, 0, 0, 0, 32, 20);
CopyBgTilemapBufferToVram(1);
DexScreen_RemoveWindow(&sPokedexScreenData->modeSelectWindowId);
DexScreen_RemoveWindow(&sPokedexScreenData->selectionIconWindowId);
DexScreen_RemoveWindow(&sPokedexScreenData->dexCountsWindowId);
sPokedexScreenData->pageNum = 0;
sPokedexScreenData->categoryCursorPosInPage = 0;
sPokedexScreenData->parentOfCategoryMenu = 0;
gTasks[taskId].func = Task_DexScreen_CategorySubmenu;
sPokedexScreenData->state = 0;
break;
case 8:
DestroyListMenuTask(sPokedexScreenData->modeSelectListMenuId, &sPokedexScreenData->modeSelectCursorPos, &sPokedexScreenData->modeSelectItemsAbove);
HideBg(1);
DexScreen_RemoveWindow(&sPokedexScreenData->modeSelectWindowId);
DexScreen_RemoveWindow(&sPokedexScreenData->selectionIconWindowId);
DexScreen_RemoveWindow(&sPokedexScreenData->dexCountsWindowId);
gTasks[taskId].func = Task_DexScreen_CharacteristicOrder;
sPokedexScreenData->state = 0;
break;
case 9:
DestroyListMenuTask(sPokedexScreenData->modeSelectListMenuId, &sPokedexScreenData->modeSelectCursorPos, &sPokedexScreenData->modeSelectItemsAbove);
HideBg(1);
DexScreen_RemoveWindow(&sPokedexScreenData->modeSelectWindowId);
DexScreen_RemoveWindow(&sPokedexScreenData->selectionIconWindowId);
DexScreen_RemoveWindow(&sPokedexScreenData->dexCountsWindowId);
gTasks[taskId].func = Task_DexScreen_NumericalOrder;
sPokedexScreenData->state = 0;
break;
}
}
static void DexScreen_InitGfxForTopMenu(void)
{
struct ListMenuTemplate listMenuTemplate;
FillBgTilemapBufferRect(3, 0x00E, 0, 0, 30, 20, 0);
FillBgTilemapBufferRect(2, 0x000, 0, 0, 30, 20, 17);
FillBgTilemapBufferRect(1, 0x000, 0, 0, 30, 20, 17);
sPokedexScreenData->modeSelectWindowId = AddWindow(&sWindowTemplate_ModeSelect);
sPokedexScreenData->selectionIconWindowId = AddWindow(&sWindowTemplate_SelectionIcon);
sPokedexScreenData->dexCountsWindowId = AddWindow(&sWindowTemplate_DexCounts);
if (IsNationalPokedexEnabled())
{
listMenuTemplate = sListMenuTemplate_NatDexModeSelect;
listMenuTemplate.windowId = sPokedexScreenData->modeSelectWindowId;
sPokedexScreenData->modeSelectListMenuId = ListMenuInit(&listMenuTemplate, sPokedexScreenData->modeSelectCursorPos, sPokedexScreenData->modeSelectItemsAbove);
FillWindowPixelBuffer(sPokedexScreenData->dexCountsWindowId, PIXEL_FILL(0));
DexScreen_AddTextPrinterParameterized(sPokedexScreenData->dexCountsWindowId, FONT_SMALL, gText_Seen, 0, 2, 0);
DexScreen_AddTextPrinterParameterized(sPokedexScreenData->dexCountsWindowId, FONT_SMALL, gText_Kanto, 8, 13, 0);
DexScreen_PrintNum3RightAlign(sPokedexScreenData->dexCountsWindowId, 0, sPokedexScreenData->numSeenKanto, 52, 13, 2);
DexScreen_AddTextPrinterParameterized(sPokedexScreenData->dexCountsWindowId, FONT_SMALL, gText_National, 8, 24, 0);
DexScreen_PrintNum3RightAlign(sPokedexScreenData->dexCountsWindowId, 0, sPokedexScreenData->numSeenNational, 52, 24, 2);
DexScreen_AddTextPrinterParameterized(sPokedexScreenData->dexCountsWindowId, FONT_SMALL, gText_Owned, 0, 37, 0);
DexScreen_AddTextPrinterParameterized(sPokedexScreenData->dexCountsWindowId, FONT_SMALL, gText_Kanto, 8, 48, 0);
DexScreen_PrintNum3RightAlign(sPokedexScreenData->dexCountsWindowId, 0, sPokedexScreenData->numOwnedKanto, 52, 48, 2);
DexScreen_AddTextPrinterParameterized(sPokedexScreenData->dexCountsWindowId, FONT_SMALL, gText_National, 8, 59, 0);
DexScreen_PrintNum3RightAlign(sPokedexScreenData->dexCountsWindowId, 0, sPokedexScreenData->numOwnedNational, 52, 59, 2);
}
else
{
listMenuTemplate = sListMenuTemplate_KantoDexModeSelect;
listMenuTemplate.windowId = sPokedexScreenData->modeSelectWindowId;
sPokedexScreenData->modeSelectListMenuId = ListMenuInit(&listMenuTemplate, sPokedexScreenData->modeSelectCursorPos, sPokedexScreenData->modeSelectItemsAbove);
FillWindowPixelBuffer(sPokedexScreenData->dexCountsWindowId, PIXEL_FILL(0));
DexScreen_AddTextPrinterParameterized(sPokedexScreenData->dexCountsWindowId, FONT_NORMAL_COPY_1, gText_Seen, 0, 9, 0);
DexScreen_PrintNum3RightAlign(sPokedexScreenData->dexCountsWindowId, 1, sPokedexScreenData->numSeenKanto, 32, 21, 2);
DexScreen_AddTextPrinterParameterized(sPokedexScreenData->dexCountsWindowId, FONT_NORMAL_COPY_1, gText_Owned, 0, 37, 0);
DexScreen_PrintNum3RightAlign(sPokedexScreenData->dexCountsWindowId, 1, sPokedexScreenData->numOwnedKanto, 32, 49, 2);
}
FillWindowPixelBuffer(0, PIXEL_FILL(15));
DexScreen_PrintStringWithAlignment(gText_PokedexTableOfContents, TEXT_CENTER);
FillWindowPixelBuffer(1, PIXEL_FILL(15));
DexScreen_PrintControlInfo(gText_PickOK);
PutWindowTilemap(0);
CopyWindowToVram(0, COPYWIN_GFX);
PutWindowTilemap(1);
CopyWindowToVram(1, COPYWIN_GFX);
PutWindowTilemap(sPokedexScreenData->dexCountsWindowId);
CopyWindowToVram(sPokedexScreenData->dexCountsWindowId, COPYWIN_GFX);
}
static void MoveCursorFunc_DexModeSelect(s32 itemIndex, bool8 onInit, struct ListMenu *list)
{
if (!onInit)
PlaySE(SE_SELECT);
if (itemIndex == LIST_CANCEL)
{
CopyToWindowPixelBuffer(sPokedexScreenData->selectionIconWindowId, sTopMenuSelectionIconTiles_Cancel, 0x000, 0x000);
LoadPalette(sTopMenuSelectionIconPals_Cancel, BG_PLTT_ID(1), PLTT_SIZE_4BPP);
}
else
{
CopyToWindowPixelBuffer(sPokedexScreenData->selectionIconWindowId, sTopMenuSelectionIconGfxPtrs[itemIndex].tiles, 0x000, 0x000);
LoadPalette(sTopMenuSelectionIconGfxPtrs[itemIndex].pal, BG_PLTT_ID(1), PLTT_SIZE_4BPP);
}
PutWindowTilemap(sPokedexScreenData->selectionIconWindowId);
CopyWindowToVram(sPokedexScreenData->selectionIconWindowId, COPYWIN_GFX);
}
static void ItemPrintFunc_DexModeSelect(u8 windowId, u32 itemId, u8 y)
{
if (itemId >= DEX_CATEGORY_COUNT || sPokedexScreenData->unlockedCategories & (1 << itemId))
ListMenuOverrideSetColors(TEXT_COLOR_WHITE, TEXT_COLOR_TRANSPARENT, TEXT_COLOR_LIGHT_GRAY);
else
ListMenuOverrideSetColors(TEXT_DYNAMIC_COLOR_1, TEXT_COLOR_TRANSPARENT, TEXT_DYNAMIC_COLOR_2);
}
static void Task_DexScreen_NumericalOrder(u8 taskId)
{
switch (sPokedexScreenData->state)
{
case 0:
ListMenuLoadStdPalAt(BG_PLTT_ID(1), 0);
ListMenuLoadStdPalAt(BG_PLTT_ID(2), 1);
sPokedexScreenData->orderedDexCount = DexScreen_CountMonsInOrderedList(sPokedexScreenData->dexOrderId);
sPokedexScreenData->state = 2;
break;
case 1:
DexScreen_DestroyDexOrderListMenu(sPokedexScreenData->dexOrderId);
HideBg(1);
DexScreen_RemoveWindow(&sPokedexScreenData->numericalOrderWindowId);
gTasks[taskId].func = Task_PokedexScreen;
sPokedexScreenData->state = 0;
break;
case 2:
DexScreen_InitGfxForNumericalOrderList();
sPokedexScreenData->state = 3;
break;
case 3:
CopyBgTilemapBufferToVram(3);
CopyBgTilemapBufferToVram(1);
sPokedexScreenData->state = 4;
break;
case 4:
ShowBg(1);
BeginNormalPaletteFade(~0x8000, 0, 16, 0, RGB_WHITEALPHA);
sPokedexScreenData->state = 5;
break;
case 5:
ListMenuGetScrollAndRow(sPokedexScreenData->modeSelectListMenuId, &sPokedexScreenData->modeSelectCursorPosBak, NULL);
sPokedexScreenData->scrollArrowsTaskId = DexScreen_CreateDexOrderScrollArrows();
sPokedexScreenData->state = 6;
break;
case 6:
sPokedexScreenData->characteristicMenuInput = ListMenu_ProcessInput(sPokedexScreenData->orderedListMenuTaskId);
ListMenuGetScrollAndRow(sPokedexScreenData->modeSelectListMenuId, &sPokedexScreenData->modeSelectCursorPosBak, NULL);
if (JOY_NEW(A_BUTTON))
{
if ((sPokedexScreenData->characteristicMenuInput >> 16) & 1)
{
sPokedexScreenData->dexSpecies = sPokedexScreenData->characteristicMenuInput;
RemoveScrollIndicatorArrowPair(sPokedexScreenData->scrollArrowsTaskId);
BeginNormalPaletteFade(~0x8000, 0, 0, 16, RGB_WHITEALPHA);
sPokedexScreenData->state = 7;
}
}
else if (JOY_NEW(B_BUTTON))
{
RemoveScrollIndicatorArrowPair(sPokedexScreenData->scrollArrowsTaskId);
BeginNormalPaletteFade(~0x8000, 0, 0, 16, RGB_WHITEALPHA);
sPokedexScreenData->state = 1;
}
break;
case 7:
DexScreen_DestroyDexOrderListMenu(sPokedexScreenData->dexOrderId);
FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 0, 32, 20);
CopyBgTilemapBufferToVram(1);
DexScreen_RemoveWindow(&sPokedexScreenData->numericalOrderWindowId);
gTasks[taskId].func = Task_DexScreen_ShowMonPage;
sPokedexScreenData->state = 0;
break;
}
}
static void DexScreen_InitGfxForNumericalOrderList(void)
{
struct ListMenuTemplate template;
FillBgTilemapBufferRect(3, 0x00E, 0, 0, 30, 20, 0);
FillBgTilemapBufferRect(1, 0x000, 0, 0, 32, 32, 17);
sPokedexScreenData->numericalOrderWindowId = AddWindow(&sWindowTemplate_OrderedListMenu);
template = sListMenuTemplate_OrderedListMenu;
template.items = sPokedexScreenData->listItems;
template.windowId = sPokedexScreenData->numericalOrderWindowId;
template.totalItems = sPokedexScreenData->orderedDexCount;
DexScreen_InitListMenuForOrderedList(&template, sPokedexScreenData->dexOrderId);
FillWindowPixelBuffer(0, PIXEL_FILL(15));
DexScreen_PrintStringWithAlignment(gText_PokemonListNoColor, TEXT_CENTER);
FillWindowPixelBuffer(1, PIXEL_FILL(15));
DexScreen_PrintControlInfo(gText_PickOKExit);
CopyWindowToVram(0, COPYWIN_GFX);
CopyWindowToVram(1, COPYWIN_GFX);
}
static void Task_DexScreen_CharacteristicOrder(u8 taskId)
{
switch (sPokedexScreenData->state)
{
case 0:
ListMenuLoadStdPalAt(BG_PLTT_ID(1), 0);
ListMenuLoadStdPalAt(BG_PLTT_ID(2), 1);
sPokedexScreenData->orderedDexCount = DexScreen_CountMonsInOrderedList(sPokedexScreenData->dexOrderId);
sPokedexScreenData->state = 2;
break;
case 1:
DexScreen_DestroyDexOrderListMenu(sPokedexScreenData->dexOrderId);
HideBg(1);
DexScreen_RemoveWindow(&sPokedexScreenData->numericalOrderWindowId);
gTasks[taskId].func = Task_PokedexScreen;
sPokedexScreenData->state = 0;
break;
case 2:
DexScreen_CreateCharacteristicListMenu();
sPokedexScreenData->state = 3;
break;
case 3:
CopyBgTilemapBufferToVram(3);
CopyBgTilemapBufferToVram(1);
sPokedexScreenData->state = 4;
break;
case 4:
ShowBg(1);
BeginNormalPaletteFade(~0x8000, 0, 16, 0, RGB_WHITEALPHA);
sPokedexScreenData->state = 5;
break;
case 5:
ListMenuGetScrollAndRow(sPokedexScreenData->modeSelectListMenuId, &sPokedexScreenData->modeSelectCursorPosBak, NULL);
sPokedexScreenData->scrollArrowsTaskId = DexScreen_CreateDexOrderScrollArrows();
sPokedexScreenData->state = 6;
break;
case 6:
sPokedexScreenData->characteristicMenuInput = ListMenu_ProcessInput(sPokedexScreenData->orderedListMenuTaskId);
ListMenuGetScrollAndRow(sPokedexScreenData->modeSelectListMenuId, &sPokedexScreenData->modeSelectCursorPosBak, NULL);
if (JOY_NEW(A_BUTTON))
{
if (((sPokedexScreenData->characteristicMenuInput >> 16) & 1) && !DexScreen_LookUpCategoryBySpecies(sPokedexScreenData->characteristicMenuInput))
{
RemoveScrollIndicatorArrowPair(sPokedexScreenData->scrollArrowsTaskId);
BeginNormalPaletteFade(~0x8000, 0, 0, 16, RGB_WHITEALPHA);
sPokedexScreenData->state = 7;
}
}
else if (JOY_NEW(B_BUTTON))
{
RemoveScrollIndicatorArrowPair(sPokedexScreenData->scrollArrowsTaskId);
BeginNormalPaletteFade(~0x8000, 0, 0, 16, RGB_WHITEALPHA);
sPokedexScreenData->state = 1;
}
break;
case 7:
DexScreen_DestroyDexOrderListMenu(sPokedexScreenData->dexOrderId);
FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 0, 32, 20);
CopyBgTilemapBufferToVram(1);
DexScreen_RemoveWindow(&sPokedexScreenData->numericalOrderWindowId);
sPokedexScreenData->parentOfCategoryMenu = 1;
gTasks[taskId].func = Task_DexScreen_CategorySubmenu;
sPokedexScreenData->state = 0;
break;
}
}
static void DexScreen_CreateCharacteristicListMenu(void)
{
struct ListMenuTemplate template;
FillBgTilemapBufferRect(3, 0x00E, 0, 0, 30, 20, 0);
FillBgTilemapBufferRect(1, 0x000, 0, 0, 32, 32, 17);
sPokedexScreenData->numericalOrderWindowId = AddWindow(&sWindowTemplate_OrderedListMenu);
template = sListMenuTemplate_OrderedListMenu;
template.items = sPokedexScreenData->listItems;
template.windowId = sPokedexScreenData->numericalOrderWindowId;
template.totalItems = sPokedexScreenData->orderedDexCount;
DexScreen_InitListMenuForOrderedList(&template, sPokedexScreenData->dexOrderId);
FillWindowPixelBuffer(0, PIXEL_FILL(15));
DexScreen_PrintStringWithAlignment(gText_SearchNoColor, TEXT_CENTER);
FillWindowPixelBuffer(1, PIXEL_FILL(15));
DexScreen_PrintControlInfo(gText_PickOKExit);
CopyWindowToVram(0, COPYWIN_GFX);
CopyWindowToVram(1, COPYWIN_GFX);
}
static u16 DexScreen_CountMonsInOrderedList(u8 orderIdx)
{
s32 max_n = IsNationalPokedexEnabled() ? NATIONAL_DEX_COUNT : KANTO_DEX_COUNT - 1;
u16 ndex_num;
u16 ret = NATIONAL_DEX_NONE;
s32 i;
bool8 caught;
bool8 seen;
switch (orderIdx)
{
default:
case DEX_ORDER_NUMERICAL_KANTO:
for (i = 0; i < KANTO_DEX_COUNT - 1; i++)
{
ndex_num = KantoToNationalOrder(i + 1);
seen = DexScreen_GetSetPokedexFlag(ndex_num, FLAG_GET_SEEN, FALSE);
caught = DexScreen_GetSetPokedexFlag(ndex_num, FLAG_GET_CAUGHT, FALSE);
if (seen)
{
sPokedexScreenData->listItems[i].label = gSpeciesInfo[NationalPokedexNumToSpecies(ndex_num)].speciesName;
ret = i + 1;
}
else
{
sPokedexScreenData->listItems[i].label = gText_5Dashes;
}
sPokedexScreenData->listItems[i].index = (caught << 17) + (seen << 16) + NationalPokedexNumToSpecies(ndex_num);
}
break;
case DEX_ORDER_ATOZ:
for (i = 0; i < NUM_SPECIES - 1; i++)
{
ndex_num = gPokedexOrder_Alphabetical[i];
if (ndex_num <= max_n)
{
seen = DexScreen_GetSetPokedexFlag(ndex_num, FLAG_GET_SEEN, FALSE);
caught = DexScreen_GetSetPokedexFlag(ndex_num, FLAG_GET_CAUGHT, FALSE);
if (seen)
{
sPokedexScreenData->listItems[ret].label = gSpeciesInfo[NationalPokedexNumToSpecies(ndex_num)].speciesName;
sPokedexScreenData->listItems[ret].index = (caught << 17) + (seen << 16) + NationalPokedexNumToSpecies(ndex_num);
ret++;
}
}
}
break;
case DEX_ORDER_TYPE:
for (i = 0; i < NUM_SPECIES - 1; i++)
{
ndex_num = SpeciesToNationalPokedexNum(gPokedexOrder_Type[i]);
if (ndex_num <= max_n)
{
seen = DexScreen_GetSetPokedexFlag(ndex_num, FLAG_GET_SEEN, FALSE);
caught = DexScreen_GetSetPokedexFlag(ndex_num, FLAG_GET_CAUGHT, FALSE);
if (caught)
{
sPokedexScreenData->listItems[ret].label = gSpeciesInfo[NationalPokedexNumToSpecies(ndex_num)].speciesName;
sPokedexScreenData->listItems[ret].index = (caught << 17) + (seen << 16) + NationalPokedexNumToSpecies(ndex_num);
ret++;
}
}
}
break;
case DEX_ORDER_LIGHTEST:
for (i = 0; i < NATIONAL_DEX_COUNT; i++)
{
ndex_num = gPokedexOrder_Weight[i];
if (ndex_num <= max_n)
{
seen = DexScreen_GetSetPokedexFlag(ndex_num, FLAG_GET_SEEN, FALSE);
caught = DexScreen_GetSetPokedexFlag(ndex_num, FLAG_GET_CAUGHT, FALSE);
if (caught)
{
sPokedexScreenData->listItems[ret].label = gSpeciesInfo[NationalPokedexNumToSpecies(ndex_num)].speciesName;
sPokedexScreenData->listItems[ret].index = (caught << 17) + (seen << 16) + NationalPokedexNumToSpecies(ndex_num);
ret++;
}
}
}
break;
case DEX_ORDER_SMALLEST:
for (i = 0; i < NATIONAL_DEX_COUNT; i++)
{
ndex_num = gPokedexOrder_Height[i];
if (ndex_num <= max_n)
{
seen = DexScreen_GetSetPokedexFlag(ndex_num, FLAG_GET_SEEN, FALSE);
caught = DexScreen_GetSetPokedexFlag(ndex_num, FLAG_GET_CAUGHT, FALSE);
if (caught)
{
sPokedexScreenData->listItems[ret].label = gSpeciesInfo[NationalPokedexNumToSpecies(ndex_num)].speciesName;
sPokedexScreenData->listItems[ret].index = (caught << 17) + (seen << 16) + NationalPokedexNumToSpecies(ndex_num);
ret++;
}
}
}
break;
case DEX_ORDER_NUMERICAL_NATIONAL:
for (i = 0; i < NATIONAL_DEX_COUNT; i++)
{
ndex_num = i + 1;
seen = DexScreen_GetSetPokedexFlag(ndex_num, FLAG_GET_SEEN, FALSE);
caught = DexScreen_GetSetPokedexFlag(ndex_num, FLAG_GET_CAUGHT, FALSE);
if (seen)
{
sPokedexScreenData->listItems[i].label = gSpeciesInfo[NationalPokedexNumToSpecies(ndex_num)].speciesName;
ret = ndex_num;
}
else
{
sPokedexScreenData->listItems[i].label = gText_5Dashes;
}
sPokedexScreenData->listItems[i].index = (caught << 17) + (seen << 16) + NationalPokedexNumToSpecies(ndex_num);
}
break;
}
return ret;
}
static void DexScreen_InitListMenuForOrderedList(const struct ListMenuTemplate * template, u8 order)
{
switch (order)
{
default:
case DEX_ORDER_NUMERICAL_KANTO:
sPokedexScreenData->orderedListMenuTaskId = ListMenuInitInRect(template, sListMenuRects_OrderedList, sPokedexScreenData->kantoOrderMenuCursorPos, sPokedexScreenData->kantoOrderMenuItemsAbove);
break;
case DEX_ORDER_ATOZ:
case DEX_ORDER_TYPE:
case DEX_ORDER_LIGHTEST:
case DEX_ORDER_SMALLEST:
sPokedexScreenData->orderedListMenuTaskId = ListMenuInitInRect(template, sListMenuRects_OrderedList, sPokedexScreenData->characteristicOrderMenuCursorPos, sPokedexScreenData->characteristicOrderMenuItemsAbove);
break;
case DEX_ORDER_NUMERICAL_NATIONAL:
sPokedexScreenData->orderedListMenuTaskId = ListMenuInitInRect(template, sListMenuRects_OrderedList, sPokedexScreenData->nationalOrderMenuCursorPos, sPokedexScreenData->nationalOrderMenuItemsAbove);
break;
}
}
static void DexScreen_DestroyDexOrderListMenu(u8 order)
{
switch (order)
{
default:
case DEX_ORDER_NUMERICAL_KANTO:
DestroyListMenuTask(sPokedexScreenData->orderedListMenuTaskId, &sPokedexScreenData->kantoOrderMenuCursorPos, &sPokedexScreenData->kantoOrderMenuItemsAbove);
break;
case DEX_ORDER_ATOZ:
case DEX_ORDER_TYPE:
case DEX_ORDER_LIGHTEST:
case DEX_ORDER_SMALLEST:
DestroyListMenuTask(sPokedexScreenData->orderedListMenuTaskId, &sPokedexScreenData->characteristicOrderMenuCursorPos, &sPokedexScreenData->characteristicOrderMenuItemsAbove);
break;
case DEX_ORDER_NUMERICAL_NATIONAL:
DestroyListMenuTask(sPokedexScreenData->orderedListMenuTaskId, &sPokedexScreenData->nationalOrderMenuCursorPos, &sPokedexScreenData->nationalOrderMenuItemsAbove);
break;
}
}
static u8 DexScreen_CreateDexOrderScrollArrows(void)
{
struct ScrollArrowsTemplate template = sDexOrderScrollArrowsTemplate;
if (sPokedexScreenData->orderedDexCount > sListMenuTemplate_OrderedListMenu.maxShowed)
template.fullyDownThreshold = sPokedexScreenData->orderedDexCount - sListMenuTemplate_OrderedListMenu.maxShowed;
else
template.fullyDownThreshold = 0;
return AddScrollIndicatorArrowPair(&template, &sPokedexScreenData->modeSelectCursorPosBak);
}
struct PokedexListItem
{
u16 species;
bool8 seen:1;
bool8 caught:1;
};
static void ItemPrintFunc_OrderedListMenu(u8 windowId, u32 itemId, u8 y)
{
u16 species = itemId;
bool8 seen = (itemId >> 16) & 1; // not used but required to match
bool8 caught = (itemId >> 17) & 1;
u8 type1;
DexScreen_PrintMonDexNo(sPokedexScreenData->numericalOrderWindowId, FONT_SMALL, species, 12, y);
if (caught)
{
BlitMenuInfoIcon(sPokedexScreenData->numericalOrderWindowId, MENU_INFO_ICON_CAUGHT, 0x28, y);
type1 = gSpeciesInfo[species].types[0];
BlitMenuInfoIcon(sPokedexScreenData->numericalOrderWindowId, type1 + 1, 0x78, y);
if (type1 != gSpeciesInfo[species].types[1])
BlitMenuInfoIcon(sPokedexScreenData->numericalOrderWindowId, gSpeciesInfo[species].types[1] + 1, 0x98, y);
}
}
static void Task_DexScreen_CategorySubmenu(u8 taskId)
{
int pageFlipCmd;
u8 *ptr;
switch (sPokedexScreenData->state)
{
case 0:
HideBg(3);
HideBg(2);
HideBg(1);
DexScreen_GetPageLimitsForCategory(sPokedexScreenData->category);
if (sPokedexScreenData->pageNum < sPokedexScreenData->firstPageInCategory)
sPokedexScreenData->pageNum = sPokedexScreenData->firstPageInCategory;
sPokedexScreenData->state = 2;
break;
case 1:
DexScreen_DestroyCategoryPageMonIconAndInfoWindows();
HideBg(2);
HideBg(1);
switch (sPokedexScreenData->parentOfCategoryMenu)
{
case 0:
default:
gTasks[taskId].func = Task_PokedexScreen;
break;
case 1:
gTasks[taskId].func = Task_DexScreen_CharacteristicOrder;
break;
}
sPokedexScreenData->state = 0;
break;
case 2:
DexScreen_CreateCategoryListGfx(FALSE);
CopyBgTilemapBufferToVram(3);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(1);
DexScreen_CreateCategoryPageSelectionCursor(0xFF);
sPokedexScreenData->state = 3;
break;
case 3:
BeginNormalPaletteFade(~0x8000, 0, 16, 0, RGB_WHITEALPHA);
ShowBg(3);
ShowBg(2);
ShowBg(1);
sPokedexScreenData->state = 4;
break;
case 4:
sPokedexScreenData->scrollArrowsTaskId = DexScreen_CreateCategoryMenuScrollArrows();
sPokedexScreenData->categoryPageCursorTaskId = ListMenuAddCursorObjectInternal(&sCursorStruct_CategoryPage, 0);
sPokedexScreenData->state = 5;
break;
case 5:
DexScreen_CreateCategoryPageSelectionCursor(sPokedexScreenData->categoryCursorPosInPage);
DexScreen_UpdateCategoryPageCursorObject(sPokedexScreenData->categoryPageCursorTaskId, sPokedexScreenData->categoryCursorPosInPage, sPokedexScreenData->numMonsOnPage);
sPokedexScreenData->modeSelectCursorPosBak = sPokedexScreenData->pageNum;
pageFlipCmd = 0;
if (JOY_NEW(A_BUTTON) && DexScreen_GetSetPokedexFlag(sPokedexScreenData->pageSpecies[sPokedexScreenData->categoryCursorPosInPage], FLAG_GET_SEEN, TRUE))
{
RemoveScrollIndicatorArrowPair(sPokedexScreenData->scrollArrowsTaskId);
ListMenuRemoveCursorObject(sPokedexScreenData->categoryPageCursorTaskId, 0);
sPokedexScreenData->state = 12;
break;
}
if (!JOY_HELD(R_BUTTON) && JOY_REPT(DPAD_LEFT))
{
if (sPokedexScreenData->categoryCursorPosInPage != 0)
{
sPokedexScreenData->categoryCursorPosInPage--;
PlaySE(SE_SELECT);
break;
}
else
pageFlipCmd = 1;
}
if (!JOY_HELD(R_BUTTON) && JOY_REPT(DPAD_RIGHT))
{
if (sPokedexScreenData->categoryCursorPosInPage < sPokedexScreenData->numMonsOnPage - 1)
{
sPokedexScreenData->categoryCursorPosInPage++;
PlaySE(SE_SELECT);
break;
}
else
pageFlipCmd = 2;
}
if (pageFlipCmd == 0)
pageFlipCmd = DexScreen_InputHandler_GetShoulderInput();
switch (pageFlipCmd)
{
case 0: // No action
break;
case 1: // Left
while (sPokedexScreenData->pageNum > sPokedexScreenData->firstPageInCategory)
{
sPokedexScreenData->pageNum--;
if (DexScreen_IsPageUnlocked(sPokedexScreenData->category, sPokedexScreenData->pageNum))
{
sPokedexScreenData->state = 8;
break;
}
}
if (sPokedexScreenData->state != 8)
sPokedexScreenData->state = 6;
break;
case 2: // Right
while (sPokedexScreenData->pageNum < sPokedexScreenData->lastPageInCategory - 1)
{
sPokedexScreenData->pageNum++;
if (DexScreen_IsPageUnlocked(sPokedexScreenData->category, sPokedexScreenData->pageNum))
{
sPokedexScreenData->state = 10;
break;
}
}
if (sPokedexScreenData->state != 10)
sPokedexScreenData->state = 6;
break;
}
if (JOY_NEW(B_BUTTON))
{
sPokedexScreenData->state = 6;
}
break;
case 6:
case 7:
RemoveScrollIndicatorArrowPair(sPokedexScreenData->scrollArrowsTaskId);
ListMenuRemoveCursorObject(sPokedexScreenData->categoryPageCursorTaskId, 0);
BeginNormalPaletteFade(~0x8000, 0, 0, 16, RGB_WHITEALPHA);
sPokedexScreenData->state = 1;
break;
case 8:
case 10:
DexScreen_DestroyCategoryPageMonIconAndInfoWindows();
DexScreen_CreateCategoryPageSelectionCursor(0xFF);
ListMenuUpdateCursorObject(sPokedexScreenData->categoryPageCursorTaskId, 0, 0xA0, 0);
sPokedexScreenData->categoryPageSelectionCursorTimer = 0;
sPokedexScreenData->data[0] = 0;
sPokedexScreenData->state++;
break;
case 9:
if (DexScreen_FlipCategoryPageInDirection(0))
{
sPokedexScreenData->categoryCursorPosInPage = sPokedexScreenData->numMonsOnPage - 1;
sPokedexScreenData->state = 5;
}
break;
case 11:
if (DexScreen_FlipCategoryPageInDirection(1))
{
sPokedexScreenData->categoryCursorPosInPage = 0;
sPokedexScreenData->state = 5;
}
break;
case 12:
sPokedexScreenData->dexSpecies = sPokedexScreenData->pageSpecies[sPokedexScreenData->categoryCursorPosInPage];
PlaySE(SE_SELECT);
sPokedexScreenData->state = 14;
break;
case 13:
RemoveDexPageWindows();
sPokedexScreenData->state = 4;
break;
case 14:
DexScreen_DrawMonDexPage(FALSE);
sPokedexScreenData->state = 15;
break;
case 15:
sPokedexScreenData->data[0] = 0;
sPokedexScreenData->data[1] = 0;
sPokedexScreenData->state++;
// fallthrough
case 16:
if (sPokedexScreenData->data[1] < 6)
{
if (sPokedexScreenData->data[0])
{
DexScreen_DexPageZoomEffectFrame(0, sPokedexScreenData->data[1]);
CopyBgTilemapBufferToVram(0);
sPokedexScreenData->data[0] = 4;
sPokedexScreenData->data[1]++;
}
else
{
sPokedexScreenData->data[0]--;
}
}
else
{
FillBgTilemapBufferRect_Palette0(0, 0x000, 0, 2, 30, 16);
CopyBgTilemapBufferToVram(3);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(0);
PlayCry_NormalNoDucking(sPokedexScreenData->dexSpecies, 0, CRY_VOLUME_RS, CRY_PRIORITY_NORMAL);
sPokedexScreenData->data[0] = 0;
sPokedexScreenData->state = 17;
}
break;
case 17:
if (JOY_NEW(A_BUTTON))
{
RemoveDexPageWindows();
FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 2, 30, 16);
CopyBgTilemapBufferToVram(1);
sPokedexScreenData->state = 21;
}
else if (JOY_NEW(B_BUTTON))
{
sPokedexScreenData->state = 18;
}
else
{
DexScreen_InputHandler_StartToCry();
}
break;
case 18:
DexScreen_CreateCategoryListGfx(FALSE);
DexScreen_DexPageZoomEffectFrame(0, 6);
CopyBgTilemapBufferToVram(3);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(0);
sPokedexScreenData->state = 19;
break;
case 19:
sPokedexScreenData->data[0] = 0;
sPokedexScreenData->data[1] = 6;
sPokedexScreenData->state++;
// fallthrough
case 20:
if (sPokedexScreenData->data[1])
{
if (sPokedexScreenData->data[0])
{
sPokedexScreenData->data[1]--;
FillBgTilemapBufferRect_Palette0(0, 0x000, 0, 2, 30, 16);
DexScreen_DexPageZoomEffectFrame(0, sPokedexScreenData->data[1]);
CopyBgTilemapBufferToVram(0);
sPokedexScreenData->data[0] = 1;
}
else
sPokedexScreenData->data[0]--;
}
else
{
FillBgTilemapBufferRect_Palette0(0, 0x000, 0, 2, 30, 16);
CopyBgTilemapBufferToVram(0);
sPokedexScreenData->state = 13;
}
break;
case 21:
DexScreen_DrawMonAreaPage();
sPokedexScreenData->state = 22;
break;
case 22:
CopyBgTilemapBufferToVram(3);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(0);
sPokedexScreenData->state = 23;
break;
case 23:
if (JOY_NEW(A_BUTTON))
{
FillBgTilemapBufferRect_Palette0(2, 0x000, 0, 2, 30, 16);
FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 2, 30, 16);
FillBgTilemapBufferRect_Palette0(0, 0x000, 0, 2, 30, 16);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(0);
sPokedexScreenData->state = 26;
}
else if (JOY_NEW(B_BUTTON))
{
FillBgTilemapBufferRect_Palette0(2, 0x000, 0, 2, 30, 16);
FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 2, 30, 16);
FillBgTilemapBufferRect_Palette0(0, 0x000, 0, 2, 30, 16);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(0);
sPokedexScreenData->state = 24;
}
else
{
DexScreen_InputHandler_StartToCry();
}
break;
case 24:
DexScreen_DestroyAreaScreenResources();
sPokedexScreenData->state = 25;
break;
case 25:
DexScreen_DrawMonDexPage(FALSE);
CopyBgTilemapBufferToVram(3);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(0);
sPokedexScreenData->state = 17;
break;
case 26:
DexScreen_DestroyAreaScreenResources();
sPokedexScreenData->state = 18;
break;
}
}
static u8 DexScreen_CreateCategoryMenuScrollArrows(void)
{
struct ScrollArrowsTemplate template = sScrollArrowsTemplate_CategoryMenu;
template.fullyUpThreshold = sPokedexScreenData->firstPageInCategory;
template.fullyDownThreshold = sPokedexScreenData->lastPageInCategory - 1;
sPokedexScreenData->modeSelectCursorPosBak = sPokedexScreenData->pageNum;
return AddScrollIndicatorArrowPair(&template, &sPokedexScreenData->modeSelectCursorPosBak);
}
/*
* Returns 1 to flip pages left, 2 to flip pages right, 0 for no action
*/
static int DexScreen_InputHandler_GetShoulderInput(void)
{
switch (gSaveBlock2Ptr->optionsButtonMode)
{
case OPTIONS_BUTTON_MODE_L_EQUALS_A:
// Using the JOY_HELD and JOY_NEW macros here does not match!
if ((gMain.heldKeys & R_BUTTON) && (gMain.newKeys & DPAD_LEFT))
return 1;
else if ((gMain.heldKeys & R_BUTTON) && (gMain.newKeys & DPAD_RIGHT))
return 2;
else
return 0;
case OPTIONS_BUTTON_MODE_LR:
if (gMain.newKeys & L_BUTTON)
return 1;
else if (gMain.newKeys & R_BUTTON)
return 2;
else
return 0;
case OPTIONS_BUTTON_MODE_HELP:
default:
return 0;
}
}
static void Task_DexScreen_ShowMonPage(u8 taskId)
{
switch (sPokedexScreenData->state)
{
case 0:
HideBg(3);
HideBg(2);
HideBg(1);
sPokedexScreenData->state = 2;
break;
case 1:
HideBg(2);
HideBg(1);
gTasks[taskId].func = Task_DexScreen_NumericalOrder;
sPokedexScreenData->state = 0;
break;
case 2:
sPokedexScreenData->numMonsOnPage = 1;
DexScreen_DrawMonDexPage(FALSE);
sPokedexScreenData->state = 3;
break;
case 3:
CopyBgTilemapBufferToVram(3);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(0);
PlayCry_NormalNoDucking(sPokedexScreenData->dexSpecies, 0, CRY_VOLUME_RS, CRY_PRIORITY_NORMAL);
sPokedexScreenData->state = 4;
break;
case 4:
BeginNormalPaletteFade(~0x8000, 0, 16, 0, RGB_WHITEALPHA);
ShowBg(3);
ShowBg(2);
ShowBg(1);
sPokedexScreenData->state = 5;
break;
case 5:
if (JOY_NEW(A_BUTTON))
{
RemoveDexPageWindows();
FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 2, 30, 16);
CopyBgTilemapBufferToVram(1);
sPokedexScreenData->state = 7;
}
else if (JOY_NEW(B_BUTTON))
{
RemoveDexPageWindows();
BeginNormalPaletteFade(~0x8000, 0, 0, 16, RGB_WHITEALPHA);
sPokedexScreenData->state = 1;
}
else if (JOY_NEW(DPAD_UP) && DexScreen_TryScrollMonsVertical(1))
{
RemoveDexPageWindows();
BeginNormalPaletteFade(~0x8000, 0, 0, 16, RGB_WHITEALPHA);
sPokedexScreenData->state = 6;
}
else if (JOY_NEW(DPAD_DOWN) && DexScreen_TryScrollMonsVertical(0))
{
RemoveDexPageWindows();
BeginNormalPaletteFade(~0x8000, 0, 0, 16, RGB_WHITEALPHA);
sPokedexScreenData->state = 6;
}
else
{
DexScreen_InputHandler_StartToCry();
}
break;
case 6:
HideBg(2);
HideBg(1);
sPokedexScreenData->dexSpecies = sPokedexScreenData->characteristicMenuInput;
sPokedexScreenData->state = 2;
break;
case 7:
DexScreen_DrawMonAreaPage();
sPokedexScreenData->state = 8;
break;
case 8:
CopyBgTilemapBufferToVram(3);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(0);
sPokedexScreenData->state = 9;
break;
case 9:
if (JOY_NEW(A_BUTTON))
{
BeginNormalPaletteFade(~0x8000, 0, 0, 16, RGB_WHITEALPHA);
sPokedexScreenData->state = 12;
}
else if (JOY_NEW(B_BUTTON))
{
FillBgTilemapBufferRect_Palette0(2, 0x000, 0, 2, 30, 16);
FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 2, 30, 16);
FillBgTilemapBufferRect_Palette0(0, 0x000, 0, 2, 30, 16);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(0);
sPokedexScreenData->state = 10;
}
else
{
DexScreen_InputHandler_StartToCry();
}
break;
case 10:
DexScreen_DestroyAreaScreenResources();
sPokedexScreenData->state = 11;
break;
case 11:
DexScreen_DrawMonDexPage(FALSE);
CopyBgTilemapBufferToVram(3);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(0);
sPokedexScreenData->state = 5;
break;
case 12:
DexScreen_DestroyAreaScreenResources();
FillBgTilemapBufferRect_Palette0(0, 0x000, 0, 2, 30, 16);
CopyBgTilemapBufferToVram(0);
sPokedexScreenData->state = 1;
break;
}
}
static bool32 DexScreen_TryScrollMonsVertical(u8 direction)
{
int selectedIndex;
u16 *itemsAbove_p, *cursorPos_p;
switch (sPokedexScreenData->dexOrderId)
{
default:
case DEX_ORDER_NUMERICAL_KANTO:
cursorPos_p = &sPokedexScreenData->kantoOrderMenuCursorPos;
itemsAbove_p = &sPokedexScreenData->kantoOrderMenuItemsAbove;
break;
case DEX_ORDER_ATOZ:
case DEX_ORDER_TYPE:
case DEX_ORDER_LIGHTEST:
case DEX_ORDER_SMALLEST:
cursorPos_p = &sPokedexScreenData->characteristicOrderMenuCursorPos;
itemsAbove_p = &sPokedexScreenData->characteristicOrderMenuItemsAbove;
break;
case DEX_ORDER_NUMERICAL_NATIONAL:
cursorPos_p = &sPokedexScreenData->nationalOrderMenuCursorPos;
itemsAbove_p = &sPokedexScreenData->nationalOrderMenuItemsAbove;
break;
}
selectedIndex = *cursorPos_p + *itemsAbove_p;
if (direction) // Seek up
{
if (selectedIndex == 0)
return FALSE;
selectedIndex--;
while (selectedIndex >= 0) //Should be while (--selectedIndex >= 0) without the selectedIndex-- in the body or before the while at all, but this is needed to match.
{
if ((sPokedexScreenData->listItems[selectedIndex].index >> 16) & 1)
{
break;
}
selectedIndex--;
}
if (selectedIndex < 0)
{
return FALSE;
}
}
else // Seek down
{
if (selectedIndex == sPokedexScreenData->orderedDexCount - 1)
{
return FALSE;
}
selectedIndex++;
while (selectedIndex < sPokedexScreenData->orderedDexCount) //Should be while (++selectedIndex < sPokedexScreenData->orderedDexCount) without the selectedIndex++ in the body or before the while at all, but this is needed to match.
{
if ((sPokedexScreenData->listItems[selectedIndex].index >> 16) & 1)
break;
selectedIndex++;
}
if (selectedIndex >= sPokedexScreenData->orderedDexCount)
{
return FALSE;
}
}
sPokedexScreenData->characteristicMenuInput = sPokedexScreenData->listItems[selectedIndex].index;
if (sPokedexScreenData->orderedDexCount > 9)
{
if (selectedIndex < 4)
{
*cursorPos_p = 0;
*itemsAbove_p = selectedIndex;
}
else if (selectedIndex >= (sPokedexScreenData->orderedDexCount - 4))
{
*cursorPos_p = (sPokedexScreenData->orderedDexCount - 9);
*itemsAbove_p = selectedIndex + 9 - (sPokedexScreenData->orderedDexCount);
}
else
{
*cursorPos_p = selectedIndex - 4;
*itemsAbove_p = 4;
}
}
else
{
*cursorPos_p = 0;
*itemsAbove_p = selectedIndex;
}
return TRUE;
}
static void DexScreen_RemoveWindow(u8 *windowId_p)
{
if (*windowId_p != 0xFF)
{
RemoveWindow(*windowId_p);
*windowId_p = 0xFF;
}
}
static void DexScreen_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 *str, u8 x, u8 y, u8 colorIdx)
{
u8 textColor[3];
switch (colorIdx)
{
case 0:
textColor[0] = 0;
textColor[1] = 1;
textColor[2] = 3;
break;
case 1:
textColor[0] = 0;
textColor[1] = 5;
textColor[2] = 1;
break;
case 2:
textColor[0] = 0;
textColor[1] = 15;
textColor[2] = 14;
break;
case 3:
textColor[0] = 0;
textColor[1] = 11;
textColor[2] = 1;
break;
case 4:
textColor[0] = 0;
textColor[1] = 1;
textColor[2] = 2;
break;
}
AddTextPrinterParameterized4(windowId, fontId, x, y, fontId == FONT_SMALL ? 0 : 1, 0, textColor, -1, str);
}
static void DexScreen_PrintNum3LeadingZeroes(u8 windowId, u8 fontId, u16 num, u8 x, u8 y, u8 colorIdx)
{
u8 buff[4];
buff[0] = (num / 100) + CHAR_0;
buff[1] = ((num %= 100) / 10) + CHAR_0;
buff[2] = (num % 10) + CHAR_0;
buff[3] = EOS;
DexScreen_AddTextPrinterParameterized(windowId, fontId, buff, x, y, colorIdx);
}
static void DexScreen_PrintNum3RightAlign(u8 windowId, u8 fontId, u16 num, u8 x, u8 y, u8 colorIdx)
{
u8 buff[4];
int i;
buff[0] = (num / 100) + CHAR_0;
buff[1] = ((num %= 100) / 10) + CHAR_0;
buff[2] = (num % 10) + CHAR_0;
buff[3] = EOS;
for (i = 0; i < 3; i++)
{
if (buff[i] != CHAR_0)
break;
buff[i] = CHAR_SPACE;
}
DexScreen_AddTextPrinterParameterized(windowId, fontId, buff, x, y, colorIdx);
}
static u32 DexScreen_GetDefaultPersonality(int species)
{
switch (species)
{
case SPECIES_SPINDA:
return gSaveBlock2Ptr->pokedex.spindaPersonality;
case SPECIES_UNOWN:
return gSaveBlock2Ptr->pokedex.unownPersonality;
default:
return 0;
}
}
static void DexScreen_LoadMonPicInWindow(u8 windowId, u16 species, u16 paletteOffset)
{
LoadMonPicInWindow(species, SHINY_ODDS, DexScreen_GetDefaultPersonality(species), TRUE, paletteOffset >> 4, windowId);
}
static void DexScreen_PrintMonDexNo(u8 windowId, u8 fontId, u16 species, u8 x, u8 y)
{
u16 dexNum;
if (IsNationalPokedexEnabled())
{
dexNum = SpeciesToNationalPokedexNum(species);
}
else
{
dexNum = NationalToKantoOrder(SpeciesToNationalPokedexNum(species));
}
DexScreen_AddTextPrinterParameterized(windowId, fontId, gText_PokedexNo, x, y, 0);
DexScreen_PrintNum3LeadingZeroes(windowId, fontId, dexNum, x + 9, y, 0);
}
s8 DexScreen_GetSetPokedexFlag(u16 nationalDexNo, u8 caseId, bool8 indexIsSpecies)
{
u8 index;
u8 bit;
u8 mask;
s8 retVal;
if (indexIsSpecies)
nationalDexNo = SpeciesToNationalPokedexNum(nationalDexNo);
nationalDexNo--;
index = nationalDexNo / 8;
bit = nationalDexNo % 8;
mask = 1 << bit;
retVal = 0;
switch (caseId)
{
case FLAG_GET_SEEN:
if (gSaveBlock2Ptr->pokedex.seen[index] & mask)
{
// Anticheat
if ((gSaveBlock2Ptr->pokedex.seen[index] & mask) == (gSaveBlock1Ptr->seen1[index] & mask)
&& (gSaveBlock2Ptr->pokedex.seen[index] & mask) == (gSaveBlock1Ptr->seen2[index] & mask))
retVal = 1;
}
break;
case FLAG_GET_CAUGHT:
if (gSaveBlock2Ptr->pokedex.owned[index] & mask)
{
// Anticheat
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;
}
break;
case FLAG_SET_SEEN:
gSaveBlock2Ptr->pokedex.seen[index] |= mask;
// Anticheat
gSaveBlock1Ptr->seen1[index] |= mask;
gSaveBlock1Ptr->seen2[index] |= mask;
break;
case FLAG_SET_CAUGHT:
gSaveBlock2Ptr->pokedex.owned[index] |= mask;
break;
}
return retVal;
}
static u16 DexScreen_GetDexCount(u8 caseId, bool8 whichDex)
{
u16 count = 0;
u16 i;
switch (whichDex)
{
case 0: // Kanto
for (i = 1; i < KANTO_DEX_COUNT; i++)
{
if (DexScreen_GetSetPokedexFlag(KantoToNationalOrder(i), caseId, FALSE))
count++;
}
break;
case 1: // National
for (i = 0; i < NATIONAL_DEX_COUNT; i++)
{
if (DexScreen_GetSetPokedexFlag(i + 1, caseId, FALSE))
count++;
}
break;
}
return count;
}
static void DexScreen_PrintControlInfo(const u8 *src)
{
DexScreen_AddTextPrinterParameterized(1, FONT_SMALL, src, 236 - GetStringWidth(FONT_SMALL, src, 0), 2, 4);
}
bool8 DexScreen_DrawMonPicInCategoryPage(u16 species, u8 slot, u8 numSlots)
{
struct WindowTemplate template;
numSlots--;
CopyToBgTilemapBufferRect_ChangePalette(3, sCategoryPageIconWindowBg, sCategoryPageIconCoords[numSlots][slot][0], sCategoryPageIconCoords[numSlots][slot][1], 8, 8, slot + 5);
if (sPokedexScreenData->categoryMonWindowIds[slot] == 0xFF)
{
template = sWindowTemplate_CategoryMonIcon;
template.tilemapLeft = sCategoryPageIconCoords[numSlots][slot][0];
template.tilemapTop = sCategoryPageIconCoords[numSlots][slot][1];
template.paletteNum = slot + 1;
template.baseBlock = slot * 64 + 8;
sPokedexScreenData->categoryMonWindowIds[slot] = AddWindow(&template);
FillWindowPixelBuffer(sPokedexScreenData->categoryMonWindowIds[slot], PIXEL_FILL(0));
DexScreen_LoadMonPicInWindow(sPokedexScreenData->categoryMonWindowIds[slot], species, slot * 16 + 16);
PutWindowTilemap(sPokedexScreenData->categoryMonWindowIds[slot]);
CopyWindowToVram(sPokedexScreenData->categoryMonWindowIds[slot], COPYWIN_GFX);
}
else
PutWindowTilemap(sPokedexScreenData->categoryMonWindowIds[slot]);
if (sPokedexScreenData->categoryMonInfoWindowIds[slot] == 0xFF)
{
if (species != SPECIES_NONE)
{
template = sWindowTemplate_CategoryMonInfo;
template.tilemapLeft = sCategoryPageIconCoords[numSlots][slot][2];
template.tilemapTop = sCategoryPageIconCoords[numSlots][slot][3];
template.baseBlock = slot * 40 + 0x108;
sPokedexScreenData->categoryMonInfoWindowIds[slot] = AddWindow(&template);
CopyToWindowPixelBuffer(sPokedexScreenData->categoryMonInfoWindowIds[slot], sCategoryMonInfoBgTiles, 0, 0);
DexScreen_PrintMonDexNo(sPokedexScreenData->categoryMonInfoWindowIds[slot], FONT_SMALL, species, 12, 0);
DexScreen_AddTextPrinterParameterized(sPokedexScreenData->categoryMonInfoWindowIds[slot], FONT_NORMAL, gSpeciesInfo[species].speciesName, 2, 13, 0);
if (DexScreen_GetSetPokedexFlag(species, FLAG_GET_CAUGHT, TRUE))
BlitBitmapRectToWindow(sPokedexScreenData->categoryMonInfoWindowIds[slot], sDexScreen_CaughtIcon, 0, 0, 8, 8, 2, 3, 8, 8);
PutWindowTilemap(sPokedexScreenData->categoryMonInfoWindowIds[slot]);
CopyWindowToVram(sPokedexScreenData->categoryMonInfoWindowIds[slot], COPYWIN_GFX);
}
}
else
PutWindowTilemap(sPokedexScreenData->categoryMonInfoWindowIds[slot]);
return TRUE;
}
static void DexScreen_DestroyCategoryPageMonIconAndInfoWindows(void)
{
int i;
for (i = 0; i < 4; i++)
{
DexScreen_RemoveWindow(&sPokedexScreenData->categoryMonWindowIds[i]);
DexScreen_RemoveWindow(&sPokedexScreenData->categoryMonInfoWindowIds[i]);
}
}
static void DexScreen_PrintCategoryPageNumbers(u8 windowId, u16 currentPage, u16 totalPages, u16 x, u16 y)
{
u8 buffer[30];
u8 *ptr = StringCopy(buffer, gText_Page);
ptr = ConvertIntToDecimalStringN(ptr, currentPage, STR_CONV_MODE_RIGHT_ALIGN, 2);
*ptr++ = CHAR_SLASH;
ptr = ConvertIntToDecimalStringN(ptr, totalPages, STR_CONV_MODE_RIGHT_ALIGN, 2);
DexScreen_PrintStringWithAlignment(buffer, TEXT_RIGHT);
}
static bool8 DexScreen_CreateCategoryListGfx(bool8 justRegistered)
{
FillBgTilemapBufferRect_Palette0(3, 2, 0, 0, 30, 20);
FillBgTilemapBufferRect_Palette0(2, 0, 0, 0, 32, 20);
FillBgTilemapBufferRect_Palette0(1, 0, 0, 0, 32, 20);
DexScreen_CreateCategoryPageSpeciesList(sPokedexScreenData->category, sPokedexScreenData->pageNum);
FillWindowPixelBuffer(0, PIXEL_FILL(15));
if (justRegistered)
{
DexScreen_PrintStringWithAlignment(sDexCategoryNamePtrs[sPokedexScreenData->category], TEXT_CENTER);
}
else
{
DexScreen_PrintStringWithAlignment(sDexCategoryNamePtrs[sPokedexScreenData->category], TEXT_LEFT);
DexScreen_PrintCategoryPageNumbers(0, DexScreen_PageNumberToRenderablePages(sPokedexScreenData->pageNum), DexScreen_PageNumberToRenderablePages(sPokedexScreenData->lastPageInCategory - 1), 160, 2);
}
CopyWindowToVram(0, COPYWIN_GFX);
FillWindowPixelBuffer(1, PIXEL_FILL(15));
if (!justRegistered)
DexScreen_PrintControlInfo(gText_PickFlipPageCheckCancel);
CopyWindowToVram(1, COPYWIN_GFX);
if (sPokedexScreenData->pageSpecies[0] != 0xFFFF)
DexScreen_DrawMonPicInCategoryPage(sPokedexScreenData->pageSpecies[0], 0, sPokedexScreenData->numMonsOnPage);
if (sPokedexScreenData->pageSpecies[1] != 0xFFFF)
DexScreen_DrawMonPicInCategoryPage(sPokedexScreenData->pageSpecies[1], 1, sPokedexScreenData->numMonsOnPage);
if (sPokedexScreenData->pageSpecies[2] != 0xFFFF)
DexScreen_DrawMonPicInCategoryPage(sPokedexScreenData->pageSpecies[2], 2, sPokedexScreenData->numMonsOnPage);
if (sPokedexScreenData->pageSpecies[3] != 0xFFFF)
DexScreen_DrawMonPicInCategoryPage(sPokedexScreenData->pageSpecies[3], 3, sPokedexScreenData->numMonsOnPage);
return FALSE;
}
static void DexScreen_CreateCategoryPageSelectionCursor(u8 cursorPos)
{
int i;
u32 palIdx;
if (cursorPos == 0xFF)
{
for (i = 0; i < 4; i++)
{
LoadPalette(&sDexScreen_CategoryCursorPals[0], PLTT_ID(i) + PLTT_ID(5) + 2 + BG_PLTT_OFFSET, PLTT_SIZEOF(1));
LoadPalette(&sDexScreen_CategoryCursorPals[1], PLTT_ID(i) + PLTT_ID(5) + 8 + BG_PLTT_OFFSET, PLTT_SIZEOF(1));
}
LoadPalette(&sDexScreen_CategoryCursorPals[0], 0x141, PLTT_SIZEOF(1));
sPokedexScreenData->categoryPageSelectionCursorTimer = 0;
}
else
{
sPokedexScreenData->categoryPageSelectionCursorTimer++;
if (sPokedexScreenData->categoryPageSelectionCursorTimer == 16)
sPokedexScreenData->categoryPageSelectionCursorTimer = 0;
palIdx = sPokedexScreenData->categoryPageSelectionCursorTimer >> 2;
for (i = 0; i < 4; i++)
{
if (i == cursorPos)
{
LoadPalette(&sDexScreen_CategoryCursorPals[2 * palIdx + 2], PLTT_ID(i) + PLTT_ID(5) + 2 + BG_PLTT_OFFSET, PLTT_SIZEOF(1));
LoadPalette(&sDexScreen_CategoryCursorPals[2 * palIdx + 3], PLTT_ID(i) + PLTT_ID(5) + 8 + BG_PLTT_OFFSET, PLTT_SIZEOF(1));
}
else
{
LoadPalette(&sDexScreen_CategoryCursorPals[0], PLTT_ID(i) + PLTT_ID(5) + 2 + BG_PLTT_OFFSET, PLTT_SIZEOF(1));
LoadPalette(&sDexScreen_CategoryCursorPals[1], PLTT_ID(i) + PLTT_ID(5) + 8 + BG_PLTT_OFFSET, PLTT_SIZEOF(1));
}
}
LoadPalette(&sDexScreen_CategoryCursorPals[2 * palIdx + 2], OBJ_PLTT_ID(4) + 1, PLTT_SIZEOF(1));
}
}
static void DexScreen_UpdateCategoryPageCursorObject(u8 taskId, u8 cursorPos, u8 numMonsInPage)
{
numMonsInPage--;
ListMenuUpdateCursorObject(taskId, sCategoryPageIconCoords[numMonsInPage][cursorPos][2] * 8, sCategoryPageIconCoords[numMonsInPage][cursorPos][3] * 8, 0);
}
bool8 DexPage_TileBuffer_CopyCol(const u16 *srcBuf, u8 srcCol, u16 *dstBuf, u8 dstCol)
{
int i;
const u16 *src = &srcBuf[srcCol];
u16 *dst = &dstBuf[dstCol];
for (i = 0; i < 20; i++)
{
*dst = *src;
dst += 32;
src += 32;
}
return FALSE;
}
bool8 DexPage_TileBuffer_FillCol(u16 tileNo, u16 *tileBuf, u8 x)
{
int i;
u16 *dst = &tileBuf[x];
for (i = 0; i < 20; i++)
{
*dst = tileNo;
dst += 32;
}
return FALSE;
}
bool8 DexScreen_TurnCategoryPage_BgEffect(u8 page)
{
int dstCol;
int srcCol;
u16 *bg1buff = GetBgTilemapBuffer(1);
u16 *bg2buff = GetBgTilemapBuffer(2);
u16 *bg3buff = GetBgTilemapBuffer(3);
u16 *bg1mem = sPokedexScreenData->bgBufsMem + 0x800;
u16 *bg2mem = sPokedexScreenData->bgBufsMem + 0x400;
u16 *bg3mem = sPokedexScreenData->bgBufsMem + 0x000;
for (dstCol = 0; dstCol < 30; dstCol++)
{
srcCol = sDexScreenPageTurnColumns[page][dstCol];
if (srcCol == 30)
{
DexPage_TileBuffer_FillCol(0x000, bg1buff, dstCol);
DexPage_TileBuffer_FillCol(0x000, bg2buff, dstCol);
DexPage_TileBuffer_FillCol(0x00C, bg3buff, dstCol);
}
else
{
DexPage_TileBuffer_CopyCol(bg1mem, srcCol, bg1buff, dstCol);
DexPage_TileBuffer_CopyCol(bg2mem, srcCol, bg2buff, dstCol);
DexPage_TileBuffer_CopyCol(bg3mem, srcCol, bg3buff, dstCol);
}
}
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(3);
return FALSE;
}
/*
* Direction = 0: Left; 1: Right
*/
static bool8 DexScreen_FlipCategoryPageInDirection(u8 direction)
{
u16 color;
if (IsNationalPokedexEnabled())
color = sNationalDexPalette[7];
else
color = sKantoDexPalette[7];
switch (sPokedexScreenData->data[0])
{
case 0:
sPokedexScreenData->bgBufsMem = Alloc(3 * BG_SCREEN_SIZE);
if (direction)
sPokedexScreenData->data[0] = 6;
else
sPokedexScreenData->data[0] = 2;
break;
case 1:
Free(sPokedexScreenData->bgBufsMem);
return TRUE;
// Go left
case 2:
BeginNormalPaletteFade(0x00007FFF, 0, 0, 16, color);
sPokedexScreenData->data[0]++;
break;
case 3:
FillBgTilemapBufferRect_Palette0(3, 0x00C, 0, 0, 30, 20);
FillBgTilemapBufferRect_Palette0(2, 0x000, 0, 0, 32, 20);
FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 0, 32, 20);
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(3);
sPokedexScreenData->data[0]++;
break;
case 4:
BeginNormalPaletteFade(0x00007FFF, 0, 0, 0, color);
DexScreen_CreateCategoryListGfx(FALSE);
CpuFastCopy(GetBgTilemapBuffer(3), &sPokedexScreenData->bgBufsMem[0 * BG_SCREEN_SIZE / 2], BG_SCREEN_SIZE);
CpuFastCopy(GetBgTilemapBuffer(2), &sPokedexScreenData->bgBufsMem[1 * BG_SCREEN_SIZE / 2], BG_SCREEN_SIZE);
CpuFastCopy(GetBgTilemapBuffer(1), &sPokedexScreenData->bgBufsMem[2 * BG_SCREEN_SIZE / 2], BG_SCREEN_SIZE);
FillBgTilemapBufferRect_Palette0(3, 0x00C, 0, 0, 30, 20);
FillBgTilemapBufferRect_Palette0(2, 0x000, 0, 0, 32, 20);
FillBgTilemapBufferRect_Palette0(1, 0x000, 0, 0, 32, 20);
sPokedexScreenData->data[1] = 0;
sPokedexScreenData->data[0]++;
PlaySE(SE_BALL_TRAY_ENTER);
break;
case 5:
if (sPokedexScreenData->data[1] < 10)
{
DexScreen_TurnCategoryPage_BgEffect(sPokedexScreenData->data[1]);
sPokedexScreenData->data[1]++;
}
else
{
sPokedexScreenData->data[0] = 1;
}
break;
// Go right
case 6:
CpuFastCopy(GetBgTilemapBuffer(3), &sPokedexScreenData->bgBufsMem[0 * BG_SCREEN_SIZE / 2], BG_SCREEN_SIZE);
CpuFastCopy(GetBgTilemapBuffer(2), &sPokedexScreenData->bgBufsMem[1 * BG_SCREEN_SIZE / 2], BG_SCREEN_SIZE);
CpuFastCopy(GetBgTilemapBuffer(1), &sPokedexScreenData->bgBufsMem[2 * BG_SCREEN_SIZE / 2], BG_SCREEN_SIZE);
sPokedexScreenData->data[1] = 9;
sPokedexScreenData->data[0]++;
PlaySE(SE_BALL_TRAY_ENTER);
break;
case 7:
if (sPokedexScreenData->data[1] != 0)
{
DexScreen_TurnCategoryPage_BgEffect(sPokedexScreenData->data[1]);
sPokedexScreenData->data[1]--;
}
else
{
#ifdef BUGFIX
DexScreen_TurnCategoryPage_BgEffect(0);
#else
DexScreen_TurnCategoryPage_BgEffect(sPokedexScreenData->data[0]);
#endif
BeginNormalPaletteFade(0x00007FFF, 0, 16, 16, color);
sPokedexScreenData->data[0]++;
}
break;
case 8:
gPaletteFade.bufferTransferDisabled = TRUE;
DexScreen_CreateCategoryListGfx(FALSE);
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(3);
sPokedexScreenData->data[0]++;
break;
case 9:
gPaletteFade.bufferTransferDisabled = FALSE;
BeginNormalPaletteFade(0x00007FFF, 0, 16, 0, color);
sPokedexScreenData->data[0] = 1;
break;
}
return FALSE;
}
// Scale from 0 to 6
void DexScreen_DexPageZoomEffectFrame(u8 bg, u8 scale)
{
u8 tileLeft, tileTop, width, height;
s16 left, top, divY;
if (!sPokedexScreenData->numMonsOnPage)
{
tileLeft = sCategoryPageIconCoords[0][0][2];
tileTop = sCategoryPageIconCoords[0][0][3];
}
else
{
tileLeft = sCategoryPageIconCoords[sPokedexScreenData->numMonsOnPage - 1][sPokedexScreenData->categoryCursorPosInPage][2];
tileTop = sCategoryPageIconCoords[sPokedexScreenData->numMonsOnPage - 1][sPokedexScreenData->categoryCursorPosInPage][3];
}
width = 6 + (scale * 4);
height = 3 + (scale * 2);
if (width >= 28) // Make sure it's not wider than the screen
width = 28;
if (height >= 14) // Make sure it's not taller than the screen
height = 14;
left = tileLeft - ((scale * 4) / 2);
top = tileTop - ((scale * 2) / 2);
if ((left + width + 2) >= 30) // Don't wrap right...
left -= ((left + width + 2) - 30);
else if (left < 0) // ... left ...
left = 0;
if ((top + height + 2) >= 18) // ... down ...
top -= ((top + height + 2) - 18);
else if (top < 2) // or up.
top = 2;
divY = (top + 1) + ((height / 2) + 1); // The horizontal divider
// Top edge
FillBgTilemapBufferRect_Palette0(bg, 4, left, top, 1, 1);
FillBgTilemapBufferRect_Palette0(bg, 5, left + 1, top, width, 1);
FillBgTilemapBufferRect_Palette0(bg, BG_TILE_H_FLIP(4), left + 1 + width, top, 1, 1);
// Bottom edge
FillBgTilemapBufferRect_Palette0(bg, 10, left, top + 1 + height, 1, 1);
FillBgTilemapBufferRect_Palette0(bg, 11, left + 1, top + 1 + height, width, 1);
FillBgTilemapBufferRect_Palette0(bg, BG_TILE_H_FLIP(10), left + 1 + width, top + 1 + height, 1, 1);
// Left edge
FillBgTilemapBufferRect_Palette0(bg, 6, left, top + 1, 1, divY - top - 1);
FillBgTilemapBufferRect_Palette0(bg, 7, left, divY, 1, 1);
FillBgTilemapBufferRect_Palette0(bg, 9, left, divY + 1, 1, top + height - divY);
// Right edge
FillBgTilemapBufferRect_Palette0(bg, BG_TILE_H_FLIP(6), left + 1 + width, top + 1, 1, divY - top - 1);
FillBgTilemapBufferRect_Palette0(bg, BG_TILE_H_FLIP(7), left + 1 + width, divY, 1, 1);
FillBgTilemapBufferRect_Palette0(bg, BG_TILE_H_FLIP(9), left + 1 + width, divY + 1, 1, top + height - divY);
// Interior
FillBgTilemapBufferRect_Palette0(bg, 1, left + 1, top + 1, width, divY - top - 1);
FillBgTilemapBufferRect_Palette0(bg, 8, left + 1, divY, width, 1);
FillBgTilemapBufferRect_Palette0(bg, 2, left + 1, divY + 1, width, top + height - divY);
}
void DexScreen_PrintMonCategory(u8 windowId, u16 species, u8 x, u8 y)
{
u8 * categoryName;
u8 index, categoryStr[12];
species = SpeciesToNationalPokedexNum(species);
categoryName = (u8 *)gSpeciesInfo[species].categoryName;
index = 0;
if (DexScreen_GetSetPokedexFlag(species, FLAG_GET_CAUGHT, FALSE))
{
#if REVISION == 0
while ((categoryName[index] != CHAR_SPACE) && (index < 11))
#else
while ((categoryName[index] != EOS) && (index < 11))
#endif
{
categoryStr[index] = categoryName[index];
index++;
}
}
else
{
while (index < 11)
{
categoryStr[index] = CHAR_QUESTION_MARK;
index++;
}
}
categoryStr[index] = EOS;
DexScreen_AddTextPrinterParameterized(windowId, FONT_SMALL, categoryStr, x, y, 0);
x += GetStringWidth(FONT_SMALL, categoryStr, 0);
DexScreen_AddTextPrinterParameterized(windowId, FONT_SMALL, gText_PokedexPokemon, x, y, 0);
}
void DexScreen_PrintMonHeight(u8 windowId, u16 species, u8 x, u8 y)
{
u16 height;
u32 inches, feet;
const u8 *labelText;
u8 buffer[32];
u8 i;
species = SpeciesToNationalPokedexNum(species);
height = gSpeciesInfo[species].height;
labelText = gText_HT;
i = 0;
buffer[i++] = EXT_CTRL_CODE_BEGIN;
buffer[i++] = EXT_CTRL_CODE_MIN_LETTER_SPACING;
buffer[i++] = 5;
buffer[i++] = CHAR_SPACE;
if (DexScreen_GetSetPokedexFlag(species, FLAG_GET_CAUGHT, FALSE))
{
inches = 10000 * height / 254; // actually tenths of inches here
if (inches % 10 >= 5)
inches += 10;
feet = inches / 120;
inches = (inches - (feet * 120)) / 10;
if (feet / 10 == 0)
{
buffer[i++] = 0;
buffer[i++] = feet + CHAR_0;
}
else
{
buffer[i++] = feet / 10 + CHAR_0;
buffer[i++] = feet % 10 + CHAR_0;
}
buffer[i++] = CHAR_SGL_QUOTE_RIGHT;
buffer[i++] = inches / 10 + CHAR_0;
buffer[i++] = inches % 10 + CHAR_0;
buffer[i++] = CHAR_DBL_QUOTE_RIGHT;
buffer[i++] = EOS;
}
else
{
buffer[i++] = CHAR_QUESTION_MARK;
buffer[i++] = CHAR_QUESTION_MARK;
buffer[i++] = CHAR_SGL_QUOTE_RIGHT;
buffer[i++] = CHAR_QUESTION_MARK;
buffer[i++] = CHAR_QUESTION_MARK;
buffer[i++] = CHAR_DBL_QUOTE_RIGHT;
}
buffer[i++] = EOS;
DexScreen_AddTextPrinterParameterized(windowId, FONT_SMALL, labelText, x, y, 0);
x += 30;
DexScreen_AddTextPrinterParameterized(windowId, FONT_SMALL, buffer, x, y, 0);
}
void DexScreen_PrintMonWeight(u8 windowId, u16 species, u8 x, u8 y)
{
u16 weight;
u32 lbs;
bool8 output;
const u8 * labelText;
const u8 * lbsText;
u8 buffer[32];
u8 i;
u32 j;
species = SpeciesToNationalPokedexNum(species);
weight = gSpeciesInfo[species].weight;
labelText = gText_WT;
lbsText = gText_Lbs;
i = 0;
buffer[i++] = EXT_CTRL_CODE_BEGIN;
buffer[i++] = EXT_CTRL_CODE_MIN_LETTER_SPACING;
buffer[i++] = 5;
if (DexScreen_GetSetPokedexFlag(species, FLAG_GET_CAUGHT, FALSE))
{
lbs = (weight * 100000) / 4536; // Convert to hundredths of lb
// Round up to the nearest 0.1 lb
if (lbs % 10 >= 5)
lbs += 10;
output = FALSE;
if ((buffer[i] = (lbs / 100000) + CHAR_0) == CHAR_0 && !output)
{
buffer[i++] = CHAR_SPACE;
}
else
{
output = TRUE;
i++;
}
lbs %= 100000;
if ((buffer[i] = (lbs / 10000) + CHAR_0) == CHAR_0 && !output)
{
buffer[i++] = CHAR_SPACE;
}
else
{
output = TRUE;
i++;
}
lbs %= 10000;
if ((buffer[i] = (lbs / 1000) + CHAR_0) == CHAR_0 && !output)
{
buffer[i++] = CHAR_SPACE;
}
else
{
output = TRUE;
i++;
}
lbs %= 1000;
buffer[i++] = (lbs / 100) + CHAR_0;
lbs %= 100;
buffer[i++] = CHAR_PERIOD;
buffer[i++] = (lbs / 10) + CHAR_0;
}
else
{
buffer[i++] = CHAR_QUESTION_MARK;
buffer[i++] = CHAR_QUESTION_MARK;
buffer[i++] = CHAR_QUESTION_MARK;
buffer[i++] = CHAR_QUESTION_MARK;
buffer[i++] = CHAR_PERIOD;
buffer[i++] = CHAR_QUESTION_MARK;
}
buffer[i++] = CHAR_SPACE;
buffer[i++] = EXT_CTRL_CODE_BEGIN;
buffer[i++] = EXT_CTRL_CODE_MIN_LETTER_SPACING;
buffer[i++] = 0;
for (j = 0; j < 33 - i && lbsText[j] != EOS; j++)
buffer[i + j] = lbsText[j];
buffer[i + j] = EOS;
DexScreen_AddTextPrinterParameterized(windowId, FONT_SMALL, labelText, x, y, 0);
x += 30;
DexScreen_AddTextPrinterParameterized(windowId, FONT_SMALL, buffer, x, y, 0);
}
void DexScreen_PrintMonFlavorText(u8 windowId, u16 species, u8 x, u8 y)
{
struct TextPrinterTemplate printerTemplate;
u16 length;
s32 xCenter;
species = SpeciesToNationalPokedexNum(species);
if (DexScreen_GetSetPokedexFlag(species, FLAG_GET_CAUGHT, FALSE))
{
printerTemplate.currentChar = gSpeciesInfo[species].description;
printerTemplate.windowId = windowId;
printerTemplate.fontId = FONT_NORMAL;
printerTemplate.letterSpacing = 1;
printerTemplate.lineSpacing = 0;
printerTemplate.unk = 0;
printerTemplate.fgColor = 1;
printerTemplate.bgColor = 0;
printerTemplate.shadowColor = 2;
length = GetStringWidth(FONT_NORMAL, gSpeciesInfo[species].description, 0);
xCenter = x + (240 - length) / 2;
if (xCenter > 0)
x = xCenter;
else
x = 0;
printerTemplate.x = x;
printerTemplate.y = y;
printerTemplate.currentX = x;
printerTemplate.currentY = y;
AddTextPrinter(&printerTemplate, TEXT_SKIP_DRAW, NULL);
}
}
void DexScreen_DrawMonFootprint(u8 windowId, u16 species, u8 x, u8 y)
{
u16 i, j, unused, tileIdx;
u8 footprintPixel, footprintTile;
u8 * buffer;
u8 * footprint;
if (!(DexScreen_GetSetPokedexFlag(species, FLAG_GET_CAUGHT, TRUE)))
return;
footprint = (u8 *)(gSpeciesInfo[species].footprint);
buffer = gDecompressionBuffer;
unused = 0;
tileIdx = 0;
// Expand 1bpp to 4bpp
for (i = 0; i < 32; i++)
{
footprintPixel = footprint[i];
for (j = 0; j < 8 / 2; j++)
{
footprintTile = 0;
if (footprintPixel & (1 << (j * 2)))
footprintTile |= 0x01;
if (footprintPixel & (2 << (j * 2)))
footprintTile |= 0x10;
buffer[tileIdx] = footprintTile;
tileIdx++;
}
}
BlitBitmapRectToWindow(windowId, buffer, 0, 0, 16, 16, x, y, 16, 16);
}
static u8 DexScreen_DrawMonDexPage(bool8 justRegistered)
{
DexScreen_DexPageZoomEffectFrame(3, 6);
FillBgTilemapBufferRect_Palette0(2, 0, 0, 0, 30, 20);
FillBgTilemapBufferRect_Palette0(1, 0, 0, 0, 30, 20);
FillBgTilemapBufferRect_Palette0(0, 0, 0, 2, 30, 16);
sPokedexScreenData->windowIds[0] = AddWindow(&sWindowTemplate_DexEntry_MonPic);
sPokedexScreenData->windowIds[1] = AddWindow(&sWindowTemplate_DexEntry_SpeciesStats);
sPokedexScreenData->windowIds[2] = AddWindow(&sWindowTemplate_DexEntry_FlavorText);
// Mon pic
FillWindowPixelBuffer(sPokedexScreenData->windowIds[0], PIXEL_FILL(0));
DexScreen_LoadMonPicInWindow(sPokedexScreenData->windowIds[0], sPokedexScreenData->dexSpecies, 144);
PutWindowTilemap(sPokedexScreenData->windowIds[0]);
CopyWindowToVram(sPokedexScreenData->windowIds[0], COPYWIN_GFX);
// Species stats
FillWindowPixelBuffer(sPokedexScreenData->windowIds[1], PIXEL_FILL(0));
DexScreen_PrintMonDexNo(sPokedexScreenData->windowIds[1], FONT_SMALL, sPokedexScreenData->dexSpecies, 0, 8);
DexScreen_AddTextPrinterParameterized(sPokedexScreenData->windowIds[1], FONT_NORMAL, gSpeciesInfo[sPokedexScreenData->dexSpecies].speciesName, 28, 8, 0);
DexScreen_PrintMonCategory(sPokedexScreenData->windowIds[1], sPokedexScreenData->dexSpecies, 0, 24);
DexScreen_PrintMonHeight(sPokedexScreenData->windowIds[1], sPokedexScreenData->dexSpecies, 0, 36);
DexScreen_PrintMonWeight(sPokedexScreenData->windowIds[1], sPokedexScreenData->dexSpecies, 0, 48);
DexScreen_DrawMonFootprint(sPokedexScreenData->windowIds[1], sPokedexScreenData->dexSpecies, 88, 40);
PutWindowTilemap(sPokedexScreenData->windowIds[1]);
CopyWindowToVram(sPokedexScreenData->windowIds[1], COPYWIN_GFX);
// Dex entry
FillWindowPixelBuffer(sPokedexScreenData->windowIds[2], PIXEL_FILL(0));
DexScreen_PrintMonFlavorText(sPokedexScreenData->windowIds[2], sPokedexScreenData->dexSpecies, 0, 8);
PutWindowTilemap(sPokedexScreenData->windowIds[2]);
CopyWindowToVram(sPokedexScreenData->windowIds[2], COPYWIN_GFX);
// Control info
FillWindowPixelBuffer(1, PIXEL_FILL(15));
if (justRegistered == FALSE)
{
DexScreen_AddTextPrinterParameterized(1, FONT_SMALL, gText_Cry, 8, 2, 4);
DexScreen_PrintControlInfo(gText_NextDataCancel);
}
else
// Just registered
DexScreen_PrintControlInfo(gText_Next);
PutWindowTilemap(1);
CopyWindowToVram(1, COPYWIN_GFX);
return 1;
}
u8 RemoveDexPageWindows(void)
{
DexScreen_RemoveWindow(&sPokedexScreenData->windowIds[0]);
DexScreen_RemoveWindow(&sPokedexScreenData->windowIds[1]);
DexScreen_RemoveWindow(&sPokedexScreenData->windowIds[2]);
return 0;
}
u8 DexScreen_DrawMonAreaPage(void)
{
int i;
u8 width, height;
bool8 monIsCaught;
s16 left, top;
u16 speciesId, species;
u16 kantoMapVoff;
species = sPokedexScreenData->dexSpecies;
speciesId = SpeciesToNationalPokedexNum(species);
monIsCaught = DexScreen_GetSetPokedexFlag(species, FLAG_GET_CAUGHT, TRUE);
width = 28;
height = 14;
left = 0;
top = 2;
FillBgTilemapBufferRect_Palette0(3, 4, left, top, 1, 1);
FillBgTilemapBufferRect_Palette0(3, BG_TILE_H_FLIP(4), left + 1 + width, top, 1, 1);
FillBgTilemapBufferRect_Palette0(3, BG_TILE_V_FLIP(4), left, top + 1 + height, 1, 1);
FillBgTilemapBufferRect_Palette0(3, BG_TILE_H_V_FLIP(4), left + 1 + width, top + 1 + height, 1, 1);
FillBgTilemapBufferRect_Palette0(3, 5, left + 1, top, width, 1);
FillBgTilemapBufferRect_Palette0(3, BG_TILE_V_FLIP(5), left + 1, top + 1 + height, width, 1);
FillBgTilemapBufferRect_Palette0(3, 6, left, top + 1, 1, height);
FillBgTilemapBufferRect_Palette0(3, BG_TILE_H_FLIP(6), left + 1 + width, top + 1, 1, height);
FillBgTilemapBufferRect_Palette0(3, 1, left + 1, top + 1, width, height);
FillBgTilemapBufferRect_Palette0(0, 0, 0, 2, 30, 16);
width = 10;
height = 6;
left = 1;
top = 9;
FillBgTilemapBufferRect_Palette0(0, 29, left, top, 1, 1);
FillBgTilemapBufferRect_Palette0(0, BG_TILE_H_FLIP(29), left + 1 + width, top, 1, 1);
FillBgTilemapBufferRect_Palette0(0, BG_TILE_V_FLIP(29), left, top + 1 + height, 1, 1);
FillBgTilemapBufferRect_Palette0(0, BG_TILE_H_V_FLIP(29), left + 1 + width, top + 1 + height, 1, 1);
FillBgTilemapBufferRect_Palette0(0, 30, left + 1, top, width, 1);
FillBgTilemapBufferRect_Palette0(0, BG_TILE_V_FLIP(30), left + 1, top + 1 + height, width, 1);
FillBgTilemapBufferRect_Palette0(0, 31, left, top + 1, 1, height);
FillBgTilemapBufferRect_Palette0(0, BG_TILE_H_FLIP(31), left + 1 + width, top + 1, 1, height);
FillBgTilemapBufferRect_Palette0(2, 0, 0, 0, 30, 20);
FillBgTilemapBufferRect_Palette0(1, 0, 0, 0, 30, 20);
sPokedexScreenData->unlockedSeviiAreas = GetUnlockedSeviiAreas();
kantoMapVoff = 4;
// If any of the postgame islands are unlocked, Kanto map needs to be flush with the
// top of the screen.
for (i = 3; i < 7; i++)
if ((sPokedexScreenData->unlockedSeviiAreas >> i) & 1)
kantoMapVoff = 0;
sPokedexScreenData->windowIds[0] = AddWindow(&sWindowTemplate_AreaMap_Kanto);
CopyToWindowPixelBuffer(sPokedexScreenData->windowIds[0], (void *)sTilemap_AreaMap_Kanto, 0, 0);
SetWindowAttribute(sPokedexScreenData->windowIds[0], WINDOW_TILEMAP_TOP,
GetWindowAttribute(sPokedexScreenData->windowIds[0], WINDOW_TILEMAP_TOP) + kantoMapVoff);
PutWindowTilemap(sPokedexScreenData->windowIds[0]);
for (i = 0; i < 7; i++)
if ((sPokedexScreenData->unlockedSeviiAreas >> i) & 1)
{
sPokedexScreenData->windowIds[i + 1] = AddWindow(sAreaMapStructs_SeviiIslands[i].window);
CopyToWindowPixelBuffer(sPokedexScreenData->windowIds[i + 1], sAreaMapStructs_SeviiIslands[i].tiles, 0, 0);
SetWindowAttribute(sPokedexScreenData->windowIds[i + 1], WINDOW_TILEMAP_TOP, GetWindowAttribute(sPokedexScreenData->windowIds[i + 1], WINDOW_TILEMAP_TOP) + kantoMapVoff);
PutWindowTilemap(sPokedexScreenData->windowIds[i + 1]);
CopyWindowToVram(sPokedexScreenData->windowIds[i + 1], COPYWIN_GFX);
}
sPokedexScreenData->windowIds[8] = AddWindow(&sWindowTemplate_AreaMap_SpeciesName);
sPokedexScreenData->windowIds[9] = AddWindow(&sWindowTemplate_AreaMap_Size);
sPokedexScreenData->windowIds[10] = AddWindow(&sWindowTemplate_AreaMap_Area);
sPokedexScreenData->windowIds[11] = AddWindow(&sWindowTemplate_AreaMap_MonIcon);
sPokedexScreenData->windowIds[12] = AddWindow(&sWindowTemplate_AreaMap_MonTypes);
// Draw the mon icon
FillWindowPixelBuffer(sPokedexScreenData->windowIds[11], PIXEL_FILL(0));
ListMenu_LoadMonIconPalette(BG_PLTT_ID(10), species);
ListMenu_DrawMonIconGraphics(sPokedexScreenData->windowIds[11], species, DexScreen_GetDefaultPersonality(species), 0, 0);
PutWindowTilemap(sPokedexScreenData->windowIds[11]);
CopyWindowToVram(sPokedexScreenData->windowIds[11], COPYWIN_GFX);
// Print "Size"
FillWindowPixelBuffer(sPokedexScreenData->windowIds[9], PIXEL_FILL(0));
{
s32 strWidth = GetStringWidth(FONT_SMALL, gText_Size, 0);
DexScreen_AddTextPrinterParameterized(sPokedexScreenData->windowIds[9], FONT_SMALL, gText_Size, (sWindowTemplate_AreaMap_Size.width * 8 - strWidth) / 2, 4, 0);
}
PutWindowTilemap(sPokedexScreenData->windowIds[9]);
CopyWindowToVram(sPokedexScreenData->windowIds[9], COPYWIN_GFX);
// Print "Area"
FillWindowPixelBuffer(sPokedexScreenData->windowIds[10], PIXEL_FILL(0));
{
s32 strWidth = GetStringWidth(FONT_SMALL, gText_Area, 0);
DexScreen_AddTextPrinterParameterized(sPokedexScreenData->windowIds[10], FONT_SMALL, gText_Area, (sWindowTemplate_AreaMap_Area.width * 8 - strWidth) / 2, 4, 0);
}
SetWindowAttribute(sPokedexScreenData->windowIds[10], WINDOW_TILEMAP_TOP, GetWindowAttribute(sPokedexScreenData->windowIds[10], WINDOW_TILEMAP_TOP) + kantoMapVoff);
PutWindowTilemap(sPokedexScreenData->windowIds[10]);
CopyWindowToVram(sPokedexScreenData->windowIds[10], COPYWIN_GFX);
// Print species name
FillWindowPixelBuffer(sPokedexScreenData->windowIds[8], PIXEL_FILL(0));
DexScreen_PrintMonDexNo(sPokedexScreenData->windowIds[8], FONT_SMALL, species, 0, 0);
DexScreen_AddTextPrinterParameterized(sPokedexScreenData->windowIds[8], FONT_NORMAL, gSpeciesInfo[species].speciesName, 3, 12, 0);
PutWindowTilemap(sPokedexScreenData->windowIds[8]);
CopyWindowToVram(sPokedexScreenData->windowIds[8], COPYWIN_GFX);
// Type icons
FillWindowPixelBuffer(sPokedexScreenData->windowIds[12], PIXEL_FILL(0));
ListMenuLoadStdPalAt(BG_PLTT_ID(11), 1);
if (monIsCaught)
{
BlitMenuInfoIcon(sPokedexScreenData->windowIds[12], 1 + gSpeciesInfo[species].types[0], 0, 1);
if (gSpeciesInfo[species].types[0] != gSpeciesInfo[species].types[1])
BlitMenuInfoIcon(sPokedexScreenData->windowIds[12], 1 + gSpeciesInfo[species].types[1], 32, 1);
}
PutWindowTilemap(sPokedexScreenData->windowIds[12]);
CopyWindowToVram(sPokedexScreenData->windowIds[12], COPYWIN_GFX);
// Show size comparison
ResetAllPicSprites();
LoadPalette(sPalette_Silhouette, OBJ_PLTT_ID(2), PLTT_SIZE_4BPP);
if (monIsCaught)
{
sPokedexScreenData->windowIds[14] = CreateMonPicSprite_HandleDeoxys(species, SHINY_ODDS, DexScreen_GetDefaultPersonality(species), TRUE, 40, 104, 0, 0xFFFF);
gSprites[sPokedexScreenData->windowIds[14]].oam.paletteNum = 2;
gSprites[sPokedexScreenData->windowIds[14]].oam.affineMode = ST_OAM_AFFINE_NORMAL;
gSprites[sPokedexScreenData->windowIds[14]].oam.matrixNum = 2;
gSprites[sPokedexScreenData->windowIds[14]].oam.priority = 1;
gSprites[sPokedexScreenData->windowIds[14]].y2 = gSpeciesInfo[speciesId].pokemonOffset;
SetOamMatrix(2, gSpeciesInfo[speciesId].pokemonScale, 0, 0, gSpeciesInfo[speciesId].pokemonScale);
sPokedexScreenData->windowIds[15] = CreateTrainerPicSprite(PlayerGenderToFrontTrainerPicId(gSaveBlock2Ptr->playerGender, TRUE), 1, 80, 104, 0, 0xFFFF);
gSprites[sPokedexScreenData->windowIds[15]].oam.paletteNum = 2;
gSprites[sPokedexScreenData->windowIds[15]].oam.affineMode = ST_OAM_AFFINE_NORMAL;
gSprites[sPokedexScreenData->windowIds[15]].oam.matrixNum = 1;
gSprites[sPokedexScreenData->windowIds[15]].oam.priority = 1;
gSprites[sPokedexScreenData->windowIds[15]].y2 = gSpeciesInfo[speciesId].trainerOffset;
SetOamMatrix(1, gSpeciesInfo[speciesId].trainerScale, 0, 0, gSpeciesInfo[speciesId].trainerScale);
}
else
{
sPokedexScreenData->windowIds[14] = 0xff;
sPokedexScreenData->windowIds[15] = 0xff;
}
// Create the area markers
sPokedexScreenData->areaMarkersTaskId = CreatePokedexAreaMarkers(species, TAG_AREA_MARKERS, 3, kantoMapVoff * 8);
if (GetNumPokedexAreaMarkers(sPokedexScreenData->areaMarkersTaskId) == 0)
{
// No markers, display "Area Unknown"
BlitBitmapRectToWindow(sPokedexScreenData->windowIds[0], (void *)sBlitTiles_WideEllipse, 0, 0, 88, 16, 4, 28, 88, 16);
{
s32 strWidth = GetStringWidth(FONT_SMALL, gText_AreaUnknown, 0);
DexScreen_AddTextPrinterParameterized(sPokedexScreenData->windowIds[0], FONT_SMALL, gText_AreaUnknown, (96 - strWidth) / 2, 29, 0);
}
}
CopyWindowToVram(sPokedexScreenData->windowIds[0], COPYWIN_GFX);
// Draw the control info
FillWindowPixelBuffer(1, PIXEL_FILL(15));
DexScreen_AddTextPrinterParameterized(1, FONT_SMALL, gText_Cry, 8, 2, 4);
DexScreen_PrintControlInfo(gText_CancelPreviousData);
PutWindowTilemap(1);
CopyWindowToVram(1, COPYWIN_GFX);
return 1;
}
u8 DexScreen_DestroyAreaScreenResources(void)
{
int i;
DestroyPokedexAreaMarkers(sPokedexScreenData->areaMarkersTaskId);
for (i = 0; i < 13; i++)
DexScreen_RemoveWindow(&sPokedexScreenData->windowIds[i]);
if (sPokedexScreenData->windowIds[15] != 0xff)
FreeAndDestroyTrainerPicSprite(sPokedexScreenData->windowIds[15]);
if (sPokedexScreenData->windowIds[14] != 0xff)
FreeAndDestroyMonPicSprite(sPokedexScreenData->windowIds[14]);
return 0;
}
static int DexScreen_CanShowMonInDex(u16 species)
{
if (IsNationalPokedexEnabled() == TRUE)
return TRUE;
if (NationalToKantoOrder(SpeciesToNationalPokedexNum(species)) > 0)
return TRUE;
return FALSE;
}
static u8 DexScreen_IsPageUnlocked(u8 categoryNum, u8 pageNum)
{
int i, count;
u16 species;
count = gDexCategories[categoryNum].page[pageNum].count;
for (i = 0; i < 4; i++)
{
if (i < count)
{
species = gDexCategories[categoryNum].page[pageNum].species[i];
if (DexScreen_CanShowMonInDex(species) == TRUE && DexScreen_GetSetPokedexFlag(species, FLAG_GET_SEEN, TRUE))
return TRUE;
}
}
return FALSE;
}
static bool8 DexScreen_IsCategoryUnlocked(u8 categoryNum)
{
int i;
u8 count;
count = gDexCategories[categoryNum].count;
for (i = 0; i < count; i++)
if (DexScreen_IsPageUnlocked(categoryNum, i))
return 1;
return 0;
}
void DexScreen_CreateCategoryPageSpeciesList(u8 categoryNum, u8 pageNum)
{
int i, count;
u16 species;
count = gDexCategories[categoryNum].page[pageNum].count;
sPokedexScreenData->numMonsOnPage = 0;
for (i = 0; i < 4; i++)
sPokedexScreenData->pageSpecies[i] = 0xffff;
for (i = 0; i < count; i++)
{
species = gDexCategories[categoryNum].page[pageNum].species[i];
if (DexScreen_CanShowMonInDex(species) == TRUE && DexScreen_GetSetPokedexFlag(species, FLAG_GET_SEEN, TRUE))
{
sPokedexScreenData->pageSpecies[sPokedexScreenData->numMonsOnPage] = gDexCategories[categoryNum].page[pageNum].species[i];
sPokedexScreenData->numMonsOnPage++;
}
}
}
static u8 DexScreen_GetPageLimitsForCategory(u8 category)
{
int i;
u8 count, firstPage, lastPage;
count = gDexCategories[category].count;
firstPage = 0xff;
lastPage = 0xff;
for (i = 0; i < count; i++)
if (DexScreen_IsPageUnlocked(category, i))
{
if (firstPage == 0xff)
firstPage = i;
lastPage = i;
}
if (lastPage != 0xff)
{
sPokedexScreenData->firstPageInCategory = firstPage;
sPokedexScreenData->lastPageInCategory = lastPage + 1;
return FALSE;
}
else
{
sPokedexScreenData->firstPageInCategory = 0;
sPokedexScreenData->lastPageInCategory = 0;
return TRUE;
}
}
static u8 DexScreen_LookUpCategoryBySpecies(u16 species)
{
int i, j, k, categoryCount, categoryPageCount, posInPage;
u16 dexSpecies;
for (i = 0; i < NELEMS(gDexCategories); i++)
{
categoryCount = gDexCategories[i].count;
for (j = 0; j < categoryCount; j++)
{
categoryPageCount = gDexCategories[i].page[j].count;
for (k = 0, posInPage = 0; k < categoryPageCount; k++)
{
dexSpecies = gDexCategories[i].page[j].species[k];
if (species == dexSpecies)
{
sPokedexScreenData->category = i;
sPokedexScreenData->pageNum = j;
sPokedexScreenData->categoryCursorPosInPage = posInPage;
return FALSE;
}
if (DexScreen_CanShowMonInDex(dexSpecies) == TRUE && DexScreen_GetSetPokedexFlag(dexSpecies, FLAG_GET_SEEN, TRUE))
posInPage++;
}
}
}
return TRUE;
}
static u8 DexScreen_PageNumberToRenderablePages(u16 page)
{
int i, count;
for (i = 0, count = 0; i < page; i++)
if (DexScreen_IsPageUnlocked(sPokedexScreenData->category, i))
count++;
return count + 1;
}
void DexScreen_InputHandler_StartToCry(void)
{
if (JOY_NEW(START_BUTTON))
PlayCry_NormalNoDucking(sPokedexScreenData->dexSpecies, 0, CRY_VOLUME_RS, CRY_PRIORITY_NORMAL);
}
u8 DexScreen_RegisterMonToPokedex(u16 species)
{
DexScreen_GetSetPokedexFlag(species, FLAG_SET_SEEN, TRUE);
DexScreen_GetSetPokedexFlag(species, FLAG_SET_CAUGHT, TRUE);
if (!IsNationalPokedexEnabled() && NationalToKantoOrder(SpeciesToNationalPokedexNum(species)) > 0)
return CreateTask(Task_DexScreen_RegisterNonKantoMonBeforeNationalDex, 0);
DexScreen_LoadResources();
gTasks[sPokedexScreenData->taskId].func = Task_DexScreen_RegisterMonToPokedex;
DexScreen_LookUpCategoryBySpecies(species);
return sPokedexScreenData->taskId;
}
static void Task_DexScreen_RegisterNonKantoMonBeforeNationalDex(u8 taskId)
{
DestroyTask(taskId);
}
static void Task_DexScreen_RegisterMonToPokedex(u8 taskId)
{
switch (sPokedexScreenData->state)
{
case 0:
DexScreen_GetPageLimitsForCategory(sPokedexScreenData->category);
if (sPokedexScreenData->pageNum < sPokedexScreenData->firstPageInCategory)
sPokedexScreenData->pageNum = sPokedexScreenData->firstPageInCategory;
sPokedexScreenData->state = 3;
break;
case 1:
RemoveDexPageWindows();
DexScreen_DestroyCategoryPageMonIconAndInfoWindows();
gMain.state = 0;
sPokedexScreenData->state = 2;
break;
case 2:
if (DoClosePokedex())
DestroyTask(taskId);
break;
case 3:
DexScreen_CreateCategoryListGfx(TRUE);
PutWindowTilemap(0);
PutWindowTilemap(1);
CopyBgTilemapBufferToVram(3);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(0);
DexScreen_CreateCategoryPageSelectionCursor(0xff);
sPokedexScreenData->state = 4;
break;
case 4:
gPaletteFade.bufferTransferDisabled = 0;
BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, 0xffff);
ShowBg(3);
ShowBg(2);
ShowBg(1);
ShowBg(0);
sPokedexScreenData->state = 5;
break;
case 5:
gTasks[taskId].data[0] = 30;
sPokedexScreenData->categoryPageCursorTaskId = ListMenuAddCursorObjectInternal(&sCursorStruct_CategoryPage, 0);
sPokedexScreenData->state = 6;
break;
case 6:
DexScreen_CreateCategoryPageSelectionCursor(sPokedexScreenData->categoryCursorPosInPage);
DexScreen_UpdateCategoryPageCursorObject(sPokedexScreenData->categoryPageCursorTaskId, sPokedexScreenData->categoryCursorPosInPage, sPokedexScreenData->numMonsOnPage);
if (gTasks[taskId].data[0])
gTasks[taskId].data[0]--;
else
{
ListMenuRemoveCursorObject(sPokedexScreenData->categoryPageCursorTaskId, 0);
sPokedexScreenData->state = 7;
}
break;
case 7:
sPokedexScreenData->dexSpecies = sPokedexScreenData->pageSpecies[sPokedexScreenData->categoryCursorPosInPage];
sPokedexScreenData->state = 8;
break;
case 8:
DexScreen_DrawMonDexPage(TRUE);
sPokedexScreenData->state = 9;
break;
case 9:
sPokedexScreenData->data[0] = 0;
sPokedexScreenData->data[1] = 0;
sPokedexScreenData->state++;
case 10:
if (sPokedexScreenData->data[1] < 6)
{
if (sPokedexScreenData->data[0])
{
DexScreen_DexPageZoomEffectFrame(0, sPokedexScreenData->data[1]);
CopyBgTilemapBufferToVram(0);
sPokedexScreenData->data[0] = 4;
sPokedexScreenData->data[1]++;
}
else
sPokedexScreenData->data[0]--;
}
else
{
FillBgTilemapBufferRect_Palette0(0, 0, 0, 2, 30, 16);
CopyBgTilemapBufferToVram(3);
CopyBgTilemapBufferToVram(2);
CopyBgTilemapBufferToVram(1);
CopyBgTilemapBufferToVram(0);
PlayCry_NormalNoDucking(sPokedexScreenData->dexSpecies, 0, CRY_VOLUME_RS, CRY_PRIORITY_NORMAL);
sPokedexScreenData->data[0] = 0;
sPokedexScreenData->state = 11;
}
break;
case 11:
if (JOY_NEW(A_BUTTON | B_BUTTON))
sPokedexScreenData->state = 2;
break;
}
}
void DexScreen_PrintStringWithAlignment(const u8 * str, s32 mode)
{
u32 x;
switch (mode)
{
case TEXT_LEFT:
x = 8;
break;
case TEXT_CENTER:
x = (u32)(240 - GetStringWidth(FONT_NORMAL, str, 0)) / 2;
break;
case TEXT_RIGHT:
default:
x = 232 - GetStringWidth(FONT_NORMAL, str, 0);
break;
}
DexScreen_AddTextPrinterParameterized(0, FONT_NORMAL, str, x, 2, 4);
}