summaryrefslogtreecommitdiff
path: root/pokemontools/crystal.py
diff options
context:
space:
mode:
Diffstat (limited to 'pokemontools/crystal.py')
-rw-r--r--pokemontools/crystal.py136
1 files changed, 67 insertions, 69 deletions
diff --git a/pokemontools/crystal.py b/pokemontools/crystal.py
index 6053f1f..74763e0 100644
--- a/pokemontools/crystal.py
+++ b/pokemontools/crystal.py
@@ -2,16 +2,15 @@
"""
utilities to help disassemble pokémon crystal
"""
+from __future__ import print_function
+from __future__ import absolute_import
import os
import sys
import inspect
-import hashlib
import json
from copy import copy, deepcopy
import subprocess
-from new import classobj
-import random
import logging
# for capwords
@@ -47,27 +46,27 @@ texts = []
# this doesn't do anything but is still used in TextScript
constant_abbreviation_bytes = {}
-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
-
-import addresses
+from . import helpers
+from . import chars
+from . import labels
+from . import pksv
+from . import romstr
+from . import pointers
+from . import interval_map
+from . import trainers
+from . import move_constants
+from . import pokemon_constants
+from . import item_constants
+from . import wram
+from . import exceptions
+
+from . import addresses
is_valid_address = addresses.is_valid_address
-import old_text_script
+from . import old_text_script
OldTextScript = old_text_script
-import configuration
+from . import configuration
conf = configuration.Config()
data_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), "data/pokecrystal/")
@@ -75,8 +74,8 @@ conf.wram = os.path.join(data_path, "wram.asm")
conf.gbhw = os.path.join(data_path, "gbhw.asm")
conf.hram = os.path.join(data_path, "hram.asm")
-from map_names import map_names
-from song_names import song_names
+from .map_names import map_names
+from .song_names import song_names
# ---- script_parse_table explanation ----
# This is an IntervalMap that keeps track of previously parsed scripts, texts
@@ -239,7 +238,7 @@ def command_debug_information(command_byte=None, map_group=None, map_id=None, ad
return info1
all_texts = []
-class TextScript:
+class TextScript(object):
"""
A text is a sequence of bytes (and sometimes commands). It's not the same
thing as a Script. The bytes are translated into characters based on the
@@ -435,7 +434,7 @@ def find_text_addresses():
useful for testing parse_text_engine_script_at"""
return TextScript.find_addresses()
-class EncodedText:
+class EncodedText(object):
"""a sequence of bytes that, when decoded, represent readable text
based on the chars table from preprocessor.py and other places"""
base_label = "UnknownRawText_"
@@ -1263,7 +1262,7 @@ class MovementPointerLabelParam(PointerLabelParam):
class MapDataPointerParam(PointerLabelParam):
pass
-class Command:
+class Command(object):
"""
Note: when dumping to asm, anything in script_parse_table that directly
inherits Command should not be .to_asm()'d.
@@ -1453,14 +1452,14 @@ event_flags = None
def read_event_flags():
global event_flags
constants = wram.read_constants(os.path.join(conf.path, 'constants.asm'))
- event_flags = dict(filter(lambda (key, value): value.startswith('EVENT_'), constants.items()))
+ event_flags = dict(filter(lambda key_value: key_value[1].startswith('EVENT_'), constants.items()))
return event_flags
engine_flags = None
def read_engine_flags():
global engine_flags
constants = wram.read_constants(os.path.join(conf.path, 'constants.asm'))
- engine_flags = dict(filter(lambda (key, value): value.startswith('ENGINE_'), constants.items()))
+ engine_flags = dict(filter(lambda key_value1: key_value1[1].startswith('ENGINE_'), constants.items()))
return engine_flags
class EventFlagParam(MultiByteParam):
@@ -1611,7 +1610,7 @@ def create_movement_commands(debug=False):
klass_name = cmd_name+"Command"
params["id"] = copy(byte)
params["macro_name"] = cmd_name
- klass = classobj(copy(klass_name), (MovementCommand,), deepcopy(params))
+ klass = type(copy(klass_name), (MovementCommand,), deepcopy(params))
globals()[klass_name] = klass
movement_command_classes2.append(klass)
@@ -1621,7 +1620,7 @@ def create_movement_commands(debug=False):
del klass_name
else:
klass_name = cmd_name+"Command"
- klass = classobj(klass_name, (MovementCommand,), params)
+ klass = type(klass_name, (MovementCommand,), params)
globals()[klass_name] = klass
movement_command_classes2.append(klass)
# later an individual klass will be instantiated to handle something
@@ -1630,7 +1629,7 @@ def create_movement_commands(debug=False):
movement_command_classes = create_movement_commands()
all_movements = []
-class ApplyMovementData:
+class ApplyMovementData(object):
base_label = "MovementData_"
def __init__(self, address, map_group=None, map_id=None, debug=False, label=None, force=False):
@@ -1763,9 +1762,9 @@ class ApplyMovementData:
def print_all_movements():
for each in all_movements:
- print each.to_asm()
- print "------------------"
- print "done"
+ print(each.to_asm())
+ print("------------------")
+ print("done")
class TextCommand(Command):
# an individual text command will not end it
@@ -2431,7 +2430,7 @@ def create_command_classes(debug=False):
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)
+ klass = type(klass_name, (Command,), params)
globals()[klass_name] = klass
klasses.append(klass)
# later an individual klass will be instantiated to handle something
@@ -2439,7 +2438,7 @@ def create_command_classes(debug=False):
command_classes = create_command_classes()
-class BigEndianParam:
+class BigEndianParam(object):
"""big-endian word"""
size = 2
should_be_decimal = False
@@ -2548,7 +2547,7 @@ def create_music_command_classes(debug=False):
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)
+ klass = type(klass_name, (Command,), params)
globals()[klass_name] = klass
if klass.macro_name == "notetype":
klass.allowed_lengths = [1, 2]
@@ -2808,7 +2807,7 @@ def create_effect_command_classes(debug=False):
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)
+ klass = type(klass_name, (Command,), params)
globals()[klass_name] = klass
klasses.append(klass)
# later an individual klass will be instantiated to handle something
@@ -2854,9 +2853,9 @@ def pretty_print_pksv_no_names():
for (command_byte, addresses) in pksv_no_names.items():
if command_byte in pksv.pksv_crystal_unknowns:
continue
- print hex(command_byte) + " appearing in these scripts: "
+ print(hex(command_byte) + " appearing in these scripts: ")
for address in addresses:
- print " " + hex(address)
+ print(" " + hex(address))
recursive_scripts = set([])
def rec_parse_script_engine_script_at(address, origin=None, debug=True):
@@ -2891,7 +2890,7 @@ stop_points = [0x1aafa2,
0x9f58f, # battle tower
0x9f62f, # battle tower
]
-class Script:
+class Script(object):
base_label = "UnknownScript_"
def __init__(self, *args, **kwargs):
self.address = None
@@ -3086,7 +3085,7 @@ class Script:
def old_parse(self, *args, **kwargs):
"""included from old_parse_scripts"""
-import old_parse_scripts
+from . 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):
@@ -3469,7 +3468,7 @@ class TrainerFragmentParam(PointerLabelParam):
return deps
trainer_group_table = None
-class TrainerGroupTable:
+class TrainerGroupTable(object):
"""
A list of pointers.
@@ -3524,7 +3523,7 @@ class TrainerGroupTable:
output = "".join([str("dw "+get_label_for(header.address)+"\n") for header in self.headers])
return output
-class TrainerGroupHeader:
+class TrainerGroupHeader(object):
"""
A trainer group header is a repeating list of individual trainer headers.
@@ -3617,7 +3616,7 @@ class TrainerGroupHeader:
output = "\n\n".join(["; "+header.make_constant_name()+" ("+str(header.trainer_id)+") at "+hex(header.address)+"\n"+header.to_asm() for header in self.individual_trainer_headers])
return output
-class TrainerHeader:
+class TrainerHeader(object):
"""
<Trainer Name> <0x50> <Data type> <Pokémon Data>+ <0xFF>
@@ -3722,7 +3721,7 @@ class TrainerHeader:
output += "\n; last_address="+hex(self.last_address)+" size="+str(self.size)
return output
-class TrainerPartyMonParser:
+class TrainerPartyMonParser(object):
"""
Just a generic trainer party mon parser.
Don't use this directly. Only use the child classes.
@@ -4251,8 +4250,8 @@ class PeopleEvent(Command):
lower_bits = color_function_byte & 0xF
higher_bits = color_function_byte >> 4
is_regular_script = lower_bits == 00
- is_give_item = lower_bits == 01
- is_trainer = lower_bits == 02
+ is_give_item = lower_bits == 0o1
+ is_trainer = lower_bits == 0o2
current_address += obj.size
self.size += obj.size
i += 1
@@ -4326,9 +4325,9 @@ def old_parse_people_event_bytes(some_bytes, address=None, map_group=None, map_i
is_regular_script = lower_bits == 00
# pointer points to script
- is_give_item = lower_bits == 01
+ is_give_item = lower_bits == 0o1
# pointer points to [Item no.][Amount]
- is_trainer = lower_bits == 02
+ is_trainer = lower_bits == 0o2
# pointer points to trainer header
# goldmap called these next two bytes "text_block" and "text_bank"?
@@ -4412,7 +4411,7 @@ def old_parse_people_event_bytes(some_bytes, address=None, map_group=None, map_i
return people_events
-class SignpostRemoteBase:
+class SignpostRemoteBase(object):
def __init__(self, address, bank=None, map_group=None, map_id=None, signpost=None, debug=False, label=None):
self.address = address
self.last_address = address + self.size
@@ -4851,7 +4850,7 @@ class TimeOfDayParam(DecimalParam):
return DecimalParam.to_asm(self)
-class MapHeader:
+class MapHeader(object):
base_label = "MapHeader_"
def __init__(self, address, map_group=None, map_id=None, debug=True, label=None, bank=0x25):
@@ -4937,7 +4936,7 @@ def get_direction(connection_byte, connection_id):
return results[connection_id]
-class SecondMapHeader:
+class SecondMapHeader(object):
base_label = "SecondMapHeader_"
def __init__(self, address, map_group=None, map_id=None, debug=True, bank=None, label=None):
@@ -5079,7 +5078,7 @@ wrong_easts = []
wrong_souths = []
wrong_wests = []
-class Connection:
+class Connection(object):
size = 12
def __init__(self, address, direction=None, map_group=None, map_id=None, debug=True, smh=None):
@@ -5743,7 +5742,7 @@ def parse_second_map_header_at(address, map_group=None, map_id=None, debug=True)
all_second_map_headers.append(smh)
return smh
-class MapBlockData:
+class MapBlockData(object):
base_label = "MapBlockData_"
maps_path = os.path.realpath(os.path.join(conf.path, "maps"))
@@ -5789,7 +5788,7 @@ class MapBlockData:
return "INCBIN \"maps/"+self.map_name+".blk\""
-class MapEventHeader:
+class MapEventHeader(object):
base_label = "MapEventHeader_"
def __init__(self, address, map_group=None, map_id=None, debug=True, bank=None, label=None):
@@ -5928,7 +5927,7 @@ def parse_map_event_header_at(address, map_group=None, map_id=None, debug=True,
all_map_event_headers.append(ev)
return ev
-class MapScriptHeader:
+class MapScriptHeader(object):
"""parses a script header
This structure allows the game to have e.g. one-time only events on a map
@@ -6121,7 +6120,7 @@ def parse_all_map_headers(map_names, all_map_headers=None, _parse_map_header_at=
"""
if _parse_map_header_at == None:
_parse_map_header_at = parse_map_header_at
- if not map_names[1].has_key("offset"):
+ if "offset" not in map_names[1]:
raise Exception("dunno what to do - map_names should have groups with pre-calculated offsets by now")
for (group_id, group_data) in map_names.items():
offset = group_data["offset"]
@@ -6140,7 +6139,7 @@ def parse_all_map_headers(map_names, all_map_headers=None, _parse_map_header_at=
new_parsed_map = _parse_map_header_at(map_header_offset, map_group=group_id, map_id=map_id, all_map_headers=all_map_headers, rom=rom, debug=debug)
map_names[group_id][map_id]["header_new"] = new_parsed_map
-class PokedexEntryPointerTable:
+class PokedexEntryPointerTable(object):
"""
A list of pointers.
"""
@@ -6190,7 +6189,7 @@ class PokedexEntryPointerTable:
output = "".join([str("dw "+get_label_for(entry.address)+"\n") for entry in self.entries])
return output
-class PokedexEntry:
+class PokedexEntry(object):
def __init__(self, address, pokemon_id):
self.address = address
self.dependencies = None
@@ -6244,7 +6243,7 @@ for map_group_id in map_names.keys():
# skip if we maybe already have the 'offset' label set in this map group
if map_id == "offset": continue
# skip if we provided a pre-set value for the map's label
- if map_group[map_id].has_key("label"): continue
+ if "label" in map_group[map_id]: continue
# convience alias
map_data = map_group[map_id]
# clean up the map name to be an asm label
@@ -6306,7 +6305,7 @@ def get_dependencies_for(some_object, recompute=False, global_dependencies=set()
else:
some_object.get_dependencies(recompute=recompute, global_dependencies=global_dependencies)
return global_dependencies
- except RuntimeError, e:
+ except RuntimeError as e:
# 1552, 1291, 2075, 1552, 1291...
errorargs = {
@@ -6532,15 +6531,14 @@ def apply_diff(diff, try_fixing=True, do_compile=True):
try:
subprocess.check_call("cd " + conf.path + "; make clean; make", shell=True)
return True
- except Exception, exc:
+ except Exception as exc:
if try_fixing:
os.system("mv " + os.path.join(conf.path, "main1.asm") + " " + os.path.join(conf.path, "main.asm"))
return False
-import crystalparts.asmline
-AsmLine = crystalparts.asmline.AsmLine
+from .crystalparts.asmline import AsmLine
-class Incbin:
+class Incbin(object):
def __init__(self, line, bank=None, debug=False):
self.line = line
self.bank = bank
@@ -6559,7 +6557,7 @@ class Incbin:
logging.debug("Incbin.parse start is {0}".format(start))
try:
start = eval(start)
- except Exception, e:
+ except Exception as e:
logging.debug("start is {0}".format(start))
raise Exception("problem with evaluating interval range: " + str(e))
@@ -6627,7 +6625,7 @@ class Incbin:
return incbins
-class AsmSection:
+class AsmSection(object):
def __init__(self, line):
self.bank_id = None
self.line = line
@@ -6669,7 +6667,7 @@ def load_asm2(filename=None, force=False):
new_asm = Asm(filename=filename)
return new_asm
-class Asm:
+class Asm(object):
"""controls the overall asm output"""
def __init__(self, filename=None, debug=True):
if filename == None:
@@ -7133,7 +7131,7 @@ def get_label_for(address, _all_labels=None, _script_parse_table=None):
# at least until the two approaches are merged in the code base.
all_new_labels = []
-class Label:
+class Label(object):
"""
Every object in script_parse_table is given a label.