diff --git a/extras/crystal.py b/extras/crystal.py index 35d3d20d2..e1f83fb8c 100644 --- a/extras/crystal.py +++ b/extras/crystal.py @@ -385,241 +385,6 @@ def command_debug_information(command_byte=None, map_group=None, map_id=None, ad #info1 += " long_info: " + long_info return info1 -class TextCommand(Command): - # an individual text command will not end it - end = False - - # this is only used for e.g. macros that don't appear as a byte in the ROM - override_byte_check = False - - # in the case of text/asm commands, size is unknown until after parsing - size = None - - params = [] - - # most text commands won't have any dependencies - # .. except for that one that points to another location for text - # get_dependencies on Command will look at the values of params - #def get_dependencies(self, recompute=False, global_dependencies=set()): - # return [] - -class MainText(TextCommand): - "Write text. Structure: [00][Text][0x50 (ends code)]" - id = 0x0 - macro_name = "do_text" - - def parse(self): - offset = self.address - - # read until $50, $57 or $58 (not sure about $58...) - jump57 = how_many_until(chr(0x57), offset) - jump50 = how_many_until(chr(0x50), offset) - jump58 = how_many_until(chr(0x58), offset) - - # pick whichever one comes first - jump = min([jump57, jump50, jump58]) - - # if $57 appears first then this command is the last in this text script - if jump == jump57: - self.end = True - - # we want the address after the $57 - # ("last_address" is misnamed everywhere) - end_address = offset + 1 + jump - self.last_address = self.end_address = end_address - - # read the text bytes into a structure - self.bytes = rom_interval(offset + 1, jump, strings=False) - - self.size = jump + 1 - - def to_asm(self): - if self.size < 2 or len(self.bytes) < 1: - raise Exception, "$0 text command can't end itself with no follow-on bytes" - - output = "db $0" - - # db $0, $57 or db $0, $50 or w/e - if self.size == 2 and len(self.bytes) == 1: - output += ", $%.2x" % (self.bytes[0]) - return output - - # whether or not quotes are open - in_quotes = False - - # whether or not to print "db " next - new_line = False - - for byte in self.bytes: - if byte in [0x4f, 0x51, 0x55]: pass - elif byte in [0x50, ]: pass - - # TODO - - return output - -class WriteTextFromRAM(TextCommand): - """ - Write text from ram. Structure: [01][Ram address (2byte)] - For valid ram addresses see Glossary. This enables use of variable text strings. - """ - id = 0x1 - macro_name = "text_from_ram" - size = 3 -class WriteNumberFromRAM(TextCommand): - """ - 02 = Write number from ram. Structure: [02][Ram address (2byte)][Byte] - - Byte: - - Bit5:Bit6:Bit7 - 1: 1: 1 = PokéDollar| Don’t write zeros - 0: 1: 1 = Don’t write zeros - 0: 0: 1 = Spaces instead of zeros - 0: 0: 0 = Write zeros - 0: 1: 0 = Write zeros - 1: 0: 0 = PokéDollar - 1: 1: 0 = PokéDollar - 1: 0: 1 = Spaces instead of zeros| PokéDollar - - Number of figures = Byte AND 0x1F *2 - No Hex --> Dec Conversio - """ - id = 0x2 - macro_name = "number_from_ram" - size = 4 -class SetWriteRAMLocation(TextCommand): - "Define new ram address to write to. Structure: [03][Ram address (2byte)]" - id = 0x3 - macro_name = "store_at" - size = 3 -class ShowBoxWithValueAt(TextCommand): - "04 = Write a box. Structure: [04][Ram address (2byte)][Y][X]" - id = 0x4 - macro_name = "text_box" - size = 5 -class Populate2ndLineOfTextBoxWithRAMContents(TextCommand): - "05 = New ram address to write to becomes 2nd line of a text box. Structure: [05]" - id = 0x5 - macro_name = "text_dunno1" - size = 1 -class ShowArrowsAndButtonWait(TextCommand): - "06 = Wait for key down + show arrows. Structure: [06]" - id = 0x6 - macro_name = "waitbutton" - size = 1 -class Populate2ndLine(TextCommand): - """ - 07 = New ram address to write to becomes 2nd line of a text box - Textbox + show arrows. Structure: [07] - """ - id = 0x7 - macro_name = "text_dunno2" - size = 1 -class TextInlineAsm(TextCommand): - "08 = After the code an ASM script starts. Structure: [08][Script]" - id = 0x8 - macro_name = "start_asm" - end = True -class WriteDecimalNumberFromRAM(TextCommand): - """ - 09 = Write number from rom/ram in decimal. Structure: [09][Ram address/Pointer (2byte)][Byte] - Byte: - - Is split: 1. 4 bits = Number of bytes to load. 0 = 3, 1 = 1, 2 = 2 - 2. 4 bits = Number of figures of displayed number - 0 = Don’t care - 1 = Don’t care - >=2 = Number - """ - id = 0x9 - macro_name = "deciram" - size = 4 -class InterpretDataStream(TextCommand): - """ - 0A = Interpret Data stream. Structure: [0A] - see: http://hax.iimarck.us/files/scriptingcodes_eng.htm#Marke88 - """ - id = 0xA - macro_name = "interpret_data" - size = 1 -class Play0thSound(TextCommand): - "0B = Play sound 0x0000. Structure: [0B]" - id = 0xB - sound_num = 0 - macro_name = "sound0" - size = 1 -class LimitedIntrepretDataStream(TextCommand): - """ - 0C = Interpret Data stream. Structure: [0C][Number of codes to interpret] - For every interpretation there is a“…“ written - """ - id = 0xC - macro_name = "limited_interpret_data" - size = 2 -class WaitForKeyDownDisplayArrow(ShowArrowsAndButtonWait): - """ - 0D = Wait for key down display arrow. Structure: [0D] - """ - id = 0xD - macro_name = "waitbutton2" - size = 1 -class Play9thSound(Play0thSound): - id = 0xE - sound_num = 9 - macro_name = "sound0x09" - size = 1 -class Play1stSound(Play0thSound): - id = 0xF - sound_num = 1 - macro_name = "sound0x0F" - size = 1 -class Play2ndSound(Play0thSound): - id = 0x10 - sound_num = 2 - macro_name = "sound0x02" - size = 1 -class Play10thSound(Play0thSound): - id = 0x11 - sound_num = 10 - macro_name = "sound0x0A" - size = 1 -class Play45thSound(Play0thSound): - id = 0x12 - sound_num = 0x2D - macro_name = "sound0x2D" - size = 1 -class Play44thSound(Play0thSound): - id = 0x13 - sound_num = 0x2C - macro_name = "sound0x2C" - size = 1 -class DisplayByteFromRAMAt(TextCommand): - """ - 14 = Display MEMORY. Structure: [14][Byte] - - Byte: - - 00 = MEMORY1 - 01 = MEMORY2 - 02 = MEMORY - 04 = TEMPMEMORY2 - 05 = TEMPMEMORY1 - """ - id = 0x14 - macro_name = "show_byte_at" - size = 2 -class WriteCurrentDay(TextCommand): - "15 = Write current day. Structure: [15]" - id = 0x15 - macro_name = "current_day" - size = 1 -class TextJump(TextCommand): - "16 = 3byte pointer to new text follows. Structure: [16][2byte pointer][bank]" - id = 0x16 - macro_name = "text_jump" - size = 4 - class NewTextScript: """ A text is a sequence of bytes (and sometimes commands). It's not the same thing as a Script. The bytes are translated into characters based @@ -2000,6 +1765,241 @@ class DataByteWordMacro(Command): def parse(self): pass def to_asm(self): pass +class TextCommand(Command): + # an individual text command will not end it + end = False + + # this is only used for e.g. macros that don't appear as a byte in the ROM + override_byte_check = False + + # in the case of text/asm commands, size is unknown until after parsing + size = None + + params = [] + + # most text commands won't have any dependencies + # .. except for that one that points to another location for text + # get_dependencies on Command will look at the values of params + #def get_dependencies(self, recompute=False, global_dependencies=set()): + # return [] + +class MainText(TextCommand): + "Write text. Structure: [00][Text][0x50 (ends code)]" + id = 0x0 + macro_name = "do_text" + + def parse(self): + offset = self.address + + # read until $50, $57 or $58 (not sure about $58...) + jump57 = how_many_until(chr(0x57), offset) + jump50 = how_many_until(chr(0x50), offset) + jump58 = how_many_until(chr(0x58), offset) + + # pick whichever one comes first + jump = min([jump57, jump50, jump58]) + + # if $57 appears first then this command is the last in this text script + if jump == jump57: + self.end = True + + # we want the address after the $57 + # ("last_address" is misnamed everywhere) + end_address = offset + 1 + jump + self.last_address = self.end_address = end_address + + # read the text bytes into a structure + self.bytes = rom_interval(offset + 1, jump, strings=False) + + self.size = jump + 1 + + def to_asm(self): + if self.size < 2 or len(self.bytes) < 1: + raise Exception, "$0 text command can't end itself with no follow-on bytes" + + output = "db $0" + + # db $0, $57 or db $0, $50 or w/e + if self.size == 2 and len(self.bytes) == 1: + output += ", $%.2x" % (self.bytes[0]) + return output + + # whether or not quotes are open + in_quotes = False + + # whether or not to print "db " next + new_line = False + + for byte in self.bytes: + if byte in [0x4f, 0x51, 0x55]: pass + elif byte in [0x50, ]: pass + + # TODO + + return output + +class WriteTextFromRAM(TextCommand): + """ + Write text from ram. Structure: [01][Ram address (2byte)] + For valid ram addresses see Glossary. This enables use of variable text strings. + """ + id = 0x1 + macro_name = "text_from_ram" + size = 3 +class WriteNumberFromRAM(TextCommand): + """ + 02 = Write number from ram. Structure: [02][Ram address (2byte)][Byte] + + Byte: + + Bit5:Bit6:Bit7 + 1: 1: 1 = PokéDollar| Don’t write zeros + 0: 1: 1 = Don’t write zeros + 0: 0: 1 = Spaces instead of zeros + 0: 0: 0 = Write zeros + 0: 1: 0 = Write zeros + 1: 0: 0 = PokéDollar + 1: 1: 0 = PokéDollar + 1: 0: 1 = Spaces instead of zeros| PokéDollar + + Number of figures = Byte AND 0x1F *2 + No Hex --> Dec Conversio + """ + id = 0x2 + macro_name = "number_from_ram" + size = 4 +class SetWriteRAMLocation(TextCommand): + "Define new ram address to write to. Structure: [03][Ram address (2byte)]" + id = 0x3 + macro_name = "store_at" + size = 3 +class ShowBoxWithValueAt(TextCommand): + "04 = Write a box. Structure: [04][Ram address (2byte)][Y][X]" + id = 0x4 + macro_name = "text_box" + size = 5 +class Populate2ndLineOfTextBoxWithRAMContents(TextCommand): + "05 = New ram address to write to becomes 2nd line of a text box. Structure: [05]" + id = 0x5 + macro_name = "text_dunno1" + size = 1 +class ShowArrowsAndButtonWait(TextCommand): + "06 = Wait for key down + show arrows. Structure: [06]" + id = 0x6 + macro_name = "waitbutton" + size = 1 +class Populate2ndLine(TextCommand): + """ + 07 = New ram address to write to becomes 2nd line of a text box + Textbox + show arrows. Structure: [07] + """ + id = 0x7 + macro_name = "text_dunno2" + size = 1 +class TextInlineAsm(TextCommand): + "08 = After the code an ASM script starts. Structure: [08][Script]" + id = 0x8 + macro_name = "start_asm" + end = True +class WriteDecimalNumberFromRAM(TextCommand): + """ + 09 = Write number from rom/ram in decimal. Structure: [09][Ram address/Pointer (2byte)][Byte] + Byte: + + Is split: 1. 4 bits = Number of bytes to load. 0 = 3, 1 = 1, 2 = 2 + 2. 4 bits = Number of figures of displayed number + 0 = Don’t care + 1 = Don’t care + >=2 = Number + """ + id = 0x9 + macro_name = "deciram" + size = 4 +class InterpretDataStream(TextCommand): + """ + 0A = Interpret Data stream. Structure: [0A] + see: http://hax.iimarck.us/files/scriptingcodes_eng.htm#Marke88 + """ + id = 0xA + macro_name = "interpret_data" + size = 1 +class Play0thSound(TextCommand): + "0B = Play sound 0x0000. Structure: [0B]" + id = 0xB + sound_num = 0 + macro_name = "sound0" + size = 1 +class LimitedIntrepretDataStream(TextCommand): + """ + 0C = Interpret Data stream. Structure: [0C][Number of codes to interpret] + For every interpretation there is a“…“ written + """ + id = 0xC + macro_name = "limited_interpret_data" + size = 2 +class WaitForKeyDownDisplayArrow(ShowArrowsAndButtonWait): + """ + 0D = Wait for key down display arrow. Structure: [0D] + """ + id = 0xD + macro_name = "waitbutton2" + size = 1 +class Play9thSound(Play0thSound): + id = 0xE + sound_num = 9 + macro_name = "sound0x09" + size = 1 +class Play1stSound(Play0thSound): + id = 0xF + sound_num = 1 + macro_name = "sound0x0F" + size = 1 +class Play2ndSound(Play0thSound): + id = 0x10 + sound_num = 2 + macro_name = "sound0x02" + size = 1 +class Play10thSound(Play0thSound): + id = 0x11 + sound_num = 10 + macro_name = "sound0x0A" + size = 1 +class Play45thSound(Play0thSound): + id = 0x12 + sound_num = 0x2D + macro_name = "sound0x2D" + size = 1 +class Play44thSound(Play0thSound): + id = 0x13 + sound_num = 0x2C + macro_name = "sound0x2C" + size = 1 +class DisplayByteFromRAMAt(TextCommand): + """ + 14 = Display MEMORY. Structure: [14][Byte] + + Byte: + + 00 = MEMORY1 + 01 = MEMORY2 + 02 = MEMORY + 04 = TEMPMEMORY2 + 05 = TEMPMEMORY1 + """ + id = 0x14 + macro_name = "show_byte_at" + size = 2 +class WriteCurrentDay(TextCommand): + "15 = Write current day. Structure: [15]" + id = 0x15 + macro_name = "current_day" + size = 1 +class TextJump(TextCommand): + "16 = 3byte pointer to new text follows. Structure: [16][2byte pointer][bank]" + id = 0x16 + macro_name = "text_jump" + size = 4 + #byte: [name, [param1 name, param1 type], [param2 name, param2 type], ...] #0x9E: ["verbosegiveitem", ["item", ItemLabelByte], ["quantity", SingleByteParam]], pksv_crystal_more = {