diff options
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | README.md | 5 | ||||
-rw-r--r-- | constants.asm | 2 | ||||
-rw-r--r-- | extras/comparator.py | 32 | ||||
-rw-r--r-- | extras/crystal.py | 130 | ||||
-rw-r--r-- | extras/gfx.py | 26 | ||||
-rw-r--r-- | extras/graph.py | 26 | ||||
-rw-r--r-- | extras/item_constants.py | 2 | ||||
-rw-r--r-- | extras/labels.py | 3 | ||||
-rw-r--r-- | extras/map_names.py | 2 | ||||
-rw-r--r-- | extras/romstr.py | 49 | ||||
-rw-r--r-- | extras/trainers.py | 3 | ||||
-rw-r--r-- | items/item_effects.asm | 1798 | ||||
-rw-r--r-- | main.asm | 205 | ||||
-rw-r--r-- | preprocessor.py | 49 |
15 files changed, 2228 insertions, 107 deletions
diff --git a/.gitignore b/.gitignore index 094c03a17..77577a838 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,6 @@ pokecrystal.rtc # for vim configuration # url: http://www.vim.org/scripts/script.php?script_id=441 .lvimrc + +# some users are dumping png.py into extras/ +extras/png.py @@ -24,9 +24,8 @@ Eventually this will not be necessary. ## Contributing -* Hang out with us on IRC: -`nucleus.kafuka.org #skeetendo` -(or use [mibbit](http://chat.mibbit.com/?server=nucleus.kafuka.org&channel=#skeetendo)). +* Hang out with us on IRC: `nucleus.kafuka.org #skeetendo` (for example, by +using [mibbit](http://chat.mibbit.com/)). * Are we missing something? Make a pull request! Contributions are welcome. diff --git a/constants.asm b/constants.asm index cd461b3b9..4885f7e98 100644 --- a/constants.asm +++ b/constants.asm @@ -1644,7 +1644,7 @@ RAINBOW_WING EQU $B2 BRICK_PIECE EQU $B4 SURF_MAIL EQU $B5 LITEBLUEMAIL EQU $B6 -PORTRAITM_AIL EQU $B7 +PORTRAITMAIL EQU $B7 LOVELY_MAIL EQU $B8 EON_MAIL EQU $B9 MORPH_MAIL EQU $BA diff --git a/extras/comparator.py b/extras/comparator.py index 6d981e493..48bdb6b09 100644 --- a/extras/comparator.py +++ b/extras/comparator.py @@ -17,12 +17,14 @@ from romstr import ( ) def load_rom(path): - """ Loads a ROM file into an abbreviated RomStr object. + """ + Loads a ROM file into an abbreviated RomStr object. """ return direct_load_rom(filename=path) def load_asm(path): - """ Loads source ASM into an abbreviated AsmList object. + """ + Loads source ASM into an abbreviated AsmList object. """ return direct_load_asm(filename=path) @@ -38,7 +40,8 @@ def findall_iter(sub, string): return iter(next_index(len(sub)).next, -1) class Address(int): - """ A simple int wrapper to take 0xFFFF and $FFFF addresses. + """ + A simple int wrapper to take 0xFFFF and $FFFF addresses. """ def __new__(cls, x=None, *args, **kwargs): @@ -59,8 +62,9 @@ class Address(int): found_blobs = [] class BinaryBlob(object): - """ Stores a label, line number, and addresses of a function from Pokémon - Red. These details can be used to determine whether or not the function was + """ + Stores a label, line number, and addresses of a function from Pokémon Red. + These details can be used to determine whether or not the function was copied into Pokémon Crystal. """ @@ -100,7 +104,8 @@ class BinaryBlob(object): self.find_by_first_bytes() def __repr__(self): - """ A beautiful poem. + """ + A beautiful poem. """ r = "BinaryBlob(" @@ -122,13 +127,15 @@ class BinaryBlob(object): return self.__repr__() def parse_from_red(self): - """ Reads bytes from Pokémon Red and stores them. + """ + Reads bytes from Pokémon Red and stores them. """ self.bytes = redrom[self.start_address : self.end_address + 1] def pretty_bytes(self): - """ Returns a better looking range of bytes. + """ + Returns a better looking range of bytes. """ bytes = redrom.interval(self.start_address, \ @@ -138,7 +145,8 @@ class BinaryBlob(object): return bytes def find_in_crystal(self): - """ Checks whether or not the bytes appear in Pokémon Crystal. + """ + Checks whether or not the bytes appear in Pokémon Crystal. """ finditer = findall_iter(self.bytes, cryrom) @@ -151,7 +159,8 @@ class BinaryBlob(object): print self.label + ": found " + str(len(self.locations)) + " matches." def find_by_first_bytes(self): - """ Finds this blob in Crystal based on the first n bytes. + """ + Finds this blob in Crystal based on the first n bytes. """ # how many bytes to match @@ -184,7 +193,8 @@ redrom = load_rom(pokered_rom_path) redsrc = load_asm(pokered_src_path) def scan_red_asm(bank_stop=3, debug=True): - """ Scans the ASM from Pokémon Red. Finds labels and objects. Does things. + """ + Scans the ASM from Pokémon Red. Finds labels and objects. Does things. Uses get_label_from_line and get_address_from_line_comment. """ diff --git a/extras/crystal.py b/extras/crystal.py index c7b09397e..680a441e3 100644 --- a/extras/crystal.py +++ b/extras/crystal.py @@ -275,10 +275,11 @@ def command_debug_information(command_byte=None, map_group=None, map_id=None, ad all_texts = [] class TextScript: - """ 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 - on the lookup table (see chars.py). The in-text commands are for including - values from RAM, playing sound, etc. + """ + 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 on the + lookup table (see chars.py). The in-text commands are for including values + from RAM, playing sound, etc. see: http://hax.iimarck.us/files/scriptingcodes_eng.htm#InText """ @@ -1157,7 +1158,8 @@ def generate_map_constants(): print maps def generate_map_constants_dimensions(): - """ Generate _WIDTH and _HEIGHT properties. + """ + Generate _WIDTH and _HEIGHT properties. """ global map_internal_ids output = "" @@ -1172,8 +1174,10 @@ def generate_map_constants_dimensions(): return output def transform_wildmons(asm): - """ Converts a wildmons section to use map constants. - input: wildmons text. """ + """ + Converts a wildmons section to use map constants. + input: wildmons text. + """ asmlines = asm.split("\n") returnlines = [] for line in asmlines: @@ -1899,7 +1903,8 @@ class GivePoke(Command): return True class DataByteWordMacro(Command): - """ Only used by the preprocessor. + """ + Only used by the preprocessor. """ id = None @@ -2000,9 +2005,9 @@ movement_command_bases = { # create MovementCommands from movement_command_bases def create_movement_commands(debug=False): - """ Creates MovementCommands from movement_command_bases. - This is just a cheap trick instead of manually defining - all of those classes. + """ + Creates MovementCommands from movement_command_bases. This is just a cheap + trick instead of manually defining all of those classes. """ #movement_command_classes = inspect.getmembers(sys.modules[__name__], \ # lambda obj: inspect.isclass(obj) and \ @@ -3776,7 +3781,8 @@ class TrainerFragmentParam(PointerLabelParam): trainer_group_table = None class TrainerGroupTable: - """ A list of pointers. + """ + A list of pointers. This should probably be called TrainerGroupPointerTable. """ @@ -3854,7 +3860,8 @@ class TrainerGroupHeader: script_parse_table[address : self.last_address] = self def get_dependencies(self, recompute=False, global_dependencies=set()): - """ TrainerGroupHeader has no dependencies. + """ + TrainerGroupHeader has no dependencies. """ # TODO: possibly include self.individual_trainer_headers if recompute or self.dependencies == None: @@ -3940,7 +3947,8 @@ class TrainerHeader: # TrainerGroupHeader covers its address range def make_name(self): - """ Must occur after parse() is called. + """ + Must occur after parse() is called. Constructs a name based on self.parent.group_name and self.name. """ if self.trainer_group_id in [0x14, 0x16, 0x17, 0x18, 0x19, 0x1B, 0x1C, 0x1D, 0x1E, 0x20, 0x21, 0x22, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2B, 0x2C, 0x2D, 0x2F, 0x30, 0x31, 0x32, 0x34, 0x35, 0x36, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x41]: @@ -4021,7 +4029,8 @@ class TrainerHeader: return output class TrainerPartyMonParser: - """ Just a generic trainer party mon parser. + """ + Just a generic trainer party mon parser. Don't use this directly. Only use the child classes. """ id = None @@ -4078,7 +4087,9 @@ class TrainerPartyMonParser: return output class TrainerPartyMonParser0(TrainerPartyMonParser): - """ Data type <0x00>: Pokémon Data is <Level> <Species>. Used by most trainers. """ + """ + Data type <0x00>: Pokémon Data is <Level> <Species>. Used by most trainers. + """ id = 0 size = 2 + 1 param_types = { @@ -4086,7 +4097,10 @@ class TrainerPartyMonParser0(TrainerPartyMonParser): 1: {"name": "species", "class": PokemonParam}, } class TrainerPartyMonParser1(TrainerPartyMonParser): - """ Data type <0x01>: Pokémon Data is <Level> <Pokémon> <Move1> <Move2> <Move3> <Move4>. Used often for Gym Leaders.""" + """ + Data type <0x01>: Pokémon Data is <Level> <Pokémon> <Move1> <Move2> <Move3> + <Move4>. Used often for Gym Leaders. + """ id = 1 size = 6 + 1 param_types = { @@ -4098,7 +4112,9 @@ class TrainerPartyMonParser1(TrainerPartyMonParser): 5: {"name": "move4", "class": MoveParam}, } class TrainerPartyMonParser2(TrainerPartyMonParser): - """ Data type <0x02>: Pokémon Data is <Level> <Pokémon> <Held Item>. Used mainly by Pokéfans. """ + """ + Data type <0x02>: Pokémon Data is <Level> <Pokémon> <Held Item>. Used mainly by Pokéfans. + """ id = 2 size = 3 + 1 param_types = { @@ -4107,8 +4123,11 @@ class TrainerPartyMonParser2(TrainerPartyMonParser): 2: {"name": "item", "class": ItemLabelByte}, } class TrainerPartyMonParser3(TrainerPartyMonParser): - """ Data type <0x03>: Pokémon Data is <Level> <Pokémon> <Held Item> <Move1> <Move2> <Move3> <Move4>. - Used by a few Cooltrainers. """ + """ + Data type <0x03>: Pokémon Data is <Level> <Pokémon> <Held Item> <Move1> + <Move2> <Move3> <Move4>. + Used by a few Cooltrainers. + """ id = 3 size = 7 + 1 param_types = { @@ -4124,7 +4143,8 @@ class TrainerPartyMonParser3(TrainerPartyMonParser): trainer_party_mon_parsers = [TrainerPartyMonParser0, TrainerPartyMonParser1, TrainerPartyMonParser2, TrainerPartyMonParser3] def find_trainer_ids_from_scripts(): - """ Looks through all scripts to find trainer group numbers and trainer numbers. + """ + Looks through all scripts to find trainer group numbers and trainer numbers. This can be used with trainer_group_maximums to figure out the current number of trainers in each of the originating trainer groups. @@ -4145,7 +4165,8 @@ def find_trainer_ids_from_scripts(): trainer_group_maximums[key] = value def report_unreferenced_trainer_ids(): - """ Reports on the number of unreferenced trainer ids in each group. + """ + Reports on the number of unreferenced trainer ids in each group. This should be called after find_trainer_ids_from_scripts. @@ -4186,7 +4207,8 @@ def report_unreferenced_trainer_ids(): print "total unreferenced trainers: " + str(total_unreferenced_trainers) def check_script_has_trainer_data(script): - """ see find_trainer_ids_from_scripts + """ + see find_trainer_ids_from_scripts """ for command in script.commands: trainer_group = None @@ -4206,7 +4228,7 @@ def check_script_has_trainer_data(script): trainer_group_maximums[trainer_group] = set([trainer_id]) def trainer_name_from_group(group_id, trainer_id=0): - """ This doesn't actually work for trainer_id > 0.""" + """This doesn't actually work for trainer_id > 0.""" bank = calculate_bank(0x39999) ptr_address = 0x39999 + ((group_id - 1)*2) address = calculate_pointer_from_bytes_at(ptr_address, bank=bank) @@ -4214,7 +4236,8 @@ def trainer_name_from_group(group_id, trainer_id=0): return text def trainer_group_report(): - """ Reports how many trainer ids are used in each trainer group. + """ + Reports how many trainer ids are used in each trainer group. """ output = "" total = 0 @@ -4231,7 +4254,8 @@ def trainer_group_report(): return output def make_trainer_group_name_trainer_ids(trainer_group_table, debug=True): - """ Edits trainer_group_names and sets the trainer names. + """ + Edits trainer_group_names and sets the trainer names. For instance, "AMY & MAY" becomes "AMY_AND_MAY1" and "AMY_AND_MAY2" This should only be used after TrainerGroupTable.parse has been called. @@ -4269,7 +4293,8 @@ def make_trainer_group_name_trainer_ids(trainer_group_table, debug=True): print "done improving trainer names" def pretty_print_trainer_id_constants(): - """ Prints out some constants for trainer ids, for "constants.asm". + """ + Prints out some constants for trainer ids, for "constants.asm". make_trainer_group_name_trainer_ids must be called prior to this. """ @@ -5000,7 +5025,8 @@ def old_parse_map_header_at(address, map_group=None, map_id=None, debug=True): def get_direction(connection_byte, connection_id): - """ Given a connection byte and a connection id, which direction is this + """ + Given a connection byte and a connection id, which direction is this connection? example: @@ -6443,7 +6469,8 @@ def parse_all_map_headers(debug=True): map_names[group_id][map_id]["header_old"] = old_parsed_map class PokedexEntryPointerTable: - """ A list of pointers. + """ + A list of pointers. """ def __init__(self): @@ -6492,8 +6519,6 @@ class PokedexEntryPointerTable: return output class PokedexEntry: - """ """ - def __init__(self, address, pokemon_id): self.address = address self.dependencies = None @@ -6982,7 +7007,8 @@ class Asm: return llabel return False def does_address_have_label(self, address): - """ Checks if an address has a label. + """ + Checks if an address has a label. """ # either something will directly have the address # or- it's possibel that no label was given @@ -7208,8 +7234,8 @@ def list_things_in_bank(bank): return objects def list_texts_in_bank(bank): - """ Narrows down the list of objects - that you will be inserting into Asm. + """ + Narrows down the list of objects that you will be inserting into Asm. """ if len(all_texts) == 0: raise Exception("all_texts is blank.. run_main() will populate it") @@ -7226,8 +7252,8 @@ def list_texts_in_bank(bank): return texts def list_movements_in_bank(bank): - """ Narrows down the list of objects - to speed up Asm insertion. + """ + Narrows down the list of objects to speed up Asm insertion. """ if len(all_movements) == 0: raise Exception("all_movements is blank.. run_main() will populate it") @@ -7242,8 +7268,9 @@ def list_movements_in_bank(bank): return movements def dump_asm_for_texts_in_bank(bank, start=50, end=100): - """ Simple utility to help with dumping texts into a particular bank. This - is helpful for figuring out which text is breaking that bank. + """ + Simple utility to help with dumping texts into a particular bank. This is + helpful for figuring out which text is breaking that bank. """ # load and parse the ROM if necessary if rom == None or len(rom) <= 4: @@ -7278,7 +7305,8 @@ def dump_asm_for_movements_in_bank(bank, start=0, end=100): print "done dumping movements for bank $%.2x" % (bank) def dump_things_in_bank(bank, start=50, end=100): - """ is helpful for figuring out which object is breaking that bank. + """ + is helpful for figuring out which object is breaking that bank. """ # load and parse the ROM if necessary if rom == None or len(rom) <= 4: @@ -7370,7 +7398,8 @@ def get_label_for(address): all_new_labels = [] class Label: - """ Every object in script_parse_table is given a label. + """ + Every object in script_parse_table is given a label. This label is simply a way to keep track of what objects have been previously written to file. @@ -7406,8 +7435,9 @@ class Label: all_new_labels.append(self) def check_is_in_file(self): - """ This method checks if the label appears in the file - based on the entries to the Asm.parts list. + """ + This method checks if the label appears in the file based on the + entries to the Asm.parts list. """ # assert new_asm != None, "new_asm should be an instance of Asm" load_asm2() @@ -7416,18 +7446,19 @@ class Label: return is_in_file def check_address_is_in_file(self): - """ Checks if the address is in use by another label. + """ + Checks if the address is in use by another label. """ load_asm2() self.address_is_in_file = new_asm.does_address_have_label(self.address) return self.address_is_in_file def old_check_address_is_in_file(self): - """ Checks whether or not the address of the object is - already in the file. This might happen if the label name - is different but the address is the same. Another scenario - is that the label is already used, but at a different - address. + """ + Checks whether or not the address of the object is already in the file. + This might happen if the label name is different but the address is the + same. Another scenario is that the label is already used, but at a + different address. This method works by looking at the INCBINs. When there is an INCBIN that covers this address in the file, then there @@ -7447,7 +7478,8 @@ class Label: return False def make_label(self): - """ Generates a label name based on parents and self.object. + """ + Generates a label name based on parents and self.object. """ object = self.object name = object.make_label() diff --git a/extras/gfx.py b/extras/gfx.py index 3d8e950bc..8b9a66ff1 100644 --- a/extras/gfx.py +++ b/extras/gfx.py @@ -1440,6 +1440,7 @@ def mass_to_colored_png(debug=False): to_png(os.path.join(root, name), None, os.path.join(root, os.path.splitext(name)[0]+'.pal')) else: to_png(os.path.join(root, name)) + os.touch(os.path.join(root, name)) # only monster and trainer pics for now for root, dirs, files in os.walk('../gfx/pics/'): @@ -1450,11 +1451,14 @@ def mass_to_colored_png(debug=False): to_png(os.path.join(root, name), None, os.path.join(root, 'normal.pal')) else: to_png(os.path.join(root, name)) + os.touch(os.path.join(root, name)) + for root, dirs, files in os.walk('../gfx/trainers/'): for name in files: if debug: print os.path.splitext(name), os.path.join(root, name) if os.path.splitext(name)[1] == '.2bpp': to_png(os.path.join(root, name), None, os.path.join(root, name[:-5]+'.pal')) + os.touch(os.path.join(root, name)) def mass_decompress(debug=False): @@ -1479,6 +1483,7 @@ def mass_decompress(debug=False): else: with open(os.path.join(root, name), 'rb') as lz: de = Decompressed(lz.read()) to_file(os.path.join(root, os.path.splitext(name)[0]+'.2bpp'), de.output) + os.touch(os.path.join(root, name)) def append_terminator_to_lzs(directory): # fix lzs that were extracted with a missing terminator @@ -1492,8 +1497,25 @@ def append_terminator_to_lzs(directory): new.write(data) new.close() - - +def lz_to_png_by_file(filename): + """ + Converts a lz file to png. Dumps a 2bpp file too. + """ + assert filename[-3:] == ".lz" + lz_data = open(filename, "rb").read() + bpp = Decompressed(lz).output + bpp_filename = filename.replace(".lz", ".2bpp") + to_file(bpp_filename, bpp) + to_png(bpp_filename) + +def dump_tileset_pngs(): + """ + Converts .lz format tilesets into .png format tilesets. Also, leaves a + bunch of wonderful .2bpp files everywhere for your amusement. + """ + for tileset_id in range(37): + tileset_filename = "../gfx/tilesets/" + str(tileset_id).zfill(2) + ".lz" + lz_to_png_by_file(tileset_filename) if __name__ == "__main__": parser = argparse.ArgumentParser() diff --git a/extras/graph.py b/extras/graph.py index b5450835f..47087e5cf 100644 --- a/extras/graph.py +++ b/extras/graph.py @@ -10,7 +10,8 @@ from romstr import ( ) class RomGraph(nx.DiGraph): - """ Graphs various functions pointing to each other. + """ + Graphs various functions pointing to each other. TODO: Bank switches are nasty. They should be detected. Otherwise, functions will point to non-functions within the same bank. Another way @@ -35,7 +36,8 @@ class RomGraph(nx.DiGraph): rompath = "../baserom.gbc" def __init__(self, rom=None, **kwargs): - """ Loads and parses the ROM into a function graph. + """ + Loads and parses the ROM into a function graph. """ # continue the initialization nx.DiGraph.__init__(self, **kwargs) @@ -50,14 +52,16 @@ class RomGraph(nx.DiGraph): self.parse() def load_rom(self): - """ Creates a RomStr from rompath. + """ + Creates a RomStr from rompath. """ file_handler = open(self.rompath, "r") self.rom = RomStr(file_handler.read()) file_handler.close() def parse(self): - """ Parses the ROM starting with the first function address. Each + """ + Parses the ROM starting with the first function address. Each function is disassembled and parsed to find where else it leads to. """ functions = {} @@ -123,13 +127,15 @@ class RomGraph(nx.DiGraph): self.functions = functions def pretty_printer(self): - """ Shows some text output describing which nodes point to which other - nodes. + """ + Shows some text output describing which nodes point to which other + nodes. """ print self.edges() def to_d3(self): - """ Exports to d3.js because we're gangster like that. + """ + Exports to d3.js because we're gangster like that. """ import networkx.readwrite.json_graph as json_graph content = json_graph.dumps(self) @@ -138,12 +144,14 @@ class RomGraph(nx.DiGraph): fh.close() def to_gephi(self): - """ Generates a gexf file. + """ + Generates a gexf file. """ nx.write_gexf(self, "graph.gexf") class RedGraph(RomGraph): - """ Not implemented. Go away. + """ + Not implemented. Go away. """ rompath = "../pokered-baserom.gbc" diff --git a/extras/item_constants.py b/extras/item_constants.py index a0506375d..929c599f8 100644 --- a/extras/item_constants.py +++ b/extras/item_constants.py @@ -159,7 +159,7 @@ item_constants = { 180: 'BRICK_PIECE', 181: 'SURF_MAIL', 182: 'LITEBLUEMAIL', -183: 'PORTRAITM_AIL', +183: 'PORTRAITMAIL', 184: 'LOVELY_MAIL', 185: 'EON_MAIL', 186: 'MORPH_MAIL', diff --git a/extras/labels.py b/extras/labels.py index e57c6e2f3..61ec4c29a 100644 --- a/extras/labels.py +++ b/extras/labels.py @@ -130,7 +130,8 @@ def line_has_comment_address(line, returnable={}, bank=None): return True def get_address_from_line_comment(line, bank=None): - """ wrapper for line_has_comment_address + """ + wrapper for line_has_comment_address """ returnable = {} result = line_has_comment_address(line, returnable=returnable, bank=bank) diff --git a/extras/map_names.py b/extras/map_names.py index 599b377db..00cf452b9 100644 --- a/extras/map_names.py +++ b/extras/map_names.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -""" -""" # this is modified in crystal.py during run-time map_names = { diff --git a/extras/romstr.py b/extras/romstr.py index 5701f19ae..90c099f3d 100644 --- a/extras/romstr.py +++ b/extras/romstr.py @@ -32,7 +32,8 @@ end_08_scripts_with = [ spacing = "\t" class RomStr(str): - """ Simple wrapper to prevent a giant rom from being shown on screen. + """ + Simple wrapper to prevent a giant rom from being shown on screen. """ def __init__(self, *args, **kwargs): @@ -41,13 +42,15 @@ class RomStr(str): str.__init__(self) def __repr__(self): - """ Simplifies this object so that the output doesn't overflow stdout. + """ + Simplifies this object so that the output doesn't overflow stdout. """ return "RomStr(too long)" @classmethod def load(cls, filename=None, crystal=True, red=False): - """ Loads a ROM into a RomStr. + """ + Loads a ROM into a RomStr. """ if crystal and not red and not filename: file_handler = open("../baserom.gbc", "r") @@ -62,8 +65,9 @@ class RomStr(str): return RomStr(bytes) def load_labels(self, filename="labels.json"): - """ Loads labels from labels.json, or parses the source code file and - generates new labels. + """ + Loads labels from labels.json, or parses the source code file and + generates new labels. """ filename = os.path.join(os.path.dirname(__file__), filename) @@ -109,7 +113,8 @@ class RomStr(str): self.labels = json.read(open(filename, "r").read()) def get_address_for(self, label): - """ Returns the address of a label. This is slow and could be improved + """ + Returns the address of a label. This is slow and could be improved dramatically. """ label = str(label) @@ -119,18 +124,20 @@ class RomStr(str): return None def length(self): - """ len(self) + """ + len(self) """ return len(self) def len(self): - """ len(self) + """ + len(self) """ return self.length() def interval(self, offset, length, strings=True, debug=True): - """ returns hex values for the rom starting at offset until - offset+length + """ + returns hex values for the rom starting at offset until offset+length """ returnable = [] for byte in self[offset:offset+length]: @@ -141,16 +148,17 @@ class RomStr(str): return returnable def until(self, offset, byte, strings=True, debug=False): - """ Returns hex values from rom starting at offset until the given - byte. + """ + Returns hex values from rom starting at offset until the given byte. """ return self.interval(offset, self.find(chr(byte), offset) - offset, strings=strings) def to_asm(self, address, end_address=None, size=None, max_size=0x4000, debug=None): - """ Disassembles ASM at some address. This will stop disassembling when - either the end_address or size is met. Also, there's a maximum size - that will be parsed, so that large patches of data aren't parsed as - code. + """ + Disassembles ASM at some address. This will stop disassembling when + either the end_address or size is met. Also, there's a maximum size + that will be parsed, so that large patches of data aren't parsed as + code. """ if type(address) in [str, unicode] and "0x" in address: address = int(address, 16) @@ -185,16 +193,19 @@ class RomStr(str): #return DisAsm(start_address=start_address, end_address=end_address, size=size, max_size=max_size, debug=debug, rom=self) class AsmList(list): - """ Simple wrapper to prevent all asm lines from being shown on screen. + """ + Simple wrapper to prevent all asm lines from being shown on screen. """ def length(self): - """ len(self) + """ + len(self) """ return len(self) def __repr__(self): - """ Simplifies this object so that the output doesn't overflow stdout. + """ + Simplifies this object so that the output doesn't overflow stdout. """ return "AsmList(too long)" diff --git a/extras/trainers.py b/extras/trainers.py index 786454a8b..cf17b9883 100644 --- a/extras/trainers.py +++ b/extras/trainers.py @@ -83,7 +83,8 @@ trainer_group_names = { } def remove_parentheticals_from_trainer_group_names(): - """ Clean up the trainer group names. + """ + Clean up the trainer group names. """ i = 0 for (key, value) in trainer_group_names.items(): diff --git a/items/item_effects.asm b/items/item_effects.asm new file mode 100644 index 000000000..f60a666d4 --- /dev/null +++ b/items/item_effects.asm @@ -0,0 +1,1798 @@ +MasterBall: +UltraBall: +GreatBall: +PokeBall: +HeavyBall: +LevelBall: +LureBall: +FastBall: +FriendBall: +MoonBall: +LoveBall: +ParkBall: ; e8a2 + ld a, [IsInBattle] + dec a + jp nz, $77a0 + ld a, [PartyCount] + cp $6 + jr nz, .asm_e8c0 + ld a, $1 + call GetSRAMBank + + ld a, [$ad10] + cp $14 + call CloseSRAM + + jp z, $77dc + +.asm_e8c0 + xor a + ld [$c64e], a + ld a, [CurItem] + cp $b1 + call nz, $6dfa + + ld hl, Options + res 4, [hl] + ld hl, $783d + call $1057 + + ld a, [EnemyMonCatchRate] + ld b, a + ld a, [BattleType] + cp $3 + jp z, .asm_e99c + ld a, [CurItem] + cp $1 + jp z, .asm_e99c + ld a, [CurItem] + ld c, a + ld hl, Table_0xec0a + +.asm_e8f2 + ld a, [hli] + cp $ff + jr z, .asm_e906 + cp c + jr z, .asm_e8fe + inc hl + inc hl + jr .asm_e8f2 + +.asm_e8fe + ld a, [hli] + ld h, [hl] + ld l, a + ld de, $6906 + push de + jp [hl] + +.asm_e906 + ld a, [CurItem] + cp $9f + ld a, b + jp z, $698e + ld a, b + ld [$ffb6], a + ld hl, EnemyMonHPHi + ld b, [hl] + inc hl + ld c, [hl] + inc hl + ld d, [hl] + inc hl + ld e, [hl] + sla c + rl b + ld h, d + ld l, e + add hl, de + add hl, de + ld d, h + ld e, l + ld a, d + and a + jr z, .asm_e940 + srl d + rr e + srl d + rr e + srl b + rr c + srl b + rr c + ld a, c + and a + jr nz, .asm_e940 + ld c, $1 + +.asm_e940 + ld b, e + push bc + ld a, b + sub c + ld [hMultiplier], a + xor a + ld [hProduct], a + ld [hMultiplicand], a + ld [$ffb5], a + call Multiply + + pop bc + ld a, b + ld [hMultiplier], a + ld b, $4 + call Divide + + ld a, [$ffb6] + and a + jr nz, .asm_e960 + ld a, $1 + +.asm_e960 + ld b, a + ld a, [EnemyMonStatus] + and $27 + ld c, $a + jr nz, .asm_e971 + and a + ld c, $5 + jr nz, .asm_e971 + ld c, $0 + +.asm_e971 + ld a, b + add c + jr nc, .asm_e977 + ld a, $ff + +.asm_e977 + ld d, a + push de + ld a, [BattleMonItem] + ld a, $d + ld hl, $7dd0 + rst FarCall + + ld a, b + cp $46 + pop de + ld a, d + jr nz, .asm_e98e + add c + jr nc, .asm_e98e + ld a, $ff + +.asm_e98e + ld b, a + ld [MagikarpLength], a + call RNG + + cp b + ld a, $0 + jr z, .asm_e99c + jr nc, .asm_e99f + +.asm_e99c + ld a, [EnemyMonSpecies] + +.asm_e99f + ld [$c64e], a + ld c, $14 + call DelayFrames + + ld a, [CurItem] + cp $6 + jr c, .asm_e9b0 + + ld a, $5 + +.asm_e9b0 + ld [$c689], a + ld de, $0100 + ld a, e + ld [FXAnimIDLo], a + ld a, d + ld [FXAnimIDHi], a + xor a + ld [hBattleTurn], a + ld [Buffer2], a + ld [$cfca], a + ld a, $37 + call Predef + + ld a, [$c64e] + and a + jr nz, .asm_e9f5 + ld a, [Buffer2] + cp $1 + ld hl, $6db5 + jp z, $6bdc + cp $2 + ld hl, $6dba + jp z, $6bdc + cp $3 + ld hl, $6dbf + jp z, $6bdc + cp $4 + ld hl, $6dc4 + jp z, $6bdc + +.asm_e9f5 + ld hl, EnemyMonStatus + ld a, [hli] + push af + inc hl + ld a, [hli] + push af + ld a, [hl] + push af + push hl + ld hl, EnemyMonItem + ld a, [hl] + push af + push hl + ld hl, EnemySubStatus5 + ld a, [hl] + push af + set 3, [hl] + bit 3, a + jr nz, .asm_ea13 + jr .asm_ea1a + +.asm_ea13 + ld a, $84 + ld [TempEnemyMonSpecies], a + jr .asm_ea27 + +.asm_ea1a + set 3, [hl] + ld hl, $c6f2 + ld a, [EnemyMonAtkDefDV] + ld [hli], a + ld a, [EnemyMonSpdSpclDV] + ld [hl], a + +.asm_ea27 + ld a, [TempEnemyMonSpecies] + ld [CurPartySpecies], a + ld a, [EnemyMonLevel] + ld [CurPartyLevel], a + ld a, $f + ld hl, $68eb + rst FarCall + + pop af + ld [EnemySubStatus5], a + pop hl + pop af + ld [hl], a + pop hl + pop af + ld [hld], a + pop af + ld [hld], a + dec hl + pop af + ld [hl], a + ld hl, EnemySubStatus5 + bit 3, [hl] + jr nz, .asm_ea67 + ld hl, $c735 + ld de, EnemyMonMove1 + ld bc, $0004 + call CopyBytes + + ld hl, $c739 + ld de, EnemyMonPPMove1 + ld bc, $0004 + call CopyBytes + +.asm_ea67 + ld a, [EnemyMonSpecies] + ld [$c64e], a + ld [CurPartySpecies], a + ld [$d265], a + ld a, [BattleType] + cp $3 + jp z, $6bd9 + ld a, $41 + ld hl, $607f + rst FarCall + + ld hl, $6dc9 + call $1057 + + call ClearSprites + + ld a, [$d265] + dec a + call $3393 + + ld a, c + push af + ld a, [$d265] + dec a + call $3380 + + pop af + and a + jr nz, .asm_eab7 + call $2ead + + jr z, .asm_eab7 + ld hl, $6df0 + call $1057 + + call ClearSprites + + ld a, [EnemyMonSpecies] + ld [$d265], a + ld a, $43 + call Predef + +.asm_eab7 + ld a, [BattleType] + cp $6 + jp z, $6bd1 + cp $b + jr nz, .asm_eac8 + ld hl, $d0ee + set 6, [hl] + +.asm_eac8 + ld a, [PartyCount] + cp $6 + jr z, .asm_eb3c + xor a + ld [MonType], a + call ClearSprites + + ld a, $6 + call Predef + + ld a, $13 + ld hl, $5b49 + rst FarCall + + ld a, [CurItem] + cp $a4 + jr nz, .asm_eaf8 + ld a, [PartyCount] + dec a + ld hl, PartyMon1Happiness + ld bc, $0030 + call AddNTimes + + ld a, $c8 + ld [hl], a + +.asm_eaf8 + ld hl, $6df5 + call $1057 + + ld a, [CurPartySpecies] + ld [$d265], a + call $343b + + call $1dcf + + jp c, $6be2 + + ld a, [PartyCount] + dec a + ld [CurPartyMon], a + ld hl, PartyMon1Nickname + ld bc, $000b + call AddNTimes + + ld d, h + ld e, l + push de + xor a + ld [MonType], a + ld b, $0 + ld a, $4 + ld hl, $56c1 + rst FarCall + + call $04b6 + + call $0e51 + + pop hl + ld de, StringBuffer1 + call $2ef9 + + jp $6be2 + +.asm_eb3c + call ClearSprites + + ld a, $9 + call Predef + + ld a, $13 + ld hl, $5b83 + rst FarCall + + ld a, $1 + call GetSRAMBank + + ld a, [$ad10] + cp $14 + jr nz, .asm_eb5b + ld hl, $d0ee + set 7, [hl] + +.asm_eb5b + ld a, [CurItem] + cp $a4 + jr nz, .asm_eb67 + ld a, $c8 + ld [$ad41], a + +.asm_eb67 + call CloseSRAM + + ld hl, $6df5 + call $1057 + + ld a, [CurPartySpecies] + ld [$d265], a + call $343b + + call $1dcf + + jr c, .asm_ebaf + + xor a + ld [CurPartyMon], a + ld a, $2 + ld [MonType], a + ld de, $d050 + ld b, $0 + ld a, $4 + ld hl, $56c1 + rst FarCall + + ld a, $1 + call GetSRAMBank + + ld hl, $d050 + ld de, $b082 + ld bc, $000b + call CopyBytes + + ld hl, $b082 + ld de, StringBuffer1 + call $2ef9 + + call CloseSRAM + +.asm_ebaf + ld a, $1 + call GetSRAMBank + + ld hl, $b082 + ld de, $d050 + ld bc, $000b + call CopyBytes + + call CloseSRAM + + ld hl, $6deb + call $1057 + + call $04b6 + + call $0e51 + + jr .asm_ebe2 + + ld a, $3 + ld hl, $66ce + rst FarCall + + jr .asm_ebe2 + + ld hl, $6dc9 + call $1057 + + call ClearSprites + +.asm_ebe2 + ld a, [BattleType] + cp $3 + ret z + cp $2 + ret z + cp $6 + jr z, .asm_ec05 + ld a, [$c64e] + and a + jr z, .asm_ebfb + call WhiteBGMap + + call ClearTileMap + +.asm_ebfb + ld hl, NumItems + inc a + ld [$d10c], a + jp $2f53 + +.asm_ec05 + ld hl, $dc79 + dec [hl] + ret +; ec0a + + +Table_0xec0a: ; ec0a + dbw ULTRA_BALL, Function_0xec29 + dbw GREAT_BALL, Function_0xec2f + dbw MOON_STONE, Function_0xec2f + dbw HEAVY_BALL, Function_0xec50 + dbw LEVEL_BALL, Function_0xed8c + dbw LURE_BALL, Function_0xeccc + dbw FAST_BALL, Function_0xed68 + dbw MOON_BALL, Function_0xecdd + dbw LOVE_BALL, Function_0xed12 + dbw PARK_BALL, Function_0xec2f + db $ff +; ec29 + + +Function_0xec29: ; ec29 + sla b + ret nc + ld b, $ff + ret +; ec2f + + +Function_0xec2f: ; ec2f + ld a, b + srl a + add b + ld b, a + ret nc + ld b, $ff + ret +; ec38 + + +INCBIN "baserom.gbc", $ec38, $ec50 - $ec38 + + +Function_0xec50: ; ec50 + ld a, [EnemyMonSpecies] + ld hl, $4378 + dec a + ld e, a + ld d, $0 + add hl, de + add hl, de + ld a, $11 + call GetFarHalfword + +.asm_ec61 + call $6c38 + + call GetFarByte + + inc hl + cp $50 + jr nz, .asm_ec61 + call $6c38 + + push bc + inc hl + inc hl + call GetFarHalfword + + srl h + rr l + ld b, h + ld c, l + srl b + rr c + srl b + rr c + srl b + rr c + srl b + rr c + call $6c99 + + srl b + rr c + call $6c99 + + ld a, h + pop bc + jr .asm_eca4 + + push bc + ld a, b + cpl + ld b, a + ld a, c + cpl + ld c, a + inc bc + add hl, bc + pop bc + ret + +.asm_eca4 + ld c, a + cp $4 + jr c, .asm_ecbc + + ld hl, $6cc4 + +.asm_ecac + ld a, c + cp [hl] + jr c, .asm_ecb4 + + inc hl + inc hl + jr .asm_ecac + +.asm_ecb4 + inc hl + ld a, b + add [hl] + ld b, a + ret nc + ld b, $ff + ret + +.asm_ecbc + ld a, b + sub $14 + ld b, a + ret nc + ld b, $1 + ret +; ecc4 + + +INCBIN "baserom.gbc", $ecc4, $eccc - $ecc4 + + +Function_0xeccc: ; eccc + ld a, [BattleType] + cp $4 + ret nz + ld a, b + add a + jr c, .asm_ecd9 + + add b + jr nc, .asm_ecdb + +.asm_ecd9 + ld a, $ff + +.asm_ecdb + ld b, a + ret +; ecdd + + +Function_0xecdd: ; ecdd + push bc + ld a, [TempEnemyMonSpecies] + dec a + ld c, a + ld b, $0 + ld hl, $65b1 + add hl, bc + add hl, bc + ld a, $10 + call GetFarHalfword + + pop bc + push bc + ld a, $10 + call GetFarByte + + cp $2 + pop bc + ret nz + inc hl + inc hl + inc hl + push bc + ld a, $10 + call GetFarByte + + cp $a + pop bc + ret nz + sla b + jr c, .asm_ed0f + + sla b + jr nc, .asm_ed11 + +.asm_ed0f + ld b, $ff + +.asm_ed11 + ret +; ed12 + + +Function_0xed12: ; ed12 + ld a, [TempEnemyMonSpecies] + ld c, a + ld a, [TempBattleMonSpecies] + cp c + ret nz + push bc + ld a, [TempBattleMonSpecies] + ld [CurPartySpecies], a + xor a + ld [MonType], a + ld a, [CurBattleMon] + ld [CurPartyMon], a + ld a, $14 + ld hl, $4bdd + rst FarCall + + jr c, .asm_ed66 + + ld d, $0 + jr nz, .asm_ed39 + inc d + +.asm_ed39 + push de + ld a, [TempEnemyMonSpecies] + ld [CurPartySpecies], a + ld a, $4 + ld [MonType], a + ld a, $14 + ld hl, $4bdd + rst FarCall + + jr c, .asm_ed65 + + ld d, $0 + jr nz, .asm_ed52 + inc d + +.asm_ed52 + ld a, d + pop de + cp d + pop bc + ret nz + sla b + jr c, .asm_ed62 + + sla b + jr c, .asm_ed62 + + sla b + ret nc + +.asm_ed62 + ld b, $ff + ret + +.asm_ed65 + pop de + +.asm_ed66 + pop bc + ret +; ed68 + + +Function_0xed68: ; ed68 + ld a, [TempEnemyMonSpecies] + ld c, a + ld hl, $459a + ld d, $3 + +.asm_ed71 + ld a, $f + call GetFarByte + + inc hl + cp $ff + jr z, .asm_ed88 + cp c + jr nz, .asm_ed88 + sla b + jr c, .asm_ed85 + + sla b + ret nc + +.asm_ed85 + ld b, $ff + ret + +.asm_ed88 + dec d + jr nz, .asm_ed71 + ret +; ed8c + + +Function_0xed8c: ; ed8c + ld a, [BattleMonLevel] + ld c, a + ld a, [EnemyMonLevel] + cp c + ret nc + sla b + jr c, .asm_eda8 + + srl c + cp c + ret nc + sla b + jr c, .asm_eda8 + + srl c + cp c + ret nc + sla b + ret nc + +.asm_eda8 + ld b, $ff + ret +; edab + + +INCBIN "baserom.gbc", $edab, $ee01 - $edab + + +Item06: ; ee01 + ld a, $24 + ld hl, $5ae1 + rst FarCall + ret +; ee08 + + +Bicycle: ; ee08 + ld a, $3 + ld hl, $50b3 + rst FarCall + ret +; ee0f + + +MoonStone: +FireStone: +Thunderstone: +WaterStone: +LeafStone: +SunStone: ; ee0f + ld b, $5 + call $71f9 + + jp c, $6e38 + + ld a, $1 + call GetPartyParamLocation + + ld a, [hl] + cp $70 + jr z, .asm_ee35 + ld a, $1 + ld [$d1e9], a + ld a, $10 + ld hl, $61d8 + rst FarCall + + ld a, [$d268] + and a + jr z, .asm_ee35 + jp $7795 + +.asm_ee35 + call $77f2 + + xor a + ld [$d0ec], a + ret +; ee3d + + +HpUp: +Protein: +Iron: +Carbos: +Calcium: ; ee3d + ld b, $1 + call $71f9 + + jp c, $6e9f + + call $6ef5 + + call $6ed9 + + ld a, $b + call GetPartyParamLocation + + add hl, bc + ld a, [hl] + cp $64 + jr nc, .asm_ee83 + add $a + ld [hl], a + call $6e8c + + call $6ed9 + + ld hl, $6eab + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + ld de, StringBuffer2 + ld bc, $000d + call CopyBytes + + call $7780 + + ld hl, $6ea6 + call $1057 + + ld c, $2 + ld a, $1 + ld hl, $71c2 + rst FarCall + + jp $7795 + +.asm_ee83 + ld hl, $781f + call $1057 + + jp ClearPalettes +; ee8c + + +INCBIN "baserom.gbc", $ee8c, $ef14 - $ee8c + + +RareCandy: ; ef14 + ld b, $1 + call $71f9 + + jp c, $6e9f + + call $6ef5 + + ld a, $1f + call GetPartyParamLocation + + ld a, [hl] + cp $64 + jp nc, $6e83 + inc a + ld [hl], a + ld [CurPartyLevel], a + push de + ld d, a + ld a, $14 + ld hl, $4e47 + rst FarCall + + pop de + ld a, $8 + call GetPartyParamLocation + + ld a, [hMultiplicand] + ld [hli], a + ld a, [$ffb5] + ld [hli], a + ld a, [$ffb6] + ld [hl], a + ld a, $24 + call GetPartyParamLocation + + ld a, [hli] + ld b, a + ld c, [hl] + push bc + call $6e8c + + ld a, $25 + call GetPartyParamLocation + + pop bc + ld a, [hld] + sub c + ld c, a + ld a, [hl] + sbc b + ld b, a + dec hl + ld a, [hl] + add c + ld [hld], a + ld a, [hl] + adc b + ld [hl], a + ld a, $9 + ld hl, $709e + rst FarCall + + ld a, $f8 + call $724a + + xor a + ld [MonType], a + ld a, $1f + call Predef + + ld hl, $c4a9 + ld b, $a + ld c, $9 + call $0fe8 + + ld hl, $c4bf + ld bc, $0004 + ld a, $28 + call Predef + + call $0a80 + + xor a + ld [MonType], a + ld a, [CurPartySpecies] + ld [$d265], a + ld a, $1a + call Predef + + xor a + ld [$d1e9], a + ld a, $10 + ld hl, $61d8 + rst FarCall + + jp $7795 +; efad + + +HealPowder: ; efad + ld b, $1 + call $71f9 + + jp c, $729e + + call $6fda + + cp $0 + jr nz, .asm_efc9 + ld c, $f + ld a, $1 + ld hl, $71c2 + rst FarCall + + call $77d6 + + ld a, $0 + +.asm_efc9 + jp $709e +; efcc + + +Antidote: +BurnHeal: +IceHeal: +Awakening: +ParlyzHeal: +FullHeal: +Psncureberry: +Przcureberry: +BurntBerry: +IceBerry: +MintBerry: +Miracleberry: ; efcc + ld b, $1 + call $71f9 + + jp c, $729e + + call $6fda + + jp $709e +; efda + + +INCBIN "baserom.gbc", $efda, $f0a9 - $efda + + +RevivalHerb: ; f0a9 + ld b, $1 + call $71f9 + + jp c, $729e + + call $70d6 + + cp $0 + jr nz, .asm_f0c5 + ld c, $11 + ld a, $1 + ld hl, $71c2 + rst FarCall + + call $77d6 + + ld a, $0 + +.asm_f0c5 + jp $709e +; f0c8 + + +Revive: +MaxRevive: ; f0c8 + ld b, $1 + call $71f9 + + jp c, $729e + + call $70d6 + + jp $709e +; f0d6 + + +INCBIN "baserom.gbc", $f0d6, $f128 - $f0d6 + + +FullRestore: ; f128 + ld b, $1 + call $71f9 + + jp c, $729e + + call $730d + + jp z, $7299 + call $731b + + jr c, .asm_f13e + + jp $6fd4 + +.asm_f13e + call $7144 + + jp $709e +; f144 + + +INCBIN "baserom.gbc", $f144, $f16a - $f144 + + +BitterBerry: ; f16a + ld hl, PlayerSubStatus3 + bit 7, [hl] + ld a, $1 + jr z, .asm_f183 + res 7, [hl] + xor a + ld [hBattleTurn], a + call $7789 + + ld hl, $4d81 + call FarBattleTextBox + + ld a, $0 + +.asm_f183 + jp $709e +; f186 + + +MaxPotion: +HyperPotion: +SuperPotion: +Potion: +FreshWater: +SodaPop: +Lemonade: +MoomooMilk: +Ragecandybar: +BerryJuice: +Berry: +GoldBerry: ; f186 + call $71a9 + jp $709e +; f18c + + +Energypowder: ; f18c + ld c, $f + jr Function_0xf192 +; f190 + +EnergyRoot: ; f190 + ld c, $10 +; f192 + +Function_0xf192: ; f192 + push bc + call $71a9 + + pop bc + cp $0 + jr nz, .asm_f1a6 + ld a, $1 + ld hl, $71c2 + rst FarCall + + call $77d6 + + ld a, $0 + +.asm_f1a6 + jp $709e +; f1a9 + + +INCBIN "baserom.gbc", $f1a9, $f44f - $f1a9 + + +EscapeRope: ; f44f + xor a + ld [$d0ec], a + ld a, $3 + ld hl, $4b95 + rst FarCall + + ld a, [$d0ec] + cp $1 + call z, $7795 + ret +; f462 + + +SuperRepel: ; f462 + ld b, $c8 + jr Function_0xf46c +; f466 + +MaxRepel: ; f466 + ld b, $fa + jr Function_0xf46c +; f466 + +Repel: ; f46a + ld b, $64 +; f46c + +Function_0xf46c: ; f46c + ld a, [$dca1] + and a + ld hl, $747d + jp nz, $1057 + ld a, b + ld [$dca1], a + jp $7789 +; f47d + + +INCBIN "baserom.gbc", $f47d, $f482 - $f47d + + +XAccuracy: ; f482 + ld hl, PlayerSubStatus4 + bit 0, [hl] + jp nz, $77ca + set 0, [hl] + jp $7789 +; f48f + + +PokeDoll: ; f48f + ld a, [IsInBattle] + dec a + jr nz, .asm_f4a6 + inc a + ld [$d232], a + ld a, [$d0ee] + and $c0 + or $2 + ld [$d0ee], a + jp $7789 + +.asm_f4a6 + xor a + ld [$d0ec], a + ret +; f4ab + + +GuardSpec: ; f4ab + ld hl, PlayerSubStatus4 + bit 1, [hl] + jp nz, $77ca + set 1, [hl] + jp $7789 +; f4b8 + + +DireHit: ; f4b8 + ld hl, PlayerSubStatus4 + bit 2, [hl] + jp nz, $77ca + set 2, [hl] + jp $7789 +; f4c5 + + +XAttack: +XDefend: +XSpeed: +XSpecial: ; f4c5 + call $7789 + + ld a, [CurItem] + ld hl, $7504 + +.asm_f4ce + cp [hl] + jr z, .asm_f4d5 + inc hl + inc hl + jr .asm_f4ce + +.asm_f4d5 + inc hl + ld b, [hl] + xor a + ld [hBattleTurn], a + ld [AttackMissed], a + ld [$c70d], a + ld a, $d + ld hl, $61ef + rst FarCall + + call WaitSFX + + ld a, $d + ld hl, $63b8 + rst FarCall + + ld a, $d + ld hl, $644c + rst FarCall + + ld a, [CurBattleMon] + ld [CurPartyMon], a + ld c, $3 + ld a, $1 + ld hl, $71c2 + rst FarCall + ret +; f504 + + +INCBIN "baserom.gbc", $f504, $f50c - $f504 + + +Item38: ; f50c + ld a, [IsInBattle] + and a + jr nz, .asm_f512 + +.asm_f512 + xor a + ld [DefaultFlypoint], a + ld b, $f8 + ld hl, PartyMon1Status + call .asm_f554 + + ld a, [IsInBattle] + cp $1 + jr z, .asm_f52b + ld hl, OTPartyMon1Status + call .asm_f554 + +.asm_f52b + ld hl, BattleMonStatus + ld a, [hl] + and b + ld [hl], a + ld hl, EnemyMonStatus + ld a, [hl] + and b + ld [hl], a + ld a, [DefaultFlypoint] + and a + ld hl, UnknownText_0xf56c + jp z, $1057 + ld hl, UnknownText_0xf576 + call $1057 + + ld a, [Danger] + and $80 + jr nz, .asm_f54e + +.asm_f54e + ld hl, UnknownText_0xf571 + jp $1057 + + +.asm_f554 + ld de, $0030 + ld c, $6 + +.asm_f559 + ld a, [hl] + push af + and $7 + jr z, .asm_f564 + ld a, $1 + ld [DefaultFlypoint], a + +.asm_f564 + pop af + and b + ld [hl], a + add hl, de + dec c + jr nz, .asm_f559 + ret +; f56c + + +UnknownText_0xf56c: ; 0xf56c + text_jump UnknownText_0x1c5bf9, BANK(UnknownText_0x1c5bf9) + db "@" +; 0xf571 + +UnknownText_0xf571: ; 0xf571 + text_jump UnknownText_0x1c5c28, BANK(UnknownText_0x1c5c28) + db "@" +; 0xf576 + +UnknownText_0xf576: ; 0xf576 + text_jump UnknownText_0x1c5c44, BANK(UnknownText_0x1c5c44) + start_asm +; 0xf57b + + +Function_0xf57b: ; f57b + ld a, [IsInBattle] + and a + jr nz, .asm_f58c + + push de + ld de, SFX_POKEFLUTE + call WaitPlaySFX + call WaitSFX + pop de + +.asm_f58c + jp $13e0 +; f58f + + +BlueCard: ; f58f + ld hl, .bluecardtext + jp $2012 + +.bluecardtext + text_jump UnknownText_0x1c5c5e, BANK(UnknownText_0x1c5c5e) + db "@" +; f59a + + +CoinCase: ; f59a + ld hl, .coincasetext + jp $2012 + +.coincasetext + text_jump UnknownText_0x1c5c7b, BANK(UnknownText_0x1c5c7b) + db "@" +; f5a5 + + +OldRod: ; f5a5 + ld e, $0 + jr Function_0xf5b1 +; f5a9 + +GoodRod: ; f5a9 + ld e, $1 + jr Function_0xf5b1 +; f5ad + +SuperRod: ; f5ad + ld e, $2 + jr Function_0xf5b1 +; f5b1 + +Function_0xf5b1: ; f5b1 + ld a, $3 + ld hl, $4f8e + rst FarCall + ret +; f5b8 + + +Itemfinder: ; f5b8 + ld a, $4 + ld hl, $6580 + rst FarCall + ret +; f5bf + + +MaxElixer: +PpUp: +Ether: +MaxEther: +Elixer: +Mysteryberry: ; f5bf + ld a, [CurItem] + ld [DefaultFlypoint], a + +.asm_f5c5 + ld b, $1 + call $71f9 + + jp c, $76e0 + +.asm_f5cd + ld a, [DefaultFlypoint] + cp $15 + jp z, $76af + cp $41 + jp z, $76af + ld hl, $7725 + ld a, [DefaultFlypoint] + cp $3e + jr z, .asm_f5e7 + ld hl, $772a + +.asm_f5e7 + call $1057 + + ld a, [CurMoveNum] + push af + xor a + ld [CurMoveNum], a + ld a, $2 + ld [$d235], a + ld a, $f + ld hl, $64bc + rst FarCall + + pop bc + ld a, b + ld [CurMoveNum], a + jr nz, .asm_f5c5 + ld hl, PartyMon1Move1 + ld bc, $0030 + call $7963 + + push hl + ld a, [hl] + ld [$d265], a + call $34f8 + + call CopyName1 + + pop hl + ld a, [DefaultFlypoint] + cp $3e + jp nz, $76a7 + ld a, [hl] + cp $a6 + jr z, .asm_f62f + ld bc, $0015 + add hl, bc + ld a, [hl] + cp $c0 + jr c, .asm_f637 + +.asm_f62f + ld hl, $772f + call $1057 + + jr .asm_f5cd + +.asm_f637 + ld a, [hl] + add $40 + ld [hl], a + ld a, $1 + ld [$d265], a + call $784c + + call $7780 + + ld hl, $7734 + call $1057 + + call ClearPalettes + + jp $7795 +; f652 + + +INCBIN "baserom.gbc", $f652, $f73e - $f652 + + +Squirtbottle: ; f73e + ld a, $14 + ld hl, $4730 + rst FarCall + ret +; f745 + + +CardKey: ; f745 + ld a, $14 + ld hl, $4779 + rst FarCall + ret +; f74c + + +BasementKey: ; f74c + ld a, $14 + ld hl, $47b4 + rst FarCall + ret +; f753 + + +SacredAsh: ; f753 + ld a, $14 + ld hl, $47e6 + rst FarCall + + ld a, [$d0ec] + cp $1 + ret nz + call $7795 + ret +; f763 + + +NormalBox: ; f763 + ld c, $2c + jr Function_0xf769 +; f767 + +GorgeousBox: ; f767 + ld c, $2b +; f769 + +Function_0xf769: ; f769 + ld a, $9 + ld hl, $6f02 + rst FarCall + + ld hl, UnknownText_0xf778 + call $1057 + + jp $7795 +; f778 + +UnknownText_0xf778: ; 0xf778 + text_jump UnknownText_0x1c5d03, BANK(UnknownText_0x1c5d03) + db "@" +; 0xf77d + + + +Brightpowder: +Item19: +LuckyPunch: +MetalPowder: +Nugget: +Item2D: +Item32: +ExpShare: +SilverLeaf: +RedScale: +Secretpotion: +SSTicket: +MysteryEgg: +ClearBell: +SilverWing: +QuickClaw: +GoldLeaf: +SoftSand: +SharpBeak: +PoisonBarb: +KingsRock: +RedApricorn: +Tinymushroom: +BigMushroom: +Silverpowder: +BluApricorn: +Item5A: +AmuletCoin: +YlwApricorn: +GrnApricorn: +CleanseTag: +MysticWater: +Twistedspoon: +WhtApricorn: +Blackbelt: +BlkApricorn: +Item64: +PnkApricorn: +Blackglasses: +Slowpoketail: +PinkBow: +Stick: +SmokeBall: +Nevermeltice: +Magnet: +Pearl: +BigPearl: +Everstone: +SpellTag: +GsBall: +MiracleSeed: +ThickClub: +FocusBand: +Item78: +HardStone: +LuckyEgg: +MachinePart: +EggTicket: +LostItem: +Stardust: +StarPiece: +Pass: +Item87: +Item88: +Item89: +Charcoal: +ScopeLens: +Item8D: +Item8E: +MetalCoat: +DragonFang: +Item91: +Leftovers: +Item93: +Item94: +Item95: +DragonScale: +BerserkGene: +Item99: +Item9A: +Item9B: +FlowerMail: +ItemA2: +LightBall: +PolkadotBow: +ItemAB: +UpGrade: +ItemB0: +RainbowWing: +ItemB3: ; f77d + jp $77ed +; f780 + + + + @@ -5947,7 +5947,210 @@ Function0xd47f: ; d47f ; d486 -INCBIN "baserom.gbc", $d486, $fa0b - $d486 +INCBIN "baserom.gbc", $d486, $e722 - $d486 + + +DoItemEffect: ; e722 + ld a, [CurItem] + ld [$d265], a + call GetItemName + call CopyName1 + ld a, 1 + ld [$d0ec], a + ld a, [CurItem] + dec a + ld hl, ItemEffects + rst $28 + ret +; e73c + + +ItemEffects: ; e73c + dw MasterBall + dw UltraBall + dw Brightpowder + dw GreatBall + dw PokeBall + dw Item06 + dw Bicycle + dw MoonStone + dw Antidote + dw BurnHeal + dw IceHeal + dw Awakening + dw ParlyzHeal + dw FullRestore + dw MaxPotion + dw HyperPotion + dw SuperPotion + dw Potion + dw EscapeRope + dw Repel + dw MaxElixer + dw FireStone + dw Thunderstone + dw WaterStone + dw Item19 + dw HpUp + dw Protein + dw Iron + dw Carbos + dw LuckyPunch + dw Calcium + dw RareCandy + dw XAccuracy + dw LeafStone + dw MetalPowder + dw Nugget + dw PokeDoll + dw FullHeal + dw Revive + dw MaxRevive + dw GuardSpec + dw SuperRepel + dw MaxRepel + dw DireHit + dw Item2D + dw FreshWater + dw SodaPop + dw Lemonade + dw XAttack + dw Item32 + dw XDefend + dw XSpeed + dw XSpecial + dw CoinCase + dw Itemfinder + dw Item38 + dw ExpShare + dw OldRod + dw GoodRod + dw SilverLeaf + dw SuperRod + dw PpUp + dw Ether + dw MaxEther + dw Elixer + dw RedScale + dw Secretpotion + dw SSTicket + dw MysteryEgg + dw ClearBell + dw SilverWing + dw MoomooMilk + dw QuickClaw + dw Psncureberry + dw GoldLeaf + dw SoftSand + dw SharpBeak + dw Przcureberry + dw BurntBerry + dw IceBerry + dw PoisonBarb + dw KingsRock + dw BitterBerry + dw MintBerry + dw RedApricorn + dw Tinymushroom + dw BigMushroom + dw Silverpowder + dw BluApricorn + dw Item5A + dw AmuletCoin + dw YlwApricorn + dw GrnApricorn + dw CleanseTag + dw MysticWater + dw Twistedspoon + dw WhtApricorn + dw Blackbelt + dw BlkApricorn + dw Item64 + dw PnkApricorn + dw Blackglasses + dw Slowpoketail + dw PinkBow + dw Stick + dw SmokeBall + dw Nevermeltice + dw Magnet + dw Miracleberry + dw Pearl + dw BigPearl + dw Everstone + dw SpellTag + dw Ragecandybar + dw GsBall + dw BlueCard + dw MiracleSeed + dw ThickClub + dw FocusBand + dw Item78 + dw Energypowder + dw EnergyRoot + dw HealPowder + dw RevivalHerb + dw HardStone + dw LuckyEgg + dw CardKey + dw MachinePart + dw EggTicket + dw LostItem + dw Stardust + dw StarPiece + dw BasementKey + dw Pass + dw Item87 + dw Item88 + dw Item89 + dw Charcoal + dw BerryJuice + dw ScopeLens + dw Item8D + dw Item8E + dw MetalCoat + dw DragonFang + dw Item91 + dw Leftovers + dw Item93 + dw Item94 + dw Item95 + dw Mysteryberry + dw DragonScale + dw BerserkGene + dw Item99 + dw Item9A + dw Item9B + dw SacredAsh + dw HeavyBall + dw FlowerMail + dw LevelBall + dw LureBall + dw FastBall + dw ItemA2 + dw LightBall + dw FriendBall + dw MoonBall + dw LoveBall + dw NormalBox + dw GorgeousBox + dw SunStone + dw PolkadotBow + dw ItemAB + dw UpGrade + dw Berry + dw GoldBerry + dw Squirtbottle + dw ItemB0 + dw ParkBall + dw RainbowWing + dw ItemB3 +; e8a2 + +INCLUDE "items/item_effects.asm" + + +INCBIN "baserom.gbc", $f780, $fa0b - $f780 SECTION "bank4",DATA,BANK[$4] diff --git a/preprocessor.py b/preprocessor.py index 48906da5e..67e4cdb9f 100644 --- a/preprocessor.py +++ b/preprocessor.py @@ -307,7 +307,8 @@ chars = { } def separate_comment(l): - """ Separates asm and comments on a single line. + """ + Separates asm and comments on a single line. """ asm = "" @@ -336,7 +337,8 @@ def separate_comment(l): return asm, comment def quote_translator(asm): - """ Writes asm with quoted text translated into bytes. + """ + Writes asm with quoted text translated into bytes. """ # split by quotes @@ -350,6 +352,11 @@ def quote_translator(asm): sys.stdout.write(asm) return + print_macro = False + if asms[0].strip() == 'print': + asms[0] = asms[0].replace('print','db 0,') + print_macro = True + output = "" even = False i = 0 @@ -357,6 +364,7 @@ def quote_translator(asm): i = i + 1 if even: + characters = [] # token is a string to convert to byte values while len(token): # read a single UTF-8 codepoint @@ -391,10 +399,35 @@ def quote_translator(asm): char = char + token[0] token = token[1:] - output += ("${0:02X}".format(chars[char])) + characters += [char] + + if print_macro: + line = 0 + while len(characters): + last_char = 1 + if len(characters) > 18 and characters[-1] != '@': + for i, char in enumerate(characters): + last_char = i + 1 + if ' ' not in characters[i+1:18]: break + output += ", ".join("${0:02X}".format(chars[char]) for char in characters[:last_char-1]) + if characters[last_char-1] != " ": + output += ", ${0:02X}".format(characters[last_char-1]) + if not line & 1: + line_ending = 0x4f + else: + line_ending = 0x51 + output += ", ${0:02X}".format(line_ending) + line += 1 + else: + output += ", ".join(["${0:02X}".format(chars[char]) for char in characters[:last_char]]) + characters = characters[last_char:] + if len(characters): output += ", " + # end text + line_ending = 0x57 + output += ", ${0:02X}".format(line_ending) + + output += ", ".join(["${0:02X}".format(chars[char]) for char in characters]) - if len(token): - output += (", ") # if not even else: output += (token) @@ -414,7 +447,8 @@ def make_macro_table(): macro_table = make_macro_table() def macro_test(asm): - """ Returns a matching macro, or None/False. + """ + Returns a matching macro, or None/False. """ # macros are determined by the first symbol on the line @@ -427,7 +461,8 @@ def macro_test(asm): return (None, None) def macro_translator(macro, token, line): - """ Converts a line with a macro into a rgbasm-compatible line. + """ + Converts a line with a macro into a rgbasm-compatible line. """ assert macro.macro_name == token, "macro/token mismatch" |