Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions include/gametypes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#ifndef GUARD_GAMETYPES_H
#define GUARD_GAMETYPES_H

#include "gba/types.h"

//
// This header includes typedefs for fields that commonly appear throughout
// the codebase, and which ROM hacks might benefit from being able to widen.
//
// These typedefs include the underlying type in their name for two reasons:
//
// - Game Freak wasn't fully consistent about field widths throughout
// their codebase. For example, when Region Map Sections are persistently
// stored in savedata, they're stored as 8-bit values; but much of the
// codebase handles them as 16-bit values.
//
// - Although Pokemon Emerald doesn't come close to maxing out RAM, it *does*
// use nearly all of its EEPROM. That is: the vanilla game uses 96% of the
// flash memory available for storing players' save files, leaving 2172
// bytes to spare within each of the game's two save files (primary and
// backup). These spare bytes are not contiguous: SaveBlock1 can only grow
// by 84 bytes, and SaveBlock2 can only grow by 120 bytes, with the rest
// of the free space located after the player's PC-boxed Pokemon.
//
// With so little flash memory to spare, keeping track of how much space
// you're using is vital -- and so is arranging struct members to minimize
// compiler-inserted padding. It's easier to deal with this when you can
// see these types' widths at a glance.
//
// Accordingly, this file generally doesn't contain just single types, but
// rather families of types. For example, Region Map Sections are saved as
// u8s within the player's save file, but are sometimes handled as u16s or
// even s16s and ints; and so there are multiple typedefs for Map Sections
// corresponding to each of these underlying types, and each typedef has a
// name which indicates the underlying type.
//
// For a given family of typedefs, the smallest one should be considered
// the "real" or "canonical" type. Continuing with Map Sections as our
// example, the smallest type is an 8-bit integer, and so any values that
// can't fit in an 8-bit integer will be truncated and lost at some point
// within the codebase. Therefore mapsec_u8_t is the "canonical" type for
// Map Sections, and the larger typedefs just exist to describe situations
// where the game handles Map Sections inconsistently with that "canon."
//

// Map Sections are named areas that can appear in the region map. Each
// individual map can be assigned to a Map Section as appropriate. The
// possible values are in constants/region_map_sections.h.
//
// If you choose to widen Map Sections, be aware that Met Locations (below)
// are based on Map Sections and will also be widened.
typedef u8 mapsec_u8_t;
typedef u16 mapsec_u16_t;
typedef s16 mapsec_s16_t;
typedef int mapsec_int_t;

// Met Locations for caught Pokemon use the same values as Map Sections,
// except that 0xFD, 0xFE, and 0xFF have special meanings.
//
// Because this value appears inside every Pokemon's data, widening it will
// consume a lot more space within flash memory. The space usage will be
// greater than you expect due to how Pokemon substructs are laid out; you
// would have to rearrange the substructs' contents in order to minimize
// how much more space a wider Met Location would consume.
typedef mapsec_u8_t metloc_u8_t;

#endif //GUARD_GAMETYPES_H
4 changes: 3 additions & 1 deletion include/global.fieldmap.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef GUARD_GLOBAL_FIELDMAP_H
#define GUARD_GLOBAL_FIELDMAP_H

#include "gametypes.h"

// Masks/shifts for blocks in the map grid
// Map grid blocks consist of a 10 bit metatile id, a 2 bit collision value, and a 4 bit elevation value
// This is the data stored in each data/layouts/*/map.bin file
Expand Down Expand Up @@ -167,7 +169,7 @@ struct MapHeader
/* 0x0C */ const struct MapConnections *connections;
/* 0x10 */ u16 music;
/* 0x12 */ u16 mapLayoutId;
/* 0x14 */ u8 regionMapSectionId;
/* 0x14 */ mapsec_u8_t regionMapSectionId;
/* 0x15 */ u8 cave;
/* 0x16 */ u8 weather;
/* 0x17 */ u8 mapType;
Expand Down
15 changes: 8 additions & 7 deletions include/global.tv.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define GUARD_GLOBAL_TV_H

#include "constants/tv.h"
#include "gametypes.h"

