Hello, intrepid reader! If you're looking at this thread, you have likely realised that there are several frustrating limits in the Gen III Pokémon game engines, which can badly alter how you wish to go about creating a hack.
What this project aims to do is offer a free to use, open source engine to base your crazy and creative hacks on!
Features:
All 649 Pokémon from Kanto, Johto, Hoenn, Sinnoh and Unova are in the base.
Built in brand new music engine especially coded to run music from the GB games with minimal conversion.
Built in RTC and Day and Night Cycle.
Fairy type (as well as all the old regular types!)
Planned Features:
Standard Pokémon features (battles, etc)
Seasonal Cycles (Day is shorter is Winter, etc)
Either Maxmod or potentially M4AA engine for 16 bit music (M4AA is Sappy to most people).
May add:
Kalos Pokémon
Contests (in spite of the fact that I personally dislike them)
Suggestions are welcome, and constructive criticism is welcomed!
The engine is planned to use the same scripting languages as the actual Gen III games, so no downloading new tools or learning new languages for this!
Details on major changes (Skip unless you're planning to ASM hack the engine):
Some screenshots:
Typedefs for Project:
Spoiler:
//
// customtypes.h:
//
#ifndef CUSTOMTYPES_H
#define CUSTOMTYPES_H
// --- primary typedefs ---
typedef enum { Time_Day, Time_Morning, Time_Afternoon, Time_Night } Times;
typedef enum { Flag_Null, Flag_RunningShoes, Flag_RunningShoesOn, Flag_UsingGBP } Flags;
typedef struct MovesetEntry {
u16 moveID;
u8 level;
u8 unused;
} MovesetEntry;
typedef struct Block {
u32 bottom[2];
u32 top[2];
} Block;
typedef struct MapConnectionData {
u32 type;
s32 offset;
u8 mapBank;
u8 map;
u16 alignment;
} MapConnectionData;
typedef struct MapConnection {
u32 numberOfConnections;
MapConnectionData* mainData[];
} MapConnection;
typedef struct PrimaryTileset {
u32 information;
u16* tilesetData[0x5000];
u16* paletteData1[0x400];
Block* blockData[0x280];
u32* blockAnimations[0x280];
u32* blockInformation[0x280];
} PrimaryTileset;
typedef struct SecondaryTileset {
u32 information;
u16* tilesetData[0x3000];
u16* paletteData2[0x400];
Block* blockData[0x100];
u32* blockAnimations[0x100];
u32* blockInformation[0x100];
} SecondaryTileset;
typedef struct MapFooter {
u32 width;
u32 height;
u16* borderBlocks;
u16* mapDataLocation;
PrimaryTileset* primaryTileset;
SecondaryTileset* secondaryTileset;
u8 borderWidth;
u8 borderHeight;
u16 alignment;
} MapFooter;
typedef struct LevelScript
{
u8 type;
u8* scriptLocation; // unaligned, make sure to load using loop
} LevelScript;
typedef struct WildPokemonEntry
{
u16 species;
u8 minLevel;
u8 maxLevel;
} WildPokemonEntry;
typedef struct WildGrassPokemonData
{
u32 information;
WildPokemonEntry* wildData[12];
} WildGrassPokemonData;
typedef struct WildWaterPokemonData
{
u32 information;
WildPokemonEntry* wildData[10];
} WildWaterPokemonData;
typedef struct WildTreePokemonData
{
u32 information;
WildPokemonEntry* wildData[5];
} WildTreePokemonData;
typedef struct WildFishingRodPokemonData
{
u32 information;
WildPokemonEntry* wildData[12];
} WildFishingRodPokemonData;
typedef struct WildData
{
WildGrassPokemonData* grassData;
WildWaterPokemonData* waterData;
WildTreePokemonData* treeData;
WildTreePokemonData* rockSmashData;
WildFishingRodPokemonData* fishingRodData;
} WildData;
typedef struct MapHeader {
MapFooter* footerLocation;
u32* eventsLocation;
LevelScript* levelScriptsLocation;
MapConnection* connections;
u16 musicTrack;
u8 mapBank;
u8 map;
u8 mapNameID;
u8 caveStatus;
u8 weatherType;
u8 lightStatus;
u8 unknown;
u8 escapeRopeType;
u8 showName;
u8 battleType;
WildData* wildDataLocation;
} MapHeader;
typedef struct AbridgedPokemon {
u32 personalityID;
u32 originalTrainerID;
char nickname[11];
u8 ability;
char originalTrainerName[7];
u8 mark;
u16 checksum;
u8 gender;
u8 nature;
u16 species;
u16 heldItem;
u32 experience:21;
u32 formeValue:10;
u32 forceShiny:1;
u8 ppBonuses;
u8 friendship;
u8 type1;
u8 type2;
u16 move1;
u16 move2;
u16 move3;
u16 move4;
u8 move1PP;
u8 move2PP;
u8 move3PP;
u8 move4PP;
u8 hpEV;
u8 attackEV;
u8 defenceEV;
u8 speedEV;
u8 specialAttackEV;
u8 specialDefenceEV;
u8 coolness;
u8 beauty;
u8 cuteness;
u8 smartness;
u8 toughness;
u8 feel;
u8 pokerusStatus:1;
u8 pokeBall:7;
u8 metLocation;
u8 catchLevel;
u8 originsInfo;
u32 hpIV:5;
u32 attackIV:5;
u32 defenceIV:5;
u32 speedIV:5;
u32 specialAttackIV:5;
u32 specialDefenceIV:5;
u32 isEgg:1;
u32 isObedient:1;
u32 ribbons;
} AbridgedPokemon;
typedef struct Pokemon {
AbridgedPokemon mainData;
u32 statusAilment;
u8 level;
u8 pokerusRemaining;
u16 currentHP;
u16 maximumHP;
u16 attack;
u16 defence;
u16 speed;
u16 specialAttack;
u16 specialDefence;
} Pokemon;
typedef struct BagItem {
u16 quantity;
u16 itemID;
} BagItem;
typedef struct Player {
u32 trainerID;
char name[8];
u8 gender;
u8 alignment1;
u16 hoursPlayed;
u8 minutesPlayed;
u8 secondsPlayed;
u8 framesPlayed;
u8 alignment2;
u16 options;
} Player;
typedef struct Buffer {
char text[20];
} Buffer;
typedef struct DexEntry {
u16 seenCaughtValue;
u16 speciesValue;
char* textPointer;
} DexEntry;
typedef struct BaseData {
u8 baseHP;
u8 baseAttack;
u8 baseDefence;
u8 baseSpeed;
u8 baseSpecialAttack;
u8 baseSpecialDefence;
u8 type1;
u8 type2;
u8 catchRate;
u8 genderSplitByte;
u16 EVYield;
u16 item1;
u16 item2;
u16 baseExpYield;
u8 hatchSteps;
u8 baseFriendship;
u8 levelUpType;
u8 eggGroup1;
u8 eggGroup2;
u8 ability1;
u8 ability2;
u8 hiddenAbility;
u8 safariZoneFleeRate;
u8 colour;
} BaseData;
typedef struct RealTimeClock {
u16 year;
u8 month;
u8 day;
u8 dayOfWeek;
u8 hour;
u8 minute;
u8 second;
u8 timeOfDay;
} RealTimeClock;
typedef enum Types {
TYPE_NORMAL,
TYPE_FIGHTING,
TYPE_FLYING,
TYPE_POISON,
TYPE_GROUND,
TYPE_ROCK,
TYPE_BUG,
TYPE_GHOST,
TYPE_STEEL,
TYPE_FIRE,
TYPE_WATER,
TYPE_GRASS,
TYPE_ELECTRIC,
TYPE_PSYCHIC,
TYPE_ICE,
TYPE_DRAGON,
TYPE_DARK,
TYPE_FAIRY,
TYPE_NONE
} Types;
typedef struct Bag {
u32 bagInformation;
BagItem bagItemsData[40];
BagItem keyItemsData[30];
BagItem ballItemsData[20];
BagItem TMData[103];
BagItem berryItemsData[30];
} Bag;
typedef struct PokemonStorageBoxes {
u32 currentBoxID;
AbridgedPokemon boxData[25][30];
} PokemonStorageBoxes;
typedef struct NoiseRegister {
u32 soundLength:6;
u32 unused1:2;
u32 volumeEnvelopeSpeed:3;
u32 volumeEnvelopeDirection:1;
u32 initialVolume:4;
u32 unused2:16;
u32 dividingRatioOfFrequencies:3;
u32 counterStepWidth:1; // 0 = 15 bits, 1 = 7 bits
u32 shiftClockFrequency:4;
u32 unused3:6;
u32 lengthUseFlag:1;
u32 initialise:1;
u32 unused4:16;
} NoiseRegister;
typedef struct WavePattern {
u32 part1;
u32 part2;
u32 part3;
u32 part4;
} WavePattern;
typedef struct ToneData {
u8* nextInstruction;
u8* returnLocation;
u8 frameDelay;
s8 pitchBend;
s8 keyShift;
u8 currentOctave;
u16 pitch;
u8 currentVoice;
u8 fadeSpeed;
u16 modulation;
u8 channelVolume;
u8 fadeDirection;
u8 velocity;
u8 loopCounter;
s8 pan;
u8 noteLength;
u16 tone;
u16 unused;
} ToneData;
typedef struct WaveData {
u8* nextInstruction;
u8* returnLocation;
u8 frameDelay;
u8 loopCounter;
s8 keyShift;
u8 currentOctave;
u16 pitch;
u8 velocity;
u8 currentVoice;
u16 modulation;
u8 pan;
u8 noteLength;
} WaveData;
typedef struct NoiseData {
u8* nextInstruction;
u8* returnLocation;
} NoiseData;
typedef struct GBPMusicStruct {
u16 tempo;
u16 tone1Included:1;
u16 tone2Included:1;
u16 waveIncluded:1;
u16 noiseIncluded:1;
u16 unused:12;
ToneData tone1;
ToneData tone2;
WaveData wave;
NoiseData noise;
} GBPMusicStruct;
typedef struct GBPTrack {
u32 trackType:2;
u32 secondaryTracks:1;
u32 unused:29;
u8* songData;
} GBPTrack;
typedef struct GBPTrackHeader {
u32 tone1Included:1;
u32 tone2Included:1;
u32 waveIncluded:1;
u32 noiseIncluded:1;
u32 numberOfTracks:3;
u32 unused:25;
GBPTrack theTracks[];
} GBPTrackHeader;
typedef struct MoveData {
u16 effectID;
u8 basePower;
u8 type;
u8 accuracy;
u8 basePP;
u8 effectAccuracy;
u8 targets;
s8 priority;
u8 specialFlags;
u8 category;
u8 padding;
} MoveData;
/*Normal
Fighting
Flying
Poison
Ground
Rock
Bug
Ghost
Steel
Fire
Water
Grass
Electric
Psychic
Ice
Dragon
Dark
Fairy
???*/
#define TILESET_TILESET_DATA_OFFSET 4
#define TILESET_PALETTE_DATA_OFFSET 8
#define TILESET_BLOCKS_DATA_OFFSET 12
#define EWRAM_LOCATION __attribute__((section (".sbss")))
#endif // TOOLBOX_H