OK. If you're not familiar with C#, you should study it a bit before trying to understand this. Obviously, you will understand what I say because my teaching level is over 9000 but it'll be quite hard for you to make a good program with it, so yeh. Google is your friend here.
I made some functions for you people. The basic functions, writeHex and readHex were made to be in a school project I did but I said meh let's do some more functions and release it here, and also making a better tutorial than my old one.
The functions can be found in the attached files.
Without further ado, let's go!
Requirements:
Before I start explaining how to make the code, I will first explain about every function I did:
WriteHex -> Writes hexadecimal data into a location at the ROM. Can write only one or two bytes.
ReadHex -> Reads hexadecimal data from the ROM, returns a string with the bytes read.
GetGameCode -> Reads the two bytes at 0xAC (default game code location for .GBA Pokémon games), converts it to UTF8 and returns a string with the game code.
IpsPatch -> Patches an .IPS file into a ROM.
WriteHexArray -> Writes hexadecimal data into a location at the ROM. Can write more than one or two bytes; depending on the array length.
Here's the usage manual and examples:
1) Adding to your project:
Import the .cs file provided in the attachments to your project. In Visual Studio, press Shift+Alt+A.
Go into the top of the form where you want to use the functions. Up, where all the "using" thingys are, add a new line:
Then, in your code, add
2) Calling the functions is very easy. Here's an explanation on every function:
WriteHex:
If I want to write 0xE0 at 0x800000, in a file opened via openFileDialog1, imma use this:
If I want to write 0xF1A9 at 0xA00000, in a file located at my desktop, imma use this:
ReadHex:
This function returns a string with the bytes read.
If I want to display in a message box 3 bytes at 0xE1, in a file opened via openFileDialog2 and I want to split them with spaces, imma do this:
If the bytes at 0xE1 are 0x10, 0x5E, 0xAA; the message box will display:
GetGameCode:
This function returns a string with the game code. Here's an example for a code for checking the game code:
This code only checks if the game code is English FR or Japanese FR, but you can do as much you want, I am just lazy.
IpsPatch:
This function is pretty simple. You just set the target GBA file and the IPS file and you're done:
That'll patch Patch.ips into Game.gba.
WriteHexArray:
This fuction will write the byte array provided into a location in the ROM.
To convert a string array (to read from text boxes and such) into a byte array, I recommend using that code:
Starting the program!
OK. I am going to show you how to make a program that enables/disable the flashback that happens when you load a save file in FireRed.
That is for Visual C#. Console-ish C# is ugly imo, therefore I won't cover it in this tutorial.
Start by making 3 buttons. Name one button "btnOpen", name another "btnEnable" and name another "btnDisable". Now, make a OpenFileDialog and name it openFileDialog1 (the default name).
Go to the code area. Where all the "using [X]" are, paste:
Now, you are officially using me (lol jk it's just a reference to the namespace of my class).
Look for:
After that code, paste:
Go back on the desinger and double click on btnOpen and paste in the code zone:
You made the open file button! Feel free to test it and change the text of the button.
Go back to the designer and double click btnEnable and paste in the code zone:
You made the enable flashback button! Again, feel free to test it and change the text of the button.
Again, go back to the designer and double click btnDiasble and paste in the code zone:
Nice nice. You finished coding your program haha. That was quick... Now design it... Make your own unique design that'll attract users. If you don't do it... why would they choose to use your program and not another one's program?
Optional: If you want to avoid error that nobody really understands, you may make a 'try' thingy before any function call. For example:
Credits (no particular order)
The functions should work fine. If you find an error or more, please contact me so I could fix it ASAP. Also, if you find a mistake in the tutorial itself, contact me so I could fix it ASAP. Sorry for not providing pictures in the tutorial. I am a really lazy person. If people find this tutorial REALLY hard to understand, I will provide pictures. I am writing this when I am really tired, so you will probably find something wrong with this tutorial.
I made some functions for you people. The basic functions, writeHex and readHex were made to be in a school project I did but I said meh let's do some more functions and release it here, and also making a better tutorial than my old one.
The functions can be found in the attached files.
Without further ado, let's go!
Requirements:
- Basic C# Knoledge
- A C# Compiler (I use Visual Studio 2013)
- My C# Functions (They're in the attachments)
Before I start explaining how to make the code, I will first explain about every function I did:
WriteHex -> Writes hexadecimal data into a location at the ROM. Can write only one or two bytes.
ReadHex -> Reads hexadecimal data from the ROM, returns a string with the bytes read.
GetGameCode -> Reads the two bytes at 0xAC (default game code location for .GBA Pokémon games), converts it to UTF8 and returns a string with the game code.
IpsPatch -> Patches an .IPS file into a ROM.
WriteHexArray -> Writes hexadecimal data into a location at the ROM. Can write more than one or two bytes; depending on the array length.
Here's the usage manual and examples:
Spoiler:
1) Adding to your project:
Import the .cs file provided in the attachments to your project. In Visual Studio, press Shift+Alt+A.
Go into the top of the form where you want to use the functions. Up, where all the "using" thingys are, add a new line:
Code:
using Gal;
Then, in your code, add
Code:
GBAFunctions gf = new GBAFunctions();
2) Calling the functions is very easy. Here's an explanation on every function:
WriteHex:
Code:
gf.WriteHex(string Byte(s)ToWrite, string Offset, string FileLocation, int AmountToWrite);
If I want to write 0xE0 at 0x800000, in a file opened via openFileDialog1, imma use this:
Code:
gf.WriteHex("A0","800000",openFileDialog1.FileName,1);
If I want to write 0xF1A9 at 0xA00000, in a file located at my desktop, imma use this:
Code:
gf.WriteHex ("F1A9", "A00000",@"C:\Users\[yourusername]\Desktop\Pokemon.GBA\",2);
ReadHex:
Code:
gf.ReadHex(int BytesToRead, string Offset, string FileLocation,bool SplitBytesBySpace);
If I want to display in a message box 3 bytes at 0xE1, in a file opened via openFileDialog2 and I want to split them with spaces, imma do this:
Code:
MessageBox.Show(gf.ReadHex(3,"E1",openFileDialog2.FileName,true));
E1 10 AA
GetGameCode:
Code:
gf.GetGameCode(string FileLocation);
Code:
string gameCode = gf.GetGameCode();
if (gameCode=="BPRE){
MessageBox.Show("English FireRed");
if (gameCode=="BPRJ){
MessageBox.Show("Japanese FireRed");
}
IpsPatch:
Code:
gf.IpsPatch(string TargetFilePath, string IpsFilePath);
Code:
gf.IpsPatch(@"C:\Users\[yourusername]\Desktop\Game.gba",@"C:\Users\[yourusername]\Desktop\Patch.ips");
That'll patch Patch.ips into Game.gba.
WriteHexArray:
Code:
gf.WriteHexArray(byte[] BytesToWrite,string Offset, string FileLocation);
Code:
byte[] bytes = {0x40,0x50,0x60};
gf.WriteHexArray(bytes,"800000",@"C:\Users\[yourusername]\Desktop\Game.gba");
To convert a string array (to read from text boxes and such) into a byte array, I recommend using that code:
Code:
byte[] byteArray = [yourstringarray].Select(x => Convert.ToByte(x, 16)).ToArray();
Starting the program!
OK. I am going to show you how to make a program that enables/disable the flashback that happens when you load a save file in FireRed.
That is for Visual C#. Console-ish C# is ugly imo, therefore I won't cover it in this tutorial.
Start by making 3 buttons. Name one button "btnOpen", name another "btnEnable" and name another "btnDisable". Now, make a OpenFileDialog and name it openFileDialog1 (the default name).
Go to the code area. Where all the "using [X]" are, paste:
Code:
using Gal;
Look for:
Code:
public [yourprojectname]()
{
InitializeComponent();
}
After that code, paste:
Code:
GBAFunctions gf = new GBAFunctions(); //References to the class I made.
byte[] EnableFlashback = { 0x00, 0x28, 0x0F, 0xD0 }; //Creates a new byte array, that's holding the data to enable the flashback.
byte[] DisableFlashback = { 0x00, 0x1C, 0x0F, 0xE0 }; //Creates a new byte array, that's holding the data to disable the flackback.
Go back on the desinger and double click on btnOpen and paste in the code zone:
Code:
if (openFileDialog1.ShowDialog() == DialogResult.OK) //Opens a file choosing dialog and checks if a file's been chosen.
{
string gameCode = gf.GetGameCode(openFileDialog1.FileName); //Creates a new string that'll hold the game code.
if (gameCode != "BPRE") //If the game code isn't "BPRE", English FireRed's game code.
{
MessageBox.Show("Sorry. Only FireRed Support.", "Sorry");
openFileDialog1.FileName = ""; //Resets the file the open file dialog's holding.
}
else {
MessageBox.Show("FireRed Opened!", "Success!");
}
}
else
{
//Whatever you want it to do if the user didn't choose a file.
}
You made the open file button! Feel free to test it and change the text of the button.
Go back to the designer and double click btnEnable and paste in the code zone:
Code:
gf.WriteHexArray(EnableFlashback, "110F54", openFileDialog1.FileName); //Writes the EnableFlashback array we created before into the offset 0x110F54, where the bytes determine if the flashback system is enabled or not are located.
You made the enable flashback button! Again, feel free to test it and change the text of the button.
Again, go back to the designer and double click btnDiasble and paste in the code zone:
Code:
gf.WriteHexArray(DisableFlashBack, "110F54", openFileDialog1.FileName); //Writes the DisableFlashBack array we created before into the offset 0x110F54, where the bytes determine if the flashback system is enabled or not are located.
Optional: If you want to avoid error that nobody really understands, you may make a 'try' thingy before any function call. For example:
Code:
try{
gf.ReadHex(2,"800000",openFileDialog1.FileName,false);
}
catch (Exception ex){
MessageBox.Show("Something went wrong with the ReadHex Command","damn"); //Alternatively, you could use MessageBox.Show(ex.ToString(),"damn");
}
Credits (no particular order)
- Hopeless Masquerade - Helping me a lot with C# and with the ReadHex function!
- SMWiki - IPS patching code. Wasn't written by me!
- Microsoft - The awesome Visual Studio program and C#!
The functions should work fine. If you find an error or more, please contact me so I could fix it ASAP. Also, if you find a mistake in the tutorial itself, contact me so I could fix it ASAP. Sorry for not providing pictures in the tutorial. I am a really lazy person. If people find this tutorial REALLY hard to understand, I will provide pictures. I am writing this when I am really tired, so you will probably find something wrong with this tutorial.
Attachments
Last edited: