ref: e099019701cad461988501ac65d35b053d29b800
parent: f70650a15836170921a549539b90942dff3a193d
author: Bryan Bishop <[email protected]>
date: Sat Apr 14 08:23:53 EDT 2012
better signpost parsing
--- a/extras/crystal.py
+++ b/extras/crystal.py
@@ -2203,11 +2203,11 @@
def __init__(self, *args, **kwargs):
#bank can be overriden
if "bank" in kwargs.keys():
- if kwargs["bank"] != False and kwargs["bank"] != None:
+ if kwargs["bank"] != False and kwargs["bank"] != None and kwargs["bank"] in [True, "reverse"]:
#not +=1 because child classes set size=3 already
self.size = self.default_size + 1
- if kwargs["bank"] not in [None, False, True, "reverse"]:
- raise Exception, "bank cannot be: " + str(bank)
+ #if kwargs["bank"] not in [None, False, True, "reverse"]:
+ # raise Exception, "bank cannot be: " + str(kwargs["bank"])
if self.size > 3:
raise Exception, "param size is too large"
#continue instantiation.. self.bank will be set down the road
@@ -5012,6 +5012,83 @@
standard_size = people_event_byte_size
parse_func = parse_people_event_bytes
+class SignpostRemoteBase:
+ def __init__(self, address, bank=None, map_group=None, map_id=None, signpost=None, debug=False, label=None):
+ self.address = address
+ self.last_address = address + self.size
+ script_parse_table[self.address : self.last_address] = self
+ self.bank = bank
+ self.map_group = map_group
+ self.map_id = map_id
+ self.signpost = signpost
+ self.debug = debug
+ self.params = []
+ if label == None:
+ self.label = self.base_label + hex(self.address)
+ else: self.label = label
+ self.parse()
+ def to_asm(self):
+ """very similar to Command.to_asm"""
+ if len(self.params) == 0: return ""
+ output = ", ".join([p.to_asm() for p in self.params])
+ return output
+class SignpostRemoteScriptChunk(SignpostRemoteBase):
+ """
+ a signpost might point to [Bit-Nr. (2byte)][2byte pointer to script]
+ """
+ base_label = "SignpostRemoteScript_"
+ size = 4
+ def parse(self):
+ address = self.address
+ bank = self.bank
+
+ #bit_table_byte1 = ord(rom[address])
+ #bit_table_byte2 = ord(rom[address+1])
+ bit_table = MultiByteParam(address=address, map_group=self.map_group, map_id=self.map_id, debug=self.debug)
+ self.params.append(bit_table)
+
+ #script_address = calculate_pointer_from_bytes_at(address+2, bank=bank)
+ #script = parse_script_engine_script_at(script_address, map_group=self.map_group, map_id=self.map_id, debug=self.debug)
+ script_param = ScriptPointerLabelParam(address=address+2, map_group=self.map_group, map_id=self.map_id, debug=self.debug, force=False)
+ self.params.append(script_param)
+ self.script = script_param.script
+ self.signpost.remote_script = self.script
+
+ #self.bit_table_bytes = [bit_table_byte1, bit_table_byte2]
+ #self.script_address = script_address
+ #self.script = script
+class SignpostRemoteItemChunk(SignpostRemoteBase):
+ """
+ a signpost might point to [Bit-Nr. (2byte)][Item no.]
+ """
+ base_label = "SignpostRemoteItem_"
+ size = 3
+ def parse(self):
+ address = self.address
+ bank = self.bank
+
+ bit_table = MultiByteParam(address=address, map_group=self.map_group, map_id=self.map_id, debug=self.debug)
+ self.params.append(bit_table)
+
+ item = ItemLabelByte(address=address+2)
+ self.params.append(item)
+ self.item = item
+class SignpostRemoteUnknownChunk(SignpostRemoteBase):
+ """
+ a signpost might point to [Bit-Nr. (2byte)][??]
+ """
+ base_label = "SignpostRemoteUnknown_"
+ size = 3
+ def parse(self):
+ address = self.address
+ bank = self.bank
+
+ bit_table = MultiByteParam(address=address, bank=self.bank, map_group=self.map_group, map_id=self.map_id, debug=self.debug)
+ self.params.append(bit_table)
+
+ byte = SingleByteParam(address=address+2)
+ self.params.append(byte)
+
class Signpost:
"""parse some number of signposts from the data
@@ -5038,6 +5115,7 @@
script pointer to: [Bit-Nr. (2byte)][??]
"""
size = 5
+ macro_name = "signpost"
def __init__(self, address, id, bank=None, map_group=None, map_id=None, debug=True, label=None):
self.address = address
self.id = id
@@ -5052,88 +5130,121 @@
self.last_address = self.address + self.size
self.y, self.x, self.func = None, None, None
script_parse_table[self.address : self.last_address] = self
+ self.remotes = []
+ self.params = []
self.parse()
def parse(self):
"""parse just one signpost"""
+ address = self.address
bank = self.bank
- some_bytes = rom_interval(self.address, self.size)
self.last_address = self.address + self.size
- for bytes in grouper(some_bytes, count=signpost_byte_size):
- self.y = int(bytes[0], 16)
- self.x = int(bytes[1], 16)
- self.func = int(bytes[2], 16)
- y, x, func = self.y, self.x, self.func
-
- output = "******* parsing signpost "+str(self.id)+" at: "
- output += "x="+str(x)+" y="+str(y)+" on map_group="
- output += str(self.map_group)+" map_id="+str(self.map_id)
-
- if func in [0, 1, 2, 3, 4]:
- #signpost's script pointer points to a script
- script_ptr_byte1 = int(bytes[3], 16)
- script_ptr_byte2 = int(bytes[4], 16)
- script_pointer = script_ptr_byte1 + (script_ptr_byte2 << 8)
+ bytes = rom_interval(self.address, self.size) #, signpost_byte_size)
- script_address = None
- script = None
-
- script_address = calculate_pointer(script_pointer, bank)
- output += " script@"+hex(script_address)
- print output
- script = parse_script_engine_script_at(script_address, map_group=self.map_group, map_id=self.map_id, debug=self.debug)
-
- self.script_address = script_address
- self.script = script
- elif func in [5, 6]:
- #signpost's script pointer points to [Bit-Nr. (2byte)][2byte pointer to script]
- ptr_byte1 = int(bytes[3], 16)
- ptr_byte2 = int(bytes[4], 16)
- pointer = ptr_byte1 + (ptr_byte2 << 8)
- address = calculate_pointer(pointer, bank)
-
- self.pointer = pointer
- self.points_to = address
-
- bit_table_byte1 = ord(rom[address])
- bit_table_byte2 = ord(rom[address+1])
- script_ptr_byte1 = ord(rom[address+2])
- script_ptr_byte2 = ord(rom[address+3])
- script_address = calculate_pointer_from_bytes_at(address+2, bank=bank)
- output += " script@"+hex(script_address)
- print output
- script = parse_script_engine_script_at(script_address, map_group=self.map_group, map_id=self.map_id, debug=self.debug)
-
- self.bit_table_bytes = [bit_table_byte1, bit_table_byte2]
- self.target_script_address = script_address
- self.target_script = script
- elif func == 7:
- #signpost's script pointer points to [Bit-Nr. (2byte)][Item no.]
- ptr_byte1 = int(bytes[3], 16)
- ptr_byte2 = int(bytes[4], 16)
- pointer = ptr_byte1 + (ptr_byte2 << 8)
- address = calculate_pointer(pointer, bank)
-
- self.pointer = pointer
- self.points_to = address
-
- bit_table_byte1 = ord(rom[address])
- bit_table_byte2 = ord(rom[address+1])
- item_id = ord(rom[address+2])
- output += " item_id="+str(item_id)
- print output
-
- self.bit_table_bytes = [bit_table_byte1, bit_table_byte2]
- self.item_id = item_id
- elif func == 8:
- #signpost's script pointer points to [Bit-Nr. (2byte)][??]
- print "... type 8 signpost not handled yet."
- else:
- raise Exception, "unknown signpost type byte="+hex(func) + " signpost@"+hex(self.address)
+ self.y = int(bytes[0], 16)
+ self.x = int(bytes[1], 16)
+ self.func = int(bytes[2], 16)
+ y, x, func = self.y, self.x, self.func
+
+ #y
+ self.params.append(DecimalParam(address=address, bank=self.bank, map_group=self.map_group, map_id=self.map_id, debug=self.debug))
+ #x
+ self.params.append(DecimalParam(address=address+1, bank=self.bank, map_group=self.map_group, map_id=self.map_id, debug=self.debug))
+ #func
+ self.params.append(HexByte(address=address+2, bank=self.bank, map_group=self.map_group, map_id=self.map_id, debug=self.debug))
+
+ output = "******* parsing signpost "+str(self.id)+" at: "
+ output += "x="+str(x)+" y="+str(y)+" on map_group="
+ output += str(self.map_group)+" map_id="+str(self.map_id)
+
+ if func in [0, 1, 2, 3, 4]:
+ #signpost's script pointer points to a script
+ script_ptr_byte1 = int(bytes[3], 16)
+ script_ptr_byte2 = int(bytes[4], 16)
+ script_pointer = script_ptr_byte1 + (script_ptr_byte2 << 8)
+
+ script_address = calculate_pointer(script_pointer, bank)
+ output += " script@"+hex(script_address)
+ print output
+
+ param = ScriptPointerLabelParam(address=self.address+3, map_group=self.map_group, map_id=self.map_id, debug=self.debug, force=False)
+ self.params.append(param)
+
+ #self.script_address = script_address
+ #self.script = script
+ elif func in [5, 6]:
+ #signpost's script pointer points to [Bit-Nr. (2byte)][2byte pointer to script]
+ ptr_byte1 = int(bytes[3], 16)
+ ptr_byte2 = int(bytes[4], 16)
+ pointer = ptr_byte1 + (ptr_byte2 << 8)
+ address = calculate_pointer(pointer, bank)
+
+ bit_table_byte1 = ord(rom[address])
+ bit_table_byte2 = ord(rom[address+1])
+ script_ptr_byte1 = ord(rom[address+2])
+ script_ptr_byte2 = ord(rom[address+3])
+ script_address = calculate_pointer_from_bytes_at(address+2, bank=bank)
+
+ output += " remote_chunk@"+hex(address)+" remote_script@"+hex(script_address)
+ print output
+
+ r1 = SignpostRemoteScriptChunk(address, signpost=self, \
+ bank=self.bank, map_group=self.map_group, map_id=self.map_id, \
+ debug=self.debug)
+ self.remotes.append(r1)
+
+ mb = PointerLabelParam(address=address, map_group=self.map_group, map_id=self.map_id, debug=self.debug)
+ self.params.append(mb)
+ elif func == 7:
+ #signpost's script pointer points to [Bit-Nr. (2byte)][Item no.]
+ ptr_byte1 = int(bytes[3], 16)
+ ptr_byte2 = int(bytes[4], 16)
+ pointer = ptr_byte1 + (ptr_byte2 << 8)
+ address = calculate_pointer(pointer, bank)
+
+ item_id = ord(rom[address+2])
+ output += " item_id="+str(item_id)
+ print output
+
+ r1 = SignpostRemoteItemChunk(address, signpost=self, \
+ bank=self.bank, map_group=self.map_group, map_id=self.map_id, \
+ debug=self.debug)
+ self.remotes.append(r1)
+
+ mb = PointerLabelParam(address=address, map_group=self.map_group, map_id=self.map_id, debug=self.debug)
+ self.params.append(mb)
+
+ #bit_table_byte1 = ord(rom[address])
+ #bit_table_byte2 = ord(rom[address+1])
+ #self.bit_table_bytes = [bit_table_byte1, bit_table_byte2]
+ #self.item_id = item_id
+ elif func == 8:
+ #signpost's script pointer points to [Bit-Nr. (2byte)][??]
+ ptr_byte1 = int(bytes[3], 16)
+ ptr_byte2 = int(bytes[4], 16)
+ pointer = ptr_byte1 + (ptr_byte2 << 8)
+ address = calculate_pointer(pointer, bank)
+
+ output += " remote unknown chunk at="+hex(address)
+ print output
+
+ r1 = SignpostRemoteUnknownChunk(address, signpost=self, \
+ bank=self.bank, map_group=self.map_group, map_id=self.map_id, \
+ debug=self.debug)
+ self.remotes.append(r1)
+
+ mb = PointerLabelParam(address=address, map_group=self.map_group, map_id=self.map_id, debug=self.debug)
+ self.params.append(mb)
+ else:
+ raise Exception, "unknown signpost type byte="+hex(func) + " signpost@"+hex(self.address)
def to_asm(self):
- raise NotImplementedError
+ output = self.macro_name + " "
+ if self.params == []: raise Exception, "signpost has no params?"
+ output += ", ".join([p.to_asm() for p in self.params])
+ return output
all_signposts = []
def parse_signpost_bytes(address, signpost_count, bank=None, map_group=None, map_id=None, debug=True):
+ if bank == None: raise Exception, "signposts need to know their bank"
signposts = []
current_address = address
id = 0