PokemonGameEditor/GBAPokemonGameEditor/WichuRomFunctions.vb
Gamer2020 ae1f427215 Massive update!
I was away for a month or so without internet. In that time I continued
to work on PGE. There are a lot of new things in this version.

The Attack adder has been updated. I've completed Jambo51's move table
hack for Fire Red and made it so the Attack adder installs it. I still
have yet to port the hack to Emerald.

The Pokemon adder works for English Fire Red. I made it add Pokemon the
same way that it's done in DoesntKnowHowToPlay's tutorial in order to
remain consistent with what others may have already done. If any
problems occur with the Pokemon adder please let me know. Unlike G3HS,
cries and other things are expanded correctly by PGE. I advise not using
G3HS to add more Pokemon.

When an offset is missing from the ini, PGE will now dump text to a file
named errors.txt letting you know what offset is missing and for what
ROM. I may expand on this in the future.

Improved importing and exporting of data. Attacks, Abilities, and
Pokemon can be exported and imported as inis. It is now handled better
than in older versions.

I fixed the Pokedex data editor because it seems it wasn't loading some
data properly.

I've added a Pokedex tab to the Pokemon Editor. Even though I feel they
should be seperate I mainly added it because I want Pokedex data to be
included when you export Pokemon Data.

I made it so that the Pokedex tab shows you how big the sprites will be
in the size compare. I will make it show where the sprites will be
onscreen once I figure out the formula for it. Bulbapedia is wrong when
it comes to the Pokedex data.

Added the item use anitmation (FR/LG) bytes to the Pokemon Editor.

Added editing of the in battle sprite positions. Has the preview from
Advance Series.  (Loading of all the Pokemon data seems slow now.
Eventually I will have to come back and optimize things.)

Pokemon sprites can be imported and exported. The format is the same as
Advance Series. The importing and exporting of the animations from
Emerald are handled better than in Advance Series.

Pokemon Icons can now be imported and exported. Advance Series
compatable as well.

Pokemon Footprints can be imported and exported.

Other Miscellaneous fixes and additions.
2016-04-01 21:23:11 -04:00

394 lines
17 KiB
VB.net

