diff --git a/include/pokedex.h b/include/pokedex.h index 0e20648f7..8e27bbe56 100644 --- a/include/pokedex.h +++ b/include/pokedex.h @@ -15,6 +15,90 @@ enum FLAG_SET_CAUGHT }; +// IDs for the pokedex area markers +enum { + DEX_AREA_NONE, + DEX_AREA_PALLET_TOWN, + DEX_AREA_VIRIDIAN_CITY, + DEX_AREA_PEWTER_CITY, + DEX_AREA_CERULEAN_CITY, + DEX_AREA_LAVENDER_TOWN, + DEX_AREA_VERMILION_CITY, + DEX_AREA_CELADON_CITY, + DEX_AREA_FUCHSIA_CITY, + DEX_AREA_CINNABAR_ISLAND, + DEX_AREA_INDIGO_PLATEAU, + DEX_AREA_SAFFRON_CITY, + DEX_AREA_ROUTE_1, + DEX_AREA_ROUTE_2, + DEX_AREA_ROUTE_3, + DEX_AREA_ROUTE_4, + DEX_AREA_ROUTE_5, + DEX_AREA_ROUTE_6, + DEX_AREA_ROUTE_7, + DEX_AREA_ROUTE_8, + DEX_AREA_ROUTE_9, + DEX_AREA_ROUTE_10, + DEX_AREA_ROUTE_11, + DEX_AREA_ROUTE_12, + DEX_AREA_ROUTE_13, + DEX_AREA_ROUTE_14, + DEX_AREA_ROUTE_15, + DEX_AREA_ROUTE_16, + DEX_AREA_ROUTE_17, + DEX_AREA_ROUTE_18, + DEX_AREA_ROUTE_19, + DEX_AREA_ROUTE_20, + DEX_AREA_ROUTE_21, + DEX_AREA_ROUTE_22, + DEX_AREA_ROUTE_23, + DEX_AREA_ROUTE_24, + DEX_AREA_ROUTE_25, + DEX_AREA_VIRIDIAN_FOREST, + DEX_AREA_DIGLETTS_CAVE, + DEX_AREA_MT_MOON, + DEX_AREA_CERULEAN_CAVE, + DEX_AREA_ROCK_TUNNEL, + DEX_AREA_POWER_PLANT, + DEX_AREA_POKEMON_TOWER, + DEX_AREA_SAFARI_ZONE, + DEX_AREA_SEAFOAM_ISLANDS, + DEX_AREA_POKEMON_MANSION, + DEX_AREA_VICTORY_ROAD, + DEX_AREA_ONE_ISLAND, + DEX_AREA_TWO_ISLAND, + DEX_AREA_THREE_ISLAND, + DEX_AREA_FOUR_ISLAND, + DEX_AREA_FIVE_ISLAND, + DEX_AREA_SIX_ISLAND, // Not associated with any MAPSEC + DEX_AREA_SEVEN_ISLAND, // Not associated with any MAPSEC + DEX_AREA_KINDLE_ROAD, + DEX_AREA_TREASURE_BEACH, + DEX_AREA_CAPE_BRINK, + DEX_AREA_BOND_BRIDGE, + DEX_AREA_THREE_ISLE_PATH, + DEX_AREA_RESORT_GORGEOUS, + DEX_AREA_WATER_LABYRINTH, + DEX_AREA_FIVE_ISLE_MEADOW, + DEX_AREA_MEMORIAL_PILLAR, + DEX_AREA_OUTCAST_ISLAND, + DEX_AREA_GREEN_PATH, + DEX_AREA_WATER_PATH, + DEX_AREA_RUIN_VALLEY, + DEX_AREA_TRAINER_TOWER, + DEX_AREA_CANYON_ENTRANCE, + DEX_AREA_SEVAULT_CANYON, + DEX_AREA_TANOBY_RUINS, + DEX_AREA_MT_EMBER, + DEX_AREA_BERRY_FOREST, + DEX_AREA_ICEFALL_CAVE, + DEX_AREA_LOST_CAVE, + DEX_AREA_ALTERING_CAVE, + DEX_AREA_PATTERN_BUSH, + DEX_AREA_DOTTED_HOLE, + DEX_AREA_TANOBY_CHAMBER, +}; + struct PokedexEntry { /*0x00*/ u8 categoryName[12]; diff --git a/include/pokedex_area_markers.h b/include/pokedex_area_markers.h index c0b1978cc..48f54389f 100644 --- a/include/pokedex_area_markers.h +++ b/include/pokedex_area_markers.h @@ -1,19 +1,9 @@ #ifndef GUARD_POKEDEX_AREA_MARKERS_H #define GUARD_POKEDEX_AREA_MARKERS_H -struct PAM_TaskData -{ - struct SubspriteTable subsprites; - void *buffer; - u8 unk_0C; - u8 spr_id; - u16 tilesTag; - u16 unk_10; -}; - -void SetAreaSubsprite(s32 i, s32 whichArea, struct Subsprite * subsprites); -void Dtor_PokedexAreaMarkers(u8 taskId); -u8 Ctor_PokedexAreaMarkers(u16 species, u16 tilesTag, u8 palIdx, u8 y); -u8 PokedexAreaMarkers_Any(u8 taskId); +void GetAreaMarkerSubsprite(s32 i, s32 dexArea, struct Subsprite * subsprites); +void DestroyPokedexAreaMarkers(u8 taskId); +u8 CreatePokedexAreaMarkers(u16 species, u16 tilesTag, u8 palIdx, u8 y); +u8 GetNumPokedexAreaMarkers(u8 taskId); #endif //GUARD_POKEDEX_AREA_MARKERS_H diff --git a/include/wild_encounter.h b/include/wild_encounter.h index 8e151d55d..b73010306 100644 --- a/include/wild_encounter.h +++ b/include/wild_encounter.h @@ -8,6 +8,8 @@ #define ROCK_WILD_COUNT 5 #define FISH_WILD_COUNT 10 +#define NUM_ALTERING_CAVE_TABLES 9 + struct WildPokemon { u8 minLevel; diff --git a/include/wild_pokemon_area.h b/include/wild_pokemon_area.h index 354683408..f1d67fd86 100644 --- a/include/wild_pokemon_area.h +++ b/include/wild_pokemon_area.h @@ -1,6 +1,6 @@ #ifndef GUARD_WILD_POKEMON_AREA_H #define GUARD_WILD_POKEMON_AREA_H -s32 BuildPokedexAreaSubspriteBuffer(u16 species, struct Subsprite * subsprites); +s32 GetSpeciesPokedexAreaMarkers(u16 species, struct Subsprite * subsprites); #endif //GUARD_WILD_POKEMON_AREA_H diff --git a/src/pokedex_area_markers.c b/src/pokedex_area_markers.c index 5226133ac..b98943b06 100644 --- a/src/pokedex_area_markers.c +++ b/src/pokedex_area_markers.c @@ -4,160 +4,191 @@ #include "task.h" #include "wild_pokemon_area.h" #include "pokedex_area_markers.h" +#include "pokedex.h" + +/* + Controls the red ellipse markers that appear on the pokedex maps to show where a species is found. + All of the markers together are a single sprite, with each individual marker being represented by + a subsprite of the necessary size and shape. + + The data about each area marker is in sAreaMarkers, each specified by a DEX_AREA constant. + A MAPSEC is associated with a DEX_AREA constant by a series of arrays in wild_pokemon_area.c +*/ + +struct PAM_TaskData +{ + struct SubspriteTable subsprites; + void *buffer; + u8 unused; + u8 spriteId; + u16 tilesTag; + u16 paletteTag; // Never read +}; + +enum { + MARKER_CIRCULAR, + MARKER_SMALL_H, + MARKER_SMALL_V, + MARKER_MED_H, + MARKER_MED_V, + MARKER_LARGE_H, + MARKER_LARGE_V, +}; static const u16 sMarkerPal[] = INCBIN_U16("graphics/pokedex/area_markers/marker.gbapal"); static const u32 sMarkerTiles[] = INCBIN_U32("graphics/pokedex/area_markers/marker.4bpp.lz"); -static const struct Subsprite sSubsprite0 = { - .size = ST_OAM_SIZE_0, - .shape = ST_OAM_SQUARE, +static const struct Subsprite sSubsprite_Circular = { + .size = SPRITE_SIZE(8x8), + .shape = SPRITE_SHAPE(8x8), .priority = 1, .tileOffset = 0 }; -static const struct Subsprite sSubsprite1 = { - .size = ST_OAM_SIZE_0, - .shape = ST_OAM_H_RECTANGLE, +static const struct Subsprite sSubsprite_SmallHorizontal = { + .size = SPRITE_SIZE(16x8), + .shape = SPRITE_SHAPE(16x8), .priority = 1, .tileOffset = 1 }; -static const struct Subsprite sSubsprite2 = { - .size = ST_OAM_SIZE_0, - .shape = ST_OAM_V_RECTANGLE, +static const struct Subsprite sSubsprite_SmallVertical = { + .size = SPRITE_SIZE(8x16), + .shape = SPRITE_SHAPE(8x16), .priority = 1, .tileOffset = 3 }; -static const struct Subsprite sSubsprite3 = { - .size = ST_OAM_SIZE_2, - .shape = ST_OAM_H_RECTANGLE, +static const struct Subsprite sSubsprite_MediumHorizontal = { + .size = SPRITE_SIZE(32x16), + .shape = SPRITE_SHAPE(32x16), .priority = 1, .tileOffset = 5 }; -static const struct Subsprite sSubsprite4 = { - .size = ST_OAM_SIZE_2, - .shape = ST_OAM_V_RECTANGLE, +static const struct Subsprite sSubsprite_MediumVertical = { + .size = SPRITE_SIZE(16x32), + .shape = SPRITE_SHAPE(16x32), .priority = 1, .tileOffset = 13 }; -static const struct Subsprite sSubsprite5 = { - .size = ST_OAM_SIZE_2, - .shape = ST_OAM_H_RECTANGLE, +static const struct Subsprite sSubsprite_LargeHorizontal = { + .size = SPRITE_SIZE(32x16), + .shape = SPRITE_SHAPE(32x16), .priority = 1, .tileOffset = 21 }; -static const struct Subsprite sSubsprite6 = { - .size = ST_OAM_SIZE_2, - .shape = ST_OAM_V_RECTANGLE, +static const struct Subsprite sSubsprite_LargeVertical = { + .size = SPRITE_SIZE(16x32), + .shape = SPRITE_SHAPE(16x32), .priority = 1, .tileOffset = 29 }; static const struct Subsprite *const sSubsprites[] = { - &sSubsprite0, - &sSubsprite1, - &sSubsprite2, - &sSubsprite3, - &sSubsprite4, - &sSubsprite5, - &sSubsprite6 + [MARKER_CIRCULAR] = &sSubsprite_Circular, + [MARKER_SMALL_H] = &sSubsprite_SmallHorizontal, + [MARKER_SMALL_V] = &sSubsprite_SmallVertical, + [MARKER_MED_H] = &sSubsprite_MediumHorizontal, + [MARKER_MED_V] = &sSubsprite_MediumVertical, + [MARKER_LARGE_H] = &sSubsprite_LargeHorizontal, + [MARKER_LARGE_V] = &sSubsprite_LargeVertical }; -static const s8 sSubspriteLookupTable[][4] = { - { 0, 0x00, 0x00 }, - { 0, 0x36, 0x2c }, - { 0, 0x36, 0x1c }, - { 0, 0x36, 0x0c }, - { 0, 0x5c, 0x0c }, - { 0, 0x6e, 0x18 }, - { 0, 0x5c, 0x24 }, - { 0, 0x4c, 0x18 }, - { 0, 0x4e, 0x34 }, - { 0, 0x36, 0x3e }, - { 0, 0x2a, 0x02 }, - { 0, 0x5c, 0x18 }, - { 2, 0x36, 0x20 }, - { 2, 0x36, 0x10 }, - { 1, 0x3d, 0x0c }, - { 1, 0x4d, 0x0c }, - { 0, 0x5c, 0x12 }, - { 0, 0x5c, 0x1e }, - { 0, 0x54, 0x18 }, - { 1, 0x62, 0x18 }, - { 1, 0x62, 0x0c }, - { 2, 0x6e, 0x0c }, - { 1, 0x62, 0x24 }, - { 4, 0x6a, 0x19 }, - { 1, 0x64, 0x2e }, - { 2, 0x5e, 0x2d }, - { 1, 0x55, 0x34 }, - { 0, 0x44, 0x18 }, - { 4, 0x3e, 0x1a }, - { 1, 0x40, 0x34 }, - { 0, 0x4e, 0x3c }, - { 3, 0x37, 0x3a }, - { 2, 0x36, 0x32 }, - { 1, 0x28, 0x1c }, - { 4, 0x26, 0x04 }, - { 0, 0x5c, 0x04 }, - { 3, 0x5a, 0xfe }, - { 0, 0x33, 0x14 }, - { 1, 0x3d, 0x12 }, - { 0, 0x48, 0x08 }, - { 0, 0x57, 0x08 }, - { 0, 0x70, 0x0e }, - { 0, 0x71, 0x14 }, - { 0, 0x71, 0x19 }, - { 1, 0x4e, 0x2c }, - { 0, 0x41, 0x3c }, - { 0, 0x34, 0x3e }, - { 0, 0x2d, 0x07 }, - { 0, 0x0a, 0x0a }, - { 0, 0x0c, 0x23 }, - { 0, 0x0e, 0x34 }, - { 0, 0x0c, 0x54 }, - { 0, 0x2d, 0x51 }, - { 0, 0x4c, 0x54 }, - { 0, 0x68, 0x52 }, - { 2, 0x0e, 0x02 }, - { 0, 0x0a, 0x0f }, - { 0, 0x0c, 0x1d }, - { 1, 0x02, 0x34 }, - { 1, 0x0c, 0x38 }, - { 1, 0x2c, 0x4a }, - { 1, 0x24, 0x4e }, - { 2, 0x30, 0x50 }, - { 2, 0x34, 0x56 }, - { 0, 0x48, 0x4a }, - { 1, 0x48, 0x4e }, - { 2, 0x51, 0x50 }, - { 0, 0x4c, 0x5c }, - { 0, 0x68, 0x4b }, - { 0, 0x68, 0x56 }, - { 2, 0x6c, 0x53 }, - { 3, 0x60, 0x5a }, - { 0, 0x0e, 0x01 }, - { 0, 0x05, 0x34 }, - { 0, 0x0d, 0x50 }, - { 0, 0x36, 0x4a }, - { 0, 0x45, 0x49 }, - { 0, 0x4c, 0x4d }, - { 0, 0x49, 0x5f }, - { 3, 0x60, 0x5a } +static const s8 sAreaMarkers[][4] = { + // Marker, x, y + [DEX_AREA_NONE] = {}, + [DEX_AREA_PALLET_TOWN] = { MARKER_CIRCULAR, 54, 44 }, + [DEX_AREA_VIRIDIAN_CITY] = { MARKER_CIRCULAR, 54, 28 }, + [DEX_AREA_PEWTER_CITY] = { MARKER_CIRCULAR, 54, 12 }, + [DEX_AREA_CERULEAN_CITY] = { MARKER_CIRCULAR, 92, 12 }, + [DEX_AREA_LAVENDER_TOWN] = { MARKER_CIRCULAR, 110, 24 }, + [DEX_AREA_VERMILION_CITY] = { MARKER_CIRCULAR, 92, 36 }, + [DEX_AREA_CELADON_CITY] = { MARKER_CIRCULAR, 76, 24 }, + [DEX_AREA_FUCHSIA_CITY] = { MARKER_CIRCULAR, 78, 52 }, + [DEX_AREA_CINNABAR_ISLAND] = { MARKER_CIRCULAR, 54, 62 }, + [DEX_AREA_INDIGO_PLATEAU] = { MARKER_CIRCULAR, 42, 2 }, + [DEX_AREA_SAFFRON_CITY] = { MARKER_CIRCULAR, 92, 24 }, + [DEX_AREA_ROUTE_1] = { MARKER_SMALL_V, 54, 32 }, + [DEX_AREA_ROUTE_2] = { MARKER_SMALL_V, 54, 16 }, + [DEX_AREA_ROUTE_3] = { MARKER_SMALL_H, 61, 12 }, + [DEX_AREA_ROUTE_4] = { MARKER_SMALL_H, 77, 12 }, + [DEX_AREA_ROUTE_5] = { MARKER_CIRCULAR, 92, 18 }, + [DEX_AREA_ROUTE_6] = { MARKER_CIRCULAR, 92, 30 }, + [DEX_AREA_ROUTE_7] = { MARKER_CIRCULAR, 84, 24 }, + [DEX_AREA_ROUTE_8] = { MARKER_SMALL_H, 98, 24 }, + [DEX_AREA_ROUTE_9] = { MARKER_SMALL_H, 98, 12 }, + [DEX_AREA_ROUTE_10] = { MARKER_SMALL_V, 110, 12 }, + [DEX_AREA_ROUTE_11] = { MARKER_SMALL_H, 98, 36 }, + [DEX_AREA_ROUTE_12] = { MARKER_MED_V, 106, 25 }, + [DEX_AREA_ROUTE_13] = { MARKER_SMALL_H, 100, 46 }, + [DEX_AREA_ROUTE_14] = { MARKER_SMALL_V, 94, 45 }, + [DEX_AREA_ROUTE_15] = { MARKER_SMALL_H, 85, 52 }, + [DEX_AREA_ROUTE_16] = { MARKER_CIRCULAR, 68, 24 }, + [DEX_AREA_ROUTE_17] = { MARKER_MED_V, 62, 26 }, + [DEX_AREA_ROUTE_18] = { MARKER_SMALL_H, 64, 52 }, + [DEX_AREA_ROUTE_19] = { MARKER_CIRCULAR, 78, 60 }, + [DEX_AREA_ROUTE_20] = { MARKER_MED_H, 55, 58 }, + [DEX_AREA_ROUTE_21] = { MARKER_SMALL_V, 54, 50 }, + [DEX_AREA_ROUTE_22] = { MARKER_SMALL_H, 40, 28 }, + [DEX_AREA_ROUTE_23] = { MARKER_MED_V, 38, 4 }, + [DEX_AREA_ROUTE_24] = { MARKER_CIRCULAR, 92, 4 }, + [DEX_AREA_ROUTE_25] = { MARKER_MED_H, 90, -2 }, + [DEX_AREA_VIRIDIAN_FOREST] = { MARKER_CIRCULAR, 51, 20 }, + [DEX_AREA_DIGLETTS_CAVE] = { MARKER_SMALL_H, 61, 18 }, + [DEX_AREA_MT_MOON] = { MARKER_CIRCULAR, 72, 8 }, + [DEX_AREA_CERULEAN_CAVE] = { MARKER_CIRCULAR, 87, 8 }, + [DEX_AREA_ROCK_TUNNEL] = { MARKER_CIRCULAR, 112, 14 }, + [DEX_AREA_POWER_PLANT] = { MARKER_CIRCULAR, 113, 20 }, + [DEX_AREA_POKEMON_TOWER] = { MARKER_CIRCULAR, 113, 25 }, + [DEX_AREA_SAFARI_ZONE] = { MARKER_SMALL_H, 78, 44 }, + [DEX_AREA_SEAFOAM_ISLANDS] = { MARKER_CIRCULAR, 65, 60 }, + [DEX_AREA_POKEMON_MANSION] = { MARKER_CIRCULAR, 52, 62 }, + [DEX_AREA_VICTORY_ROAD] = { MARKER_CIRCULAR, 45, 7 }, + [DEX_AREA_ONE_ISLAND] = { MARKER_CIRCULAR, 10, 10 }, + [DEX_AREA_TWO_ISLAND] = { MARKER_CIRCULAR, 12, 35 }, + [DEX_AREA_THREE_ISLAND] = { MARKER_CIRCULAR, 14, 52 }, + [DEX_AREA_FOUR_ISLAND] = { MARKER_CIRCULAR, 12, 84 }, + [DEX_AREA_FIVE_ISLAND] = { MARKER_CIRCULAR, 45, 81 }, + [DEX_AREA_SIX_ISLAND] = { MARKER_CIRCULAR, 76, 84 }, + [DEX_AREA_SEVEN_ISLAND] = { MARKER_CIRCULAR, 104, 82 }, + [DEX_AREA_KINDLE_ROAD] = { MARKER_SMALL_V, 14, 2 }, + [DEX_AREA_TREASURE_BEACH] = { MARKER_CIRCULAR, 10, 15 }, + [DEX_AREA_CAPE_BRINK] = { MARKER_CIRCULAR, 12, 29 }, + [DEX_AREA_BOND_BRIDGE] = { MARKER_SMALL_H, 2, 52 }, + [DEX_AREA_THREE_ISLE_PATH] = { MARKER_SMALL_H, 12, 56 }, + [DEX_AREA_RESORT_GORGEOUS] = { MARKER_SMALL_H, 44, 74 }, + [DEX_AREA_WATER_LABYRINTH] = { MARKER_SMALL_H, 36, 78 }, + [DEX_AREA_FIVE_ISLE_MEADOW] = { MARKER_SMALL_V, 48, 80 }, + [DEX_AREA_MEMORIAL_PILLAR] = { MARKER_SMALL_V, 52, 86 }, + [DEX_AREA_OUTCAST_ISLAND] = { MARKER_CIRCULAR, 72, 74 }, + [DEX_AREA_GREEN_PATH] = { MARKER_SMALL_H, 72, 78 }, + [DEX_AREA_WATER_PATH] = { MARKER_SMALL_V, 81, 80 }, + [DEX_AREA_RUIN_VALLEY] = { MARKER_CIRCULAR, 76, 92 }, + [DEX_AREA_TRAINER_TOWER] = { MARKER_CIRCULAR, 104, 75 }, + [DEX_AREA_CANYON_ENTRANCE] = { MARKER_CIRCULAR, 104, 86 }, + [DEX_AREA_SEVAULT_CANYON] = { MARKER_SMALL_V, 108, 83 }, + [DEX_AREA_TANOBY_RUINS] = { MARKER_MED_H, 96, 90 }, + [DEX_AREA_MT_EMBER] = { MARKER_CIRCULAR, 14, 1 }, + [DEX_AREA_BERRY_FOREST] = { MARKER_CIRCULAR, 5, 52 }, + [DEX_AREA_ICEFALL_CAVE] = { MARKER_CIRCULAR, 13, 80 }, + [DEX_AREA_LOST_CAVE] = { MARKER_CIRCULAR, 54, 74 }, + [DEX_AREA_ALTERING_CAVE] = { MARKER_CIRCULAR, 69, 73 }, + [DEX_AREA_PATTERN_BUSH] = { MARKER_CIRCULAR, 76, 77 }, + [DEX_AREA_DOTTED_HOLE] = { MARKER_CIRCULAR, 73, 95 }, + [DEX_AREA_TANOBY_CHAMBER] = { MARKER_MED_H, 96, 90 }, }; static void Task_ShowAreaMarkers(u8 taskId) { struct PAM_TaskData * data = (void *)gTasks[taskId].data; - gSprites[data->spr_id].invisible = FALSE; + gSprites[data->spriteId].invisible = FALSE; } -u8 Ctor_PokedexAreaMarkers(u16 species, u16 tilesTag, u8 palIdx, u8 y) +u8 CreatePokedexAreaMarkers(u16 species, u16 tilesTag, u8 palIdx, u8 y) { struct SpriteTemplate spriteTemplate; struct CompressedSpriteSheet spriteSheet; @@ -165,34 +196,42 @@ u8 Ctor_PokedexAreaMarkers(u16 species, u16 tilesTag, u8 palIdx, u8 y) struct PAM_TaskData * data; struct Subsprite * subsprites; + // Load gfx spriteSheet.data = sMarkerTiles; spriteSheet.size = 0x4A0; spriteSheet.tag = tilesTag; LoadCompressedSpriteSheet(&spriteSheet); LoadPalette(sMarkerPal, 0x100 + 16 * palIdx, 0x20); + + // Get marker subsprites taskId = CreateTask(Task_ShowAreaMarkers, 0); data = (void *)gTasks[taskId].data; - data->unk_0C = 0; + data->unused = 0; data->tilesTag = tilesTag; - data->unk_10 = 0xFFFF; + data->paletteTag = TAG_NONE; subsprites = Alloc(120 * sizeof(struct Subsprite)); data->buffer = subsprites; data->subsprites.subsprites = subsprites; - data->subsprites.subspriteCount = BuildPokedexAreaSubspriteBuffer(species, subsprites); + data->subsprites.subspriteCount = GetSpeciesPokedexAreaMarkers(species, subsprites); + SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON); SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG0 | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_BD); SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(12, 8)); SetGpuReg(REG_OFFSET_BLDY, 0); - SetGpuReg(REG_OFFSET_WININ, 0x1F1F); - SetGpuReg(REG_OFFSET_WINOUT, 0x2F3D); + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG0 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_CLR); + + // Set marker subsprites on full sprite spriteTemplate = gDummySpriteTemplate; spriteTemplate.tileTag = tilesTag; - data->spr_id = CreateSprite(&spriteTemplate, 104, y + 32, 0); - SetSubspriteTables(&gSprites[data->spr_id], &data->subsprites); - gSprites[data->spr_id].oam.objMode = ST_OAM_OBJ_WINDOW; - gSprites[data->spr_id].oam.paletteNum = palIdx; - gSprites[data->spr_id].subspriteTableNum = 0; - gSprites[data->spr_id].invisible = TRUE; + data->spriteId = CreateSprite(&spriteTemplate, 104, y + 32, 0); + SetSubspriteTables(&gSprites[data->spriteId], &data->subsprites); + gSprites[data->spriteId].oam.objMode = ST_OAM_OBJ_WINDOW; + gSprites[data->spriteId].oam.paletteNum = palIdx; + gSprites[data->spriteId].subspriteTableNum = 0; + gSprites[data->spriteId].invisible = TRUE; + + // Show markers HideBg(1); SetBgAttribute(1, BG_ATTR_CHARBASEINDEX, 0); FillBgTilemapBufferRect_Palette0(1, 0x00F, 0, 0, 30, 20); @@ -201,17 +240,17 @@ u8 Ctor_PokedexAreaMarkers(u16 species, u16 tilesTag, u8 palIdx, u8 y) return taskId; } -void Dtor_PokedexAreaMarkers(u8 taskId) +void DestroyPokedexAreaMarkers(u8 taskId) { struct PAM_TaskData * data = (void *)gTasks[taskId].data; FreeSpriteTilesByTag(data->tilesTag); - DestroySprite(&gSprites[data->spr_id]); + DestroySprite(&gSprites[data->spriteId]); Free(data->buffer); SetGpuReg(REG_OFFSET_BLDCNT, 0); SetGpuReg(REG_OFFSET_BLDALPHA, 0); SetGpuReg(REG_OFFSET_BLDY, 0); - SetGpuReg(REG_OFFSET_WININ, 0x1F1F); - SetGpuReg(REG_OFFSET_WINOUT, 0x1F1F); + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ); ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON); HideBg(1); SetBgAttribute(1, BG_ATTR_CHARBASEINDEX, 2); @@ -221,14 +260,14 @@ void Dtor_PokedexAreaMarkers(u8 taskId) DestroyTask(taskId); } -void SetAreaSubsprite(s32 i, s32 whichArea, struct Subsprite * subsprites) +void GetAreaMarkerSubsprite(s32 i, s32 dexArea, struct Subsprite * subsprites) { - subsprites[i] = *sSubsprites[sSubspriteLookupTable[whichArea][0]]; - subsprites[i].x = sSubspriteLookupTable[whichArea][1]; - subsprites[i].y = sSubspriteLookupTable[whichArea][2]; + subsprites[i] = *sSubsprites[sAreaMarkers[dexArea][0]]; + subsprites[i].x = sAreaMarkers[dexArea][1]; + subsprites[i].y = sAreaMarkers[dexArea][2]; } -u8 PokedexAreaMarkers_Any(u8 taskId) +u8 GetNumPokedexAreaMarkers(u8 taskId) { struct PAM_TaskData * data = (void *)gTasks[taskId].data; return data->subsprites.subspriteCount; diff --git a/src/pokedex_screen.c b/src/pokedex_screen.c index 5da6f5b3d..691b3447f 100644 --- a/src/pokedex_screen.c +++ b/src/pokedex_screen.c @@ -21,6 +21,8 @@ #include "pokedex_area_markers.h" #include "field_specials.h" +#define TAG_AREA_MARKERS 2001 + enum TextMode { TEXT_LEFT, TEXT_CENTER, @@ -31,7 +33,8 @@ struct PokedexScreenData { u8 taskId; u8 state; - u8 data[4]; + u8 data[2]; + u8 areaMarkersTaskId; u32 unlockedCategories; u32 modeSelectInput; u16 modeSelectItemsAbove; @@ -3123,9 +3126,10 @@ u8 DexScreen_DrawMonAreaPage(void) } // Create the area markers - sPokedexScreenData->data[2] = Ctor_PokedexAreaMarkers(species, 2001, 3, kantoMapVoff * 8); - if (!(PokedexAreaMarkers_Any(sPokedexScreenData->data[2]))) + 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_0, gText_AreaUnknown, 0); @@ -3149,7 +3153,7 @@ u8 DexScreen_DestroyAreaScreenResources(void) { int i; - Dtor_PokedexAreaMarkers(sPokedexScreenData->data[2]); + DestroyPokedexAreaMarkers(sPokedexScreenData->areaMarkersTaskId); for (i = 0; i < 13; i++) DexScreen_RemoveWindow(&sPokedexScreenData->windowIds[i]); diff --git a/src/wild_encounter.c b/src/wild_encounter.c index 288a6b235..a49b48910 100644 --- a/src/wild_encounter.c +++ b/src/wild_encounter.c @@ -186,7 +186,7 @@ static u16 GetCurrentMapWildMonHeaderId(void) gSaveBlock1Ptr->location.mapNum == MAP_NUM(SIX_ISLAND_ALTERING_CAVE)) { u16 alteringCaveId = VarGet(VAR_ALTERING_CAVE_WILD_SET); - if (alteringCaveId > 8) + if (alteringCaveId >= NUM_ALTERING_CAVE_TABLES) alteringCaveId = 0; i += alteringCaveId; diff --git a/src/wild_pokemon_area.c b/src/wild_pokemon_area.c index c93ae36b6..1fc25e12c 100644 --- a/src/wild_pokemon_area.c +++ b/src/wild_pokemon_area.c @@ -4,16 +4,11 @@ #include "wild_encounter.h" #include "roamer.h" #include "overworld.h" +#include "pokedex.h" #include "pokedex_area_markers.h" #include "constants/region_map_sections.h" #include "constants/maps.h" -struct SeviiDexArea -{ - const u16 (*lut)[2]; - s32 count; -}; - struct RoamerPair { u16 roamer; @@ -21,137 +16,141 @@ struct RoamerPair }; static s32 GetRoamerIndex(u16 species); -static s32 CountRoamerNests(u16 species, struct Subsprite * subsprites); -static bool32 PokemonInAnyEncounterTableInMap(const struct WildPokemonHeader * data, s32 species); -static bool32 PokemonInEncounterTable(const struct WildPokemonInfo * pokemon, s32 species, s32 count); +static s32 GetRoamerPokedexAreaMarkers(u16 species, struct Subsprite * subsprites); +static bool32 IsSpeciesOnMap(const struct WildPokemonHeader * data, s32 species); +static bool32 IsSpeciesInEncounterTable(const struct WildPokemonInfo * pokemon, s32 species, s32 count); static u16 GetMapSecIdFromWildMonHeader(const struct WildPokemonHeader * header); -static bool32 TryGetMapSecPokedexAreaEntry(u16 mapSecId, const u16 (*lut)[2], s32 count, s32 * lutIdx_p, u16 * tableIdx_p); +static bool32 FindDexAreaByMapSec(u16 mapSecId, const u16 (*lut)[2], s32 count, s32 * lutIdx_p, u16 * tableIdx_p); static const u16 sDexAreas_Kanto[][2] = { - { MAPSEC_PALLET_TOWN, 1 }, - { MAPSEC_VIRIDIAN_CITY, 2 }, - { MAPSEC_PEWTER_CITY, 3 }, - { MAPSEC_CERULEAN_CITY, 4 }, - { MAPSEC_LAVENDER_TOWN, 5 }, - { MAPSEC_VERMILION_CITY, 6 }, - { MAPSEC_CELADON_CITY, 7 }, - { MAPSEC_FUCHSIA_CITY, 8 }, - { MAPSEC_CINNABAR_ISLAND, 9 }, - { MAPSEC_INDIGO_PLATEAU, 10 }, - { MAPSEC_SAFFRON_CITY, 11 }, - { MAPSEC_ROUTE_4_POKECENTER, 15 }, - { MAPSEC_ROUTE_10_POKECENTER, 21 }, - { MAPSEC_ROUTE_1, 12 }, - { MAPSEC_ROUTE_2, 13 }, - { MAPSEC_ROUTE_3, 14 }, - { MAPSEC_ROUTE_4, 15 }, - { MAPSEC_ROUTE_5, 16 }, - { MAPSEC_ROUTE_6, 17 }, - { MAPSEC_ROUTE_7, 18 }, - { MAPSEC_ROUTE_8, 19 }, - { MAPSEC_ROUTE_9, 20 }, - { MAPSEC_ROUTE_10, 21 }, - { MAPSEC_ROUTE_11, 22 }, - { MAPSEC_ROUTE_12, 23 }, - { MAPSEC_ROUTE_13, 24 }, - { MAPSEC_ROUTE_14, 25 }, - { MAPSEC_ROUTE_15, 26 }, - { MAPSEC_ROUTE_16, 27 }, - { MAPSEC_ROUTE_17, 28 }, - { MAPSEC_ROUTE_18, 29 }, - { MAPSEC_ROUTE_19, 30 }, - { MAPSEC_ROUTE_20, 31 }, - { MAPSEC_ROUTE_21, 32 }, - { MAPSEC_ROUTE_22, 33 }, - { MAPSEC_ROUTE_23, 34 }, - { MAPSEC_ROUTE_24, 35 }, - { MAPSEC_ROUTE_25, 36 }, - { MAPSEC_VIRIDIAN_FOREST, 37 }, - { MAPSEC_MT_MOON, 39 }, - { MAPSEC_S_S_ANNE, 6 }, - { MAPSEC_UNDERGROUND_PATH, 11 }, - { MAPSEC_UNDERGROUND_PATH_2, 11 }, - { MAPSEC_DIGLETTS_CAVE, 38 }, - { MAPSEC_KANTO_VICTORY_ROAD, 47 }, - { MAPSEC_ROCKET_HIDEOUT, 7 }, - { MAPSEC_SILPH_CO, 11 }, - { MAPSEC_POKEMON_MANSION, 46 }, - { MAPSEC_KANTO_SAFARI_ZONE, 44 }, - { MAPSEC_POKEMON_LEAGUE, 47 }, - { MAPSEC_ROCK_TUNNEL, 41 }, - { MAPSEC_SEAFOAM_ISLANDS, 45 }, - { MAPSEC_POKEMON_TOWER, 43 }, - { MAPSEC_CERULEAN_CAVE, 40 }, - { MAPSEC_POWER_PLANT, 42 } + { MAPSEC_PALLET_TOWN, DEX_AREA_PALLET_TOWN }, + { MAPSEC_VIRIDIAN_CITY, DEX_AREA_VIRIDIAN_CITY }, + { MAPSEC_PEWTER_CITY, DEX_AREA_PEWTER_CITY }, + { MAPSEC_CERULEAN_CITY, DEX_AREA_CERULEAN_CITY }, + { MAPSEC_LAVENDER_TOWN, DEX_AREA_LAVENDER_TOWN }, + { MAPSEC_VERMILION_CITY, DEX_AREA_VERMILION_CITY }, + { MAPSEC_CELADON_CITY, DEX_AREA_CELADON_CITY }, + { MAPSEC_FUCHSIA_CITY, DEX_AREA_FUCHSIA_CITY }, + { MAPSEC_CINNABAR_ISLAND, DEX_AREA_CINNABAR_ISLAND }, + { MAPSEC_INDIGO_PLATEAU, DEX_AREA_INDIGO_PLATEAU }, + { MAPSEC_SAFFRON_CITY, DEX_AREA_SAFFRON_CITY }, + { MAPSEC_ROUTE_4_POKECENTER, DEX_AREA_ROUTE_4 }, + { MAPSEC_ROUTE_10_POKECENTER, DEX_AREA_ROUTE_10 }, + { MAPSEC_ROUTE_1, DEX_AREA_ROUTE_1 }, + { MAPSEC_ROUTE_2, DEX_AREA_ROUTE_2 }, + { MAPSEC_ROUTE_3, DEX_AREA_ROUTE_3 }, + { MAPSEC_ROUTE_4, DEX_AREA_ROUTE_4 }, + { MAPSEC_ROUTE_5, DEX_AREA_ROUTE_5 }, + { MAPSEC_ROUTE_6, DEX_AREA_ROUTE_6 }, + { MAPSEC_ROUTE_7, DEX_AREA_ROUTE_7 }, + { MAPSEC_ROUTE_8, DEX_AREA_ROUTE_8 }, + { MAPSEC_ROUTE_9, DEX_AREA_ROUTE_9 }, + { MAPSEC_ROUTE_10, DEX_AREA_ROUTE_10 }, + { MAPSEC_ROUTE_11, DEX_AREA_ROUTE_11 }, + { MAPSEC_ROUTE_12, DEX_AREA_ROUTE_12 }, + { MAPSEC_ROUTE_13, DEX_AREA_ROUTE_13 }, + { MAPSEC_ROUTE_14, DEX_AREA_ROUTE_14 }, + { MAPSEC_ROUTE_15, DEX_AREA_ROUTE_15 }, + { MAPSEC_ROUTE_16, DEX_AREA_ROUTE_16 }, + { MAPSEC_ROUTE_17, DEX_AREA_ROUTE_17 }, + { MAPSEC_ROUTE_18, DEX_AREA_ROUTE_18 }, + { MAPSEC_ROUTE_19, DEX_AREA_ROUTE_19 }, + { MAPSEC_ROUTE_20, DEX_AREA_ROUTE_20 }, + { MAPSEC_ROUTE_21, DEX_AREA_ROUTE_21 }, + { MAPSEC_ROUTE_22, DEX_AREA_ROUTE_22 }, + { MAPSEC_ROUTE_23, DEX_AREA_ROUTE_23 }, + { MAPSEC_ROUTE_24, DEX_AREA_ROUTE_24 }, + { MAPSEC_ROUTE_25, DEX_AREA_ROUTE_25 }, + { MAPSEC_VIRIDIAN_FOREST, DEX_AREA_VIRIDIAN_FOREST }, + { MAPSEC_MT_MOON, DEX_AREA_MT_MOON }, + { MAPSEC_S_S_ANNE, DEX_AREA_VERMILION_CITY }, + { MAPSEC_UNDERGROUND_PATH, DEX_AREA_SAFFRON_CITY }, + { MAPSEC_UNDERGROUND_PATH_2, DEX_AREA_SAFFRON_CITY }, + { MAPSEC_DIGLETTS_CAVE, DEX_AREA_DIGLETTS_CAVE }, + { MAPSEC_KANTO_VICTORY_ROAD, DEX_AREA_VICTORY_ROAD }, + { MAPSEC_ROCKET_HIDEOUT, DEX_AREA_CELADON_CITY }, + { MAPSEC_SILPH_CO, DEX_AREA_SAFFRON_CITY }, + { MAPSEC_POKEMON_MANSION, DEX_AREA_POKEMON_MANSION }, + { MAPSEC_KANTO_SAFARI_ZONE, DEX_AREA_SAFARI_ZONE }, + { MAPSEC_POKEMON_LEAGUE, DEX_AREA_VICTORY_ROAD }, + { MAPSEC_ROCK_TUNNEL, DEX_AREA_ROCK_TUNNEL }, + { MAPSEC_SEAFOAM_ISLANDS, DEX_AREA_SEAFOAM_ISLANDS }, + { MAPSEC_POKEMON_TOWER, DEX_AREA_POKEMON_TOWER }, + { MAPSEC_CERULEAN_CAVE, DEX_AREA_CERULEAN_CAVE }, + { MAPSEC_POWER_PLANT, DEX_AREA_POWER_PLANT } }; static const u16 sDexAreas_Sevii1[][2] = { - { MAPSEC_KINDLE_ROAD, 55 }, - { MAPSEC_TREASURE_BEACH, 56 }, - { MAPSEC_ONE_ISLAND, 48 }, - { MAPSEC_MT_EMBER, 72 } + { MAPSEC_KINDLE_ROAD, DEX_AREA_KINDLE_ROAD }, + { MAPSEC_TREASURE_BEACH, DEX_AREA_TREASURE_BEACH }, + { MAPSEC_ONE_ISLAND, DEX_AREA_ONE_ISLAND }, + { MAPSEC_MT_EMBER, DEX_AREA_MT_EMBER } }; static const u16 sDexAreas_Sevii2[][2] = { - { MAPSEC_CAPE_BRINK, 57 }, - { MAPSEC_TWO_ISLAND, 49 } + { MAPSEC_CAPE_BRINK, DEX_AREA_CAPE_BRINK }, + { MAPSEC_TWO_ISLAND, DEX_AREA_TWO_ISLAND } }; static const u16 sDexAreas_Sevii3[][2] = { - { MAPSEC_BOND_BRIDGE, 58 }, - { MAPSEC_THREE_ISLE_PORT, 59 }, - { MAPSEC_THREE_ISLAND, 50 }, - { MAPSEC_BERRY_FOREST, 73 }, - { MAPSEC_THREE_ISLE_PATH, 59 } + { MAPSEC_BOND_BRIDGE, DEX_AREA_BOND_BRIDGE }, + { MAPSEC_THREE_ISLE_PORT, DEX_AREA_THREE_ISLE_PATH }, + { MAPSEC_THREE_ISLAND, DEX_AREA_THREE_ISLAND }, + { MAPSEC_BERRY_FOREST, DEX_AREA_BERRY_FOREST }, + { MAPSEC_THREE_ISLE_PATH, DEX_AREA_THREE_ISLE_PATH } }; static const u16 sDexAreas_Sevii4[][2] = { - { MAPSEC_FOUR_ISLAND, 51 }, - { MAPSEC_ICEFALL_CAVE, 74 } + { MAPSEC_FOUR_ISLAND, DEX_AREA_FOUR_ISLAND }, + { MAPSEC_ICEFALL_CAVE, DEX_AREA_ICEFALL_CAVE } }; static const u16 sDexAreas_Sevii5[][2] = { - { MAPSEC_RESORT_GORGEOUS, 60 }, - { MAPSEC_WATER_LABYRINTH, 61 }, - { MAPSEC_FIVE_ISLE_MEADOW, 62 }, - { MAPSEC_MEMORIAL_PILLAR, 63 }, - { MAPSEC_FIVE_ISLAND, 52 }, - { MAPSEC_ROCKET_WAREHOUSE, 62 }, - { MAPSEC_LOST_CAVE, 75 } + { MAPSEC_RESORT_GORGEOUS, DEX_AREA_RESORT_GORGEOUS }, + { MAPSEC_WATER_LABYRINTH, DEX_AREA_WATER_LABYRINTH }, + { MAPSEC_FIVE_ISLE_MEADOW, DEX_AREA_FIVE_ISLE_MEADOW }, + { MAPSEC_MEMORIAL_PILLAR, DEX_AREA_MEMORIAL_PILLAR }, + { MAPSEC_FIVE_ISLAND, DEX_AREA_FIVE_ISLAND }, + { MAPSEC_ROCKET_WAREHOUSE, DEX_AREA_FIVE_ISLE_MEADOW }, + { MAPSEC_LOST_CAVE, DEX_AREA_LOST_CAVE } }; static const u16 sDexAreas_Sevii6[][2] = { - { MAPSEC_OUTCAST_ISLAND, 64 }, - { MAPSEC_GREEN_PATH, 65 }, - { MAPSEC_WATER_PATH, 66 }, - { MAPSEC_RUIN_VALLEY, 67 }, - { MAPSEC_DOTTED_HOLE, 78 }, - { MAPSEC_PATTERN_BUSH, 77 }, - { MAPSEC_ALTERING_CAVE, 76 } + { MAPSEC_OUTCAST_ISLAND, DEX_AREA_OUTCAST_ISLAND }, + { MAPSEC_GREEN_PATH, DEX_AREA_GREEN_PATH }, + { MAPSEC_WATER_PATH, DEX_AREA_WATER_PATH }, + { MAPSEC_RUIN_VALLEY, DEX_AREA_RUIN_VALLEY }, + { MAPSEC_DOTTED_HOLE, DEX_AREA_DOTTED_HOLE }, + { MAPSEC_PATTERN_BUSH, DEX_AREA_PATTERN_BUSH }, + { MAPSEC_ALTERING_CAVE, DEX_AREA_ALTERING_CAVE } }; static const u16 sDexAreas_Sevii7[][2] = { - { MAPSEC_TRAINER_TOWER, 68 }, - { MAPSEC_CANYON_ENTRANCE, 69 }, - { MAPSEC_SEVAULT_CANYON, 70 }, - { MAPSEC_TANOBY_RUINS, 71 }, - { MAPSEC_MONEAN_CHAMBER, 79 }, - { MAPSEC_LIPTOO_CHAMBER, 79 }, - { MAPSEC_WEEPTH_CHAMBER, 79 }, - { MAPSEC_DILFORD_CHAMBER, 79 }, - { MAPSEC_SCUFIB_CHAMBER, 79 }, - { MAPSEC_RIXY_CHAMBER, 79 }, - { MAPSEC_VIAPOIS_CHAMBER, 79 } + { MAPSEC_TRAINER_TOWER, DEX_AREA_TRAINER_TOWER }, + { MAPSEC_CANYON_ENTRANCE, DEX_AREA_CANYON_ENTRANCE }, + { MAPSEC_SEVAULT_CANYON, DEX_AREA_SEVAULT_CANYON }, + { MAPSEC_TANOBY_RUINS, DEX_AREA_TANOBY_RUINS }, + { MAPSEC_MONEAN_CHAMBER, DEX_AREA_TANOBY_CHAMBER }, + { MAPSEC_LIPTOO_CHAMBER, DEX_AREA_TANOBY_CHAMBER }, + { MAPSEC_WEEPTH_CHAMBER, DEX_AREA_TANOBY_CHAMBER }, + { MAPSEC_DILFORD_CHAMBER, DEX_AREA_TANOBY_CHAMBER }, + { MAPSEC_SCUFIB_CHAMBER, DEX_AREA_TANOBY_CHAMBER }, + { MAPSEC_RIXY_CHAMBER, DEX_AREA_TANOBY_CHAMBER }, + { MAPSEC_VIAPOIS_CHAMBER, DEX_AREA_TANOBY_CHAMBER } }; -static const struct SeviiDexArea sSeviiDexAreas[] = { - { sDexAreas_Sevii1, 4 }, - { sDexAreas_Sevii2, 2 }, - { sDexAreas_Sevii3, 5 }, - { sDexAreas_Sevii4, 2 }, - { sDexAreas_Sevii5, 7 }, - { sDexAreas_Sevii6, 7 }, - { sDexAreas_Sevii7, 11 } +static const struct +{ + const u16 (*table)[2]; + s32 count; +} sSeviiDexAreas[] = { + { sDexAreas_Sevii1, ARRAY_COUNT(sDexAreas_Sevii1) }, + { sDexAreas_Sevii2, ARRAY_COUNT(sDexAreas_Sevii2) }, + { sDexAreas_Sevii3, ARRAY_COUNT(sDexAreas_Sevii3) }, + { sDexAreas_Sevii4, ARRAY_COUNT(sDexAreas_Sevii4) }, + { sDexAreas_Sevii5, ARRAY_COUNT(sDexAreas_Sevii5) }, + { sDexAreas_Sevii6, ARRAY_COUNT(sDexAreas_Sevii6) }, + { sDexAreas_Sevii7, ARRAY_COUNT(sDexAreas_Sevii7) } }; static const struct RoamerPair sRoamerPairs[] = { @@ -160,27 +159,27 @@ static const struct RoamerPair sRoamerPairs[] = { { SPECIES_RAIKOU, SPECIES_SQUIRTLE } }; -s32 BuildPokedexAreaSubspriteBuffer(u16 species, struct Subsprite * subsprites) +// Scans for the given species and populates 'subsprites' with the area markers. +// Returns the number of areas where the species was found. +s32 GetSpeciesPokedexAreaMarkers(u16 species, struct Subsprite * subsprites) { s32 areaCount; s32 j; s32 mapSecId; - u16 dexAreaSubspriteIdx; - s32 dexAreaEntryLUTidx; + u16 dexArea; + s32 tableIndex; s32 seviiAreas; s32 alteringCaveCount; s32 alteringCaveNum; s32 i; - if (GetRoamerIndex(species) >= SPECIES_NONE) - { - return CountRoamerNests(species, subsprites); - } + if (GetRoamerIndex(species) >= 0) + return GetRoamerPokedexAreaMarkers(species, subsprites); seviiAreas = GetUnlockedSeviiAreas(); alteringCaveCount = 0; alteringCaveNum = VarGet(VAR_ALTERING_CAVE_WILD_SET); - if (alteringCaveNum > 8) + if (alteringCaveNum >= NUM_ALTERING_CAVE_TABLES) alteringCaveNum = 0; for (i = 0, areaCount = 0; gWildMonHeaders[i].mapGroup != MAP_GROUP(UNDEFINED); i++) { @@ -191,27 +190,27 @@ s32 BuildPokedexAreaSubspriteBuffer(u16 species, struct Subsprite * subsprites) if (alteringCaveNum != alteringCaveCount - 1) continue; } - if (PokemonInAnyEncounterTableInMap(&gWildMonHeaders[i], species)) + if (IsSpeciesOnMap(&gWildMonHeaders[i], species)) { - dexAreaEntryLUTidx = 0; - while (TryGetMapSecPokedexAreaEntry(mapSecId, sDexAreas_Kanto, 55, &dexAreaEntryLUTidx, &dexAreaSubspriteIdx)) + // Search for all dex areas associated with this MAPSEC. + // In the vanilla game each MAPSEC only has at most one DEX_AREA. + tableIndex = 0; + while (FindDexAreaByMapSec(mapSecId, sDexAreas_Kanto, ARRAY_COUNT(sDexAreas_Kanto), &tableIndex, &dexArea)) { - if (dexAreaSubspriteIdx != 0) - { - SetAreaSubsprite(areaCount++, dexAreaSubspriteIdx, subsprites); - } + if (dexArea != DEX_AREA_NONE) + GetAreaMarkerSubsprite(areaCount++, dexArea, subsprites); } - for (j = 0; j < NELEMS(sSeviiDexAreas); j++) + + for (j = 0; j < ARRAY_COUNT(sSeviiDexAreas); j++) { if ((seviiAreas >> j) & 1) { - dexAreaEntryLUTidx = 0; - while (TryGetMapSecPokedexAreaEntry(mapSecId, sSeviiDexAreas[j].lut, sSeviiDexAreas[j].count, &dexAreaEntryLUTidx, &dexAreaSubspriteIdx)) + // Search for all dex areas associated with this MAPSEC in this unlocked Sevii Island + tableIndex = 0; + while (FindDexAreaByMapSec(mapSecId, sSeviiDexAreas[j].table, sSeviiDexAreas[j].count, &tableIndex, &dexArea)) { - if (dexAreaSubspriteIdx != 0) - { - SetAreaSubsprite(areaCount++, dexAreaSubspriteIdx, subsprites); - } + if (dexArea != DEX_AREA_NONE) + GetAreaMarkerSubsprite(areaCount++, dexArea, subsprites); } } } @@ -224,7 +223,7 @@ s32 BuildPokedexAreaSubspriteBuffer(u16 species, struct Subsprite * subsprites) static s32 GetRoamerIndex(u16 species) { s32 i; - for (i = 0; i < NELEMS(sRoamerPairs); i++) + for (i = 0; i < ARRAY_COUNT(sRoamerPairs); i++) { if (sRoamerPairs[i].roamer == species) return i; @@ -233,46 +232,54 @@ static s32 GetRoamerIndex(u16 species) return -1; } -static s32 CountRoamerNests(u16 species, struct Subsprite * subsprites) +static s32 GetRoamerPokedexAreaMarkers(u16 species, struct Subsprite * subsprites) { - u16 roamerLocation; + u16 mapSecId; s32 roamerIdx; - u16 dexAreaSubspriteIdx; - s32 dexAreaEntryLUTidx; + u16 dexArea; + s32 tableIndex; + // Make sure that this is a roamer species, and that it corresponds to the player's starter. roamerIdx = GetRoamerIndex(species); if (roamerIdx < 0) return 0; if (sRoamerPairs[roamerIdx].starter != GetStarterSpecies()) return 0; - roamerLocation = GetRoamerLocationMapSectionId(); - dexAreaEntryLUTidx = 0; - if (TryGetMapSecPokedexAreaEntry(roamerLocation, sDexAreas_Kanto, 55, &dexAreaEntryLUTidx, &dexAreaSubspriteIdx)) + + mapSecId = GetRoamerLocationMapSectionId(); + tableIndex = 0; + if (FindDexAreaByMapSec(mapSecId, sDexAreas_Kanto, ARRAY_COUNT(sDexAreas_Kanto), &tableIndex, &dexArea)) { - if (dexAreaSubspriteIdx != 0) + if (dexArea != DEX_AREA_NONE) { - SetAreaSubsprite(0, dexAreaSubspriteIdx, subsprites); + GetAreaMarkerSubsprite(0, dexArea, subsprites); return 1; } } return 0; } -static bool32 PokemonInAnyEncounterTableInMap(const struct WildPokemonHeader * data, s32 species) +static bool32 IsSpeciesOnMap(const struct WildPokemonHeader * data, s32 species) { - if (PokemonInEncounterTable(data->landMonsInfo, species, 12)) + if (IsSpeciesInEncounterTable(data->landMonsInfo, species, LAND_WILD_COUNT)) return TRUE; - if (PokemonInEncounterTable(data->waterMonsInfo, species, 5)) + if (IsSpeciesInEncounterTable(data->waterMonsInfo, species, WATER_WILD_COUNT)) return TRUE; - if (PokemonInEncounterTable(data->fishingMonsInfo, species, 12)) // 10 +// When searching the fishing encounters, this incorrectly uses the size of the land encounters. +// As a result it's reading out of bounds of the fishing encounters tables. +#ifdef BUGFIX + if (IsSpeciesInEncounterTable(data->fishingMonsInfo, species, FISH_WILD_COUNT)) +#else + if (IsSpeciesInEncounterTable(data->fishingMonsInfo, species, LAND_WILD_COUNT)) +#endif return TRUE; - if (PokemonInEncounterTable(data->rockSmashMonsInfo, species, 5)) + if (IsSpeciesInEncounterTable(data->rockSmashMonsInfo, species, ROCK_WILD_COUNT)) return TRUE; return FALSE; } -static bool32 PokemonInEncounterTable(const struct WildPokemonInfo * info, s32 species, s32 count) +static bool32 IsSpeciesInEncounterTable(const struct WildPokemonInfo * info, s32 species, s32 count) { s32 i; if (info != NULL) @@ -291,15 +298,18 @@ static u16 GetMapSecIdFromWildMonHeader(const struct WildPokemonHeader * header) return Overworld_GetMapHeaderByGroupAndId(header->mapGroup, header->mapNum)->regionMapSectionId; } -static bool32 TryGetMapSecPokedexAreaEntry(u16 mapSecId, const u16 (*lut)[2], s32 count, s32 * lutIdx_p, u16 * tableIdx_p) +// Search a MAPSEC -> DEX_AREA table for the given mapsec. +// Assigns the DEX_AREA (if found) to 'dexArea', and the first unread table index to 'index'. +// Returns TRUE if DEX_AREA was found, FALSE otherwise. +static bool32 FindDexAreaByMapSec(u16 mapSecId, const u16 (*table)[2], s32 count, s32 * index, u16 * dexArea) { s32 i; - for (i = *lutIdx_p; i < count; i++) + for (i = *index; i < count; i++) { - if (lut[i][0] == mapSecId) + if (table[i][0] == mapSecId) { - *tableIdx_p = lut[i][1]; - *lutIdx_p = i + 1; + *dexArea = table[i][1]; + *index = i + 1; return TRUE; } }