ref: da22f934f9442f40dbce7ab4e3709f67240039af
parent: d497a0a00190bf59c8b95b48fb5b996712a5d7b8
author: Bryan Bishop <[email protected]>
date: Fri Mar 23 22:13:59 EDT 2012
pretty printer for text scripts
--- a/extras/crystal.py
+++ b/extras/crystal.py
@@ -533,7 +533,7 @@
class TextScript():
"a text is a sequence of commands different from a script-engine script"
- def to_asm(self): pass
+ def to_asm(self): raise NotImplementedError, bryan_message
@staticmethod
def find_addresses():
"""returns a list of text pointers
@@ -835,6 +835,202 @@
# sys.exit()
return commands
+ @staticmethod
+ def to_asm_at(address, label="SomeLabel"):
+ #parse the text script
+ commands = TextScript.parse_text_at(start_address)
+ #apparently this isn't important anymore?
+ needs_to_begin_with_0 = True
+ #start with zero please
+ byte_count = 0
+ #where we store all output
+ output = ""
+ had_text_end_byte = False
+ had_text_end_byte_57_58 = False
+ had_db_last = False
+ #reset this pretty fast..
+ first_line = True
+ #for each command..
+ for this_command in commands.keys():
+ if not "lines" in commands[this_command].keys():
+ command = commands[this_command]
+ if not "type" in command.keys():
+ print "ERROR in command: " + str(command)
+ continue #dunno what to do here?
+
+ if command["type"] == 0x1: #TX_RAM
+ if first_line:
+ output = "\n"
+ output += label + ": ; " + hex(start_address)
+ first_line = False
+ p1 = command["pointer"][0]
+ p2 = command["pointer"][1]
+
+ #remember to account for big endian -> little endian
+ output += "\n" + spacing + "TX_RAM $%.2x%.2x" %(p2, p1)
+ byte_count += 3
+ had_db_last = False
+ elif command["type"] == 0x17: #TX_FAR
+ if first_line:
+ output = "\n"
+ output += label + ": ; " + hex(start_address)
+ first_line = False
+ #p1 = command["pointer"][0]
+ #p2 = command["pointer"][1]
+ output += "\n" + spacing + "TX_FAR _" + label + " ; " + hex(command["pointer"])
+ byte_count += 4 #$17, bank, address word
+ had_db_last = False
+ elif command["type"] == 0x9: #TX_RAM_HEX2DEC
+ if first_line:
+ output = "\n" + label + ": ; " + hex(start_address)
+ first_line = False
+ #address, read_byte
+ output += "\n" + spacing + "TX_NUM $%.2x%.2x, $%.2x" % (command["address"][1], command["address"][0], command["read_byte"])
+ had_db_last = False
+ byte_count += 4
+ elif command["type"] == 0x50 and not had_text_end_byte:
+ #had_text_end_byte helps us avoid repeating $50s
+ if first_line:
+ output = "\n" + label + ": ; " + hex(start_address)
+ first_line = False
+ if had_db_last:
+ output += ", $50"
+ else:
+ output += "\n" + spacing + "db $50"
+ byte_count += 1
+ had_db_last = True
+ elif command["type"] in [0x57, 0x58] and not had_text_end_byte_57_58:
+ if first_line: #shouldn't happen, really
+ output = "\n" + label + ": ; " + hex(start_address)
+ first_line = False
+ if had_db_last:
+ output += ", $%.2x" % (command["type"])
+ else:
+ output += "\n" + spacing + "db $%.2x" % (command["type"])
+ byte_count += 1
+ had_db_last = True
+ elif command["type"] in [0x57, 0x58] and had_text_end_byte_57_58:
+ pass #this is ok
+ elif command["type"] == 0x50 and had_text_end_byte:
+ pass #this is also ok
+ elif command["type"] == 0x0b:
+ if first_line:
+ output = "\n" + label + ": ; " + hex(start_address)
+ first_line = False
+ if had_db_last:
+ output += ", $0b"
+ else:
+ output += "\n" + spacing + "db $0B"
+ byte_count += 1
+ had_db_last = True
+ elif command["type"] == 0x11:
+ if first_line:
+ output = "\n" + label + ": ; " + hex(start_address)
+ first_line = False
+ if had_db_last:
+ output += ", $11"
+ else:
+ output += "\n" + spacing + "db $11"
+ byte_count += 1
+ had_db_last = True
+ elif command["type"] == 0x6: #wait for keypress
+ if first_line:
+ output = "\n" + label + ": ; " + hex(start_address)
+ first_line = False
+ if had_db_last:
+ output += ", $6"
+ else:
+ output += "\n" + spacing + "db $6"
+ byte_count += 1
+ had_db_last = True
+ else:
+ print "ERROR in command: " + hex(command["type"])
+ had_db_last = False
+
+ #everything else is for $0s, really
+ continue
+ lines = commands[this_command]["lines"]
+
+ #reset this in case we have non-$0s later
+ had_db_last = False
+
+ #add the ending byte to the last line- always seems $57
+ #this should already be in there, but it's not because of a bug in the text parser
+ lines[len(lines.keys())-1].append(commands[len(commands.keys())-1]["type"])
+
+ if first_line:
+ output = "\n"
+ output += label + ": ; " + hex(start_address) + "\n"
+ first_line = False
+ else:
+ output += "\n"
+
+ first = True #first byte
+ for line_id in lines:
+ line = lines[line_id]
+ output += spacing + "db "
+ if first and needs_to_begin_with_0:
+ output += "$0, "
+ first = False
+ byte_count += 1
+
+ quotes_open = False
+ first_byte = True
+ was_byte = False
+ for byte in line:
+ if byte == 0x50:
+ had_text_end_byte = True #don't repeat it
+ if byte in [0x58, 0x57]:
+ had_text_end_byte_57_58 = True
+
+ if byte in txt_bytes:
+ if not quotes_open and not first_byte: #start text
+ output += ", \""
+ quotes_open = True
+ first_byte = False
+ if not quotes_open and first_byte: #start text
+ output += "\""
+ quotes_open = True
+ output += txt_bytes[byte]
+ elif byte in constant_abbreviation_bytes:
+ if quotes_open:
+ output += "\""
+ quotes_open = False
+ if not first_byte:
+ output += ", "
+ output += constant_abbreviation_bytes[byte]
+ else:
+ if quotes_open:
+ output += "\""
+ quotes_open = False
+
+ #if you want the ending byte on the last line
+ #if not (byte == 0x57 or byte == 0x50 or byte == 0x58):
+ if not first_byte:
+ output += ", "
+
+ output += "$" + hex(byte)[2:]
+ was_byte = True
+
+ #add a comma unless it's the end of the line
+ #if byte_count+1 != len(line):
+ # output += ", "
+
+ first_byte = False
+ byte_count += 1
+ #close final quotes
+ if quotes_open:
+ output += "\""
+ quotes_open = False
+
+ output += "\n"
+ include_newline = "\n"
+ if len(output)!=0 and output[-1] == "\n":
+ include_newline = ""
+ output += include_newline + "; " + hex(start_address) + " + " + str(byte_count) + " bytes = " + hex(start_address + byte_count)
+ print output
+ return (output, byte_count)
+
def parse_text_engine_script_at(address, map_group=None, map_id=None, debug=True, show=True):
"""parses a text-engine script ("in-text scripts")
http://hax.iimarck.us/files/scriptingcodes_eng.htm#InText
@@ -849,7 +1045,7 @@
class EncodedText():
"""a sequence of bytes that, when decoded, represent readable text
based on the chars table from textpre.py and other places"""
- def to_asm(self): pass
+ def to_asm(self): raise NotImplementedError, bryan_message
@staticmethod
def process_00_subcommands(start_address, end_address):
"""split this text up into multiple lines