summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan Bishop <kanzure@gmail.com>2013-09-01 19:34:50 -0700
committerBryan Bishop <kanzure@gmail.com>2013-09-01 19:34:50 -0700
commit2e6d805aea27741bc0e6097bd52c6f2b6d176b74 (patch)
treebb91bace929310f2787b80424fdada70bba94e81
parent7aa016fb528bcc8dcb30c6a887957851623eccc0 (diff)
parent52d4978974263f4f19985632442291c2d30c4b67 (diff)
Merge pull request #7 from kanzure/september-cleanup
python cleanup
-rw-r--r--pokemontools/crystal.py935
-rw-r--r--pokemontools/disassemble_map_scripts.py4
-rw-r--r--pokemontools/exceptions.py13
-rw-r--r--pokemontools/gbz80disasm.py1
-rw-r--r--pokemontools/gfx.py25
-rw-r--r--pokemontools/helpers.py51
-rw-r--r--pokemontools/labels.py9
-rw-r--r--redtools/gbz80disasm.py5
-rw-r--r--tests/integration/tests.py9
-rw-r--r--tests/tests.py7
10 files changed, 656 insertions, 403 deletions
diff --git a/pokemontools/crystal.py b/pokemontools/crystal.py
index 4941dc2..d6dba89 100644
--- a/pokemontools/crystal.py
+++ b/pokemontools/crystal.py
@@ -1,5 +1,8 @@
# -*- coding: utf-8 -*-
-# utilities to help disassemble pokémon crystal
+"""
+utilities to help disassemble pokémon crystal
+"""
+
import os
import sys
import inspect
@@ -9,6 +12,7 @@ from copy import copy, deepcopy
import subprocess
from new import classobj
import random
+import logging
# for capwords
import string
@@ -17,18 +21,6 @@ import string
if not hasattr(json, "dumps"):
json.dumps = json.write
-# New versions of json don't have read anymore.
-if not hasattr(json, "read"):
- json.read = json.loads
-
-from labels import (
- remove_quoted_text,
- line_has_comment_address,
- line_has_label,
- get_label_from_line,
- get_address_from_line_comment
-)
-
spacing = "\t"
lousy_dragon_shrine_hack = [0x18d079, 0x18d0a9, 0x18d061, 0x18d091]
@@ -47,9 +39,6 @@ trigger_byte_size = 8
signpost_byte_size = 5
people_event_byte_size = 13
-# a message to show with NotImplementedErrors
-bryan_message = "bryan hasn't got to this yet"
-
max_texts = 3
text_count = 0
texts = []
@@ -58,28 +47,21 @@ texts = []
# this doesn't do anything but is still used in TextScript
constant_abbreviation_bytes = {}
-# Import the characters from its module.
-from chars import chars, jap_chars
-
-from trainers import (
- trainer_group_pointer_table_address, # 0x39999
- trainer_group_pointer_table_address_gs, # 0x3993E
- trainer_group_names,
-)
+import helpers
+import chars
+import labels
+import pksv
+import romstr
+import pointers
+import interval_map
+import trainers
+import move_constants
+import pokemon_constants
+import item_constants
+import wram
+import exceptions
-from move_constants import moves
-
-# for fixing trainer_group_names
-import re
-
-from interval_map import IntervalMap
-
-from pksv import (
- pksv_gs,
- pksv_crystal,
- pksv_crystal_unknowns,
- pksv_crystal_more_enders
-)
+from map_names import map_names
# ---- script_parse_table explanation ----
# This is an IntervalMap that keeps track of previously parsed scripts, texts
@@ -93,7 +75,7 @@ from pksv import (
# keys are intervals "500..555" of byte addresses for each script
# last byte is not inclusive(?) really? according to who??
# this is how to make sure scripts are not recalculated
-script_parse_table = IntervalMap()
+script_parse_table = interval_map.IntervalMap()
def is_script_already_parsed_at(address):
"""looks up whether or not a script is parsed at a certain address"""
@@ -104,7 +86,7 @@ def is_script_already_parsed_at(address):
def script_parse_table_pretty_printer():
"""helpful debugging output"""
for each in script_parse_table.items():
- print each
+ logging.info("{0}".format(each))
def map_name_cleaner(input):
"""generate a valid asm label for a given map name"""
@@ -122,18 +104,13 @@ def map_name_cleaner(input):
replace("hooh", "HoOh").\
replace(" ", "")
-from romstr import (
- RomStr,
- AsmList,
-)
-
-rom = RomStr(None)
+rom = romstr.RomStr(None)
def direct_load_rom(filename="../baserom.gbc"):
"""loads bytes into memory"""
global rom
file_handler = open(filename, "rb")
- rom = RomStr(file_handler.read())
+ rom = romstr.RomStr(file_handler.read())
file_handler.close()
return rom
@@ -141,9 +118,9 @@ def load_rom(filename="../baserom.gbc"):
"""checks that the loaded rom matches the path
and then loads the rom if necessary."""
global rom
- if rom != RomStr(None) and rom != None:
+ if rom != romstr.RomStr(None) and rom != None:
return rom
- if not isinstance(rom, RomStr):
+ if not isinstance(rom, romstr.RomStr):
return direct_load_rom(filename=filename)
elif os.lstat(filename).st_size != len(rom):
return direct_load_rom(filename)
@@ -151,7 +128,7 @@ def load_rom(filename="../baserom.gbc"):
def direct_load_asm(filename="../main.asm"):
"""returns asm source code (AsmList) from a file"""
asm = open(filename, "r").read().split("\n")
- asm = AsmList(asm)
+ asm = romstr.AsmList(asm)
return asm
def load_asm(filename="../main.asm"):
@@ -160,12 +137,6 @@ def load_asm(filename="../main.asm"):
asm = direct_load_asm(filename=filename)
return asm
-def grouper(some_list, count=2):
- """splits a list into sublists
- given: [1, 2, 3, 4]
- returns: [[1, 2], [3, 4]]"""
- return [some_list[i:i+count] for i in range(0, len(some_list), count)]
-
def is_valid_address(address):
"""is_valid_rom_address"""
if address == None:
@@ -197,18 +168,13 @@ def load_map_group_offsets():
global rom
map_group_offsets = [] # otherwise this method can only be used once
data = rom_interval(map_group_pointer_table, map_group_count*2, strings=False)
- data = grouper(data)
+ data = helpers.grouper(data)
for pointer_parts in data:
pointer = pointer_parts[0] + (pointer_parts[1] << 8)
offset = pointer - 0x4000 + map_group_pointer_table
map_group_offsets.append(offset)
return map_group_offsets
-from pointers import (
- calculate_bank,
- calculate_pointer,
-)
-
def calculate_pointer_from_bytes_at(address, bank=False):
"""calculates a pointer from 2 bytes at a location
or 3-byte pointer [bank][2-byte pointer] if bank=True"""
@@ -216,7 +182,7 @@ def calculate_pointer_from_bytes_at(address, bank=False):
bank = ord(rom[address])
address += 1
elif bank == False or bank == None:
- bank = calculate_bank(address)
+ bank = pointers.calculate_bank(address)
elif bank == "reverse" or bank == "reversed":
bank = ord(rom[address+2])
elif type(bank) == int:
@@ -228,7 +194,7 @@ def calculate_pointer_from_bytes_at(address, bank=False):
temp = byte1 + (byte2 << 8)
if temp == 0:
return None
- return calculate_pointer(temp, bank)
+ return pointers.calculate_pointer(temp, bank)
def clean_up_long_info(long_info):
"""cleans up some data from parse_script_engine_script_at formatting issues"""
@@ -250,19 +216,11 @@ def clean_up_long_info(long_info):
long_info = "\n".join(new_lines)
return long_info
-from pokemon_constants import pokemon_constants
-
def get_pokemon_constant_by_id(id):
if id == 0:
- return None
+ return None
else:
- return pokemon_constants[id]
-
-from item_constants import (
- item_constants,
- find_item_label_by_id,
- generate_item_constants,
-)
+ return pokemon_constants.pokemon_constants[id]
def command_debug_information(command_byte=None, map_group=None, map_id=None, address=0, info=None, long_info=None, pksv_name=None):
"used to help debug in parse_script_engine_script_at"
@@ -337,7 +295,14 @@ class TextScript:
# don't clutter up my screen
if self.debug:
- print "NewTextScript.parse address="+hex(self.address)+" map_group="+str(self.map_group)+" map_id="+str(self.map_id)
+ logging.debug(
+ "NewTextScript.parse address={address} map_group={map_group} map_id={map_id}"
+ .format(
+ address=hex(self.address),
+ map_group=str(self.map_group),
+ map_id=self.map_id,
+ )
+ )
# load up the rom if it hasn't been loaded already
load_rom()
@@ -366,9 +331,16 @@ class TextScript:
if self.address == 0x9c00e and self.debug:
if current_address > 0x9c087:
- print "self.commands is: " + str(commands)
- print "command 0 address is: " + hex(commands[0].address) + " last_address="+hex(commands[0].last_address)
- print "command 1 address is: " + hex(commands[1].address) + " last_address="+hex(commands[1].last_address)
+ logging.debug("self.commands is: {commands}".format(commands=commands))
+ for num in [0, 1]:
+ logging.debug(
+ "command {id} address={address} last_address={last}"
+ .format(
+ id=str(num),
+ address=hex(commands[num].address),
+ last=hex(commands[num].last_address),
+ )
+ )
raise Exception("going beyond the bounds for this text script")
# no matching command found
@@ -379,7 +351,7 @@ class TextScript:
cls = scripting_command_class(address=current_address, map_group=self.map_group, map_id=self.map_id, debug=self.debug, force=self.force)
if self.debug:
- print cls.to_asm()
+ logging.debug(cls.to_asm())
# store it in this script object
commands.append(cls)
@@ -397,18 +369,25 @@ class TextScript:
self.last_address = current_address
if self.debug:
- print "cls.address is: " + hex(cls.address)
- print "cls.size is: " + hex(cls.size)
- print "cls.last_address is: " + hex(cls.last_address)
- print "self.last_address is: " + hex(self.last_address)
+ logging.debug("cls.address is {0}".format(hex(cls.address)))
+ logging.debug("cls.size is {0}".format(hex(cls.size)))
+ logging.debug("cls.last_address is {0}".format(hex(cls.last_address)))
+ logging.debug("self.last_address is {0}".format(hex(self.last_address)))
- assert self.last_address == (cls.address + cls.size), "the last address should equal the last command's (address + size)"
- assert self.last_address == cls.last_address, "the last address of the TextScript should be the last_address of its last command"
+ if self.last_address != (cls.address + cls.size):
+ raise exceptions.TextScriptException(
+ "the last address should equal the last command's (address + size)"
+ )
+
+ if self.last_address != cls.last_address:
+ raise exceptions.TextScriptException(
+ "the last address of the TextScript should be the last_address of its last command"
+ )
# just some debugging..
if self.debug:
last_address = self.last_address
- print "TextScript last_address == " + hex(last_address)
+ logging.debug("TextScript last_address == {0}".format(hex(last_address)))
#assert last_address != 0x5db06, "TextScript.parse somehow has a text with a last_address of 0x5db06 instead of 0x5db07"
# store the script in the global table/map thing
@@ -417,7 +396,7 @@ class TextScript:
if self.debug:
asm_output = "\n".join([command.to_asm() for command in commands])
- print "--------------\n"+asm_output
+ logging.debug("asm_output is:\n{0}".format(asm_output))
# store the script
self.commands = commands
@@ -496,7 +475,7 @@ class OldTextScript:
# dump this into script
script = trigger["script"]
# find all text pointers in script
- texts = find_all_text_pointers_in_script_engine_script(script, calculate_bank(trigger["address"]))
+ texts = find_all_text_pointers_in_script_engine_script(script, pointers.calculate_bank(trigger["address"]))
# dump these addresses in
addresses.update(texts)
# callback scripts
@@ -506,7 +485,7 @@ class OldTextScript:
# dump this into script
script = callback["script"]
# find all text pointers in script
- texts = find_all_text_pointers_in_script_engine_script(script, calculate_bank(callback["address"]))
+ texts = find_all_text_pointers_in_script_engine_script(script, pointers.calculate_bank(callback["address"]))
# dump these addresses in
addresses.update(texts)
# people-events
@@ -524,7 +503,7 @@ class OldTextScript:
trainer_data = event["trainer_data"]
addresses.update([trainer_data["text_when_seen_ptr"]])
addresses.update([trainer_data["text_when_trainer_beaten_ptr"]])
- trainer_bank = calculate_bank(event["trainer_data_address"])
+ trainer_bank = pointers.calculate_bank(event["trainer_data_address"])
script1 = trainer_data["script_talk_again"]
texts1 = find_all_text_pointers_in_script_engine_script(script1, trainer_bank)
addresses.update(texts1)
@@ -550,7 +529,7 @@ class OldTextScript:
commands = {}
if is_script_already_parsed_at(address) and not force:
- print "text is already parsed at this location: " + hex(address)
+ logging.debug("text is already parsed at this location: {0}".format(hex(address)))
raise Exception("text is already parsed, what's going on ?")
return script_parse_table[address]
@@ -565,7 +544,10 @@ class OldTextScript:
command = {}
command_byte = ord(rom[address])
if debug:
- print "TextScript.parse_script_at has encountered a command byte " + hex(command_byte) + " at " + hex(address)
+ logging.debug(
+ "TextScript.parse_script_at has encountered a command byte {0} at {1}"
+ .format(hex(command_byte), hex(address))
+ )
end_address = address + 1
if command_byte == 0:
# read until $57, $50 or $58
@@ -582,7 +564,7 @@ class OldTextScript:
if show and debug:
text = parse_text_at2(offset+1, end_address-offset+1, debug=debug)
- print text
+ logging.debug("output of parse_text_at2 is {0}".format(text))
command = {"type": command_byte,
"start_address": offset,
@@ -660,7 +642,15 @@ class OldTextScript:
# use this to look at the surrounding bytes
if debug:
- print "next command is: " + hex(ord(rom[offset])) + " ... we are at command number: " + str(command_counter) + " near " + hex(offset) + " on map_id=" + str(map_id)
+ logging.debug("next command is {0}".format(hex(ord(rom[offset]))))
+ logging.debug(
+ ".. current command number is {counter} near {offset} on map_id={map_id}"
+ .format(
+ counter=command_counter,
+ offset=hex(offset),
+ map_id=map_id,
+ )
+ )
elif command_byte == 0x7:
# 07 = shift texts 1 row above (2nd line becomes 1st line); address for next text = 2nd line. [07]
size = 1
@@ -702,7 +692,7 @@ class OldTextScript:
if show and debug:
text = parse_text_at2(offset+1, end_address-offset+1, debug=debug)
- print text
+ logging.debug("parse_text_at2 text is {0}".format(text))
command = {"type": command_byte,
"start_address": offset,
@@ -744,7 +734,14 @@ class OldTextScript:
#if len(commands) > 0:
# print "Unknown text command " + hex(command_byte) + " at " + hex(offset) + ", script began with " + hex(commands[0]["type"])
if debug:
- print "Unknown text command at " + hex(offset) + " - command: " + hex(ord(rom[offset])) + " on map_id=" + str(map_id)
+ logging.debug(
+ "Unknown text command at {offset} - command: {command} on map_id={map_id}"
+ .format(
+ offset=hex(offset),
+ command=hex(ord(rom[offset])),
+ map_id=map_id,
+ )
+ )
# end at the first unknown command
end = True
@@ -764,8 +761,6 @@ class OldTextScript:
return commands
def get_dependencies(self, recompute=False, global_dependencies=set()):
- #if recompute:
- # raise NotImplementedError(bryan_message)
global_dependencies.update(self.dependencies)
return self.dependencies
@@ -793,7 +788,7 @@ class OldTextScript:
if not "lines" in commands[this_command].keys():
command = commands[this_command]
if not "type" in command.keys():
- print "ERROR in command: " + str(command)
+ logging.debug("ERROR in command: {0}".format(command))
continue # dunno what to do here?
if command["type"] == 0x1: # TX_RAM
@@ -856,7 +851,7 @@ class OldTextScript:
byte_count += 1
had_db_last = True
else:
- print "ERROR in command: " + hex(command["type"])
+ logging.debug("ERROR in command: {0}".format(hex(command["type"])))
had_db_last = False
# everything else is for $0s, really
@@ -888,7 +883,7 @@ class OldTextScript:
if byte in [0x58, 0x57]:
had_text_end_byte_57_58 = True
- if byte in chars:
+ if byte in chars.chars:
if not quotes_open and not first_byte: # start text
output += ", \""
quotes_open = True
@@ -896,7 +891,7 @@ class OldTextScript:
if not quotes_open and first_byte: # start text
output += "\""
quotes_open = True
- output += chars[byte]
+ output += chars.chars[byte]
elif byte in constant_abbreviation_bytes:
if quotes_open:
output += "\""
@@ -962,7 +957,7 @@ class EncodedText:
if bank:
self.bank = bank
else:
- self.bank = calculate_bank(address)
+ self.bank = pointers.calculate_bank(address)
self.map_group, self.map_id, self.debug = map_group, map_id, debug
if not label:
label = self.base_label + hex(address)
@@ -1004,7 +999,13 @@ class EncodedText:
"""split this text up into multiple lines
based on subcommands ending each line"""
if debug:
- print "process_00_subcommands(" + hex(start_address) + ", " + hex(end_address) + ")"
+ logging.debug(
+ "process_00_subcommands({start}, {end})"
+ .format(
+ start=hex(start_address),
+ end=hex(end_address),
+ )
+ )
lines = {}
subsection = rom[start_address:end_address]
@@ -1027,15 +1028,15 @@ class EncodedText:
def from_bytes(bytes, debug=True, japanese=False):
"""assembles a string based on bytes looked up in the chars table"""
line = ""
- if japanese: charset = jap_chars
- else: charset = chars
+ if japanese: charset = chars.jap_chars
+ else: charset = chars.chars
for byte in bytes:
if type(byte) != int:
byte = ord(byte)
if byte in charset.keys():
line += charset[byte]
elif debug:
- print "byte not known: " + hex(byte)
+ logging.debug("byte not known: {0}".format(hex(byte)))
return line
@staticmethod
@@ -1153,9 +1154,9 @@ def generate_map_constants():
globals += "\n"
#for multi-byte constants:
#print each["label"] + " EQUS \"$%.2x,$%.2x\"" % (each["map_group"], each["map_id"])
- print globals
- print groups
- print maps
+ logging.debug("globals: {0}".format(globals))
+ logging.debug("groups: {0}".format(groups))
+ logging.debug("maps: {0}".format(maps))
def generate_map_constants_dimensions():
"""
@@ -1193,6 +1194,7 @@ def transform_wildmons(asm):
def parse_script_asm_at(*args, **kwargs):
# XXX TODO
+ logging.debug("TODO: parse_script_asm_at")
return None
def find_all_text_pointers_in_script_engine_script(script, bank=None, debug=False):
@@ -1204,7 +1206,7 @@ def find_all_text_pointers_in_script_engine_script(script, bank=None, debug=Fals
addresses = set()
for (k, command) in enumerate(script.commands):
if debug:
- print "command is: " + str(command)
+ logging.debug("command is: {0}".format(command))
if command.id == 0x4B:
addresses.add(command.params[0].parsed_address)
elif command.id == 0x4C:
@@ -1286,7 +1288,7 @@ HexByte=DollarSignByte
class ItemLabelByte(DollarSignByte):
def to_asm(self):
- label = find_item_label_by_id(self.byte)
+ label = item_constants.item_constants.find_item_label_by_id(self.byte)
if label:
return label
elif not label:
@@ -1420,10 +1422,10 @@ class PointerLabelParam(MultiByteParam):
else:
if "$" in label:
if 0x4000 <= caddress <= 0x7FFF:
- #bank_part = "$%.2x" % (calculate_bank(self.parent.parent.address))
+ #bank_part = "$%.2x" % (pointers.calculate_bank(self.parent.parent.address))
bank_part = "1"
else:
- bank_part = "$%.2x" % (calculate_bank(caddress))
+ bank_part = "$%.2x" % (pointers.calculate_bank(caddress))
else:
bank_part = "BANK("+label+")"
# return the asm based on the order the bytes were specified to be in
@@ -1463,10 +1465,18 @@ class ScriptPointerLabelAfterBank(PointerLabelAfterBank): pass
def _parse_script_pointer_bytes(self, debug = False):
PointerLabelParam.parse(self)
- if debug: print "_parse_script_pointer_bytes - calculating the pointer located at " + hex(self.address)
+ if debug:
+ logging.debug(
+ "_parse_script_pointer_bytes - calculating the pointer located at {0}"
+ .format(hex(self.address))
+ )
address = calculate_pointer_from_bytes_at(self.address, bank=self.bank)
if address != None and address > 0x4000:
- if debug: print "_parse_script_pointer_bytes - the pointer is: " + hex(address)
+ if debug:
+ logging.debug(
+ "_parse_script_pointer_bytes - the pointer is: {0}"
+ .format(hex(address))
+ )
self.script = parse_script_engine_script_at(address, debug=self.debug, force=self.force, map_group=self.map_group, map_id=self.map_id)
ScriptPointerLabelParam.parse = _parse_script_pointer_bytes
ScriptPointerLabelBeforeBank.parse = _parse_script_pointer_bytes
@@ -1606,7 +1616,6 @@ class PokemonParam(SingleByteParam):
class PointerParamToItemAndLetter(MultiByteParam):
# [2F][2byte pointer to item no + 0x20 bytes letter text]
- #raise NotImplementedError(bryan_message)
pass
@@ -1628,29 +1637,27 @@ class TrainerIdParam(SingleByteParam):
trainer_group_id = self.parent.params[foundit].byte
# check the rule to see whether to use an id or not
- if ("uses_numeric_trainer_ids" in trainer_group_names[trainer_group_id].keys()) or \
- (not "trainer_names" in trainer_group_names[trainer_group_id].keys()):
+ if ("uses_numeric_trainer_ids" in trainers.trainer_group_names[trainer_group_id].keys()) or \
+ (not "trainer_names" in trainers.trainer_group_names[trainer_group_id].keys()):
return str(self.byte)
else:
- return trainer_group_names[trainer_group_id]["trainer_names"][self.byte-1]
+ return trainers.trainer_group_names[trainer_group_id]["trainer_names"][self.byte-1]
class TrainerGroupParam(SingleByteParam):
def to_asm(self):
trainer_group_id = self.byte
- return trainer_group_names[trainer_group_id]["constant"]
+ return trainers.trainer_group_names[trainer_group_id]["constant"]
class MoveParam(SingleByteParam):
def to_asm(self):
- if self.byte in moves.keys():
- return moves[self.byte]
+ if self.byte in move_constants.moves.keys():
+ return move_constants.moves[self.byte]
else:
# this happens for move=0 (no move) in trainer headers
return str(self.byte)
class MenuDataPointerParam(PointerLabelParam):
- # read menu data at the target site
- #raise NotImplementedError(bryan_message)
- pass
+ """read menu data at the target site"""
string_to_text_texts = []
@@ -1658,7 +1665,7 @@ class RawTextPointerLabelParam(PointerLabelParam):
# not sure if these are always to a text script or raw text?
def parse(self):
PointerLabelParam.parse(self)
- #bank = calculate_bank(self.address)
+ #bank = pointers.calculate_bank(self.address)
address = calculate_pointer_from_bytes_at(self.address, bank=False)
self.calculated_address = address
#self.text = parse_text_at3(address, map_group=self.map_group, map_id=self.map_id, debug=self.debug)
@@ -1886,7 +1893,8 @@ class GivePoke(Command):
self.size = 1
for (key, param_type) in self.param_types.items():
# stop executing after the 4th byte unless it == 0x1
- if i == 4: print "self.params[3].byte is: " + str(self.params[3].byte)
+ if i == 4:
+ logging.debug("self.params[3].byte is: {0}".format(str(self.params[3].byte)))
if i == 4 and self.params[3].byte != 1: break
name = param_type["name"]
klass = param_type["class"]
@@ -2029,8 +2037,10 @@ def create_movement_commands(debug=False):
thing = {"name": each[0], "class": each[1]}
params["param_types"][i] = thing
if debug:
- print "each is: " + str(each)
- print "thing[class] is: " + str(thing["class"])
+ logging.debug(
+ "each is {0} and thing[class] is {1}"
+ .format(each, str(thing["class"]))
+ )
params["size"] += thing["class"].size
if byte <= 0x34:
@@ -2097,14 +2107,25 @@ class ApplyMovementData:
address = self.address
# i feel like checking myself
- assert is_valid_address(address), "ApplyMovementData.parse must be given a valid address"
+ if not is_valid_address(address):
+ raise exceptions.AddressException(
+ "ApplyMovementData.parse must be given a valid address (but got {0})."
+ .format(hex(address))
+ )
current_address = copy(self.address)
start_address = copy(current_address)
# don't clutter up my screen
if self.debug:
- print "ApplyMovementData.parse address="+hex(self.address)+" map_group="+str(self.map_group)+" map_id="+str(self.map_id)
+ logging.debug(
+ "ApplyMovementData.parse address={address} map_group={map_group} map_id={map_id}"
+ .format(
+ address=hex(self.address),
+ map_group=str(self.map_group),
+ map_id=str(self.map_id),
+ )
+ )
# load up the rom if it hasn't been loaded already
load_rom()
@@ -2155,7 +2176,7 @@ class ApplyMovementData:
cls = scripting_command_class(address=current_address, map_group=self.map_group, map_id=self.map_id, debug=self.debug, force=self.force)
if self.debug:
- print cls.to_asm()
+ logging.debug("cls.to_asm() is: {0}".format(cls.to_asm()))
# store it in this script object
commands.append(cls)
@@ -2177,7 +2198,7 @@ class ApplyMovementData:
if self.debug:
asm_output = "\n".join([command.to_asm() for command in commands])
- print "--------------\n"+asm_output
+ logging.debug("asm_output: {0}".format(asm_output))
# store the script
self.commands = commands
@@ -2276,11 +2297,16 @@ class MainText(TextCommand):
if self.address == 0x9c00e and self.debug:
if self.last_address != 0x9c086:
- print "self.address is: " + hex(self.address)
- print "jump is: " + str(jump)
- print "bytes are: " + str(self.bytes)
- print "self.size is: " + str(self.size)
- print "self.last_address is: " + hex(self.last_address)
+ argparams = {
+ "self.address": hex(self.address),
+ "jump": str(jump),
+ "bytes": str(self.bytes),
+ "self.size": str(self.size),
+ "self.last_address": hex(self.last_address),
+ }
+
+ logging.debug(str(argparams))
+
raise Exception("last_address is wrong for 0x9c00e")
def to_asm(self):
@@ -2328,7 +2354,8 @@ class MainText(TextCommand):
# $4f, $51 and $55 can end a line
if byte in [0x4f, 0x51, 0x55]:
- assert not new_line, "can't have $4f, $51, $55 as the first character on a newline"
+ if new_line:
+ raise exceptions.TextScriptException("can't have $4f, $51, $55 as the first character on a newline")
if in_quotes:
output += "\", $%.2x\n" % (byte)
@@ -2384,9 +2411,9 @@ class MainText(TextCommand):
# so this is pretty useless overall...
if byte == 0x58:
self.end = True
- elif byte in chars.keys():
+ elif byte in chars.chars.keys():
# figure out what the character actually is
- char = chars[byte]
+ char = chars.chars[byte]
# oh wait.. quotes isn't a valid character in the first place :(
if char == "\"":
@@ -2844,7 +2871,7 @@ def create_command_classes(debug=False):
klasses = [GivePoke]
for (byte, cmd) in pksv_crystal_more.items():
cmd_name = cmd[0].replace(" ", "_")
- params = {"id": byte, "size": 1, "end": byte in pksv_crystal_more_enders, "macro_name": cmd_name}
+ params = {"id": byte, "size": 1, "end": byte in pksv.pksv_crystal_more_enders, "macro_name": cmd_name}
params["param_types"] = {}
if len(cmd) > 1:
param_types = cmd[1:]
@@ -2852,8 +2879,7 @@ def create_command_classes(debug=False):
thing = {"name": each[0], "class": each[1]}
params["param_types"][i] = thing
if debug:
- print "each is: " + str(each)
- print "thing[class] is: " + str(thing["class"])
+ logging.debug("each is {0} and thing[class] is {1}".format(each, thing["class"]))
params["size"] += thing["class"].size
klass_name = cmd_name+"Command"
klass = classobj(klass_name, (Command,), params)
@@ -2931,8 +2957,7 @@ def create_music_command_classes(debug=False):
thing = {"name": each[0], "class": each[1]}
params["param_types"][i] = thing
if debug:
- print "each is: " + str(each)
- print "thing[class] is: " + str(thing["class"])
+ logging.debug("each is {0} and thing[class] is {1}".format(each, thing["class"]))
params["size"] += thing["class"].size
klass_name = cmd_name+"Command"
klass = classobj(klass_name, (Command,), params)
@@ -3147,8 +3172,7 @@ def create_effect_command_classes(debug=False):
thing = {"name": each[0], "class": each[1]}
params["param_types"][i] = thing
if debug:
- print "each is: " + str(each)
- print "thing[class] is: " + str(thing["class"])
+ logging.debug("each is {0} and thing[class] is {1}".format(each, thing["class"]))
params["size"] += thing["class"].size
klass_name = cmd_name+"Command"
klass = classobj(klass_name, (Command,), params)
@@ -3193,7 +3217,8 @@ def pretty_print_pksv_no_names():
use this to keep track of commands without pksv names
pksv_no_names is created in parse_script_engine_script_at"""
for (command_byte, addresses) in pksv_no_names.items():
- if command_byte in pksv_crystal_unknowns: continue
+ if command_byte in pksv.pksv_crystal_unknowns:
+ continue
print hex(command_byte) + " appearing in these scripts: "
for address in addresses:
print " " + hex(address)
@@ -3215,11 +3240,16 @@ def find_broken_recursive_scripts(output=False, debug=True):
script = script_parse_table[r[0]]
length = str(len(script))
if len(script) > 20 or script == {}:
- print "******************* begin"
- print "script at " + hex(r[0]) + " from main script " + hex(r[1]) + " with length: " + length
+ logging.debug(
+ "script at {address} from main script {scr} with length {length}"
+ .format(
+ address=hex(r[0]),
+ scr=hex(r[1]),
+ length=length,
+ )
+ )
if output:
parse_script_engine_script_at(r[0], force=True, debug=True)
- print "==================== end"
stop_points = [0x1aafa2,
@@ -3268,8 +3298,8 @@ class Script:
items = []
if type(self.commands) == dict:
for (id, command) in self.commands.items():
- if command["type"] in pksv_crystal:
- items.append(pksv_crystal[command["type"]])
+ if command["type"] in pksv.pksv_crystal:
+ items.append(pksv.pksv_crystal[command["type"]])
else:
items.append(hex(command["type"]))
else:
@@ -3294,7 +3324,7 @@ class Script:
def show_pksv(self):
"""prints a list of pksv command names in this script"""
- print self.to_pksv()
+ logging.debug("to_pksv(): {0}".format(self.to_pksv()))
def parse(self, start_address, force=False, map_group=None, map_id=None, force_top=True, origin=True, debug=False):
"""parses a script using the Command classes
@@ -3304,12 +3334,29 @@ class Script:
"""
global command_classes, rom, script_parse_table
current_address = start_address
- if debug: print "Script.parse address="+hex(self.address) +" map_group="+str(map_group)+" map_id="+str(map_id)
+ if debug:
+ logging.debug(
+ "Script.parse address={address} map_group={map_group} map_id={map_id}"
+ .format(
+ address=hex(self.address),
+ map_group=str(map_group),
+ map_id=str(map_id),
+ )
+ )
if start_address in stop_points and force == False:
- if debug: print "script parsing is stopping at stop_point=" + hex(start_address) + " at map_group="+str(map_group)+" map_id="+str(map_id)
+ if debug:
+ logging.debug(
+ "script parsing is stopping at stop_point={address} at map_group={map_group} map_id={map_id}"
+ .format(
+ stop_point=hex(start_address),
+ map_group=str(map_group),
+ map_id=str(map_id),
+ )
+ )
return None
if start_address < 0x4000 and start_address not in [0x26ef, 0x114, 0x1108]:
- if debug: print "address is less than 0x4000.. address is: " + hex(start_address)
+ if debug:
+ logging.debug("address is less than 0x4000.. address is {0}".format(hex(start_address)))
sys.exit(1)
if is_script_already_parsed_at(start_address) and not force and not force_top:
raise Exception("this script has already been parsed before, please use that instance ("+hex(start_address)+")")
@@ -3342,7 +3389,8 @@ class Script:
# no matching command found (not implemented yet)- just end this script
# NOTE: might be better to raise an exception and end the program?
if scripting_command_class == None:
- if debug: print "parsing script; current_address is: " + hex(current_address)
+ if debug:
+ logging.debug("parsing script; current_address is: {0}".format(hex(current_address)))
current_address += 1
asm_output = "\n".join([command.to_asm() for command in commands])
end = True
@@ -3375,7 +3423,8 @@ class Script:
script_parse_table[start_address:current_address] = self
asm_output = "\n".join([command.to_asm() for command in commands])
- if debug: print "--------------\n"+asm_output
+ if debug:
+ logging.debug("asm_output is: {0}".format(asm_output))
# store the script
self.commands = commands
@@ -3401,8 +3450,9 @@ class Script:
def old_parse(self, *args, **kwargs):
"""included from old_parse_scripts"""
-from old_parse_scripts import old_parse
-Script.old_parse = old_parse
+
+import old_parse_scripts
+Script.old_parse = old_parse_scripts.old_parse
def parse_script_engine_script_at(address, map_group=None, map_id=None, force=False, debug=True, origin=True):
if is_script_already_parsed_at(address) and not force:
@@ -3423,29 +3473,43 @@ def compare_script_parsing_methods(address):
load_rom()
separator = "################ compare_script_parsing_methods"
# first do it the old way
- print separator
- print "parsing the script at " + hex(address) + " using the old method"
+ logging.debug(separator)
+ logging.debug("parsing the script at {address} using the old method".format(address=hex(address)))
oldscript = Script(address, debug=True, force=True, origin=True, use_old_parse=True)
# and now the old way
- print separator
- print "parsing the script at " + hex(address) + " using the new method"
+ logging.debug(separator)
+ logging.debug("parsing the script at {address} using the new method".format(address=hex(address)))
newscript = Script(address, debug=True, force=True, origin=True)
# let the comparison begin..
errors = 0
- print separator + " COMPARISON RESULTS"
+ logging.debug("{0} COMPARISON RESULTS".format(separator))
if not len(oldscript.commands.keys()) == len(newscript.commands):
- print "the two scripts don't have the same number of commands"
+ logging.debug("the two scripts don't have the same number of commands")
errors += 1
for (id, oldcommand) in oldscript.commands.items():
newcommand = newscript.commands[id]
- oldcommand_pksv_name = pksv_crystal[oldcommand["type"]].replace(" ", "_")
+ oldcommand_pksv_name = pksv.pksv_crystal[oldcommand["type"]].replace(" ", "_")
if oldcommand["start_address"] != newcommand.address:
- print "the two addresses (command id="+str(id)+") do not match old="+hex(oldcommand["start_address"]) + " new="+hex(newcommand.address)
+ logging.debug(
+ "The two address (command id={id}) do not match old={old} new={new}"
+ .format(
+ id=id,
+ old=hex(oldcommand["start_address"]),
+ new=hex(newcommand.address),
+ )
+ )
errors += 1
if oldcommand_pksv_name != newcommand.macro_name:
- print "the two commands (id="+str(id)+") do not have the same name old="+oldcommand_pksv_name+" new="+newcommand.macro_name
+ logging.debug(
+ "The two commands (id={id}) do not have the same name old={old} new={new}"
+ .format(
+ id=id,
+ old=oldcommand_pksv_name,
+ new=newcommand.macro_name,
+ )
+ )
errors += 1
- print "total comparison errors: " + str(errors)
+ logging.info("total comparison errors: {0}".format(errors))
return oldscript, newscript
@@ -3485,7 +3549,7 @@ def old_parse_warp_bytes(some_bytes, debug=True):
"""parse some number of warps from the data"""
assert len(some_bytes) % warp_byte_size == 0, "wrong number of bytes"
warps = []
- for bytes in grouper(some_bytes, count=warp_byte_size):
+ for bytes in helpers.grouper(some_bytes, count=warp_byte_size):
y = int(bytes[0], 16)
x = int(bytes[1], 16)
warp_to = int(bytes[2], 16)
@@ -3546,7 +3610,7 @@ def old_parse_xy_trigger_bytes(some_bytes, bank=None, map_group=None, map_id=Non
"""parse some number of triggers from the data"""
assert len(some_bytes) % trigger_byte_size == 0, "wrong number of bytes"
triggers = []
- for bytes in grouper(some_bytes, count=trigger_byte_size):
+ for bytes in helpers.grouper(some_bytes, count=trigger_byte_size):
trigger_number = int(bytes[0], 16)
y = int(bytes[1], 16)
x = int(bytes[2], 16)
@@ -3557,8 +3621,11 @@ def old_parse_xy_trigger_bytes(some_bytes, bank=None, map_group=None, map_id=Non
script_address = None
script = None
if bank:
- script_address = calculate_pointer(script_ptr, bank)
- print "******* parsing xy trigger byte scripts... x=" + str(x) + " y=" + str(y)
+ script_address = pointers.calculate_pointer(script_ptr, bank)
+ logging.debug(
+ "parsing xy trigger byte scripts.. x={x} y={y}"
+ .format(x=x, y=y)
+ )
script = parse_script_engine_script_at(script_address, map_group=map_group, map_id=map_id)
triggers.append({
@@ -3587,7 +3654,11 @@ class ItemFragment(Command):
}
def __init__(self, address=None, bank=None, map_group=None, map_id=None, debug=False, label=None):
- assert is_valid_address(address), "ItemFragment must be given a valid address"
+ if not is_valid_address(address):
+ raise exceptions.AddressException(
+ "ItemFragment must be given a valid address (but got {0})."
+ .format(hex(address))
+ )
self.address = address
self.last_address = address + self.size
self.bank = bank
@@ -3661,7 +3732,7 @@ class TrainerFragment(Command):
def __init__(self, *args, **kwargs):
address = kwargs["address"]
- print "TrainerFragment address=" + hex(address)
+ logging.debug("TrainerFragment address={0}".format(hex(address)))
self.address = address
self.last_address = self.address + self.size
if not is_valid_address(address) or address in [0x26ef]:
@@ -3705,15 +3776,15 @@ class TrainerFragment(Command):
# give this object a possibly better label
label = "Trainer"
- if ("uses_numeric_trainer_ids" in trainer_group_names[trainer_group].keys()) \
- or ("trainer_names" not in trainer_group_names[trainer_group].keys()):
- label += string.capwords(trainer_group_names[trainer_group]["constant"])
- if "trainer_names" in trainer_group_names[trainer_group].keys() \
- and len(trainer_group_names[trainer_group]["trainer_names"]) > 1:
+ if ("uses_numeric_trainer_ids" in trainers.trainer_group_names[trainer_group].keys()) \
+ or ("trainer_names" not in trainers.trainer_group_names[trainer_group].keys()):
+ label += string.capwords(trainers.trainer_group_names[trainer_group]["constant"])
+ if "trainer_names" in trainers.trainer_group_names[trainer_group].keys() \
+ and len(trainers.trainer_group_names[trainer_group]["trainer_names"]) > 1:
label += str(trainer_id)
else:
- label += string.capwords(trainer_group_names[trainer_group]["constant"]) + \
- string.capwords(trainer_group_names[trainer_group]["trainer_names"][trainer_id-1])
+ label += string.capwords(trainers.trainer_group_names[trainer_group]["constant"]) + \
+ string.capwords(trainers.trainer_group_names[trainer_group]["trainer_names"][trainer_id-1])
label = label.replace("Gruntm", "GruntM").replace("Gruntf", "GruntF").replace("Lt_surge", "LtSurge")
@@ -3791,9 +3862,9 @@ class TrainerGroupTable:
"""
def __init__(self):
- assert 0x43 in trainer_group_maximums.keys(), "TrainerGroupTable should onyl be created after all the trainers have been found"
- self.address = trainer_group_pointer_table_address
- self.bank = calculate_bank(trainer_group_pointer_table_address)
+ assert 0x43 in trainer_group_maximums.keys(), "TrainerGroupTable should only be created after all the trainers have been found"
+ self.address = trainers.trainer_group_pointer_table_address
+ self.bank = pointers.calculate_bank(trainers.trainer_group_pointer_table_address)
self.label = Label(name="TrainerGroupPointerTable", address=self.address, object=self)
self.size = None
self.last_address = None
@@ -3814,16 +3885,16 @@ class TrainerGroupTable:
def parse(self):
size = 0
- for (key, kvalue) in trainer_group_names.items():
+ for (key, kvalue) in trainers.trainer_group_names.items():
# calculate the location of this trainer group header from its pointer
pointer_bytes_location = kvalue["pointer_address"]
parsed_address = calculate_pointer_from_bytes_at(pointer_bytes_location, bank=self.bank)
- trainer_group_names[key]["parsed_address"] = parsed_address
+ trainers.trainer_group_names[key]["parsed_address"] = parsed_address
# parse the trainer group header at this location
name = kvalue["name"]
trainer_group_header = TrainerGroupHeader(address=parsed_address, group_id=key, group_name=name)
- trainer_group_names[key]["header"] = trainer_group_header
+ trainers.trainer_group_names[key]["header"] = trainer_group_header
self.headers.append(trainer_group_header)
# keep track of the size of this pointer table
@@ -3970,7 +4041,7 @@ class TrainerHeader:
x = 2
else:
x = 1
- seed = trainer_group_names[self.trainer_group_id]["name"]+"_"+seed[-x:]
+ seed = trainers.trainer_group_names[self.trainer_group_id]["name"]+"_"+seed[-x:]
elif self.trainer_group_id == 0x1f and "EXECUTIVE" in seed:
seed = "GRUNT_"+seed
elif self.trainer_group_id == 0x2d and "BENNY" in seed.upper():
@@ -4202,12 +4273,12 @@ def report_unreferenced_trainer_ids():
if len(unreferenced) > 0:
total_unreferenced_trainers += len(unreferenced)
- output = "trainer group "+hex(key)+" (\""+trainer_group_names[key]["name"]+"\")"
+ output = "trainer group "+hex(key)+" (\""+trainers.trainer_group_names[key]["name"]+"\")"
output += " (min="+str(min_id)+", max="+str(max_id)+")"
output += " has "+str(len(unreferenced))+" unreferenced trainer ids"
output += ": " + str(unreferenced)
- print output
- print "total unreferenced trainers: " + str(total_unreferenced_trainers)
+ logging.info(output)
+ logging.info("total unreferenced trainers: {0}".format(total_unreferenced_trainers))
def check_script_has_trainer_data(script):
"""
@@ -4232,7 +4303,7 @@ def check_script_has_trainer_data(script):
def trainer_name_from_group(group_id, trainer_id=0):
"""This doesn't actually work for trainer_id > 0."""
- bank = calculate_bank(0x39999)
+ bank = pointers.calculate_bank(0x39999)
ptr_address = 0x39999 + ((group_id - 1)*2)
address = calculate_pointer_from_bytes_at(ptr_address, bank=bank)
text = parse_text_at2(address, how_many_until(chr(0x50), address))
@@ -4245,7 +4316,7 @@ def trainer_group_report():
output = ""
total = 0
for trainer_group_id in trainer_group_maximums.keys():
- group_name = trainer_group_names[trainer_group_id]["name"]
+ group_name = trainers.trainer_group_names[trainer_group_id]["name"]
first_name = trainer_name_from_group(trainer_group_id).replace("\n", "")
trainers = len(trainer_group_maximums[trainer_group_id])
total += trainers
@@ -4258,7 +4329,7 @@ def trainer_group_report():
def make_trainer_group_name_trainer_ids(trainer_group_table, debug=True):
"""
- Edits trainer_group_names and sets the trainer names.
+ Edits trainers.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.
@@ -4266,7 +4337,7 @@ def make_trainer_group_name_trainer_ids(trainer_group_table, debug=True):
assert trainer_group_table != None, "TrainerGroupTable must be called before setting the trainer names"
if debug:
- print "starting to make trainer names and give ids to repeated trainer names"
+ logging.info("starting to make trainer names and give ids to repeated trainer names")
i = 1
for header in trainer_group_table.headers:
@@ -4287,13 +4358,13 @@ def make_trainer_group_name_trainer_ids(trainer_group_table, debug=True):
culprit.seed_constant_name = culprit.name.replace("@", "") + str(id+1)
culprit.constant_name = culprit.make_constant_name()
- # now add the trainer names to trainer_group_names
- trainer_group_names[i]["trainer_names"] = [theader.make_constant_name() for theader in header.individual_trainer_headers]
+ # now add the trainer names to trainers.trainer_group_names
+ trainers.trainer_group_names[i]["trainer_names"] = [theader.make_constant_name() for theader in header.individual_trainer_headers]
i += 1
if debug:
- print "done improving trainer names"
+ logging.info("done improving trainer names")
def pretty_print_trainer_id_constants():
"""
@@ -4302,12 +4373,12 @@ def pretty_print_trainer_id_constants():
make_trainer_group_name_trainer_ids must be called prior to this.
"""
assert trainer_group_table != None, "must make trainer_group_table first"
- assert trainer_group_names != None, "must have trainer_group_names available"
- assert "trainer_names" in trainer_group_names[1].keys(), "trainer_names must be set in trainer_group_names"
+ assert trainers.trainer_group_names != None, "must have trainers.trainer_group_names available"
+ assert "trainer_names" in trainers.trainer_group_names[1].keys(), "trainer_names must be set in trainers.trainer_group_names"
output = ""
- for (key, value) in trainer_group_names.items():
- if "uses_numeric_trainer_ids" in trainer_group_names[key].keys():
+ for (key, value) in trainers.trainer_group_names.items():
+ if "uses_numeric_trainer_ids" in trainers.trainer_group_names[key].keys():
continue
id = key
group = value
@@ -4347,7 +4418,11 @@ class PeopleEvent(Command):
return output
def __init__(self, address, id, bank=None, map_group=None, map_id=None, debug=False, label=None, force=False):
- assert is_valid_address(address), "PeopleEvent must be given a valid address"
+ if not is_valid_address(address):
+ raise exceptions.AddressException(
+ "PeopleEvent must be given a valid address (but got {0})."
+ .format(hex(address))
+ )
self.address = address
self.last_address = address + people_event_byte_size
self.id = id
@@ -4458,10 +4533,10 @@ def old_parse_people_event_bytes(some_bytes, address=None, map_group=None, map_i
# address is not actually required for this function to work...
bank = None
if address:
- bank = calculate_bank(address)
+ bank = pointers.calculate_bank(address)
people_events = []
- for bytes in grouper(some_bytes, count=people_event_byte_size):
+ for bytes in helpers.grouper(some_bytes, count=people_event_byte_size):
pict = int(bytes[0], 16)
y = int(bytes[1], 16) # y from top + 4
x = int(bytes[2], 16) # x from left + 4
@@ -4494,9 +4569,16 @@ def old_parse_people_event_bytes(some_bytes, address=None, map_group=None, map_i
# but what if it's not in the same bank?
extra_portion = {}
if bank:
- ptr_address = calculate_pointer(script_pointer, bank)
+ ptr_address = pointers.calculate_pointer(script_pointer, bank)
if is_regular_script:
- print "parsing a person-script at x=" + str(x-4) + " y=" + str(y-4) + " address="+hex(ptr_address)
+ logging.debug(
+ "parsing a person-script at x={x} y={y} address={address}"
+ .format(
+ x=(x-4),
+ y=(y-4),
+ address=hex(ptr_address),
+ )
+ )
script = parse_script_engine_script_at(ptr_address, map_group=map_group, map_id=map_id)
extra_portion = {
"script_address": ptr_address,
@@ -4504,7 +4586,7 @@ def old_parse_people_event_bytes(some_bytes, address=None, map_group=None, map_i
"event_type": "script",
}
if is_give_item:
- print "... not parsing give item event... [item id][quantity]"
+ logging.debug("not parsing give item event.. [item id][quantity]")
extra_portion = {
"event_type": "give_item",
"give_item_data_address": ptr_address,
@@ -4512,7 +4594,10 @@ def old_parse_people_event_bytes(some_bytes, address=None, map_group=None, map_i
"item_qty": ord(rom[ptr_address+1]),
}
if is_trainer:
- print "parsing a trainer (person-event) at x=" + str(x) + " y=" + str(y)
+ logging.debug(
+ "parsing a trainer (person-event) at x={x} y={y}"
+ .format(x=x, y=y)
+ )
parsed_trainer = parse_trainer_header_at(ptr_address, map_group=map_group, map_id=map_id)
extra_portion = {
"event_type": "trainer",
@@ -4752,9 +4837,9 @@ class Signpost(Command):
script_ptr_byte2 = int(bytes[4], 16)
script_pointer = script_ptr_byte1 + (script_ptr_byte2 << 8)
- script_address = calculate_pointer(script_pointer, bank)
+ script_address = pointers.calculate_pointer(script_pointer, bank)
output += " script@"+hex(script_address)
- print output
+ logging.debug(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)
@@ -4768,7 +4853,7 @@ class Signpost(Command):
ptr_byte1 = int(bytes[3], 16)
ptr_byte2 = int(bytes[4], 16)
pointer = ptr_byte1 + (ptr_byte2 << 8)
- address = calculate_pointer(pointer, bank)
+ address = pointers.calculate_pointer(pointer, bank)
bit_table_byte1 = ord(rom[address])
bit_table_byte2 = ord(rom[address+1])
@@ -4777,7 +4862,7 @@ class Signpost(Command):
script_address = calculate_pointer_from_bytes_at(address+2, bank=bank)
output += " remote_chunk@"+hex(address)+" remote_script@"+hex(script_address)
- print output
+ logging.debug(output)
r1 = SignpostRemoteScriptChunk(address, signpost=self, \
bank=self.bank, map_group=self.map_group, map_id=self.map_id, \
@@ -4799,11 +4884,11 @@ class Signpost(Command):
ptr_byte1 = int(bytes[3], 16)
ptr_byte2 = int(bytes[4], 16)
pointer = ptr_byte1 + (ptr_byte2 << 8)
- address = calculate_pointer(pointer, bank)
+ address = pointers.calculate_pointer(pointer, bank)
item_id = ord(rom[address+2])
output += " item_id="+str(item_id)
- print output
+ logging.debug(output)
r1 = SignpostRemoteItemChunk(address, signpost=self, \
bank=self.bank, map_group=self.map_group, map_id=self.map_id, \
@@ -4823,10 +4908,10 @@ class Signpost(Command):
ptr_byte1 = int(bytes[3], 16)
ptr_byte2 = int(bytes[4], 16)
pointer = ptr_byte1 + (ptr_byte2 << 8)
- address = calculate_pointer(pointer, bank)
+ address = pointers.calculate_pointer(pointer, bank)
output += " remote unknown chunk at="+hex(address)
- print output
+ logging.debug(output)
r1 = SignpostRemoteUnknownChunk(address, signpost=self, \
bank=self.bank, map_group=self.map_group, map_id=self.map_id, \
@@ -4873,14 +4958,17 @@ def parse_signposts(address, signpost_count, bank=None, map_group=None, map_id=N
def old_parse_signpost_bytes(some_bytes, bank=None, map_group=None, map_id=None, debug=True):
assert len(some_bytes) % signpost_byte_size == 0, "wrong number of bytes"
signposts = []
- for bytes in grouper(some_bytes, count=signpost_byte_size):
+ for bytes in helpers.grouper(some_bytes, count=signpost_byte_size):
y = int(bytes[0], 16)
x = int(bytes[1], 16)
func = int(bytes[2], 16)
additional = {}
if func in [0, 1, 2, 3, 4]:
- print "******* parsing signpost script.. signpost is at: x=" + str(x) + " y=" + str(y)
+ logging.debug(
+ "parsing signpost script.. signpost is at x={x} y={y}"
+ .format(x=x, y=y)
+ )
script_ptr_byte1 = int(bytes[3], 16)
script_ptr_byte2 = int(bytes[4], 16)
script_pointer = script_ptr_byte1 + (script_ptr_byte2 << 8)
@@ -4888,7 +4976,7 @@ def old_parse_signpost_bytes(some_bytes, bank=None, map_group=None, map_id=None,
script_address = None
script = None
- script_address = calculate_pointer(script_pointer, bank)
+ script_address = pointers.calculate_pointer(script_pointer, bank)
script = parse_script_engine_script_at(script_address, map_group=map_group, map_id=map_id)
additional = {
@@ -4898,11 +4986,15 @@ def old_parse_signpost_bytes(some_bytes, bank=None, map_group=None, map_id=None,
"script": script,
}
elif func in [5, 6]:
- print "******* parsing signpost script.. signpost is at: x=" + str(x) + " y=" + str(y)
+ logging.debug(
+ "parsing signpost script.. signpost is at x={x} y={y}"
+ .format(x=x, y=y)
+ )
+
ptr_byte1 = int(bytes[3], 16)
ptr_byte2 = int(bytes[4], 16)
pointer = ptr_byte1 + (ptr_byte2 << 8)
- address = calculate_pointer(pointer, bank)
+ address = pointers.calculate_pointer(pointer, bank)
bit_table_byte1 = ord(rom[address])
bit_table_byte2 = ord(rom[address+1])
script_ptr_byte1 = ord(rom[address+2])
@@ -4918,7 +5010,7 @@ def old_parse_signpost_bytes(some_bytes, bank=None, map_group=None, map_id=None,
"script": script,
}
else:
- print ".. type 7 or 8 signpost not parsed yet."
+ logging.debug(".. type 7 or 8 signpost not parsed yet.")
spost = {
"y": y,
@@ -4934,7 +5026,10 @@ class MapHeader:
base_label = "MapHeader_"
def __init__(self, address, map_group=None, map_id=None, debug=True, label=None, bank=0x25):
- print "creating a MapHeader at "+hex(address)+" map_group="+str(map_group)+" map_id="+str(map_id)
+ logging.debug(
+ "creating a MapHeader at {address} map_group={map_group} map_id={map_id}"
+ .format(address=hex(address), map_group=map_group, map_id=map_id)
+ )
self.address = address
self.map_group = map_group
self.map_id = map_id
@@ -4952,11 +5047,11 @@ class MapHeader:
def parse(self):
address = self.address
- print "parsing a MapHeader at " + hex(address)
+ logging.debug("parsing a MapHeader at {0}".format(hex(address)))
self.bank = HexByte(address=address)
self.tileset = HexByte(address=address+1)
self.permission = DecimalParam(address=address+2)
- self.second_map_header_address = calculate_pointer(ord(rom[address+3])+(ord(rom[address+4])<<8), self.bank.byte)
+ self.second_map_header_address = pointers.calculate_pointer(ord(rom[address+3])+(ord(rom[address+4])<<8), self.bank.byte)
# TODO: is the bank really supposed to be 0x25 all the time ??
self.second_map_header = SecondMapHeader(self.second_map_header_address, map_group=self.map_group, map_id=self.map_id, debug=self.debug)
all_second_map_headers.append(self.second_map_header)
@@ -4988,19 +5083,19 @@ class MapHeader:
all_map_headers = []
def parse_map_header_at(address, map_group=None, map_id=None, debug=True):
"""parses an arbitrary map header at some address"""
- print "parsing a map header at: " + hex(address)
+ logging.debug("parsing a map header at {0}".format(hex(address)))
map_header = MapHeader(address, map_group=map_group, map_id=map_id, debug=debug)
all_map_headers.append(map_header)
return map_header
def old_parse_map_header_at(address, map_group=None, map_id=None, debug=True):
"""parses an arbitrary map header at some address"""
- print "parsing a map header at: " + hex(address)
+ logging.debug("parsing a map header at {0}".format(hex(address)))
bytes = rom_interval(address, map_header_byte_size, strings=False, debug=debug)
bank = bytes[0]
tileset = bytes[1]
permission = bytes[2]
- second_map_header_address = calculate_pointer(bytes[3] + (bytes[4] << 8), 0x25)
+ second_map_header_address = pointers.calculate_pointer(bytes[3] + (bytes[4] << 8), 0x25)
location_on_world_map = bytes[5] # pokegear world map location
music = bytes[6]
time_of_day = bytes[7]
@@ -5017,7 +5112,7 @@ def old_parse_map_header_at(address, map_group=None, map_id=None, debug=True):
"time_of_day": time_of_day,
"fishing": fishing_group,
}
- print "second map header address is: " + hex(second_map_header_address)
+ logging.debug("second map header address is {0}".format(hex(second_map_header_address)))
map_header["second_map_header"] = old_parse_second_map_header_at(second_map_header_address, debug=debug)
event_header_address = map_header["second_map_header"]["event_address"]
script_header_address = map_header["second_map_header"]["script_address"]
@@ -5053,7 +5148,7 @@ class SecondMapHeader:
base_label = "SecondMapHeader_"
def __init__(self, address, map_group=None, map_id=None, debug=True, bank=None, label=None):
- print "creating a SecondMapHeader at " + hex(address)
+ logging.debug("creating a SecondMapHeader at {0}".format(hex(address)))
self.address = address
self.map_group = map_group
self.map_id = map_id
@@ -5337,7 +5432,7 @@ class Connection:
p += (h * connected_map_width) - (connected_map_width * 3) + (connected_map_width - 1) - 2
method = "west1"
elif ((p + connected_map_width - 3)%0x4000)+0x4000 == strip_pointer:
- print "west h <= 0"
+ logging.debug("west h <= 0")
# lin's method:
# p += otherMap.width - 3
p += connected_map_width - 3
@@ -5354,7 +5449,7 @@ class Connection:
# do nothing
method = "west5"
elif ldirection == "south":
- print "south.. dunno what to do?"
+ logging.debug("south.. dunno what to do?")
if (p%0x4000)+0x4000 == strip_pointer:
# do nothing
@@ -5414,23 +5509,43 @@ class Connection:
strip_pointer_data.append(data)
if p != strip_pointer:
- print "method: " + method + " direction: " + ldirection
- print "other map blockdata address: " + hex(connected_second_map_header.blockdata.address)
- print "h = " + str(h)
- print "initial p = " + hex(connected_second_map_header.blockdata.address)
- print "intermediate p = " + hex(intermediate_p)
- print "final p = " + hex(p)
- print "connection length = " + str(connection_strip_length)
- print "strip_pointer = " + hex(strip_pointer)
- print "other map height = " + str(connected_map_height)
- print "other map width = " + str(connected_map_width)
- o = "other map group_id="+hex(connected_map_group_id) + " map_id="+hex(connected_map_id)+" "+map_names[connected_map_group_id][connected_map_id]["label"] + " smh="+hex(connected_second_map_header.address)
- o += " width="+str(connected_second_map_header.width.byte)+" height="+str(connected_second_map_header.height.byte)
- print o
-
- o = "current map group_id="+hex(self.map_group)+" map_id="+hex(self.map_id)+" "+map_names[self.map_group][self.map_id]["label"]+" smh="+hex(self.smh.address)
- o += " width="+str(self.smh.width.byte)+" height="+str(self.smh.height.byte)
- print o
+ wowparams = {
+ "method": method,
+ "direction": ldirection,
+ "other map blockdata address": hex(connected_second_map_header.blockdata.address),
+ "h": h,
+ "initial p": hex(connected_second_map_header.blockdata.address),
+ "intermediate p": hex(intermediate_p),
+ "final p": hex(p),
+ "connection length": connection_strip_length,
+ "strip_pointer": hex(strip_pointer),
+ "other map height": connected_map_height,
+ "other map width": connected_map_width,
+ }
+
+ logging.debug(wowparams)
+
+ whatparams = {
+ "other map group_id": hex(connected_map_group_id),
+ "other map map_id": hex(connected_map_id),
+ "other map name": +map_names[connected_map_group_id][connected_map_id]["label"],
+ "smh": hex(connected_second_map_header.address),
+ "width": connected_second_map_header.width.byte,
+ "height": connected_second_map_header.height.byte,
+ }
+
+ logging.debug(whatparams)
+
+ curparams = {
+ "current map group_id": hex(self.map_group),
+ "current map map_id": hex(self.map_id),
+ "current map name": map_names[self.map_group][self.map_id]["label"],
+ "smh": hex(self.smh.address),
+ "width": self.smh.width.byte,
+ "height": self.smh.height.byte,
+ }
+
+ logging.debug(curparams)
if ldirection == "east":
wrong_easts.append(data)
@@ -5462,24 +5577,36 @@ class Connection:
# (depending on the connection's direction)
if ldirection == "north":
x_movement_of_the_connection_strip_in_blocks = strip_destination - 0xC703
- print "(north) x_movement_of_the_connection_strip_in_blocks is: " + str(x_movement_of_the_connection_strip_in_blocks)
+ logging.debug(
+ "(north) x_movement_of_the_connection_strip_in_blocks is: {0}"
+ .format(x_movement_of_the_connection_strip_in_blocks)
+ )
if x_movement_of_the_connection_strip_in_blocks < 0:
raise Exception("x_movement_of_the_connection_strip_in_blocks is wrong? " + str(x_movement_of_the_connection_strip_in_blocks))
elif ldirection == "south":
# strip_destination =
# 0xc703 + (current_map_height + 3) * (current_map_width + 6) + x_movement_of_the_connection_strip_in_blocks
x_movement_of_the_connection_strip_in_blocks = strip_destination - (0xc703 + (current_map_height + 3) * (current_map_width + 6))
- print "(south) x_movement_of_the_connection_strip_in_blocks is: " + str(x_movement_of_the_connection_strip_in_blocks)
+ logging.debug(
+ "(south) x_movement_of_the_connection_strip_in_blocks is: {0}"
+ .format(x_movement_of_the_connection_strip_in_blocks)
+ )
elif ldirection == "east":
# strip_destination =
# 0xc700 + (current_map_width + 6) * (y_movement_of_the_connection_strip_in_blocks + 3)
y_movement_of_the_connection_strip_in_blocks = (strip_destination - 0xc700) / (current_map_width + 6) - 3
- print "(east) y_movement_of_the_connection_strip_in_blocks is: " + str(y_movement_of_the_connection_strip_in_blocks)
+ logging.debug(
+ "(east) y_movement_of_the_connection_strip_in_blocks is {0}"
+ .format(y_movement_of_the_connection_strip_in_blocks)
+ )
elif ldirection == "west":
# strip_destination =
# 0xc6fd + (current_map_width + 6) * (y_movement_of_the_connection_strip_in_blocks + 4)
y_movement_of_the_connection_strip_in_blocks = (strip_destination - 0xc6fd) / (current_map_width + 6) - 4
- print "(west) y_movement_of_the_connection_strip_in_blocks is: " + str(y_movement_of_the_connection_strip_in_blocks)
+ logging.debug(
+ "(west) y_movement_of_the_connection_strip_in_blocks is {0}"
+ .format(y_movement_of_the_connection_strip_in_blocks)
+ )
# let's also check the window equations
# tauwasser calls this "window" and lin calls this "memoryCurrentPointer"
@@ -5625,7 +5752,7 @@ class Connection:
this_part = "((" + h_out + " * " + map_constant_label + "_WIDTH) - (" + map_constant_label + "_WIDTH * 3) + (" + map_constant_label + "_WIDTH - 1) - 2)"
output += "(" + get_label_for(connected_second_map_header.blockdata.address) + " + " + this_part + ")"
elif ((p + connected_map_width - 3)%0x4000)+0x4000 == strip_pointer:
- print "west h <= 0"
+ logging.debug("west h <= 0")
# lin's method:
# p += otherMap.width - 3
p += connected_map_width - 3
@@ -5831,13 +5958,13 @@ def old_parse_second_map_header_at(address, map_group=None, map_id=None, debug=T
width = bytes[2]
blockdata_bank = bytes[3]
blockdata_pointer = bytes[4] + (bytes[5] << 8)
- blockdata_address = calculate_pointer(blockdata_pointer, blockdata_bank)
+ blockdata_address = pointers.calculate_pointer(blockdata_pointer, blockdata_bank)
script_bank = bytes[6]
script_pointer = bytes[7] + (bytes[8] << 8)
- script_address = calculate_pointer(script_pointer, script_bank)
+ script_address = pointers.calculate_pointer(script_pointer, script_bank)
event_bank = script_bank
event_pointer = bytes[9] + (bytes[10] << 8)
- event_address = calculate_pointer(event_pointer, event_bank)
+ event_address = pointers.calculate_pointer(event_pointer, event_bank)
connections = bytes[11]
return {
"border_block": border_block,
@@ -5906,7 +6033,14 @@ class MapEventHeader:
base_label = "MapEventHeader_"
def __init__(self, address, map_group=None, map_id=None, debug=True, bank=None, label=None):
- print "making a MapEventHeader at "+hex(address)+" map_group="+str(map_group)+" map_id="+str(map_id)
+ logging.debug(
+ "making a MapEventHeader at {address} map_group={map_group} map_id={map_id}"
+ .format(
+ address=hex(address),
+ map_group=map_group,
+ map_id=map_id,
+ )
+ )
self.address = address
self.map_group = map_group
self.map_id = map_id
@@ -5924,8 +6058,8 @@ class MapEventHeader:
def parse(self):
map_group, map_id, debug = self.map_group, self.map_id, self.debug
address = self.address
- bank = calculate_bank(self.address) # or use self.bank
- print "event header address is: " + hex(address)
+ bank = pointers.calculate_bank(self.address) # or use self.bank
+ logging.debug("event header address is {0}".format(hex(address)))
filler1 = ord(rom[address])
filler2 = ord(rom[address+1])
@@ -5961,7 +6095,7 @@ class MapEventHeader:
people_event_byte_count = people_event_byte_size * people_event_count
# people_events_bytes = rom_interval(after_signposts+1, people_event_byte_count)
# people_events = parse_people_event_bytes(people_events_bytes, address=after_signposts+1, map_group=map_group, map_id=map_id)
- people_events = parse_people_events(after_signposts+1, people_event_count, bank=calculate_bank(after_signposts+2), map_group=map_group, map_id=map_id, debug=debug)
+ people_events = parse_people_events(after_signposts+1, people_event_count, bank=pointers.calculate_bank(after_signposts+2), map_group=map_group, map_id=map_id, debug=debug)
self.people_event_count = people_event_count
self.people_events = people_events
@@ -6038,9 +6172,9 @@ def old_parse_map_event_header_at(address, map_group=None, map_id=None, debug=Tr
"""parse crystal map event header byte structure thing"""
returnable = {}
- bank = calculate_bank(address)
+ bank = pointers.calculate_bank(address)
- print "event header address is: " + hex(address)
+ logging.debug("event header address is {0}".format(hex(address)))
filler1 = ord(rom[address])
filler2 = ord(rom[address+1])
returnable.update({"1": filler1, "2": filler2})
@@ -6131,7 +6265,14 @@ class MapScriptHeader:
base_label = "MapScriptHeader_"
def __init__(self, address, map_group=None, map_id=None, debug=True, bank=None, label=None):
- print "creating a MapScriptHeader at " + hex(address) + " map_group="+str(map_group)+" map_id="+str(map_id)
+ logging.debug(
+ "creating a MapScriptHeader at {address} map_group={map_group} map_id={map_id}"
+ .format(
+ address=hex(address),
+ map_group=map_group,
+ map_id=map_id,
+ )
+ )
self.address = address
self.map_group = map_group
self.map_id = map_id
@@ -6155,10 +6296,17 @@ class MapScriptHeader:
self.trigger_count = ord(rom[address])
self.triggers = []
ptr_line_size = 4
- groups = grouper(rom_interval(address+1, self.trigger_count * ptr_line_size, strings=False), count=ptr_line_size)
+ groups = helpers.grouper(rom_interval(address+1, self.trigger_count * ptr_line_size, strings=False), count=ptr_line_size)
current_address = address+1
for (index, trigger_bytes) in enumerate(groups):
- print "parsing a map trigger script at "+hex(current_address)+" map_group="+str(map_group)+" map_id="+str(map_id)
+ logging.debug(
+ "parsing a map trigger script at {address} map_group={map_group} map_id={map_id}"
+ .format(
+ address=hex(current_address),
+ map_group=map_group,
+ map_id=map_id,
+ )
+ )
script = ScriptPointerLabelParam(address=current_address, map_group=map_group, map_id=map_id, debug=debug)
extra_bytes = MultiByteParam(address=current_address+2, map_group=map_group, map_id=map_id, debug=debug)
self.triggers.append([script, extra_bytes])
@@ -6171,13 +6319,23 @@ class MapScriptHeader:
current_address += 1
self.callbacks = []
for index in range(self.callback_count):
- print "parsing a callback script at "+hex(current_address)+" map_group="+str(map_group)+" map_id="+str(map_id)
+ logging.debug(
+ "parsing a callback script at {address} map_group={map_group} map_id={map_id}"
+ .format(
+ address=hex(current_address),
+ map_group=map_group,
+ map_id=map_id,
+ )
+ )
hook_byte = HexByte(address=current_address)
callback = ScriptPointerLabelParam(address=current_address+1, map_group=map_group, map_id=map_id, debug=debug)
self.callbacks.append({"hook": hook_byte, "callback": callback})
current_address += 3 # i think?
self.last_address = current_address
- print "done parsing a MapScriptHeader map_group="+str(map_group)+" map_id="+str(map_id)
+ logging.debug(
+ "done parsing a MapScriptHeader map_group={map_group} map_id={map_id}"
+ .format(map_group=map_group, map_id=map_id)
+ )
return True
def get_dependencies(self, recompute=False, global_dependencies=set()):
@@ -6217,18 +6375,18 @@ def parse_map_script_header_at(address, map_group=None, map_id=None, debug=True)
return evv
def old_parse_map_script_header_at(address, map_group=None, map_id=None, debug=True):
- print "starting to parse the map's script header.."
+ logging.debug("starting to parse the map's script header..")
#[[Number1 of pointers] Number1 * [2byte pointer to script][00][00]]
ptr_line_size = 4 #[2byte pointer to script][00][00]
trigger_ptr_cnt = ord(rom[address])
- trigger_pointers = grouper(rom_interval(address+1, trigger_ptr_cnt * ptr_line_size, strings=False), count=ptr_line_size)
+ trigger_pointers = helpers.grouper(rom_interval(address+1, trigger_ptr_cnt * ptr_line_size, strings=False), count=ptr_line_size)
triggers = {}
for index, trigger_pointer in enumerate(trigger_pointers):
- print "parsing a trigger header..."
+ logging.debug("parsing a trigger header...")
byte1 = trigger_pointer[0]
byte2 = trigger_pointer[1]
ptr = byte1 + (byte2 << 8)
- trigger_address = calculate_pointer(ptr, calculate_bank(address))
+ trigger_address = pointers.calculate_pointer(ptr, pointers.calculate_bank(address))
trigger_script = parse_script_engine_script_at(trigger_address, map_group=map_group, map_id=map_id)
triggers[index] = {
"script": trigger_script,
@@ -6242,16 +6400,16 @@ def old_parse_map_script_header_at(address, map_group=None, map_id=None, debug=T
#[[Number2 of pointers] Number2 * [hook number][2byte pointer to script]]
callback_ptr_line_size = 3
callback_ptr_cnt = ord(rom[address])
- callback_ptrs = grouper(rom_interval(address+1, callback_ptr_cnt * callback_ptr_line_size, strings=False), count=callback_ptr_line_size)
+ callback_ptrs = helpers.grouper(rom_interval(address+1, callback_ptr_cnt * callback_ptr_line_size, strings=False), count=callback_ptr_line_size)
callback_pointers = {}
callbacks = {}
for index, callback_line in enumerate(callback_ptrs):
- print "parsing a callback header..."
+ logging.debug("parsing a callback header..")
hook_byte = callback_line[0] # 1, 2, 3, 4, 5
callback_byte1 = callback_line[1]
callback_byte2 = callback_line[2]
callback_ptr = callback_byte1 + (callback_byte2 << 8)
- callback_address = calculate_pointer(callback_ptr, calculate_bank(address))
+ callback_address = pointers.calculate_pointer(callback_ptr, pointers.calculate_bank(address))
callback_script = parse_script_engine_script_at(callback_address)
callback_pointers[len(callback_pointers.keys())] = [hook_byte, callback_ptr]
callbacks[index] = {
@@ -6272,7 +6430,7 @@ def old_parse_map_script_header_at(address, map_group=None, map_id=None, debug=T
}
def old_parse_trainer_header_at(address, map_group=None, map_id=None, debug=True):
- bank = calculate_bank(address)
+ bank = pointers.calculate_bank(address)
bytes = rom_interval(address, 12, strings=False)
bit_number = bytes[0] + (bytes[1] << 8)
trainer_group = bytes[2]
@@ -6286,14 +6444,14 @@ def old_parse_trainer_header_at(address, map_group=None, map_id=None, debug=True
script_when_lost_ptr = 0
script_when_lost = None
else:
- print "parsing script-when-lost"
+ logging.debug("parsing script-when-lost")
script_when_lost_ptr = calculate_pointer_from_bytes_at(address+8, bank=bank)
script_when_lost = None
silver_avoids = [0xfa53]
if script_when_lost_ptr > 0x4000 and not script_when_lost_ptr in silver_avoids:
script_when_lost = parse_script_engine_script_at(script_when_lost_ptr, map_group=map_group, map_id=map_id, debug=debug)
- print "parsing script-talk-again" # or is this a text?
+ logging.debug("parsing script-talk-again") # or is this a text?
script_talk_again_ptr = calculate_pointer_from_bytes_at(address+10, bank=bank)
script_talk_again = None
if script_talk_again_ptr > 0x4000:
@@ -6332,10 +6490,10 @@ def old_parse_people_event_bytes(some_bytes, address=None, map_group=None, map_i
# address is not actually required for this function to work...
bank = None
if address:
- bank = calculate_bank(address)
+ bank = pointers.calculate_bank(address)
people_events = []
- for bytes in grouper(some_bytes, count=people_event_byte_size):
+ for bytes in helpers.grouper(some_bytes, count=people_event_byte_size):
pict = int(bytes[0], 16)
y = int(bytes[1], 16) # y from top + 4
x = int(bytes[2], 16) # x from left + 4
@@ -6368,9 +6526,12 @@ def old_parse_people_event_bytes(some_bytes, address=None, map_group=None, map_i
# but what if it's not in the same bank?
extra_portion = {}
if bank:
- ptr_address = calculate_pointer(script_pointer, bank)
+ ptr_address = pointers.calculate_pointer(script_pointer, bank)
if is_regular_script:
- print "parsing a person-script at x=" + str(x-4) + " y=" + str(y-4) + " address="+hex(ptr_address)
+ logging.debug(
+ "parsing a person-script at x={x} y={y} address={address}"
+ .format(x=(x-4), y=(y-4), address=hex(ptr_address))
+ )
script = parse_script_engine_script_at(ptr_address, map_group=map_group, map_id=map_id)
extra_portion = {
"script_address": ptr_address,
@@ -6378,7 +6539,7 @@ def old_parse_people_event_bytes(some_bytes, address=None, map_group=None, map_i
"event_type": "script",
}
if is_give_item:
- print "... not parsing give item event... [item id][quantity]"
+ logging.debug("not parsing give item event.. [item id][quantity]")
extra_portion = {
"event_type": "give_item",
"give_item_data_address": ptr_address,
@@ -6386,7 +6547,7 @@ def old_parse_people_event_bytes(some_bytes, address=None, map_group=None, map_i
"item_qty": ord(rom[ptr_address+1]),
}
if is_trainer:
- print "parsing a trainer (person-event) at x=" + str(x) + " y=" + str(y)
+ logging.debug("parsing a trainer (person-event) at x={x} y={y}".format(x=x, y=y))
parsed_trainer = old_parse_trainer_header_at(ptr_address, map_group=map_group, map_id=map_id)
extra_portion = {
"event_type": "trainer",
@@ -6462,7 +6623,11 @@ def parse_all_map_headers(debug=True):
#del group_data["offset"]
for map_id, map_data in group_data.items():
if map_id == "offset": continue # skip the "offset" address for this map group
- if debug: print "map_group is: " + str(group_id) + " map_id is: " + str(map_id)
+ if debug:
+ logging.debug(
+ "map_group={group_id} map_id={map_id}"
+ .format(group_id=group_id, map_id=map_id)
+ )
map_header_offset = offset + ((map_id - 1) * map_header_byte_size)
map_names[group_id][map_id]["header_offset"] = map_header_offset
@@ -6478,7 +6643,7 @@ class PokedexEntryPointerTable:
def __init__(self):
self.address = 0x44378
- self.target_bank = calculate_bank(0x181695)
+ self.target_bank = pointers.calculate_bank(0x181695)
self.label = Label(name="PokedexDataPointerTable", address=self.address, object=self)
self.size = None
self.last_address = None
@@ -6526,8 +6691,8 @@ class PokedexEntry:
self.address = address
self.dependencies = None
#label = self.make_label()
- if pokemon_id in pokemon_constants:
- pokename = string.capwords(pokemon_constants[pokemon_id].replace("__", " ").replace("_", " ")).replace(" ", "")
+ if pokemon_id in pokemon_constants.pokemon_constants:
+ pokename = string.capwords(pokemon_constants.pokemon_constants[pokemon_id].replace("__", " ").replace("_", " ")).replace(" ", "")
else:
pokename = "Pokemon{0}".format(pokemon_id)
self.label = Label(name=pokename+"PokedexEntry", address=self.address, object=self)
@@ -6567,8 +6732,6 @@ class PokedexEntry:
{4}""".format(self.species, self.weight, self.height, self.page1.to_asm(), self.page2.to_asm())
return output
-from map_names import map_names
-
# map names with no labels will be generated
# generate labels for each map name
for map_group_id in map_names.keys():
@@ -6622,21 +6785,6 @@ def to_asm(some_object, use_asm_rules=False):
asm += "\n; " + hex(last_address)
return asm
-def flattener(x):
- "flattens a list of sublists into just one list (generator)"
- try:
- it = iter(x)
- except TypeError:
- yield x
- else:
- for i in it:
- for j in flattener(i):
- yield j
-
-def flatten(x):
- "flattens a list of sublists into just one list"
- return list(flattener(x))
-
def get_dependencies_for(some_object, recompute=False, global_dependencies=set()):
"""
calculates which labels need to be satisfied for an object
@@ -6656,11 +6804,17 @@ def get_dependencies_for(some_object, recompute=False, global_dependencies=set()
return global_dependencies
except RuntimeError, e:
# 1552, 1291, 2075, 1552, 1291...
- print "some_object is: " + str(some_object)
- print "class type: " + str(some_object.__class__)
- print "label name: " + str(some_object.label.name)
- print "address: " + str(some_object.address)
- print "asm is: \n\n" + to_asm(some_object)
+
+ errorargs = {
+ "some_object": some_object,
+ "class type": some_object.__class__,
+ "label name": some_object.label.name,
+ "address": some_object.address,
+ "asm": to_asm(some_object),
+ }
+
+ logging.debug(str(errorargs))
+
raise e
def isolate_incbins(asm=None):
@@ -6744,10 +6898,21 @@ def find_incbin_to_replace_for(address, debug=False, rom_file="../baserom.gbc"):
start = incbin["start"]
end = incbin["end"]
if debug:
- print "start is: " + str(start)
- print "end is: " + str(end)
- print "address is: " + str(type(address))
- print "checking.... " + hex(start) + " <= " + hex(address) + " <= " + hex(end)
+ argstuff = {
+ "start": start,
+ "end": end,
+ "address": str(type(address)),
+ }
+
+ logging.debug(str(argstuff))
+ logging.debug(
+ "checking... {start} <= {address} <= {end}"
+ .format(
+ start=hex(start),
+ address=hex(address),
+ end=hex(end),
+ )
+ )
if start <= address <= end:
return incbin_key
return None
@@ -6828,11 +6993,12 @@ def generate_diff_insert(line_number, newline, debug=False):
os.system("rm " + original_filename)
os.system("rm " + newfile_filename)
- if debug: print diffcontent
+ if debug:
+ logging.debug("diffcontent is {0}".format(diffcontent))
return diffcontent
def apply_diff(diff, try_fixing=True, do_compile=True):
- print "... Applying diff."
+ logging.info("Applying diff.")
# write the diff to a file
fh = open("temp.patch", "w")
@@ -6861,6 +7027,7 @@ class AsmLine:
def __init__(self, line, bank=None):
self.line = line
self.bank = bank
+
def to_asm(self):
return self.line
@@ -6871,19 +7038,20 @@ class Incbin:
self.replace_me = False
self.debug = debug
self.parse()
+
def parse(self):
incbin = self.line
partial_start = incbin[21:]
start = partial_start.split(",")[0].replace("$", "0x")
if self.debug:
- print "Incbin.parse -- line is: " + self.line
- print "Incbin.parse -- partial_start is: " + partial_start
- print "Incbin.parse -- start is: " + start
+ logging.debug("Incbin.parse line is {0}".format(self.line))
+ logging.debug("Incbin.parse partial_start is {0}".format(partial_start))
+ logging.debug("Incbin.parse start is {0}".format(start))
try:
start = eval(start)
except Exception, e:
- print "start is: " + str(start)
+ logging.debug("start is {0}".format(start))
raise Exception("problem with evaluating interval range: " + str(e))
start_hex = hex(start).replace("0x", "$")
@@ -6902,11 +7070,13 @@ class Incbin:
self.end_address = end
self.last_address = end
self.interval = interval
+
def to_asm(self):
if self.interval > 0:
return self.line
else:
return ""
+
def split(self, start_address, byte_count):
"""splits this incbin into three separate incbins"""
if start_address < self.start_address or start_address > self.end_address:
@@ -6914,14 +7084,21 @@ class Incbin:
incbins = []
if self.debug:
- print "splitting an incbin ("+self.line+") into three at "+hex(start_address)+" for "+str(byte_count)+" bytes"
+ logging.debug(
+ "splitting an incbin (\"{line}\") into three at {start} for {count} bytes"
+ .format(
+ line=self.line,
+ start=hex(start_address),
+ count=byte_count,
+ )
+ )
# start, end1, end2 (to be printed as start, end1 - end2)
if (start_address - self.start_address) > 0:
first = (self.start_address, start_address, self.start_address)
incbins.append(Incbin("INCBIN \"baserom.gbc\",$%.2x,$%.2x - $%.2x" % (first[0], first[1], first[2])))
if self.debug:
- print " " + incbins[0].line
+ logging.debug(incbins[0].line)
else:
# skip this one because we're not including anything
first = None
@@ -6931,13 +7108,13 @@ class Incbin:
incbins.append(Incbin("INCBIN \"baserom.gbc\",$%.2x,$%.2x" % (start_address, byte_count)))
incbins[-1].replace_me = True
if self.debug:
- print " " + incbins[-1].line
+ logging.debug(incbins[-1].line)
if (self.last_address - (start_address + byte_count)) > 0:
third = (start_address + byte_count, self.last_address - (start_address + byte_count))
incbins.append(Incbin("INCBIN \"baserom.gbc\",$%.2x,$%.2x" % (third[0], third[1])))
if self.debug:
- print " " + incbins[-1].line
+ logging.debug(incbins[-1].line)
return incbins
@@ -6946,6 +7123,7 @@ class AsmSection:
self.bank_id = None
self.line = line
self.parse()
+
def parse(self):
line = self.line
@@ -6968,6 +7146,7 @@ class AsmSection:
# although it could be argued that lines should exist under this object
#self.address = self.start_address = start_address
#self.last_address = self.end_address = end_address
+
def to_asm(self):
return self.line
@@ -6987,10 +7166,11 @@ class Asm:
self.filename = filename
self.debug = debug
self.load_and_parse()
+
def load_and_parse(self):
self.parts = []
asm = open(self.filename, "r").read().split("\n")
- asm_list = AsmList(asm)
+ asm_list = romstr.AsmList(asm)
bank = 0
for line in asm_list:
if (line[0:6] == "INCBIN" or line[1:6] == "INCBIN") and not any([contaminant+"\"" in line for contaminant in [".2bpp", ".1bpp", ".asm", ".lz"]]):
@@ -7000,17 +7180,19 @@ class Asm:
bank = thing.bank_id
else:
thing = AsmLine(line, bank=bank)
- label = get_label_from_line(line)
+ label = labels.get_label_from_line(line)
if label:
- laddress = get_address_from_line_comment(line)
+ laddress = labels.get_address_from_line_comment(line)
thing.label = Label(name=label, address=laddress, object=thing, add_to_globals=False)
self.labels.append(thing.label)
self.parts.append(thing)
+
def is_label_name_in_file(self, label_name):
for llabel in self.labels:
if llabel.name == label_name:
return llabel
return False
+
def does_address_have_label(self, address):
"""
Checks if an address has a label.
@@ -7025,15 +7207,16 @@ class Asm:
return part.label
return None
+
def insert(self, new_object):
if isinstance(new_object, ScriptPointerLabelParam):
# its' probably being injected in some get_dependencies() somewhere
- print "don't know why ScriptPointerLabelParam is getting to this point?"
+ logging.debug("don't know why ScriptPointerLabelParam is getting to this point?")
return
# first some validation
if not hasattr(new_object, "address"):
- print "object needs to have an address property: " + str(new_object)
+ logging.debug("object needs to have an address property: {0}".format(new_object))
return
start_address = new_object.address
@@ -7041,7 +7224,7 @@ class Asm:
# skip this dragon shrine script calling itself
# what about other scripts that call themselves ?
if start_address in lousy_dragon_shrine_hack:
- print "skipping 0x18d079 in dragon shrine for a lousy hack"
+ logging.debug("skipping 0x18d079 in dragon shrine for a lousy hack")
return
if not hasattr(new_object, "label") and hasattr(new_object, "is_valid") and not new_object.is_valid():
@@ -7052,20 +7235,34 @@ class Asm:
debugmsg += " start_address="+hex(start_address)#+" end_address="+hex(end_address)
if not hasattr(new_object, "last_address"):
- print debugmsg
+ logging.debug(debugmsg)
raise Exception("object needs to have a last_address property")
end_address = new_object.last_address
debugmsg += " last_address="+hex(end_address)
# check if the object is already inserted
if new_object in self.parts:
- print "object was previously inserted ("+str(new_object)+"; " + hex(new_object.address) + ")"
+ logging.debug(
+ "object was previously inserted ({new_object}; {address})"
+ .format(
+ new_object=new_object,
+ address=hex(new_object.address),
+ )
+ )
return
# check by label
other_obj = self.is_label_name_in_file(new_object.label.name)
if other_obj:
other_obj = other_obj.object
- print "object was previously inserted ("+new_object.label.name+" at "+hex(new_object.address)+") by "+other_obj.label.name+" at "+hex(other_obj.address)
+ logging.debug(
+ "object was previously inserted ({name} at {address}) by {othername} at {otheraddress}"
+ .format(
+ name=new_object.label.name,
+ address=hex(new_object.address),
+ othername=other_obj.label.name,
+ otheraddress=other_obj.address,
+ )
+ )
return
# check by address
#if self.does_address_have_label(new_object.address):
@@ -7073,14 +7270,17 @@ class Asm:
# return
if self.debug:
- print debugmsg
+ logging.debug(debugmsg)
del debugmsg
if (end_address < start_address) or ((end_address - start_address) < 0):
if not self.debug:
- print "object is new_object="+str(new_object)
- print "start_address="+hex(start_address)+" end_address="+hex(end_address)
+ logging.debug("object is new_object={0}".format(new_object))
+ logging.deubg(
+ "start_address={start} end_address={end}"
+ .format(start=hex(start_address), end=hex(end_address))
+ )
if hasattr(new_object, "to_asm"):
- print to_asm(new_object)
+ logging.debug(to_asm(new_object))
raise Exception("Asm.insert was given an object with a bad address range")
# 1) find which object needs to be replaced
@@ -7112,7 +7312,7 @@ class Asm:
found = True
break
elif object.address <= start_address < object.last_address:
- print "this is probably a script that is looping back on itself?"
+ logging.debug("this is probably a script that is looping back on itself?")
found = True
break
# insert before the current object
@@ -7126,6 +7326,7 @@ class Asm:
raise Exception("unable to insert object into Asm")
self.labels.append(new_object.label)
return True
+
def insert_with_dependencies(self, input):
if type(input) == list:
input_objects = input
@@ -7150,7 +7351,7 @@ class Asm:
# " for object.__class__="+str(object0.__class__)+" object="+str(object0)
# continue
if self.debug:
- print " object is: " + str(object)
+ logging.debug("object is: {0}".format(object))
self.insert(object)
# just some old debugging
@@ -7158,10 +7359,13 @@ class Asm:
# raise Exception("debugging...")
#elif object.label.name == "UnknownScript_0x60011":
# raise Exception("debugging.. dependencies are: " + str(object.dependencies) + " versus: " + str(object.get_dependencies()))
+
def insert_single_with_dependencies(self, object):
self.insert_with_dependencies(object)
+
def insert_multiple_with_dependencies(self, objects):
self.insert_with_dependencies(objects)
+
def insert_all(self, limit=100):
count = 0
for each in script_parse_table.items():
@@ -7170,9 +7374,11 @@ class Asm:
if type(object) == str: continue
self.insert_single_with_dependencies(object)
count += 1
+
def insert_and_dump(self, limit=100, filename="output.txt"):
self.insert_all(limit=limit)
self.dump(filename=filename)
+
def dump(self, filename="output.txt"):
fh = open(filename, "w")
newlines_before_next_obj_requested = 0
@@ -7234,7 +7440,7 @@ def list_things_in_bank(bank):
objects = []
for blah in script_parse_table.items():
object = blah[1]
- if hasattr(object, "address") and calculate_bank(object.address) == bank:
+ if hasattr(object, "address") and pointers.calculate_bank(object.address) == bank:
objects.append(object)
return objects
@@ -7251,7 +7457,7 @@ def list_texts_in_bank(bank):
texts = []
for text in all_texts:
- if calculate_bank(text.address) == bank:
+ if pointers.calculate_bank(text.address) == bank:
texts.append(text)
return texts
@@ -7268,7 +7474,7 @@ def list_movements_in_bank(bank):
movements = []
for movement in all_movements:
- if calculate_bank(movement.address) == bank:
+ if pointers.calculate_bank(movement.address) == bank:
movements.append(movement)
return movements
@@ -7295,7 +7501,7 @@ def dump_asm_for_texts_in_bank(bank, start=50, end=100):
# start dumping
asm.dump()
- print "done dumping texts for bank $%.2x" % (bank)
+ logging.info("done dumping texts for bank {banked}".format(banked="$%.2x" % bank))
def dump_asm_for_movements_in_bank(bank, start=0, end=100):
if rom == None or len(rom) <= 4:
@@ -7307,7 +7513,7 @@ def dump_asm_for_movements_in_bank(bank, start=0, end=100):
asm = Asm()
asm.insert_with_dependencies(movements)
asm.dump()
- print "done dumping movements for bank $%.2x" % (bank)
+ logging.info("done dumping movements for bank {banked}".format(banked="$%.2x" % bank))
def dump_things_in_bank(bank, start=50, end=100):
"""
@@ -7329,12 +7535,7 @@ def dump_things_in_bank(bank, start=50, end=100):
# start dumping
asm.dump()
- print "done dumping things for bank $%.2x" % (bank)
-
-def index(seq, f):
- """return the index of the first item in seq
- where f(item) == True."""
- return next((i for i in xrange(len(seq)) if f(seq[i])), None)
+ logging.info("done dumping things for bank {banked}".format(banked="$%.2x" % bank))
def analyze_intervals():
"""find the largest baserom.gbc intervals"""
@@ -7358,13 +7559,12 @@ def write_all_labels(all_labels, filename="labels.json"):
fh.close()
return True
-from wram import wram_labels
def get_ram_label(address):
"""
returns a label assigned to a particular ram address
"""
- if address in wram_labels.keys():
- return wram_labels[address][-1]
+ if address in wram.wram_labels.keys():
+ return wram.wram_labels[address][-1]
return None
def get_label_for(address):
@@ -7498,9 +7698,9 @@ def find_labels_without_addresses():
"""scans the asm source and finds labels that are unmarked"""
without_addresses = []
for (line_number, line) in enumerate(asm):
- if line_has_label(line):
- label = get_label_from_line(line)
- if not line_has_comment_address(line):
+ if labels.line_has_label(line):
+ label = labels.get_label_from_line(line)
+ if not labels.line_has_comment_address(line):
without_addresses.append({"line_number": line_number, "line": line, "label": label})
return without_addresses
@@ -7519,16 +7719,16 @@ def get_labels_between(start_line_id, end_line_id, bank):
sublines = asm[start_line_id : end_line_id + 1]
for (current_line_offset, line) in enumerate(sublines):
# skip lines without labels
- if not line_has_label(line): continue
+ if not labels.line_has_label(line): continue
# reset some variables
line_id = start_line_id + current_line_offset
- line_label = get_label_from_line(line)
+ line_label = labels.get_label_from_line(line)
address = None
offset = None
# setup a place to store return values from line_has_comment_address
returnable = {}
# get the address from the comment
- has_comment = line_has_comment_address(line, returnable=returnable, bank=bank)
+ has_comment = labels.line_has_comment_address(line, returnable=returnable, bank=bank)
# skip this line if it has no address in the comment
if not has_comment: continue
# parse data from line_has_comment_address
@@ -7575,9 +7775,9 @@ def scan_for_predefined_labels(debug=False):
abbreviation_next = "1"
# calculate the start/stop line numbers for this bank
- start_line_id = index(asm, lambda line: "\"bank" + abbreviation.lower() + "\"" in line.lower())
+ start_line_id = helpers.index(asm, lambda line: "\"bank" + abbreviation.lower() + "\"" in line.lower())
if bank_id != 0x7F:
- end_line_id = index(asm, lambda line: "\"bank" + abbreviation_next.lower() + "\"" in line.lower())
+ end_line_id = helpers.index(asm, lambda line: "\"bank" + abbreviation_next.lower() + "\"" in line.lower())
end_line_id += 1
else:
end_line_id = len(asm) - 1
@@ -7587,7 +7787,7 @@ def scan_for_predefined_labels(debug=False):
output += str(start_line_id)
output += " to "
output += str(end_line_id)
- print output
+ logging.debug(output)
# store the start/stop line number for this bank
bank_intervals[bank_id] = {"start": start_line_id,
@@ -7630,6 +7830,5 @@ def run_main():
# just a helpful alias
main = run_main
-# when you load the module.. parse everything
if __name__ == "crystal":
pass
diff --git a/pokemontools/disassemble_map_scripts.py b/pokemontools/disassemble_map_scripts.py
index 21df569..f51fb92 100644
--- a/pokemontools/disassemble_map_scripts.py
+++ b/pokemontools/disassemble_map_scripts.py
@@ -5,7 +5,7 @@ and insert all scripting commands.
"""
import crystal
-from gbz80disasm import output_bank_opcodes
+import gbz80disasm
rom = crystal.load_rom()
roml = [ord(x) for x in rom]
@@ -78,7 +78,7 @@ class DisassembledScriptCommand():
max_byte_count = 86
# disassemble and laso get the last address
- (asm, last_address, last_hl_address, last_a_address, used_3d97) = output_bank_opcodes(address, max_byte_count=max_byte_count, stop_at=command_pointers, include_last_address=False)
+ (asm, last_address, last_hl_address, last_a_address, used_3d97) = gbz80disasm.output_bank_opcodes(address, max_byte_count=max_byte_count, stop_at=command_pointers, include_last_address=False)
# remove indentation
asm = asm.replace("\n\t", "\n")
diff --git a/pokemontools/exceptions.py b/pokemontools/exceptions.py
new file mode 100644
index 0000000..71d0da2
--- /dev/null
+++ b/pokemontools/exceptions.py
@@ -0,0 +1,13 @@
+"""
+Custom exceptions used throughout the project.
+"""
+
+class AddressException(Exception):
+ """
+ There was a problem with an address. Maybe it was out of range or invalid.
+ """
+
+class TextScriptException(Exception):
+ """
+ TextScript encountered an inconsistency or problem.
+ """
diff --git a/pokemontools/gbz80disasm.py b/pokemontools/gbz80disasm.py
index 6759a4a..7499982 100644
--- a/pokemontools/gbz80disasm.py
+++ b/pokemontools/gbz80disasm.py
@@ -6,6 +6,7 @@ from copy import copy, deepcopy
from ctypes import c_int8
import random
import json
+
from wram import *
# New versions of json don't have read anymore.
diff --git a/pokemontools/gfx.py b/pokemontools/gfx.py
index 6d9614f..c7c6bec 100644
--- a/pokemontools/gfx.py
+++ b/pokemontools/gfx.py
@@ -5,25 +5,12 @@ import sys
import png
from math import sqrt, floor, ceil
-from crystal import load_rom
-
-from pokemon_constants import pokemon_constants
-from trainers import trainer_group_names
+import crystal
+import pokemon_constants
+import trainers
if __name__ != "__main__":
- rom = load_rom()
-
-def mkdir_p(path):
- """
- Make a directory at a given path.
- """
- try:
- os.makedirs(path)
- except OSError as exc: # Python >2.5
- if exc.errno == errno.EEXIST:
- pass
- else: raise
-
+ rom = crystal.load_rom()
def hex_dump(input, debug=True):
"""
@@ -1122,7 +1109,7 @@ def dump_monster_pals():
pal_length = 0x4
for mon in range(251):
- name = pokemon_constants[mon+1].title().replace('_','')
+ name = pokemon_constants.pokemon_constants[mon+1].title().replace('_','')
num = str(mon+1).zfill(3)
dir = 'gfx/pics/'+num+'/'
@@ -1160,7 +1147,7 @@ def dump_trainer_pals():
pal_length = 0x4
for trainer in range(67):
- name = trainer_group_names[trainer+1]['constant'].title().replace('_','')
+ name = trainers.trainer_group_names[trainer+1]['constant'].title().replace('_','')
num = str(trainer).zfill(3)
dir = 'gfx/trainers/'
diff --git a/pokemontools/helpers.py b/pokemontools/helpers.py
new file mode 100644
index 0000000..2ecb073
--- /dev/null
+++ b/pokemontools/helpers.py
@@ -0,0 +1,51 @@
+"""
+Generic functions that should be reusable anywhere in pokemontools.
+"""
+import os
+
+def index(seq, f):
+ """
+ return the index of the first item in seq
+ where f(item) == True.
+ """
+ return next((i for i in xrange(len(seq)) if f(seq[i])), None)
+
+def grouper(some_list, count=2):
+ """
+ splits a list into sublists
+
+ given: [1, 2, 3, 4]
+ returns: [[1, 2], [3, 4]]
+ """
+ return [some_list[i:i+count] for i in range(0, len(some_list), count)]
+
+def flattener(x):
+ """
+ flattens a list of sublists into just one list (generator)
+ """
+ try:
+ it = iter(x)
+ except TypeError:
+ yield x
+ else:
+ for i in it:
+ for j in flattener(i):
+ yield j
+
+def flatten(x):
+ """
+ flattens a list of sublists into just one list
+ """
+ return list(flattener(x))
+
+def mkdir_p(path):
+ """
+ Make a directory at a given path.
+ """
+ try:
+ os.makedirs(path)
+ except OSError as exc: # Python >2.5
+ if exc.errno == errno.EEXIST:
+ pass
+ else:
+ raise exc
diff --git a/pokemontools/labels.py b/pokemontools/labels.py
index d553bdc..ca411d1 100644
--- a/pokemontools/labels.py
+++ b/pokemontools/labels.py
@@ -3,10 +3,7 @@
Various label/line-related functions.
"""
-from pointers import (
- calculate_pointer,
- calculate_bank,
-)
+import pointers
def remove_quoted_text(line):
"""get rid of content inside quotes
@@ -125,10 +122,10 @@ def line_has_comment_address(line, returnable={}, bank=None):
if offset == None and bank == None:
return False
if bank == None:
- bank = calculate_bank(offset)
+ bank = pointers.calculate_bank(offset)
returnable["bank"] = bank
returnable["offset"] = offset
- returnable["address"] = calculate_pointer(offset, bank=bank)
+ returnable["address"] = pointers.calculate_pointer(offset, bank=bank)
return True
def get_address_from_line_comment(line, bank=None):
diff --git a/redtools/gbz80disasm.py b/redtools/gbz80disasm.py
index 5319898..396ce5b 100644
--- a/redtools/gbz80disasm.py
+++ b/redtools/gbz80disasm.py
@@ -7,7 +7,8 @@ from copy import copy, deepcopy
from pretty_map_headers import random_hash, map_name_cleaner
from ctypes import c_int8
import sys
-spacing = " "
+
+spacing = "\t"
temp_opt_table = [
[ "ADC A", 0x8f, 0 ],
@@ -848,6 +849,4 @@ if __name__ == "__main__":
extract_maps.load_map_pointers()
extract_maps.read_all_map_headers()
- #0x18f96 is PalletTownText1
- #0x19B5D is BluesHouseText1
print output_bank_opcodes(int(sys.argv[1], 16))[0]
diff --git a/tests/integration/tests.py b/tests/integration/tests.py
index 7dcfbf4..1dffd4e 100644
--- a/tests/integration/tests.py
+++ b/tests/integration/tests.py
@@ -37,6 +37,11 @@ from pokemontools.labels import (
get_label_from_line,
)
+from pokemontools.helpers import (
+ grouper,
+ index,
+)
+
from pokemontools.crystal import (
rom,
load_rom,
@@ -69,9 +74,7 @@ from pokemontools.crystal import (
load_asm,
asm,
is_valid_address,
- index,
how_many_until,
- grouper,
get_pokemon_constant_by_id,
generate_map_constant_labels,
get_map_constant_label_by_id,
@@ -321,7 +324,7 @@ class TestMultiByteParam(unittest.TestCase):
}]
self.assertEqual(self.cls.to_asm(), "poop")
-class TestPostParsing: #(unittest.TestCase):
+class TestPostParsing(unittest.TestCase):
"""tests that must be run after parsing all maps"""
def test_signpost_counts(self):
self.assertEqual(len(map_names[1][1]["signposts"]), 0)
diff --git a/tests/tests.py b/tests/tests.py
index 3b77d41..c6c1265 100644
--- a/tests/tests.py
+++ b/tests/tests.py
@@ -37,6 +37,11 @@ from pokemontools.labels import (
get_label_from_line,
)
+from pokemontools.helpers import (
+ grouper,
+ index,
+)
+
from pokemontools.crystal import (
rom,
load_rom,
@@ -69,9 +74,7 @@ from pokemontools.crystal import (
load_asm,
asm,
is_valid_address,
- index,
how_many_until,
- grouper,
get_pokemon_constant_by_id,
generate_map_constant_labels,
get_map_constant_label_by_id,