Skip to content

Commit

Permalink
simplifications: structs with pad bytes, exceptions, += notation
Browse files Browse the repository at this point in the history
  • Loading branch information
patters-match committed May 3, 2023
1 parent cf8ff56 commit b3ae58f
Show file tree
Hide file tree
Showing 12 changed files with 248 additions and 260 deletions.
23 changes: 11 additions & 12 deletions cologne_compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
default_outputfile = "cologne-compilation.gba"
default_emubinary = "cologne.gba"
default_bios = "bios.bin" # recommended to use 'ColecoVision BIOS (1982) (No Title Delay Hack)'
header_struct_format = "<8I31sc" # https://docs.python.org/3/library/struct.html
header_struct_format = "<8I31sx" # https://docs.python.org/3/library/struct.html

# ROM header
#
Expand Down Expand Up @@ -123,25 +123,25 @@ def set_bit(value, n):
compilation = args.emubinary.read()

if args.splashscreen:
compilation = compilation + args.splashscreen.read()
compilation += args.splashscreen.read()

biosflag = 1
flags = 0
follow = 0 # sprite or address follow for 'Unscaled (Auto)' display mode
bios = args.bios.read()
bios = bios + b"\0" * ((4 - (len(bios)%4))%4)
bios += b"\0" * ((4 - (len(bios)%4))%4)
biosfilename = os.path.split(args.bios.name)[1]
biosheader = struct.pack(header_struct_format, EMUID, len(bios), flags, follow, biosflag, 0, 0, 0, biosfilename[:31].encode('ascii'), b"\0")
compilation = compilation + biosheader + bios
biosheader = struct.pack(header_struct_format, EMUID, len(bios), flags, follow, biosflag, 0, 0, 0, biosfilename[:31].encode('ascii'))
compilation += biosheader + bios

if args.bb:
biosflag = 0
flags = 0
follow = 0 # sprite or address follow for 'Unscaled (Auto)' display mode
empty = b"\xff" * 16384
emptyname = "-- Empty --"
emptyheader = struct.pack(header_struct_format, EMU_ID, len(empty), flags, follow, biosflag, 0, 0, 0, emptyname.encode('ascii'), b"\0")
compilation = compilation + emptyheader + empty
emptyheader = struct.pack(header_struct_format, EMU_ID, len(empty), flags, follow, biosflag, 0, 0, 0, emptyname.encode('ascii'))
compilation += emptyheader + empty

for item in args.romfile:

Expand All @@ -159,8 +159,7 @@ def set_bit(value, n):
flags = set_bit (flags, 0) # set PAL timing for EUR-only titles

else:
print("Error: unsupported filetype for compilation -", romfilename)
sys.exit(1)
raise Exception(f'unsupported filetype for compilation - {romfilename}')

if args.c:
romtitle = romtitle.split(" [")[0] # strip the square bracket parts of the name
Expand All @@ -169,9 +168,9 @@ def set_bit(value, n):
romtitle = romtitle[:31]

rom = item.read()
rom = rom + b"\0" * ((4 - (len(rom)%4))%4)
romheader = struct.pack(header_struct_format, EMUID, len(rom), flags, follow, biosflag, 0, 0, 0, romtitle.encode('ascii'), b"\0")
compilation = compilation + romheader + rom
rom += b"\0" * ((4 - (len(rom)%4))%4)
romheader = struct.pack(header_struct_format, EMUID, len(rom), flags, follow, biosflag, 0, 0, 0, romtitle.encode('ascii'))
compilation += romheader + rom

print (romtitle)

Expand Down
9 changes: 4 additions & 5 deletions goomba_compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def writefile(name, contents):
compilation = args.emubinary.read()

if args.splashscreen:
compilation = compilation + args.splashscreen.read()
compilation += args.splashscreen.read()

for item in args.romfile:
romfilename = os.path.split(item.name)[1]
Expand Down Expand Up @@ -127,16 +127,15 @@ def writefile(name, contents):
romarray[308:308+titlelength] = headername
rom = romarray