Imports Microsoft.VisualBasic
Imports Microsoft.VisualBasic.CompilerServices
Imports System
Imports System.IO
Imports System.Runtime.CompilerServices
Imports System.Text
'The following functions were extracted from A-series. All credit goes to it's programmer Wichu!
Module WichuRomFunctions
Public Function CompressLz77(ByRef data As Byte()) As Collection
Dim position As Integer = 0
Dim length As Integer = data.Length
Dim collection3 As New Collection
Dim collection As New Collection
collection.Add(&H10, Nothing, Nothing, Nothing)
collection.Add((length And &HFF), Nothing, Nothing, Nothing)
collection.Add(((length >> 8) And &HFF), Nothing, Nothing, Nothing)
collection.Add(((length >> &H10) And &HFF), Nothing, Nothing, Nothing)
Do While (position < length)
Dim item As Byte = 0
collection3.Clear()
Dim num4 As Integer = 0
Do
Dim numArray As Integer() = Lz77Search(data, position)
If (numArray(0) > 2) Then
collection3.Add(((((numArray(0) - 3) And 15) << 4) Or (((numArray(1) - 1) >> 8) And 15)), Nothing, Nothing, Nothing)
collection3.Add(((numArray(1) - 1) And &HFF), Nothing, Nothing, Nothing)
position = (position + numArray(0))
item = CByte((item Or (CInt(1) << (7 - num4))))
Else
If (numArray(0) < 0) Then
Exit Do
End If
collection3.Add(data(position), Nothing, Nothing, Nothing)
position += 1
End If
num4 += 1
Loop While (num4 <= 7)
collection.Add(item, Nothing, Nothing, Nothing)
Dim count As Integer = collection3.Count
Dim i As Integer = 1
Do While (i <= count)
collection.Add(RuntimeHelpers.GetObjectValue(collection3.Item(i)), Nothing, Nothing, Nothing)
i += 1
Loop
Loop
Return collection
End Function
Public Function CompressLz77String(ByRef srcString As String) As String
Dim length As Integer = 1
Dim num3 As UInt32 = Len(CStr(srcString))
Dim str2 As String = (ChrW(16) & Conversions.ToString(Strings.Chr(CInt((num3 And &HFF)))) & Conversions.ToString(Strings.Chr(CInt(((num3 >> 8) And &HFF)))) & Conversions.ToString(Strings.Chr(CInt(((num3 >> &H10) And &HFF)))))
Do While (length <= num3)
Dim charCode As Byte = 0
Dim str3 As String = ""
Dim num5 As Integer = 0
Do
If (length > num3) Then
Exit Do
End If
Dim num6 As Integer = &H12
Dim num4 As Integer = Strings.InStr(1, Strings.Left(srcString, length), Strings.Mid(srcString, length, num6), CompareMethod.Binary)
If ((num4 > 0) And ((length + num6) <= num3)) Then
num4 = (length - num4)
str3 = (str3 & Conversions.ToString(Strings.Chr(((((num6 - 3) And 15) << 4) + (((num4 - 1) >> 8) And 15)))) & Conversions.ToString(Strings.Chr(((num4 - 1) And &HFF))))
length = (length + num6)
charCode = CByte((charCode Or (CInt(1) << (7 - num5))))
Else
str3 = (str3 & Strings.Mid(srcString, length, 1))
length += 1
End If
num5 += 1
Loop While (num5 <= 7)
str2 = (str2 & Conversions.ToString(Strings.Chr(charCode)) & str3)
Loop
Do While ((str2.Length Mod 4) > 0)
str2 = (str2 & ChrW(0))
Loop
Return str2
End Function
Public Function ConvertByteArrayToString(ByRef ary As Byte()) As String
Dim str2 As String = ""
Dim num2 As Integer = (ary.Length - 1)
Dim i As Integer = 0
Do While (i <= num2)
str2 = (str2 & Conversions.ToString(Strings.Chr(ary(i))))
i += 1
Loop
Return str2
End Function
Public Function ConvertCollectionToByteArray(ByRef col As Collection) As Byte()
Dim buffer2 As Byte() = New Byte(((col.Count - 1) + 1) - 1) {}
Dim count As Integer = col.Count
Dim i As Integer = 1
Do While (i <= count)
buffer2((i - 1)) = Conversions.ToByte(col.Item(i))
i += 1
Loop
Return buffer2
End Function
Public Function ConvertStringToByteArray(ByRef str As String) As Byte()
Dim buffer2 As Byte() = New Byte(((str.Length - 1) + 1) - 1) {}
Dim num2 As Integer = (str.Length - 1)
Dim i As Integer = 0
Do While (i <= num2)
buffer2(i) = CByte(Strings.Asc(Strings.Mid(str, (i + 1), 1)))
i += 1
Loop
Return buffer2
End Function
Public Function FindNextFreeSpace(ByRef Stream As FileStream, ByVal length As Integer) As Integer
Do While (Stream.Position < Stream.Length)
Dim num As Byte = CByte(Stream.ReadByte)
If ((num = 0) Or (num = &HFF)) Then
Dim num3 As Integer = 1
Dim num4 As Integer = CInt((Stream.Position - 1))
Do While ((num3 < length) And (Stream.Position < Stream.Length))
num = CByte(Stream.ReadByte)
If ((num <> &HFF) And (num <> 0)) Then
Exit Do
End If
num3 += 1
Loop
If (num3 = length) Then
Return num4
End If
End If
Do While ((Stream.Position Mod 4) > 0)
Stream.ReadByte()
Loop
Loop
Return -1
End Function
Public Function FromRSChar(ByVal ch As Byte) As Object
Dim array As Byte() = New Byte() {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &HFE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &HAB, 0, 0, &HB7, &H5B, 0, 180, &H5C, &H5D, &HB9, &H2E, &HB8, &HAE, &HAD, &HBA, &HA1, &HA2, &HA3, &HA4, &HA5, &HA6, &HA7, &HA8, &HA9, 170, 240, &H36, 0, &H35, 0, &HAC, 0, &HBB, &HBC, &HBD, 190, &HBF, &HC0, &HC1, &HC2, &HC3, &HC4, &HC5, &HC6, &HC7, 200, &HC9, &HCA, &HCB, &HCC, &HCD, &HCE, &HCF, &HD0, &HD1, 210, &HD3, &HD4, 0, 0, 0, 0, 0, &HB3, &HD5, &HD6, &HD7, &HD8, &HD9, &HDA, &HDB, 220, &HDD, &HDE, &HDF, &HE0, &HE1, &HE2, &HE3, &HE4, &HE5, 230, &HE7, &HE8, &HE9, &HEA, &HEB, &HEC, &HED, &HEE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &H52, 0, 0, 0, 0, 0, 0, 0, 0, &H2B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &H2A, 0, 0, 0, 0, &H51, 1, 2, 0, 0, &HF1, 0, 0, 4, 5, 6, 7, 8, 9, 90, 11, 12, 0, 20, 13, 14, 15, 0, &HF2, 0, 0, &H11, &H12, &H13, &HF3, 0, 0, &H15, &H16, &H17, &H68, 0, &HF4, 0, 0, &H19, &H1A, &H1B, &H1C, &H1D, 30, &H6F, &H20, &H21, 0, &H29, &H22, &H23, &H24, 0, &HF5, 0, 0, &H26, &H27, 40, &HF6, 0, 0, 0, 0}
'Dim index As Integer = array.IndexOf(Of Byte)(array, ch)
Dim index As Integer = array.IndexOf(array, ch)
If (index = -1) Then
index = 0
End If
Return Strings.Chr(index)
End Function
Public Function GetDoublePointerTable(ByRef Stream As FileStream, ByVal length As Integer) As UInt32()
Dim numArray2 As UInt32() = New UInt32(((length - 1) + 1) - 1) {}
Dim num3 As Integer = (length - 1)
Dim i As Integer = 0
Do While (i <= num3)
Dim streamvar As Stream = Stream
streamvar = DirectCast(streamvar, FileStream)
Dim num As UInt32 = Conversions.ToUInteger(GetDWord(streamvar))
If (num > &H8000000) Then
numArray2(i) = (num - &H8000000)
streamvar.Seek(4, SeekOrigin.Current)
End If
i += 1
Loop
Return numArray2
End Function
Public Function GetDWord(ByRef streaminput As Stream) As Object
Dim num As UInt32 = streaminput.ReadByte
num = (num Or (Convert.ToUInt32(streaminput.ReadByte) << 8))
num = (num Or (Convert.ToUInt32(streaminput.ReadByte) << &H10))
Return (num Or (Convert.ToUInt32(streaminput.ReadByte) << &H18))
End Function
Public Function GetGameCode(ByRef filename As String) As String
Dim stream As New FileStream(filename, FileMode.Open)
Dim reader As New StreamReader(stream, Encoding.ASCII)
Dim str As String = ""
stream.Seek(&HAC, SeekOrigin.Begin)
Dim num As Integer = 0
Do
str = (str & Conversions.ToString(Strings.Chr(reader.Read)))
num += 1
Loop While (num <= 3)
reader.Close()
stream.Close()
Return str
End Function
Public Function GetLz77UncompressedLength(ByRef stream As FileStream) As Integer
Dim num2 As Integer = 0
If (stream.ReadByte <> &H10) Then
Interaction.MsgBox("Data is not LZ77 compressed!", MsgBoxStyle.ApplicationModal, Nothing)
Return 0
End If
num2 = (stream.ReadByte + (stream.ReadByte << 8))
Return (num2 + (stream.ReadByte << &H10))
End Function
Public Function GetSinglePointerTable(ByRef streaminput As FileStream, ByVal length As Integer) As UInt32()
Dim numArray2 As UInt32() = New UInt32(((length - 1) + 1) - 1) {}
Dim num3 As Integer = (length - 1)
Dim i As Integer = 0
Do While (i <= num3)
Dim stream As Stream = streaminput
stream = DirectCast(stream, FileStream)
Dim num As UInt32 = Conversions.ToUInteger(GetDWord(stream))
If (num > &H8000000) Then
numArray2(i) = (num - (&H8000000))
End If
i += 1
Loop
Return numArray2
End Function
Public Function GetWord(ByRef stream As Stream) As Object
Dim num As UInt16 = CUShort(stream.ReadByte)
Return CUShort((num Or CUShort((Convert.ToUInt16(stream.ReadByte) << 8))))
End Function
Public Function LoadString(ByRef Stream As FileStream, ByVal length As Integer) As Object
Dim chArray As Char() = New Char(((length - 1) + 1) - 1) {}
Dim flag As Boolean = False
Dim num3 As Integer = (length - 1)
Dim i As Integer = 0
Do While (i <= num3)
Dim ch As Byte = CByte(Stream.ReadByte)
If Not flag Then
Select Case ch
Case &HFF
flag = True
Continue Do
Case 0
chArray(i) = "?"c
Continue Do
End Select
chArray(i) = Conversions.ToChar(FromRSChar(ch))
End If
i += 1
Loop
Return Convert.ToString(New String(chArray))
End Function
Public Function Lz77Search(ByRef data As Byte(), ByVal position As Integer) As Integer()
Dim length As Integer = data.Length
Dim numArray2 As Integer() = New Integer(2 - 1) {}
Dim collection As New Collection
If ((position < 3) Or ((length - position) < 3)) Then
numArray2(0) = 0
numArray2(1) = 0
Return numArray2
End If
If (position >= length) Then
numArray2(0) = -1
numArray2(1) = 0
Return numArray2
End If
Dim num4 As Integer = &H1000
If (num4 > position) Then
num4 = position
End If
Dim num6 As Integer = (num4 - 1)
Dim i As Integer = 0
Do While (i <= num6)
If (data(((position - i) - 1)) = data(position)) Then
collection.Add((i + 1), Nothing, Nothing, Nothing)
End If
i += 1
Loop
If (collection.Count = 0) Then
numArray2(0) = 0
numArray2(1) = 0
Return numArray2
End If
Dim left As Byte = 0
Dim flag As Boolean = False
Do While (left < &H12)
left = CByte((left + 1))
Dim j As Integer
For j = 0 To collection.Count - 1
If ((position + left) >= data.Length) Then
flag = True
ElseIf (data((position + left)) <> data(Conversions.ToInteger(Operators.AddObject(Operators.SubtractObject(position, collection.Item((j + 1))), Operators.ModObject(left, collection.Item((j + 1))))))) Then
If (collection.Count > 1) Then
collection.Remove(CInt((j + 1)))
j -= 1
Else
flag = True
End If
End If
If flag Then
Exit For
End If
Next j
If flag Then
Exit Do
End If
Loop
numArray2(0) = left
numArray2(1) = Conversions.ToInteger(collection.Item(1))
Return numArray2
End Function
Public Sub SetDWord(ByRef stream As Stream, ByVal dword As UInt32)
stream.WriteByte(CByte((dword And &HFF)))
stream.WriteByte(CByte(((dword >> 8) And &HFF)))
stream.WriteByte(CByte(((dword >> &H10) And &HFF)))
stream.WriteByte(CByte(((dword >> 0) And &HFF)))
End Sub
Public Sub SetOffset(ByRef stream As Stream, ByVal offset As UInt32)
stream.WriteByte(CByte((offset And &HFF)))
stream.WriteByte(CByte(((offset >> 8) And &HFF)))
stream.WriteByte(CByte(((offset >> &H10) And &HFF)))
stream.WriteByte(8)
End Sub
Public Sub SetWord(ByRef stream As Stream, ByVal word As UInt16)
stream.WriteByte(CByte((word And &HFF)))
stream.WriteByte(CByte((CUShort((word >> 8)) And &HFF)))
End Sub
Public Sub ToNextValidOffset(ByRef Stream As FileStream)
Do While ((Stream.Position Mod 4) > 0)
Stream.ReadByte()
Loop
End Sub
Public Function ToRSChar(ByVal [chr] As Char) As Object
Dim buffer As Byte() = New Byte() {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &HFE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &HAB, 0, 0, &HB7, &H5B, 0, 180, &H5C, &H5D, &HB9, &H2E, &HB8, &HAE, &HAD, &HBA, &HA1, &HA2, &HA3, &HA4, &HA5, &HA6, &HA7, &HA8, &HA9, 170, 240, &H36, 0, &H35, 0, &HAC, 0, &HBB, &HBC, &HBD, 190, &HBF, &HC0, &HC1, &HC2, &HC3, &HC4, &HC5, &HC6, &HC7, 200, &HC9, &HCA, &HCB, &HCC, &HCD, &HCE, &HCF, &HD0, &HD1, 210, &HD3, &HD4, 0, 0, 0, 0, 0, &HB3, &HD5, &HD6, &HD7, &HD8, &HD9, &HDA, &HDB, 220, &HDD, &HDE, &HDF, &HE0, &HE1, &HE2, &HE3, &HE4, &HE5, 230, &HE7, &HE8, &HE9, &HEA, &HEB, &HEC, &HED, &HEE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &H52, 0, 0, 0, 0, 0, 0, 0, 0, &H2B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &H2A, 0, 0, 0, 0, &H51, 1, 2, 0, 0, &HF1, 0, 0, 4, 5, 6, 7, 8, 9, 90, 11, 12, 0, 20, 13, 14, 15, 0, &HF2, 0, 0, &H11, &H12, &H13, &HF3, 0, 0, &H15, &H16, &H17, &H68, 0, &HF4, 0, 0, &H19, &H1A, &H1B, &H1C, &H1D, 30, &H6F, &H20, &H21, 0, &H29, &H22, &H23, &H24, 0, &HF5, 0, 0, &H26, &H27, 40, &HF6, 0, 0, 0, 0}
Return buffer(Strings.Asc([chr]))
End Function
Public Function UncompressLZ77(ByRef Stream As FileStream) As Byte()
Return UncompressLZ77(Stream, True)
End Function
Public Function UncompressLZ77(ByRef Stream As FileStream, ByVal message As Boolean) As Byte()
Dim num7 As UInt32
Dim array As Byte() = New Byte(0 - 1) {}
If (Stream.ReadByte <> &H10) Then
If message Then
Interaction.MsgBox("Data is not LZ77 compressed!", MsgBoxStyle.ApplicationModal, Nothing)
End If
Return array
End If
Dim num6 As UInt32 = Stream.ReadByte
num6 = (num6 + (Stream.ReadByte << 8))
num6 = (num6 + (Stream.ReadByte << &H10))
If (num6 > &H2404) Then
If message Then
Interaction.MsgBox("Invalid LZ77 offset", MsgBoxStyle.ApplicationModal, Nothing)
End If
Return array
End If
array.Resize(Of Byte)(array, CInt(num6))
Do While (num7 < num6)
Dim num3 As Byte = CByte(Stream.ReadByte)
Dim num8 As Integer = 0
Do
If ((num3 And &H80) > 0) Then
Dim num2 As UInt32 = Stream.ReadByte
Dim num5 As UInt32 = Stream.ReadByte
Dim num4 As UInt32 = ((((num2 << 8) + num5) And &HFFF) + CULng(1))
Dim num As UInt32 = (CULng(3) + ((num2 >> 4) And 15))
If (num4 > num7) Then
Return array
End If
Dim num10 As Long = (num - 1)
Dim i As Long = 0
Do While (i <= num10)
If ((num7 + i) >= num6) Then
Exit Do
End If
array(CInt((num7 + i))) = array(CInt(((num7 - num4) + (i Mod CULng(num4)))))
i = (i + 1)
Loop
num7 = (num7 + num)
Else
array(num7) = CByte(Stream.ReadByte)
num7 = (num7 + 1)
End If
If (num7 >= num6) Then
Return array
End If
num3 = CByte((num3 << 1))
num8 += 1
Loop While (num8 <= 7)
Loop
Return array
End Function
End Module