mirror of
https://github.com/pret/pokefirered.git
synced 2026-05-14 16:20:24 -05:00
3461 lines
122 KiB
C
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);
|
|
}
|