compilation = compilation + rom
compilation += rom
print('{:<17}{}'.format(outputtitle.rstrip("\x00"),romtype.strip(".")))
else:
print("Error: unsupported filetype for compilation -", romfilename)
sys.exit(1)
raise Exception(f'unsupported filetype for compilation - {romfilename}')

# on EZ-Flash IV, random data in PSRAM after Goomba compilation may be interpreted as GB roms without 264 null bytes of padding
# which can result in duplicate game list entries
# https://www.dwedit.org/dwedit_board/viewtopic.php?id=643
compilation = compilation + b"\0" * 264
compilation += b"\0" * 264

writefile(args.outputfile, compilation)

Expand Down
16 changes: 7 additions & 9 deletions hvca_compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
default_emubinpath = "bin"
default_bios = "disksys.rom" # must be 8KB
default_palette = "hvca.pal"
header_struct_format = "<I31sc3scI" # https://docs.python.org/3/library/struct.html
header_struct_format = "<I31sx3sxI" # https://docs.python.org/3/library/struct.html

# hvcamkfs file header
#
Expand Down Expand Up @@ -50,16 +50,15 @@ def appendfile(file, verbose):
name = name.split(" (")[0] # strip the bracket parts of the name
contents = file.read()
if ext.lower() == "nes" and contents[:4] != b'NES\x1a':
print("Error: NES ROMs must be headered")
sys.exit(1)
raise Exception('NES ROMs must be headered')
if ext.lower() == "fds" and contents[:4] != b'FDS\x1a':
# reconstruct missing FDS header which HVCA requires
num_disk_sides = int(len(contents)/65500).to_bytes(1, byteorder='little')
contents = b'FDS\x1a' + num_disk_sides + b"\0" * 11 + contents
size = len(contents)
contents = contents + b"\0" * ((4 - (len(contents)%4))%4) # 4 byte alignment
fileheader = struct.pack(header_struct_format, EMU_ID, name.encode('ascii'), b"\0", ext.encode('ascii'), b"\0", size)
compilation = compilation + fileheader + contents
contents += b"\0" * ((4 - (len(contents)%4))%4) # 4 byte alignment
fileheader = struct.pack(header_struct_format, EMU_ID, name.encode('ascii'), ext.encode('ascii'), size)
compilation += fileheader + contents
if verbose:
print('{:<32}{}'.format(name,ext))

Expand Down Expand Up @@ -184,8 +183,7 @@ def appendfile(file, verbose):
elif romfileext.lower() == ".cfg":
cfgfiles.append(item)
else:
print("Error: unsupported filetype for compilation -", romfilename)
sys.exit(1)
raise Exception(f'unsupported filetype for compilation - {romfilename}')

if fdsfiles:
appendfile(args.bios, args.v)
Expand All @@ -201,7 +199,7 @@ def appendfile(file, verbose):

# this does not appear to be needed, but it's here for consistency with merge.bat's use of the hvcamkfs -c option:
# -c Add END-MAGIC-NUM (FCA compatible)
compilation = compilation + EMU_END_MARKER.to_bytes(4, byteorder='little') + b"\0" * (EMU_HEADER - 4)
compilation += EMU_END_MARKER.to_bytes(4, byteorder='little') + b"\0" * (EMU_HEADER - 4)

writefile(args.outputfile, compilation)

Expand Down
21 changes: 10 additions & 11 deletions msxadvance_compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
default_outputfile = "msxadv-compilation.gba"
default_emubinary = "msxadva.gba"
default_bios = "bios.bin" # recommended to use 'MSX System v1.0 + MSX BASIC (1983)(Microsoft)[MSX.ROM]'
header_struct_format = "<8I31sc" # https://docs.python.org/3/library/struct.html
header_struct_format = "<8I31sx" # https://docs.python.org/3/library/struct.html

