Dynamic-Pokemon-Expansion/scripts/data_extractor.py
2019-05-24 09:57:49 -04:00

195 lines
8.6 KiB
Python

#!/usr/bin/env python3
import os
############
#Options go here.
############
ROM_NAME = "BPRE0.gba" #the name of your rom
NumberOfPokemon = 440 #Change to total number of species in original rom
OutputFolder = os.getcwd() + "/extracted/"
SpeciesDefines = os.getcwd() + "/include/species.h"
############
#Code
############
def GeneralTableExtractor(dynamicOffset, definesDict, definesDict2, outputPath, tableType, tableName,
indexOffset, tableLengthName, startIndex, numEntries, entryLength, alignData):
output = open(outputPath, 'w')
startIndexName = ""
if startIndex != 0:
startIndexName = " - " + indexOffset
dataAlignment = 0
if alignData:
dataAlignment = GetLengthOfLongestValue(definesDict)
with open(ROM_NAME, 'rb') as binary_file:
#Load Dynamic Pointer to Table
binary_file.seek(dynamicOffset)
line = binary_file.read(3)
TablePointer = ExtractPointer(line)
output.write('#include "defines.h"\n\n')
output.write(tableType + ' ' + tableName + '[' + tableLengthName + startIndexName + '] =\n{\n')
for i in range(startIndex, numEntries):
binary_file.seek(TablePointer + ((i - startIndex) * entryLength))
byteList = binary_file.read(entryLength)
if i in definesDict:
output.write('\t[' + definesDict[i] + startIndexName + '] = ')
lenEntry = len(definesDict[i] + startIndexName)
else:
output.write('\t[' + str(i) + startIndexName + '] = ')
lenEntry = len(str(i) + startIndexName)
while lenEntry < dataAlignment: #Align Data
output.write(' ')
lenEntry += 1
data = ExtractPointer(byteList)
if definesDict2 is not False and data in definesDict2:
data = definesDict2[data]
else:
data = hex(data)
output.write(data + ',\n')
output.write('};\n')
output.close()
print("Success!")
def GeneralStructTableExtractor(dynamicOffset, definesDict, outputPath, tableType, tableName, tableLengthName,
numEntries, structLength, memberNames, memberLengths, memberDicts, useMemberNames,
loadDictDataFromIndex, offsetForForce):
assert(len(memberNames) == len(memberLengths) or not useMemberNames)
output = open(outputPath, 'w')
with open(ROM_NAME, 'rb') as binary_file:
#Load Dynamic Pointer to Table
binary_file.seek(dynamicOffset)
line = binary_file.read(3)
TablePointer = ExtractPointer(line)
output.write('#include "defines.h"\n\n')
output.write(tableType + ' ' + tableName + '[' + tableLengthName + '] =\n{\n')
for i in range(numEntries):
binary_file.seek(TablePointer + (i * structLength))
byteList = binary_file.read(structLength)
lenName = 0
if i in definesDict:
output.write('\t[' + definesDict[i] + '] =')
lenName = len(definesDict[i])
else:
output.write('\t[' + str(i) + '] =')
lenName = len(str(i))
if useMemberNames:
output.write('\n\t{\n')
else:
while lenName < 28: #Align structs
output.write(' ')
lenName += 1
output.write(' {')
for j in range(len(memberLengths)):
data = int(ExtractPointer(byteList[:memberLengths[j]]))
if memberDicts != [] and memberDicts[j] is not False:
if loadDictDataFromIndex:
if i in memberDicts[j]:
data = memberDicts[j][i]
else:
data = hex(data)
if offsetForForce > 0:
data += ' + ' + str(offsetForForce)
elif data in memberDicts[j]:
data = memberDicts[j][data]
else:
data = hex(data)
else:
data = hex(data)
if useMemberNames:
output.write('\t\t.' + memberNames[j] + ' = ' + str(data) + ',\n')
elif j + 1 < len(memberLengths):
output.write(str(data) + ', ')
else:
output.write(str(data))
byteList = byteList[memberLengths[j]:]
if i + 1 == numEntries: #Last iteration of loop
if useMemberNames:
output.write('\t},\n};\n')
else:
output.write('},\n};\n')
else:
if useMemberNames:
output.write('\t},\n')
else:
output.write('},\n')
output.close()
print("Success!")
def ExtractPointer(line):
offset = 0
for i in range(len(line)):
offset += (line[i] << (8 * i))
return offset
def DefinesDictMaker(definesFile):
definesDict = {}
with open(definesFile, 'r') as file:
for line in file:
if '#define ' in line:
linelist = line.split()
try:
definesDict[int(linelist[2])] = linelist[1]
except:
try:
definesDict[int(linelist[2], 16)] = linelist[1]
except:
pass
return definesDict
def GetLengthOfLongestValue(dicty):
maxim = ""
for key in dicty:
if len(dicty[key]) > len(maxim):
maxim = dicty[key]
return len(maxim)
#Code Execution Begins Here
try:
os.makedirs(OutputFolder)
except FileExistsError:
pass
SpeciesDict = DefinesDictMaker(SpeciesDefines)
GeneralStructTableExtractor(0x128, SpeciesDict, OutputFolder + "Front_Pic_Table.c", "const struct CompressedSpriteSheet", "gMonFrontPicTable", "NUM_SPECIES", NumberOfPokemon, 8, [], [4, 2, 2], [False, False, SpeciesDict], False, True, 0)
GeneralStructTableExtractor(0x12C, SpeciesDict, OutputFolder + "Back_Pic_Table.c", "const struct CompressedSpriteSheet", "gMonBackPicTable", "NUM_SPECIES", NumberOfPokemon, 8, [], [4, 2, 2], [False, False, SpeciesDict], False, True, 0)
GeneralStructTableExtractor(0x130, SpeciesDict, OutputFolder + "Palette_Table.c", "const struct CompressedSpritePalette", "gMonPaletteTable", "NUM_SPECIES", NumberOfPokemon, 8, [], [4, 2, 2], [False, SpeciesDict, False], False, True, 0)
GeneralStructTableExtractor(0x134, SpeciesDict, OutputFolder + "Shiny_Palette_Table.c", "const struct CompressedSpritePalette", "gMonShinyPaletteTable", "NUM_SPECIES", NumberOfPokemon, 8, [], [4, 2, 2], [False, SpeciesDict, False], False, True, 1500)
GeneralStructTableExtractor(0x11F4C, SpeciesDict, OutputFolder + "Front_Pic_Coords_Table.c", "const struct MonCoords", "gMonFrontPicCoords", "NUM_SPECIES", NumberOfPokemon, 4, ["size", "y_offset"], [1, 1], [], True, False, 0)
GeneralStructTableExtractor(0x74634, SpeciesDict, OutputFolder + "Back_Pic_Coords_Table.c", "const struct MonCoords", "gMonBackPicCoords", "NUM_SPECIES", NumberOfPokemon, 4, ["size", "y_offset"], [1, 1], [], True, False, 0)
GeneralTableExtractor(0x356F8, SpeciesDict, False, OutputFolder + "Enemy_Elevation_Table.c", "const u8", "gEnemyMonElevation", "", "NUM_SPECIES", 0, NumberOfPokemon, 1, False)
GeneralTableExtractor(0x138, SpeciesDict, False, OutputFolder + "Icon_Table.c", "const u32", "gMonIconTable", "", "NUM_SPECIES", 0, NumberOfPokemon, 4, False)
GeneralTableExtractor(0x13C, SpeciesDict, False, OutputFolder + "Icon_Palette_Table.c", "const u8", "gMonIconPaletteIndices", "", "NUM_SPECIES", 0, NumberOfPokemon, 1, False)
GeneralTableExtractor(0x105E14, SpeciesDict, False, OutputFolder + "Footprint_Table.c", "const u32", "gMonFootprintTable", "", "NUM_SPECIES", 0, NumberOfPokemon, 4, False)
GeneralStructTableExtractor(0x72114, SpeciesDict, OutputFolder + "Cry_Table.c", "const struct ToneData", "gCryTable", "NUM_SPECIES", NumberOfPokemon, 12, ["type", "key", "length", "pan_sweep", "wav", "attack", "decay", "sustain", "release"], [1, 1, 1, 1, 4, 1, 1, 1, 1], [], True, False, 0)
GeneralStructTableExtractor(0x72104, SpeciesDict, OutputFolder + "Cry_Table_2.c", "const struct ToneData", "gCryTable2", "NUM_SPECIES", NumberOfPokemon, 12, ["type", "key", "length", "pan_sweep", "wav", "attack", "decay", "sustain", "release"], [1, 1, 1, 1, 4, 1, 1, 1, 1], [], True, False, 0)