mirror of
https://github.com/notwa/mm
synced 2025-01-02 17:08:06 -08:00
use debug ROM filenames, less verbose
This commit is contained in:
parent
e823103995
commit
5742f395a9
2 changed files with 70 additions and 34 deletions
5
util.py
5
util.py
|
@ -8,8 +8,11 @@ W1 = lambda data: struct.pack('>B', data)
|
||||||
W2 = lambda data: struct.pack('>H', data)
|
W2 = lambda data: struct.pack('>H', data)
|
||||||
W4 = lambda data: struct.pack('>I', data)
|
W4 = lambda data: struct.pack('>I', data)
|
||||||
|
|
||||||
def dump_as(b, fn):
|
def dump_as(b, fn, size=None):
|
||||||
with open(fn, 'w+b') as f:
|
with open(fn, 'w+b') as f:
|
||||||
|
if size:
|
||||||
|
f.write(bytearray(size))
|
||||||
|
f.seek(0)
|
||||||
f.write(b)
|
f.write(b)
|
||||||
|
|
||||||
def swap_order(f, size='H'):
|
def swap_order(f, size='H'):
|
||||||
|
|
99
z64dump.py
99
z64dump.py
|
@ -15,7 +15,7 @@ lament = lambda *args, **kwargs: print(*args, file=sys.stderr, **kwargs)
|
||||||
# assume first entry is makerom (0x1060), and second entry begins from makerom
|
# assume first entry is makerom (0x1060), and second entry begins from makerom
|
||||||
dma_sig = b"\x00\x00\x00\x00\x00\x00\x10\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x60"
|
dma_sig = b"\x00\x00\x00\x00\x00\x00\x10\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x60"
|
||||||
|
|
||||||
def z_dump_file(f, prefix=None):
|
def z_dump_file(f, i=0, name=None):
|
||||||
vs = R4(f.read(4)) # virtual start
|
vs = R4(f.read(4)) # virtual start
|
||||||
ve = R4(f.read(4)) # virtual end
|
ve = R4(f.read(4)) # virtual end
|
||||||
ps = R4(f.read(4)) # physical start
|
ps = R4(f.read(4)) # physical start
|
||||||
|
@ -25,28 +25,30 @@ def z_dump_file(f, prefix=None):
|
||||||
if vs == ve == ps == pe == 0:
|
if vs == ve == ps == pe == 0:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
fn = 'V{:08X}-{:08X},P{:08X}-{:08X}'.format(vs, ve, ps, pe)
|
# ve inferred from filesize, and we're making pe be 0
|
||||||
if prefix is not None:
|
# ps can just be the end of the last file
|
||||||
fn = str(prefix) + fn
|
fn = '{:04} V{:08X}'.format(i, vs)
|
||||||
|
if name is not None:
|
||||||
|
fn = fn + ' ' + str(name)
|
||||||
|
|
||||||
size = ve - vs
|
size = ve - vs
|
||||||
|
|
||||||
if ps == 0xFFFFFFFF or pe == 0xFFFFFFFF:
|
if ps == 0xFFFFFFFF or pe == 0xFFFFFFFF:
|
||||||
#lament('file does not exist')
|
#lament('file does not exist')
|
||||||
dump_as(b'', fn)
|
dump_as(b'', fn, size)
|
||||||
elif pe == 0:
|
elif pe == 0:
|
||||||
#lament('file is uncompressed')
|
#lament('file is uncompressed')
|
||||||
pe = ps + size
|
pe = ps + size
|
||||||
f.seek(ps)
|
f.seek(ps)
|
||||||
data = f.read(pe - ps)
|
data = f.read(pe - ps)
|
||||||
dump_as(data, fn)
|
dump_as(data, fn, size)
|
||||||
else:
|
else:
|
||||||
#lament('file is compressed')
|
#lament('file is compressed')
|
||||||
f.seek(ps)
|
f.seek(ps)
|
||||||
compressed = f.read(pe - ps)
|
compressed = f.read(pe - ps)
|
||||||
if compressed[:4] == b'Yaz0':
|
if compressed[:4] == b'Yaz0':
|
||||||
data = Yaz0.decode(compressed)
|
data = Yaz0.decode(compressed)
|
||||||
dump_as(data, fn)
|
dump_as(data, fn, size)
|
||||||
else:
|
else:
|
||||||
lament('unknown compression; skipping:', fn)
|
lament('unknown compression; skipping:', fn)
|
||||||
lament(compressed[:4])
|
lament(compressed[:4])
|
||||||
|
@ -67,8 +69,8 @@ def z_find_dma(f):
|
||||||
else:
|
else:
|
||||||
f.seek(len(rest), 1)
|
f.seek(len(rest), 1)
|
||||||
|
|
||||||
def z_dump(f):
|
def z_dump(f, names=None):
|
||||||
f.seek(0x1060) # skip header when finding dma
|
f.seek(0x1060) # skip header when finding dmatable
|
||||||
addr = z_find_dma(f)
|
addr = z_find_dma(f)
|
||||||
if addr == None:
|
if addr == None:
|
||||||
lament("couldn't find file offset table")
|
lament("couldn't find file offset table")
|
||||||
|
@ -80,8 +82,17 @@ def z_dump(f):
|
||||||
|
|
||||||
f.seek(addr)
|
f.seek(addr)
|
||||||
i = 0
|
i = 0
|
||||||
while z_dump_file(f, '{:05} '.format(i)):
|
if names:
|
||||||
|
for n in names:
|
||||||
|
if z_dump_file(f, i, n):
|
||||||
|
i += 1
|
||||||
|
else:
|
||||||
|
lament("ran out of filenames")
|
||||||
|
break
|
||||||
|
while z_dump_file(f, i):
|
||||||
i += 1
|
i += 1
|
||||||
|
if names and i > len(names):
|
||||||
|
lament("extraneous filenames")
|
||||||
|
|
||||||
def dump_rom(fn):
|
def dump_rom(fn):
|
||||||
with open(fn, 'rb') as f:
|
with open(fn, 'rb') as f:
|
||||||
|
@ -96,36 +107,40 @@ def dump_rom(fn):
|
||||||
return
|
return
|
||||||
|
|
||||||
f.seek(0)
|
f.seek(0)
|
||||||
outdir = sha1(f.read()).hexdigest()
|
romhash = sha1(f.read()).hexdigest()
|
||||||
|
|
||||||
with SubDir(outdir):
|
names = None
|
||||||
|
if romhash == '50bebedad9e0f10746a52b07239e47fa6c284d03':
|
||||||
|
# OoT debug rom filenames
|
||||||
|
f.seek(0xBE80)
|
||||||
|
names = f.read(0x6490).split(b'\x00')
|
||||||
|
names = [str(n, 'utf-8') for n in names if n != b'']
|
||||||
|
|
||||||
|
with SubDir(romhash):
|
||||||
f.seek(0)
|
f.seek(0)
|
||||||
z_dump(f)
|
z_dump(f, names)
|
||||||
|
|
||||||
def z_read_file(path, fn=None):
|
def z_read_file(path, fn=None):
|
||||||
if fn == None:
|
if fn == None:
|
||||||
fn = os.path.basename(path)
|
fn = os.path.basename(path)
|
||||||
|
|
||||||
if len(fn) < 37:
|
if len(fn) < 14:
|
||||||
return False
|
return False, None, None
|
||||||
|
|
||||||
fn = str(fn[-37:])
|
fn = str(fn[:14])
|
||||||
|
|
||||||
if fn[0] != 'V' or fn[9] != '-' or fn[18:20] != ',P' or fn[28] != '-':
|
if fn[4:6] != ' V':
|
||||||
return False
|
return False, None, None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
vs = int(fn[ 1: 9], 16)
|
vs = int(fn[ 6: 14], 16)
|
||||||
ve = int(fn[10:18], 16)
|
|
||||||
ps = int(fn[20:28], 16)
|
|
||||||
pe = int(fn[29:37], 16)
|
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return False
|
return False, None, None
|
||||||
|
|
||||||
with open(path, 'rb') as f:
|
with open(path, 'rb') as f:
|
||||||
data = f.read()
|
data = f.read()
|
||||||
|
|
||||||
return True, data, vs, ve, ps, pe
|
return True, data, vs
|
||||||
|
|
||||||
def z_write_dma(f, dma):
|
def z_write_dma(f, dma):
|
||||||
dma.sort(key=lambda vf: vf[0]) # sort by vs
|
dma.sort(key=lambda vf: vf[0]) # sort by vs
|
||||||
|
@ -159,6 +174,7 @@ def fix_rom(f):
|
||||||
|
|
||||||
def create_rom(d):
|
def create_rom(d):
|
||||||
root, _, files = next(os.walk(d))
|
root, _, files = next(os.walk(d))
|
||||||
|
files.sort()
|
||||||
|
|
||||||
rom_size = 64*1024*1024
|
rom_size = 64*1024*1024
|
||||||
with open(d+'.z64', 'w+b') as f:
|
with open(d+'.z64', 'w+b') as f:
|
||||||
|
@ -168,25 +184,42 @@ def create_rom(d):
|
||||||
f.write(bytearray(rom_size))
|
f.write(bytearray(rom_size))
|
||||||
f.seek(0)
|
f.seek(0)
|
||||||
|
|
||||||
for fn in files:
|
start = 0
|
||||||
|
|
||||||
|
for i, fn in enumerate(files):
|
||||||
path = os.path.join(root, fn)
|
path = os.path.join(root, fn)
|
||||||
success, data, vs, ve, ps, pe = z_read_file(path, fn)
|
success, data, vs = z_read_file(path, fn)
|
||||||
if not success:
|
if not success:
|
||||||
lament('skipping:', fn)
|
lament('skipping:', fn)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
assert(vs < rom_size)
|
if i <= 2:
|
||||||
assert(ve <= rom_size)
|
# makerom, boot, dmadata need to be exactly where they were
|
||||||
if ps == 0xFFFFFFFF or pe == 0xFFFFFFFF:
|
start = vs
|
||||||
|
else:
|
||||||
|
# align to next row
|
||||||
|
start = (start + 15)//16*16
|
||||||
|
|
||||||
|
size = len(data)
|
||||||
|
if size:
|
||||||
|
ps = start
|
||||||
|
pe = 0
|
||||||
|
else:
|
||||||
ps = 0xFFFFFFFF
|
ps = 0xFFFFFFFF
|
||||||
pe = 0xFFFFFFFF
|
pe = 0xFFFFFFFF
|
||||||
else:
|
ve = vs + size
|
||||||
ps = vs
|
|
||||||
pe = 0
|
assert(start <= rom_size)
|
||||||
f.seek(vs)
|
assert(start + size <= rom_size)
|
||||||
|
assert(vs < rom_size)
|
||||||
|
assert(ve <= rom_size)
|
||||||
|
|
||||||
|
if size:
|
||||||
|
f.seek(start)
|
||||||
f.write(data)
|
f.write(data)
|
||||||
|
|
||||||
dma.append([vs, ve, ps, pe])
|
dma.append([vs, ve, ps, pe])
|
||||||
|
start += size
|
||||||
|
|
||||||
z_write_dma(f, dma)
|
z_write_dma(f, dma)
|
||||||
fix_rom(f)
|
fix_rom(f)
|
||||||
|
|
Loading…
Reference in a new issue