# ROM header
#
Expand Down Expand Up @@ -219,10 +219,10 @@ def detectmapper(romdata):
mapper = 0
follow = 0 # sprite or address follow for 'Unscaled (Auto)' display mode
bios = args.bios.read()
bios = bios + b"\0" * ((4 - (len(bios)%4))%4)
bios += b"\0" * ((4 - (len(bios)%4))%4)
biosfilename = os.path.split(args.bios.name)[1]
biosheader = struct.pack(header_struct_format, EMUID, len(bios), flags, follow, biosflag, mapper, 0, 0, biosfilename[:31].encode('ascii'), b"\0")
compilation = compilation + biosheader + bios
biosheader = struct.pack(header_struct_format, EMUID, len(bios), flags, follow, biosflag, mapper, 0, 0, biosfilename[:31].encode('ascii'))
compilation += biosheader + bios

if args.bb:
biosflag = 0
Expand All @@ -231,8 +231,8 @@ def detectmapper(romdata):
follow = 0 # sprite or address follow for 'Unscaled (Auto)' display mode
empty = b"\xff" * 16384
emptyname = "-- Empty --"
emptyheader = struct.pack(header_struct_format, EMU_ID, len(empty), flags, follow, biosflag, mapper, 0, 0, emptyname.encode('ascii'), b"\0")
compilation = compilation + emptyheader + empty
emptyheader = struct.pack(header_struct_format, EMU_ID, len(empty), flags, follow, biosflag, mapper, 0, 0, emptyname.encode('ascii'))
compilation += emptyheader + empty

for item in args.romfile:

Expand All @@ -246,7 +246,7 @@ def detectmapper(romdata):
romtype = os.path.splitext(romfilename)[1]
romtitle = os.path.splitext(romfilename)[0]
rom = item.read()
rom = rom + b"\0" * ((4 - (len(rom)%4))%4)
rom += b"\0" * ((4 - (len(rom)%4))%4)

if romtype.lower() == ".rom":

Expand All @@ -262,8 +262,7 @@ def detectmapper(romdata):
elif mappername == 'RTYPE': mapper = 5

else:
print("Error: unsupported filetype for compilation -", romfilename)
sys.exit(1)
raise Exception(f'unsupported filetype for compilation - {romfilename}')

if args.c:
romtitle = romtitle.split(" [")[0] # strip the square bracket parts of the name
Expand All @@ -277,8 +276,8 @@ def detectmapper(romdata):
else:
romtitle = romtitle[:31]

romheader = struct.pack(header_struct_format, EMUID, len(rom), flags, follow, biosflag, mapper, 0, 0, romtitle.encode('ascii'), b"\0")
compilation = compilation + romheader + rom
romheader = struct.pack(header_struct_format, EMUID, len(rom), flags, follow, biosflag, mapper, 0, 0, romtitle.encode('ascii'))
compilation += romheader + rom

print(romtitle.ljust(32), mappername)

Expand Down
21 changes: 10 additions & 11 deletions ngpgba_compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

default_outputfile = "ngpgba-compilation.gba"
default_emubinary = "NGPGBA.gba"
header_struct_format = "<8I31sc" # https://docs.python.org/3/library/struct.html
header_struct_format = "<8I31sx" # https://docs.python.org/3/library/struct.html

# ROM header
#
Expand Down Expand Up @@ -125,20 +125,20 @@ def set_bit(value, n):
# flags = 0
# follow = 0 # sprite or address follow for 'Unscaled (Auto)' display mode
# bios = args.bios.read()
# bios = bios + b"\0" * ((4 - (len(bios)%4))%4)
# bios += b"\0" * ((4 - (len(bios)%4))%4)
#
# biosfilename = os.path.split(args.bios.name)[1]
# biosheader = struct.pack(header_struct_format, EMU_ID, len(bios), flags, follow, biosflag, 0, 0, 0, biosfilename[:31].encode('ascii'), b"\0")
# compilation = compilation + biosheader + bios
# biosheader = struct.pack(header_struct_format, EMU_ID, len(bios), flags, follow, biosflag, 0, 0, 0, biosfilename[:31].encode('ascii'))
# compilation += biosheader + bios
#
# if args.bb:
# biosflag = 0
# flags = 0
# follow = 0 # sprite or address follow for 'Unscaled (Auto)' display mode
# empty = b"\xff" * 16384
# emptyname = "-- Empty --"
# emptyheader = struct.pack(header_struct_format, EMU_ID, len(empty), flags, follow, biosflag, 0, 0, 0, emptyname.encode('ascii'), b"\0")
# compilation = compilation + emptyheader + empty
# emptyheader = struct.pack(header_struct_format, EMU_ID, len(empty), flags, follow, biosflag, 0, 0, 0, emptyname.encode('ascii'))
# compilation += emptyheader + empty

