Finally fixed builder script and gba_db.bin
The generated gba_db.bin now works with open_agb_firm! With a ton of help from profi200, I finally figured out the issue. Turns out open_agb_firm uses a binary search algorithm to find the hash from the gba_db.bin file. After a ton of (probably unnecessary) trial and error, I fixed my script so that it sorts the entries in the way open_agb_firm expects, and boom, it works!
This commit is contained in:
parent
2d26f51d56
commit
355971c9a2
Binary file not shown.
|
@ -1,4 +1,4 @@
|
|||
# open_agb_firm gba_db.bin Builder v2.1
|
||||
# open_agb_firm gba_db.bin Builder v2.5
|
||||
# By HTV04
|
||||
#
|
||||
# This script parses MAME's gba.xml (found here: https://github.com/mamedev/mame/blob/master/hash/gba.xml) and converts it to a gba_db.bin file for open_agb_firm.
|
||||
|
@ -7,22 +7,49 @@
|
|||
# This script should work with any updates to MAME's gba.xml and the No-Intro DAT, unless something this script expects is changed.
|
||||
|
||||
import math
|
||||
import re
|
||||
# import sys
|
||||
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
# Use title, serial, SHA-1, size, and save type to generate gba_db entry as binary string
|
||||
def gbadbentry(title, serial, sha, size, savetype):
|
||||
entry = b''
|
||||
def gbadbentry(a, b, c, d, e):
|
||||
entry = []
|
||||
|
||||
entry += title.encode().ljust(200, b'\x00')[0:200]
|
||||
entry += serial.encode().ljust(4, b'\x00')[0:4]
|
||||
entry += bytes.fromhex(sha).ljust(20, b'\x00')[0:20]
|
||||
entry += (int(math.log(size, 2)) << 27 | savetype).to_bytes(4, 'little') # Save type is stored weirdly
|
||||
if len(c) != 40:
|
||||
c = '0000000000000000000000000000000000000000'
|
||||
cbytes = bytes.fromhex(c)
|
||||
|
||||
entry.append(int.from_bytes(cbytes[:8], 'little')) # Sorting key
|
||||
entry.append(a.encode().ljust(200, b'\x00')[:200])
|
||||
if len(b) != 4 or bool(re.search('[^A-Z0-9]', b)):
|
||||
entry.append(b'\x00\x00\x00\x00')
|
||||
else:
|
||||
entry.append(b.encode())
|
||||
entry.append(cbytes)
|
||||
entry.append((int(math.log(d, 2)) << 27 | e).to_bytes(4, 'little')) # Save type is stored weirdly
|
||||
|
||||
return entry
|
||||
|
||||
# Prepare gba_db.bin binary string from gba_db list.
|
||||
def preparegbadbbin(a):
|
||||
gbadbbin = b''
|
||||
|
||||
# Use sort key to sort the gba_db list and delete it from each entry
|
||||
a = sorted(a, key=lambda l:l[0])
|
||||
length = len(a)
|
||||
for i in range(length):
|
||||
a[i].pop(0)
|
||||
|
||||
# Compile gba_db binary
|
||||
for i in a:
|
||||
for j in i:
|
||||
gbadbbin += j
|
||||
|
||||
return gbadbbin
|
||||
|
||||
if __name__ == '__main__':
|
||||
gbadb = b''
|
||||
gbadb = []
|
||||
skipcount = 0
|
||||
count = 0
|
||||
addcount = 0
|
||||
|
@ -30,7 +57,10 @@ if __name__ == '__main__':
|
|||
gba = ET.parse('gba.xml').getroot() # MAME gba.xml
|
||||
nointro = ET.parse('gba.dat').getroot() # No-Intro GBA DAT
|
||||
|
||||
addentries = False # Determine whether to include additional entries
|
||||
# # Arguments
|
||||
# if sys.argv[1] == 'noaddentries': # Don't include additional entries
|
||||
# addentries = False
|
||||
addentries = False # Leave as False for now since no additional entries have been added yet
|
||||
|
||||
# Start adding entries
|
||||
for software in gba.findall('software'):
|
||||
|
@ -52,8 +82,8 @@ if __name__ == '__main__':
|
|||
|
||||
title = game.get('name')
|
||||
serial = rom.get('serial')
|
||||
if serial in (None, 'N/A'):
|
||||
serial = '\x00\x00\x00\x00' # If a serial can't be found, default to null bytes
|
||||
if serial == None:
|
||||
serial = ''
|
||||
size = int(rom.get('size'))
|
||||
|
||||
# If not in No-Intro DAT, skip entry
|
||||
|
@ -94,7 +124,7 @@ if __name__ == '__main__':
|
|||
continue
|
||||
|
||||
# Expand gba_db with entry
|
||||
gbadb += gbadbentry(title, serial, sha, size, savetype)
|
||||
gbadb.append(gbadbentry(title, serial, sha, size, savetype))
|
||||
|
||||
print('Added entry "' + software.find('description').text + '"')
|
||||
count += 1
|
||||
|
@ -102,23 +132,27 @@ if __name__ == '__main__':
|
|||
# Add additional entries
|
||||
if addentries == True:
|
||||
# Example entries for demonstration purposes (to do: replace with valid entries)
|
||||
gbadbentries = ([['AAAA - A', 'AAAA', 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', 0x1000000, 0],
|
||||
['BBBB - B', 'BBBB', 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', 0x1000000, 14],
|
||||
['CCCC - C', 'CCCC', 'CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC', 0x1000000, 15]])
|
||||
gbadbentries = ([['AAAA - A', 'AAAA', 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', 0x400000, 15],
|
||||
['BBBB - B', 'BBBB', 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', 0x400000, 15],
|
||||
['CCCC - C', 'CCCC', 'CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC', 0x400000, 15]])
|
||||
|
||||
print()
|
||||
|
||||
for title, serial, sha, size, savetype in gbadbentries:
|
||||
gbadb += gbadbentry(title, serial, sha, size, savetype)
|
||||
gbadb.append(gbadbentry(title, serial, sha, size, savetype))
|
||||
|
||||
print('Added additional entry "' + title + '"')
|
||||
addcount += 1
|
||||
|
||||
print('\nFinalizing...\n')
|
||||
|
||||
gbadbbin = preparegbadbbin(gbadb)
|
||||
|
||||
# Create and write to gba_db.bin
|
||||
with open('gba_db.bin', 'wb') as f:
|
||||
f.write(gbadb)
|
||||
f.write(gbadbbin)
|
||||
|
||||
if addentries == True:
|
||||
print('\n' + str(count) + ' entries added, ' + str(addcount) + ' additional entries added, ' + str(skipcount) + ' entries skipped')
|
||||
print(str(count) + ' entries added, ' + str(addcount) + ' additional entries added, ' + str(skipcount) + ' entries skipped')
|
||||
else:
|
||||
print('\n' + str(count) + ' entries added, ' + str(skipcount) + ' entries skipped')
|
||||
print(str(count) + ' entries added, ' + str(skipcount) + ' entries skipped')
|
||||
|
|
Loading…
Reference in New Issue