pokefirered/include/global.h
2018-10-03 21:30:13 -04:00

493 lines
10 KiB
C

#ifndef GUARD_GLOBAL_H
#define GUARD_GLOBAL_H
#include "config.h"
#include "gba/gba.h"
// Prevent cross-jump optimization.
#define BLOCK_CROSS_JUMP asm("");
// to help in decompiling
#define asm_comment(x) asm volatile("@ -- " x " -- ")
#define asm_unified(x) asm(".syntax unified\n" x "\n.syntax divided")
#if defined (__APPLE__) || defined (__CYGWIN__)
void *memset(void *, int, size_t);
void *memcpy(void *, const void *, size_t);
int strcmp(const char *s1, const char *s2);
char* strcpy(char *dst0, const char *src0);
#endif // __APPLE__
#define ARRAY_COUNT(array) (sizeof(array) / sizeof((array)[0]))
// useful math macros
// Converts a number to Q8.8 fixed-point format
#define Q_8_8(n) ((s16)((n) * 256))
// Converts a number to Q4.12 fixed-point format
#define Q_4_12(n) ((s16)((n) * 4096))
#define POKEMON_NAME_LENGTH 10
#define OT_NAME_LENGTH 7
// There are many quirks in the source code which have overarching behavioral differences from
// a number of other files. For example, diploma.c seems to declare rodata before each use while
// other files declare out of order and must be at the beginning. There are also a number of
// macros which differ from one file to the next due to the method of obtaining the result, such
// as these below. Because of this, there is a theory (Two Team Theory) that states that these
// programming projects had more than 1 "programming team" which utilized different macros for
// each of the files that were worked on.
#define T1_READ_8(ptr) ((ptr)[0])
#define T1_READ_16(ptr) ((ptr)[0] | ((ptr)[1] << 8))
#define T1_READ_32(ptr) ((ptr)[0] | ((ptr)[1] << 8) | ((ptr)[2] << 16) | ((ptr)[3] << 24))
#define T1_READ_PTR(ptr) (u8*) T1_READ_32(ptr)
// T2_READ_8 is a duplicate to remain consistent with each group.
#define T2_READ_8(ptr) ((ptr)[0])
#define T2_READ_16(ptr) ((ptr)[0] + ((ptr)[1] << 8))
#define T2_READ_32(ptr) ((ptr)[0] + ((ptr)[1] << 8) + ((ptr)[2] << 16) + ((ptr)[3] << 24))
#define T2_READ_PTR(ptr) (void*) T2_READ_32(ptr)
extern u8 gStringVar1[];
extern u8 gStringVar2[];
extern u8 gStringVar3[];
extern u8 gStringVar4[];
enum
{
VERSION_SAPPHIRE = 1,
VERSION_RUBY = 2,
VERSION_EMERALD = 3,
VERSION_FIRE_RED = 4,
VERSION_LEAF_GREEN = 5,
};
enum LanguageId {
LANGUAGE_JAPANESE = 1,
LANGUAGE_ENGLISH = 2,
LANGUAGE_FRENCH = 3,
LANGUAGE_ITALIAN = 4,
LANGUAGE_GERMAN = 5,
// 6 goes unused but the theory is it was meant to be Korean
LANGUAGE_SPANISH = 7,
};
#define GAME_LANGUAGE (LANGUAGE_ENGLISH)
enum
{
MALE,
FEMALE
};
enum
{
OPTIONS_BUTTON_MODE_NORMAL,
OPTIONS_BUTTON_MODE_LR,
OPTIONS_BUTTON_MODE_L_EQUALS_A
};
enum
{
OPTIONS_TEXT_SPEED_SLOW,
OPTIONS_TEXT_SPEED_MID,
OPTIONS_TEXT_SPEED_FAST
};
enum
{
OPTIONS_SOUND_MONO,
OPTIONS_SOUND_STEREO
};
enum
{
OPTIONS_BATTLE_STYLE_SHIFT,
OPTIONS_BATTLE_STYLE_SET
};
enum
{
BAG_ITEMS = 1,
BAG_POKEBALLS,
BAG_TMsHMs,
BAG_BERRIES,
BAG_KEYITEMS
};
struct Coords16
{
s16 x;
s16 y;
};
struct UCoords16
{
u16 x;
u16 y;
};
struct Time
{
/*0x00*/ s16 days;
/*0x02*/ s8 hours;
/*0x03*/ s8 minutes;
/*0x04*/ s8 seconds;
};
struct Pokedex
{
/*0x00*/ u8 order;
/*0x01*/ u8 unknown1;
/*0x02*/ u8 nationalMagic; // must equal 0xDA in order to have National mode
/*0x03*/ u8 unknown2;
/*0x04*/ u32 unownPersonality; // set when you first see Unown
/*0x08*/ u32 spindaPersonality; // set when you first see Spinda
/*0x0C*/ u32 unknown3;
/*0x10*/ u8 owned[52];
/*0x44*/ u8 seen[52];
};
struct PokemonJumpResults // possibly used in the game itself?
{
u16 jumpsInRow;
u16 field2;
u16 excellentsInRow;
u16 field6;
u16 field8;
u16 fieldA;
u32 bestJumpScore;
};
struct BerryPickingResults // possibly used in the game itself? Size may be wrong as well
{
u32 bestScore;
u16 berriesPicked;
u16 berriesPickedInRow;
u8 field_8;
u8 field_9;
u8 field_A;
u8 field_B;
u8 field_C;
u8 field_D;
u8 field_E;
u8 field_F;
};
struct PyramidBag
{
u16 items_Lvl50[10];
u16 items_OpenLvl[10];
u8 quantity[10];
};
struct BerryCrush
{
u16 berryCrushResults[4];
u32 berryPowderAmount;
u32 unk;
};
#define PLAYER_NAME_LENGTH 8
struct UnknownSaveBlock2Struct
{
u8 field_0;
u8 field_1;
u8 field_2[2];
u8 field_4[8];
u8 field_C[16];
u16 field_1C[6];
u16 field_28[6];
u8 field_34[176];
u8 field_E4;
u8 field_E5;
u8 field_E6;
u8 field_E7;
u8 field_E8;
u8 field_E9;
u8 field_EA;
u8 field_EB;
}; // sizeof = 0xEC
struct SaveBlock2
{
/*0x000*/ u8 playerName[PLAYER_NAME_LENGTH];
/*0x008*/ u8 playerGender; // MALE, FEMALE
/*0x009*/ u8 specialSaveWarp;
/*0x00A*/ u8 playerTrainerId[4];
/*0x00E*/ u16 playTimeHours;
/*0x010*/ u8 playTimeMinutes;
/*0x011*/ u8 playTimeSeconds;
/*0x012*/ u8 playTimeVBlanks;
/*0x013*/ u8 optionsButtonMode; // OPTIONS_BUTTON_MODE_[NORMAL/LR/L_EQUALS_A]
/*0x014*/ u16 optionsTextSpeed:3; // OPTIONS_TEXT_SPEED_[SLOW/MID/FAST]
u16 optionsWindowFrameType:5; // Specifies one of the 20 decorative borders for text boxes
u16 optionsSound:1; // OPTIONS_SOUND_[MONO/STEREO]
u16 optionsBattleStyle:1; // OPTIONS_BATTLE_STYLE_[SHIFT/SET]
u16 optionsBattleSceneOff:1; // whether battle animations are disabled
u16 regionMapZoom:1; // whether the map is zoomed in
/*0x018*/ struct Pokedex pokedex;
/*0x090*/ u8 filler_90[0x8];
/*0x098*/ struct Time localTimeOffset;
/*0x0A0*/ struct Time lastBerryTreeUpdate;
/*0x0A8*/ u32 field_A8;
/*0x0AC*/ u8 filler_AC[0xE74];
/*0xF20*/ u32 encryptionKey;
};
extern struct SaveBlock2 *gSaveBlock2Ptr;
struct SecretBaseRecord
{
/*0x1A9C*/ u8 secretBaseId;
/*0x1A9D*/ u8 sbr_field_1_0:4;
/*0x1A9D*/ u8 gender:1;
/*0x1A9D*/ u8 sbr_field_1_5:1;
/*0x1A9D*/ u8 sbr_field_1_6:2;
/*0x1A9E*/ u8 trainerName[OT_NAME_LENGTH];
/*0x1AA5*/ u8 trainerId[4]; // byte 0 is used for determining trainer class
/*0x1AA9*/ u8 language;
/*0x1AAA*/ u16 sbr_field_e;
/*0x1AAC*/ u8 sbr_field_10;
/*0x1AAD*/ u8 sbr_field_11;
/*0x1AAE*/ u8 decorations[16];
/*0x1ABE*/ u8 decorationPos[16];
/*0x1AD0*/ u32 partyPersonality[6];
/*0x1AE8*/ u16 partyMoves[6 * 4];
/*0x1B18*/ u16 partySpecies[6];
/*0x1B24*/ u16 partyHeldItems[6];
/*0x1B2E*/ u8 partyLevels[6];
/*0x1B34*/ u8 partyEVs[6];
};
#include "constants/game_stat.h"
#include "global.fieldmap.h"
#include "global.berry.h"
#include "pokemon.h"
struct WarpData
{
s8 mapGroup;
s8 mapNum;
s8 warpId;
s16 x, y;
};
struct ItemSlot
{
u16 itemId;
u16 quantity;
};
struct Pokeblock
{
u8 color;
u8 spicy;
u8 dry;
u8 sweet;
u8 bitter;
u8 sour;
u8 feel;
};
struct Roamer
{
/*0x00*/ u32 ivs;
/*0x04*/ u32 personality;
/*0x08*/ u16 species;
/*0x0A*/ u16 hp;
/*0x0C*/ u8 level;
/*0x0D*/ u8 status;
/*0x0E*/ u8 cool;
/*0x0F*/ u8 beauty;
/*0x10*/ u8 cute;
/*0x11*/ u8 smart;
/*0x12*/ u8 tough;
/*0x13*/ bool8 active;
/*0x14*/ u8 filler[0x8];
};
struct RamScriptData
{
u8 magic;
u8 mapGroup;
u8 mapNum;
u8 objectId;
u8 script[995];
};
struct RamScript
{
u32 checksum;
struct RamScriptData data;
};
struct EasyChatPair
{
u16 unk0_0:7;
u16 unk0_7:7;
u16 unk1_6:1;
u16 unk2;
u16 words[2];
}; /*size = 0x8*/
struct MailStruct
{
/*0x00*/ u16 words[9];
/*0x12*/ u8 playerName[8];
/*0x1A*/ u8 trainerId[4];
/*0x1E*/ u16 species;
/*0x20*/ u16 itemId;
};
struct UnkMauvilleOldManStruct
{
u8 unk_2D94;
u8 unk_2D95;
/*0x2D96*/ u16 mauvilleOldMan_ecArray[6];
/*0x2DA2*/ u16 mauvilleOldMan_ecArray2[6];
/*0x2DAE*/ u8 playerName[8];
/*0x2DB6*/ u8 filler_2DB6[0x3];
/*0x2DB9*/ u8 playerTrainerId[4];
u8 unk_2DBD;
}; /*size = 0x2C*/
struct UnkMauvilleOldManStruct2
{
u8 filler0;
u8 unk1;
u8 unk2;
u16 mauvilleOldMan_ecArray[10];
u8 mauvilleOldMan_ecArray2[12];
u8 fillerF[0x2];
}; /*size = 0x2C*/
struct MauvilleOldManTrader
{
u8 unk0;
u8 unk1[4];
u8 unk5[4][11];
u8 unk31;
};
typedef union OldMan
{
struct UnkMauvilleOldManStruct oldMan1;
struct UnkMauvilleOldManStruct2 oldMan2;
struct MauvilleOldManTrader trader;
u8 filler[0x40];
} OldMan;
struct RecordMixing_UnknownStructSub
{
u32 unk0;
u8 data[0x34];
//u8 data[0x38];
};
struct RecordMixing_UnknownStruct
{
struct RecordMixing_UnknownStructSub data[2];
u32 unk70;
u16 unk74[0x2];
};
struct LinkBattleRecord
{
u8 name[8];
u16 trainerId;
u16 wins;
u16 losses;
u16 draws;
};
struct RecordMixingGiftData
{
u8 unk0;
u8 quantity;
u16 itemId;
u8 filler4[8];
};
struct RecordMixingGift
{
int checksum;
struct RecordMixingGiftData data;
};
struct ContestWinner
{
u32 personality;
u32 trainerId;
u16 species;
u8 contestCategory;
u8 monName[11];
u8 trainerName[8];
u8 contestRank;
};
struct DaycareMiscMon
{
struct MailStruct mail;
u8 OT_name[OT_NAME_LENGTH + 1];
u8 monName[POKEMON_NAME_LENGTH + 1];
u8 gameLanguage:4;
u8 monLanguage:4;
};
struct DaycareMon
{
struct BoxPokemon mon;
struct DaycareMiscMon misc;
u32 steps;
};
#define DAYCARE_MON_COUNT 2
struct DayCare
{
struct DaycareMon mons[DAYCARE_MON_COUNT];
u32 offspringPersonality;
u8 stepCounter;
};
struct DayCareMail
{
/*0x00*/ struct MailStruct message;
/*0x24*/ u8 names[19];
};
struct RecordMixingDayCareMail
{
struct DayCareMail mail[DAYCARE_MON_COUNT];
u32 numDaycareMons;
bool16 holdsItem[DAYCARE_MON_COUNT];
};
#define MAP_OBJECTS_COUNT 16
#define BERRY_TREES_COUNT 128
#define FLAGS_COUNT 300
#define VARS_COUNT 256
#define MAIL_COUNT 16
struct SaveBlock1
{
/*0x0000*/ u8 filler[0x3A4C];
/*0x3A4C*/ u8 rivalName[PLAYER_NAME_LENGTH];
};
extern struct SaveBlock1* gSaveBlock1Ptr;
struct Bitmap // TODO: Find a better spot for this
{
u8* pixels;
u32 width:16;
u32 height:16;
};
extern u8 gReservedSpritePaletteCount;
#endif // GUARD_GLOBAL_H