for item in args.romfile:

Expand All @@ -154,18 +154,17 @@ def set_bit(value, n):
# no special cases
flags = 0
else:
print("Error: unsupported filetype for compilation -", romfilename)
sys.exit(1)
raise Exception(f'unsupported filetype for compilation - {romfilename}')

if args.c:
romtitle = romtitle.split(" [")[0] # strip the square bracket parts of the name
romtitle = romtitle.split(" (")[0] # strip the bracket parts of the name

romtitle = romtitle[:31]
rom = item.read()
rom = rom + b"\0" * ((4 - (len(rom)%4))%4)
romheader = struct.pack(header_struct_format, EMU_ID, len(rom), flags, follow, biosflag, 0, 0, 0, romtitle.encode('ascii'), b"\0")
compilation = compilation + romheader + rom
rom += b"\0" * ((4 - (len(rom)%4))%4)
romheader = struct.pack(header_struct_format, EMU_ID, len(rom), flags, follow, biosflag, 0, 0, 0, romtitle.encode('ascii'))
compilation += romheader + rom

print('{:<32}{}'.format(romtitle,romtype.strip(".")))

Expand Down
30 changes: 14 additions & 16 deletions pceadvance_compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
default_outputfile = "pceadv-compilation.gba"
default_emubinary = "pceadvance.gba"
default_cdrombios = "bios.bin"
header_struct_format = "<31sc5I12s" # https://docs.python.org/3/library/struct.html
header_struct_format = "<31sx5I12s" # https://docs.python.org/3/library/struct.html

# ROM header
#
Expand Down Expand Up @@ -131,7 +131,7 @@ def set_bit(value, n):
compilation = args.emubinary.read()

if args.splashscreen:
compilation = compilation + args.splashscreen.read()
compilation += args.splashscreen.read()

iso_count = 0

Expand All @@ -147,7 +147,7 @@ def set_bit(value, n):
# HuCard
if romtype.lower() == ".pce":
rom = item.read()
rom = rom + b"\0" * ((4 - (len(rom)%4))%4)
rom += b"\0" * ((4 - (len(rom)%4))%4)

# USA ROMs need this specific flag - remember, most will need to be decrypted first using PCEToy
if "(U)" in romtitle or "(USA)" in romtitle:
Expand Down Expand Up @@ -179,17 +179,17 @@ def set_bit(value, n):

# unsure why 16 bytes are added to len(rom), but the original builder does this, despite that it pads the roms a lot more than 16b
# however, you can't add more than one rom to the compilation unless this is done
romheader = struct.pack(header_struct_format, romtitle.encode('ascii'), b"\0", len(rom)+16, flags, follow, 0, EMUID, b"@ ")
romheader = struct.pack(header_struct_format, romtitle.encode('ascii'), len(rom)+16, flags, follow, 0, EMUID, b"@ ")

compilation = compilation + romheader + rom
compilation += romheader + rom

# CD-ROM
elif romtype.lower() == ".iso":
# only a single CD-ROM image is supported per compilation
if iso_count == 0:
# first data track ISO needs a CD-ROM BIOS + optional TCD tracklist first
cdbios = readfile(args.cdrombios)
cdbios = cdbios + b"\0" * ((4 - (len(cdbios)%4))%4)
cdbios += b"\0" * ((4 - (len(cdbios)%4))%4)
cdtitle = romtitle

