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:
Harrison 2021-02-28 22:09:01 -05:00 committed by profi200
parent 2d26f51d56
commit 355971c9a2
2 changed files with 53 additions and 19 deletions

Binary file not shown.

View File

@ -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')