typedef union // size = 0x24
{
Expand Down Expand Up @@ -226,7 +227,7 @@ typedef union // size = 0x24
/*0x04*/ u8 filler_04[2];
/*0x06*/ u16 itemIds[SMARTSHOPPER_NUM_ITEMS];
/*0x0C*/ u16 itemAmounts[SMARTSHOPPER_NUM_ITEMS];
/*0x12*/ u8 shopLocation;
/*0x12*/ mapsec_u8_t shopLocation;
/*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1];
/*0x1B*/ //u8 padding;
} smartshopperShow;
Expand All @@ -241,7 +242,7 @@ typedef union // size = 0x24
/*0x0E*/ u16 species2;
/*0x10*/ u8 nBallsUsed;
/*0x11*/ u8 outcome;
/*0x12*/ u8 location;
/*0x12*/ mapsec_u8_t location;
/*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1];
/*0x1B*/ //u8 padding;
} pokemonTodayFailed;
Expand All @@ -267,7 +268,7 @@ typedef union // size = 0x24
/*0x04*/ u16 caughtPoke;
/*0x06*/ u16 steps;
/*0x08*/ u16 species;
/*0x0A*/ u8 location;
/*0x0A*/ mapsec_u8_t location;
/*0x0B*/ u8 language;
/*0x0C*/ u8 filler_0C[7];
/*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1];
Expand All @@ -282,7 +283,7 @@ typedef union // size = 0x24
/*0x04*/ u8 badgeCount;
/*0x05*/ u8 nSilverSymbols;
/*0x06*/ u8 nGoldSymbols;
/*0x07*/ u8 location;
/*0x07*/ mapsec_u8_t location;
/*0x08*/ u16 battlePoints;
/*0x0A*/ u16 mapLayoutId;
/*0x0C*/ u8 language;
Expand All @@ -309,7 +310,7 @@ typedef union // size = 0x24
/*0x00*/ u8 kind;
/*0x01*/ bool8 active;
/*0x02*/ u16 item;
/*0x04*/ u8 location;
/*0x04*/ mapsec_u8_t location;
/*0x05*/ u8 language;
/*0x06*/ u16 mapLayoutId;
/*0x08*/ u8 filler_08[11];
Expand All @@ -336,7 +337,7 @@ typedef union // size = 0x24
/*0x00*/ u8 kind;
/*0x01*/ bool8 active;
/*0x02*/ u16 lastOpponentSpecies;
/*0x04*/ u8 location;
/*0x04*/ mapsec_u8_t location;
/*0x05*/ u8 outcome;
/*0x06*/ u16 caughtMonBall;
/*0x08*/ u16 balls;
Expand Down Expand Up @@ -505,7 +506,7 @@ struct GabbyAndTyData
/*2BA6*/ u16 mon2;
/*2BA8*/ u16 lastMove;
/*2BAA*/ u16 quote[1];
/*2BAC*/ u8 mapnum;
/*2BAC*/ mapsec_u8_t mapnum;
/*2BAD*/ u8 battleNum;
/*2BAE*/ u8 battleTookMoreThanOneTurn:1;
u8 playerLostAMon:1;
Expand Down
4 changes: 3 additions & 1 deletion include/landmark.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef GUARD_LANDMARK_H
#define GUARD_LANDMARK_H

const u8 *GetLandmarkName(u8 mapSection, u8 id, u8 count);
#include "gametypes.h"

const u8 *GetLandmarkName(mapsec_u8_t mapSection, u8 id, u8 count);

#endif // GUARD_LANDMARK_H
6 changes: 4 additions & 2 deletions include/overworld.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef GUARD_OVERWORLD_H
#define GUARD_OVERWORLD_H

#include "gametypes.h"

#define LINK_KEY_CODE_NULL 0x00
#define LINK_KEY_CODE_EMPTY 0x11
#define LINK_KEY_CODE_DPAD_DOWN 0x12
Expand Down Expand Up @@ -121,8 +123,8 @@ u8 GetLastUsedWarpMapType(void);
bool8 IsMapTypeOutdoors(u8 mapType);
bool8 Overworld_MapTypeAllowsTeleportAndFly(u8 mapType);
bool8 IsMapTypeIndoors(u8 mapType);
u8 GetSavedWarpRegionMapSectionId(void);
u8 GetCurrentRegionMapSectionId(void);
mapsec_u8_t GetSavedWarpRegionMapSectionId(void);
mapsec_u8_t GetCurrentRegionMapSectionId(void);
u8 GetCurrentMapBattleScene(void);
void CleanupOverworldWindowsAndTilemaps(void);
bool32 IsOverworldLinkActive(void);
Expand Down
3 changes: 2 additions & 1 deletion include/pokemon.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef GUARD_POKEMON_H
#define GUARD_POKEMON_H

#include "gametypes.h"
#include "sprite.h"

