PHO - Pokémon Hackers Online
Go Back   PHO - Pokémon Hackers Online > Homebrew & Coding > Homebrew Projects

Homebrew Projects Working on a Homebrew project of some kind? Come and show it off!

Reply
 
Thread Tools Display Modes
Old 22nd October 2013, 12:40 PM   #1
Jambo51
Glory To Arstotzka
Ex-Staff
 
Jambo51's Avatar
 
Join Date: May 2012
Location: Scotland
Posts: 92
Jambo51
Default Jambo51's Homebrew Pokémon Engine

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):
Spoiler:
The Pokémon structure has been changed somewhat, separating out many PID dependent features into their own memory locations. Further details can be found in documentation.

The Real Time Clock data is (currently) held at 0x03000180, format being:
Year - u16
Month - u8
Day - u8
Day of week - u8
Hour - u8
Minute - u8
Second - u8
Time of Day - u8
Season - u8 (when implemented)

Flags are currently held at 0x0200F83C and are accessed in a bit wise manner, just like the original games. The valid flags range is 0x1 - 0x1FFF.

Variables are currently held at (unknown) and have a range of 0x0000 to 0xFFFF for values. the valid ranges of variables are from 0x4000 to 0x41FF, and 0x8000 to 0x801F.

The seen and caught flags for the Pokédex are held at (unknown), and are accessed as flags. the valid range of these is (technically) 0x1 to 0x290, but obviously, those flags above 0x289 are unused.

The Pokémon structure is held at (unknown) and follows the same structure as defined in the documentation.


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
__________________
I have nothing interesting to add

Last edited by Jambo51; 27th October 2013 at 06:43 PM.
Jambo51 is offline   Reply With Quote
Sponsored Links
Old 22nd October 2013, 12:53 PM   #2
Pia Carrot
Orange Developer
Administrator
 
Pia Carrot's Avatar
 
Join Date: Aug 2010
Location: Valencia Island
Age: 21
Posts: 848
Pia Carrot Pia Carrot Pia Carrot Pia Carrot
Default

Sounds great, may even consider hacking again when this comes out.
__________________

I'm a boob
Pia Carrot is offline   Reply With Quote
Old 22nd October 2013, 02:09 PM   #3
Team Fail
Balance and Ruin
Ex-StaffStyle AdminstratorPHO VIP
 
Team Fail's Avatar
 
Join Date: Jul 2010
Posts: 585
Team Fail Team Fail Team Fail Team Fail Team Fail
Default

I actually really like this. I'm just curious, is it possible at all to toggle the Fairy-Type in case we don't want it?
__________________
twitter | dropbox | youtube | bro

Thank you for your time, PHO. I won't soon forget it.
Team Fail is offline   Reply With Quote
Old 22nd October 2013, 03:21 PM   #4
Jambo51
Glory To Arstotzka
Ex-Staff
 
Jambo51's Avatar
 
Join Date: May 2012
Location: Scotland
Posts: 92
Jambo51
Default

Quote:
Originally Posted by Team Fail View Post
I actually really like this. I'm just curious, is it possible at all to toggle the Fairy-Type in case we don't want it?
No, but like hacking any normal ROM, if you don't want to use something, then you just, well, don't use it! :P

Quote:
Originally Posted by Pia Carrot View Post
Sounds great, may even consider hacking again when this comes out.
Thanks, man.

I'll stick up some screenshots and a download link when I get home (if I remember! Haha).

Currently working on getting the music engine to produce wave sounds, so I'm getting reasonably close to finishing the first part of that.

The documentation I refer to will also be linked to once I've created it. Hope you guys appreciate the work going into this as much as I've enjoyed writing this thing! (The engine, not this post haha).
__________________
I have nothing interesting to add
Jambo51 is offline   Reply With Quote
Old 22nd October 2013, 05:28 PM   #5
Team Fail
Balance and Ruin
Ex-StaffStyle AdminstratorPHO VIP
 
Team Fail's Avatar
 
Join Date: Jul 2010
Posts: 585
Team Fail Team Fail Team Fail Team Fail Team Fail
Default

Quote:
Originally Posted by Jambo51 View Post
No, but like hacking any normal ROM, if you don't want to use something, then you just, well, don't use it! :P
That could work. Change the typing so that nothing uses Fairy Type, and change the effectiveness table back to pre-Gen 6 settings.

I really like that you're using the M4A engine, since it's so usable everywhere anyways.
__________________
twitter | dropbox | youtube | bro

Thank you for your time, PHO. I won't soon forget it.
Team Fail is offline   Reply With Quote
Old 22nd October 2013, 07:23 PM   #6
Linkandzelda
RHO つぃちょう
Webmaster
 
Linkandzelda's Avatar
 
Join Date: Apr 2012
Location: United Kingdom
Posts: 302
Linkandzelda Linkandzelda Linkandzelda
Default

This is really great to see this on there. I have an idea, perhaps have a config file that allows the selection of max generation to use? For example it could be configured to use only gen1, or up to gen6+. That way the amount of Pokémon and abilities could be tailored for what people want (and for example, make it have a GBC mode for gen2 games) and turning off Fairy type if you do add Kalos stuff.

Just a little idea, and really great to see this here!
__________________





