Some tooling to extract assets
Run: restool.py decode to extract assets into assets/defs/* Run: restool.py compile to compile the assets back into a rom
This commit is contained in:
95
assets/palfx_decode.py
Normal file
95
assets/palfx_decode.py
Normal file
@@ -0,0 +1,95 @@
|
||||
from decode_common import *
|
||||
|
||||
BANK = 0x8D
|
||||
|
||||
kInstructionSet = {
|
||||
0x8dc595: ('Wait', ''),
|
||||
0x8dc599: ('ColorPlus2', ''),
|
||||
0x8dc5a2: ('ColorPlus3', ''),
|
||||
0x8dc5ab: ('ColorPlus4', ''),
|
||||
0x8dc5b4: ('ColorPlus8', ''),
|
||||
0x8dc5bd: ('ColorPlus9', ''),
|
||||
0x8dc5c6: ('ColorPlus15', ''),
|
||||
0x8dc5cf: ('Delete', ''),
|
||||
0x8dc5d4: ('SetPreInstr', 'A'),
|
||||
0x8dc5dd: ('ClearPreInstr', ''),
|
||||
0x8dc61e: ('Goto', 'G'),
|
||||
0x8dc639: ('DecTimerGoto', 'G'),
|
||||
0x8dc648: ('SetTimer', 'B'),
|
||||
0x8dc655: ('SetColorIndex', 'H'),
|
||||
0x8dc65e: ('QueueMusic', 'B'),
|
||||
0x8dc66a: ('QueueSfx1', 'B'),
|
||||
0x8dc673: ('QueueSfx2', 'B'),
|
||||
0x8dc67c: ('QueueSfx3', 'B'),
|
||||
0x8df1c6: ('SetPalfxIndex', 'B'),
|
||||
}
|
||||
|
||||
kCommandByName = {v[0] : (k, v[1]) for k, v in kInstructionSet.items()}
|
||||
|
||||
class PalfxParser(InstrParserCommon):
|
||||
instruction_set = kInstructionSet
|
||||
instruction_set_term = {0x8DC5CF, 0x8DC61E}
|
||||
TAG = 'palfx'
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def handle_draw_command(self, ins, ea):
|
||||
xs = []
|
||||
while (x := get_word(ea + 2 + len(xs) * 2)) & 0x8000 == 0:
|
||||
xs.append('%.4x' % x)
|
||||
s = f'{ins:2} ' if ins != None else ''
|
||||
s = f' {s}! {" ".join(xs)}'
|
||||
if x != 0xc595:
|
||||
s += ' !'
|
||||
self.print_line(ea, s)
|
||||
return 2 + len(xs) * 2
|
||||
|
||||
def process_queue_entry(self, ea):
|
||||
assert ea & 0x8000
|
||||
is_finish = True
|
||||
while ea not in self.visited:
|
||||
self.visited.add(ea)
|
||||
ins = get_word(ea)
|
||||
if ins & 0x8000:
|
||||
if ins == 0xc595:
|
||||
assert not is_finish
|
||||
ea += 2
|
||||
is_finish = True
|
||||
continue
|
||||
ea_org = ea
|
||||
ins = (BANK << 16) | ins
|
||||
if ins not in self.instruction_set:
|
||||
raise Exception(f'Ins {ins:X} not in iset at {ea:X}')
|
||||
name, operands = self.instruction_set[ins]
|
||||
ea += 2
|
||||
r = []
|
||||
for op in operands:
|
||||
if op == 'B':
|
||||
r.append('%d' % get_byte(ea))
|
||||
ea += 1
|
||||
elif op == 'H':
|
||||
r.append('%d' % get_word(ea))
|
||||
ea += 2
|
||||
elif op == 'G':
|
||||
addr = (BANK << 16) | get_word(ea)
|
||||
r.append(get_ea_name(addr, short_label=True))
|
||||
self.visit(addr)
|
||||
ea += 2
|
||||
elif op == 'A':
|
||||
addr = (BANK << 16) | get_word(ea)
|
||||
assert addr & 0x8000
|
||||
r.append(get_ea_name(addr, short_label=True))
|
||||
ea += 2
|
||||
else:
|
||||
assert 0
|
||||
self.print_line(ea_org, f' {name}({", ".join(r)})')
|
||||
if ins in self.instruction_set_term:
|
||||
self.print_line(ea_org + 1, '')
|
||||
break
|
||||
else:
|
||||
if not is_finish:
|
||||
ea -= 2
|
||||
ins = None
|
||||
ea += self.handle_draw_command(ins, ea)
|
||||
is_finish = False
|
||||
Reference in New Issue
Block a user