// Property labels for Get(Box)MonData / Set(Box)MonData
Expand Down Expand Up @@ -131,7 +132,7 @@ struct PokemonSubstruct2
struct PokemonSubstruct3
{
/* 0x00 */ u8 pokerus;
/* 0x01 */ u8 metLocation;
/* 0x01 */ metloc_u8_t metLocation;

/* 0x02 */ u16 metLevel:7;
/* 0x02 */ u16 metGame:4;
Expand Down
7 changes: 4 additions & 3 deletions include/pokenav.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define GUARD_POKENAV_H

#include "bg.h"
#include "gametypes.h"
#include "main.h"
#include "pokemon_storage_system.h"

Expand All @@ -17,7 +18,7 @@ struct PokenavMonListItem
struct PokenavMatchCallEntry
{
bool8 isSpecialTrainer;
u8 mapSec;
mapsec_u8_t mapSec;
u16 headerId;
};

Expand Down Expand Up @@ -410,7 +411,7 @@ void FreeMatchCallSubstruct1(void);
int IsMatchCallListInitFinished(void);
int GetNumberRegistered(void);
struct PokenavMatchCallEntry *GetMatchCallList(void);
u16 GetMatchCallMapSec(int index);
mapsec_u16_t GetMatchCallMapSec(int index);
bool32 ShouldDrawRematchPokeballIcon(int index);
void ClearRematchPokeballIcon(u16 windowId, u32 tileOffset);
int GetMatchCallTrainerPic(int index);
Expand All @@ -419,7 +420,7 @@ const u8 *GetMatchCallMessageText(int index, bool8 *newRematchRequest);
u16 GetMatchCallOptionCursorPos(void);
u16 GetMatchCallOptionId(int optionId);
void BufferMatchCallNameAndDesc(struct PokenavMatchCallEntry *matchCallEntry, u8 *str);
u8 GetMatchTableMapSectionId(int rematchIndex);
mapsec_u8_t GetMatchTableMapSectionId(int rematchIndex);
int GetIndexDeltaOfNextCheckPageDown(int index);
int GetIndexDeltaOfNextCheckPageUp(int index);
bool32 IsRematchEntryRegistered(int rematchIndex);
Expand Down
17 changes: 9 additions & 8 deletions include/region_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define GUARD_REGION_MAP_H

#include "bg.h"
#include "gametypes.h"

// Exported type declarations
#define MAP_NAME_LENGTH 16
Expand All @@ -22,11 +23,11 @@ enum {
MAPSECTYPE_CITY_CANFLY,
MAPSECTYPE_CITY_CANTFLY,
MAPSECTYPE_BATTLE_FRONTIER,
NUM_MAPSEC_TYPES
NUM_mapsec_u8_tYPES
};

struct RegionMap {
/*0x000*/ u16 mapSecId;
/*0x000*/ mapsec_u16_t mapSecId;
/*0x002*/ u8 mapSecType;
/*0x003*/ u8 posWithinMapSec;
/*0x004*/ u8 mapSecName[20];
Expand Down Expand Up @@ -99,14 +100,14 @@ void InitRegionMap(struct RegionMap *regionMap, bool8 zoomed);
u8 DoRegionMapInputCallback(void);
bool8 UpdateRegionMapZoom(void);
void FreeRegionMapIconResources(void);
u16 GetRegionMapSecIdAt(u16 x, u16 y);
mapsec_u16_t GetRegionMapSecIdAt(u16 x, u16 y);
void CreateRegionMapPlayerIcon(u16 tileTag, u16 paletteTag);
void CreateRegionMapCursor(u16 tileTag, u16 paletteTag);
bool32 IsEventIslandMapSecId(u8 mapSecId);
u8 *GetMapName(u8 *dest, u16 regionMapId, u16 padLength);
u8 *GetMapNameGeneric(u8 *dest, u16 mapSecId);
u8 *GetMapNameHandleAquaHideout(u8 *dest, u16 mapSecId);
u16 CorrectSpecialMapSecId(u16 mapSecId);
bool32 IsEventIslandMapSecId(mapsec_u8_t mapSecId);
u8 *GetMapName(u8 *dest, mapsec_u16_t regionMapId, u16 padLength);
u8 *GetMapNameGeneric(u8 *dest, mapsec_u16_t mapSecId);
u8 *GetMapNameHandleAquaHideout(u8 *dest, mapsec_u16_t mapSecId);
mapsec_u16_t CorrectSpecialMapSecId(mapsec_u16_t mapSecId);
void ShowRegionMapForPokedexAreaScreen(struct RegionMap *regionMap);
void PokedexAreaScreen_UpdateRegionMapVariablesAndVideoRegs(s16 x, s16 y);
void CB2_OpenFlyMap(void);
Expand Down
2 changes: 1 addition & 1 deletion src/data/region_map/region_map_layout.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
static const u8 sRegionMap_MapSectionLayout[MAP_HEIGHT][MAP_WIDTH] = {
static const mapsec_u8_t sRegionMap_MapSectionLayout[MAP_HEIGHT][MAP_WIDTH] = {
{MAPSEC_NONE, MAPSEC_ROUTE_114, MAPSEC_ROUTE_114, MAPSEC_FALLARBOR_TOWN, MAPSEC_ROUTE_113, MAPSEC_ROUTE_113, MAPSEC_ROUTE_113, MAPSEC_ROUTE_113, MAPSEC_ROUTE_111, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_119, MAPSEC_FORTREE_CITY, MAPSEC_ROUTE_120, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
{MAPSEC_NONE, MAPSEC_ROUTE_114, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_MT_CHIMNEY, MAPSEC_MT_CHIMNEY, MAPSEC_ROUTE_111, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_119, MAPSEC_NONE, MAPSEC_ROUTE_120, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
{MAPSEC_ROUTE_115, MAPSEC_ROUTE_114, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_MT_CHIMNEY, MAPSEC_MT_CHIMNEY, MAPSEC_ROUTE_111, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_ROUTE_119, MAPSEC_NONE, MAPSEC_ROUTE_120, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_SAFARI_ZONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE, MAPSEC_NONE},
Expand Down
3 changes: 2 additions & 1 deletion src/daycare.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "pokemon.h"
#include "battle.h"
#include "daycare.h"
#include "gametypes.h"
#include "string_util.h"
#include "mail.h"
#include "pokemon_storage_system.h"
Expand Down Expand Up @@ -830,7 +831,7 @@ void CreateEgg(struct Pokemon *mon, u16 species, bool8 setHotSpringsLocation)
u8 metLevel;
u16 ball;
u8 language;
u8 metLocation;
metloc_u8_t metLocation;
u8 isEgg;

CreateMon(mon, species, EGG_HATCH_LEVEL, USE_RANDOM_IVS, FALSE, 0, OT_ID_PLAYER_ID, 0);
Expand Down
3 changes: 2 additions & 1 deletion src/egg_hatch.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "global.h"
#include "gametypes.h"
#include "pokemon.h"
#include "egg_hatch.h"
#include "pokedex.h"
Expand Down Expand Up @@ -362,7 +363,7 @@ static void AddHatchedMonToParty(u8 id)
u8 name[POKEMON_NAME_LENGTH + 1];
u16 ball;
u16 metLevel;
u8 metLocation;
metloc_u8_t metLocation;
struct Pokemon *mon = &gPlayerParty[id];

CreateHatchedMon(mon, &gEnemyParty[0]);
Expand Down
5 changes: 4 additions & 1 deletion src/frontier_pass.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "global.h"
#include "gametypes.h"
#include "gpu_regs.h"
#include "main.h"
#include "trainer_card.h"
Expand Down Expand Up @@ -606,7 +607,9 @@ static void LeaveFrontierPass(void)

static u32 AllocateFrontierPassData(void (*callback)(void))
{
u8 i;
// This variable is a MAPSEC initially, but is recycled as a
// bare integer near the end of the function.
mapsec_u8_t i;

if (sPassData != NULL)
return ERR_ALREADY_DONE;
Expand Down
8 changes: 4 additions & 4 deletions src/landmark.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ struct Landmark

struct LandmarkList
{
u8 mapSection;
mapsec_u8_t mapSection;
u8 id;
const struct Landmark *const *landmarks;
};
Expand Down Expand Up @@ -392,9 +392,9 @@ static const struct LandmarkList sLandmarkLists[] =
{MAPSEC_NONE, 0, NULL},
};

static const struct Landmark *const *GetLandmarks(u8 mapSection, u8 id);
static const struct Landmark *const *GetLandmarks(mapsec_u8_t mapSection, u8 id);

const u8 *GetLandmarkName(u8 mapSection, u8 id, u8 count)
const u8 *GetLandmarkName(mapsec_u8_t mapSection, u8 id, u8 count)
{
const struct Landmark *const *landmarks = GetLandmarks(mapSection, id);

Expand All @@ -421,7 +421,7 @@ const u8 *GetLandmarkName(u8 mapSection, u8 id, u8 count)
return (*landmarks)->name;
}

static const struct Landmark *const *GetLandmarks(u8 mapSection, u8 id)
static const struct Landmark *const *GetLandmarks(mapsec_u8_t mapSection, u8 id)
{
u16 i = 0;

Expand Down
3 changes: 2 additions & 1 deletion src/map_name_popup.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "global.h"
#include "gametypes.h"
#include "battle_pyramid.h"
#include "bg.h"
#include "event_data.h"
Expand Down Expand Up @@ -404,7 +405,7 @@ static void LoadMapNamePopUpWindowBg(void)
{
u8 popUpThemeId;
u8 popupWindowId = GetMapNamePopUpWindowId();
u16 regionMapSectionId = gMapHeader.regionMapSectionId;
mapsec_u16_t regionMapSectionId = gMapHeader.regionMapSectionId;

if (regionMapSectionId >= KANTO_MAPSEC_START)
{
Expand Down
Loading