StarterMod -- Change R/S/E starter Pokemon! 07-17-2013, 05:26 PM
#1
I started this project about an hour and a half ago, after finding the hexadecimal
offsets within 3rd generation Pokemon ROM files that affect the starter Pokemon.
This program will automatically detect the version you're loading based on certain
offsets, then will present you with the current 3 starters. You may choose any
Pokemon from the first 386 in the Pokedex as your starter. Clicking Save will
create a new ROM file in the directory of the application, and will close automatically
after saving. As proof, I will provide a modified Sapphire ROM which you can test.
![[Image: 3n.png]](http://www.lensert.com/3n.png)
EXE Download | Virus Scan
Pokemon Sapphire ROM
Source:
offsets within 3rd generation Pokemon ROM files that affect the starter Pokemon.
This program will automatically detect the version you're loading based on certain
offsets, then will present you with the current 3 starters. You may choose any
Pokemon from the first 386 in the Pokedex as your starter. Clicking Save will
create a new ROM file in the directory of the application, and will close automatically
after saving. As proof, I will provide a modified Sapphire ROM which you can test.
![[Image: 3n.png]](http://www.lensert.com/3n.png)
EXE Download | Virus Scan
Pokemon Sapphire ROM
Source:
Code:
Imports System.Globalization
Imports System.Text
Public Class Form1
Dim x As Array = {"0100:BULBASAUR", "0200:IVYSAUR", "0300:VENESAUR", "0400:CHARMANDER", "0500:CHARMELEON", "0600:CHARIZARD", "0700:SQUIRTLE", "0800:WARTORTLE", "0900:BLASTOISE", "0A00:CATERPIE", "0B00:METAPOD", "0C00:BUTTERFREE", "0D00:WEEDLE", "0E00:KAKUNA", "0F00:BEEDRILL", "1000:PIDGEY", "1100:PIDGEOTTO", "1200:PIDGEOT", "1300:RATTATA", "1400:RATICATE", "1500:SPEAROW", "1600:FEAROW", "1700:EKANS", "1800:ARBOK", "1900:PIKACHU", "1A00:RAICHU", "1B00:SANDSHREW", "1C00:SANDSLASH", "1D00:NIDORAN (FEMALE)", "1E00:NIDORINA", "1F00:NIDOQUEEN", "2000:NIDORAN (MALE)", "2100:NIDORINO", "2200:NIDOKING", "2300:CLEFAIRY", "2400:CLEFABLE", "2500:VULPIX", "2600:NINETALES", "2700:JIGGLYPUFF", "2800:WIGGLYTUFF", "2900:ZUBAT", "2A00:GOLBAT", "2B00:ODDISH", "2C00:GLOOM", "2D00:VILEPLUME", "2E00:PARAS", "2F00:PARASECT", "3000:VENONAT", "3100:VENOMOTH", "3200:DIGLETT", "3300:DUGTRIO", "3400:MEOWTH", "3500:PERSIAN", "3600:PSYDUCK", "3700:GOLDUCK", "3800:MANKEY", "3900:PRIMEAPE", "3A00:GROWLITHE", "3B00:ARCANINE", "3C00:POLIWAG", "3D00:POLIWHIRL", "3E00:POLIWRATH", "3F00:ABRA", "4000:KADABRA", "4100:ALAKAZAM", "4200:MACHOP", "4300:MACHOKE", "4400:MACHAMP", "4500:BELLSPROUT", "4600:WEEPINBELL", "4700:VICTREEBELL", "4800:TENTACOOL", "4900:TENTACRUEL", "4A00:GEODUDE", "4B00:GRAVELER", "4C00:GOLEM", "4D00:PONYTA", "4E00:RAPIDASH", "4F00:SLOWPOKE", "5000:SLOWBRO", "5100:MAGNEMITE", "5200:MAGNETON", "5300:FARFETCH'D", "5400:DODUO", "5500:DODRIO", "5600:SEEL", "5700:DEWGONG", "5800:GRIMER", "5900:MUK", "5A00:SHELLDER", "5B00:CLOYSTER", "5C00:GASTLY", "5D00:HAUNTER", "5E00:GENGAR", "5F00:ONIX", "6000:DROWZEE", "6100:HYPNO", "6200:KRABBY", "6300:KINGLER", "6400:VOLTORB", "6500:ELECTRODE", "6600:EXEGGCUTE", "6700:EXEGGUTOR", "6800:CUBONE", "6900:MAROWAK", "6A00:HITMONLEEE", "6B00:HITMONCHAN", "6C00:LICKITUNG", "6D00:KOFFING", "6E00:WEEZING", "6F00:RHYHORN", "7000:RHYDON", "7100:CHANSEY", "7200:TANGELA", "7300:KANGASKHAN", "7400:HORSEA", "7500:SEADRA", "7600:GOLDEEN", "7700:SEAKING", "7800:STARYU", "7900:STARMIE", "7A00:MR. MIME", "7B00:SCYTHER", "7C00:JYNX", "7D00:ELECTABUZZ", "7E00:MAGMAR", "7F00:PINSIR", "8000:TAUROS", "8100:MAGIKARP", "8200:GYARADOS", "8300:LAPRAS", "8400:DITTO", "8500:EEVEE", "8600:VAPOREON", "8700:JOLTEON", "8800:FLAREON", "8900:PORYGON", "8A00:OMANYTE", "8B00:OMASTAR", "8C00:KABUTO", "8D00:KABUTOPS", "8E00:AERODACTYL", "8F00:SNORLAX", "9000:ARTICUNO", "9100:ZAPDOS", "9200:MOLTRES", "9300:DRATINI", "9400:DRAGONAIR", "9500:DRAGONITE", "9600:MEWTWO", "9700:MEW", "9800:CHIKORITA", "9900:BAYLEEF", "9A00:MEGANIUM", "9B00:CYNDAQUIL", "9C00:QUILAVA", "9D00:TYPLOSION", "9E00:TOTODILE", "9F00:CROCONAW", "A000:FERALIGATR", "A100:SENTRET", "A200:FURRET", "A300:HOOTHOOT", "A400:NOCTOWL", "A500:LEDYBA", "A600:LEDIAN", "A700:SPINARAK", "A800:ARIADOS", "A900:CROBAT", "AA00:CHINCHOU", "AB00:LANTURN", "AC00:PICHU", "AD00:CLEFFA", "AE00:IGGLYBUFF", "AF00:TOGEPI", "B000:TOGETIC", "B100:NATU", "B200:XATU", "B300:MAREEP", "B400:FLAAFFY", "B500:AMPHAROS", "B600:BELLOSSOM", "B700:MARRILL", "B800:AZUMARILL", "B900:SUDOWOODO", "BA00:POLITOED", "BB00:HOPPIP", "BC00:SKI PLOOM", "BD00:JUMPLUFF", "BE00:AIPOM", "BF00:SUNKERN", "C000:SUNFLORA", "C100:YANMA", "C200:WOOPER", "C300:QUAGSIRE", "C400:ESPEON", "C500:UMBREON", "C600:MURKROW", "C700:SLOWKING", "C800:MISDREAVUS", "C900:UNOWN", "CA00:WOBBUFFET", "CB00:GIRAFARIG", "CC00:PINECO", "CD00:FORRETRESS", "CE00:DUNSPARCE", "CF00:GLIGAR", "D000:STEELIX", "D100:SNUBBULL", "D200:GRANBULL", "D300:QWILFISH", "D400:SCIZOR", "D500:SHUCKLE", "D600:HERACROSS", "D700:SNEASEL", "D800:TEDDIURSA", "D900:URSARING", "DA00:SLUGMA", "DB00:MAGCARGO", "DC00:SWINUB", "DD00:PILOSWINE", "DE00:CORSOLA", "DF00:REMORAID", "E000:OCTILLERY", "E100:DELIBIRD", "E200:MANTINE", "E300:SKARMORY", "E400:HOUNDOUR", "E500:DOUNDOOM", "E600:KINGDRA", "E700:PHANPY", "E800:DONPHAN", "E900:PORYGON2", "EA00:STANTLER", "EB00:SMEARGLE", "EC00:TYROGUE", "ED00:HITMONTOP", "EE00:SMOOCHUM", "EF00:ELEKID", "F000:MAGBY", "F100:MILTANK", "F200:BLISSEY", "F300:RAIKOU", "F400:ENTEI", "F500:SUICINE", "F600:LARVITAR", "F700:PUPITAR", "F800:TYRANITAR", "F900:LUGIA", "FA00:HO-OH", "FB00:CELEBI", "1501:TREECKO", "1601:GROVYLE", "1701:SCEPTILE", "1801:TORCHIC", "1901:COMBUSKEN", "1A01:BLAZIKEN", "1B01:MUDKIP", "1C01:MARSHTOMP", "1D01:SWAMPERT", "1E01:POOCHYENA", "1F01:MIGHTYENA", "2001:ZIGZAGOON", "2101:LINOONE", "2201:WURMPLE", "2301:SILCOON", "2401:BEAUTIFLY", "2501:CASCOON", "2601:DUSTOX", "2701:LOTAD", "2801:LOMBRE", "2901:LUDICOLO", "2A01:SEEDOT", "2B01:NUZLEAF", "2C01:SHIFTRY", "2D01:NINCADA", "2E01:NINJASK", "2F01:SHEDINJA", "3001:TAILLOW", "3101:SWELLOW", "3201:SHROOMISH", "3301:BRELOOM", "3401:SPINDA", "3501:WINGULL", "3601:PELIPPER", "3701:SURSKIT", "3801:MASQUERAIN", "3901:WAILMER", "3A01:WAILORD", "3B01:SKITTY", "3C01:DELCATTY", "3D01:KECLEON", "3E01:BALTOY", "3F01:CLAYDOL", "4001:NOSEPASS", "4101:TORKOAL", "4201:SABLEYE", "4301:BARBOACH", "4401:WHISCASH", "4501:LUVDISC", "4601:CORPHISH", "4701:CRAWDAUNT", "4801:FEEBAS", "4901:MILOTIC", "4A01:CARVANHA", "4B01:SHARPEDO", "4C01:TRAPINCH", "4D01:VIBRAVA", "4E01:FLYGON", "4F01:MAKUHITA", "5001:HARIYAMA", "5101:ELECTRIKE", "5201:MANECTRIC", "5301:NUMEL", "5401:CAMERUPT", "5501:SPHEAL", "5601:SEALEO", "5701:WALREIN", "5801:CACNEA", "5901:CACTURNE", "5A01:SNORUNT", "5B01:GLALIE", "5C01:LUNATONE", "5D01:SOLROCK", "5E01:AZURILL", "5F01:SPOINK", "6001:GRUMPIG", "6101:PLUSLE", "6201:MINUN", "6301:MAWILE", "6401:MEDITITE", "6501:MEDICHAM", "6601:SWABLU", "6701:ALTARIA", "6801:WYNAUT", "6901:DUSKULL", "6A01:DUSCLOPS", "6B01:ROSELIA", "6C01:SLAKOTH", "6D01:VIGOROTH", "6E01:SLAKING", "6F01:GULPIN", "7001:SWALOT", "7101:TROPIUS", "7201:WHISMUR", "7301:LOUDRED", "7401:EXPLOUD", "7501:CLAMPERL", "7601:HUNTAIL", "7701:GOREBYSS", "7801:ABSOL", "7901:SHUPPET", "7A01:BANNETE", "7B01:SEVIPER", "7C01:ZANGOOSE", "7D01:RELICANTH", "7E01:ARON", "7F01:LAIRON", "8001:AGGRON", "8101:CASTFORM", "8201:VOLBEAT", "8301:ILLUMISE", "8401:LILEEP", "8501:CRADILY", "8601:ANORITH", "8701:ARMALDO", "8801:RALTS", "8901:KIRLIA", "8A01:GARDEVOIR", "8B01:BAGON", "8C01:SHELGON", "8D01:SALAMENCE", "8E01:BELDUM", "8F01:METANG", "9001:METAGROSS", "9101:REGI ROCK", "9201:REGICE", "9301:REGI STEEL", "9401:KYOGRE", "9501:GROUDON", "9601:RAYQUAZA", "9701:LATIAS", "9801:LATIOS", "9901:JIRACHI", "9A01:DEOXYS", "9B01:CHIMECHO"}
Dim gloBytes As String()
Dim gloGame As String
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim o As New OpenFileDialog
o.Filter = "GBA ROM Files (*.gba)|*.gba"
Dim dr As DialogResult = o.ShowDialog
Dim path As String
If dr = Windows.Forms.DialogResult.OK Then
path = o.FileName
Else
MsgBox("FATAL ERROR: 0xA")
Me.Close()
End If
Dim T As New Threading.Thread(Sub() LoadFile(path))
T.IsBackground = True : T.Start()
End Sub
Private Function Hex2Bin(hex As String) As Byte()
If (hex Is Nothing) OrElse (hex.Length < 1) Then
Return New Byte(-1) {}
End If
Dim num As Integer = hex.Length / 2
Dim buffer As Byte() = New Byte(num - 1) {}
num *= 2
For i As Integer = 0 To num - 1
Dim num3 As Integer = Integer.Parse(hex.Substring(i, 2), NumberStyles.HexNumber)
buffer(i / 2) = CByte(num3)
i += 1
Next
Return buffer
End Function
Public Sub LoadFile(ByVal place As String)
Invoke(New MethodInvoker(Sub() Button1.Enabled = False))
Invoke(New MethodInvoker(Sub() Button1.Text = "Working..."))
gloBytes = String.Join(" ", IO.File.ReadAllBytes(place).Select(Function(b) b.ToString("X2")).ToArray()).Split(" ")
Dim game As String = ""
If gloBytes(168) = "52" Then
game = "Ruby"
gloGame = "Ruby"
ElseIf gloBytes(168) = "45" Then
game = "Emerald"
gloGame = "Emerald"
ElseIf gloBytes(168) = "53" Then
game = "Sapphire"
gloGame = "Sapphire"
Else
MsgBox("FATAL ERROR: 0x1")
Me.Close()
End If
Invoke(New MethodInvoker(Sub() Button1.Text = "Loaded Pokemon " & game & "!"))
Dim T As New Threading.Thread(Sub() changeForm())
T.IsBackground = True : T.Start()
For i = 0 To 385
Select Case game
Case "Emerald"
If gloBytes(5971448) & gloBytes(5971449) = x(i).Split(":")(0) Then
Invoke(New MethodInvoker(Sub() ComboBox1.SelectedIndex = i))
End If
If gloBytes(5971450) & gloBytes(5971451) = x(i).Split(":")(0) Then
Invoke(New MethodInvoker(Sub() ComboBox2.SelectedIndex = i))
End If
If gloBytes(5971452) & gloBytes(5971453) = x(i).Split(":")(0) Then
Invoke(New MethodInvoker(Sub() ComboBox3.SelectedIndex = i))
End If
Case "Ruby"
If gloBytes(4159172) & gloBytes(4159173) = x(i).Split(":")(0) Then
Invoke(New MethodInvoker(Sub() ComboBox1.SelectedIndex = i))
End If
If gloBytes(4159174) & gloBytes(4159175) = x(i).Split(":")(0) Then
Invoke(New MethodInvoker(Sub() ComboBox2.SelectedIndex = i))
End If
If gloBytes(4159176) & gloBytes(4159177) = x(i).Split(":")(0) Then
Invoke(New MethodInvoker(Sub() ComboBox3.SelectedIndex = i))
End If
Case "Sapphire"
If gloBytes(4159260) & gloBytes(4159261) = x(i).Split(":")(0) Then
Invoke(New MethodInvoker(Sub() ComboBox1.SelectedIndex = i))
End If
If gloBytes(4159262) & gloBytes(4159263) = x(i).Split(":")(0) Then
Invoke(New MethodInvoker(Sub() ComboBox2.SelectedIndex = i))
End If
If gloBytes(4159264) & gloBytes(4159265) = x(i).Split(":")(0) Then
Invoke(New MethodInvoker(Sub() ComboBox3.SelectedIndex = i))
End If
Case Else
MsgBox("FATAL ERROR: 0x1")
Me.Close()
End Select
Next
End Sub
Public Shared Function ConvertHexStringToByteArray(hexString As String) As Byte()
If hexString.Length Mod 2 <> 0 Then
Throw New ArgumentException([String].Format(CultureInfo.InvariantCulture, "The binary key cannot have an odd number of digits: {0}", hexString))
End If
Dim HexAsBytes As Byte() = New Byte(hexString.Length / 2 - 1) {}
For index As Integer = 0 To HexAsBytes.Length - 1
Dim byteValue As String = hexString.Substring(index * 2, 2)
HexAsBytes(index) = Byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture)
Next
Return HexAsBytes
End Function
Public Sub changeForm()
Invoke(New MethodInvoker(Sub() pSub()))
End Sub
Public Sub pSub()
For i = 80 To 198 Step 2
Dim x As Integer = Me.Location.Y - 1
Me.Height = i
Me.Location = New Point(Me.Location.X, x)
Threading.Thread.Sleep(1)
Next
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For i = 0 To 385
Dim cur As String = x(i)
cur = cur.Split(":")(1)
ComboBox1.Items.Add(cur)
ComboBox2.Items.Add(cur)
ComboBox3.Items.Add(cur)
Next
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Select Case gloGame
Case "Emerald"
gloBytes(5971448) = x(ComboBox1.SelectedIndex).ToString.Split(":")(0).Substring(0, 2)
gloBytes(5971449) = x(ComboBox1.SelectedIndex).ToString.Split(":")(0).Substring(2, 2)
gloBytes(5971450) = x(ComboBox2.SelectedIndex).ToString.Split(":")(0).Substring(0, 2)
gloBytes(5971451) = x(ComboBox2.SelectedIndex).ToString.Split(":")(0).Substring(2, 2)
gloBytes(5971452) = x(ComboBox3.SelectedIndex).ToString.Split(":")(0).Substring(0, 2)
gloBytes(5971453) = x(ComboBox3.SelectedIndex).ToString.Split(":")(0).Substring(2, 2)
Dim tHex As String = ""
Dim g As New StringBuilder
For i = 0 To gloBytes.Length - 1
g.Append(gloBytes(i))
Next
tHex = g.ToString()
Dim b As Byte() = ConvertHexStringToByteArray(tHex)
Dim d As DateTime = DateTime.Now
IO.File.WriteAllBytes(CurDir() & "\Pokemon-Emerald-" & d.Millisecond & ".gba", b)
Button2.Text = "Saved!"
Button2.Enabled = False
Threading.Thread.Sleep(3000)
Me.Close()
Case "Ruby"
gloBytes(4159172) = x(ComboBox1.SelectedIndex).ToString.Split(":")(0).Substring(0, 2)
gloBytes(4159173) = x(ComboBox1.SelectedIndex).ToString.Split(":")(0).Substring(2, 2)
gloBytes(4159174) = x(ComboBox2.SelectedIndex).ToString.Split(":")(0).Substring(0, 2)
gloBytes(4159175) = x(ComboBox2.SelectedIndex).ToString.Split(":")(0).Substring(2, 2)
gloBytes(4159176) = x(ComboBox3.SelectedIndex).ToString.Split(":")(0).Substring(0, 2)
gloBytes(4159177) = x(ComboBox3.SelectedIndex).ToString.Split(":")(0).Substring(2, 2)
Dim tHex As String = ""
Dim g As New StringBuilder
For i = 0 To gloBytes.Length - 1
g.Append(gloBytes(i))
Next
tHex = g.ToString()
Dim b As Byte() = ConvertHexStringToByteArray(tHex)
Dim d As DateTime = DateTime.Now
IO.File.WriteAllBytes(CurDir() & "\Pokemon-Ruby-" & d.Millisecond & ".gba", b)
Button2.Text = "Saved!"
Button2.Enabled = False
Threading.Thread.Sleep(3000)
Me.Close()
Case "Sapphire"
gloBytes(4159260) = x(ComboBox1.SelectedIndex).ToString.Split(":")(0).Substring(0, 2)
gloBytes(4159261) = x(ComboBox1.SelectedIndex).ToString.Split(":")(0).Substring(2, 2)
gloBytes(4159262) = x(ComboBox2.SelectedIndex).ToString.Split(":")(0).Substring(0, 2)
gloBytes(4159263) = x(ComboBox2.SelectedIndex).ToString.Split(":")(0).Substring(2, 2)
gloBytes(4159264) = x(ComboBox3.SelectedIndex).ToString.Split(":")(0).Substring(0, 2)
gloBytes(4159265) = x(ComboBox3.SelectedIndex).ToString.Split(":")(0).Substring(2, 2)
Dim tHex As String = ""
Dim g As New StringBuilder
For i = 0 To gloBytes.Length - 1
g.Append(gloBytes(i))
Next
tHex = g.ToString()
Dim b As Byte() = ConvertHexStringToByteArray(tHex)
Dim d As DateTime = DateTime.Now
IO.File.WriteAllBytes(CurDir() & "\Pokemon-Sapphire-" & d.Millisecond & ".gba", b)
Button2.Text = "Saved!"
Button2.Enabled = False
Threading.Thread.Sleep(3000)
Me.Close()
End Select
End Sub
End Class




![[+]](https://sinister.ly/images/modern/collapse_collapsed.png)