Linkandzelda is offline   Reply With Quote
Old 22nd October 2013, 07:59 PM   #7
Jambo51
Glory To Arstotzka
Ex-Staff
 
Jambo51's Avatar
 
Join Date: May 2012
Location: Scotland
Posts: 92
Jambo51
Default

Quote:
Originally Posted by Linkandzelda View Post
This is really great to see this on there. I have an idea, perhaps have a config file that allows the selection of max generation to use? For example it could be configured to use only gen1, or up to gen6+. That way the amount of Pokémon and abilities could be tailored for what people want (and for example, make it have a GBC mode for gen2 games) and turning off Fairy type if you do add Kalos stuff.

Just a little idea, and really great to see this here!
I'd have to recompile the ROM several times, I'm not doing that. Since I'd just get confused about what's in one and not in another.

Like I said, if you don't want to use something, then just don't. All 649 Pokémon currently in it use their Gen 5 typings (so no fairies anywhere) but the type is there and has data in case people DO want to use it. Seem fair?

I'll also put in 2 separate Exp Calculations, one in gen 1-4 style, and one in gen 5 style.
__________________
I have nothing interesting to add
Jambo51 is offline   Reply With Quote
Old 22nd October 2013, 08:59 PM   #8
Pia Carrot
Orange Developer
Administrator
 
Pia Carrot's Avatar
 
Join Date: Aug 2010
Location: Valencia Island
Age: 21
Posts: 848
Pia Carrot Pia Carrot Pia Carrot Pia Carrot
Default

Just a couple questions.

How difficult would it be to change the screen resolution/size and how the textbox is positioned with your engine?

Also, will attacks be like they were before generation 4 or will they be split into Special and Physical individually?

Finally, so, like editing any normal ROM, I could use YAPE or something to change Pokémon typings and moves learned(if that's even still the modern tool to use, haven't hacked properly since 2010)?
__________________

I'm a boob
Pia Carrot is offline   Reply With Quote
Old 22nd October 2013, 09:06 PM   #9
Team Fail
Balance and Ruin
Ex-StaffStyle AdminstratorPHO VIP
 
Team Fail's Avatar
 
Join Date: Jul 2010
Posts: 585
Team Fail Team Fail Team Fail Team Fail Team Fail
Default

Quote:
Originally Posted by Pia Carrot View Post
Just a couple questions.

How difficult would it be to change the screen resolution/size and how the textbox is positioned with your engine?

Also, will attacks be like they were before generation 4 or will they be split into Special and Physical individually?

Finally, so, like editing any normal ROM, I could use YAPE or something to change Pokémon typings and moves learned(if that's even still the modern tool to use, haven't hacked properly since 2010)?
You never noticed that he's using either MaxMod or the M4A engine for music. Which implies he's making it as GBA homebrew using devkitarm. So your screen resolution will be that of the GBA itself.
__________________
twitter | dropbox | youtube | bro

Thank you for your time, PHO. I won't soon forget it.
Team Fail is offline   Reply With Quote
Old 22nd October 2013, 09:09 PM   #10
Jambo51
Glory To Arstotzka
Ex-Staff
 
Jambo51's Avatar
 
Join Date: May 2012
Location: Scotland
Posts: 92
Jambo51
Default

Quote:
Originally Posted by Pia Carrot View Post
Just a couple questions.

How difficult would it be to change the screen resolution/size and how the textbox is positioned with your engine?
Resolution and size are predetermined by the GBA, so no way of changing them.

Textbox positioning... I'm sure I can come up with some way of giving the hacker some form of control over it. I'll cross that bridge when I come to it! :P

Quote:
Originally Posted by Pia Carrot View Post
Also, will attacks be like they were before generation 4 or will they be split into Special and Physical individually?
They'll be split by default, using the new system.

Quote:
Originally Posted by Pia Carrot View Post
Finally, so, like editing any normal ROM, I could use YAPE or something to change Pokémon typings and moves learned(if that's even still the modern tool to use, haven't hacked properly since 2010)?
Yes, and no. Since I had to rearrange some of the data, some parts won't work properly inside existing editors.

For example, I reworked the base stats data to include extra information (like a hidden ability) and extend or remove other data from it. In general, I'm trying to stick to Game Freak's systems though.
__________________
I have nothing interesting to add
Jambo51 is offline   Reply With Quote
Reply

Tags
engine, homebrew, jambo51, pokemon

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 01:59 PM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2017, vBulletin Solutions, Inc. User Alert System provided by Advanced User Tagging (Lite) - vBulletin Mods & Addons Copyright © 2017 DragonByte Technologies Ltd.
Feedback Buttons provided by Advanced Post Thanks / Like (Lite) - vBulletin Mods & Addons Copyright © 2017 DragonByte Technologies Ltd.
Pokémon characters and images belong to Pokémon USA, Inc. and Nintendo.
Pokémon Hackers Online (PHO) is in no way affiliated with or endorsed by Nintendo LLC, Creatures, GAMEFREAK inc,
The Pokémon Company, Pokémon USA, Inc., The Pokémon Company International, or Wizards of the Coast.
All forum/site content (unless noted otherwise) and site designs are © 2006-2013 Pokémon Hackers Online (PHO).
Green Charizard Christos TreeckoLv100

"Black 2" by ARTPOP. Kyurem artwork by XOUS.

no new posts