if args.c:
Expand All @@ -199,8 +199,8 @@ def set_bit(value, n):
romtitle = romtitle[:31]

# use the ISO name for the cdbios entry in the rom list
cdromheader = struct.pack(header_struct_format, romtitle.encode('ascii'), b"\0", len(cdbios)+16, flags, follow, 0, EMUID, b"@ ")
compilation = compilation + cdromheader + cdbios
cdromheader = struct.pack(header_struct_format, romtitle.encode('ascii'), len(cdbios)+16, flags, follow, 0, EMUID, b"@ ")
compilation += cdromheader + cdbios

if args.tcdfile:
tracklist = args.tcdfile.read()
Expand All @@ -212,22 +212,20 @@ def set_bit(value, n):
cdrom = tracklist

# append data track (any subsequent tracks are simply concatenated - a TCD file is required for multiple data tracks)
cdrom = cdrom + item.read()
iso_count = iso_count + 1
cdrom += item.read()
iso_count += 1
if iso_count == 2 and tracklist == b"":
print("Error: multiple ISO data tracks require a TCD tracklist, either named to match the first ISO, or defined via -t")
print(" Note that PCEAdvance supports only a single CD-ROM game per compilation")
sys.exit(1)
raise Exception('multiple ISO data tracks require a TCD tracklist, either named to match the first ISO, or defined via -t\n' +
'Note that PCEAdvance supports only a single CD-ROM game per compilation')

else:
print("Error: unsupported filetype for compilation -", romfilename)
sys.exit(1)
raise Exception(f'unsupported filetype for compilation - {romfilename}')

print (romtitle)

# finished iterating rom list, append any CD-ROM data
if iso_count:
compilation = compilation + cdrom
compilation += cdrom

if args.trim:
# Super CD-ROM compilations cannot be larger than 16384-192KB or they won't fit into PSRAM
Expand Down
15 changes: 7 additions & 8 deletions pocketnes_compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
default_outputfile = "pocketnes-compilation.gba"
default_emubinary = "pocketnes.gba"
default_database = "pnesmmw.mdb"
header_struct_format = "<31sc4I" # https://docs.python.org/3/library/struct.html
header_struct_format = "<31sx4I" # https://docs.python.org/3/library/struct.html

# ROM header
#
Expand Down Expand Up @@ -128,10 +128,10 @@ def set_bit(value, n):

# ensure the first ROM's data is 256 byte aligned (after headers) for optimal performance
# https://github.com/Dwedit/PocketNES/issues/5
compilation = compilation + b"\0" * ((256 - ((len(compilation) + EMU_HEADER + NES_HEADER)%256))%256)
compilation += cb"\0" * ((256 - ((len(compilation) + EMU_HEADER + NES_HEADER)%256))%256)

if args.splashscreen:
compilation = compilation + args.splashscreen.read()
compilation += args.splashscreen.read()

for item in args.romfile:

Expand Down Expand Up @@ -198,16 +198,15 @@ def set_bit(value, n):
romtitle = romtitle[:31]

else:
print("Error: unsupported filetype for compilation -", romfilename)
sys.exit(1)
raise Exception(f'unsupported filetype for compilation - {romfilename}')

# align rom data (after headers) on 256 byte boundaries for optimal performance
# https://github.com/Dwedit/PocketNES/issues/5
# https://en.wikipedia.org/wiki/Data_structure_alignment
rom = rom + b"\0" * ((256 - ((len(rom) + EMU_HEADER)%256))%256)
rom += b"\0" * ((256 - ((len(rom) + EMU_HEADER)%256))%256)

romheader = struct.pack(header_struct_format, romtitle.encode('ascii'), b"\0", len(rom), flags, follow, 0)
compilation = compilation + romheader + rom
romheader = struct.pack(header_struct_format, romtitle.encode('ascii'), len(rom), flags, follow, 0)
compilation += romheader + rom

print (db_match, romtitle)

Expand Down
Loading

0 comments on commit b3ae58f

Please sign in to comment.